]> git.wh0rd.org - tt-rss.git/blobdiff - lib/dojo/_base/html.js
lib: Upgrade Dojo and Dijit from 1.8.3 to 1.12.1
[tt-rss.git] / lib / dojo / _base / html.js
index 8661b2b123c53c6b4b0cf7c39b1032ed9ee3685d..2bf3589069bbb030c53ff6f7d0bb67e41e5738cf 100644 (file)
 /*
-       Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+       Copyright (c) 2004-2016, The JS Foundation All Rights Reserved.
        Available via Academic Free License >= 2.1 OR the modified BSD license.
        see: http://dojotoolkit.org/license for details
 */
 
-
-if(!dojo._hasResource["dojo._base.html"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
-dojo._hasResource["dojo._base.html"] = true;
-dojo.provide("dojo._base.html");
-dojo.require("dojo._base.lang");
-
-
-// FIXME: need to add unit tests for all the semi-public methods
-
-try{
-       document.execCommand("BackgroundImageCache", false, true);
-}catch(e){
-       // sane browsers don't have cache "issues"
-}
-
-// =============================
-// DOM Functions
-// =============================
-
-/*=====
-dojo.byId = function(id, doc){
-       //      summary:
-       //              Returns DOM node with matching `id` attribute or `null`
-       //              if not found. If `id` is a DomNode, this function is a no-op.
-       //
-       //      id: String|DOMNode
-       //              A string to match an HTML id attribute or a reference to a DOM Node
-       //
-       //      doc: Document?
-       //              Document to work in. Defaults to the current value of
-       //              dojo.doc.  Can be used to retrieve
-       //              node references from other documents.
-       //
-       //      example:
-       //      Look up a node by ID:
-       //      |       var n = dojo.byId("foo");
-       //
-       //      example:
-       //      Check if a node exists, and use it.
-       //      |       var n = dojo.byId("bar");
-       //      |       if(n){ doStuff() ... }
-       //
-       //      example:
-       //      Allow string or DomNode references to be passed to a custom function:
-       //      |       var foo = function(nodeOrId){
-       //      |               nodeOrId = dojo.byId(nodeOrId);
-       //      |               // ... more stuff
-       //      |       }
-=====*/
-
-if(dojo.isIE){
-       dojo.byId = function(id, doc){
-               if(typeof id != "string"){
-                       return id;
-               }
-               var _d = doc || dojo.doc, te = _d.getElementById(id);
-               // attributes.id.value is better than just id in case the
-               // user has a name=id inside a form
-               if(te && (te.attributes.id.value == id || te.id == id)){
-                       return te;
-               }else{
-                       var eles = _d.all[id];
-                       if(!eles || eles.nodeName){
-                               eles = [eles];
-                       }
-                       // if more than 1, choose first with the correct id
-                       var i=0;
-                       while((te=eles[i++])){
-                               if((te.attributes && te.attributes.id && te.attributes.id.value == id)
-                                       || te.id == id){
-                                       return te;
-                               }
-                       }
-               }
-       };
-}else{
-       dojo.byId = function(id, doc){
-               // inline'd type check.
-               // be sure to return null per documentation, to match IE branch.
-               return ((typeof id == "string") ? (doc || dojo.doc).getElementById(id) : id) || null; // DomNode
-       };
-}
-/*=====
-};
-=====*/
-
-(function(){
-       var d = dojo;
-       var byId = d.byId;
-
-       var _destroyContainer = null,
-               _destroyDoc;
-               d.addOnWindowUnload(function(){
-               _destroyContainer = null; //prevent IE leak
-       });
-       
-/*=====
-       dojo._destroyElement = function(node){
-               // summary:
-               //              Existing alias for `dojo.destroy`. Deprecated, will be removed
-               //              in 2.0
-       }
-=====*/
-       dojo._destroyElement = dojo.destroy = function(/*String|DomNode*/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:
-               //              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 = byId(node);
-               try{
-                       var doc = node.ownerDocument;
-                       // cannot use _destroyContainer.ownerDocument since this can throw an exception on IE
-                       if(!_destroyContainer || _destroyDoc != doc){
-                               _destroyContainer = doc.createElement("div");
-                               _destroyDoc = doc;
-                       }
-                       _destroyContainer.appendChild(node.parentNode ? node.parentNode.removeChild(node) : node);
-                       // NOTE: see http://trac.dojotoolkit.org/ticket/2931. This may be a bug and not a feature
-                       _destroyContainer.innerHTML = "";
-               }catch(e){
-                       /* squelch */
-               }
-       };
-
-       dojo.isDescendant = function(/*DomNode|String*/node, /*DomNode|String*/ancestor){
-               //      summary:
-               //              Returns true if node is a descendant of ancestor
-               //      node: string id or node reference to test
-               //      ancestor: string id or node reference of potential parent to test against
-               //
-               // example:
-               //      Test is node id="bar" is a descendant of node id="foo"
-               //      |       if(dojo.isDescendant("bar", "foo")){ ... }
-               try{
-                       node = byId(node);
-                       ancestor = byId(ancestor);
-                       while(node){
-                               if(node == ancestor){
-                                       return true; // Boolean
-                               }
-                               node = node.parentNode;
-                       }
-               }catch(e){ /* squelch, return false */ }
-               return false; // Boolean
-       };
-
-       dojo.setSelectable = function(/*DomNode|String*/node, /*Boolean*/selectable){
-               //      summary:
-               //              Enable or disable selection on a node
-               //      node:
-               //              id or reference to node
-               //      selectable:
-               //              state to put the node in. false indicates unselectable, true
-               //              allows selection.
-               //      example:
-               //      Make the node id="bar" unselectable
-               //      |       dojo.setSelectable("bar");
-               //      example:
-               //      Make the node id="bar" selectable
-               //      |       dojo.setSelectable("bar", true);
-               node = byId(node);
-                               if(d.isMozilla){
-                       node.style.MozUserSelect = selectable ? "" : "none";
-               }else if(d.isKhtml || d.isWebKit){
-                                       node.style.KhtmlUserSelect = selectable ? "auto" : "none";
-                               }else if(d.isIE){
-                       var v = (node.unselectable = selectable ? "" : "on");
-                       d.query("*", node).forEach("item.unselectable = '"+v+"'");
-               }
-                               //FIXME: else?  Opera?
-       };
-
-       var _insertBefore = function(/*DomNode*/node, /*DomNode*/ref){
-               var parent = ref.parentNode;
-               if(parent){
-                       parent.insertBefore(node, ref);
-               }
-       };
-
-       var _insertAfter = function(/*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);
-                       }
-               }
-       };
-
-       dojo.place = function(node, refNode, position){
-               //      summary:
-               //              Attempt to insert node into the DOM, choosing from various positioning options.
-               //              Returns the first argument resolved to a DOM node.
-               //
-               //      node: String|DomNode
-               //              id or node reference, or HTML fragment starting with "<" to place relative to refNode
-               //
-               //      refNode: String|DomNode
-               //              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 = byId(refNode);
-               if(typeof node == "string"){ // inline'd type check
-                       node = /^\s*</.test(node) ? d._toDom(node, refNode.ownerDocument) : 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":
-                                       d.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
-       };
-
-       // Box functions will assume this model.
-       // On IE/Opera, BORDER_BOX will be set if the primary document is in quirks mode.
-       // Can be set to change behavior of box setters.
-
-       // can be either:
-       //      "border-box"
-       //      "content-box" (default)
-       dojo.boxModel = "content-box";
-
-       // We punt per-node box mode testing completely.
-       // If anybody cares, we can provide an additional (optional) unit
-       // that overrides existing code to include per-node box sensitivity.
-
-       // Opera documentation claims that Opera 9 uses border-box in BackCompat mode.
-       // but experiments (Opera 9.10.8679 on Windows Vista) indicate that it actually continues to use content-box.
-       // IIRC, earlier versions of Opera did in fact use border-box.
-       // Opera guys, this is really confusing. Opera being broken in quirks mode is not our fault.
-
-               if(d.isIE /*|| dojo.isOpera*/){
-               // client code may have to adjust if compatMode varies across iframes
-               d.boxModel = document.compatMode == "BackCompat" ? "border-box" : "content-box";
-       }
-       
-       // =============================
-       // Style Functions
-       // =============================
-
-       // getComputedStyle drives most of the style code.
-       // Wherever possible, reuse the returned object.
-       //
-       // API functions below that need to access computed styles accept an
-       // optional computedStyle parameter.
-       // If this parameter is omitted, the functions will call getComputedStyle themselves.
-       // This way, calling code can access computedStyle once, and then pass the reference to
-       // multiple API functions.
-
-/*=====
-       dojo.getComputedStyle = function(node){
-               //      summary:
-               //              Returns a "computed style" object.
-               //
-               //      description:
-               //              Gets a "computed style" object which can be used to gather
-               //              information about the current state of the rendered node.
-               //
-               //              Note that this may behave differently on different browsers.
-               //              Values may have different formats and value encodings across
-               //              browsers.
-               //
-               //              Note also that this method is expensive.  Wherever possible,
-               //              reuse the returned object.
-               //
-               //              Use the dojo.style() method for more consistent (pixelized)
-               //              return values.
-               //
-               //      node: DOMNode
-               //              A reference to a DOM node. Does NOT support taking an
-               //              ID string for speed reasons.
-               //      example:
-               //      |       dojo.getComputedStyle(dojo.byId('foo')).borderWidth;
-               //
-               //      example:
-               //      Reusing the returned object, avoiding multiple lookups:
-               //      |       var cs = dojo.getComputedStyle(dojo.byId("someNode"));
-               //      |       var w = cs.width, h = cs.height;
-               return; // CSS2Properties
-       }
-=====*/
-
-       // Although we normally eschew argument validation at this
-       // level, here we test argument 'node' for (duck)type,
-       // by testing nodeType, ecause 'document' is the 'parentNode' of 'body'
-       // it is frequently sent to this function even
-       // though it is not Element.
-       var gcs;
-               if(d.isWebKit){
-                       gcs = function(/*DomNode*/node){
-                       var s;
-                       if(node.nodeType == 1){
-                               var dv = node.ownerDocument.defaultView;
-                               s = dv.getComputedStyle(node, null);
-                               if(!s && node.style){
-                                       node.style.display = "";
-                                       s = dv.getComputedStyle(node, null);
-                               }
-                       }
-                       return s || {};
-               };
-               }else if(d.isIE){
-               gcs = function(node){
-                       // IE (as of 7) doesn't expose Element like sane browsers
-                       return node.nodeType == 1 /* ELEMENT_NODE*/ ? node.currentStyle : {};
-               };
-       }else{
-               gcs = function(node){
-                       return node.nodeType == 1 ?
-                               node.ownerDocument.defaultView.getComputedStyle(node, null) : {};
-               };
-       }
-               dojo.getComputedStyle = gcs;
-
-               if(!d.isIE){
-                       d._toPixelValue = function(element, value){
-                       // style values can be floats, client code may want
-                       // to round for integer pixels.
-                       return parseFloat(value) || 0;
-               };
-               }else{
-               d._toPixelValue = function(element, avalue){
-                       if(!avalue){ return 0; }
-                       // on IE7, medium is usually 4 pixels
-                       if(avalue == "medium"){ return 4; }
-                       // style values can be floats, client code may
-                       // want to round this value for integer pixels.
-                       if(avalue.slice && avalue.slice(-2) == 'px'){ return parseFloat(avalue); }
-                       with(element){
-                               var sLeft = style.left;
-                               var rsLeft = runtimeStyle.left;
-                               runtimeStyle.left = currentStyle.left;
-                               try{
-                                       // 'avalue' may be incompatible with style.left, which can cause IE to throw
-                                       // this has been observed for border widths using "thin", "medium", "thick" constants
-                                       // those particular constants could be trapped by a lookup
-                                       // but perhaps there are more
-                                       style.left = avalue;
-                                       avalue = style.pixelLeft;
-                               }catch(e){
-                                       avalue = 0;
-                               }
-                               style.left = sLeft;
-                               runtimeStyle.left = rsLeft;
-                       }
-                       return avalue;
-               };
-       }
-               var px = d._toPixelValue;
-
-       // FIXME: there opacity quirks on FF that we haven't ported over. Hrm.
-       /*=====
-       dojo._getOpacity = function(node){
-                       //      summary:
-                       //              Returns the current opacity of the passed node as a
-                       //              floating-point value between 0 and 1.
-                       //      node: DomNode
-                       //              a reference to a DOM node. Does NOT support taking an
-                       //              ID string for speed reasons.
-                       //      returns: Number between 0 and 1
-                       return; // Number
-       }
-       =====*/
-
-               var astr = "DXImageTransform.Microsoft.Alpha";
-       var af = function(n, f){
-               try{
-                       return n.filters.item(astr);
-               }catch(e){
-                       return f ? {} : null;
-               }
-       };
-
-               dojo._getOpacity =
-                       d.isIE < 9 ? function(node){
-                       try{
-                               return af(node).Opacity / 100; // Number
-                       }catch(e){
-                               return 1; // Number
-                       }
-               } :
-                       function(node){
-                       return gcs(node).opacity;
-               };
-
-       /*=====
-       dojo._setOpacity = function(node, opacity){
-                       //      summary:
-                       //              set the opacity of the passed node portably. Returns the
-                       //              new opacity of the node.
-                       //      node: DOMNode
-                       //              a reference to a DOM node. Does NOT support taking an
-                       //              ID string for performance reasons.
-                       //      opacity: Number
-                       //              A Number between 0 and 1. 0 specifies transparent.
-                       //      returns: Number between 0 and 1
-                       return; // Number
-       }
-       =====*/
-
-       dojo._setOpacity =
-                               d.isIE < 9 ? function(/*DomNode*/node, /*Number*/opacity){
-                       var ov = opacity * 100, opaque = opacity == 1;
-                       node.style.zoom = opaque ? "" : 1;
-
-                       if(!af(node)){
-                               if(opaque){
-                                       return opacity;
-                               }
-                               node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")";
-                       }else{
-                               af(node, 1).Opacity = ov;
-                       }
-
-                       // on IE7 Alpha(Filter opacity=100) makes text look fuzzy so disable it altogether (bug #2661),
-                       //but still update the opacity value so we can get a correct reading if it is read later.
-                       af(node, 1).Enabled = !opaque;
-
-                       if(node.nodeName.toLowerCase() == "tr"){
-                               d.query("> td", node).forEach(function(i){
-                                       d._setOpacity(i, opacity);
-                               });
-                       }
-                       return opacity;
-               } :
-                               function(node, opacity){
-                       return node.style.opacity = opacity;
-               };
-
-       var _pixelNamesCache = {
-               left: true, top: true
-       };
-       var _pixelRegExp = /margin|padding|width|height|max|min|offset/;  // |border
-       var _toStyleValue = function(node, type, value){
-               type = type.toLowerCase(); // FIXME: should we really be doing string case conversion here? Should we cache it? Need to profile!
-                               if(d.isIE){
-                       if(value == "auto"){
-                               if(type == "height"){ return node.offsetHeight; }
-                               if(type == "width"){ return node.offsetWidth; }
-                       }
-                       if(type == "fontweight"){
-                               switch(value){
-                                       case 700: return "bold";
-                                       case 400:
-                                       default: return "normal";
-                               }
-                       }
-               }
-                               if(!(type in _pixelNamesCache)){
-                       _pixelNamesCache[type] = _pixelRegExp.test(type);
-               }
-               return _pixelNamesCache[type] ? px(node, value) : value;
-       };
-
-       var _floatStyle = d.isIE ? "styleFloat" : "cssFloat",
-               _floatAliases = { "cssFloat": _floatStyle, "styleFloat": _floatStyle, "float": _floatStyle }
-       ;
-
-       // public API
-
-       dojo.style = function(  /*DomNode|String*/ node,
-                                                       /*String?|Object?*/ style,
-                                                       /*String?*/ value){
-               //      summary:
-               //              Accesses styles on a node. If 2 arguments are
-               //              passed, acts as a getter. If 3 arguments are passed, acts
-               //              as a setter.
-               //      description:
-               //              Getting the style value uses the computed style for the node, so the value
-               //              will be a calculated value, not just the immediate node.style value.
-               //              Also when getting values, use specific style names,
-               //              like "borderBottomWidth" instead of "border" since compound values like
-               //              "border" are not necessarily reflected as expected.
-               //              If you want to get node dimensions, use `dojo.marginBox()`,
-               //              `dojo.contentBox()` or `dojo.position()`.
-               //      node:
-               //              id or reference to node to get/set style for
-               //      style:
-               //              the style property to set in DOM-accessor format
-               //              ("borderWidth", not "border-width") or an object with key/value
-               //              pairs suitable for setting each property.
-               //      value:
-               //              If passed, sets value on the node for style, handling
-               //              cross-browser concerns.  When setting a pixel value,
-               //              be sure to include "px" in the value. For instance, top: "200px".
-               //              Otherwise, in some cases, some browsers will not apply the style.
-               //      example:
-               //              Passing only an ID or node returns the computed style object of
-               //              the node:
-               //      |       dojo.style("thinger");
-               //      example:
-               //              Passing a node and a style property returns the current
-               //              normalized, computed value for that property:
-               //      |       dojo.style("thinger", "opacity"); // 1 by default
-               //
-               //      example:
-               //              Passing a node, a style property, and a value changes the
-               //              current display of the node and returns the new computed value
-               //      |       dojo.style("thinger", "opacity", 0.5); // == 0.5
-               //
-               //      example:
-               //              Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
-               //      |       dojo.style("thinger", {
-               //      |               "opacity": 0.5,
-               //      |               "border": "3px solid black",
-               //      |               "height": "300px"
-               //      |       });
-               //
-               //      example:
-               //              When the CSS style property is hyphenated, the JavaScript property is camelCased.
-               //              font-size becomes fontSize, and so on.
-               //      |       dojo.style("thinger",{
-               //      |               fontSize:"14pt",
-               //      |               letterSpacing:"1.2em"
-               //      |       });
-               //
-               //      example:
-               //              dojo.NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
-               //              dojo.style() on every element of the list. See: `dojo.query()` and `dojo.NodeList()`
-               //      |       dojo.query(".someClassName").style("visibility","hidden");
-               //      |       // or
-               //      |       dojo.query("#baz > div").style({
-               //      |               opacity:0.75,
-               //      |               fontSize:"13pt"
-               //      |       });
-
-               var n = byId(node), args = arguments.length, op = (style == "opacity");
-               style = _floatAliases[style] || style;
-               if(args == 3){
-                       return op ? d._setOpacity(n, value) : n.style[style] = value; /*Number*/
-               }
-               if(args == 2 && op){
-                       return d._getOpacity(n);
-               }
-               var s = gcs(n);
-               if(args == 2 && typeof style != "string"){ // inline'd type check
-                       for(var x in style){
-                               d.style(node, x, style[x]);
-                       }
-                       return s;
-               }
-               return (args == 1) ? s : _toStyleValue(n, style, s[style] || n.style[style]); /* CSS2Properties||String||Number */
-       };
-
-       // =============================
-       // Box Functions
-       // =============================
-
-       dojo._getPadExtents = function(/*DomNode*/n, /*Object*/computedStyle){
-               //      summary:
-               //              Returns object with special values specifically useful for node
-               //              fitting.
-               //      description:
-               //              Returns an object with `w`, `h`, `l`, `t` properties:
-               //      |               l/t = left/top padding (respectively)
-               //      |               w = the total of the left and right padding
-               //      |               h = the total of the top and bottom padding
-               //              If 'node' has position, l/t forms the origin for child nodes.
-               //              The w/h are used for calculating boxes.
-               //              Normally application code will not need to invoke this
-               //              directly, and will use the ...box... functions instead.
-               var
-                       s = computedStyle||gcs(n),
-                       l = px(n, s.paddingLeft),
-                       t = px(n, s.paddingTop);
-               return {
-                       l: l,
-                       t: t,
-                       w: l+px(n, s.paddingRight),
-                       h: t+px(n, s.paddingBottom)
-               };
-       };
-
-       dojo._getBorderExtents = function(/*DomNode*/n, /*Object*/computedStyle){
-               //      summary:
-               //              returns an object with properties useful for noting the border
-               //              dimensions.
-               //      description:
-               //              * l/t = the sum of left/top border (respectively)
-               //              * w = the sum of the left and right border
-               //              * h = the sum of the top and bottom border
-               //
-               //              The w/h are used for calculating boxes.
-               //              Normally application code will not need to invoke this
-               //              directly, and will use the ...box... functions instead.
-               var
-                       ne = "none",
-                       s = computedStyle||gcs(n),
-                       bl = (s.borderLeftStyle != ne ? px(n, s.borderLeftWidth) : 0),
-                       bt = (s.borderTopStyle != ne ? px(n, s.borderTopWidth) : 0);
-               return {
-                       l: bl,
-                       t: bt,
-                       w: bl + (s.borderRightStyle!=ne ? px(n, s.borderRightWidth) : 0),
-                       h: bt + (s.borderBottomStyle!=ne ? px(n, s.borderBottomWidth) : 0)
-               };
-       };
-
-       dojo._getPadBorderExtents = function(/*DomNode*/n, /*Object*/computedStyle){
-               //      summary:
-               //              Returns object with properties useful for box fitting with
-               //              regards to padding.
-               // description:
-               //              * l/t = the sum of left/top padding and left/top border (respectively)
-               //              * w = the sum of the left and right padding and border
-               //              * h = the sum of the top and bottom padding and border
-               //
-               //              The w/h are used for calculating boxes.
-               //              Normally application code will not need to invoke this
-               //              directly, and will use the ...box... functions instead.
-               var
-                       s = computedStyle||gcs(n),
-                       p = d._getPadExtents(n, s),
-                       b = d._getBorderExtents(n, s);
-               return {
-                       l: p.l + b.l,
-                       t: p.t + b.t,
-                       w: p.w + b.w,
-                       h: p.h + b.h
-               };
-       };
-
-       dojo._getMarginExtents = function(n, computedStyle){
-               //      summary:
-               //              returns object with properties useful for box fitting with
-               //              regards to box margins (i.e., the outer-box).
-               //
-               //              * l/t = marginLeft, marginTop, respectively
-               //              * w = total width, margin inclusive
-               //              * h = total height, margin inclusive
-               //
-               //              The w/h are used for calculating boxes.
-               //              Normally application code will not need to invoke this
-               //              directly, and will use the ...box... functions instead.
-               var
-                       s = computedStyle||gcs(n),
-                       l = px(n, s.marginLeft),
-                       t = px(n, s.marginTop),
-                       r = px(n, s.marginRight),
-                       b = px(n, s.marginBottom);
-               if(d.isWebKit && (s.position != "absolute")){
-                       // FIXME: Safari's version of the computed right margin
-                       // is the space between our right edge and the right edge
-                       // of our offsetParent.
-                       // What we are looking for is the actual margin value as
-                       // determined by CSS.
-                       // Hack solution is to assume left/right margins are the same.
-                       r = l;
-               }
-               return {
-                       l: l,
-                       t: t,
-                       w: l+r,
-                       h: t+b
-               };
-       };
-
-       // Box getters work in any box context because offsetWidth/clientWidth
-       // are invariant wrt box context
-       //
-       // They do *not* work for display: inline objects that have padding styles
-       // because the user agent ignores padding (it's bogus styling in any case)
-       //
-       // Be careful with IMGs because they are inline or block depending on
-       // browser and browser mode.
-
-       // Although it would be easier to read, there are not separate versions of
-       // _getMarginBox for each browser because:
-       // 1. the branching is not expensive
-       // 2. factoring the shared code wastes cycles (function call overhead)
-       // 3. duplicating the shared code wastes bytes
-
-       dojo._getMarginBox = function(/*DomNode*/node, /*Object*/computedStyle){
-               // summary:
-               //              returns an object that encodes the width, height, left and top
-               //              positions of the node's margin box.
-               var s = computedStyle || gcs(node), me = d._getMarginExtents(node, s);
-               var l = node.offsetLeft - me.l, t = node.offsetTop - me.t, p = node.parentNode;
-                               if(d.isMoz){
-                       // Mozilla:
-                       // If offsetParent has a computed overflow != visible, the offsetLeft is decreased
-                       // by the parent's border.
-                       // We don't want to compute the parent's style, so instead we examine node's
-                       // computed left/top which is more stable.
-                       var sl = parseFloat(s.left), st = parseFloat(s.top);
-                       if(!isNaN(sl) && !isNaN(st)){
-                               l = sl, t = st;
-                       }else{
-                               // If child's computed left/top are not parseable as a number (e.g. "auto"), we
-                               // have no choice but to examine the parent's computed style.
-                               if(p && p.style){
-                                       var pcs = gcs(p);
-                                       if(pcs.overflow != "visible"){
-                                               var be = d._getBorderExtents(p, pcs);
-                                               l += be.l, t += be.t;
-                                       }
-                               }
-                       }
-               }else if(d.isOpera || (d.isIE > 7 && !d.isQuirks)){
-                       // On Opera and IE 8, offsetLeft/Top includes the parent's border
-                       if(p){
-                               be = d._getBorderExtents(p);
-                               l -= be.l;
-                               t -= be.t;
-                       }
-               }
-                               return {
-                       l: l,
-                       t: t,
-                       w: node.offsetWidth + me.w,
-                       h: node.offsetHeight + me.h
-               };
-       }
-       
-       dojo._getMarginSize = function(/*DomNode*/node, /*Object*/computedStyle){
-               // summary:
-               //      returns an object that encodes the width and height of
-               //      the node's margin box
-               node = byId(node);
-               var me = d._getMarginExtents(node, computedStyle || gcs(node));
-
-               var size = node.getBoundingClientRect();
-               return {
-                       w: (size.right - size.left) + me.w,
-                       h: (size.bottom - size.top) + me.h
-               }
-       }
-
-       dojo._getContentBox = function(node, computedStyle){
-               // summary:
-               //              Returns an object that encodes the width, height, left and top
-               //              positions of the node's content box, irrespective of the
-               //              current box model.
-
-               // clientWidth/Height are important since the automatically account for scrollbars
-               // fallback to offsetWidth/Height for special cases (see #3378)
-               var s = computedStyle || gcs(node),
-                       pe = d._getPadExtents(node, s),
-                       be = d._getBorderExtents(node, s),
-                       w = node.clientWidth,
-                       h
-               ;
-               if(!w){
-                       w = node.offsetWidth, h = node.offsetHeight;
-               }else{
-                       h = node.clientHeight, be.w = be.h = 0;
-               }
-               // On Opera, offsetLeft includes the parent's border
-                               if(d.isOpera){ pe.l += be.l; pe.t += be.t; };
-                               return {
-                       l: pe.l,
-                       t: pe.t,
-                       w: w - pe.w - be.w,
-                       h: h - pe.h - be.h
-               };
-       };
-
-       dojo._getBorderBox = function(node, computedStyle){
-               var s = computedStyle || gcs(node),
-                       pe = d._getPadExtents(node, s),
-                       cb = d._getContentBox(node, s)
-               ;
-               return {
-                       l: cb.l - pe.l,
-                       t: cb.t - pe.t,
-                       w: cb.w + pe.w,
-                       h: cb.h + pe.h
-               };
-       };
-
-       // Box setters depend on box context because interpretation of width/height styles
-       // vary wrt box context.
-       //
-       // The value of dojo.boxModel is used to determine box context.
-       // dojo.boxModel can be set directly to change behavior.
-       //
-       // Beware of display: inline objects that have padding styles
-       // because the user agent ignores padding (it's a bogus setup anyway)
-       //
-       // Be careful with IMGs because they are inline or block depending on
-       // browser and browser mode.
-       //
-       // Elements other than DIV may have special quirks, like built-in
-       // margins or padding, or values not detectable via computedStyle.
-       // In particular, margins on TABLE do not seems to appear
-       // at all in computedStyle on Mozilla.
-
-       dojo._setBox = function(/*DomNode*/node, /*Number?*/l, /*Number?*/t, /*Number?*/w, /*Number?*/h, /*String?*/u){
-               //      summary:
-               //              sets width/height/left/top in the current (native) box-model
-               //              dimentions. Uses the unit passed in u.
-               //      node:
-               //              DOM Node reference. Id string not supported for performance
-               //              reasons.
-               //      l:
-               //              left offset from parent.
-               //      t:
-               //              top offset from parent.
-               //      w:
-               //              width in current box model.
-               //      h:
-               //              width in current box model.
-               //      u:
-               //              unit measure to use for other measures. Defaults to "px".
-               u = u || "px";
-               var s = node.style;
-               if(!isNaN(l)){ s.left = l + u; }
-               if(!isNaN(t)){ s.top = t + u; }
-               if(w >= 0){ s.width = w + u; }
-               if(h >= 0){ s.height = h + u; }
-       };
-
-       dojo._isButtonTag = function(/*DomNode*/node) {
-               // summary:
-               //              True if the node is BUTTON or INPUT.type="button".
-               return node.tagName == "BUTTON"
-                       || node.tagName=="INPUT" && (node.getAttribute("type")||'').toUpperCase() == "BUTTON"; // boolean
-       };
-
-       dojo._usesBorderBox = function(/*DomNode*/node){
-               //      summary:
-               //              True if the node uses border-box layout.
-
-               // We could test the computed style of node to see if a particular box
-               // has been specified, but there are details and we choose not to bother.
-
-               // TABLE and BUTTON (and INPUT type=button) are always border-box by default.
-               // If you have assigned a different box to either one via CSS then
-               // box functions will break.
-
-               var n = node.tagName;
-               return d.boxModel=="border-box" || n=="TABLE" || d._isButtonTag(node); // boolean
-       };
-
-       dojo._setContentSize = function(/*DomNode*/node, /*Number*/widthPx, /*Number*/heightPx, /*Object*/computedStyle){
-               //      summary:
-               //              Sets the size of the node's contents, irrespective of margins,
-               //              padding, or borders.
-               if(d._usesBorderBox(node)){
-                       var pb = d._getPadBorderExtents(node, computedStyle);
-                       if(widthPx >= 0){ widthPx += pb.w; }
-                       if(heightPx >= 0){ heightPx += pb.h; }
-               }
-               d._setBox(node, NaN, NaN, widthPx, heightPx);
-       };
-
-       dojo._setMarginBox = function(/*DomNode*/node,  /*Number?*/leftPx, /*Number?*/topPx,
-                                                                                                       /*Number?*/widthPx, /*Number?*/heightPx,
-                                                                                                       /*Object*/computedStyle){
-               //      summary:
-               //              sets the size of the node's margin box and placement
-               //              (left/top), irrespective of box model. Think of it as a
-               //              passthrough to dojo._setBox that handles box-model vagaries for
-               //              you.
-
-               var s = computedStyle || gcs(node),
-               // Some elements have special padding, margin, and box-model settings.
-               // To use box functions you may need to set padding, margin explicitly.
-               // Controlling box-model is harder, in a pinch you might set dojo.boxModel.
-                       bb = d._usesBorderBox(node),
-                       pb = bb ? _nilExtents : d._getPadBorderExtents(node, s)
-               ;
-               if(d.isWebKit){
-                       // on Safari (3.1.2), button nodes with no explicit size have a default margin
-                       // setting an explicit size eliminates the margin.
-                       // We have to swizzle the width to get correct margin reading.
-                       if(d._isButtonTag(node)){
-                               var ns = node.style;
-                               if(widthPx >= 0 && !ns.width) { ns.width = "4px"; }
-                               if(heightPx >= 0 && !ns.height) { ns.height = "4px"; }
-                       }
-               }
-               var mb = d._getMarginExtents(node, s);
-               if(widthPx >= 0){ widthPx = Math.max(widthPx - pb.w - mb.w, 0); }
-               if(heightPx >= 0){ heightPx = Math.max(heightPx - pb.h - mb.h, 0); }
-               d._setBox(node, leftPx, topPx, widthPx, heightPx);
-       };
-
-       var _nilExtents = { l:0, t:0, w:0, h:0 };
-
-       // public API
-
-       dojo.marginBox = function(/*DomNode|String*/node, /*Object?*/box){
-               //      summary:
-               //              Getter/setter for the margin-box of node.
-               //      description:
-               //              Getter/setter for the margin-box of node.
-               //              Returns an object in the expected format of box (regardless
-               //              if box is passed). The object might look like:
-               //                      `{ l: 50, t: 200, w: 300: h: 150 }`
-               //              for a node offset from its parent 50px to the left, 200px from
-               //              the top with a margin width of 300px and a margin-height of
-               //              150px.
-               //      node:
-               //              id or reference to DOM Node to get/set box for
-               //      box:
-               //              If passed, denotes that dojo.marginBox() should
-               //              update/set the margin box for node. Box is an object in the
-               //              above format. All properties are optional if passed.
-               //      example:
-               //      Retrieve the marginbox of a passed node
-               //      |       var box = dojo.marginBox("someNodeId");
-               //      |       console.dir(box);
-               //
-               //      example:
-               //      Set a node's marginbox to the size of another node
-               //      |       var box = dojo.marginBox("someNodeId");
-               //      |       dojo.marginBox("someOtherNode", box);
-               
-               var n = byId(node), s = gcs(n), b = box;
-               return !b ? d._getMarginBox(n, s) : d._setMarginBox(n, b.l, b.t, b.w, b.h, s); // Object
-       };
-
-       dojo.contentBox = function(/*DomNode|String*/node, /*Object?*/box){
-               //      summary:
-               //              Getter/setter for the content-box of node.
-               //      description:
-               //              Returns an object in the expected format of box (regardless if box is passed).
-               //              The object might look like:
-               //                      `{ l: 50, t: 200, w: 300: h: 150 }`
-               //              for a node offset from its parent 50px to the left, 200px from
-               //              the top with a content width of 300px and a content-height of
-               //              150px. Note that the content box may have a much larger border
-               //              or margin box, depending on the box model currently in use and
-               //              CSS values set/inherited for node.
-               //              While the getter will return top and left values, the
-               //              setter only accepts setting the width and height.
-               //      node:
-               //              id or reference to DOM Node to get/set box for
-               //      box:
-               //              If passed, denotes that dojo.contentBox() should
-               //              update/set the content box for node. Box is an object in the
-               //              above format, but only w (width) and h (height) are supported.
-               //              All properties are optional if passed.
-               var n = byId(node), s = gcs(n), b = box;
-               return !b ? d._getContentBox(n, s) : d._setContentSize(n, b.w, b.h, s); // Object
-       };
-
-       // =============================
-       // Positioning
-       // =============================
-
-       var _sumAncestorProperties = function(node, prop){
-               if(!(node = (node||0).parentNode)){return 0;}
-               var val, retVal = 0, _b = d.body();
-               while(node && node.style){
-                       if(gcs(node).position == "fixed"){
-                               return 0;
-                       }
-                       val = node[prop];
-                       if(val){
-                               retVal += val - 0;
-                               // opera and khtml #body & #html has the same values, we only
-                               // need one value
-                               if(node == _b){ break; }
-                       }
-                       node = node.parentNode;
-               }
-               return retVal;  //      integer
-       };
-
-       dojo._docScroll = function(){
-               var n = d.global;
-               return "pageXOffset" in n
-                       ? { x:n.pageXOffset, y:n.pageYOffset }
-                       : (n = d.isQuirks? d.doc.body : d.doc.documentElement, { x:d._fixIeBiDiScrollLeft(n.scrollLeft || 0), y:n.scrollTop || 0 });
-       };
-
-       dojo._isBodyLtr = function(){
-               return "_bodyLtr" in d? d._bodyLtr :
-                       d._bodyLtr = (d.body().dir || d.doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean
-       };
-
-               dojo._getIeDocumentElementOffset = function(){
-               //      summary:
-               //              returns the offset in x and y from the document body to the
-               //              visual edge of the page
-               //      description:
-               // The following values in IE contain an offset:
-               //      |               event.clientX
-               //      |               event.clientY
-               //      |               node.getBoundingClientRect().left
-               //      |               node.getBoundingClientRect().top
-               //              But other position related values do not contain this offset,
-               //              such as node.offsetLeft, node.offsetTop, node.style.left and
-               //              node.style.top. The offset is always (2, 2) in LTR direction.
-               //              When the body is in RTL direction, the offset counts the width
-               //              of left scroll bar's width.  This function computes the actual
-               //              offset.
-
-               //NOTE: assumes we're being called in an IE browser
-
-               var de = d.doc.documentElement; // only deal with HTML element here, _abs handles body/quirks
-
-               if(d.isIE < 8){
-                       var r = de.getBoundingClientRect(); // works well for IE6+
-                       //console.debug('rect left,top = ' + r.left+','+r.top + ', html client left/top = ' + de.clientLeft+','+de.clientTop + ', rtl = ' + (!d._isBodyLtr()) + ', quirks = ' + d.isQuirks);
-                       var l = r.left,
-                           t = r.top;
-                       if(d.isIE < 7){
-                               l += de.clientLeft;     // scrollbar size in strict/RTL, or,
-                               t += de.clientTop;      // HTML border size in strict
-                       }
-                       return {
-                               x: l < 0? 0 : l, // FRAME element border size can lead to inaccurate negative values
-                               y: t < 0? 0 : t
-                       };
-               }else{
-                       return {
-                               x: 0,
-                               y: 0
-                       };
-               }
-
-       };
-       
-       dojo._fixIeBiDiScrollLeft = function(/*Integer*/ scrollLeft){
-               // In RTL direction, scrollLeft should be a negative value, but IE
-               // returns a positive one. All codes using documentElement.scrollLeft
-               // must call this function to fix this error, otherwise the position
-               // will offset to right when there is a horizontal scrollbar.
-
-                               var ie = d.isIE;
-               if(ie && !d._isBodyLtr()){
-                       var qk = d.isQuirks,
-                               de = qk ? d.doc.body : d.doc.documentElement;
-                       if(ie == 6 && !qk && d.global.frameElement && de.scrollHeight > de.clientHeight){
-                               scrollLeft += de.clientLeft; // workaround ie6+strict+rtl+iframe+vertical-scrollbar bug where clientWidth is too small by clientLeft pixels
-                       }
-                       return (ie < 8 || qk) ? (scrollLeft + de.clientWidth - de.scrollWidth) : -scrollLeft; // Integer
-               }
-                               return scrollLeft; // Integer
-       };
-
-       // FIXME: need a setter for coords or a moveTo!!
-       dojo._abs = dojo.position = function(/*DomNode*/node, /*Boolean?*/includeScroll){
-               //      summary:
-               //              Gets the position and size of the passed element relative to
-               //              the viewport (if includeScroll==false), or relative to the
-               //              document root (if includeScroll==true).
-               //
-               //      description:
-               //              Returns an object of the form:
-               //                      { x: 100, y: 300, w: 20, h: 15 }
-               //              If includeScroll==true, the x and y values will include any
-               //              document offsets that may affect the position relative to the
-               //              viewport.
-               //              Uses the border-box model (inclusive of border and padding but
-               //              not margin).  Does not act as a setter.
-
-               node = byId(node);
-               var     db = d.body(),
-                       dh = db.parentNode,
-                       ret = node.getBoundingClientRect();
-                       ret = { x: ret.left, y: ret.top, w: ret.right - ret.left, h: ret.bottom - ret.top };
-                                       if(d.isIE){
-                               // On IE there's a 2px offset that we need to adjust for, see _getIeDocumentElementOffset()
-                               var offset = d._getIeDocumentElementOffset();
-
-                               // fixes the position in IE, quirks mode
-                               ret.x -= offset.x + (d.isQuirks ? db.clientLeft+db.offsetLeft : 0);
-                               ret.y -= offset.y + (d.isQuirks ? db.clientTop+db.offsetTop : 0);
-                       }else if(d.isFF == 3){
-                               // In FF3 you have to subtract the document element margins.
-                               // Fixed in FF3.5 though.
-                               var cs = gcs(dh);
-                               ret.x -= px(dh, cs.marginLeft) + px(dh, cs.borderLeftWidth);
-                               ret.y -= px(dh, cs.marginTop) + px(dh, cs.borderTopWidth);
-                       }
-                               // account for document scrolling
-               if(includeScroll){
-                       var scroll = d._docScroll();
-                       ret.x += scroll.x;
-                       ret.y += scroll.y;
-               }
-
-               return ret; // Object
-       };
-
-       dojo.coords = function(/*DomNode|String*/node, /*Boolean?*/includeScroll){
-               //      summary:
-               //              Deprecated: Use position() for border-box x/y/w/h
-               //              or marginBox() for margin-box w/h/l/t.
-               //              Returns an object representing a node's size and position.
-               //
-               //      description:
-               //              Returns an object that measures margin-box (w)idth/(h)eight
-               //              and absolute position x/y of the border-box. Also returned
-               //              is computed (l)eft and (t)op values in pixels from the
-               //              node's offsetParent as returned from marginBox().
-               //              Return value will be in the form:
-               //|                     { l: 50, t: 200, w: 300: h: 150, x: 100, y: 300 }
-               //              Does not act as a setter. If includeScroll is passed, the x and
-               //              y params are affected as one would expect in dojo.position().
-               var n = byId(node), s = gcs(n), mb = d._getMarginBox(n, s);
-               var abs = d.position(n, includeScroll);
-               mb.x = abs.x;
-               mb.y = abs.y;
-               return mb;
-       };
-
-       // =============================
-       // Element attribute Functions
-       // =============================
-
-       // dojo.attr() should conform to http://www.w3.org/TR/DOM-Level-2-Core/
-
-       var _propNames = {
-                       // 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",
-                       valuetype: "valueType"
-               },
-               _attrNames = {
-                       // original attribute names
-                       classname: "class",
-                       htmlfor:   "for",
-                       // for IE
-                       tabindex:  "tabIndex",
-                       readonly:  "readOnly"
-               },
-               _forcePropNames = {
-                       innerHTML: 1,
-                       className: 1,
-                       htmlFor:   d.isIE,
-                       value:     1
-               };
-
-       var _fixAttrName = function(/*String*/ name){
-               return _attrNames[name.toLowerCase()] || name;
-       };
-
-       var _hasAttr = function(node, name){
-               var attr = node.getAttributeNode && node.getAttributeNode(name);
-               return attr && attr.specified; // Boolean
-       };
-
-       // There is a difference in the presence of certain properties and their default values
-       // between browsers. For example, on IE "disabled" is present on all elements,
-       // but it is value is "false"; "tabIndex" of <div> returns 0 by default on IE, yet other browsers
-       // can return -1.
-
-       dojo.hasAttr = function(/*DomNode|String*/node, /*String*/name){
-               //      summary:
-               //              Returns true if the requested attribute is specified on the
-               //              given element, and false otherwise.
-               //      node:
-               //              id or reference to the element to check
-               //      name:
-               //              the name of the attribute
-               //      returns:
-               //              true if the requested attribute is specified on the
-               //              given element, and false otherwise
-               var lc = name.toLowerCase();
-               return _forcePropNames[_propNames[lc] || name] || _hasAttr(byId(node), _attrNames[lc] || name); // Boolean
-       };
-
-       var _evtHdlrMap = {}, _ctr = 0,
-               _attrId = dojo._scopeName + "attrid",
-               // the next dictionary lists elements with read-only innerHTML on IE
-               _roInnerHtml = {col: 1, colgroup: 1,
-                       // frameset: 1, head: 1, html: 1, style: 1,
-                       table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1};
-
-       dojo.attr = function(/*DomNode|String*/node, /*String|Object*/name, /*String?*/value){
-               //      summary:
-               //              Gets or sets an attribute on an HTML element.
-               //      description:
-               //              Handles normalized getting and setting of attributes on DOM
-               //              Nodes. If 2 arguments are passed, and a the second argumnt is a
-               //              string, acts as a getter.
-               //
-               //              If a third argument is passed, or if the second argument is a
-               //              map of attributes, acts as a setter.
-               //
-               //              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:
-               //              id or reference to the element to get or set the attribute on
-               //      name:
-               //              the name of the attribute to get or set.
-               //      value:
-               //              The value to set for the attribute
-               //      returns:
-               //              when used as a getter, the value of the requested attribute
-               //              or null if that attribute does not have a specified or
-               //              default value;
-               //
-               //              when used as a setter, the DOM node
-               //
-               //      example:
-               //      |       // get the current value of the "foo" attribute on a node
-               //      |       dojo.attr(dojo.byId("nodeId"), "foo");
-               //      |       // or we can just pass the id:
-               //      |       dojo.attr("nodeId", "foo");
-               //
-               //      example:
-               //      |       // use attr() to set the tab index
-               //      |       dojo.attr("nodeId", "tabIndex", 3);
-               //      |
-               //
-               //      example:
-               //      Set multiple values at once, including event handlers:
-               //      |       dojo.attr("formId", {
-               //      |               "foo": "bar",
-               //      |               "tabIndex": -1,
-               //      |               "method": "POST",
-               //      |               "onsubmit": function(e){
-               //      |                       // stop submitting the form. Note that the IE behavior
-               //      |                       // of returning true or false will have no effect here
-               //      |                       // since our handler is connect()ed to the built-in
-               //      |                       // onsubmit behavior and so we need to use
-               //      |                       // dojo.stopEvent() to ensure that the submission
-               //      |                       // doesn't proceed.
-               //      |                       dojo.stopEvent(e);
-               //      |
-               //      |                       // submit the form with Ajax
-               //      |                       dojo.xhrPost({ form: "formId" });
-               //      |               }
-               //      |       });
-               //
-               //      example:
-               //      Style is s special case: Only set with an object hash of styles
-               //      |       dojo.attr("someNode",{
-               //      |               id:"bar",
-               //      |               style:{
-               //      |                       width:"200px", height:"100px", color:"#000"
-               //      |               }
-               //      |       });
-               //
-               //      example:
-               //      Again, only set style as an object hash of styles:
-               //      |       var obj = { color:"#fff", backgroundColor:"#000" };
-               //      |       dojo.attr("someNode", "style", obj);
-               //      |
-               //      |       // though shorter to use `dojo.style()` in this case:
-               //      |       dojo.style("someNode", obj);
-
-               node = byId(node);
-               var args = arguments.length, prop;
-               if(args == 2 && typeof name != "string"){ // inline'd type check
-                       // the object form of setter: the 2nd argument is a dictionary
-                       for(var x in name){
-                               d.attr(node, x, name[x]);
-                       }
-                       return node; // DomNode
-               }
-               var lc = name.toLowerCase(),
-                       propName = _propNames[lc] || name,
-                       forceProp = _forcePropNames[propName],
-                       attrName = _attrNames[lc] || name;
-               if(args == 3){
-                       // setter
-                       do{
-                               if(propName == "style" && typeof value != "string"){ // inline'd type check
-                                       // special case: setting a style
-                                       d.style(node, value);
-                                       break;
-                               }
-                               if(propName == "innerHTML"){
-                                       // special case: assigning HTML
-                                                                               if(d.isIE && node.tagName.toLowerCase() in _roInnerHtml){
-                                               d.empty(node);
-                                               node.appendChild(d._toDom(value, node.ownerDocument));
-                                       }else{
-                                                                                       node[propName] = value;
-                                                                               }
-                                                                               break;
-                               }
-                               if(d.isFunction(value)){
-                                       // special case: assigning an event handler
-                                       // clobber if we can
-                                       var attrId = d.attr(node, _attrId);
-                                       if(!attrId){
-                                               attrId = _ctr++;
-                                               d.attr(node, _attrId, attrId);
-                                       }
-                                       if(!_evtHdlrMap[attrId]){
-                                               _evtHdlrMap[attrId] = {};
-                                       }
-                                       var h = _evtHdlrMap[attrId][propName];
-                                       if(h){
-                                               d.disconnect(h);
-                                       }else{
-                                               try{
-                                                       delete node[propName];
-                                               }catch(e){}
-                                       }
-                                       // ensure that event objects are normalized, etc.
-                                       _evtHdlrMap[attrId][propName] = d.connect(node, propName, value);
-                                       break;
-                               }
-                               if(forceProp || typeof value == "boolean"){
-                                       // special case: forcing assignment to the property
-                                       // special case: setting boolean to a property instead of attribute
-                                       node[propName] = value;
-                                       break;
-                               }
-                               // node's attribute
-                               node.setAttribute(attrName, value);
-                       }while(false);
-                       return node; // DomNode
-               }
-               // getter
-               // should we access this attribute via a property or
-               // via getAttribute()?
-               value = node[propName];
-               if(forceProp && typeof value != "undefined"){
-                       // node's property
-                       return value;   // Anything
-               }
-               if(propName != "href" && (typeof value == "boolean" || d.isFunction(value))){
-                       // node's property
-                       return value;   // Anything
-               }
-               // node's attribute
-               // we need _hasAttr() here to guard against IE returning a default value
-               return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
-       };
-
-       dojo.removeAttr = function(/*DomNode|String*/ node, /*String*/ name){
-               //      summary:
-               //              Removes an attribute from an HTML element.
-               //      node:
-               //              id or reference to the element to remove the attribute from
-               //      name:
-               //              the name of the attribute to remove
-               byId(node).removeAttribute(_fixAttrName(name));
-       };
-
-       dojo.getNodeProp = function(/*DomNode|String*/ node, /*String*/ name){
-               //      summary:
-               //              Returns an effective value of a property or an attribute.
-               //      node:
-               //              id or reference to the element to remove the attribute from
-               //      name:
-               //              the name of the attribute
-               node = byId(node);
-               var lc = name.toLowerCase(),
-                       propName = _propNames[lc] || name;
-               if((propName in node) && propName != "href"){
-                       // node's property
-                       return node[propName];  // Anything
-               }
-               // node's attribute
-               var attrName = _attrNames[lc] || name;
-               return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
-       };
-
-       dojo.create = function(tag, attrs, refNode, 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.attr`.
-               //              See `dojo.attr` 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: String|DomNode
-               //              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.attr` for a description of available attributes.
-               //
-               // refNode: String?|DomNode?
-               //              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.
-               //
-               // returns: DomNode
-               //
-               // 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 syntatic sugar):
-               //      |       dojo.query(dojo.create('div'))
-               //      |               .addClass("newDiv")
-               //      |               .onclick(function(e){ console.log('clicked', e.target) })
-               //      |               .place("#someNode"); // redundant, but cleaner.
-
-               var doc = d.doc;
-               if(refNode){
-                       refNode = byId(refNode);
-                       doc = refNode.ownerDocument;
-               }
-               if(typeof tag == "string"){ // inline'd type check
-                       tag = doc.createElement(tag);
-               }
-               if(attrs){ d.attr(tag, attrs); }
-               if(refNode){ d.place(tag, refNode, pos); }
-               return tag; // DomNode
-       };
-
-       /*=====
-       dojo.empty = function(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);
-       }
-       =====*/
-
-       d.empty =
-                               d.isIE ?  function(node){
-                       node = byId(node);
-                       for(var c; c = node.lastChild;){ // intentional assignment
-                               d.destroy(c);
-                       }
-               } :
-                               function(node){
-                       byId(node).innerHTML = "";
-               };
-
-       /*=====
-       dojo._toDom = function(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: DocumentFragment
-                       //
-                       //      example:
-                       //      Create a table row:
-                       //      |       var tr = dojo._toDom("<tr><td>First!</td></tr>");
-       }
-       =====*/
-
-       // support stuff for dojo._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 = "__" + d._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
-               }
-       }
-
-       d._toDom = function(frag, doc){
-               //      summary:
-               //              converts HTML string into DOM nodes.
-
-               doc = doc || d.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; // DOMNode
-       };
-
-       // =============================
-       // (CSS) Class Functions
-       // =============================
-       var _className = "className";
-
-       dojo.hasClass = function(/*DomNode|String*/node, /*String*/classStr){
-               //      summary:
-               //              Returns whether or not the specified classes are a portion of the
-               //              class list currently applied to the node.
-               //
-               //      node:
-               //              String ID or DomNode reference to check the class for.
-               //
-               //      classStr:
-               //              A string class name to look for.
-               //
-               //      example:
-               //      Do something if a node with id="someNode" has class="aSillyClassName" present
-               //      |       if(dojo.hasClass("someNode","aSillyClassName")){ ... }
-
-               return ((" "+ byId(node)[_className] +" ").indexOf(" " + classStr + " ") >= 0);  // Boolean
-       };
-
-       var spaces = /\s+/, a1 = [""],
-               fakeNode = {},
-               str2array = function(s){
-                       if(typeof s == "string" || s instanceof String){
-                               if(s.indexOf(" ") < 0){
-                                       a1[0] = s;
-                                       return a1;
-                               }else{
-                                       return s.split(spaces);
-                               }
-                       }
-                       // assumed to be an array
-                       return s || "";
-               };
-
-       dojo.addClass = function(/*DomNode|String*/node, /*String|Array*/classStr){
-               //      summary:
-               //              Adds the specified classes to the end of the class list on the
-               //              passed node. Will not re-apply duplicate classes.
-               //
-               //      node:
-               //              String ID or DomNode reference to add a class string too
-               //
-               //      classStr:
-               //              A String class name to add, or several space-separated class names,
-               //              or an array of class names.
-               //
-               // example:
-               //      Add a class to some node:
-               //      |       dojo.addClass("someNode", "anewClass");
-               //
-               // example:
-               //      Add two classes at once:
-               //      |       dojo.addClass("someNode", "firstClass secondClass");
-               //
-               // example:
-               //      Add two classes at once (using array):
-               //      |       dojo.addClass("someNode", ["firstClass", "secondClass"]);
-               //
-               // example:
-               //      Available in `dojo.NodeList` for multiple additions
-               //      |       dojo.query("ul > li").addClass("firstLevel");
-
-               node = byId(node);
-               classStr = str2array(classStr);
-               var cls = node[_className], oldLen;
-               cls = cls ? " " + cls + " " : " ";
-               oldLen = cls.length;
-               for(var i = 0, len = classStr.length, c; i < len; ++i){
-                       c = classStr[i];
-                       if(c && cls.indexOf(" " + c + " ") < 0){
-                               cls += c + " ";
-                       }
-               }
-               if(oldLen < cls.length){
-                       node[_className] = cls.substr(1, cls.length - 2);
-               }
-       };
-
-       dojo.removeClass = function(/*DomNode|String*/node, /*String|Array?*/classStr){
-               // summary:
-               //              Removes the specified classes from node. No `dojo.hasClass`
-               //              check is required.
-               //
-               // node:
-               //              String ID or DomNode reference to remove the class from.
-               //
-               // classStr:
-               //              An optional String class name to remove, or several space-separated
-               //              class names, or an array of class names. If omitted, all class names
-               //              will be deleted.
-               //
-               // example:
-               //      Remove a class from some node:
-               //      |       dojo.removeClass("someNode", "firstClass");
-               //
-               // example:
-               //      Remove two classes from some node:
-               //      |       dojo.removeClass("someNode", "firstClass secondClass");
-               //
-               // example:
-               //      Remove two classes from some node (using array):
-               //      |       dojo.removeClass("someNode", ["firstClass", "secondClass"]);
-               //
-               // example:
-               //      Remove all classes from some node:
-               //      |       dojo.removeClass("someNode");
-               //
-               // example:
-               //      Available in `dojo.NodeList()` for multiple removal
-               //      |       dojo.query(".foo").removeClass("foo");
-
-               node = byId(node);
-               var cls;
-               if(classStr !== undefined){
-                       classStr = str2array(classStr);
-                       cls = " " + node[_className] + " ";
-                       for(var i = 0, len = classStr.length; i < len; ++i){
-                               cls = cls.replace(" " + classStr[i] + " ", " ");
-                       }
-                       cls = d.trim(cls);
-               }else{
-                       cls = "";
-               }
-               if(node[_className] != cls){ node[_className] = cls; }
-       };
-
-       dojo.replaceClass = function(/*DomNode|String*/node, /*String|Array*/addClassStr, /*String|Array?*/removeClassStr){
-               // summary:
-               //              Replaces one or more classes on a node if not present.
-               //              Operates more quickly than calling dojo.removeClass and dojo.addClass
-               // node:
-               //              String ID or DomNode reference to remove the class from.
-               // addClassStr:
-               //              A String class name to add, or several space-separated class names,
-               //              or an array of class names.
-               // removeClassStr:
-               //              A String class name to remove, or several space-separated class names,
-               //              or an array of class names.
-               //
-               // example:
-               //      |       dojo.replaceClass("someNode", "add1 add2", "remove1 remove2");
-               //
-               // example:
-               //      Replace all classes with addMe
-               //      |       dojo.replaceClass("someNode", "addMe");
-               //
-               // example:
-               //      Available in `dojo.NodeList()` for multiple toggles
-               //      |       dojo.query(".findMe").replaceClass("addMe", "removeMe");
-
-        node = byId(node);
-               fakeNode.className = node.className;
-               dojo.removeClass(fakeNode, removeClassStr);
-               dojo.addClass(fakeNode, addClassStr);
-               if(node.className !== fakeNode.className){
-                       node.className = fakeNode.className;
-               }
-       };
-
-       dojo.toggleClass = function(/*DomNode|String*/node, /*String|Array*/classStr, /*Boolean?*/condition){
-               //      summary:
-               //              Adds a class to node if not present, or removes if present.
-               //              Pass a boolean condition if you want to explicitly add or remove.
-               //      condition:
-               //              If passed, true means to add the class, false means to remove.
-               //
-               // example:
-               //      |       dojo.toggleClass("someNode", "hovered");
-               //
-               // example:
-               //      Forcefully add a class
-               //      |       dojo.toggleClass("someNode", "hovered", true);
-               //
-               // example:
-               //      Available in `dojo.NodeList()` for multiple toggles
-               //      |       dojo.query(".toggleMe").toggleClass("toggleMe");
-
-               if(condition === undefined){
-                       condition = !d.hasClass(node, classStr);
-               }
-               d[condition ? "addClass" : "removeClass"](node, classStr);
-       };
-
-})();
-
-}
+//>>built
+define("dojo/_base/html",["./kernel","../dom","../dom-style","../dom-attr","../dom-prop","../dom-class","../dom-construct","../dom-geometry"],function(_1,_2,_3,_4,_5,_6,_7,_8){_1.byId=_2.byId;_1.isDescendant=_2.isDescendant;_1.setSelectable=_2.setSelectable;_1.getAttr=_4.get;_1.setAttr=_4.set;_1.hasAttr=_4.has;_1.removeAttr=_4.remove;_1.getNodeProp=_4.getNodeProp;_1.attr=function(_9,_a,_b){if(arguments.length==2){return _4[typeof _a=="string"?"get":"set"](_9,_a);}return _4.set(_9,_a,_b);};_1.hasClass=_6.contains;_1.addClass=_6.add;_1.removeClass=_6.remove;_1.toggleClass=_6.toggle;_1.replaceClass=_6.replace;_1._toDom=_1.toDom=_7.toDom;_1.place=_7.place;_1.create=_7.create;_1.empty=function(_c){_7.empty(_c);};_1._destroyElement=_1.destroy=function(_d){_7.destroy(_d);};_1._getPadExtents=_1.getPadExtents=_8.getPadExtents;_1._getBorderExtents=_1.getBorderExtents=_8.getBorderExtents;_1._getPadBorderExtents=_1.getPadBorderExtents=_8.getPadBorderExtents;_1._getMarginExtents=_1.getMarginExtents=_8.getMarginExtents;_1._getMarginSize=_1.getMarginSize=_8.getMarginSize;_1._getMarginBox=_1.getMarginBox=_8.getMarginBox;_1.setMarginBox=_8.setMarginBox;_1._getContentBox=_1.getContentBox=_8.getContentBox;_1.setContentSize=_8.setContentSize;_1._isBodyLtr=_1.isBodyLtr=_8.isBodyLtr;_1._docScroll=_1.docScroll=_8.docScroll;_1._getIeDocumentElementOffset=_1.getIeDocumentElementOffset=_8.getIeDocumentElementOffset;_1._fixIeBiDiScrollLeft=_1.fixIeBiDiScrollLeft=_8.fixIeBiDiScrollLeft;_1.position=_8.position;_1.marginBox=function marginBox(_e,_f){return _f?_8.setMarginBox(_e,_f):_8.getMarginBox(_e);};_1.contentBox=function contentBox(_10,box){return box?_8.setContentSize(_10,box):_8.getContentBox(_10);};_1.coords=function(_11,_12){_1.deprecated("dojo.coords()","Use dojo.position() or dojo.marginBox().");_11=_2.byId(_11);var s=_3.getComputedStyle(_11),mb=_8.getMarginBox(_11,s);var abs=_8.position(_11,_12);mb.x=abs.x;mb.y=abs.y;return mb;};_1.getProp=_5.get;_1.setProp=_5.set;_1.prop=function(_13,_14,_15){if(arguments.length==2){return _5[typeof _14=="string"?"get":"set"](_13,_14);}return _5.set(_13,_14,_15);};_1.getStyle=_3.get;_1.setStyle=_3.set;_1.getComputedStyle=_3.getComputedStyle;_1.__toPixelValue=_1.toPixelValue=_3.toPixelValue;_1.style=function(_16,_17,_18){switch(arguments.length){case 1:return _3.get(_16);case 2:return _3[typeof _17=="string"?"get":"set"](_16,_17);}return _3.set(_16,_17,_18);};return _1;});
\ No newline at end of file