@gouvfr/dsfr-roller 1.0.0

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 (113) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +11 -0
  3. package/index.js +5 -0
  4. package/package.json +65 -0
  5. package/src/component/component.js +50 -0
  6. package/src/component/components/action.js +28 -0
  7. package/src/component/components/breadcrumb.js +33 -0
  8. package/src/component/components/button.js +37 -0
  9. package/src/component/components/display-body.js +41 -0
  10. package/src/component/components/display-modal.js +29 -0
  11. package/src/component/components/footer.js +85 -0
  12. package/src/component/components/header.js +96 -0
  13. package/src/component/components/navigation.js +72 -0
  14. package/src/component/components/sidemenu.js +58 -0
  15. package/src/component/components/skiplink.js +49 -0
  16. package/src/component/components/translate.js +32 -0
  17. package/src/component/components/version.js +21 -0
  18. package/src/component/ejs/version/version.ejs +46 -0
  19. package/src/component/ejs/version/versions.ejs +31 -0
  20. package/src/component/ejs-pkg.js +6 -0
  21. package/src/component/render.js +19 -0
  22. package/src/constants.js +7 -0
  23. package/src/core/format-html.js +16 -0
  24. package/src/core/format-link.js +8 -0
  25. package/src/core/html-renderable.js +10 -0
  26. package/src/core/renderable.js +20 -0
  27. package/src/integration/bundler.js +47 -0
  28. package/src/integration/indexing/indexer.js +23 -0
  29. package/src/integration/indexing/sitemap.js +44 -0
  30. package/src/integration/redirect/redirection-type.js +4 -0
  31. package/src/integration/redirect/redirection.js +77 -0
  32. package/src/node/custom/html-container-node.js +7 -0
  33. package/src/node/directive/doc/accordion-container-directive.js +59 -0
  34. package/src/node/directive/doc/accordions-group-container-directive.js +12 -0
  35. package/src/node/directive/doc/anatomy-container-directive.js +61 -0
  36. package/src/node/directive/doc/button-leaf-directive.js +37 -0
  37. package/src/node/directive/doc/changelog-leaf-directive.js +238 -0
  38. package/src/node/directive/doc/figma-leaf-directive.js +21 -0
  39. package/src/node/directive/doc/guideline-container-directive.js +71 -0
  40. package/src/node/directive/doc/guidelines-container-directive.js +13 -0
  41. package/src/node/directive/doc/image-text-directive.js +13 -0
  42. package/src/node/directive/doc/pin-leaf-directive.js +46 -0
  43. package/src/node/directive/doc/storybook-leaf-directive.js +18 -0
  44. package/src/node/directive/doc/tab-container-directive.js +22 -0
  45. package/src/node/directive/doc/tab-navigation-container-directive.js +49 -0
  46. package/src/node/directive/doc/table-container-directive.js +56 -0
  47. package/src/node/directive/doc/tabs-container-directive.js +71 -0
  48. package/src/node/generic/blockquote-node.js +26 -0
  49. package/src/node/generic/break-node.js +11 -0
  50. package/src/node/generic/code-node.js +37 -0
  51. package/src/node/generic/definition-node.js +13 -0
  52. package/src/node/generic/emphasis-node.js +11 -0
  53. package/src/node/generic/heading-node.js +56 -0
  54. package/src/node/generic/html-node.js +11 -0
  55. package/src/node/generic/image-node.js +14 -0
  56. package/src/node/generic/image-reference-node.js +14 -0
  57. package/src/node/generic/inline-code-node.js +21 -0
  58. package/src/node/generic/link-node.js +26 -0
  59. package/src/node/generic/link-reference-node.js +14 -0
  60. package/src/node/generic/list-item-node.js +11 -0
  61. package/src/node/generic/list-node.js +15 -0
  62. package/src/node/generic/paragraph-node.js +11 -0
  63. package/src/node/generic/strong-node.js +11 -0
  64. package/src/node/generic/text-node.js +15 -0
  65. package/src/node/generic/thematic-break-node.js +12 -0
  66. package/src/node/gfm/table-body-node.js +11 -0
  67. package/src/node/gfm/table-cell-node.js +17 -0
  68. package/src/node/gfm/table-head-node.js +11 -0
  69. package/src/node/gfm/table-header-node.js +16 -0
  70. package/src/node/gfm/table-node.js +91 -0
  71. package/src/node/gfm/table-row-node.js +11 -0
  72. package/src/node/node-factory.js +128 -0
  73. package/src/node/node-root.js +25 -0
  74. package/src/node/node.js +106 -0
  75. package/src/page/body/custom-header.js +40 -0
  76. package/src/page/body/main.js +23 -0
  77. package/src/page/body/scheme.js +9 -0
  78. package/src/page/head/canonical.js +16 -0
  79. package/src/page/head/favicon.js +14 -0
  80. package/src/page/head/head.js +35 -0
  81. package/src/page/head/share.js +14 -0
  82. package/src/page/head/stylesheets.js +48 -0
  83. package/src/page/head/title.js +9 -0
  84. package/src/page/html.js +46 -0
  85. package/src/page/page.js +39 -0
  86. package/src/page/scripts/highlight.js +53 -0
  87. package/src/page/scripts/scripts.js +57 -0
  88. package/src/script/main/core/element.js +29 -0
  89. package/src/script/main/elements/copy-snippet.js +35 -0
  90. package/src/script/main/elements/searchbar.js +18 -0
  91. package/src/script/main/elements/storybook.js +20 -0
  92. package/src/script/main/index.js +10 -0
  93. package/src/script/search/index.js +0 -0
  94. package/src/style/main/components/_dsfr-doc-anatomy.scss +54 -0
  95. package/src/style/main/components/_dsfr-doc-code-snippet.scss +9 -0
  96. package/src/style/main/components/_dsfr-doc-figma-leaf.scss +6 -0
  97. package/src/style/main/components/_dsfr-doc-guideline.scss +58 -0
  98. package/src/style/main/components/_dsfr-doc-tab-navigation.scss +99 -0
  99. package/src/style/main/components/_dsfr-doc-version.scss +154 -0
  100. package/src/style/main/components/_index.scss +6 -0
  101. package/src/style/main/index.scss +3 -0
  102. package/src/style/main/third-party/_highlight.scss +227 -0
  103. package/src/style/main/third-party/_index.scss +1 -0
  104. package/src/style/main/utility/_dsfr-doc-code.scss +9 -0
  105. package/src/style/main/utility/_font.scss +31 -0
  106. package/src/style/main/utility/_icon.scss +4 -0
  107. package/src/style/main/utility/_index.scss +3 -0
  108. package/src/style/search/index.scss +0 -0
  109. package/src/template/template-factory.js +16 -0
  110. package/src/template/template.js +27 -0
  111. package/src/template/templates/editorial-template.js +45 -0
  112. package/src/template/templates/home-template.js +18 -0
  113. package/src/template/templates/search-template.js +20 -0
@@ -0,0 +1,37 @@
1
+ import { Node } from '../node.js';
2
+ import { convertHTMLEntities } from '@gouvfr/dsfr-forge';
3
+
4
+ class CodeNode extends Node {
5
+ constructor (data) {
6
+ super(data);
7
+ this._value = data.value;
8
+ this._lang = data.lang;
9
+ this._meta = data.meta;
10
+ }
11
+
12
+ get value () {
13
+ return this._value;
14
+ }
15
+
16
+ get lang () {
17
+ return this._lang;
18
+ }
19
+
20
+ get meta () {
21
+ return this._meta;
22
+ }
23
+
24
+ async render () {
25
+ if (this.lang) this.attributes.addClass(`language-${this.lang}`);
26
+ return `
27
+ <div class="code-snippet">
28
+ <pre><code${this.renderAttributes()}>${convertHTMLEntities(this.value)}</code></pre>
29
+ <button type="button" class="code-snippet--copy fr-btn fr-btn--sm fr-btn--tertiary" data-label-copied="${this.data?.fragments?.button?.copied}">${this.data?.fragments?.button?.copy}</button>
30
+ </div>
31
+ `;
32
+ }
33
+ }
34
+
35
+ CodeNode.TYPE = 'code';
36
+
37
+ export { CodeNode };
@@ -0,0 +1,13 @@
1
+ import { Node } from '../node.js';
2
+ import { log } from '@gouvfr/dsfr-forge';
3
+
4
+ class DefinitionNode extends Node {
5
+ async render() {
6
+ log.warn(`Markdown node type 'definition' isn't yet supported`);
7
+ return '';
8
+ }
9
+ }
10
+
11
+ DefinitionNode.TYPE = 'definition';
12
+
13
+ export { DefinitionNode };
@@ -0,0 +1,11 @@
1
+ import { Node } from '../node.js';
2
+
3
+ class EmphasisNode extends Node {
4
+ constructor (data) {
5
+ super(data, 'i');
6
+ }
7
+ }
8
+
9
+ EmphasisNode.TYPE = 'emphasis';
10
+
11
+ export { EmphasisNode };
@@ -0,0 +1,56 @@
1
+ import { Node } from '../node.js';
2
+ import { log } from '@gouvfr/dsfr-forge';
3
+
4
+ class HeadingNode extends Node {
5
+ constructor (data) {
6
+ super(data, `h${data.depth}`, false, true);
7
+ this._depth = data.depth;
8
+ }
9
+
10
+ adjust (map) {
11
+ if (map.has(this.data.depth)) {
12
+ this._depth = map.get(this.data.depth);
13
+ this.tagName = `h${this._depth}`;
14
+
15
+ switch (true) {
16
+ case this._data?.data?.isSemantic:
17
+ case this.attributes.classes.some(className => className.match(/^fr-h\d$/) || className.match(/__title$/)):
18
+ break;
19
+
20
+ default:
21
+ this.attributes.addClass(`fr-h${this.data.depth}`);
22
+ }
23
+ }
24
+ }
25
+ }
26
+
27
+ HeadingNode.TYPE = 'heading';
28
+
29
+ const adjustHeading = (nodes) => {
30
+ let isPromoted = false;
31
+ const headings = nodes.map(node => node.data.depth);
32
+
33
+ if (headings.indexOf(1) === -1) {
34
+ if (headings.filter(heading => heading === 2).length === 1) {
35
+ log.warn('No h1 found in the document, promoting h2 to h1');
36
+ isPromoted = true;
37
+ } else {
38
+ log.warn('No h1 found in the document');
39
+ }
40
+ } else if (!headings.filter(heading => heading === 1).length > 1) {
41
+ log.warn('Several instance of h1 found in the document');
42
+ }
43
+
44
+ const depths = headings.filter((heading, index, self) => self.indexOf(heading) === index && (heading > 1 || isPromoted) ).sort((a, b) => a - b);
45
+
46
+ const mapped = depths.map((depth, index) => [depth, index + (isPromoted ? 1 : 2)]).filter(([depth, index]) => depth !== index);
47
+ const map = new Map(mapped);
48
+
49
+ if (map.size === 0) return;
50
+
51
+ log.warn(`Adjusting heading levels : ${Array.from(map).map(([from, to]) => `h${from} -> h${to}`).join(', ')}`);
52
+
53
+ nodes.forEach(node => node.adjust(map));
54
+ };
55
+
56
+ export { HeadingNode, adjustHeading};
@@ -0,0 +1,11 @@
1
+ import { Node } from '../node.js';
2
+
3
+ class HtmlNode extends Node {
4
+ async render() {
5
+ return /^<\//.test(this.data.value) ? this.data.value : this.data.value.replace(/>$/, `${this.renderAttributes()}>`);
6
+ }
7
+ }
8
+
9
+ HtmlNode.TYPE = 'html';
10
+
11
+ export { HtmlNode };
@@ -0,0 +1,14 @@
1
+ import { Node } from '../node.js';
2
+
3
+ class ImageNode extends Node {
4
+ constructor(data) {
5
+ super(data, 'img', true);
6
+ this.attributes.setAttribute('src', this.data.url);
7
+ if (this.data.alt) this.attributes.setAttribute('alt', this.data.alt);
8
+ if (this.data.title) this.attributes.setAttribute('title', this.data.title);
9
+ }
10
+ }
11
+
12
+ ImageNode.TYPE = 'image';
13
+
14
+ export { ImageNode };
@@ -0,0 +1,14 @@
1
+ import { Node } from '../node.js';
2
+ import { log } from '@gouvfr/dsfr-forge';
3
+
4
+ class ImageReferenceNode extends Node {
5
+ async render() {
6
+ log.warn(`Markdown node type 'imageReference' isn't yet supported`);
7
+ return '';
8
+ }
9
+
10
+ }
11
+
12
+ ImageReferenceNode.TYPE = 'imageReference';
13
+
14
+ export { ImageReferenceNode };
@@ -0,0 +1,21 @@
1
+ import { Node } from '../node.js';
2
+ import { convertHTMLEntities } from '@gouvfr/dsfr-forge';
3
+
4
+ class InlineCodeNode extends Node {
5
+ constructor (data) {
6
+ super(data);
7
+ this._value = data.value;
8
+ }
9
+
10
+ get value () {
11
+ return this._value
12
+ }
13
+
14
+ async render () {
15
+ return `<code class="dsfr-doc-inline-code">${convertHTMLEntities(this.value)}</code>`;
16
+ }
17
+ }
18
+
19
+ InlineCodeNode.TYPE = 'inlineCode';
20
+
21
+ export { InlineCodeNode };
@@ -0,0 +1,26 @@
1
+ import { Node } from '../node.js';
2
+ import { Action } from '../../component/components/action.js';
3
+
4
+ class LinkNode extends Node {
5
+ constructor (data) {
6
+ super(data);
7
+ const blank = /^(http|www)/.test(data.url);
8
+ const actionData = {
9
+ markup: 'a',
10
+ href: data.url,
11
+ blank
12
+ };
13
+ if (blank) actionData.attributes = { title: `${this.text} - ${data.fragments.blank}` };
14
+ this._action = new Action(actionData);
15
+ }
16
+ async render () {
17
+ return this._action.render({
18
+ label: await super.render(),
19
+ attributes: this.getAttributes()
20
+ });
21
+ }
22
+ }
23
+
24
+ LinkNode.TYPE = 'link';
25
+
26
+ export { LinkNode };
@@ -0,0 +1,14 @@
1
+ import { Node } from '../node.js';
2
+ import { log } from '@gouvfr/dsfr-forge';
3
+
4
+ class LinkReferenceNode extends Node {
5
+ async render() {
6
+ log.warn(`Markdown node type 'linkReference' isn't yet supported`);
7
+ return '';
8
+ }
9
+
10
+ }
11
+
12
+ LinkReferenceNode.TYPE = 'linkReference';
13
+
14
+ export { LinkReferenceNode };
@@ -0,0 +1,11 @@
1
+ import { Node } from '../node.js';
2
+
3
+ class ListItemNode extends Node {
4
+ constructor (data) {
5
+ super(data, 'li');
6
+ }
7
+ }
8
+
9
+ ListItemNode.TYPE = 'listItem';
10
+
11
+ export { ListItemNode };
@@ -0,0 +1,15 @@
1
+ import { Node } from '../node.js';
2
+
3
+ class ListNode extends Node {
4
+
5
+ constructor (data) {
6
+ super(data, data.ordered === true ? 'ol' : 'ul');
7
+ if (data.ordered === true && this.data.start !== undefined && !isNaN(this.data.start)) {
8
+ this.attributes.setAttribute('start', this.data.start);
9
+ }
10
+ }
11
+ }
12
+
13
+ ListNode.TYPE = 'list';
14
+
15
+ export { ListNode };
@@ -0,0 +1,11 @@
1
+ import { Node } from '../node.js';
2
+
3
+ class ParagraphNode extends Node {
4
+ constructor (data) {
5
+ super(data, 'p');
6
+ }
7
+ }
8
+
9
+ ParagraphNode.TYPE = 'paragraph';
10
+
11
+ export { ParagraphNode };
@@ -0,0 +1,11 @@
1
+ import { Node } from '../node.js';
2
+
3
+ class StrongNode extends Node {
4
+ constructor(data) {
5
+ super(data, 'b');
6
+ }
7
+ }
8
+
9
+ StrongNode.TYPE = 'strong';
10
+
11
+ export { StrongNode };
@@ -0,0 +1,15 @@
1
+ import { Node } from '../node.js';
2
+
3
+ class TextNode extends Node {
4
+ async render () {
5
+ return this.data.value;
6
+ }
7
+
8
+ get text () {
9
+ return this.data.value;
10
+ }
11
+ }
12
+
13
+ TextNode.TYPE = 'text';
14
+
15
+ export { TextNode };
@@ -0,0 +1,12 @@
1
+ import { Node } from '../node.js';
2
+ import { log } from '@gouvfr/dsfr-forge';
3
+
4
+ class ThematicBreakNode extends Node {
5
+ constructor(data) {
6
+ super(data, 'hr', true);
7
+ }
8
+ }
9
+
10
+ ThematicBreakNode.TYPE = 'thematicBreak';
11
+
12
+ export { ThematicBreakNode };
@@ -0,0 +1,11 @@
1
+ import { Node } from '../node.js';
2
+
3
+ class TableBodyNode extends Node {
4
+ constructor (data) {
5
+ super(data, `tbody`);
6
+ }
7
+ }
8
+
9
+ TableBodyNode.TYPE = 'tableBody';
10
+
11
+ export { TableBodyNode };
@@ -0,0 +1,17 @@
1
+ import { Node } from '../node.js';
2
+
3
+ const ALIGN = new Map([
4
+ ['center', 'fr-cell--center'],
5
+ ['right', 'fr-cell--right']
6
+ ]);
7
+
8
+ class TableCellNode extends Node {
9
+ constructor (data, tagName = 'td') {
10
+ super(data, tagName);
11
+ if (ALIGN.has(this.data?.align)) this.attributes.addClass(ALIGN.get(this.data.align));
12
+ }
13
+ }
14
+
15
+ TableCellNode.TYPE = 'tableCell';
16
+
17
+ export { TableCellNode };
@@ -0,0 +1,11 @@
1
+ import { Node } from '../node.js';
2
+
3
+ class TableHeadNode extends Node {
4
+ constructor (data) {
5
+ super(data, `thead`);
6
+ }
7
+ }
8
+
9
+ TableHeadNode.TYPE = 'tableHead';
10
+
11
+ export { TableHeadNode };
@@ -0,0 +1,16 @@
1
+ import { TableCellNode } from './table-cell-node.js';
2
+
3
+ class TableHeaderNode extends TableCellNode {
4
+ constructor (data) {
5
+ super(data, 'th');
6
+ if (this.data.scope) {
7
+ this.attributes.setAttribute('scope', this.data.scope);
8
+ if (this.data.scope === 'row') this.attributes.addClass('fr-cell--fixed');
9
+ }
10
+ if (this.data.isColumnHeader) this.attributes.setAttribute('role', 'columnheader');
11
+ }
12
+ }
13
+
14
+ TableHeaderNode.TYPE = 'tableHeader';
15
+
16
+ export { TableHeaderNode };
@@ -0,0 +1,91 @@
1
+ import { Node } from '../node.js';
2
+ import { log } from '@gouvfr/dsfr-forge';
3
+
4
+ class TableNode extends Node {
5
+ constructor (data) {
6
+ super(data);
7
+ this._caption = data.caption;
8
+ this.attributes.addClass('fr-table');
9
+ }
10
+
11
+ structure (data) {
12
+ if (!data.children.length) return data;
13
+
14
+ const thead = data.children[0];
15
+ const tbody = data.children.slice(1);
16
+
17
+ if (!thead) {
18
+ log.warn('TableNode: missing thead');
19
+ return data;
20
+ }
21
+
22
+ if (!tbody.length) {
23
+ log.warn('TableNode: missing tbody');
24
+ return data;
25
+ }
26
+
27
+ const isEmptyThead = thead.children.every(child => { return child.type === 'tableCell' && !child.children });
28
+ const hasColThead = tbody.every(child => { return child.children?.[0]?.children?.some(child => child.type === 'strong') });
29
+ const children = [];
30
+
31
+ if (isEmptyThead) {
32
+ log.warn('TableNode: thead is empty and is removed');
33
+ } else {
34
+ thead.children = thead.children.map((child, index) => ({
35
+ ...child,
36
+ type: 'tableHeader',
37
+ scope: 'col',
38
+ isColumnHeader: hasColThead && index === 0,
39
+ }));
40
+ children.push({
41
+ type: 'tableHead',
42
+ children: [thead]
43
+ });
44
+ }
45
+
46
+ if (hasColThead) {
47
+ tbody.forEach((row) => {
48
+ row.children[0] = {
49
+ ...row.children[0],
50
+ type: 'tableHeader',
51
+ scope: 'row'
52
+ }
53
+ });
54
+ }
55
+
56
+ children.push({
57
+ type: 'tableBody',
58
+ children: tbody
59
+ });
60
+
61
+ data.children = children;
62
+
63
+ return data;
64
+ }
65
+
66
+ async render () {
67
+ const caption = this._caption ? `<caption>${this._caption}</caption>` : '';
68
+ return `
69
+ <div ${this.renderAttributes()}>
70
+ <div class="fr-table__wrapper">
71
+ <div class="fr-table__container">
72
+ <div class="fr-table__content">
73
+ <table>
74
+ ${caption}
75
+ ${await this.renderChildren()}
76
+ </table>
77
+ </div>
78
+ </div>
79
+ </div>
80
+ </div>
81
+ `;
82
+ }
83
+
84
+ get caption () {
85
+ return this._caption;
86
+ }
87
+ }
88
+
89
+ TableNode.TYPE = 'table';
90
+
91
+ export { TableNode };
@@ -0,0 +1,11 @@
1
+ import { Node } from '../node.js';
2
+
3
+ class TableRowNode extends Node {
4
+ constructor (data, tagName = 'tr') {
5
+ super(data, tagName);
6
+ }
7
+ }
8
+
9
+ TableRowNode.TYPE = 'tableRow';
10
+
11
+ export { TableRowNode };
@@ -0,0 +1,128 @@
1
+ import { Node } from './node.js';
2
+ import { BlockquoteNode } from './generic/blockquote-node.js';
3
+ import { BreakNode } from './generic/break-node.js';
4
+ import { CodeNode } from './generic/code-node.js';
5
+ import { DefinitionNode } from './generic/definition-node.js';
6
+ import { EmphasisNode } from './generic/emphasis-node.js';
7
+ import { HeadingNode } from './generic/heading-node.js';
8
+ import { HtmlNode } from './generic/html-node.js';
9
+ import { ImageNode } from './generic/image-node.js';
10
+ import { ImageReferenceNode } from './generic/image-reference-node.js';
11
+ import { InlineCodeNode } from './generic/inline-code-node.js';
12
+ import { LinkNode } from './generic/link-node.js';
13
+ import { LinkReferenceNode } from './generic/link-reference-node.js';
14
+ import { ListItemNode } from './generic/list-item-node.js';
15
+ import { ListNode } from './generic/list-node.js';
16
+ import { ParagraphNode } from './generic/paragraph-node.js';
17
+ import { StrongNode } from './generic/strong-node.js';
18
+ import { TextNode } from './generic/text-node.js';
19
+ import { ThematicBreakNode } from './generic/thematic-break-node.js';
20
+ import { TableNode } from './gfm/table-node.js';
21
+ import { TableHeadNode } from './gfm/table-head-node.js';
22
+ import { TableBodyNode } from './gfm/table-body-node.js';
23
+ import { TableRowNode } from './gfm/table-row-node.js';
24
+ import { TableHeaderNode } from './gfm/table-header-node.js';
25
+ import { TableCellNode } from './gfm/table-cell-node.js';
26
+ import { NodeRoot } from './node-root.js';
27
+ import { TabNavigationContainerDirective } from './directive/doc/tab-navigation-container-directive.js';
28
+ import { StorybookLeafDirective } from './directive/doc/storybook-leaf-directive.js';
29
+ import { FigmaLeafDirective } from './directive/doc/figma-leaf-directive.js';
30
+ import { AnatomyContainerDirective } from './directive/doc/anatomy-container-directive.js';
31
+ import { PinLeafDirective } from './directive/doc/pin-leaf-directive.js';
32
+ import { AccordionContainerDirective } from './directive/doc/accordion-container-directive.js';
33
+ import { AccordionsGroupContainerDirective } from './directive/doc/accordions-group-container-directive.js';
34
+ import { GuidelineContainerDirective } from './directive/doc/guideline-container-directive.js';
35
+ import { GuidelinesContainerDirective } from './directive/doc/guidelines-container-directive.js';
36
+ import { TableContainerDirective } from './directive/doc/table-container-directive.js';
37
+ import { TabContainerDirective } from './directive/doc/tab-container-directive.js'
38
+ import { TabsContainerDirective } from './directive/doc/tabs-container-directive.js'
39
+ import { ImageTextDirective } from './directive/doc/image-text-directive.js'
40
+ import { ChangelogLeafDirective } from './directive/doc/changelog-leaf-directive.js'
41
+ import { ButtonLeafDirective } from './directive/doc/button-leaf-directive.js'
42
+
43
+
44
+ const NODES = [
45
+ NodeRoot,
46
+ BlockquoteNode,
47
+ BreakNode,
48
+ CodeNode,
49
+ DefinitionNode,
50
+ EmphasisNode,
51
+ HeadingNode,
52
+ HtmlNode,
53
+ ImageNode,
54
+ ImageReferenceNode,
55
+ InlineCodeNode,
56
+ LinkNode,
57
+ LinkReferenceNode,
58
+ ListItemNode,
59
+ ListNode,
60
+ ParagraphNode,
61
+ StrongNode,
62
+ TextNode,
63
+ ThematicBreakNode,
64
+ TableNode,
65
+ TableHeadNode,
66
+ TableBodyNode,
67
+ TableHeaderNode,
68
+ TableRowNode,
69
+ TableCellNode
70
+ ];
71
+
72
+ const nodesMap = new Map(NODES.map(Node => [Node.TYPE, Node]));
73
+
74
+ const DIRECTIVE_CONTAINERS = [
75
+ AccordionContainerDirective,
76
+ AccordionsGroupContainerDirective,
77
+ GuidelineContainerDirective,
78
+ GuidelinesContainerDirective,
79
+ TabNavigationContainerDirective,
80
+ TableContainerDirective,
81
+ TabContainerDirective,
82
+ TabsContainerDirective,
83
+ AnatomyContainerDirective
84
+ ];
85
+ const DIRECTIVE_LEAFS = [
86
+ ButtonLeafDirective,
87
+ StorybookLeafDirective,
88
+ FigmaLeafDirective,
89
+ ChangelogLeafDirective,
90
+ PinLeafDirective
91
+ ];
92
+ const DIRECTIVE_TEXTS = [
93
+ ImageTextDirective
94
+ ];
95
+ const containersMap = new Map(DIRECTIVE_CONTAINERS.map(Container => [Container.NAME, Container]));
96
+ const leafsMap = new Map(DIRECTIVE_LEAFS.map(Leaf => [Leaf.NAME, Leaf]));
97
+ const textsMap = new Map(DIRECTIVE_TEXTS.map(Text => [Text.NAME, Text]));
98
+
99
+ class NodeFactory {
100
+ populate (fragments) {
101
+ this._fragments = fragments;
102
+ }
103
+
104
+ decorate (data) {
105
+ data.fragments = this._fragments;
106
+ }
107
+
108
+ getNodeConstructor (data) {
109
+ switch (data.type) {
110
+ case 'containerDirective':
111
+ return containersMap.get(data.name);
112
+ case 'leafDirective':
113
+ return leafsMap.get(data.name);
114
+ case 'textDirective':
115
+ return textsMap.get(data.name);
116
+ }
117
+ return nodesMap.get(data.type);
118
+ }
119
+
120
+ create (data) {
121
+ const NodeConstructor = this.getNodeConstructor(data) ?? Node;
122
+ this.decorate(data);
123
+ const node = new NodeConstructor(data);
124
+ return node;
125
+ }
126
+ }
127
+
128
+ export const nodeFactory = new NodeFactory();
@@ -0,0 +1,25 @@
1
+ import { Node } from './node.js';
2
+ import { adjustHeading } from './generic/heading-node.js';
3
+
4
+ const gather = (node) => {
5
+ const nodes = node.children.map(child => gather(child)).flat();
6
+ nodes.push(node);
7
+ return nodes;
8
+ }
9
+
10
+ class NodeRoot extends Node {
11
+ constructor (data) {
12
+ super(data);
13
+ this._nodes = gather(this);
14
+ }
15
+
16
+ async render () {
17
+ adjustHeading(this._nodes.filter(node => node.type === 'heading'));
18
+
19
+ return await super.render();
20
+ }
21
+ }
22
+
23
+ NodeRoot.TYPE = 'root';
24
+
25
+ export { NodeRoot };