|
28 | 28 | Toc.prototype._collectTitleElements = function () {
|
29 | 29 | this._elTitlesNames = []
|
30 | 30 | this.elTitleElements = []
|
31 |
| - for (var i = 1; i < 7; i++) { |
| 31 | + for (var i = 1; i < 6; i++) { |
32 | 32 | if (this.el.getElementsByTagName('h' + i).length) {
|
33 | 33 | this._elTitlesNames.push('h' + i)
|
34 | 34 | }
|
|
44 | 44 | }
|
45 | 45 | }
|
46 | 46 |
|
47 |
| - Toc.prototype._createTocContent = function () { |
48 |
| - this._elTitleElementsLen = this.elTitleElements.length |
49 |
| - if (!this._elTitleElementsLen) return |
50 |
| - this.tocContent = '' |
51 |
| - this._tempLists = [] |
| 47 | + Toc.prototype._createTocContent = function recursiveToc(level = 0, titleElements = [], titleNames = [], ulClass = undefined) { |
| 48 | + // Inititalize our elements from the toc object |
| 49 | + // which is only available on level 0 |
| 50 | + if (level === 0) { |
| 51 | + titleElements = this.elTitleElements |
| 52 | + titleNames = this._elTitlesNames |
| 53 | + ulClass = this.ulClass |
| 54 | + } |
| 55 | + // No need to do anything for an empty ToC |
| 56 | + if (!titleElements.length) return |
52 | 57 |
|
53 |
| - for (var i = 0; i < this._elTitleElementsLen; i++) { |
54 |
| - var j = i + 1 |
55 |
| - this._elTitleElement = this.elTitleElements[i] |
56 |
| - this._elTitleElementName = this._elTitleElement.tagName |
57 |
| - this._elTitleElementTitle = this._elTitleElement.textContent.replace(/"/g, '"') |
58 |
| - this._elTitleElementText = (typeof this.process === 'function' ? this.process(this._elTitleElement) : this._elTitleElement.innerHTML).replace(/<(?:.|\n)*?>/gm, '') |
59 |
| - var id = this._elTitleElement.getAttribute('id') |
60 |
| - if (!id) { |
61 |
| - this._elTitleElement.setAttribute('id', 'tip' + i) |
62 |
| - id = '#tip' + i |
63 |
| - } else { |
64 |
| - id = '#' + id |
65 |
| - } |
| 58 | + var content = '<ul' |
| 59 | + if (ulClass) { |
| 60 | + content += ' class="' + ulClass + '"' |
| 61 | + } |
| 62 | + content += '>\n' |
| 63 | + var iterTag = titleNames[level] |
| 64 | + var recurse = false |
| 65 | + var openTag = false |
66 | 66 |
|
67 |
| - this.tocContent += '<li><a href="' + id + '" title="'+ this._elTitleElementTitle +'">' + this._elTitleElementText + '</a>' |
| 67 | + for (var element; element = titleElements.shift();) { |
| 68 | + var elementTag = element.tagName.toLowerCase() |
68 | 69 |
|
69 |
| - if (j !== this._elTitleElementsLen) { |
70 |
| - this._elNextTitleElementName = this.elTitleElements[j].tagName |
71 |
| - if (this._elTitleElementName !== this._elNextTitleElementName) { |
72 |
| - var checkColse = false |
73 |
| - var y = 1 |
74 |
| - for (var t = this._tempLists.length - 1; t >= 0; t--) { |
75 |
| - if (this._tempLists[t].tagName === this._elNextTitleElementName) { |
76 |
| - checkColse = true |
77 |
| - break |
78 |
| - } |
79 |
| - y++ |
80 |
| - } |
81 |
| - if (checkColse) { |
82 |
| - this.tocContent += new Array(y + 1).join('</li></ul>') |
83 |
| - this._tempLists.length = this._tempLists.length - y |
84 |
| - } else { |
85 |
| - this._tempLists.push(this._elTitleElement) |
86 |
| - if (this.ulClass) { this.tocContent += '<ul class="' + this.ulClass + '">' } else { this.tocContent += '<ul>' } |
87 |
| - } |
| 70 | + // We only care about tags on our level to add them as list item |
| 71 | + if (elementTag == iterTag) { |
| 72 | + // Let's do some cleaning |
| 73 | + var elementTitle = element.textContent.replace(/"/g, '"') |
| 74 | + var elementText = (typeof this.process === 'function' ? this.process(element) : element.innerHTML).replace(/<(?:.|\n)*?>/gm, '') |
| 75 | + var id = element.getAttribute('id') |
| 76 | + if (!id) { |
| 77 | + element.setAttribute('id', 'tip' + i) |
| 78 | + id = '#tip' + i |
88 | 79 | } else {
|
89 |
| - this.tocContent += '</li>' |
| 80 | + id = '#' + id |
90 | 81 | }
|
91 |
| - } else { |
92 |
| - if (this._tempLists.length) { |
93 |
| - this.tocContent += new Array(this._tempLists.length + 1).join('</li></ul>') |
94 |
| - } else { |
95 |
| - this.tocContent += '</li>' |
| 82 | + if (openTag) { |
| 83 | + content += '</li>\n' |
| 84 | + openTag = false |
| 85 | + } |
| 86 | + content += '<li><a href="' + id + '" title="'+ elementTitle +'">' + elementText + '</a>' |
| 87 | + // Reset recursion. We need it for the next subsections |
| 88 | + recurse = false |
| 89 | + openTag = true |
| 90 | + // Check if the current element has a lower level than ours, if so, we have to go down the rabbithole! |
| 91 | + } else if (!recurse && titleNames.indexOf(elementTag.toLowerCase()) > level) { |
| 92 | + recurse = true |
| 93 | + if (!openTag) { |
| 94 | + content += '<li class="invisable-node">' |
| 95 | + openTag = true |
96 | 96 | }
|
| 97 | + // This element is for the lower lever, we have to re-add it before we send the list down there. |
| 98 | + titleElements.unshift(element) |
| 99 | + // Let's call ourself and get to the next level |
| 100 | + content += recursiveToc(level + 1, titleElements, titleNames, ulClass) |
| 101 | + } else { |
| 102 | + // When we end up here, met a higher level element |
| 103 | + // This is not our business so back into the list with the element and let's end this loop |
| 104 | + titleElements.unshift(element) |
| 105 | + break |
97 | 106 | }
|
98 | 107 | }
|
99 |
| - if (this.ulClass) { this.tocContent = '<ul class="' + this.ulClass + '">' + this.tocContent + '</ul>' } else { this.tocContent = '<ul>' + this.tocContent + '</ul>' } |
| 108 | + |
| 109 | + if (openTag) { |
| 110 | + content += '</li>\n' |
| 111 | + } |
| 112 | + content += '</ul>\n' |
| 113 | + |
| 114 | + // Set ToC content of the level 0 everything else pass things to the upper level! |
| 115 | + if (level === 0) { |
| 116 | + this.tocContent = content |
| 117 | + } else { |
| 118 | + return content |
| 119 | + } |
100 | 120 | }
|
101 | 121 |
|
102 | 122 | Toc.prototype._showToc = function () {
|
|
0 commit comments