@bquery/bquery 1.2.0 → 1.4.0
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/README.md +127 -27
- package/dist/batch-x7b2eZST.js +13 -0
- package/dist/batch-x7b2eZST.js.map +1 -0
- package/dist/component/component.d.ts +69 -0
- package/dist/component/component.d.ts.map +1 -0
- package/dist/component/html.d.ts +35 -0
- package/dist/component/html.d.ts.map +1 -0
- package/dist/component/index.d.ts +3 -126
- package/dist/component/index.d.ts.map +1 -1
- package/dist/component/props.d.ts +18 -0
- package/dist/component/props.d.ts.map +1 -0
- package/dist/component/types.d.ts +77 -0
- package/dist/component/types.d.ts.map +1 -0
- package/dist/component.es.mjs +90 -59
- package/dist/component.es.mjs.map +1 -1
- package/dist/core/collection.d.ts +55 -3
- package/dist/core/collection.d.ts.map +1 -1
- package/dist/core/dom.d.ts +6 -0
- package/dist/core/dom.d.ts.map +1 -0
- package/dist/core/element.d.ts +31 -4
- package/dist/core/element.d.ts.map +1 -1
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/utils/array.d.ts +74 -0
- package/dist/core/utils/array.d.ts.map +1 -0
- package/dist/core/utils/function.d.ts +87 -0
- package/dist/core/utils/function.d.ts.map +1 -0
- package/dist/core/utils/index.d.ts +70 -0
- package/dist/core/utils/index.d.ts.map +1 -0
- package/dist/core/utils/misc.d.ts +63 -0
- package/dist/core/utils/misc.d.ts.map +1 -0
- package/dist/core/utils/number.d.ts +65 -0
- package/dist/core/utils/number.d.ts.map +1 -0
- package/dist/core/utils/object.d.ts +133 -0
- package/dist/core/utils/object.d.ts.map +1 -0
- package/dist/core/utils/string.d.ts +80 -0
- package/dist/core/utils/string.d.ts.map +1 -0
- package/dist/core/utils/type-guards.d.ts +79 -0
- package/dist/core/utils/type-guards.d.ts.map +1 -0
- package/dist/core-BhpuvPhy.js +170 -0
- package/dist/core-BhpuvPhy.js.map +1 -0
- package/dist/core.es.mjs +495 -489
- package/dist/core.es.mjs.map +1 -1
- package/dist/full.d.ts +2 -2
- package/dist/full.d.ts.map +1 -1
- package/dist/full.es.mjs +87 -64
- package/dist/full.es.mjs.map +1 -1
- package/dist/full.iife.js +2 -2
- package/dist/full.iife.js.map +1 -1
- package/dist/full.umd.js +2 -2
- package/dist/full.umd.js.map +1 -1
- package/dist/index.es.mjs +138 -68
- package/dist/index.es.mjs.map +1 -1
- package/dist/motion/animate.d.ts +25 -0
- package/dist/motion/animate.d.ts.map +1 -0
- package/dist/motion/easing.d.ts +30 -0
- package/dist/motion/easing.d.ts.map +1 -0
- package/dist/motion/flip.d.ts +55 -0
- package/dist/motion/flip.d.ts.map +1 -0
- package/dist/motion/index.d.ts +11 -138
- package/dist/motion/index.d.ts.map +1 -1
- package/dist/motion/keyframes.d.ts +21 -0
- package/dist/motion/keyframes.d.ts.map +1 -0
- package/dist/motion/reduced-motion.d.ts +12 -0
- package/dist/motion/reduced-motion.d.ts.map +1 -0
- package/dist/motion/scroll.d.ts +15 -0
- package/dist/motion/scroll.d.ts.map +1 -0
- package/dist/motion/spring.d.ts +42 -0
- package/dist/motion/spring.d.ts.map +1 -0
- package/dist/motion/stagger.d.ts +22 -0
- package/dist/motion/stagger.d.ts.map +1 -0
- package/dist/motion/timeline.d.ts +21 -0
- package/dist/motion/timeline.d.ts.map +1 -0
- package/dist/motion/transition.d.ts +22 -0
- package/dist/motion/transition.d.ts.map +1 -0
- package/dist/motion/types.d.ts +182 -0
- package/dist/motion/types.d.ts.map +1 -0
- package/dist/motion.es.mjs +320 -61
- package/dist/motion.es.mjs.map +1 -1
- package/dist/persisted-DHoi3uEs.js +278 -0
- package/dist/persisted-DHoi3uEs.js.map +1 -0
- package/dist/platform/storage.d.ts.map +1 -1
- package/dist/platform.es.mjs +12 -7
- package/dist/platform.es.mjs.map +1 -1
- package/dist/reactive/batch.d.ts +13 -0
- package/dist/reactive/batch.d.ts.map +1 -0
- package/dist/reactive/computed.d.ts +50 -0
- package/dist/reactive/computed.d.ts.map +1 -0
- package/dist/reactive/core.d.ts +72 -0
- package/dist/reactive/core.d.ts.map +1 -0
- package/dist/reactive/effect.d.ts +15 -0
- package/dist/reactive/effect.d.ts.map +1 -0
- package/dist/reactive/index.d.ts +2 -2
- package/dist/reactive/index.d.ts.map +1 -1
- package/dist/reactive/internals.d.ts +42 -0
- package/dist/reactive/internals.d.ts.map +1 -0
- package/dist/reactive/linked.d.ts +36 -0
- package/dist/reactive/linked.d.ts.map +1 -0
- package/dist/reactive/persisted.d.ts +14 -0
- package/dist/reactive/persisted.d.ts.map +1 -0
- package/dist/reactive/readonly.d.ts +26 -0
- package/dist/reactive/readonly.d.ts.map +1 -0
- package/dist/reactive/signal.d.ts +13 -312
- package/dist/reactive/signal.d.ts.map +1 -1
- package/dist/reactive/type-guards.d.ts +20 -0
- package/dist/reactive/type-guards.d.ts.map +1 -0
- package/dist/reactive/untrack.d.ts +29 -0
- package/dist/reactive/untrack.d.ts.map +1 -0
- package/dist/reactive/watch.d.ts +42 -0
- package/dist/reactive/watch.d.ts.map +1 -0
- package/dist/reactive.es.mjs +30 -163
- package/dist/reactive.es.mjs.map +1 -1
- package/dist/router/index.d.ts +6 -252
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/links.d.ts +44 -0
- package/dist/router/links.d.ts.map +1 -0
- package/dist/router/match.d.ts +20 -0
- package/dist/router/match.d.ts.map +1 -0
- package/dist/router/navigation.d.ts +45 -0
- package/dist/router/navigation.d.ts.map +1 -0
- package/dist/router/query.d.ts +16 -0
- package/dist/router/query.d.ts.map +1 -0
- package/dist/router/router.d.ts +34 -0
- package/dist/router/router.d.ts.map +1 -0
- package/dist/router/state.d.ts +27 -0
- package/dist/router/state.d.ts.map +1 -0
- package/dist/router/types.d.ts +88 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/router/utils.d.ts +65 -0
- package/dist/router/utils.d.ts.map +1 -0
- package/dist/router.es.mjs +168 -132
- package/dist/router.es.mjs.map +1 -1
- package/dist/sanitize-Cxvxa-DX.js +283 -0
- package/dist/sanitize-Cxvxa-DX.js.map +1 -0
- package/dist/security/constants.d.ts +42 -0
- package/dist/security/constants.d.ts.map +1 -0
- package/dist/security/csp.d.ts +24 -0
- package/dist/security/csp.d.ts.map +1 -0
- package/dist/security/index.d.ts +4 -2
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/sanitize-core.d.ts +13 -0
- package/dist/security/sanitize-core.d.ts.map +1 -0
- package/dist/security/sanitize.d.ts +5 -57
- package/dist/security/sanitize.d.ts.map +1 -1
- package/dist/security/trusted-types.d.ts +25 -0
- package/dist/security/trusted-types.d.ts.map +1 -0
- package/dist/security/types.d.ts +36 -0
- package/dist/security/types.d.ts.map +1 -0
- package/dist/security.es.mjs +50 -277
- package/dist/security.es.mjs.map +1 -1
- package/dist/store/create-store.d.ts +15 -0
- package/dist/store/create-store.d.ts.map +1 -0
- package/dist/store/define-store.d.ts +28 -0
- package/dist/store/define-store.d.ts.map +1 -0
- package/dist/store/devtools.d.ts +22 -0
- package/dist/store/devtools.d.ts.map +1 -0
- package/dist/store/index.d.ts +10 -286
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/mapping.d.ts +28 -0
- package/dist/store/mapping.d.ts.map +1 -0
- package/dist/store/persisted.d.ts +13 -0
- package/dist/store/persisted.d.ts.map +1 -0
- package/dist/store/plugins.d.ts +13 -0
- package/dist/store/plugins.d.ts.map +1 -0
- package/dist/store/registry.d.ts +28 -0
- package/dist/store/registry.d.ts.map +1 -0
- package/dist/store/types.d.ts +71 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/utils.d.ts +28 -0
- package/dist/store/utils.d.ts.map +1 -0
- package/dist/store/watch.d.ts +23 -0
- package/dist/store/watch.d.ts.map +1 -0
- package/dist/store.es.mjs +22 -224
- package/dist/store.es.mjs.map +1 -1
- package/dist/type-guards-BdKlYYlS.js +32 -0
- package/dist/type-guards-BdKlYYlS.js.map +1 -0
- package/dist/untrack-DNnnqdlR.js +6 -0
- package/dist/untrack-DNnnqdlR.js.map +1 -0
- package/dist/view/directives/bind.d.ts +7 -0
- package/dist/view/directives/bind.d.ts.map +1 -0
- package/dist/view/directives/class.d.ts +8 -0
- package/dist/view/directives/class.d.ts.map +1 -0
- package/dist/view/directives/for.d.ts +23 -0
- package/dist/view/directives/for.d.ts.map +1 -0
- package/dist/view/directives/html.d.ts +7 -0
- package/dist/view/directives/html.d.ts.map +1 -0
- package/dist/view/directives/if.d.ts +7 -0
- package/dist/view/directives/if.d.ts.map +1 -0
- package/dist/view/directives/index.d.ts +12 -0
- package/dist/view/directives/index.d.ts.map +1 -0
- package/dist/view/directives/model.d.ts +7 -0
- package/dist/view/directives/model.d.ts.map +1 -0
- package/dist/view/directives/on.d.ts +7 -0
- package/dist/view/directives/on.d.ts.map +1 -0
- package/dist/view/directives/ref.d.ts +7 -0
- package/dist/view/directives/ref.d.ts.map +1 -0
- package/dist/view/directives/show.d.ts +7 -0
- package/dist/view/directives/show.d.ts.map +1 -0
- package/dist/view/directives/style.d.ts +7 -0
- package/dist/view/directives/style.d.ts.map +1 -0
- package/dist/view/directives/text.d.ts +7 -0
- package/dist/view/directives/text.d.ts.map +1 -0
- package/dist/view/evaluate.d.ts +43 -0
- package/dist/view/evaluate.d.ts.map +1 -0
- package/dist/view/index.d.ts +3 -93
- package/dist/view/index.d.ts.map +1 -1
- package/dist/view/mount.d.ts +69 -0
- package/dist/view/mount.d.ts.map +1 -0
- package/dist/view/process.d.ts +26 -0
- package/dist/view/process.d.ts.map +1 -0
- package/dist/view/types.d.ts +36 -0
- package/dist/view/types.d.ts.map +1 -0
- package/dist/view.es.mjs +358 -251
- package/dist/view.es.mjs.map +1 -1
- package/dist/watch-DXXv3iAI.js +58 -0
- package/dist/watch-DXXv3iAI.js.map +1 -0
- package/package.json +14 -14
- package/src/component/component.ts +289 -0
- package/src/component/html.ts +53 -0
- package/src/component/index.ts +40 -414
- package/src/component/props.ts +116 -0
- package/src/component/types.ts +85 -0
- package/src/core/collection.ts +181 -7
- package/src/core/dom.ts +38 -0
- package/src/core/element.ts +59 -25
- package/src/core/index.ts +48 -4
- package/src/core/utils/array.ts +102 -0
- package/src/core/utils/function.ts +151 -0
- package/src/core/utils/index.ts +83 -0
- package/src/core/utils/misc.ts +82 -0
- package/src/core/utils/number.ts +78 -0
- package/src/core/utils/object.ts +206 -0
- package/src/core/utils/string.ts +112 -0
- package/src/core/utils/type-guards.ts +112 -0
- package/src/full.ts +187 -150
- package/src/index.ts +36 -36
- package/src/motion/animate.ts +113 -0
- package/src/motion/easing.ts +40 -0
- package/src/motion/flip.ts +176 -0
- package/src/motion/index.ts +41 -358
- package/src/motion/keyframes.ts +46 -0
- package/src/motion/reduced-motion.ts +17 -0
- package/src/motion/scroll.ts +57 -0
- package/src/motion/spring.ts +150 -0
- package/src/motion/stagger.ts +43 -0
- package/src/motion/timeline.ts +246 -0
- package/src/motion/transition.ts +51 -0
- package/src/motion/types.ts +198 -0
- package/src/platform/storage.ts +215 -208
- package/src/reactive/batch.ts +22 -0
- package/src/reactive/computed.ts +92 -0
- package/src/reactive/core.ts +114 -0
- package/src/reactive/effect.ts +54 -0
- package/src/reactive/index.ts +23 -22
- package/src/reactive/internals.ts +122 -0
- package/src/reactive/linked.ts +56 -0
- package/src/reactive/persisted.ts +74 -0
- package/src/reactive/readonly.ts +35 -0
- package/src/reactive/signal.ts +20 -520
- package/src/reactive/type-guards.ts +22 -0
- package/src/reactive/untrack.ts +31 -0
- package/src/reactive/watch.ts +73 -0
- package/src/router/index.ts +41 -718
- package/src/router/links.ts +130 -0
- package/src/router/match.ts +106 -0
- package/src/router/navigation.ts +71 -0
- package/src/router/query.ts +35 -0
- package/src/router/router.ts +211 -0
- package/src/router/state.ts +46 -0
- package/src/router/types.ts +93 -0
- package/src/router/utils.ts +116 -0
- package/src/security/constants.ts +209 -0
- package/src/security/csp.ts +77 -0
- package/src/security/index.ts +4 -12
- package/src/security/sanitize-core.ts +364 -0
- package/src/security/sanitize.ts +66 -625
- package/src/security/trusted-types.ts +69 -0
- package/src/security/types.ts +40 -0
- package/src/store/create-store.ts +329 -0
- package/src/store/define-store.ts +48 -0
- package/src/store/devtools.ts +45 -0
- package/src/store/index.ts +22 -848
- package/src/store/mapping.ts +73 -0
- package/src/store/persisted.ts +61 -0
- package/src/store/plugins.ts +32 -0
- package/src/store/registry.ts +51 -0
- package/src/store/types.ts +94 -0
- package/src/store/utils.ts +141 -0
- package/src/store/watch.ts +52 -0
- package/src/view/directives/bind.ts +23 -0
- package/src/view/directives/class.ts +70 -0
- package/src/view/directives/for.ts +275 -0
- package/src/view/directives/html.ts +19 -0
- package/src/view/directives/if.ts +30 -0
- package/src/view/directives/index.ts +11 -0
- package/src/view/directives/model.ts +56 -0
- package/src/view/directives/on.ts +41 -0
- package/src/view/directives/ref.ts +41 -0
- package/src/view/directives/show.ts +26 -0
- package/src/view/directives/style.ts +47 -0
- package/src/view/directives/text.ts +15 -0
- package/src/view/evaluate.ts +290 -0
- package/src/view/index.ts +112 -1041
- package/src/view/mount.ts +200 -0
- package/src/view/process.ts +92 -0
- package/src/view/types.ts +44 -0
- package/dist/core/utils.d.ts +0 -313
- package/dist/core/utils.d.ts.map +0 -1
- package/src/core/utils.ts +0 -444
package/src/core/collection.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
createElementFromHtml,
|
|
3
|
+
insertContent,
|
|
4
|
+
sanitizeContent,
|
|
5
|
+
type InsertableContent,
|
|
6
|
+
} from './dom';
|
|
2
7
|
import { BQueryElement } from './element';
|
|
3
|
-
import { applyAll } from './shared';
|
|
8
|
+
import { applyAll, toElementList } from './shared';
|
|
4
9
|
|
|
5
10
|
/** Handler signature for delegated events */
|
|
6
11
|
type DelegatedHandler = (event: Event, target: Element) => void;
|
|
@@ -181,6 +186,20 @@ export class BQueryCollection {
|
|
|
181
186
|
return this;
|
|
182
187
|
}
|
|
183
188
|
|
|
189
|
+
/** Toggle an attribute on all elements. */
|
|
190
|
+
toggleAttr(name: string, force?: boolean): this {
|
|
191
|
+
applyAll(this.elements, (el) => {
|
|
192
|
+
const hasAttr = el.hasAttribute(name);
|
|
193
|
+
const shouldAdd = force ?? !hasAttr;
|
|
194
|
+
if (shouldAdd) {
|
|
195
|
+
el.setAttribute(name, '');
|
|
196
|
+
} else {
|
|
197
|
+
el.removeAttribute(name);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
return this;
|
|
201
|
+
}
|
|
202
|
+
|
|
184
203
|
/**
|
|
185
204
|
* Sets text content on all elements or gets from first.
|
|
186
205
|
*
|
|
@@ -207,7 +226,7 @@ export class BQueryCollection {
|
|
|
207
226
|
if (value === undefined) {
|
|
208
227
|
return this.first()?.innerHTML ?? '';
|
|
209
228
|
}
|
|
210
|
-
const sanitized =
|
|
229
|
+
const sanitized = sanitizeContent(value);
|
|
211
230
|
applyAll(this.elements, (el) => {
|
|
212
231
|
el.innerHTML = sanitized;
|
|
213
232
|
});
|
|
@@ -228,21 +247,58 @@ export class BQueryCollection {
|
|
|
228
247
|
return this;
|
|
229
248
|
}
|
|
230
249
|
|
|
250
|
+
/** Append content to all elements. */
|
|
251
|
+
append(content: InsertableContent): this {
|
|
252
|
+
this.insertAll(content, 'beforeend');
|
|
253
|
+
return this;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/** Prepend content to all elements. */
|
|
257
|
+
prepend(content: InsertableContent): this {
|
|
258
|
+
this.insertAll(content, 'afterbegin');
|
|
259
|
+
return this;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/** Insert content before all elements. */
|
|
263
|
+
before(content: InsertableContent): this {
|
|
264
|
+
this.insertAll(content, 'beforebegin');
|
|
265
|
+
return this;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/** Insert content after all elements. */
|
|
269
|
+
after(content: InsertableContent): this {
|
|
270
|
+
this.insertAll(content, 'afterend');
|
|
271
|
+
return this;
|
|
272
|
+
}
|
|
273
|
+
|
|
231
274
|
/**
|
|
232
|
-
*
|
|
275
|
+
* Gets or sets CSS styles on all elements.
|
|
276
|
+
* When getting, returns the computed style value from the first element.
|
|
233
277
|
*
|
|
234
278
|
* @param property - Property name or object of properties
|
|
235
279
|
* @param value - Value when setting single property
|
|
236
|
-
* @returns The instance
|
|
280
|
+
* @returns The computed style value when getting, instance when setting
|
|
237
281
|
*/
|
|
238
|
-
css(property: string
|
|
282
|
+
css(property: string): string;
|
|
283
|
+
css(property: string, value: string): this;
|
|
284
|
+
css(property: Record<string, string>): this;
|
|
285
|
+
css(property: string | Record<string, string>, value?: string): string | this {
|
|
239
286
|
if (typeof property === 'string') {
|
|
240
287
|
if (value !== undefined) {
|
|
241
288
|
applyAll(this.elements, (el) => {
|
|
242
289
|
(el as HTMLElement).style.setProperty(property, value);
|
|
243
290
|
});
|
|
291
|
+
return this;
|
|
292
|
+
}
|
|
293
|
+
const first = this.first();
|
|
294
|
+
if (!first) {
|
|
295
|
+
return '';
|
|
244
296
|
}
|
|
245
|
-
|
|
297
|
+
const view = first.ownerDocument?.defaultView;
|
|
298
|
+
if (!view || typeof view.getComputedStyle !== 'function') {
|
|
299
|
+
return '';
|
|
300
|
+
}
|
|
301
|
+
return view.getComputedStyle(first).getPropertyValue(property);
|
|
246
302
|
}
|
|
247
303
|
|
|
248
304
|
applyAll(this.elements, (el) => {
|
|
@@ -253,6 +309,78 @@ export class BQueryCollection {
|
|
|
253
309
|
return this;
|
|
254
310
|
}
|
|
255
311
|
|
|
312
|
+
/** Wrap each element with a wrapper element or tag. */
|
|
313
|
+
wrap(wrapper: string | Element): this {
|
|
314
|
+
this.elements.forEach((el, index) => {
|
|
315
|
+
const wrapperEl =
|
|
316
|
+
typeof wrapper === 'string'
|
|
317
|
+
? document.createElement(wrapper)
|
|
318
|
+
: index === 0
|
|
319
|
+
? wrapper
|
|
320
|
+
: (wrapper.cloneNode(true) as Element);
|
|
321
|
+
el.parentNode?.insertBefore(wrapperEl, el);
|
|
322
|
+
wrapperEl.appendChild(el);
|
|
323
|
+
});
|
|
324
|
+
return this;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Remove the parent element of each element, keeping the elements in place.
|
|
329
|
+
*
|
|
330
|
+
* **Important**: This method unwraps ALL children of each parent element,
|
|
331
|
+
* not just the elements in the collection. If you call `unwrap()` on a
|
|
332
|
+
* collection containing only some children of a parent, all siblings will
|
|
333
|
+
* also be unwrapped. This behavior is consistent with jQuery's `.unwrap()`.
|
|
334
|
+
*
|
|
335
|
+
* @returns The collection for chaining
|
|
336
|
+
*
|
|
337
|
+
* @example
|
|
338
|
+
* ```ts
|
|
339
|
+
* // HTML: <div><section><span>A</span><span>B</span></section></div>
|
|
340
|
+
* const spans = $$('span');
|
|
341
|
+
* spans.unwrap(); // Removes <section>, both spans move to <div>
|
|
342
|
+
* // Result: <div><span>A</span><span>B</span></div>
|
|
343
|
+
* ```
|
|
344
|
+
*/
|
|
345
|
+
unwrap(): this {
|
|
346
|
+
// Collect unique parent elements to avoid removing the same parent multiple times.
|
|
347
|
+
const parents = new Set<Element>();
|
|
348
|
+
for (const el of this.elements) {
|
|
349
|
+
if (el.parentElement) {
|
|
350
|
+
parents.add(el.parentElement);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Unwrap each parent once: move all children out, then remove the wrapper.
|
|
355
|
+
parents.forEach((parent) => {
|
|
356
|
+
const grandParent = parent.parentNode;
|
|
357
|
+
if (!grandParent) return;
|
|
358
|
+
|
|
359
|
+
while (parent.firstChild) {
|
|
360
|
+
grandParent.insertBefore(parent.firstChild, parent);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
parent.remove();
|
|
364
|
+
});
|
|
365
|
+
return this;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/** Replace each element with provided content. */
|
|
369
|
+
replaceWith(content: string | Element): BQueryCollection {
|
|
370
|
+
const replacements: Element[] = [];
|
|
371
|
+
this.elements.forEach((el, index) => {
|
|
372
|
+
const replacement =
|
|
373
|
+
typeof content === 'string'
|
|
374
|
+
? createElementFromHtml(content)
|
|
375
|
+
: index === 0
|
|
376
|
+
? content
|
|
377
|
+
: (content.cloneNode(true) as Element);
|
|
378
|
+
el.replaceWith(replacement);
|
|
379
|
+
replacements.push(replacement);
|
|
380
|
+
});
|
|
381
|
+
return new BQueryCollection(replacements);
|
|
382
|
+
}
|
|
383
|
+
|
|
256
384
|
/**
|
|
257
385
|
* Shows all elements.
|
|
258
386
|
*
|
|
@@ -430,6 +558,33 @@ export class BQueryCollection {
|
|
|
430
558
|
return this;
|
|
431
559
|
}
|
|
432
560
|
|
|
561
|
+
/**
|
|
562
|
+
* Finds all descendant elements matching the selector across all elements
|
|
563
|
+
* in the collection. Returns a new BQueryCollection with the results.
|
|
564
|
+
*
|
|
565
|
+
* @param selector - CSS selector to match
|
|
566
|
+
* @returns A new BQueryCollection with all matching descendants
|
|
567
|
+
*
|
|
568
|
+
* @example
|
|
569
|
+
* ```ts
|
|
570
|
+
* $$('.container').find('.item').addClass('highlight');
|
|
571
|
+
* ```
|
|
572
|
+
*/
|
|
573
|
+
find(selector: string): BQueryCollection {
|
|
574
|
+
const seen = new Set<Element>();
|
|
575
|
+
const results: Element[] = [];
|
|
576
|
+
for (const el of this.elements) {
|
|
577
|
+
const found = el.querySelectorAll(selector);
|
|
578
|
+
for (let i = 0; i < found.length; i++) {
|
|
579
|
+
if (!seen.has(found[i])) {
|
|
580
|
+
seen.add(found[i]);
|
|
581
|
+
results.push(found[i]);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
return new BQueryCollection(results);
|
|
586
|
+
}
|
|
587
|
+
|
|
433
588
|
/**
|
|
434
589
|
* Removes all elements from the DOM.
|
|
435
590
|
*
|
|
@@ -451,4 +606,23 @@ export class BQueryCollection {
|
|
|
451
606
|
});
|
|
452
607
|
return this;
|
|
453
608
|
}
|
|
609
|
+
|
|
610
|
+
/** @internal */
|
|
611
|
+
private insertAll(content: InsertableContent, position: InsertPosition): void {
|
|
612
|
+
if (typeof content === 'string') {
|
|
613
|
+
// Sanitize once and reuse for all elements
|
|
614
|
+
const sanitized = sanitizeContent(content);
|
|
615
|
+
applyAll(this.elements, (el) => {
|
|
616
|
+
el.insertAdjacentHTML(position, sanitized);
|
|
617
|
+
});
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
const elements = toElementList(content);
|
|
622
|
+
this.elements.forEach((el, index) => {
|
|
623
|
+
const nodes =
|
|
624
|
+
index === 0 ? elements : elements.map((node) => node.cloneNode(true) as Element);
|
|
625
|
+
insertContent(el, nodes, position);
|
|
626
|
+
});
|
|
627
|
+
}
|
|
454
628
|
}
|
package/src/core/dom.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { sanitizeHtml } from '../security/sanitize';
|
|
2
|
+
import { applyAll, toElementList } from './shared';
|
|
3
|
+
|
|
4
|
+
export type InsertableContent = string | Element | Element[];
|
|
5
|
+
|
|
6
|
+
export const sanitizeContent = (html: string): string => sanitizeHtml(html);
|
|
7
|
+
|
|
8
|
+
export const setHtml = (element: Element, html: string): void => {
|
|
9
|
+
element.innerHTML = sanitizeHtml(html);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const createElementFromHtml = (html: string): Element => {
|
|
13
|
+
const template = document.createElement('template');
|
|
14
|
+
template.innerHTML = sanitizeHtml(html);
|
|
15
|
+
return template.content.firstElementChild ?? document.createElement('div');
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const insertContent = (
|
|
19
|
+
target: Element,
|
|
20
|
+
content: InsertableContent,
|
|
21
|
+
position: InsertPosition
|
|
22
|
+
): void => {
|
|
23
|
+
if (typeof content === 'string') {
|
|
24
|
+
target.insertAdjacentHTML(position, sanitizeHtml(content));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const elements = toElementList(content);
|
|
29
|
+
|
|
30
|
+
// For positions that insert at the beginning (afterbegin, afterend), reverse
|
|
31
|
+
// the array to maintain the caller's order. For beforeend/beforebegin, keep order.
|
|
32
|
+
const needsReverse = position === 'afterbegin' || position === 'afterend';
|
|
33
|
+
const orderedElements = needsReverse ? elements.slice().reverse() : elements;
|
|
34
|
+
|
|
35
|
+
applyAll(orderedElements, (el) => {
|
|
36
|
+
target.insertAdjacentElement(position, el);
|
|
37
|
+
});
|
|
38
|
+
};
|
package/src/core/element.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { applyAll, toElementList } from './shared';
|
|
1
|
+
import { createElementFromHtml, insertContent, setHtml } from './dom';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* Wrapper for a single DOM element.
|
|
@@ -83,6 +82,24 @@ export class BQueryElement {
|
|
|
83
82
|
return this;
|
|
84
83
|
}
|
|
85
84
|
|
|
85
|
+
/** Remove an attribute. */
|
|
86
|
+
removeAttr(name: string): this {
|
|
87
|
+
this.element.removeAttribute(name);
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Toggle an attribute on/off. */
|
|
92
|
+
toggleAttr(name: string, force?: boolean): this {
|
|
93
|
+
const hasAttr = this.element.hasAttribute(name);
|
|
94
|
+
const shouldAdd = force ?? !hasAttr;
|
|
95
|
+
if (shouldAdd) {
|
|
96
|
+
this.element.setAttribute(name, '');
|
|
97
|
+
} else {
|
|
98
|
+
this.element.removeAttribute(name);
|
|
99
|
+
}
|
|
100
|
+
return this;
|
|
101
|
+
}
|
|
102
|
+
|
|
86
103
|
/** Get or set a property. */
|
|
87
104
|
prop<T extends keyof Element>(name: T, value?: Element[T]): Element[T] | this {
|
|
88
105
|
if (value === undefined) {
|
|
@@ -125,7 +142,7 @@ export class BQueryElement {
|
|
|
125
142
|
* ```
|
|
126
143
|
*/
|
|
127
144
|
html(value: string): this {
|
|
128
|
-
this.element
|
|
145
|
+
setHtml(this.element, value);
|
|
129
146
|
return this;
|
|
130
147
|
}
|
|
131
148
|
|
|
@@ -148,23 +165,34 @@ export class BQueryElement {
|
|
|
148
165
|
*
|
|
149
166
|
* @param property - A CSS property name or an object of property-value pairs
|
|
150
167
|
* @param value - The value when setting a single property
|
|
151
|
-
* @returns The instance for method chaining
|
|
168
|
+
* @returns The computed style value when getting a single property, or the instance for method chaining when setting
|
|
152
169
|
*
|
|
153
170
|
* @example
|
|
154
171
|
* ```ts
|
|
155
|
-
* //
|
|
172
|
+
* // Get a computed style value
|
|
173
|
+
* const color = $('#box').css('color');
|
|
174
|
+
*
|
|
175
|
+
* // Set a single property
|
|
156
176
|
* $('#box').css('color', 'red');
|
|
157
177
|
*
|
|
158
|
-
* //
|
|
178
|
+
* // Set multiple properties
|
|
159
179
|
* $('#box').css({ color: 'red', 'font-size': '16px' });
|
|
160
180
|
* ```
|
|
161
181
|
*/
|
|
162
|
-
css(property: string
|
|
182
|
+
css(property: string): string;
|
|
183
|
+
css(property: string, value: string): this;
|
|
184
|
+
css(property: Record<string, string>): this;
|
|
185
|
+
css(property: string | Record<string, string>, value?: string): string | this {
|
|
163
186
|
if (typeof property === 'string') {
|
|
164
187
|
if (value !== undefined) {
|
|
165
188
|
(this.element as HTMLElement).style.setProperty(property, value);
|
|
189
|
+
return this;
|
|
190
|
+
}
|
|
191
|
+
const view = this.element.ownerDocument?.defaultView;
|
|
192
|
+
if (!view || typeof view.getComputedStyle !== 'function') {
|
|
193
|
+
return '';
|
|
166
194
|
}
|
|
167
|
-
return this;
|
|
195
|
+
return view.getComputedStyle(this.element).getPropertyValue(property);
|
|
168
196
|
}
|
|
169
197
|
|
|
170
198
|
for (const [key, val] of Object.entries(property)) {
|
|
@@ -240,6 +268,10 @@ export class BQueryElement {
|
|
|
240
268
|
* Removes the parent element, keeping this element in its place.
|
|
241
269
|
* Essentially the opposite of wrap().
|
|
242
270
|
*
|
|
271
|
+
* **Important**: This method only moves the current element out of its parent
|
|
272
|
+
* before removing the parent. Any sibling elements will be removed along with
|
|
273
|
+
* the parent. For unwrapping multiple siblings, use a collection: `$$(siblings).unwrap()`.
|
|
274
|
+
*
|
|
243
275
|
* @returns The instance for method chaining
|
|
244
276
|
*
|
|
245
277
|
* @example
|
|
@@ -270,14 +302,7 @@ export class BQueryElement {
|
|
|
270
302
|
* ```
|
|
271
303
|
*/
|
|
272
304
|
replaceWith(content: string | Element): BQueryElement {
|
|
273
|
-
|
|
274
|
-
if (typeof content === 'string') {
|
|
275
|
-
const template = document.createElement('template');
|
|
276
|
-
template.innerHTML = sanitizeHtml(content);
|
|
277
|
-
newEl = template.content.firstElementChild ?? document.createElement('div');
|
|
278
|
-
} else {
|
|
279
|
-
newEl = content;
|
|
280
|
-
}
|
|
305
|
+
const newEl = typeof content === 'string' ? createElementFromHtml(content) : content;
|
|
281
306
|
this.element.replaceWith(newEl);
|
|
282
307
|
return new BQueryElement(newEl);
|
|
283
308
|
}
|
|
@@ -549,6 +574,23 @@ export class BQueryElement {
|
|
|
549
574
|
return this.element.matches(selector);
|
|
550
575
|
}
|
|
551
576
|
|
|
577
|
+
/**
|
|
578
|
+
* Alias for `matches()`. Checks if the element matches a CSS selector.
|
|
579
|
+
*
|
|
580
|
+
* @param selector - CSS selector to match against
|
|
581
|
+
* @returns True if the element matches the selector
|
|
582
|
+
*
|
|
583
|
+
* @example
|
|
584
|
+
* ```ts
|
|
585
|
+
* if ($('#el').is('.active')) {
|
|
586
|
+
* console.log('Element is active');
|
|
587
|
+
* }
|
|
588
|
+
* ```
|
|
589
|
+
*/
|
|
590
|
+
is(selector: string): boolean {
|
|
591
|
+
return this.matches(selector);
|
|
592
|
+
}
|
|
593
|
+
|
|
552
594
|
/**
|
|
553
595
|
* Checks if the element has a specific class.
|
|
554
596
|
*
|
|
@@ -727,14 +769,6 @@ export class BQueryElement {
|
|
|
727
769
|
* @internal
|
|
728
770
|
*/
|
|
729
771
|
private insertContent(content: string | Element | Element[], position: InsertPosition) {
|
|
730
|
-
|
|
731
|
-
this.element.insertAdjacentHTML(position, sanitizeHtml(content));
|
|
732
|
-
return;
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
const elements = toElementList(content);
|
|
736
|
-
applyAll(elements, (el) => {
|
|
737
|
-
this.element.insertAdjacentElement(position, el);
|
|
738
|
-
});
|
|
772
|
+
insertContent(this.element, content, position);
|
|
739
773
|
}
|
|
740
774
|
}
|
package/src/core/index.ts
CHANGED
|
@@ -1,4 +1,48 @@
|
|
|
1
|
-
export { BQueryCollection } from './collection';
|
|
2
|
-
export { BQueryElement } from './element';
|
|
3
|
-
export { $, $$ } from './selector';
|
|
4
|
-
export
|
|
1
|
+
export { BQueryCollection } from './collection';
|
|
2
|
+
export { BQueryElement } from './element';
|
|
3
|
+
export { $, $$ } from './selector';
|
|
4
|
+
// Re-export the utils namespace for backward compatibility
|
|
5
|
+
export { utils } from './utils';
|
|
6
|
+
// Export individual utilities (except internal helpers)
|
|
7
|
+
export {
|
|
8
|
+
chunk,
|
|
9
|
+
compact,
|
|
10
|
+
ensureArray,
|
|
11
|
+
flatten,
|
|
12
|
+
unique,
|
|
13
|
+
debounce,
|
|
14
|
+
noop,
|
|
15
|
+
once,
|
|
16
|
+
throttle,
|
|
17
|
+
isEmpty,
|
|
18
|
+
parseJson,
|
|
19
|
+
sleep,
|
|
20
|
+
uid,
|
|
21
|
+
clamp,
|
|
22
|
+
inRange,
|
|
23
|
+
randomInt,
|
|
24
|
+
toNumber,
|
|
25
|
+
clone,
|
|
26
|
+
hasOwn,
|
|
27
|
+
isPlainObject,
|
|
28
|
+
merge,
|
|
29
|
+
omit,
|
|
30
|
+
pick,
|
|
31
|
+
capitalize,
|
|
32
|
+
escapeRegExp,
|
|
33
|
+
slugify,
|
|
34
|
+
toCamelCase,
|
|
35
|
+
toKebabCase,
|
|
36
|
+
truncate,
|
|
37
|
+
isArray,
|
|
38
|
+
isBoolean,
|
|
39
|
+
isCollection,
|
|
40
|
+
isDate,
|
|
41
|
+
isElement,
|
|
42
|
+
isFunction,
|
|
43
|
+
isNumber,
|
|
44
|
+
isObject,
|
|
45
|
+
isPromise,
|
|
46
|
+
isString,
|
|
47
|
+
} from './utils';
|
|
48
|
+
export type { DebouncedFn, ThrottledFn } from './utils';
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Array-focused utility helpers.
|
|
3
|
+
*
|
|
4
|
+
* @module bquery/core/utils/array
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Ensures the input is always returned as an array.
|
|
9
|
+
*
|
|
10
|
+
* @template T - The item type
|
|
11
|
+
* @param value - A single value, array, or nullish value
|
|
12
|
+
* @returns An array (empty if nullish)
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* ensureArray('a'); // ['a']
|
|
17
|
+
* ensureArray(['a', 'b']); // ['a', 'b']
|
|
18
|
+
* ensureArray(null); // []
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function ensureArray<T>(value: T | T[] | null | undefined): T[] {
|
|
22
|
+
if (value == null) return [];
|
|
23
|
+
return Array.isArray(value) ? value : [value];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Removes duplicate entries from an array.
|
|
28
|
+
*
|
|
29
|
+
* @template T - The item type
|
|
30
|
+
* @param items - The array to deduplicate
|
|
31
|
+
* @returns A new array with unique items
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* unique([1, 2, 2, 3]); // [1, 2, 3]
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export function unique<T>(items: T[]): T[] {
|
|
39
|
+
return Array.from(new Set(items));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Splits an array into chunks of a given size.
|
|
44
|
+
*
|
|
45
|
+
* @template T - The item type
|
|
46
|
+
* @param items - The array to chunk
|
|
47
|
+
* @param size - The maximum size of each chunk
|
|
48
|
+
* @returns An array of chunks
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* chunk([1, 2, 3, 4, 5], 2); // [[1,2],[3,4],[5]]
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export function chunk<T>(items: T[], size: number): T[][] {
|
|
56
|
+
if (size <= 0) return [];
|
|
57
|
+
const result: T[][] = [];
|
|
58
|
+
for (let i = 0; i < items.length; i += size) {
|
|
59
|
+
result.push(items.slice(i, i + size));
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Removes falsy values from an array.
|
|
66
|
+
*
|
|
67
|
+
* @template T - The item type
|
|
68
|
+
* @param items - The array to compact
|
|
69
|
+
* @returns A new array without falsy values
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* compact([0, 1, '', 'ok', null]); // [1, 'ok']
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export function compact<T>(items: Array<T | null | undefined | false | 0 | ''>): T[] {
|
|
77
|
+
return items.filter(Boolean) as T[];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Flattens a single level of nested arrays.
|
|
82
|
+
*
|
|
83
|
+
* @template T - The item type
|
|
84
|
+
* @param items - The array to flatten
|
|
85
|
+
* @returns A new flattened array
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* flatten([1, [2, 3], 4]); // [1, 2, 3, 4]
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export function flatten<T>(items: Array<T | T[]>): T[] {
|
|
93
|
+
const result: T[] = [];
|
|
94
|
+
for (const item of items) {
|
|
95
|
+
if (Array.isArray(item)) {
|
|
96
|
+
result.push(...item);
|
|
97
|
+
} else {
|
|
98
|
+
result.push(item);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
}
|