@webtides/element-js 1.0.0-alpha.9 → 1.1.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.
- package/CHANGELOG.md +369 -0
- package/README.md +3 -3
- package/docs/README.md +70 -89
- package/docs/concepts/classes.md +37 -66
- package/docs/concepts/hierarchy.md +29 -31
- package/docs/concepts/lifecycle.md +9 -23
- package/docs/concepts/reactivity.md +1 -3
- package/docs/features/computed-properties.md +13 -16
- package/docs/features/dependency-injection-context-protocol.md +75 -87
- package/docs/features/global-styles.md +1 -1
- package/docs/features/methods.md +14 -15
- package/docs/features/properties.md +21 -33
- package/docs/features/refs.md +23 -31
- package/docs/features/renderless.md +31 -37
- package/docs/features/store.md +63 -78
- package/docs/features/templates.md +4 -1
- package/docs/features/watch.md +28 -35
- package/docs/getting-started/upgrade-to-v1.md +16 -0
- package/docs/guide/guide.md +10 -22
- package/index.js +29 -2
- package/package.json +62 -62
- package/src/BaseElement.js +637 -632
- package/src/StyledElement.js +104 -104
- package/src/TemplateElement.js +53 -58
- package/src/dom-parts/AttributePart.js +116 -116
- package/src/dom-parts/ChildNodePart.js +288 -288
- package/src/dom-parts/NodePart.js +27 -27
- package/src/dom-parts/Part.js +6 -6
- package/src/dom-parts/TemplatePart.js +119 -119
- package/src/dom-parts/TemplateResult.js +274 -267
- package/src/dom-parts/directives.js +105 -48
- package/src/dom-parts/html.js +2 -2
- package/src/dom-parts/render.js +6 -1
- package/src/util/AttributeParser.js +47 -47
- package/src/util/DOMHelper.js +190 -191
- package/src/util/Directive.js +31 -24
- package/src/util/GlobalStylesStore.js +56 -49
- package/src/util/SerializeStateHelper.js +56 -56
- package/src/util/Store.js +174 -174
- package/src/util/defineElement.js +5 -5
- package/src/util/toString.js +5 -5
|
@@ -5,34 +5,34 @@ import { isObjectLike } from '../util/AttributeParser.js';
|
|
|
5
5
|
* For updating a directive on a node
|
|
6
6
|
*/
|
|
7
7
|
export class NodePart extends Part {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
/** @type {Node} */
|
|
9
|
+
node = undefined;
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
/** @type {Directive} */
|
|
12
|
+
directive = undefined;
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
14
|
+
/**
|
|
15
|
+
* @param {Node} node
|
|
16
|
+
* @param {() => {}} initialValue
|
|
17
|
+
*/
|
|
18
|
+
constructor(node, initialValue) {
|
|
19
|
+
if (!isObjectLike(initialValue) && !initialValue.directiveClass) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
'NodePart: value is not a wrapped directive function. You must wrap you custom directive class with the defineDirective function.',
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
super();
|
|
25
|
+
node.__part = this; // add Part to comment node for debugging in the browser
|
|
26
|
+
this.node = node.nextElementSibling;
|
|
27
|
+
const { directiveClass, values } = initialValue;
|
|
28
|
+
this.directive = new directiveClass(node.nextElementSibling);
|
|
29
|
+
}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
/**
|
|
32
|
+
* @param {() => {}} value
|
|
33
|
+
*/
|
|
34
|
+
update(value) {
|
|
35
|
+
const { directiveClass, values } = value;
|
|
36
|
+
this.directive.update(...values);
|
|
37
|
+
}
|
|
38
38
|
}
|
package/src/dom-parts/Part.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* @abstract
|
|
3
3
|
*/
|
|
4
4
|
export class Part {
|
|
5
|
-
|
|
5
|
+
processor = undefined;
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
/**
|
|
8
|
+
* @abstract
|
|
9
|
+
* @param {TemplateResult | any[] | any} value
|
|
10
|
+
*/
|
|
11
|
+
update(value) {}
|
|
12
12
|
}
|
|
@@ -12,123 +12,123 @@ const partsCache = new WeakMap();
|
|
|
12
12
|
const fragmentsCache = new WeakMap();
|
|
13
13
|
|
|
14
14
|
export class TemplatePart extends Part {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
15
|
+
/** @type {Part[]} */
|
|
16
|
+
parts = [];
|
|
17
|
+
|
|
18
|
+
/** @type {TemplateStringsArray} */
|
|
19
|
+
strings = undefined;
|
|
20
|
+
|
|
21
|
+
/** @type {Node[]} */
|
|
22
|
+
childNodes = [];
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {Node} startNode - the start comment marker node
|
|
26
|
+
* @param {TemplateResult} value
|
|
27
|
+
*/
|
|
28
|
+
constructor(startNode, value) {
|
|
29
|
+
if (startNode && startNode?.nodeType !== COMMENT_NODE) {
|
|
30
|
+
throw new Error('TemplatePart: startNode is not a comment node');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
super();
|
|
34
|
+
|
|
35
|
+
let serverSideRendered = false;
|
|
36
|
+
if (startNode) {
|
|
37
|
+
startNode.__part = this; // add Part to comment node for debugging in the browser
|
|
38
|
+
|
|
39
|
+
const placeholder = startNode.data;
|
|
40
|
+
const childNodes = [startNode];
|
|
41
|
+
let childNode = startNode.nextSibling;
|
|
42
|
+
while (childNode && childNode.data !== `/${placeholder}`) {
|
|
43
|
+
childNodes.push(childNode);
|
|
44
|
+
childNode = childNode.nextSibling;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const endNode = childNode;
|
|
48
|
+
childNodes.push(endNode);
|
|
49
|
+
|
|
50
|
+
// if not SSRed, childNodes will only ever have two comment nodes, the start and the end marker
|
|
51
|
+
if (childNodes.length > 2) {
|
|
52
|
+
serverSideRendered = true;
|
|
53
|
+
this.childNodes = childNodes;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
this.parseValue(value);
|
|
58
|
+
|
|
59
|
+
if (!serverSideRendered) {
|
|
60
|
+
this.updateParts(value.values);
|
|
61
|
+
// We need a childNodes list that is NOT live so that we don't loose elements when they get removed from the dom and we can (re)add them back in later.
|
|
62
|
+
this.childNodes = [...this.childNodes];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {TemplateResult} value
|
|
68
|
+
*/
|
|
69
|
+
update(value) {
|
|
70
|
+
this.parseValue(value);
|
|
71
|
+
this.updateParts(value.values);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @param {any[]} values
|
|
76
|
+
*/
|
|
77
|
+
updateParts(values) {
|
|
78
|
+
for (let index = 0; index < values.length; index++) {
|
|
79
|
+
this.parts[index]?.update(values[index]);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @param {TemplateResult} templateResult
|
|
85
|
+
*/
|
|
86
|
+
parseValue(templateResult) {
|
|
87
|
+
if (this.strings !== templateResult.strings) {
|
|
88
|
+
if (this.childNodes.length === 0) {
|
|
89
|
+
let fragment = fragmentsCache.get(templateResult.strings);
|
|
90
|
+
if (!fragment) {
|
|
91
|
+
fragment = this.parseFragment(templateResult);
|
|
92
|
+
fragmentsCache.set(templateResult.strings, fragment);
|
|
93
|
+
}
|
|
94
|
+
const importedFragment = globalThis.document?.importNode(fragment, true);
|
|
95
|
+
this.childNodes = importedFragment.childNodes;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
let parts = partsCache.get(templateResult.strings);
|
|
99
|
+
if (!parts) {
|
|
100
|
+
parts = templateResult.parseParts(this.childNodes);
|
|
101
|
+
partsCache.set(templateResult.strings, parts);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
this.parts = parts
|
|
105
|
+
.map((part) => {
|
|
106
|
+
// We currently need the path because the fragment will be cloned via importNode and therefore the node will be a different one
|
|
107
|
+
part.node = part.path.reduceRight(({ childNodes }, i) => childNodes[i], this);
|
|
108
|
+
return part;
|
|
109
|
+
})
|
|
110
|
+
.map((part, index) => {
|
|
111
|
+
if (part.type === 'node') {
|
|
112
|
+
return new ChildNodePart(part.node, templateResult.values[index]);
|
|
113
|
+
}
|
|
114
|
+
if (part.type === 'attribute') {
|
|
115
|
+
return new AttributePart(part.node, part.name, part.initialValue);
|
|
116
|
+
}
|
|
117
|
+
if (part.type === 'directive') {
|
|
118
|
+
return new NodePart(part.node, templateResult.values[index]);
|
|
119
|
+
}
|
|
120
|
+
throw `cannot map part: ${part}`;
|
|
121
|
+
});
|
|
122
|
+
this.strings = templateResult.strings;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* @param {TemplateResult} templateResult
|
|
128
|
+
* @return {DocumentFragment}
|
|
129
|
+
*/
|
|
130
|
+
parseFragment(templateResult) {
|
|
131
|
+
const templateString = templateResult.templateString;
|
|
132
|
+
return convertStringToTemplate(templateString);
|
|
133
|
+
}
|
|
134
134
|
}
|