@valaxyjs/utils 0.19.12 → 0.20.0-beta.1

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/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var i=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var h=(r,e)=>{for(var t in e)i(r,t,{get:e[t],enumerable:!0})},y=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of p(e))!b.call(r,o)&&o!==t&&i(r,o,{get:()=>e[o],enumerable:!(n=f(e,o))||n.enumerable});return r};var g=r=>y(i({},"__esModule",{value:!0}),r);var H={};h(H,{addToParent:()=>s,getHeaders:()=>x,groupHeaders:()=>m,resolveHeaders:()=>a,serializeHeader:()=>c});module.exports=g(H);function m(r,e){let t=[];return r=r.map(n=>({...n})),r.forEach((n,o)=>{n.level>=e[0]&&n.level<=e[1]&&s(o,r,e)&&t.push(n)}),t}function s(r,e,t){if(r===0)return!0;let n=e[r];for(let o=r-1;o>=0;o--){let l=e[o];if(l.level<n.level&&l.level>=t[0]&&l.level<=t[1])return l.children==null&&(l.children=[]),l.children.push(n),!1}return!0}function a(r,e=[2,4]){return m(r,typeof e=="number"?[e,e]:e==="deep"?[2,6]:e)}function c(r){let e="";for(let t of Array.from(r.childNodes))if(t.nodeType===1){if(t.classList.contains("VABadge")||t.classList.contains("header-anchor"))continue;e+=t.textContent}else t.nodeType===3&&(e+=t.textContent);return e.trim()}function x(r={range:[2,4],selector:".markdown-body"}){let e=r.selector||".markdown-body",t=document.querySelectorAll(e),n=t[t.length-1],o=Array.from(n.querySelectorAll(`${e} :where(h1,h2,h3,h4,h5,h6)`)).filter(l=>r.filter?r.filter(l):!0).map(l=>{let d=Number(l.tagName[1]);return{title:c(l),link:`#${l.id}`,level:d,lang:l.lang}});return a(o,r.range)}0&&(module.exports={addToParent,getHeaders,groupHeaders,resolveHeaders,serializeHeader});
1
+ "use strict";var u=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var g=Object.prototype.hasOwnProperty;var b=(n,e)=>{for(var t in e)u(n,t,{get:e[t],enumerable:!0})},y=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of p(e))!g.call(n,r)&&r!==t&&u(n,r,{get:()=>e[r],enumerable:!(o=f(e,r))||o.enumerable});return n};var v=n=>y(u({},"__esModule",{value:!0}),n);var M={};b(M,{addToParent:()=>H,buildTree:()=>d,getHeaders:()=>x,resolveHeaders:()=>c,resolvedHeaders:()=>m,serializeHeader:()=>h});module.exports=v(M);var m=[];function d(n,e,t){m.length=0;let o=[],r=[];return n.forEach(l=>{let s={...l,children:[]},i=r[r.length-1];for(;i&&i.level>=s.level;)r.pop(),i=r[r.length-1];if(s.element.classList.contains("ignore-header")||i&&"shouldIgnore"in i){r.push({level:s.level,shouldIgnore:!0});return}s.level>t||s.level<e||(m.push({element:s.element,link:s.link}),i?i.children.push(s):o.push(s),r.push(s))}),o}function H(n,e,t){if(n===0)return!0;let o=e[n];for(let r=n-1;r>=0;r--){let l=e[r];if(l.level<o.level&&l.level>=t[0]&&l.level<=t[1])return l.children==null&&(l.children=[]),l.children.push(o),!1}return!0}function c(n,e=[2,4]){let t=(typeof e=="object"&&!Array.isArray(e)?e.level:e)||2,[o,r]=typeof t=="number"?[t,t]:t==="deep"?[2,6]:t;return d(n,o,r)}function h(n){let e="";for(let t of Array.from(n.childNodes))if(t.nodeType===1){if(t.classList.contains("VABadge")||t.classList.contains("header-anchor"))continue;e+=t.textContent}else t.nodeType===3&&(e+=t.textContent);return e.trim()}function x(n={range:[2,4],selector:".markdown-body"}){let e=n.selector||".markdown-body",t=document.querySelectorAll(e),o=t[t.length-1],r=Array.from(o.querySelectorAll(`${e} :where(h1,h2,h3,h4,h5,h6)`)).filter(l=>n.filter?n.filter(l):!0).map(l=>{let s=Number(l.tagName[1]);return{element:l,title:h(l),link:`#${l.id}`,level:s,lang:l.lang}});return c(r,n.range)}0&&(module.exports={addToParent,buildTree,getHeaders,resolveHeaders,resolvedHeaders,serializeHeader});
package/dist/index.d.cts CHANGED
@@ -34,21 +34,31 @@ interface Header {
34
34
  * 菜单项,从文章中解析出的标题菜单。
35
35
  */
36
36
  type MenuItem = Omit<Header, 'slug' | 'children'> & {
37
+ element: HTMLHeadElement;
37
38
  children?: MenuItem[];
38
39
  };
39
40
 
41
+ /**
42
+ * @ref vitepress src/client/theme-chalk/composables/outline.ts
43
+ */
44
+ declare const resolvedHeaders: {
45
+ element: HTMLHeadElement;
46
+ link: string;
47
+ }[];
40
48
  interface GetHeadersOptions {
41
- range?: number | [number, number] | 'deep';
49
+ range?: number | [number, number] | 'deep' | {
50
+ level: [number, number];
51
+ };
42
52
  selector?: string;
43
53
  filter?: (el: Element) => boolean;
44
54
  }
45
- declare function groupHeaders(headers: MenuItem[], levelsRange: [number, number]): MenuItem[];
55
+ declare function buildTree(data: MenuItem[], min: number, max: number): MenuItem[];
46
56
  declare function addToParent(currIndex: number, headers: MenuItem[], levelsRange: [number, number]): boolean;
47
- declare function resolveHeaders(headers: MenuItem[], levelsRange?: GetHeadersOptions['range']): MenuItem[];
57
+ declare function resolveHeaders(headers: MenuItem[], range?: GetHeadersOptions['range']): MenuItem[];
48
58
  declare function serializeHeader(h: Element): string;
49
59
  /**
50
60
  * get headers from document directly
51
61
  */
52
62
  declare function getHeaders(options?: GetHeadersOptions): MenuItem[];
53
63
 
54
- export { type GetHeadersOptions, type Header, type MenuItem, addToParent, getHeaders, groupHeaders, resolveHeaders, serializeHeader };
64
+ export { type GetHeadersOptions, type Header, type MenuItem, addToParent, buildTree, getHeaders, resolveHeaders, resolvedHeaders, serializeHeader };
package/dist/index.d.ts CHANGED
@@ -34,21 +34,31 @@ interface Header {
34
34
  * 菜单项,从文章中解析出的标题菜单。
35
35
  */
36
36
  type MenuItem = Omit<Header, 'slug' | 'children'> & {
37
+ element: HTMLHeadElement;
37
38
  children?: MenuItem[];
38
39
  };
39
40
 
41
+ /**
42
+ * @ref vitepress src/client/theme-chalk/composables/outline.ts
43
+ */
44
+ declare const resolvedHeaders: {
45
+ element: HTMLHeadElement;
46
+ link: string;
47
+ }[];
40
48
  interface GetHeadersOptions {
41
- range?: number | [number, number] | 'deep';
49
+ range?: number | [number, number] | 'deep' | {
50
+ level: [number, number];
51
+ };
42
52
  selector?: string;
43
53
  filter?: (el: Element) => boolean;
44
54
  }
45
- declare function groupHeaders(headers: MenuItem[], levelsRange: [number, number]): MenuItem[];
55
+ declare function buildTree(data: MenuItem[], min: number, max: number): MenuItem[];
46
56
  declare function addToParent(currIndex: number, headers: MenuItem[], levelsRange: [number, number]): boolean;
47
- declare function resolveHeaders(headers: MenuItem[], levelsRange?: GetHeadersOptions['range']): MenuItem[];
57
+ declare function resolveHeaders(headers: MenuItem[], range?: GetHeadersOptions['range']): MenuItem[];
48
58
  declare function serializeHeader(h: Element): string;
49
59
  /**
50
60
  * get headers from document directly
51
61
  */
52
62
  declare function getHeaders(options?: GetHeadersOptions): MenuItem[];
53
63
 
54
- export { type GetHeadersOptions, type Header, type MenuItem, addToParent, getHeaders, groupHeaders, resolveHeaders, serializeHeader };
64
+ export { type GetHeadersOptions, type Header, type MenuItem, addToParent, buildTree, getHeaders, resolveHeaders, resolvedHeaders, serializeHeader };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- function s(r,e){let t=[];return r=r.map(o=>({...o})),r.forEach((o,l)=>{o.level>=e[0]&&o.level<=e[1]&&a(l,r,e)&&t.push(o)}),t}function a(r,e,t){if(r===0)return!0;let o=e[r];for(let l=r-1;l>=0;l--){let n=e[l];if(n.level<o.level&&n.level>=t[0]&&n.level<=t[1])return n.children==null&&(n.children=[]),n.children.push(o),!1}return!0}function c(r,e=[2,4]){return s(r,typeof e=="number"?[e,e]:e==="deep"?[2,6]:e)}function d(r){let e="";for(let t of Array.from(r.childNodes))if(t.nodeType===1){if(t.classList.contains("VABadge")||t.classList.contains("header-anchor"))continue;e+=t.textContent}else t.nodeType===3&&(e+=t.textContent);return e.trim()}function f(r={range:[2,4],selector:".markdown-body"}){let e=r.selector||".markdown-body",t=document.querySelectorAll(e),o=t[t.length-1],l=Array.from(o.querySelectorAll(`${e} :where(h1,h2,h3,h4,h5,h6)`)).filter(n=>r.filter?r.filter(n):!0).map(n=>{let m=Number(n.tagName[1]);return{title:d(n),link:`#${n.id}`,level:m,lang:n.lang}});return c(l,r.range)}export{a as addToParent,f as getHeaders,s as groupHeaders,c as resolveHeaders,d as serializeHeader};
1
+ var a=[];function d(l,t,e){a.length=0;let s=[],r=[];return l.forEach(n=>{let o={...n,children:[]},i=r[r.length-1];for(;i&&i.level>=o.level;)r.pop(),i=r[r.length-1];if(o.element.classList.contains("ignore-header")||i&&"shouldIgnore"in i){r.push({level:o.level,shouldIgnore:!0});return}o.level>e||o.level<t||(a.push({element:o.element,link:o.link}),i?i.children.push(o):s.push(o),r.push(o))}),s}function f(l,t,e){if(l===0)return!0;let s=t[l];for(let r=l-1;r>=0;r--){let n=t[r];if(n.level<s.level&&n.level>=e[0]&&n.level<=e[1])return n.children==null&&(n.children=[]),n.children.push(s),!1}return!0}function c(l,t=[2,4]){let e=(typeof t=="object"&&!Array.isArray(t)?t.level:t)||2,[s,r]=typeof e=="number"?[e,e]:e==="deep"?[2,6]:e;return d(l,s,r)}function h(l){let t="";for(let e of Array.from(l.childNodes))if(e.nodeType===1){if(e.classList.contains("VABadge")||e.classList.contains("header-anchor"))continue;t+=e.textContent}else e.nodeType===3&&(t+=e.textContent);return t.trim()}function p(l={range:[2,4],selector:".markdown-body"}){let t=l.selector||".markdown-body",e=document.querySelectorAll(t),s=e[e.length-1],r=Array.from(s.querySelectorAll(`${t} :where(h1,h2,h3,h4,h5,h6)`)).filter(n=>l.filter?l.filter(n):!0).map(n=>{let o=Number(n.tagName[1]);return{element:n,title:h(n),link:`#${n.id}`,level:o,lang:n.lang}});return c(r,l.range)}export{f as addToParent,d as buildTree,p as getHeaders,c as resolveHeaders,a as resolvedHeaders,h as serializeHeader};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@valaxyjs/utils",
3
3
  "type": "module",
4
- "version": "0.19.12",
4
+ "version": "0.20.0-beta.1",
5
5
  "description": "A utility library for Valaxy",
6
6
  "author": {
7
7
  "name": "Valaxy",
@@ -1,20 +1,49 @@
1
1
  import type { MenuItem } from '../types'
2
2
 
3
+ /**
4
+ * @ref vitepress src/client/theme-chalk/composables/outline.ts
5
+ */
6
+ // cached list of anchor elements from resolveHeaders
7
+ export const resolvedHeaders: { element: HTMLHeadElement, link: string }[] = []
8
+
3
9
  export interface GetHeadersOptions {
4
- range?: number | [number, number] | 'deep'
10
+ range?: number | [number, number] | 'deep' | { level: [number, number] }
5
11
  selector?: string
6
12
  filter?: (el: Element) => boolean
7
13
  }
8
14
 
9
- export function groupHeaders(headers: MenuItem[], levelsRange: [number, number]) {
15
+ export function buildTree(data: MenuItem[], min: number, max: number): MenuItem[] {
16
+ resolvedHeaders.length = 0
17
+
10
18
  const result: MenuItem[] = []
19
+ const stack: (MenuItem | { level: number, shouldIgnore: true })[] = []
11
20
 
12
- headers = headers.map(h => ({ ...h }))
13
- headers.forEach((h, index) => {
14
- if (h.level >= levelsRange[0] && h.level <= levelsRange[1]) {
15
- if (addToParent(index, headers, levelsRange))
16
- result.push(h)
21
+ data.forEach((item) => {
22
+ const node = { ...item, children: [] }
23
+ let parent = stack[stack.length - 1]
24
+
25
+ while (parent && parent.level >= node.level) {
26
+ stack.pop()
27
+ parent = stack[stack.length - 1]
17
28
  }
29
+
30
+ if (
31
+ node.element.classList.contains('ignore-header')
32
+ || (parent && 'shouldIgnore' in parent)
33
+ ) {
34
+ stack.push({ level: node.level, shouldIgnore: true })
35
+ return
36
+ }
37
+
38
+ if (node.level > max || node.level < min)
39
+ return
40
+ resolvedHeaders.push({ element: node.element, link: node.link })
41
+
42
+ if (parent)
43
+ parent.children!.push(node)
44
+ else result.push(node)
45
+
46
+ stack.push(node)
18
47
  })
19
48
 
20
49
  return result
@@ -49,16 +78,21 @@ export function addToParent(
49
78
 
50
79
  export function resolveHeaders(
51
80
  headers: MenuItem[],
52
- levelsRange: GetHeadersOptions['range'] = [2, 4],
81
+ range: GetHeadersOptions['range'] = [2, 4],
53
82
  ) {
54
- const levels: [number, number]
83
+ const levelsRange
84
+ = (typeof range === 'object' && !Array.isArray(range)
85
+ ? range.level
86
+ : range) || 2
87
+
88
+ const [high, low]: [number, number]
55
89
  = typeof levelsRange === 'number'
56
90
  ? [levelsRange, levelsRange]
57
91
  : levelsRange === 'deep'
58
92
  ? [2, 6]
59
93
  : levelsRange
60
94
 
61
- return groupHeaders(headers, levels)
95
+ return buildTree(headers, high, low)
62
96
  }
63
97
 
64
98
  export function serializeHeader(h: Element): string {
@@ -98,6 +132,7 @@ export function getHeaders(options: GetHeadersOptions = {
98
132
  .map((el) => {
99
133
  const level = Number(el.tagName[1])
100
134
  return {
135
+ element: el as HTMLHeadElement,
101
136
  title: serializeHeader(el),
102
137
  link: `#${el.id}`,
103
138
  level,
@@ -35,5 +35,6 @@ export interface Header {
35
35
  * 菜单项,从文章中解析出的标题菜单。
36
36
  */
37
37
  export type MenuItem = Omit<Header, 'slug' | 'children'> & {
38
+ element: HTMLHeadElement
38
39
  children?: MenuItem[]
39
40
  }