@webtides/element-js 0.6.2 → 0.7.1
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 +24 -0
- package/dist/index.js +86 -17
- package/dist/index.js.map +2 -2
- package/index.js +7 -7
- package/package.json +2 -2
- package/src/BaseElement.js +116 -22
- package/src/StyledElement.js +3 -3
- package/src/TemplateElement.js +2 -2
- package/src/renderer/vanilla/TemplateElement.js +4 -6
- package/src/renderer/vanilla/index.js +6 -6
- package/src/renderer/vanilla/util/html.js +1 -1
- package/src/renderer/vanilla/util/render.js +7 -16
- package/src/util/AttributeParser.js +12 -0
- package/src/util/Store.js +32 -9
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,30 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
|
|
|
14
14
|
<!-- ### Changed -->
|
|
15
15
|
<!-- ### Removed -->
|
|
16
16
|
<!-- ### Fixed -->
|
|
17
|
+
|
|
18
|
+
## [0.7.1] - 2023-03-03
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
* Elements are now able to watch Stores
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
* Injection of falsy values
|
|
25
|
+
|
|
26
|
+
## [0.7.0] - 2023-02-13
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
* Dependency Injection via Context Protocol 💉
|
|
30
|
+
* Provide reactive Properties or entire Stores via: provideProperties() { return { name : value}}
|
|
31
|
+
* Inject / Request them via injectProperties() { return { name : 'defaultValue'}}
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
* docs structure
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
* Cannot re-render slotted light dom when using the vanilla renderer https://github.com/webtides/element-js/issues/76
|
|
38
|
+
* adds Vanilla Renderer Tests
|
|
39
|
+
|
|
40
|
+
|
|
17
41
|
## [0.6.2] - 2022-11-18
|
|
18
42
|
|
|
19
43
|
### FIXED
|
package/dist/index.js
CHANGED
|
@@ -33,6 +33,9 @@ function isNumber(value) {
|
|
|
33
33
|
function isNaN(value) {
|
|
34
34
|
return Number.isNaN(value);
|
|
35
35
|
}
|
|
36
|
+
function deepEquals(valueA, valueB) {
|
|
37
|
+
return JSON.stringify(valueA) === JSON.stringify(valueB);
|
|
38
|
+
}
|
|
36
39
|
function parseAttribute(value, options = {}) {
|
|
37
40
|
if (options.parse === false || !isString(value)) {
|
|
38
41
|
return value;
|
|
@@ -88,13 +91,16 @@ var Store = class {
|
|
|
88
91
|
return this._state[key];
|
|
89
92
|
},
|
|
90
93
|
set: (newValue) => {
|
|
94
|
+
const oldState = structuredClone(this._state);
|
|
91
95
|
const oldValue = this._state[key];
|
|
92
96
|
this._state[key] = newValue;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
watch[key]
|
|
97
|
+
if (!deepEquals(newValue, oldValue)) {
|
|
98
|
+
const watch = this.watch();
|
|
99
|
+
if (watch.hasOwnProperty(key) && typeof watch[key] === "function") {
|
|
100
|
+
watch[key](newValue, oldValue);
|
|
101
|
+
}
|
|
102
|
+
this.requestUpdate(oldState);
|
|
96
103
|
}
|
|
97
|
-
this.requestUpdate();
|
|
98
104
|
}
|
|
99
105
|
});
|
|
100
106
|
});
|
|
@@ -117,8 +123,26 @@ var Store = class {
|
|
|
117
123
|
unsubscribe(observer) {
|
|
118
124
|
this._observer.delete(observer);
|
|
119
125
|
}
|
|
120
|
-
requestUpdate() {
|
|
121
|
-
this._observer.forEach((observer) =>
|
|
126
|
+
requestUpdate(oldState) {
|
|
127
|
+
this._observer.forEach(async (observer) => {
|
|
128
|
+
var _a, _b;
|
|
129
|
+
if (observer instanceof BaseElement) {
|
|
130
|
+
await observer.requestUpdate();
|
|
131
|
+
if (Object.keys((_a = observer.watch()) != null ? _a : {}).length > 0) {
|
|
132
|
+
const properties = observer.properties();
|
|
133
|
+
Object.keys((_b = observer.watch()) != null ? _b : {}).forEach((key) => {
|
|
134
|
+
if (properties[key] === this) {
|
|
135
|
+
observer.callPropertyWatcher(key, this._state, oldState);
|
|
136
|
+
observer.notifyPropertyChange(key, this._state);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
} else if (typeof observer === "function") {
|
|
141
|
+
observer();
|
|
142
|
+
} else {
|
|
143
|
+
console.error("Store: observer type is not supported.", observer);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
122
146
|
}
|
|
123
147
|
};
|
|
124
148
|
|
|
@@ -170,6 +194,7 @@ var BaseElement = class extends HTMLElement {
|
|
|
170
194
|
this.defineAttributesAsProperties();
|
|
171
195
|
this.defineProperties();
|
|
172
196
|
this.defineComputedProperties();
|
|
197
|
+
this.definePropertyInjection();
|
|
173
198
|
this.defineObserver();
|
|
174
199
|
if (this.hasAttribute("defer-update") || this._options.deferUpdate) {
|
|
175
200
|
this.registerEventsAndRefs();
|
|
@@ -203,6 +228,9 @@ var BaseElement = class extends HTMLElement {
|
|
|
203
228
|
}
|
|
204
229
|
disconnectedCallback() {
|
|
205
230
|
this.removeEvents();
|
|
231
|
+
if (Object.keys(this.provideProperties()).length > 0) {
|
|
232
|
+
this.removeEventListener("request-context", this.onRequestContext);
|
|
233
|
+
}
|
|
206
234
|
if (this._mutationObserver)
|
|
207
235
|
this._mutationObserver.disconnect();
|
|
208
236
|
Object.values(this.properties()).forEach((property) => {
|
|
@@ -257,7 +285,7 @@ var BaseElement = class extends HTMLElement {
|
|
|
257
285
|
return {};
|
|
258
286
|
}
|
|
259
287
|
defineProperties() {
|
|
260
|
-
Object.keys(this.properties()).forEach((prop) => {
|
|
288
|
+
Object.keys({...this.injectProperties(), ...this.properties()}).forEach((prop) => {
|
|
261
289
|
const value = this[prop] || this.properties()[prop];
|
|
262
290
|
this.defineProperty(prop, value);
|
|
263
291
|
});
|
|
@@ -287,17 +315,12 @@ var BaseElement = class extends HTMLElement {
|
|
|
287
315
|
const newValueString = JSON.stringify(newValue);
|
|
288
316
|
if (JSON.stringify(oldValue) !== newValueString) {
|
|
289
317
|
this._state[property] = newValue;
|
|
318
|
+
if (newValue instanceof Store) {
|
|
319
|
+
newValue.subscribe(this);
|
|
320
|
+
}
|
|
290
321
|
if (reflectAttribute || ((_a2 = this._options.propertyOptions[property]) == null ? void 0 : _a2.reflect)) {
|
|
291
322
|
this.reflectProperty({property, newValue, newValueString});
|
|
292
323
|
}
|
|
293
|
-
const informWatchedPropertiesAndDispatchChangeEvent = () => {
|
|
294
|
-
if (property in this.watch()) {
|
|
295
|
-
this.watch()[property](newValue, oldValue);
|
|
296
|
-
}
|
|
297
|
-
if (property in this._options["propertyOptions"] && this._options["propertyOptions"][property]["notify"] === true) {
|
|
298
|
-
this.dispatch(`${camelToDash(property)}-changed`, newValue, true);
|
|
299
|
-
}
|
|
300
|
-
};
|
|
301
324
|
if (this._options.autoUpdate) {
|
|
302
325
|
this.requestUpdate({
|
|
303
326
|
notify: true,
|
|
@@ -306,16 +329,29 @@ var BaseElement = class extends HTMLElement {
|
|
|
306
329
|
newValueString,
|
|
307
330
|
oldValue
|
|
308
331
|
}).finally(() => {
|
|
309
|
-
|
|
332
|
+
this.callPropertyWatcher(property, newValue, oldValue);
|
|
333
|
+
this.notifyPropertyChange(property, newValue);
|
|
310
334
|
});
|
|
311
335
|
} else {
|
|
312
|
-
|
|
336
|
+
this.callPropertyWatcher(property, newValue, oldValue);
|
|
337
|
+
this.notifyPropertyChange(property, newValue);
|
|
313
338
|
}
|
|
314
339
|
}
|
|
315
340
|
return this;
|
|
316
341
|
}
|
|
317
342
|
});
|
|
318
343
|
}
|
|
344
|
+
callPropertyWatcher(property, newValue, oldValue) {
|
|
345
|
+
const watch = this.watch();
|
|
346
|
+
if (property in watch) {
|
|
347
|
+
watch[property](newValue, oldValue);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
notifyPropertyChange(property, newValue) {
|
|
351
|
+
if (property in this._options["propertyOptions"] && this._options["propertyOptions"][property]["notify"] === true) {
|
|
352
|
+
this.dispatch(`${camelToDash(property)}-changed`, newValue, true);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
319
355
|
reflectProperty(options) {
|
|
320
356
|
var _a;
|
|
321
357
|
const {property, newValue} = options;
|
|
@@ -330,6 +366,39 @@ var BaseElement = class extends HTMLElement {
|
|
|
330
366
|
this.setAttribute(camelToDash(property), attributeValue);
|
|
331
367
|
}
|
|
332
368
|
}
|
|
369
|
+
injectProperties() {
|
|
370
|
+
return {};
|
|
371
|
+
}
|
|
372
|
+
provideProperties() {
|
|
373
|
+
return {};
|
|
374
|
+
}
|
|
375
|
+
definePropertyInjection() {
|
|
376
|
+
Object.entries(this.injectProperties()).forEach(([key, value]) => {
|
|
377
|
+
this.requestContext(key, value);
|
|
378
|
+
});
|
|
379
|
+
if (Object.keys(this.provideProperties()).length > 0) {
|
|
380
|
+
this.addEventListener("request-context", this.onRequestContext);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
requestContext(propertyName, valueOrCallback) {
|
|
384
|
+
this.dispatch("request-context", {[propertyName]: valueOrCallback}, true);
|
|
385
|
+
}
|
|
386
|
+
onRequestContext(event) {
|
|
387
|
+
var _a;
|
|
388
|
+
const properties = this.properties();
|
|
389
|
+
const provideProperties = this.provideProperties();
|
|
390
|
+
Object.entries((_a = event.detail) != null ? _a : {}).forEach(([key, valueOrCallback]) => {
|
|
391
|
+
if (key in provideProperties) {
|
|
392
|
+
const providedValue = provideProperties[key];
|
|
393
|
+
event.stopPropagation();
|
|
394
|
+
if (typeof valueOrCallback === "function") {
|
|
395
|
+
valueOrCallback(providedValue);
|
|
396
|
+
} else {
|
|
397
|
+
event.target[key] = providedValue;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
}
|
|
333
402
|
hooks() {
|
|
334
403
|
return {};
|
|
335
404
|
}
|