blob: ec97cb7dbf15a5e1e3a0851a64a7cdb1304a895e [file] [log] [blame] [edit]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Adds toggle controls to the sidebar list.
*
* Controls are inserted as the first children of list items in the sidebar
* which contain only text (not a link). Handlers are set up so that when a
* toggle control is clicked, any <ul> elements who are siblings of the
* control are hidden/revealed as appropriate given the control's state.
*
* If a list item possesses the class 'selected' its ancestor <ul> is
* revealed by default (it represents the current page).
*/
(function() {
var sidebar = document.getElementById('gc-sidebar');
if (!sidebar)
return;
// Figure out which link matches the current page so it can be styled
// differently.
var pathParts = document.location.pathname.replace(/\/+$/, '').split('/')
Array.prototype.forEach.call(sidebar.getElementsByTagName('a'),
function(link) {
if (link.getAttribute('href') != pathParts[pathParts.length - 1])
return;
link.className = 'selected';
link.removeAttribute('href');
});
// Go through the items on the sidebar and add toggles.
Array.prototype.forEach.call(sidebar.querySelectorAll('[toggleable]'),
function(toggleable) {
var buttonContent = toggleable.previousElementSibling;
if (!buttonContent) {
console.warn('Cannot toggle %s, no previous sibling', toggleable);
return;
}
var button = document.createElement('a');
button.className = 'button';
var toggleIndicator = document.createElement('div');
toggleIndicator.className = 'toggleIndicator';
var isToggled = false;
function toggle() {
if (isToggled) {
toggleable.classList.add('hidden');
toggleIndicator.classList.remove('toggled');
} else {
toggleable.classList.remove('hidden');
toggleIndicator.classList.add('toggled');
}
isToggled = !isToggled;
}
// TODO(kalman): needs a button role for accessibility?
button.setAttribute('href', 'javascript:void(0)');
button.addEventListener('click', toggle);
buttonContent.parentElement.insertBefore(button, buttonContent);
button.appendChild(buttonContent);
button.appendChild(toggleIndicator);
// Leave the toggle open if the selected link is a child.
if (toggleable.querySelector('.selected'))
toggle();
else
toggleable.classList.add('hidden');
});
// Each level of the sidebar is displayed differently. Rather than trying
// to nest CSS selectors in a crazy way, programmatically assign levels
// to them.
function addNestLevels(node, currentLevel) {
node.classList.add('level' + currentLevel);
if (node.tagName == 'UL')
currentLevel++;
Array.prototype.forEach.call(node.children, function(child) {
addNestLevels(child, currentLevel);
});
}
addNestLevels(sidebar, 1);
})()