<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The source code</title>
- <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../prettify/prettify.js"></script>
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
<style type="text/css">
.highlight { display: block; background-color: #ddd; }
</style>
</script>
</head>
<body onload="prettyPrint(); highlight();">
- <pre class="prettyprint lang-js"><span id='Ext-util-KeyNav'>/**
-</span> * @class Ext.util.KeyNav
- * <p>Provides a convenient wrapper for normalized keyboard navigation. KeyNav allows you to bind
- * navigation keys to function calls that will get called when the keys are pressed, providing an easy
- * way to implement custom navigation schemes for any UI component.</p>
- * <p>The following are all of the possible keys that can be implemented: enter, space, left, right, up, down, tab, esc,
- * pageUp, pageDown, del, backspace, home, end. Usage:</p>
- <pre><code>
-var nav = new Ext.util.KeyNav("my-element", {
- "left" : function(e){
- this.moveLeft(e.ctrlKey);
- },
- "right" : function(e){
- this.moveRight(e.ctrlKey);
- },
- "enter" : function(e){
- this.save();
- },
- scope : this
-});
-</code></pre>
+ <pre class="prettyprint lang-js"><span id='Ext-menu-KeyNav'>/**
+</span> * @class Ext.menu.KeyNav
+ * @private
*/
-Ext.define('Ext.util.KeyNav', {
-
- alternateClassName: 'Ext.KeyNav',
-
- requires: ['Ext.util.KeyMap'],
+Ext.define('Ext.menu.KeyNav', {
+ extend: 'Ext.util.KeyNav',
+
+ requires: ['Ext.FocusManager'],
- statics: {
- keyOptions: {
- left: 37,
- right: 39,
- up: 38,
- down: 40,
- space: 32,
- pageUp: 33,
- pageDown: 34,
- del: 46,
- backspace: 8,
- home: 36,
- end: 35,
- enter: 13,
- esc: 27,
- tab: 9
- }
+ constructor: function(menu) {
+ var me = this;
+
+ me.menu = menu;
+ me.callParent([menu.el, {
+ down: me.down,
+ enter: me.enter,
+ esc: me.escape,
+ left: me.left,
+ right: me.right,
+ space: me.enter,
+ tab: me.tab,
+ up: me.up
+ }]);
},
-<span id='Ext-util-KeyNav-method-constructor'> /**
-</span> * Creates new KeyNav.
- * @param {Mixed} el The element to bind to
- * @param {Object} config The config
- */
- constructor: function(el, config){
- this.setConfig(el, config || {});
+ down: function(e) {
+ var me = this,
+ fi = me.menu.focusedItem;
+
+ if (fi && e.getKey() == Ext.EventObject.DOWN && me.isWhitelisted(fi)) {
+ return true;
+ }
+ me.focusNextItem(1);
},
-
-<span id='Ext-util-KeyNav-method-setConfig'> /**
-</span> * Sets up a configuration for the KeyNav.
- * @private
- * @param {Mixed} el The element to bind to
- * @param {Object}A configuration object as specified in the constructor.
- */
- setConfig: function(el, config) {
- if (this.map) {
- this.map.destroy();
+
+ enter: function(e) {
+ var menu = this.menu,
+ focused = menu.focusedItem;
+
+ if (menu.activeItem) {
+ menu.onClick(e);
+ } else if (focused && focused.isFormField) {
+ // prevent stopEvent being called
+ return true;
}
-
- var map = Ext.create('Ext.util.KeyMap', el, null, this.getKeyEvent('forceKeyDown' in config ? config.forceKeyDown : this.forceKeyDown)),
- keys = Ext.util.KeyNav.keyOptions,
- scope = config.scope || this,
- key;
-
- this.map = map;
- for (key in keys) {
- if (keys.hasOwnProperty(key)) {
- if (config[key]) {
- map.addBinding({
- scope: scope,
- key: keys[key],
- handler: Ext.Function.bind(this.handleEvent, scope, [config[key]], true),
- defaultEventAction: config.defaultEventAction || this.defaultEventAction
- });
- }
+ },
+
+ escape: function(e) {
+ Ext.menu.Manager.hideAll();
+ },
+
+ focusNextItem: function(step) {
+ var menu = this.menu,
+ items = menu.items,
+ focusedItem = menu.focusedItem,
+ startIdx = focusedItem ? items.indexOf(focusedItem) : -1,
+ idx = startIdx + step;
+
+ while (idx != startIdx) {
+ if (idx < 0) {
+ idx = items.length - 1;
+ } else if (idx >= items.length) {
+ idx = 0;
}
+
+ var item = items.getAt(idx);
+ if (menu.canActivateItem(item)) {
+ menu.setActiveItem(item);
+ break;
+ }
+ idx += step;
}
-
- map.disable();
- if (!config.disabled) {
- map.enable();
- }
- },
-
-<span id='Ext-util-KeyNav-method-handleEvent'> /**
-</span> * Method for filtering out the map argument
- * @private
- * @param {Ext.util.KeyMap} map
- * @param {Ext.EventObject} event
- * @param {Object} options Contains the handler to call
- */
- handleEvent: function(map, event, handler){
- return handler.call(this, event);
},
-
-<span id='Ext-util-KeyNav-cfg-disabled'> /**
-</span> * @cfg {Boolean} disabled
- * True to disable this KeyNav instance (defaults to false)
- */
- disabled: false,
-
-<span id='Ext-util-KeyNav-cfg-defaultEventAction'> /**
-</span> * @cfg {String} defaultEventAction
- * The method to call on the {@link Ext.EventObject} after this KeyNav intercepts a key. Valid values are
- * {@link Ext.EventObject#stopEvent}, {@link Ext.EventObject#preventDefault} and
- * {@link Ext.EventObject#stopPropagation} (defaults to 'stopEvent')
- */
- defaultEventAction: "stopEvent",
-
-<span id='Ext-util-KeyNav-cfg-forceKeyDown'> /**
-</span> * @cfg {Boolean} forceKeyDown
- * Handle the keydown event instead of keypress (defaults to false). KeyNav automatically does this for IE since
- * IE does not propagate special keys on keypress, but setting this to true will force other browsers to also
- * handle keydown instead of keypress.
- */
- forceKeyDown: false,
-
-<span id='Ext-util-KeyNav-method-destroy'> /**
-</span> * Destroy this KeyNav (this is the same as calling disable).
- * @param {Boolean} removeEl True to remove the element associated with this KeyNav.
- */
- destroy: function(removeEl){
- this.map.destroy(removeEl);
- delete this.map;
+
+ isWhitelisted: function(item) {
+ return Ext.FocusManager.isWhitelisted(item);
},
-<span id='Ext-util-KeyNav-method-enable'> /**
-</span> * Enable this KeyNav
- */
- enable: function() {
- this.map.enable();
- this.disabled = false;
+ left: function(e) {
+ var menu = this.menu,
+ fi = menu.focusedItem,
+ ai = menu.activeItem;
+
+ if (fi && this.isWhitelisted(fi)) {
+ return true;
+ }
+
+ menu.hide();
+ if (menu.parentMenu) {
+ menu.parentMenu.focus();
+ }
},
-<span id='Ext-util-KeyNav-method-disable'> /**
-</span> * Disable this KeyNav
- */
- disable: function() {
- this.map.disable();
- this.disabled = true;
+ right: function(e) {
+ var menu = this.menu,
+ fi = menu.focusedItem,
+ ai = menu.activeItem,
+ am;
+
+ if (fi && this.isWhitelisted(fi)) {
+ return true;
+ }
+
+ if (ai) {
+ am = menu.activeItem.menu;
+ if (am) {
+ ai.expandMenu(0);
+ Ext.defer(function() {
+ am.setActiveItem(am.items.getAt(0));
+ }, 25);
+ }
+ }
},
-
-<span id='Ext-util-KeyNav-method-setDisabled'> /**
-</span> * Convenience function for setting disabled/enabled by boolean.
- * @param {Boolean} disabled
- */
- setDisabled : function(disabled){
- this.map.setDisabled(disabled);
- this.disabled = disabled;
+
+ tab: function(e) {
+ var me = this;
+
+ if (e.shiftKey) {
+ me.up(e);
+ } else {
+ me.down(e);
+ }
},
-
-<span id='Ext-util-KeyNav-method-getKeyEvent'> /**
-</span> * Determines the event to bind to listen for keys. Depends on the {@link #forceKeyDown} setting,
- * as well as the useKeyDown option on the EventManager.
- * @return {String} The type of event to listen for.
- */
- getKeyEvent: function(forceKeyDown){
- return (forceKeyDown || Ext.EventManager.useKeyDown) ? 'keydown' : 'keypress';
+
+ up: function(e) {
+ var me = this,
+ fi = me.menu.focusedItem;
+
+ if (fi && e.getKey() == Ext.EventObject.UP && me.isWhitelisted(fi)) {
+ return true;
+ }
+ me.focusNextItem(-1);
}
-});
-</pre>
+});</pre>
</body>
</html>