diff options
author | mensonge <mensonge@b3834d28-1941-0410-a4f8-b48e95affb8f> | 2008-11-13 09:49:11 +0000 |
---|---|---|
committer | mensonge <mensonge@b3834d28-1941-0410-a4f8-b48e95affb8f> | 2008-11-13 09:49:11 +0000 |
commit | e44a7e37b6c7b5961adaffc62b9042b8d442938e (patch) | |
tree | 95b67c356e93163467db2451f2b8cce84ed5d582 /includes/js/dijit/_base | |
parent | a62b9742ee5e28bcec6872d88f50f25b820914f6 (diff) | |
download | semanticscuttle-e44a7e37b6c7b5961adaffc62b9042b8d442938e.tar.gz semanticscuttle-e44a7e37b6c7b5961adaffc62b9042b8d442938e.tar.bz2 |
New feature: basic Ajax suggestion for tags and implementation of Dojo toolkit
git-svn-id: https://semanticscuttle.svn.sourceforge.net/svnroot/semanticscuttle/trunk@151 b3834d28-1941-0410-a4f8-b48e95affb8f
Diffstat (limited to 'includes/js/dijit/_base')
-rw-r--r-- | includes/js/dijit/_base/bidi.js | 13 | ||||
-rw-r--r-- | includes/js/dijit/_base/focus.js | 342 | ||||
-rw-r--r-- | includes/js/dijit/_base/manager.js | 194 | ||||
-rw-r--r-- | includes/js/dijit/_base/place.js | 213 | ||||
-rw-r--r-- | includes/js/dijit/_base/popup.js | 269 | ||||
-rw-r--r-- | includes/js/dijit/_base/scroll.js | 29 | ||||
-rw-r--r-- | includes/js/dijit/_base/sniff.js | 45 | ||||
-rw-r--r-- | includes/js/dijit/_base/typematic.js | 139 | ||||
-rw-r--r-- | includes/js/dijit/_base/wai.js | 143 | ||||
-rw-r--r-- | includes/js/dijit/_base/window.js | 47 |
10 files changed, 1434 insertions, 0 deletions
diff --git a/includes/js/dijit/_base/bidi.js b/includes/js/dijit/_base/bidi.js new file mode 100644 index 0000000..7cd3f46 --- /dev/null +++ b/includes/js/dijit/_base/bidi.js @@ -0,0 +1,13 @@ +if(!dojo._hasResource["dijit._base.bidi"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit._base.bidi"] = true; +dojo.provide("dijit._base.bidi"); + +// summary: applies a class to the top of the document for right-to-left stylesheet rules + +dojo.addOnLoad(function(){ + if(!dojo._isBodyLtr()){ + dojo.addClass(dojo.body(), "dijitRtl"); + } +}); + +} diff --git a/includes/js/dijit/_base/focus.js b/includes/js/dijit/_base/focus.js new file mode 100644 index 0000000..46230b5 --- /dev/null +++ b/includes/js/dijit/_base/focus.js @@ -0,0 +1,342 @@ +if(!dojo._hasResource["dijit._base.focus"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit._base.focus"] = true; +dojo.provide("dijit._base.focus"); + +// summary: +// These functions are used to query or set the focus and selection. +// +// Also, they trace when widgets become actived/deactivated, +// so that the widget can fire _onFocus/_onBlur events. +// "Active" here means something similar to "focused", but +// "focus" isn't quite the right word because we keep track of +// a whole stack of "active" widgets. Example: Combobutton --> Menu --> +// MenuItem. The onBlur event for Combobutton doesn't fire due to focusing +// on the Menu or a MenuItem, since they are considered part of the +// Combobutton widget. It only happens when focus is shifted +// somewhere completely different. + +dojo.mixin(dijit, +{ + // _curFocus: DomNode + // Currently focused item on screen + _curFocus: null, + + // _prevFocus: DomNode + // Previously focused item on screen + _prevFocus: null, + + isCollapsed: function(){ + // summary: tests whether the current selection is empty + var _window = dojo.global; + var _document = dojo.doc; + if(_document.selection){ // IE + return !_document.selection.createRange().text; // Boolean + }else{ + var selection = _window.getSelection(); + if(dojo.isString(selection)){ // Safari + return !selection; // Boolean + }else{ // Mozilla/W3 + return selection.isCollapsed || !selection.toString(); // Boolean + } + } + }, + + getBookmark: function(){ + // summary: Retrieves a bookmark that can be used with moveToBookmark to return to the same range + var bookmark, selection = dojo.doc.selection; + if(selection){ // IE + var range = selection.createRange(); + if(selection.type.toUpperCase()=='CONTROL'){ + if(range.length){ + bookmark=[]; + var i=0,len=range.length; + while(i<len){ + bookmark.push(range.item(i++)); + } + }else{ + bookmark=null; + } + }else{ + bookmark = range.getBookmark(); + } + }else{ + if(window.getSelection){ + selection = dojo.global.getSelection(); + if(selection){ + range = selection.getRangeAt(0); + bookmark = range.cloneRange(); + } + }else{ + console.warn("No idea how to store the current selection for this browser!"); + } + } + return bookmark; // Array + }, + + moveToBookmark: function(/*Object*/bookmark){ + // summary: Moves current selection to a bookmark + // bookmark: This should be a returned object from dojo.html.selection.getBookmark() + var _document = dojo.doc; + if(_document.selection){ // IE + var range; + if(dojo.isArray(bookmark)){ + range = _document.body.createControlRange(); + dojo.forEach(bookmark, "range.addElement(item)"); //range.addElement does not have call/apply method, so can not call it directly + }else{ + range = _document.selection.createRange(); + range.moveToBookmark(bookmark); + } + range.select(); + }else{ //Moz/W3C + var selection = dojo.global.getSelection && dojo.global.getSelection(); + if(selection && selection.removeAllRanges){ + selection.removeAllRanges(); + selection.addRange(bookmark); + }else{ + console.warn("No idea how to restore selection for this browser!"); + } + } + }, + + getFocus: function(/*Widget?*/menu, /*Window?*/openedForWindow){ + // summary: + // Returns the current focus and selection. + // Called when a popup appears (either a top level menu or a dialog), + // or when a toolbar/menubar receives focus + // + // menu: + // The menu that's being opened + // + // openedForWindow: + // iframe in which menu was opened + // + // returns: + // A handle to restore focus/selection + + return { + // Node to return focus to + node: menu && dojo.isDescendant(dijit._curFocus, menu.domNode) ? dijit._prevFocus : dijit._curFocus, + + // Previously selected text + bookmark: + !dojo.withGlobal(openedForWindow||dojo.global, dijit.isCollapsed) ? + dojo.withGlobal(openedForWindow||dojo.global, dijit.getBookmark) : + null, + + openedForWindow: openedForWindow + }; // Object + }, + + focus: function(/*Object || DomNode */ handle){ + // summary: + // Sets the focused node and the selection according to argument. + // To set focus to an iframe's content, pass in the iframe itself. + // handle: + // object returned by get(), or a DomNode + + if(!handle){ return; } + + var node = "node" in handle ? handle.node : handle, // because handle is either DomNode or a composite object + bookmark = handle.bookmark, + openedForWindow = handle.openedForWindow; + + // Set the focus + // Note that for iframe's we need to use the <iframe> to follow the parentNode chain, + // but we need to set focus to iframe.contentWindow + if(node){ + var focusNode = (node.tagName.toLowerCase()=="iframe") ? node.contentWindow : node; + if(focusNode && focusNode.focus){ + try{ + // Gecko throws sometimes if setting focus is impossible, + // node not displayed or something like that + focusNode.focus(); + }catch(e){/*quiet*/} + } + dijit._onFocusNode(node); + } + + // set the selection + // do not need to restore if current selection is not empty + // (use keyboard to select a menu item) + if(bookmark && dojo.withGlobal(openedForWindow||dojo.global, dijit.isCollapsed)){ + if(openedForWindow){ + openedForWindow.focus(); + } + try{ + dojo.withGlobal(openedForWindow||dojo.global, dijit.moveToBookmark, null, [bookmark]); + }catch(e){ + /*squelch IE internal error, see http://trac.dojotoolkit.org/ticket/1984 */ + } + } + }, + + // _activeStack: Array + // List of currently active widgets (focused widget and it's ancestors) + _activeStack: [], + + registerWin: function(/*Window?*/targetWindow){ + // summary: + // Registers listeners on the specified window (either the main + // window or an iframe) to detect when the user has clicked somewhere. + // Anyone that creates an iframe should call this function. + + if(!targetWindow){ + targetWindow = window; + } + + dojo.connect(targetWindow.document, "onmousedown", function(evt){ + dijit._justMouseDowned = true; + setTimeout(function(){ dijit._justMouseDowned = false; }, 0); + dijit._onTouchNode(evt.target||evt.srcElement); + }); + //dojo.connect(targetWindow, "onscroll", ???); + + // Listen for blur and focus events on targetWindow's body + var body = targetWindow.document.body || targetWindow.document.getElementsByTagName("body")[0]; + if(body){ + if(dojo.isIE){ + body.attachEvent('onactivate', function(evt){ + if(evt.srcElement.tagName.toLowerCase() != "body"){ + dijit._onFocusNode(evt.srcElement); + } + }); + body.attachEvent('ondeactivate', function(evt){ dijit._onBlurNode(evt.srcElement); }); + }else{ + body.addEventListener('focus', function(evt){ dijit._onFocusNode(evt.target); }, true); + body.addEventListener('blur', function(evt){ dijit._onBlurNode(evt.target); }, true); + } + } + body = null; // prevent memory leak (apparent circular reference via closure) + }, + + _onBlurNode: function(/*DomNode*/ node){ + // summary: + // Called when focus leaves a node. + // Usually ignored, _unless_ it *isn't* follwed by touching another node, + // which indicates that we tabbed off the last field on the page, + // in which case every widget is marked inactive + dijit._prevFocus = dijit._curFocus; + dijit._curFocus = null; + + if(dijit._justMouseDowned){ + // the mouse down caused a new widget to be marked as active; this blur event + // is coming late, so ignore it. + return; + } + + // if the blur event isn't followed by a focus event then mark all widgets as inactive. + if(dijit._clearActiveWidgetsTimer){ + clearTimeout(dijit._clearActiveWidgetsTimer); + } + dijit._clearActiveWidgetsTimer = setTimeout(function(){ + delete dijit._clearActiveWidgetsTimer; + dijit._setStack([]); + dijit._prevFocus = null; + }, 100); + }, + + _onTouchNode: function(/*DomNode*/ node){ + // summary: + // Callback when node is focused or mouse-downed + + // ignore the recent blurNode event + if(dijit._clearActiveWidgetsTimer){ + clearTimeout(dijit._clearActiveWidgetsTimer); + delete dijit._clearActiveWidgetsTimer; + } + + // compute stack of active widgets (ex: ComboButton --> Menu --> MenuItem) + var newStack=[]; + try{ + while(node){ + if(node.dijitPopupParent){ + node=dijit.byId(node.dijitPopupParent).domNode; + }else if(node.tagName && node.tagName.toLowerCase()=="body"){ + // is this the root of the document or just the root of an iframe? + if(node===dojo.body()){ + // node is the root of the main document + break; + } + // otherwise, find the iframe this node refers to (can't access it via parentNode, + // need to do this trick instead). window.frameElement is supported in IE/FF/Webkit + node=dijit.getDocumentWindow(node.ownerDocument).frameElement; + }else{ + var id = node.getAttribute && node.getAttribute("widgetId"); + if(id){ + newStack.unshift(id); + } + node=node.parentNode; + } + } + }catch(e){ /* squelch */ } + + dijit._setStack(newStack); + }, + + _onFocusNode: function(/*DomNode*/ node){ + // summary + // Callback when node is focused + if(node && node.tagName && node.tagName.toLowerCase() == "body"){ + return; + } + dijit._onTouchNode(node); + + if(node==dijit._curFocus){ return; } + if(dijit._curFocus){ + dijit._prevFocus = dijit._curFocus; + } + dijit._curFocus = node; + dojo.publish("focusNode", [node]); + }, + + _setStack: function(newStack){ + // summary + // The stack of active widgets has changed. Send out appropriate events and record new stack + + var oldStack = dijit._activeStack; + dijit._activeStack = newStack; + + // compare old stack to new stack to see how many elements they have in common + for(var nCommon=0; nCommon<Math.min(oldStack.length, newStack.length); nCommon++){ + if(oldStack[nCommon] != newStack[nCommon]){ + break; + } + } + + // for all elements that have gone out of focus, send blur event + for(var i=oldStack.length-1; i>=nCommon; i--){ + var widget = dijit.byId(oldStack[i]); + if(widget){ + widget._focused = false; + widget._hasBeenBlurred = true; + if(widget._onBlur){ + widget._onBlur(); + } + if (widget._setStateClass){ + widget._setStateClass(); + } + dojo.publish("widgetBlur", [widget]); + } + } + + // for all element that have come into focus, send focus event + for(i=nCommon; i<newStack.length; i++){ + widget = dijit.byId(newStack[i]); + if(widget){ + widget._focused = true; + if(widget._onFocus){ + widget._onFocus(); + } + if (widget._setStateClass){ + widget._setStateClass(); + } + dojo.publish("widgetFocus", [widget]); + } + } + } +}); + +// register top window and all the iframes it contains +dojo.addOnLoad(dijit.registerWin); + +} diff --git a/includes/js/dijit/_base/manager.js b/includes/js/dijit/_base/manager.js new file mode 100644 index 0000000..cfb5337 --- /dev/null +++ b/includes/js/dijit/_base/manager.js @@ -0,0 +1,194 @@ +if(!dojo._hasResource["dijit._base.manager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit._base.manager"] = true; +dojo.provide("dijit._base.manager"); + +dojo.declare("dijit.WidgetSet", null, { + // summary: + // A set of widgets indexed by id + + constructor: function(){ + this._hash={}; + }, + + add: function(/*Widget*/ widget){ + if(this._hash[widget.id]){ + throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered"); + } + this._hash[widget.id]=widget; + }, + + remove: function(/*String*/ id){ + delete this._hash[id]; + }, + + forEach: function(/*Function*/ func){ + for(var id in this._hash){ + func(this._hash[id]); + } + }, + + filter: function(/*Function*/ filter){ + var res = new dijit.WidgetSet(); + this.forEach(function(widget){ + if(filter(widget)){ res.add(widget); } + }); + return res; // dijit.WidgetSet + }, + + byId: function(/*String*/ id){ + return this._hash[id]; + }, + + byClass: function(/*String*/ cls){ + return this.filter(function(widget){ return widget.declaredClass==cls; }); // dijit.WidgetSet + } + }); + +/*===== +dijit.registry = { + // summary: A list of widgets on a page. + // description: Is an instance of dijit.WidgetSet +}; +=====*/ +dijit.registry = new dijit.WidgetSet(); + +dijit._widgetTypeCtr = {}; + +dijit.getUniqueId = function(/*String*/widgetType){ + // summary + // Generates a unique id for a given widgetType + + var id; + do{ + id = widgetType + "_" + + (widgetType in dijit._widgetTypeCtr ? + ++dijit._widgetTypeCtr[widgetType] : dijit._widgetTypeCtr[widgetType] = 0); + }while(dijit.byId(id)); + return id; // String +}; + + +if(dojo.isIE){ + // Only run this for IE because we think it's only necessary in that case, + // and because it causes problems on FF. See bug #3531 for details. + dojo.addOnUnload(function(){ + dijit.registry.forEach(function(widget){ widget.destroy(); }); + }); +} + +dijit.byId = function(/*String|Widget*/id){ + // summary: + // Returns a widget by its id, or if passed a widget, no-op (like dojo.byId()) + return (dojo.isString(id)) ? dijit.registry.byId(id) : id; // Widget +}; + +dijit.byNode = function(/* DOMNode */ node){ + // summary: + // Returns the widget as referenced by node + return dijit.registry.byId(node.getAttribute("widgetId")); // Widget +}; + +dijit.getEnclosingWidget = function(/* DOMNode */ node){ + // summary: + // Returns the widget whose dom tree contains node or null if + // the node is not contained within the dom tree of any widget + while(node){ + if(node.getAttribute && node.getAttribute("widgetId")){ + return dijit.registry.byId(node.getAttribute("widgetId")); + } + node = node.parentNode; + } + return null; +}; + +// elements that are tab-navigable if they have no tabindex value set +// (except for "a", which must have an href attribute) +dijit._tabElements = { + area: true, + button: true, + input: true, + object: true, + select: true, + textarea: true +}; + +dijit._isElementShown = function(/*Element*/elem){ + var style = dojo.style(elem); + return (style.visibility != "hidden") + && (style.visibility != "collapsed") + && (style.display != "none"); +} + +dijit.isTabNavigable = function(/*Element*/elem){ + // summary: + // Tests if an element is tab-navigable + if(dojo.hasAttr(elem, "disabled")){ return false; } + var hasTabindex = dojo.hasAttr(elem, "tabindex"); + var tabindex = dojo.attr(elem, "tabindex"); + if(hasTabindex && tabindex >= 0) { + return true; // boolean + } + var name = elem.nodeName.toLowerCase(); + if(((name == "a" && dojo.hasAttr(elem, "href")) + || dijit._tabElements[name]) + && (!hasTabindex || tabindex >= 0)){ + return true; // boolean + } + return false; // boolean +}; + +dijit._getTabNavigable = function(/*DOMNode*/root){ + // summary: + // Finds the following descendants of the specified root node: + // * the first tab-navigable element in document order + // without a tabindex or with tabindex="0" + // * the last tab-navigable element in document order + // without a tabindex or with tabindex="0" + // * the first element in document order with the lowest + // positive tabindex value + // * the last element in document order with the highest + // positive tabindex value + var first, last, lowest, lowestTabindex, highest, highestTabindex; + var walkTree = function(/*DOMNode*/parent){ + dojo.query("> *", parent).forEach(function(child){ + var isShown = dijit._isElementShown(child); + if(isShown && dijit.isTabNavigable(child)){ + var tabindex = dojo.attr(child, "tabindex"); + if(!dojo.hasAttr(child, "tabindex") || tabindex == 0){ + if(!first){ first = child; } + last = child; + }else if(tabindex > 0){ + if(!lowest || tabindex < lowestTabindex){ + lowestTabindex = tabindex; + lowest = child; + } + if(!highest || tabindex >= highestTabindex){ + highestTabindex = tabindex; + highest = child; + } + } + } + if(isShown){ walkTree(child) } + }); + }; + if(dijit._isElementShown(root)){ walkTree(root) } + return { first: first, last: last, lowest: lowest, highest: highest }; +} + +dijit.getFirstInTabbingOrder = function(/*String|DOMNode*/root){ + // summary: + // Finds the descendant of the specified root node + // that is first in the tabbing order + var elems = dijit._getTabNavigable(dojo.byId(root)); + return elems.lowest ? elems.lowest : elems.first; // Element +}; + +dijit.getLastInTabbingOrder = function(/*String|DOMNode*/root){ + // summary: + // Finds the descendant of the specified root node + // that is last in the tabbing order + var elems = dijit._getTabNavigable(dojo.byId(root)); + return elems.last ? elems.last : elems.highest; // Element +}; + +} diff --git a/includes/js/dijit/_base/place.js b/includes/js/dijit/_base/place.js new file mode 100644 index 0000000..3165c11 --- /dev/null +++ b/includes/js/dijit/_base/place.js @@ -0,0 +1,213 @@ +if(!dojo._hasResource["dijit._base.place"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit._base.place"] = true; +dojo.provide("dijit._base.place"); + +// ported from dojo.html.util + +dijit.getViewport = function(){ + // summary + // Returns the dimensions and scroll position of the viewable area of a browser window + + var _window = dojo.global; + var _document = dojo.doc; + + // get viewport size + var w = 0, h = 0; + var de = _document.documentElement; + var dew = de.clientWidth, deh = de.clientHeight; + if(dojo.isMozilla){ + // mozilla + // _window.innerHeight includes the height taken by the scroll bar + // clientHeight is ideal but has DTD issues: + // #4539: FF reverses the roles of body.clientHeight/Width and documentElement.clientHeight/Width based on the DTD! + // check DTD to see whether body or documentElement returns the viewport dimensions using this algorithm: + var minw, minh, maxw, maxh; + var dbw = _document.body.clientWidth; + if(dbw > dew){ + minw = dew; + maxw = dbw; + }else{ + maxw = dew; + minw = dbw; + } + var dbh = _document.body.clientHeight; + if(dbh > deh){ + minh = deh; + maxh = dbh; + }else{ + maxh = deh; + minh = dbh; + } + w = (maxw > _window.innerWidth) ? minw : maxw; + h = (maxh > _window.innerHeight) ? minh : maxh; + }else if(!dojo.isOpera && _window.innerWidth){ + //in opera9, dojo.body().clientWidth should be used, instead + //of window.innerWidth/document.documentElement.clientWidth + //so we have to check whether it is opera + w = _window.innerWidth; + h = _window.innerHeight; + }else if(dojo.isIE && de && deh){ + w = dew; + h = deh; + }else if(dojo.body().clientWidth){ + // IE5, Opera + w = dojo.body().clientWidth; + h = dojo.body().clientHeight; + } + + // get scroll position + var scroll = dojo._docScroll(); + + return { w: w, h: h, l: scroll.x, t: scroll.y }; // object +}; + +dijit.placeOnScreen = function( + /* DomNode */ node, + /* Object */ pos, + /* Object */ corners, + /* boolean? */ tryOnly){ + // summary: + // Keeps 'node' in the visible area of the screen while trying to + // place closest to pos.x, pos.y. The input coordinates are + // expected to be the desired document position. + // + // Set which corner(s) you want to bind to, such as + // + // placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"]) + // + // The desired x/y will be treated as the topleft(TL)/topright(TR) or + // BottomLeft(BL)/BottomRight(BR) corner of the node. Each corner is tested + // and if a perfect match is found, it will be used. Otherwise, it goes through + // all of the specified corners, and choose the most appropriate one. + // + // NOTE: node is assumed to be absolutely or relatively positioned. + + var choices = dojo.map(corners, function(corner){ return { corner: corner, pos: pos }; }); + + return dijit._place(node, choices); +} + +dijit._place = function(/*DomNode*/ node, /* Array */ choices, /* Function */ layoutNode){ + // summary: + // Given a list of spots to put node, put it at the first spot where it fits, + // of if it doesn't fit anywhere then the place with the least overflow + // choices: Array + // Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} } + // Above example says to put the top-left corner of the node at (10,20) + // layoutNode: Function(node, aroundNodeCorner, nodeCorner) + // for things like tooltip, they are displayed differently (and have different dimensions) + // based on their orientation relative to the parent. This adjusts the popup based on orientation. + + // get {x: 10, y: 10, w: 100, h:100} type obj representing position of + // viewport over document + var view = dijit.getViewport(); + + // This won't work if the node is inside a <div style="position: relative">, + // so reattach it to dojo.doc.body. (Otherwise, the positioning will be wrong + // and also it might get cutoff) + if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){ + dojo.body().appendChild(node); + } + + var best = null; + dojo.some(choices, function(choice){ + var corner = choice.corner; + var pos = choice.pos; + + // configure node to be displayed in given position relative to button + // (need to do this in order to get an accurate size for the node, because + // a tooltips size changes based on position, due to triangle) + if(layoutNode){ + layoutNode(node, choice.aroundCorner, corner); + } + + // get node's size + var style = node.style; + var oldDisplay = style.display; + var oldVis = style.visibility; + style.visibility = "hidden"; + style.display = ""; + var mb = dojo.marginBox(node); + style.display = oldDisplay; + style.visibility = oldVis; + + // coordinates and size of node with specified corner placed at pos, + // and clipped by viewport + var startX = (corner.charAt(1) == 'L' ? pos.x : Math.max(view.l, pos.x - mb.w)), + startY = (corner.charAt(0) == 'T' ? pos.y : Math.max(view.t, pos.y - mb.h)), + endX = (corner.charAt(1) == 'L' ? Math.min(view.l + view.w, startX + mb.w) : pos.x), + endY = (corner.charAt(0) == 'T' ? Math.min(view.t + view.h, startY + mb.h) : pos.y), + width = endX - startX, + height = endY - startY, + overflow = (mb.w - width) + (mb.h - height); + + if(best == null || overflow < best.overflow){ + best = { + corner: corner, + aroundCorner: choice.aroundCorner, + x: startX, + y: startY, + w: width, + h: height, + overflow: overflow + }; + } + return !overflow; + }); + + node.style.left = best.x + "px"; + node.style.top = best.y + "px"; + if(best.overflow && layoutNode){ + layoutNode(node, best.aroundCorner, best.corner); + } + return best; +} + +dijit.placeOnScreenAroundElement = function( + /* DomNode */ node, + /* DomNode */ aroundNode, + /* Object */ aroundCorners, + /* Function */ layoutNode){ + + // summary + // Like placeOnScreen, except it accepts aroundNode instead of x,y + // and attempts to place node around it. Uses margin box dimensions. + // + // aroundCorners + // specify Which corner of aroundNode should be + // used to place the node => which corner(s) of node to use (see the + // corners parameter in dijit.placeOnScreen) + // e.g. {'TL': 'BL', 'BL': 'TL'} + // + // layoutNode: Function(node, aroundNodeCorner, nodeCorner) + // for things like tooltip, they are displayed differently (and have different dimensions) + // based on their orientation relative to the parent. This adjusts the popup based on orientation. + + + // get coordinates of aroundNode + aroundNode = dojo.byId(aroundNode); + var oldDisplay = aroundNode.style.display; + aroundNode.style.display=""; + // #3172: use the slightly tighter border box instead of marginBox + var aroundNodeW = aroundNode.offsetWidth; //mb.w; + var aroundNodeH = aroundNode.offsetHeight; //mb.h; + var aroundNodePos = dojo.coords(aroundNode, true); + aroundNode.style.display=oldDisplay; + + // Generate list of possible positions for node + var choices = []; + for(var nodeCorner in aroundCorners){ + choices.push( { + aroundCorner: nodeCorner, + corner: aroundCorners[nodeCorner], + pos: { + x: aroundNodePos.x + (nodeCorner.charAt(1) == 'L' ? 0 : aroundNodeW), + y: aroundNodePos.y + (nodeCorner.charAt(0) == 'T' ? 0 : aroundNodeH) + } + }); + } + + return dijit._place(node, choices, layoutNode); +} + +} diff --git a/includes/js/dijit/_base/popup.js b/includes/js/dijit/_base/popup.js new file mode 100644 index 0000000..6cb4dfc --- /dev/null +++ b/includes/js/dijit/_base/popup.js @@ -0,0 +1,269 @@ +if(!dojo._hasResource["dijit._base.popup"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit._base.popup"] = true; +dojo.provide("dijit._base.popup"); + +dojo.require("dijit._base.focus"); +dojo.require("dijit._base.place"); +dojo.require("dijit._base.window"); + +dijit.popup = new function(){ + // summary: + // This class is used to show/hide widgets as popups. + // + + var stack = [], + beginZIndex=1000, + idGen = 1; + + this.prepare = function(/*DomNode*/ node){ + // summary: + // Prepares a node to be used as a popup + // + // description: + // Attaches node to dojo.doc.body, and + // positions it off screen, but not display:none, so that + // the widget doesn't appear in the page flow and/or cause a blank + // area at the bottom of the viewport (making scrollbar longer), but + // initialization of contained widgets works correctly + + dojo.body().appendChild(node); + var s = node.style; + if(s.display == "none"){ + s.display=""; + } + s.visibility = "hidden"; // not needed for hiding, but used as flag that node is off-screen + s.position = "absolute"; + s.top = "-9999px"; + }; + + this.open = function(/*Object*/ args){ + // summary: + // Popup the widget at the specified position + // + // args: Object + // popup: Widget + // widget to display, + // parent: Widget + // the button etc. that is displaying this popup + // around: DomNode + // DOM node (typically a button); place popup relative to this node + // orient: Object + // structure specifying possible positions of popup relative to "around" node + // onCancel: Function + // callback when user has canceled the popup by + // 1. hitting ESC or + // 2. by using the popup widget's proprietary cancel mechanism (like a cancel button in a dialog); + // ie: whenever popupWidget.onCancel() is called, args.onCancel is called + // onClose: Function + // callback whenever this popup is closed + // onExecute: Function + // callback when user "executed" on the popup/sub-popup by selecting a menu choice, etc. (top menu only) + // + // examples: + // 1. opening at the mouse position + // dijit.popup.open({popup: menuWidget, x: evt.pageX, y: evt.pageY}); + // 2. opening the widget as a dropdown + // dijit.popup.open({parent: this, popup: menuWidget, around: this.domNode, onClose: function(){...} }); + // + // Note that whatever widget called dijit.popup.open() should also listen to it's own _onBlur callback + // (fired from _base/focus.js) to know that focus has moved somewhere else and thus the popup should be closed. + + var widget = args.popup, + orient = args.orient || {'BL':'TL', 'TL':'BL'}, + around = args.around, + id = (args.around && args.around.id) ? (args.around.id+"_dropdown") : ("popup_"+idGen++); + + // make wrapper div to hold widget and possibly hold iframe behind it. + // we can't attach the iframe as a child of the widget.domNode because + // widget.domNode might be a <table>, <ul>, etc. + var wrapper = dojo.doc.createElement("div"); + dijit.setWaiRole(wrapper, "presentation"); + wrapper.id = id; + wrapper.className="dijitPopup"; + wrapper.style.zIndex = beginZIndex + stack.length; + wrapper.style.visibility = "hidden"; + if(args.parent){ + wrapper.dijitPopupParent=args.parent.id; + } + dojo.body().appendChild(wrapper); + + var s = widget.domNode.style; + s.display = ""; + s.visibility = ""; + s.position = ""; + wrapper.appendChild(widget.domNode); + + var iframe = new dijit.BackgroundIframe(wrapper); + + // position the wrapper node + var best = around ? + dijit.placeOnScreenAroundElement(wrapper, around, orient, widget.orient ? dojo.hitch(widget, "orient") : null) : + dijit.placeOnScreen(wrapper, args, orient == 'R' ? ['TR','BR','TL','BL'] : ['TL','BL','TR','BR']); + + wrapper.style.visibility = "visible"; + // TODO: use effects to fade in wrapper + + var handlers = []; + + // Compute the closest ancestor popup that's *not* a child of another popup. + // Ex: For a TooltipDialog with a button that spawns a tree of menus, find the popup of the button. + var getTopPopup = function(){ + for(var pi=stack.length-1; pi > 0 && stack[pi].parent === stack[pi-1].widget; pi--){ + /* do nothing, just trying to get right value for pi */ + } + return stack[pi]; + } + + // provide default escape and tab key handling + // (this will work for any widget, not just menu) + handlers.push(dojo.connect(wrapper, "onkeypress", this, function(evt){ + if(evt.keyCode == dojo.keys.ESCAPE && args.onCancel){ + dojo.stopEvent(evt); + args.onCancel(); + }else if(evt.keyCode == dojo.keys.TAB){ + dojo.stopEvent(evt); + var topPopup = getTopPopup(); + if(topPopup && topPopup.onCancel){ + topPopup.onCancel(); + } + } + })); + + // watch for cancel/execute events on the popup and notify the caller + // (for a menu, "execute" means clicking an item) + if(widget.onCancel){ + handlers.push(dojo.connect(widget, "onCancel", null, args.onCancel)); + } + + handlers.push(dojo.connect(widget, widget.onExecute ? "onExecute" : "onChange", null, function(){ + var topPopup = getTopPopup(); + if(topPopup && topPopup.onExecute){ + topPopup.onExecute(); + } + })); + + stack.push({ + wrapper: wrapper, + iframe: iframe, + widget: widget, + parent: args.parent, + onExecute: args.onExecute, + onCancel: args.onCancel, + onClose: args.onClose, + handlers: handlers + }); + + if(widget.onOpen){ + widget.onOpen(best); + } + + return best; + }; + + this.close = function(/*Widget*/ popup){ + // summary: + // Close specified popup and any popups that it parented + while(dojo.some(stack, function(elem){return elem.widget == popup;})){ + var top = stack.pop(), + wrapper = top.wrapper, + iframe = top.iframe, + widget = top.widget, + onClose = top.onClose; + + if(widget.onClose){ + widget.onClose(); + } + dojo.forEach(top.handlers, dojo.disconnect); + + // #2685: check if the widget still has a domNode so ContentPane can change its URL without getting an error + if(!widget||!widget.domNode){ return; } + + this.prepare(widget.domNode); + + iframe.destroy(); + dojo._destroyElement(wrapper); + + if(onClose){ + onClose(); + } + } + }; +}(); + +dijit._frames = new function(){ + // summary: cache of iframes + var queue = []; + + this.pop = function(){ + var iframe; + if(queue.length){ + iframe = queue.pop(); + iframe.style.display=""; + }else{ + if(dojo.isIE){ + var html="<iframe src='javascript:\"\"'" + + " style='position: absolute; left: 0px; top: 0px;" + + "z-index: -1; filter:Alpha(Opacity=\"0\");'>"; + iframe = dojo.doc.createElement(html); + }else{ + iframe = dojo.doc.createElement("iframe"); + iframe.src = 'javascript:""'; + iframe.className = "dijitBackgroundIframe"; + } + iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didnt work. + dojo.body().appendChild(iframe); + } + return iframe; + }; + + this.push = function(iframe){ + iframe.style.display=""; + if(dojo.isIE){ + iframe.style.removeExpression("width"); + iframe.style.removeExpression("height"); + } + queue.push(iframe); + } +}(); + +// fill the queue +if(dojo.isIE && dojo.isIE < 7){ + dojo.addOnLoad(function(){ + var f = dijit._frames; + dojo.forEach([f.pop()], f.push); + }); +} + + +dijit.BackgroundIframe = function(/* DomNode */node){ + // summary: + // For IE z-index schenanigans. id attribute is required. + // + // description: + // new dijit.BackgroundIframe(node) + // Makes a background iframe as a child of node, that fills + // area (and position) of node + + if(!node.id){ throw new Error("no id"); } + if((dojo.isIE && dojo.isIE < 7) || (dojo.isFF && dojo.isFF < 3 && dojo.hasClass(dojo.body(), "dijit_a11y"))){ + var iframe = dijit._frames.pop(); + node.appendChild(iframe); + if(dojo.isIE){ + iframe.style.setExpression("width", dojo._scopeName + ".doc.getElementById('" + node.id + "').offsetWidth"); + iframe.style.setExpression("height", dojo._scopeName + ".doc.getElementById('" + node.id + "').offsetHeight"); + } + this.iframe = iframe; + } +}; + +dojo.extend(dijit.BackgroundIframe, { + destroy: function(){ + // summary: destroy the iframe + if(this.iframe){ + dijit._frames.push(this.iframe); + delete this.iframe; + } + } +}); + +} diff --git a/includes/js/dijit/_base/scroll.js b/includes/js/dijit/_base/scroll.js new file mode 100644 index 0000000..2aeac5a --- /dev/null +++ b/includes/js/dijit/_base/scroll.js @@ -0,0 +1,29 @@ +if(!dojo._hasResource["dijit._base.scroll"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit._base.scroll"] = true; +dojo.provide("dijit._base.scroll"); + +dijit.scrollIntoView = function(/* DomNode */node){ + // summary + // Scroll the passed node into view, if it is not. + + // don't rely on that node.scrollIntoView works just because the function is there + // it doesnt work in Konqueror or Opera even though the function is there and probably + // not safari either + // native scrollIntoView() causes FF3's whole window to scroll if there is no scroll bar + // on the immediate parent + // dont like browser sniffs implementations but sometimes you have to use it + // #6146: IE scrollIntoView is broken + // It's not enough just to scroll the menu node into view if + // node.scrollIntoView hides part of the parent's scrollbar, + // so just manage the parent scrollbar ourselves + var parent = node.parentNode; + var parentBottom = parent.scrollTop + dojo.marginBox(parent).h; //PORT was getBorderBox + var nodeBottom = node.offsetTop + dojo.marginBox(node).h; + if(parentBottom < nodeBottom){ + parent.scrollTop += (nodeBottom - parentBottom); + }else if(parent.scrollTop > node.offsetTop){ + parent.scrollTop -= (parent.scrollTop - node.offsetTop); + } +}; + +} diff --git a/includes/js/dijit/_base/sniff.js b/includes/js/dijit/_base/sniff.js new file mode 100644 index 0000000..30835cc --- /dev/null +++ b/includes/js/dijit/_base/sniff.js @@ -0,0 +1,45 @@ +if(!dojo._hasResource["dijit._base.sniff"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit._base.sniff"] = true; +dojo.provide("dijit._base.sniff"); + +// ported from dojo.html.applyBrowserClass (style.js) + +// summary: +// Applies pre-set class names based on browser & version to the +// top-level HTML node. Simply doing a require on this module will +// establish this CSS. Modified version of Morris' CSS hack. +(function(){ + var d = dojo; + var ie = d.isIE; + var opera = d.isOpera; + var maj = Math.floor; + var ff = d.isFF; + var classes = { + dj_ie: ie, +// dj_ie55: ie == 5.5, + dj_ie6: maj(ie) == 6, + dj_ie7: maj(ie) == 7, + dj_iequirks: ie && d.isQuirks, +// NOTE: Opera not supported by dijit + dj_opera: opera, + dj_opera8: maj(opera) == 8, + dj_opera9: maj(opera) == 9, + dj_khtml: d.isKhtml, + dj_safari: d.isSafari, + dj_gecko: d.isMozilla, + dj_ff2: maj(ff) == 2 + }; // no dojo unsupported browsers + + for(var p in classes){ + if(classes[p]){ + var html = dojo.doc.documentElement; //TODO browser-specific DOM magic needed? + if(html.className){ + html.className += " " + p; + }else{ + html.className = p; + } + } + } +})(); + +} diff --git a/includes/js/dijit/_base/typematic.js b/includes/js/dijit/_base/typematic.js new file mode 100644 index 0000000..9500839 --- /dev/null +++ b/includes/js/dijit/_base/typematic.js @@ -0,0 +1,139 @@ +if(!dojo._hasResource["dijit._base.typematic"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit._base.typematic"] = true; +dojo.provide("dijit._base.typematic"); + +dijit.typematic = { + // summary: + // These functions are used to repetitively call a user specified callback + // method when a specific key or mouse click over a specific DOM node is + // held down for a specific amount of time. + // Only 1 such event is allowed to occur on the browser page at 1 time. + + _fireEventAndReload: function(){ + this._timer = null; + this._callback(++this._count, this._node, this._evt); + this._currentTimeout = (this._currentTimeout < 0) ? this._initialDelay : ((this._subsequentDelay > 1) ? this._subsequentDelay : Math.round(this._currentTimeout * this._subsequentDelay)); + this._timer = setTimeout(dojo.hitch(this, "_fireEventAndReload"), this._currentTimeout); + }, + + trigger: function(/*Event*/ evt, /* Object */ _this, /*DOMNode*/ node, /* Function */ callback, /* Object */ obj, /* Number */ subsequentDelay, /* Number */ initialDelay){ + // summary: + // Start a timed, repeating callback sequence. + // If already started, the function call is ignored. + // This method is not normally called by the user but can be + // when the normal listener code is insufficient. + // Parameters: + // evt: key or mouse event object to pass to the user callback + // _this: pointer to the user's widget space. + // node: the DOM node object to pass the the callback function + // callback: function to call until the sequence is stopped called with 3 parameters: + // count: integer representing number of repeated calls (0..n) with -1 indicating the iteration has stopped + // node: the DOM node object passed in + // evt: key or mouse event object + // obj: user space object used to uniquely identify each typematic sequence + // subsequentDelay: if > 1, the number of milliseconds until the 3->n events occur + // or else the fractional time multiplier for the next event's delay, default=0.9 + // initialDelay: the number of milliseconds until the 2nd event occurs, default=500ms + if(obj != this._obj){ + this.stop(); + this._initialDelay = initialDelay || 500; + this._subsequentDelay = subsequentDelay || 0.90; + this._obj = obj; + this._evt = evt; + this._node = node; + this._currentTimeout = -1; + this._count = -1; + this._callback = dojo.hitch(_this, callback); + this._fireEventAndReload(); + } + }, + + stop: function(){ + // summary: + // Stop an ongoing timed, repeating callback sequence. + if(this._timer){ + clearTimeout(this._timer); + this._timer = null; + } + if(this._obj){ + this._callback(-1, this._node, this._evt); + this._obj = null; + } + }, + + addKeyListener: function(/*DOMNode*/ node, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){ + // summary: Start listening for a specific typematic key. + // keyObject: an object defining the key to listen for. + // key: (mandatory) the keyCode (number) or character (string) to listen for. + // ctrlKey: desired ctrl key state to initiate the calback sequence: + // pressed (true) + // released (false) + // either (unspecified) + // altKey: same as ctrlKey but for the alt key + // shiftKey: same as ctrlKey but for the shift key + // See the trigger method for other parameters. + // Returns an array of dojo.connect handles + return [ + dojo.connect(node, "onkeypress", this, function(evt){ + if(evt.keyCode == keyObject.keyCode && (!keyObject.charCode || keyObject.charCode == evt.charCode) && + (keyObject.ctrlKey === undefined || keyObject.ctrlKey == evt.ctrlKey) && + (keyObject.altKey === undefined || keyObject.altKey == evt.ctrlKey) && + (keyObject.shiftKey === undefined || keyObject.shiftKey == evt.ctrlKey)){ + dojo.stopEvent(evt); + dijit.typematic.trigger(keyObject, _this, node, callback, keyObject, subsequentDelay, initialDelay); + }else if(dijit.typematic._obj == keyObject){ + dijit.typematic.stop(); + } + }), + dojo.connect(node, "onkeyup", this, function(evt){ + if(dijit.typematic._obj == keyObject){ + dijit.typematic.stop(); + } + }) + ]; + }, + + addMouseListener: function(/*DOMNode*/ node, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){ + // summary: Start listening for a typematic mouse click. + // See the trigger method for other parameters. + // Returns an array of dojo.connect handles + var dc = dojo.connect; + return [ + dc(node, "mousedown", this, function(evt){ + dojo.stopEvent(evt); + dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay); + }), + dc(node, "mouseup", this, function(evt){ + dojo.stopEvent(evt); + dijit.typematic.stop(); + }), + dc(node, "mouseout", this, function(evt){ + dojo.stopEvent(evt); + dijit.typematic.stop(); + }), + dc(node, "mousemove", this, function(evt){ + dojo.stopEvent(evt); + }), + dc(node, "dblclick", this, function(evt){ + dojo.stopEvent(evt); + if(dojo.isIE){ + dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay); + setTimeout(dojo.hitch(this, dijit.typematic.stop), 50); + } + }) + ]; + }, + + addListener: function(/*Node*/ mouseNode, /*Node*/ keyNode, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){ + // summary: Start listening for a specific typematic key and mouseclick. + // This is a thin wrapper to addKeyListener and addMouseListener. + // mouseNode: the DOM node object to listen on for mouse events. + // keyNode: the DOM node object to listen on for key events. + // See the addMouseListener and addKeyListener methods for other parameters. + // Returns an array of dojo.connect handles + return this.addKeyListener(keyNode, keyObject, _this, callback, subsequentDelay, initialDelay).concat( + this.addMouseListener(mouseNode, _this, callback, subsequentDelay, initialDelay)); + } +}; + +} diff --git a/includes/js/dijit/_base/wai.js b/includes/js/dijit/_base/wai.js new file mode 100644 index 0000000..a9d47a2 --- /dev/null +++ b/includes/js/dijit/_base/wai.js @@ -0,0 +1,143 @@ +if(!dojo._hasResource["dijit._base.wai"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit._base.wai"] = true; +dojo.provide("dijit._base.wai"); + +dijit.wai = { + onload: function(){ + // summary: + // Detects if we are in high-contrast mode or not + + // This must be a named function and not an anonymous + // function, so that the widget parsing code can make sure it + // registers its onload function after this function. + // DO NOT USE "this" within this function. + + // create div for testing if high contrast mode is on or images are turned off + var div = dojo.doc.createElement("div"); + div.id = "a11yTestNode"; + div.style.cssText = 'border: 1px solid;' + + 'border-color:red green;' + + 'position: absolute;' + + 'height: 5px;' + + 'top: -999px;' + + 'background-image: url("' + dojo.moduleUrl("dojo", "resources/blank.gif") + '");'; + dojo.body().appendChild(div); + + // test it + var cs = dojo.getComputedStyle(div); + if(cs){ + var bkImg = cs.backgroundImage; + var needsA11y = (cs.borderTopColor==cs.borderRightColor) || (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" )); + dojo[needsA11y ? "addClass" : "removeClass"](dojo.body(), "dijit_a11y"); + dojo.body().removeChild(div); + } + } +}; + +// Test if computer is in high contrast mode. +// Make sure the a11y test runs first, before widgets are instantiated. +if(dojo.isIE || dojo.isMoz){ // NOTE: checking in Safari messes things up + dojo._loaders.unshift(dijit.wai.onload); +} + +dojo.mixin(dijit, +{ + hasWaiRole: function(/*Element*/ elem){ + // summary: Determines if an element has a role. + // returns: true if elem has a role attribute and false if not. + return elem.hasAttribute ? elem.hasAttribute("role") : !!elem.getAttribute("role"); + }, + + getWaiRole: function(/*Element*/ elem){ + // summary: Gets the role for an element. + // returns: + // The role of elem or an empty string if elem + // does not have a role. + var value = elem.getAttribute("role"); + if(value){ + var prefixEnd = value.indexOf(":"); + return prefixEnd == -1 ? value : value.substring(prefixEnd+1); + }else{ + return ""; + } + }, + + setWaiRole: function(/*Element*/ elem, /*String*/ role){ + // summary: Sets the role on an element. + // description: + // On Firefox 2 and below, "wairole:" is + // prepended to the provided role value. + elem.setAttribute("role", (dojo.isFF && dojo.isFF < 3) ? "wairole:" + role : role); + }, + + removeWaiRole: function(/*Element*/ elem){ + // summary: Removes the role from an element. + elem.removeAttribute("role"); + }, + + hasWaiState: function(/*Element*/ elem, /*String*/ state){ + // summary: Determines if an element has a given state. + // description: + // On Firefox 2 and below, we check for an attribute in namespace + // "http://www.w3.org/2005/07/aaa" with a name of the given state. + // On all other browsers, we check for an attribute + // called "aria-"+state. + // returns: + // true if elem has a value for the given state and + // false if it does not. + if(dojo.isFF && dojo.isFF < 3){ + return elem.hasAttributeNS("http://www.w3.org/2005/07/aaa", state); + }else{ + return elem.hasAttribute ? elem.hasAttribute("aria-"+state) : !!elem.getAttribute("aria-"+state); + } + }, + + getWaiState: function(/*Element*/ elem, /*String*/ state){ + // summary: Gets the value of a state on an element. + // description: + // On Firefox 2 and below, we check for an attribute in namespace + // "http://www.w3.org/2005/07/aaa" with a name of the given state. + // On all other browsers, we check for an attribute called + // "aria-"+state. + // returns: + // The value of the requested state on elem + // or an empty string if elem has no value for state. + if(dojo.isFF && dojo.isFF < 3){ + return elem.getAttributeNS("http://www.w3.org/2005/07/aaa", state); + }else{ + var value = elem.getAttribute("aria-"+state); + return value ? value : ""; + } + }, + + setWaiState: function(/*Element*/ elem, /*String*/ state, /*String*/ value){ + // summary: Sets a state on an element. + // description: + // On Firefox 2 and below, we set an attribute in namespace + // "http://www.w3.org/2005/07/aaa" with a name of the given state. + // On all other browsers, we set an attribute called + // "aria-"+state. + if(dojo.isFF && dojo.isFF < 3){ + elem.setAttributeNS("http://www.w3.org/2005/07/aaa", + "aaa:"+state, value); + }else{ + elem.setAttribute("aria-"+state, value); + } + }, + + removeWaiState: function(/*Element*/ elem, /*String*/ state){ + // summary: Removes a state from an element. + // description: + // On Firefox 2 and below, we remove the attribute in namespace + // "http://www.w3.org/2005/07/aaa" with a name of the given state. + // On all other browsers, we remove the attribute called + // "aria-"+state. + if(dojo.isFF && dojo.isFF < 3){ + elem.removeAttributeNS("http://www.w3.org/2005/07/aaa", state); + }else{ + elem.removeAttribute("aria-"+state); + } + } +}); + +} diff --git a/includes/js/dijit/_base/window.js b/includes/js/dijit/_base/window.js new file mode 100644 index 0000000..c1bbb54 --- /dev/null +++ b/includes/js/dijit/_base/window.js @@ -0,0 +1,47 @@ +if(!dojo._hasResource["dijit._base.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit._base.window"] = true; +dojo.provide("dijit._base.window"); + +dijit.getDocumentWindow = function(doc){ + // summary + // Get window object associated with document doc + + // With Safari, there is not way to retrieve the window from the document, so we must fix it. + if(dojo.isSafari && !doc._parentWindow){ + /* + This is a Safari specific function that fix the reference to the parent + window from the document object. + TODO: #5711: should the use of document below reference dojo.doc instead + in case they're not the same? + */ + var fix=function(win){ + win.document._parentWindow=win; + for(var i=0; i<win.frames.length; i++){ + fix(win.frames[i]); + } + } + fix(window.top); + } + + //In some IE versions (at least 6.0), document.parentWindow does not return a + //reference to the real window object (maybe a copy), so we must fix it as well + //We use IE specific execScript to attach the real window reference to + //document._parentWindow for later use + //TODO: #5711: should the use of document below reference dojo.doc instead in case they're not the same? + if(dojo.isIE && window !== document.parentWindow && !doc._parentWindow){ + /* + In IE 6, only the variable "window" can be used to connect events (others + may be only copies). + */ + doc.parentWindow.execScript("document._parentWindow = window;", "Javascript"); + //to prevent memory leak, unset it after use + //another possibility is to add an onUnload handler which seems overkill to me (liucougar) + var win = doc._parentWindow; + doc._parentWindow = null; + return win; // Window + } + + return doc._parentWindow || doc.parentWindow || doc.defaultView; // Window +} + +} |