@xiee/utils 1.12.1 → 1.12.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.
package/css/default.css CHANGED
@@ -47,8 +47,10 @@ hr, .footnotes::before { border: 1px dashed #ddd; }
47
47
  #TOC .numbered ul { padding-left: 1em; }
48
48
  table, .body h2 { border-bottom: 1px solid #666; }
49
49
  .body .appendix, .appendix ~ h2 { border-bottom-style: dashed; }
50
+ .main-number::after { content: "."; }
50
51
  .footnote-ref a::before { content: "["; }
51
52
  .footnote-ref a::after { content: "]"; }
53
+ section.footnotes { margin-top: 2em; }
52
54
  section.footnotes::before { content: ""; display: block; max-width: 20em; }
53
55
 
54
56
  @media print {
@@ -1 +1 @@
1
- body{font-family:sans-serif;max-width:800px;margin:auto;padding:1em;line-height:1.5;box-sizing:border-box}.footnotes,body,code{font-size:.9em}li li{font-size:.95em}*,:after,:before{box-sizing:inherit}img,pre{max-width:100%}pre,pre:hover{white-space:pre-wrap;word-break:break-all}pre code{display:block;overflow-x:auto}code{font-family:'DejaVu Sans Mono','Droid Sans Mono','Lucida Console',Consolas,Monaco,monospace}.box>div,:not(pre)>code,code[class]{background-color:#f8f8f8}.box,pre>.language-plain,pre>code:not([class]){background-color:inherit;border:1px solid #eee}pre>.message{border-color:#9eeaf9}pre>.warning{background:#fff3cd;border-color:#fff3cd}pre>.error{background:#f8d7da;border-color:#f8d7da}.fenced-chunk{border-left:1px solid #666}.code-fence{opacity:.4;border:1px dashed #666;border-left:2px solid}.code-fence:hover{opacity:inherit}.box{margin:1em 0}.box>:first-child>p:first-child,.box>:last-child>p:last-child{padding:1em}.box>:first-child,.box>:first-child>p:first-child{margin-top:0}.box>:last-child,.box>:last-child>p:last-child{margin-bottom:0}.figure>p{text-align:center}table{margin:auto;border-top:1px solid #666}table thead th{border-bottom:1px solid #ddd}td,th{padding:5px}tfoot,thead,tr:nth-child(2n){background:#eee}blockquote{color:#666;margin:0;padding-left:1em;border-left:.5em solid #eee}.footnotes::before,hr{border:1px dashed #ddd}.frontmatter{text-align:center}#TOC .numbered li{list-style:none}#TOC .numbered{padding-left:0}#TOC .numbered ul{padding-left:1em}.body h2,table{border-bottom:1px solid #666}.appendix~h2,.body .appendix{border-bottom-style:dashed}.footnote-ref a::before{content:"["}.footnote-ref a::after{content:"]"}section.footnotes::before{content:"";display:block;max-width:20em}@media print{body{font-size:12pt;max-width:100%}img,tr{page-break-inside:avoid}}@media only screen and (min-width:992px){pre{white-space:pre}}
1
+ body{font-family:sans-serif;max-width:800px;margin:auto;padding:1em;line-height:1.5;box-sizing:border-box}.footnotes,body,code{font-size:.9em}li li{font-size:.95em}*,:after,:before{box-sizing:inherit}img,pre{max-width:100%}pre,pre:hover{white-space:pre-wrap;word-break:break-all}pre code{display:block;overflow-x:auto}code{font-family:'DejaVu Sans Mono','Droid Sans Mono','Lucida Console',Consolas,Monaco,monospace}.box>div,:not(pre)>code,code[class]{background-color:#f8f8f8}.box,pre>.language-plain,pre>code:not([class]){background-color:inherit;border:1px solid #eee}pre>.message{border-color:#9eeaf9}pre>.warning{background:#fff3cd;border-color:#fff3cd}pre>.error{background:#f8d7da;border-color:#f8d7da}.fenced-chunk{border-left:1px solid #666}.code-fence{opacity:.4;border:1px dashed #666;border-left:2px solid}.code-fence:hover{opacity:inherit}.box{margin:1em 0}.box>:first-child>p:first-child,.box>:last-child>p:last-child{padding:1em}.box>:first-child,.box>:first-child>p:first-child{margin-top:0}.box>:last-child,.box>:last-child>p:last-child{margin-bottom:0}.figure>p{text-align:center}table{margin:auto;border-top:1px solid #666}table thead th{border-bottom:1px solid #ddd}td,th{padding:5px}tfoot,thead,tr:nth-child(2n){background:#eee}blockquote{color:#666;margin:0;padding-left:1em;border-left:.5em solid #eee}.footnotes::before,hr{border:1px dashed #ddd}.frontmatter{text-align:center}#TOC .numbered li{list-style:none}#TOC .numbered{padding-left:0}#TOC .numbered ul{padding-left:1em}.body h2,table{border-bottom:1px solid #666}.appendix~h2,.body .appendix{border-bottom-style:dashed}.main-number::after{content:"."}.footnote-ref a::before{content:"["}.footnote-ref a::after{content:"]"}section.footnotes{margin-top:2em}section.footnotes::before{content:"";display:block;max-width:20em}@media print{body{font-size:12pt;max-width:100%}img,tr{page-break-inside:avoid}}@media only screen and (min-width:992px){pre{white-space:pre}}
@@ -3,29 +3,36 @@
3
3
  // assume TOC has these possible IDs (we can also consider other selectors)
4
4
  const toc = d.querySelector('#TableOfContents, #TOC');
5
5
  if (!toc) return;
6
- const links = toc.querySelectorAll('a');
6
+ const links = toc.querySelectorAll('a[href^="#"]');
7
7
  if (!links.length) return;
8
- const lis = toc.querySelectorAll('li');
8
+ const lis = toc.querySelectorAll('li'), dict = {};
9
+ links.forEach(a => dict[a.getAttribute('href').replace('#', '')] = a);
10
+ const ids = Object.keys(dict);
9
11
 
10
12
  // record which elements are currently in the viewport
11
- const ids = [];
13
+ const stack = [], id2 = [];
12
14
  // create a new Intersection Observer instance
13
15
  const observer = new IntersectionObserver(els => els.forEach(el => {
14
- const id = el.target.id, i = ids.indexOf(id);
15
- el.isIntersecting ? ids.push(id) : (i > -1 && ids.splice(i, 1));
16
- const n = ids.length;
17
- if (!n) return;
18
- links.forEach(a => {
19
- const action = (a.getAttribute('href') === '#' + ids[n - 1]) ? 'add' : 'remove';
20
- a.classList[action]('active');
21
- });
16
+ const id = el.target.id, i = stack.indexOf(id);
17
+ el.isIntersecting ? stack.push(id) : (i > -1 && stack.splice(i, 1));
18
+ let id_active;
19
+ const n = stack.length;
20
+ if (!n) {
21
+ if (el.target.getBoundingClientRect().top < 0) return;
22
+ // if a heading exits from bottom and no heading is in view, activate previous ID
23
+ const k = ids.indexOf(id) - 1;
24
+ if (k >= 0) id_active = ids[k];
25
+ } else id_active = stack[n - 1];
26
+ for (const i in dict) {
27
+ dict[i].classList[i === id_active ? 'add' : 'remove']('active');
28
+ }
22
29
  lis.forEach(li => {
23
30
  li.classList[li.querySelector('.active') ? 'add' : 'remove']('open');
24
31
  });
25
32
  }));
26
-
27
- // observe all section headings
33
+
34
+ // observe all section headings associated with TOC links
28
35
  d.querySelectorAll('h1,h2,h3,h4,h5,h6').forEach(h => {
29
- h.nodeType === 1 && h.id && observer.observe(h);
36
+ h.nodeType === 1 && dict.hasOwnProperty(h.id) && observer.observe(h);
30
37
  });
31
38
  })(document);
@@ -1 +1 @@
1
- (e=>{const t=e.querySelector("#TableOfContents, #TOC");if(!t)return;const r=t.querySelectorAll("a");if(!r.length)return;const c=t.querySelectorAll("li"),o=[],n=new IntersectionObserver((e=>e.forEach((e=>{const t=e.target.id,n=o.indexOf(t);e.isIntersecting?o.push(t):n>-1&&o.splice(n,1);const s=o.length;s&&(r.forEach((e=>{const t=e.getAttribute("href")==="#"+o[s-1]?"add":"remove";e.classList[t]("active")})),c.forEach((e=>{e.classList[e.querySelector(".active")?"add":"remove"]("open")})))}))));e.querySelectorAll("h1,h2,h3,h4,h5,h6").forEach((e=>{1===e.nodeType&&e.id&&n.observe(e)}))})(document);
1
+ (e=>{const t=e.querySelector("#TableOfContents, #TOC");if(!t)return;const r=t.querySelectorAll('a[href^="#"]');if(!r.length)return;const n=t.querySelectorAll("li"),o={};r.forEach((e=>o[e.getAttribute("href").replace("#","")]=e));const c=Object.keys(o),s=[],l=new IntersectionObserver((e=>e.forEach((e=>{const t=e.target.id,r=s.indexOf(t);let l;e.isIntersecting?s.push(t):r>-1&&s.splice(r,1);const i=s.length;if(i)l=s[i-1];else{if(e.target.getBoundingClientRect().top<0)return;const r=c.indexOf(t)-1;r>=0&&(l=c[r])}for(const e in o)o[e].classList[e===l?"add":"remove"]("active");n.forEach((e=>{e.classList[e.querySelector(".active")?"add":"remove"]("open")}))}))));e.querySelectorAll("h1,h2,h3,h4,h5,h6").forEach((e=>{1===e.nodeType&&o.hasOwnProperty(e.id)&&l.observe(e)}))})(document);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiee/utils",
3
- "version": "1.12.1",
3
+ "version": "1.12.3",
4
4
  "description": "Miscellaneous tools and utilities to manipulate HTML pages",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"