UNPKG

dijit

Version:

Dijit provides a complete collection of user interface controls based on Dojo, giving you the power to create web applications that are highly optimized for usability, performance, internationalization, accessibility, but above all deliver an incredible u

208 lines (181 loc) 7.38 kB
define([ "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", "../selection", "../main" // for exporting symbols to dijit ], function(array, dom, lang, topic, win, focus, selection, dijit){ // module: // dijit/_base/focus var exports = { // summary: // Deprecated module to monitor currently focused node and stack of currently focused widgets. // New code should access dijit/focus directly. // _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 sel = win.global == window ? selection : new selection.SelectionManager(win.global); return sel.getBookmark(); }, moveToBookmark: function(/*Object*/ bookmark){ // summary: // Moves current selection to a bookmark // bookmark: // This should be a returned object from dijit.getBookmark() var sel = win.global == window ? selection : new selection.SelectionManager(win.global); return sel.moveToBookmark(bookmark); }, 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/_WidgetBase|{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/_WidgetBase[] // 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 }); lang.mixin(dijit, exports); /*===== return exports; =====*/ return dijit; // for back compat :-( });