docs/html/navtree.js   F
last analyzed

Complexity

Total Complexity 106
Complexity/F 2.36

Size

Lines of Code 516
Function Count 45

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 364
c 0
b 0
f 0
dl 0
loc 516
rs 2
wmc 106
mnd 61
bc 61
fnc 45
bpm 1.3555
cpm 2.3555
noi 18

28 Functions

Rating   Name   Duplication   Size   Complexity  
C navtree.js ➔ initNavTree 0 56 11
A navtree.js ➔ storeLink 0 6 2
A navtree.js ➔ gotoNode 0 14 4
A navtree.js ➔ getNode 0 12 2
B navtree.js ➔ expandNode 0 23 6
C navtree.js ➔ showNode 0 40 9
A navtree.js ➔ highlightAnchor 0 18 5
A navtree.js ➔ removeToInsertLater 0 12 3
A navtree.js ➔ hashValue 0 4 1
A navtree.js ➔ selectAndHighlight 0 22 5
A navtree.js ➔ deleteLink 0 6 2
A navtree.js ➔ showSyncOff 0 4 1
C navtree.js ➔ navTo 0 29 9
A navtree.js ➔ stripPath2 0 7 2
A navtree.js ➔ toggleSyncButton 0 13 2
A navtree.js ➔ glowEffect 0 6 2
A navtree.js ➔ stripPath 0 4 1
B navtree.js ➔ createIndent 0 32 5
A navtree.js ➔ showSyncOn 0 4 1
B navtree.js ➔ gotoAnchor 0 27 6
D navtree.js ➔ newNode 0 80 11
A navtree.js ➔ hashUrl 0 4 1
A navtree.js ➔ getData 0 6 2
A navtree.js ➔ localStorageSupported 0 9 2
A navtree.js ➔ pathName 0 4 1
A navtree.js ➔ getScript 0 18 5
A navtree.js ➔ showRoot 0 14 3
A navtree.js ➔ cachedLink 0 8 2

How to fix   Complexity   

Complexity

Complex classes like docs/html/navtree.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
var navTreeSubIndices = [];
2
var arrowDown = '▼';
3
var arrowRight = '►';
4
5
function getData(varName)
6
{
7
  var i = varName.lastIndexOf('/');
8
  var n = i>=0 ? varName.substring(i+1) : varName;
9
  return eval(n.replace(/\-/g,'_'));
0 ignored issues
show
Security Performance introduced by
Calls to eval are slow and potentially dangerous, especially on untrusted code. Please consider whether there is another way to achieve your goal.
Loading history...
10
}
11
12
function stripPath(uri)
13
{
14
  return uri.substring(uri.lastIndexOf('/')+1);
15
}
16
17
function stripPath2(uri)
18
{
19
  var i = uri.lastIndexOf('/');
20
  var s = uri.substring(i+1);
21
  var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/);
22
  return m ? uri.substring(i-6) : s;
23
}
24
25
function hashValue()
26
{
27
  return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,'');
28
}
29
30
function hashUrl()
31
{
32
  return '#'+hashValue();
33
}
34
35
function pathName()
36
{
37
  return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, '');
38
}
39
40
function localStorageSupported()
41
{
42
  try {
43
    return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem;
44
  }
45
  catch(e) {
46
    return false;
47
  }
48
}
49
50
51
function storeLink(link)
52
{
53
  if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) {
54
      window.localStorage.setItem('navpath',link);
55
  }
56
}
57
58
function deleteLink()
59
{
60
  if (localStorageSupported()) {
61
    window.localStorage.setItem('navpath','');
62
  }
63
}
64
65
function cachedLink()
66
{
67
  if (localStorageSupported()) {
68
    return window.localStorage.getItem('navpath');
69
  } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
70
    return '';
71
  }
72
}
73
74
function getScript(scriptName,func,show)
75
{
76
  var head = document.getElementsByTagName("head")[0];
77
  var script = document.createElement('script');
78
  script.id = scriptName;
79
  script.type = 'text/javascript';
80
  script.onload = func;
81
  script.src = scriptName+'.js';
82
  if ($.browser.msie && $.browser.version<=8) {
83
    // script.onload does not work with older versions of IE
84
    script.onreadystatechange = function() {
85
      if (script.readyState=='complete' || script.readyState=='loaded') {
86
        func(); if (show) showRoot();
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
87
      }
88
    }
89
  }
90
  head.appendChild(script);
91
}
92
93
function createIndent(o,domNode,node,level)
94
{
95
  var level=-1;
96
  var n = node;
97
  while (n.parentNode) { level++; n=n.parentNode; }
98
  if (node.childrenData) {
99
    var imgNode = document.createElement("span");
100
    imgNode.className = 'arrow';
101
    imgNode.style.paddingLeft=(16*level).toString()+'px';
102
    imgNode.innerHTML=arrowRight;
103
    node.plus_img = imgNode;
104
    node.expandToggle = document.createElement("a");
105
    node.expandToggle.href = "javascript:void(0)";
106
    node.expandToggle.onclick = function() {
107
      if (node.expanded) {
108
        $(node.getChildrenUL()).slideUp("fast");
109
        node.plus_img.innerHTML=arrowRight;
110
        node.expanded = false;
111
      } else {
112
        expandNode(o, node, false, false);
113
      }
114
    };
115
    node.expandToggle.appendChild(imgNode);
116
    domNode.appendChild(node.expandToggle);
117
  } else {
118
    var span = document.createElement("span");
119
    span.className = 'arrow';
120
    span.style.width   = 16*(level+1)+'px';
121
    span.innerHTML = '&#160;';
122
    domNode.appendChild(span);
123
  }
124
}
125
126
var animationInProgress = false;
127
128
function gotoAnchor(anchor,aname,updateLocation)
129
{
130
  var pos, docContent = $('#doc-content');
131
  var ancParent = $(anchor.parent());
132
  if (ancParent.hasClass('memItemLeft') ||
133
      ancParent.hasClass('fieldname') ||
134
      ancParent.hasClass('fieldtype') ||
135
      ancParent.is(':header'))
136
  {
137
    pos = ancParent.position().top;
138
  } else if (anchor.position()) {
139
    pos = anchor.position().top;
140
  }
141
  if (pos) {
142
    var dist = Math.abs(Math.min(
143
               pos-docContent.offset().top,
144
               docContent[0].scrollHeight-
145
               docContent.height()-docContent.scrollTop()));
146
    animationInProgress=true;
147
    docContent.animate({
148
      scrollTop: pos + docContent.scrollTop() - docContent.offset().top
149
    },Math.max(50,Math.min(500,dist)),function(){
150
      if (updateLocation) window.location.href=aname;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
151
      animationInProgress=false;
152
    });
153
  }
154
}
155
156
function newNode(o, po, text, link, childrenData, lastNode)
157
{
158
  var node = {};
159
  node.children = Array();
160
  node.childrenData = childrenData;
161
  node.depth = po.depth + 1;
162
  node.relpath = po.relpath;
163
  node.isLast = lastNode;
164
165
  node.li = document.createElement("li");
166
  po.getChildrenUL().appendChild(node.li);
167
  node.parentNode = po;
168
169
  node.itemDiv = document.createElement("div");
170
  node.itemDiv.className = "item";
171
172
  node.labelSpan = document.createElement("span");
173
  node.labelSpan.className = "label";
174
175
  createIndent(o,node.itemDiv,node,0);
176
  node.itemDiv.appendChild(node.labelSpan);
177
  node.li.appendChild(node.itemDiv);
178
179
  var a = document.createElement("a");
180
  node.labelSpan.appendChild(a);
181
  node.label = document.createTextNode(text);
182
  node.expanded = false;
183
  a.appendChild(node.label);
184
  if (link) {
185
    var url;
186
    if (link.substring(0,1)=='^') {
187
      url = link.substring(1);
188
      link = url;
189
    } else {
190
      url = node.relpath+link;
191
    }
192
    a.className = stripPath(link.replace('#',':'));
193
    if (link.indexOf('#')!=-1) {
194
      var aname = '#'+link.split('#')[1];
195
      var srcPage = stripPath(pathName());
196
      var targetPage = stripPath(link.split('#')[0]);
197
      a.href = srcPage!=targetPage ? url : "javascript:void(0)";
198
      a.onclick = function(){
199
        storeLink(link);
200
        if (!$(a).parent().parent().hasClass('selected'))
201
        {
202
          $('.item').removeClass('selected');
203
          $('.item').removeAttr('id');
204
          $(a).parent().parent().addClass('selected');
205
          $(a).parent().parent().attr('id','selected');
206
        }
207
        var anchor = $(aname);
208
        gotoAnchor(anchor,aname,true);
209
      };
210
    } else {
211
      a.href = url;
212
      a.onclick = function() { storeLink(link); }
213
    }
214
  } else {
215
    if (childrenData != null)
0 ignored issues
show
Best Practice introduced by
Comparing childrenData to null using the != operator is not safe. Consider using !== instead.
Loading history...
216
    {
217
      a.className = "nolink";
218
      a.href = "javascript:void(0)";
219
      a.onclick = node.expandToggle.onclick;
220
    }
221
  }
222
223
  node.childrenUL = null;
224
  node.getChildrenUL = function() {
225
    if (!node.childrenUL) {
226
      node.childrenUL = document.createElement("ul");
227
      node.childrenUL.className = "children_ul";
228
      node.childrenUL.style.display = "none";
229
      node.li.appendChild(node.childrenUL);
230
    }
231
    return node.childrenUL;
232
  };
233
234
  return node;
235
}
236
237
function showRoot()
238
{
239
  var headerHeight = $("#top").height();
240
  var footerHeight = $("#nav-path").height();
241
  var windowHeight = $(window).height() - headerHeight - footerHeight;
242
  (function (){ // retry until we can scroll to the selected item
243
    try {
244
      var navtree=$('#nav-tree');
245
      navtree.scrollTo('#selected',0,{offset:-windowHeight/2});
246
    } catch (err) {
247
      setTimeout(arguments.callee, 0);
248
    }
249
  })();
250
}
251
252
function expandNode(o, node, imm, showRoot)
253
{
254
  if (node.childrenData && !node.expanded) {
255
    if (typeof(node.childrenData)==='string') {
256
      var varName    = node.childrenData;
257
      getScript(node.relpath+varName,function(){
258
        node.childrenData = getData(varName);
259
        expandNode(o, node, imm, showRoot);
260
      }, showRoot);
261
    } else {
262
      if (!node.childrenVisited) {
263
        getNode(o, node);
264
      } if (imm || ($.browser.msie && $.browser.version>8)) {
265
        // somehow slideDown jumps to the start of tree for IE9 :-(
266
        $(node.getChildrenUL()).show();
267
      } else {
268
        $(node.getChildrenUL()).slideDown("fast");
269
      }
270
      node.plus_img.innerHTML = arrowDown;
271
      node.expanded = true;
272
    }
273
  }
274
}
275
276
function glowEffect(n,duration)
277
{
278
  n.addClass('glow').delay(duration).queue(function(next){
279
    $(this).removeClass('glow');next();
280
  });
281
}
282
283
function highlightAnchor()
284
{
285
  var aname = hashUrl();
286
  var anchor = $(aname);
287
  if (anchor.parent().attr('class')=='memItemLeft'){
288
    var rows = $('.memberdecls tr[class$="'+hashValue()+'"]');
289
    glowEffect(rows.children(),300); // member without details
290
  } else if (anchor.parent().attr('class')=='fieldname'){
291
    glowEffect(anchor.parent().parent(),1000); // enum value
292
  } else if (anchor.parent().attr('class')=='fieldtype'){
293
    glowEffect(anchor.parent().parent(),1000); // struct field
294
  } else if (anchor.parent().is(":header")) {
295
    glowEffect(anchor.parent(),1000); // section header
296
  } else {
297
    glowEffect(anchor.next(),1000); // normal member
298
  }
299
  gotoAnchor(anchor,aname,false);
300
}
301
302
function selectAndHighlight(hash,n)
303
{
304
  var a;
305
  if (hash) {
306
    var link=stripPath(pathName())+':'+hash.substring(1);
307
    a=$('.item a[class$="'+link+'"]');
308
  }
309
  if (a && a.length) {
310
    a.parent().parent().addClass('selected');
311
    a.parent().parent().attr('id','selected');
312
    highlightAnchor();
313
  } else if (n) {
314
    $(n.itemDiv).addClass('selected');
315
    $(n.itemDiv).attr('id','selected');
316
  }
317
  if ($('#nav-tree-contents .item:first').hasClass('selected')) {
318
    $('#nav-sync').css('top','30px');
319
  } else {
320
    $('#nav-sync').css('top','5px');
321
  }
322
  showRoot();
323
}
324
325
function showNode(o, node, index, hash)
326
{
327
  if (node && node.childrenData) {
328
    if (typeof(node.childrenData)==='string') {
329
      var varName    = node.childrenData;
330
      getScript(node.relpath+varName,function(){
331
        node.childrenData = getData(varName);
332
        showNode(o,node,index,hash);
333
      },true);
334
    } else {
335
      if (!node.childrenVisited) {
336
        getNode(o, node);
337
      }
338
      $(node.getChildrenUL()).css({'display':'block'});
339
      node.plus_img.innerHTML = arrowDown;
340
      node.expanded = true;
341
      var n = node.children[o.breadcrumbs[index]];
342
      if (index+1<o.breadcrumbs.length) {
343
        showNode(o,n,index+1,hash);
344
      } else {
345
        if (typeof(n.childrenData)==='string') {
346
          var varName = n.childrenData;
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable varName already seems to be declared on line 329. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
347
          getScript(n.relpath+varName,function(){
348
            n.childrenData = getData(varName);
349
            node.expanded=false;
350
            showNode(o,node,index,hash); // retry with child node expanded
351
          },true);
352
        } else {
353
          var rootBase = stripPath(o.toroot.replace(/\..+$/, ''));
354
          if (rootBase=="index" || rootBase=="pages" || rootBase=="search") {
355
            expandNode(o, n, true, true);
356
          }
357
          selectAndHighlight(hash,n);
358
        }
359
      }
360
    }
361
  } else {
362
    selectAndHighlight(hash);
363
  }
364
}
365
366
function removeToInsertLater(element) {
367
  var parentNode = element.parentNode;
368
  var nextSibling = element.nextSibling;
369
  parentNode.removeChild(element);
370
  return function() {
371
    if (nextSibling) {
372
      parentNode.insertBefore(element, nextSibling);
373
    } else {
374
      parentNode.appendChild(element);
375
    }
376
  };
377
}
378
379
function getNode(o, po)
380
{
381
  var insertFunction = removeToInsertLater(po.li);
382
  po.childrenVisited = true;
383
  var l = po.childrenData.length-1;
384
  for (var i in po.childrenData) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
385
    var nodeData = po.childrenData[i];
386
    po.children[i] = newNode(o, po, nodeData[0], nodeData[1], nodeData[2],
387
      i==l);
388
  }
389
  insertFunction();
390
}
391
392
function gotoNode(o,subIndex,root,hash,relpath)
393
{
394
  var nti = navTreeSubIndices[subIndex][root+hash];
395
  o.breadcrumbs = $.extend(true, [], nti ? nti : navTreeSubIndices[subIndex][root]);
396
  if (!o.breadcrumbs && root!=NAVTREE[0][1]) { // fallback: show index
0 ignored issues
show
Bug introduced by
The variable NAVTREE seems to be never declared. If this is a global, consider adding a /** global: NAVTREE */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
397
    navTo(o,NAVTREE[0][1],"",relpath);
398
    $('.item').removeClass('selected');
399
    $('.item').removeAttr('id');
400
  }
401
  if (o.breadcrumbs) {
402
    o.breadcrumbs.unshift(0); // add 0 for root node
403
    showNode(o, o.node, 0, hash);
404
  }
405
}
406
407
function navTo(o,root,hash,relpath)
408
{
409
  var link = cachedLink();
410
  if (link) {
411
    var parts = link.split('#');
412
    root = parts[0];
413
    if (parts.length>1) hash = '#'+parts[1].replace(/[^\w\-]/g,'');
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
414
    else hash='';
415
  }
416
  if (hash.match(/^#l\d+$/)) {
417
    var anchor=$('a[name='+hash.substring(1)+']');
418
    glowEffect(anchor.parent(),1000); // line number
419
    hash=''; // strip line number anchors
420
  }
421
  var url=root+hash;
422
  var i=-1;
423
  while (NAVTREEINDEX[i+1]<=url) i++;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
Bug introduced by
The variable NAVTREEINDEX seems to be never declared. If this is a global, consider adding a /** global: NAVTREEINDEX */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
424
  if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index
0 ignored issues
show
Bug introduced by
The variable NAVTREE seems to be never declared. If this is a global, consider adding a /** global: NAVTREE */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
425
  if (navTreeSubIndices[i]) {
426
    gotoNode(o,i,root,hash,relpath)
427
  } else {
428
    getScript(relpath+'navtreeindex'+i,function(){
429
      navTreeSubIndices[i] = eval('NAVTREEINDEX'+i);
0 ignored issues
show
Security Performance introduced by
Calls to eval are slow and potentially dangerous, especially on untrusted code. Please consider whether there is another way to achieve your goal.
Loading history...
430
      if (navTreeSubIndices[i]) {
431
        gotoNode(o,i,root,hash,relpath);
432
      }
433
    },true);
434
  }
435
}
436
437
function showSyncOff(n,relpath)
438
{
439
    n.html('<img src="'+relpath+'sync_off.png" title="'+SYNCOFFMSG+'"/>');
0 ignored issues
show
Bug introduced by
The variable SYNCOFFMSG seems to be never declared. If this is a global, consider adding a /** global: SYNCOFFMSG */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
440
}
441
442
function showSyncOn(n,relpath)
443
{
444
    n.html('<img src="'+relpath+'sync_on.png" title="'+SYNCONMSG+'"/>');
0 ignored issues
show
Bug introduced by
The variable SYNCONMSG seems to be never declared. If this is a global, consider adding a /** global: SYNCONMSG */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
445
}
446
447
function toggleSyncButton(relpath)
448
{
449
  var navSync = $('#nav-sync');
450
  if (navSync.hasClass('sync')) {
451
    navSync.removeClass('sync');
452
    showSyncOff(navSync,relpath);
453
    storeLink(stripPath2(pathName())+hashUrl());
454
  } else {
455
    navSync.addClass('sync');
456
    showSyncOn(navSync,relpath);
457
    deleteLink();
458
  }
459
}
460
461
function initNavTree(toroot,relpath)
462
{
463
  var o = {};
464
  o.toroot = toroot;
465
  o.node = {};
466
  o.node.li = document.getElementById("nav-tree-contents");
467
  o.node.childrenData = NAVTREE;
0 ignored issues
show
Bug introduced by
The variable NAVTREE seems to be never declared. If this is a global, consider adding a /** global: NAVTREE */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
468
  o.node.children = [];
469
  o.node.childrenUL = document.createElement("ul");
470
  o.node.getChildrenUL = function() { return o.node.childrenUL; };
471
  o.node.li.appendChild(o.node.childrenUL);
472
  o.node.depth = 0;
473
  o.node.relpath = relpath;
474
  o.node.expanded = false;
475
  o.node.isLast = true;
476
  o.node.plus_img = document.createElement("span");
477
  o.node.plus_img.className = 'arrow';
478
  o.node.plus_img.innerHTML = arrowRight;
479
480
  if (localStorageSupported()) {
481
    var navSync = $('#nav-sync');
482
    if (cachedLink()) {
483
      showSyncOff(navSync,relpath);
484
      navSync.removeClass('sync');
485
    } else {
486
      showSyncOn(navSync,relpath);
487
    }
488
    navSync.click(function(){ toggleSyncButton(relpath); });
489
  }
490
491
  $(window).load(function(){
492
    navTo(o,toroot,hashUrl(),relpath);
493
    showRoot();
494
  });
495
496
  $(window).bind('hashchange', function(){
497
     if (window.location.hash && window.location.hash.length>1){
498
       var a;
499
       if ($(location).attr('hash')){
500
         var clslink=stripPath(pathName())+':'+hashValue();
501
         a=$('.item a[class$="'+clslink.replace(/</g,'\\3c ')+'"]');
502
       }
503
       if (a==null || !$(a).parent().parent().hasClass('selected')){
0 ignored issues
show
Best Practice introduced by
Comparing a to null using the == operator is not safe. Consider using === instead.
Loading history...
Bug introduced by
The variable a does not seem to be initialized in case $(location).attr("hash") on line 499 is false. Are you sure this can never be the case?
Loading history...
504
         $('.item').removeClass('selected');
505
         $('.item').removeAttr('id');
506
       }
507
       var link=stripPath2(pathName());
508
       navTo(o,link,hashUrl(),relpath);
509
     } else if (!animationInProgress) {
510
       $('#doc-content').scrollTop(0);
511
       $('.item').removeClass('selected');
512
       $('.item').removeAttr('id');
513
       navTo(o,toroot,hashUrl(),relpath);
514
     }
515
  })
516
}
517
518