1/**
2 * Copyright (c) 2010 The Chromium Authors. All rights reserved.  Use of this
3 * source code is governed by a BSD-style license that can be found in the
4 * LICENSE file.
5 */
6
7var TEXT_NODE = 3; // Text nodes have nodeType of 3.
8
9/**
10 * Toggles the display of nodes given the status of their associated controls.
11 *
12 * For each node passed to this function, check to see if a toggle has been
13 * inserted into the node's parent.  If yes, change the state of the toggle and
14 * hide/reveal the node as needed.
15 *
16 * @param {NodeList|Node|Array.<Node>} Nodes to operate on.
17 */
18function toggleList(list) {
19  if (typeof list.length != 'number') {
20    list = Array(list);
21  }
22
23  for (var i = 0; i < list.length; i++) {
24    var toggle = list[i].parentNode &&
25                 list[i].parentNode.firstChild;
26    if (toggle && toggle.className.substring(0, 6) == 'toggle') {
27      var visible = toggle.className == 'toggle';
28      list[i].style.display = visible ? 'block' : 'none';
29      toggle.className = visible ? 'toggle selected' : 'toggle';
30    }
31  }
32};
33
34/**
35 * Reveals the hidden ancestor of the passed node, adjusts toggles as needed.
36 *
37 * @param {Node} node The node whose ancestor is a hidden toggleable element.
38 */
39function revealAncestor(node) {
40  while (node.parentNode) {
41    if (node.style.display == 'none') {
42      toggleList(node);
43      break;
44    }
45    node = node.parentNode;
46  }
47};
48
49/**
50 * Adds toggle controls to the sidebar list.
51 *
52 * Controls are inserted as the first children of list items in the sidebar
53 * which contain only text (not a link).  Handlers are set up so that when a
54 * toggle control is clicked, any <ul> elements who are siblings of the control
55 * are hidden/revealed as appropriate given the control's state.
56 *
57 * If a list item possesses the class "leftNavSelected" its ancestor <ul> is
58 * revealed by default (it represents the current page).
59 */
60function initToggles() {
61  var toc = document.getElementById('gc-toc');
62  var items = toc.getElementsByTagName('li');
63  var selectedNode = null;
64  for (var i = 0; i < items.length; i++) {
65    var item = items[i];
66    if (item.className == 'leftNavSelected') {
67      selectedNode = item;
68    } else if (item.firstChild &&
69               item.firstChild.nodeType == TEXT_NODE) {
70      // Only assign toggles to text nodes in the sidebar.
71      var a = document.createElement('a');
72      a.className = 'toggle selected';
73      a.appendChild(document.createTextNode(' '));
74      a.onclick = function() {
75        toggleList(this.parentNode.getElementsByTagName('ul'));
76      };
77      item.insertBefore(a, item.firstChild);
78      toggleList(item.getElementsByTagName('ul'));
79    }
80  }
81  if (selectedNode) {
82    revealAncestor(selectedNode);
83  }
84};
85