structured-fw 0.8.71 → 0.9.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.
|
@@ -137,14 +137,13 @@ export class Component extends EventEmitter {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
async initChildren(passData) {
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const
|
|
144
|
-
const component = this.document.application.components.getByName(childNode.tagName);
|
|
140
|
+
const potentialComponents = this.dom.components();
|
|
141
|
+
for (let i = 0; i < potentialComponents.length; i++) {
|
|
142
|
+
const potentialComponent = potentialComponents[i];
|
|
143
|
+
const component = this.document.application.components.getByName(potentialComponent.tagName);
|
|
145
144
|
if (component) {
|
|
146
|
-
const child = new Component(component.name,
|
|
147
|
-
await child.init(
|
|
145
|
+
const child = new Component(component.name, potentialComponent, this, false);
|
|
146
|
+
await child.init(potentialComponent.outerHTML, passData);
|
|
148
147
|
this.children.push(child);
|
|
149
148
|
}
|
|
150
149
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DOMFragment } from "./DOMFragment.js";
|
|
1
2
|
type DOMNodeAttribute = {
|
|
2
3
|
name: string;
|
|
3
4
|
value: string | true;
|
|
@@ -9,20 +10,27 @@ type JSONNode = {
|
|
|
9
10
|
strings: Array<string>;
|
|
10
11
|
};
|
|
11
12
|
export declare const selfClosingTags: ReadonlyArray<string>;
|
|
13
|
+
export declare const recognizedHTMLTags: ReadonlyArray<string>;
|
|
12
14
|
export declare class DOMNode {
|
|
13
15
|
tagName: string;
|
|
16
|
+
root: DOMFragment;
|
|
14
17
|
parentNode: DOMNode | null;
|
|
15
18
|
children: Array<DOMNode | string>;
|
|
19
|
+
isRoot: boolean;
|
|
16
20
|
attributes: Array<DOMNodeAttribute>;
|
|
17
21
|
attributeMap: Record<string, DOMNodeAttribute>;
|
|
18
22
|
style: Partial<CSSStyleDeclaration>;
|
|
19
23
|
selfClosing: boolean;
|
|
20
|
-
|
|
24
|
+
potentialComponentChildren: Record<string, Array<DOMNode>>;
|
|
25
|
+
constructor(root: DOMFragment | null, parentNode: DOMNode | null, tagName: string);
|
|
21
26
|
appendChild(node: DOMNode | string): void;
|
|
22
27
|
setAttribute(attributeName: string, attributeValue: string | true): void;
|
|
23
28
|
hasAttribute(attributeName: string): boolean;
|
|
24
29
|
queryByTagName(...tagNames: Array<string>): Array<DOMNode>;
|
|
25
30
|
queryByHasAttribute(...attributeNames: Array<string>): Array<DOMNode>;
|
|
31
|
+
isPotentialComponent(): boolean;
|
|
32
|
+
registerPotentialComponent(node: DOMNode): void;
|
|
33
|
+
components(): Array<DOMNode>;
|
|
26
34
|
get innerHTML(): string;
|
|
27
35
|
set innerHTML(html: string);
|
|
28
36
|
get outerHTML(): string;
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
import { HTMLParser } from "./HTMLParser.js";
|
|
2
2
|
export const selfClosingTags = ['br', 'hr', 'input', 'img', 'link', 'meta', 'source', 'embed', 'path', 'area'];
|
|
3
|
+
export const recognizedHTMLTags = ['body', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'b', 'i', 'a', 'em', 'strong', 'br', 'hr', 'abbr', 'address', 'bdi', 'bdo', 'blockquote', 'cite', 'code', 'del', 'dfn', 'ins', 'kbd', 'mark', 'pre', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'small', 'span', 'sub', 'sup', 'time', 'u', 'var', 'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'img', 'area', 'map', 'object', 'param', 'picture', 'table', 'tr', 'td', 'th', 'caption', 'colgroup', 'col', 'form', 'input', 'label', 'select', 'option', 'textarea', 'button', 'fieldset', 'legend', 'datalist', 'output', 'iframe', 'audio', 'video', 'source', 'track', 'script', 'noscript', 'div', 'nav', 'aside', 'article', 'section', 'main', 'canvas', 'details', 'dialog', 'embed', 'figure', 'figcaption', 'hgroup', 'meter', 'progress', 'template'];
|
|
3
4
|
export class DOMNode {
|
|
4
|
-
constructor(tagName) {
|
|
5
|
+
constructor(root, parentNode, tagName) {
|
|
5
6
|
this.parentNode = null;
|
|
6
7
|
this.children = [];
|
|
7
8
|
this.attributes = [];
|
|
8
9
|
this.attributeMap = {};
|
|
9
10
|
this.style = {};
|
|
11
|
+
this.potentialComponentChildren = {};
|
|
12
|
+
this.root = root === null ? this : root;
|
|
13
|
+
this.isRoot = root === null;
|
|
14
|
+
this.parentNode = parentNode;
|
|
10
15
|
this.tagName = tagName;
|
|
11
16
|
this.selfClosing = selfClosingTags.includes(tagName);
|
|
17
|
+
if (this.isPotentialComponent()) {
|
|
18
|
+
this.registerPotentialComponent(this);
|
|
19
|
+
}
|
|
12
20
|
}
|
|
13
21
|
appendChild(node) {
|
|
14
22
|
if (typeof node !== 'string') {
|
|
@@ -63,6 +71,27 @@ export class DOMNode {
|
|
|
63
71
|
}
|
|
64
72
|
return nodes;
|
|
65
73
|
}
|
|
74
|
+
isPotentialComponent() {
|
|
75
|
+
return !recognizedHTMLTags.includes(this.tagName.toLowerCase());
|
|
76
|
+
}
|
|
77
|
+
registerPotentialComponent(node) {
|
|
78
|
+
if (this.parentNode !== null) {
|
|
79
|
+
if (this.parentNode.isRoot || this.parentNode.isPotentialComponent()) {
|
|
80
|
+
if (!(node.tagName in this.parentNode.potentialComponentChildren)) {
|
|
81
|
+
this.parentNode.potentialComponentChildren[node.tagName] = [];
|
|
82
|
+
}
|
|
83
|
+
this.parentNode.potentialComponentChildren[node.tagName].push(node);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
this.parentNode.registerPotentialComponent(node);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
components() {
|
|
91
|
+
return Object.values(this.potentialComponentChildren).reduce((prev, curr) => {
|
|
92
|
+
return prev.concat(curr);
|
|
93
|
+
}, []);
|
|
94
|
+
}
|
|
66
95
|
get innerHTML() {
|
|
67
96
|
return this.children.reduce((html, child) => {
|
|
68
97
|
if (typeof child === 'string') {
|
|
@@ -76,6 +105,7 @@ export class DOMNode {
|
|
|
76
105
|
set innerHTML(html) {
|
|
77
106
|
const fragment = new HTMLParser(html).dom();
|
|
78
107
|
this.children = fragment.children;
|
|
108
|
+
this.potentialComponentChildren = fragment.potentialComponentChildren;
|
|
79
109
|
}
|
|
80
110
|
get outerHTML() {
|
|
81
111
|
const attributes = this.attributes.reduce((attributes, attribute) => {
|
|
@@ -64,7 +64,7 @@ export class HTMLParser {
|
|
|
64
64
|
if (this.tokenCurrent.length === 0) {
|
|
65
65
|
throw this.error(`Found an empty HTML tag <>`);
|
|
66
66
|
}
|
|
67
|
-
const node = new DOMNode(this.tokenCurrent);
|
|
67
|
+
const node = new DOMNode(this.fragment, this.context, this.tokenCurrent);
|
|
68
68
|
this.context.appendChild(node);
|
|
69
69
|
this.state = 'idle';
|
|
70
70
|
this.tokenCurrent = '';
|
|
@@ -79,7 +79,7 @@ export class HTMLParser {
|
|
|
79
79
|
return true;
|
|
80
80
|
}
|
|
81
81
|
this.state = 'attributeName';
|
|
82
|
-
const node = new DOMNode(this.tokenCurrent);
|
|
82
|
+
const node = new DOMNode(this.fragment, this.context, this.tokenCurrent);
|
|
83
83
|
this.context.appendChild(node);
|
|
84
84
|
this.tokenCurrent = '';
|
|
85
85
|
if (!node.selfClosing) {
|
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"main": "build/index",
|
|
17
|
-
"version": "0.
|
|
17
|
+
"version": "0.9.0",
|
|
18
18
|
"scripts": {
|
|
19
19
|
"develop": "tsc --watch",
|
|
20
20
|
"startDev": "cd build && nodemon --watch '../app/**/*' --watch '../build/**/*' -e js,html,css index.js",
|