| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 | define("dijit/_base/focus", [	"dojo/_base/array", // array.forEach	"dojo/dom", // dom.isDescendant	"dojo/_base/lang", // lang.isArray	"dojo/topic", // publish	"dojo/_base/window", // win.doc win.doc.selection win.global win.global.getSelection win.withGlobal	"../focus",	".."	// for exporting symbols to dijit], function(array, dom, lang, topic, win, focus, dijit){	// module:	//		dijit/_base/focus	// summary:	//		Deprecated module to monitor currently focused node and stack of currently focused widgets.	//		New code should access dijit/focus directly.	lang.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 = win.doc.selection, cf = focus.curNode;			if(win.global.getSelection){				//W3C Range API for selections.				sel = win.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 = win.doc,				mark = bookmark.mark;			if(mark){				if(win.global.getSelection){					//W3C Rangi API (FF, WebKit, Opera, etc)					var sel = win.global.getSelection();					if(sel && sel.removeAllRanges){						if(mark.pRange){							var n = mark.node;							n.selectionStart = mark.start;							n.selectionEnd = mark.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(lang.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						array.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 = !focus.curNode || (menu && dom.isDescendant(focus.curNode, menu.domNode)) ? dijit._prevFocus : focus.curNode;			return {				node: node,				bookmark: node && (node == focus.curNode) && win.withGlobal(openedForWindow || win.global, dijit.getBookmark),				openedForWindow: openedForWindow			}; // Object		},		// _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 focus.registerIframe(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()			handle && handle.remove();		},		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()			return focus.registerWin(targetWindow, effectiveNode);		},		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.			handle && handle.remove();		}	});	// Override focus singleton's focus function so that dijit.focus()	// has backwards compatible behavior of restoring selection (although	// probably no one is using that).	focus.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*/}			}			focus._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 && win.withGlobal(openedForWindow || win.global, dijit.isCollapsed) && !collapsed){			if(openedForWindow){				openedForWindow.focus();			}			try{				win.withGlobal(openedForWindow || win.global, dijit.moveToBookmark, null, [bookmark]);			}catch(e2){				/*squelch IE internal error, see http://trac.dojotoolkit.org/ticket/1984 */			}		}	};	// For back compatibility, monitor changes to focused node and active widget stack,	// publishing events and copying changes from focus manager variables into dijit (top level) variables	focus.watch("curNode", function(name, oldVal, newVal){		dijit._curFocus = newVal;		dijit._prevFocus = oldVal;		if(newVal){			topic.publish("focusNode", newVal);	// publish		}	});	focus.watch("activeStack", function(name, oldVal, newVal){		dijit._activeStack = newVal;	});	focus.on("widget-blur", function(widget, by){		topic.publish("widgetBlur", widget, by);	// publish	});	focus.on("widget-focus", function(widget, by){		topic.publish("widgetFocus", widget, by);	// publish	});	return dijit;});
 |