diff options
author | Andrew Dolgov <[email protected]> | 2011-11-08 20:40:44 +0400 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2011-11-08 20:40:44 +0400 |
commit | 81bea17aefb26859f825b9293c7c99192874806e (patch) | |
tree | fb244408ca271affa2899adb634788802c9a89d8 /lib/dojo/_base/html.js | |
parent | 870a70e109ac9e80a88047044530de53d0404ec7 (diff) |
upgrade Dojo to 1.6.1
Diffstat (limited to 'lib/dojo/_base/html.js')
-rw-r--r-- | lib/dojo/_base/html.js | 266 |
1 files changed, 134 insertions, 132 deletions
diff --git a/lib/dojo/_base/html.js b/lib/dojo/_base/html.js index be5fd2aaa..8661b2b12 100644 --- a/lib/dojo/_base/html.js +++ b/lib/dojo/_base/html.js @@ -1,5 +1,5 @@ /* - Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved. + Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved. Available via Academic Free License >= 2.1 OR the modified BSD license. see: http://dojotoolkit.org/license for details */ @@ -7,8 +7,9 @@ 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"); +dojo.require("dojo._base.lang"); + // FIXME: need to add unit tests for all the semi-public methods @@ -53,13 +54,13 @@ dojo.byId = function(id, doc){ // | } =====*/ -if(dojo.isIE || dojo.isOpera){ +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 + // 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; @@ -80,8 +81,9 @@ if(dojo.isIE || dojo.isOpera){ }; }else{ dojo.byId = function(id, doc){ - // inline'd type check - return (typeof id == "string") ? (doc || dojo.doc).getElementById(id) : id; // DomNode + // 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 }; } /*===== @@ -164,16 +166,16 @@ if(dojo.isIE || dojo.isOpera){ }; dojo.setSelectable = function(/*DomNode|String*/node, /*Boolean*/selectable){ - // summary: + // 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 + // state to put the node in. false indicates unselectable, true // allows selection. // example: // Make the node id="bar" unselectable - // | dojo.setSelectable("bar"); + // | dojo.setSelectable("bar"); // example: // Make the node id="bar" selectable // | dojo.setSelectable("bar", true); @@ -256,7 +258,7 @@ if(dojo.isIE || dojo.isOpera){ refNode = byId(refNode); if(typeof node == "string"){ // inline'd type check - node = node.charAt(0) == "<" ? d._toDom(node, refNode.ownerDocument) : byId(node); + node = /^\s*</.test(node) ? d._toDom(node, refNode.ownerDocument) : byId(node); } if(typeof position == "number"){ // inline'd type check var cn = refNode.childNodes; @@ -291,7 +293,7 @@ if(dojo.isIE || dojo.isOpera){ } } 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. @@ -303,7 +305,7 @@ if(dojo.isIE || dojo.isOpera){ dojo.boxModel = "content-box"; // We punt per-node box mode testing completely. - // If anybody cares, we can provide an additional (optional) unit + // 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. @@ -323,10 +325,10 @@ if(dojo.isIE || dojo.isOpera){ // getComputedStyle drives most of the style code. // Wherever possible, reuse the returned object. // - // API functions below that need to access computed styles accept an + // 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 + // This way, calling code can access computedStyle once, and then pass the reference to // multiple API functions. /*===== @@ -365,7 +367,7 @@ if(dojo.isIE || dojo.isOpera){ // 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 + // it is frequently sent to this function even // though it is not Element. var gcs; if(d.isWebKit){ @@ -426,7 +428,7 @@ if(dojo.isIE || dojo.isOpera){ runtimeStyle.left = rsLeft; } return avalue; - } + }; } var px = d._toPixelValue; @@ -454,7 +456,7 @@ if(dojo.isIE || dojo.isOpera){ }; dojo._getOpacity = - d.isIE ? function(node){ + d.isIE < 9 ? function(node){ try{ return af(node).Opacity / 100; // Number }catch(e){ @@ -481,7 +483,7 @@ if(dojo.isIE || dojo.isOpera){ =====*/ dojo._setOpacity = - d.isIE ? function(/*DomNode*/node, /*Number*/opacity){ + d.isIE < 9 ? function(/*DomNode*/node, /*Number*/opacity){ var ov = opacity * 100, opaque = opacity == 1; node.style.zoom = opaque ? "" : 1; @@ -553,7 +555,7 @@ if(dojo.isIE || dojo.isOpera){ // 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()`, + // 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 @@ -622,7 +624,7 @@ if(dojo.isIE || dojo.isOpera){ return s; } return (args == 1) ? s : _toStyleValue(n, style, s[style] || n.style[style]); /* CSS2Properties||String||Number */ - } + }; // ============================= // Box Functions @@ -635,13 +637,13 @@ if(dojo.isIE || dojo.isOpera){ // 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 + // | 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 + var s = computedStyle||gcs(n), l = px(n, s.paddingLeft), t = px(n, s.paddingTop); @@ -651,7 +653,7 @@ if(dojo.isIE || dojo.isOpera){ w: l+px(n, s.paddingRight), h: t+px(n, s.paddingBottom) }; - } + }; dojo._getBorderExtents = function(/*DomNode*/n, /*Object*/computedStyle){ // summary: @@ -665,7 +667,7 @@ if(dojo.isIE || dojo.isOpera){ // 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 + var ne = "none", s = computedStyle||gcs(n), bl = (s.borderLeftStyle != ne ? px(n, s.borderLeftWidth) : 0), @@ -676,7 +678,7 @@ if(dojo.isIE || dojo.isOpera){ 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: @@ -690,7 +692,7 @@ if(dojo.isIE || dojo.isOpera){ // 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 + var s = computedStyle||gcs(n), p = d._getPadExtents(n, s), b = d._getBorderExtents(n, s); @@ -700,7 +702,7 @@ if(dojo.isIE || dojo.isOpera){ w: p.w + b.w, h: p.h + b.h }; - } + }; dojo._getMarginExtents = function(n, computedStyle){ // summary: @@ -714,7 +716,7 @@ if(dojo.isIE || dojo.isOpera){ // 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 + var s = computedStyle||gcs(n), l = px(n, s.marginLeft), t = px(n, s.marginTop), @@ -722,9 +724,9 @@ if(dojo.isIE || dojo.isOpera){ 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 + // 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 + // 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; @@ -735,7 +737,7 @@ if(dojo.isIE || dojo.isOpera){ w: l+r, h: t+b }; - } + }; // Box getters work in any box context because offsetWidth/clientWidth // are invariant wrt box context @@ -743,10 +745,10 @@ if(dojo.isIE || dojo.isOpera){ // 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 + // 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 + // 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) @@ -790,9 +792,23 @@ if(dojo.isIE || dojo.isOpera){ l: l, t: t, w: node.offsetWidth + me.w, - h: node.offsetHeight + me.h + 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: @@ -821,7 +837,7 @@ if(dojo.isIE || dojo.isOpera){ w: w - pe.w - be.w, h: h - pe.h - be.h }; - } + }; dojo._getBorderBox = function(node, computedStyle){ var s = computedStyle || gcs(node), @@ -834,7 +850,7 @@ if(dojo.isIE || dojo.isOpera){ 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. @@ -845,12 +861,12 @@ if(dojo.isIE || dojo.isOpera){ // 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 + // 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 + // 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){ @@ -876,14 +892,14 @@ if(dojo.isIE || dojo.isOpera){ 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: @@ -898,7 +914,7 @@ if(dojo.isIE || dojo.isOpera){ 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: @@ -910,7 +926,7 @@ if(dojo.isIE || dojo.isOpera){ 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, @@ -942,7 +958,7 @@ if(dojo.isIE || dojo.isOpera){ 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 }; @@ -977,7 +993,7 @@ if(dojo.isIE || dojo.isOpera){ 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: @@ -1002,14 +1018,14 @@ if(dojo.isIE || dojo.isOpera){ // 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 + // Positioning // ============================= var _sumAncestorProperties = function(node, prop){ - if(!(node = (node||0).parentNode)){return 0} + if(!(node = (node||0).parentNode)){return 0;} var val, retVal = 0, _b = d.body(); while(node && node.style){ if(gcs(node).position == "fixed"){ @@ -1025,19 +1041,19 @@ if(dojo.isIE || dojo.isOpera){ 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.doc.documentElement, n.clientHeight? { x:d._fixIeBiDiScrollLeft(n.scrollLeft), y:n.scrollTop } : - (n=d.body(), { x:n.scrollLeft||0, y:n.scrollTop||0 })); + 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 - } + d._bodyLtr = (d.body().dir || d.doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean + }; dojo._getIeDocumentElementOffset = function(){ // summary: @@ -1058,7 +1074,7 @@ if(dojo.isIE || dojo.isOpera){ //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 + 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+ @@ -1083,18 +1099,22 @@ if(dojo.isIE || dojo.isOpera){ }; dojo._fixIeBiDiScrollLeft = function(/*Integer*/ scrollLeft){ - // In RTL direction, scrollLeft should be a negative value, but IE < 8 + // 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 < 8 && !d._isBodyLtr()){ - var de = d.isQuirks ? dd.body : dd.documentElement; - return scrollLeft + de.clientWidth - de.scrollWidth; // Integer + var ie = d.isIE; + if(ie && !d._isBodyLtr()){ + var qk = d.isQuirks, + de = qk ? d.doc.body : d.doc.documentElement; + if(ie == 6 && !qk && d.global.frameElement && de.scrollHeight > de.clientHeight){ + scrollLeft += de.clientLeft; // workaround ie6+strict+rtl+iframe+vertical-scrollbar bug where clientWidth is too small by clientLeft pixels + } + return (ie < 8 || qk) ? (scrollLeft + de.clientWidth - de.scrollWidth) : -scrollLeft; // Integer } return scrollLeft; // Integer - } + }; // FIXME: need a setter for coords or a moveTo!! dojo._abs = dojo.position = function(/*DomNode*/node, /*Boolean?*/includeScroll){ @@ -1112,10 +1132,9 @@ if(dojo.isIE || dojo.isOpera){ // Uses the border-box model (inclusive of border and padding but // not margin). Does not act as a setter. - var db = d.body(), dh = db.parentNode, ret; node = byId(node); - if(node["getBoundingClientRect"]){ - // IE6+, FF3+, super-modern WebKit, and Opera 9.6+ all take this branch + var db = d.body(), + dh = db.parentNode, ret = node.getBoundingClientRect(); ret = { x: ret.left, y: ret.top, w: ret.right - ret.left, h: ret.bottom - ret.top }; if(d.isIE){ @@ -1132,60 +1151,7 @@ if(dojo.isIE || dojo.isOpera){ ret.x -= px(dh, cs.marginLeft) + px(dh, cs.borderLeftWidth); ret.y -= px(dh, cs.marginTop) + px(dh, cs.borderTopWidth); } - }else{ - // FF2 and older WebKit - ret = { - x: 0, - y: 0, - w: node.offsetWidth, - h: node.offsetHeight - }; - if(node["offsetParent"]){ - ret.x -= _sumAncestorProperties(node, "scrollLeft"); - ret.y -= _sumAncestorProperties(node, "scrollTop"); - - var curnode = node; - do{ - var n = curnode.offsetLeft, - t = curnode.offsetTop; - ret.x += isNaN(n) ? 0 : n; - ret.y += isNaN(t) ? 0 : t; - - cs = gcs(curnode); - if(curnode != node){ - if(d.isMoz){ - // tried left+right with differently sized left/right borders - // it really is 2xleft border in FF, not left+right, even in RTL! - ret.x += 2 * px(curnode,cs.borderLeftWidth); - ret.y += 2 * px(curnode,cs.borderTopWidth); - }else{ - ret.x += px(curnode, cs.borderLeftWidth); - ret.y += px(curnode, cs.borderTopWidth); - } - } - // static children in a static div in FF2 are affected by the div's border as well - // but offsetParent will skip this div! - if(d.isMoz && cs.position=="static"){ - var parent=curnode.parentNode; - while(parent!=curnode.offsetParent){ - var pcs=gcs(parent); - if(pcs.position=="static"){ - ret.x += px(curnode,pcs.borderLeftWidth); - ret.y += px(curnode,pcs.borderTopWidth); - } - parent=parent.parentNode; - } - } - curnode = curnode.offsetParent; - }while((curnode != dh) && 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 + // account for document scrolling if(includeScroll){ var scroll = d._docScroll(); ret.x += scroll.x; @@ -1193,7 +1159,7 @@ if(dojo.isIE || dojo.isOpera){ } return ret; // Object - } + }; dojo.coords = function(/*DomNode|String*/node, /*Boolean?*/includeScroll){ // summary: @@ -1215,7 +1181,7 @@ if(dojo.isIE || dojo.isOpera){ mb.x = abs.x; mb.y = abs.y; return mb; - } + }; // ============================= // Element attribute Functions @@ -1277,7 +1243,7 @@ if(dojo.isIE || dojo.isOpera){ // given element, and false otherwise var lc = name.toLowerCase(); return _forcePropNames[_propNames[lc] || name] || _hasAttr(byId(node), _attrNames[lc] || name); // Boolean - } + }; var _evtHdlrMap = {}, _ctr = 0, _attrId = dojo._scopeName + "attrid", @@ -1447,7 +1413,7 @@ if(dojo.isIE || dojo.isOpera){ // node's attribute // we need _hasAttr() here to guard against IE returning a default value return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything - } + }; dojo.removeAttr = function(/*DomNode|String*/ node, /*String*/ name){ // summary: @@ -1457,7 +1423,7 @@ if(dojo.isIE || dojo.isOpera){ // name: // the name of the attribute to remove byId(node).removeAttribute(_fixAttrName(name)); - } + }; dojo.getNodeProp = function(/*DomNode|String*/ node, /*String*/ name){ // summary: @@ -1476,7 +1442,7 @@ if(dojo.isIE || dojo.isOpera){ // node's attribute var attrName = _attrNames[lc] || name; return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything - } + }; dojo.create = function(tag, attrs, refNode, pos){ // summary: @@ -1491,7 +1457,7 @@ if(dojo.isIE || dojo.isOpera){ // Attributes are set by passing the optional object through `dojo.attr`. // See `dojo.attr` for noted caveats and nuances, and API if applicable. //| - // Placement is done via `dojo.place`, assuming the new node to be the action + // Placement is done via `dojo.place`, assuming the new node to be the action // node, passing along the optional reference node and position. // // tag: String|DomNode @@ -1529,7 +1495,7 @@ if(dojo.isIE || dojo.isOpera){ // | var n = dojo.create("div", null, dojo.body()); // // example: - // Create an UL, and populate it with LI's. Place the list as the first-child of a + // Create an UL, and populate it with LI's. Place the list as the first-child of a // node with id="someId": // | var ul = dojo.create("ul", null, "someId", "first"); // | var items = ["one", "two", "three", "four"]; @@ -1559,7 +1525,7 @@ if(dojo.isIE || dojo.isOpera){ if(attrs){ d.attr(tag, attrs); } if(refNode){ d.place(tag, refNode, pos); } return tag; // DomNode - } + }; /*===== dojo.empty = function(node){ @@ -1627,11 +1593,13 @@ if(dojo.isIE || dojo.isOpera){ // generate start/end tag strings to use // for the injection for each special tag wrap case. for(var param in tagWrap){ - var tw = tagWrap[param]; - tw.pre = param == "option" ? '<select multiple="multiple">' : "<" + tw.join("><") + ">"; - tw.post = "</" + tw.reverse().join("></") + ">"; - // the last line is destructive: it reverses the array, - // but we don't care at this point + if(tagWrap.hasOwnProperty(param)){ + var tw = tagWrap[param]; + tw.pre = param == "option" ? '<select multiple="multiple">' : "<" + tw.join("><") + ">"; + tw.post = "</" + tw.reverse().join("></") + ">"; + // the last line is destructive: it reverses the array, + // but we don't care at this point + } } d._toDom = function(frag, doc){ @@ -1674,7 +1642,7 @@ if(dojo.isIE || dojo.isOpera){ df.appendChild(fc); } return df; // DOMNode - } + }; // ============================= // (CSS) Class Functions @@ -1700,6 +1668,7 @@ if(dojo.isIE || dojo.isOpera){ }; var spaces = /\s+/, a1 = [""], + fakeNode = {}, str2array = function(s){ if(typeof s == "string" || s instanceof String){ if(s.indexOf(" ") < 0){ @@ -1805,6 +1774,39 @@ if(dojo.isIE || dojo.isOpera){ if(node[_className] != cls){ node[_className] = cls; } }; + dojo.replaceClass = function(/*DomNode|String*/node, /*String|Array*/addClassStr, /*String|Array?*/removeClassStr){ + // summary: + // Replaces one or more classes on a node if not present. + // Operates more quickly than calling dojo.removeClass and dojo.addClass + // node: + // String ID or DomNode reference to remove the class from. + // addClassStr: + // A String class name to add, or several space-separated class names, + // or an array of class names. + // removeClassStr: + // A String class name to remove, or several space-separated class names, + // or an array of class names. + // + // example: + // | dojo.replaceClass("someNode", "add1 add2", "remove1 remove2"); + // + // example: + // Replace all classes with addMe + // | dojo.replaceClass("someNode", "addMe"); + // + // example: + // Available in `dojo.NodeList()` for multiple toggles + // | dojo.query(".findMe").replaceClass("addMe", "removeMe"); + + node = byId(node); + fakeNode.className = node.className; + dojo.removeClass(fakeNode, removeClassStr); + dojo.addClass(fakeNode, addClassStr); + if(node.className !== fakeNode.className){ + node.className = fakeNode.className; + } + }; + dojo.toggleClass = function(/*DomNode|String*/node, /*String|Array*/classStr, /*Boolean?*/condition){ // summary: // Adds a class to node if not present, or removes if present. |