mount-observer 0.0.25 → 0.0.26
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/README.md +13 -10
- package/Synthesizer.js +6 -5
- package/package.json +2 -2
- package/types.d.ts +1 -0
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Author: Bruce B. Anderson (with valuable feedback from @doeixd )
|
|
|
11
11
|
|
|
12
12
|
Issues / pr's / polyfill: [mount-observer](https://github.com/bahrus/mount-observer)
|
|
13
13
|
|
|
14
|
-
Last Update: 2024-5-
|
|
14
|
+
Last Update: 2024-5-27
|
|
15
15
|
|
|
16
16
|
## Benefits of this API
|
|
17
17
|
|
|
@@ -105,7 +105,7 @@ const observer = new MountObserver({
|
|
|
105
105
|
observer.observe(document);
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
-
Once again, the key can accept either a single import
|
|
108
|
+
Once again, the key can accept either a single import and it can also support multiple imports (via an array).
|
|
109
109
|
|
|
110
110
|
The do event won't be invoked until all the imports have been successfully completed and inserted into the modules array.
|
|
111
111
|
|
|
@@ -113,7 +113,7 @@ Previously, this proposal called for allowing arrow functions as well, thinking
|
|
|
113
113
|
|
|
114
114
|
This proposal would also include support for JSON and HTML module imports.
|
|
115
115
|
|
|
116
|
-
##
|
|
116
|
+
## Mount Observer Script Elements (MOSEs)
|
|
117
117
|
|
|
118
118
|
Following an approach similar to the [speculation api](https://developer.chrome.com/blog/speculation-rules-improvements), we can add a script element anywhere in the DOM:
|
|
119
119
|
|
|
@@ -136,7 +136,7 @@ Following an approach similar to the [speculation api](https://developer.chrome.
|
|
|
136
136
|
</script>
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
The
|
|
139
|
+
The things that make this API work together, namely the "modules", "observer", and "mountedElements" (an array of an array of weak refs to elements that match all the criteria for the ith "on" selector) would be accessible as properties of the script element:
|
|
140
140
|
|
|
141
141
|
```JavaScript
|
|
142
142
|
const {modules, observer, mountedElements, mountInit} = myMountObserver;
|
|
@@ -144,11 +144,11 @@ const {modules, observer, mountedElements, mountInit} = myMountObserver;
|
|
|
144
144
|
|
|
145
145
|
The "scope" of the observer would be the ShadowRoot containing the script element (or the document outside Shadow if placed outside any shadow DOM, like in the head element).
|
|
146
146
|
|
|
147
|
-
No arrays of settings would be supported within a single tag (as this causes issues as far as supporting a single onmount, ondismount, etc event attributes).
|
|
147
|
+
No arrays of settings would be supported within a single tag (as this causes issues as far as supporting a single onmount, ondismount, etc event attributes), but remember that the on criteria can be an array of selectors.
|
|
148
148
|
|
|
149
149
|
## Shadow Root inheritance
|
|
150
150
|
|
|
151
|
-
Inside a shadow root, we can plop a script element, also with type mountobserver, optionally giving it the same id as above:
|
|
151
|
+
Inside a shadow root, we can plop a script element, also with type "mountobserver", optionally giving it the same id as above:
|
|
152
152
|
|
|
153
153
|
```html
|
|
154
154
|
#shadowRoot
|
|
@@ -163,7 +163,7 @@ If no id is found in the parent ShadowRoot (or in the parent window if the shado
|
|
|
163
163
|
|
|
164
164
|
But if a matching id is found, then the values from the parent script element get merged in with the one in the child, with the child settings, including the event handling attributes.
|
|
165
165
|
|
|
166
|
-
We will come back to some [additional features](#creating-frameworks-that-revolve-around-moses) of using these script elements later, but
|
|
166
|
+
We will come back to some important [additional features](#creating-frameworks-that-revolve-around-moses) of using these script elements later, but first we want to cover the highlights of this proposal, in order to give more context as to what kinds of functionality these MOSEs can provide.
|
|
167
167
|
|
|
168
168
|
## Binding from a distance
|
|
169
169
|
|
|
@@ -325,9 +325,9 @@ The alternative to providing this feature, which I'm leaning towards, is to just
|
|
|
325
325
|
|
|
326
326
|
## A tribute to attributes
|
|
327
327
|
|
|
328
|
-
Attributes of DOM elements are tricky. They've been around since the get-go of the Web, and they've survived multiple
|
|
328
|
+
Attributes of DOM elements are tricky. They've been around since the get-go of the Web, and they've survived multiple eras of web development, where different philosophies have prevailed, so prepare yourself for some esoteric discussions in what follows.
|
|
329
329
|
|
|
330
|
-
|
|
330
|
+
The MountObserver API provides explicit support for monitoring attributes. There are two primary reasons for why it is important to provide this as part of the API:
|
|
331
331
|
|
|
332
332
|
Being that for both custom elements, as well as (hopefully) [custom enhancements](https://github.com/WICG/webcomponents/issues/1000) we need to carefully work with sets of "owned" [observed](https://github.com/WICG/webcomponents/issues/1045) attributes, and in some cases we may need to manage combinations of prefixes and suffixes for better name-spacing management, creating the most effective css query becomes challenging.
|
|
333
333
|
|
|
@@ -339,7 +339,9 @@ I think it is useful to divide [attributes](https://jakearchibald.com/2024/attri
|
|
|
339
339
|
|
|
340
340
|
1. Invariably named, prefix-less, "top-level" attributes that serve as the "source of truth" for key features of the DOM element itself. We will refer to these attributes as "Source of Truth" attributes.
|
|
341
341
|
|
|
342
|
-
Examples are many built-in global attributes, like lang, or contenteditable, or more specialized examples such as "content" for the meta tag. I think in the vast majority of cases, setting the property values corresponding to these attributes results in directly reflecting those property values to the attributes. There are exceptions, especially for non-string attributes like the checked property of the input element / type=checkbox
|
|
342
|
+
Examples are many built-in global attributes, like lang, or contenteditable, or more specialized examples such as "content" for the meta tag. I think in the vast majority of cases, setting the property values corresponding to these attributes results in directly reflecting those property values to the attributes. There are exceptions, especially for non-string attributes like the checked property of the input element / type=checkbox, and JSON based attributes for custom elements.
|
|
343
|
+
|
|
344
|
+
Usually, that are no events we can subscribe to in order to know when the property changes. Hijacking the property setter in order to observe changes may not always work or feel very resilient. So monitoring the attribute value associated with the property is often the most effective way of observing when the property/attribute state for these elements change. And some attributes (like the microdata attributes such as itemprop) don't even have properties that they pair with!
|
|
343
345
|
|
|
344
346
|
|
|
345
347
|
2. In contrast, there are scenarios where we want to support somewhat fluid, renamable attributes within different Shadow DOM scopes, which add behavior/enhancement capabilities on top of built-in or third party custom elements. We'll refer to these attributes as "Enhancement Attributes."
|
|
@@ -376,6 +378,7 @@ mo.addEventListener('attrChange', e => {
|
|
|
376
378
|
// attrChangeInfo:[{
|
|
377
379
|
// idx: 0,
|
|
378
380
|
// name: 'lang'
|
|
381
|
+
// isSOfTAttr: true,
|
|
379
382
|
// oldValue: null,
|
|
380
383
|
// newValue: 'en-GB',
|
|
381
384
|
// }]
|
package/Synthesizer.js
CHANGED
|
@@ -43,6 +43,7 @@ export class Synthesizer extends HTMLElement {
|
|
|
43
43
|
import(mose) {
|
|
44
44
|
const { init, do: d, id, synConfig } = mose;
|
|
45
45
|
const se = document.createElement('script');
|
|
46
|
+
se.type = 'mountobserver';
|
|
46
47
|
se.init = { ...init };
|
|
47
48
|
se.id = id;
|
|
48
49
|
se.do = { ...d };
|
|
@@ -57,15 +58,15 @@ export class Synthesizer extends HTMLElement {
|
|
|
57
58
|
const parentShadowRealm = host.getRootNode();
|
|
58
59
|
const { localName } = this;
|
|
59
60
|
const parentScopeSynthesizer = parentShadowRealm.querySelector(localName);
|
|
61
|
+
if (parentScopeSynthesizer === null)
|
|
62
|
+
throw 404;
|
|
60
63
|
const { mountObserverElements } = parentScopeSynthesizer;
|
|
61
64
|
for (const moe of mountObserverElements) {
|
|
62
65
|
this.import(moe);
|
|
63
66
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
});
|
|
68
|
-
}
|
|
67
|
+
parentScopeSynthesizer.addEventListener(SynthesizeEvent.eventName, e => {
|
|
68
|
+
this.import(e.mountObserverElement);
|
|
69
|
+
});
|
|
69
70
|
}
|
|
70
71
|
disconnectedCallback() {
|
|
71
72
|
if (this.#mutationObserver !== undefined) {
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mount-observer",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.26",
|
|
4
4
|
"description": "Observe and act on css matches.",
|
|
5
5
|
"main": "MountObserver.js",
|
|
6
6
|
"module": "MountObserver.js",
|
|
7
7
|
"devDependencies": {
|
|
8
|
-
"@playwright/test": "1.
|
|
8
|
+
"@playwright/test": "1.44.1",
|
|
9
9
|
"may-it-serve": "0.0.6"
|
|
10
10
|
},
|
|
11
11
|
"exports": {
|
package/types.d.ts
CHANGED