Форк Rambox
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

200 lines
4.6 KiB

/**
* The FocusManager is responsible for managing the following according to WAI ARIA practices:
*
* 1. Component focus
* 2. Keyboard navigation
* 3. Provide a visual cue for focused components, in the form of a focus ring/frame.
*
*/
Ext.define('Ext.aria.FocusManager', {
singleton: true,
requires: [
'Ext.util.KeyNav',
'Ext.util.Observable'
],
mixins: {
observable: 'Ext.util.Observable'
},
/**
* @property {Boolean} enabled
* Whether or not the FocusManager is currently enabled
*/
enabled: false,
/**
* @event disable
* Fires when the FocusManager is disabled
* @param {Ext.aria.FocusManager} fm A reference to the FocusManager singleton
*/
/**
* @event enable
* Fires when the FocusManager is enabled
* @param {Ext.aria.FocusManager} fm A reference to the FocusManager singleton
*/
// Array to keep track of open windows
windows: [],
constructor: function(config) {
var me = this,
whitelist = me.whitelist,
cache, i, len;
me.mixins.observable.constructor.call(me, config);
},
/**
* @private
* Enables the FocusManager by turning on window management and keyboard navigation
*/
enable: function() {
var me = this,
doc = Ext.getDoc();
if (me.enabled) {
return;
}
// initDom will call addFocusListener which needs the FocusManager to be enabled
me.enabled = true;
// map F6 to toggle focus among open windows
me.toggleKeyMap = new Ext.util.KeyMap({
target: doc,
scope: me,
defaultEventAction: 'stopEvent',
key: Ext.event.Event.F6,
fn: me.toggleWindow
});
me.fireEvent('enable', me);
},
onComponentBlur: function(cmp, e) {
var me = this;
if (me.focusedCmp === cmp) {
me.previousFocusedCmp = cmp;
}
Ext.globalEvents.fireEvent('componentblur', me, cmp, me.previousFocusedCmp);
return false;
},
onComponentFocus: function(cmp, e) {
var me = this;
if (Ext.globalEvents.fireEvent('beforecomponentfocus', me, cmp, me.previousFocusedCmp) === false) {
me.clearComponent(cmp);
return;
}
me.focusedCmp = cmp;
return false;
},
// This should be fixed in https://sencha.jira.com/browse/EXTJS-14124
onComponentHide: Ext.emptyFn,
toggleWindow: function(key, e) {
var me = this,
windows = me.windows,
length = windows.length,
focusedCmp = me.focusedCmp,
curIndex = 0,
newIndex = 0,
current;
if (length === 1) {
return;
}
current = focusedCmp.isWindow ? focusedCmp : focusedCmp.up('window');
if (current) {
curIndex = me.findWindowIndex(current);
}
if (e.shiftKey) {
newIndex = curIndex - 1;
if (newIndex < 0) {
newIndex = length - 1;
}
} else {
newIndex = curIndex + 1;
if (newIndex === length) {
newIndex = 0;
}
}
current = windows[newIndex];
if (current.cmp.isWindow) {
current.cmp.toFront();
}
current.cmp.focus(false, 100);
return false;
},
addWindow: function(window) {
var me = this,
win = {
cmp: window
};
me.windows.push(win);
},
removeWindow: function(window) {
var me = this,
windows = me.windows,
current;
if (windows.length === 1) {
return;
}
current = me.findWindowIndex(window);
if (current >= 0) {
Ext.Array.erase(windows, current, 1);
}
},
findWindowIndex: function(window) {
var me = this,
windows = me.windows,
length = windows.length,
curIndex = -1,
i;
for (i = 0; i < length; i++) {
if (windows[i].cmp === window) {
curIndex = i;
break;
}
}
return curIndex;
}
},
function() {
var mgr = Ext['FocusManager'] = Ext.aria.FocusManager;
Ext.onReady(function() {
mgr.enable();
});
});