1/*--------------------------------------------------| 2 3| dTree 2.05 | www.destroydrop.com/javascript/tree/ | 4 5|---------------------------------------------------| 6 7| Copyright (c) 2002-2003 Geir Landr� | 8 9| | 10 11| This script can be used freely as long as all | 12 13| copyright messages are intact. | 14 15| | 16 17| Updated: 17.04.2003 | 18 19|--------------------------------------------------*/ 20 21 22 23// Node object 24 25function Node(id, pid, name, url, title, target, icon, iconOpen, open) { 26 27 this.id = id; 28 29 this.pid = pid; 30 31 this.name = name; 32 33 this.url = url; 34 35 this.title = title; 36 37 this.target = target; 38 39 this.icon = icon; 40 41 this.iconOpen = iconOpen; 42 43 this._io = open || false; 44 45 this._is = false; 46 47 this._ls = false; 48 49 this._hc = false; 50 51 this._ai = 0; 52 53 this._p; 54 55}; 56 57 58 59// Tree object 60 61function dTree(objName) { 62 63 this.config = { 64 65 target : null, 66 67 folderLinks : true, 68 69 useSelection : true, 70 71 useCookies : true, 72 73 useLines : true, 74 75 useIcons : true, 76 77 useStatusText : false, 78 79 closeSameLevel : false, 80 81 inOrder : false 82 83 } 84 85 this.icon = { 86 87 root : 'fas fa-home', 88 89 folder : 'far fa-folder', 90 91 folderOpen : 'far fa-folder-open', 92 93 node : 'far fa-file-alt', 94 95 empty : '', 96 97 line : 'fas fa-ellipsis-v', 98 99 join : 'fas fa-angle-right', 100 101 joinBottom : 'fas fa-angle-right', 102 103 plus : 'far fa-plus-square', 104 105 plusBottom : 'far fa-plus-square', 106 107 minus : 'far fa-minus-square', 108 109 minusBottom : 'far fa-minus-square', 110 111 nlPlus : 'far fa-plus-square', 112 113 nlMinus : 'far fa-minus-square' 114 115 }; 116 117 this.obj = objName; 118 119 this.aNodes = []; 120 121 this.aIndent = []; 122 123 this.root = new Node(-1); 124 125 this.selectedNode = null; 126 127 this.selectedFound = false; 128 129 this.completed = false; 130 131}; 132 133 134 135// Adds a new node to the node array 136 137dTree.prototype.add = function(id, pid, name, url, title, target, icon, iconOpen, open) { 138 139 this.aNodes[this.aNodes.length] = new Node(id, pid, name, url, title, target, icon, iconOpen, open); 140 141}; 142 143 144 145// Open/close all nodes 146 147dTree.prototype.openAll = function() { 148 149 this.oAll(true); 150 151}; 152 153dTree.prototype.closeAll = function() { 154 155 this.oAll(false); 156 157}; 158 159 160 161// Outputs the tree to the page 162 163dTree.prototype.toString = function() { 164 165 var str = '<div class="dtree">\n'; 166 167 if (document.getElementById) { 168 169 if (this.config.useCookies) this.selectedNode = this.getSelected(); 170 171 str += this.addNode(this.root); 172 173 } else str += 'Browser not supported.'; 174 175 str += '</div>'; 176 177 if (!this.selectedFound) this.selectedNode = null; 178 179 this.completed = true; 180 181 return str; 182 183}; 184 185 186 187// Creates the tree structure 188 189dTree.prototype.addNode = function(pNode) { 190 191 var str = ''; 192 193 var n=0; 194 195 if (this.config.inOrder) n = pNode._ai; 196 197 for (n; n<this.aNodes.length; n++) { 198 199 if (this.aNodes[n].pid == pNode.id) { 200 201 var cn = this.aNodes[n]; 202 203 cn._p = pNode; 204 205 cn._ai = n; 206 207 this.setCS(cn); 208 209 if (!cn.target && this.config.target) cn.target = this.config.target; 210 211 if (cn._hc && !cn._io && this.config.useCookies) cn._io = this.isOpen(cn.id); 212 213 if (!this.config.folderLinks && cn._hc) cn.url = null; 214 215 if (this.config.useSelection && cn.id == this.selectedNode && !this.selectedFound) { 216 217 cn._is = true; 218 219 this.selectedNode = n; 220 221 this.selectedFound = true; 222 223 } 224 225 str += this.node(cn, n); 226 227 if (cn._ls) break; 228 229 } 230 231 } 232 233 return str; 234 235}; 236 237 238 239// Creates the node icon, url and text 240 241dTree.prototype.node = function(node, nodeId) { 242 243 var str = '<div class="dTreeNode">' + this.indent(node, nodeId); 244 245 if (this.config.useIcons) { 246 247 if (!node.icon) node.icon = (this.root.id == node.pid) ? this.icon.root : ((node._hc) ? this.icon.folder : this.icon.node); 248 249 if (!node.iconOpen) node.iconOpen = (node._hc) ? this.icon.folderOpen : this.icon.node; 250 251 if (this.root.id == node.pid) { 252 253 node.icon = this.icon.root; 254 255 node.iconOpen = this.icon.root; 256 257 } 258
259 str += '<i id="i' + this.obj + nodeId + '" class="' + ((node._io) ? node.iconOpen : node.icon) + '"></i>'; 260 261 } 262 263 if (node.url) { 264 265 str += '<a id="s' + this.obj + nodeId + '" class="' + ((this.config.useSelection) ? ((node._is ? 'nodeSel' : 'node')) : 'node') + '" href="' + node.url + '"'; 266 267 if (node.title) str += ' title="' + node.title + '"'; 268 269 if (node.target) str += ' target="' + node.target + '"'; 270 271 if (this.config.useStatusText) str += ' onmouseover="window.status=\'' + node.name + '\';return true;" onmouseout="window.status=\'\';return true;" '; 272 273 if (this.config.useSelection && ((node._hc && this.config.folderLinks) || !node._hc)) 274 275 str += ' onclick="javascript: ' + this.obj + '.s(' + nodeId + ');"'; 276 277 str += '>'; 278 279 } 280 281 else if ((!this.config.folderLinks || !node.url) && node._hc && node.pid != this.root.id) 282 283 str += '<a href="javascript: ' + this.obj + '.o(' + nodeId + ');" class="node">'; 284 285 str += node.name; 286 287 if (node.url || ((!this.config.folderLinks || !node.url) && node._hc)) str += '</a>'; 288 289 str += '</div>'; 290 291 if (node._hc) { 292 293 str += '<div id="d' + this.obj + nodeId + '" class="clip" style="display:' + ((this.root.id == node.pid || node._io) ? 'block' : 'none') + ';">'; 294 295 str += this.addNode(node); 296 297 str += '</div>'; 298 299 } 300 301 this.aIndent.pop(); 302 303 return str; 304 305}; 306 307 308 309// Adds the empty and line icons 310 311dTree.prototype.indent = function(node, nodeId) { 312 313 var str = ''; 314 315 if (this.root.id != node.pid) { 316 317 for (var n=0; n<this.aIndent.length; n++) 318 319 str += '<i class="' + ( (this.aIndent[n] == 1 && this.config.useLines) ? this.icon.line : this.icon.empty ) + '"></i>'; 320 321 (node._ls) ? this.aIndent.push(0) : this.aIndent.push(1); 322 323 if (node._hc) { 324 325 str += '<a href="javascript: ' + this.obj + '.o(' + nodeId + ');"><i id="j' + this.obj + nodeId + '" class="'; 326 327 if (!this.config.useLines) str += (node._io) ? this.icon.nlMinus : this.icon.nlPlus; 328 329 else str += ( (node._io) ? ((node._ls && this.config.useLines) ? this.icon.minusBottom : this.icon.minus) : ((node._ls && this.config.useLines) ? this.icon.plusBottom : this.icon.plus ) ); 330 331 str += '"></i></a>'; 332 333 } else str += '<i class="' + ( (this.config.useLines) ? ((node._ls) ? this.icon.joinBottom : this.icon.join ) : this.icon.empty) + '" alt=""></i>'; 334 335 } 336 337 return str; 338 339}; 340 341 342 343// Checks if a node has any children and if it is the last sibling 344 345dTree.prototype.setCS = function(node) { 346 347 var lastId; 348 349 for (var n=0; n<this.aNodes.length; n++) { 350 351 if (this.aNodes[n].pid == node.id) node._hc = true; 352 353 if (this.aNodes[n].pid == node.pid) lastId = this.aNodes[n].id; 354 355 } 356 357 if (lastId==node.id) node._ls = true; 358 359}; 360 361 362 363// Returns the selected node 364 365dTree.prototype.getSelected = function() { 366 367 var sn = this.getCookie('cs' + this.obj); 368 369 return (sn) ? sn : null; 370 371}; 372 373 374 375// Highlights the selected node 376 377dTree.prototype.s = function(id) { 378 379 if (!this.config.useSelection) return; 380 381 var cn = this.aNodes[id]; 382 383 if (cn._hc && !this.config.folderLinks) return; 384 385 if (this.selectedNode != id) { 386 387 if (this.selectedNode || this.selectedNode==0) { 388 389 eOld = document.getElementById("s" + this.obj + this.selectedNode); 390 391 eOld.className = "node"; 392 393 } 394 395 eNew = document.getElementById("s" + this.obj + id); 396 397 eNew.className = "nodeSel"; 398 399 this.selectedNode = id; 400 401 if (this.config.useCookies) this.setCookie('cs' + this.obj, cn.id); 402 403 } 404 405}; 406 407 408 409// Toggle Open or close 410 411dTree.prototype.o = function(id) { 412 413 var cn = this.aNodes[id]; 414 415 this.nodeStatus(!cn._io, id, cn._ls); 416 417 cn._io = !cn._io; 418 419 if (this.config.closeSameLevel) this.closeLevel(cn); 420 421 if (this.config.useCookies) this.updateCookie(); 422 423}; 424 425 426 427// Open or close all nodes 428 429dTree.prototype.oAll = function(status) { 430 431 for (var n=0; n<this.aNodes.length; n++) { 432 433 if (this.aNodes[n]._hc && this.aNodes[n].pid != this.root.id) { 434 435 this.nodeStatus(status, n, this.aNodes[n]._ls) 436 437 this.aNodes[n]._io = status; 438 439 } 440 441 } 442 443 if (this.config.useCookies) this.updateCookie(); 444 445}; 446 447 448 449// Opens the tree to a specific node 450 451dTree.prototype.openTo = function(nId, bSelect, bFirst) { 452 453 if (!bFirst) { 454 455 for (var n=0; n<this.aNodes.length; n++) { 456 457 if (this.aNodes[n].id == nId) { 458 459 nId=n; 460 461 break; 462 463 } 464 465 } 466 467 } 468
469 var cn=this.aNodes[nId]; 470 471 if (cn.pid==this.root.id || !cn._p) return; 472 473 cn._io = true; 474 475 cn._is = bSelect; 476 477 if (this.completed && cn._hc) this.nodeStatus(true, cn._ai, cn._ls); 478 479 if (this.completed && bSelect) this.s(cn._ai); 480 481 else if (bSelect) this._sn=cn._ai; 482 483 this.openTo(cn._p._ai, false, true); 484 485}; 486 487 488 489// Closes all nodes on the same level as certain node 490 491dTree.prototype.closeLevel = function(node) { 492 493 for (var n=0; n<this.aNodes.length; n++) { 494 495 if (this.aNodes[n].pid == node.pid && this.aNodes[n].id != node.id && this.aNodes[n]._hc) { 496 497 this.nodeStatus(false, n, this.aNodes[n]._ls); 498 499 this.aNodes[n]._io = false; 500 501 this.closeAllChildren(this.aNodes[n]); 502 503 } 504 505 } 506 507} 508 509 510 511// Closes all children of a node 512 513dTree.prototype.closeAllChildren = function(node) { 514 515 for (var n=0; n<this.aNodes.length; n++) { 516 517 if (this.aNodes[n].pid == node.id && this.aNodes[n]._hc) { 518 519 if (this.aNodes[n]._io) this.nodeStatus(false, n, this.aNodes[n]._ls); 520 521 this.aNodes[n]._io = false; 522 523 this.closeAllChildren(this.aNodes[n]); 524 525 } 526 527 } 528 529} 530 531 532 533// Change the status of a node(open or closed) 534 535dTree.prototype.nodeStatus = function(status, id, bottom) { 536 537 eDiv = document.getElementById('d' + this.obj + id); 538 539 eJoin = document.getElementById('j' + this.obj + id); 540 541 if (this.config.useIcons) { 542 543 eIcon = document.getElementById('i' + this.obj + id); 544 545 eIcon.src = (status) ? this.aNodes[id].iconOpen : this.aNodes[id].icon; 546 547 } 548 549 eJoin.src = (this.config.useLines)? 550 551 ((status)?((bottom)?this.icon.minusBottom:this.icon.minus):((bottom)?this.icon.plusBottom:this.icon.plus)): 552 553 ((status)?this.icon.nlMinus:this.icon.nlPlus); 554 555 eDiv.style.display = (status) ? 'block': 'none'; 556 557}; 558 559 560 561 562 563// [Cookie] Clears a cookie 564 565dTree.prototype.clearCookie = function() { 566 567 var now = new Date(); 568 569 var yesterday = new Date(now.getTime() - 1000 * 60 * 60 * 24); 570 571 this.setCookie('co'+this.obj, 'cookieValue', yesterday); 572 573 this.setCookie('cs'+this.obj, 'cookieValue', yesterday); 574 575}; 576 577 578 579// [Cookie] Sets value in a cookie 580 581dTree.prototype.setCookie = function(cookieName, cookieValue, expires, path, domain, secure) { 582 583 document.cookie = 584 585 escape(cookieName) + '=' + escape(cookieValue) 586 587 + (expires ? '; expires=' + expires.toGMTString() : '') 588 589 + (path ? '; path=' + path : '') 590 591 + (domain ? '; domain=' + domain : '') 592 593 + (secure ? '; secure' : ''); 594 595}; 596 597 598 599// [Cookie] Gets a value from a cookie 600 601dTree.prototype.getCookie = function(cookieName) { 602 603 var cookieValue = ''; 604 605 var posName = document.cookie.indexOf(escape(cookieName) + '='); 606 607 if (posName != -1) { 608 609 var posValue = posName + (escape(cookieName) + '=').length; 610 611 var endPos = document.cookie.indexOf(';', posValue); 612 613 if (endPos != -1) cookieValue = unescape(document.cookie.substring(posValue, endPos)); 614 615 else cookieValue = unescape(document.cookie.substring(posValue)); 616 617 } 618 619 return (cookieValue); 620 621}; 622 623 624 625// [Cookie] Returns ids of open nodes as a string 626 627dTree.prototype.updateCookie = function() { 628 629 var str = ''; 630 631 for (var n=0; n<this.aNodes.length; n++) { 632 633 if (this.aNodes[n]._io && this.aNodes[n].pid != this.root.id) { 634 635 if (str) str += '.'; 636 637 str += this.aNodes[n].id; 638 639 } 640 641 } 642 643 this.setCookie('co' + this.obj, str); 644 645}; 646 647 648 649// [Cookie] Checks if a node id is in a cookie 650 651dTree.prototype.isOpen = function(id) { 652 653 var aOpen = this.getCookie('co' + this.obj).split('.'); 654 655 for (var n=0; n<aOpen.length; n++) 656 657 if (aOpen[n] == id) return true; 658 659 return false; 660 661}; 662 663 664 665// If Push and pop is not implemented by the browser 666 667if (!Array.prototype.push) { 668 669 Array.prototype.push = function array_push() { 670 671 for(var i=0;i<arguments.length;i++) 672 673 this[this.length]=arguments[i]; 674 675 return this.length; 676 677 } 678 679}; 680 681if (!Array.prototype.pop) { 682 683 Array.prototype.pop = function array_pop() { 684 685 lastElement = this[this.length-1]; 686 687 this.length = Math.max(this.length-1,0); 688 689 return lastElement; 690 691 } 692 693};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.