Merge branch 'MDL-35926_alt_c' of git://github.com/rwijaya/moodle

This commit is contained in:
Sam Hemelryk 2013-10-08 08:27:46 +13:00
commit 81a939be02
4 changed files with 130 additions and 7 deletions

View File

@ -41,7 +41,8 @@ var DIALOGUE_NAME = 'Moodle dialogue',
DIALOGUE_FULLSCREEN_CLASS = DIALOGUE_PREFIX + '-fullscreen',
DIALOGUE_HIDDEN_CLASS = DIALOGUE_PREFIX + '-hidden',
DIALOGUE_SELECTOR =' [role=dialog]',
MENUBAR_SELECTOR = '[role=menubar]';
MENUBAR_SELECTOR = '[role=menubar]',
CAN_RECEIVE_FOCUS_SELECTOR = 'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]';
/**
* A re-usable dialogue box with Moodle classes applied.
@ -143,6 +144,7 @@ Y.extend(DIALOGUE, Y.Panel, {
// been positioned it will scroll back to the top of the page.
if (config.visible) {
this.show();
this.keyDelegation();
}
},
@ -198,10 +200,11 @@ Y.extend(DIALOGUE, Y.Panel, {
* @return void
*/
visibilityChanged : function(e) {
var titlebar;
var titlebar, bb;
if (e.attrName === 'visible') {
this.get('maskNode').addClass(CSS.LIGHTBOX);
if (e.prevVal && !e.newVal) {
bb = this.get('boundingBox');
if (this._resizeevent) {
this._resizeevent.detach();
this._resizeevent = null;
@ -210,6 +213,7 @@ Y.extend(DIALOGUE, Y.Panel, {
this._orientationevent.detach();
this._orientationevent = null;
}
bb.detach('key', this.keyDelegation);
}
if (!e.prevVal && e.newVal) {
// This needs to be done each time the dialog is shown as new dialogs may have been opened.
@ -223,6 +227,7 @@ Y.extend(DIALOGUE, Y.Panel, {
Y.one(titlebar).setStyle('cursor', 'move');
}
}
this.keyDelegation();
}
if (this.get('center') && !e.prevVal && e.newVal) {
this.centerDialogue();
@ -326,6 +331,42 @@ Y.extend(DIALOGUE, Y.Panel, {
content.focus();
}
return result;
},
/**
* Setup key delegation to keep tabbing within the open dialogue.
*
* @method keyDelegation
*/
keyDelegation : function() {
var bb = this.get('boundingBox');
bb.delegate('key', function(e){
var target = e.target;
var direction = 'forward';
if (e.shiftKey) {
direction = 'backward';
}
if (this.trapFocus(target, direction)) {
e.preventDefault();
}
}, 'down:9', CAN_RECEIVE_FOCUS_SELECTOR, this);
},
/**
* Trap the tab focus within the open modal.
*
* @param string target the element target
* @param string direction tab key for forward and tab+shift for backward
* @returns bool
*/
trapFocus : function(target, direction) {
var bb = this.get('boundingBox'),
firstitem = bb.one(CAN_RECEIVE_FOCUS_SELECTOR),
lastitem = bb.all(CAN_RECEIVE_FOCUS_SELECTOR).pop();
if (target === lastitem && direction === 'forward') { // Tab key.
return firstitem.focus();
} else if (target === firstitem && direction === 'backward') { // Tab+shift key.
return lastitem.focus();
}
}
}, {
NAME : DIALOGUE_NAME,

File diff suppressed because one or more lines are too long

View File

@ -41,7 +41,8 @@ var DIALOGUE_NAME = 'Moodle dialogue',
DIALOGUE_FULLSCREEN_CLASS = DIALOGUE_PREFIX + '-fullscreen',
DIALOGUE_HIDDEN_CLASS = DIALOGUE_PREFIX + '-hidden',
DIALOGUE_SELECTOR =' [role=dialog]',
MENUBAR_SELECTOR = '[role=menubar]';
MENUBAR_SELECTOR = '[role=menubar]',
CAN_RECEIVE_FOCUS_SELECTOR = 'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]';
/**
* A re-usable dialogue box with Moodle classes applied.
@ -143,6 +144,7 @@ Y.extend(DIALOGUE, Y.Panel, {
// been positioned it will scroll back to the top of the page.
if (config.visible) {
this.show();
this.keyDelegation();
}
},
@ -198,10 +200,11 @@ Y.extend(DIALOGUE, Y.Panel, {
* @return void
*/
visibilityChanged : function(e) {
var titlebar;
var titlebar, bb;
if (e.attrName === 'visible') {
this.get('maskNode').addClass(CSS.LIGHTBOX);
if (e.prevVal && !e.newVal) {
bb = this.get('boundingBox');
if (this._resizeevent) {
this._resizeevent.detach();
this._resizeevent = null;
@ -210,6 +213,7 @@ Y.extend(DIALOGUE, Y.Panel, {
this._orientationevent.detach();
this._orientationevent = null;
}
bb.detach('key', this.keyDelegation);
}
if (!e.prevVal && e.newVal) {
// This needs to be done each time the dialog is shown as new dialogs may have been opened.
@ -223,6 +227,7 @@ Y.extend(DIALOGUE, Y.Panel, {
Y.one(titlebar).setStyle('cursor', 'move');
}
}
this.keyDelegation();
}
if (this.get('center') && !e.prevVal && e.newVal) {
this.centerDialogue();
@ -326,6 +331,42 @@ Y.extend(DIALOGUE, Y.Panel, {
content.focus();
}
return result;
},
/**
* Setup key delegation to keep tabbing within the open dialogue.
*
* @method keyDelegation
*/
keyDelegation : function() {
var bb = this.get('boundingBox');
bb.delegate('key', function(e){
var target = e.target;
var direction = 'forward';
if (e.shiftKey) {
direction = 'backward';
}
if (this.trapFocus(target, direction)) {
e.preventDefault();
}
}, 'down:9', CAN_RECEIVE_FOCUS_SELECTOR, this);
},
/**
* Trap the tab focus within the open modal.
*
* @param string target the element target
* @param string direction tab key for forward and tab+shift for backward
* @returns bool
*/
trapFocus : function(target, direction) {
var bb = this.get('boundingBox'),
firstitem = bb.one(CAN_RECEIVE_FOCUS_SELECTOR),
lastitem = bb.all(CAN_RECEIVE_FOCUS_SELECTOR).pop();
if (target === lastitem && direction === 'forward') { // Tab key.
return firstitem.focus();
} else if (target === firstitem && direction === 'backward') { // Tab+shift key.
return lastitem.focus();
}
}
}, {
NAME : DIALOGUE_NAME,

View File

@ -10,7 +10,8 @@ var DIALOGUE_NAME = 'Moodle dialogue',
DIALOGUE_FULLSCREEN_CLASS = DIALOGUE_PREFIX + '-fullscreen',
DIALOGUE_HIDDEN_CLASS = DIALOGUE_PREFIX + '-hidden',
DIALOGUE_SELECTOR =' [role=dialog]',
MENUBAR_SELECTOR = '[role=menubar]';
MENUBAR_SELECTOR = '[role=menubar]',
CAN_RECEIVE_FOCUS_SELECTOR = 'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]';
/**
* A re-usable dialogue box with Moodle classes applied.
@ -112,6 +113,7 @@ Y.extend(DIALOGUE, Y.Panel, {
// been positioned it will scroll back to the top of the page.
if (config.visible) {
this.show();
this.keyDelegation();
}
},
@ -167,10 +169,11 @@ Y.extend(DIALOGUE, Y.Panel, {
* @return void
*/
visibilityChanged : function(e) {
var titlebar;
var titlebar, bb;
if (e.attrName === 'visible') {
this.get('maskNode').addClass(CSS.LIGHTBOX);
if (e.prevVal && !e.newVal) {
bb = this.get('boundingBox');
if (this._resizeevent) {
this._resizeevent.detach();
this._resizeevent = null;
@ -179,6 +182,7 @@ Y.extend(DIALOGUE, Y.Panel, {
this._orientationevent.detach();
this._orientationevent = null;
}
bb.detach('key', this.keyDelegation);
}
if (!e.prevVal && e.newVal) {
// This needs to be done each time the dialog is shown as new dialogs may have been opened.
@ -192,6 +196,7 @@ Y.extend(DIALOGUE, Y.Panel, {
Y.one(titlebar).setStyle('cursor', 'move');
}
}
this.keyDelegation();
}
if (this.get('center') && !e.prevVal && e.newVal) {
this.centerDialogue();
@ -295,6 +300,42 @@ Y.extend(DIALOGUE, Y.Panel, {
content.focus();
}
return result;
},
/**
* Setup key delegation to keep tabbing within the open dialogue.
*
* @method keyDelegation
*/
keyDelegation : function() {
var bb = this.get('boundingBox');
bb.delegate('key', function(e){
var target = e.target;
var direction = 'forward';
if (e.shiftKey) {
direction = 'backward';
}
if (this.trapFocus(target, direction)) {
e.preventDefault();
}
}, 'down:9', CAN_RECEIVE_FOCUS_SELECTOR, this);
},
/**
* Trap the tab focus within the open modal.
*
* @param string target the element target
* @param string direction tab key for forward and tab+shift for backward
* @returns bool
*/
trapFocus : function(target, direction) {
var bb = this.get('boundingBox'),
firstitem = bb.one(CAN_RECEIVE_FOCUS_SELECTOR),
lastitem = bb.all(CAN_RECEIVE_FOCUS_SELECTOR).pop();
if (target === lastitem && direction === 'forward') { // Tab key.
return firstitem.focus();
} else if (target === firstitem && direction === 'backward') { // Tab+shift key.
return lastitem.focus();
}
}
}, {
NAME : DIALOGUE_NAME,