mount-observer 0.0.16 → 0.0.18
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 +53 -47
- package/birtualizeMatch.js +0 -1
- package/getWhereAttrSelector.js +55 -10
- package/package.json +1 -1
- package/types.d.ts +2 -0
package/MountObserver.js
CHANGED
|
@@ -29,6 +29,7 @@ export class MountObserver extends EventTarget {
|
|
|
29
29
|
//this.#unmounted = new WeakSet();
|
|
30
30
|
}
|
|
31
31
|
#calculatedSelector;
|
|
32
|
+
#attrParts;
|
|
32
33
|
#fullListOfAttrs;
|
|
33
34
|
//get #attrVals
|
|
34
35
|
async #selector() {
|
|
@@ -40,8 +41,9 @@ export class MountObserver extends EventTarget {
|
|
|
40
41
|
return withoutAttrs;
|
|
41
42
|
const { getWhereAttrSelector } = await import('./getWhereAttrSelector.js');
|
|
42
43
|
const info = getWhereAttrSelector(whereAttr, withoutAttrs);
|
|
43
|
-
const { fullListOfAttrs, calculatedSelector } = info;
|
|
44
|
+
const { fullListOfAttrs, calculatedSelector, partitionedAttrs } = info;
|
|
44
45
|
this.#fullListOfAttrs = fullListOfAttrs;
|
|
46
|
+
this.#attrParts = partitionedAttrs;
|
|
45
47
|
this.#calculatedSelector = calculatedSelector;
|
|
46
48
|
return this.#calculatedSelector;
|
|
47
49
|
}
|
|
@@ -98,6 +100,7 @@ export class MountObserver extends EventTarget {
|
|
|
98
100
|
}
|
|
99
101
|
}
|
|
100
102
|
async observe(within) {
|
|
103
|
+
await this.#selector();
|
|
101
104
|
this.objNde = new WeakRef(within);
|
|
102
105
|
const nodeToMonitor = this.#isComplex ? (within instanceof ShadowRoot ? within : within.getRootNode()) : within;
|
|
103
106
|
if (!mutationObserverLookup.has(nodeToMonitor)) {
|
|
@@ -114,7 +117,6 @@ export class MountObserver extends EventTarget {
|
|
|
114
117
|
}
|
|
115
118
|
}
|
|
116
119
|
const rootMutObs = mutationObserverLookup.get(within);
|
|
117
|
-
//const {whereAttr} = this.#mountInit;
|
|
118
120
|
const fullListOfAttrs = this.#fullListOfAttrs;
|
|
119
121
|
rootMutObs.addEventListener('mutation-event', async (e) => {
|
|
120
122
|
//TODO: disconnected
|
|
@@ -126,32 +128,33 @@ export class MountObserver extends EventTarget {
|
|
|
126
128
|
const elsToInspect = [];
|
|
127
129
|
//const elsToDisconnect: Array<Element> = [];
|
|
128
130
|
const doDisconnect = this.#mountInit.do?.disconnect;
|
|
131
|
+
let attrChangeInfosMap;
|
|
129
132
|
for (const mutationRecord of mutationRecords) {
|
|
130
133
|
const { addedNodes, type, removedNodes } = mutationRecord;
|
|
131
|
-
//console.log(mutationRecord);
|
|
132
134
|
const addedElements = Array.from(addedNodes).filter(x => x instanceof Element);
|
|
133
135
|
addedElements.forEach(x => elsToInspect.push(x));
|
|
134
136
|
if (type === 'attributes') {
|
|
135
137
|
const { target, attributeName, oldValue } = mutationRecord;
|
|
136
|
-
if (target instanceof Element && attributeName !== null
|
|
138
|
+
if (target instanceof Element && attributeName !== null /*&& this.#mounted.has(target)*/) {
|
|
137
139
|
if (fullListOfAttrs !== undefined) {
|
|
138
140
|
const idx = fullListOfAttrs.indexOf(attributeName);
|
|
139
|
-
if (idx
|
|
141
|
+
if (idx !== -1) {
|
|
142
|
+
if (attrChangeInfosMap === undefined)
|
|
143
|
+
attrChangeInfosMap = new Map();
|
|
144
|
+
let attrChangeInfos = attrChangeInfosMap.get(target);
|
|
145
|
+
if (attrChangeInfos === undefined) {
|
|
146
|
+
attrChangeInfos = [];
|
|
147
|
+
attrChangeInfosMap.set(target, attrChangeInfos);
|
|
148
|
+
}
|
|
140
149
|
const newValue = target.getAttribute(attributeName);
|
|
150
|
+
const parts = this.#attrParts[idx];
|
|
141
151
|
const attrChangeInfo = {
|
|
142
|
-
name: attributeName,
|
|
143
152
|
oldValue,
|
|
144
153
|
newValue,
|
|
145
|
-
idx
|
|
154
|
+
idx,
|
|
155
|
+
parts
|
|
146
156
|
};
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
const { whereAttr } = this.#mountInit;
|
|
152
|
-
if (whereAttr !== undefined) {
|
|
153
|
-
const { doWhereAttr } = await import('./doWhereAttr.js');
|
|
154
|
-
doWhereAttr(whereAttr, attributeName, target, oldValue, this);
|
|
157
|
+
attrChangeInfos.push(attrChangeInfo);
|
|
155
158
|
}
|
|
156
159
|
}
|
|
157
160
|
}
|
|
@@ -166,6 +169,11 @@ export class MountObserver extends EventTarget {
|
|
|
166
169
|
this.dispatchEvent(new DisconnectEvent(deletedElement));
|
|
167
170
|
}
|
|
168
171
|
}
|
|
172
|
+
if (attrChangeInfosMap !== undefined) {
|
|
173
|
+
for (const [key, value] of attrChangeInfosMap) {
|
|
174
|
+
this.dispatchEvent(new AttrChangeEvent(key, value));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
169
177
|
this.#filterAndMount(elsToInspect, true, false);
|
|
170
178
|
}, { signal: this.#abortController.signal });
|
|
171
179
|
await this.#inspectWithin(within, true);
|
|
@@ -182,7 +190,6 @@ export class MountObserver extends EventTarget {
|
|
|
182
190
|
const alreadyMounted = await this.#filterAndDismount();
|
|
183
191
|
const mount = this.#mountInit.do?.mount;
|
|
184
192
|
const { import: imp } = this.#mountInit;
|
|
185
|
-
const fullListOfAttrs = this.#fullListOfAttrs;
|
|
186
193
|
for (const match of matching) {
|
|
187
194
|
if (alreadyMounted.has(match))
|
|
188
195
|
continue;
|
|
@@ -212,37 +219,36 @@ export class MountObserver extends EventTarget {
|
|
|
212
219
|
});
|
|
213
220
|
}
|
|
214
221
|
this.dispatchEvent(new MountEvent(match, initializing));
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
+
//should we automatically call readAttrs?
|
|
223
|
+
//the thinking is it might make more sense to call that after mounting
|
|
224
|
+
this.#mountedList?.push(new WeakRef(match));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
readAttrs(match, branchIndexes) {
|
|
228
|
+
const fullListOfAttrs = this.#fullListOfAttrs;
|
|
229
|
+
const attrChangeInfos = [];
|
|
230
|
+
if (fullListOfAttrs !== undefined) {
|
|
231
|
+
const attrParts = this.#attrParts;
|
|
232
|
+
for (let idx = 0, ii = fullListOfAttrs.length; idx < ii; idx++) {
|
|
233
|
+
const parts = attrParts[idx];
|
|
234
|
+
const { branchIdx } = parts;
|
|
235
|
+
if (branchIndexes !== undefined) {
|
|
236
|
+
if (!branchIndexes.has(branchIdx))
|
|
237
|
+
continue;
|
|
222
238
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
// }
|
|
233
|
-
// const attribInfo: AttrChangeInfo = {
|
|
234
|
-
// oldValue: null,
|
|
235
|
-
// newValue,
|
|
236
|
-
// idx,
|
|
237
|
-
// name: nonNullName
|
|
238
|
-
// };
|
|
239
|
-
// this.dispatchEvent(new AttrChangeEvent(match, attribInfo));
|
|
240
|
-
// idx++;
|
|
241
|
-
// }
|
|
239
|
+
const name = fullListOfAttrs[idx];
|
|
240
|
+
const oldValue = null;
|
|
241
|
+
const newValue = match.getAttribute(name);
|
|
242
|
+
attrChangeInfos.push({
|
|
243
|
+
idx,
|
|
244
|
+
newValue,
|
|
245
|
+
oldValue,
|
|
246
|
+
parts
|
|
247
|
+
});
|
|
242
248
|
}
|
|
243
|
-
this
|
|
244
|
-
//if(this.#unmounted.has(match)) this.#unmounted.delete(match);
|
|
249
|
+
//this.dispatchEvent(new AttrChangeEvent(match, attrChangeInfos));
|
|
245
250
|
}
|
|
251
|
+
return attrChangeInfos;
|
|
246
252
|
}
|
|
247
253
|
async #dismount(unmatching) {
|
|
248
254
|
const onDismount = this.#mountInit.do?.dismount;
|
|
@@ -342,12 +348,12 @@ export class DisconnectEvent extends Event {
|
|
|
342
348
|
}
|
|
343
349
|
export class AttrChangeEvent extends Event {
|
|
344
350
|
mountedElement;
|
|
345
|
-
|
|
351
|
+
attrChangeInfos;
|
|
346
352
|
static eventName = 'attr-change';
|
|
347
|
-
constructor(mountedElement,
|
|
353
|
+
constructor(mountedElement, attrChangeInfos) {
|
|
348
354
|
super(AttrChangeEvent.eventName);
|
|
349
355
|
this.mountedElement = mountedElement;
|
|
350
|
-
this.
|
|
356
|
+
this.attrChangeInfos = attrChangeInfos;
|
|
351
357
|
}
|
|
352
358
|
}
|
|
353
359
|
//const hasRootInDefault = ['data', 'enh', 'data-enh']
|
package/birtualizeMatch.js
CHANGED
package/getWhereAttrSelector.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
export function getWhereAttrSelector(whereAttr, withoutAttrs) {
|
|
2
2
|
const { hasBase, hasBranchIn, hasRootIn } = whereAttr;
|
|
3
|
+
const hasRootInGuaranteed = hasRootIn || [{
|
|
4
|
+
start: '',
|
|
5
|
+
context: 'Both'
|
|
6
|
+
}];
|
|
3
7
|
const fullListOfAttrs = [];
|
|
4
|
-
|
|
8
|
+
const partitionedAttrs = [];
|
|
9
|
+
let prefixLessMatches = [];
|
|
5
10
|
const hasBaseIsString = typeof hasBase === 'string';
|
|
6
11
|
const baseSelector = hasBaseIsString ? hasBase : hasBase[1];
|
|
7
12
|
const rootToBaseDelimiter = hasBaseIsString ? '-' : hasBase[0];
|
|
8
|
-
//end TODO
|
|
9
|
-
let prefixLessMatches = [baseSelector];
|
|
10
13
|
if (hasBranchIn !== undefined) {
|
|
11
14
|
let baseToBranchDelimiter = '-';
|
|
12
15
|
let branches;
|
|
@@ -17,19 +20,61 @@ export function getWhereAttrSelector(whereAttr, withoutAttrs) {
|
|
|
17
20
|
else {
|
|
18
21
|
branches = hasBranchIn;
|
|
19
22
|
}
|
|
20
|
-
prefixLessMatches = branches.map(x =>
|
|
23
|
+
prefixLessMatches = branches.map(x => ({
|
|
24
|
+
rootToBaseDelimiter,
|
|
25
|
+
base: baseSelector,
|
|
26
|
+
baseToBranchDelimiter: x ? baseToBranchDelimiter : '',
|
|
27
|
+
branch: x
|
|
28
|
+
}));
|
|
21
29
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
else {
|
|
31
|
+
prefixLessMatches.push({
|
|
32
|
+
rootToBaseDelimiter,
|
|
33
|
+
base: baseSelector,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
for (const rootCnfg of hasRootInGuaranteed) {
|
|
37
|
+
const { start } = rootCnfg;
|
|
38
|
+
for (const match of prefixLessMatches) {
|
|
39
|
+
const { base, baseToBranchDelimiter, branch, rootToBaseDelimiter } = match;
|
|
40
|
+
let branchIdx = 0;
|
|
41
|
+
for (const prefixLessMatch of prefixLessMatches) {
|
|
42
|
+
const { base, baseToBranchDelimiter, branch } = prefixLessMatch;
|
|
43
|
+
const startAndRootToBaseDelimiter = start ? `${start}${rootToBaseDelimiter}` : '';
|
|
44
|
+
//TODO: could probably reduce the size of the code below
|
|
45
|
+
if (branch) {
|
|
46
|
+
//will always have branch?
|
|
47
|
+
const name = `${startAndRootToBaseDelimiter}${base}${baseToBranchDelimiter}${branch}`;
|
|
48
|
+
fullListOfAttrs.push(name);
|
|
49
|
+
partitionedAttrs.push({
|
|
50
|
+
root: start,
|
|
51
|
+
name,
|
|
52
|
+
base,
|
|
53
|
+
branch,
|
|
54
|
+
branchIdx,
|
|
55
|
+
rootCnfg
|
|
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
|
+
});
|
|
68
|
+
}
|
|
69
|
+
branchIdx++;
|
|
70
|
+
}
|
|
27
71
|
}
|
|
28
72
|
}
|
|
29
73
|
const listOfSelectors = fullListOfAttrs.map(s => `${withoutAttrs}[${s}]`);
|
|
30
74
|
const calculatedSelector = listOfSelectors.join(',');
|
|
31
75
|
return {
|
|
32
76
|
fullListOfAttrs,
|
|
33
|
-
calculatedSelector
|
|
77
|
+
calculatedSelector,
|
|
78
|
+
partitionedAttrs,
|
|
34
79
|
};
|
|
35
80
|
}
|
package/package.json
CHANGED