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/dijit/_base/focus.js | |
parent | 870a70e109ac9e80a88047044530de53d0404ec7 (diff) |
upgrade Dojo to 1.6.1
Diffstat (limited to 'lib/dijit/_base/focus.js')
-rw-r--r-- | lib/dijit/_base/focus.js | 803 |
1 files changed, 517 insertions, 286 deletions
diff --git a/lib/dijit/_base/focus.js b/lib/dijit/_base/focus.js index 32be06aa7..55c5b682d 100644 --- a/lib/dijit/_base/focus.js +++ b/lib/dijit/_base/focus.js @@ -1,299 +1,530 @@ /* - 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 */ -if(!dojo._hasResource["dijit._base.focus"]){ -dojo._hasResource["dijit._base.focus"]=true; +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"); dojo.require("dojo.window"); dojo.require("dijit._base.manager"); -dojo.mixin(dijit,{_curFocus:null,_prevFocus:null,isCollapsed:function(){ -return dijit.getBookmark().isCollapsed; -},getBookmark:function(){ -var bm,rg,tg,_1=dojo.doc.selection,cf=dijit._curFocus; -if(dojo.global.getSelection){ -_1=dojo.global.getSelection(); -if(_1){ -if(_1.isCollapsed){ -tg=cf?cf.tagName:""; -if(tg){ -tg=tg.toLowerCase(); -if(tg=="textarea"||(tg=="input"&&(!cf.type||cf.type.toLowerCase()=="text"))){ -_1={start:cf.selectionStart,end:cf.selectionEnd,node:cf,pRange:true}; -return {isCollapsed:(_1.end<=_1.start),mark:_1}; -} -} -bm={isCollapsed:true}; -}else{ -rg=_1.getRangeAt(0); -bm={isCollapsed:false,mark:rg.cloneRange()}; -} -} -}else{ -if(_1){ -tg=cf?cf.tagName:""; -tg=tg.toLowerCase(); -if(cf&&tg&&(tg=="button"||tg=="textarea"||tg=="input")){ -if(_1.type&&_1.type.toLowerCase()=="none"){ -return {isCollapsed:true,mark:null}; -}else{ -rg=_1.createRange(); -return {isCollapsed:rg.text&&rg.text.length?false:true,mark:{range:rg,pRange:true}}; -} -} -bm={}; -try{ -rg=_1.createRange(); -bm.isCollapsed=!(_1.type=="Text"?rg.htmlText.length:rg.length); -} -catch(e){ -bm.isCollapsed=true; -return bm; -} -if(_1.type.toUpperCase()=="CONTROL"){ -if(rg.length){ -bm.mark=[]; -var i=0,_2=rg.length; -while(i<_2){ -bm.mark.push(rg.item(i++)); -} -}else{ -bm.isCollapsed=true; -bm.mark=null; -} -}else{ -bm.mark=rg.getBookmark(); -} -}else{ -console.warn("No idea how to store the current selection for this browser!"); -} -} -return bm; -},moveToBookmark:function(_3){ -var _4=dojo.doc,_5=_3.mark; -if(_5){ -if(dojo.global.getSelection){ -var _6=dojo.global.getSelection(); -if(_6&&_6.removeAllRanges){ -if(_5.pRange){ -var r=_5; -var n=r.node; -n.selectionStart=r.start; -n.selectionEnd=r.end; -}else{ -_6.removeAllRanges(); -_6.addRange(_5); -} -}else{ -console.warn("No idea how to restore selection for this browser!"); -} -}else{ -if(_4.selection&&_5){ -var rg; -if(_5.pRange){ -rg=_5.range; -}else{ -if(dojo.isArray(_5)){ -rg=_4.body.createControlRange(); -dojo.forEach(_5,function(n){ -rg.addElement(n); + + +// summary: +// These functions are used to query or set the focus and selection. +// +// Also, they trace when widgets become activated/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: + // Returns true if there is no text selected + return dijit.getBookmark().isCollapsed; + }, + + getBookmark: function(){ + // summary: + // Retrieves a bookmark that can be used with moveToBookmark to return to the same range + var bm, rg, tg, sel = dojo.doc.selection, cf = dijit._curFocus; + + if(dojo.global.getSelection){ + //W3C Range API for selections. + sel = dojo.global.getSelection(); + if(sel){ + if(sel.isCollapsed){ + tg = cf? cf.tagName : ""; + if(tg){ + //Create a fake rangelike item to restore selections. + tg = tg.toLowerCase(); + if(tg == "textarea" || + (tg == "input" && (!cf.type || cf.type.toLowerCase() == "text"))){ + sel = { + start: cf.selectionStart, + end: cf.selectionEnd, + node: cf, + pRange: true + }; + return {isCollapsed: (sel.end <= sel.start), mark: sel}; //Object. + } + } + bm = {isCollapsed:true}; + if(sel.rangeCount){ + bm.mark = sel.getRangeAt(0).cloneRange(); + } + }else{ + rg = sel.getRangeAt(0); + bm = {isCollapsed: false, mark: rg.cloneRange()}; + } + } + }else if(sel){ + // If the current focus was a input of some sort and no selection, don't bother saving + // a native bookmark. This is because it causes issues with dialog/page selection restore. + // So, we need to create psuedo bookmarks to work with. + tg = cf ? cf.tagName : ""; + tg = tg.toLowerCase(); + if(cf && tg && (tg == "button" || tg == "textarea" || tg == "input")){ + if(sel.type && sel.type.toLowerCase() == "none"){ + return { + isCollapsed: true, + mark: null + } + }else{ + rg = sel.createRange(); + return { + isCollapsed: rg.text && rg.text.length?false:true, + mark: { + range: rg, + pRange: true + } + }; + } + } + bm = {}; + + //'IE' way for selections. + try{ + // createRange() throws exception when dojo in iframe + //and nothing selected, see #9632 + rg = sel.createRange(); + bm.isCollapsed = !(sel.type == 'Text' ? rg.htmlText.length : rg.length); + }catch(e){ + bm.isCollapsed = true; + return bm; + } + if(sel.type.toUpperCase() == 'CONTROL'){ + if(rg.length){ + bm.mark=[]; + var i=0,len=rg.length; + while(i<len){ + bm.mark.push(rg.item(i++)); + } + }else{ + bm.isCollapsed = true; + bm.mark = null; + } + }else{ + bm.mark = rg.getBookmark(); + } + }else{ + console.warn("No idea how to store the current selection for this browser!"); + } + return bm; // Object + }, + + moveToBookmark: function(/*Object*/bookmark){ + // summary: + // Moves current selection to a bookmark + // bookmark: + // This should be a returned object from dijit.getBookmark() + + var _doc = dojo.doc, + mark = bookmark.mark; + if(mark){ + if(dojo.global.getSelection){ + //W3C Rangi API (FF, WebKit, Opera, etc) + var sel = dojo.global.getSelection(); + if(sel && sel.removeAllRanges){ + if(mark.pRange){ + var r = mark; + var n = r.node; + n.selectionStart = r.start; + n.selectionEnd = r.end; + }else{ + sel.removeAllRanges(); + sel.addRange(mark); + } + }else{ + console.warn("No idea how to restore selection for this browser!"); + } + }else if(_doc.selection && mark){ + //'IE' way. + var rg; + if(mark.pRange){ + rg = mark.range; + }else if(dojo.isArray(mark)){ + rg = _doc.body.createControlRange(); + //rg.addElement does not have call/apply method, so can not call it directly + //rg is not available in "range.addElement(item)", so can't use that either + dojo.forEach(mark, function(n){ + rg.addElement(n); + }); + }else{ + rg = _doc.body.createTextRange(); + rg.moveToBookmark(mark); + } + rg.select(); + } + } + }, + + getFocus: function(/*Widget?*/ menu, /*Window?*/ openedForWindow){ + // summary: + // Called as getFocus(), this returns an Object showing the current focus + // and selected text. + // + // Called as getFocus(widget), where widget is a (widget representing) a button + // that was just pressed, it returns where focus was before that button + // was pressed. (Pressing the button may have either shifted focus to the button, + // or removed focus altogether.) In this case the selected text is not returned, + // since it can't be accurately determined. + // + // menu: dijit._Widget or {domNode: DomNode} structure + // The button that was just pressed. If focus has disappeared or moved + // to this button, returns the previous focus. In this case the bookmark + // information is already lost, and null is returned. + // + // openedForWindow: + // iframe in which menu was opened + // + // returns: + // A handle to restore focus/selection, to be passed to `dijit.focus` + var node = !dijit._curFocus || (menu && dojo.isDescendant(dijit._curFocus, menu.domNode)) ? dijit._prevFocus : dijit._curFocus; + return { + node: node, + bookmark: (node == dijit._curFocus) && dojo.withGlobal(openedForWindow || dojo.global, dijit.getBookmark), + 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, + collapsed = bookmark ? bookmark.isCollapsed : false; + + // 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) or if previous selection was collapsed + // as it may cause focus shift (Esp in IE). + if(bookmark && dojo.withGlobal(openedForWindow || dojo.global, dijit.isCollapsed) && !collapsed){ + if(openedForWindow){ + openedForWindow.focus(); + } + try{ + dojo.withGlobal(openedForWindow || dojo.global, dijit.moveToBookmark, null, [bookmark]); + }catch(e2){ + /*squelch IE internal error, see http://trac.dojotoolkit.org/ticket/1984 */ + } + } + }, + + // _activeStack: dijit._Widget[] + // List of currently active widgets (focused widget and it's ancestors) + _activeStack: [], + + registerIframe: function(/*DomNode*/ iframe){ + // summary: + // Registers listeners on the specified iframe so that any click + // or focus event on that iframe (or anything in it) is reported + // as a focus/click event on the <iframe> itself. + // description: + // Currently only used by editor. + // returns: + // Handle to pass to unregisterIframe() + return dijit.registerWin(iframe.contentWindow, iframe); + }, + + unregisterIframe: function(/*Object*/ handle){ + // summary: + // Unregisters listeners on the specified iframe created by registerIframe. + // After calling be sure to delete or null out the handle itself. + // handle: + // Handle returned by registerIframe() + + dijit.unregisterWin(handle); + }, + + registerWin: function(/*Window?*/targetWindow, /*DomNode?*/ effectiveNode){ + // summary: + // Registers listeners on the specified window (either the main + // window or an iframe's window) to detect when the user has clicked somewhere + // or focused somewhere. + // description: + // Users should call registerIframe() instead of this method. + // targetWindow: + // If specified this is the window associated with the iframe, + // i.e. iframe.contentWindow. + // effectiveNode: + // If specified, report any focus events inside targetWindow as + // an event on effectiveNode, rather than on evt.target. + // returns: + // Handle to pass to unregisterWin() + + // TODO: make this function private in 2.0; Editor/users should call registerIframe(), + + var mousedownListener = function(evt){ + dijit._justMouseDowned = true; + setTimeout(function(){ dijit._justMouseDowned = false; }, 0); + + // workaround weird IE bug where the click is on an orphaned node + // (first time clicking a Select/DropDownButton inside a TooltipDialog) + if(dojo.isIE && evt && evt.srcElement && evt.srcElement.parentNode == null){ + return; + } + + dijit._onTouchNode(effectiveNode || evt.target || evt.srcElement, "mouse"); + }; + //dojo.connect(targetWindow, "onscroll", ???); + + // Listen for blur and focus events on targetWindow's document. + // IIRC, I'm using attachEvent() rather than dojo.connect() because focus/blur events don't bubble + // through dojo.connect(), and also maybe to catch the focus events early, before onfocus handlers + // fire. + // Connect to <html> (rather than document) on IE to avoid memory leaks, but document on other browsers because + // (at least for FF) the focus event doesn't fire on <html> or <body>. + var doc = dojo.isIE ? targetWindow.document.documentElement : targetWindow.document; + if(doc){ + if(dojo.isIE){ + targetWindow.document.body.attachEvent('onmousedown', mousedownListener); + var activateListener = function(evt){ + // IE reports that nodes like <body> have gotten focus, even though they have tabIndex=-1, + // Should consider those more like a mouse-click than a focus.... + if(evt.srcElement.tagName.toLowerCase() != "#document" && + dijit.isTabNavigable(evt.srcElement)){ + dijit._onFocusNode(effectiveNode || evt.srcElement); + }else{ + dijit._onTouchNode(effectiveNode || evt.srcElement); + } + }; + doc.attachEvent('onactivate', activateListener); + var deactivateListener = function(evt){ + dijit._onBlurNode(effectiveNode || evt.srcElement); + }; + doc.attachEvent('ondeactivate', deactivateListener); + + return function(){ + targetWindow.document.detachEvent('onmousedown', mousedownListener); + doc.detachEvent('onactivate', activateListener); + doc.detachEvent('ondeactivate', deactivateListener); + doc = null; // prevent memory leak (apparent circular reference via closure) + }; + }else{ + doc.body.addEventListener('mousedown', mousedownListener, true); + var focusListener = function(evt){ + dijit._onFocusNode(effectiveNode || evt.target); + }; + doc.addEventListener('focus', focusListener, true); + var blurListener = function(evt){ + dijit._onBlurNode(effectiveNode || evt.target); + }; + doc.addEventListener('blur', blurListener, true); + + return function(){ + doc.body.removeEventListener('mousedown', mousedownListener, true); + doc.removeEventListener('focus', focusListener, true); + doc.removeEventListener('blur', blurListener, true); + doc = null; // prevent memory leak (apparent circular reference via closure) + }; + } + } + }, + + unregisterWin: function(/*Handle*/ handle){ + // summary: + // Unregisters listeners on the specified window (either the main + // window or an iframe's window) according to handle returned from registerWin(). + // After calling be sure to delete or null out the handle itself. + + // Currently our handle is actually a function + handle && handle(); + }, + + _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, /*String*/ by){ + // summary: + // Callback when node is focused or mouse-downed + // node: + // The node that was touched. + // by: + // "mouse" if the focus/touch was caused by a mouse down event + + // 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){ + var popupParent = dojo.attr(node, "dijitPopupParent"); + if(popupParent){ + node=dijit.byId(popupParent).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=dojo.window.get(node.ownerDocument).frameElement; + }else{ + // if this node is the root node of a widget, then add widget id to stack, + // except ignore clicks on disabled widgets (actually focusing a disabled widget still works, + // to support MenuItem) + var id = node.getAttribute && node.getAttribute("widgetId"), + widget = id && dijit.byId(id); + if(widget && !(by == "mouse" && widget.get("disabled"))){ + newStack.unshift(id); + } + node=node.parentNode; + } + } + }catch(e){ /* squelch */ } + + dijit._setStack(newStack, by); + }, + + _onFocusNode: function(/*DomNode*/ node){ + // summary: + // Callback when node is focused + + if(!node){ + return; + } + + if(node.nodeType == 9){ + // Ignore focus events on the document itself. This is here so that + // (for example) clicking the up/down arrows of a spinner + // (which don't get focus) won't cause that widget to blur. (FF issue) + 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(/*String[]*/ newStack, /*String*/ by){ + // summary: + // The stack of active widgets has changed. Send out appropriate events and records new stack. + // newStack: + // array of widget id's, starting from the top (outermost) widget + // by: + // "mouse" if the focus/touch was caused by a mouse down event + + 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; + } + } + + var widget; + // for all elements that have gone out of focus, send blur event + for(var i=oldStack.length-1; i>=nCommon; i--){ + widget = dijit.byId(oldStack[i]); + if(widget){ + widget._focused = false; + widget.set("focused", false); + widget._hasBeenBlurred = true; + if(widget._onBlur){ + widget._onBlur(by); + } + dojo.publish("widgetBlur", [widget, by]); + } + } + + // 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; + widget.set("focused", true); + if(widget._onFocus){ + widget._onFocus(by); + } + dojo.publish("widgetFocus", [widget, by]); + } + } + } }); -}else{ -rg=_4.body.createTextRange(); -rg.moveToBookmark(_5); -} -} -rg.select(); -} -} -} -},getFocus:function(_7,_8){ -var _9=!dijit._curFocus||(_7&&dojo.isDescendant(dijit._curFocus,_7.domNode))?dijit._prevFocus:dijit._curFocus; -return {node:_9,bookmark:(_9==dijit._curFocus)&&dojo.withGlobal(_8||dojo.global,dijit.getBookmark),openedForWindow:_8}; -},focus:function(_a){ -if(!_a){ -return; -} -var _b="node" in _a?_a.node:_a,_c=_a.bookmark,_d=_a.openedForWindow,_e=_c?_c.isCollapsed:false; -if(_b){ -var _f=(_b.tagName.toLowerCase()=="iframe")?_b.contentWindow:_b; -if(_f&&_f.focus){ -try{ -_f.focus(); -} -catch(e){ -} -} -dijit._onFocusNode(_b); -} -if(_c&&dojo.withGlobal(_d||dojo.global,dijit.isCollapsed)&&!_e){ -if(_d){ -_d.focus(); -} -try{ -dojo.withGlobal(_d||dojo.global,dijit.moveToBookmark,null,[_c]); -} -catch(e2){ -} -} -},_activeStack:[],registerIframe:function(_10){ -return dijit.registerWin(_10.contentWindow,_10); -},unregisterIframe:function(_11){ -dijit.unregisterWin(_11); -},registerWin:function(_12,_13){ -var _14=function(evt){ -dijit._justMouseDowned=true; -setTimeout(function(){ -dijit._justMouseDowned=false; -},0); -if(dojo.isIE&&evt&&evt.srcElement&&evt.srcElement.parentNode==null){ -return; -} -dijit._onTouchNode(_13||evt.target||evt.srcElement,"mouse"); -}; -var doc=dojo.isIE?_12.document.documentElement:_12.document; -if(doc){ -if(dojo.isIE){ -doc.attachEvent("onmousedown",_14); -var _15=function(evt){ -if(evt.srcElement.tagName.toLowerCase()!="#document"&&dijit.isTabNavigable(evt.srcElement)){ -dijit._onFocusNode(_13||evt.srcElement); -}else{ -dijit._onTouchNode(_13||evt.srcElement); -} -}; -doc.attachEvent("onactivate",_15); -var _16=function(evt){ -dijit._onBlurNode(_13||evt.srcElement); -}; -doc.attachEvent("ondeactivate",_16); -return function(){ -doc.detachEvent("onmousedown",_14); -doc.detachEvent("onactivate",_15); -doc.detachEvent("ondeactivate",_16); -doc=null; -}; -}else{ -doc.addEventListener("mousedown",_14,true); -var _17=function(evt){ -dijit._onFocusNode(_13||evt.target); -}; -doc.addEventListener("focus",_17,true); -var _18=function(evt){ -dijit._onBlurNode(_13||evt.target); -}; -doc.addEventListener("blur",_18,true); -return function(){ -doc.removeEventListener("mousedown",_14,true); -doc.removeEventListener("focus",_17,true); -doc.removeEventListener("blur",_18,true); -doc=null; -}; -} -} -},unregisterWin:function(_19){ -_19&&_19(); -},_onBlurNode:function(_1a){ -dijit._prevFocus=dijit._curFocus; -dijit._curFocus=null; -if(dijit._justMouseDowned){ -return; -} -if(dijit._clearActiveWidgetsTimer){ -clearTimeout(dijit._clearActiveWidgetsTimer); -} -dijit._clearActiveWidgetsTimer=setTimeout(function(){ -delete dijit._clearActiveWidgetsTimer; -dijit._setStack([]); -dijit._prevFocus=null; -},100); -},_onTouchNode:function(_1b,by){ -if(dijit._clearActiveWidgetsTimer){ -clearTimeout(dijit._clearActiveWidgetsTimer); -delete dijit._clearActiveWidgetsTimer; -} -var _1c=[]; -try{ -while(_1b){ -var _1d=dojo.attr(_1b,"dijitPopupParent"); -if(_1d){ -_1b=dijit.byId(_1d).domNode; -}else{ -if(_1b.tagName&&_1b.tagName.toLowerCase()=="body"){ -if(_1b===dojo.body()){ -break; -} -_1b=dojo.window.get(_1b.ownerDocument).frameElement; -}else{ -var id=_1b.getAttribute&&_1b.getAttribute("widgetId"),_1e=id&&dijit.byId(id); -if(_1e&&!(by=="mouse"&&_1e.get("disabled"))){ -_1c.unshift(id); -} -_1b=_1b.parentNode; -} -} -} -} -catch(e){ -} -dijit._setStack(_1c,by); -},_onFocusNode:function(_1f){ -if(!_1f){ -return; -} -if(_1f.nodeType==9){ -return; -} -dijit._onTouchNode(_1f); -if(_1f==dijit._curFocus){ -return; -} -if(dijit._curFocus){ -dijit._prevFocus=dijit._curFocus; -} -dijit._curFocus=_1f; -dojo.publish("focusNode",[_1f]); -},_setStack:function(_20,by){ -var _21=dijit._activeStack; -dijit._activeStack=_20; -for(var _22=0;_22<Math.min(_21.length,_20.length);_22++){ -if(_21[_22]!=_20[_22]){ -break; -} -} -var _23; -for(var i=_21.length-1;i>=_22;i--){ -_23=dijit.byId(_21[i]); -if(_23){ -_23._focused=false; -_23._hasBeenBlurred=true; -if(_23._onBlur){ -_23._onBlur(by); -} -dojo.publish("widgetBlur",[_23,by]); -} -} -for(i=_22;i<_20.length;i++){ -_23=dijit.byId(_20[i]); -if(_23){ -_23._focused=true; -if(_23._onFocus){ -_23._onFocus(by); -} -dojo.publish("widgetFocus",[_23,by]); -} -} -}}); + +// register top window and all the iframes it contains dojo.addOnLoad(function(){ -var _24=dijit.registerWin(window); -if(dojo.isIE){ -dojo.addOnWindowUnload(function(){ -dijit.unregisterWin(_24); -_24=null; -}); -} + var handle = dijit.registerWin(window); + if(dojo.isIE){ + dojo.addOnWindowUnload(function(){ + dijit.unregisterWin(handle); + handle = null; + }) + } }); + } |