/** * @class Ext.tree.NavigationModel * @private * This class listens for key events fired from a {@link Ext.tree.Panel TreePanel}, and moves the currently focused item * by adding the class {@link #focusCls}. * * Navigation and interactions are defined by http://www.w3.org/TR/2013/WD-wai-aria-practices-20130307/#TreeView */Ext.define('Ext.tree.NavigationModel', { extend: 'Ext.grid.NavigationModel', alias: 'view.navigation.tree', initKeyNav: function(view) { var me = this; me.callParent([view]); me.keyNav.map.addBinding([{ key: '8', shift: true, handler: me.onAsterisk, scope: me }, { key: Ext.event.Event.NUM_MULTIPLY, handler: me.onAsterisk, scope: me }]); }, onKeyLeft: function(keyEvent) { var me = this, view = me.view, record = me.record; // Left arrow key on an expanded node closes the node. if (!record.isLeaf() && record.isExpanded()) { view.collapse(record); } // Left arrow key on a closed or end node moves focus to the node's parent (don't attempt to focus hidden root). else { record = record.parentNode; if (record && !(record.isRoot() && !view.rootVisible)) { me.setPosition(record, null, keyEvent); } } }, onKeyRight: function(keyEvent) { var me = this, record = me.record; // Right arrow key expands a closed node, moves to the first child of an open node, or does nothing on an end node. if (!record.isLeaf()) { if (!record.isExpanded()) { me.view.expand(record); } else { record = record.childNodes[0]; if (record) { me.setPosition(record); } } } }, onKeyEnter: function(keyEvent) { if (this.record.data.checked != null) { this.toggleCheck(keyEvent); } else { this.callParent([keyEvent]); } }, onKeySpace: function(keyEvent) { if (this.record.data.checked != null) { this.toggleCheck(keyEvent); } else { this.callParent([keyEvent]); } }, toggleCheck: function(keyEvent) { this.view.onCheckChange(this.record); }, // (asterisk) on keypad expands all nodes. onAsterisk: function(keyEvent) { this.view.ownerCt.expandAll(); }});