diff --git a/course/yui/build/moodle-course-categoryexpander/moodle-course-categoryexpander-debug.js b/course/yui/build/moodle-course-categoryexpander/moodle-course-categoryexpander-debug.js index 3bddd80acf7..ebcec70cd19 100644 --- a/course/yui/build/moodle-course-categoryexpander/moodle-course-categoryexpander-debug.js +++ b/course/yui/build/moodle-course-categoryexpander/moodle-course-categoryexpander-debug.js @@ -51,9 +51,35 @@ var CSS = { * @method init */ NS.init = function() { - Y.one(Y.config.doc).delegate('click', this.toggle_category_expansion, SELECTORS.CATEGORYLISTENLINK, this); - Y.one(Y.config.doc).delegate('click', this.toggle_coursebox_expansion, SELECTORS.COURSEBOXLISTENLINK, this); - Y.one(Y.config.doc).delegate('click', this.collapse_expand_all, SELECTORS.COLLAPSEEXPAND, this); + var doc = Y.one(Y.config.doc); + doc.delegate('click', this.toggle_category_expansion, SELECTORS.CATEGORYLISTENLINK, this); + doc.delegate('click', this.toggle_coursebox_expansion, SELECTORS.COURSEBOXLISTENLINK, this); + doc.delegate('click', this.collapse_expand_all, SELECTORS.COLLAPSEEXPAND, this); + + // Only set up they keybaord listeners when tab is first pressed - it + // may never happen and modifying the DOM on a large number of nodes + // can be very expensive. + doc.once('key', this.setup_keyboard_listeners, 'tab', this); +}; + +/** + * Set up keyboard expansion for course content. + * + * This includes setting up the delegation but also adding the nodes to the + * tabflow. + * + * @method setup_keyboard_listeners + */ +NS.setup_keyboard_listeners = function() { + var doc = Y.one(Y.config.doc); + + Y.log('Setting the tabindex for all expandable course nodes', 'info', 'moodle-course-categoryexpander'); + doc.all(SELECTORS.CATEGORYLISTENLINK, SELECTORS.COURSEBOXLISTENLINK, SELECTORS.COLLAPSEEXPAND).setAttribute('tabindex', '0'); + + + Y.one(Y.config.doc).delegate('key', this.toggle_category_expansion, 'enter', SELECTORS.CATEGORYLISTENLINK, this); + Y.one(Y.config.doc).delegate('key', this.toggle_coursebox_expansion, 'enter', SELECTORS.COURSEBOXLISTENLINK, this); + Y.one(Y.config.doc).delegate('key', this.collapse_expand_all, 'enter', SELECTORS.COLLAPSEEXPAND, this); }; /** @@ -408,4 +434,4 @@ NS.add_animation = function(childnode) { }; -}, '@VERSION@', {"requires": ["node"]}); +}, '@VERSION@', {"requires": ["node", "event-key"]}); diff --git a/course/yui/build/moodle-course-categoryexpander/moodle-course-categoryexpander-min.js b/course/yui/build/moodle-course-categoryexpander/moodle-course-categoryexpander-min.js index 95e4e49b8e6..5219087eece 100644 --- a/course/yui/build/moodle-course-categoryexpander/moodle-course-categoryexpander-min.js +++ b/course/yui/build/moodle-course-categoryexpander/moodle-course-categoryexpander-min.js @@ -1 +1 @@ -YUI.add("moodle-course-categoryexpander",function(e,t){var n={CONTENTNODE:"content",COLLAPSEALL:"collapse-all",DISABLED:"disabled",LOADED:"loaded",NOTLOADED:"notloaded",SECTIONCOLLAPSED:"collapsed",HASCHILDREN:"with_children"},r={LOADEDTREES:".with_children.loaded",CONTENTNODE:".content",CATEGORYLISTENLINK:".category .info .name",CATEGORYSPINNERLOCATION:".name",CATEGORYWITHCOLLAPSEDLOADEDCHILDREN:".category.with_children.loaded.collapsed",CATEGORYWITHMAXIMISEDLOADEDCHILDREN:".category.with_children.loaded:not(.collapsed)",COLLAPSEEXPAND:".collapseexpand",COURSEBOX:".coursebox",COURSEBOXLISTENLINK:".coursebox .moreinfo",COURSEBOXSPINNERLOCATION:".name a",COURSECATEGORYTREE:".course_category_tree",PARENTWITHCHILDREN:".category"},i=e.namespace("Moodle.course.categoryexpander"),s=0,o=1,u=M.cfg.wwwroot+"/course/category.ajax.php";i.init=function(){e.one(e.config.doc).delegate("click",this.toggle_category_expansion,r.CATEGORYLISTENLINK,this),e.one(e.config.doc).delegate("click",this.toggle_coursebox_expansion,r.COURSEBOXLISTENLINK,this),e.one(e.config.doc).delegate("click",this.collapse_expand_all,r.COLLAPSEEXPAND,this)},i.toggle_category_expansion=function(t){e.use("io-base","json-parse","moodle-core-notification","anim",function(){i.toggle_category_expansion=i._toggle_category_expansion,i.toggle_category_expansion(t)})},i.toggle_coursebox_expansion=function(t){e.use("io-base","json-parse","moodle-core-notification","anim",function(){i.toggle_coursebox_expansion=i._toggle_coursebox_expansion,i.toggle_coursebox_expansion(t)}),t.preventDefault()},i._toggle_coursebox_expansion=function(e){var t;t=e.target.ancestor(r.COURSEBOX,!0),e.preventDefault();if(t.hasClass(n.LOADED)){this.run_expansion(t);return}this._toggle_generic_expansion({parentnode:t,childnode:t.one(r.CONTENTNODE),spinnerhandle:r.COURSEBOXSPINNERLOCATION,data:{courseid:t.getData("courseid"),type:o}})},i._toggle_category_expansion=function(e){var t,i,o;if(e.target.test("a")||e.target.test("img"))return;t=e.target.ancestor(r.PARENTWITHCHILDREN,!0);if(!t.hasClass(n.HASCHILDREN))return;if(t.hasClass(n.LOADED)){this.run_expansion(t);return}i=t.getData("categoryid"),o=t.getData("depth");if(typeof i=="undefined"||typeof o=="undefined")return;this._toggle_generic_expansion({parentnode:t,childnode:t.one(r.CONTENTNODE),spinnerhandle:r.CATEGORYSPINNERLOCATION,data:{categoryid:i,depth:o,showcourses:t.getData("showcourses"),type:s}})},i._toggle_generic_expansion=function(t){t.spinnerhandle&&(spinner=M.util.add_spinner(e,t.parentnode.one(t.spinnerhandle)).show()),e.io(u,{method:"POST",context:this,on:{complete:this.process_results},data:t.data,arguments:{parentnode:t.parentnode,childnode:t.childnode,spinner:spinner}})},i.run_expansion=function(e){var t=e.one(r.CONTENTNODE),i=this,s=e.ancestor(r.COURSECATEGORYTREE);this.add_animation(t),e.hasClass(n.SECTIONCOLLAPSED)?(t.setStyle("height","0"),e.removeClass(n.SECTIONCOLLAPSED),t.fx.set("reverse",!1)):(t.fx.set("reverse",!0),t.fx.once("end",function(e,t){t.addClass(n.SECTIONCOLLAPSED)},this,e)),t.fx.once("end",function(e,t){t.setStyles({height:"",opacity:""}),this.destroy(),i.update_collapsible_actions(s)},t.fx,t),t.fx.run()},i.collapse_expand_all=function(e){e.preventDefault();if(e.currentTarget.hasClass(n.DISABLED))return;var t=e.currentTarget.ancestor(r.COURSECATEGORYTREE);if(!t)return;var i=t.one(r.COLLAPSEEXPAND);i.hasClass(n.COLLAPSEALL)?this.collapse_all(t):this.expand_all(t),this.update_collapsible_actions(t)},i.expand_all=function(t){var i=[];t.all(r.CATEGORYWITHCOLLAPSEDLOADEDCHILDREN).each(function(e){e.ancestor(r.CATEGORYWITHCOLLAPSEDLOADEDCHILDREN)?(e.removeClass(n.SECTIONCOLLAPSED),e.all(r.LOADEDTREES).removeClass(n.SECTIONCOLLAPSED)):i.push(e)},this),e.all(i).each(function(e){this.run_expansion(e)},this)},i.collapse_all=function(t){var i=[];t.all(r.CATEGORYWITHMAXIMISEDLOADEDCHILDREN).each(function(e){e.ancestor(r.CATEGORYWITHMAXIMISEDLOADEDCHILDREN)?i.push(e):this.run_expansion(e)},this),e.all(i).each(function(e){e.addClass(n.SECTIONCOLLAPSED),e.all(r.LOADEDTREES).addClass(n.SECTIONCOLLAPSED)},this)},i.update_collapsible_actions=function(e){var t=!1,i=e.one(r.COLLAPSEEXPAND);if(!i)return;e.all(r.CATEGORYWITHMAXIMISEDLOADEDCHILDREN).each(function(e){return e.ancestor(r.CATEGORYWITHCOLLAPSEDLOADEDCHILDREN)?!1:(t=!0,!0)}),t?i.setHTML(M.util.get_string("collapseall","moodle")).addClass(n.COLLAPSEALL).removeClass(n.DISABLED):i.setHTML(M.util.get_string("expandall","moodle")).removeClass(n.COLLAPSEALL).removeClass(n.DISABLED)},i.process_results=function(t,r,i){var s,o;try{o=e.JSON.parse(r.responseText);if(o.error)return new M.core.ajaxException(o)}catch(u){return new M.core.exception(u)}s=e.Node.create(o),i.childnode.appendChild(s),i.parentnode.addClass(n.LOADED).removeClass(n.NOTLOADED),this.run_expansion(i.parentnode),i.spinner&&i.spinner.hide().destroy()},i.add_animation=function(t){return typeof t.fx!="undefined"?t:(t.plug(e.Plugin.NodeFX,{from:{height:0,opacity:0},to:{height:function(e){return e.get("scrollHeight")},opacity:1},duration:.2}),t)}},"@VERSION@",{requires:["node"]}); +YUI.add("moodle-course-categoryexpander",function(e,t){var n={CONTENTNODE:"content",COLLAPSEALL:"collapse-all",DISABLED:"disabled",LOADED:"loaded",NOTLOADED:"notloaded",SECTIONCOLLAPSED:"collapsed",HASCHILDREN:"with_children"},r={LOADEDTREES:".with_children.loaded",CONTENTNODE:".content",CATEGORYLISTENLINK:".category .info .name",CATEGORYSPINNERLOCATION:".name",CATEGORYWITHCOLLAPSEDLOADEDCHILDREN:".category.with_children.loaded.collapsed",CATEGORYWITHMAXIMISEDLOADEDCHILDREN:".category.with_children.loaded:not(.collapsed)",COLLAPSEEXPAND:".collapseexpand",COURSEBOX:".coursebox",COURSEBOXLISTENLINK:".coursebox .moreinfo",COURSEBOXSPINNERLOCATION:".name a",COURSECATEGORYTREE:".course_category_tree",PARENTWITHCHILDREN:".category"},i=e.namespace("Moodle.course.categoryexpander"),s=0,o=1,u=M.cfg.wwwroot+"/course/category.ajax.php";i.init=function(){var t=e.one(e.config.doc);t.delegate("click",this.toggle_category_expansion,r.CATEGORYLISTENLINK,this),t.delegate("click",this.toggle_coursebox_expansion,r.COURSEBOXLISTENLINK,this),t.delegate("click",this.collapse_expand_all,r.COLLAPSEEXPAND,this),t.once("key",this.setup_keyboard_listeners,"tab",this)},i.setup_keyboard_listeners=function(){var t=e.one(e.config.doc);t.all(r.CATEGORYLISTENLINK,r.COURSEBOXLISTENLINK,r.COLLAPSEEXPAND).setAttribute("tabindex","0"),e.one(e.config.doc).delegate("key",this.toggle_category_expansion,"enter",r.CATEGORYLISTENLINK,this),e.one(e.config.doc).delegate("key",this.toggle_coursebox_expansion,"enter",r.COURSEBOXLISTENLINK,this),e.one(e.config.doc).delegate("key",this.collapse_expand_all,"enter",r.COLLAPSEEXPAND,this)},i.toggle_category_expansion=function(t){e.use("io-base","json-parse","moodle-core-notification","anim",function(){i.toggle_category_expansion=i._toggle_category_expansion,i.toggle_category_expansion(t)})},i.toggle_coursebox_expansion=function(t){e.use("io-base","json-parse","moodle-core-notification","anim",function(){i.toggle_coursebox_expansion=i._toggle_coursebox_expansion,i.toggle_coursebox_expansion(t)}),t.preventDefault()},i._toggle_coursebox_expansion=function(e){var t;t=e.target.ancestor(r.COURSEBOX,!0),e.preventDefault();if(t.hasClass(n.LOADED)){this.run_expansion(t);return}this._toggle_generic_expansion({parentnode:t,childnode:t.one(r.CONTENTNODE),spinnerhandle:r.COURSEBOXSPINNERLOCATION,data:{courseid:t.getData("courseid"),type:o}})},i._toggle_category_expansion=function(e){var t,i,o;if(e.target.test("a")||e.target.test("img"))return;t=e.target.ancestor(r.PARENTWITHCHILDREN,!0);if(!t.hasClass(n.HASCHILDREN))return;if(t.hasClass(n.LOADED)){this.run_expansion(t);return}i=t.getData("categoryid"),o=t.getData("depth");if(typeof i=="undefined"||typeof o=="undefined")return;this._toggle_generic_expansion({parentnode:t,childnode:t.one(r.CONTENTNODE),spinnerhandle:r.CATEGORYSPINNERLOCATION,data:{categoryid:i,depth:o,showcourses:t.getData("showcourses"),type:s}})},i._toggle_generic_expansion=function(t){t.spinnerhandle&&(spinner=M.util.add_spinner(e,t.parentnode.one(t.spinnerhandle)).show()),e.io(u,{method:"POST",context:this,on:{complete:this.process_results},data:t.data,arguments:{parentnode:t.parentnode,childnode:t.childnode,spinner:spinner}})},i.run_expansion=function(e){var t=e.one(r.CONTENTNODE),i=this,s=e.ancestor(r.COURSECATEGORYTREE);this.add_animation(t),e.hasClass(n.SECTIONCOLLAPSED)?(t.setStyle("height","0"),e.removeClass(n.SECTIONCOLLAPSED),t.fx.set("reverse",!1)):(t.fx.set("reverse",!0),t.fx.once("end",function(e,t){t.addClass(n.SECTIONCOLLAPSED)},this,e)),t.fx.once("end",function(e,t){t.setStyles({height:"",opacity:""}),this.destroy(),i.update_collapsible_actions(s)},t.fx,t),t.fx.run()},i.collapse_expand_all=function(e){e.preventDefault();if(e.currentTarget.hasClass(n.DISABLED))return;var t=e.currentTarget.ancestor(r.COURSECATEGORYTREE);if(!t)return;var i=t.one(r.COLLAPSEEXPAND);i.hasClass(n.COLLAPSEALL)?this.collapse_all(t):this.expand_all(t),this.update_collapsible_actions(t)},i.expand_all=function(t){var i=[];t.all(r.CATEGORYWITHCOLLAPSEDLOADEDCHILDREN).each(function(e){e.ancestor(r.CATEGORYWITHCOLLAPSEDLOADEDCHILDREN)?(e.removeClass(n.SECTIONCOLLAPSED),e.all(r.LOADEDTREES).removeClass(n.SECTIONCOLLAPSED)):i.push(e)},this),e.all(i).each(function(e){this.run_expansion(e)},this)},i.collapse_all=function(t){var i=[];t.all(r.CATEGORYWITHMAXIMISEDLOADEDCHILDREN).each(function(e){e.ancestor(r.CATEGORYWITHMAXIMISEDLOADEDCHILDREN)?i.push(e):this.run_expansion(e)},this),e.all(i).each(function(e){e.addClass(n.SECTIONCOLLAPSED),e.all(r.LOADEDTREES).addClass(n.SECTIONCOLLAPSED)},this)},i.update_collapsible_actions=function(e){var t=!1,i=e.one(r.COLLAPSEEXPAND);if(!i)return;e.all(r.CATEGORYWITHMAXIMISEDLOADEDCHILDREN).each(function(e){return e.ancestor(r.CATEGORYWITHCOLLAPSEDLOADEDCHILDREN)?!1:(t=!0,!0)}),t?i.setHTML(M.util.get_string("collapseall","moodle")).addClass(n.COLLAPSEALL).removeClass(n.DISABLED):i.setHTML(M.util.get_string("expandall","moodle")).removeClass(n.COLLAPSEALL).removeClass(n.DISABLED)},i.process_results=function(t,r,i){var s,o;try{o=e.JSON.parse(r.responseText);if(o.error)return new M.core.ajaxException(o)}catch(u){return new M.core.exception(u)}s=e.Node.create(o),i.childnode.appendChild(s),i.parentnode.addClass(n.LOADED).removeClass(n.NOTLOADED),this.run_expansion(i.parentnode),i.spinner&&i.spinner.hide().destroy()},i.add_animation=function(t){return typeof t.fx!="undefined"?t:(t.plug(e.Plugin.NodeFX,{from:{height:0,opacity:0},to:{height:function(e){return e.get("scrollHeight")},opacity:1},duration:.2}),t)}},"@VERSION@",{requires:["node","event-key"]}); diff --git a/course/yui/build/moodle-course-categoryexpander/moodle-course-categoryexpander.js b/course/yui/build/moodle-course-categoryexpander/moodle-course-categoryexpander.js index 3bddd80acf7..079ff5ba136 100644 --- a/course/yui/build/moodle-course-categoryexpander/moodle-course-categoryexpander.js +++ b/course/yui/build/moodle-course-categoryexpander/moodle-course-categoryexpander.js @@ -51,9 +51,34 @@ var CSS = { * @method init */ NS.init = function() { - Y.one(Y.config.doc).delegate('click', this.toggle_category_expansion, SELECTORS.CATEGORYLISTENLINK, this); - Y.one(Y.config.doc).delegate('click', this.toggle_coursebox_expansion, SELECTORS.COURSEBOXLISTENLINK, this); - Y.one(Y.config.doc).delegate('click', this.collapse_expand_all, SELECTORS.COLLAPSEEXPAND, this); + var doc = Y.one(Y.config.doc); + doc.delegate('click', this.toggle_category_expansion, SELECTORS.CATEGORYLISTENLINK, this); + doc.delegate('click', this.toggle_coursebox_expansion, SELECTORS.COURSEBOXLISTENLINK, this); + doc.delegate('click', this.collapse_expand_all, SELECTORS.COLLAPSEEXPAND, this); + + // Only set up they keybaord listeners when tab is first pressed - it + // may never happen and modifying the DOM on a large number of nodes + // can be very expensive. + doc.once('key', this.setup_keyboard_listeners, 'tab', this); +}; + +/** + * Set up keyboard expansion for course content. + * + * This includes setting up the delegation but also adding the nodes to the + * tabflow. + * + * @method setup_keyboard_listeners + */ +NS.setup_keyboard_listeners = function() { + var doc = Y.one(Y.config.doc); + + doc.all(SELECTORS.CATEGORYLISTENLINK, SELECTORS.COURSEBOXLISTENLINK, SELECTORS.COLLAPSEEXPAND).setAttribute('tabindex', '0'); + + + Y.one(Y.config.doc).delegate('key', this.toggle_category_expansion, 'enter', SELECTORS.CATEGORYLISTENLINK, this); + Y.one(Y.config.doc).delegate('key', this.toggle_coursebox_expansion, 'enter', SELECTORS.COURSEBOXLISTENLINK, this); + Y.one(Y.config.doc).delegate('key', this.collapse_expand_all, 'enter', SELECTORS.COLLAPSEEXPAND, this); }; /** @@ -408,4 +433,4 @@ NS.add_animation = function(childnode) { }; -}, '@VERSION@', {"requires": ["node"]}); +}, '@VERSION@', {"requires": ["node", "event-key"]}); diff --git a/course/yui/src/categoryexpander/js/categoryexpander.js b/course/yui/src/categoryexpander/js/categoryexpander.js index d69b12369c0..9552b4617db 100644 --- a/course/yui/src/categoryexpander/js/categoryexpander.js +++ b/course/yui/src/categoryexpander/js/categoryexpander.js @@ -49,9 +49,35 @@ var CSS = { * @method init */ NS.init = function() { - Y.one(Y.config.doc).delegate('click', this.toggle_category_expansion, SELECTORS.CATEGORYLISTENLINK, this); - Y.one(Y.config.doc).delegate('click', this.toggle_coursebox_expansion, SELECTORS.COURSEBOXLISTENLINK, this); - Y.one(Y.config.doc).delegate('click', this.collapse_expand_all, SELECTORS.COLLAPSEEXPAND, this); + var doc = Y.one(Y.config.doc); + doc.delegate('click', this.toggle_category_expansion, SELECTORS.CATEGORYLISTENLINK, this); + doc.delegate('click', this.toggle_coursebox_expansion, SELECTORS.COURSEBOXLISTENLINK, this); + doc.delegate('click', this.collapse_expand_all, SELECTORS.COLLAPSEEXPAND, this); + + // Only set up they keybaord listeners when tab is first pressed - it + // may never happen and modifying the DOM on a large number of nodes + // can be very expensive. + doc.once('key', this.setup_keyboard_listeners, 'tab', this); +}; + +/** + * Set up keyboard expansion for course content. + * + * This includes setting up the delegation but also adding the nodes to the + * tabflow. + * + * @method setup_keyboard_listeners + */ +NS.setup_keyboard_listeners = function() { + var doc = Y.one(Y.config.doc); + + Y.log('Setting the tabindex for all expandable course nodes', 'info', 'moodle-course-categoryexpander'); + doc.all(SELECTORS.CATEGORYLISTENLINK, SELECTORS.COURSEBOXLISTENLINK, SELECTORS.COLLAPSEEXPAND).setAttribute('tabindex', '0'); + + + Y.one(Y.config.doc).delegate('key', this.toggle_category_expansion, 'enter', SELECTORS.CATEGORYLISTENLINK, this); + Y.one(Y.config.doc).delegate('key', this.toggle_coursebox_expansion, 'enter', SELECTORS.COURSEBOXLISTENLINK, this); + Y.one(Y.config.doc).delegate('key', this.collapse_expand_all, 'enter', SELECTORS.COLLAPSEEXPAND, this); }; /** diff --git a/course/yui/src/categoryexpander/meta/categoryexpander.json b/course/yui/src/categoryexpander/meta/categoryexpander.json index db1b328b631..67c51f9b97a 100644 --- a/course/yui/src/categoryexpander/meta/categoryexpander.json +++ b/course/yui/src/categoryexpander/meta/categoryexpander.json @@ -1,7 +1,8 @@ { "moodle-course-categoryexpander": { "requires": [ - "node" + "node", + "event-key" ] } }