mount-observer 0.0.3 → 0.0.4
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 +2 -1
- package/README.md +6 -1
- package/package.json +11 -2
- package/.github/workflows/CI.yml +0 -18
- package/MountObserver.ts +0 -282
- package/RootMutObs.ts +0 -37
- package/demo/test1.html +0 -28
- package/playwright.config.ts +0 -29
- package/tests/test1.html +0 -30
- package/tests/test1.spec.mjs +0 -8
- package/tests/test2.html +0 -34
- package/tests/test2.spec.mjs +0 -8
- package/tests/test3.html +0 -34
- package/tests/test3.spec.mjs +0 -8
- package/tests/test4.html +0 -31
- package/tests/test4.spec.mjs +0 -8
- package/tests/test5.html +0 -34
- package/tests/test5.spec.mjs +0 -8
- package/tests/test6.html +0 -33
- package/tests/test6.spec.mjs +0 -8
- package/tsconfig.json +0 -17
package/MountObserver.js
CHANGED
|
@@ -136,7 +136,8 @@ export class MountObserver extends EventTarget {
|
|
|
136
136
|
break;
|
|
137
137
|
case 'object':
|
|
138
138
|
if (Array.isArray(imp)) {
|
|
139
|
-
|
|
139
|
+
throw 'NI: Firefox';
|
|
140
|
+
//this.module = await import(imp[0], imp[1]);
|
|
140
141
|
}
|
|
141
142
|
break;
|
|
142
143
|
case 'function':
|
package/README.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
[](https://github.com/bahrus/mount-observer/actions/workflows/CI.yml)
|
|
2
|
+
[](http://badge.fury.io/js/mount-observer)
|
|
3
|
+
[](https://bundlephobia.com/result?p=mount-observer)
|
|
4
|
+
<img src="http://img.badgesize.io/https://cdn.jsdelivr.net/npm/mount-observer?compression=gzip">
|
|
5
|
+
|
|
1
6
|
# The MountObserver api.
|
|
2
7
|
|
|
3
8
|
Author: Bruce B. Anderson
|
|
@@ -179,7 +184,7 @@ If an element that is in "mounted" state according to a MountObserver instance i
|
|
|
179
184
|
4) If the new place it was added remains within the original rootNode and remains either dismounted or mounted, the MountObserver instance dispatches event "reconfirmed".
|
|
180
185
|
5) If the element no longer satisfies the criteria of the MountObserver instance, the MountObserver instance will dispatch event "dismount". The same is done in reverse for moved elements that started out in a "dismounted" state.
|
|
181
186
|
|
|
182
|
-
## Special support for attributes
|
|
187
|
+
## Special support for observable attributes
|
|
183
188
|
|
|
184
189
|
Extra support is provided for monitoring attributes.
|
|
185
190
|
|
package/package.json
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mount-observer",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "0.0.4",
|
|
4
|
+
"description": "Observe and act on css matches.",
|
|
5
5
|
"main": "MountObserver.js",
|
|
6
6
|
"module": "MountObserver.js",
|
|
7
7
|
"devDependencies": {
|
|
8
8
|
"@playwright/test": "1.39.0",
|
|
9
9
|
"may-it-serve": "0.0.6"
|
|
10
10
|
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": "./MountObserver.js",
|
|
13
|
+
"./MountObserver.js": "./MountObserver.js"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"*.js",
|
|
17
|
+
"types.d.ts"
|
|
18
|
+
],
|
|
19
|
+
"types": "types.d.ts",
|
|
11
20
|
"scripts": {
|
|
12
21
|
"serve": "node node_modules/may-it-serve",
|
|
13
22
|
"test": "playwright test",
|
package/.github/workflows/CI.yml
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
name: Playwright Tests
|
|
2
|
-
on: [push]
|
|
3
|
-
jobs:
|
|
4
|
-
test:
|
|
5
|
-
timeout-minutes: 10
|
|
6
|
-
runs-on: ubuntu-latest
|
|
7
|
-
steps:
|
|
8
|
-
- uses: actions/checkout@v2
|
|
9
|
-
- uses: actions/setup-node@v2
|
|
10
|
-
with:
|
|
11
|
-
node-version: '16.x'
|
|
12
|
-
- name: Install dependencies
|
|
13
|
-
run: npm ci
|
|
14
|
-
- name: Install Playwright
|
|
15
|
-
run: npx playwright install --with-deps
|
|
16
|
-
- name: Run Playwright tests
|
|
17
|
-
run: npm run test
|
|
18
|
-
|
package/MountObserver.ts
DELETED
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
import {MountInit, MountContext, AddMutationEventListener,
|
|
2
|
-
MutationEvent, dismountEventName, mountEventName, IMountEvent, IDismountEvent,
|
|
3
|
-
disconnectedEventName, IDisconnectEvent, IAttrChangeEvent, attrChangeEventName, AttrChangeInfo
|
|
4
|
-
} from './types';
|
|
5
|
-
import {RootMutObs} from './RootMutObs.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const mutationObserverLookup = new WeakMap<Node, RootMutObs>();
|
|
9
|
-
export class MountObserver extends EventTarget implements MountContext{
|
|
10
|
-
|
|
11
|
-
#mountInit: MountInit;
|
|
12
|
-
#rootMutObs: RootMutObs | undefined;
|
|
13
|
-
#abortController: AbortController;
|
|
14
|
-
#mounted: WeakSet<Element>;
|
|
15
|
-
#mountedList: Array<WeakRef<Element>> | undefined;
|
|
16
|
-
#disconnected: WeakSet<Element>;
|
|
17
|
-
//#unmounted: WeakSet<Element>;
|
|
18
|
-
#isComplex: boolean;
|
|
19
|
-
|
|
20
|
-
constructor(init: MountInit){
|
|
21
|
-
super();
|
|
22
|
-
const {match, whereElementIntersectsWith, whereMediaMatches} = init;
|
|
23
|
-
let isComplex = false;
|
|
24
|
-
if(match !== undefined){
|
|
25
|
-
const reducedMatch = match.replaceAll(':not(', '');
|
|
26
|
-
isComplex = reducedMatch.includes(' ') || reducedMatch.includes(':');
|
|
27
|
-
}
|
|
28
|
-
this.#isComplex = isComplex;
|
|
29
|
-
if(whereElementIntersectsWith || whereMediaMatches) throw 'NI'; //not implemented
|
|
30
|
-
this.#mountInit = init;
|
|
31
|
-
this.#abortController = new AbortController();
|
|
32
|
-
this.#mounted = new WeakSet();
|
|
33
|
-
this.#disconnected = new WeakSet();
|
|
34
|
-
//this.#unmounted = new WeakSet();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
#calculatedSelector: string | undefined;
|
|
38
|
-
get #selector(){
|
|
39
|
-
if(this.#calculatedSelector !== undefined) return this.#calculatedSelector;
|
|
40
|
-
const {match, attribMatches} = this.#mountInit;
|
|
41
|
-
const base = match || '*';
|
|
42
|
-
if(attribMatches === undefined) return base;
|
|
43
|
-
const matches: Array<string> = [];
|
|
44
|
-
attribMatches.forEach(x => {
|
|
45
|
-
const {names} = x;
|
|
46
|
-
names.forEach(y => {
|
|
47
|
-
matches.push(`${base}[${y}]`)
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
this.#calculatedSelector = matches.join(',');
|
|
51
|
-
return this.#calculatedSelector;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async observe(within: Node){
|
|
55
|
-
const nodeToMonitor = this.#isComplex ? (within instanceof ShadowRoot ? within : within.getRootNode()) : within;
|
|
56
|
-
if(!mutationObserverLookup.has(nodeToMonitor)){
|
|
57
|
-
mutationObserverLookup.set(nodeToMonitor, new RootMutObs(nodeToMonitor));
|
|
58
|
-
}
|
|
59
|
-
const rootMutObs = mutationObserverLookup.get(within)!;
|
|
60
|
-
const {attribMatches} = this.#mountInit;
|
|
61
|
-
(rootMutObs as any as AddMutationEventListener).addEventListener('mutation-event', (e: MutationEvent) => {
|
|
62
|
-
//TODO: disconnected
|
|
63
|
-
if(this.#isComplex){
|
|
64
|
-
this.#inspectWithin(within);
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
const {mutationRecords} = e;
|
|
68
|
-
const elsToInspect: Array<Element> = [];
|
|
69
|
-
//const elsToDisconnect: Array<Element> = [];
|
|
70
|
-
const doDisconnect = this.#mountInit.do?.onDisconnect;
|
|
71
|
-
for(const mutationRecord of mutationRecords){
|
|
72
|
-
const {addedNodes, type, removedNodes} = mutationRecord;
|
|
73
|
-
//console.log(mutationRecord);
|
|
74
|
-
const addedElements = Array.from(addedNodes).filter(x => x instanceof Element) as Array<Element>;
|
|
75
|
-
addedElements.forEach(x => elsToInspect.push(x));
|
|
76
|
-
if(type === 'attributes'){
|
|
77
|
-
const {target, attributeName, oldValue} = mutationRecord;
|
|
78
|
-
if(target instanceof Element && attributeName !== null && attribMatches !== undefined && this.#mounted.has(target)){
|
|
79
|
-
let idx = 0;
|
|
80
|
-
for(const attrMatch of attribMatches){
|
|
81
|
-
const {names} = attrMatch;
|
|
82
|
-
if(names.includes(attributeName)){
|
|
83
|
-
const newValue = target.getAttribute(attributeName);
|
|
84
|
-
// let parsedNewValue = undefined;
|
|
85
|
-
// switch(type){
|
|
86
|
-
// case 'boolean':
|
|
87
|
-
// parsedNewValue = newValue === 'true' ? true : newValue === 'false' ? false : null;
|
|
88
|
-
// break;
|
|
89
|
-
// case 'date':
|
|
90
|
-
// parsedNewValue = newValue === null ? null : new Date(newValue);
|
|
91
|
-
// break;
|
|
92
|
-
// case ''
|
|
93
|
-
|
|
94
|
-
// }
|
|
95
|
-
const attrChangeInfo: AttrChangeInfo = {
|
|
96
|
-
name: attributeName,
|
|
97
|
-
oldValue,
|
|
98
|
-
newValue,
|
|
99
|
-
idx
|
|
100
|
-
};
|
|
101
|
-
this.dispatchEvent(new AttrChangeEvent(target, attrChangeInfo));
|
|
102
|
-
}
|
|
103
|
-
idx++;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
elsToInspect.push(target as Element);
|
|
107
|
-
}
|
|
108
|
-
const deletedElements = Array.from(removedNodes).filter(x => x instanceof Element) as Array<Element>;
|
|
109
|
-
for(const deletedElement of deletedElements){
|
|
110
|
-
// if(!this.#mounted.has(deletedElement)) continue;
|
|
111
|
-
// this.#mounted.delete(deletedElement);
|
|
112
|
-
// this.#mountedList = this.#mountedList?.filter(x => x.deref() !== deletedElement);
|
|
113
|
-
this.#disconnected.add(deletedElement);
|
|
114
|
-
if(doDisconnect !== undefined){
|
|
115
|
-
doDisconnect(deletedElement, this);
|
|
116
|
-
}
|
|
117
|
-
this.dispatchEvent(new DisconnectEvent(deletedElement));
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
this.#filterAndMount(elsToInspect, true);
|
|
122
|
-
}, {signal: this.#abortController.signal});
|
|
123
|
-
await this.#inspectWithin(within);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
#confirmInstanceOf(el: Element, whereInstanceOf: Array<typeof Node>){
|
|
127
|
-
for(const test of whereInstanceOf){
|
|
128
|
-
if(el instanceof test) return true;
|
|
129
|
-
}
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
async #mount(matching: Array<Element>){
|
|
134
|
-
//first unmount non matching
|
|
135
|
-
const alreadyMounted = this.#filterAndDismount();
|
|
136
|
-
const onMount = this.#mountInit.do?.onMount;
|
|
137
|
-
const {import: imp, attribMatches} = this.#mountInit;
|
|
138
|
-
for(const match of matching){
|
|
139
|
-
if(alreadyMounted.has(match)) continue;
|
|
140
|
-
this.#mounted.add(match);
|
|
141
|
-
if(imp !== undefined){
|
|
142
|
-
switch(typeof imp){
|
|
143
|
-
case 'string':
|
|
144
|
-
this.module = await import(imp);
|
|
145
|
-
break;
|
|
146
|
-
case 'object':
|
|
147
|
-
if(Array.isArray(imp)){
|
|
148
|
-
this.module = await import(imp[0], imp[1]);
|
|
149
|
-
}
|
|
150
|
-
break;
|
|
151
|
-
case 'function':
|
|
152
|
-
this.module = await imp(match, this, 'Import');
|
|
153
|
-
break;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
if(onMount !== undefined) onMount(match, this, 'PostImport');
|
|
157
|
-
this.dispatchEvent(new MountEvent(match));
|
|
158
|
-
if(attribMatches !== undefined){
|
|
159
|
-
let idx = 0;
|
|
160
|
-
for(const attribMatch of attribMatches){
|
|
161
|
-
let newValue = null;
|
|
162
|
-
const {names} = attribMatch;
|
|
163
|
-
let nonNullName = names[0];
|
|
164
|
-
for(const name of names){
|
|
165
|
-
const attrVal = match.getAttribute(name);
|
|
166
|
-
if(attrVal !== null) nonNullName = name;
|
|
167
|
-
newValue = newValue || attrVal;
|
|
168
|
-
}
|
|
169
|
-
const attribInfo: AttrChangeInfo = {
|
|
170
|
-
oldValue: null,
|
|
171
|
-
newValue,
|
|
172
|
-
idx,
|
|
173
|
-
name: nonNullName
|
|
174
|
-
};
|
|
175
|
-
this.dispatchEvent(new AttrChangeEvent(match, attribInfo));
|
|
176
|
-
idx++;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
this.#mountedList?.push(new WeakRef(match));
|
|
180
|
-
//if(this.#unmounted.has(match)) this.#unmounted.delete(match);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
async #dismount(unmatching: Array<Element>){
|
|
185
|
-
const onDismount = this.#mountInit.do?.onDismount
|
|
186
|
-
for(const unmatch of unmatching){
|
|
187
|
-
if(onDismount !== undefined){
|
|
188
|
-
onDismount(unmatch, this);
|
|
189
|
-
}
|
|
190
|
-
this.dispatchEvent(new DismountEvent(unmatch));
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
#filterAndDismount(): Set<Element>{
|
|
195
|
-
const returnSet = new Set<Element>();
|
|
196
|
-
if(this.#mountedList !== undefined){
|
|
197
|
-
const previouslyMounted = this.#mountedList.map(x => x.deref());
|
|
198
|
-
const {whereSatisfies, whereInstanceOf} = this.#mountInit;
|
|
199
|
-
const match = this.#selector;
|
|
200
|
-
const elsToUnMount = previouslyMounted.filter(x => {
|
|
201
|
-
if(x === undefined) return false;
|
|
202
|
-
if(!x.matches(match)) return true;
|
|
203
|
-
if(whereSatisfies !== undefined){
|
|
204
|
-
if(!whereSatisfies(x, this, 'Inspecting')) return true;
|
|
205
|
-
}
|
|
206
|
-
returnSet.add(x);
|
|
207
|
-
return false;
|
|
208
|
-
}) as Array<Element>;
|
|
209
|
-
this.#dismount(elsToUnMount);
|
|
210
|
-
}
|
|
211
|
-
this.#mountedList = Array.from(returnSet).map(x => new WeakRef(x));
|
|
212
|
-
return returnSet;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
async #filterAndMount(els: Array<Element>, checkMatch: boolean){
|
|
216
|
-
const {whereSatisfies, whereInstanceOf} = this.#mountInit;
|
|
217
|
-
const match = this.#selector;
|
|
218
|
-
const elsToMount = els.filter(x => {
|
|
219
|
-
if(checkMatch){
|
|
220
|
-
if(!x.matches(match)) return false;
|
|
221
|
-
}
|
|
222
|
-
if(whereSatisfies !== undefined){
|
|
223
|
-
if(!whereSatisfies(x, this, 'Inspecting')) return false;
|
|
224
|
-
}
|
|
225
|
-
if(whereInstanceOf !== undefined){
|
|
226
|
-
if(!this.#confirmInstanceOf(x, whereInstanceOf)) return false;
|
|
227
|
-
}
|
|
228
|
-
return true;
|
|
229
|
-
});
|
|
230
|
-
this.#mount(elsToMount);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
async #inspectWithin(within: Node){
|
|
234
|
-
const els = Array.from((within as Element).querySelectorAll(this.#selector));
|
|
235
|
-
this.#filterAndMount(els, false);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
unobserve(){
|
|
239
|
-
throw 'NI';
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
export interface MountObserver extends MountContext{}
|
|
245
|
-
|
|
246
|
-
// https://github.com/webcomponents-cg/community-protocols/issues/12#issuecomment-872415080
|
|
247
|
-
/**
|
|
248
|
-
* The `mutation-event` event represents something that happened.
|
|
249
|
-
* We can document it here.
|
|
250
|
-
*/
|
|
251
|
-
export class MountEvent extends Event implements IMountEvent {
|
|
252
|
-
static eventName: mountEventName = 'mount';
|
|
253
|
-
|
|
254
|
-
constructor(public mountedElement: Element) {
|
|
255
|
-
super(MountEvent.eventName);
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
export class DismountEvent extends Event implements IDismountEvent{
|
|
261
|
-
static eventName: dismountEventName = 'dismount';
|
|
262
|
-
|
|
263
|
-
constructor(public dismountedElement: Element){
|
|
264
|
-
super(DismountEvent.eventName)
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
export class DisconnectEvent extends Event implements IDisconnectEvent{
|
|
269
|
-
static eventName: disconnectedEventName = 'disconnect';
|
|
270
|
-
|
|
271
|
-
constructor(public disconnectedElement: Element){
|
|
272
|
-
super(DisconnectEvent.eventName);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
export class AttrChangeEvent extends Event implements IAttrChangeEvent{
|
|
277
|
-
static eventName: attrChangeEventName = 'attr-change';
|
|
278
|
-
constructor(public mountedElement: Element, public attrChangeInfo: AttrChangeInfo){
|
|
279
|
-
super(AttrChangeEvent.eventName);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
package/RootMutObs.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import {mutationEventName, AddMutationEventListener} from './types';
|
|
2
|
-
|
|
3
|
-
export class RootMutObs extends EventTarget{
|
|
4
|
-
constructor(rootNode: Node ){
|
|
5
|
-
super();
|
|
6
|
-
this.#mutationObserver = new MutationObserver(mutationRecords => {
|
|
7
|
-
this.dispatchEvent(new MutationEvent(mutationRecords))
|
|
8
|
-
})
|
|
9
|
-
this.#mutationObserver.observe(rootNode, {
|
|
10
|
-
subtree: true,
|
|
11
|
-
childList: true,
|
|
12
|
-
attributes: true,
|
|
13
|
-
attributeOldValue: true,
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
#mutationObserver: MutationObserver;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// https://github.com/webcomponents-cg/community-protocols/issues/12#issuecomment-872415080
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* The `mutation-event` event represents something that happened.
|
|
25
|
-
* We can document it here.
|
|
26
|
-
*/
|
|
27
|
-
export class MutationEvent extends Event implements MutationEvent {
|
|
28
|
-
static eventName: mutationEventName = 'mutation-event';
|
|
29
|
-
|
|
30
|
-
constructor(public mutationRecords: Array<MutationRecord>) {
|
|
31
|
-
// Since these are hard-coded, dispatchers can't get them wrong
|
|
32
|
-
super(MutationEvent.eventName);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
package/demo/test1.html
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Document</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div id=div>
|
|
10
|
-
<span id=span></span>
|
|
11
|
-
</div>
|
|
12
|
-
<script type=module>
|
|
13
|
-
import {MountObserver} from '../MountObserver.js';
|
|
14
|
-
const mo = new MountObserver({
|
|
15
|
-
match: '#span',
|
|
16
|
-
do:{
|
|
17
|
-
onMount: (el, ctx) => {
|
|
18
|
-
console.log({el, ctx});
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
mo.addEventListener('mount', e => {
|
|
23
|
-
console.log(e);
|
|
24
|
-
});
|
|
25
|
-
mo.observe(div);
|
|
26
|
-
</script>
|
|
27
|
-
</body>
|
|
28
|
-
</html>
|
package/playwright.config.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
// playwright.config.ts
|
|
2
|
-
import { PlaywrightTestConfig, devices } from '@playwright/test';
|
|
3
|
-
const config: PlaywrightTestConfig = {
|
|
4
|
-
webServer: {
|
|
5
|
-
command: 'npm run serve',
|
|
6
|
-
url: 'http://localhost:3030/',
|
|
7
|
-
timeout: 120 * 1000,
|
|
8
|
-
reuseExistingServer: !process.env.CI,
|
|
9
|
-
},
|
|
10
|
-
use: {
|
|
11
|
-
baseURL: 'http://localhost:3030/',
|
|
12
|
-
},
|
|
13
|
-
projects: [
|
|
14
|
-
{
|
|
15
|
-
name: 'chromium',
|
|
16
|
-
use: { ...devices['Desktop Chrome'] },
|
|
17
|
-
},
|
|
18
|
-
//firefox lacks support for import assertions
|
|
19
|
-
// {
|
|
20
|
-
// name: 'firefox',
|
|
21
|
-
// use: { ...devices['Desktop Firefox'] },
|
|
22
|
-
// },
|
|
23
|
-
{
|
|
24
|
-
name: 'webkit',
|
|
25
|
-
use: { ...devices['Desktop Safari'] },
|
|
26
|
-
},
|
|
27
|
-
],
|
|
28
|
-
};
|
|
29
|
-
export default config;
|
package/tests/test1.html
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Document</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div id=div>
|
|
10
|
-
<span id=span></span>
|
|
11
|
-
</div>
|
|
12
|
-
<div id=target></div>
|
|
13
|
-
<script type=module>
|
|
14
|
-
import {MountObserver} from '../MountObserver.js';
|
|
15
|
-
const mo = new MountObserver({
|
|
16
|
-
match: '#span',
|
|
17
|
-
do:{
|
|
18
|
-
onMount: (el, ctx) => {
|
|
19
|
-
console.log({el, ctx});
|
|
20
|
-
target.setAttribute('mark', 'good');
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
mo.addEventListener('mount', e => {
|
|
25
|
-
console.log(e);
|
|
26
|
-
});
|
|
27
|
-
mo.observe(div);
|
|
28
|
-
</script>
|
|
29
|
-
</body>
|
|
30
|
-
</html>
|
package/tests/test1.spec.mjs
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { test, expect } from '@playwright/test';
|
|
2
|
-
test('test1', async ({ page }) => {
|
|
3
|
-
await page.goto('./tests/test1.html');
|
|
4
|
-
// wait for 1 second
|
|
5
|
-
await page.waitForTimeout(1000);
|
|
6
|
-
const editor = page.locator('#target');
|
|
7
|
-
await expect(editor).toHaveAttribute('mark', 'good');
|
|
8
|
-
});
|
package/tests/test2.html
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Document</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div id=div>
|
|
10
|
-
</div>
|
|
11
|
-
<div id=target></div>
|
|
12
|
-
<script type=module>
|
|
13
|
-
import {MountObserver} from '../MountObserver.js';
|
|
14
|
-
const mo = new MountObserver({
|
|
15
|
-
match: '#span',
|
|
16
|
-
do:{
|
|
17
|
-
onMount: (el, ctx) => {
|
|
18
|
-
console.log({el, ctx});
|
|
19
|
-
target.setAttribute('mark', 'good');
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
mo.addEventListener('mount', e => {
|
|
24
|
-
console.log(e);
|
|
25
|
-
});
|
|
26
|
-
mo.observe(div);
|
|
27
|
-
setTimeout(() => {
|
|
28
|
-
const span = document.createElement('span');
|
|
29
|
-
span.id = 'span';
|
|
30
|
-
div.appendChild(span);
|
|
31
|
-
}, 500);
|
|
32
|
-
</script>
|
|
33
|
-
</body>
|
|
34
|
-
</html>
|
package/tests/test2.spec.mjs
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { test, expect } from '@playwright/test';
|
|
2
|
-
test('test1', async ({ page }) => {
|
|
3
|
-
await page.goto('./tests/test2.html');
|
|
4
|
-
// wait for 1 second
|
|
5
|
-
await page.waitForTimeout(1000);
|
|
6
|
-
const editor = page.locator('#target');
|
|
7
|
-
await expect(editor).toHaveAttribute('mark', 'good');
|
|
8
|
-
});
|
package/tests/test3.html
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Document</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div id=div>
|
|
10
|
-
<span></span>
|
|
11
|
-
</div>
|
|
12
|
-
<div id=target></div>
|
|
13
|
-
<script type=module>
|
|
14
|
-
import {MountObserver} from '../MountObserver.js';
|
|
15
|
-
const mo = new MountObserver({
|
|
16
|
-
match: '#span',
|
|
17
|
-
do:{
|
|
18
|
-
onMount: (el, ctx) => {
|
|
19
|
-
console.log({el, ctx});
|
|
20
|
-
target.setAttribute('mark', 'good');
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
mo.addEventListener('mount', e => {
|
|
25
|
-
console.log(e);
|
|
26
|
-
});
|
|
27
|
-
mo.observe(div);
|
|
28
|
-
setTimeout(() => {
|
|
29
|
-
const span = div.querySelector('span');
|
|
30
|
-
span.id = 'span';
|
|
31
|
-
}, 500);
|
|
32
|
-
</script>
|
|
33
|
-
</body>
|
|
34
|
-
</html>
|
package/tests/test3.spec.mjs
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { test, expect } from '@playwright/test';
|
|
2
|
-
test('test1', async ({ page }) => {
|
|
3
|
-
await page.goto('./tests/test3.html');
|
|
4
|
-
// wait for 1 second
|
|
5
|
-
await page.waitForTimeout(1000);
|
|
6
|
-
const editor = page.locator('#target');
|
|
7
|
-
await expect(editor).toHaveAttribute('mark', 'good');
|
|
8
|
-
});
|
package/tests/test4.html
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Document</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div id=div>
|
|
10
|
-
<span id=span></span>
|
|
11
|
-
</div>
|
|
12
|
-
<div id=target></div>
|
|
13
|
-
<script type=module>
|
|
14
|
-
import {MountObserver} from '../MountObserver.js';
|
|
15
|
-
const mo = new MountObserver({
|
|
16
|
-
match: '#span',
|
|
17
|
-
do:{
|
|
18
|
-
onMount: (el, ctx) => {
|
|
19
|
-
console.log({el, ctx});
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
mo.addEventListener('mount', e => {
|
|
25
|
-
console.log(e);
|
|
26
|
-
target.setAttribute('mark', 'good');
|
|
27
|
-
});
|
|
28
|
-
mo.observe(div);
|
|
29
|
-
</script>
|
|
30
|
-
</body>
|
|
31
|
-
</html>
|
package/tests/test4.spec.mjs
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { test, expect } from '@playwright/test';
|
|
2
|
-
test('test1', async ({ page }) => {
|
|
3
|
-
await page.goto('./tests/test4.html');
|
|
4
|
-
// wait for 1 second
|
|
5
|
-
await page.waitForTimeout(1000);
|
|
6
|
-
const editor = page.locator('#target');
|
|
7
|
-
await expect(editor).toHaveAttribute('mark', 'good');
|
|
8
|
-
});
|
package/tests/test5.html
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Document</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div id=div>
|
|
10
|
-
<span id=span></span>
|
|
11
|
-
</div>
|
|
12
|
-
<div id=target></div>
|
|
13
|
-
<script type=module>
|
|
14
|
-
import {MountObserver} from '../MountObserver.js';
|
|
15
|
-
const mo = new MountObserver({
|
|
16
|
-
match: '#span',
|
|
17
|
-
do:{
|
|
18
|
-
onDisconnect: (el, ctx) => {
|
|
19
|
-
console.log({el, ctx});
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
mo.addEventListener('disconnect', e => {
|
|
25
|
-
console.log(e);
|
|
26
|
-
target.setAttribute('mark', 'good');
|
|
27
|
-
});
|
|
28
|
-
mo.observe(div);
|
|
29
|
-
setTimeout(() => {
|
|
30
|
-
span.remove();
|
|
31
|
-
}, 1000);
|
|
32
|
-
</script>
|
|
33
|
-
</body>
|
|
34
|
-
</html>
|
package/tests/test5.spec.mjs
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { test, expect } from '@playwright/test';
|
|
2
|
-
test('test1', async ({ page }) => {
|
|
3
|
-
await page.goto('./tests/test5.html');
|
|
4
|
-
// wait for 1 second
|
|
5
|
-
await page.waitForTimeout(1000);
|
|
6
|
-
const editor = page.locator('#target');
|
|
7
|
-
await expect(editor).toHaveAttribute('mark', 'good');
|
|
8
|
-
});
|
package/tests/test6.html
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Document</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div id=div>
|
|
10
|
-
<span id=span></span>
|
|
11
|
-
</div>
|
|
12
|
-
<div id=target></div>
|
|
13
|
-
<script type=module>
|
|
14
|
-
import {MountObserver} from '../MountObserver.js';
|
|
15
|
-
const mo = new MountObserver({
|
|
16
|
-
match: '#span',
|
|
17
|
-
attribMatches:[
|
|
18
|
-
{
|
|
19
|
-
names: ['test-1']
|
|
20
|
-
}
|
|
21
|
-
]
|
|
22
|
-
});
|
|
23
|
-
mo.addEventListener('attr-change', e => {
|
|
24
|
-
console.log(e);
|
|
25
|
-
target.setAttribute('mark', 'good');
|
|
26
|
-
});
|
|
27
|
-
mo.observe(div);
|
|
28
|
-
setTimeout(() => {
|
|
29
|
-
span.setAttribute('test-1', 'hello')
|
|
30
|
-
}, 1000);
|
|
31
|
-
</script>
|
|
32
|
-
</body>
|
|
33
|
-
</html>
|
package/tests/test6.spec.mjs
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { test, expect } from '@playwright/test';
|
|
2
|
-
test('test1', async ({ page }) => {
|
|
3
|
-
await page.goto('./tests/test6.html');
|
|
4
|
-
// wait for 1 second
|
|
5
|
-
await page.waitForTimeout(1000);
|
|
6
|
-
const editor = page.locator('#target');
|
|
7
|
-
await expect(editor).toHaveAttribute('mark', 'good');
|
|
8
|
-
});
|
package/tsconfig.json
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ESNext",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"sourceMap": false,
|
|
6
|
-
"experimentalDecorators": false,
|
|
7
|
-
"newLine": "LF",
|
|
8
|
-
"strict": true,
|
|
9
|
-
},
|
|
10
|
-
"files": [
|
|
11
|
-
"MountObserver.ts",
|
|
12
|
-
],
|
|
13
|
-
"exclude":[
|
|
14
|
-
"node_modules"
|
|
15
|
-
]
|
|
16
|
-
|
|
17
|
-
}
|