@healthcatalyst/catalyst-docfx-template 1.0.158 → 1.0.161

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@healthcatalyst/catalyst-docfx-template",
3
- "version": "1.0.158",
3
+ "version": "1.0.161",
4
4
  "license": "MIT",
5
5
  "description": "A DocFX Template patching the Default template.",
6
6
  "publishConfig": {
package/styles/main.js CHANGED
@@ -154,66 +154,131 @@ copyCode.on('success', function(event) {
154
154
  }, 2000);
155
155
  });
156
156
 
157
+ // Helper function to replace tokens in text nodes only (preserves DOM and event listeners)
158
+ function replaceTokensInNode(node, replacements) {
159
+ if (node.nodeType === Node.TEXT_NODE) {
160
+ let text = node.textContent;
161
+ for (let [key, value] of Object.entries(replacements)) {
162
+ let token = "{{ " + key + " }}";
163
+ if (text.includes(token)) {
164
+ text = text.replaceAll(token, value);
165
+ }
166
+ }
167
+ if (text !== node.textContent) {
168
+ node.textContent = text;
169
+ }
170
+ } else {
171
+ for (let child of node.childNodes) {
172
+ replaceTokensInNode(child, replacements);
173
+ }
174
+ }
175
+ }
176
+
177
+ function getSiteRootPath() {
178
+ var pathSegments = window.location.pathname.split('/').filter(Boolean);
179
+ return pathSegments.length ? '/' + pathSegments[0] + '/' : '/';
180
+ }
181
+
157
182
  // Replace {{ keys }} with plain-text values in sourcedContent/terms.json at directory root
158
183
 
159
- /*var terms = (function () {
184
+ var terms = (function () {
160
185
  var json = null;
161
- var pathname = window.location.pathname;
162
- // console.log(pathname);
186
+ var termsPath = getSiteRootPath() + "sourcedContent/terms.json";
163
187
  $.ajax({
164
- async: false,
188
+ async: true,
165
189
  global: false,
166
- url: pathname + "/sourcedContent/terms.json",
190
+ url: termsPath,
167
191
  dataType: "json",
168
192
  success: function (data) {
169
193
  json = data;
194
+
195
+ // Replace tokens after data loads
196
+ if (json) {
197
+ replaceTokensInNode(document.body, json);
198
+ }
199
+ },
200
+ error: function(xhr, status, error) {
201
+ console.error('❌ TERMS LOAD FAILED: Could not fetch ' + termsPath);
202
+ console.error('Status:', status, '| Error:', error);
203
+ console.error('Token replacement will NOT occur. Check terms.json path and CORS.');
204
+ document.body.setAttribute('data-terms-load-failed', 'true');
170
205
  }
171
206
  });
172
-
173
- for (let [key, value] of Object.entries(json)) {
174
- // console.log(`${key}: ${value}`);
175
- var toReplace = "{{ " + key + " }}";
176
- var replaceWith = value;
177
- document.body.innerHTML = document.body.innerHTML.replace(
178
- toReplace,
179
- replaceWith
180
- );
181
- }
182
207
  return terms;
183
- })();*/
208
+ })();
184
209
 
185
210
  // Replace {{ keys }} with icon and message banner from sourcedContent/messages.json at directory root
186
211
 
187
212
  var messages = (function () {
188
213
  var json = null;
189
- var pathname = window.location.pathname;
190
- // console.log(pathname)
214
+ var messagesPath = getSiteRootPath() + "sourcedContent/messages.json";
215
+
191
216
  $.ajax({
192
- async: false,
217
+ async: true,
193
218
  global: false,
194
- url: pathname + "/sourcedContent/messages.json",
219
+ url: messagesPath,
195
220
  dataType: "json",
196
221
  success: function (data) {
197
222
  json = data;
223
+
224
+ if (json) {
225
+ // Create a TreeWalker to find text nodes with message tokens
226
+ var walker = document.createTreeWalker(
227
+ document.body,
228
+ NodeFilter.SHOW_TEXT,
229
+ null,
230
+ false
231
+ );
232
+
233
+ var nodesToReplace = [];
234
+ var node;
235
+
236
+ // Find all text nodes containing message tokens
237
+ while (node = walker.nextNode()) {
238
+ for (var k in json) {
239
+ var token = "{{ " + k + " }}";
240
+ if (node.textContent.includes(token)) {
241
+ nodesToReplace.push({ node: node, key: k, token: token });
242
+ }
243
+ }
244
+ }
245
+
246
+ // Replace tokens with message elements (safe DOM manipulation)
247
+ nodesToReplace.forEach(function(item) {
248
+ var o = json[item.key];
249
+ var parts = item.node.textContent.split(item.token);
250
+
251
+ // Create message element safely
252
+ var messageP = document.createElement('p');
253
+ messageP.className = 'message';
254
+
255
+ var icon = document.createElement('i');
256
+ icon.className = 'fa ' + o.icon; // CSS classes are safe
257
+
258
+ var messageText = document.createTextNode(o.message); // Text is safe
259
+
260
+ messageP.appendChild(icon);
261
+ messageP.appendChild(messageText);
262
+
263
+ // Replace the text node with: textBefore + messageElement + textAfter
264
+ var parent = item.node.parentNode;
265
+
266
+ if (parts[0]) {
267
+ parent.insertBefore(document.createTextNode(parts[0]), item.node);
268
+ }
269
+ parent.insertBefore(messageP, item.node);
270
+ if (parts[1]) {
271
+ parent.insertBefore(document.createTextNode(parts[1]), item.node);
272
+ }
273
+ parent.removeChild(item.node);
274
+ });
275
+ }
198
276
  },
277
+ error: function(xhr, status, error) {
278
+ console.error('❌ MESSAGES LOAD FAILED: Could not fetch ' + messagesPath);
279
+ console.error('Status:', status, '| Error:', error);
280
+ document.body.setAttribute('data-messages-load-failed', 'true');
281
+ }
199
282
  });
200
- for (var k in json) {
201
- var o = json[k];
202
- // console.log(o.message);
203
- // console.log(o.icon);
204
- var toReplace = "{{ " + k + " }}";
205
- var replaceWith =
206
- '<p class="message">' +
207
- '<i class="fa ' +
208
- o.icon +
209
- '"></i>' +
210
- o.message +
211
- "</p>";
212
- document.body.innerHTML = document.body.innerHTML.replace(
213
- toReplace,
214
- replaceWith
215
- );
216
- }
217
283
  return messages;
218
- })();
219
-
284
+ })();