fw4spl
navtree.js
1 var navTreeSubIndices = new Array();
2 
3 function getData(varName)
4 {
5  var i = varName.lastIndexOf('/');
6  var n = i>=0 ? varName.substring(i+1) : varName;
7  return eval(n.replace(/\-/g,'_'));
8 }
9 
10 function stripPath(uri)
11 {
12  return uri.substring(uri.lastIndexOf('/')+1);
13 }
14 
15 function stripPath2(uri)
16 {
17  var i = uri.lastIndexOf('/');
18  var s = uri.substring(i+1);
19  var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/);
20  return m ? uri.substring(i-6) : s;
21 }
22 
23 function hashValue()
24 {
25  return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,'');
26 }
27 
28 function hashUrl()
29 {
30  return '#'+hashValue();
31 }
32 
33 function pathName()
34 {
35  return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, '');
36 }
37 
38 function localStorageSupported()
39 {
40  try {
41  return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem;
42  }
43  catch(e) {
44  return false;
45  }
46 }
47 
48 
49 function storeLink(link)
50 {
51  if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) {
52  window.localStorage.setItem('navpath',link);
53  }
54 }
55 
56 function deleteLink()
57 {
58  if (localStorageSupported()) {
59  window.localStorage.setItem('navpath','');
60  }
61 }
62 
63 function cachedLink()
64 {
65  if (localStorageSupported()) {
66  return window.localStorage.getItem('navpath');
67  } else {
68  return '';
69  }
70 }
71 
72 function getScript(scriptName,func,show)
73 {
74  var head = document.getElementsByTagName("head")[0];
75  var script = document.createElement('script');
76  script.id = scriptName;
77  script.type = 'text/javascript';
78  script.onload = func;
79  script.src = scriptName+'.js';
80  if ($.browser.msie && $.browser.version<=8) {
81  // script.onload does not work with older versions of IE
82  script.onreadystatechange = function() {
83  if (script.readyState=='complete' || script.readyState=='loaded') {
84  func(); if (show) showRoot();
85  }
86  }
87  }
88  head.appendChild(script);
89 }
90 
91 function createIndent(o,domNode,node,level)
92 {
93  var level=-1;
94  var n = node;
95  while (n.parentNode) { level++; n=n.parentNode; }
96  if (node.childrenData) {
97  var imgNode = document.createElement("img");
98  imgNode.style.paddingLeft=(16*level).toString()+'px';
99  imgNode.width = 16;
100  imgNode.height = 22;
101  imgNode.border = 0;
102  node.plus_img = imgNode;
103  node.expandToggle = document.createElement("a");
104  node.expandToggle.href = "javascript:void(0)";
105  node.expandToggle.onclick = function() {
106  if (node.expanded) {
107  $(node.getChildrenUL()).slideUp("fast");
108  node.plus_img.src = node.relpath+"arrowright.png";
109  node.expanded = false;
110  } else {
111  expandNode(o, node, false, false);
112  }
113  }
114  node.expandToggle.appendChild(imgNode);
115  domNode.appendChild(node.expandToggle);
116  imgNode.src = node.relpath+"arrowright.png";
117  } else {
118  var span = document.createElement("span");
119  span.style.display = 'inline-block';
120  span.style.width = 16*(level+1)+'px';
121  span.style.height = '22px';
122  span.innerHTML = '&#160;';
123  domNode.appendChild(span);
124  }
125 }
126 
127 var animationInProgress = false;
128 
129 function gotoAnchor(anchor,aname,updateLocation)
130 {
131  var pos, docContent = $('#doc-content');
132  var ancParent = $(anchor.parent());
133  if (ancParent.hasClass('memItemLeft') ||
134  ancParent.hasClass('fieldname') ||
135  ancParent.hasClass('fieldtype') ||
136  ancParent.is(':header'))
137  {
138  pos = ancParent.position().top;
139  } else if (anchor.position()) {
140  pos = anchor.position().top;
141  }
142  if (pos) {
143  var dist = Math.abs(Math.min(
144  pos-docContent.offset().top,
145  docContent[0].scrollHeight-
146  docContent.height()-docContent.scrollTop()));
147  animationInProgress=true;
148  docContent.animate({
149  scrollTop: pos + docContent.scrollTop() - docContent.offset().top
150  },Math.max(50,Math.min(500,dist)),function(){
151  if (updateLocation) window.location.href=aname;
152  animationInProgress=false;
153  });
154  }
155 }
156 
157 function newNode(o, po, text, link, childrenData, lastNode)
158 {
159  var node = new Object();
160  node.children = Array();
161  node.childrenData = childrenData;
162  node.depth = po.depth + 1;
163  node.relpath = po.relpath;
164  node.isLast = lastNode;
165 
166  node.li = document.createElement("li");
167  po.getChildrenUL().appendChild(node.li);
168  node.parentNode = po;
169 
170  node.itemDiv = document.createElement("div");
171  node.itemDiv.className = "item";
172 
173  node.labelSpan = document.createElement("span");
174  node.labelSpan.className = "label";
175 
176  createIndent(o,node.itemDiv,node,0);
177  node.itemDiv.appendChild(node.labelSpan);
178  node.li.appendChild(node.itemDiv);
179 
180  var a = document.createElement("a");
181  node.labelSpan.appendChild(a);
182  node.label = document.createTextNode(text);
183  node.expanded = false;
184  a.appendChild(node.label);
185  if (link) {
186  var url;
187  if (link.substring(0,1)=='^') {
188  url = link.substring(1);
189  link = url;
190  } else {
191  url = node.relpath+link;
192  }
193  a.className = stripPath(link.replace('#',':'));
194  if (link.indexOf('#')!=-1) {
195  var aname = '#'+link.split('#')[1];
196  var srcPage = stripPath(pathName());
197  var targetPage = stripPath(link.split('#')[0]);
198  a.href = srcPage!=targetPage ? url : "javascript:void(0)";
199  a.onclick = function(){
200  storeLink(link);
201  if (!$(a).parent().parent().hasClass('selected'))
202  {
203  $('.item').removeClass('selected');
204  $('.item').removeAttr('id');
205  $(a).parent().parent().addClass('selected');
206  $(a).parent().parent().attr('id','selected');
207  }
208  var anchor = $(aname);
209  gotoAnchor(anchor,aname,true);
210  };
211  } else {
212  a.href = url;
213  a.onclick = function() { storeLink(link); }
214  }
215  } else {
216  if (childrenData != null)
217  {
218  a.className = "nolink";
219  a.href = "javascript:void(0)";
220  a.onclick = node.expandToggle.onclick;
221  }
222  }
223 
224  node.childrenUL = null;
225  node.getChildrenUL = function() {
226  if (!node.childrenUL) {
227  node.childrenUL = document.createElement("ul");
228  node.childrenUL.className = "children_ul";
229  node.childrenUL.style.display = "none";
230  node.li.appendChild(node.childrenUL);
231  }
232  return node.childrenUL;
233  };
234 
235  return node;
236 }
237 
238 function showRoot()
239 {
240  var headerHeight = $("#top").height();
241  var footerHeight = $("#nav-path").height();
242  var windowHeight = $(window).height() - headerHeight - footerHeight;
243  (function (){ // retry until we can scroll to the selected item
244  try {
245  var navtree=$('#nav-tree');
246  navtree.scrollTo('#selected',0,{offset:-windowHeight/2});
247  } catch (err) {
248  setTimeout(arguments.callee, 0);
249  }
250  })();
251 }
252 
253 function expandNode(o, node, imm, showRoot)
254 {
255  if (node.childrenData && !node.expanded) {
256  if (typeof(node.childrenData)==='string') {
257  var varName = node.childrenData;
258  getScript(node.relpath+varName,function(){
259  node.childrenData = getData(varName);
260  expandNode(o, node, imm, showRoot);
261  }, showRoot);
262  } else {
263  if (!node.childrenVisited) {
264  getNode(o, node);
265  } if (imm || ($.browser.msie && $.browser.version>8)) {
266  // somehow slideDown jumps to the start of tree for IE9 :-(
267  $(node.getChildrenUL()).show();
268  } else {
269  $(node.getChildrenUL()).slideDown("fast");
270  }
271  if (node.isLast) {
272  node.plus_img.src = node.relpath+"arrowdown.png";
273  } else {
274  node.plus_img.src = node.relpath+"arrowdown.png";
275  }
276  node.expanded = true;
277  }
278  }
279 }
280 
281 function glowEffect(n,duration)
282 {
283  n.addClass('glow').delay(duration).queue(function(next){
284  $(this).removeClass('glow');next();
285  });
286 }
287 
288 function highlightAnchor()
289 {
290  var aname = hashUrl();
291  var anchor = $(aname);
292  if (anchor.parent().attr('class')=='memItemLeft'){
293  var rows = $('.memberdecls tr[class$="'+hashValue()+'"]');
294  glowEffect(rows.children(),300); // member without details
295  } else if (anchor.parent().attr('class')=='fieldname'){
296  glowEffect(anchor.parent().parent(),1000); // enum value
297  } else if (anchor.parent().attr('class')=='fieldtype'){
298  glowEffect(anchor.parent().parent(),1000); // struct field
299  } else if (anchor.parent().is(":header")) {
300  glowEffect(anchor.parent(),1000); // section header
301  } else {
302  glowEffect(anchor.next(),1000); // normal member
303  }
304  gotoAnchor(anchor,aname,false);
305 }
306 
307 function selectAndHighlight(hash,n)
308 {
309  var a;
310  if (hash) {
311  var link=stripPath(pathName())+':'+hash.substring(1);
312  a=$('.item a[class$="'+link+'"]');
313  }
314  if (a && a.length) {
315  a.parent().parent().addClass('selected');
316  a.parent().parent().attr('id','selected');
317  highlightAnchor();
318  } else if (n) {
319  $(n.itemDiv).addClass('selected');
320  $(n.itemDiv).attr('id','selected');
321  }
322  if ($('#nav-tree-contents .item:first').hasClass('selected')) {
323  $('#nav-sync').css('top','30px');
324  } else {
325  $('#nav-sync').css('top','5px');
326  }
327  showRoot();
328 }
329 
330 function showNode(o, node, index, hash)
331 {
332  if (node && node.childrenData) {
333  if (typeof(node.childrenData)==='string') {
334  var varName = node.childrenData;
335  getScript(node.relpath+varName,function(){
336  node.childrenData = getData(varName);
337  showNode(o,node,index,hash);
338  },true);
339  } else {
340  if (!node.childrenVisited) {
341  getNode(o, node);
342  }
343  $(node.getChildrenUL()).css({'display':'block'});
344  node.plus_img.src = node.relpath+"arrowdown.png";
345  node.expanded = true;
346  var n = node.children[o.breadcrumbs[index]];
347  if (index+1<o.breadcrumbs.length) {
348  showNode(o,n,index+1,hash);
349  } else {
350  if (typeof(n.childrenData)==='string') {
351  var varName = n.childrenData;
352  getScript(n.relpath+varName,function(){
353  n.childrenData = getData(varName);
354  node.expanded=false;
355  showNode(o,node,index,hash); // retry with child node expanded
356  },true);
357  } else {
358  var rootBase = stripPath(o.toroot.replace(/\..+$/, ''));
359  if (rootBase=="index" || rootBase=="pages" || rootBase=="search") {
360  expandNode(o, n, true, true);
361  }
362  selectAndHighlight(hash,n);
363  }
364  }
365  }
366  } else {
367  selectAndHighlight(hash);
368  }
369 }
370 
371 function removeToInsertLater(element) {
372  var parentNode = element.parentNode;
373  var nextSibling = element.nextSibling;
374  parentNode.removeChild(element);
375  return function() {
376  if (nextSibling) {
377  parentNode.insertBefore(element, nextSibling);
378  } else {
379  parentNode.appendChild(element);
380  }
381  };
382 }
383 
384 function getNode(o, po)
385 {
386  var insertFunction = removeToInsertLater(po.li);
387  po.childrenVisited = true;
388  var l = po.childrenData.length-1;
389  for (var i in po.childrenData) {
390  var nodeData = po.childrenData[i];
391  po.children[i] = newNode(o, po, nodeData[0], nodeData[1], nodeData[2],
392  i==l);
393  }
394  insertFunction();
395 }
396 
397 function gotoNode(o,subIndex,root,hash,relpath)
398 {
399  var nti = navTreeSubIndices[subIndex][root+hash];
400  o.breadcrumbs = $.extend(true, [], nti ? nti : navTreeSubIndices[subIndex][root]);
401  if (!o.breadcrumbs && root!=NAVTREE[0][1]) { // fallback: show index
402  navTo(o,NAVTREE[0][1],"",relpath);
403  $('.item').removeClass('selected');
404  $('.item').removeAttr('id');
405  }
406  if (o.breadcrumbs) {
407  o.breadcrumbs.unshift(0); // add 0 for root node
408  showNode(o, o.node, 0, hash);
409  }
410 }
411 
412 function navTo(o,root,hash,relpath)
413 {
414  var link = cachedLink();
415  if (link) {
416  var parts = link.split('#');
417  root = parts[0];
418  if (parts.length>1) hash = '#'+parts[1].replace(/[^\w\-]/g,'');
419  else hash='';
420  }
421  if (hash.match(/^#l\d+$/)) {
422  var anchor=$('a[name='+hash.substring(1)+']');
423  glowEffect(anchor.parent(),1000); // line number
424  hash=''; // strip line number anchors
425  }
426  var url=root+hash;
427  var i=-1;
428  while (NAVTREEINDEX[i+1]<=url) i++;
429  if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index
430  if (navTreeSubIndices[i]) {
431  gotoNode(o,i,root,hash,relpath)
432  } else {
433  getScript(relpath+'navtreeindex'+i,function(){
434  navTreeSubIndices[i] = eval('NAVTREEINDEX'+i);
435  if (navTreeSubIndices[i]) {
436  gotoNode(o,i,root,hash,relpath);
437  }
438  },true);
439  }
440 }
441 
442 function showSyncOff(n,relpath)
443 {
444  n.html('<img src="'+relpath+'sync_off.png" title="'+SYNCOFFMSG+'"/>');
445 }
446 
447 function showSyncOn(n,relpath)
448 {
449  n.html('<img src="'+relpath+'sync_on.png" title="'+SYNCONMSG+'"/>');
450 }
451 
452 function toggleSyncButton(relpath)
453 {
454  var navSync = $('#nav-sync');
455  if (navSync.hasClass('sync')) {
456  navSync.removeClass('sync');
457  showSyncOff(navSync,relpath);
458  storeLink(stripPath2(pathName())+hashUrl());
459  } else {
460  navSync.addClass('sync');
461  showSyncOn(navSync,relpath);
462  deleteLink();
463  }
464 }
465 
466 function initNavTree(toroot,relpath)
467 {
468  var o = new Object();
469  o.toroot = toroot;
470  o.node = new Object();
471  o.node.li = document.getElementById("nav-tree-contents");
472  o.node.childrenData = NAVTREE;
473  o.node.children = new Array();
474  o.node.childrenUL = document.createElement("ul");
475  o.node.getChildrenUL = function() { return o.node.childrenUL; };
476  o.node.li.appendChild(o.node.childrenUL);
477  o.node.depth = 0;
478  o.node.relpath = relpath;
479  o.node.expanded = false;
480  o.node.isLast = true;
481  o.node.plus_img = document.createElement("img");
482  o.node.plus_img.src = relpath+"arrowright.png";
483  o.node.plus_img.width = 16;
484  o.node.plus_img.height = 22;
485 
486  if (localStorageSupported()) {
487  var navSync = $('#nav-sync');
488  if (cachedLink()) {
489  showSyncOff(navSync,relpath);
490  navSync.removeClass('sync');
491  } else {
492  showSyncOn(navSync,relpath);
493  }
494  navSync.click(function(){ toggleSyncButton(relpath); });
495  }
496 
497  $(window).load(function(){
498  navTo(o,toroot,hashUrl(),relpath);
499  showRoot();
500  });
501 
502  $(window).bind('hashchange', function(){
503  if (window.location.hash && window.location.hash.length>1){
504  var a;
505  if ($(location).attr('hash')){
506  var clslink=stripPath(pathName())+':'+hashValue();
507  a=$('.item a[class$="'+clslink.replace(/</g,'\\3c ')+'"]');
508  }
509  if (a==null || !$(a).parent().parent().hasClass('selected')){
510  $('.item').removeClass('selected');
511  $('.item').removeAttr('id');
512  }
513  var link=stripPath2(pathName());
514  navTo(o,link,hashUrl(),relpath);
515  } else if (!animationInProgress) {
516  $('#doc-content').scrollTop(0);
517  $('.item').removeClass('selected');
518  $('.item').removeAttr('id');
519  navTo(o,toroot,hashUrl(),relpath);
520  }
521  })
522 }
523