Changes for page Alder Support Center scripts
Last modified by wiki admin on 2026/08/26 01:04
From version 8.1
edited by wiki admin
on 2026/08/24 22:49
on 2026/08/24 22:49
Change comment:
There is no comment for this version
To version 2.1
edited by wiki admin
on 2026/08/24 21:04
on 2026/08/24 21:04
Change comment:
There is no comment for this version
Summary
-
Page properties (1 modified, 0 added, 0 removed)
-
Objects (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Content
-
... ... @@ -1,1 +1,1 @@ 1 -Article accordion. Edit the object, not this text. 1 +Article accordion for the customer-facing design. Edit the object, not this text.
- XWiki.JavaScriptExtension[0]
-
- Code
-
... ... @@ -38,134 +38,57 @@ 38 38 return svg; 39 39 } 40 40 41 - function isWikiHome() { 42 - // The employees home page has several H2s (departments, article status, 43 - // publishing workflow). Collapsing a landing page into rows hides the 44 - // thing people came for, so skip it. Matches both URL schemes this 45 - // deployment serves: /bin/view/Main/ and /wiki/<name>/view/Main/. 46 - var path = (window.location.pathname || '').replace(/\/+$/, ''); 47 - return /\/view\/Main(\/WebHome)?$/.test(path); 48 - } 49 - 50 50 function build() { 51 51 var body = document.body; 52 52 if (!body || body.className.indexOf('viewbody') === -1) { 53 53 return; // edit, preview, or anything that is not a rendered page 54 54 } 55 - if (isWikiHome()) { return; } 56 56 var content = document.getElementById('xwikicontent'); 57 57 if (!content) { return; } 58 58 59 - // XWiki renders each section as its own <div class="f-accordion-panel">, 60 - // with the section heading as the first child and everything else after it: 61 - // 62 - // <div class="f-accordion-panel" data-controller="accordion"> 63 - // <h2>Arm/Disarm</h2> <- section heading 64 - // <h1>Arm</h1><p>...</p> <- content, including Helpjuice's inverted 65 - // </div> h1 "subsections" 66 - // 67 - // So the section container already exists and we only need to make it 68 - // collapsible. Two earlier versions of this script tried to rebuild sections 69 - // by grouping sibling headings -- first from content.children (headings are 70 - // nested, so it found none), then by grouping headings that share a parent 71 - // (each heading has its OWN panel, so every group had one item and the 72 - // script bailed silently). Both looked fine on a hand-written preview page. 73 - var made = []; 74 - var panels = content.querySelectorAll('.f-accordion-panel'); 75 - 76 - var eligible = []; 77 - for (var p = 0; p < panels.length; p++) { 78 - var first = panels[p].firstElementChild; 79 - if (first && /^H[1-4]$/.test(first.tagName)) { 80 - eligible.push({ panel: panels[p], heading: first }); 81 - } 49 + // Only top-level headings. An h2 nested inside a table or a macro box is 50 + // part of that structure and must not be torn out of it. 51 + var headings = []; 52 + for (var i = 0; i < content.children.length; i++) { 53 + if (content.children[i].tagName === 'H2') { headings.push(content.children[i]); } 82 82 } 55 + if (headings.length < MIN_SECTIONS) { return; } 83 83 84 - if (eligible.length >= MIN_SECTIONS) { 85 - eligible.forEach(function (item, index) { 86 - var panel = item.panel; 87 - var heading = item.heading; 57 + var made = []; 58 + headings.forEach(function (h2, index) { 59 + var details = document.createElement('details'); 60 + details.className = 'alder-sec'; 61 + if (index === 0) { details.open = true; } 88 88 89 - var details = document.createElement('details'); 90 - details.className = 'alder-sec'; 91 - if (index === 0) { details.open = true; } 92 - if (heading.id) { details.id = heading.id; heading.removeAttribute('id'); } 63 + var summary = document.createElement('summary'); 64 + var title = document.createElement('span'); 65 + title.className = 'alder-sec-title'; 66 + title.textContent = (h2.textContent || '').trim(); 67 + summary.appendChild(title); 68 + summary.appendChild(chevron()); 69 + details.appendChild(summary); 93 93 94 - var summary = document.createElement('summary'); 95 - var title = document.createElement('span'); 96 - title.className = 'alder-sec-title'; 97 - title.textContent = (heading.textContent || '').trim(); 98 - summary.appendChild(title); 99 - summary.appendChild(chevron()); 100 - details.appendChild(summary); 71 + var wrap = document.createElement('div'); 72 + wrap.className = 'alder-sec-body'; 73 + details.appendChild(wrap); 101 101 102 - // The heading is now the summary, so it must not also appear inside. 103 - panel.removeChild(heading); 75 + // Keep the heading's id on the details element so existing anchors and 76 + // the table-of-contents macro still resolve to something. 77 + if (h2.id) { details.id = h2.id; h2.removeAttribute('id'); } 104 104 105 - var wrap = document.createElement('div'); 106 - wrap.className = 'alder-sec-body'; 107 - while (panel.firstChild) { wrap.appendChild(panel.firstChild); } 108 - details.appendChild(wrap); 79 + content.insertBefore(details, h2); 109 109 110 - // Keep the panel as the outer element: it carries XWiki's own 111 - // data-controller, and removing it could break behaviour we did not 112 - // write and cannot see. 113 - panel.appendChild(details); 114 - made.push(details); 115 - }); 116 - } else { 117 - // Fallback for content without those panels -- hand-written wiki markup, 118 - // and any XWiki version that renders sections differently. 119 - var found = content.querySelectorAll('h2'); 120 - if (found.length < MIN_SECTIONS) { return; } 121 - 122 - var byParent = []; 123 - for (var f = 0; f < found.length; f++) { 124 - var parent = found[f].parentNode; 125 - var slot = null; 126 - for (var b = 0; b < byParent.length; b++) { 127 - if (byParent[b].parent === parent) { slot = byParent[b]; break; } 128 - } 129 - if (!slot) { slot = { parent: parent, items: [] }; byParent.push(slot); } 130 - slot.items.push(found[f]); 81 + // Move the heading and everything up to the next h2 into the body. 82 + var node = h2; 83 + while (node && !(node !== h2 && node.tagName === 'H2')) { 84 + var next = node.nextSibling; 85 + wrap.appendChild(node); 86 + node = next; 87 + if (node && node.nodeType === 1 && node.tagName === 'H2') { break; } 131 131 } 132 - byParent.sort(function (a, b) { return b.items.length - a.items.length; }); 89 + made.push(details); 90 + }); 133 133 134 - var container = byParent[0].parent; 135 - var headings = byParent[0].items; 136 - if (headings.length < MIN_SECTIONS) { return; } 137 - 138 - headings.forEach(function (h2, index) { 139 - var details = document.createElement('details'); 140 - details.className = 'alder-sec'; 141 - if (index === 0) { details.open = true; } 142 - 143 - var summary = document.createElement('summary'); 144 - var title = document.createElement('span'); 145 - title.className = 'alder-sec-title'; 146 - title.textContent = (h2.textContent || '').trim(); 147 - summary.appendChild(title); 148 - summary.appendChild(chevron()); 149 - details.appendChild(summary); 150 - 151 - var wrap = document.createElement('div'); 152 - wrap.className = 'alder-sec-body'; 153 - details.appendChild(wrap); 154 - 155 - if (h2.id) { details.id = h2.id; h2.removeAttribute('id'); } 156 - container.insertBefore(details, h2); 157 - 158 - var node = h2; 159 - while (node && !(node !== h2 && node.tagName === 'H2')) { 160 - var next = node.nextSibling; 161 - wrap.appendChild(node); 162 - node = next; 163 - if (node && node.nodeType === 1 && node.tagName === 'H2') { break; } 164 - } 165 - made.push(details); 166 - }); 167 - } 168 - 169 169 if (!made.length) { return; } 170 170 171 171 var tools = document.createElement('div'); ... ... @@ -172,7 +172,7 @@ 172 172 tools.className = 'alder-tools'; 173 173 tools.appendChild(button('Expand all', true, made)); 174 174 tools.appendChild(button('Collapse all', false, made)); 175 - made[0].parentNode.insertBefore(tools, made[0]);98 + content.insertBefore(tools, made[0]); 176 176 177 177 openFromHash(); 178 178 window.addEventListener('hashchange', openFromHash); - Name
-
... ... @@ -1,1 +1,1 @@ 1 -Article accordion 1 +Alder article accordion - Use this extension
-
... ... @@ -1,1 +1,1 @@ 1 -a lways1 +onDemand