summaryrefslogtreecommitdiff
path: root/lib/dojo/dom-construct.js.uncompressed.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dojo/dom-construct.js.uncompressed.js')
-rw-r--r--lib/dojo/dom-construct.js.uncompressed.js329
1 files changed, 329 insertions, 0 deletions
diff --git a/lib/dojo/dom-construct.js.uncompressed.js b/lib/dojo/dom-construct.js.uncompressed.js
new file mode 100644
index 000000000..6abef71aa
--- /dev/null
+++ b/lib/dojo/dom-construct.js.uncompressed.js
@@ -0,0 +1,329 @@
+define("dojo/dom-construct", ["exports", "./_base/kernel", "./sniff", "./_base/window", "./dom", "./dom-attr", "./on"],
+ function(exports, dojo, has, win, dom, attr, on){
+ // module:
+ // dojo/dom-construct
+ // summary:
+ // This module defines the core dojo DOM construction API.
+
+ // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42
+
+ // support stuff for toDom()
+ var tagWrap = {
+ option: ["select"],
+ tbody: ["table"],
+ thead: ["table"],
+ tfoot: ["table"],
+ tr: ["table", "tbody"],
+ td: ["table", "tbody", "tr"],
+ th: ["table", "thead", "tr"],
+ legend: ["fieldset"],
+ caption: ["table"],
+ colgroup: ["table"],
+ col: ["table", "colgroup"],
+ li: ["ul"]
+ },
+ reTag = /<\s*([\w\:]+)/,
+ masterNode = {}, masterNum = 0,
+ masterName = "__" + dojo._scopeName + "ToDomId";
+
+ // generate start/end tag strings to use
+ // for the injection for each special tag wrap case.
+ for(var param in tagWrap){
+ if(tagWrap.hasOwnProperty(param)){
+ var tw = tagWrap[param];
+ tw.pre = param == "option" ? '<select multiple="multiple">' : "<" + tw.join("><") + ">";
+ tw.post = "</" + tw.reverse().join("></") + ">";
+ // the last line is destructive: it reverses the array,
+ // but we don't care at this point
+ }
+ }
+
+ function _insertBefore(/*DomNode*/ node, /*DomNode*/ ref){
+ var parent = ref.parentNode;
+ if(parent){
+ parent.insertBefore(node, ref);
+ }
+ }
+
+ function _insertAfter(/*DomNode*/ node, /*DomNode*/ ref){
+ // summary:
+ // Try to insert node after ref
+ var parent = ref.parentNode;
+ if(parent){
+ if(parent.lastChild == ref){
+ parent.appendChild(node);
+ }else{
+ parent.insertBefore(node, ref.nextSibling);
+ }
+ }
+ }
+
+ exports.toDom = function toDom(frag, doc){
+ // summary:
+ // instantiates an HTML fragment returning the corresponding DOM.
+ // frag: String
+ // the HTML fragment
+ // doc: DocumentNode?
+ // optional document to use when creating DOM nodes, defaults to
+ // dojo.doc if not specified.
+ // returns:
+ // Document fragment, unless it's a single node in which case it returns the node itself
+ // example:
+ // Create a table row:
+ // | var tr = dojo.toDom("<tr><td>First!</td></tr>");
+
+ doc = doc || win.doc;
+ var masterId = doc[masterName];
+ if(!masterId){
+ doc[masterName] = masterId = ++masterNum + "";
+ masterNode[masterId] = doc.createElement("div");
+ }
+
+ // make sure the frag is a string.
+ frag += "";
+
+ // find the starting tag, and get node wrapper
+ var match = frag.match(reTag),
+ tag = match ? match[1].toLowerCase() : "",
+ master = masterNode[masterId],
+ wrap, i, fc, df;
+ if(match && tagWrap[tag]){
+ wrap = tagWrap[tag];
+ master.innerHTML = wrap.pre + frag + wrap.post;
+ for(i = wrap.length; i; --i){
+ master = master.firstChild;
+ }
+ }else{
+ master.innerHTML = frag;
+ }
+
+ // one node shortcut => return the node itself
+ if(master.childNodes.length == 1){
+ return master.removeChild(master.firstChild); // DOMNode
+ }
+
+ // return multiple nodes as a document fragment
+ df = doc.createDocumentFragment();
+ while((fc = master.firstChild)){ // intentional assignment
+ df.appendChild(fc);
+ }
+ return df; // DocumentFragment
+ };
+
+ exports.place = function place(/*DOMNode|String*/ node, /*DOMNode|String*/ refNode, /*String|Number?*/ position){
+ // summary:
+ // Attempt to insert node into the DOM, choosing from various positioning options.
+ // Returns the first argument resolved to a DOM node.
+ // node: DOMNode|String
+ // id or node reference, or HTML fragment starting with "<" to place relative to refNode
+ // refNode: DOMNode|String
+ // id or node reference to use as basis for placement
+ // position: String|Number?
+ // string noting the position of node relative to refNode or a
+ // number indicating the location in the childNodes collection of refNode.
+ // Accepted string values are:
+ //
+ // - before
+ // - after
+ // - replace
+ // - only
+ // - first
+ // - last
+ //
+ // "first" and "last" indicate positions as children of refNode, "replace" replaces refNode,
+ // "only" replaces all children. position defaults to "last" if not specified
+ // returns: DOMNode
+ // Returned values is the first argument resolved to a DOM node.
+ //
+ // .place() is also a method of `dojo/NodeList`, allowing `dojo.query` node lookups.
+ // example:
+ // Place a node by string id as the last child of another node by string id:
+ // | dojo.place("someNode", "anotherNode");
+ // example:
+ // Place a node by string id before another node by string id
+ // | dojo.place("someNode", "anotherNode", "before");
+ // example:
+ // Create a Node, and place it in the body element (last child):
+ // | dojo.place("<div></div>", dojo.body());
+ // example:
+ // Put a new LI as the first child of a list by id:
+ // | dojo.place("<li></li>", "someUl", "first");
+
+ refNode = dom.byId(refNode);
+ if(typeof node == "string"){ // inline'd type check
+ node = /^\s*</.test(node) ? exports.toDom(node, refNode.ownerDocument) : dom.byId(node);
+ }
+ if(typeof position == "number"){ // inline'd type check
+ var cn = refNode.childNodes;
+ if(!cn.length || cn.length <= position){
+ refNode.appendChild(node);
+ }else{
+ _insertBefore(node, cn[position < 0 ? 0 : position]);
+ }
+ }else{
+ switch(position){
+ case "before":
+ _insertBefore(node, refNode);
+ break;
+ case "after":
+ _insertAfter(node, refNode);
+ break;
+ case "replace":
+ refNode.parentNode.replaceChild(node, refNode);
+ break;
+ case "only":
+ exports.empty(refNode);
+ refNode.appendChild(node);
+ break;
+ case "first":
+ if(refNode.firstChild){
+ _insertBefore(node, refNode.firstChild);
+ break;
+ }
+ // else fallthrough...
+ default: // aka: last
+ refNode.appendChild(node);
+ }
+ }
+ return node; // DomNode
+ };
+
+ exports.create = function create(/*DOMNode|String*/ tag, /*Object*/ attrs, /*DOMNode|String?*/ refNode, /*String?*/ pos){
+ // summary:
+ // Create an element, allowing for optional attribute decoration
+ // and placement.
+ // description:
+ // A DOM Element creation function. A shorthand method for creating a node or
+ // a fragment, and allowing for a convenient optional attribute setting step,
+ // as well as an optional DOM placement reference.
+ //
+ // Attributes are set by passing the optional object through `dojo.setAttr`.
+ // See `dojo.setAttr` for noted caveats and nuances, and API if applicable.
+ //
+ // Placement is done via `dojo.place`, assuming the new node to be the action
+ // node, passing along the optional reference node and position.
+ // tag: DOMNode|String
+ // A string of the element to create (eg: "div", "a", "p", "li", "script", "br"),
+ // or an existing DOM node to process.
+ // attrs: Object
+ // An object-hash of attributes to set on the newly created node.
+ // Can be null, if you don't want to set any attributes/styles.
+ // See: `dojo.setAttr` for a description of available attributes.
+ // refNode: DOMNode|String?
+ // Optional reference node. Used by `dojo.place` to place the newly created
+ // node somewhere in the dom relative to refNode. Can be a DomNode reference
+ // or String ID of a node.
+ // pos: String?
+ // Optional positional reference. Defaults to "last" by way of `dojo.place`,
+ // though can be set to "first","after","before","last", "replace" or "only"
+ // to further control the placement of the new node relative to the refNode.
+ // 'refNode' is required if a 'pos' is specified.
+ // example:
+ // Create a DIV:
+ // | var n = dojo.create("div");
+ //
+ // example:
+ // Create a DIV with content:
+ // | var n = dojo.create("div", { innerHTML:"<p>hi</p>" });
+ //
+ // example:
+ // Place a new DIV in the BODY, with no attributes set
+ // | var n = dojo.create("div", null, dojo.body());
+ //
+ // example:
+ // Create an UL, and populate it with LI's. Place the list as the first-child of a
+ // node with id="someId":
+ // | var ul = dojo.create("ul", null, "someId", "first");
+ // | var items = ["one", "two", "three", "four"];
+ // | dojo.forEach(items, function(data){
+ // | dojo.create("li", { innerHTML: data }, ul);
+ // | });
+ //
+ // example:
+ // Create an anchor, with an href. Place in BODY:
+ // | dojo.create("a", { href:"foo.html", title:"Goto FOO!" }, dojo.body());
+ //
+ // example:
+ // Create a `dojo/NodeList()` from a new element (for syntactic sugar):
+ // | dojo.query(dojo.create('div'))
+ // | .addClass("newDiv")
+ // | .onclick(function(e){ console.log('clicked', e.target) })
+ // | .place("#someNode"); // redundant, but cleaner.
+
+ var doc = win.doc;
+ if(refNode){
+ refNode = dom.byId(refNode);
+ doc = refNode.ownerDocument;
+ }
+ if(typeof tag == "string"){ // inline'd type check
+ tag = doc.createElement(tag);
+ }
+ if(attrs){ attr.set(tag, attrs); }
+ if(refNode){ exports.place(tag, refNode, pos); }
+ return tag; // DomNode
+ };
+
+ var _empty = has("ie") ?
+ function(/*DomNode*/ node){
+ try{
+ node.innerHTML = ""; // really fast when it works
+ }catch(e){ // IE can generate Unknown Error
+ for(var c; c = node.lastChild;){ // intentional assignment
+ _destroy(c, node); // destroy is better than removeChild so TABLE elements are removed in proper order
+ }
+ }
+ } :
+ function(/*DomNode*/ node){
+ node.innerHTML = "";
+ };
+
+ exports.empty = function empty(/*DOMNode|String*/ node){
+ // summary:
+ // safely removes all children of the node.
+ // node: DOMNode|String
+ // a reference to a DOM node or an id.
+ // example:
+ // Destroy node's children byId:
+ // | dojo.empty("someId");
+ //
+ // example:
+ // Destroy all nodes' children in a list by reference:
+ // | dojo.query(".someNode").forEach(dojo.empty);
+
+ _empty(dom.byId(node));
+ };
+
+
+ function _destroy(/*DomNode*/ node, /*DomNode*/ parent){
+ if(node.firstChild){
+ _empty(node);
+ }
+ if(parent){
+ parent.removeChild(node);
+ }
+ }
+ exports.destroy = function destroy(/*DOMNode|String*/ node){
+ // summary:
+ // Removes a node from its parent, clobbering it and all of its
+ // children.
+ //
+ // description:
+ // Removes a node from its parent, clobbering it and all of its
+ // children. Function only works with DomNodes, and returns nothing.
+ //
+ // node: DOMNode|String
+ // A String ID or DomNode reference of the element to be destroyed
+ //
+ // example:
+ // Destroy a node byId:
+ // | dojo.destroy("someId");
+ //
+ // example:
+ // Destroy all nodes in a list by reference:
+ // | dojo.query(".someNode").forEach(dojo.destroy);
+
+ node = dom.byId(node);
+ if(!node){ return; }
+ _destroy(node, node.parentNode);
+ };
+});