spec-up-t 1.6.3-beta.1 → 1.6.3

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.
Files changed (33) hide show
  1. package/.github/copilot-instructions.md +2 -0
  2. package/assets/compiled/body.js +9 -7
  3. package/assets/compiled/head.css +6 -6
  4. package/assets/css/adjust-font-size.css +0 -4
  5. package/assets/css/download-pdf-docx.css +19 -20
  6. package/assets/css/header-navbar.css +0 -4
  7. package/assets/css/index.css +36 -0
  8. package/assets/css/terms-and-definitions.css +0 -1
  9. package/assets/css/validate-external-refs.css +198 -3
  10. package/assets/js/add-href-to-snapshot-link.js +11 -5
  11. package/assets/js/download-pdf-docx.js +20 -9
  12. package/assets/js/edit-term-buttons.js +71 -68
  13. package/assets/js/github-issues.js +27 -27
  14. package/assets/js/insert-irefs.js +1 -1
  15. package/assets/js/validate-external-refs.js +356 -7
  16. package/package.json +3 -3
  17. package/src/add-remove-xref-source.js +0 -5
  18. package/src/collect-external-references.test.js +98 -0
  19. package/src/install-from-boilerplate/boilerplate/gitignore +2 -2
  20. package/src/install-from-boilerplate/boilerplate/menu-wrapper.sh +19 -0
  21. package/src/install-from-boilerplate/boilerplate/specs.json +3 -6
  22. package/src/install-from-boilerplate/config-scripts-keys.js +1 -1
  23. package/src/install-from-boilerplate/config-system-files.js +1 -0
  24. package/src/pipeline/references/collect-external-references.js +12 -0
  25. package/src/pipeline/references/external-references-service.js +1 -1
  26. package/src/pipeline/rendering/render-spec-document.js +5 -1
  27. package/templates/template.html +43 -10
  28. package/src/health-check/destination-gitignore-checker.js +0 -414
  29. package/src/health-check/external-specs-checker.js +0 -287
  30. package/src/health-check/specs-configuration-checker.js +0 -387
  31. package/src/health-check/term-references-checker.js +0 -270
  32. package/src/health-check/terms-intro-checker.js +0 -82
  33. package/src/health-check/tref-term-checker.js +0 -549
@@ -453,7 +453,6 @@ a.iref-go-to-glossary-button {
453
453
  white-space: nowrap;
454
454
  text-decoration: none;
455
455
  position: relative;
456
- padding-left: 1.5rem;
457
456
  }
458
457
 
459
458
  a.iref-go-to-glossary-button:hover {
@@ -171,10 +171,9 @@
171
171
  }
172
172
 
173
173
  /**
174
- * Show details on hover
174
+ * Show details on click (when the active class is applied via JavaScript)
175
175
  */
176
- .external-ref-validation-indicator.has-details:hover .validation-details,
177
- .external-ref-validation-indicator.has-details:focus .validation-details {
176
+ .external-ref-validation-indicator.has-details.active .validation-details {
178
177
  display: block;
179
178
  }
180
179
 
@@ -367,3 +366,199 @@ a.x-term-reference + .external-ref-validation-indicator {
367
366
  font-size: 0.7em;
368
367
  }
369
368
  }
369
+
370
+ /* ===== External Reference Changes Report ===== */
371
+
372
+ /**
373
+ * Container for the changes report in the settings panel
374
+ */
375
+ .external-ref-changes-report {
376
+ max-height: 300px;
377
+ overflow-y: auto;
378
+ border: 1px solid var(--bs-border-color, #dee2e6);
379
+ border-radius: 6px;
380
+ background: var(--bs-body-bg, #fff);
381
+ }
382
+
383
+ /**
384
+ * Table styling for the changes report
385
+ */
386
+ .external-ref-changes-table {
387
+ margin-bottom: 0;
388
+ font-size: 0.8rem;
389
+ }
390
+
391
+ .external-ref-changes-table th {
392
+ position: sticky;
393
+ top: 0;
394
+ background: var(--bs-secondary-bg, #e9ecef);
395
+ border-bottom: 2px solid var(--bs-border-color, #dee2e6);
396
+ font-weight: 600;
397
+ font-size: 0.7rem;
398
+ text-transform: uppercase;
399
+ letter-spacing: 0.5px;
400
+ padding: 0.5rem 0.4rem;
401
+ }
402
+
403
+ .external-ref-changes-table td {
404
+ padding: 0.4rem;
405
+ vertical-align: middle;
406
+ }
407
+
408
+ /**
409
+ * Column widths
410
+ */
411
+ .external-ref-changes-table .col-status {
412
+ width: 40px;
413
+ text-align: center;
414
+ }
415
+
416
+ .external-ref-changes-table .col-term {
417
+ min-width: 80px;
418
+ max-width: 120px;
419
+ }
420
+
421
+ .external-ref-changes-table .col-spec {
422
+ min-width: 60px;
423
+ max-width: 100px;
424
+ }
425
+
426
+ .external-ref-changes-table .col-similarity {
427
+ width: 50px;
428
+ text-align: center;
429
+ }
430
+
431
+ .external-ref-changes-table .col-action {
432
+ width: 40px;
433
+ text-align: center;
434
+ }
435
+
436
+ /**
437
+ * Status icons in the table
438
+ */
439
+ .status-icon {
440
+ display: inline-flex;
441
+ align-items: center;
442
+ justify-content: center;
443
+ width: 1.5em;
444
+ height: 1.5em;
445
+ font-size: 1rem;
446
+ }
447
+
448
+ /**
449
+ * Term name styling
450
+ */
451
+ .term-name {
452
+ display: block;
453
+ font-weight: 500;
454
+ word-break: break-word;
455
+ overflow: hidden;
456
+ text-overflow: ellipsis;
457
+ }
458
+
459
+ /**
460
+ * Spec badge styling
461
+ */
462
+ .spec-badge {
463
+ display: inline-block;
464
+ padding: 0.15em 0.4em;
465
+ font-size: 0.7rem;
466
+ background: var(--bs-secondary-bg, #e9ecef);
467
+ border-radius: 4px;
468
+ word-break: break-word;
469
+ }
470
+
471
+ /**
472
+ * Similarity value styling
473
+ */
474
+ .similarity-value {
475
+ font-size: 0.75rem;
476
+ font-weight: 500;
477
+ color: var(--bs-warning, #ffc107);
478
+ }
479
+
480
+ .similarity-na {
481
+ color: var(--bs-secondary, #6c757d);
482
+ font-size: 0.8rem;
483
+ }
484
+
485
+ /**
486
+ * Go to reference button
487
+ */
488
+ .go-to-ref-btn {
489
+ padding: 0.15rem 0.35rem;
490
+ font-size: 0.75rem;
491
+ line-height: 1;
492
+ }
493
+
494
+ /**
495
+ * Row highlighting based on status
496
+ */
497
+ .external-ref-changes-table tr.result-changed {
498
+ background-color: rgba(255, 193, 7, 0.08);
499
+ }
500
+
501
+ .external-ref-changes-table tr.result-missing {
502
+ background-color: rgba(220, 53, 69, 0.08);
503
+ }
504
+
505
+ .external-ref-changes-table tr.result-error {
506
+ background-color: rgba(108, 117, 125, 0.08);
507
+ }
508
+
509
+ .external-ref-changes-table tr:hover {
510
+ background-color: rgba(0, 0, 0, 0.05);
511
+ }
512
+
513
+ /**
514
+ * Highlight animation when scrolling to a reference
515
+ */
516
+ @keyframes highlight-flash {
517
+ 0%, 100% {
518
+ background-color: transparent;
519
+ }
520
+ 50% {
521
+ background-color: rgba(255, 193, 7, 0.3);
522
+ }
523
+ }
524
+
525
+ .highlight-ref {
526
+ animation: highlight-flash 0.5s ease-in-out 3;
527
+ outline: 2px solid var(--bs-warning, #ffc107);
528
+ outline-offset: 2px;
529
+ border-radius: 4px;
530
+ }
531
+
532
+ /* ===== Dark Mode Support for Report ===== */
533
+
534
+ [data-bs-theme="dark"] .external-ref-changes-report {
535
+ border-color: var(--bs-gray-700, #495057);
536
+ }
537
+
538
+ [data-bs-theme="dark"] .external-ref-changes-table th {
539
+ background: var(--bs-gray-800, #343a40);
540
+ }
541
+
542
+ [data-bs-theme="dark"] .spec-badge {
543
+ background: var(--bs-gray-700, #495057);
544
+ }
545
+
546
+ [data-bs-theme="dark"] .external-ref-changes-table tr:hover {
547
+ background-color: rgba(255, 255, 255, 0.05);
548
+ }
549
+
550
+ [data-bs-theme="dark"] .external-ref-changes-table tr.result-changed {
551
+ background-color: rgba(255, 193, 7, 0.15);
552
+ }
553
+
554
+ [data-bs-theme="dark"] .external-ref-changes-table tr.result-missing {
555
+ background-color: rgba(220, 53, 69, 0.15);
556
+ }
557
+
558
+ [data-bs-theme="dark"] .external-ref-changes-table tr.result-error {
559
+ background-color: rgba(108, 117, 125, 0.15);
560
+ }
561
+
562
+ [data-bs-theme="dark"] .highlight-ref {
563
+ background-color: rgba(255, 193, 7, 0.4);
564
+ }
@@ -9,11 +9,17 @@
9
9
  function addHrefToSnapshotLink() {
10
10
  const snapshotLink = document.querySelector('#snapshot-link-in-content');
11
11
 
12
- // Get the current URL of the page
13
- const currentUrl = window.location.href;
14
-
15
- // Remove query parameters and hash for URL processing
16
- const urlWithoutParams = currentUrl.split('?')[0].split('#')[0];
12
+ // Get the current URL of the page using URL object for proper parsing
13
+ let urlWithoutParams;
14
+ try {
15
+ const url = new URL(window.location.href);
16
+ // Get pathname and origin, ignoring query parameters and hash
17
+ urlWithoutParams = url.origin + url.pathname;
18
+ } catch (e) {
19
+ // Fallback to string manipulation if URL parsing fails
20
+ const currentUrl = window.location.href;
21
+ urlWithoutParams = currentUrl.split('?')[0].split('#')[0];
22
+ }
17
23
 
18
24
  // Regex to match up to and including the 'versions/' directory (if it exists)
19
25
  // Updated to handle file:// URLs and various protocols
@@ -14,20 +14,31 @@
14
14
  .then((r) => r.ok)
15
15
  .catch(() => false);
16
16
 
17
- const fileIconSvg =
18
- '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" class="me-1" viewBox="0 0 16 16">\
19
- <path d="M4 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.5L9.5 0H4zm0 1h5v4h4v9a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zm7 4h-1V2l3 3h-2z"/>\
17
+ // PDF icon with recognizable red color
18
+ const pdfIconSvg =
19
+ '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" class="me-1">\
20
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z" fill="#e74c3c"/>\
21
+ <path d="M14 2v6h6" fill="none" stroke="#c0392b" stroke-width="1.5"/>\
22
+ <text x="12" y="17" font-size="6" font-weight="bold" text-anchor="middle" fill="white">PDF</text>\
20
23
  </svg>';
21
24
 
22
- function createButton(href, title, cls) {
25
+ // DOCX/Word icon with recognizable blue color
26
+ const docxIconSvg =
27
+ '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" class="me-1">\
28
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z" fill="#2b579a"/>\
29
+ <path d="M14 2v6h6" fill="none" stroke="#1e4378" stroke-width="1.5"/>\
30
+ <text x="12" y="17" font-size="5" font-weight="bold" text-anchor="middle" fill="white">DOCX</text>\
31
+ </svg>';
32
+
33
+ function createButton(href, title, cls, icon, label) {
23
34
  const a = document.createElement("a");
24
- a.classList.add(cls, "btn", "d-block", "btn-sm", "btn-outline-secondary");
35
+ a.classList.add(cls, "btn", "btn-sm");
25
36
  a.target = "_blank";
26
37
  a.rel = "noopener noreferrer";
27
38
  a.href = href;
28
39
  a.title = title;
29
40
  a.setAttribute("aria-label", title);
30
- a.innerHTML = fileIconSvg;
41
+ a.innerHTML = icon + '<span class="button-label visually-hidden">' + label + '</span>';
31
42
  return a;
32
43
  }
33
44
 
@@ -36,8 +47,8 @@
36
47
  if (!container) return;
37
48
 
38
49
  const items = [
39
- { href: "./index.pdf", title: "Download this page as a PDF", cls: "button-pdf-download" },
40
- { href: "./index.docx", title: "Download this page as a DOCX", cls: "button-docx-download" },
50
+ { href: "./index.pdf", title: "Download this page as a PDF", cls: "button-pdf-download", icon: pdfIconSvg, label: "PDF" },
51
+ { href: "./index.docx", title: "Download this page as a DOCX", cls: "button-docx-download", icon: docxIconSvg, label: "DOCX" },
41
52
  ];
42
53
 
43
54
  const exists = await Promise.all(items.map((i) => checkExists(i.href)));
@@ -47,7 +58,7 @@
47
58
  items.forEach((item, idx) => {
48
59
  if (!exists[idx]) return;
49
60
  if (buttonExists(item.cls)) return;
50
- const btn = createButton(item.href, item.title, item.cls);
61
+ const btn = createButton(item.href, item.title, item.cls, item.icon, item.label);
51
62
  container.insertBefore(btn, anchor);
52
63
  anchor = btn;
53
64
  });
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * @file This file creates links to the terms definitions on GitHub via client side JS DOM manipulation.
3
+ * Repository information (account, repo name, branch) is obtained from the meta tag
4
+ * 'spec-up-t:github-repo-info' using the getGithubRepoInfo() function.
3
5
  * @author Kor Dwarshuis
4
- * @version 0.0.1
6
+ * @version 0.0.2
5
7
  * @license MIT
6
8
  * @since 2024-06-09
7
9
  */
@@ -30,6 +32,15 @@ function editTermButtons() {
30
32
 
31
33
 
32
34
 
35
+ // Get GitHub repo info from meta tag
36
+ const repoInfo = getGithubRepoInfo();
37
+
38
+ // Early return if no repo info available
39
+ if (!repoInfo) {
40
+ console.warn('GitHub repository information not available, edit buttons will not be added');
41
+ return;
42
+ }
43
+
33
44
  document.querySelectorAll('dt.term-local').forEach(item => {
34
45
  const term = findDeepestSpan(item);
35
46
  const url = term.getAttribute('id');
@@ -37,22 +48,17 @@ function editTermButtons() {
37
48
  const localFileName = url.split(":")[1];
38
49
  const pathLocalTerms = pathJoin(specConfig.spec_directory, specConfig.spec_terms_directory, localFileName + '.md');
39
50
 
40
- // cut "url" on the ":" and keep the second part
41
-
42
- const branch = specConfig.source.branch || "main";
43
-
44
-
45
51
  // add edit and history buttons to term
46
52
  term.innerHTML += `<span class="edit-term-buttons">
47
53
  <a title="Link to the term file in the Github repo in a new tab" target="_blank" rel="noopener"
48
- href="https://github.com/${specConfig.source.account}/${specConfig.source.repo}/blob/${branch}/${pathLocalTerms}"
54
+ href="https://github.com/${repoInfo.username}/${repoInfo.repo}/blob/${repoInfo.branch}/${pathLocalTerms}"
49
55
  class="p-1 edit-term-button btn">
50
56
  <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16" style="shape-rendering: geometricPrecision;">
51
57
  <path fill-rule="evenodd" d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
52
58
  </svg>
53
59
  </a>
54
60
  <a title="Link to a GitHub page that shows a history of the edits in a new tab" target="_blank" rel="noopener"
55
- href="https://github.com/${specConfig.source.account}/${specConfig.source.repo}/commits/${branch}/${pathLocalTerms}"
61
+ href="https://github.com/${repoInfo.username}/${repoInfo.repo}/commits/${repoInfo.branch}/${pathLocalTerms}"
56
62
  class="p-1 history-term-button btn">
57
63
  <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16" style="shape-rendering: geometricPrecision;">
58
64
  <path fill-rule="evenodd" d="M8 1a7 7 0 1 0 4.95 11.95l.707.707A8.001 8.001 0 1 1 8 0v1z"/>
@@ -63,66 +69,63 @@ function editTermButtons() {
63
69
  </span>`;
64
70
  });
65
71
 
66
- // document.querySelectorAll('dt.term-external').forEach(item => {
67
- // const term = findDeepestSpan(item);
68
- // console.log("🚀 ~ editTermButtons ~ term:", term)
69
- // const url = term.getAttribute('id');
70
-
71
- // // Find the term in data-original-term attribute somewhere in a child of dt.term-external
72
- // const originalTerm = term.dataset.originalTerm || url.split(":")[1];
73
- // console.log("🚀 ~ editTermButtons ~ originalTerm:", originalTerm)
74
-
75
- // // Lookup this term in the embedded allXTrefs object
76
- // const matchingXtrefs = (allXTrefs?.xtrefs || []).filter(xref => xref.term === originalTerm);
77
- // console.log("🚀 ~ editTermButtons ~ matchingXtrefs:", matchingXtrefs)
78
-
79
- // if (matchingXtrefs.length > 0) {
80
- // // Create edit and history buttons for each matching xtref
81
- // const buttonsHtml = matchingXtrefs.map(xtref => {
82
- // // Find sourceFiles with type "tref" - these are the files that define the term
83
- // const trefFiles = xtref.sourceFiles?.filter(sf => sf.type === 'tref') || [];
84
- // console.log("🚀 ~ editTermButtons ~ trefFiles:", trefFiles)
85
-
86
- // if (trefFiles.length === 0) return '';
87
-
88
- // // Find the corresponding repoUrl, terms_dir, branch from the xref
89
- // const repoUrl = xtref.repoUrl;
90
- // const termsDir = xtref.terms_dir;
91
- // const branch = xtref.branch || "main";
92
-
93
- // // Construct the edit pencil from that info
94
- // return trefFiles.map(sf => {
95
- // const filePath = pathJoin(termsDir, sf.file);
96
- // console.log("🚀 ~ editTermButtons ~ filePath:", filePath)
97
- // const editUrl = `${repoUrl}/blob/${branch}/${filePath}`;
98
- // const historyUrl = `${repoUrl}/commits/${branch}/${filePath}`;
99
-
100
- // return `
101
- // <a title="Link to the term file '${sf.file}' in the Github repo in a new tab" target="_blank" rel="noopener"
102
- // href="${editUrl}"
103
- // class="p-1 edit-term-button btn">
104
- // <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16" style="shape-rendering: geometricPrecision;">
105
- // <path fill-rule="evenodd" d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
106
- // </svg>
107
- // </a>
108
- // <a title="Link to a GitHub page that shows a history of the edits in '${sf.file}' in a new tab" target="_blank" rel="noopener"
109
- // href="${historyUrl}"
110
- // class="p-1 history-term-button btn">
111
- // <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16" style="shape-rendering: geometricPrecision;">
112
- // <path fill-rule="evenodd" d="M8 1a7 7 0 1 0 4.95 11.95l.707.707A8.001 8.001 0 1 1 8 0v1z"/>
113
- // <path fill-rule="evenodd" d="M7.5 3a.5.5 0 0 1 .5.5v5.21l3.248 1.856a.5.5 0 0 1-.496.868l-3.5-2A.5.5 0 0 1 7 9V3.5a.5.5 0 0 1 .5-.5z"/>
114
- // <circle cx="8" cy="8" r="0.3"/>
115
- // </svg>
116
- // </a>
117
- // `;
118
- // }).join('');
119
- // }).join('');
120
-
121
- // if (buttonsHtml) {
122
- // term.innerHTML += `<span class="edit-term-buttons">${buttonsHtml}</span>`;
123
- // }
124
- // }
125
- // });
72
+ // Process external terms (trefs)
73
+ // External terms are those referenced from external specs via [[tref: spec, term]]
74
+ // The pencil button should point to the LOCAL markdown file where the tref is written
75
+ document.querySelectorAll('dt.term-external').forEach(item => {
76
+ const term = findDeepestSpan(item);
77
+ const url = term.getAttribute('id');
78
+
79
+ // Find the term in data-original-term attribute
80
+ // This attribute contains the original term name from the tref
81
+ const originalTerm = term.dataset.originalTerm || url.split(":")[2];
82
+
83
+ // Lookup this term in the embedded allXTrefs object
84
+ // Match by term name - could match multiple specs
85
+ const matchingXtrefs = (allXTrefs?.xtrefs || []).filter(xref => xref.term === originalTerm);
86
+
87
+ if (matchingXtrefs.length > 0) {
88
+ // Create edit and history buttons for each matching xtref
89
+ // Multiple buttons may appear if the term is referenced in multiple files
90
+ const buttonsHtml = matchingXtrefs.map(xtref => {
91
+ // Find sourceFiles with type "tref" - these are the local files that reference this external term
92
+ const trefFiles = xtref.sourceFiles?.filter(sf => sf.type === 'tref') || [];
93
+
94
+ if (trefFiles.length === 0) return '';
95
+
96
+ // Create buttons for each local tref file that references this external term
97
+ return trefFiles.map(sf => {
98
+ // Build path to the local markdown file where the tref is written
99
+ const filePath = pathJoin(specConfig.spec_directory, specConfig.spec_terms_directory, sf.file);
100
+ const editUrl = `https://github.com/${repoInfo.username}/${repoInfo.repo}/blob/${repoInfo.branch}/${filePath}`;
101
+ const historyUrl = `https://github.com/${repoInfo.username}/${repoInfo.repo}/commits/${repoInfo.branch}/${filePath}`;
102
+
103
+ return `
104
+ <a title="Link to the term file in the Github repo in a new tab" target="_blank" rel="noopener"
105
+ href="${editUrl}"
106
+ class="p-1 edit-term-button btn">
107
+ <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16" style="shape-rendering: geometricPrecision;">
108
+ <path fill-rule="evenodd" d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
109
+ </svg>
110
+ </a>
111
+ <a title="Link to a GitHub page that shows a history of the edits in a new tab" target="_blank" rel="noopener"
112
+ href="${historyUrl}"
113
+ class="p-1 history-term-button btn">
114
+ <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16" style="shape-rendering: geometricPrecision;">
115
+ <path fill-rule="evenodd" d="M8 1a7 7 0 1 0 4.95 11.95l.707.707A8.001 8.001 0 1 1 8 0v1z"/>
116
+ <path fill-rule="evenodd" d="M7.5 3a.5.5 0 0 1 .5.5v5.21l3.248 1.856a.5.5 0 0 1-.496.868l-3.5-2A.5.5 0 0 1 7 9V3.5a.5.5 0 0 1 .5-.5z"/>
117
+ <circle cx="8" cy="8" r="0.3"/>
118
+ </svg>
119
+ </a>
120
+ `;
121
+ }).join('');
122
+ }).join('');
123
+
124
+ if (buttonsHtml) {
125
+ term.innerHTML += `<span class="edit-term-buttons">${buttonsHtml}</span>`;
126
+ }
127
+ }
128
+ });
126
129
  }
127
130
 
128
131
  document.addEventListener("DOMContentLoaded", function () {
@@ -3,33 +3,33 @@
3
3
 
4
4
  /* GitHub Issues */
5
5
 
6
- let source = specConfig.source;
7
- if (source) {
8
- if (source.host === 'github') {
9
- fetch(`https://api.github.com/repos/${source.account + '/' + source.repo}/issues`)
10
- .then(response => response.json())
11
- .then(issues => {
12
- let count = issues.length;
13
- document.querySelectorAll('[data-issue-count]').forEach(node => {
14
- node.setAttribute('data-issue-count', count)
15
- });
16
- repo_issue_list.innerHTML = issues.map(issue => {
17
- return `<li class="repo-issue">
18
- <detail-box>
19
- <div>${md.render(issue.body || '')}</div>
20
- <header class="repo-issue-title">
21
- <span class="repo-issue-number">${issue.number}</span>
22
- <span class="repo-issue-link">
23
- <a href="${issue.html_url}" target="_blank">${issue.title}</a>
24
- </span>
25
- <span detail-box-toggle></span>
26
- </header>
27
- </detail-box>
28
- </li>`
29
- }).join('');
30
- Prism.highlightAllUnder(repo_issue_list);
31
- })
32
- }
6
+ // Get GitHub repo info from meta tag
7
+ const repoInfo = getGithubRepoInfo();
8
+
9
+ if (repoInfo) {
10
+ fetch(`https://api.github.com/repos/${repoInfo.username}/${repoInfo.repo}/issues`)
11
+ .then(response => response.json())
12
+ .then(issues => {
13
+ let count = issues.length;
14
+ document.querySelectorAll('[data-issue-count]').forEach(node => {
15
+ node.setAttribute('data-issue-count', count)
16
+ });
17
+ repo_issue_list.innerHTML = issues.map(issue => {
18
+ return `<li class="repo-issue">
19
+ <detail-box>
20
+ <div>${md.render(issue.body || '')}</div>
21
+ <header class="repo-issue-title">
22
+ <span class="repo-issue-number">${issue.number}</span>
23
+ <span class="repo-issue-link">
24
+ <a href="${issue.html_url}" target="_blank">${issue.title}</a>
25
+ </span>
26
+ <span detail-box-toggle></span>
27
+ </header>
28
+ </detail-box>
29
+ </li>`
30
+ }).join('');
31
+ Prism.highlightAllUnder(repo_issue_list);
32
+ })
33
33
  }
34
34
 
35
35
  })();
@@ -131,7 +131,7 @@ function insertIrefs() {
131
131
  const glossaryLink = document.createElement('a');
132
132
  glossaryLink.href = `#${termIdAttr}`;
133
133
  glossaryLink.className = 'iref-go-to-glossary-button btn btn-sm btn-outline-secondary py-1';
134
- glossaryLink.innerHTML = '<span class="iref-button-icon"></span>Glossary';
134
+ glossaryLink.innerHTML = 'Glossary';
135
135
  glossaryLink.title = `Go to original definition of ${originalTerm}`;
136
136
 
137
137
  // Append the button to the cloned dt