diff --git a/lib/form/filemanager.js b/lib/form/filemanager.js index fa0c62e3e53..91cf8c11188 100644 --- a/lib/form/filemanager.js +++ b/lib/form/filemanager.js @@ -255,6 +255,7 @@ M.form_filemanager.init = function(Y, options) { this.msg_dlg_node.one('.fp-msg-butok').on('click', function(e) { e.preventDefault(); this.msg_dlg.hide(); + this.detachKeyDelegation(this.msg_dlg); }, this); } @@ -262,6 +263,7 @@ M.form_filemanager.init = function(Y, options) { this.msg_dlg_node.removeClass('fp-msg-info').removeClass('fp-msg-error').addClass('fp-msg-'+type) this.msg_dlg_node.one('.fp-msg-text').setContent(Y.Escape.html(msg)); this.msg_dlg.show(); + this.keyDelegation(this.msg_dlg); }, is_disabled: function() { return this.filemanager.ancestor('.fitem.disabled') != null; @@ -330,6 +332,7 @@ M.form_filemanager.init = function(Y, options) { node.all('.fp-dlg-curpath').set('id', 'fm-curpath-'+this.client_id); } this.mkdir_dialog.show(); + this.keyDelegation(this.mkdir_dialog); Y.one('#fm-newname-'+scope.client_id).focus(); Y.all('#fm-curpath-'+scope.client_id).setContent(Y.Escape.html(this.currentpath)) }, this); @@ -685,6 +688,7 @@ M.form_filemanager.init = function(Y, options) { if (!action) { // no changes this.selectui.hide(); + this.detachKeyDelegation(this.selectui); return; } selectnode.addClass('loading'); @@ -730,6 +734,7 @@ M.form_filemanager.init = function(Y, options) { var dlgopt = this.confirm_dlg.dlgopt; ev.preventDefault(); this.confirm_dlg.hide(); + this.detachKeyDelegation(this.confirm_dlg); if (dlgopt.callback) { if (dlgopt.callbackargs) { dlgopt.callback.apply(dlgopt.scope || this, dlgopt.callbackargs); @@ -741,6 +746,7 @@ M.form_filemanager.init = function(Y, options) { var handle_cancel = function(ev) { ev.preventDefault(); this.confirm_dlg.hide(); + this.detachKeyDelegation(this.confirm_dlg); } node.one('.fp-dlg-butconfirm').on('click', handle_confirm, this); node.one('.fp-dlg-butcancel').on('click', handle_cancel, this); @@ -748,6 +754,7 @@ M.form_filemanager.init = function(Y, options) { this.confirm_dlg.dlgopt = dialog_options; this.confirm_dlg_node.one('.fp-dlg-text').setContent(dialog_options.message); this.confirm_dlg.show(); + this.keyDelegation(this.confirm_dlg); }, setup_select_file: function() { var selectnode = this.selectnode; @@ -884,6 +891,7 @@ M.form_filemanager.init = function(Y, options) { e.preventDefault(); // TODO if changed asked to confirm, the same with close button this.selectui.hide(); + this.detachKeyDelegation(this.selectui); }, this); }, get_parent_folder_name: function(node) { @@ -1002,11 +1010,37 @@ M.form_filemanager.init = function(Y, options) { Y.one('#fm-dialog-label_'+selectnode.get('id')).setContent(Y.Escape.html(M.str.moodle.edit+' '+nodename)); // show panel this.selectui.show(); + this.keyDelegation(this.selectui); Y.one('#'+selectnode.get('id')).focus(); }, render: function() { this.print_path(); this.view_files(); + }, + keyDelegation: function (dialog) { + var bb = dialog.get('boundingBox'); + var can_receive_focus_selector = 'input:not([type="hidden"]), a[href], button, textarea, select'; + bb.delegate('key', function(e) { + var target = e.target; + var firstitem = bb.one(can_receive_focus_selector); + var lastitem = bb.all(can_receive_focus_selector).pop(); + + if (e.shiftKey) { + if (target === firstitem) { + lastitem.focus(); + e.preventDefault(); + } + } else { + if (target === lastitem) { + firstitem.focus(); + e.preventDefault(); + } + } + }, 'down:9', can_receive_focus_selector, this); + }, + detachKeyDelegation: function(dialog) { + var bb = dialog.get('boundingBox'); + bb.detach('key', this.keyDelegation); } }); diff --git a/repository/filepicker.js b/repository/filepicker.js index 1beaf56fe22..f51a62e118f 100644 --- a/repository/filepicker.js +++ b/repository/filepicker.js @@ -710,7 +710,9 @@ M.core_filepicker.init = function(Y, options) { } }, false); this.process_dlg.hide(); + this.deleteKeyDelegation(this.process_dlg); this.selectui.hide(); + this.deleteKeyDelegation(this.selectui); } if (!this.process_dlg) { this.process_dlg_node = Y.Node.createWithFilesSkin(M.core_filepicker.templates.processexistingfile); @@ -740,6 +742,7 @@ M.core_filepicker.init = function(Y, options) { this.process_dlg.dialogdata = data; this.process_dlg_node.one('.fp-dlg-butrename').setContent(M.util.get_string('renameto', 'repository', data.newfile.filename)); this.process_dlg.show(); + this.keyDelegation(this.process_dlg); }, /** displays error instead of filepicker contents */ display_error: function(errortext, errorcode) { @@ -771,6 +774,7 @@ M.core_filepicker.init = function(Y, options) { this.msg_dlg_node.one('.fp-msg-butok').on('click', function(e) { e.preventDefault(); this.msg_dlg.hide(); + this.deleteKeyDelegation(this.msg_dlg); }, this); } @@ -778,6 +782,7 @@ M.core_filepicker.init = function(Y, options) { this.msg_dlg_node.removeClass('fp-msg-info').removeClass('fp-msg-error').addClass('fp-msg-'+type) this.msg_dlg_node.one('.fp-msg-text').setContent(Y.Escape.html(msg)); this.msg_dlg.show(); + this.keyDelegation(this.msg_dlg); }, view_files: function(appenditems) { this.viewbar_set_enabled(true); @@ -897,7 +902,7 @@ M.core_filepicker.init = function(Y, options) { } }, false); }, - classnamecallback : function(node) { + classnamecallback : function(node) { var classname = ''; if (node.children) { classname = classname + ' fp-folder'; @@ -1076,6 +1081,7 @@ M.core_filepicker.init = function(Y, options) { } Y.one('#fp-file_label_'+this.options.client_id).setContent(Y.Escape.html(M.str.repository.select+' '+argstitle)); this.selectui.show(); + this.keyDelegation(this.selectui); Y.one('#'+this.selectnode.get('id')).focus(); var client_id = this.options.client_id; var selectnode = this.selectnode; @@ -1228,6 +1234,7 @@ M.core_filepicker.init = function(Y, options) { cancel.on('click', function(e) { e.preventDefault(); this.selectui.hide(); + this.deleteKeyDelegation(this.selectui); }, this); }, wait: function() { @@ -1314,6 +1321,7 @@ M.core_filepicker.init = function(Y, options) { // allow to move the panel dragging it by it's header: this.mainui.plug(Y.Plugin.Drag,{handles:['#filepicker-'+client_id+' .yui3-widget-hd']}); this.mainui.show(); + this.keyDelegation(this.mainui); if (this.mainui.get('y') < 0) { this.mainui.set('y', 0); } @@ -1337,6 +1345,7 @@ M.core_filepicker.init = function(Y, options) { this.selectui.plug(Y.Plugin.Drag,{handles:['#filepicker-select-'+client_id+' .yui3-widget-hd']}); Y.one('#'+this.selectnode.get('id')).setAttribute('aria-labelledby', fplabel); this.selectui.hide(); + this.deleteKeyDelegation(this.selectui); // event handler for lazy loading of thumbnails and next page this.fpnode.one('.fp-content').on(['scroll','resize'], this.content_scrolled, this); // save template for one path element and location of path bar @@ -1910,13 +1919,17 @@ M.core_filepicker.init = function(Y, options) { }, hide: function() { this.selectui.hide(); + this.deleteKeyDelegation(this.selectui); if (this.process_dlg) { this.process_dlg.hide(); + this.deleteKeyDelegation(this.process_dlg); } if (this.msg_dlg) { this.msg_dlg.hide(); + this.deleteKeyDelegation(this.msg_dlg); } this.mainui.hide(); + this.deleteKeyDelegation(this.mainui); }, show: function() { if (this.fpnode) { @@ -1926,6 +1939,7 @@ M.core_filepicker.init = function(Y, options) { } else { this.launch(); } + this.keyDelegation(this.mainui); }, launch: function() { this.render(); @@ -1954,6 +1968,31 @@ M.core_filepicker.init = function(Y, options) { M.util.set_user_preference('filepicker_' + name, value); this.options.userprefs[name] = value; } + }, + keyDelegation: function (dialog) { + var bb = dialog.get('boundingBox'); + var can_receive_focus_selector = 'input:not([type="hidden"]), a[href], button, textarea, select'; + bb.delegate('key', function(e) { + var target = e.target; + var firstitem = bb.one(can_receive_focus_selector); + var lastitem = bb.all(can_receive_focus_selector).pop(); + + if (e.shiftKey) { + if (target === firstitem) { + lastitem.focus(); + e.preventDefault(); + } + } else { + if (target === lastitem) { + firstitem.focus(); + e.preventDefault(); + } + } + }, 'down:9', can_receive_focus_selector, this); + }, + detachKeyDelegation: function(dialog) { + var bb = dialog.get('boundingBox'); + bb.detach('key', this.keyDelegation); } }); var loading = Y.one('#filepicker-loading-'+options.client_id);