plugins/org.symbian.tools.wrttools.doc.WebDeveloper/html/js/toc.js
changeset 470 d4809db37847
parent 229 716254ccbcc0
equal deleted inserted replaced
469:4d198a32ac7d 470:d4809db37847
       
     1 /* Constants */
       
     2 
       
     3 var STATIC_STRING_TOC_SYNC = "TOC Sync";
       
     4 var STATIC_STRING_TOC_SYNC_HELP = "Refresh / Show current topic";
       
     5 
       
     6 /** TOC item element name. */
       
     7 var TOC_ELEMENT_ITEM = "li";
       
     8 /** TOC block element name. */
       
     9 var TOC_ELEMENT_BLOCK = "ul";
       
    10 /** TOC controller element name. */
       
    11 var TOC_ELEMENT_CONTROL = "span";
       
    12 /** TOC link element name. */
       
    13 var TOC_ELEMENT_LINK = "a";
       
    14 /** TOC controller expanded symbol. */
       
    15 var TOC_SYMBOL_EXPANDED = "-";
       
    16 /** TOC controller collapsed symbol. */
       
    17 var TOC_SYMBOL_COLLAPSED = "+";
       
    18 
       
    19 /* TODO: move to common. */
       
    20 var TOC_CLASS_ACTIVE = "on3";
       
    21 var TOC_CLASS_COLLAPSED = "toc-controller-closed";
       
    22 var TOC_CLASS_EXPANDED = "toc-controller-open";
       
    23 var TOC_CLASS_CONTROL = "toc-controller";
       
    24 var TOC_CLASS_SPACE = "toc-space";
       
    25 var TOC_CLASS_TITLE = "toc-title";
       
    26 var TOC_DISPLAY_COLLAPSED = "none";
       
    27 var TOC_DISPLAY_EXPANDED = "block";
       
    28 
       
    29 /* Variables */
       
    30 
       
    31 /** Should TOC be initially fully collapsed. */
       
    32 var initialCollapse = true;
       
    33 /** Should node's children be collapsed upon expanding a node. */
       
    34 var childCollapse = false;
       
    35 /** Synchronize TOC automatically on link traversal. */
       
    36 var automaticSync = true;
       
    37 /** Add controllers to TOC on load. */
       
    38 var addControllers = true;
       
    39 
       
    40 /**
       
    41  * Add TOC controllers.
       
    42  */
       
    43 function addTocControllers() {
       
    44     var nl = getFirstElementByClassName(document, "nav3", "div");
       
    45     if (nl === null) {
       
    46       return;
       
    47     }
       
    48     if (addControllers) {
       
    49         var lis = nl.getElementsByTagName(TOC_ELEMENT_ITEM);
       
    50         for (var j = 0; j < lis.length; j++) {
       
    51             var li = lis[j];
       
    52             // check that list item is a toc item title
       
    53             var title = null;
       
    54             for (var child = li.firstChild; child !== null; child = child.nextSibling) {
       
    55                 if (isClass(child, TOC_CLASS_TITLE)) {
       
    56                     title = child;
       
    57                     break;
       
    58                 }
       
    59             }
       
    60             if (title !== null) {
       
    61                 var uls = li.getElementsByTagName(TOC_ELEMENT_BLOCK);        
       
    62                 if (uls.length !== 0) {
       
    63                     // add controller
       
    64                     var c = document.createElement(TOC_ELEMENT_CONTROL);
       
    65                     addClass(c, TOC_CLASS_CONTROL);
       
    66 //                          if (initialCollapse) {
       
    67 //                            addClass(c, TOC_CLASS_COLLAPSED);
       
    68 //                              c.appendChild(document.createTextNode(TOC_SYMBOL_EXPANDED));
       
    69 //                          }  else {
       
    70                         addClass(c, TOC_CLASS_EXPANDED);
       
    71                         c.appendChild(document.createTextNode(TOC_SYMBOL_COLLAPSED));
       
    72 //                          }
       
    73                     attachEventListener(c, "click", toggleHandler);
       
    74                     li.insertBefore(c, li.firstChild);
       
    75                     // hide kids
       
    76                     if (initialCollapse) {
       
    77                         collapseChildBlocks(li);
       
    78                     }
       
    79                 } else {
       
    80                     // add space
       
    81                     var sp = document.createElement(TOC_ELEMENT_CONTROL);
       
    82                     addClass(sp, TOC_CLASS_SPACE);
       
    83                     var pls = document.createTextNode("x");
       
    84                     sp.appendChild(pls);
       
    85                     li.insertBefore(sp, li.firstChild);                        
       
    86                 }
       
    87                 attachEventListener(title, "click", tocItemClickHandler);
       
    88             }
       
    89         }
       
    90     // hide kids
       
    91     } else if (initialCollapse) {
       
    92         var lis = nl.getElementsByTagName(TOC_ELEMENT_ITEM);
       
    93         for (var j = 0; j < lis.length; j++) {
       
    94             var li = lis[j];
       
    95             collapseChildBlocks(li);
       
    96         }
       
    97       
       
    98     }
       
    99     /*
       
   100     } else if (childCollapse) {
       
   101         var nl = getFirstElementByClassName(document, "nav3", "div");
       
   102         if (nl !== null) {
       
   103             var tocRoot = getFirstChildElementByTagName(nl, TOC_ELEMENT_BLOCK);
       
   104             if (tocRoot !== null) {
       
   105                 var li = getChildElementsByTagName(tocRoot, TOC_ELEMENT_ITEM);
       
   106                 for (var i = 0; i < li.length; i++) {
       
   107                     collapseChildBlocks(li[i]);
       
   108                 }
       
   109             }
       
   110         }
       
   111     }
       
   112     */   
       
   113 }
       
   114 
       
   115 /**
       
   116  * Collapse child TOC blocks.
       
   117  *
       
   118  * @param li TOC item whose child TOC blocks to collapse.
       
   119  */
       
   120 function collapseChildBlocks(li) {
       
   121     for (var k = li.firstChild; k != null; k = k.nextSibling) {
       
   122         if (k.nodeType == 1 && k.nodeName.toLowerCase() == TOC_ELEMENT_CONTROL && isClass(k, TOC_CLASS_CONTROL)) {
       
   123             if (isClass(k, TOC_CLASS_EXPANDED)) {
       
   124                 tocNodeCollapse(k);
       
   125             }
       
   126             break;  
       
   127         }
       
   128         /*
       
   129          else if (k.nodeType == 1 && k.nodeName.toLowerCase() == TOC_ELEMENT_BLOCK) {
       
   130             k.style.display = "none";
       
   131         }
       
   132         */
       
   133     }
       
   134 }
       
   135 
       
   136 /**
       
   137  * Toggle child node display.
       
   138  */
       
   139 function toggleHandler(event) {
       
   140     toggle(getTargetNode(event));
       
   141 }
       
   142 
       
   143 /**
       
   144  * Set current node as current.
       
   145  */
       
   146 function tocItemClickHandler(event) {
       
   147     var t = getTargetNode(event);
       
   148     highlightTocItem(t);
       
   149     var p = t.parentNode.firstChild;
       
   150     if (p !== null && isClass(p, "toc-controller") && isClass(p, TOC_CLASS_COLLAPSED)) {
       
   151         tocNodeExpand(p);
       
   152     }    
       
   153 }
       
   154 
       
   155 /**
       
   156  * Generate TOC synchronization button.
       
   157  */
       
   158 function addSyncButton() {
       
   159     if (!automaticSync) {
       
   160         //var b = document.createElement("img");
       
   161         //b.src = "images/xhtml/e_synch_nav.gif";
       
   162         var b = document.createElement("button");
       
   163         b.appendChild(document.createTextNode(STATIC_STRING_TOC_SYNC));
       
   164         b.title = STATIC_STRING_TOC_SYNC_HELP;
       
   165         addClass(b, "button-manual_sync");
       
   166         attachEventListener(b, "click", manualSyncTocHandler);
       
   167         var bc = document.createElement("div");
       
   168         addClass(bc, "button-manual_sync-container");
       
   169         bc.appendChild(b);
       
   170         var nav3 = getFirstElementByClassName(document, "nav3", "div");
       
   171         if (nav3 !== null) {
       
   172           nav3.insertBefore(bc, nav3.firstChild);
       
   173         }
       
   174     }
       
   175 }
       
   176 
       
   177 /**
       
   178  * Button listener for manual TOC sync.
       
   179  */
       
   180 function manualSyncTocHandler(event) {
       
   181     startProcess("Synchronizing TOC");
       
   182     var b = getTargetNode(event);
       
   183     var baseUrl = getBaseUrl();
       
   184     var contentUrl = String(window.top.frames.main.location.href);
       
   185     var href = getRelativeUrl(contentUrl, baseUrl);
       
   186     findTocItem(href);
       
   187     endProcess("Done");    
       
   188 }
       
   189 
       
   190 /**
       
   191  * Initialize TOC.
       
   192  */
       
   193 function initToc() {
       
   194     if (tocSupported) {
       
   195         startProcess("Initializing TOC");
       
   196         addTocControllers();
       
   197         addSyncButton();
       
   198         endProcess("Done");
       
   199     }    
       
   200 }
       
   201 
       
   202 /* Move to common. */
       
   203 
       
   204 /**
       
   205  * Toggle child node display.
       
   206  *
       
   207  * @param n Target node of the event.
       
   208  */
       
   209 function toggle(n) {
       
   210   	if (isClass(n, TOC_CLASS_EXPANDED)) {
       
   211   		  tocNodeCollapse(n);
       
   212   	} else {
       
   213   	    tocNodeExpand(n);
       
   214   	}
       
   215 }
       
   216 
       
   217 /**
       
   218  * Expand TOC node.
       
   219  *
       
   220  * @param n TOC node
       
   221  */
       
   222 function tocNodeExpand(n, collapseOverride) {
       
   223     if (collapseOverride === undefined) {
       
   224         collapseOverride = true;
       
   225     }
       
   226     n.firstChild.data = TOC_SYMBOL_EXPANDED;
       
   227     switchClass(n, TOC_CLASS_EXPANDED, TOC_CLASS_COLLAPSED);
       
   228     var ul = getNextSiblingByTagName(n.nextSibling, TOC_ELEMENT_BLOCK);
       
   229     if (ul !== null) {
       
   230         // collapse children
       
   231         if (childCollapse && collapseOverride) {
       
   232           var li = getChildElementsByTagName(ul, "li");
       
   233           for (var i = 0; i < li.length; i++) {
       
   234             collapseChildBlocks(li[i]);
       
   235           }
       
   236         }
       
   237         ul.style.display = TOC_DISPLAY_EXPANDED;
       
   238         //switchClass(ul, "toc-expanded", "toc-collapsed");
       
   239     }
       
   240 }
       
   241 
       
   242 /**
       
   243  * Collapse TOC node.
       
   244  *
       
   245  * @param n TOC node
       
   246  */
       
   247 function tocNodeCollapse(n) {
       
   248     n.firstChild.data = TOC_SYMBOL_COLLAPSED;
       
   249     switchClass(n, TOC_CLASS_COLLAPSED, TOC_CLASS_EXPANDED);
       
   250     var ul = getNextSiblingByTagName(n.nextSibling, TOC_ELEMENT_BLOCK);
       
   251     if (ul !== null) {
       
   252         ul.style.display = TOC_DISPLAY_COLLAPSED;
       
   253         //switchClass(ul, "toc-collapsed", "toc-expanded");
       
   254     }
       
   255 }
       
   256 
       
   257 var processStart;
       
   258 var processEnd;
       
   259 var processDuration
       
   260 
       
   261 /**
       
   262  * Signal start of processing.
       
   263  *
       
   264  * @param message Message description of the process start
       
   265  */
       
   266 function startProcess(message) {
       
   267     processStart = new Date();
       
   268     window.status = (message === undefined ? "" : message);    
       
   269 }
       
   270 
       
   271 /**
       
   272  * Signal end of processing.
       
   273  *
       
   274  * @param message Message description of the process result
       
   275  */
       
   276 function endProcess(message) {
       
   277     processEnd = new Date();
       
   278     window.status = (message === undefined ? "" : message);
       
   279     processDuration = processEnd - processStart;
       
   280 }