Skip to content

Commit

Permalink
MDL-35590 block_navigation: Add aria roles to navigation block tree
Browse files Browse the repository at this point in the history
  • Loading branch information
John Okely authored and lameze committed Jan 21, 2016
1 parent e8d5100 commit f889544
Show file tree
Hide file tree
Showing 19 changed files with 929 additions and 2,765 deletions.
163 changes: 163 additions & 0 deletions blocks/navigation/amd/src/ajax_response_renderer.js
@@ -0,0 +1,163 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Parse the response from the navblock ajax page and render the correct DOM
* structure for the tree from it.
*
* @module block_navigation/ajax_response_renderer
* @package core
* @copyright 2015 John Okely <john@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['jquery'], function($) {

// Mappings for the different types of nodes coming from the navigation.
// Copied from lib/navigationlib.php navigation_node constants.
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 site administration = 71
SITEADMIN : 71,
// @type int User context = 80
USER : 80,
// @type int Container = 90
CONTAINER : 90
};

function buildDOM(rootElement, nodes) {
var ul = $('<ul></ul>');
ul.attr('role', 'group');

$.each(nodes, function(index, node) {
if (typeof node !== 'object') {
return;
}

var li = $('<li></li>');
var p = $('<p></p>');
var icon = null;
var isBranch = (node.expandable || node.haschildren) ? true : false;

p.addClass('tree_item');
p.attr('id', node.id);
li.attr('role', 'treeitem');

if (node.requiresajaxloading) {
li.attr('data-requires-ajax', true);
li.attr('data-node-id', node.id);
li.attr('data-node-key', node.key);
li.attr('data-node-type', node.type);
}

if (isBranch) {
li.addClass('collapsed contains_branch');
li.attr('aria-expanded', false);
p.addClass('branch');
}

if (node.icon && (!isBranch || node.type === NODETYPE.ACTIVITY || node.type === NODETYPE.RESOURCE)) {
li.addClass('item_with_icon');
p.addClass('hasicon');

icon = $('<img/>');
icon.attr('alt', node.icon.alt);
icon.attr('title', node.icon.title);
icon.attr('src', M.util.image_url(node.icon.pix, node.icon.component));
$.each(node.icon.classes, function(index, className) {
icon.addClass(className);
});
}

if (node.link) {
var link = $('<a></a>');
link.attr('title', node.title);
link.attr('href', node.link);

if (icon) {
link.append(icon);
link.append('<span class="item-content-wrap">'+node.name+'</span>');
} else {
link.text(node.name);
}

if (node.hidden) {
link.addClass('dimmed');
}

p.append(link);
} else {
var span = $('<span></span>');

if (icon) {
span.append(icon);
span.append('<span class="item-content-wrap">'+node.name+'</span>');
} else {
span.text(node.name);
}

if (node.hidden) {
span.addClass('dimmed');
}

p.append(span);
}

li.append(p);
ul.append(li);

if (node.children && node.children.length) {
buildDOM(li, node.children);
} else if (isBranch && !node.requiresajaxloading) {
li.removeClass('contains_branch');
li.addClass('emptybranch');
}
});

rootElement.append(ul);
}

return {
render: function(element, nodes) {
// The first element of the response is the existing node
// so we start with processing the children.
if (nodes.children && nodes.children.length) {
buildDOM(element, nodes.children);
} else {
if (element.hasClass('contains_branch')) {
element.removeClass('contains_branch').addClass('emptybranch');
}
}
}
};
});
58 changes: 58 additions & 0 deletions blocks/navigation/amd/src/nav_loader.js
@@ -0,0 +1,58 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Load the nav tree items via ajax and render the response.
*
* @module block_navigation/nav_loader
* @package core
* @copyright 2015 John Okely <john@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['jquery', 'core/ajax', 'core/config', 'block_navigation/ajax_response_renderer'],
function($, ajax, config, renderer) {

var URL = config.wwwroot + '/lib/ajax/getnavbranch.php';

function getBlockInstanceId(element) {
return element.closest('[data-block]').attr('data-instanceid');
}

return {
load: function(element) {
element = $(element);
var promise = $.Deferred();
var data = {
elementid: element.attr('data-node-id'),
id: element.attr('data-node-key'),
type: element.attr('data-node-type'),
sesskey: config.sesskey,
instance: getBlockInstanceId(element)
};
var settings = {
type: 'POST',
dataType: 'json',
data: data
};

$.ajax(URL, settings).done(function(nodes) {
renderer.render(element, nodes);
promise.resolve();
});

return promise;
}
};
});
30 changes: 30 additions & 0 deletions blocks/navigation/amd/src/navblock.js
@@ -0,0 +1,30 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Load the navtree javscript
*
* @module block_navigation/navblock
* @package core
* @copyright 2015 John Okely <john@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['jquery', 'core/tree'], function($, Tree) {
return {
init: function() {
new Tree(".block_navigation .block_tree");
}
};
});
52 changes: 52 additions & 0 deletions blocks/navigation/amd/src/site_admin_loader.js
@@ -0,0 +1,52 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Load the site admin nav tree via ajax and render the response.
*
* @module block_navigation/site_admin_loader
* @package core
* @copyright 2015 John Okely <john@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['jquery', 'core/ajax', 'core/config', 'block_navigation/ajax_response_renderer'],
function($, ajax, config, renderer) {

var SITE_ADMIN_NODE_TYPE = 71;
var URL = config.wwwroot + '/lib/ajax/getsiteadminbranch.php';

return {
load: function(element) {
element = $(element);
var promise = $.Deferred();
var data = {
type: SITE_ADMIN_NODE_TYPE,
sesskey: config.sesskey,
};
var settings = {
type: 'POST',
dataType: 'json',
data: data
};

$.ajax(URL, settings).done(function(nodes) {
renderer.render(element, nodes);
promise.resolve();
});

return promise;
}
};
});
33 changes: 16 additions & 17 deletions blocks/navigation/block_navigation.php
Expand Up @@ -109,23 +109,8 @@ function instance_can_be_docked() {
function get_required_javascript() {
global $CFG;
parent::get_required_javascript();
$limit = 20;
if (!empty($CFG->navcourselimit)) {
$limit = $CFG->navcourselimit;
}
$expansionlimit = 0;
if (!empty($this->config->expansionlimit)) {
$expansionlimit = $this->config->expansionlimit;
}
$arguments = array(
'id' => $this->instance->id,
'instance' => $this->instance->id,
'candock' => $this->instance_can_be_docked(),
'courselimit' => $limit,
'expansionlimit' => $expansionlimit
);
$this->page->requires->string_for_js('viewallcourses', 'moodle');
$this->page->requires->yui_module('moodle-block_navigation-navigation', 'M.block_navigation.init_add_tree', array($arguments));
$this->page->requires->js_call_amd('block_navigation/navblock', 'init', array());
}

/**
Expand Down Expand Up @@ -196,7 +181,21 @@ function get_content() {
}
}

$this->page->requires->data_for_js('navtreeexpansions'.$this->instance->id, $expandable);
$limit = 20;
if (!empty($CFG->navcourselimit)) {
$limit = $CFG->navcourselimit;
}
$expansionlimit = 0;
if (!empty($this->config->expansionlimit)) {
$expansionlimit = $this->config->expansionlimit;
}
$arguments = array(
'id' => $this->instance->id,
'instance' => $this->instance->id,
'candock' => $this->instance_can_be_docked(),
'courselimit' => $limit,
'expansionlimit' => $expansionlimit
);

$options = array();
$options['linkcategories'] = (!empty($this->config->linkcategories) && $this->config->linkcategories == 'yes');
Expand Down

0 comments on commit f889544

Please sign in to comment.