|
34 | 34 | }); |
35 | 35 | } |
36 | 36 |
|
37 | | - // Each box on the page has its own collection of URL targets so its |
38 | | - // contents update in place when the region changes. |
| 37 | + // All URL occurrences across the page content (text nodes + relevant |
| 38 | + // attributes). Boxes are separate — each holds its selector buttons so |
| 39 | + // every box on the page stays visually in sync on region change. |
| 40 | + const targets = []; |
39 | 41 | const boxes = []; |
40 | 42 |
|
41 | 43 | function collectTargets(root) { |
42 | | - const targets = []; |
43 | 44 | const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, { |
44 | 45 | acceptNode: function (node) { |
45 | 46 | if (!node.nodeValue || !DETECT_PATTERN.test(node.nodeValue)) { |
|
66 | 67 | } |
67 | 68 | }); |
68 | 69 | }); |
69 | | - return targets; |
70 | 70 | } |
71 | 71 |
|
72 | | - function applyToBox(box, regionKey) { |
73 | | - for (let i = 0; i < box.targets.length; i++) { |
74 | | - const t = box.targets[i]; |
| 72 | + function applyRegion(regionKey) { |
| 73 | + for (let i = 0; i < targets.length; i++) { |
| 74 | + const t = targets[i]; |
75 | 75 | const next = rewrite(t.original, regionKey); |
76 | 76 | if (t.kind === "text") { |
77 | 77 | if (t.node.nodeValue !== next) t.node.nodeValue = next; |
78 | 78 | } else { |
79 | 79 | if (t.node.getAttribute(t.attr) !== next) t.node.setAttribute(t.attr, next); |
80 | 80 | } |
81 | 81 | } |
82 | | - updateBoxButtons(box, regionKey); |
83 | | - } |
84 | | - |
85 | | - function updateBoxButtons(box, regionKey) { |
86 | | - box.buttons.forEach(function (btn) { |
87 | | - const isActive = btn.getAttribute("data-region") === regionKey; |
88 | | - btn.classList.toggle("is-active", isActive); |
89 | | - btn.setAttribute("aria-checked", String(isActive)); |
90 | | - }); |
| 82 | + for (let j = 0; j < boxes.length; j++) { |
| 83 | + const buttons = boxes[j].buttons; |
| 84 | + for (let k = 0; k < buttons.length; k++) { |
| 85 | + const btn = buttons[k]; |
| 86 | + const active = btn.getAttribute("data-region") === regionKey; |
| 87 | + btn.classList.toggle("is-active", active); |
| 88 | + btn.setAttribute("aria-checked", String(active)); |
| 89 | + } |
| 90 | + } |
91 | 91 | } |
92 | 92 |
|
93 | 93 | function syncAll(regionKey) { |
94 | 94 | saveRegion(regionKey); |
95 | | - boxes.forEach(function (box) { |
96 | | - applyToBox(box, regionKey); |
97 | | - }); |
| 95 | + applyRegion(regionKey); |
98 | 96 | } |
99 | 97 |
|
100 | 98 | function buildBar(currentRegion) { |
|
103 | 101 |
|
104 | 102 | const label = document.createElement("span"); |
105 | 103 | label.className = "robusta-region-box__bar-label"; |
106 | | - label.textContent = "Region"; |
| 104 | + label.textContent = "Select Region"; |
107 | 105 | bar.appendChild(label); |
108 | 106 |
|
109 | 107 | const group = document.createElement("div"); |
|
133 | 131 | return { bar: bar, buttons: buttons }; |
134 | 132 | } |
135 | 133 |
|
136 | | - function initBox(el, currentRegion) { |
137 | | - const existingBar = el.querySelector(":scope > ." + BAR_CLASS); |
138 | | - if (existingBar) existingBar.remove(); |
139 | | - |
140 | | - const built = buildBar(currentRegion); |
141 | | - el.insertBefore(built.bar, el.firstChild); |
142 | | - |
143 | | - const targetRoot = el.querySelector(".robusta-region-box__body") || el; |
144 | | - const targets = collectTargets(targetRoot); |
145 | | - |
146 | | - const box = { |
147 | | - el: el, |
148 | | - bar: built.bar, |
149 | | - buttons: built.buttons, |
150 | | - targets: targets, |
151 | | - }; |
152 | | - boxes.push(box); |
153 | | - applyToBox(box, currentRegion); |
154 | | - } |
155 | | - |
156 | 134 | function init() { |
| 135 | + targets.length = 0; |
157 | 136 | boxes.length = 0; |
| 137 | + |
158 | 138 | const content = |
159 | 139 | document.querySelector(".md-content__inner") || |
160 | 140 | document.querySelector("article") || |
|
163 | 143 | if (!content) return; |
164 | 144 |
|
165 | 145 | const region = getRegion(); |
166 | | - const elements = content.querySelectorAll(".robusta-region-box"); |
167 | | - elements.forEach(function (el) { |
168 | | - initBox(el, region); |
| 146 | + |
| 147 | + content.querySelectorAll(".robusta-region-box").forEach(function (el) { |
| 148 | + const existingBar = el.querySelector(":scope > ." + BAR_CLASS); |
| 149 | + if (existingBar) existingBar.remove(); |
| 150 | + const built = buildBar(region); |
| 151 | + el.insertBefore(built.bar, el.firstChild); |
| 152 | + boxes.push({ buttons: built.buttons }); |
169 | 153 | }); |
| 154 | + |
| 155 | + collectTargets(content); |
| 156 | + |
| 157 | + if (targets.length === 0 && boxes.length === 0) return; |
| 158 | + |
| 159 | + applyRegion(region); |
170 | 160 | } |
171 | 161 |
|
172 | 162 | if (document.readyState === "loading") { |
|
0 commit comments