@xtia/jel 0.6.3 → 0.6.4
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/internal/element.js +66 -24
- package/internal/types.d.ts +4 -4
- package/package.json +1 -1
package/internal/element.js
CHANGED
|
@@ -2,7 +2,7 @@ import { attribsProxy, eventsProxy, styleProxy } from "./proxy";
|
|
|
2
2
|
import { entityDataSymbol, isContent, isJelEntity } from "./util";
|
|
3
3
|
const elementWrapCache = new WeakMap();
|
|
4
4
|
const recursiveAppend = (parent, c) => {
|
|
5
|
-
if (c === null)
|
|
5
|
+
if (c === null || c === undefined)
|
|
6
6
|
return;
|
|
7
7
|
if (Array.isArray(c)) {
|
|
8
8
|
c.forEach(item => recursiveAppend(parent, item));
|
|
@@ -52,8 +52,9 @@ function createElement(tag, descriptor = {}) {
|
|
|
52
52
|
domElement.setAttribute(k, v === true ? k : v);
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
|
-
if (
|
|
56
|
-
|
|
55
|
+
if ("content" in descriptor) {
|
|
56
|
+
ent.content = descriptor.content;
|
|
57
|
+
}
|
|
57
58
|
if (descriptor.style) {
|
|
58
59
|
ent.style(descriptor.style);
|
|
59
60
|
}
|
|
@@ -127,6 +128,9 @@ function observeMutations() {
|
|
|
127
128
|
subtree: true
|
|
128
129
|
});
|
|
129
130
|
}
|
|
131
|
+
function isReactiveSource(value) {
|
|
132
|
+
return typeof value == "object" && value && ("listen" in value || "subscribe" in value);
|
|
133
|
+
}
|
|
130
134
|
function getWrappedElement(element) {
|
|
131
135
|
if (!elementWrapCache.has(element)) {
|
|
132
136
|
const setCSSVariable = (k, v) => {
|
|
@@ -137,53 +141,69 @@ function getWrappedElement(element) {
|
|
|
137
141
|
element.style.setProperty("--" + k, v);
|
|
138
142
|
}
|
|
139
143
|
};
|
|
140
|
-
const
|
|
141
|
-
|
|
144
|
+
const listeners = {
|
|
145
|
+
style: {},
|
|
146
|
+
cssVariable: {},
|
|
147
|
+
content: {},
|
|
148
|
+
};
|
|
149
|
+
function addListener(type, prop, source) {
|
|
150
|
+
const set = {
|
|
151
|
+
style: (v) => element.style[prop] = v,
|
|
152
|
+
cssVariable: (v) => setCSSVariable(prop, v),
|
|
153
|
+
content: (v) => {
|
|
154
|
+
element.innerHTML = "";
|
|
155
|
+
recursiveAppend(element, v);
|
|
156
|
+
}
|
|
157
|
+
}[type];
|
|
142
158
|
const subscribe = "subscribe" in source
|
|
143
|
-
? () => source.subscribe(
|
|
144
|
-
: () => source.listen(
|
|
145
|
-
|
|
159
|
+
? () => source.subscribe(set)
|
|
160
|
+
: () => source.listen(set);
|
|
161
|
+
listeners[type][prop] = {
|
|
146
162
|
subscribe,
|
|
147
163
|
unsubscribe: element.isConnected ? subscribe() : null,
|
|
148
164
|
};
|
|
149
165
|
if (!elementMutationMap.has(element)) {
|
|
150
166
|
elementMutationMap.set(element, {
|
|
151
167
|
add: () => {
|
|
152
|
-
Object.values(
|
|
168
|
+
Object.values(listeners).forEach(group => {
|
|
169
|
+
Object.values(group).forEach(l => { var _a; return l.unsubscribe = (_a = l.subscribe) === null || _a === void 0 ? void 0 : _a.call(l); });
|
|
170
|
+
});
|
|
153
171
|
},
|
|
154
172
|
remove: () => {
|
|
155
|
-
Object.values(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
173
|
+
Object.values(listeners).forEach(group => {
|
|
174
|
+
Object.values(group).forEach(l => {
|
|
175
|
+
var _a;
|
|
176
|
+
(_a = l.unsubscribe) === null || _a === void 0 ? void 0 : _a.call(l);
|
|
177
|
+
l.unsubscribe = null;
|
|
178
|
+
});
|
|
159
179
|
});
|
|
160
180
|
}
|
|
161
181
|
});
|
|
162
182
|
}
|
|
163
183
|
observeMutations();
|
|
164
184
|
}
|
|
165
|
-
function
|
|
166
|
-
if (
|
|
167
|
-
|
|
185
|
+
function removeListener(type, prop) {
|
|
186
|
+
if (listeners[type][prop].unsubscribe) {
|
|
187
|
+
listeners[type][prop].unsubscribe();
|
|
168
188
|
}
|
|
169
|
-
delete
|
|
170
|
-
if (Object.keys(
|
|
189
|
+
delete listeners[type][prop];
|
|
190
|
+
if (!Object.keys(listeners).some(group => Object.keys(group).length == 0)) {
|
|
171
191
|
elementMutationMap.delete(element);
|
|
172
192
|
}
|
|
173
193
|
}
|
|
174
194
|
function setStyle(prop, value) {
|
|
175
|
-
if (
|
|
176
|
-
|
|
195
|
+
if (listeners.style[prop])
|
|
196
|
+
removeListener("style", prop);
|
|
177
197
|
if (typeof value == "object" && value) {
|
|
178
198
|
if ("listen" in value || "subscribe" in value) {
|
|
179
|
-
|
|
199
|
+
addListener("style", prop, value);
|
|
180
200
|
return;
|
|
181
201
|
}
|
|
182
202
|
value = value.toString();
|
|
183
203
|
}
|
|
184
204
|
if (value === undefined) {
|
|
185
|
-
return prop in
|
|
186
|
-
?
|
|
205
|
+
return prop in listeners
|
|
206
|
+
? listeners.style[prop].subscribe
|
|
187
207
|
: element.style[prop];
|
|
188
208
|
}
|
|
189
209
|
element.style[prop] = value;
|
|
@@ -199,12 +219,27 @@ function getWrappedElement(element) {
|
|
|
199
219
|
});
|
|
200
220
|
},
|
|
201
221
|
append(...content) {
|
|
222
|
+
var _a;
|
|
223
|
+
if ((_a = listeners.content) === null || _a === void 0 ? void 0 : _a[""])
|
|
224
|
+
removeListener("content", "");
|
|
202
225
|
recursiveAppend(element, content);
|
|
203
226
|
},
|
|
204
227
|
remove: () => element.remove(),
|
|
205
228
|
setCSSVariable(variableNameOrTable, value) {
|
|
206
229
|
if (typeof variableNameOrTable == "object") {
|
|
207
|
-
Object.entries(variableNameOrTable).forEach(([k, v]) =>
|
|
230
|
+
Object.entries(variableNameOrTable).forEach(([k, v]) => {
|
|
231
|
+
if (isReactiveSource(v)) {
|
|
232
|
+
addListener("cssVariable", k, v);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
setCSSVariable(k, v);
|
|
236
|
+
});
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
if (listeners.cssVariable[variableNameOrTable])
|
|
240
|
+
removeListener("cssVariable", variableNameOrTable);
|
|
241
|
+
if (isReactiveSource(value)) {
|
|
242
|
+
addListener("cssVariable", variableNameOrTable, value);
|
|
208
243
|
return;
|
|
209
244
|
}
|
|
210
245
|
setCSSVariable(variableNameOrTable, value);
|
|
@@ -231,6 +266,13 @@ function getWrappedElement(element) {
|
|
|
231
266
|
});
|
|
232
267
|
},
|
|
233
268
|
set content(v) {
|
|
269
|
+
var _a;
|
|
270
|
+
if ((_a = listeners.content) === null || _a === void 0 ? void 0 : _a[""])
|
|
271
|
+
removeListener("content", "");
|
|
272
|
+
if (isReactiveSource(v)) {
|
|
273
|
+
addListener("content", "", v);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
234
276
|
element.innerHTML = "";
|
|
235
277
|
recursiveAppend(element, v);
|
|
236
278
|
},
|
package/internal/types.d.ts
CHANGED
|
@@ -38,7 +38,7 @@ export type ElementDescriptor<Tag extends string> = {
|
|
|
38
38
|
[E in keyof HTMLElementEventMap]+?: (event: HTMLElementEventMap[E]) => void;
|
|
39
39
|
};
|
|
40
40
|
style?: StylesDescriptor;
|
|
41
|
-
cssVariables?: Record<string, CSSValue
|
|
41
|
+
cssVariables?: Record<string, CSSValue | ReactiveSource<CSSValue>>;
|
|
42
42
|
} & (Tag extends TagWithValue ? {
|
|
43
43
|
value?: string | number;
|
|
44
44
|
} : {}) & (Tag extends ContentlessTag ? {} : {
|
|
@@ -63,8 +63,8 @@ type ElementAPI<T extends HTMLElement> = {
|
|
|
63
63
|
};
|
|
64
64
|
readonly events: EventsAccessor;
|
|
65
65
|
readonly style: StyleAccessor;
|
|
66
|
-
setCSSVariable(variableName: string, value: CSSValue): void;
|
|
67
|
-
setCSSVariable(table: Record<string, CSSValue
|
|
66
|
+
setCSSVariable(variableName: string, value: CSSValue | ReactiveSource<CSSValue>): void;
|
|
67
|
+
setCSSVariable(table: Record<string, CSSValue | ReactiveSource<CSSValue>>): void;
|
|
68
68
|
qsa(selector: string): (Element | DomEntity<HTMLElement>)[];
|
|
69
69
|
remove(): void;
|
|
70
70
|
getRect(): DOMRect;
|
|
@@ -74,7 +74,7 @@ type ElementAPI<T extends HTMLElement> = {
|
|
|
74
74
|
} & (T extends ContentlessElement ? {} : {
|
|
75
75
|
append(...content: DOMContent[]): void;
|
|
76
76
|
innerHTML: string;
|
|
77
|
-
content: DOMContent
|
|
77
|
+
content: DOMContent | ReactiveSource<DOMContent>;
|
|
78
78
|
}) & (T extends HTMLElementTagNameMap[TagWithValue] ? {
|
|
79
79
|
value: string;
|
|
80
80
|
select(): void;
|