/* Copyright (c) 2004-2010, 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 */ /* This is an optimized version of Dojo, built for deployment and not for development. To get sources and documentation, please visit: http://dojotoolkit.org */ if(!dojo._hasResource["dojo.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. dojo._hasResource["dojo.window"] = true; dojo.provide("dojo.window"); dojo.window.getBox = function(){ // summary: // Returns the dimensions and scroll position of the viewable area of a browser window var scrollRoot = (dojo.doc.compatMode == 'BackCompat') ? dojo.body() : dojo.doc.documentElement; // get scroll position var scroll = dojo._docScroll(); // scrollRoot.scrollTop/Left should work return { w: scrollRoot.clientWidth, h: scrollRoot.clientHeight, l: scroll.x, t: scroll.y }; }; dojo.window.get = function(doc){ // summary: // Get window object associated with document doc // 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 if(dojo.isIE && window !== document.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.defaultView; // Window }; dojo.window.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){ // summary: // Scroll the passed node into view, if it is not already. // don't rely on node.scrollIntoView working just because the function is there try{ // catch unexpected/unrecreatable errors (#7808) since we can recover using a semi-acceptable native method node = dojo.byId(node); var doc = node.ownerDocument || dojo.doc, body = doc.body || dojo.body(), html = doc.documentElement || body.parentNode, isIE = dojo.isIE, isWK = dojo.isWebKit; // if an untested browser, then use the native method if((!(dojo.isMoz || isIE || isWK || dojo.isOpera) || node == body || node == html) && (typeof node.scrollIntoView != "undefined")){ node.scrollIntoView(false); // short-circuit to native if possible return; } var backCompat = doc.compatMode == 'BackCompat', clientAreaRoot = backCompat? body : html, scrollRoot = isWK ? body : clientAreaRoot, rootWidth = clientAreaRoot.clientWidth, rootHeight = clientAreaRoot.clientHeight, rtl = !dojo._isBodyLtr(), nodePos = pos || dojo.position(node), el = node.parentNode, isFixed = function(el){ return ((isIE <= 6 || (isIE && backCompat))? false : (dojo.style(el, 'position').toLowerCase() == "fixed")); }; if(isFixed(node)){ return; } // nothing to do while(el){ if(el == body){ el = scrollRoot; } var elPos = dojo.position(el), fixedPos = isFixed(el); if(el == scrollRoot){ elPos.w = rootWidth; elPos.h = rootHeight; if(scrollRoot == html && isIE && rtl){ elPos.x += scrollRoot.offsetWidth-elPos.w; } // IE workaround where scrollbar causes negative x if(elPos.x < 0 || !isIE){ elPos.x = 0; } // IE can have values > 0 if(elPos.y < 0 || !isIE){ elPos.y = 0; } }else{ var pb = dojo._getPadBorderExtents(el); elPos.w -= pb.w; elPos.h -= pb.h; elPos.x += pb.l; elPos.y += pb.t; } if(el != scrollRoot){ // body, html sizes already have the scrollbar removed var clientSize = el.clientWidth, scrollBarSize = elPos.w - clientSize; if(clientSize > 0 && scrollBarSize > 0){ elPos.w = clientSize; if(isIE && rtl){ elPos.x += scrollBarSize; } } clientSize = el.clientHeight; scrollBarSize = elPos.h - clientSize; if(clientSize > 0 && scrollBarSize > 0){ elPos.h = clientSize; } } if(fixedPos){ // bounded by viewport, not parents if(elPos.y < 0){ elPos.h += elPos.y; elPos.y = 0; } if(elPos.x < 0){ elPos.w += elPos.x; elPos.x = 0; } if(elPos.y + elPos.h > rootHeight){ elPos.h = rootHeight - elPos.y; } if(elPos.x + elPos.w > rootWidth){ elPos.w = rootWidth - elPos.x; } } // calculate overflow in all 4 directions var l = nodePos.x - elPos.x, // beyond left: < 0 t = nodePos.y - Math.max(elPos.y, 0), // beyond top: < 0 r = l + nodePos.w - elPos.w, // beyond right: > 0 bot = t + nodePos.h - elPos.h; // beyond bottom: > 0 if(r * l > 0){ var s = Math[l < 0? "max" : "min"](l, r); nodePos.x += el.scrollLeft; el.scrollLeft += (isIE >= 8 && !backCompat && rtl)? -s : s; nodePos.x -= el.scrollLeft; } if(bot * t > 0){ nodePos.y += el.scrollTop; el.scrollTop += Math[t < 0? "max" : "min"](t, bot); nodePos.y -= el.scrollTop; } el = (el != scrollRoot) && !fixedPos && el.parentNode; } }catch(error){ console.error('scrollIntoView: ' + error); node.scrollIntoView(false); } }; } 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. A default instance of this class is // available as `dijit.registry` // // example: // Create a small list of widgets: // | var ws = new dijit.WidgetSet(); // | ws.add(dijit.byId("one")); // | ws.add(dijit.byId("two")); // | // destroy both: // | ws.forEach(function(w){ w.destroy(); }); // // example: // Using dijit.registry: // | dijit.registry.forEach(function(w){ /* do something */ }); constructor: function(){ this._hash = {}; this.length = 0; }, add: function(/*dijit._Widget*/ widget){ // summary: // Add a widget to this list. If a duplicate ID is detected, a error is thrown. // // widget: dijit._Widget // Any dijit._Widget subclass. 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; this.length++; }, remove: function(/*String*/ id){ // summary: // Remove a widget from this WidgetSet. Does not destroy the widget; simply // removes the reference. if(this._hash[id]){ delete this._hash[id]; this.length--; } }, forEach: function(/*Function*/ func, /* Object? */thisObj){ // summary: // Call specified function for each widget in this set. // // func: // A callback function to run for each item. Is passed the widget, the index // in the iteration, and the full hash, similar to `dojo.forEach`. // // thisObj: // An optional scope parameter // // example: // Using the default `dijit.registry` instance: // | dijit.registry.forEach(function(widget){ // | console.log(widget.declaredClass); // | }); // // returns: // Returns self, in order to allow for further chaining. thisObj = thisObj || dojo.global; var i = 0, id; for(id in this._hash){ func.call(thisObj, this._hash[id], i++, this._hash); } return this; // dijit.WidgetSet }, filter: function(/*Function*/ filter, /* Object? */thisObj){ // summary: // Filter down this WidgetSet to a smaller new WidgetSet // Works the same as `dojo.filter` and `dojo.NodeList.filter` // // filter: // Callback function to test truthiness. Is passed the widget // reference and the pseudo-index in the object. // // thisObj: Object? // Option scope to use for the filter function. // // example: // Arbitrary: select the odd widgets in this list // | dijit.registry.filter(function(w, i){ // | return i % 2 == 0; // | }).forEach(function(w){ /* odd ones */ }); thisObj = thisObj || dojo.global; var res = new dijit.WidgetSet(), i = 0, id; for(id in this._hash){ var w = this._hash[id]; if(filter.call(thisObj, w, i++, this._hash)){ res.add(w); } } return res; // dijit.WidgetSet }, byId: function(/*String*/ id){ // summary: // Find a widget in this list by it's id. // example: // Test if an id is in a particular WidgetSet // | var ws = new dijit.WidgetSet(); // | ws.add(dijit.byId("bar")); // | var t = ws.byId("bar") // returns a widget // | var x = ws.byId("foo"); // returns undefined return this._hash[id]; // dijit._Widget }, byClass: function(/*String*/ cls){ // summary: // Reduce this widgetset to a new WidgetSet of a particular `declaredClass` // // cls: String // The Class to scan for. Full dot-notated string. // // example: // Find all `dijit.TitlePane`s in a page: // | dijit.registry.byClass("dijit.TitlePane").forEach(function(tp){ tp.close(); }); var res = new dijit.WidgetSet(), id, widget; for(id in this._hash){ widget = this._hash[id]; if(widget.declaredClass == cls){ res.add(widget); } } return res; // dijit.WidgetSet }, toArray: function(){ // summary: // Convert this WidgetSet into a true Array // // example: // Work with the widget .domNodes in a real Array // | dojo.map(dijit.registry.toArray(), function(w){ return w.domNode; }); var ar = []; for(var id in this._hash){ ar.push(this._hash[id]); } return ar; // dijit._Widget[] }, map: function(/* Function */func, /* Object? */thisObj){ // summary: // Create a new Array from this WidgetSet, following the same rules as `dojo.map` // example: // | var nodes = dijit.registry.map(function(w){ return w.domNode; }); // // returns: // A new array of the returned values. return dojo.map(this.toArray(), func, thisObj); // Array }, every: function(func, thisObj){ // summary: // A synthetic clone of `dojo.every` acting explicitly on this WidgetSet // // func: Function // A callback function run for every widget in this list. Exits loop // when the first false return is encountered. // // thisObj: Object? // Optional scope parameter to use for the callback thisObj = thisObj || dojo.global; var x = 0, i; for(i in this._hash){ if(!func.call(thisObj, this._hash[i], x++, this._hash)){ return false; // Boolean } } return true; // Boolean }, some: function(func, thisObj){ // summary: // A synthetic clone of `dojo.some` acting explictly on this WidgetSet // // func: Function // A callback function run for every widget in this list. Exits loop // when the first true return is encountered. // // thisObj: Object? // Optional scope parameter to use for the callback thisObj = thisObj || dojo.global; var x = 0, i; for(i in this._hash){ if(func.call(thisObj, this._hash[i], x++, this._hash)){ return true; // Boolean } } return false; // Boolean } }); (function(){ /*===== dijit.registry = { // summary: // A list of widgets on a page. // description: // Is an instance of `dijit.WidgetSet` }; =====*/ dijit.registry = new dijit.WidgetSet(); var hash = dijit.registry._hash, attr = dojo.attr, hasAttr = dojo.hasAttr, style = dojo.style; dijit.byId = function(/*String|dijit._Widget*/ id){ // summary: // Returns a widget by it's id, or if passed a widget, no-op (like dojo.byId()) return typeof id == "string" ? hash[id] : id; // dijit._Widget }; var _widgetTypeCtr = {}; dijit.getUniqueId = function(/*String*/widgetType){ // summary: // Generates a unique id for a given widgetType var id; do{ id = widgetType + "_" + (widgetType in _widgetTypeCtr ? ++_widgetTypeCtr[widgetType] : _widgetTypeCtr[widgetType] = 0); }while(hash[id]); return dijit._scopeName == "dijit" ? id : dijit._scopeName + "_" + id; // String }; dijit.findWidgets = function(/*DomNode*/ root){ // summary: // Search subtree under root returning widgets found. // Doesn't search for nested widgets (ie, widgets inside other widgets). var outAry = []; function getChildrenHelper(root){ for(var node = root.firstChild; node; node = node.nextSibling){ if(node.nodeType == 1){ var widgetId = node.getAttribute("widgetId"); if(widgetId){ outAry.push(hash[widgetId]); }else{ getChildrenHelper(node); } } } } getChildrenHelper(root); return outAry; }; dijit._destroyAll = function(){ // summary: // Code to destroy all widgets and do other cleanup on page unload // Clean up focus manager lingering references to widgets and nodes dijit._curFocus = null; dijit._prevFocus = null; dijit._activeStack = []; // Destroy all the widgets, top down dojo.forEach(dijit.findWidgets(dojo.body()), function(widget){ // Avoid double destroy of widgets like Menu that are attached to // even though they are logically children of other widgets. if(!widget._destroyed){ if(widget.destroyRecursive){ widget.destroyRecursive(); }else if(widget.destroy){ widget.destroy(); } } }); }; if(dojo.isIE){ // Only run _destroyAll() 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.addOnWindowUnload(function(){ dijit._destroyAll(); }); } dijit.byNode = function(/*DOMNode*/ node){ // summary: // Returns the widget corresponding to the given DOMNode return hash[node.getAttribute("widgetId")]; // dijit._Widget }; dijit.getEnclosingWidget = function(/*DOMNode*/ node){ // summary: // Returns the widget whose DOM tree contains the specified DOMNode, or null if // the node is not contained within the DOM tree of any widget while(node){ var id = node.getAttribute && node.getAttribute("widgetId"); if(id){ return hash[id]; } node = node.parentNode; } return null; }; var shown = (dijit._isElementShown = function(/*Element*/ elem){ var s = style(elem); return (s.visibility != "hidden") && (s.visibility != "collapsed") && (s.display != "none") && (attr(elem, "type") != "hidden"); }); dijit.hasDefaultTabStop = function(/*Element*/ elem){ // summary: // Tests if element is tab-navigable even without an explicit tabIndex setting // No explicit tabIndex setting, need to investigate node type switch(elem.nodeName.toLowerCase()){ case "a": // An w/out a tabindex is only navigable if it has an href return hasAttr(elem, "href"); case "area": case "button": case "input": case "object": case "select": case "textarea": // These are navigable by default return true; case "iframe": // If it's an editor