aboutsummaryrefslogtreecommitdiff
path: root/includes/js/dojo/_base/html.js
diff options
context:
space:
mode:
Diffstat (limited to 'includes/js/dojo/_base/html.js')
-rw-r--r--includes/js/dojo/_base/html.js1227
1 files changed, 0 insertions, 1227 deletions
diff --git a/includes/js/dojo/_base/html.js b/includes/js/dojo/_base/html.js
deleted file mode 100644
index d673eb1..0000000
--- a/includes/js/dojo/_base/html.js
+++ /dev/null
@@ -1,1227 +0,0 @@
-if(!dojo._hasResource["dojo._base.html"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
-dojo._hasResource["dojo._base.html"] = true;
-dojo.require("dojo._base.lang");
-dojo.provide("dojo._base.html");
-
-// FIXME: need to add unit tests for all the semi-public methods
-
-try{
- document.execCommand("BackgroundImageCache", false, true);
-}catch(e){
- // sane browsers don't have cache "issues"
-}
-
-// =============================
-// DOM Functions
-// =============================
-
-/*=====
-dojo.byId = function(id, doc){
- // summary:
- // Returns DOM node with matching `id` attribute or `null`
- // if not found, similar to "$" function in another library.
- // 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.
-=====*/
-if(dojo.isIE || dojo.isOpera){
- dojo.byId = function(id, doc){
- if(dojo.isString(id)){
- var _d = doc || dojo.doc;
- var 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){
- return te;
- }else{
- var eles = _d.all[id];
- if(!eles || !eles.length){ return eles; }
- // if more than 1, choose first with the correct id
- var i=0;
- while((te=eles[i++])){
- if(te.attributes.id.value == id){ return te; }
- }
- }
- }else{
- return id; // DomNode
- }
- }
-}else{
- dojo.byId = function(id, doc){
- return dojo.isString(id) ? (doc || dojo.doc).getElementById(id) : id; // DomNode
- }
-}
-/*=====
-}
-=====*/
-
-(function(){
- /*
- dojo.createElement = function(obj, parent, position){
- // TODO: need to finish this!
- }
- */
-
- var d = dojo;
-
- var _destroyContainer = null;
- dojo.addOnUnload(function(){
- _destroyContainer=null; //prevent IE leak
- });
- dojo._destroyElement = function(/*String||DomNode*/node){
- // summary:
- // removes node from its parent, clobbers it and all of its
- // children.
- // node:
- // the element to be destroyed, either as an ID or a reference
-
- node = d.byId(node);
- try{
- if(!_destroyContainer){
- _destroyContainer = document.createElement("div");
- }
- _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: id or node reference to test
- // ancestor: id or node reference of potential parent to test against
- try{
- node = d.byId(node);
- ancestor = d.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:
- node = d.byId(node);
- if(d.isMozilla){
- node.style.MozUserSelect = selectable ? "" : "none";
- }else if(d.isKhtml){
- node.style.KhtmlUserSelect = selectable ? "auto" : "none";
- }else if(d.isIE){
- node.unselectable = selectable ? "" : "on";
- d.query("*", node).forEach(function(descendant){
- descendant.unselectable = selectable ? "" : "on";
- });
- }
- //FIXME: else? Opera?
- };
-
- var _insertBefore = function(/*Node*/node, /*Node*/ref){
- ref.parentNode.insertBefore(node, ref);
- return true; // boolean
- }
-
- var _insertAfter = function(/*Node*/node, /*Node*/ref){
- // summary:
- // Try to insert node after ref
- var pn = ref.parentNode;
- if(ref == pn.lastChild){
- pn.appendChild(node);
- }else{
- return _insertBefore(node, ref.nextSibling); // boolean
- }
- return true; // boolean
- }
-
- dojo.place = function(/*String|DomNode*/node, /*String|DomNode*/refNode, /*String|Number*/position){
- // summary:
- // Attempt to insert node into the DOM, choosing from various positioning options.
- // Returns true if successful, false otherwise.
- // node:
- // id or node reference to place relative to refNode
- // refNode:
- // id or node reference to use as basis for placement
- // position:
- // 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
- // * first
- // * last
- //
- // "first" and "last" indicate positions as children of refNode.
-
- // FIXME: need to write tests for this!!!!
- if(!node || !refNode || position === undefined){
- return false; // boolean
- }
- node = d.byId(node);
- refNode = d.byId(refNode);
- if(typeof position == "number"){
- var cn = refNode.childNodes;
- if((position == 0 && cn.length == 0) ||
- cn.length == position){
- refNode.appendChild(node); return true;
- }
- if(position == 0){
- return _insertBefore(node, refNode.firstChild);
- }
- return _insertAfter(node, cn[position-1]);
- }
- switch(position.toLowerCase()){
- case "before":
- return _insertBefore(node, refNode); // boolean
- case "after":
- return _insertAfter(node, refNode); // boolean
- case "first":
- if(refNode.firstChild){
- return _insertBefore(node, refNode.firstChild); // boolean
- }
- // else fallthrough...
- default: // aka: last
- refNode.appendChild(node);
- return true; // boolean
- }
- }
-
- // Box functions will assume this model.
- // On IE/Opera, BORDER_BOX will be set if the primary document is in quirks mode.
- // Can be set to change behavior of box setters.
-
- // can be either:
- // "border-box"
- // "content-box" (default)
- dojo.boxModel = "content-box";
-
- // We punt per-node box mode testing completely.
- // If anybody cares, we can provide an additional (optional) unit
- // that overrides existing code to include per-node box sensitivity.
-
- // Opera documentation claims that Opera 9 uses border-box in BackCompat mode.
- // but experiments (Opera 9.10.8679 on Windows Vista) indicate that it actually continues to use content-box.
- // IIRC, earlier versions of Opera did in fact use border-box.
- // Opera guys, this is really confusing. Opera being broken in quirks mode is not our fault.
-
- if(d.isIE /*|| dojo.isOpera*/){
- var _dcm = document.compatMode;
- // client code may have to adjust if compatMode varies across iframes
- d.boxModel = _dcm == "BackCompat" || _dcm == "QuirksMode" || d.isIE<6 ? "border-box" : "content-box"; // FIXME: remove IE < 6 support?
- }
-
- // =============================
- // 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;
- return; // CSS2Properties
- }
-=====*/
-
- var gcs, dv = document.defaultView;
- if(d.isSafari){
- gcs = function(/*DomNode*/node){
- var s = dv.getComputedStyle(node, null);
- if(!s && node.style){
- node.style.display = "";
- s = dv.getComputedStyle(node, null);
- }
- return s || {};
- };
- }else if(d.isIE){
- gcs = function(node){
- return node.currentStyle;
- };
- }else{
- gcs = function(node){
- return dv.getComputedStyle(node, null);
- };
- }
- dojo.getComputedStyle = gcs;
-
- if(!d.isIE){
- dojo._toPixelValue = function(element, value){
- // style values can be floats, client code may want
- // to round for integer pixels.
- return parseFloat(value) || 0;
- }
- }else{
- dojo._toPixelValue = function(element, avalue){
- if(!avalue){ return 0; }
- // on IE7, medium is usually 4 pixels
- if(avalue=="medium"){ return 4; }
- // style values can be floats, client code may
- // want to round this value for integer pixels.
- if(avalue.slice && (avalue.slice(-2)=='px')){ return parseFloat(avalue); }
- with(element){
- var sLeft = style.left;
- var rsLeft = runtimeStyle.left;
- runtimeStyle.left = currentStyle.left;
- try{
- // 'avalue' may be incompatible with style.left, which can cause IE to throw
- // this has been observed for border widths using "thin", "medium", "thick" constants
- // those particular constants could be trapped by a lookup
- // but perhaps there are more
- style.left = avalue;
- avalue = style.pixelLeft;
- }catch(e){
- avalue = 0;
- }
- style.left = sLeft;
- runtimeStyle.left = rsLeft;
- }
- return avalue;
- }
- }
- var px = d._toPixelValue;
-
- // FIXME: there opacity quirks on FF that we haven't ported over. Hrm.
- /*=====
- dojo._getOpacity = function(node){
- // summary:
- // Returns the current opacity of the passed node as a
- // floating-point value between 0 and 1.
- // node: DomNode
- // a reference to a DOM node. Does NOT support taking an
- // ID string for speed reasons.
- // return: Number between 0 and 1
- }
- =====*/
-
- dojo._getOpacity = d.isIE ? function(node){
- try{
- return node.filters.alpha.opacity / 100; // Number
- }catch(e){
- return 1; // Number
- }
- } : function(node){
- return gcs(node).opacity;
- };
-
- /*=====
- dojo._setOpacity = function(node, opacity){
- // summary:
- // set the opacity of the passed node portably. Returns the
- // new opacity of the node.
- // node: DOMNode
- // a reference to a DOM node. Does NOT support taking an
- // ID string for performance reasons.
- // opacity: Number
- // A Number between 0 and 1. 0 specifies transparent.
- // return: Number between 0 and 1
- }
- =====*/
-
- dojo._setOpacity = d.isIE ? function(/*DomNode*/node, /*Number*/opacity){
- if(opacity == 1){
- // on IE7 Alpha(Filter opacity=100) makes text look fuzzy so remove it altogether (bug #2661)
- var filterRE = /FILTER:[^;]*;?/i;
- node.style.cssText = node.style.cssText.replace(filterRE, "");
- if(node.nodeName.toLowerCase() == "tr"){
- d.query("> td", node).forEach(function(i){
- i.style.cssText = i.style.cssText.replace(filterRE, "");
- });
- }
- }else{
- var o = "Alpha(Opacity="+ opacity * 100 +")";
- node.style.filter = o;
- }
- if(node.nodeName.toLowerCase() == "tr"){
- d.query("> td", node).forEach(function(i){
- i.style.filter = o;
- });
- }
- return opacity;
- } : function(node, opacity){
- return node.style.opacity = opacity;
- };
-
- var _pixelNamesCache = {
- left: true, top: true
- };
- var _pixelRegExp = /margin|padding|width|height|max|min|offset/; // |border
- var _toStyleValue = function(node, type, value){
- type = type.toLowerCase();
- if(d.isIE && value == "auto"){
- if(type == "height"){ return node.offsetHeight; }
- if(type == "width"){ return node.offsetWidth; }
- }
- if(!(type in _pixelNamesCache)){
- // if(dojo.isOpera && type == "cssText"){
- // FIXME: add workaround for #2855 here
- // }
- _pixelNamesCache[type] = _pixelRegExp.test(type);
- }
- return _pixelNamesCache[type] ? px(node, value) : value;
- }
-
- var _floatStyle = d.isIE ? "styleFloat" : "cssFloat";
- var _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.
- // 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.
- // 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": 300
- // | });
- //
- // 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 = d.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 && !d.isString(style)){
- for(var x in style){
- d.style(node, x, style[x]);
- }
- return s;
- }
- return (args == 1) ? s : _toStyleValue(n, style, s[style]); /* CSS2Properties||String||Number */
- }
-
- // =============================
- // Box Functions
- // =============================
-
- dojo._getPadExtents = function(/*DomNode*/n, /*Object*/computedStyle){
- // summary:
- // Returns object with special values specifically useful for node
- // fitting.
- //
- // * 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.
- //
- // * 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.
- //
- // * 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.isSafari && (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;
- 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.
- var p = node.parentNode;
- 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){
- // On Opera, offsetLeft includes the parent's border
- var p = node.parentNode;
- if(p){
- var be = d._getBorderExtents(p);
- l -= be.l, t -= be.t;
- }
- }
- return {
- l: l,
- t: t,
- w: node.offsetWidth + me.w,
- h: node.offsetHeight + me.h
- };
- }
-
- dojo._getContentBox = function(node, computedStyle){
- // summary:
- // Returns an object that encodes the width, height, left and top
- // positions of the node's content box, irrespective of the
- // current box model.
-
- // clientWidth/Height are important since the automatically account for scrollbars
- // fallback to offsetWidth/Height for special cases (see #3378)
- var s=computedStyle||gcs(node), pe=d._getPadExtents(node, s), be=d._getBorderExtents(node, s), w=node.clientWidth, h;
- if(!w){
- w=node.offsetWidth, h=node.offsetHeight;
- }else{
- h=node.clientHeight, be.w = be.h = 0;
- }
- // On Opera, offsetLeft includes the parent's border
- if(d.isOpera){ pe.l += be.l; pe.t += be.t; };
- return {
- l: pe.l,
- t: pe.t,
- w: w - pe.w - be.w,
- h: h - pe.h - be.h
- };
- }
-
- dojo._getBorderBox = function(node, computedStyle){
- var s=computedStyle||gcs(node), pe=d._getPadExtents(node, s), cb=d._getContentBox(node, s);
- return {
- l: cb.l - pe.l,
- t: cb.t - pe.t,
- w: cb.w + pe.w,
- h: cb.h + pe.h
- };
- }
-
- // Box setters depend on box context because interpretation of width/height styles
- // vary wrt box context.
- //
- // The value of dojo.boxModel is used to determine box context.
- // dojo.boxModel can be set directly to change behavior.
- //
- // Beware of display: inline objects that have padding styles
- // because the user agent ignores padding (it's a bogus setup anyway)
- //
- // Be careful with IMGs because they are inline or block depending on
- // browser and browser mode.
- //
- // Elements other than DIV may have special quirks, like built-in
- // margins or padding, or values not detectable via computedStyle.
- // In particular, margins on TABLE do not seems to appear
- // at all in computedStyle on Mozilla.
-
- dojo._setBox = function(/*DomNode*/node, /*Number?*/l, /*Number?*/t, /*Number?*/w, /*Number?*/h, /*String?*/u){
- // summary:
- // sets width/height/left/top in the current (native) box-model
- // dimentions. Uses the unit passed in u.
- // node: DOM Node reference. Id string not supported for performance reasons.
- // l: optional. left offset from parent.
- // t: optional. top offset from parent.
- // w: optional. width in current box model.
- // h: optional. width in current box model.
- // u: optional. 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._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.
- var n = node.tagName;
- // For whatever reason, TABLE and BUTTON are always border-box by default.
- // If you have assigned a different box to either one via CSS then
- // box functions will break.
- return d.boxModel=="border-box" || n=="TABLE" || n=="BUTTON"; // 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.
- var bb=d._usesBorderBox(node),
- pb=bb ? _nilExtents : d._getPadBorderExtents(node, s),
- 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:
- // 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.
- var n=d.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.
- // 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. All properties are optional if passed.
- var n=dojo.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
- _b = d.body(),
- _w = d.global,
- de = d.doc.documentElement;
- return {
- y: (_w.pageYOffset || de.scrollTop || _b.scrollTop || 0),
- x: (_w.pageXOffset || d._fixIeBiDiScrollLeft(de.scrollLeft) || _b.scrollLeft || 0)
- };
- };
-
- dojo._isBodyLtr = function(){
- //FIXME: could check html and body tags directly instead of computed style? need to ignore case, accept empty values
- return !("_bodyLtr" in d) ?
- d._bodyLtr = gcs(d.body()).direction == "ltr" :
- d._bodyLtr; // Boolean
- }
-
- dojo._getIeDocumentElementOffset = function(){
- // summary
- // 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;
- //FIXME: use this instead? var de = d.compatMode == "BackCompat" ? d.body : d.documentElement;
-
- return (d.isIE >= 7) ?
- {x: de.getBoundingClientRect().left, y: de.getBoundingClientRect().top}
- :
- // IE 6.0
- {x: d._isBodyLtr() || window.parent == window ?
- de.clientLeft : de.offsetWidth - de.clientWidth - de.clientLeft,
- y: de.clientTop}; // Object
- };
-
- dojo._fixIeBiDiScrollLeft = function(/*Integer*/ scrollLeft){
- // In RTL direction, scrollLeft should be a negative value, but IE
- // returns a positive one. All codes using documentElement.scrollLeft
- // must call this function to fix this error, otherwise the position
- // will offset to right when there is a horizontal scrollbar.
- var dd = d.doc;
- if(d.isIE && !dojo._isBodyLtr()){
- var de = dd.compatMode == "BackCompat" ? dd.body : dd.documentElement;
- return scrollLeft + de.clientWidth - de.scrollWidth; // Integer
- }
- return scrollLeft; // Integer
- }
-
- dojo._abs = function(/*DomNode*/node, /*Boolean?*/includeScroll){
- // summary:
- // Gets the position of the passed element relative to
- // the viewport (if includeScroll==false), or relative to the
- // document root (if includeScroll==true).
- //
- // Returns an object of the form:
- // { x: 100, y: 300 }
- // if includeScroll is passed, the x and y values will include any
- // document offsets that may affect the position relative to the
- // viewport.
-
- // FIXME: need to decide in the brave-new-world if we're going to be
- // margin-box or border-box.
- var ownerDocument = node.ownerDocument;
- var ret = {
- x: 0,
- y: 0
- };
-
- // targetBoxType == "border-box"
- var db = d.body();
- if(d.isIE || (d.isFF >= 3)){
- var client = node.getBoundingClientRect();
- var offset = (d.isIE) ? d._getIeDocumentElementOffset() : { x: 0, y: 0};
- ret.x = client.left - offset.x;
- ret.y = client.top - offset.y;
- }else if(ownerDocument["getBoxObjectFor"]){
- // mozilla
- var bo = ownerDocument.getBoxObjectFor(node),
- b = d._getBorderExtents(node);
- ret.x = bo.x - b.l - _sumAncestorProperties(node, "scrollLeft");
- ret.y = bo.y - b.t - _sumAncestorProperties(node, "scrollTop");
- }else{
- if(node["offsetParent"]){
- var endNode;
- // in Safari, if the node is an absolutely positioned child of
- // the body and the body has a margin the offset of the child
- // and the body contain the body's margins, so we need to end
- // at the body
- // FIXME: getting contrary results to the above in latest WebKit.
- if(d.isSafari &&
- //(node.style.getPropertyValue("position") == "absolute") &&
- (gcs(node).position == "absolute") &&
- (node.parentNode == db)){
- endNode = db;
- }else{
- endNode = db.parentNode;
- }
- if(node.parentNode != db){
- var nd = node;
- if(d.isOpera){ nd = db; }
- ret.x -= _sumAncestorProperties(nd, "scrollLeft");
- ret.y -= _sumAncestorProperties(nd, "scrollTop");
- }
- var curnode = node;
- do{
- var n = curnode.offsetLeft;
- //FIXME: ugly hack to workaround the submenu in
- //popupmenu2 does not shown up correctly in opera.
- //Someone have a better workaround?
- if(!d.isOpera || n > 0){
- ret.x += isNaN(n) ? 0 : n;
- }
- var t = curnode.offsetTop;
- ret.y += isNaN(t) ? 0 : t;
- if(d.isSafari && curnode != node){
- var cs = gcs(curnode);
- ret.x += px(curnode, cs.borderLeftWidth);
- ret.y += px(curnode, cs.borderTopWidth);
- }
- curnode = curnode.offsetParent;
- }while((curnode != endNode) && curnode);
- }else if(node.x && node.y){
- ret.x += isNaN(node.x) ? 0 : node.x;
- ret.y += isNaN(node.y) ? 0 : node.y;
- }
- }
- // account for document scrolling
- // if offsetParent is used, ret value already includes scroll position
- // so we may have to actually remove that value if !includeScroll
- if(includeScroll){
- var scroll = d._docScroll();
- ret.y += scroll.y;
- ret.x += scroll.x;
- }
-
- return ret; // object
- }
-
- // FIXME: need a setter for coords or a moveTo!!
- dojo.coords = function(/*DomNode|String*/node, /*Boolean?*/includeScroll){
- // summary:
- // Returns an object that measures margin box width/height and
- // absolute positioning data from dojo._abs().
- //
- // description:
- // Returns an object that measures margin box width/height and
- // absolute positioning data from dojo._abs().
- // Return value will be in the form:
- // `{ l: 50, t: 200, w: 300: h: 150, x: 100, y: 300 }`
- // Does not act as a setter. If includeScroll is passed, the x and
- // y params are affected as one would expect in dojo._abs().
- var n=d.byId(node), s=gcs(n), mb=d._getMarginBox(n, s);
- var abs = d._abs(n, includeScroll);
- mb.x = abs.x;
- mb.y = abs.y;
- return mb;
- }
-
- // =============================
- // Element attribute Functions
- // =============================
-
- var _fixAttrName = function(/*String*/name){
- switch(name.toLowerCase()){
- case "tabindex":
- // Internet Explorer will only set or remove tabindex
- // if it is spelled "tabIndex"
- // console.debug((dojo.isIE && dojo.isIE < 8)? "tabIndex" : "tabindex");
- return (d.isIE && d.isIE < 8) ? "tabIndex" : "tabindex";
- default:
- return name;
- }
- }
-
- // non-deprecated HTML4 attributes with default values
- // http://www.w3.org/TR/html401/index/attributes.html
- // FF and Safari will return the default values if you
- // access the attributes via a property but not
- // via getAttribute()
- var _attrProps = {
- colspan: "colSpan",
- enctype: "enctype",
- frameborder: "frameborder",
- method: "method",
- rowspan: "rowSpan",
- scrolling: "scrolling",
- shape: "shape",
- span: "span",
- type: "type",
- valuetype: "valueType"
- }
-
- dojo.hasAttr = function(/*DomNode|String*/node, /*String*/name){
- // summary:
- // Returns true if the requested attribute is specified on the
- // given element, and false otherwise.
- // node:
- // id or reference to the element to check
- // name:
- // the name of the attribute
- // returns:
- // true if the requested attribute is specified on the
- // given element, and false otherwise
- var attr = d.byId(node).getAttributeNode(_fixAttrName(name));
- return attr ? attr.specified : false; // Boolean
- }
-
- var _evtHdlrMap = {
-
- }
-
- var _ctr = 0;
- var _attrId = dojo._scopeName + "attrid";
-
- dojo.attr = function(/*DomNode|String*/node, /*String|Object*/name, /*String?*/value){
- // summary:
- // Gets or sets an attribute on an HTML element.
- // description:
- // Handles normalized getting and setting of attributes on DOM
- // Nodes. If 2 arguments are passed, and a the second argumnt is a
- // string, acts as a getter.
- //
- // If a third argument is passed, or if the second argumnt is a
- // map of attributes, acts as a setter.
- //
- // When passing functions as values, note that they will not be
- // directly assigned to slots on the node, but rather the default
- // behavior will be removed and the new behavior will be added
- // using `dojo.connect()`, meaning that event handler properties
- // will be normalized and that some caveats with regards to
- // non-standard behaviors for onsubmit apply. Namely that you
- // should cancel form submission using `dojo.stopEvent()` on the
- // passed event object instead of returning a boolean value from
- // the handler itself.
- // node:
- // id or reference to the element to get or set the attribute on
- // name:
- // the name of the attribute to get or set.
- // value:
- // The value to set for the attribute
- // returns:
- // when used as a getter, the value of the requested attribute
- // or null if that attribute does not have a specified or
- // default value;
- //
- // when user as a setter, undefined
- // example:
- // | // get the current value of the "foo" attribute on a node
- // | dojo.attr(dojo.byId("nodeId"), "foo");
- // |
- // | // we can just pass the id:
- // | dojo.attr("nodeId", "foo");
- // |
- // | // use attr() to set the tab index
- // | dojo.attr("nodeId", "tabindex", 3);
- // |
- // | // set multiple values at once, including event handlers:
- // | dojo.attr("formId", {
- // | "foo": "bar",
- // | "tabindex": -1,
- // | "method": "POST",
- // | "onsubmit": function(e){
- // | // stop submitting the form. Note that the IE behavior
- // | // of returning true or false will have no effect here
- // | // since our handler is connect()ed to the built-in
- // | // onsubmit behavior and so we need to use
- // | // dojo.stopEvent() to ensure that the submission
- // | // doesn't proceed.
- // | dojo.stopEvent(e);
- // |
- // | // submit the form with Ajax
- // | dojo.xhrPost({ form: "formId" });
- // | }
- // | });
-
- var args = arguments.length;
- if(args == 2 && !d.isString(name)){
- for(var x in name){ d.attr(node, x, name[x]); }
- return;
- }
- node = d.byId(node);
- name = _fixAttrName(name);
- if(args == 3){
- if(d.isFunction(value)){
- // clobber if we can
- var attrId = d.attr(node, _attrId);
- if(!attrId){
- attrId = _ctr++;
- d.attr(node, _attrId, attrId);
- }
- if(!_evtHdlrMap[attrId]){
- _evtHdlrMap[attrId] = {};
- }
- var h = _evtHdlrMap[attrId][name];
- if(h){
- d.disconnect(h);
- }else{
- try{
- delete node[name];
- }catch(e){}
- }
-
- // ensure that event objects are normalized, etc.
- _evtHdlrMap[attrId][name] = d.connect(node, name, value);
-
- }else if(typeof value == "boolean"){ // e.g. onsubmit, disabled
- // if a function, we should normalize the event object here!!!
- node[name] = value;
- }else{
- node.setAttribute(name, value);
- }
- return;
- }else{
- // should we access this attribute via a property or
- // via getAttribute()?
- var prop = _attrProps[name.toLowerCase()];
- if(prop){
- return node[prop];
- }else{
- var value = node[name];
- return (typeof value == 'boolean' || typeof value == 'function') ? value : (d.hasAttr(node, name) ? node.getAttribute(name) : null);
- }
- }
- }
-
- dojo.removeAttr = function(/*DomNode|String*/node, /*String*/name){
- // summary:
- // Removes an attribute from an HTML element.
- // node:
- // id or reference to the element to remove the attribute from
- // name:
- // the name of the attribute to remove
- d.byId(node).removeAttribute(_fixAttrName(name));
- }
-})();
-
-// =============================
-// (CSS) Class Functions
-// =============================
-
-dojo.hasClass = function(/*DomNode|String*/node, /*String*/classStr){
- // summary:
- // Returns whether or not the specified classes are a portion of the
- // class list currently applied to the node.
- return ((" "+dojo.byId(node).className+" ").indexOf(" "+classStr+" ") >= 0); // Boolean
-};
-
-dojo.addClass = function(/*DomNode|String*/node, /*String*/classStr){
- // summary:
- // Adds the specified classes to the end of the class list on the
- // passed node.
- node = dojo.byId(node);
- var cls = node.className;
- if((" "+cls+" ").indexOf(" "+classStr+" ") < 0){
- node.className = cls + (cls ? ' ' : '') + classStr;
- }
-};
-
-dojo.removeClass = function(/*DomNode|String*/node, /*String*/classStr){
- // summary: Removes the specified classes from node.
- node = dojo.byId(node);
- var t = dojo.trim((" " + node.className + " ").replace(" " + classStr + " ", " "));
- if(node.className != t){ node.className = t; }
-};
-
-dojo.toggleClass = function(/*DomNode|String*/node, /*String*/classStr, /*Boolean?*/condition){
- // summary:
- // Adds a class to node if not present, or removes if present.
- // Pass a boolean condition if you want to explicitly add or remove.
- // condition:
- // If passed, true means to add the class, false means to remove.
- if(condition === undefined){
- condition = !dojo.hasClass(node, classStr);
- }
- dojo[condition ? "addClass" : "removeClass"](node, classStr);
-};
-
-}