mount-observer 0.0.19 → 0.0.21
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/MountObserver.js +6 -3
- package/README.md +110 -36
- package/getWhereAttrSelector.js +66 -64
- package/package.json +1 -1
- package/types.d.ts +5 -4
package/MountObserver.js
CHANGED
|
@@ -15,9 +15,10 @@ export class MountObserver extends EventTarget {
|
|
|
15
15
|
super();
|
|
16
16
|
const { on, whereElementIntersectsWith, whereMediaMatches } = init;
|
|
17
17
|
let isComplex = false;
|
|
18
|
+
//TODO: study this problem further. Starting to think this is basically not polyfillable
|
|
18
19
|
if (on !== undefined) {
|
|
19
20
|
const reducedMatch = on.replaceAll(':not(', '');
|
|
20
|
-
isComplex = reducedMatch.includes(' ') || reducedMatch.includes(':');
|
|
21
|
+
isComplex = reducedMatch.includes(' ') || (reducedMatch.includes(':') && reducedMatch.includes('('));
|
|
21
22
|
}
|
|
22
23
|
this.#isComplex = isComplex;
|
|
23
24
|
if (whereElementIntersectsWith || whereMediaMatches)
|
|
@@ -40,7 +41,7 @@ export class MountObserver extends EventTarget {
|
|
|
40
41
|
if (whereAttr === undefined)
|
|
41
42
|
return withoutAttrs;
|
|
42
43
|
const { getWhereAttrSelector } = await import('./getWhereAttrSelector.js');
|
|
43
|
-
const info = getWhereAttrSelector(whereAttr, withoutAttrs);
|
|
44
|
+
const info = await getWhereAttrSelector(whereAttr, withoutAttrs);
|
|
44
45
|
const { fullListOfAttrs, calculatedSelector, partitionedAttrs } = info;
|
|
45
46
|
this.#fullListOfAttrs = fullListOfAttrs;
|
|
46
47
|
this.#attrParts = partitionedAttrs;
|
|
@@ -151,6 +152,7 @@ export class MountObserver extends EventTarget {
|
|
|
151
152
|
const parts = this.#attrParts[idx];
|
|
152
153
|
const attrChangeInfo = {
|
|
153
154
|
oldValue,
|
|
155
|
+
name: attributeName,
|
|
154
156
|
newValue,
|
|
155
157
|
idx,
|
|
156
158
|
parts
|
|
@@ -244,6 +246,7 @@ export class MountObserver extends EventTarget {
|
|
|
244
246
|
idx,
|
|
245
247
|
newValue,
|
|
246
248
|
oldValue,
|
|
249
|
+
name,
|
|
247
250
|
parts
|
|
248
251
|
});
|
|
249
252
|
}
|
|
@@ -350,7 +353,7 @@ export class DisconnectEvent extends Event {
|
|
|
350
353
|
export class AttrChangeEvent extends Event {
|
|
351
354
|
mountedElement;
|
|
352
355
|
attrChangeInfos;
|
|
353
|
-
static eventName = '
|
|
356
|
+
static eventName = 'attrChange';
|
|
354
357
|
constructor(mountedElement, attrChangeInfos) {
|
|
355
358
|
super(AttrChangeEvent.eventName);
|
|
356
359
|
this.mountedElement = mountedElement;
|
package/README.md
CHANGED
|
@@ -7,11 +7,11 @@ Note that much of what is described below has not yet been polyfilled.
|
|
|
7
7
|
|
|
8
8
|
# The MountObserver api.
|
|
9
9
|
|
|
10
|
-
Author: Bruce B. Anderson (with valuable feedback from
|
|
10
|
+
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-21
|
|
15
15
|
|
|
16
16
|
## Benefits of this API
|
|
17
17
|
|
|
@@ -72,6 +72,8 @@ observer.observe(document);
|
|
|
72
72
|
|
|
73
73
|
Invoking "disconnect" as shown above causes the observer to emit event "disconnectedCallback".
|
|
74
74
|
|
|
75
|
+
The argument can also be an array of objects that fit the pattern shown above.
|
|
76
|
+
|
|
75
77
|
If no imports are specified, it would go straight to do.* (if any such callbacks are specified), and it will also dispatch events as discussed below.
|
|
76
78
|
|
|
77
79
|
This only searches for elements matching 'my-element' outside any shadow DOM.
|
|
@@ -235,7 +237,41 @@ If an element that is in "mounted" state according to a MountObserver instance i
|
|
|
235
237
|
3) If the mounted element is added outside the rootNode being observed, the mountObserver instance will dispatch event "exit", and the MountObserver instance will relinquish any further responsibility for this element.
|
|
236
238
|
4) Ideally event "forget" would be dispatched just before the platform garbage collects an element the MountObserver instance is still monitoring, after all hard references are relinquished (or is that self-contradictory?).
|
|
237
239
|
5) If the new place it was added remains within the original rootNode and remains mounted, the MountObserver instance dispatches event "reconfirmed".
|
|
238
|
-
6) If the element no longer satisfies the criteria of the MountObserver instance, the MountObserver instance will dispatch event "dismount".
|
|
240
|
+
6) If the element no longer satisfies the criteria of the MountObserver instance, the MountObserver instance will dispatch event "dismount".
|
|
241
|
+
|
|
242
|
+
## Dismounting
|
|
243
|
+
|
|
244
|
+
In many cases, it will be critical to inform the developer **why** the element no longer satisfies all the criteria. For example, we may be using an intersection observer, and when we've scrolled away from view, we can "shut down" until the element is (nearly) scrolled back into view. We may also be displaying things differently depending on the network speed. How we should respond when one of the original conditions, but not the other, no longer applies, is of paramount importance.
|
|
245
|
+
|
|
246
|
+
So the dismount event should provide a "checklist" of all the conditions, and their current value:
|
|
247
|
+
|
|
248
|
+
```JavaScript
|
|
249
|
+
mediaMatches: true,
|
|
250
|
+
containerMatches: true,
|
|
251
|
+
satisifiesCustomCondition: true,
|
|
252
|
+
whereLangIn: ['en-GB'],
|
|
253
|
+
whereConnection:{
|
|
254
|
+
effectiveTypeMatches: true
|
|
255
|
+
},
|
|
256
|
+
isIntersecting: false,
|
|
257
|
+
changedConditions: ['isIntersecting']
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Get play-by-play updates?
|
|
261
|
+
|
|
262
|
+
An issue raised by @doeixd, I think, is what if we want to be informed of the status of all the conditions that are applicable to an element being mounted / dismounted? I can see scenarios where this would be useful, for reasons similar to wanting to know why the element dismounted.
|
|
263
|
+
|
|
264
|
+
Since this could have a negative impact on performance, I think it should be something we opt-in to:
|
|
265
|
+
|
|
266
|
+
```JavaScript
|
|
267
|
+
getPlayByPlay: true
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Now the question is when should this progress reporting start? It could either start the moment the element becomes mounted the first time. Or it could happen the moment any of the conditions are satisfied. But some of the conditions could be trivially satisfied for the vast majority of elements (e.g. network speed is 4g or greater).
|
|
271
|
+
|
|
272
|
+
So I believe the prudent thing to do is wait for all the conditions to be satisfied, before engaging in this kind of commentary, i.e. after the first mount.
|
|
273
|
+
|
|
274
|
+
The alternative to providing this feature, which I'm leaning towards, is to just ask the developer to create "specialized" mountObserver construction arguments, that turn on and off precisely when the developer needs to know.
|
|
239
275
|
|
|
240
276
|
## A tribute to attributes
|
|
241
277
|
|
|
@@ -245,40 +281,59 @@ Being that for both custom elements, as well as (hopefully) [custom enhancements
|
|
|
245
281
|
|
|
246
282
|
We want to be alerted by the discovery of elements adorned by these attributes, but then continue to be alerted to changes of their values, and we can't enumerate which values we are interested in, so we must subscribe to all values as they change.
|
|
247
283
|
|
|
248
|
-
|
|
249
|
-
### Scenario 1 -- Custom Element integration with ObserveObservedAttributes API [WIP]
|
|
284
|
+
## A key attribute of attributes
|
|
250
285
|
|
|
251
|
-
|
|
286
|
+
I think it is useful to divide [attributes](https://jakearchibald.com/2024/attributes-vs-properties/) that we we would want to observe into two categories:
|
|
252
287
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
288
|
+
1. Invariably named, prefix-less, "top-level" attributes that serve as the "source of the truth".
|
|
289
|
+
|
|
290
|
+
Examples are many built-in global attributes, like lang, or contenteditable, or more specialized examples such as "content" for the meta tag. Often, setting the property values corresponding to these attributes results in directly reflecting those property values to the attributes (perhaps in a round about way). And there are usually 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 is often the most effective way of observing when the property/attribute state for these elements change. Some attributes of custom elements may fit this category (but maybe a minority of them).
|
|
291
|
+
|
|
292
|
+
And in some application environments, adjusting state via attributes may be the preferred approach, so we want to support this scenario, even if it doesn't abide by a common view of what constitutes "best practices." Again, the distinguishing feature of the attributes that we would want to monitor in this way is that they are "top-level" and unlikely to differ in name across different Shadow DOM scopes.
|
|
293
|
+
|
|
294
|
+
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.
|
|
295
|
+
|
|
296
|
+
We want our api to be able to distinguish between these two, and to be able to combine both types in one mount observer instance.
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
### Attributes that are the "source of truth"
|
|
300
|
+
|
|
301
|
+
So for the first scenario, we can specify attributes to listen for as follows:
|
|
302
|
+
|
|
303
|
+
```JavaScript
|
|
304
|
+
import {MountObserver} from 'mount-observer/MountObserver.js';
|
|
305
|
+
const mo = new MountObserver({
|
|
306
|
+
on: '*',
|
|
307
|
+
whereAttr:{
|
|
308
|
+
isIn: ['lang', 'contenteditable']
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
mo.addEventListener('attrChange', e => {
|
|
313
|
+
console.log(e);
|
|
314
|
+
// {
|
|
315
|
+
// matchingElement,
|
|
316
|
+
// attrChangeInfo:[{
|
|
317
|
+
// idx: 0,
|
|
318
|
+
// name: 'lang'
|
|
319
|
+
// oldValue: null,
|
|
320
|
+
// newValue: 'en-GB',
|
|
321
|
+
// }]
|
|
322
|
+
// }
|
|
323
|
+
});
|
|
273
324
|
```
|
|
274
|
-
-->
|
|
275
325
|
|
|
326
|
+
### Help with parsing?
|
|
327
|
+
|
|
328
|
+
This proposal is likely to evolve going forward, attempting to synthesize [separate ideas](https://github.com/WICG/webcomponents/issues/1045) for declaratively specifying how to interpret the attributes, parsing them so that they may be merged into properties of a class instance.
|
|
329
|
+
|
|
330
|
+
But for now, such support is not part of this proposal (though we can see a glimpse of what that support might look like below).
|
|
276
331
|
|
|
277
332
|
### Custom Enhancements in userland
|
|
278
333
|
|
|
279
|
-
[This proposal could take quite a while to see the light of day, if ever](https://github.com/WICG/webcomponents/issues/1000).
|
|
334
|
+
[This proposal, support for (progressive) enhancement of built-in or third-party custom elements, could take quite a while to see the light of day, if ever](https://github.com/WICG/webcomponents/issues/1000).
|
|
280
335
|
|
|
281
|
-
In the meantime, we want to provide the most help for providing for custom enhancements in userland, and for any other kind of (progressive) enhancement based on attributes going forward.
|
|
336
|
+
In the meantime, we want to provide the most help for providing for custom enhancements in userland, and for any other kind of (progressive) enhancement based on (server-rendered) attributes going forward.
|
|
282
337
|
|
|
283
338
|
Suppose we have a (progressive) enhancement that we want to apply based on the presence of 1 or more attributes.
|
|
284
339
|
|
|
@@ -316,7 +371,7 @@ We want to also support:
|
|
|
316
371
|
|
|
317
372
|
Based on the current unspoken rules, no one will raise an eyebrow with these attributes, because the platform has indicated it will generally avoid dashes in attributes (with an exception or two that will only happen in a blue moon, like aria-*).
|
|
318
373
|
|
|
319
|
-
But now when we consider applying this enhancement to custom elements, we have a new risk. What's to prevent the custom element from having an attribute named my-enhancement?
|
|
374
|
+
But now when we consider applying this enhancement to third party custom elements, we have a new risk. What's to prevent the custom element from having an attribute named my-enhancement?
|
|
320
375
|
|
|
321
376
|
So let's say we want to insist that on custom elements, we must have the data- prefix?
|
|
322
377
|
|
|
@@ -324,7 +379,9 @@ And we want to support an alternative, more semantic sounding prefix to data, sa
|
|
|
324
379
|
|
|
325
380
|
Here's what the api **doesn't** provide (as originally proposed):
|
|
326
381
|
|
|
327
|
-
|
|
382
|
+
#### The carpal syndrome syntax
|
|
383
|
+
|
|
384
|
+
Using the same expression structure as above, we would end up with this avalanche of settings:
|
|
328
385
|
|
|
329
386
|
```JavaScript
|
|
330
387
|
import {MountObserver} from '../MountObserver.js';
|
|
@@ -358,7 +415,9 @@ const mo = new MountObserver({
|
|
|
358
415
|
});
|
|
359
416
|
```
|
|
360
417
|
|
|
361
|
-
|
|
418
|
+
#### The DRY Way
|
|
419
|
+
|
|
420
|
+
This seems like a much better approach, and is supported by this proposal:
|
|
362
421
|
|
|
363
422
|
```JavaScript
|
|
364
423
|
import {MountObserver} from '../MountObserver.js';
|
|
@@ -394,7 +453,7 @@ MountObserver provides a breakdown of the matching attribute when encountered:
|
|
|
394
453
|
}
|
|
395
454
|
}
|
|
396
455
|
});
|
|
397
|
-
mo.addEventListener('
|
|
456
|
+
mo.addEventListener('attrChange', e => {
|
|
398
457
|
console.log(e);
|
|
399
458
|
// {
|
|
400
459
|
// matchingElement,
|
|
@@ -465,6 +524,8 @@ Tentative rules:
|
|
|
465
524
|
|
|
466
525
|
The thinking here is that longer roots indicate higher "specificity", so it is safer to use that one.
|
|
467
526
|
|
|
527
|
+
|
|
528
|
+
|
|
468
529
|
## Preemptive downloading
|
|
469
530
|
|
|
470
531
|
There are two significant steps to imports, each of which imposes a cost:
|
|
@@ -481,7 +542,7 @@ So for this we add option:
|
|
|
481
542
|
```JavaScript
|
|
482
543
|
const observer = new MountObserver({
|
|
483
544
|
on: 'my-element',
|
|
484
|
-
|
|
545
|
+
loadingEagerness: 'eager',
|
|
485
546
|
import: './my-element.js',
|
|
486
547
|
do:{
|
|
487
548
|
mount: (matchingElement, {modules}) => customElements.define(modules[0].MyElement)
|
|
@@ -491,13 +552,16 @@ const observer = new MountObserver({
|
|
|
491
552
|
|
|
492
553
|
So what this does is only check for the presence of an element with tag name "my-element", and it starts downloading the resource, even before the element has "mounted" based on other criteria.
|
|
493
554
|
|
|
555
|
+
> [!NOTE]
|
|
556
|
+
> As a result of the google IO 2024 talks, I became aware that there is some similarity between this proposal and the [speculation rules api](https://developer.chrome.com/blog/speculation-rules-improvements). This motivated the change to the property from "loading" to loadingEagerness above.
|
|
557
|
+
|
|
494
558
|
## Intra document html imports
|
|
495
559
|
|
|
496
560
|
This proposal "sneaks in" one more feature, that perhaps should stand separately as its own proposal. Because the MountObserver api allows us to attach behaviors on the fly based on css matching, and because the MountObserver would provide developers the "first point of contact" for such functionality, the efficiency argument seemingly "screams out" for this feature.
|
|
497
561
|
|
|
498
562
|
Also, this proposal is partly focused on better management of importing resources "from a distance", in particular via imports carried out via http. Is it such a stretch to look closely at scenarios where that distance happens to be shorter, i.e. found somewhere [in the document tree structure](https://github.com/tc39/proposal-module-expressions)?
|
|
499
563
|
|
|
500
|
-
The mount-observer is always on the lookout for template tags with
|
|
564
|
+
The mount-observer is always on the lookout for template tags with a src attribute starting with #:
|
|
501
565
|
|
|
502
566
|
```html
|
|
503
567
|
<template src=#id-of-source-template></template>
|
|
@@ -521,7 +585,7 @@ Let's say the source template looks as follows:
|
|
|
521
585
|
|
|
522
586
|
```html
|
|
523
587
|
<template id=id-of-source-template>
|
|
524
|
-
I don't know why you say <slot name=slot2></slot> I say <slot name=slot1></slot>
|
|
588
|
+
<div>I don't know why you say <slot name=slot2></slot> I say <slot name=slot1></slot></div>
|
|
525
589
|
</template>
|
|
526
590
|
```
|
|
527
591
|
|
|
@@ -583,3 +647,13 @@ This proposal (and polyfill) also supports the option to utilize ShadowDOM / slo
|
|
|
583
647
|
</div>
|
|
584
648
|
```
|
|
585
649
|
|
|
650
|
+
> [!NOTE]
|
|
651
|
+
> An intriguing sounding alternative to using the template tag that disappears, as shown above, is to use a new tag for this purpose. I think something along the lines of what is [proposed here](https://github.com/WICG/webcomponents/issues/1059) has a much better semantic ring to it:
|
|
652
|
+
|
|
653
|
+
```html
|
|
654
|
+
<compose src="#sharedHeader"></compose>
|
|
655
|
+
<compose src="#productCard"></compose>
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
The discussion there leads to an open question whether a processing instruction would be better. I think the compose tag would make much more sense, vs a processing instruction, as it could then support slotted children (behaving similar to the Beatles' example above). Or maybe another tag should be introduced that is the equivalent of the slot, to avoid confusion. or some equivalent. But I strongly suspect that could significantly reduce the payload size of some documents, if we can reuse blocks of HTML, inserting sections of customized content for each instance.
|
|
659
|
+
|
package/getWhereAttrSelector.js
CHANGED
|
@@ -1,72 +1,74 @@
|
|
|
1
|
-
export function getWhereAttrSelector(whereAttr, withoutAttrs) {
|
|
2
|
-
const { hasBase, hasBranchIn, hasRootIn } = whereAttr;
|
|
3
|
-
const
|
|
4
|
-
start: '',
|
|
5
|
-
context: 'Both'
|
|
6
|
-
}];
|
|
7
|
-
const fullListOfAttrs = [];
|
|
1
|
+
export async function getWhereAttrSelector(whereAttr, withoutAttrs) {
|
|
2
|
+
const { hasBase, hasBranchIn, hasRootIn, isIn } = whereAttr;
|
|
3
|
+
const fullListOfAttrs = isIn !== undefined ? [...isIn] : [];
|
|
8
4
|
const partitionedAttrs = [];
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
let
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
5
|
+
if (hasBase !== undefined) {
|
|
6
|
+
const hasRootInGuaranteed = hasRootIn || [{
|
|
7
|
+
start: '',
|
|
8
|
+
context: 'Both'
|
|
9
|
+
}];
|
|
10
|
+
let prefixLessMatches = [];
|
|
11
|
+
const hasBaseIsString = typeof hasBase === 'string';
|
|
12
|
+
const baseSelector = hasBaseIsString ? hasBase : hasBase[1];
|
|
13
|
+
const rootToBaseDelimiter = hasBaseIsString ? '-' : hasBase[0];
|
|
14
|
+
if (hasBranchIn !== undefined) {
|
|
15
|
+
let baseToBranchDelimiter = '-';
|
|
16
|
+
let branches;
|
|
17
|
+
if (hasBranchIn.length === 2 && Array.isArray(hasBranchIn[1])) {
|
|
18
|
+
baseToBranchDelimiter = hasBranchIn[0];
|
|
19
|
+
branches = hasBranchIn[1];
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
branches = hasBranchIn;
|
|
23
|
+
}
|
|
24
|
+
prefixLessMatches = branches.map(x => ({
|
|
25
|
+
rootToBaseDelimiter,
|
|
26
|
+
base: baseSelector,
|
|
27
|
+
baseToBranchDelimiter: x ? baseToBranchDelimiter : '',
|
|
28
|
+
branch: x
|
|
29
|
+
}));
|
|
19
30
|
}
|
|
20
31
|
else {
|
|
21
|
-
|
|
32
|
+
prefixLessMatches.push({
|
|
33
|
+
rootToBaseDelimiter,
|
|
34
|
+
base: baseSelector,
|
|
35
|
+
});
|
|
22
36
|
}
|
|
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
|
-
else {
|
|
59
|
-
const name = `${startAndRootToBaseDelimiter}${base}`;
|
|
60
|
-
fullListOfAttrs.push(name);
|
|
61
|
-
partitionedAttrs.push({
|
|
62
|
-
root: start,
|
|
63
|
-
name,
|
|
64
|
-
base,
|
|
65
|
-
rootCnfg,
|
|
66
|
-
branchIdx
|
|
67
|
-
});
|
|
37
|
+
for (const rootCnfg of hasRootInGuaranteed) {
|
|
38
|
+
const { start } = rootCnfg;
|
|
39
|
+
for (const match of prefixLessMatches) {
|
|
40
|
+
const { base, baseToBranchDelimiter, branch, rootToBaseDelimiter } = match;
|
|
41
|
+
let branchIdx = 0;
|
|
42
|
+
for (const prefixLessMatch of prefixLessMatches) {
|
|
43
|
+
const { base, baseToBranchDelimiter, branch } = prefixLessMatch;
|
|
44
|
+
const startAndRootToBaseDelimiter = start ? `${start}${rootToBaseDelimiter}` : '';
|
|
45
|
+
//TODO: could probably reduce the size of the code below
|
|
46
|
+
if (branch) {
|
|
47
|
+
//will always have branch?
|
|
48
|
+
const name = `${startAndRootToBaseDelimiter}${base}${baseToBranchDelimiter}${branch}`;
|
|
49
|
+
fullListOfAttrs.push(name);
|
|
50
|
+
partitionedAttrs.push({
|
|
51
|
+
root: start,
|
|
52
|
+
name,
|
|
53
|
+
base,
|
|
54
|
+
branch,
|
|
55
|
+
branchIdx,
|
|
56
|
+
rootCnfg
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
const name = `${startAndRootToBaseDelimiter}${base}`;
|
|
61
|
+
fullListOfAttrs.push(name);
|
|
62
|
+
partitionedAttrs.push({
|
|
63
|
+
root: start,
|
|
64
|
+
name,
|
|
65
|
+
base,
|
|
66
|
+
rootCnfg,
|
|
67
|
+
branchIdx
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
branchIdx++;
|
|
68
71
|
}
|
|
69
|
-
branchIdx++;
|
|
70
72
|
}
|
|
71
73
|
}
|
|
72
74
|
}
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -30,7 +30,8 @@ export interface RootCnfg{
|
|
|
30
30
|
//export type RootAttrOptions = Array<string | RootCnfg>;
|
|
31
31
|
export type delimiter = string;
|
|
32
32
|
export interface WhereAttr{
|
|
33
|
-
|
|
33
|
+
isIn?: Array<string>,
|
|
34
|
+
hasBase?: string | [delimiter, string],
|
|
34
35
|
hasBranchIn?: Array<string> | [delimiter, Array<string>],
|
|
35
36
|
hasRootIn?: Array<RootCnfg>,
|
|
36
37
|
/**
|
|
@@ -66,7 +67,7 @@ export interface MountContext{
|
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
type PipelineStage = 'Inspecting' | 'PreImport' | 'PostImport' | 'Import'
|
|
69
|
-
export type PipelineProcessor<ReturnType = void> = (matchingElement: Element, observer: IMountObserver, ctx: MountContext) => Promise<ReturnType
|
|
70
|
+
export type PipelineProcessor<ReturnType = void> = (matchingElement: Element, observer: IMountObserver, ctx: MountContext) => Promise<ReturnType> | ReturnType;
|
|
70
71
|
|
|
71
72
|
//#region mutation event
|
|
72
73
|
export type mutationEventName = 'mutation-event';
|
|
@@ -96,8 +97,8 @@ interface AttrChangeInfo{
|
|
|
96
97
|
oldValue: string | null,
|
|
97
98
|
newValue: string | null,
|
|
98
99
|
idx: number,
|
|
100
|
+
name: string,
|
|
99
101
|
parts: AttrParts,
|
|
100
|
-
//parsedNewValue?: any,
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
//#region mount event
|
|
@@ -139,7 +140,7 @@ export interface AddDisconnectEventListener {
|
|
|
139
140
|
//endregion
|
|
140
141
|
|
|
141
142
|
//#region attribute change event
|
|
142
|
-
export type attrChangeEventName = '
|
|
143
|
+
export type attrChangeEventName = 'attrChange';
|
|
143
144
|
export interface IAttrChangeEvent extends IMountEvent {
|
|
144
145
|
attrChangeInfos: Array<AttrChangeInfo>,
|
|
145
146
|
}
|