UNPKG

can

Version:

MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.

215 lines (214 loc) 9.28 kB
/*! * CanJS - 2.3.34 * http://canjs.com/ * Copyright (c) 2018 Bitovi * Mon, 30 Apr 2018 20:56:51 GMT * Licensed MIT */ /*can@2.3.34#util/attr/attr*/ define(['can/util/can'], function (can) { var namespaces = { 'xlink': 'http://www.w3.org/1999/xlink' }; var setImmediate = can.global.setImmediate || function (cb) { return setTimeout(cb, 0); }, formElements = { 'input': true, 'textarea': true, 'select': true }, hasProperty = function (el, attrName) { return attrName in el || can.document && formElements[el.nodeName.toLowerCase()]; }, attr = { MutationObserver: can.global.MutationObserver || can.global.WebKitMutationObserver || can.global.MozMutationObserver, map: { 'class': function (el, val) { val = val || ''; if (el.namespaceURI === 'http://www.w3.org/2000/svg') { el.setAttribute('class', val); } else { el.className = val; } return val; }, 'value': 'value', 'innertext': 'innerText', 'innerhtml': 'innerHTML', 'textcontent': 'textContent', 'for': 'htmlFor', 'checked': true, 'disabled': true, 'readonly': function (el, val) { el.readOnly = val || typeof val === 'string' ? true : false; return val; }, 'required': true, src: function (el, val) { if (val == null || val === '') { el.removeAttribute('src'); return null; } else { el.setAttribute('src', val); return val; } }, style: function () { var el = can.global.document && document.createElement('div'); if (el && el.style && 'cssText' in el.style) { return function (el, val) { return el.style.cssText = val || ''; }; } else { return function (el, val) { return el.setAttribute('style', val); }; } }() }, defaultValue: [ 'input', 'textarea' ], setAttrOrProp: function (el, attrName, val) { attrName = attrName.toLowerCase(); var prop = attr.map[attrName]; if (prop === true && !val) { this.remove(el, attrName); } else { this.set(el, attrName, val); } }, setSelectValue: function (el, val) { if (val != null) { var options = el.getElementsByTagName('option'); for (var i = 0; i < options.length; i++) { if (val == options[i].value) { options[i].selected = true; return; } } } el.selectedIndex = -1; }, set: function (el, attrName, val) { var usingMutationObserver = can.isDOM(el) && attr.MutationObserver; attrName = attrName.toLowerCase(); var oldValue; if (!usingMutationObserver) { oldValue = attr.get(el, attrName); } var prop = attr.map[attrName], newValue; if (typeof prop === 'function') { newValue = prop(el, val); } else if (prop === true && hasProperty(el, attrName)) { newValue = el[attrName] = true; if (attrName === 'checked' && el.type === 'radio') { if (can.inArray((el.nodeName + '').toLowerCase(), attr.defaultValue) >= 0) { el.defaultChecked = true; } } } else if (typeof prop === 'string' && hasProperty(el, prop)) { newValue = val; if (el[prop] !== val || el.nodeName.toUpperCase() === 'OPTION') { el[prop] = val; } if (prop === 'value' && can.inArray((el.nodeName + '').toLowerCase(), attr.defaultValue) >= 0) { el.defaultValue = val; } } else { attr.setAttribute(el, attrName, val); } if (!usingMutationObserver && newValue !== oldValue) { attr.trigger(el, attrName, oldValue); } }, setAttribute: function () { var doc = can.global.document; if (doc && document.createAttribute) { try { doc.createAttribute('{}'); } catch (e) { var invalidNodes = {}, attributeDummy = document.createElement('div'); return function (el, attrName, val) { var first = attrName.charAt(0), cachedNode, node, attr; if ((first === '{' || first === '(' || first === '*') && el.setAttributeNode) { cachedNode = invalidNodes[attrName]; if (!cachedNode) { attributeDummy.innerHTML = '<div ' + attrName + '=""></div>'; cachedNode = invalidNodes[attrName] = attributeDummy.childNodes[0].attributes[0]; } node = cachedNode.cloneNode(); node.value = val; el.setAttributeNode(node); } else { attr = attrName.split(':'); if (attr.length !== 1) { el.setAttributeNS(namespaces[attr[0]], attrName, val); } else { el.setAttribute(attrName, val); } } }; } } return function (el, attrName, val) { el.setAttribute(attrName, val); }; }(), trigger: function (el, attrName, oldValue) { if (can.data(can.$(el), 'canHasAttributesBindings')) { attrName = attrName.toLowerCase(); return setImmediate(function () { can.trigger(el, { type: 'attributes', attributeName: attrName, target: el, oldValue: oldValue, bubbles: false }, []); }); } }, get: function (el, attrName) { attrName = attrName.toLowerCase(); var prop = attr.map[attrName]; if (typeof prop === 'string' && hasProperty(el, prop)) { return el[prop]; } else if (prop === true && hasProperty(el, attrName)) { return el[attrName]; } return el.getAttribute(attrName); }, remove: function (el, attrName) { attrName = attrName.toLowerCase(); var oldValue; if (!attr.MutationObserver) { oldValue = attr.get(el, attrName); } var setter = attr.map[attrName]; if (typeof setter === 'function') { setter(el, undefined); } if (setter === true && hasProperty(el, attrName)) { el[attrName] = false; } else if (typeof setter === 'string' && hasProperty(el, setter)) { el[setter] = ''; } else { el.removeAttribute(attrName); } if (!attr.MutationObserver && oldValue != null) { attr.trigger(el, attrName, oldValue); } }, has: function () { var el = can.global.document && document.createElement('div'); if (el && el.hasAttribute) { return function (el, name) { return el.hasAttribute(name); }; } else { return function (el, name) { return el.getAttribute(name) !== null; }; } }() }; return attr; });