1 | /*! |
---|
2 | * Ext JS Library 3.0.0 |
---|
3 | * Copyright(c) 2006-2009 Ext JS, LLC |
---|
4 | * licensing@extjs.com |
---|
5 | * http://www.extjs.com/license |
---|
6 | */ |
---|
7 | (function(){ |
---|
8 | Ext.ns('Ext.a11y'); |
---|
9 | |
---|
10 | Ext.a11y.Frame = Ext.extend(Object, { |
---|
11 | initialized: false, |
---|
12 | |
---|
13 | constructor: function(size, color){ |
---|
14 | this.setSize(size || 1); |
---|
15 | this.setColor(color || '15428B'); |
---|
16 | }, |
---|
17 | |
---|
18 | init: function(){ |
---|
19 | if (!this.initialized) { |
---|
20 | this.sides = []; |
---|
21 | |
---|
22 | var s, i; |
---|
23 | |
---|
24 | this.ct = Ext.DomHelper.append(document.body, { |
---|
25 | cls: 'x-a11y-focusframe' |
---|
26 | }, true); |
---|
27 | |
---|
28 | for (i = 0; i < 4; i++) { |
---|
29 | s = Ext.DomHelper.append(this.ct, { |
---|
30 | cls: 'x-a11y-focusframe-side', |
---|
31 | style: 'background-color: #' + this.color |
---|
32 | }, true); |
---|
33 | s.visibilityMode = Ext.Element.DISPLAY; |
---|
34 | this.sides.push(s); |
---|
35 | } |
---|
36 | |
---|
37 | this.frameTask = new Ext.util.DelayedTask(function(el){ |
---|
38 | var newEl = Ext.get(el); |
---|
39 | if (newEl != this.curEl) { |
---|
40 | var w = newEl.getWidth(); |
---|
41 | var h = newEl.getHeight(); |
---|
42 | this.sides[0].show().setSize(w, this.size).anchorTo(el, 'tl', [0, -1]); |
---|
43 | this.sides[2].show().setSize(w, this.size).anchorTo(el, 'bl', [0, -1]); |
---|
44 | this.sides[1].show().setSize(this.size, h).anchorTo(el, 'tr', [-1, 0]); |
---|
45 | this.sides[3].show().setSize(this.size, h).anchorTo(el, 'tl', [-1, 0]); |
---|
46 | this.curEl = newEl; |
---|
47 | } |
---|
48 | }, this); |
---|
49 | |
---|
50 | this.unframeTask = new Ext.util.DelayedTask(function(){ |
---|
51 | if (this.initialized) { |
---|
52 | this.sides[0].hide(); |
---|
53 | this.sides[1].hide(); |
---|
54 | this.sides[2].hide(); |
---|
55 | this.sides[3].hide(); |
---|
56 | this.curEl = null; |
---|
57 | } |
---|
58 | }, this); |
---|
59 | this.initialized = true; |
---|
60 | } |
---|
61 | }, |
---|
62 | |
---|
63 | frame: function(el){ |
---|
64 | this.init(); |
---|
65 | this.unframeTask.cancel(); |
---|
66 | this.frameTask.delay(2, false, false, [el]); |
---|
67 | }, |
---|
68 | |
---|
69 | unframe: function(){ |
---|
70 | this.init(); |
---|
71 | this.unframeTask.delay(2); |
---|
72 | }, |
---|
73 | |
---|
74 | setSize: function(size){ |
---|
75 | this.size = size; |
---|
76 | }, |
---|
77 | |
---|
78 | setColor: function(color){ |
---|
79 | this.color = color; |
---|
80 | } |
---|
81 | }); |
---|
82 | |
---|
83 | Ext.a11y.FocusFrame = new Ext.a11y.Frame(2, '15428B'); |
---|
84 | Ext.a11y.RelayFrame = new Ext.a11y.Frame(1, '6B8CBF'); |
---|
85 | |
---|
86 | Ext.a11y.Focusable = Ext.extend(Ext.util.Observable, { |
---|
87 | constructor: function(el, relayTo, noFrame, frameEl){ |
---|
88 | Ext.a11y.Focusable.superclass.constructor.call(this); |
---|
89 | |
---|
90 | this.addEvents('focus', 'blur', 'left', 'right', 'up', 'down', 'esc', 'enter', 'space'); |
---|
91 | |
---|
92 | if (el instanceof Ext.Component) { |
---|
93 | this.el = el.el; |
---|
94 | this.setComponent(el); |
---|
95 | } |
---|
96 | else { |
---|
97 | this.el = Ext.get(el); |
---|
98 | this.setComponent(null); |
---|
99 | } |
---|
100 | |
---|
101 | this.setRelayTo(relayTo) |
---|
102 | this.setNoFrame(noFrame); |
---|
103 | this.setFrameEl(frameEl); |
---|
104 | |
---|
105 | this.init(); |
---|
106 | |
---|
107 | Ext.a11y.FocusMgr.register(this); |
---|
108 | }, |
---|
109 | |
---|
110 | init: function(){ |
---|
111 | this.el.dom.tabIndex = '1'; |
---|
112 | this.el.addClass('x-a11y-focusable'); |
---|
113 | this.el.on({ |
---|
114 | focus: this.onFocus, |
---|
115 | blur: this.onBlur, |
---|
116 | keydown: this.onKeyDown, |
---|
117 | scope: this |
---|
118 | }); |
---|
119 | }, |
---|
120 | |
---|
121 | setRelayTo: function(relayTo){ |
---|
122 | this.relayTo = relayTo ? Ext.a11y.FocusMgr.get(relayTo) : null; |
---|
123 | }, |
---|
124 | |
---|
125 | setNoFrame: function(noFrame){ |
---|
126 | this.noFrame = (noFrame === true) ? true : false; |
---|
127 | }, |
---|
128 | |
---|
129 | setFrameEl: function(frameEl){ |
---|
130 | this.frameEl = frameEl && Ext.get(frameEl) || this.el; |
---|
131 | }, |
---|
132 | |
---|
133 | setComponent: function(cmp){ |
---|
134 | this.component = cmp || null; |
---|
135 | }, |
---|
136 | |
---|
137 | onKeyDown: function(e, t){ |
---|
138 | var k = e.getKey(), SK = Ext.a11y.Focusable.SpecialKeys, ret, tf; |
---|
139 | |
---|
140 | tf = (t !== this.el.dom) ? Ext.a11y.FocusMgr.get(t, true) : this; |
---|
141 | if (!tf) { |
---|
142 | // this can happen when you are on a focused item within a panel body |
---|
143 | // that is not a Ext.a11y.Focusable |
---|
144 | tf = Ext.a11y.FocusMgr.get(Ext.fly(t).parent('.x-a11y-focusable')); |
---|
145 | } |
---|
146 | |
---|
147 | if (SK[k] !== undefined) { |
---|
148 | ret = this.fireEvent(SK[k], e, t, tf, this); |
---|
149 | } |
---|
150 | if (ret === false || this.fireEvent('keydown', e, t, tf, this) === false) { |
---|
151 | e.stopEvent(); |
---|
152 | } |
---|
153 | }, |
---|
154 | |
---|
155 | focus: function(){ |
---|
156 | this.el.dom.focus(); |
---|
157 | }, |
---|
158 | |
---|
159 | blur: function(){ |
---|
160 | this.el.dom.blur(); |
---|
161 | }, |
---|
162 | |
---|
163 | onFocus: function(e, t){ |
---|
164 | this.el.addClass('x-a11y-focused'); |
---|
165 | if (this.relayTo) { |
---|
166 | this.relayTo.el.addClass('x-a11y-focused-relay'); |
---|
167 | if (!this.relayTo.noFrame) { |
---|
168 | Ext.a11y.FocusFrame.frame(this.relayTo.frameEl); |
---|
169 | } |
---|
170 | if (!this.noFrame) { |
---|
171 | Ext.a11y.RelayFrame.frame(this.frameEl); |
---|
172 | } |
---|
173 | } |
---|
174 | else { |
---|
175 | if (!this.noFrame) { |
---|
176 | Ext.a11y.FocusFrame.frame(this.frameEl); |
---|
177 | } |
---|
178 | } |
---|
179 | |
---|
180 | this.fireEvent('focus', e, t, this); |
---|
181 | }, |
---|
182 | |
---|
183 | onBlur: function(e, t){ |
---|
184 | if (this.relayTo) { |
---|
185 | this.relayTo.el.removeClass('x-a11y-focused-relay'); |
---|
186 | Ext.a11y.RelayFrame.unframe(); |
---|
187 | } |
---|
188 | this.el.removeClass('x-a11y-focused'); |
---|
189 | Ext.a11y.FocusFrame.unframe(); |
---|
190 | this.fireEvent('blur', e, t, this); |
---|
191 | }, |
---|
192 | |
---|
193 | destroy: function(){ |
---|
194 | this.el.un('keydown', this.onKeyDown); |
---|
195 | this.el.un('focus', this.onFocus); |
---|
196 | this.el.un('blur', this.onBlur); |
---|
197 | this.el.removeClass('x-a11y-focusable'); |
---|
198 | this.el.removeClass('x-a11y-focused'); |
---|
199 | if (this.relayTo) { |
---|
200 | this.relayTo.el.removeClass('x-a11y-focused-relay'); |
---|
201 | } |
---|
202 | } |
---|
203 | }); |
---|
204 | |
---|
205 | Ext.a11y.FocusItem = Ext.extend(Object, { |
---|
206 | constructor: function(el, enableTabbing){ |
---|
207 | Ext.a11y.FocusItem.superclass.constructor.call(this); |
---|
208 | |
---|
209 | this.el = Ext.get(el); |
---|
210 | this.fi = new Ext.a11y.Focusable(el); |
---|
211 | this.fi.setComponent(this); |
---|
212 | |
---|
213 | this.fi.on('tab', this.onTab, this); |
---|
214 | |
---|
215 | this.enableTabbing = enableTabbing === true ? true : false; |
---|
216 | }, |
---|
217 | |
---|
218 | getEnterItem: function(){ |
---|
219 | if (this.enableTabbing) { |
---|
220 | var items = this.getFocusItems(); |
---|
221 | if (items && items.length) { |
---|
222 | return items[0]; |
---|
223 | } |
---|
224 | } |
---|
225 | }, |
---|
226 | |
---|
227 | getFocusItems: function(){ |
---|
228 | if (this.enableTabbing) { |
---|
229 | return this.el.query('a, button, input, select'); |
---|
230 | } |
---|
231 | return null; |
---|
232 | }, |
---|
233 | |
---|
234 | onTab: function(e, t){ |
---|
235 | var items = this.getFocusItems(), i; |
---|
236 | |
---|
237 | if (items && items.length && (i = items.indexOf(t)) !== -1) { |
---|
238 | if (e.shiftKey && i > 0) { |
---|
239 | e.stopEvent(); |
---|
240 | items[i - 1].focus(); |
---|
241 | Ext.a11y.FocusFrame.frame.defer(20, Ext.a11y.FocusFrame, [this.el]); |
---|
242 | return; |
---|
243 | } |
---|
244 | else |
---|
245 | if (!e.shiftKey && i < items.length - 1) { |
---|
246 | e.stopEvent(); |
---|
247 | items[i + 1].focus(); |
---|
248 | Ext.a11y.FocusFrame.frame.defer(20, Ext.a11y.FocusFrame, [this.el]); |
---|
249 | return; |
---|
250 | } |
---|
251 | } |
---|
252 | }, |
---|
253 | |
---|
254 | focus: function(){ |
---|
255 | if (this.enableTabbing) { |
---|
256 | var items = this.getFocusItems(); |
---|
257 | if (items && items.length) { |
---|
258 | items[0].focus(); |
---|
259 | Ext.a11y.FocusFrame.frame.defer(20, Ext.a11y.FocusFrame, [this.el]); |
---|
260 | return; |
---|
261 | } |
---|
262 | } |
---|
263 | this.fi.focus(); |
---|
264 | }, |
---|
265 | |
---|
266 | blur: function(){ |
---|
267 | this.fi.blur(); |
---|
268 | } |
---|
269 | }); |
---|
270 | |
---|
271 | Ext.a11y.FocusMgr = function(){ |
---|
272 | var all = new Ext.util.MixedCollection(); |
---|
273 | |
---|
274 | return { |
---|
275 | register: function(f){ |
---|
276 | all.add(f.el && Ext.id(f.el), f); |
---|
277 | }, |
---|
278 | |
---|
279 | unregister: function(f){ |
---|
280 | all.remove(f); |
---|
281 | }, |
---|
282 | |
---|
283 | get: function(el, noCreate){ |
---|
284 | return all.get(Ext.id(el)) || (noCreate ? false : new Ext.a11y.Focusable(el)); |
---|
285 | }, |
---|
286 | |
---|
287 | all: all |
---|
288 | } |
---|
289 | }(); |
---|
290 | |
---|
291 | Ext.a11y.Focusable.SpecialKeys = {}; |
---|
292 | Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.LEFT] = 'left'; |
---|
293 | Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.RIGHT] = 'right'; |
---|
294 | Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.DOWN] = 'down'; |
---|
295 | Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.UP] = 'up'; |
---|
296 | Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.ESC] = 'esc'; |
---|
297 | Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.ENTER] = 'enter'; |
---|
298 | Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.SPACE] = 'space'; |
---|
299 | Ext.a11y.Focusable.SpecialKeys[Ext.EventObjectImpl.prototype.TAB] = 'tab'; |
---|
300 | |
---|
301 | // we use the new observeClass method to fire our new initFocus method on components |
---|
302 | Ext.util.Observable.observeClass(Ext.Component); |
---|
303 | Ext.Component.on('render', function(cmp){ |
---|
304 | cmp.initFocus(); |
---|
305 | cmp.initARIA(); |
---|
306 | }); |
---|
307 | Ext.override(Ext.Component, { |
---|
308 | initFocus: Ext.emptyFn, |
---|
309 | initARIA: Ext.emptyFn |
---|
310 | }); |
---|
311 | |
---|
312 | Ext.override(Ext.Container, { |
---|
313 | isFocusable: true, |
---|
314 | noFocus: false, |
---|
315 | |
---|
316 | // private |
---|
317 | initFocus: function(){ |
---|
318 | if (!this.fi && !this.noFocus) { |
---|
319 | this.fi = new Ext.a11y.Focusable(this); |
---|
320 | } |
---|
321 | this.mon(this.fi, { |
---|
322 | focus: this.onFocus, |
---|
323 | blur: this.onBlur, |
---|
324 | tab: this.onTab, |
---|
325 | enter: this.onEnter, |
---|
326 | esc: this.onEsc, |
---|
327 | scope: this |
---|
328 | }); |
---|
329 | |
---|
330 | if (this.hidden) { |
---|
331 | this.isFocusable = false; |
---|
332 | } |
---|
333 | |
---|
334 | this.on('show', function(){ |
---|
335 | this.isFocusable = true; |
---|
336 | }, this); |
---|
337 | this.on('hide', function(){ |
---|
338 | this.isFocusable = false; |
---|
339 | }, this); |
---|
340 | }, |
---|
341 | |
---|
342 | focus: function(){ |
---|
343 | this.fi.focus(); |
---|
344 | }, |
---|
345 | |
---|
346 | blur: function(){ |
---|
347 | this.fi.blur(); |
---|
348 | }, |
---|
349 | |
---|
350 | enter: function(){ |
---|
351 | var eitem = this.getEnterItem(); |
---|
352 | if (eitem) { |
---|
353 | eitem.focus(); |
---|
354 | } |
---|
355 | }, |
---|
356 | |
---|
357 | onFocus: Ext.emptyFn, |
---|
358 | onBlur: Ext.emptyFn, |
---|
359 | |
---|
360 | onTab: function(e, t, tf){ |
---|
361 | var rf = tf.relayTo || tf; |
---|
362 | if (rf.component && rf.component !== this) { |
---|
363 | e.stopEvent(); |
---|
364 | var item = e.shiftKey ? this.getPreviousFocus(rf.component) : this.getNextFocus(rf.component); |
---|
365 | item.focus(); |
---|
366 | } |
---|
367 | }, |
---|
368 | |
---|
369 | onEnter: function(e, t, tf){ |
---|
370 | // check to see if enter is pressed while "on" the panel |
---|
371 | if (tf.component && tf.component === this) { |
---|
372 | e.stopEvent(); |
---|
373 | this.enter(); |
---|
374 | } |
---|
375 | e.stopPropagation(); |
---|
376 | }, |
---|
377 | |
---|
378 | onEsc: function(e, t){ |
---|
379 | e.preventDefault(); |
---|
380 | |
---|
381 | // check to see if esc is pressed while "inside" the panel |
---|
382 | // or while "on" the panel |
---|
383 | if (t === this.el.dom) { |
---|
384 | // "on" the panel, check if this panel has an owner panel and focus that |
---|
385 | // we dont stop the event in this case so that this same check will be |
---|
386 | // done for this ownerCt |
---|
387 | if (this.ownerCt) { |
---|
388 | this.ownerCt.focus(); |
---|
389 | } |
---|
390 | } |
---|
391 | else { |
---|
392 | // we were inside the panel when esc was pressed, |
---|
393 | // so go back "on" the panel |
---|
394 | if (this.ownerCt && this.ownerCt.isFocusable) { |
---|
395 | var si = this.ownerCt.getFocusItems(); |
---|
396 | |
---|
397 | if (si && si.getCount() > 1) { |
---|
398 | e.stopEvent(); |
---|
399 | } |
---|
400 | } |
---|
401 | this.focus(); |
---|
402 | } |
---|
403 | }, |
---|
404 | |
---|
405 | getFocusItems: function(){ |
---|
406 | return this.items && |
---|
407 | this.items.filterBy(function(o){ |
---|
408 | return o.isFocusable; |
---|
409 | }) || |
---|
410 | null; |
---|
411 | }, |
---|
412 | |
---|
413 | getEnterItem: function(){ |
---|
414 | var ci = this.getFocusItems(), length = ci ? ci.getCount() : 0; |
---|
415 | |
---|
416 | if (length === 1) { |
---|
417 | return ci.first().getEnterItem && ci.first().getEnterItem() || ci.first(); |
---|
418 | } |
---|
419 | else |
---|
420 | if (length > 1) { |
---|
421 | return ci.first(); |
---|
422 | } |
---|
423 | }, |
---|
424 | |
---|
425 | getNextFocus: function(current){ |
---|
426 | var items = this.getFocusItems(), next = current, i = items.indexOf(current), length = items.getCount(); |
---|
427 | |
---|
428 | if (i === length - 1) { |
---|
429 | next = items.first(); |
---|
430 | } |
---|
431 | else { |
---|
432 | next = items.get(i + 1); |
---|
433 | } |
---|
434 | return next; |
---|
435 | }, |
---|
436 | |
---|
437 | getPreviousFocus: function(current){ |
---|
438 | var items = this.getFocusItems(), prev = current, i = items.indexOf(current), length = items.getCount(); |
---|
439 | |
---|
440 | if (i === 0) { |
---|
441 | prev = items.last(); |
---|
442 | } |
---|
443 | else { |
---|
444 | prev = items.get(i - 1); |
---|
445 | } |
---|
446 | return prev; |
---|
447 | }, |
---|
448 | |
---|
449 | getFocusable : function() { |
---|
450 | return this.fi; |
---|
451 | } |
---|
452 | }); |
---|
453 | |
---|
454 | Ext.override(Ext.Panel, { |
---|
455 | /** |
---|
456 | * @cfg {Boolean} enableTabbing <tt>true</tt> to enable tabbing. Default is <tt>false</tt>. |
---|
457 | */ |
---|
458 | getFocusItems: function(){ |
---|
459 | // items gets all the items inside the body |
---|
460 | var items = Ext.Panel.superclass.getFocusItems.call(this), bodyFocus = null; |
---|
461 | |
---|
462 | if (!items) { |
---|
463 | items = new Ext.util.MixedCollection(); |
---|
464 | this.bodyFocus = this.bodyFocus || new Ext.a11y.FocusItem(this.body, this.enableTabbing); |
---|
465 | items.add('body', this.bodyFocus); |
---|
466 | } |
---|
467 | // but panels can also have tbar, bbar, fbar |
---|
468 | if (this.tbar && this.topToolbar) { |
---|
469 | items.insert(0, this.topToolbar); |
---|
470 | } |
---|
471 | if (this.bbar && this.bottomToolbar) { |
---|
472 | items.add(this.bottomToolbar); |
---|
473 | } |
---|
474 | if (this.fbar) { |
---|
475 | items.add(this.fbar); |
---|
476 | } |
---|
477 | |
---|
478 | return items; |
---|
479 | } |
---|
480 | }); |
---|
481 | |
---|
482 | Ext.override(Ext.TabPanel, { |
---|
483 | // private |
---|
484 | initFocus: function(){ |
---|
485 | Ext.TabPanel.superclass.initFocus.call(this); |
---|
486 | this.mon(this.fi, { |
---|
487 | left: this.onLeft, |
---|
488 | right: this.onRight, |
---|
489 | scope: this |
---|
490 | }); |
---|
491 | }, |
---|
492 | |
---|
493 | onLeft: function(e){ |
---|
494 | if (!this.activeTab) { |
---|
495 | return; |
---|
496 | } |
---|
497 | e.stopEvent(); |
---|
498 | var prev = this.items.itemAt(this.items.indexOf(this.activeTab) - 1); |
---|
499 | if (prev) { |
---|
500 | this.setActiveTab(prev); |
---|
501 | } |
---|
502 | return false; |
---|
503 | }, |
---|
504 | |
---|
505 | onRight: function(e){ |
---|
506 | if (!this.activeTab) { |
---|
507 | return; |
---|
508 | } |
---|
509 | e.stopEvent(); |
---|
510 | var next = this.items.itemAt(this.items.indexOf(this.activeTab) + 1); |
---|
511 | if (next) { |
---|
512 | this.setActiveTab(next); |
---|
513 | } |
---|
514 | return false; |
---|
515 | } |
---|
516 | }); |
---|
517 | |
---|
518 | Ext.override(Ext.tree.TreeNodeUI, { |
---|
519 | // private |
---|
520 | focus: function(){ |
---|
521 | this.node.getOwnerTree().bodyFocus.focus(); |
---|
522 | } |
---|
523 | }); |
---|
524 | |
---|
525 | Ext.override(Ext.tree.TreePanel, { |
---|
526 | // private |
---|
527 | afterRender : function(){ |
---|
528 | Ext.tree.TreePanel.superclass.afterRender.call(this); |
---|
529 | this.root.render(); |
---|
530 | if(!this.rootVisible){ |
---|
531 | this.root.renderChildren(); |
---|
532 | } |
---|
533 | this.bodyFocus = new Ext.a11y.FocusItem(this.body.down('.x-tree-root-ct')); |
---|
534 | this.bodyFocus.fi.setFrameEl(this.body); |
---|
535 | } |
---|
536 | }); |
---|
537 | |
---|
538 | Ext.override(Ext.grid.GridPanel, { |
---|
539 | initFocus: function(){ |
---|
540 | Ext.grid.GridPanel.superclass.initFocus.call(this); |
---|
541 | this.bodyFocus = new Ext.a11y.FocusItem(this.view.focusEl); |
---|
542 | this.bodyFocus.fi.setFrameEl(this.body); |
---|
543 | } |
---|
544 | }); |
---|
545 | |
---|
546 | Ext.override(Ext.Button, { |
---|
547 | isFocusable: true, |
---|
548 | noFocus: false, |
---|
549 | |
---|
550 | initFocus: function(){ |
---|
551 | Ext.Button.superclass.initFocus.call(this); |
---|
552 | this.fi = this.fi || new Ext.a11y.Focusable(this.btnEl, null, null, this.el); |
---|
553 | this.fi.setComponent(this); |
---|
554 | |
---|
555 | this.mon(this.fi, { |
---|
556 | focus: this.onFocus, |
---|
557 | blur: this.onBlur, |
---|
558 | scope: this |
---|
559 | }); |
---|
560 | |
---|
561 | if (this.menu) { |
---|
562 | this.mon(this.fi, 'down', this.showMenu, this); |
---|
563 | this.on('menuhide', this.focus, this); |
---|
564 | } |
---|
565 | |
---|
566 | if (this.hidden) { |
---|
567 | this.isFocusable = false; |
---|
568 | } |
---|
569 | |
---|
570 | this.on('show', function(){ |
---|
571 | this.isFocusable = true; |
---|
572 | }, this); |
---|
573 | this.on('hide', function(){ |
---|
574 | this.isFocusable = false; |
---|
575 | }, this); |
---|
576 | }, |
---|
577 | |
---|
578 | focus: function(){ |
---|
579 | this.fi.focus(); |
---|
580 | }, |
---|
581 | |
---|
582 | blur: function(){ |
---|
583 | this.fi.blur(); |
---|
584 | }, |
---|
585 | |
---|
586 | onFocus: function(){ |
---|
587 | if (!this.disabled) { |
---|
588 | this.el.addClass("x-btn-focus"); |
---|
589 | } |
---|
590 | }, |
---|
591 | |
---|
592 | onBlur: function(){ |
---|
593 | this.el.removeClass("x-btn-focus"); |
---|
594 | } |
---|
595 | }); |
---|
596 | |
---|
597 | Ext.override(Ext.Toolbar, { |
---|
598 | initFocus: function(){ |
---|
599 | Ext.Toolbar.superclass.initFocus.call(this); |
---|
600 | this.mon(this.fi, { |
---|
601 | left: this.onLeft, |
---|
602 | right: this.onRight, |
---|
603 | scope: this |
---|
604 | }); |
---|
605 | |
---|
606 | this.on('focus', this.onButtonFocus, this, { |
---|
607 | stopEvent: true |
---|
608 | }); |
---|
609 | }, |
---|
610 | |
---|
611 | addItem: function(item){ |
---|
612 | Ext.Toolbar.superclass.add.apply(this, arguments); |
---|
613 | if (item.rendered && item.fi !== undefined) { |
---|
614 | item.fi.setRelayTo(this.el); |
---|
615 | this.relayEvents(item.fi, ['focus']); |
---|
616 | } |
---|
617 | else { |
---|
618 | item.on('render', function(){ |
---|
619 | if (item.fi !== undefined) { |
---|
620 | item.fi.setRelayTo(this.el); |
---|
621 | this.relayEvents(item.fi, ['focus']); |
---|
622 | } |
---|
623 | }, this, { |
---|
624 | single: true |
---|
625 | }); |
---|
626 | } |
---|
627 | return item; |
---|
628 | }, |
---|
629 | |
---|
630 | onFocus: function(){ |
---|
631 | var items = this.getFocusItems(); |
---|
632 | if (items && items.getCount() > 0) { |
---|
633 | if (this.lastFocus && items.indexOf(this.lastFocus) !== -1) { |
---|
634 | this.lastFocus.focus(); |
---|
635 | } |
---|
636 | else { |
---|
637 | items.first().focus(); |
---|
638 | } |
---|
639 | } |
---|
640 | }, |
---|
641 | |
---|
642 | onButtonFocus: function(e, t, tf){ |
---|
643 | this.lastFocus = tf.component || null; |
---|
644 | }, |
---|
645 | |
---|
646 | onLeft: function(e, t, tf){ |
---|
647 | e.stopEvent(); |
---|
648 | this.getPreviousFocus(tf.component).focus(); |
---|
649 | }, |
---|
650 | |
---|
651 | onRight: function(e, t, tf){ |
---|
652 | e.stopEvent(); |
---|
653 | this.getNextFocus(tf.component).focus(); |
---|
654 | }, |
---|
655 | |
---|
656 | getEnterItem: Ext.emptyFn, |
---|
657 | onTab: Ext.emptyFn, |
---|
658 | onEsc: Ext.emptyFn |
---|
659 | }); |
---|
660 | |
---|
661 | Ext.override(Ext.menu.BaseItem, { |
---|
662 | initFocus: function(){ |
---|
663 | this.fi = new Ext.a11y.Focusable(this, this.parentMenu && this.parentMenu.el || null, true); |
---|
664 | } |
---|
665 | }); |
---|
666 | |
---|
667 | Ext.override(Ext.menu.Menu, { |
---|
668 | initFocus: function(){ |
---|
669 | this.fi = new Ext.a11y.Focusable(this); |
---|
670 | this.focusEl = this.fi; |
---|
671 | } |
---|
672 | }); |
---|
673 | |
---|
674 | Ext.a11y.WindowMgr = new Ext.WindowGroup(); |
---|
675 | |
---|
676 | Ext.apply(Ext.WindowMgr, { |
---|
677 | bringToFront: function(win){ |
---|
678 | Ext.a11y.WindowMgr.bringToFront.call(this, win); |
---|
679 | if (win.modal) { |
---|
680 | win.enter(); |
---|
681 | } |
---|
682 | else { |
---|
683 | win.focus(); |
---|
684 | } |
---|
685 | } |
---|
686 | }); |
---|
687 | |
---|
688 | Ext.override(Ext.Window, { |
---|
689 | initFocus: function(){ |
---|
690 | Ext.Window.superclass.initFocus.call(this); |
---|
691 | this.on('beforehide', function(){ |
---|
692 | Ext.a11y.RelayFrame.unframe(); |
---|
693 | Ext.a11y.FocusFrame.unframe(); |
---|
694 | }); |
---|
695 | } |
---|
696 | }); |
---|
697 | |
---|
698 | Ext.override(Ext.form.Field, { |
---|
699 | isFocusable: true, |
---|
700 | noFocus: false, |
---|
701 | |
---|
702 | initFocus: function(){ |
---|
703 | this.fi = this.fi || new Ext.a11y.Focusable(this, null, true); |
---|
704 | |
---|
705 | Ext.form.Field.superclass.initFocus.call(this); |
---|
706 | |
---|
707 | if (this.hidden) { |
---|
708 | this.isFocusable = false; |
---|
709 | } |
---|
710 | |
---|
711 | this.on('show', function(){ |
---|
712 | this.isFocusable = true; |
---|
713 | }, this); |
---|
714 | this.on('hide', function(){ |
---|
715 | this.isFocusable = false; |
---|
716 | }, this); |
---|
717 | } |
---|
718 | }); |
---|
719 | |
---|
720 | Ext.override(Ext.FormPanel, { |
---|
721 | initFocus: function(){ |
---|
722 | Ext.FormPanel.superclass.initFocus.call(this); |
---|
723 | this.on('focus', this.onFieldFocus, this, { |
---|
724 | stopEvent: true |
---|
725 | }); |
---|
726 | }, |
---|
727 | |
---|
728 | // private |
---|
729 | createForm: function(){ |
---|
730 | delete this.initialConfig.listeners; |
---|
731 | var form = new Ext.form.BasicForm(null, this.initialConfig); |
---|
732 | form.afterMethod('add', this.formItemAdd, this); |
---|
733 | return form; |
---|
734 | }, |
---|
735 | |
---|
736 | formItemAdd: function(item){ |
---|
737 | item.on('render', function(field){ |
---|
738 | field.fi.setRelayTo(this.el); |
---|
739 | this.relayEvents(field.fi, ['focus']); |
---|
740 | }, this, { |
---|
741 | single: true |
---|
742 | }); |
---|
743 | }, |
---|
744 | |
---|
745 | onFocus: function(){ |
---|
746 | var items = this.getFocusItems(); |
---|
747 | if (items && items.getCount() > 0) { |
---|
748 | if (this.lastFocus && items.indexOf(this.lastFocus) !== -1) { |
---|
749 | this.lastFocus.focus(); |
---|
750 | } |
---|
751 | else { |
---|
752 | items.first().focus(); |
---|
753 | } |
---|
754 | } |
---|
755 | }, |
---|
756 | |
---|
757 | onFieldFocus: function(e, t, tf){ |
---|
758 | this.lastFocus = tf.component || null; |
---|
759 | }, |
---|
760 | |
---|
761 | onTab: function(e, t, tf){ |
---|
762 | if (tf.relayTo.component === this) { |
---|
763 | var item = e.shiftKey ? this.getPreviousFocus(tf.component) : this.getNextFocus(tf.component); |
---|
764 | |
---|
765 | if (item) { |
---|
766 | ev.stopEvent(); |
---|
767 | item.focus(); |
---|
768 | return; |
---|
769 | } |
---|
770 | } |
---|
771 | Ext.FormPanel.superclass.onTab.apply(this, arguments); |
---|
772 | }, |
---|
773 | |
---|
774 | getNextFocus: function(current){ |
---|
775 | var items = this.getFocusItems(), i = items.indexOf(current), length = items.getCount(); |
---|
776 | |
---|
777 | return (i < length - 1) ? items.get(i + 1) : false; |
---|
778 | }, |
---|
779 | |
---|
780 | getPreviousFocus: function(current){ |
---|
781 | var items = this.getFocusItems(), i = items.indexOf(current), length = items.getCount(); |
---|
782 | |
---|
783 | return (i > 0) ? items.get(i - 1) : false; |
---|
784 | } |
---|
785 | }); |
---|
786 | |
---|
787 | Ext.override(Ext.Viewport, { |
---|
788 | initFocus: function(){ |
---|
789 | Ext.Viewport.superclass.initFocus.apply(this); |
---|
790 | this.mon(Ext.get(document), 'focus', this.focus, this); |
---|
791 | this.mon(Ext.get(document), 'blur', this.blur, this); |
---|
792 | this.fi.setNoFrame(true); |
---|
793 | }, |
---|
794 | |
---|
795 | onTab: function(e, t, tf, f){ |
---|
796 | e.stopEvent(); |
---|
797 | |
---|
798 | if (tf === f) { |
---|
799 | items = this.getFocusItems(); |
---|
800 | if (items && items.getCount() > 0) { |
---|
801 | items.first().focus(); |
---|
802 | } |
---|
803 | } |
---|
804 | else { |
---|
805 | var rf = tf.relayTo || tf; |
---|
806 | var item = e.shiftKey ? this.getPreviousFocus(rf.component) : this.getNextFocus(rf.component); |
---|
807 | item.focus(); |
---|
808 | } |
---|
809 | } |
---|
810 | }); |
---|
811 | |
---|
812 | })(); |
---|