solarite 0.5.2 → 0.7.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/LICENSE +21 -0
- package/dist/Solarite-debug.js +2823 -1856
- package/dist/Solarite.js +2779 -1824
- package/dist/Solarite.min.js +2 -4
- package/package.json +16 -3
- package/readme.md +58 -11
- package/src/Globals.js +54 -72
- package/src/HtmlParser.js +90 -90
- package/src/MultiValueMap.js +57 -105
- package/src/NodeGroup.js +624 -470
- package/src/Path.js +224 -211
- package/src/PathToAttribValue.js +401 -261
- package/src/PathToAttribs.js +113 -80
- package/src/PathToComment.js +7 -7
- package/src/PathToComponent.js +183 -188
- package/src/PathToEvent.js +76 -64
- package/src/PathToKey.js +19 -0
- package/src/PathToNodes.js +1053 -566
- package/src/RootNodeGroup.js +120 -8
- package/src/Shell.js +570 -348
- package/src/Solarite.d.ts +134 -113
- package/src/Solarite.js +243 -286
- package/src/Template.js +195 -274
- package/src/Util.js +353 -351
- package/src/assert.js +10 -10
- package/src/assignAttributes.js +63 -0
- package/src/delve.js +55 -43
- package/src/h.js +220 -138
- package/src/jsx-dev-runtime.d.ts +1 -0
- package/src/jsx-dev-runtime.js +5 -0
- package/src/jsx-runtime.d.ts +21 -0
- package/src/jsx-runtime.js +84 -0
- package/src/jsx.js +194 -0
- package/src/toEl.js +77 -82
- package/dist/udomdiff-license.txt +0 -18
- package/src/getArg.js +0 -137
- package/src/hash.js +0 -89
- package/src/udomdiff.js +0 -176
- package/src/unused/FastLookupArray.js +0 -54
- package/src/unused/Hashes.js +0 -339
- package/src/unused/InUse.test.js +0 -92
- package/src/unused/InUseMap.js +0 -98
- package/src/unused/LinkedList.js +0 -117
- package/src/unused/LinkedList.test.js +0 -115
- package/src/unused/Misc.js +0 -13
- package/src/unused/Perf.js +0 -47
- package/src/unused/TrackedArray.js +0 -54
- package/src/unused/WeakArray.js +0 -33
- package/src/watch.js +0 -543
package/src/PathToAttribs.js
CHANGED
|
@@ -1,81 +1,114 @@
|
|
|
1
|
-
import Path from "./Path.js";
|
|
2
|
-
import
|
|
3
|
-
import assert from "./assert.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
//#
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
let
|
|
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
|
-
node.setAttribute(name,
|
|
67
|
-
this.attrNames.add(name)
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Remove old attributes.
|
|
73
|
-
for (let oldName of oldNames)
|
|
74
|
-
if (!this.attrNames.has(oldName))
|
|
75
|
-
node.removeAttribute(oldName);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
1
|
+
import Path from "./Path.js";
|
|
2
|
+
import Util from "./Util.js";
|
|
3
|
+
import assert from "./assert.js";
|
|
4
|
+
import PathToAttribValue from "./PathToAttribValue.js";
|
|
5
|
+
import PathToEvent from "./PathToEvent.js";
|
|
6
|
+
import {JsxAttr, styleToCss} from "./jsx.js";
|
|
7
|
+
|
|
8
|
+
export default class PathToAttribs extends Path {
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @type {Set<string>} Used for type=AttribType.Multiple to remember the attributes that were added. */
|
|
12
|
+
attrNames;
|
|
13
|
+
|
|
14
|
+
/** @type {boolean} Provides one or more attributes on a component. */
|
|
15
|
+
isComponent;
|
|
16
|
+
|
|
17
|
+
constructor(nodeBefore, nodeMarker) {
|
|
18
|
+
super(null, null);
|
|
19
|
+
this.nodeMarker = nodeMarker;
|
|
20
|
+
this.attrNames = new Set();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param exprs {Expr[][]} Only the first is used. */
|
|
25
|
+
apply(exprs) {
|
|
26
|
+
//#IFDEV
|
|
27
|
+
assert(Array.isArray(exprs));
|
|
28
|
+
//#ENDIF
|
|
29
|
+
this.applySingle(exprs[0]);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param expr {Expr} */
|
|
34
|
+
applySingle(expr) {
|
|
35
|
+
let node = this.nodeMarker;
|
|
36
|
+
|
|
37
|
+
// JSX Tier 1 whole-attribute hole: `<a ` + jsxAttr("href", v) + `>`.
|
|
38
|
+
if (expr instanceof JsxAttr)
|
|
39
|
+
return this.applyJsxAttr(expr);
|
|
40
|
+
|
|
41
|
+
if (Array.isArray(expr))
|
|
42
|
+
expr = expr.flat().join(' '); // flat and join so we can accept arrays of arrays of strings.
|
|
43
|
+
|
|
44
|
+
// Add new attributes
|
|
45
|
+
let oldNames = this.attrNames;
|
|
46
|
+
this.attrNames = new Set();
|
|
47
|
+
if (expr) {
|
|
48
|
+
if (typeof expr === 'function')
|
|
49
|
+
expr = expr();
|
|
50
|
+
|
|
51
|
+
// Attribute as name: value object.
|
|
52
|
+
if (typeof expr === 'object') {
|
|
53
|
+
for (let name in expr) {
|
|
54
|
+
let value = expr[name];
|
|
55
|
+
if (value === undefined || value === false || value === null)
|
|
56
|
+
continue;
|
|
57
|
+
node.setAttribute(name, value);
|
|
58
|
+
this.attrNames.add(name)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Attributes as string
|
|
63
|
+
else {
|
|
64
|
+
let attribs = Util.splitAttribs(expr);
|
|
65
|
+
for (let name in attribs) {
|
|
66
|
+
node.setAttribute(name, attribs[name]);
|
|
67
|
+
this.attrNames.add(name);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Remove old attributes.
|
|
73
|
+
for (let oldName of oldNames)
|
|
74
|
+
if (!this.attrNames.has(oldName))
|
|
75
|
+
node.removeAttribute(oldName);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Apply a single JSX jsxAttr(name, value) pair. We delegate to a cached PathToEvent or
|
|
81
|
+
* PathToAttribValue sub-path so events, html properties, two-way binding, booleans, and
|
|
82
|
+
* contenteditable all behave exactly as `name=${value}` in a tagged template. The attr name
|
|
83
|
+
* at a given hole is a compile-time literal, so the sub-path is stable across renders.
|
|
84
|
+
* @param attr {JsxAttr} */
|
|
85
|
+
applyJsxAttr(attr) {
|
|
86
|
+
let name = attr.name;
|
|
87
|
+
if (name === 'key') // Lifted onto template.key by jsxTemplate(); never rendered as an attribute.
|
|
88
|
+
return;
|
|
89
|
+
let value = attr.value;
|
|
90
|
+
|
|
91
|
+
let sub = this.jsxSub;
|
|
92
|
+
if (sub === undefined || this.jsxSubName !== name) {
|
|
93
|
+
let node = this.nodeMarker;
|
|
94
|
+
if (Util.isEvent(name))
|
|
95
|
+
sub = new PathToEvent(null, node, name, null);
|
|
96
|
+
else {
|
|
97
|
+
sub = new PathToAttribValue(null, node, name, null);
|
|
98
|
+
sub.isHtmlProperty = Util.isHtmlProp(node, name);
|
|
99
|
+
}
|
|
100
|
+
sub.isComponentAttrib = this.isComponentAttrib;
|
|
101
|
+
this.jsxSub = sub;
|
|
102
|
+
this.jsxSubName = name;
|
|
103
|
+
}
|
|
104
|
+
sub.nodeMarker = this.nodeMarker;
|
|
105
|
+
sub.parentNg = this.parentNg;
|
|
106
|
+
if (name === 'style')
|
|
107
|
+
value = styleToCss(value);
|
|
108
|
+
sub.applySingle(value);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
getExpressionCount() { return 1 }
|
|
113
|
+
getValue(exprs) { return exprs[0]; }
|
|
81
114
|
}
|
package/src/PathToComment.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import Path from "./Path.js";
|
|
2
|
-
|
|
3
|
-
// This Path renders nothing.
|
|
4
|
-
export default class PathToComment extends Path {
|
|
5
|
-
constructor(nodeBefore, nodeMarker) {
|
|
6
|
-
super(nodeBefore, nodeMarker);
|
|
7
|
-
}
|
|
1
|
+
import Path from "./Path.js";
|
|
2
|
+
|
|
3
|
+
// This Path renders nothing.
|
|
4
|
+
export default class PathToComment extends Path {
|
|
5
|
+
constructor(nodeBefore, nodeMarker) {
|
|
6
|
+
super(nodeBefore, nodeMarker);
|
|
7
|
+
}
|
|
8
8
|
}
|
package/src/PathToComponent.js
CHANGED
|
@@ -1,189 +1,184 @@
|
|
|
1
|
-
import Path from "./Path.js";
|
|
2
|
-
import Util from "./Util.js";
|
|
3
|
-
import delve from "./delve.js";
|
|
4
|
-
import assert from "./assert.js";
|
|
5
|
-
import PathToAttribValue from "./PathToAttribValue.js";
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
//#
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
result.push(current)
|
|
185
|
-
current = current.nextSibling
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return result;
|
|
1
|
+
import Path from "./Path.js";
|
|
2
|
+
import Util from "./Util.js";
|
|
3
|
+
import delve, {isDelvePath} from "./delve.js";
|
|
4
|
+
import assert from "./assert.js";
|
|
5
|
+
import PathToAttribValue from "./PathToAttribValue.js";
|
|
6
|
+
import PathToKey from "./PathToKey.js";
|
|
7
|
+
import Globals from "./Globals.js";
|
|
8
|
+
import {getObjectHash} from "./Template.js";
|
|
9
|
+
|
|
10
|
+
export default class PathToComponent extends Path {
|
|
11
|
+
|
|
12
|
+
/** @type {PathToAttribValue[]} Paths to dynamics attributes that will be set on the component.*/
|
|
13
|
+
attribPaths;
|
|
14
|
+
|
|
15
|
+
/** @type {string} Hash of the exprs from the previous apply(), used to detect changes. */
|
|
16
|
+
appliedExprsHash;
|
|
17
|
+
|
|
18
|
+
constructor(nodeBefore, nodeMarker) {
|
|
19
|
+
super(null, nodeMarker);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Call render() on the component pointed to by this Path.
|
|
24
|
+
* And instantiate it (from a -solarite-placeholder element) if it hasn't been done yet.
|
|
25
|
+
* @param exprs {Expr[][]} Expressions to evaluate for each attribute to pass to the constructor.
|
|
26
|
+
* This is different than other Path.apply() functions which only receive Expr[] and not Expr[][].
|
|
27
|
+
* Because here we're receiving an array of arrays of expressions, one for each dynamic attribute. */
|
|
28
|
+
apply(exprs) {
|
|
29
|
+
//#IFDEV
|
|
30
|
+
assert(Array.isArray(exprs));
|
|
31
|
+
assert(!exprs.length || Array.isArray(exprs[0]));
|
|
32
|
+
//#ENDIF
|
|
33
|
+
|
|
34
|
+
//#IFDEV
|
|
35
|
+
assert(exprs.length === this.attribPaths.length);
|
|
36
|
+
//#ENDIF
|
|
37
|
+
|
|
38
|
+
// Deep comparison via hashing, so mutating a field on the same object counts as changed.
|
|
39
|
+
let newHash = getObjectHash(exprs);
|
|
40
|
+
let changed = newHash !== this.appliedExprsHash;
|
|
41
|
+
this.appliedExprsHash = newHash;
|
|
42
|
+
|
|
43
|
+
let el = this.nodeMarker;
|
|
44
|
+
|
|
45
|
+
// 1. Attributes
|
|
46
|
+
let attribs = Util.attribsToObject(el, '_is');
|
|
47
|
+
for (let i=0, attribPath; attribPath = this.attribPaths[i]; i++) {
|
|
48
|
+
if (attribPath instanceof PathToKey) // The list key is never a component arg.
|
|
49
|
+
continue;
|
|
50
|
+
if (attribPath instanceof PathToAttribValue) {
|
|
51
|
+
let name = Util.dashesToCamel(attribPath.attrName);
|
|
52
|
+
|
|
53
|
+
// Resolve two way bindimg path before we pass it to the component.
|
|
54
|
+
let value = attribPath.getValue(exprs[i]);
|
|
55
|
+
if (!attribPath.attrValue && isDelvePath(value))
|
|
56
|
+
value = delve(value[0], value.slice(1));
|
|
57
|
+
|
|
58
|
+
attribs[name] = value;
|
|
59
|
+
}
|
|
60
|
+
else { // PathToAttribs
|
|
61
|
+
let val = attribPath.getValue(exprs[i]);
|
|
62
|
+
if (typeof val === 'object')
|
|
63
|
+
for (let name in val)
|
|
64
|
+
attribs[Util.dashesToCamel(name)] = val[name];
|
|
65
|
+
else if (typeof val === 'string') {
|
|
66
|
+
let attrs = Util.splitAttribs(val);
|
|
67
|
+
for (let name in attrs)
|
|
68
|
+
attribs[Util.dashesToCamel(name)] = attrs[name];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 2. Instantiate component on first time.
|
|
74
|
+
let isAttrib = el.getAttribute('_is');
|
|
75
|
+
if (el.tagName.endsWith('-SOLARITE-PLACEHOLDER') || isAttrib) {
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
// 2a. Instantiate component
|
|
79
|
+
let tagName = (isAttrib || el.tagName.slice(0, -21)).toLowerCase(); // Remove -SOLARITE-PLACEHOLDER
|
|
80
|
+
let Constructor = customElements.get(tagName);
|
|
81
|
+
if (!Constructor)
|
|
82
|
+
throw new Error(`Must call customElements.define('${tagName}', Class) before using it.`);
|
|
83
|
+
|
|
84
|
+
Globals.currentSlotChildren = [...el.childNodes]; // TODO: Does this need to be a stack?
|
|
85
|
+
let newEl = new Constructor(attribs);
|
|
86
|
+
|
|
87
|
+
// 2b. Copy attributes over.
|
|
88
|
+
if (isAttrib) {
|
|
89
|
+
newEl.setAttribute('is', isAttrib);
|
|
90
|
+
// el.removeAttribute('_is');
|
|
91
|
+
}
|
|
92
|
+
for (let attrib of el.attributes)
|
|
93
|
+
if (attrib.name !== '_is')
|
|
94
|
+
newEl.setAttribute(attrib.name, attrib.value);
|
|
95
|
+
|
|
96
|
+
// Set dynamic attributes if they are primitive types.
|
|
97
|
+
for (let name in attribs) {
|
|
98
|
+
let val = attribs[name];
|
|
99
|
+
let valType = typeof val;
|
|
100
|
+
if (valType === 'boolean') {
|
|
101
|
+
if (val !== false && val !== undefined && val !== null) // Util.isFalsy() inlined
|
|
102
|
+
newEl.setAttribute(name, '');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// If type is a non-boolean primitive, set the attribute value.
|
|
106
|
+
else if (valType==='string' || valType === 'number' || valType==='bigint')
|
|
107
|
+
newEl.setAttribute(name, val);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
// 2c. If an id pointed at the placeholder, update it to point to the new element.
|
|
112
|
+
let id = newEl.getAttribute('data-id') || newEl.getAttribute('id');
|
|
113
|
+
if (id)
|
|
114
|
+
delve(this.parentNg.getRootNode(), id.split(/\./g), newEl);
|
|
115
|
+
|
|
116
|
+
// 2d. Update paths to use replaced element.
|
|
117
|
+
let ng = this.parentNg;
|
|
118
|
+
this.nodeMarker = newEl;
|
|
119
|
+
for (let path of ng.paths) {
|
|
120
|
+
if (path.nodeMarker === el)
|
|
121
|
+
path.nodeMarker = newEl;
|
|
122
|
+
if (path.nodeBefore === el)
|
|
123
|
+
path.nodeBefore = newEl;
|
|
124
|
+
}
|
|
125
|
+
if (ng.startNode === el)
|
|
126
|
+
ng.startNode = newEl;
|
|
127
|
+
if (ng.endNode === el)
|
|
128
|
+
ng.endNode = newEl;
|
|
129
|
+
|
|
130
|
+
// 2f. Call render() if it wasn't called by the constructor.
|
|
131
|
+
// This must happen before we add it to the DOM which can trigger connectedCallback() -> renderFirstTime()
|
|
132
|
+
// Because that path renders it without the attribute expressions.
|
|
133
|
+
if (typeof newEl.render === 'function' && !Globals.rendered.has(newEl))
|
|
134
|
+
newEl.render(attribs, true);
|
|
135
|
+
|
|
136
|
+
// 2g. Update attribute paths to use the new element and re-apply them.
|
|
137
|
+
for (let i=0, attribPath; attribPath = this.attribPaths[i]; i++) {
|
|
138
|
+
attribPath.parentNg = this.parentNg;
|
|
139
|
+
attribPath.nodeMarker = newEl;
|
|
140
|
+
attribPath.apply(exprs[i]);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 2e. Swap it to the DOM.
|
|
144
|
+
el.replaceWith(newEl);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// 2f. Render
|
|
148
|
+
else if (typeof el.render === 'function')
|
|
149
|
+
el.render(attribs, changed);
|
|
150
|
+
|
|
151
|
+
Globals.currentSlotChildren = null;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @param newRoot {HTMLElement}
|
|
156
|
+
* @param pathOffset {int}
|
|
157
|
+
* @return {Path} */
|
|
158
|
+
clone(newRoot, pathOffset=0) {
|
|
159
|
+
/*#IFDEV*/this.verify();/*#ENDIF*/
|
|
160
|
+
let nodeMarker = this.getNewNodeMarker(newRoot, pathOffset);
|
|
161
|
+
let result = new PathToComponent(null, nodeMarker);
|
|
162
|
+
result.attribPaths = this.attribPaths.map(path => path.clone(newRoot, pathOffset));
|
|
163
|
+
|
|
164
|
+
//#IFDEV
|
|
165
|
+
result.verify();
|
|
166
|
+
//#ENDIF
|
|
167
|
+
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
getExpressionCount() { return 0 }
|
|
172
|
+
|
|
173
|
+
//#IFDEV
|
|
174
|
+
verify() {
|
|
175
|
+
super.verify();
|
|
176
|
+
assert(this.nodeMarker.nodeType === Node.ELEMENT_NODE);
|
|
177
|
+
assert(this.nodeMarker.tagName.includes('-') || this.nodeMarker.hasAttribute('is') || this.nodeMarker.hasAttribute('_is'));
|
|
178
|
+
if (this.attribPaths)
|
|
179
|
+
for (let path of this.attribPaths)
|
|
180
|
+
path.verify();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
//#ENDIF
|
|
189
184
|
}
|