Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'MDL-38516-m' of https://github.com/andrewnicols/moodle

  • Loading branch information...
commit 50206449b62680db4688dc11ed05962f7bb40b55 2 parents 113f9a6 + 81c8a42
@stronk7 stronk7 authored
View
908 ...i/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-coverage.js
@@ -0,0 +1,908 @@
+if (typeof _yuitest_coverage == "undefined"){
+ _yuitest_coverage = {};
+ _yuitest_coverline = function(src, line){
+ var coverage = _yuitest_coverage[src];
+ if (!coverage.lines[line]){
+ coverage.calledLines++;
+ }
+ coverage.lines[line]++;
+ };
+ _yuitest_coverfunc = function(src, name, line){
+ var coverage = _yuitest_coverage[src],
+ funcId = name + ":" + line;
+ if (!coverage.functions[funcId]){
+ coverage.calledFunctions++;
+ }
+ coverage.functions[funcId]++;
+ };
+}
+_yuitest_coverage["build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js"] = {
+ lines: {},
+ functions: {},
+ coveredLines: 0,
+ calledLines: 0,
+ coveredFunctions: 0,
+ calledFunctions: 0,
+ path: "build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js",
+ code: []
+};
+_yuitest_coverage["build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js"].code=["YUI.add('moodle-block_navigation-navigation', function (Y, NAME) {","","/**"," * A 'actionkey' Event to help with Y.delegate()."," * The event consists of the left arrow, right arrow, enter and space keys."," * More keys can be mapped to action meanings."," * actions: collapse , expand, toggle, enter."," *"," * This event is delegated to branches in the navigation tree."," * The on() method to subscribe allows specifying the desired trigger actions as JSON."," *"," * Todo: This could be centralised, a similar Event is defined in blocks/dock.js"," */","Y.Event.define(\"actionkey\", {"," // Webkit and IE repeat keydown when you hold down arrow keys."," // Opera links keypress to page scroll; others keydown."," // Firefox prevents page scroll via preventDefault() on either"," // keydown or keypress."," _event: (Y.UA.webkit || Y.UA.ie) ? 'keydown' : 'keypress',",""," _keys: {"," //arrows"," '37': 'collapse',"," '39': 'expand',"," //(@todo: lrt/rtl/M.core_dock.cfg.orientation decision to assign arrow to meanings)"," '32': 'toggle',"," '13': 'enter'"," },",""," _keyHandler: function (e, notifier, args) {"," var actObj;"," if (!args.actions) {"," actObj = {collapse:true, expand:true, toggle:true, enter:true};"," } else {"," actObj = args.actions;"," }"," if (this._keys[e.keyCode] && actObj[this._keys[e.keyCode]]) {"," e.action = this._keys[e.keyCode];"," notifier.fire(e);"," }"," },",""," on: function (node, sub, notifier) {"," // subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions)."," if (sub.args === null) {"," //no actions given"," sub._detacher = node.on(this._event, this._keyHandler,this, notifier, {actions:false});"," } else {"," sub._detacher = node.on(this._event, this._keyHandler,this, notifier, sub.args[0]);"," }"," },",""," detach: function (node, sub) {"," //detach our _detacher handle of the subscription made in on()"," sub._detacher.detach();"," },",""," delegate: function (node, sub, notifier, filter) {"," // subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions)."," if (sub.args === null) {"," //no actions given"," sub._delegateDetacher = node.delegate(this._event, this._keyHandler,filter, this, notifier, {actions:false});"," } else {"," sub._delegateDetacher = node.delegate(this._event, this._keyHandler,filter, this, notifier, sub.args[0]);"," }"," },",""," detachDelegate: function (node, sub) {"," sub._delegateDetacher.detach();"," }","});","","var EXPANSIONLIMIT_EVERYTHING = 0,"," //EXPANSIONLIMIT_COURSE = 20,"," //EXPANSIONLIMIT_SECTION = 30,"," EXPANSIONLIMIT_ACTIVITY = 40;","","/**"," * Mappings for the different types of nodes coming from the navigation."," * Copied from lib/navigationlib.php navigation_node constants."," * @type object"," */","var NODETYPE = {"," /** @type int Root node = 0 */"," ROOTNODE : 0,"," /** @type int System context = 1 */"," SYSTEM : 1,"," /** @type int Course category = 10 */"," CATEGORY : 10,"," /** @type int MYCATEGORY = 11 */"," MYCATEGORY : 11,"," /** @type int Course = 20 */"," COURSE : 20,"," /** @type int Course section = 30 */"," SECTION : 30,"," /** @type int Activity (course module) = 40 */"," ACTIVITY : 40,"," /** @type int Resource (course module = 50 */"," RESOURCE : 50,"," /** @type int Custom node (could be anything) = 60 */"," CUSTOM : 60,"," /** @type int Setting = 70 */"," SETTING : 70,"," /** @type int User context = 80 */"," USER : 80,"," /** @type int Container = 90 */"," CONTAINER : 90","};","","/**"," * Navigation tree class."," *"," * This class establishes the tree initially, creating expandable branches as"," * required, and delegating the expand/collapse event."," */","var TREE = function() {"," TREE.superclass.constructor.apply(this, arguments);","};","TREE.prototype = {"," /**"," * The tree's ID, normally its block instance id."," */"," id : null,"," /**"," * An array of initialised branches."," */"," branches : [],"," /**"," * Initialise the tree object when its first created."," */"," initializer : function(config) {"," this.id = config.id;",""," var node = Y.one('#inst'+config.id);",""," // Can't find the block instance within the page"," if (node === null) {"," return;"," }",""," // Delegate event to toggle expansion"," Y.delegate('click', this.toggleExpansion, node.one('.block_tree'), '.tree_item.branch', this);"," Y.delegate('actionkey', this.toggleExpansion, node.one('.block_tree'), '.tree_item.branch', this);",""," // Gather the expandable branches ready for initialisation."," var expansions = [];"," if (config.expansions) {"," expansions = config.expansions;"," } else if (window['navtreeexpansions'+config.id]) {"," expansions = window['navtreeexpansions'+config.id];"," }"," // Establish each expandable branch as a tree branch."," for (var i in expansions) {"," var branch = new BRANCH({"," tree:this,"," branchobj:expansions[i],"," overrides : {"," expandable : true,"," children : [],"," haschildren : true"," }"," }).wire();"," M.block_navigation.expandablebranchcount++;"," this.branches[branch.get('id')] = branch;"," }"," if (M.block_navigation.expandablebranchcount > 0) {"," // Delegate some events to handle AJAX loading."," Y.delegate('click', this.fire_branch_action, node.one('.block_tree'), '.tree_item.branch[data-expandable]', this);"," Y.delegate('actionkey', this.fire_branch_action, node.one('.block_tree'), '.tree_item.branch[data-expandable]', this);"," }",""," // Call the generic blocks init method to add all the generic stuff"," if (this.get('candock')) {"," this.initialise_block(Y, node);"," }"," },"," /**"," * Fire actions for a branch when an event occurs."," */"," fire_branch_action : function(event) {"," var id = event.currentTarget.getAttribute('id');"," var branch = this.branches[id];"," branch.ajaxLoad(event);"," },"," /**"," * This is a callback function responsible for expanding and collapsing the"," * branches of the tree. It is delegated to rather than multiple event handles."," */"," toggleExpansion : function(e) {"," // First check if they managed to click on the li iteslf, then find the closest"," // LI ancestor and use that",""," if (e.target.test('a') && (e.keyCode === 0 || e.keyCode === 13)) {"," // A link has been clicked (or keypress is 'enter') don't fire any more events just do the default."," e.stopPropagation();"," return;"," }",""," // Makes sure we can get to the LI containing the branch."," var target = e.target;"," if (!target.test('li')) {"," target = target.ancestor('li');"," }"," if (!target) {"," return;"," }",""," // Toggle expand/collapse providing its not a root level branch."," if (!target.hasClass('depth_1')) {"," if (e.type === 'actionkey') {"," switch (e.action) {"," case 'expand' :"," target.removeClass('collapsed');"," target.set('aria-expanded', true);"," break;"," case 'collapse' :"," target.addClass('collapsed');"," target.set('aria-expanded', false);"," break;"," default :"," target.toggleClass('collapsed');"," target.set('aria-expanded', !target.hasClass('collapsed'));"," }"," e.halt();"," } else {"," target.toggleClass('collapsed');"," target.set('aria-expanded', !target.hasClass('collapsed'));"," }"," }",""," // If the accordian feature has been enabled collapse all siblings."," if (this.get('accordian')) {"," target.siblings('li').each(function(){"," if (this.get('id') !== target.get('id') && !this.hasClass('collapsed')) {"," this.addClass('collapsed');"," this.set('aria-expanded', false);"," }"," });"," }",""," // If this block can dock tell the dock to resize if required and check"," // the width on the dock panel in case it is presently in use."," if (this.get('candock')) {"," M.core_dock.resize();"," var panel = M.core_dock.getPanel();"," if (panel.visible) {"," panel.correctWidth();"," }"," }"," }","};","// The tree extends the YUI base foundation.","Y.extend(TREE, Y.Base, TREE.prototype, {"," NAME : 'navigation-tree',"," ATTRS : {"," instance : {"," value : null"," },"," candock : {"," validator : Y.Lang.isBool,"," value : false"," },"," accordian : {"," validator : Y.Lang.isBool,"," value : false"," },"," expansionlimit : {"," value : 0,"," setter : function(val) {"," return parseInt(val, 10);"," }"," }"," }","});","if (M.core_dock && M.core_dock.genericblock) {"," Y.augment(TREE, M.core_dock.genericblock);","}","","/**"," * The tree branch class."," * This class is used to manage a tree branch, in particular its ability to load"," * its contents by AJAX."," */","BRANCH = function() {"," BRANCH.superclass.constructor.apply(this, arguments);","};","BRANCH.prototype = {"," /**"," * The node for this branch (p)"," */"," node : null,"," /**"," * Initialises the branch when it is first created."," */"," initializer : function(config) {"," var i,"," children;"," if (config.branchobj !== null) {"," // Construct from the provided xml"," for (i in config.branchobj) {"," this.set(i, config.branchobj[i]);"," }"," children = this.get('children');"," this.set('haschildren', (children.length > 0));"," }"," if (config.overrides !== null) {"," // Construct from the provided xml"," for (i in config.overrides) {"," this.set(i, config.overrides[i]);"," }"," }"," // Get the node for this branch"," this.node = Y.one('#', this.get('id'));"," // Now check whether the branch is not expandable because of the expansionlimit"," var expansionlimit = this.get('tree').get('expansionlimit');"," var type = this.get('type');"," if (expansionlimit !== EXPANSIONLIMIT_EVERYTHING && type >= expansionlimit && type <= EXPANSIONLIMIT_ACTIVITY) {"," this.set('expandable', false);"," this.set('haschildren', false);"," }"," },"," /**"," * Draws the branch within the tree."," *"," * This function creates a DOM structure for the branch and then injects"," * it into the navigation tree at the correct point."," */"," draw : function(element) {",""," var isbranch = (this.get('expandable') || this.get('haschildren'));"," var branchli = Y.Node.create('<li></li>');"," var link = this.get('link');"," var branchp = Y.Node.create('<p class=\"tree_item\"></p>').setAttribute('id', this.get('id'));"," if (!link) {"," //add tab focus if not link (so still one focus per menu node)."," // it was suggested to have 2 foci. one for the node and one for the link in MDL-27428."," branchp.setAttribute('tabindex', '0');"," }"," if (isbranch) {"," branchli.addClass('collapsed').addClass('contains_branch');"," branchli.set('aria-expanded', false);"," branchp.addClass('branch');"," }",""," // Prepare the icon, should be an object representing a pix_icon"," var branchicon = false;"," var icon = this.get('icon');"," if (icon && (!isbranch || this.get('type') == NODETYPE.ACTIVITY)) {"," branchicon = Y.Node.create('<img alt=\"\" />');"," branchicon.setAttribute('src', M.util.image_url(icon.pix, icon.component));"," branchli.addClass('item_with_icon');"," if (icon.alt) {"," branchicon.setAttribute('alt', icon.alt);"," }"," if (icon.title) {"," branchicon.setAttribute('title', icon.title);"," }"," if (icon.classes) {"," for (var i in icon.classes) {"," branchicon.addClass(icon.classes[i]);"," }"," }"," }",""," if (!link) {"," if (branchicon) {"," branchp.appendChild(branchicon);"," }"," branchp.append(this.get('name'));"," } else {"," var branchlink = Y.Node.create('<a title=\"'+this.get('title')+'\" href=\"'+link+'\"></a>');"," if (branchicon) {"," branchlink.appendChild(branchicon);"," }"," branchlink.append(this.get('name'));"," if (this.get('hidden')) {"," branchlink.addClass('dimmed');"," }"," branchp.appendChild(branchlink);"," }",""," branchli.appendChild(branchp);"," element.appendChild(branchli);"," this.node = branchp;"," return this;"," },"," /**"," * Attaches required events to the branch structure."," */"," wire : function() {"," this.node = this.node || Y.one('#'+this.get('id'));"," if (!this.node) {"," return false;"," }"," if (this.get('expandable')) {"," this.node.setAttribute('data-expandable', '1');"," this.node.setAttribute('data-loaded', '0');"," }"," return this;"," },"," /**"," * Gets the UL element that children for this branch should be inserted into."," */"," getChildrenUL : function() {"," var ul = this.node.next('ul');"," if (!ul) {"," ul = Y.Node.create('<ul></ul>');"," this.node.ancestor().append(ul);"," }"," return ul;"," },"," /**"," * Load the content of the branch via AJAX."," *"," * This function calls ajaxProcessResponse with the result of the AJAX"," * request made here."," */"," ajaxLoad : function(e) {"," if (e.type === 'actionkey' && e.action !== 'enter') {"," e.halt();"," } else {"," e.stopPropagation();"," }"," if (e.type === 'actionkey' && e.action === 'enter' && e.target.test('A')) {"," // No ajaxLoad for enter."," this.node.setAttribute('data-expandable', '0');"," this.node.setAttribute('data-loaded', '1');"," return true;"," }",""," if (this.node.hasClass('loadingbranch')) {"," // Already loading. Just skip."," return true;"," }",""," if (this.node.getAttribute('data-loaded') === '1') {"," // We've already loaded this stuff."," return true;"," }"," this.node.addClass('loadingbranch');",""," var params = {"," elementid : this.get('id'),"," id : this.get('key'),"," type : this.get('type'),"," sesskey : M.cfg.sesskey,"," instance : this.get('tree').get('instance')"," };",""," Y.io(M.cfg.wwwroot+'/lib/ajax/getnavbranch.php', {"," method:'POST',"," data: build_querystring(params),"," on: {"," complete: this.ajaxProcessResponse"," },"," context:this"," });"," return true;"," },"," /**"," * Processes an AJAX request to load the content of this branch through"," * AJAX."," */"," ajaxProcessResponse : function(tid, outcome) {"," this.node.removeClass('loadingbranch');"," this.node.setAttribute('data-loaded', '1');"," try {"," var object = Y.JSON.parse(outcome.responseText);"," if (object.children && object.children.length > 0) {"," var coursecount = 0;"," for (var i in object.children) {"," if (typeof(object.children[i])==='object') {"," if (object.children[i].type == NODETYPE.COURSE) {"," coursecount++;"," }"," this.addChild(object.children[i]);"," }"," }"," if ((this.get('type') == NODETYPE.CATEGORY || this.get('type') == NODETYPE.ROOTNODE || this.get('type') == NODETYPE.MYCATEGORY)"," && coursecount >= M.block_navigation.courselimit) {"," this.addViewAllCoursesChild(this);"," }"," return true;"," }"," } catch (ex) {"," // If we got here then there was an error parsing the result"," }"," // The branch is empty so class it accordingly"," this.node.replaceClass('branch', 'emptybranch');"," return true;"," },"," /**"," * Turns the branch object passed to the method into a proper branch object"," * and then adds it as a child of this branch."," */"," addChild : function(branchobj) {"," // Make the new branch into an object"," var branch = new BRANCH({tree:this.get('tree'), branchobj:branchobj});"," if (branch.draw(this.getChildrenUL())) {"," this.get('tree').branches[branch.get('id')] = branch;"," branch.wire();"," var count = 0, i, children = branch.get('children');"," for (i in children) {"," // Add each branch to the tree"," if (children[i].type == NODETYPE.COURSE) {"," count++;"," }"," if (typeof(children[i]) === 'object') {"," branch.addChild(children[i]);"," }"," }"," if ((branch.get('type') == NODETYPE.CATEGORY || branch.get('type') == NODETYPE.MYCATEGORY)"," && count >= M.block_navigation.courselimit) {"," this.addViewAllCoursesChild(branch);"," }"," }"," return true;"," },",""," /**"," * Add a link to view all courses in a category"," */"," addViewAllCoursesChild: function(branch) {"," var url = null;"," if (branch.get('type') == NODETYPE.ROOTNODE) {"," if (branch.get('key') === 'mycourses') {"," url = M.cfg.wwwroot + '/my';"," } else {"," url = M.cfg.wwwroot + '/course/index.php';"," }"," } else {"," url = M.cfg.wwwroot+'/course/category.php?id=' + branch.get('key');"," }"," branch.addChild({"," name : M.str.moodle.viewallcourses,"," title : M.str.moodle.viewallcourses,"," link : url,"," haschildren : false,"," icon : {'pix':\"i/navigationitem\",'component':'moodle'}"," });"," }","};","Y.extend(BRANCH, Y.Base, BRANCH.prototype, {"," NAME : 'navigation-branch',"," ATTRS : {"," tree : {"," validator : Y.Lang.isObject"," },"," name : {"," value : '',"," validator : Y.Lang.isString,"," setter : function(val) {"," return val.replace(/\\n/g, '<br />');"," }"," },"," title : {"," value : '',"," validator : Y.Lang.isString"," },"," id : {"," value : '',"," validator : Y.Lang.isString,"," getter : function(val) {"," if (val === '') {"," val = 'expandable_branch_'+M.block_navigation.expandablebranchcount;"," M.block_navigation.expandablebranchcount++;"," }"," return val;"," }"," },"," key : {"," value : null"," },"," type : {"," value : null"," },"," link : {"," value : false"," },"," icon : {"," value : false,"," validator : Y.Lang.isObject"," },"," expandable : {"," value : false,"," validator : Y.Lang.isBool"," },"," hidden : {"," value : false,"," validator : Y.Lang.isBool"," },"," haschildren : {"," value : false,"," validator : Y.Lang.isBool"," },"," children : {"," value : [],"," validator : Y.Lang.isArray"," }"," }","});","","/**"," * This namespace will contain all of the contents of the navigation blocks"," * global navigation and settings."," * @namespace"," */","M.block_navigation = M.block_navigation || {"," /** The number of expandable branches in existence */"," expandablebranchcount:1,"," courselimit : 20,"," instance : null,"," /**"," * Add new instance of navigation tree to tree collection"," */"," init_add_tree:function(properties) {"," if (properties.courselimit) {"," this.courselimit = properties.courselimit;"," }"," if (M.core_dock) {"," M.core_dock.init(Y);"," }"," new TREE(properties);"," }","};","","","}, '@VERSION@', {"," \"requires\": ["," \"base\","," \"core_dock\","," \"io-base\","," \"node\","," \"dom\","," \"event-custom\","," \"event-delegate\","," \"json-parse\""," ]","});"];
+_yuitest_coverage["build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js"].lines = {"1":0,"14":0,"31":0,"32":0,"33":0,"35":0,"37":0,"38":0,"39":0,"45":0,"47":0,"49":0,"55":0,"60":0,"62":0,"64":0,"69":0,"73":0,"83":0,"116":0,"117":0,"119":0,"132":0,"134":0,"137":0,"138":0,"142":0,"143":0,"146":0,"147":0,"148":0,"149":0,"150":0,"153":0,"154":0,"163":0,"164":0,"166":0,"168":0,"169":0,"173":0,"174":0,"181":0,"182":0,"183":0,"193":0,"195":0,"196":0,"200":0,"201":0,"202":0,"204":0,"205":0,"209":0,"210":0,"211":0,"213":0,"214":0,"215":0,"217":0,"218":0,"219":0,"221":0,"222":0,"224":0,"226":0,"227":0,"232":0,"233":0,"234":0,"235":0,"236":0,"243":0,"244":0,"245":0,"246":0,"247":0,"253":0,"270":0,"275":0,"276":0,"284":0,"285":0,"287":0,"296":0,"298":0,"300":0,"301":0,"303":0,"304":0,"306":0,"308":0,"309":0,"313":0,"315":0,"316":0,"317":0,"318":0,"319":0,"330":0,"331":0,"332":0,"333":0,"334":0,"337":0,"339":0,"340":0,"341":0,"342":0,"346":0,"347":0,"348":0,"349":0,"350":0,"351":0,"352":0,"353":0,"355":0,"356":0,"358":0,"359":0,"360":0,"365":0,"366":0,"367":0,"369":0,"371":0,"372":0,"373":0,"375":0,"376":0,"377":0,"379":0,"382":0,"383":0,"384":0,"385":0,"391":0,"392":0,"393":0,"395":0,"396":0,"397":0,"399":0,"405":0,"406":0,"407":0,"408":0,"410":0,"419":0,"420":0,"422":0,"424":0,"426":0,"427":0,"428":0,"431":0,"433":0,"436":0,"438":0,"440":0,"442":0,"450":0,"458":0,"465":0,"466":0,"467":0,"468":0,"469":0,"470":0,"471":0,"472":0,"473":0,"474":0,"476":0,"479":0,"481":0,"483":0,"489":0,"490":0,"498":0,"499":0,"500":0,"501":0,"502":0,"503":0,"505":0,"506":0,"508":0,"509":0,"512":0,"514":0,"517":0,"524":0,"525":0,"526":0,"527":0,"529":0,"532":0,"534":0,"543":0,"553":0,"564":0,"565":0,"566":0,"568":0,"608":0,"617":0,"618":0,"620":0,"621":0,"623":0};
+_yuitest_coverage["build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js"].functions = {"_keyHandler:30":0,"on:43":0,"detach:53":0,"delegate:58":0,"detachDelegate:68":0,"TREE:116":0,"initializer:131":0,"fire_branch_action:180":0,"(anonymous 2):233":0,"toggleExpansion:189":0,"setter:269":0,"BRANCH:284":0,"initializer:295":0,"draw:328":0,"wire:390":0,"getChildrenUL:404":0,"ajaxLoad:418":0,"ajaxProcessResponse:464":0,"addChild:496":0,"addViewAllCoursesChild:523":0,"setter:552":0,"getter:563":0,"init_add_tree:616":0,"(anonymous 1):1":0};
+_yuitest_coverage["build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js"].coveredLines = 212;
+_yuitest_coverage["build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js"].coveredFunctions = 24;
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 1);
+YUI.add('moodle-block_navigation-navigation', function (Y, NAME) {
+
+/**
+ * A 'actionkey' Event to help with Y.delegate().
+ * The event consists of the left arrow, right arrow, enter and space keys.
+ * More keys can be mapped to action meanings.
+ * actions: collapse , expand, toggle, enter.
+ *
+ * This event is delegated to branches in the navigation tree.
+ * The on() method to subscribe allows specifying the desired trigger actions as JSON.
+ *
+ * Todo: This could be centralised, a similar Event is defined in blocks/dock.js
+ */
+_yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "(anonymous 1)", 1);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 14);
+Y.Event.define("actionkey", {
+ // Webkit and IE repeat keydown when you hold down arrow keys.
+ // Opera links keypress to page scroll; others keydown.
+ // Firefox prevents page scroll via preventDefault() on either
+ // keydown or keypress.
+ _event: (Y.UA.webkit || Y.UA.ie) ? 'keydown' : 'keypress',
+
+ _keys: {
+ //arrows
+ '37': 'collapse',
+ '39': 'expand',
+ //(@todo: lrt/rtl/M.core_dock.cfg.orientation decision to assign arrow to meanings)
+ '32': 'toggle',
+ '13': 'enter'
+ },
+
+ _keyHandler: function (e, notifier, args) {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "_keyHandler", 30);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 31);
+var actObj;
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 32);
+if (!args.actions) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 33);
+actObj = {collapse:true, expand:true, toggle:true, enter:true};
+ } else {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 35);
+actObj = args.actions;
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 37);
+if (this._keys[e.keyCode] && actObj[this._keys[e.keyCode]]) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 38);
+e.action = this._keys[e.keyCode];
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 39);
+notifier.fire(e);
+ }
+ },
+
+ on: function (node, sub, notifier) {
+ // subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions).
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "on", 43);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 45);
+if (sub.args === null) {
+ //no actions given
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 47);
+sub._detacher = node.on(this._event, this._keyHandler,this, notifier, {actions:false});
+ } else {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 49);
+sub._detacher = node.on(this._event, this._keyHandler,this, notifier, sub.args[0]);
+ }
+ },
+
+ detach: function (node, sub) {
+ //detach our _detacher handle of the subscription made in on()
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "detach", 53);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 55);
+sub._detacher.detach();
+ },
+
+ delegate: function (node, sub, notifier, filter) {
+ // subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions).
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "delegate", 58);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 60);
+if (sub.args === null) {
+ //no actions given
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 62);
+sub._delegateDetacher = node.delegate(this._event, this._keyHandler,filter, this, notifier, {actions:false});
+ } else {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 64);
+sub._delegateDetacher = node.delegate(this._event, this._keyHandler,filter, this, notifier, sub.args[0]);
+ }
+ },
+
+ detachDelegate: function (node, sub) {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "detachDelegate", 68);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 69);
+sub._delegateDetacher.detach();
+ }
+});
+
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 73);
+var EXPANSIONLIMIT_EVERYTHING = 0,
+ //EXPANSIONLIMIT_COURSE = 20,
+ //EXPANSIONLIMIT_SECTION = 30,
+ EXPANSIONLIMIT_ACTIVITY = 40;
+
+/**
+ * Mappings for the different types of nodes coming from the navigation.
+ * Copied from lib/navigationlib.php navigation_node constants.
+ * @type object
+ */
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 83);
+var NODETYPE = {
+ /** @type int Root node = 0 */
+ ROOTNODE : 0,
+ /** @type int System context = 1 */
+ SYSTEM : 1,
+ /** @type int Course category = 10 */
+ CATEGORY : 10,
+ /** @type int MYCATEGORY = 11 */
+ MYCATEGORY : 11,
+ /** @type int Course = 20 */
+ COURSE : 20,
+ /** @type int Course section = 30 */
+ SECTION : 30,
+ /** @type int Activity (course module) = 40 */
+ ACTIVITY : 40,
+ /** @type int Resource (course module = 50 */
+ RESOURCE : 50,
+ /** @type int Custom node (could be anything) = 60 */
+ CUSTOM : 60,
+ /** @type int Setting = 70 */
+ SETTING : 70,
+ /** @type int User context = 80 */
+ USER : 80,
+ /** @type int Container = 90 */
+ CONTAINER : 90
+};
+
+/**
+ * Navigation tree class.
+ *
+ * This class establishes the tree initially, creating expandable branches as
+ * required, and delegating the expand/collapse event.
+ */
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 116);
+var TREE = function() {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "TREE", 116);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 117);
+TREE.superclass.constructor.apply(this, arguments);
+};
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 119);
+TREE.prototype = {
+ /**
+ * The tree's ID, normally its block instance id.
+ */
+ id : null,
+ /**
+ * An array of initialised branches.
+ */
+ branches : [],
+ /**
+ * Initialise the tree object when its first created.
+ */
+ initializer : function(config) {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "initializer", 131);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 132);
+this.id = config.id;
+
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 134);
+var node = Y.one('#inst'+config.id);
+
+ // Can't find the block instance within the page
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 137);
+if (node === null) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 138);
+return;
+ }
+
+ // Delegate event to toggle expansion
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 142);
+Y.delegate('click', this.toggleExpansion, node.one('.block_tree'), '.tree_item.branch', this);
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 143);
+Y.delegate('actionkey', this.toggleExpansion, node.one('.block_tree'), '.tree_item.branch', this);
+
+ // Gather the expandable branches ready for initialisation.
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 146);
+var expansions = [];
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 147);
+if (config.expansions) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 148);
+expansions = config.expansions;
+ } else {_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 149);
+if (window['navtreeexpansions'+config.id]) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 150);
+expansions = window['navtreeexpansions'+config.id];
+ }}
+ // Establish each expandable branch as a tree branch.
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 153);
+for (var i in expansions) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 154);
+var branch = new BRANCH({
+ tree:this,
+ branchobj:expansions[i],
+ overrides : {
+ expandable : true,
+ children : [],
+ haschildren : true
+ }
+ }).wire();
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 163);
+M.block_navigation.expandablebranchcount++;
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 164);
+this.branches[branch.get('id')] = branch;
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 166);
+if (M.block_navigation.expandablebranchcount > 0) {
+ // Delegate some events to handle AJAX loading.
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 168);
+Y.delegate('click', this.fire_branch_action, node.one('.block_tree'), '.tree_item.branch[data-expandable]', this);
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 169);
+Y.delegate('actionkey', this.fire_branch_action, node.one('.block_tree'), '.tree_item.branch[data-expandable]', this);
+ }
+
+ // Call the generic blocks init method to add all the generic stuff
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 173);
+if (this.get('candock')) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 174);
+this.initialise_block(Y, node);
+ }
+ },
+ /**
+ * Fire actions for a branch when an event occurs.
+ */
+ fire_branch_action : function(event) {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "fire_branch_action", 180);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 181);
+var id = event.currentTarget.getAttribute('id');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 182);
+var branch = this.branches[id];
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 183);
+branch.ajaxLoad(event);
+ },
+ /**
+ * This is a callback function responsible for expanding and collapsing the
+ * branches of the tree. It is delegated to rather than multiple event handles.
+ */
+ toggleExpansion : function(e) {
+ // First check if they managed to click on the li iteslf, then find the closest
+ // LI ancestor and use that
+
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "toggleExpansion", 189);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 193);
+if (e.target.test('a') && (e.keyCode === 0 || e.keyCode === 13)) {
+ // A link has been clicked (or keypress is 'enter') don't fire any more events just do the default.
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 195);
+e.stopPropagation();
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 196);
+return;
+ }
+
+ // Makes sure we can get to the LI containing the branch.
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 200);
+var target = e.target;
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 201);
+if (!target.test('li')) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 202);
+target = target.ancestor('li');
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 204);
+if (!target) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 205);
+return;
+ }
+
+ // Toggle expand/collapse providing its not a root level branch.
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 209);
+if (!target.hasClass('depth_1')) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 210);
+if (e.type === 'actionkey') {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 211);
+switch (e.action) {
+ case 'expand' :
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 213);
+target.removeClass('collapsed');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 214);
+target.set('aria-expanded', true);
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 215);
+break;
+ case 'collapse' :
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 217);
+target.addClass('collapsed');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 218);
+target.set('aria-expanded', false);
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 219);
+break;
+ default :
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 221);
+target.toggleClass('collapsed');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 222);
+target.set('aria-expanded', !target.hasClass('collapsed'));
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 224);
+e.halt();
+ } else {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 226);
+target.toggleClass('collapsed');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 227);
+target.set('aria-expanded', !target.hasClass('collapsed'));
+ }
+ }
+
+ // If the accordian feature has been enabled collapse all siblings.
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 232);
+if (this.get('accordian')) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 233);
+target.siblings('li').each(function(){
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "(anonymous 2)", 233);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 234);
+if (this.get('id') !== target.get('id') && !this.hasClass('collapsed')) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 235);
+this.addClass('collapsed');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 236);
+this.set('aria-expanded', false);
+ }
+ });
+ }
+
+ // If this block can dock tell the dock to resize if required and check
+ // the width on the dock panel in case it is presently in use.
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 243);
+if (this.get('candock')) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 244);
+M.core_dock.resize();
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 245);
+var panel = M.core_dock.getPanel();
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 246);
+if (panel.visible) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 247);
+panel.correctWidth();
+ }
+ }
+ }
+};
+// The tree extends the YUI base foundation.
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 253);
+Y.extend(TREE, Y.Base, TREE.prototype, {
+ NAME : 'navigation-tree',
+ ATTRS : {
+ instance : {
+ value : null
+ },
+ candock : {
+ validator : Y.Lang.isBool,
+ value : false
+ },
+ accordian : {
+ validator : Y.Lang.isBool,
+ value : false
+ },
+ expansionlimit : {
+ value : 0,
+ setter : function(val) {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "setter", 269);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 270);
+return parseInt(val, 10);
+ }
+ }
+ }
+});
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 275);
+if (M.core_dock && M.core_dock.genericblock) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 276);
+Y.augment(TREE, M.core_dock.genericblock);
+}
+
+/**
+ * The tree branch class.
+ * This class is used to manage a tree branch, in particular its ability to load
+ * its contents by AJAX.
+ */
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 284);
+BRANCH = function() {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "BRANCH", 284);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 285);
+BRANCH.superclass.constructor.apply(this, arguments);
+};
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 287);
+BRANCH.prototype = {
+ /**
+ * The node for this branch (p)
+ */
+ node : null,
+ /**
+ * Initialises the branch when it is first created.
+ */
+ initializer : function(config) {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "initializer", 295);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 296);
+var i,
+ children;
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 298);
+if (config.branchobj !== null) {
+ // Construct from the provided xml
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 300);
+for (i in config.branchobj) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 301);
+this.set(i, config.branchobj[i]);
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 303);
+children = this.get('children');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 304);
+this.set('haschildren', (children.length > 0));
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 306);
+if (config.overrides !== null) {
+ // Construct from the provided xml
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 308);
+for (i in config.overrides) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 309);
+this.set(i, config.overrides[i]);
+ }
+ }
+ // Get the node for this branch
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 313);
+this.node = Y.one('#', this.get('id'));
+ // Now check whether the branch is not expandable because of the expansionlimit
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 315);
+var expansionlimit = this.get('tree').get('expansionlimit');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 316);
+var type = this.get('type');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 317);
+if (expansionlimit !== EXPANSIONLIMIT_EVERYTHING && type >= expansionlimit && type <= EXPANSIONLIMIT_ACTIVITY) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 318);
+this.set('expandable', false);
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 319);
+this.set('haschildren', false);
+ }
+ },
+ /**
+ * Draws the branch within the tree.
+ *
+ * This function creates a DOM structure for the branch and then injects
+ * it into the navigation tree at the correct point.
+ */
+ draw : function(element) {
+
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "draw", 328);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 330);
+var isbranch = (this.get('expandable') || this.get('haschildren'));
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 331);
+var branchli = Y.Node.create('<li></li>');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 332);
+var link = this.get('link');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 333);
+var branchp = Y.Node.create('<p class="tree_item"></p>').setAttribute('id', this.get('id'));
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 334);
+if (!link) {
+ //add tab focus if not link (so still one focus per menu node).
+ // it was suggested to have 2 foci. one for the node and one for the link in MDL-27428.
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 337);
+branchp.setAttribute('tabindex', '0');
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 339);
+if (isbranch) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 340);
+branchli.addClass('collapsed').addClass('contains_branch');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 341);
+branchli.set('aria-expanded', false);
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 342);
+branchp.addClass('branch');
+ }
+
+ // Prepare the icon, should be an object representing a pix_icon
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 346);
+var branchicon = false;
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 347);
+var icon = this.get('icon');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 348);
+if (icon && (!isbranch || this.get('type') == NODETYPE.ACTIVITY)) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 349);
+branchicon = Y.Node.create('<img alt="" />');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 350);
+branchicon.setAttribute('src', M.util.image_url(icon.pix, icon.component));
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 351);
+branchli.addClass('item_with_icon');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 352);
+if (icon.alt) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 353);
+branchicon.setAttribute('alt', icon.alt);
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 355);
+if (icon.title) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 356);
+branchicon.setAttribute('title', icon.title);
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 358);
+if (icon.classes) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 359);
+for (var i in icon.classes) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 360);
+branchicon.addClass(icon.classes[i]);
+ }
+ }
+ }
+
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 365);
+if (!link) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 366);
+if (branchicon) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 367);
+branchp.appendChild(branchicon);
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 369);
+branchp.append(this.get('name'));
+ } else {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 371);
+var branchlink = Y.Node.create('<a title="'+this.get('title')+'" href="'+link+'"></a>');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 372);
+if (branchicon) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 373);
+branchlink.appendChild(branchicon);
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 375);
+branchlink.append(this.get('name'));
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 376);
+if (this.get('hidden')) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 377);
+branchlink.addClass('dimmed');
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 379);
+branchp.appendChild(branchlink);
+ }
+
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 382);
+branchli.appendChild(branchp);
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 383);
+element.appendChild(branchli);
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 384);
+this.node = branchp;
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 385);
+return this;
+ },
+ /**
+ * Attaches required events to the branch structure.
+ */
+ wire : function() {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "wire", 390);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 391);
+this.node = this.node || Y.one('#'+this.get('id'));
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 392);
+if (!this.node) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 393);
+return false;
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 395);
+if (this.get('expandable')) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 396);
+this.node.setAttribute('data-expandable', '1');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 397);
+this.node.setAttribute('data-loaded', '0');
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 399);
+return this;
+ },
+ /**
+ * Gets the UL element that children for this branch should be inserted into.
+ */
+ getChildrenUL : function() {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "getChildrenUL", 404);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 405);
+var ul = this.node.next('ul');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 406);
+if (!ul) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 407);
+ul = Y.Node.create('<ul></ul>');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 408);
+this.node.ancestor().append(ul);
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 410);
+return ul;
+ },
+ /**
+ * Load the content of the branch via AJAX.
+ *
+ * This function calls ajaxProcessResponse with the result of the AJAX
+ * request made here.
+ */
+ ajaxLoad : function(e) {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "ajaxLoad", 418);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 419);
+if (e.type === 'actionkey' && e.action !== 'enter') {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 420);
+e.halt();
+ } else {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 422);
+e.stopPropagation();
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 424);
+if (e.type === 'actionkey' && e.action === 'enter' && e.target.test('A')) {
+ // No ajaxLoad for enter.
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 426);
+this.node.setAttribute('data-expandable', '0');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 427);
+this.node.setAttribute('data-loaded', '1');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 428);
+return true;
+ }
+
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 431);
+if (this.node.hasClass('loadingbranch')) {
+ // Already loading. Just skip.
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 433);
+return true;
+ }
+
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 436);
+if (this.node.getAttribute('data-loaded') === '1') {
+ // We've already loaded this stuff.
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 438);
+return true;
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 440);
+this.node.addClass('loadingbranch');
+
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 442);
+var params = {
+ elementid : this.get('id'),
+ id : this.get('key'),
+ type : this.get('type'),
+ sesskey : M.cfg.sesskey,
+ instance : this.get('tree').get('instance')
+ };
+
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 450);
+Y.io(M.cfg.wwwroot+'/lib/ajax/getnavbranch.php', {
+ method:'POST',
+ data: build_querystring(params),
+ on: {
+ complete: this.ajaxProcessResponse
+ },
+ context:this
+ });
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 458);
+return true;
+ },
+ /**
+ * Processes an AJAX request to load the content of this branch through
+ * AJAX.
+ */
+ ajaxProcessResponse : function(tid, outcome) {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "ajaxProcessResponse", 464);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 465);
+this.node.removeClass('loadingbranch');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 466);
+this.node.setAttribute('data-loaded', '1');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 467);
+try {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 468);
+var object = Y.JSON.parse(outcome.responseText);
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 469);
+if (object.children && object.children.length > 0) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 470);
+var coursecount = 0;
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 471);
+for (var i in object.children) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 472);
+if (typeof(object.children[i])==='object') {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 473);
+if (object.children[i].type == NODETYPE.COURSE) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 474);
+coursecount++;
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 476);
+this.addChild(object.children[i]);
+ }
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 479);
+if ((this.get('type') == NODETYPE.CATEGORY || this.get('type') == NODETYPE.ROOTNODE || this.get('type') == NODETYPE.MYCATEGORY)
+ && coursecount >= M.block_navigation.courselimit) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 481);
+this.addViewAllCoursesChild(this);
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 483);
+return true;
+ }
+ } catch (ex) {
+ // If we got here then there was an error parsing the result
+ }
+ // The branch is empty so class it accordingly
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 489);
+this.node.replaceClass('branch', 'emptybranch');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 490);
+return true;
+ },
+ /**
+ * Turns the branch object passed to the method into a proper branch object
+ * and then adds it as a child of this branch.
+ */
+ addChild : function(branchobj) {
+ // Make the new branch into an object
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "addChild", 496);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 498);
+var branch = new BRANCH({tree:this.get('tree'), branchobj:branchobj});
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 499);
+if (branch.draw(this.getChildrenUL())) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 500);
+this.get('tree').branches[branch.get('id')] = branch;
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 501);
+branch.wire();
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 502);
+var count = 0, i, children = branch.get('children');
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 503);
+for (i in children) {
+ // Add each branch to the tree
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 505);
+if (children[i].type == NODETYPE.COURSE) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 506);
+count++;
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 508);
+if (typeof(children[i]) === 'object') {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 509);
+branch.addChild(children[i]);
+ }
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 512);
+if ((branch.get('type') == NODETYPE.CATEGORY || branch.get('type') == NODETYPE.MYCATEGORY)
+ && count >= M.block_navigation.courselimit) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 514);
+this.addViewAllCoursesChild(branch);
+ }
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 517);
+return true;
+ },
+
+ /**
+ * Add a link to view all courses in a category
+ */
+ addViewAllCoursesChild: function(branch) {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "addViewAllCoursesChild", 523);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 524);
+var url = null;
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 525);
+if (branch.get('type') == NODETYPE.ROOTNODE) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 526);
+if (branch.get('key') === 'mycourses') {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 527);
+url = M.cfg.wwwroot + '/my';
+ } else {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 529);
+url = M.cfg.wwwroot + '/course/index.php';
+ }
+ } else {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 532);
+url = M.cfg.wwwroot+'/course/category.php?id=' + branch.get('key');
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 534);
+branch.addChild({
+ name : M.str.moodle.viewallcourses,
+ title : M.str.moodle.viewallcourses,
+ link : url,
+ haschildren : false,
+ icon : {'pix':"i/navigationitem",'component':'moodle'}
+ });
+ }
+};
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 543);
+Y.extend(BRANCH, Y.Base, BRANCH.prototype, {
+ NAME : 'navigation-branch',
+ ATTRS : {
+ tree : {
+ validator : Y.Lang.isObject
+ },
+ name : {
+ value : '',
+ validator : Y.Lang.isString,
+ setter : function(val) {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "setter", 552);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 553);
+return val.replace(/\n/g, '<br />');
+ }
+ },
+ title : {
+ value : '',
+ validator : Y.Lang.isString
+ },
+ id : {
+ value : '',
+ validator : Y.Lang.isString,
+ getter : function(val) {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "getter", 563);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 564);
+if (val === '') {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 565);
+val = 'expandable_branch_'+M.block_navigation.expandablebranchcount;
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 566);
+M.block_navigation.expandablebranchcount++;
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 568);
+return val;
+ }
+ },
+ key : {
+ value : null
+ },
+ type : {
+ value : null
+ },
+ link : {
+ value : false
+ },
+ icon : {
+ value : false,
+ validator : Y.Lang.isObject
+ },
+ expandable : {
+ value : false,
+ validator : Y.Lang.isBool
+ },
+ hidden : {
+ value : false,
+ validator : Y.Lang.isBool
+ },
+ haschildren : {
+ value : false,
+ validator : Y.Lang.isBool
+ },
+ children : {
+ value : [],
+ validator : Y.Lang.isArray
+ }
+ }
+});
+
+/**
+ * This namespace will contain all of the contents of the navigation blocks
+ * global navigation and settings.
+ * @namespace
+ */
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 608);
+M.block_navigation = M.block_navigation || {
+ /** The number of expandable branches in existence */
+ expandablebranchcount:1,
+ courselimit : 20,
+ instance : null,
+ /**
+ * Add new instance of navigation tree to tree collection
+ */
+ init_add_tree:function(properties) {
+ _yuitest_coverfunc("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", "init_add_tree", 616);
+_yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 617);
+if (properties.courselimit) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 618);
+this.courselimit = properties.courselimit;
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 620);
+if (M.core_dock) {
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 621);
+M.core_dock.init(Y);
+ }
+ _yuitest_coverline("build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js", 623);
+new TREE(properties);
+ }
+};
+
+
+}, '@VERSION@', {
+ "requires": [
+ "base",
+ "core_dock",
+ "io-base",
+ "node",
+ "dom",
+ "event-custom",
+ "event-delegate",
+ "json-parse"
+ ]
+});
View
639 .../yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-debug.js
@@ -0,0 +1,639 @@
+YUI.add('moodle-block_navigation-navigation', function (Y, NAME) {
+
+/**
+ * A 'actionkey' Event to help with Y.delegate().
+ * The event consists of the left arrow, right arrow, enter and space keys.
+ * More keys can be mapped to action meanings.
+ * actions: collapse , expand, toggle, enter.
+ *
+ * This event is delegated to branches in the navigation tree.
+ * The on() method to subscribe allows specifying the desired trigger actions as JSON.
+ *
+ * Todo: This could be centralised, a similar Event is defined in blocks/dock.js
+ */
+Y.Event.define("actionkey", {
+ // Webkit and IE repeat keydown when you hold down arrow keys.
+ // Opera links keypress to page scroll; others keydown.
+ // Firefox prevents page scroll via preventDefault() on either
+ // keydown or keypress.
+ _event: (Y.UA.webkit || Y.UA.ie) ? 'keydown' : 'keypress',
+
+ _keys: {
+ //arrows
+ '37': 'collapse',
+ '39': 'expand',
+ //(@todo: lrt/rtl/M.core_dock.cfg.orientation decision to assign arrow to meanings)
+ '32': 'toggle',
+ '13': 'enter'
+ },
+
+ _keyHandler: function (e, notifier, args) {
+ var actObj;
+ if (!args.actions) {
+ actObj = {collapse:true, expand:true, toggle:true, enter:true};
+ } else {
+ actObj = args.actions;
+ }
+ if (this._keys[e.keyCode] && actObj[this._keys[e.keyCode]]) {
+ e.action = this._keys[e.keyCode];
+ notifier.fire(e);
+ }
+ },
+
+ on: function (node, sub, notifier) {
+ // subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions).
+ if (sub.args === null) {
+ //no actions given
+ sub._detacher = node.on(this._event, this._keyHandler,this, notifier, {actions:false});
+ } else {
+ sub._detacher = node.on(this._event, this._keyHandler,this, notifier, sub.args[0]);
+ }
+ },
+
+ detach: function (node, sub) {
+ //detach our _detacher handle of the subscription made in on()
+ sub._detacher.detach();
+ },
+
+ delegate: function (node, sub, notifier, filter) {
+ // subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions).
+ if (sub.args === null) {
+ //no actions given
+ sub._delegateDetacher = node.delegate(this._event, this._keyHandler,filter, this, notifier, {actions:false});
+ } else {
+ sub._delegateDetacher = node.delegate(this._event, this._keyHandler,filter, this, notifier, sub.args[0]);
+ }
+ },
+
+ detachDelegate: function (node, sub) {
+ sub._delegateDetacher.detach();
+ }
+});
+
+var EXPANSIONLIMIT_EVERYTHING = 0,
+ //EXPANSIONLIMIT_COURSE = 20,
+ //EXPANSIONLIMIT_SECTION = 30,
+ EXPANSIONLIMIT_ACTIVITY = 40;
+
+/**
+ * Mappings for the different types of nodes coming from the navigation.
+ * Copied from lib/navigationlib.php navigation_node constants.
+ * @type object
+ */
+var NODETYPE = {
+ /** @type int Root node = 0 */
+ ROOTNODE : 0,
+ /** @type int System context = 1 */
+ SYSTEM : 1,
+ /** @type int Course category = 10 */
+ CATEGORY : 10,
+ /** @type int MYCATEGORY = 11 */
+ MYCATEGORY : 11,
+ /** @type int Course = 20 */
+ COURSE : 20,
+ /** @type int Course section = 30 */
+ SECTION : 30,
+ /** @type int Activity (course module) = 40 */
+ ACTIVITY : 40,
+ /** @type int Resource (course module = 50 */
+ RESOURCE : 50,
+ /** @type int Custom node (could be anything) = 60 */
+ CUSTOM : 60,
+ /** @type int Setting = 70 */
+ SETTING : 70,
+ /** @type int User context = 80 */
+ USER : 80,
+ /** @type int Container = 90 */
+ CONTAINER : 90
+};
+
+/**
+ * Navigation tree class.
+ *
+ * This class establishes the tree initially, creating expandable branches as
+ * required, and delegating the expand/collapse event.
+ */
+var TREE = function() {
+ TREE.superclass.constructor.apply(this, arguments);
+};
+TREE.prototype = {
+ /**
+ * The tree's ID, normally its block instance id.
+ */
+ id : null,
+ /**
+ * An array of initialised branches.
+ */
+ branches : [],
+ /**
+ * Initialise the tree object when its first created.
+ */
+ initializer : function(config) {
+ this.id = config.id;
+
+ var node = Y.one('#inst'+config.id);
+
+ // Can't find the block instance within the page
+ if (node === null) {
+ return;
+ }
+
+ // Delegate event to toggle expansion
+ Y.delegate('click', this.toggleExpansion, node.one('.block_tree'), '.tree_item.branch', this);
+ Y.delegate('actionkey', this.toggleExpansion, node.one('.block_tree'), '.tree_item.branch', this);
+
+ // Gather the expandable branches ready for initialisation.
+ var expansions = [];
+ if (config.expansions) {
+ expansions = config.expansions;
+ } else if (window['navtreeexpansions'+config.id]) {
+ expansions = window['navtreeexpansions'+config.id];
+ }
+ // Establish each expandable branch as a tree branch.
+ for (var i in expansions) {
+ var branch = new BRANCH({
+ tree:this,
+ branchobj:expansions[i],
+ overrides : {
+ expandable : true,
+ children : [],
+ haschildren : true
+ }
+ }).wire();
+ M.block_navigation.expandablebranchcount++;
+ this.branches[branch.get('id')] = branch;
+ }
+ if (M.block_navigation.expandablebranchcount > 0) {
+ // Delegate some events to handle AJAX loading.
+ Y.delegate('click', this.fire_branch_action, node.one('.block_tree'), '.tree_item.branch[data-expandable]', this);
+ Y.delegate('actionkey', this.fire_branch_action, node.one('.block_tree'), '.tree_item.branch[data-expandable]', this);
+ }
+
+ // Call the generic blocks init method to add all the generic stuff
+ if (this.get('candock')) {
+ this.initialise_block(Y, node);
+ }
+ },
+ /**
+ * Fire actions for a branch when an event occurs.
+ */
+ fire_branch_action : function(event) {
+ var id = event.currentTarget.getAttribute('id');
+ var branch = this.branches[id];
+ branch.ajaxLoad(event);
+ },
+ /**
+ * This is a callback function responsible for expanding and collapsing the
+ * branches of the tree. It is delegated to rather than multiple event handles.
+ */
+ toggleExpansion : function(e) {
+ // First check if they managed to click on the li iteslf, then find the closest
+ // LI ancestor and use that
+
+ if (e.target.test('a') && (e.keyCode === 0 || e.keyCode === 13)) {
+ // A link has been clicked (or keypress is 'enter') don't fire any more events just do the default.
+ e.stopPropagation();
+ return;
+ }
+
+ // Makes sure we can get to the LI containing the branch.
+ var target = e.target;
+ if (!target.test('li')) {
+ target = target.ancestor('li');
+ }
+ if (!target) {
+ return;
+ }
+
+ // Toggle expand/collapse providing its not a root level branch.
+ if (!target.hasClass('depth_1')) {
+ if (e.type === 'actionkey') {
+ switch (e.action) {
+ case 'expand' :
+ target.removeClass('collapsed');
+ target.set('aria-expanded', true);
+ break;
+ case 'collapse' :
+ target.addClass('collapsed');
+ target.set('aria-expanded', false);
+ break;
+ default :
+ target.toggleClass('collapsed');
+ target.set('aria-expanded', !target.hasClass('collapsed'));
+ }
+ e.halt();
+ } else {
+ target.toggleClass('collapsed');
+ target.set('aria-expanded', !target.hasClass('collapsed'));
+ }
+ }
+
+ // If the accordian feature has been enabled collapse all siblings.
+ if (this.get('accordian')) {
+ target.siblings('li').each(function(){
+ if (this.get('id') !== target.get('id') && !this.hasClass('collapsed')) {
+ this.addClass('collapsed');
+ this.set('aria-expanded', false);
+ }
+ });
+ }
+
+ // If this block can dock tell the dock to resize if required and check
+ // the width on the dock panel in case it is presently in use.
+ if (this.get('candock')) {
+ M.core_dock.resize();
+ var panel = M.core_dock.getPanel();
+ if (panel.visible) {
+ panel.correctWidth();
+ }
+ }
+ }
+};
+// The tree extends the YUI base foundation.
+Y.extend(TREE, Y.Base, TREE.prototype, {
+ NAME : 'navigation-tree',
+ ATTRS : {
+ instance : {
+ value : null
+ },
+ candock : {
+ validator : Y.Lang.isBool,
+ value : false
+ },
+ accordian : {
+ validator : Y.Lang.isBool,
+ value : false
+ },
+ expansionlimit : {
+ value : 0,
+ setter : function(val) {
+ return parseInt(val, 10);
+ }
+ }
+ }
+});
+if (M.core_dock && M.core_dock.genericblock) {
+ Y.augment(TREE, M.core_dock.genericblock);
+}
+
+/**
+ * The tree branch class.
+ * This class is used to manage a tree branch, in particular its ability to load
+ * its contents by AJAX.
+ */
+BRANCH = function() {
+ BRANCH.superclass.constructor.apply(this, arguments);
+};
+BRANCH.prototype = {
+ /**
+ * The node for this branch (p)
+ */
+ node : null,
+ /**
+ * Initialises the branch when it is first created.
+ */
+ initializer : function(config) {
+ var i,
+ children;
+ if (config.branchobj !== null) {
+ // Construct from the provided xml
+ for (i in config.branchobj) {
+ this.set(i, config.branchobj[i]);
+ }
+ children = this.get('children');
+ this.set('haschildren', (children.length > 0));
+ }
+ if (config.overrides !== null) {
+ // Construct from the provided xml
+ for (i in config.overrides) {
+ this.set(i, config.overrides[i]);
+ }
+ }
+ // Get the node for this branch
+ this.node = Y.one('#', this.get('id'));
+ // Now check whether the branch is not expandable because of the expansionlimit
+ var expansionlimit = this.get('tree').get('expansionlimit');
+ var type = this.get('type');
+ if (expansionlimit !== EXPANSIONLIMIT_EVERYTHING && type >= expansionlimit && type <= EXPANSIONLIMIT_ACTIVITY) {
+ this.set('expandable', false);
+ this.set('haschildren', false);
+ }
+ },
+ /**
+ * Draws the branch within the tree.
+ *
+ * This function creates a DOM structure for the branch and then injects
+ * it into the navigation tree at the correct point.
+ */
+ draw : function(element) {
+
+ var isbranch = (this.get('expandable') || this.get('haschildren'));
+ var branchli = Y.Node.create('<li></li>');
+ var link = this.get('link');
+ var branchp = Y.Node.create('<p class="tree_item"></p>').setAttribute('id', this.get('id'));
+ if (!link) {
+ //add tab focus if not link (so still one focus per menu node).
+ // it was suggested to have 2 foci. one for the node and one for the link in MDL-27428.
+ branchp.setAttribute('tabindex', '0');
+ }
+ if (isbranch) {
+ branchli.addClass('collapsed').addClass('contains_branch');
+ branchli.set('aria-expanded', false);
+ branchp.addClass('branch');
+ }
+
+ // Prepare the icon, should be an object representing a pix_icon
+ var branchicon = false;
+ var icon = this.get('icon');
+ if (icon && (!isbranch || this.get('type') == NODETYPE.ACTIVITY)) {
+ branchicon = Y.Node.create('<img alt="" />');
+ branchicon.setAttribute('src', M.util.image_url(icon.pix, icon.component));
+ branchli.addClass('item_with_icon');
+ if (icon.alt) {
+ branchicon.setAttribute('alt', icon.alt);
+ }
+ if (icon.title) {
+ branchicon.setAttribute('title', icon.title);
+ }
+ if (icon.classes) {
+ for (var i in icon.classes) {
+ branchicon.addClass(icon.classes[i]);
+ }
+ }
+ }
+
+ if (!link) {
+ if (branchicon) {
+ branchp.appendChild(branchicon);
+ }
+ branchp.append(this.get('name'));
+ } else {
+ var branchlink = Y.Node.create('<a title="'+this.get('title')+'" href="'+link+'"></a>');
+ if (branchicon) {
+ branchlink.appendChild(branchicon);
+ }
+ branchlink.append(this.get('name'));
+ if (this.get('hidden')) {
+ branchlink.addClass('dimmed');
+ }
+ branchp.appendChild(branchlink);
+ }
+
+ branchli.appendChild(branchp);
+ element.appendChild(branchli);
+ this.node = branchp;
+ return this;
+ },
+ /**
+ * Attaches required events to the branch structure.
+ */
+ wire : function() {
+ this.node = this.node || Y.one('#'+this.get('id'));
+ if (!this.node) {
+ return false;
+ }
+ if (this.get('expandable')) {
+ this.node.setAttribute('data-expandable', '1');
+ this.node.setAttribute('data-loaded', '0');
+ }
+ return this;
+ },
+ /**
+ * Gets the UL element that children for this branch should be inserted into.
+ */
+ getChildrenUL : function() {
+ var ul = this.node.next('ul');
+ if (!ul) {
+ ul = Y.Node.create('<ul></ul>');
+ this.node.ancestor().append(ul);
+ }
+ return ul;
+ },
+ /**
+ * Load the content of the branch via AJAX.
+ *
+ * This function calls ajaxProcessResponse with the result of the AJAX
+ * request made here.
+ */
+ ajaxLoad : function(e) {
+ if (e.type === 'actionkey' && e.action !== 'enter') {
+ e.halt();
+ } else {
+ e.stopPropagation();
+ }
+ if (e.type === 'actionkey' && e.action === 'enter' && e.target.test('A')) {
+ // No ajaxLoad for enter.
+ this.node.setAttribute('data-expandable', '0');
+ this.node.setAttribute('data-loaded', '1');
+ return true;
+ }
+
+ if (this.node.hasClass('loadingbranch')) {
+ // Already loading. Just skip.
+ return true;
+ }
+
+ if (this.node.getAttribute('data-loaded') === '1') {
+ // We've already loaded this stuff.
+ return true;
+ }
+ this.node.addClass('loadingbranch');
+
+ var params = {
+ elementid : this.get('id'),
+ id : this.get('key'),
+ type : this.get('type'),
+ sesskey : M.cfg.sesskey,
+ instance : this.get('tree').get('instance')
+ };
+
+ Y.io(M.cfg.wwwroot+'/lib/ajax/getnavbranch.php', {
+ method:'POST',
+ data: build_querystring(params),
+ on: {
+ complete: this.ajaxProcessResponse
+ },
+ context:this
+ });
+ return true;
+ },
+ /**
+ * Processes an AJAX request to load the content of this branch through
+ * AJAX.
+ */
+ ajaxProcessResponse : function(tid, outcome) {
+ this.node.removeClass('loadingbranch');
+ this.node.setAttribute('data-loaded', '1');
+ try {
+ var object = Y.JSON.parse(outcome.responseText);
+ if (object.children && object.children.length > 0) {
+ var coursecount = 0;
+ for (var i in object.children) {
+ if (typeof(object.children[i])==='object') {
+ if (object.children[i].type == NODETYPE.COURSE) {
+ coursecount++;
+ }
+ this.addChild(object.children[i]);
+ }
+ }
+ if ((this.get('type') == NODETYPE.CATEGORY || this.get('type') == NODETYPE.ROOTNODE || this.get('type') == NODETYPE.MYCATEGORY)
+ && coursecount >= M.block_navigation.courselimit) {
+ this.addViewAllCoursesChild(this);
+ }
+ return true;
+ }
+ } catch (ex) {
+ // If we got here then there was an error parsing the result
+ }
+ // The branch is empty so class it accordingly
+ this.node.replaceClass('branch', 'emptybranch');
+ return true;
+ },
+ /**
+ * Turns the branch object passed to the method into a proper branch object
+ * and then adds it as a child of this branch.
+ */
+ addChild : function(branchobj) {
+ // Make the new branch into an object
+ var branch = new BRANCH({tree:this.get('tree'), branchobj:branchobj});
+ if (branch.draw(this.getChildrenUL())) {
+ this.get('tree').branches[branch.get('id')] = branch;
+ branch.wire();
+ var count = 0, i, children = branch.get('children');
+ for (i in children) {
+ // Add each branch to the tree
+ if (children[i].type == NODETYPE.COURSE) {
+ count++;
+ }
+ if (typeof(children[i]) === 'object') {
+ branch.addChild(children[i]);
+ }
+ }
+ if ((branch.get('type') == NODETYPE.CATEGORY || branch.get('type') == NODETYPE.MYCATEGORY)
+ && count >= M.block_navigation.courselimit) {
+ this.addViewAllCoursesChild(branch);
+ }
+ }
+ return true;
+ },
+
+ /**
+ * Add a link to view all courses in a category
+ */
+ addViewAllCoursesChild: function(branch) {
+ var url = null;
+ if (branch.get('type') == NODETYPE.ROOTNODE) {
+ if (branch.get('key') === 'mycourses') {
+ url = M.cfg.wwwroot + '/my';
+ } else {
+ url = M.cfg.wwwroot + '/course/index.php';
+ }
+ } else {
+ url = M.cfg.wwwroot+'/course/category.php?id=' + branch.get('key');
+ }
+ branch.addChild({
+ name : M.str.moodle.viewallcourses,
+ title : M.str.moodle.viewallcourses,
+ link : url,
+ haschildren : false,
+ icon : {'pix':"i/navigationitem",'component':'moodle'}
+ });
+ }
+};
+Y.extend(BRANCH, Y.Base, BRANCH.prototype, {
+ NAME : 'navigation-branch',
+ ATTRS : {
+ tree : {
+ validator : Y.Lang.isObject
+ },
+ name : {
+ value : '',
+ validator : Y.Lang.isString,
+ setter : function(val) {
+ return val.replace(/\n/g, '<br />');
+ }
+ },
+ title : {
+ value : '',
+ validator : Y.Lang.isString
+ },
+ id : {
+ value : '',
+ validator : Y.Lang.isString,
+ getter : function(val) {
+ if (val === '') {
+ val = 'expandable_branch_'+M.block_navigation.expandablebranchcount;
+ M.block_navigation.expandablebranchcount++;
+ }
+ return val;
+ }
+ },
+ key : {
+ value : null
+ },
+ type : {
+ value : null
+ },
+ link : {
+ value : false
+ },
+ icon : {
+ value : false,
+ validator : Y.Lang.isObject
+ },
+ expandable : {
+ value : false,
+ validator : Y.Lang.isBool
+ },
+ hidden : {
+ value : false,
+ validator : Y.Lang.isBool
+ },
+ haschildren : {
+ value : false,
+ validator : Y.Lang.isBool
+ },
+ children : {
+ value : [],
+ validator : Y.Lang.isArray
+ }
+ }
+});
+
+/**
+ * This namespace will contain all of the contents of the navigation blocks
+ * global navigation and settings.
+ * @namespace
+ */
+M.block_navigation = M.block_navigation || {
+ /** The number of expandable branches in existence */
+ expandablebranchcount:1,
+ courselimit : 20,
+ instance : null,
+ /**
+ * Add new instance of navigation tree to tree collection
+ */
+ init_add_tree:function(properties) {
+ if (properties.courselimit) {
+ this.courselimit = properties.courselimit;
+ }
+ if (M.core_dock) {
+ M.core_dock.init(Y);
+ }
+ new TREE(properties);
+ }
+};
+
+
+}, '@VERSION@', {
+ "requires": [
+ "base",
+ "core_dock",
+ "io-base",
+ "node",
+ "dom",
+ "event-custom",
+ "event-delegate",
+ "json-parse"
+ ]
+});
View
2  ...on/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-min.js
@@ -0,0 +1,2 @@
+YUI.add("moodle-block_navigation-navigation",function(e,t){e.Event.define("actionkey",{_event:e.UA.webkit||e.UA.ie?"keydown":"keypress",_keys:{37:"collapse",39:"expand",32:"toggle",13:"enter"},_keyHandler:function(e,t,n){var r;n.actions?r=n.actions:r={collapse:!0,expand:!0,toggle:!0,enter:!0},this._keys[e.keyCode]&&r[this._keys[e.keyCode]]&&(e.action=this._keys[e.keyCode],t.fire(e))},on:function(e,t,n){t.args===null?t._detacher=e.on(this._event,this._keyHandler,this,n,{actions:!1}):t._detacher=e.on(this._event,this._keyHandler,this,n,t.args[0])},detach:function(e,t){t._detacher.detach()},delegate:function(e,t,n,r){t.args===null?t._delegateDetacher=e.delegate(this._event,this._keyHandler,r,this,n,{actions:!1}):t._delegateDetacher=e.delegate(this._event,this._keyHandler,r,this,n,t.args[0])},detachDelegate:function(e,t){t._delegateDetacher.detach()}});var n=0,r=40,i={ROOTNODE:0,SYSTEM:1,CATEGORY:10,MYCATEGORY:11,COURSE:20,SECTION:30,ACTIVITY:40,RESOURCE:50,CUSTOM:60,SETTING:70,USER:80,CONTAINER:90},s=function(){s.superclass.constructor.apply(this,arguments)};s.prototype={id:null,branches:[],initializer:function(t){this.id=t.id;var n=e.one("#inst"+t.id);if(n===null)return;e.delegate("click",this.toggleExpansion,n.one(".block_tree"),".tree_item.branch",this),e.delegate("actionkey",this.toggleExpansion,n.one(".block_tree"),".tree_item.branch",this);var r=[];t.expansions?r=t.expansions:window["navtreeexpansions"+t.id]&&(r=window["navtreeexpansions"+t.id]);for(var i in r){var s=(new BRANCH({tree:this,branchobj:r[i],overrides:{expandable:!0,children:[],haschildren:!0}})).wire();M.block_navigation.expandablebranchcount++,this.branches[s.get("id")]=s}M.block_navigation.expandablebranchcount>0&&(e.delegate("click",this.fire_branch_action,n.one(".block_tree"),".tree_item.branch[data-expandable]",this),e.delegate("actionkey",this.fire_branch_action,n.one(".block_tree"),".tree_item.branch[data-expandable]",this)),this.get("candock")&&this.initialise_block(e,n)},fire_branch_action:function(e){var t=e.currentTarget.getAttribute("id"),n=this.branches[t];n.ajaxLoad(e)},toggleExpansion:function(e){if(!(!e.target.test("a")||e.keyCode!==0&&e.keyCode!==13)){e.stopPropagation();return}var t=e.target;t.test("li")||(t=t.ancestor("li"));if(!t)return;if(!t.hasClass("depth_1"))if(e.type==="actionkey"){switch(e.action){case"expand":t.removeClass("collapsed"),t.set("aria-expanded",!0);break;case"collapse":t.addClass("collapsed"),t.set("aria-expanded",!1);break;default:t.toggleClass("collapsed"),t.set("aria-expanded",!t.hasClass("collapsed"))}e.halt()}else t.toggleClass("collapsed"),t.set("aria-expanded",!t.hasClass("collapsed"));this.get("accordian")&&t.siblings("li").each(function(){this.get("id")!==t.get("id")&&!this.hasClass("collapsed")&&(this.addClass("collapsed"),this.set("aria-expanded",!1))});if(this.get("candock")){M.core_dock.resize();var n=M.core_dock.getPanel();n.visible&&n.correctWidth()}}},e.extend(s,e.Base,s.prototype,{NAME:"navigation-tree",ATTRS:{instance:{value:null},candock:{validator:e.Lang.isBool,value:!1},accordian:{validator:e.Lang.isBool,value:!1},expansionlimit:{value:0,setter:function(e){return parseInt(e,10)}}}}),M.core_dock&&M.core_dock.genericblock&&e.augment(s,M.core_dock.genericblock),BRANCH=function(){BRANCH.superclass.constructor.apply(this,arguments)},BRANCH.prototype={node:null,initializer:function(t){var i,s;if(t.branchobj!==null){for(i in t.branchobj)this.set(i,t.branchobj[i]);s=this.get("children"),this.set("haschildren",s.length>0)}if(t.overrides!==null)for(i in t.overrides)this.set(i,t.overrides[i]);this.node=e.one("#",this.get("id"));var o=this.get("tree").get("expansionlimit"),u=this.get("type");o!==n&&u>=o&&u<=r&&(this.set("expandable",!1),this.set("haschildren",!1))},draw:function(t){var n=this.get("expandable")||this.get("haschildren"),r=e.Node.create("<li></li>"),s=this.get("link"),o=e.Node.create('<p class="tree_item"></p>').setAttribute("id",this.get("id"));s||o.setAttribute("tabindex","0"),n&&(r.addClass("collapsed").addClass("contains_branch"),r.set("aria-expanded",!1),o.addClass("branch"));var u=!1,a=this.get("icon");if(a&&(!n||this.get("type")==i.ACTIVITY)){u=e.Node.create('<img alt="" />'),u.setAttribute("src",M.util.image_url(a.pix,a.component)),r.addClass("item_with_icon"),a.alt&&u.setAttribute("alt",a.alt),a.title&&u.setAttribute("title",a.title);if(a.classes)for(var f in a.classes)u.addClass(a.classes[f])}if(!s)u&&o.appendChild(u),o.append(this.get("name"));else{var l=e.Node.create('<a title="'+this.get("title")+'" href="'+s+'"></a>');u&&l.appendChild(u),l.append(this.get("name")),this.get("hidden")&&l.addClass("dimmed"),o.appendChild(l)}return r.appendChild(o),t.appendChild(r),this.node=o,this},wire:function(){return this.node=this.node||e.one("#"+this.get("id")),this.node?(this.get("expandable")&&(this.node.setAttribute("data-expandable","1"),this.node.setAttribute("data-loaded","0")),this):!1},getChildrenUL:function(){var t=this.node.next("ul");return t||(t=e.Node.create("<ul></ul>"),this.node.ancestor().append(t)),t},ajaxLoad:function(t){t.type==="actionkey"&&t.action!=="enter"?t.halt():t.stopPropagation();if(t.type==="actionkey"&&t.action==="enter"&&t.target.test("A"))return this.node.setAttribute("data-expandable","0"),this.node.setAttribute("data-loaded","1"),!0;if(this.node.hasClass("loadingbranch"))return!0;if(this.node.getAttribute("data-loaded")==="1")return!0;this.node.addClass("loadingbranch");var n={elementid:this.get("id"),id:this.get("key"),type:this.get("type"),sesskey:M.cfg.sesskey,instance:this.get("tree").get("instance")};return e.io(M.cfg.wwwroot+"/lib/ajax/getnavbranch.php",{method:"POST",data:build_querystring(n),on:{complete:this.ajaxProcessResponse},context:this}),!0},ajaxProcessResponse:function(t,n){this.node.removeClass("loadingbranch"),this.node.setAttribute("data-loaded","1");try{var r=e.JSON.parse(n.responseText);if(r.children&&r.children.length>0){var s=0;for(var o in r.children)typeof r.children[o]=="object"&&(r.children[o].type==
+i.COURSE&&s++,this.addChild(r.children[o]));return(this.get("type")==i.CATEGORY||this.get("type")==i.ROOTNODE||this.get("type")==i.MYCATEGORY)&&s>=M.block_navigation.courselimit&&this.addViewAllCoursesChild(this),!0}}catch(u){}return this.node.replaceClass("branch","emptybranch"),!0},addChild:function(e){var t=new BRANCH({tree:this.get("tree"),branchobj:e});if(t.draw(this.getChildrenUL())){this.get("tree").branches[t.get("id")]=t,t.wire();var n=0,r,s=t.get("children");for(r in s)s[r].type==i.COURSE&&n++,typeof s[r]=="object"&&t.addChild(s[r]);(t.get("type")==i.CATEGORY||t.get("type")==i.MYCATEGORY)&&n>=M.block_navigation.courselimit&&this.addViewAllCoursesChild(t)}return!0},addViewAllCoursesChild:function(e){var t=null;e.get("type")==i.ROOTNODE?e.get("key")==="mycourses"?t=M.cfg.wwwroot+"/my":t=M.cfg.wwwroot+"/course/index.php":t=M.cfg.wwwroot+"/course/category.php?id="+e.get("key"),e.addChild({name:M.str.moodle.viewallcourses,title:M.str.moodle.viewallcourses,link:t,haschildren:!1,icon:{pix:"i/navigationitem",component:"moodle"}})}},e.extend(BRANCH,e.Base,BRANCH.prototype,{NAME:"navigation-branch",ATTRS:{tree:{validator:e.Lang.isObject},name:{value:"",validator:e.Lang.isString,setter:function(e){return e.replace(/\n/g,"<br />")}},title:{value:"",validator:e.Lang.isString},id:{value:"",validator:e.Lang.isString,getter:function(e){return e===""&&(e="expandable_branch_"+M.block_navigation.expandablebranchcount,M.block_navigation.expandablebranchcount++),e}},key:{value:null},type:{value:null},link:{value:!1},icon:{value:!1,validator:e.Lang.isObject},expandable:{value:!1,validator:e.Lang.isBool},hidden:{value:!1,validator:e.Lang.isBool},haschildren:{value:!1,validator:e.Lang.isBool},children:{value:[],validator:e.Lang.isArray}}}),M.block_navigation=M.block_navigation||{expandablebranchcount:1,courselimit:20,instance:null,init_add_tree:function(t){t.courselimit&&(this.courselimit=t.courselimit),M.core_dock&&M.core_dock.init(e),new s(t)}}},"@VERSION@",{requires:["base","core_dock","io-base","node","dom","event-custom","event-delegate","json-parse"]});
View
639 ...gation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js
@@ -0,0 +1,639 @@
+YUI.add('moodle-block_navigation-navigation', function (Y, NAME) {
+
+/**
+ * A 'actionkey' Event to help with Y.delegate().
+ * The event consists of the left arrow, right arrow, enter and space keys.
+ * More keys can be mapped to action meanings.
+ * actions: collapse , expand, toggle, enter.
+ *
+ * This event is delegated to branches in the navigation tree.
+ * The on() method to subscribe allows specifying the desired trigger actions as JSON.
+ *
+ * Todo: This could be centralised, a similar Event is defined in blocks/dock.js
+ */
+Y.Event.define("actionkey", {
+ // Webkit and IE repeat keydown when you hold down arrow keys.
+ // Opera links keypress to page scroll; others keydown.
+ // Firefox prevents page scroll via preventDefault() on either
+ // keydown or keypress.
+ _event: (Y.UA.webkit || Y.UA.ie) ? 'keydown' : 'keypress',
+
+ _keys: {
+ //arrows
+ '37': 'collapse',
+ '39': 'expand',
+ //(@todo: lrt/rtl/M.core_dock.cfg.orientation decision to assign arrow to meanings)
+ '32': 'toggle',
+ '13': 'enter'
+ },
+
+ _keyHandler: function (e, notifier, args) {
+ var actObj;
+ if (!args.actions) {
+ actObj = {collapse:true, expand:true, toggle:true, enter:true};
+ } else {
+ actObj = args.actions;
+ }
+ if (this._keys[e.keyCode] && actObj[this._keys[e.keyCode]]) {
+ e.action = this._keys[e.keyCode];
+ notifier.fire(e);
+ }
+ },
+
+ on: function (node, sub, notifier) {
+ // subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions).
+ if (sub.args === null) {
+ //no actions given
+ sub._detacher = node.on(this._event, this._keyHandler,this, notifier, {actions:false});
+ } else {
+ sub._detacher = node.on(this._event, this._keyHandler,this, notifier, sub.args[0]);
+ }
+ },
+
+ detach: function (node, sub) {
+ //detach our _detacher handle of the subscription made in on()
+ sub._detacher.detach();
+ },
+
+ delegate: function (node, sub, notifier, filter) {
+ // subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions).
+ if (sub.args === null) {
+ //no actions given
+ sub._delegateDetacher = node.delegate(this._event, this._keyHandler,filter, this, notifier, {actions:false});
+ } else {
+ sub._delegateDetacher = node.delegate(this._event, this._keyHandler,filter, this, notifier, sub.args[0]);
+ }
+ },
+
+ detachDelegate: function (node, sub) {
+ sub._delegateDetacher.detach();
+ }
+});
+
+var EXPANSIONLIMIT_EVERYTHING = 0,
+ //EXPANSIONLIMIT_COURSE = 20,
+ //EXPANSIONLIMIT_SECTION = 30,
+ EXPANSIONLIMIT_ACTIVITY = 40;
+
+/**
+ * Mappings for the different types of nodes coming from the navigation.
+ * Copied from lib/navigationlib.php navigation_node constants.
+ * @type object
+ */
+var NODETYPE = {
+ /** @type int Root node = 0 */
+ ROOTNODE : 0,
+ /** @type int System context = 1 */
+ SYSTEM : 1,
+ /** @type int Course category = 10 */
+ CATEGORY : 10,
+ /** @type int MYCATEGORY = 11 */
+ MYCATEGORY : 11,
+ /** @type int Course = 20 */
+ COURSE : 20,
+ /** @type int Course section = 30 */
+ SECTION : 30,
+ /** @type int Activity (course module) = 40 */
+ ACTIVITY : 40,
+ /** @type int Resource (course module = 50 */
+ RESOURCE : 50,
+ /** @type int Custom node (could be anything) = 60 */
+ CUSTOM : 60,
+ /** @type int Setting = 70 */
+ SETTING : 70,
+ /** @type int User context = 80 */
+ USER : 80,
+ /** @type int Container = 90 */
+ CONTAINER : 90
+};
+
+/**
+ * Navigation tree class.
+ *
+ * This class establishes the tree initially, creating expandable branches as
+ * required, and delegating the expand/collapse event.
+ */
+var TREE = function() {
+ TREE.superclass.constructor.apply(this, arguments);
+};
+TREE.prototype = {
+ /**
+ * The tree's ID, normally its block instance id.
+ */
+ id : null,
+ /**
+ * An array of initialised branches.
+ */
+ branches : [],
+ /**
+ * Initialise the tree object when its first created.
+ */
+ initializer : function(config) {
+ this.id = config.id;
+
+ var node = Y.one('#inst'+config.id);
+
+ // Can't find the block instance within the page
+ if (node === null) {
+ return;
+ }
+
+ // Delegate event to toggle expansion
+ Y.delegate('click', this.toggleExpansion, node.one('.block_tree'), '.tree_item.branch', this);
+ Y.delegate('actionkey', this.toggleExpansion, node.one('.block_tree'), '.tree_item.branch', this);
+
+ // Gather the expandable branches ready for initialisation.
+ var expansions = [];
+ if (config.expansions) {
+ expansions = config.expansions;
+ } else if (window['navtreeexpansions'+config.id]) {
+ expansions = window['navtreeexpansions'+config.id];
+ }
+ // Establish each expandable branch as a tree branch.
+ for (var i in expansions) {
+ var branch = new BRANCH({
+ tree:this,
+ branchobj:expansions[i],
+ overrides : {
+ expandable : true,
+ children : [],
+ haschildren : true
+ }
+ }).wire();
+ M.block_navigation.expandablebranchcount++;
+ this.branches[branch.get('id')] = branch;
+ }
+ if (M.block_navigation.expandablebranchcount > 0) {
+ // Delegate some events to handle AJAX loading.
+ Y.delegate('click', this.fire_branch_action, node.one('.block_tree'), '.tree_item.branch[data-expandable]', this);
+ Y.delegate('actionkey', this.fire_branch_action, node.one('.block_tree'), '.tree_item.branch[data-expandable]', this);
+ }
+
+ // Call the generic blocks init method to add all the generic stuff
+ if (this.get('candock')) {
+ this.initialise_block(Y, node);
+ }
+ },
+ /**
+ * Fire actions for a branch when an event occurs.
+ */
+ fire_branch_action : function(event) {
+ var id = event.currentTarget.getAttribute('id');
+ var branch = this.branches[id];
+ branch.ajaxLoad(event);
+ },
+ /**
+ * This is a callback function responsible for expanding and collapsing the
+ * branches of the tree. It is delegated to rather than multiple event handles.
+ */
+ toggleExpansion : function(e) {
+ // First check if they managed to click on the li iteslf, then find the closest
+ // LI ancestor and use that
+
+ if (e.target.test('a') && (e.keyCode === 0 || e.keyCode === 13)) {
+ // A link has been clicked (or keypress is 'enter') don't fire any more events just do the default.
+ e.stopPropagation();
+ return;
+ }
+
+ // Makes sure we can get to the LI containing the branch.
+ var target = e.target;
+ if (!target.test('li')) {
+ target = target.ancestor('li');
+ }
+ if (!target) {
+ return;
+ }
+
+ // Toggle expand/collapse providing its not a root level branch.
+ if (!target.hasClass('depth_1')) {
+ if (e.type === 'actionkey') {
+ switch (e.action) {
+ case 'expand' :
+ target.removeClass('collapsed');
+ target.set('aria-expanded', true);
+ break;
+ case 'collapse' :
+ target.addClass('collapsed');
+ target.set('aria-expanded', false);
+ break;
+ default :
+ target.toggleClass('collapsed');
+ target.set('aria-expanded', !target.hasClass('collapsed'));
+ }
+ e.halt();
+ } else {
+ target.toggleClass('collapsed');
+ target.set('aria-expanded', !target.hasClass('collapsed'));
+ }
+ }
+
+ // If the accordian feature has been enabled collapse all siblings.
+ if (this.get('accordian')) {
+ target.siblings('li').each(function(){
+ if (this.get('id') !== target.get('id') && !this.hasClass('collapsed')) {
+ this.addClass('collapsed');
+ this.set('aria-expanded', false);
+ }
+ });
+ }
+
+ // If this block can dock tell the dock to resize if required and check
+ // the width on the dock panel in case it is presently in use.
+ if (this.get('candock')) {
+ M.core_dock.resize();
+ var panel = M.core_dock.getPanel();
+ if (panel.visible) {
+ panel.correctWidth();
+ }
+ }
+ }
+};
+// The tree extends the YUI base foundation.
+Y.extend(TREE, Y.Base, TREE.prototype, {
+ NAME : 'navigation-tree',
+ ATTRS : {
+ instance : {
+ value : null
+ },
+ candock : {
+ validator : Y.Lang.isBool,
+ value : false
+ },
+ accordian : {
+ validator : Y.Lang.isBool,
+ value : false
+ },
+ expansionlimit : {
+ value : 0,
+ setter : function(val) {
+ return parseInt(val, 10);
+ }
+ }
+ }
+});
+if (M.core_dock && M.core_dock.genericblock) {
+ Y.augment(TREE, M.core_dock.genericblock);
+}
+
+/**
+ * The tree branch class.
+ * This class is used to manage a tree branch, in particular its ability to load
+ * its contents by AJAX.
+ */
+BRANCH = function() {
+ BRANCH.superclass.constructor.apply(this, arguments);
+};
+BRANCH.prototype = {
+ /**
+ * The node for this branch (p)
+ */
+ node : null,
+ /**
+ * Initialises the branch when it is first created.
+ */
+ initializer : function(config) {
+ var i,
+ children;
+ if (config.branchobj !== null) {
+ // Construct from the provided xml
+ for (i in config.branchobj) {
+ this.set(i, config.branchobj[i]);
+ }
+ children = this.get('children');
+ this.set('haschildren', (children.length > 0));
+ }
+ if (config.overrides !== null) {
+ // Construct from the provided xml
+ for (i in config.overrides) {
+ this.set(i, config.overrides[i]);
+ }
+ }
+ // Get the node for this branch
+ this.node = Y.one('#', this.get('id'));
+ // Now check whether the branch is not expandable because of the expansionlimit
+ var expansionlimit = this.get('tree').get('expansionlimit');
+ var type = this.get('type');
+ if (expansionlimit !== EXPANSIONLIMIT_EVERYTHING && type >= expansionlimit && type <= EXPANSIONLIMIT_ACTIVITY) {
+ this.set('expandable', false);
+ this.set('haschildren', false);
+ }
+ },
+ /**
+ * Draws the branch within the tree.
+ *
+ * This function creates a DOM structure for the branch and then injects
+ * it into the navigation tree at the correct point.
+ */
+ draw : function(element) {
+
+ var isbranch = (this.get('expandable') || this.get('haschildren'));
+ var branchli = Y.Node.create('<li></li>');
+ var link = this.get('link');
+ var branchp = Y.Node.create('<p class="tree_item"></p>').setAttribute('id', this.get('id'));
+ if (!link) {
+ //add tab focus if not link (so still one focus per menu node).
+ // it was suggested to have 2 foci. one for the node and one for the link in MDL-27428.
+ branchp.setAttribute('tabindex', '0');
+ }
+ if (isbranch) {
+ branchli.addClass('collapsed').addClass('contains_branch');
+ branchli.set('aria-expanded', false);
+ branchp.addClass('branch');
+ }
+
+ // Prepare the icon, should be an object representing a pix_icon
+ var branchicon = false;
+ var icon = this.get('icon');
+ if (icon && (!isbranch || this.get('type') == NODETYPE.ACTIVITY)) {
+ branchicon = Y.Node.create('<img alt="" />');
+ branchicon.setAttribute('src', M.util.image_url(icon.pix, icon.component));
+ branchli.addClass('item_with_icon');
+ if (icon.alt) {
+ branchicon.setAttribute('alt', icon.alt);
+ }
+ if (icon.title) {
+ branchicon.setAttribute('title', icon.title);
+ }
+ if (icon.classes) {
+ for (var i in icon.classes) {
+ branchicon.addClass(icon.classes[i]);
+ }
+ }
+ }
+
+ if (!link) {
+ if (branchicon) {
+ branchp.appendChild(branchicon);
+ }
+ branchp.append(this.get('name'));
+ } else {
+ var branchlink = Y.Node.create('<a title="'+this.get('title')+'" href="'+link+'"></a>');
+ if (branchicon) {
+ branchlink.appendChild(branchicon);
+ }
+ branchlink.append(this.get('name'));
+ if (this.get('hidden')) {
+ branchlink.addClass('dimmed');
+ }
+ branchp.appendChild(branchlink);
+ }
+
+ branchli.appendChild(branchp);
+ element.appendChild(branchli);
+ this.node = branchp;
+ return this;
+ },
+ /**
+ * Attaches required events to the branch structure.
+ */
+ wire : function() {
+ this.node = this.node || Y.one('#'+this.get('id'));
+ if (!this.node) {
+ return false;
+ }
+ if (this.get('expandable')) {
+ this.node.setAttribute('data-expandable', '1');
+ this.node.setAttribute('data-loaded', '0');
+ }
+ return this;
+ },
+ /**
+ * Gets the UL element that children for this branch should be inserted into.
+ */
+ getChildrenUL : function() {
+ var ul = this.node.next('ul');
+ if (!ul) {
+ ul = Y.Node.create('<ul></ul>');
+ this.node.ancestor().append(ul);
+ }
+ return ul;
+ },
+ /**
+ * Load the content of the branch via AJAX.
+ *
+ * This function calls ajaxProcessResponse with the result of the AJAX
+ * request made here.
+ */
+ ajaxLoad : function(e) {
+ if (e.type === 'actionkey' && e.action !== 'enter') {
+ e.halt();
+ } else {
+ e.stopPropagation();
+ }
+ if (e.type === 'actionkey' && e.action === 'enter' && e.target.test('A')) {
+ // No ajaxLoad for enter.
+ this.node.setAttribute('data-expandable', '0');
+ this.node.setAttribute('data-loaded', '1');
+ return true;
+ }
+
+ if (this.node.hasClass('loadingbranch')) {
+ // Already loading. Just skip.
+ return true;
+ }
+
+ if (this.node.getAttribute('data-loaded') === '1') {
+ // We've already loaded this stuff.
+ return true;
+ }
+ this.node.addClass('loadingbranch');
+
+ var params = {
+ elementid : this.get('id'),
+ id : this.get('key'),
+ type : this.get('type'),
+ sesskey : M.cfg.sesskey,
+ instance : this.get('tree').get('instance')
+ };
+
+ Y.io(M.cfg.wwwroot+'/lib/ajax/getnavbranch.php', {
+ method:'POST',
+ data: build_querystring(params),
+ on: {
+ complete: this.ajaxProcessResponse
+ },
+ context:this
+ });
+ return true;
+ },
+ /**
+ * Processes an AJAX request to load the content of this branch through
+ * AJAX.
+ */
+ ajaxProcessResponse : function(tid, outcome) {
+ this.node.removeClass('loadingbranch');
+ this.node.setAttribute('data-loaded', '1');
+ try {
+ var object = Y.JSON.parse(outcome.responseText);
+ if (object.children && object.children.length > 0) {
+ var coursecount = 0;
+ for (var i in object.children) {
+ if (typeof(object.children[i])==='object') {
+ if (object.children[i].type == NODETYPE.COURSE) {
+ coursecount++;
+ }
+ this.addChild(object.children[i]);
+ }
+ }
+ if ((this.get('type') == NODETYPE.CATEGORY || this.get('type') == NODETYPE.ROOTNODE || this.get('type') == NODETYPE.MYCATEGORY)
+ && coursecount >= M.block_navigation.courselimit) {
+ this.addViewAllCoursesChild(this);
+ }
+ return true;
+ }
+ } catch (ex) {
+ // If we got here then there was an error parsing the result
+ }
+ // The branch is empty so class it accordingly
+ this.node.replaceClass('branch', 'emptybranch');
+ return true;
+ },
+ /**
+ * Turns the branch object passed to the method into a proper branch object
+ * and then adds it as a child of this branch.
+ */
+ addChild : function(branchobj) {
+ // Make the new branch into an object
+ var branch = new BRANCH({tree:this.get('tree'), branchobj:branchobj});
+ if (branch.draw(this.getChildrenUL())) {
+ this.get('tree').branches[branch.get('id')] = branch;
+ branch.wire();
+ var count = 0, i, children = branch.get('children');
+ for (i in children) {
+ // Add each branch to the tree
+ if (children[i].type == NODETYPE.COURSE) {
+ count++;
+ }
+ if (typeof(children[i]) === 'object') {
+ branch.addChild(children[i]);
+ }
+ }
+ if ((branch.get('type') == NODETYPE.CATEGORY || branch.get('type') == NODETYPE.MYCATEGORY)
+ && count >= M.block_navigation.courselimit) {
+ this.addViewAllCoursesChild(branch);
+ }
+ }
+ return true;
+ },
+
+ /**
+ * Add a link to view all courses in a category
+ */
+ addViewAllCoursesChild: function(branch) {
+ var url = null;
+ if (branch.get('type') == NODETYPE.ROOTNODE) {
+ if (branch.get('key') === 'mycourses') {
+ url = M.cfg.wwwroot + '/my';
+ } else {
+ url = M.cfg.wwwroot + '/course/index.php';
+ }
+ } else {
+ url = M.cfg.wwwroot+'/course/category.php?id=' + branch.get('key');
+ }
+ branch.addChild({
+ name : M.str.moodle.viewallcourses,
+ title : M.str.moodle.viewallcourses,
+ link : url,
+ haschildren : false,
+ icon : {'pix':"i/navigationitem",'component':'moodle'}
+ });
+ }
+};
+Y.extend(BRANCH, Y.Base, BRANCH.prototype, {
+ NAME : 'navigation-branch',
+ ATTRS : {
+ tree : {
+ validator : Y.Lang.isObject
+ },
+ name : {
+ value : '',
+ validator : Y.Lang.isString,
+ setter : function(val) {
+ return val.replace(/\n/g, '<br />');
+ }
+ },
+ title : {
+ value : '',
+ validator : Y.Lang.isString
+ },
+ id : {
+ value : '',
+ validator : Y.Lang.isString,
+ getter : function(val) {
+ if (val === '') {
+ val = 'expandable_branch_'+M.block_navigation.expandablebranchcount;
+ M.block_navigation.expandablebranchcount++;
+ }
+ return val;
+ }
+ },
+ key : {
+ value : null
+ },
+ type : {
+ value : null
+ },
+ link : {
+ value : false
+ },
+ icon : {
+ value : false,
+ validator : Y.Lang.isObject
+ },
+ expandable : {
+ value : false,
+ validator : Y.Lang.isBool
+ },
+ hidden : {
+ value : false,
+ validator : Y.Lang.isBool
+ },
+ haschildren : {
+ value : false,
+ validator : Y.Lang.isBool
+ },
+ children : {
+ value : [],
+ validator : Y.Lang.isArray
+ }
+ }
+});
+
+/**
+ * This namespace will contain all of the contents of the navigation blocks
+ * global navigation and settings.
+ * @namespace
+ */
+M.block_navigation = M.block_navigation || {
+ /** The number of expandable branches in existence */
+ expandablebranchcount:1,
+ courselimit : 20,
+ instance : null,
+ /**
+ * Add new instance of navigation tree to tree collection
+ */
+ init_add_tree:function(properties) {
+ if (properties.courselimit) {
+ this.courselimit = properties.courselimit;
+ }
+ if (M.core_dock) {
+ M.core_dock.init(Y);
+ }
+ new TREE(properties);
+ }
+};
+
+
+}, '@VERSION@', {
+ "requires": [
+ "base",
+ "core_dock",
+ "io-base",
+ "node",
+ "dom",
+ "event-custom",
+ "event-delegate",
+ "json-parse"
+ ]
+});
View
10 blocks/navigation/yui/src/navigation/build.json
@@ -0,0 +1,10 @@
+{
+ "name": "moodle-block_navigation-navigation",
+ "builds": {
+ "moodle-block_navigation-navigation": {
+ "jsfiles": [
+ "navigation.js"
+ ]
+ }
+ }
+}
View
63 ...s/navigation/yui/navigation/navigation.js → ...ation/yui/src/navigation/js/navigation.js
@@ -1,5 +1,3 @@
-YUI.add('moodle-block_navigation-navigation', function(Y){
-
/**