dojo/_base/html.js

  • Provides:

    • dojo
  • dojo.byId

    • type
      Function
    • parameters:
      • id: (typeof String|DOMNode)
        A string to match an HTML id attribute or a reference to a DOM Node
      • doc: (typeof Document)
        Document to work in. Defaults to the current value of
        dojo.doc.  Can be used to retrieve
        node references from other documents.
    • source: [view]
      define("dojo/_base/html", ["dojo/lib/kernel", "dojo/_base/lang"], function(dojo){


      // FIXME: need to add unit tests for all the semi-public methods


      //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
      try{
       document.execCommand("BackgroundImageCache", false, true);
      }catch(e){
       // sane browsers don't have cache "issues"
      }
      //>>excludeEnd("webkitMobile");


      // =============================
      // 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
       // | }




      //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
      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{
      //>>excludeEnd("webkitMobile");
       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
       };
      //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
      }
      //>>excludeEnd("webkitMobile");
    • summary
      Returns DOM node with matching `id` attribute or `null`
      if not found. If `id` is a DomNode, this function is a no-op.
    • returns
      DomNode
    • 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() ... }
  • dojo._destroyElement

    • type
      Function
    • parameters:
      • node: (typeof )
    • source: [view]
        // summary:
        //   Existing alias for `dojo.destroy`. Deprecated, will be removed
        //   in 2.0
    • summary
      Existing alias for `dojo.destroy`. Deprecated, will be removed
      in 2.0
  • dojo.boxModel

    • summary
  • dojo.getComputedStyle

    • type
      Function
    • parameters:
      • node: (typeof DOMNode)
        A reference to a DOM node. Does NOT support taking an
        ID string for speed reasons.
    • source: [view]
        return; // CSS2Properties
    • 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.
    • returns
      CSS2Properties
    • 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;
  • dojo._getOpacity

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
        a reference to a DOM node. Does NOT support taking an
        ID string for speed reasons.
    • source: [view]
         return; // Number
    • summary
      Returns the current opacity of the passed node as a
      floating-point value between 0 and 1.
    • return_summary
      Number between 0 and 1
    • returns
      Number
  • dojo._setOpacity

    • type
      Function
    • parameters:
      • node: (typeof DOMNode)
        a reference to a DOM node. Does NOT support taking an
        ID string for performance reasons.
      • opacity: (typeof Number)
        A Number between 0 and 1. 0 specifies transparent.
    • source: [view]
         return; // Number
    • summary
      set the opacity of the passed node portably. Returns the
      new opacity of the node.
    • return_summary
      Number between 0 and 1
    • returns
      Number
  • _floatAliases

    • type
      Object
    • summary
  • dojo._abs

    • ?? aliases = dojo.position (debug: string) ??
    • summary
  • _attrNames

    • type
      Object
    • summary
  • _forcePropNames

    • type
      Object
    • summary
  • _roInnerHtml

    • type
      Object
    • summary
  • dojo.empty

    • type
      Function
    • parameters:
      • node: (typeof DOMNode|String)
        a reference to a DOM node or an id.
    • source: [view]
         // 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);
    • summary
      safely removes all children of the node.
    • 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);
  • reTag

    • summary
  • masterNode

    • type
      Object
    • summary
  • masterName

    • summary
  • tw.pre

    • summary
  • tw.post

    • summary
  • fakeNode

    • type
      Object
    • summary
  • dojo.destroy

    • type
      Function
    • parameters:
      • node: (typeof String|DomNode)
        A String ID or DomNode reference of the element to be destroyed
    • source: [view]
        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 */
        }
    • 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.
    • example
      Destroy a node byId:
      
      	dojo.destroy("someId");
    • example
      Destroy all nodes in a list by reference:
      
      	dojo.query(".someNode").forEach(dojo.destroy);
  • dojo.isDescendant

    • type
      Function
    • parameters:
      • node: (typeof DomNode|String)
        string id or node reference to test
      • ancestor: (typeof DomNode|String)
        string id or node reference of potential parent to test against
    • source: [view]
        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
    • summary
      Returns true if node is a descendant of ancestor
    • returns
      Boolean
    • example
      Test is node id="bar" is a descendant of node id="foo"
      
      	if(dojo.isDescendant("bar", "foo")){ ... }
  • dojo.setSelectable

    • type
      Function
    • parameters:
      • node: (typeof DomNode|String)
        id or reference to node
      • selectable: (typeof Boolean)
        state to put the node in. false indicates unselectable, true
        allows selection.
    • source: [view]
        node = byId(node);
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        if(d.isMozilla){
         node.style.MozUserSelect = selectable ? "" : "none";
        }else if(d.isKhtml || d.isWebKit){
        //>>excludeEnd("webkitMobile");
         node.style.KhtmlUserSelect = selectable ? "auto" : "none";
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        }else if(d.isIE){
         var v = (node.unselectable = selectable ? "" : "on");
         d.query("*", node).forEach("item.unselectable = '"+v+"'");
        }
        //>>excludeEnd("webkitMobile");
        //FIXME: else? Opera?
    • summary
      Enable or disable selection on a node
    • example
      Make the node id="bar" unselectable
      
      	dojo.setSelectable("bar");
    • example
      Make the node id="bar" selectable
      
      	dojo.setSelectable("bar", true);
  • dojo.place

    • type
      Function
    • parameters:
      • node: (typeof String|DomNode)
        id or node reference, or HTML fragment starting with "<" to place relative to refNode
      • refNode: (typeof String|DomNode)
        id or node reference to use as basis for placement
      • position: (typeof 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
    • source: [view]
        refNode = byId(refNode);
        if(typeof node == "string"){ // inline'd type check
         node = /^\s*  }
        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
    • summary
      Attempt to insert node into the DOM, choosing from various positioning options.
      Returns the first argument resolved to a DOM node.
    • return_summary
      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.
    • returns
      DomNode
    • 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");
  • dojo._toPixelValue

    • type
      Function
    • parameters:
      • element: (typeof )
      • value: (typeof )
      • avalue: (typeof )
    • source: [view]
         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;
    • returns
      DomNode|Boolean|CSS2Properties
    • summary
  • dojo.style

    • type
      Function
    • parameters:
      • node: (typeof DomNode|String)
        id or reference to node to get/set style for
      • style: (typeof String?|Object)
        the style property to set in DOM-accessor format
        (&quot;borderWidth&quot;, not &quot;border-width&quot;) or an object with key/value
        pairs suitable for setting each property.
      • value: (typeof String)
        If passed, sets value on the node for style, handling
        cross-browser concerns.  When setting a pixel value,
        be sure to include &quot;px&quot; in the value. For instance, top: &quot;200px&quot;.
        Otherwise, in some cases, some browsers will not apply the style.
    • source: [view]
        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 */
    • 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()`.
    • returns
      Number|CSS2Properties||String||Number
    • 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"
      	});
  • dojo._getPadExtents

    • type
      Function
    • parameters:
      • n: (typeof DomNode)
      • computedStyle: (typeof Object)
    • source: [view]
        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)
        };
    • 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.
  • dojo._getBorderExtents

    • type
      Function
    • parameters:
      • n: (typeof DomNode)
      • computedStyle: (typeof Object)
    • source: [view]
        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)
        };
    • 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.
  • dojo._getPadBorderExtents

    • type
      Function
    • parameters:
      • n: (typeof DomNode)
      • computedStyle: (typeof Object)
    • source: [view]
        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
        };
    • 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.
  • dojo._getMarginExtents

    • type
      Function
    • parameters:
      • n: (typeof )
      • computedStyle: (typeof )
    • source: [view]
        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
        };
    • 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.
  • dojo._getMarginBox

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
      • computedStyle: (typeof Object)
    • source: [view]
        var s = computedStyle || gcs(node), me = d._getMarginExtents(node, s);
        var l = node.offsetLeft - me.l, t = node.offsetTop - me.t, p = node.parentNode;
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        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;
         }
        }
        //>>excludeEnd("webkitMobile");
        return {
         l: l,
         t: t,
         w: node.offsetWidth + me.w,
         h: node.offsetHeight + me.h
        };
    • summary
      returns an object that encodes the width, height, left and top
      positions of the node's margin box.
  • dojo._getMarginSize

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
      • computedStyle: (typeof Object)
    • source: [view]
        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
        }
    • summary
      returns an object that encodes the width and height of
      the node's margin box
  • dojo._getContentBox

    • type
      Function
    • parameters:
      • node: (typeof )
      • computedStyle: (typeof )
    • source: [view]
      define("dojo/_base/html", ["dojo/lib/kernel", "dojo/_base/lang"], function(dojo){


      // FIXME: need to add unit tests for all the semi-public methods


      //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
      try{
       document.execCommand("BackgroundImageCache", false, true);
      }catch(e){
       // sane browsers don't have cache "issues"
      }
      //>>excludeEnd("webkitMobile");


      // =============================
      // 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
       // | }




      //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
      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{
      //>>excludeEnd("webkitMobile");
       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
       };
      //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
      }
      //>>excludeEnd("webkitMobile");


      };




      //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
      (function(){
       var d = dojo;
      //>>excludeEnd("webkitMobile");
       var byId = d.byId;


       var _destroyContainer = null,
        _destroyDoc;
       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       d.addOnWindowUnload(function(){
        _destroyContainer = null; //prevent IE leak
       });
       //>>excludeEnd("webkitMobile");




       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);
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        if(d.isMozilla){
         node.style.MozUserSelect = selectable ? "" : "none";
        }else if(d.isKhtml || d.isWebKit){
        //>>excludeEnd("webkitMobile");
         node.style.KhtmlUserSelect = selectable ? "auto" : "none";
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        }else if(d.isIE){
         var v = (node.unselectable = selectable ? "" : "on");
         d.query("*", node).forEach("item.unselectable = '"+v+"'");
        }
        //>>excludeEnd("webkitMobile");
        //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("
      ", dojo.body());
        //
        // example:
        //  Put a new LI as the first child of a list by id:
        // | dojo.place("
    • ", "someUl", "first");


        refNode = byId(refNode);
        if(typeof node == "string"){ // inline'd type check
         node = /^\s*  }
        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.


       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       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";
       }
       //>>excludeEnd("webkitMobile");


       // =============================
       // 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;
       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       if(d.isWebKit){
       //>>excludeEnd("webkitMobile");
        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 || {};
        };
       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       }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) : {};
        };
       }
       //>>excludeEnd("webkitMobile");
       dojo.getComputedStyle = gcs;


       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       if(!d.isIE){
       //>>excludeEnd("webkitMobile");
        d._toPixelValue = function(element, value){
         // style values can be floats, client code may want
         // to round for integer pixels.
         return parseFloat(value) || 0;
        };
       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       }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;
        };
       }
       //>>excludeEnd("webkitMobile");
       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
       }

       


       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       var astr = "DXImageTransform.Microsoft.Alpha";
       var af = function(n, f){
        try{
         return n.filters.item(astr);
        }catch(e){
         return f ? {} : null;
        }
       };


       //>>excludeEnd("webkitMobile");
       dojo._getOpacity =
       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        d.isIE < 9 ? function(node){
         try{
          return af(node).Opacity / 100; // Number
         }catch(e){
          return 1; // Number
         }
        } :
       //>>excludeEnd("webkitMobile");
        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 =
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        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;
        } :
        //>>excludeEnd("webkitMobile");
        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!
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        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";
          }
         }
        }
        //>>excludeEnd("webkitMobile");
        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;
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        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;
         }
        }
        //>>excludeEnd("webkitMobile");
        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
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        if(d.isOpera){ pe.l += be.l; pe.t += be.t; };
        //>>excludeEnd("webkitMobile");
        return {
         l: pe.l,
         t: pe.t,
         w: w - pe.w - be.w,
         h: h - pe.h - be.h
        };
  • returns
    DomNode|Boolean|CSS2Properties|Number|CSS2Properties||String||Number
  • summary
  • dojo._getBorderBox

    • type
      Function
    • parameters:
      • node: (typeof )
      • computedStyle: (typeof )
    • source: [view]
        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
        };
    • summary
  • dojo._setBox

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
        DOM Node reference. Id string not supported for performance
        reasons.
      • l: (typeof Number)
        left offset from parent.
      • t: (typeof Number)
        top offset from parent.
      • w: (typeof Number)
        width in current box model.
      • h: (typeof Number)
        width in current box model.
      • u: (typeof String)
        unit measure to use for other measures. Defaults to &quot;px&quot;.
    • source: [view]
        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; }
    • summary
      sets width/height/left/top in the current (native) box-model
      dimentions. Uses the unit passed in u.
  • dojo._isButtonTag

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
    • source: [view]
        return node.tagName == "BUTTON"
         || node.tagName=="INPUT" && (node.getAttribute("type")||'').toUpperCase() == "BUTTON"; // boolean
    • summary
      True if the node is BUTTON or INPUT.type=&quot;button&quot;.
  • dojo._usesBorderBox

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
    • source: [view]
      define("dojo/_base/html", ["dojo/lib/kernel", "dojo/_base/lang"], function(dojo){


      // FIXME: need to add unit tests for all the semi-public methods


      //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
      try{
       document.execCommand("BackgroundImageCache", false, true);
      }catch(e){
       // sane browsers don't have cache "issues"
      }
      //>>excludeEnd("webkitMobile");


      // =============================
      // 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
       // | }




      //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
      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{
      //>>excludeEnd("webkitMobile");
       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
       };
      //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
      }
      //>>excludeEnd("webkitMobile");


      };




      //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
      (function(){
       var d = dojo;
      //>>excludeEnd("webkitMobile");
       var byId = d.byId;


       var _destroyContainer = null,
        _destroyDoc;
       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       d.addOnWindowUnload(function(){
        _destroyContainer = null; //prevent IE leak
       });
       //>>excludeEnd("webkitMobile");




       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);
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        if(d.isMozilla){
         node.style.MozUserSelect = selectable ? "" : "none";
        }else if(d.isKhtml || d.isWebKit){
        //>>excludeEnd("webkitMobile");
         node.style.KhtmlUserSelect = selectable ? "auto" : "none";
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        }else if(d.isIE){
         var v = (node.unselectable = selectable ? "" : "on");
         d.query("*", node).forEach("item.unselectable = '"+v+"'");
        }
        //>>excludeEnd("webkitMobile");
        //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("
      ", dojo.body());
        //
        // example:
        //  Put a new LI as the first child of a list by id:
        // | dojo.place("
    • ", "someUl", "first");


        refNode = byId(refNode);
        if(typeof node == "string"){ // inline'd type check
         node = /^\s*  }
        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.


       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       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";
       }
       //>>excludeEnd("webkitMobile");


       // =============================
       // 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;
       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       if(d.isWebKit){
       //>>excludeEnd("webkitMobile");
        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 || {};
        };
       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       }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) : {};
        };
       }
       //>>excludeEnd("webkitMobile");
       dojo.getComputedStyle = gcs;


       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       if(!d.isIE){
       //>>excludeEnd("webkitMobile");
        d._toPixelValue = function(element, value){
         // style values can be floats, client code may want
         // to round for integer pixels.
         return parseFloat(value) || 0;
        };
       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       }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;
        };
       }
       //>>excludeEnd("webkitMobile");
       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
       }

       


       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       var astr = "DXImageTransform.Microsoft.Alpha";
       var af = function(n, f){
        try{
         return n.filters.item(astr);
        }catch(e){
         return f ? {} : null;
        }
       };


       //>>excludeEnd("webkitMobile");
       dojo._getOpacity =
       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        d.isIE < 9 ? function(node){
         try{
          return af(node).Opacity / 100; // Number
         }catch(e){
          return 1; // Number
         }
        } :
       //>>excludeEnd("webkitMobile");
        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 =
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        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;
        } :
        //>>excludeEnd("webkitMobile");
        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!
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        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";
          }
         }
        }
        //>>excludeEnd("webkitMobile");
        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;
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        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;
         }
        }
        //>>excludeEnd("webkitMobile");
        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
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        if(d.isOpera){ pe.l += be.l; pe.t += be.t; };
        //>>excludeEnd("webkitMobile");
        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
  • returns
    DomNode|Boolean|CSS2Properties|Number|CSS2Properties||String||Number|boolean
  • summary
  • dojo._setContentSize

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
      • widthPx: (typeof Number)
      • heightPx: (typeof Number)
      • computedStyle: (typeof Object)
    • source: [view]
        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);
    • summary
      Sets the size of the node's contents, irrespective of margins,
      padding, or borders.
  • dojo._setMarginBox

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
      • leftPx: (typeof Number)
      • topPx: (typeof Number)
      • widthPx: (typeof Number)
      • heightPx: (typeof Number)
      • computedStyle: (typeof Object)
    • source: [view]
        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);
    • 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.
  • dojo.marginBox

    • type
      Function
    • parameters:
      • node: (typeof DomNode|String)
        id or reference to DOM Node to get/set box for
      • box: (typeof Object)
        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.
    • source: [view]
        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
    • 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.
    • returns
      Object
    • 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);
  • dojo.contentBox

    • type
      Function
    • parameters:
      • node: (typeof DomNode|String)
        id or reference to DOM Node to get/set box for
      • box: (typeof Object)
        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.
    • source: [view]
        var n = byId(node), s = gcs(n), b = box;
        return !b ? d._getContentBox(n, s) : d._setContentSize(n, b.w, b.h, s); // Object
    • 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.
    • returns
      Object
  • dojo._docScroll

    • type
      Function
    • source: [view]
        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 });
    • summary
  • dojo._isBodyLtr

    • type
      Function
    • source: [view]
        return "_bodyLtr" in d? d._bodyLtr :
         d._bodyLtr = (d.body().dir || d.doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean
    • summary
  • dojo._getIeDocumentElementOffset

    • type
      Function
    • source: [view]
      define("dojo/_base/html", ["dojo/lib/kernel", "dojo/_base/lang"], function(dojo){


      // FIXME: need to add unit tests for all the semi-public methods


      //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
      try{
       document.execCommand("BackgroundImageCache", false, true);
      }catch(e){
       // sane browsers don't have cache "issues"
      }
      //>>excludeEnd("webkitMobile");


      // =============================
      // 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
       // | }




      //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
      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{
      //>>excludeEnd("webkitMobile");
       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
       };
      //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
      }
      //>>excludeEnd("webkitMobile");


      };




      //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
      (function(){
       var d = dojo;
      //>>excludeEnd("webkitMobile");
       var byId = d.byId;


       var _destroyContainer = null,
        _destroyDoc;
       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       d.addOnWindowUnload(function(){
        _destroyContainer = null; //prevent IE leak
       });
       //>>excludeEnd("webkitMobile");




       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);
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        if(d.isMozilla){
         node.style.MozUserSelect = selectable ? "" : "none";
        }else if(d.isKhtml || d.isWebKit){
        //>>excludeEnd("webkitMobile");
         node.style.KhtmlUserSelect = selectable ? "auto" : "none";
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        }else if(d.isIE){
         var v = (node.unselectable = selectable ? "" : "on");
         d.query("*", node).forEach("item.unselectable = '"+v+"'");
        }
        //>>excludeEnd("webkitMobile");
        //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("
      ", dojo.body());
        //
        // example:
        //  Put a new LI as the first child of a list by id:
        // | dojo.place("
    • ", "someUl", "first");


        refNode = byId(refNode);
        if(typeof node == "string"){ // inline'd type check
         node = /^\s*  }
        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.


       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       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";
       }
       //>>excludeEnd("webkitMobile");


       // =============================
       // 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;
       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       if(d.isWebKit){
       //>>excludeEnd("webkitMobile");
        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 || {};
        };
       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       }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) : {};
        };
       }
       //>>excludeEnd("webkitMobile");
       dojo.getComputedStyle = gcs;


       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       if(!d.isIE){
       //>>excludeEnd("webkitMobile");
        d._toPixelValue = function(element, value){
         // style values can be floats, client code may want
         // to round for integer pixels.
         return parseFloat(value) || 0;
        };
       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       }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;
        };
       }
       //>>excludeEnd("webkitMobile");
       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
       }

       


       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       var astr = "DXImageTransform.Microsoft.Alpha";
       var af = function(n, f){
        try{
         return n.filters.item(astr);
        }catch(e){
         return f ? {} : null;
        }
       };


       //>>excludeEnd("webkitMobile");
       dojo._getOpacity =
       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        d.isIE < 9 ? function(node){
         try{
          return af(node).Opacity / 100; // Number
         }catch(e){
          return 1; // Number
         }
        } :
       //>>excludeEnd("webkitMobile");
        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 =
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        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;
        } :
        //>>excludeEnd("webkitMobile");
        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!
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        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";
          }
         }
        }
        //>>excludeEnd("webkitMobile");
        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;
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        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;
         }
        }
        //>>excludeEnd("webkitMobile");
        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
        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
        if(d.isOpera){ pe.l += be.l; pe.t += be.t; };
        //>>excludeEnd("webkitMobile");
        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
       };


       //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
       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
         };
        }
  • summary
    returns the offset in x and y from the document body to the
    visual edge of the page
  • returns
    DomNode|Boolean|CSS2Properties|Number|CSS2Properties||String||Number|boolean|Object|integer
  • dojo._fixIeBiDiScrollLeft

  • returns
    DomNode|Boolean|CSS2Properties|Number|CSS2Properties||String||Number|boolean|Object|integer|Integer
  • summary
  • dojo.position

  • dojo.coords

  • dojo.hasAttr

  • dojo.attr

  • dojo.removeAttr

  • dojo.getNodeProp

  • dojo.create

  • dojo._toDom

  • dojo.hasClass

  • str2array

  • dojo.addClass

  • dojo.removeClass

  • dojo.replaceClass

  • dojo.toggleClass

  • _floatAliases.cssFloat

  • _floatAliases.styleFloat

  • _floatAliases.float

  • ret.x

  • ret.y

  • ret.w

  • ret.h

  • ret

  • _attrNames.classname

  • _attrNames.htmlfor

  • _attrNames.tabindex

  • _attrNames.readonly

  • _forcePropNames.innerHTML

  • _forcePropNames.className

  • _forcePropNames.htmlFor

  • _forcePropNames.value

  • _roInnerHtml.col

  • _roInnerHtml.colgroup

  • _roInnerHtml.table

  • dojo