@whitesev/domutils 1.5.9 → 1.5.11
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/dist/index.amd.js +153 -139
- package/dist/index.amd.js.map +1 -1
- package/dist/index.cjs.js +153 -139
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +153 -139
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +153 -139
- package/dist/index.iife.js.map +1 -1
- package/dist/index.system.js +153 -139
- package/dist/index.system.js.map +1 -1
- package/dist/index.umd.js +153 -139
- package/dist/index.umd.js.map +1 -1
- package/dist/types/src/DOMUtilsEvent.d.ts +6 -4
- package/package.json +11 -9
- package/src/DOMUtils.ts +1 -1
- package/src/DOMUtilsEvent.ts +28 -19
package/dist/index.esm.js
CHANGED
|
@@ -98,155 +98,168 @@ const LAST_NUMBER_WEAK_MAP = new WeakMap();
|
|
|
98
98
|
const cache = createCache(LAST_NUMBER_WEAK_MAP);
|
|
99
99
|
const generateUniqueNumber = createGenerateUniqueNumber(cache, LAST_NUMBER_WEAK_MAP);
|
|
100
100
|
|
|
101
|
-
const
|
|
102
|
-
return
|
|
101
|
+
const isMessagePort = (sender) => {
|
|
102
|
+
return typeof sender.start === 'function';
|
|
103
103
|
};
|
|
104
104
|
|
|
105
|
-
const
|
|
106
|
-
return typeof message.id === 'number' && typeof message.result === 'boolean';
|
|
107
|
-
};
|
|
105
|
+
const PORT_MAP = new WeakMap();
|
|
108
106
|
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const timerIdAndTimerType = unrespondedRequests.get(idOrFunc);
|
|
125
|
-
if (timerIdAndTimerType === undefined ||
|
|
126
|
-
timerIdAndTimerType.timerId !== timerId ||
|
|
127
|
-
timerIdAndTimerType.timerType !== timerType) {
|
|
128
|
-
throw new Error('The timer is in an undefined state.');
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
else if (typeof idOrFunc === 'function') {
|
|
132
|
-
idOrFunc();
|
|
133
|
-
}
|
|
107
|
+
const extendBrokerImplementation = (partialBrokerImplementation) => ({
|
|
108
|
+
...partialBrokerImplementation,
|
|
109
|
+
connect: ({ call }) => {
|
|
110
|
+
return async () => {
|
|
111
|
+
const { port1, port2 } = new MessageChannel();
|
|
112
|
+
const portId = await call('connect', { port: port1 }, [port1]);
|
|
113
|
+
PORT_MAP.set(port2, portId);
|
|
114
|
+
return port2;
|
|
115
|
+
};
|
|
116
|
+
},
|
|
117
|
+
disconnect: ({ call }) => {
|
|
118
|
+
return async (port) => {
|
|
119
|
+
const portId = PORT_MAP.get(port);
|
|
120
|
+
if (portId === undefined) {
|
|
121
|
+
throw new Error('The given port is not connected.');
|
|
134
122
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
123
|
+
await call('disconnect', { portId });
|
|
124
|
+
};
|
|
125
|
+
},
|
|
126
|
+
isSupported: ({ call }) => {
|
|
127
|
+
return () => call('isSupported');
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const ONGOING_REQUESTS = new WeakMap();
|
|
132
|
+
const createOrGetOngoingRequests = (sender) => {
|
|
133
|
+
if (ONGOING_REQUESTS.has(sender)) {
|
|
134
|
+
// @todo TypeScript needs to be convinced that has() works as expected.
|
|
135
|
+
return ONGOING_REQUESTS.get(sender);
|
|
136
|
+
}
|
|
137
|
+
const ongoingRequests = new Map();
|
|
138
|
+
ONGOING_REQUESTS.set(sender, ongoingRequests);
|
|
139
|
+
return ongoingRequests;
|
|
140
|
+
};
|
|
141
|
+
const createBroker = (brokerImplementation) => {
|
|
142
|
+
const fullBrokerImplementation = extendBrokerImplementation(brokerImplementation);
|
|
143
|
+
return (sender) => {
|
|
144
|
+
const ongoingRequests = createOrGetOngoingRequests(sender);
|
|
145
|
+
sender.addEventListener('message', (({ data: message }) => {
|
|
146
|
+
const { id } = message;
|
|
147
|
+
if (id !== null && ongoingRequests.has(id)) {
|
|
148
|
+
const { reject, resolve } = ongoingRequests.get(id);
|
|
149
|
+
ongoingRequests.delete(id);
|
|
150
|
+
if (message.error === undefined) {
|
|
151
|
+
resolve(message.result);
|
|
147
152
|
}
|
|
148
|
-
else
|
|
149
|
-
|
|
150
|
-
// A timeout can be savely deleted because it is only called once.
|
|
151
|
-
scheduledTimeoutFunctions.delete(timerId);
|
|
153
|
+
else {
|
|
154
|
+
reject(new Error(message.error.message));
|
|
152
155
|
}
|
|
153
156
|
}
|
|
157
|
+
}));
|
|
158
|
+
if (isMessagePort(sender)) {
|
|
159
|
+
sender.start();
|
|
154
160
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
scheduledTimeoutFunctions.delete(timerId);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
else {
|
|
171
|
-
const { error: { message } } = data;
|
|
172
|
-
throw new Error(message);
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
const clearInterval = (timerId) => {
|
|
176
|
-
if (typeof scheduledIntervalFunctions.get(timerId) === 'function') {
|
|
177
|
-
const id = generateUniqueNumber(unrespondedRequests);
|
|
178
|
-
unrespondedRequests.set(id, { timerId, timerType: 'interval' });
|
|
179
|
-
scheduledIntervalFunctions.set(timerId, id);
|
|
180
|
-
worker.postMessage({
|
|
181
|
-
id,
|
|
182
|
-
method: 'clear',
|
|
183
|
-
params: { timerId, timerType: 'interval' }
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
const clearTimeout = (timerId) => {
|
|
188
|
-
if (typeof scheduledTimeoutFunctions.get(timerId) === 'function') {
|
|
189
|
-
const id = generateUniqueNumber(unrespondedRequests);
|
|
190
|
-
unrespondedRequests.set(id, { timerId, timerType: 'timeout' });
|
|
191
|
-
scheduledTimeoutFunctions.set(timerId, id);
|
|
192
|
-
worker.postMessage({
|
|
193
|
-
id,
|
|
194
|
-
method: 'clear',
|
|
195
|
-
params: { timerId, timerType: 'timeout' }
|
|
161
|
+
const call = (method, params = null, transferables = []) => {
|
|
162
|
+
return new Promise((resolve, reject) => {
|
|
163
|
+
const id = generateUniqueNumber(ongoingRequests);
|
|
164
|
+
ongoingRequests.set(id, { reject, resolve });
|
|
165
|
+
if (params === null) {
|
|
166
|
+
sender.postMessage({ id, method }, transferables);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
sender.postMessage({ id, method, params }, transferables);
|
|
170
|
+
}
|
|
196
171
|
});
|
|
172
|
+
};
|
|
173
|
+
const notify = (method, params, transferables = []) => {
|
|
174
|
+
sender.postMessage({ id: null, method, params }, transferables);
|
|
175
|
+
};
|
|
176
|
+
let functions = {};
|
|
177
|
+
for (const [key, handler] of Object.entries(fullBrokerImplementation)) {
|
|
178
|
+
functions = { ...functions, [key]: handler({ call, notify }) };
|
|
197
179
|
}
|
|
180
|
+
return { ...functions };
|
|
198
181
|
};
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
timerId,
|
|
212
|
-
timerType: 'interval'
|
|
213
|
-
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// Prefilling the Maps with a function indexed by zero is necessary to be compliant with the specification.
|
|
185
|
+
const scheduledIntervalsState = new Map([[0, null]]); // tslint:disable-line no-empty
|
|
186
|
+
const scheduledTimeoutsState = new Map([[0, null]]); // tslint:disable-line no-empty
|
|
187
|
+
const wrap = createBroker({
|
|
188
|
+
clearInterval: ({ call }) => {
|
|
189
|
+
return (timerId) => {
|
|
190
|
+
if (typeof scheduledIntervalsState.get(timerId) === 'symbol') {
|
|
191
|
+
scheduledIntervalsState.set(timerId, null);
|
|
192
|
+
call('clear', { timerId, timerType: 'interval' }).then(() => {
|
|
193
|
+
scheduledIntervalsState.delete(timerId);
|
|
214
194
|
});
|
|
215
195
|
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
196
|
+
};
|
|
197
|
+
},
|
|
198
|
+
clearTimeout: ({ call }) => {
|
|
199
|
+
return (timerId) => {
|
|
200
|
+
if (typeof scheduledTimeoutsState.get(timerId) === 'symbol') {
|
|
201
|
+
scheduledTimeoutsState.set(timerId, null);
|
|
202
|
+
call('clear', { timerId, timerType: 'timeout' }).then(() => {
|
|
203
|
+
scheduledTimeoutsState.delete(timerId);
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
},
|
|
208
|
+
setInterval: ({ call }) => {
|
|
209
|
+
return (func, delay = 0, ...args) => {
|
|
210
|
+
const symbol = Symbol();
|
|
211
|
+
const timerId = generateUniqueNumber(scheduledIntervalsState);
|
|
212
|
+
scheduledIntervalsState.set(timerId, symbol);
|
|
213
|
+
const schedule = () => call('set', {
|
|
221
214
|
delay,
|
|
222
215
|
now: performance.timeOrigin + performance.now(),
|
|
223
216
|
timerId,
|
|
224
217
|
timerType: 'interval'
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
218
|
+
}).then(() => {
|
|
219
|
+
const state = scheduledIntervalsState.get(timerId);
|
|
220
|
+
if (state === undefined) {
|
|
221
|
+
throw new Error('The timer is in an undefined state.');
|
|
222
|
+
}
|
|
223
|
+
if (state === symbol) {
|
|
224
|
+
func(...args);
|
|
225
|
+
// Doublecheck if the interval should still be rescheduled because it could have been cleared inside of func().
|
|
226
|
+
if (scheduledIntervalsState.get(timerId) === symbol) {
|
|
227
|
+
schedule();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
schedule();
|
|
232
|
+
return timerId;
|
|
233
|
+
};
|
|
234
|
+
},
|
|
235
|
+
setTimeout: ({ call }) => {
|
|
236
|
+
return (func, delay = 0, ...args) => {
|
|
237
|
+
const symbol = Symbol();
|
|
238
|
+
const timerId = generateUniqueNumber(scheduledTimeoutsState);
|
|
239
|
+
scheduledTimeoutsState.set(timerId, symbol);
|
|
240
|
+
call('set', {
|
|
236
241
|
delay,
|
|
237
242
|
now: performance.timeOrigin + performance.now(),
|
|
238
243
|
timerId,
|
|
239
244
|
timerType: 'timeout'
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
245
|
+
}).then(() => {
|
|
246
|
+
const state = scheduledTimeoutsState.get(timerId);
|
|
247
|
+
if (state === undefined) {
|
|
248
|
+
throw new Error('The timer is in an undefined state.');
|
|
249
|
+
}
|
|
250
|
+
if (state === symbol) {
|
|
251
|
+
// A timeout can be savely deleted because it is only called once.
|
|
252
|
+
scheduledTimeoutsState.delete(timerId);
|
|
253
|
+
func(...args);
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
return timerId;
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
const load = (url) => {
|
|
261
|
+
const worker = new Worker(url);
|
|
262
|
+
return wrap(worker);
|
|
250
263
|
};
|
|
251
264
|
|
|
252
265
|
const createLoadOrReturnBroker = (loadBroker, worker) => {
|
|
@@ -265,7 +278,7 @@ const createLoadOrReturnBroker = (loadBroker, worker) => {
|
|
|
265
278
|
};
|
|
266
279
|
|
|
267
280
|
// This is the minified and stringified code of the worker-timers-worker package.
|
|
268
|
-
const worker = `(()=>{"use strict";
|
|
281
|
+
const worker = `(()=>{var e={455:function(e,t){!function(e){"use strict";var t=function(e){return function(t){var r=e(t);return t.add(r),r}},r=function(e){return function(t,r){return e.set(t,r),r}},n=void 0===Number.MAX_SAFE_INTEGER?9007199254740991:Number.MAX_SAFE_INTEGER,o=536870912,s=2*o,a=function(e,t){return function(r){var a=t.get(r),i=void 0===a?r.size:a<s?a+1:0;if(!r.has(i))return e(r,i);if(r.size<o){for(;r.has(i);)i=Math.floor(Math.random()*s);return e(r,i)}if(r.size>n)throw new Error("Congratulations, you created a collection of unique numbers which uses all available integers!");for(;r.has(i);)i=Math.floor(Math.random()*n);return e(r,i)}},i=new WeakMap,u=r(i),c=a(u,i),d=t(c);e.addUniqueNumber=d,e.generateUniqueNumber=c}(t)}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var s=t[n]={exports:{}};return e[n].call(s.exports,s,s.exports,r),s.exports}(()=>{"use strict";const e=-32603,t=-32602,n=-32601,o=(e,t)=>Object.assign(new Error(e),{status:t}),s=t=>o('The handler of the method called "'.concat(t,'" returned an unexpected result.'),e),a=(t,r)=>async({data:{id:a,method:i,params:u}})=>{const c=r[i];try{if(void 0===c)throw(e=>o('The requested method called "'.concat(e,'" is not supported.'),n))(i);const r=void 0===u?c():c(u);if(void 0===r)throw(t=>o('The handler of the method called "'.concat(t,'" returned no required result.'),e))(i);const d=r instanceof Promise?await r:r;if(null===a){if(void 0!==d.result)throw s(i)}else{if(void 0===d.result)throw s(i);const{result:e,transferables:r=[]}=d;t.postMessage({id:a,result:e},r)}}catch(e){const{message:r,status:n=-32603}=e;t.postMessage({error:{code:n,message:r},id:a})}};var i=r(455);const u=new Map,c=(e,r,n)=>({...r,connect:({port:t})=>{t.start();const n=e(t,r),o=(0,i.generateUniqueNumber)(u);return u.set(o,(()=>{n(),t.close(),u.delete(o)})),{result:o}},disconnect:({portId:e})=>{const r=u.get(e);if(void 0===r)throw(e=>o('The specified parameter called "portId" with the given value "'.concat(e,'" does not identify a port connected to this worker.'),t))(e);return r(),{result:null}},isSupported:async()=>{if(await new Promise((e=>{const t=new ArrayBuffer(0),{port1:r,port2:n}=new MessageChannel;r.onmessage=({data:t})=>e(null!==t),n.postMessage(t,[t])}))){const e=n();return{result:e instanceof Promise?await e:e}}return{result:!1}}}),d=(e,t,r=()=>!0)=>{const n=c(d,t,r),o=a(e,n);return e.addEventListener("message",o),()=>e.removeEventListener("message",o)},l=e=>t=>{const r=e.get(t);if(void 0===r)return Promise.resolve(!1);const[n,o]=r;return clearTimeout(n),e.delete(t),o(!1),Promise.resolve(!0)},f=(e,t,r)=>(n,o,s)=>{const{expected:a,remainingDelay:i}=e(n,o);return new Promise((e=>{t.set(s,[setTimeout(r,i,a,t,e,s),e])}))},m=(e,t)=>{const r=performance.now(),n=e+t-r-performance.timeOrigin;return{expected:r+n,remainingDelay:n}},p=(e,t,r,n)=>{const o=e-performance.now();o>0?t.set(n,[setTimeout(p,o,e,t,r,n),r]):(t.delete(n),r(!0))},h=new Map,v=l(h),w=new Map,g=l(w),M=f(m,h,p),y=f(m,w,p);d(self,{clear:async({timerId:e,timerType:t})=>({result:await("interval"===t?v(e):g(e))}),set:async({delay:e,now:t,timerId:r,timerType:n})=>({result:await("interval"===n?M:y)(e,t,r)})})})()})();`; // tslint:disable-line:max-line-length
|
|
269
282
|
|
|
270
283
|
const loadOrReturnBroker = createLoadOrReturnBroker(load, worker);
|
|
271
284
|
const clearInterval = (timerId) => loadOrReturnBroker().clearInterval(timerId);
|
|
@@ -1292,16 +1305,17 @@ class DOMUtilsEvent {
|
|
|
1292
1305
|
},
|
|
1293
1306
|
};
|
|
1294
1307
|
}
|
|
1295
|
-
selector(selector) {
|
|
1296
|
-
return this.selectorAll(selector)[0];
|
|
1308
|
+
selector(selector, parent) {
|
|
1309
|
+
return this.selectorAll(selector, parent)[0];
|
|
1297
1310
|
}
|
|
1298
|
-
selectorAll(selector) {
|
|
1311
|
+
selectorAll(selector, parent) {
|
|
1299
1312
|
const context = this;
|
|
1313
|
+
parent = parent || context.windowApi.document;
|
|
1300
1314
|
selector = selector.trim();
|
|
1301
1315
|
if (selector.match(/[^\s]{1}:empty$/gi)) {
|
|
1302
1316
|
// empty 语法
|
|
1303
1317
|
selector = selector.replace(/:empty$/gi, "");
|
|
1304
|
-
return Array.from(
|
|
1318
|
+
return Array.from(parent.querySelectorAll(selector)).filter(($ele) => {
|
|
1305
1319
|
return $ele?.innerHTML?.trim() === "";
|
|
1306
1320
|
});
|
|
1307
1321
|
}
|
|
@@ -1311,7 +1325,7 @@ class DOMUtilsEvent {
|
|
|
1311
1325
|
let textMatch = selector.match(/:contains\(("|')(.*)("|')\)$/i);
|
|
1312
1326
|
let text = textMatch[2];
|
|
1313
1327
|
selector = selector.replace(/:contains\(("|')(.*)("|')\)$/gi, "");
|
|
1314
|
-
return Array.from(
|
|
1328
|
+
return Array.from(parent.querySelectorAll(selector)).filter(($ele) => {
|
|
1315
1329
|
// @ts-ignore
|
|
1316
1330
|
return ($ele?.textContent || $ele?.innerText)?.includes(text);
|
|
1317
1331
|
});
|
|
@@ -1329,14 +1343,14 @@ class DOMUtilsEvent {
|
|
|
1329
1343
|
}
|
|
1330
1344
|
let regexp = new RegExp(pattern, flags);
|
|
1331
1345
|
selector = selector.replace(/:regexp\(("|')(.*)("|')\)$/gi, "");
|
|
1332
|
-
return Array.from(
|
|
1346
|
+
return Array.from(parent.querySelectorAll(selector)).filter(($ele) => {
|
|
1333
1347
|
// @ts-ignore
|
|
1334
1348
|
return Boolean(($ele?.textContent || $ele?.innerText)?.match(regexp));
|
|
1335
1349
|
});
|
|
1336
1350
|
}
|
|
1337
1351
|
else {
|
|
1338
1352
|
// 普通语法
|
|
1339
|
-
return Array.from(
|
|
1353
|
+
return Array.from(parent.querySelectorAll(selector));
|
|
1340
1354
|
}
|
|
1341
1355
|
}
|
|
1342
1356
|
/**
|
|
@@ -1471,7 +1485,7 @@ class DOMUtils extends DOMUtilsEvent {
|
|
|
1471
1485
|
super(option);
|
|
1472
1486
|
}
|
|
1473
1487
|
/** 版本号 */
|
|
1474
|
-
version = "2025.6.
|
|
1488
|
+
version = "2025.6.26";
|
|
1475
1489
|
attr(element, attrName, attrValue) {
|
|
1476
1490
|
let DOMUtilsContext = this;
|
|
1477
1491
|
if (typeof element === "string") {
|
|
@@ -2436,10 +2450,10 @@ class DOMUtils extends DOMUtilsEvent {
|
|
|
2436
2450
|
if (typeof duration !== "number" || duration <= 0) {
|
|
2437
2451
|
throw new TypeError("duration must be a positive number");
|
|
2438
2452
|
}
|
|
2439
|
-
if (typeof callback !== "function" && callback !==
|
|
2453
|
+
if (typeof callback !== "function" && callback !== void 0) {
|
|
2440
2454
|
throw new TypeError("callback must be a function or null");
|
|
2441
2455
|
}
|
|
2442
|
-
if (typeof styles !== "object" || styles ===
|
|
2456
|
+
if (typeof styles !== "object" || styles === void 0) {
|
|
2443
2457
|
throw new TypeError("styles must be an object");
|
|
2444
2458
|
}
|
|
2445
2459
|
if (Object.keys(styles).length === 0) {
|