UNPKG

dojo

Version:

Dojo core is a powerful, lightweight library that makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.

189 lines (177 loc) 5.9 kB
define(["exports", "./_base/kernel", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-construct", "./_base/connect"], function(exports, dojo, has, lang, dom, style, ctr, conn){ // module: // dojo/dom-prop // summary: // This module defines the core dojo DOM properties API. // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42 // ============================= // Element properties Functions // ============================= // helper to connect events var _evtHdlrMap = {}, _ctr = 1, _attrId = dojo._scopeName + "attrid"; has.add('dom-textContent', function (global, doc, element) { return 'textContent' in element; }); exports.names = { // properties renamed to avoid clashes with reserved words "class": "className", "for": "htmlFor", // properties written as camelCase tabindex: "tabIndex", readonly: "readOnly", colspan: "colSpan", frameborder: "frameBorder", rowspan: "rowSpan", textcontent: "textContent", valuetype: "valueType" }; function getText(/*DOMNode*/node){ // summary: // recursion method for get('textContent') to use. Gets text value for a node. // description: // Juse uses nodedValue so things like <br/> tags do not end up in // the text as any sort of line return. var text = "", ch = node.childNodes; for(var i = 0, n; n = ch[i]; i++){ //Skip comments. if(n.nodeType != 8){ if(n.nodeType == 1){ text += getText(n); }else{ text += n.nodeValue; } } } return text; } exports.get = function getProp(/*DOMNode|String*/ node, /*String*/ name){ // summary: // Gets a property on an HTML element. // description: // Handles normalized getting of properties on DOM nodes. // // node: DOMNode|String // id or reference to the element to get the property on // name: String // the name of the property to get. // returns: // the value of the requested property or its default value // // example: // | // get the current value of the "foo" property on a node // | require(["dojo/dom-prop", "dojo/dom"], function(domProp, dom){ // | domProp.get(dom.byId("nodeId"), "foo"); // | // or we can just pass the id: // | domProp.get("nodeId", "foo"); // | }); node = dom.byId(node); var lc = name.toLowerCase(), propName = exports.names[lc] || name; if(propName == "textContent" && !has("dom-textContent")){ return getText(node); } return node[propName]; // Anything }; exports.set = function setProp(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){ // summary: // Sets a property on an HTML element. // description: // Handles normalized setting of properties on DOM nodes. // // When passing functions as values, note that they will not be // directly assigned to slots on the node, but rather the default // behavior will be removed and the new behavior will be added // using `dojo.connect()`, meaning that event handler properties // will be normalized and that some caveats with regards to // non-standard behaviors for onsubmit apply. Namely that you // should cancel form submission using `dojo.stopEvent()` on the // passed event object instead of returning a boolean value from // the handler itself. // node: DOMNode|String // id or reference to the element to set the property on // name: String|Object // the name of the property to set, or a hash object to set // multiple properties at once. // value: String? // The value to set for the property // returns: // the DOM node // // example: // | // use prop() to set the tab index // | require(["dojo/dom-prop"], function(domProp){ // | domProp.set("nodeId", "tabIndex", 3); // | }); // // example: // Set multiple values at once, including event handlers: // | require(["dojo/dom-prop"], function(domProp){ // | domProp.set("formId", { // | "foo": "bar", // | "tabIndex": -1, // | "method": "POST", // | }); // | }); node = dom.byId(node); var l = arguments.length; if(l == 2 && typeof name != "string"){ // inline'd type check // the object form of setter: the 2nd argument is a dictionary for(var x in name){ exports.set(node, x, name[x]); } return node; // DomNode } var lc = name.toLowerCase(), propName = exports.names[lc] || name; if(propName == "style" && typeof value != "string"){ // inline'd type check // special case: setting a style style.set(node, value); return node; // DomNode } if(propName == "innerHTML"){ // special case: assigning HTML // the hash lists elements with read-only innerHTML on IE if(has("ie") && node.tagName.toLowerCase() in {col: 1, colgroup: 1, table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1}){ ctr.empty(node); node.appendChild(ctr.toDom(value, node.ownerDocument)); }else{ node[propName] = value; } return node; // DomNode } if(propName == "textContent" && !has("dom-textContent")) { ctr.empty(node); node.appendChild(node.ownerDocument.createTextNode(value)); return node; } if(lang.isFunction(value)){ // special case: assigning an event handler // clobber if we can var attrId = node[_attrId]; if(!attrId){ attrId = _ctr++; node[_attrId] = attrId; } if(!_evtHdlrMap[attrId]){ _evtHdlrMap[attrId] = {}; } var h = _evtHdlrMap[attrId][propName]; if(h){ //h.remove(); conn.disconnect(h); }else{ try{ delete node[propName]; }catch(e){} } // ensure that event objects are normalized, etc. if(value){ //_evtHdlrMap[attrId][propName] = on(node, propName, value); _evtHdlrMap[attrId][propName] = conn.connect(node, propName, value); }else{ node[propName] = null; } return node; // DomNode } node[propName] = value; return node; // DomNode }; });