mount-observer 0.0.67 → 0.0.69
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 +35 -4
- package/MountObserver.ts +37 -5
- package/Newish.js +8 -5
- package/Newish.ts +8 -5
- package/README.md +45 -1
- package/compose.js +38 -5
- package/compose.ts +38 -7
- package/doCleanup.js +31 -0
- package/doCleanup.ts +34 -0
- package/package.json +13 -1
- package/refid/getAdjRefs.js +16 -0
- package/refid/getAdjRefs.ts +16 -0
- package/ts-refs/be-imbued/types.d.ts +30 -0
- package/ts-refs/be-included/types.d.ts +20 -0
- package/ts-refs/per-each/types.d.ts +2 -1
- package/ts-refs/trans-render/froop/types.d.ts +1 -0
- package/ts-refs/trans-render/types.d.ts +2 -1
package/MountObserver.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { RootMutObs } from './RootMutObs.js';
|
|
2
2
|
import { bindish, bindishIt } from './bindish.js';
|
|
3
3
|
export const guid = '5Pv6bHOVH0ae07opRZ8N/g';
|
|
4
|
+
export const wasItemReffed = Symbol.for('8aA6xB8+PkScmivaslBk5Q');
|
|
4
5
|
export const mutationObserverLookup = new WeakMap();
|
|
5
6
|
const refCount = new WeakMap();
|
|
6
7
|
export class MountObserver extends EventTarget {
|
|
@@ -72,10 +73,10 @@ export class MountObserver extends EventTarget {
|
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
#templLookUp = new Map();
|
|
75
|
-
findByID(id, fragment) {
|
|
76
|
+
async findByID(id, fragment) {
|
|
76
77
|
if (this.#templLookUp.has(id))
|
|
77
78
|
return this.#templLookUp.get(id);
|
|
78
|
-
let templ = fragment.
|
|
79
|
+
let templ = fragment.querySelector(`#${id}`);
|
|
79
80
|
if (templ === null) {
|
|
80
81
|
let rootToSearchOutwardFrom = ((fragment.isConnected ? fragment.getRootNode() : this.#mountInit.withTargetShadowRoot) || document);
|
|
81
82
|
templ = rootToSearchOutwardFrom.getElementById(id);
|
|
@@ -84,8 +85,34 @@ export class MountObserver extends EventTarget {
|
|
|
84
85
|
templ = rootToSearchOutwardFrom.getElementById(id);
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
|
-
if (templ !== null)
|
|
88
|
+
if (templ !== null) {
|
|
89
|
+
if (!(templ instanceof HTMLTemplateElement)) {
|
|
90
|
+
const newTempl = document.createElement('template');
|
|
91
|
+
const { getAdjRefs } = await import('./refid/getAdjRefs.js');
|
|
92
|
+
const adjRefs = getAdjRefs(templ);
|
|
93
|
+
// if(adjRefs.length > 1){
|
|
94
|
+
// (<any>newTempl)[wasItemReffed] = true;
|
|
95
|
+
// adjRefs[0].setAttribute('itemref', '<autogen>');
|
|
96
|
+
// }
|
|
97
|
+
const fragment = document.createDocumentFragment();
|
|
98
|
+
let first = true;
|
|
99
|
+
for (const adjRef of adjRefs) {
|
|
100
|
+
const clone = adjRef.cloneNode(true);
|
|
101
|
+
if (first && adjRefs.length > 1) {
|
|
102
|
+
clone.setAttribute('itemref', '<autogen>');
|
|
103
|
+
newTempl[wasItemReffed] = true;
|
|
104
|
+
first = false;
|
|
105
|
+
}
|
|
106
|
+
clone.removeAttribute('id');
|
|
107
|
+
fragment.appendChild(clone);
|
|
108
|
+
}
|
|
109
|
+
const { doCleanup } = await import('./doCleanup.js');
|
|
110
|
+
doCleanup(templ, fragment);
|
|
111
|
+
newTempl.content.appendChild(fragment);
|
|
112
|
+
templ = newTempl;
|
|
113
|
+
}
|
|
88
114
|
this.#templLookUp.set(id, templ);
|
|
115
|
+
}
|
|
89
116
|
return templ;
|
|
90
117
|
}
|
|
91
118
|
disconnect(within) {
|
|
@@ -423,7 +450,11 @@ export class MountObserver extends EventTarget {
|
|
|
423
450
|
this.#mount(elsToMount, initializing);
|
|
424
451
|
}
|
|
425
452
|
async #inspectWithin(within, initializing) {
|
|
426
|
-
await bindish
|
|
453
|
+
//the line below had an await for bindish, consistent with the rest of the code, but it was
|
|
454
|
+
//getting into a catch-22 scenario frequently, blocking the code for resuming.
|
|
455
|
+
//This was observed with per-each package, demo/ScopeScript.html, clicking refresh a few times
|
|
456
|
+
//one will see the inconsistent behavior if await is added below.
|
|
457
|
+
bindish(within, within, { assigner: this.#mountInit.assigner });
|
|
427
458
|
await this.composeFragment(within, 0);
|
|
428
459
|
const match = await this.#selector();
|
|
429
460
|
const els = Array.from(within.querySelectorAll(match));
|
package/MountObserver.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {RootMutObs} from './RootMutObs.js';
|
|
|
10
10
|
import {bindish, bindishIt} from './bindish.js';
|
|
11
11
|
export {MOSE} from './ts-refs/mount-observer/types';
|
|
12
12
|
export const guid = '5Pv6bHOVH0ae07opRZ8N/g';
|
|
13
|
+
export const wasItemReffed = Symbol.for('8aA6xB8+PkScmivaslBk5Q');
|
|
13
14
|
|
|
14
15
|
export const mutationObserverLookup = new WeakMap<Node, RootMutObs>();
|
|
15
16
|
const refCount = new WeakMap<Node, number>();
|
|
@@ -87,9 +88,9 @@ export class MountObserver extends EventTarget implements IMountObserver{
|
|
|
87
88
|
|
|
88
89
|
}
|
|
89
90
|
#templLookUp: Map<string, HTMLElement> = new Map();
|
|
90
|
-
findByID(id: string, fragment: DocumentFragment): HTMLElement | null{
|
|
91
|
+
async findByID(id: string, fragment: DocumentFragment): Promise<HTMLElement | null>{
|
|
91
92
|
if(this.#templLookUp.has(id)) return this.#templLookUp.get(id)!;
|
|
92
|
-
let templ = fragment.
|
|
93
|
+
let templ = fragment.querySelector(`#${id}`);
|
|
93
94
|
if(templ === null){
|
|
94
95
|
let rootToSearchOutwardFrom = ((fragment.isConnected ? fragment.getRootNode() : this.#mountInit.withTargetShadowRoot) || document) as any;
|
|
95
96
|
templ = rootToSearchOutwardFrom.getElementById(id);
|
|
@@ -98,8 +99,35 @@ export class MountObserver extends EventTarget implements IMountObserver{
|
|
|
98
99
|
templ = rootToSearchOutwardFrom.getElementById(id);
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
|
-
if(templ !== null)
|
|
102
|
-
|
|
102
|
+
if(templ !== null) {
|
|
103
|
+
if(!(templ instanceof HTMLTemplateElement)){
|
|
104
|
+
const newTempl = document.createElement('template');
|
|
105
|
+
const {getAdjRefs} = await import('./refid/getAdjRefs.js');
|
|
106
|
+
const adjRefs = getAdjRefs(templ);
|
|
107
|
+
// if(adjRefs.length > 1){
|
|
108
|
+
// (<any>newTempl)[wasItemReffed] = true;
|
|
109
|
+
// adjRefs[0].setAttribute('itemref', '<autogen>');
|
|
110
|
+
// }
|
|
111
|
+
const fragment = document.createDocumentFragment();
|
|
112
|
+
let first = true;
|
|
113
|
+
for(const adjRef of adjRefs){
|
|
114
|
+
const clone = adjRef.cloneNode(true) as HTMLElement;
|
|
115
|
+
if(first && adjRefs.length > 1){
|
|
116
|
+
clone.setAttribute('itemref', '<autogen>');
|
|
117
|
+
(<any>newTempl)[wasItemReffed] = true;
|
|
118
|
+
first = false;
|
|
119
|
+
}
|
|
120
|
+
clone.removeAttribute('id');
|
|
121
|
+
fragment.appendChild(clone);
|
|
122
|
+
}
|
|
123
|
+
const {doCleanup} = await import('./doCleanup.js');
|
|
124
|
+
doCleanup(templ as HTMLElement, fragment);
|
|
125
|
+
newTempl.content.appendChild(fragment);
|
|
126
|
+
templ = newTempl;
|
|
127
|
+
}
|
|
128
|
+
this.#templLookUp.set(id, templ as HTMLTemplateElement);
|
|
129
|
+
}
|
|
130
|
+
return templ as HTMLTemplateElement;
|
|
103
131
|
}
|
|
104
132
|
|
|
105
133
|
disconnect(within: Node){
|
|
@@ -442,7 +470,11 @@ export class MountObserver extends EventTarget implements IMountObserver{
|
|
|
442
470
|
}
|
|
443
471
|
|
|
444
472
|
async #inspectWithin(within: Node, initializing: boolean){
|
|
445
|
-
await bindish
|
|
473
|
+
//the line below had an await for bindish, consistent with the rest of the code, but it was
|
|
474
|
+
//getting into a catch-22 scenario frequently, blocking the code for resuming.
|
|
475
|
+
//This was observed with per-each package, demo/ScopeScript.html, clicking refresh a few times
|
|
476
|
+
//one will see the inconsistent behavior if await is added below.
|
|
477
|
+
bindish(within as DocumentFragment, within, {assigner: this.#mountInit.assigner});
|
|
446
478
|
await this.composeFragment(within as DocumentFragment, 0);
|
|
447
479
|
const match = await this.#selector();
|
|
448
480
|
const els = Array.from((within as Element).querySelectorAll(match));
|
package/Newish.js
CHANGED
|
@@ -45,9 +45,9 @@ export class Newish {
|
|
|
45
45
|
if (initPropVals !== undefined)
|
|
46
46
|
this.queue.push(initPropVals);
|
|
47
47
|
}
|
|
48
|
-
if
|
|
49
|
-
|
|
50
|
-
}
|
|
48
|
+
// if('tbd' in ce && typeof ce['tbd'] === 'function'){
|
|
49
|
+
// await ce['tbd'](ce, enhancedElement, this.#options);
|
|
50
|
+
// }
|
|
51
51
|
this.#ce = ce;
|
|
52
52
|
const self = this;
|
|
53
53
|
Object.defineProperty(enhancedElement, 'ish', {
|
|
@@ -121,12 +121,15 @@ export class Newish {
|
|
|
121
121
|
actions.add('ishListAssigned');
|
|
122
122
|
}
|
|
123
123
|
else {
|
|
124
|
-
|
|
124
|
+
let { assigner } = this.#options;
|
|
125
|
+
if (assigner === undefined) {
|
|
126
|
+
assigner = Object.assign;
|
|
127
|
+
}
|
|
125
128
|
await assigner(ce, fi);
|
|
126
129
|
actions.add('ishAssigned');
|
|
127
130
|
}
|
|
128
131
|
}
|
|
129
|
-
if (fromDo && !foundArray) {
|
|
132
|
+
if (fromDo && !foundArray && hasArrFilter) {
|
|
130
133
|
const filtered = await (ce['arr=>'])(ce, undefined, ref, this.#options);
|
|
131
134
|
if (filtered !== undefined) {
|
|
132
135
|
ce[arr] = filtered;
|
package/Newish.ts
CHANGED
|
@@ -51,9 +51,9 @@ export class Newish implements EventListenerObject {
|
|
|
51
51
|
ce = new (ctr as any)();
|
|
52
52
|
if(initPropVals !== undefined) this.queue.push(initPropVals);
|
|
53
53
|
}
|
|
54
|
-
if('tbd' in ce && typeof ce['tbd'] === 'function'){
|
|
55
|
-
|
|
56
|
-
}
|
|
54
|
+
// if('tbd' in ce && typeof ce['tbd'] === 'function'){
|
|
55
|
+
// await ce['tbd'](ce, enhancedElement, this.#options);
|
|
56
|
+
// }
|
|
57
57
|
|
|
58
58
|
this.#ce = ce;
|
|
59
59
|
const self = this;
|
|
@@ -130,13 +130,16 @@ export class Newish implements EventListenerObject {
|
|
|
130
130
|
(<any>ce)[arr] = filtered;
|
|
131
131
|
actions.add('ishListAssigned');
|
|
132
132
|
}else{
|
|
133
|
-
|
|
133
|
+
let {assigner} = this.#options;
|
|
134
|
+
if(assigner === undefined){
|
|
135
|
+
assigner = Object.assign;
|
|
136
|
+
}
|
|
134
137
|
await assigner!(ce, fi);
|
|
135
138
|
actions.add('ishAssigned');
|
|
136
139
|
}
|
|
137
140
|
|
|
138
141
|
}
|
|
139
|
-
if(fromDo && !foundArray){
|
|
142
|
+
if(fromDo && !foundArray && hasArrFilter){
|
|
140
143
|
const filtered = await (ce['arr=>']!)(ce, undefined, ref! as HasIsh & Element, this.#options);
|
|
141
144
|
if(filtered !== undefined){
|
|
142
145
|
(<any>ce)[arr] = filtered;
|
package/README.md
CHANGED
|
@@ -295,6 +295,7 @@ const observer = new MountObserver({
|
|
|
295
295
|
on: 'div > p + p ~ span[class$="name"]',
|
|
296
296
|
whereMediaMatches: '(max-width: 1250px)',
|
|
297
297
|
whereSizeOfContainerMatches: '(min-width: 700px)',
|
|
298
|
+
whereContainerHas: '[itemprop=isActive][value="true"]',
|
|
298
299
|
whereInstanceOf: [HTMLMarqueeElement], //or ['HTMLMarqueeElement']
|
|
299
300
|
whereLangIn: ['en-GB'],
|
|
300
301
|
whereConnection:{
|
|
@@ -850,10 +851,53 @@ This proposal (and polyfill) also supports the option to utilize ShadowDOM / slo
|
|
|
850
851
|
<compose src="#productCard"></compose>
|
|
851
852
|
```
|
|
852
853
|
|
|
853
|
-
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. But I strongly suspect
|
|
854
|
+
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. But I strongly suspect supporting intra document HTML imports could significantly reduce the payload size of some documents, if we can reuse blocks of HTML, inserting sections of customized content for each instance.
|
|
854
855
|
|
|
855
856
|
The [add src attribute to template to load a template from file](https://github.com/whatwg/html/issues/10571) and an interesting proposal that is [coming from](https://github.com/htmlcomponents/declarative-shadow-imports/blob/main/examples/02-explainer-proposal/02-html.html) the Edge team [seem quite compatible](https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/ShadowDOM/explainer.md#proposal-inline-declarative-css-module-scripts) with this idea.
|
|
856
857
|
|
|
858
|
+
## Lazy Loading / Conditionally loading intra document imports [WIP specification]
|
|
859
|
+
|
|
860
|
+
Just as it is useful to be able lazy load external imports when needed, it would also be useful to do the same for intra document HTML imports. The most straightforward way this could be done seems to be as follows, either introducing some attribute like "type=conditional", or defining a new element that inherits from the HTMLTemplateElement, for example:
|
|
861
|
+
|
|
862
|
+
```html
|
|
863
|
+
<template id=source-template type=conditional>
|
|
864
|
+
|
|
865
|
+
<template mount='{
|
|
866
|
+
"on": ":not([defer-loading])",
|
|
867
|
+
"loadingEagerness": "eager",
|
|
868
|
+
"whereMediaMatches": "(min-width: 700px)",
|
|
869
|
+
"whereLangIn": ["en-GB"],
|
|
870
|
+
}'>
|
|
871
|
+
<div>I don't know why you say <slot name=slot2></slot> I say <slot name=slot1></slot></div>
|
|
872
|
+
</template>
|
|
873
|
+
|
|
874
|
+
<template mount='{
|
|
875
|
+
"on": ":not([defer-loading])",
|
|
876
|
+
"loadingEagerness": "lazy",
|
|
877
|
+
"whereMediaMatches": "(max-width: 700px)",
|
|
878
|
+
"whereLangIn": ["fr"],
|
|
879
|
+
}'>
|
|
880
|
+
<div>Je ne sais pas pourquoi tu dis <slot name=slot2></slot> je dis <slot name=slot1></slot></div>
|
|
881
|
+
</template>
|
|
882
|
+
|
|
883
|
+
</template>
|
|
884
|
+
|
|
885
|
+
...
|
|
886
|
+
<template src=#source-template>
|
|
887
|
+
<span slot=slot1>hello</span>
|
|
888
|
+
<span slot=slot2>goodbye<span>
|
|
889
|
+
</template>
|
|
890
|
+
|
|
891
|
+
<!-- or, alternatively: -->
|
|
892
|
+
|
|
893
|
+
<compose src=#source-template>
|
|
894
|
+
<span slot=slot1>hello</span>
|
|
895
|
+
<span slot=slot2>goodbye<span>
|
|
896
|
+
</compose>
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
|
|
857
901
|
## Creating "frameworks" that revolve around MOSEs.
|
|
858
902
|
|
|
859
903
|
Often, we will want to define a large number of "mount observer script elements (MOSEs)" programmatically, and we need it to be done in a generic way, that can be published and easily referenced.
|
package/compose.js
CHANGED
|
@@ -1,20 +1,53 @@
|
|
|
1
|
-
import { inclTemplQry } from './MountObserver.js';
|
|
1
|
+
import { inclTemplQry, wasItemReffed } from './MountObserver.js';
|
|
2
2
|
export const childRefsKey = Symbol.for('Wr0WPVh84k+O93miuENdMA');
|
|
3
3
|
export const cloneKey = Symbol.for('LD97VKZYc02CQv23DT/6fQ');
|
|
4
|
+
const autogenKey = Symbol.for('YpP5EP0i1UKcBBBH9tsm0w');
|
|
4
5
|
export async function compose(self, el, level) {
|
|
5
|
-
if (!el.hasAttribute('src')) {
|
|
6
|
-
return;
|
|
7
|
-
}
|
|
8
6
|
const src = el.getAttribute('src');
|
|
7
|
+
if (src === null)
|
|
8
|
+
return;
|
|
9
9
|
el.removeAttribute('src');
|
|
10
10
|
const templID = src.substring(1);
|
|
11
11
|
const fragment = self.objNde?.deref();
|
|
12
12
|
if (fragment === undefined)
|
|
13
13
|
return;
|
|
14
|
-
const templ = self.findByID(templID, fragment);
|
|
14
|
+
const templ = await self.findByID(templID, fragment);
|
|
15
15
|
if (!(templ instanceof HTMLTemplateElement))
|
|
16
16
|
throw 404;
|
|
17
17
|
const clone = templ.content.cloneNode(true);
|
|
18
|
+
const dataLd = el.dataset.ld;
|
|
19
|
+
const wasReffed = templ[wasItemReffed];
|
|
20
|
+
if (wasReffed || dataLd) {
|
|
21
|
+
const firstElement = clone.firstElementChild;
|
|
22
|
+
if (wasReffed) {
|
|
23
|
+
let ns = firstElement.nextElementSibling;
|
|
24
|
+
const ids = [];
|
|
25
|
+
let count = window[autogenKey];
|
|
26
|
+
if (count === undefined) {
|
|
27
|
+
count = 0;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
count++;
|
|
31
|
+
}
|
|
32
|
+
window[autogenKey] = count;
|
|
33
|
+
while (ns !== null) {
|
|
34
|
+
const id = ns.id = `mount-observer-${count}`;
|
|
35
|
+
ids.push(id);
|
|
36
|
+
ns = ns.nextElementSibling;
|
|
37
|
+
}
|
|
38
|
+
firstElement.setAttribute('itemref', ids.join(' '));
|
|
39
|
+
}
|
|
40
|
+
if (dataLd) {
|
|
41
|
+
const parsed = JSON.parse(dataLd);
|
|
42
|
+
let type = parsed['@type'];
|
|
43
|
+
const itemscopeAttr = firstElement.getAttribute('itemscope');
|
|
44
|
+
if (type && !itemscopeAttr) {
|
|
45
|
+
firstElement.setAttribute('itemscope', type);
|
|
46
|
+
}
|
|
47
|
+
firstElement['ish'] = parsed;
|
|
48
|
+
delete el.dataset.ld;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
18
51
|
const slots = el.content.querySelectorAll(`[slot]`);
|
|
19
52
|
for (const slot of slots) {
|
|
20
53
|
const name = slot.getAttribute('slot');
|
package/compose.ts
CHANGED
|
@@ -1,25 +1,56 @@
|
|
|
1
1
|
import { ILoadEvent, loadEventName } from './ts-refs/mount-observer/types';
|
|
2
|
-
import { MountObserver, inclTemplQry } from './MountObserver.js';
|
|
2
|
+
import { MountObserver, inclTemplQry, wasItemReffed } from './MountObserver.js';
|
|
3
3
|
|
|
4
4
|
export const childRefsKey = Symbol.for('Wr0WPVh84k+O93miuENdMA');
|
|
5
5
|
export const cloneKey = Symbol.for('LD97VKZYc02CQv23DT/6fQ');
|
|
6
|
-
|
|
6
|
+
const autogenKey = Symbol.for('YpP5EP0i1UKcBBBH9tsm0w');
|
|
7
7
|
export async function compose(
|
|
8
8
|
self: MountObserver,
|
|
9
9
|
el: HTMLTemplateElement,
|
|
10
10
|
level: number
|
|
11
11
|
){
|
|
12
|
-
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
const src = el.getAttribute('src');
|
|
12
|
+
const src = el.getAttribute('src'); if(src === null) return;
|
|
16
13
|
el.removeAttribute('src');
|
|
17
14
|
const templID = src!.substring(1);
|
|
18
15
|
const fragment = self.objNde?.deref() as DocumentFragment;
|
|
19
16
|
if(fragment === undefined) return;
|
|
20
|
-
const templ = self.findByID(templID, fragment);
|
|
17
|
+
const templ = await self.findByID(templID, fragment);
|
|
21
18
|
if(!(templ instanceof HTMLTemplateElement)) throw 404;
|
|
22
19
|
const clone = templ.content.cloneNode(true) as DocumentFragment;
|
|
20
|
+
const dataLd = el.dataset.ld;
|
|
21
|
+
const wasReffed = (<any>templ)[wasItemReffed];
|
|
22
|
+
if(wasReffed || dataLd){
|
|
23
|
+
const firstElement = clone.firstElementChild!;
|
|
24
|
+
if(wasReffed){
|
|
25
|
+
let ns = firstElement.nextElementSibling;
|
|
26
|
+
const ids = [];
|
|
27
|
+
let count = (<any>window)[autogenKey];
|
|
28
|
+
if(count === undefined){
|
|
29
|
+
count = 0;
|
|
30
|
+
}else{
|
|
31
|
+
count++;
|
|
32
|
+
}
|
|
33
|
+
(<any>window)[autogenKey] = count;
|
|
34
|
+
while(ns !== null){
|
|
35
|
+
const id = ns.id = `mount-observer-${count}`;
|
|
36
|
+
ids.push(id);
|
|
37
|
+
ns = ns.nextElementSibling;
|
|
38
|
+
}
|
|
39
|
+
firstElement.setAttribute('itemref', ids.join(' '));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if(dataLd){
|
|
43
|
+
const parsed = JSON.parse(dataLd);
|
|
44
|
+
let type = parsed['@type'];
|
|
45
|
+
const itemscopeAttr = firstElement.getAttribute('itemscope');
|
|
46
|
+
if(type && !itemscopeAttr){
|
|
47
|
+
firstElement.setAttribute('itemscope', type);
|
|
48
|
+
}
|
|
49
|
+
(<any>firstElement)['ish'] = parsed;
|
|
50
|
+
delete el.dataset.ld;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
}
|
|
23
54
|
const slots = el.content.querySelectorAll(`[slot]`);
|
|
24
55
|
|
|
25
56
|
for(const slot of slots){
|
package/doCleanup.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function doCleanup(htmlSrc, clone, options = {
|
|
2
|
+
removeInner: '[itemprop]:not([itemscope])',
|
|
3
|
+
removeOuter: '[itemprop][itemscope]'
|
|
4
|
+
}) {
|
|
5
|
+
const removeInner = htmlSrc.getAttribute('remove-inner') || options.removeInner;
|
|
6
|
+
if (removeInner) {
|
|
7
|
+
const removeInnerEls = clone.querySelectorAll(removeInner);
|
|
8
|
+
for (const removeInnerEl of removeInnerEls) {
|
|
9
|
+
if ('href' in removeInnerEl) {
|
|
10
|
+
removeInnerEl.href = '';
|
|
11
|
+
}
|
|
12
|
+
else if ('value' in removeInnerEl) {
|
|
13
|
+
removeInnerEl.value = '';
|
|
14
|
+
}
|
|
15
|
+
else if ('datetime' in removeInnerEl) {
|
|
16
|
+
removeInnerEl.datetime = '';
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
//any other exceptions?
|
|
20
|
+
removeInnerEl.textContent = '';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const removeOuter = htmlSrc.getAttribute('remove-outer') || options.removeOuter;
|
|
25
|
+
if (removeOuter) {
|
|
26
|
+
const removeOuterEls = clone.querySelectorAll(removeOuter);
|
|
27
|
+
for (const removeOuterEl of removeOuterEls) {
|
|
28
|
+
removeOuterEl.remove();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
package/doCleanup.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
interface doCleanUpOptions {
|
|
2
|
+
removeInner?: string;
|
|
3
|
+
removeOuter?: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export function doCleanup(htmlSrc: HTMLElement, clone: DocumentFragment, options: doCleanUpOptions = {
|
|
7
|
+
removeInner: '[itemprop]:not([itemscope])',
|
|
8
|
+
removeOuter: '[itemprop][itemscope]'
|
|
9
|
+
}){
|
|
10
|
+
const removeInner = htmlSrc.getAttribute('remove-inner') || options.removeInner;
|
|
11
|
+
if(removeInner){
|
|
12
|
+
const removeInnerEls = clone.querySelectorAll(removeInner);
|
|
13
|
+
for(const removeInnerEl of removeInnerEls){
|
|
14
|
+
if('href' in removeInnerEl){
|
|
15
|
+
removeInnerEl.href = '';
|
|
16
|
+
} else if ('value' in removeInnerEl){
|
|
17
|
+
removeInnerEl.value = '';
|
|
18
|
+
}else if('datetime' in removeInnerEl){
|
|
19
|
+
removeInnerEl.datetime = '';
|
|
20
|
+
}else{
|
|
21
|
+
//any other exceptions?
|
|
22
|
+
removeInnerEl.textContent = '';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const removeOuter = htmlSrc.getAttribute('remove-outer') || options.removeOuter;
|
|
27
|
+
if(removeOuter){
|
|
28
|
+
const removeOuterEls = clone.querySelectorAll(removeOuter);
|
|
29
|
+
for(const removeOuterEl of removeOuterEls){
|
|
30
|
+
removeOuterEl.remove();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mount-observer",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.69",
|
|
4
4
|
"description": "Observe and act on css matches.",
|
|
5
5
|
"main": "MountObserver.js",
|
|
6
6
|
"module": "MountObserver.js",
|
|
@@ -37,6 +37,10 @@
|
|
|
37
37
|
"default": "./compose.js",
|
|
38
38
|
"types": "./compose.ts"
|
|
39
39
|
},
|
|
40
|
+
"./doCleanup.js": {
|
|
41
|
+
"default": "./doCleanup.js",
|
|
42
|
+
"types": "./doCleanup.ts"
|
|
43
|
+
},
|
|
40
44
|
"./waitForEvent.js": {
|
|
41
45
|
"default": "./waitForEvent.js",
|
|
42
46
|
"types": "./waitForEvent.ts"
|
|
@@ -45,6 +49,10 @@
|
|
|
45
49
|
"default": "./waitForIsh.js",
|
|
46
50
|
"types": "./waitForIsh.ts"
|
|
47
51
|
},
|
|
52
|
+
"./refid/getAdjRefs.js": {
|
|
53
|
+
"default": "./refid/getAdjRefs.js",
|
|
54
|
+
"types": "./refid/getAdjRefs.ts"
|
|
55
|
+
},
|
|
48
56
|
"./refid/regIsh.js": {
|
|
49
57
|
"default": "./refid/regIsh.js",
|
|
50
58
|
"types": "./refid/regIsh.js"
|
|
@@ -52,6 +60,10 @@
|
|
|
52
60
|
"./refid/splitRefs.js": {
|
|
53
61
|
"default": "./refid/splitRefs.js",
|
|
54
62
|
"types": "./refid/splitRefs.ts"
|
|
63
|
+
},
|
|
64
|
+
"./slotkin/beKindred.js": {
|
|
65
|
+
"default": "./slotkin/beKindred.js",
|
|
66
|
+
"types": "./slotkin/beKindred.ts"
|
|
55
67
|
}
|
|
56
68
|
},
|
|
57
69
|
"files": [
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { splitRefs } from './splitRefs.js';
|
|
2
|
+
export function getAdjRefs(el) {
|
|
3
|
+
const returnArr = [el];
|
|
4
|
+
const itemref = el.getAttribute('itemref');
|
|
5
|
+
if (itemref === null)
|
|
6
|
+
return returnArr;
|
|
7
|
+
const itemrefList = splitRefs(itemref); // itemref.split(' ').map((id) => id.trim()).filter((id) => id.length > 0);
|
|
8
|
+
if (itemrefList.length === 0)
|
|
9
|
+
return returnArr;
|
|
10
|
+
let ns = el.nextElementSibling;
|
|
11
|
+
while (ns !== null && itemrefList.includes(ns.id)) {
|
|
12
|
+
returnArr.push(ns);
|
|
13
|
+
ns = ns.nextElementSibling;
|
|
14
|
+
}
|
|
15
|
+
return returnArr;
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { splitRefs } from './splitRefs.js';
|
|
2
|
+
export function getAdjRefs(el: Element): Array<Element>{
|
|
3
|
+
const returnArr = [el];
|
|
4
|
+
const itemref = el.getAttribute('itemref');
|
|
5
|
+
if(itemref === null) return returnArr;
|
|
6
|
+
const itemrefList = splitRefs(itemref);// itemref.split(' ').map((id) => id.trim()).filter((id) => id.length > 0);
|
|
7
|
+
if(itemrefList.length === 0) return returnArr;
|
|
8
|
+
let ns = el.nextElementSibling;
|
|
9
|
+
while(ns !== null && itemrefList.includes(ns.id)){
|
|
10
|
+
returnArr.push(ns);
|
|
11
|
+
ns = ns.nextElementSibling;
|
|
12
|
+
}
|
|
13
|
+
return returnArr;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {IEnhancement, BEAllProps} from '../trans-render/be/types';
|
|
2
|
+
import {Specifier} from '../trans-render/dss/types';
|
|
3
|
+
|
|
4
|
+
export interface EndUserProps extends IEnhancement<HTMLTemplateElement>{
|
|
5
|
+
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface AllProps extends EndUserProps{
|
|
9
|
+
nodesToImbue: Element[],
|
|
10
|
+
imbueRules: Array<ImbueRule>,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type AP = AllProps;
|
|
14
|
+
|
|
15
|
+
export type PAP = Partial<AP>;
|
|
16
|
+
|
|
17
|
+
export type ProPAP = Promise<PAP>;
|
|
18
|
+
|
|
19
|
+
export type BAP = AP & BEAllProps;
|
|
20
|
+
|
|
21
|
+
export interface Actions{
|
|
22
|
+
hydrate(self: BAP): Promise<PAP>;
|
|
23
|
+
imbue(self: BAP): void;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ImbueRule {
|
|
27
|
+
remoteSpecifierString?: string,
|
|
28
|
+
remoteSpecifier: Specifier,
|
|
29
|
+
}
|
|
30
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {IEnhancement, BEAllProps} from '../trans-render/be/types';
|
|
2
|
+
|
|
3
|
+
export interface EndUserProps extends IEnhancement<HTMLTemplateElement>{
|
|
4
|
+
in: string,
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface AllProps extends EndUserProps{
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type AP = AllProps;
|
|
11
|
+
|
|
12
|
+
export type PAP = Partial<AP>;
|
|
13
|
+
|
|
14
|
+
export type ProPAP = Promise<PAP>;
|
|
15
|
+
|
|
16
|
+
export type BAP = AP & BEAllProps;
|
|
17
|
+
|
|
18
|
+
export interface Actions{
|
|
19
|
+
hydrate(self: BAP): void;
|
|
20
|
+
}
|
|
@@ -12,7 +12,8 @@ export interface EndUserProps extends IEnhancement{
|
|
|
12
12
|
export interface AllProps extends EndUserProps{
|
|
13
13
|
listProp: string;
|
|
14
14
|
itemProp: string;
|
|
15
|
-
ish:
|
|
15
|
+
ish: HasIshList;
|
|
16
|
+
ishContainer: Element;
|
|
16
17
|
itemTemplate: HTMLTemplateElement;
|
|
17
18
|
emc: any;
|
|
18
19
|
//updateCnt: number;
|
|
@@ -191,6 +191,7 @@ export interface IshConfig<TProps = any, TActions = TProps, ETProps = TProps>{
|
|
|
191
191
|
xform?: XForm<TProps, TActions>;
|
|
192
192
|
inScopeXForms?: {[key: CSSQuery]: XForm<TProps, TActions>};
|
|
193
193
|
ishListCountProp?: keyof TProps & string;
|
|
194
|
+
defaultIshList?: any[];
|
|
194
195
|
}
|
|
195
196
|
export interface OConfig<TProps = any, TActions = TProps, ETProps = TProps> extends IshConfig<TProps, TActions, ETProps>{
|
|
196
197
|
mainTemplate?: string | HTMLTemplateElement;
|
|
@@ -556,7 +556,8 @@ export type StringWithAutocompleteOptions<TOptions> =
|
|
|
556
556
|
| TOptions;
|
|
557
557
|
|
|
558
558
|
export interface Clone$Options{
|
|
559
|
-
ish:
|
|
559
|
+
ish: HasIshList,
|
|
560
|
+
ishContainer: Element,
|
|
560
561
|
seedEl: Element,
|
|
561
562
|
idxStart: number,
|
|
562
563
|
itemProp: string,
|