You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
5.8 KiB
188 lines
5.8 KiB
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 |
|
}; |
|
});
|
|
|