3 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
4 <title>The source code</title>
5 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
6 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <body onload="prettyPrint();">
9 <pre class="prettyprint lang-js">/*!
10 * Ext JS Library 3.3.1
11 * Copyright(c) 2006-2010 Sencha Inc.
12 * licensing@sencha.com
13 * http://www.sencha.com/license
18 Ext.a11y.Frame = Ext.extend(Object, {
21 constructor: function(size, color){
22 this.setSize(size || 1);
23 this.setColor(color || '15428B');
27 if (!this.initialized) {
32 this.ct = Ext.DomHelper.append(document.body, {
33 cls: 'x-a11y-focusframe'
36 for (i = 0; i < 4; i++) {
37 s = Ext.DomHelper.append(this.ct, {
38 cls: 'x-a11y-focusframe-side',
39 style: 'background-color: #' + this.color
41 s.visibilityMode = Ext.Element.DISPLAY;
45 this.frameTask = new Ext.util.DelayedTask(function(el){
46 var newEl = Ext.get(el);
47 if (newEl != this.curEl) {
48 var w = newEl.getWidth();
49 var h = newEl.getHeight();
50 this.sides[0].show().setSize(w, this.size).anchorTo(el, 'tl', [0, -1]);
51 this.sides[2].show().setSize(w, this.size).anchorTo(el, 'bl', [0, -1]);
52 this.sides[1].show().setSize(this.size, h).anchorTo(el, 'tr', [-1, 0]);
53 this.sides[3].show().setSize(this.size, h).anchorTo(el, 'tl', [-1, 0]);
58 this.unframeTask = new Ext.util.DelayedTask(function(){
59 if (this.initialized) {
67 this.initialized = true;
73 this.unframeTask.cancel();
74 this.frameTask.delay(2, false, false, [el]);
79 this.unframeTask.delay(2);
82 setSize: function(size){
86 setColor: function(color){
91 Ext.a11y.FocusFrame = new Ext.a11y.Frame(2, '15428B');
92 Ext.a11y.RelayFrame = new Ext.a11y.Frame(1, '6B8CBF');
94 Ext.a11y.Focusable = Ext.extend(Ext.util.Observable, {
95 constructor: function(el, relayTo, noFrame, frameEl){
96 Ext.a11y.Focusable.superclass.constructor.call(this);
98 this.addEvents('focus', 'blur', 'left', 'right', 'up', 'down', 'esc', 'enter', 'space');
100 if (el instanceof Ext.Component) {
102 this.setComponent(el);
105 this.el = Ext.get(el);
106 this.setComponent(null);
109 this.setRelayTo(relayTo)
110 this.setNoFrame(noFrame);
111 this.setFrameEl(frameEl);
115 Ext.a11y.FocusMgr.register(this);
119 this.el.dom.tabIndex = '1';
120 this.el.addClass('x-a11y-focusable');
124 keydown: this.onKeyDown,
129 setRelayTo: function(relayTo){
130 this.relayTo = relayTo ? Ext.a11y.FocusMgr.get(relayTo) : null;
133 setNoFrame: function(noFrame){
134 this.noFrame = (noFrame === true) ? true : false;
137 setFrameEl: function(frameEl){
138 this.frameEl = frameEl && Ext.get(frameEl) || this.el;
141 setComponent: function(cmp){
142 this.component = cmp || null;
145 onKeyDown: function(e, t){
146 var k = e.getKey(), SK = Ext.a11y.Focusable.SpecialKeys, ret, tf;
148 tf = (t !== this.el.dom) ? Ext.a11y.FocusMgr.get(t, true) : this;
150 // this can happen when you are on a focused item within a panel body
151 // that is not a Ext.a11y.Focusable
152 tf = Ext.a11y.FocusMgr.get(Ext.fly(t).parent('.x-a11y-focusable'));
155 if (SK[k] !== undefined) {
156 ret = this.fireEvent(SK[k], e, t, tf, this);
158 if (ret === false || this.fireEvent('keydown', e, t, tf, this) === false) {
171 onFocus: function(e, t){
172 this.el.addClass('x-a11y-focused');
174 this.relayTo.el.addClass('x-a11y-focused-relay');
175 if (!this.relayTo.noFrame) {
176 Ext.a11y.FocusFrame.frame(this.relayTo.frameEl);
179 Ext.a11y.RelayFrame.frame(this.frameEl);
184 Ext.a11y.FocusFrame.frame(this.frameEl);
188 this.fireEvent('focus', e, t, this);
191 onBlur: function(e, t){
193 this.relayTo.el.removeClass('x-a11y-focused-relay');
194 Ext.a11y.RelayFrame.unframe();
196 this.el.removeClass('x-a11y-focused');
197 Ext.a11y.FocusFrame.unframe();
198 this.fireEvent('blur', e, t, this);
202 this.el.un('keydown', this.onKeyDown);
203 this.el.un('focus', this.onFocus);
204 this.el.un('blur', this.onBlur);
205 this.el.removeClass('x-a11y-focusable');
206 this.el.removeClass('x-a11y-focused');
208 this.relayTo.el.removeClass('x-a11y-focused-relay');
213 Ext.a11y.FocusItem = Ext.extend(Object, {
214 constructor: function(el, enableTabbing){
215 Ext.a11y.FocusItem.superclass.constructor.call(this);
217 this.el = Ext.get(el);
218 this.fi = new Ext.a11y.Focusable(el);
219 this.fi.setComponent(this);
221 this.fi.on('tab', this.onTab, this);
223 this.enableTabbing = enableTabbing === true ? true : false;
226 getEnterItem: function(){
227 if (this.enableTabbing) {
228 var items = this.getFocusItems();
229 if (items && items.length) {
235 getFocusItems: function(){
236 if (this.enableTabbing) {
237 return this.el.query('a, button, input, select');
242 onTab: function(e, t){
243 var items = this.getFocusItems(), i;
245 if (items && items.length && (i = items.indexOf(t)) !== -1) {
246 if (e.shiftKey && i > 0) {
248 items[i - 1].focus();
249 Ext.a11y.FocusFrame.frame.defer(20, Ext.a11y.FocusFrame, [this.el]);
253 if (!e.shiftKey && i < items.length - 1) {
255 items[i + 1].focus();
256 Ext.a11y.FocusFrame.frame.defer(20, Ext.a11y.FocusFrame, [this.el]);
263 if (this.enableTabbing) {
264 var items = this.getFocusItems();
265 if (items && items.length) {
267 Ext.a11y.FocusFrame.frame.defer(20, Ext.a11y.FocusFrame, [this.el]);
279 Ext.a11y.FocusMgr = function(){
280 var all = new Ext.util.MixedCollection();
283 register: function(f){
284 all.add(f.el && Ext.id(f.el), f);
287 unregister: function(f){
291 get: function(el, noCreate){
292 return all.get(Ext.id(el)) || (noCreate ? false : new Ext.a11y.Focusable(el));
299 Ext.a11y.Focusable.SpecialKeys = {};
300 Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.LEFT] = 'left';
301 Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.RIGHT] = 'right';
302 Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.DOWN] = 'down';
303 Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.UP] = 'up';
304 Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.ESC] = 'esc';
305 Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.ENTER] = 'enter';
306 Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.SPACE] = 'space';
307 Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.TAB] = 'tab';
309 // we use the new observeClass method to fire our new initFocus method on components
310 Ext.util.Observable.observeClass(Ext.Component);
311 Ext.Component.on('render', function(cmp){
315 Ext.override(Ext.Component, {
316 initFocus: Ext.emptyFn,
317 initARIA: Ext.emptyFn
320 Ext.override(Ext.Container, {
325 initFocus: function(){
326 if (!this.fi && !this.noFocus) {
327 this.fi = new Ext.a11y.Focusable(this);
339 this.isFocusable = false;
342 this.on('show', function(){
343 this.isFocusable = true;
345 this.on('hide', function(){
346 this.isFocusable = false;
359 var eitem = this.getEnterItem();
365 onFocus: Ext.emptyFn,
368 onTab: function(e, t, tf){
369 var rf = tf.relayTo || tf;
370 if (rf.component && rf.component !== this) {
372 var item = e.shiftKey ? this.getPreviousFocus(rf.component) : this.getNextFocus(rf.component);
377 onEnter: function(e, t, tf){
378 // check to see if enter is pressed while "on" the panel
379 if (tf.component && tf.component === this) {
386 onEsc: function(e, t){
389 // check to see if esc is pressed while "inside" the panel
390 // or while "on" the panel
391 if (t === this.el.dom) {
392 // "on" the panel, check if this panel has an owner panel and focus that
393 // we dont stop the event in this case so that this same check will be
394 // done for this ownerCt
396 this.ownerCt.focus();
400 // we were inside the panel when esc was pressed,
401 // so go back "on" the panel
402 if (this.ownerCt && this.ownerCt.isFocusable) {
403 var si = this.ownerCt.getFocusItems();
405 if (si && si.getCount() > 1) {
413 getFocusItems: function(){
415 this.items.filterBy(function(o){
416 return o.isFocusable;
421 getEnterItem: function(){
422 var ci = this.getFocusItems(), length = ci ? ci.getCount() : 0;
425 return ci.first().getEnterItem && ci.first().getEnterItem() || ci.first();
427 else if (length > 1) {
432 getNextFocus: function(current){
433 var items = this.getFocusItems(), next = current, i = items.indexOf(current), length = items.getCount();
435 if (i === length - 1) {
436 next = items.first();
439 next = items.get(i + 1);
444 getPreviousFocus: function(current){
445 var items = this.getFocusItems(), prev = current, i = items.indexOf(current), length = items.getCount();
451 prev = items.get(i - 1);
456 getFocusable : function() {
461 Ext.override(Ext.Panel, {
462 <div id="cfg-Ext.ux.DataViewTransition-enableTabbing"></div>/**
463 * @cfg {Boolean} enableTabbing <tt>true</tt> to enable tabbing. Default is <tt>false</tt>.
465 getFocusItems: function(){
466 // items gets all the items inside the body
467 var items = Ext.Panel.superclass.getFocusItems.call(this), bodyFocus = null;
470 items = new Ext.util.MixedCollection();
471 this.bodyFocus = this.bodyFocus || new Ext.a11y.FocusItem(this.body, this.enableTabbing);
472 items.add('body', this.bodyFocus);
474 // but panels can also have tbar, bbar, fbar
475 if (this.tbar && this.topToolbar) {
476 items.insert(0, this.topToolbar);
478 if (this.bbar && this.bottomToolbar) {
479 items.add(this.bottomToolbar);
482 items.add(this.fbar);
489 Ext.override(Ext.TabPanel, {
491 initFocus: function(){
492 Ext.TabPanel.superclass.initFocus.call(this);
501 if (!this.activeTab) {
505 var prev = this.items.itemAt(this.items.indexOf(this.activeTab) - 1);
507 this.setActiveTab(prev);
512 onRight: function(e){
513 if (!this.activeTab) {
517 var next = this.items.itemAt(this.items.indexOf(this.activeTab) + 1);
519 this.setActiveTab(next);
525 Ext.override(Ext.tree.TreeNodeUI, {
528 this.node.getOwnerTree().bodyFocus.focus();
532 Ext.override(Ext.tree.TreePanel, {
534 afterRender : function(){
535 Ext.tree.TreePanel.superclass.afterRender.call(this);
537 if(!this.rootVisible){
538 this.root.renderChildren();
540 this.bodyFocus = new Ext.a11y.FocusItem(this.body.down('.x-tree-root-ct'));
541 this.bodyFocus.fi.setFrameEl(this.body);
545 Ext.override(Ext.grid.GridPanel, {
546 initFocus: function(){
547 Ext.grid.GridPanel.superclass.initFocus.call(this);
548 this.bodyFocus = new Ext.a11y.FocusItem(this.view.focusEl);
549 this.bodyFocus.fi.setFrameEl(this.body);
553 Ext.override(Ext.Button, {
557 initFocus: function(){
558 Ext.Button.superclass.initFocus.call(this);
559 this.fi = this.fi || new Ext.a11y.Focusable(this.btnEl, null, null, this.el);
560 this.fi.setComponent(this);
569 this.mon(this.fi, 'down', this.showMenu, this);
570 this.on('menuhide', this.focus, this);
574 this.isFocusable = false;
577 this.on('show', function(){
578 this.isFocusable = true;
580 this.on('hide', function(){
581 this.isFocusable = false;
594 if (!this.disabled) {
595 this.el.addClass("x-btn-focus");
600 this.el.removeClass("x-btn-focus");
604 Ext.override(Ext.Toolbar, {
605 initFocus: function(){
606 Ext.Toolbar.superclass.initFocus.call(this);
613 this.on('focus', this.onButtonFocus, this, {
619 var item = Ext.Toolbar.superclass.add.apply(this, arguments);
620 if(!item || !item.events) {
623 if (item.rendered && item.fi !== undefined) {
624 item.fi.setRelayTo(this.el);
625 this.relayEvents(item.fi, ['focus']);
628 item.on('render', function(){
629 if (item.fi !== undefined) {
630 item.fi.setRelayTo(this.el);
631 this.relayEvents(item.fi, ['focus']);
641 var items = this.getFocusItems();
642 if (items && items.getCount() > 0) {
643 if (this.lastFocus && items.indexOf(this.lastFocus) !== -1) {
644 this.lastFocus.focus();
647 items.first().focus();
652 onButtonFocus: function(e, t, tf){
653 this.lastFocus = tf.component || null;
656 onLeft: function(e, t, tf){
658 this.getPreviousFocus(tf.component).focus();
661 onRight: function(e, t, tf){
663 this.getNextFocus(tf.component).focus();
666 getEnterItem: Ext.emptyFn,
671 Ext.override(Ext.menu.BaseItem, {
672 initFocus: function(){
673 this.fi = new Ext.a11y.Focusable(this, this.parentMenu && this.parentMenu.el || null, true);
677 Ext.override(Ext.menu.Menu, {
678 initFocus: function(){
679 this.fi = new Ext.a11y.Focusable(this);
680 this.focusEl = this.fi;
684 Ext.a11y.WindowMgr = new Ext.WindowGroup();
686 Ext.apply(Ext.WindowMgr, {
687 bringToFront: function(win){
688 Ext.a11y.WindowMgr.bringToFront.call(this, win);
698 Ext.override(Ext.Window, {
699 initFocus: function(){
700 Ext.Window.superclass.initFocus.call(this);
701 this.on('beforehide', function(){
702 Ext.a11y.RelayFrame.unframe();
703 Ext.a11y.FocusFrame.unframe();
708 Ext.override(Ext.form.Field, {
712 initFocus: function(){
713 this.fi = this.fi || new Ext.a11y.Focusable(this, null, true);
715 Ext.form.Field.superclass.initFocus.call(this);
718 this.isFocusable = false;
721 this.on('show', function(){
722 this.isFocusable = true;
724 this.on('hide', function(){
725 this.isFocusable = false;
730 Ext.override(Ext.FormPanel, {
731 initFocus: function(){
732 Ext.FormPanel.superclass.initFocus.call(this);
733 this.on('focus', this.onFieldFocus, this, {
739 createForm: function(){
740 delete this.initialConfig.listeners;
741 var form = new Ext.form.BasicForm(null, this.initialConfig);
742 form.afterMethod('add', this.formItemAdd, this);
746 formItemAdd: function(item){
747 item.on('render', function(field){
748 field.fi.setRelayTo(this.el);
749 this.relayEvents(field.fi, ['focus']);
756 var items = this.getFocusItems();
757 if (items && items.getCount() > 0) {
758 if (this.lastFocus && items.indexOf(this.lastFocus) !== -1) {
759 this.lastFocus.focus();
762 items.first().focus();
767 onFieldFocus: function(e, t, tf){
768 this.lastFocus = tf.component || null;
771 onTab: function(e, t, tf){
772 if (tf.relayTo.component === this) {
773 var item = e.shiftKey ? this.getPreviousFocus(tf.component) : this.getNextFocus(tf.component);
781 Ext.FormPanel.superclass.onTab.apply(this, arguments);
784 getNextFocus: function(current){
785 var items = this.getFocusItems(), i = items.indexOf(current), length = items.getCount();
787 return (i < length - 1) ? items.get(i + 1) : false;
790 getPreviousFocus: function(current){
791 var items = this.getFocusItems(), i = items.indexOf(current), length = items.getCount();
793 return (i > 0) ? items.get(i - 1) : false;
797 Ext.override(Ext.Viewport, {
798 initFocus: function(){
799 Ext.Viewport.superclass.initFocus.apply(this);
800 this.mon(Ext.get(document), 'focus', this.focus, this);
801 this.mon(Ext.get(document), 'blur', this.blur, this);
802 this.fi.setNoFrame(true);
805 onTab: function(e, t, tf, f){
809 items = this.getFocusItems();
810 if (items && items.getCount() > 0) {
811 items.first().focus();
815 var rf = tf.relayTo || tf;
816 var item = e.shiftKey ? this.getPreviousFocus(rf.component) : this.getNextFocus(rf.component);