@pacem/pacem-core 1.0.0-bernoulli → 1.0.0-binet
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/browser/pacem-core.js +919 -32
- package/dist/browser/pacem-core.js.map +1 -1
- package/dist/browser/pacem-core.min.js +2 -3
- package/dist/bundle/pacem-core.min.mjs +6 -6
- package/dist/bundle/pacem-core.mjs +510 -22
- package/dist/bundle/pacem-core.mjs.map +2 -2
- package/dist/docs/pacem-core.json +40109 -0
- package/dist/esm/adapter.js +2 -1
- package/dist/esm/command.js +6 -1
- package/dist/esm/comparers.js +1 -1
- package/dist/esm/converters.js +6 -1
- package/dist/esm/decorators-next.js +1 -1
- package/dist/esm/decorators.js +94 -1
- package/dist/esm/defaults.js +2 -1
- package/dist/esm/events.js +55 -1
- package/dist/esm/eventtarget.js +11 -1
- package/dist/esm/expression.js +37 -1
- package/dist/esm/index-animations.js +1 -1
- package/dist/esm/index-behaviors.js +1 -1
- package/dist/esm/index-components.js +1 -1
- package/dist/esm/index-iife.js +1 -1
- package/dist/esm/index-logging.js +1 -1
- package/dist/esm/index-net.js +1 -1
- package/dist/esm/index-root.js +1 -1
- package/dist/esm/index-ui.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/logger.js +8 -1
- package/dist/esm/prefix.js +2 -1
- package/dist/esm/promise.js +11 -1
- package/dist/esm/regex.js +3 -1
- package/dist/esm/storage.js +14 -1
- package/dist/esm/template.js +2 -1
- package/dist/esm/transforms.js +53 -1
- package/dist/esm/types.js +6 -1
- package/dist/esm/utils-customelement.js +165 -6
- package/dist/esm/utils-customevent.js +27 -1
- package/dist/esm/utils.js +96 -1
- package/package.json +2 -1
- package/typings/index.d.ts +1105 -20
- package/dist/browser/pacem-core.min.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @pacem/pacem-core v1.0.0-
|
|
2
|
+
* @pacem/pacem-core v1.0.0-binet (https://js.pacem.it)
|
|
3
3
|
* Pacem (https://pacem.it)
|
|
4
4
|
* Licensed under Apache-2.0
|
|
5
5
|
*/
|
|
@@ -38,13 +38,20 @@ function assembleEasing(fn, css) {
|
|
|
38
38
|
return output;
|
|
39
39
|
}
|
|
40
40
|
var Easings = {
|
|
41
|
+
/** No easing: progress is proportional to elapsed time. */
|
|
41
42
|
linear: assembleEasing(EASINGS.linear, "linear"),
|
|
43
|
+
/** Sine ease-in: starts slow, accelerates towards the end. */
|
|
42
44
|
sineIn: assembleEasing(EASINGS.sineIn, "cubic-bezier(0.12, 0, 0.39, 0)"),
|
|
45
|
+
/** Sine ease-out: starts fast, decelerates towards the end. */
|
|
43
46
|
sineOut: assembleEasing(EASINGS.sineOut, "cubic-bezier(0.61, 1, 0.88, 1)"),
|
|
47
|
+
/** Sine ease-in-out: accelerates then decelerates, symmetric around the midpoint. */
|
|
44
48
|
sineInOut: assembleEasing(EASINGS.sineInOut, "cubic-bezier(0.37, 0, 0.63, 1)"),
|
|
45
49
|
// TODO: set correct pairing
|
|
50
|
+
/** Exponential ease-in: starts very slow, accelerates sharply towards the end. */
|
|
46
51
|
expoIn: assembleEasing(EASINGS.expoIn, "cubic-bezier(0.7, 0, 0.84, 0)"),
|
|
52
|
+
/** Exponential ease-out: starts very fast, decelerates sharply towards the end. */
|
|
47
53
|
expoOut: assembleEasing(EASINGS.expoOut, "cubic-bezier(0.16, 1, 0.3, 1)"),
|
|
54
|
+
/** Exponential ease-in-out: sharp acceleration then sharp deceleration, symmetric around the midpoint. */
|
|
48
55
|
expoInOut: assembleEasing(EASINGS.expoInOut, "cubic-bezier(0.87, 0, 0.13, 1)")
|
|
49
56
|
};
|
|
50
57
|
|
|
@@ -55,6 +62,7 @@ import { Keys as Keys2, Dates, Colors, Strings, Blobs, Imaging, NullChecker, det
|
|
|
55
62
|
var DeepCloner = class _DeepCloner {
|
|
56
63
|
constructor() {
|
|
57
64
|
}
|
|
65
|
+
/** Deep-clones `obj`; see {@link DeepCloner} for what gets cloned vs. passed through by reference. */
|
|
58
66
|
static clone(obj2) {
|
|
59
67
|
return new _DeepCloner()._clone(obj2);
|
|
60
68
|
}
|
|
@@ -127,9 +135,16 @@ var Json = class _Json {
|
|
|
127
135
|
constructor(_options) {
|
|
128
136
|
this._options = _options;
|
|
129
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Serializes `obj` to a JSON string, extended to support circular/shared references, `RegExp`s,
|
|
140
|
+
* `Element`s (by `id`) and, per `options`, functions.
|
|
141
|
+
* @param obj Value to serialize.
|
|
142
|
+
* @param options Controls how function-valued properties are handled.
|
|
143
|
+
*/
|
|
130
144
|
static serialize(obj2, options) {
|
|
131
145
|
return new _Json(options)._serialize(obj2);
|
|
132
146
|
}
|
|
147
|
+
/** Deserializes a string produced by {@link serialize}, restoring references, `RegExp`s, `Element`s and functions. */
|
|
133
148
|
static deserialize(json2) {
|
|
134
149
|
return new _Json()._deserialize(json2);
|
|
135
150
|
}
|
|
@@ -240,6 +255,7 @@ var DeferPromise = class _DeferPromise {
|
|
|
240
255
|
me.deferred = { "resolve": resolve, "reject": reject, "promise": me };
|
|
241
256
|
});
|
|
242
257
|
}
|
|
258
|
+
/** Standard `PromiseLike.then`, delegating to the underlying native `Promise`. */
|
|
243
259
|
then(onCompleted, onFailed) {
|
|
244
260
|
return this.promise.then(onCompleted, onFailed);
|
|
245
261
|
}
|
|
@@ -251,14 +267,17 @@ var DeferPromise = class _DeferPromise {
|
|
|
251
267
|
this.promise.then(callback, callback);
|
|
252
268
|
return this;
|
|
253
269
|
}
|
|
270
|
+
/** Registers a fulfillment-only callback (fluent, chainable alternative to `then(callback)`). */
|
|
254
271
|
success(callback) {
|
|
255
272
|
this.promise.then(callback, null);
|
|
256
273
|
return this;
|
|
257
274
|
}
|
|
275
|
+
/** Registers a rejection-only callback (fluent, chainable alternative to `then(null, callback)`). */
|
|
258
276
|
error(callback) {
|
|
259
277
|
this.promise.then(null, callback);
|
|
260
278
|
return this;
|
|
261
279
|
}
|
|
280
|
+
/** Creates a new deferred promise and returns its controller: `{ resolve, reject, promise }`. */
|
|
262
281
|
static defer() {
|
|
263
282
|
var q = new _DeferPromise();
|
|
264
283
|
return q.deferred;
|
|
@@ -281,27 +300,34 @@ var avoidHandler = (evt) => {
|
|
|
281
300
|
var SEGMENT_PATTERN = /^\/[^\/]+/;
|
|
282
301
|
var ROUTE_SEGMENT_PATTERN = /\/\{([a-z\$_][\w]*)\??\}/;
|
|
283
302
|
var Utils = class _Utils {
|
|
303
|
+
/** The framework's global scratch/registry object (`window[id]`, where `id` defaults to `'pacem'` and is configurable via `window.Pacem.Configuration.core`); created on first access. Used e.g. to store {@link Transformer}-registered transform functions. */
|
|
284
304
|
static get core() {
|
|
285
305
|
const root2 = window["Pacem"];
|
|
286
306
|
var id = root2 && root2.Configuration && root2.Configuration.core || PACEM_CORE_DEFAULT;
|
|
287
307
|
return window[id] = window[id] || {};
|
|
288
308
|
}
|
|
309
|
+
/** The platform's (native or polyfilled) `customElements` registry. */
|
|
289
310
|
static get customElements() {
|
|
290
311
|
return window["customElements"];
|
|
291
312
|
}
|
|
292
313
|
// #region GENERAL
|
|
314
|
+
/** Generates a unique numeric-ish id string. */
|
|
293
315
|
static uniqueId() {
|
|
294
316
|
return Keys2.uniqueId();
|
|
295
317
|
}
|
|
318
|
+
/** Generates a unique short code string. */
|
|
296
319
|
static uniqueCode() {
|
|
297
320
|
return Keys2.uniqueCode();
|
|
298
321
|
}
|
|
322
|
+
/** Generates a random string of the given `length`. */
|
|
299
323
|
static randomString(length) {
|
|
300
324
|
return Keys2.randomString(length);
|
|
301
325
|
}
|
|
326
|
+
/** Parses a date-like value (ISO string, `Date`, or timestamp) into a `Date`. */
|
|
302
327
|
static parseDate(input) {
|
|
303
328
|
return Dates.parse(input);
|
|
304
329
|
}
|
|
330
|
+
/** Writes `input` to the system clipboard, using the async Clipboard API when available and falling back to `document.execCommand('copy')` otherwise. */
|
|
305
331
|
static copyToClipboard(input) {
|
|
306
332
|
if (navigator.clipboard) {
|
|
307
333
|
return navigator.clipboard.writeText(input);
|
|
@@ -368,6 +394,7 @@ var Utils = class _Utils {
|
|
|
368
394
|
return filter;
|
|
369
395
|
}
|
|
370
396
|
}
|
|
397
|
+
/** Escapes `input` for safe use as a CSS identifier/selector fragment. */
|
|
371
398
|
static cssEscape(input) {
|
|
372
399
|
return escape(input).replace("%", "\\");
|
|
373
400
|
}
|
|
@@ -375,9 +402,11 @@ var Utils = class _Utils {
|
|
|
375
402
|
this.Css = {
|
|
376
403
|
colorize: _Utils.colorize,
|
|
377
404
|
escape: _Utils.cssEscape,
|
|
405
|
+
/** Reads a CSS custom property's current value off the document root (`:root`/`html`). */
|
|
378
406
|
getVariableValue(name) {
|
|
379
407
|
return getComputedStyle(document.documentElement).getPropertyValue(name);
|
|
380
408
|
},
|
|
409
|
+
/** Sets a CSS custom property's value on the document root (`:root`/`html`). */
|
|
381
410
|
setVariable(name, value2) {
|
|
382
411
|
getComputedStyle(document.documentElement).setProperty(name, value2);
|
|
383
412
|
},
|
|
@@ -405,6 +434,7 @@ var Utils = class _Utils {
|
|
|
405
434
|
}
|
|
406
435
|
return false;
|
|
407
436
|
},
|
|
437
|
+
/** Parses an element's (or style declaration's) computed `transform: matrix(...)` CSS value into its 2D affine matrix components; identity if unset. */
|
|
408
438
|
deserializeTransform(element) {
|
|
409
439
|
const style = element instanceof Element ? getComputedStyle(element) : element;
|
|
410
440
|
let a = 1, b = 0, c = 0, d = 1, x = 0, y = 0, matches = /^matrix\((.*)\)$/.exec(style.transform), mij;
|
|
@@ -434,6 +464,7 @@ var Utils = class _Utils {
|
|
|
434
464
|
leftPad: Strings.leftPad,
|
|
435
465
|
format: Strings.format,
|
|
436
466
|
diff: Strings.diff,
|
|
467
|
+
/** Strips HTML markup from `html`, returning its plain-text content. */
|
|
437
468
|
stripHTML: (html) => {
|
|
438
469
|
let doc = new DOMParser().parseFromString(html, "text/html");
|
|
439
470
|
return doc.body.textContent || "";
|
|
@@ -454,6 +485,7 @@ var Utils = class _Utils {
|
|
|
454
485
|
resize: Imaging.resizeImage
|
|
455
486
|
};
|
|
456
487
|
}
|
|
488
|
+
/** Loads an image from `src` and resolves with the `HTMLImageElement` once ready (or rejects on error). */
|
|
457
489
|
static loadImage(src) {
|
|
458
490
|
return new Promise((resolve, reject) => {
|
|
459
491
|
const img = new Image();
|
|
@@ -470,15 +502,19 @@ var Utils = class _Utils {
|
|
|
470
502
|
}
|
|
471
503
|
});
|
|
472
504
|
}
|
|
505
|
+
/** Converts a `Blob` to a `data:` URL string. */
|
|
473
506
|
static blobToDataURL(blob) {
|
|
474
507
|
return _Utils.Blobs.toDataURL(blob);
|
|
475
508
|
}
|
|
509
|
+
/** Converts a `data:` URL string back into a `Blob`. */
|
|
476
510
|
static dataURLToBlob(dataURL) {
|
|
477
511
|
return _Utils.Blobs.fromDataURL(dataURL);
|
|
478
512
|
}
|
|
513
|
+
/** Reads a `Blob`'s content as text, using the given `encoding` (default UTF-8). */
|
|
479
514
|
static blobToText(blob, encoding) {
|
|
480
515
|
return _Utils.Blobs.toText(blob, encoding);
|
|
481
516
|
}
|
|
517
|
+
/** Wraps `content` in a `Blob` of the given MIME `type` (default `'text/plain'`). */
|
|
482
518
|
static textToBlob(content, type = "text/plain") {
|
|
483
519
|
return _Utils.Blobs.fromText(content, type);
|
|
484
520
|
}
|
|
@@ -556,6 +592,7 @@ var Utils = class _Utils {
|
|
|
556
592
|
el.src = url;
|
|
557
593
|
return deferred.promise;
|
|
558
594
|
}
|
|
595
|
+
/** Returns the list of vendor-prefixed `getUserMedia` implementations available on `navigator`, if any. */
|
|
559
596
|
static getUserMediaFunctions() {
|
|
560
597
|
var _getUserMedia = [];
|
|
561
598
|
let methods = [navigator["getUserMedia"], navigator["webkitGetUserMedia"], navigator["msGetUserMedia"], navigator["mozGetUserMedia"]];
|
|
@@ -773,12 +810,14 @@ var Utils = class _Utils {
|
|
|
773
810
|
}
|
|
774
811
|
// #endregion
|
|
775
812
|
// #region DOM
|
|
813
|
+
/** Whether the document (including module scripts) has fully finished loading (`document.readyState === 'complete'`). */
|
|
776
814
|
static isDOMReady() {
|
|
777
815
|
return (
|
|
778
816
|
/* document.readyState === 'interactive' ||*/
|
|
779
817
|
document.readyState === "complete"
|
|
780
818
|
);
|
|
781
819
|
}
|
|
820
|
+
/** Registers `listener` to run once the document (and its resources, e.g. images) has fully loaded (the `window` `'load'` event). */
|
|
782
821
|
static onDOMReady(listener) {
|
|
783
822
|
window.addEventListener("load", listener, false);
|
|
784
823
|
}
|
|
@@ -805,12 +844,15 @@ var Utils = class _Utils {
|
|
|
805
844
|
}
|
|
806
845
|
return dom;
|
|
807
846
|
}
|
|
847
|
+
/** Cross-browser `Element.matches(selector)`, falling back to vendor-prefixed variants. */
|
|
808
848
|
static is(el, selector) {
|
|
809
849
|
return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector);
|
|
810
850
|
}
|
|
851
|
+
/** Resolves the effective language for `el`: its own `lang` attribute, else the document's, else the browser's. */
|
|
811
852
|
static lang(el) {
|
|
812
853
|
return el.lang || document.documentElement.lang || navigator.language;
|
|
813
854
|
}
|
|
855
|
+
/** JSON-stringifies `obj` (via {@link Json}), or passes through `null`/`undefined` unchanged. */
|
|
814
856
|
static jsonSortStringify(obj2) {
|
|
815
857
|
if (_Utils.isNull(obj2)) {
|
|
816
858
|
return obj2;
|
|
@@ -822,6 +864,7 @@ var Utils = class _Utils {
|
|
|
822
864
|
detect
|
|
823
865
|
};
|
|
824
866
|
}
|
|
867
|
+
/** Parses a `document.cookie`-style string (or `document.cookie` itself, by default) into a name/value map. */
|
|
825
868
|
static cookies(cookie) {
|
|
826
869
|
const cookies = (cookie ?? document.cookie).split(";"), retval = {};
|
|
827
870
|
for (var pair of cookies) {
|
|
@@ -841,6 +884,7 @@ var Utils = class _Utils {
|
|
|
841
884
|
}
|
|
842
885
|
static {
|
|
843
886
|
this.Cookies = {
|
|
887
|
+
/** Retrieves all cookies (or just `cookieName`, if given) as {@link CookieData} entries. */
|
|
844
888
|
getAll: async (cookieName) => {
|
|
845
889
|
const store = "cookieStore" in window ? window.cookieStore : null;
|
|
846
890
|
const retval = [];
|
|
@@ -857,6 +901,7 @@ var Utils = class _Utils {
|
|
|
857
901
|
return await store.getAll(cookieName);
|
|
858
902
|
}
|
|
859
903
|
},
|
|
904
|
+
/** Serializes a {@link CookieData} descriptor into a `document.cookie`-assignable string (including `domain`/`path`/`max-age`/`expires`/`Partitioned`/`SameSite`/`Secure` attributes, as provided). */
|
|
860
905
|
stringify: (data) => {
|
|
861
906
|
let retval = `${data.name}=${encodeURIComponent(data.value ?? "")}`;
|
|
862
907
|
if (!_Utils.isNullOrEmpty(data.domain)) {
|
|
@@ -884,6 +929,7 @@ var Utils = class _Utils {
|
|
|
884
929
|
}
|
|
885
930
|
};
|
|
886
931
|
}
|
|
932
|
+
/** Tests whether `el` is currently visible (via the `checkVisibility` API when available, falling back to a CSS-visibility/size heuristic). */
|
|
887
933
|
static isVisible(el) {
|
|
888
934
|
if ("checkVisibility" in el) {
|
|
889
935
|
return el.checkVisibility({ checkOpacity: true, checkVisibilityCSS: true });
|
|
@@ -891,6 +937,7 @@ var Utils = class _Utils {
|
|
|
891
937
|
return getComputedStyle(el).visibility !== "hidden" && (el.clientWidth > 0 || el.clientHeight > 0);
|
|
892
938
|
}
|
|
893
939
|
//#region classList DOMTokenList (css)
|
|
940
|
+
/** Tests whether `el` has `className` set, using `classList` when available (with a regex-based fallback). */
|
|
894
941
|
static hasClass(el, className) {
|
|
895
942
|
if (el.classList) {
|
|
896
943
|
return el.classList.contains(className);
|
|
@@ -898,6 +945,7 @@ var Utils = class _Utils {
|
|
|
898
945
|
return new RegExp("(^| )" + className + "( |$)", "gi").test(el.className);
|
|
899
946
|
}
|
|
900
947
|
}
|
|
948
|
+
/** Adds one or more (space-separated) classes to `el`, using `classList` when available. */
|
|
901
949
|
static addClass(el, className) {
|
|
902
950
|
const css = className.trim();
|
|
903
951
|
if (el.classList) {
|
|
@@ -906,6 +954,7 @@ var Utils = class _Utils {
|
|
|
906
954
|
el.setAttribute("class", el.className + " " + css);
|
|
907
955
|
}
|
|
908
956
|
}
|
|
957
|
+
/** Removes one or more (space-separated) classes from `el`, using `classList` when available. */
|
|
909
958
|
static removeClass(el, className) {
|
|
910
959
|
const css = className.trim();
|
|
911
960
|
if (el.classList) {
|
|
@@ -914,6 +963,7 @@ var Utils = class _Utils {
|
|
|
914
963
|
el.setAttribute("class", el.className.replace(new RegExp("(^|\\b)" + css.split(" ").join("|") + "(\\b|$)", "gi"), " "));
|
|
915
964
|
}
|
|
916
965
|
}
|
|
966
|
+
/** Adds or removes `className` on `el` depending on `on`; see {@link addClass}/{@link removeClass}. */
|
|
917
967
|
static toggleClass(el, className, on) {
|
|
918
968
|
if (on) {
|
|
919
969
|
_Utils.addClass(el, className);
|
|
@@ -923,15 +973,19 @@ var Utils = class _Utils {
|
|
|
923
973
|
}
|
|
924
974
|
//#endregion
|
|
925
975
|
//#region part DOMTokenList (shadow-DOM)
|
|
976
|
+
/** Tests whether `el`'s `part` attribute (CSS Shadow Parts) contains `partName`. */
|
|
926
977
|
static hasPart(el, partName) {
|
|
927
978
|
return el.part.contains(partName);
|
|
928
979
|
}
|
|
980
|
+
/** Adds one or more (space-separated) shadow-part names to `el`'s `part` attribute. */
|
|
929
981
|
static addPart(el, partName) {
|
|
930
982
|
DOMTokenList.prototype.add.apply(el.part, partName.trim().split(" "));
|
|
931
983
|
}
|
|
984
|
+
/** Removes one or more (space-separated) shadow-part names from `el`'s `part` attribute. */
|
|
932
985
|
static removePart(el, partName) {
|
|
933
986
|
DOMTokenList.prototype.remove.apply(el.part, partName.trim().split(" "));
|
|
934
987
|
}
|
|
988
|
+
/** Adds or removes `partName` on `el`'s `part` attribute depending on `on`; see {@link addPart}/{@link removePart}. */
|
|
935
989
|
static togglePart(el, partName, on) {
|
|
936
990
|
if (on) {
|
|
937
991
|
_Utils.addPart(el, partName);
|
|
@@ -966,9 +1020,11 @@ var Utils = class _Utils {
|
|
|
966
1020
|
height: rect.height
|
|
967
1021
|
};
|
|
968
1022
|
}
|
|
1023
|
+
/** Sums `offsetTop` up the `offsetParent` chain, giving `el`'s vertical position relative to the document rather than just its nearest positioned ancestor. */
|
|
969
1024
|
static naturalOffsetTop(el) {
|
|
970
1025
|
return (el?.offsetTop ?? 0) + (el?.offsetParent && el.offsetParent instanceof HTMLElement ? this.naturalOffsetTop(el.offsetParent) : 0);
|
|
971
1026
|
}
|
|
1027
|
+
/** Sums `offsetTop` up the `offsetParent` chain (note: mirrors {@link naturalOffsetTop}'s calculation, not `offsetLeft`), giving `el`'s horizontal position relative to the document. */
|
|
972
1028
|
static naturalOffsetLeft(el) {
|
|
973
1029
|
return (el?.offsetTop ?? 0) + (el?.offsetParent && el.offsetParent instanceof HTMLElement ? this.naturalOffsetLeft(el.offsetParent) : 0);
|
|
974
1030
|
}
|
|
@@ -996,18 +1052,30 @@ var Utils = class _Utils {
|
|
|
996
1052
|
static deserializeTransform(obj2) {
|
|
997
1053
|
return _Utils.Css.deserializeTransform(obj2);
|
|
998
1054
|
}
|
|
1055
|
+
/** Sets the window's vertical scroll position, keeping the current horizontal position. */
|
|
999
1056
|
static set scrollTop(y) {
|
|
1000
1057
|
window.scrollTo(_Utils.scrollLeft, y);
|
|
1001
1058
|
}
|
|
1059
|
+
/** Sets the window's horizontal scroll position, keeping the current vertical position. */
|
|
1002
1060
|
static set scrollLeft(x) {
|
|
1003
1061
|
window.scrollTo(x, _Utils.scrollTop);
|
|
1004
1062
|
}
|
|
1063
|
+
static scrollTo(x, y = true, smooth = true) {
|
|
1064
|
+
const yFirst = _Utils.isNull(y) || typeof y === "boolean";
|
|
1065
|
+
const left = yFirst ? _Utils.scrollLeft : x;
|
|
1066
|
+
const top = yFirst ? x : y;
|
|
1067
|
+
const behavior = (yFirst ? y : smooth) ? "smooth" : "instant";
|
|
1068
|
+
window.scrollTo({ behavior, left, top });
|
|
1069
|
+
}
|
|
1070
|
+
/** The window's current vertical scroll position, with fallbacks for older browsers. */
|
|
1005
1071
|
static get scrollTop() {
|
|
1006
1072
|
return window.scrollY || document.documentElement.scrollTop || document.body.scrollTop || 0;
|
|
1007
1073
|
}
|
|
1074
|
+
/** The window's current horizontal scroll position, with fallbacks for older browsers. */
|
|
1008
1075
|
static get scrollLeft() {
|
|
1009
1076
|
return window.scrollX || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
|
|
1010
1077
|
}
|
|
1078
|
+
/** The window's current viewport size (`{ width, height }`), with fallbacks for older browsers. */
|
|
1011
1079
|
static get windowSize() {
|
|
1012
1080
|
let win = window;
|
|
1013
1081
|
return {
|
|
@@ -1081,16 +1149,20 @@ var Utils = class _Utils {
|
|
|
1081
1149
|
}
|
|
1082
1150
|
// #endregion
|
|
1083
1151
|
// #region other
|
|
1152
|
+
/** Tests whether `obj` is "empty" (per {@link NullChecker.isEmpty}: `null`/`undefined`/`''`/an empty array or object), excluding DOM `Node`s (which are never considered empty here). */
|
|
1084
1153
|
static isEmpty(obj2) {
|
|
1085
1154
|
return NullChecker.isEmpty(obj2) && !(obj2 instanceof Node);
|
|
1086
1155
|
}
|
|
1156
|
+
/** Type-guarding test for `obj` being `null` or `undefined`. */
|
|
1087
1157
|
static isNull(obj2) {
|
|
1088
1158
|
return NullChecker.isNull(obj2);
|
|
1089
1159
|
}
|
|
1090
1160
|
// legacy
|
|
1161
|
+
/** Type-guarding test for `val` being an array. */
|
|
1091
1162
|
static isArray(val) {
|
|
1092
1163
|
return Array.isArray(val);
|
|
1093
1164
|
}
|
|
1165
|
+
/** Tests whether `val` is `null`/`undefined` or "empty"; see {@link isNull}/{@link isEmpty}. */
|
|
1094
1166
|
static isNullOrEmpty(val) {
|
|
1095
1167
|
return _Utils.isNull(val) || _Utils.isEmpty(val);
|
|
1096
1168
|
}
|
|
@@ -1109,6 +1181,7 @@ var Utils = class _Utils {
|
|
|
1109
1181
|
static {
|
|
1110
1182
|
this.extend = Object.assign;
|
|
1111
1183
|
}
|
|
1184
|
+
/** Deep-clones `obj`; see {@link DeepCloner}. */
|
|
1112
1185
|
static clone(obj2) {
|
|
1113
1186
|
if (obj2 === void 0)
|
|
1114
1187
|
return void 0;
|
|
@@ -1118,6 +1191,7 @@ var Utils = class _Utils {
|
|
|
1118
1191
|
static fromResult(v) {
|
|
1119
1192
|
return Promise.resolve(v);
|
|
1120
1193
|
}
|
|
1194
|
+
/** Runs `task` on the next animation frame and wraps its result in a `Promise`. */
|
|
1121
1195
|
static fromResultAsync(task) {
|
|
1122
1196
|
return new Promise((resolve) => requestAnimationFrame(() => resolve(task())));
|
|
1123
1197
|
}
|
|
@@ -1140,6 +1214,13 @@ var Utils = class _Utils {
|
|
|
1140
1214
|
}
|
|
1141
1215
|
static {
|
|
1142
1216
|
this.URIs = {
|
|
1217
|
+
/**
|
|
1218
|
+
* Substitutes each `{name}`/`{name?}` template segment in `url` with the matching entry of `parameters`
|
|
1219
|
+
* (URL-encoded), then strips out any remaining unmatched *optional* segments.
|
|
1220
|
+
* @param url URL/route template containing `{name}`/`{name?}` segments.
|
|
1221
|
+
* @param parameters Values to substitute, keyed by segment name.
|
|
1222
|
+
* @param removeMatchedParameters When `true`, consumed entries are deleted from `parameters`.
|
|
1223
|
+
*/
|
|
1143
1224
|
format: function(url, parameters, removeMatchedParameters) {
|
|
1144
1225
|
for (let name in parameters || {}) {
|
|
1145
1226
|
let tmpl = new RegExp("(^|\\/)\\{" + name + "\\??\\}(\\/|$)");
|
|
@@ -1160,11 +1241,20 @@ var Utils = class _Utils {
|
|
|
1160
1241
|
}
|
|
1161
1242
|
return url;
|
|
1162
1243
|
},
|
|
1244
|
+
/**
|
|
1245
|
+
* Appends `parameters` to `url`'s query string (or hash fragment, when `hash` is `true`), URL-encoding
|
|
1246
|
+
* names and values, and correctly choosing `?`/`&` (or `#`/`&`) as the joining separator.
|
|
1247
|
+
* @param url Base URL.
|
|
1248
|
+
* @param parameters Values to append, keyed by parameter name.
|
|
1249
|
+
* @param removeNullEntries When `true`, entries whose value is `null`/`undefined` are omitted instead of appended as empty.
|
|
1250
|
+
* @param hash When `true`, appends to the URL's hash fragment instead of its query string.
|
|
1251
|
+
*/
|
|
1163
1252
|
appendQuery: function(url, parameters, removeNullEntries = false, hash = false) {
|
|
1164
1253
|
const char = hash ? "#" : "?", pattern = hash ? /#/ : /\?/;
|
|
1165
1254
|
const query = (pattern.test(url) ? "&" : char) + Object.keys(parameters).filter((k) => !_Utils.isNull(parameters[k]) || !removeNullEntries).map((k) => encodeURIComponent(k) + "=" + encodeURIComponent(parameters[k] ?? "")).join("&");
|
|
1166
1255
|
return url + (query.length > 1 ? query : "");
|
|
1167
1256
|
},
|
|
1257
|
+
/** Parses a query string (or a `Location`'s `.search`, defaulting to `window.location`) into a name/value map. */
|
|
1168
1258
|
parseQuery: (query = window.location) => {
|
|
1169
1259
|
if (typeof query !== "string") {
|
|
1170
1260
|
query = query.search;
|
|
@@ -1175,9 +1265,11 @@ var Utils = class _Utils {
|
|
|
1175
1265
|
});
|
|
1176
1266
|
return obj2;
|
|
1177
1267
|
},
|
|
1268
|
+
/** Tests whether `url` contains at least one non-optional `{name}` template segment (as opposed to only `{name?}` ones). */
|
|
1178
1269
|
hasMandatoryTemplateSegments: function(url) {
|
|
1179
1270
|
return /(^|\/)\{\.*\}(\/|$)/.test(url);
|
|
1180
1271
|
},
|
|
1272
|
+
/** Parses a route template's `{name}`/`{name?}` segments into an ordered list of {@link RouteMetadata} descriptors, consumed by {@link parseState}. */
|
|
1181
1273
|
parseRoute: function(pathTemplate) {
|
|
1182
1274
|
let tmpl = pathTemplate;
|
|
1183
1275
|
const trunks = [];
|
|
@@ -1197,6 +1289,7 @@ var Utils = class _Utils {
|
|
|
1197
1289
|
}
|
|
1198
1290
|
return trunks;
|
|
1199
1291
|
},
|
|
1292
|
+
/** Splits `url` into its `protocol`, `domain`, `path`, `query` (including leading `?`) and `hash` (including leading `#`) parts, or `null` if it can't be parsed. */
|
|
1200
1293
|
split: function(url) {
|
|
1201
1294
|
const URL_PATTERN = /^((https?:)?\/\/[^\/]+)?([^\?#]+)(\?[^#]*)?(#[^#]*)?$/;
|
|
1202
1295
|
const regArr = URL_PATTERN.exec(url);
|
|
@@ -1205,6 +1298,16 @@ var Utils = class _Utils {
|
|
|
1205
1298
|
}
|
|
1206
1299
|
return { domain: regArr[2] ?? "", protocol: regArr[1] ?? "", path: regArr[3] ?? "", query: regArr[4] ?? "", hash: regArr[5] ?? "" };
|
|
1207
1300
|
},
|
|
1301
|
+
/**
|
|
1302
|
+
* Builds a {@link RouterState} for `url`, extracting named route segments per `metadata` (see
|
|
1303
|
+
* {@link parseRoute}) as top-level properties, alongside the standard `$path`/`$pathname`/`$querystring`/
|
|
1304
|
+
* `$query`/`$hash` keys. Throws if a non-optional route segment declared in `metadata` isn't present in `path`.
|
|
1305
|
+
* @param metadata Route segment descriptors, as produced by {@link parseRoute}.
|
|
1306
|
+
* @param url Full URL/path being navigated to.
|
|
1307
|
+
* @param path Path component override; parsed out of `url` via {@link split} when omitted.
|
|
1308
|
+
* @param query Query-string override (including leading `?`); parsed out of `url` when omitted.
|
|
1309
|
+
* @param hash Hash-fragment override (including leading `#`); parsed out of `url` when omitted.
|
|
1310
|
+
*/
|
|
1208
1311
|
parseState: function(metadata, url, path, query, hash) {
|
|
1209
1312
|
let fullPath = url;
|
|
1210
1313
|
if (_Utils.isNullOrEmpty(path)) {
|
|
@@ -1295,9 +1398,21 @@ var EventKeyModifier;
|
|
|
1295
1398
|
EventKeyModifier2["MetaKey"] = "Cmd";
|
|
1296
1399
|
})(EventKeyModifier || (EventKeyModifier = {}));
|
|
1297
1400
|
var CustomEventUtils = class {
|
|
1401
|
+
/**
|
|
1402
|
+
* Type-guarding check for whether `evt` is an instance of the given event `type`.
|
|
1403
|
+
* @param evt Event to test.
|
|
1404
|
+
* @param type Event constructor to test against.
|
|
1405
|
+
* @returns `true` (narrowing `evt` to `TEvent`) if `evt instanceof type`.
|
|
1406
|
+
*/
|
|
1298
1407
|
static isInstanceOf(evt, type) {
|
|
1299
1408
|
return evt instanceof type;
|
|
1300
1409
|
}
|
|
1410
|
+
/**
|
|
1411
|
+
* Extracts page/client/screen coordinates from a mouse or (single-)touch event, using the first
|
|
1412
|
+
* active touch (`touches[0]`, falling back to `changedTouches[0]`) for `TouchEvent`s.
|
|
1413
|
+
* @param evt Source mouse/touch event, or an already-extracted {@link UIEventLike}.
|
|
1414
|
+
* @returns The event's position in all three coordinate systems.
|
|
1415
|
+
*/
|
|
1301
1416
|
static getEventCoordinates(evt) {
|
|
1302
1417
|
var src;
|
|
1303
1418
|
if ("touches" in evt) {
|
|
@@ -1315,6 +1430,11 @@ var CustomEventUtils = class {
|
|
|
1315
1430
|
client: { x: src.clientX, y: src.clientY }
|
|
1316
1431
|
};
|
|
1317
1432
|
}
|
|
1433
|
+
/**
|
|
1434
|
+
* Extracts the keyboard-modifier flags (and, for mouse events, the pressed button as `which`) from a native event.
|
|
1435
|
+
* @param evt Source keyboard/mouse/touch event, or an already-extracted {@link KeyEventLike}.
|
|
1436
|
+
* @returns The captured modifier flags.
|
|
1437
|
+
*/
|
|
1318
1438
|
static getEventKeyModifiers(evt) {
|
|
1319
1439
|
var which = evt.which;
|
|
1320
1440
|
if (evt instanceof MouseEvent) {
|
|
@@ -1336,6 +1456,13 @@ var CustomEventUtils = class {
|
|
|
1336
1456
|
}
|
|
1337
1457
|
return true;
|
|
1338
1458
|
}
|
|
1459
|
+
/**
|
|
1460
|
+
* Works around a legacy Edge/ChakraCore bug (see {@link https://github.com/Microsoft/ChakraCore/issues/3952})
|
|
1461
|
+
* where an instance built via `super(...)` from a `CustomEvent` subclass constructor doesn't correctly
|
|
1462
|
+
* pass `instanceof` checks against that subclass; forcibly resets its prototype when so.
|
|
1463
|
+
* @param evt Event instance to fix up.
|
|
1464
|
+
* @param type The subclass constructor `evt` is supposed to be an instance of.
|
|
1465
|
+
*/
|
|
1339
1466
|
static fixEdgeCustomEventSubClassInstance(evt, type) {
|
|
1340
1467
|
if (!(evt instanceof type)) {
|
|
1341
1468
|
Object.setPrototypeOf(evt, type);
|
|
@@ -1345,6 +1472,11 @@ var CustomEventUtils = class {
|
|
|
1345
1472
|
|
|
1346
1473
|
// packages/core/dist/esm/events.js
|
|
1347
1474
|
var CustomTypedEvent = class extends CustomEvent {
|
|
1475
|
+
/**
|
|
1476
|
+
* @param type Event name.
|
|
1477
|
+
* @param detail Strongly-typed payload, exposed as `event.detail`.
|
|
1478
|
+
* @param eventInit Standard `CustomEvent` initialization options (`bubbles`, `cancelable`, `composed`).
|
|
1479
|
+
*/
|
|
1348
1480
|
constructor(type, detail, eventInit) {
|
|
1349
1481
|
super(type, Utils.extend({ detail }, eventInit || {}));
|
|
1350
1482
|
CustomEventUtils.fixEdgeCustomEventSubClassInstance(this, this.constructor);
|
|
@@ -1362,6 +1494,12 @@ function isEventInit(obj2) {
|
|
|
1362
1494
|
return false;
|
|
1363
1495
|
}
|
|
1364
1496
|
var CustomUIEvent = class extends CustomEvent {
|
|
1497
|
+
/**
|
|
1498
|
+
* @param type Event name.
|
|
1499
|
+
* @param detail Either the strongly-typed payload, or (when it satisfies `CustomEventInit`, i.e. has a `detail` key) the full event-init object.
|
|
1500
|
+
* @param eventInit Either standard `CustomEvent` init options, or the original native event this custom event derives from (in which case its coordinates/modifiers get captured).
|
|
1501
|
+
* @param orig The original native mouse/touch/keyboard event this custom event derives from, when `eventInit` is itself the init options.
|
|
1502
|
+
*/
|
|
1365
1503
|
constructor(type, detail, eventInit, orig) {
|
|
1366
1504
|
super(type, Utils.extend(isEventInit(detail || {}) ? detail : { detail }, !(eventInit instanceof Event) && eventInit || {}));
|
|
1367
1505
|
const originalEvent = orig || eventInit;
|
|
@@ -1426,6 +1564,20 @@ var PropertyChangeEvent = class extends CustomTypedEvent {
|
|
|
1426
1564
|
super(PropertyChangeEventName, args);
|
|
1427
1565
|
}
|
|
1428
1566
|
};
|
|
1567
|
+
var RouterNavigatingEventName = "navigating";
|
|
1568
|
+
var RouterNavigateEventName = "navigate";
|
|
1569
|
+
var RouterNavigateEvent = class extends CustomTypedEvent {
|
|
1570
|
+
/** @param path Either the destination path alone, or the full navigation args (path, title, referrer). */
|
|
1571
|
+
constructor(path) {
|
|
1572
|
+
super(RouterNavigateEventName, typeof path === "string" ? { path } : path, { cancelable: false, bubbles: false });
|
|
1573
|
+
}
|
|
1574
|
+
};
|
|
1575
|
+
var RouterNavigatingEvent = class extends CustomTypedEvent {
|
|
1576
|
+
/** @param path Destination path about to be navigated to. */
|
|
1577
|
+
constructor(path) {
|
|
1578
|
+
super(RouterNavigatingEventName, path, { cancelable: true, bubbles: false });
|
|
1579
|
+
}
|
|
1580
|
+
};
|
|
1429
1581
|
|
|
1430
1582
|
// packages/core/dist/esm/animations/events.js
|
|
1431
1583
|
var AnimationEvent = class extends CustomTypedEvent {
|
|
@@ -1446,6 +1598,16 @@ var AnimationStartEvent = class extends CustomEvent {
|
|
|
1446
1598
|
|
|
1447
1599
|
// packages/core/dist/esm/animations/tween-service.js
|
|
1448
1600
|
var TweenService = class {
|
|
1601
|
+
/**
|
|
1602
|
+
* Tweens a numeric value from `from` to `to` over `duration` milliseconds, invoking `callback` on every animation frame.
|
|
1603
|
+
* @param from Starting value.
|
|
1604
|
+
* @param to Ending value.
|
|
1605
|
+
* @param duration Tween duration, in milliseconds.
|
|
1606
|
+
* @param delay Delay before the tween starts, in milliseconds (default `0`).
|
|
1607
|
+
* @param easing Easing function applied to the normalized `[0,1]` time (defaults to {@link Easings.linear}).
|
|
1608
|
+
* @param callback Invoked on every frame (and once more with `time === 1.0`) with the normalized time and the current value.
|
|
1609
|
+
* @returns A promise resolved when the tween completes.
|
|
1610
|
+
*/
|
|
1449
1611
|
run(from, to, duration, delay = 0, easing = Easings.linear, callback = null) {
|
|
1450
1612
|
return new Promise((resolve, _) => {
|
|
1451
1613
|
const now = performance && performance.now() || Date.now();
|
|
@@ -1495,9 +1657,15 @@ var Timer = class _Timer {
|
|
|
1495
1657
|
this.#handle = requestAnimationFrame(this._run);
|
|
1496
1658
|
}
|
|
1497
1659
|
#then;
|
|
1660
|
+
/**
|
|
1661
|
+
* Creates and starts a new {@link Timer}.
|
|
1662
|
+
* @param callback Invoked on every tick with the current frame timestamp.
|
|
1663
|
+
* @param fps Target frame rate, in frames per second (default `60`).
|
|
1664
|
+
*/
|
|
1498
1665
|
static run(callback, fps = 60) {
|
|
1499
1666
|
return new _Timer(callback, fps);
|
|
1500
1667
|
}
|
|
1668
|
+
/** Stops the timer, cancelling any pending animation frame. */
|
|
1501
1669
|
stop() {
|
|
1502
1670
|
cancelAnimationFrame(this.#handle);
|
|
1503
1671
|
}
|
|
@@ -1533,6 +1701,7 @@ var FetchResultEventName = "fetchresult";
|
|
|
1533
1701
|
var FetchErrorEventName = "error";
|
|
1534
1702
|
var FetchSuccessEventName = "success";
|
|
1535
1703
|
var Fetcher = class {
|
|
1704
|
+
/** Tests whether a response carries no body (HTTP 204, or an explicit `Content-Length: 0`). */
|
|
1536
1705
|
static isEmpty(r) {
|
|
1537
1706
|
return r.status === 204 || r.headers.get("Content-Length") === "0";
|
|
1538
1707
|
}
|
|
@@ -1542,15 +1711,18 @@ var Fetcher = class {
|
|
|
1542
1711
|
var noop = () => {
|
|
1543
1712
|
};
|
|
1544
1713
|
var StatusCodeError = class extends Error {
|
|
1714
|
+
/** @param statusCode HTTP status code (`500` for network-level failures). @param statusText Status text / error message. */
|
|
1545
1715
|
constructor(statusCode, statusText) {
|
|
1546
1716
|
super(statusText);
|
|
1547
1717
|
this.statusCode = statusCode;
|
|
1548
1718
|
}
|
|
1719
|
+
/** The HTTP status code that caused this error. */
|
|
1549
1720
|
get status() {
|
|
1550
1721
|
return this.statusCode;
|
|
1551
1722
|
}
|
|
1552
1723
|
};
|
|
1553
1724
|
var Response = class {
|
|
1725
|
+
/** @param req The completed `XMLHttpRequest`. @param processTime Elapsed request time, in milliseconds. */
|
|
1554
1726
|
constructor(req, processTime) {
|
|
1555
1727
|
if (!req)
|
|
1556
1728
|
return;
|
|
@@ -1561,20 +1733,25 @@ var Response = class {
|
|
|
1561
1733
|
this._allHeadersRaw = req.getAllResponseHeaders();
|
|
1562
1734
|
this._processTime = processTime;
|
|
1563
1735
|
}
|
|
1736
|
+
/** Elapsed request time, in milliseconds. */
|
|
1564
1737
|
get processTime() {
|
|
1565
1738
|
return this._processTime;
|
|
1566
1739
|
}
|
|
1740
|
+
/** Response headers, parsed into a name/value map (lazily, on first access). */
|
|
1567
1741
|
get headers() {
|
|
1568
1742
|
if (this._headers === void 0 && this._allHeadersRaw)
|
|
1569
1743
|
this._parseHeaders();
|
|
1570
1744
|
return this._headers;
|
|
1571
1745
|
}
|
|
1746
|
+
/** The `Content-Length` response header, parsed as a number. */
|
|
1572
1747
|
get size() {
|
|
1573
1748
|
return +this.headers["Content-Length"];
|
|
1574
1749
|
}
|
|
1750
|
+
/** The `Content-Type` response header. */
|
|
1575
1751
|
get mime() {
|
|
1576
1752
|
return this.headers["Content-Type"];
|
|
1577
1753
|
}
|
|
1754
|
+
/** The `Date` response header, parsed into a `Date`. */
|
|
1578
1755
|
get date() {
|
|
1579
1756
|
return new Date(Date.parse(this.headers["Date"]));
|
|
1580
1757
|
}
|
|
@@ -1590,15 +1767,19 @@ var Response = class {
|
|
|
1590
1767
|
});
|
|
1591
1768
|
this._headers = headers;
|
|
1592
1769
|
}
|
|
1770
|
+
/** HTTP status code. */
|
|
1593
1771
|
get status() {
|
|
1594
1772
|
return this._status;
|
|
1595
1773
|
}
|
|
1774
|
+
/** Raw response body as text. */
|
|
1596
1775
|
get text() {
|
|
1597
1776
|
return this._text;
|
|
1598
1777
|
}
|
|
1778
|
+
/** Response body, typed per `XMLHttpRequest.responseType` (see {@link type}). */
|
|
1599
1779
|
get content() {
|
|
1600
1780
|
return this._body;
|
|
1601
1781
|
}
|
|
1782
|
+
/** The `XMLHttpRequest.responseType` used for this request. */
|
|
1602
1783
|
get type() {
|
|
1603
1784
|
return this._type;
|
|
1604
1785
|
}
|
|
@@ -1786,6 +1967,7 @@ var DragDropInitEventArgsClass = class _DragDropInitEventArgsClass extends DragD
|
|
|
1786
1967
|
this.placeholder = _builder.placeholder;
|
|
1787
1968
|
this.data = _builder.data;
|
|
1788
1969
|
}
|
|
1970
|
+
/** Builds a new {@link DragDropInitEventArgsClass} out of a plain {@link DragDropEventArgs} builder. */
|
|
1789
1971
|
static fromArgs(builder) {
|
|
1790
1972
|
return new _DragDropInitEventArgsClass(Utils.extend({}, builder));
|
|
1791
1973
|
}
|
|
@@ -1796,12 +1978,15 @@ var DragDropEventArgsClass = class _DragDropEventArgsClass extends DragDropEvent
|
|
|
1796
1978
|
this._placeholder = _placeholder;
|
|
1797
1979
|
this._data = _data;
|
|
1798
1980
|
}
|
|
1981
|
+
/** @readonly Gets the element used as a dragging placeholder. */
|
|
1799
1982
|
get placeholder() {
|
|
1800
1983
|
return this._placeholder;
|
|
1801
1984
|
}
|
|
1985
|
+
/** @readonly Gets the logical payload being dragged. */
|
|
1802
1986
|
get data() {
|
|
1803
1987
|
return this._data;
|
|
1804
1988
|
}
|
|
1989
|
+
/** Builds a new {@link DragDropEventArgsClass} out of a plain {@link DragDropEventArgs} builder. */
|
|
1805
1990
|
static fromArgs(builder) {
|
|
1806
1991
|
return new _DragDropEventArgsClass(Utils.extend({}, builder));
|
|
1807
1992
|
}
|
|
@@ -1831,18 +2016,23 @@ var RescaleEventArgsClass = class _RescaleEventArgsClass {
|
|
|
1831
2016
|
constructor(_builder) {
|
|
1832
2017
|
this._builder = _builder;
|
|
1833
2018
|
}
|
|
2019
|
+
/** @readonly Gets the current pointer position. */
|
|
1834
2020
|
get currentPosition() {
|
|
1835
2021
|
return this._builder.currentPosition;
|
|
1836
2022
|
}
|
|
2023
|
+
/** @readonly Gets the rectangle the element is being resized to. */
|
|
1837
2024
|
get targetRect() {
|
|
1838
2025
|
return this._builder.targetRect;
|
|
1839
2026
|
}
|
|
2027
|
+
/** @readonly Gets the element being resized. */
|
|
1840
2028
|
get element() {
|
|
1841
2029
|
return this._builder.element;
|
|
1842
2030
|
}
|
|
2031
|
+
/** @readonly Gets the handle being dragged (see {@link RescaleHandle}). */
|
|
1843
2032
|
get handle() {
|
|
1844
2033
|
return this._builder.handle;
|
|
1845
2034
|
}
|
|
2035
|
+
/** Builds a new {@link RescaleEventArgsClass} out of a plain {@link RescaleEventArgs} builder. */
|
|
1846
2036
|
static fromArgs(builder) {
|
|
1847
2037
|
return new _RescaleEventArgsClass(Utils.extend({}, builder));
|
|
1848
2038
|
}
|
|
@@ -1864,18 +2054,23 @@ var RotateEventArgsClass = class _RotateEventArgsClass {
|
|
|
1864
2054
|
constructor(_builder) {
|
|
1865
2055
|
this._builder = _builder;
|
|
1866
2056
|
}
|
|
2057
|
+
/** @readonly Gets the current pointer position. */
|
|
1867
2058
|
get currentPosition() {
|
|
1868
2059
|
return this._builder.currentPosition;
|
|
1869
2060
|
}
|
|
2061
|
+
/** @readonly Gets the current rotation, in radians. */
|
|
1870
2062
|
get rotation() {
|
|
1871
2063
|
return this._builder.rotation;
|
|
1872
2064
|
}
|
|
2065
|
+
/** @readonly Gets the element being rotated. */
|
|
1873
2066
|
get element() {
|
|
1874
2067
|
return this._builder.element;
|
|
1875
2068
|
}
|
|
2069
|
+
/** @readonly Gets the pivot point the element is rotating around. */
|
|
1876
2070
|
get center() {
|
|
1877
2071
|
return this._builder.center;
|
|
1878
2072
|
}
|
|
2073
|
+
/** Builds a new {@link RotateEventArgsClass} out of a plain {@link RotateEventArgs} builder. */
|
|
1879
2074
|
static fromArgs(builder) {
|
|
1880
2075
|
return new _RotateEventArgsClass(Utils.extend({}, builder));
|
|
1881
2076
|
}
|
|
@@ -1910,6 +2105,7 @@ var SwipeEventArgsClass = class _SwipeEventArgsClass {
|
|
|
1910
2105
|
const isVertical = vertical ?? Math.abs(horizontalspeed) < Math.abs(verticalspeed);
|
|
1911
2106
|
return isVertical;
|
|
1912
2107
|
}
|
|
2108
|
+
/** @readonly Gets the resolved swipe direction (`'up'`, `'down'`, `'left'` or `'right'`). */
|
|
1913
2109
|
get direction() {
|
|
1914
2110
|
return this.#isVertical ? this._builder.verticalspeed > 0 ? "down" : "up" : this._builder.horizontalspeed > 0 ? "right" : "left";
|
|
1915
2111
|
}
|
|
@@ -1940,9 +2136,11 @@ var SwipeEventArgsClass = class _SwipeEventArgsClass {
|
|
|
1940
2136
|
/* v/v0 where v ~ 0 <=> 1% of v0 */
|
|
1941
2137
|
) / inertia;
|
|
1942
2138
|
}
|
|
2139
|
+
/** @readonly Gets the element being swiped. */
|
|
1943
2140
|
get element() {
|
|
1944
2141
|
return this._builder.element;
|
|
1945
2142
|
}
|
|
2143
|
+
/** Builds a new {@link SwipeEventArgsClass} out of a plain {@link SwipeEventArgs} builder. */
|
|
1946
2144
|
static fromArgs(builder) {
|
|
1947
2145
|
return new _SwipeEventArgsClass(Utils.extend({}, builder));
|
|
1948
2146
|
}
|
|
@@ -2025,10 +2223,6 @@ __export(index_components_exports, {
|
|
|
2025
2223
|
RepeaterItemRemoveEventName: () => RepeaterItemRemoveEventName,
|
|
2026
2224
|
ResizeEvent: () => ResizeEvent,
|
|
2027
2225
|
ResizeEventName: () => ResizeEventName,
|
|
2028
|
-
RouterNavigateEvent: () => RouterNavigateEvent,
|
|
2029
|
-
RouterNavigateEventName: () => RouterNavigateEventName,
|
|
2030
|
-
RouterNavigatingEvent: () => RouterNavigatingEvent,
|
|
2031
|
-
RouterNavigatingEventName: () => RouterNavigatingEventName,
|
|
2032
2226
|
ScrollEvent: () => ScrollEvent,
|
|
2033
2227
|
ScrollEventName: () => ScrollEventName,
|
|
2034
2228
|
StateEvent: () => StateEvent,
|
|
@@ -2063,17 +2257,40 @@ var TemplateElement = class extends HTMLElement {
|
|
|
2063
2257
|
var PACEM_BAG = "__pacem__";
|
|
2064
2258
|
var bindingPattern = /^\{\{(.|\n)+\}\}$/;
|
|
2065
2259
|
var CustomElementUtils = class _CustomElementUtils {
|
|
2260
|
+
/** `true` when the platform's `customElements` registry is the Custom Elements polyfill rather than a native implementation. */
|
|
2066
2261
|
static get polyfilling() {
|
|
2067
2262
|
return customElements instanceof window["CustomElementRegistry"];
|
|
2068
2263
|
}
|
|
2264
|
+
/** Converts a camelCase property name to its kebab-case attribute-name equivalent (e.g. `myProp` → `my-prop`). */
|
|
2069
2265
|
static camelToKebab(camelCased) {
|
|
2070
2266
|
return camelCased && camelCased.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
2071
2267
|
}
|
|
2268
|
+
/** Converts a kebab-case attribute name to its camelCase property-name equivalent (e.g. `my-prop` → `myProp`). */
|
|
2072
2269
|
static kebabToCamel(kebabCased) {
|
|
2073
2270
|
return kebabCased && kebabCased.replace(/(-[a-z])/g, (m) => {
|
|
2074
2271
|
return m[1].toUpperCase();
|
|
2075
2272
|
});
|
|
2076
2273
|
}
|
|
2274
|
+
/** Waits for the specified alement to be ready. */
|
|
2275
|
+
static waitForReady(element) {
|
|
2276
|
+
return new Promise((resolve, reject) => {
|
|
2277
|
+
if (Utils.isNull(element)) {
|
|
2278
|
+
reject("Not found.");
|
|
2279
|
+
}
|
|
2280
|
+
if (element.isReady) {
|
|
2281
|
+
resolve();
|
|
2282
|
+
}
|
|
2283
|
+
const callback = () => {
|
|
2284
|
+
element.removeEventListener("load", callback);
|
|
2285
|
+
resolve();
|
|
2286
|
+
};
|
|
2287
|
+
element.addEventListener("load", callback);
|
|
2288
|
+
});
|
|
2289
|
+
}
|
|
2290
|
+
/** Waits for the specified element to be ready, then executes the provided callback. */
|
|
2291
|
+
static whenReady(element, callback) {
|
|
2292
|
+
_CustomElementUtils.waitForReady(element).then(callback);
|
|
2293
|
+
}
|
|
2077
2294
|
static getWatchedProperties(target, includeInherited = true) {
|
|
2078
2295
|
var properties = [];
|
|
2079
2296
|
var chain = target instanceof HTMLElement ? target.constructor : target;
|
|
@@ -2084,9 +2301,16 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2084
2301
|
} while (includeInherited && (chain = Object.getPrototypeOf(chain)));
|
|
2085
2302
|
return properties;
|
|
2086
2303
|
}
|
|
2304
|
+
/** Retrieves a single `@Watch`-decorated property descriptor by name; see {@link getWatchedProperties}. */
|
|
2087
2305
|
static getWatchedProperty(target, name) {
|
|
2088
2306
|
return this.getWatchedProperties(target, true).find((p) => p.name === name);
|
|
2089
2307
|
}
|
|
2308
|
+
/**
|
|
2309
|
+
* Loads a `<script>` tag once (deduplicated by `src`, cached via {@link import}), resolving when it fires `load`.
|
|
2310
|
+
* @param src Script URL.
|
|
2311
|
+
* @param integrity Optional Subresource Integrity hash.
|
|
2312
|
+
* @param crossorigin Whether to set `crossorigin` on the tag.
|
|
2313
|
+
*/
|
|
2090
2314
|
static importjs(src, integrity = null, crossorigin = false) {
|
|
2091
2315
|
var attrs = { "type": "text/javascript", "src": src };
|
|
2092
2316
|
if (!Utils.isNullOrEmpty(integrity))
|
|
@@ -2095,6 +2319,12 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2095
2319
|
Utils.extend(attrs, { "crossorigin": "" });
|
|
2096
2320
|
return _CustomElementUtils.import(src, "script", attrs, document.head || document.getElementsByTagName("head")[0]);
|
|
2097
2321
|
}
|
|
2322
|
+
/**
|
|
2323
|
+
* Loads a `<link rel="stylesheet">` tag once (deduplicated by `src`, cached via {@link import}), resolving when it fires `load`.
|
|
2324
|
+
* @param src Stylesheet URL.
|
|
2325
|
+
* @param integrity Optional Subresource Integrity hash.
|
|
2326
|
+
* @param crossorigin Whether to set `crossorigin="anonymous"` on the tag.
|
|
2327
|
+
*/
|
|
2098
2328
|
static importcss(src, integrity = null, crossorigin = false) {
|
|
2099
2329
|
var attrs = { "rel": "stylesheet", "href": src };
|
|
2100
2330
|
if (!Utils.isNullOrEmpty(integrity))
|
|
@@ -2103,6 +2333,15 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2103
2333
|
Utils.extend(attrs, { "crossorigin": "anonymous" });
|
|
2104
2334
|
return _CustomElementUtils.import(src, "link", attrs, document.head || document.getElementsByTagName("head")[0]);
|
|
2105
2335
|
}
|
|
2336
|
+
/**
|
|
2337
|
+
* Creates (or reuses an already-present, matching) element of `tagName` with the given attributes and
|
|
2338
|
+
* appends it to the DOM, returning a promise that resolves once it loads (or rejects on error). Results
|
|
2339
|
+
* are cached per `key` (under `Utils.core.imports`) so repeated calls with the same key are a no-op.
|
|
2340
|
+
* @param key Cache/dedupe key (typically the resource URL).
|
|
2341
|
+
* @param tagName Tag name of the element to create (e.g. `'script'`, `'link'`).
|
|
2342
|
+
* @param attrs Attributes to set on the element, also used to build a matching CSS selector to detect a pre-existing element.
|
|
2343
|
+
* @param appendTo Node to append the newly created element to, if none was found. Defaults to `document.body`.
|
|
2344
|
+
*/
|
|
2106
2345
|
static import(key2, tagName, attrs, appendTo = document.body) {
|
|
2107
2346
|
const _p = Utils.core;
|
|
2108
2347
|
var _imports = _p["imports"] = _p["imports"] || {};
|
|
@@ -2131,6 +2370,7 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2131
2370
|
}
|
|
2132
2371
|
static {
|
|
2133
2372
|
this.Theme = {
|
|
2373
|
+
/** Downloads the web fonts referenced by the current theme's `--{@link PCSS}-font-*` CSS custom properties, resolving once at least one font face is ready (or after a short timeout). */
|
|
2134
2374
|
importWebFonts() {
|
|
2135
2375
|
function cleanupQuotes(input) {
|
|
2136
2376
|
if (/^('|").*\1$/.test(input)) {
|
|
@@ -2165,6 +2405,14 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2165
2405
|
}
|
|
2166
2406
|
};
|
|
2167
2407
|
}
|
|
2408
|
+
/**
|
|
2409
|
+
* Stores an arbitrary value "attached" to `target` under `name`, in a private, non-enumerable bag
|
|
2410
|
+
* (rather than as a plain expando property) so it doesn't show up in `for...in`/`Object.keys`/JSON
|
|
2411
|
+
* serialization. Setting `value` to `null`/`undefined` removes the entry. See {@link getAttachedPropertyValue}.
|
|
2412
|
+
* @param target Object to attach the value to.
|
|
2413
|
+
* @param name Key under which the value is stored.
|
|
2414
|
+
* @param value Value to store, or `null`/`undefined` to remove the entry.
|
|
2415
|
+
*/
|
|
2168
2416
|
static setAttachedPropertyValue(target, name, value2) {
|
|
2169
2417
|
if (Utils.isNull(target))
|
|
2170
2418
|
return;
|
|
@@ -2180,9 +2428,16 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2180
2428
|
else
|
|
2181
2429
|
bag[name] = value2;
|
|
2182
2430
|
}
|
|
2431
|
+
/** Removes a value previously stored via {@link setAttachedPropertyValue}. */
|
|
2183
2432
|
static deleteAttachedPropertyValue(target, name) {
|
|
2184
2433
|
_CustomElementUtils.setAttachedPropertyValue(target, name, void 0);
|
|
2185
2434
|
}
|
|
2435
|
+
/**
|
|
2436
|
+
* Reads a value previously stored via {@link setAttachedPropertyValue}.
|
|
2437
|
+
* @param target Object the value is attached to.
|
|
2438
|
+
* @param name Key the value is stored under.
|
|
2439
|
+
* @param ensureValue If provided and no value is currently stored, this value is stored and returned (lazy-initialization).
|
|
2440
|
+
*/
|
|
2186
2441
|
static getAttachedPropertyValue(target, name, ensureValue) {
|
|
2187
2442
|
const propKey = Object.getOwnPropertyDescriptor(target, PACEM_BAG), bag = propKey && propKey.value;
|
|
2188
2443
|
if (Utils.isNull(bag && bag[name]) && !Utils.isNull(ensureValue)) {
|
|
@@ -2227,6 +2482,17 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2227
2482
|
}
|
|
2228
2483
|
return { target: { value: ref, name }, parent: { value: parent || scope, path: path.substring(0, ndx) }, root: { value: root2, property: core } };
|
|
2229
2484
|
}
|
|
2485
|
+
/**
|
|
2486
|
+
* Writes `value` at the given dotted `path`, rooted at `element` (see {@link resolvePath}), triggering
|
|
2487
|
+
* the appropriate `propertychange` notification. For paths nested more than one level deep (and not
|
|
2488
|
+
* targeting an `HTMLElement`, which fires change notifications autonomously), the whole root property
|
|
2489
|
+
* is cloned, mutated and reassigned so that a `propertychange` fires with meaningful old/new values -
|
|
2490
|
+
* a plain nested assignment wouldn't otherwise be observed. Repeater-bound `item` paths are special-cased
|
|
2491
|
+
* to update the owning {@link Repeater}'s `datasource` array in place.
|
|
2492
|
+
* @param element Root element the path is resolved against.
|
|
2493
|
+
* @param path Dotted path (e.g. `'foo.bar[0].baz'`) to the target property.
|
|
2494
|
+
* @param value New value to assign.
|
|
2495
|
+
*/
|
|
2230
2496
|
static set(element, path, value2) {
|
|
2231
2497
|
var obj2 = _CustomElementUtils.resolvePath(path, element);
|
|
2232
2498
|
var current = obj2.target.value;
|
|
@@ -2246,6 +2512,7 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2246
2512
|
}
|
|
2247
2513
|
}
|
|
2248
2514
|
}
|
|
2515
|
+
/** Reads the value at the given dotted `path`, rooted at `element`; see {@link resolvePath}. */
|
|
2249
2516
|
static get(element, path) {
|
|
2250
2517
|
var obj2 = _CustomElementUtils.resolvePath(path, element);
|
|
2251
2518
|
return obj2 && obj2.target && obj2.target.value;
|
|
@@ -2262,11 +2529,26 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2262
2529
|
} while (el != null && (el != (retval = element.ownerDocument) || el instanceof HTMLElement && (retval = el.shadowRoot) != null));
|
|
2263
2530
|
return retval;
|
|
2264
2531
|
}
|
|
2532
|
+
/**
|
|
2533
|
+
* Finds the `Document` or `ShadowRoot` that `element` belongs to - used as the root for resolving
|
|
2534
|
+
* scoped binding expressions (e.g. `$document`/`$host` lookups). Falls back to the previously-attached
|
|
2535
|
+
* scope value (see `INSTANCE_SCOPE_VAR`, set on `connectedCallback`) when `element` is currently
|
|
2536
|
+
* disconnected, and to a legacy manual-walk implementation as a last resort (needed under Jasmine tests,
|
|
2537
|
+
* where `element.isConnected` never reports `true`).
|
|
2538
|
+
* @param element Element to resolve the containing document/shadow-root scope for.
|
|
2539
|
+
*/
|
|
2265
2540
|
static findScopeContext(element) {
|
|
2266
2541
|
let retval = element.isConnected ? element.getRootNode() : _CustomElementUtils.getAttachedPropertyValue(element, INSTANCE_SCOPE_VAR);
|
|
2267
2542
|
return retval ?? /* in Jasmine TESTS `element.isConnected` always returns false (attached to #document-fragment) */
|
|
2268
2543
|
_CustomElementUtils._findScopeContextLegacy(element);
|
|
2269
2544
|
}
|
|
2545
|
+
/**
|
|
2546
|
+
* Walks up from `element` (crossing shadow-root boundaries via the host element) looking for the
|
|
2547
|
+
* first ancestor matching `predicate`.
|
|
2548
|
+
* @param element Element to start the upward search from.
|
|
2549
|
+
* @param predicate Test invoked (as `this`-bound and argument-passed) against each ancestor.
|
|
2550
|
+
* @returns The first matching ancestor, or `undefined` if none matches.
|
|
2551
|
+
*/
|
|
2270
2552
|
static findAncestor(element, predicate) {
|
|
2271
2553
|
let el = element;
|
|
2272
2554
|
let retval;
|
|
@@ -2280,12 +2562,20 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2280
2562
|
}
|
|
2281
2563
|
return retval;
|
|
2282
2564
|
}
|
|
2565
|
+
/** Finds the nearest ancestor "shell" element - matching `.{@link PCSS}-body` - or falls back to `document.body`; see {@link findAncestor}. */
|
|
2283
2566
|
static findAncestorShell(element) {
|
|
2284
2567
|
return _CustomElementUtils.findAncestor(element, (el) => Utils.is(el, `.${PCSS}-body`) || el === document.body);
|
|
2285
2568
|
}
|
|
2569
|
+
/** Finds the nearest ancestor that is an instance of `ctor`; see {@link findAncestor}. */
|
|
2286
2570
|
static findAncestorOfType(element, ctor) {
|
|
2287
2571
|
return _CustomElementUtils.findAncestor(element, (el) => el instanceof ctor);
|
|
2288
2572
|
}
|
|
2573
|
+
/**
|
|
2574
|
+
* Collects the descendants of `element` matching `predicate`, via a `TreeWalker` over element nodes.
|
|
2575
|
+
* @param element Root element to search from (exclusive - the walker starts on its descendants).
|
|
2576
|
+
* @param predicate Test invoked against each descendant element.
|
|
2577
|
+
* @param firstOnly When `true`, stops and returns as soon as one match is found.
|
|
2578
|
+
*/
|
|
2289
2579
|
static findDescendants(element, predicate, firstOnly = false) {
|
|
2290
2580
|
const walker = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT);
|
|
2291
2581
|
var retval = [];
|
|
@@ -2300,10 +2590,16 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2300
2590
|
}
|
|
2301
2591
|
return retval;
|
|
2302
2592
|
}
|
|
2593
|
+
/** Finds the first descendant of `element` matching `predicate`, or `undefined` if none matches; see {@link findDescendants}. */
|
|
2303
2594
|
static findFirstDescendant(element, predicate) {
|
|
2304
2595
|
const any = _CustomElementUtils.findDescendants(element, predicate, true);
|
|
2305
2596
|
return Utils.isNullOrEmpty(any) ? void 0 : any[0];
|
|
2306
2597
|
}
|
|
2598
|
+
/**
|
|
2599
|
+
* Queries the whole document for elements matching `selector`, additionally filtered by `filter`.
|
|
2600
|
+
* @param selector CSS selector to query for. Defaults to `'[pacem]'` (every Pacem custom element, which all carry that attribute once connected).
|
|
2601
|
+
* @param filter Extra predicate applied to each matched element. Defaults to accepting everything.
|
|
2602
|
+
*/
|
|
2307
2603
|
static findAll(selector = "[pacem]", filter = (e) => true) {
|
|
2308
2604
|
const retval = [];
|
|
2309
2605
|
document.querySelectorAll(selector).forEach((e, i, arr2) => {
|
|
@@ -2363,6 +2659,14 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2363
2659
|
} while (el != null);
|
|
2364
2660
|
return retval;
|
|
2365
2661
|
}
|
|
2662
|
+
/**
|
|
2663
|
+
* Tags every element/document-fragment node inside `template`'s content (that isn't already tagged)
|
|
2664
|
+
* with `host` under `INSTANCE_HOST_VAR`, so that once cloned and inserted into the DOM, binding
|
|
2665
|
+
* expressions in that fragment can resolve back to the custom element instance ("host") that owns
|
|
2666
|
+
* this template. See {@link findHostContext}.
|
|
2667
|
+
* @param host The custom element instance whose template this is.
|
|
2668
|
+
* @param template Template whose content's descendants should be tagged.
|
|
2669
|
+
*/
|
|
2366
2670
|
static assignHostContext(host, template) {
|
|
2367
2671
|
const walker = document.createTreeWalker(template.content, NodeFilter.SHOW_ELEMENT + /* traverse templates' content */
|
|
2368
2672
|
NodeFilter.SHOW_DOCUMENT_FRAGMENT);
|
|
@@ -2373,6 +2677,13 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2373
2677
|
}
|
|
2374
2678
|
}
|
|
2375
2679
|
}
|
|
2680
|
+
/**
|
|
2681
|
+
* Walks up from `element` looking for the nearest ancestor (inclusive) tagged with a host reference
|
|
2682
|
+
* via {@link assignHostContext}; this is the custom element instance whose template produced `element`,
|
|
2683
|
+
* used to resolve `$host`/scope references in binding expressions. Returns `undefined` (with a console
|
|
2684
|
+
* warning) if `element` is disconnected or isn't part of any templated component.
|
|
2685
|
+
* @param element Element to resolve the owning host for.
|
|
2686
|
+
*/
|
|
2376
2687
|
static findHostContext(element) {
|
|
2377
2688
|
let el = element;
|
|
2378
2689
|
let retval;
|
|
@@ -2390,9 +2701,11 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2390
2701
|
logFn(`Element "${element.constructor.name}" isn't a descendant of a templated component.`);
|
|
2391
2702
|
return retval;
|
|
2392
2703
|
}
|
|
2704
|
+
/** Tests whether an attribute's raw string value has binding-expression syntax (`{{ ... }}`). */
|
|
2393
2705
|
static isBindingAttribute(attr) {
|
|
2394
2706
|
return bindingPattern.test(attr);
|
|
2395
2707
|
}
|
|
2708
|
+
/** Strips the `{{ }}` delimiters off a binding attribute's raw value, returning the bare expression text. Throws if `attr` isn't a valid binding attribute; see {@link isBindingAttribute}. */
|
|
2396
2709
|
static extractBindingAttributeExpression(attr) {
|
|
2397
2710
|
if (_CustomElementUtils.isBindingAttribute(attr)) {
|
|
2398
2711
|
return attr.substr(2, attr.length - 4);
|
|
@@ -2400,6 +2713,13 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2400
2713
|
throw `Invalid attribute: incorrect binding syntax.`;
|
|
2401
2714
|
}
|
|
2402
2715
|
}
|
|
2716
|
+
/**
|
|
2717
|
+
* Parses a `{{ ... }}` binding attribute value into an {@link Expression}, recognizing the optional
|
|
2718
|
+
* trailing `, twoway` / `, once` modifier and stamping it onto the expression's dependencies (`twoway`
|
|
2719
|
+
* only applies when the expression has exactly one dependency that itself allows two-way binding).
|
|
2720
|
+
* @param attr Raw binding attribute value, including the `{{ }}` delimiters.
|
|
2721
|
+
* @param element Element the expression is evaluated/bound against (used to resolve scope references).
|
|
2722
|
+
*/
|
|
2403
2723
|
static parseBindingAttribute(attr, element) {
|
|
2404
2724
|
let expression = _CustomElementUtils.extractBindingAttributeExpression(attr);
|
|
2405
2725
|
const arr2 = /,\s*(twoway|once)\s*$/.exec(expression), mode = arr2 && arr2.length > 1 && arr2[1];
|
|
@@ -2419,6 +2739,14 @@ var CustomElementUtils = class _CustomElementUtils {
|
|
|
2419
2739
|
});
|
|
2420
2740
|
return expr;
|
|
2421
2741
|
}
|
|
2742
|
+
/**
|
|
2743
|
+
* Defines an own property `name` on `o` with `attributes`, unless `o` already has an own property
|
|
2744
|
+
* descriptor for that name (in which case the existing descriptor is returned untouched).
|
|
2745
|
+
* @param o Object to define the property on.
|
|
2746
|
+
* @param name Property name.
|
|
2747
|
+
* @param attributes Property descriptor to apply if the property isn't already defined.
|
|
2748
|
+
* @returns The (possibly pre-existing) property descriptor.
|
|
2749
|
+
*/
|
|
2422
2750
|
static ensureMember(o, name, attributes) {
|
|
2423
2751
|
let original = Object.getOwnPropertyDescriptor(o, name);
|
|
2424
2752
|
if (original != void 0)
|
|
@@ -2493,6 +2821,15 @@ var Repeater = class {
|
|
|
2493
2821
|
}
|
|
2494
2822
|
};
|
|
2495
2823
|
var RepeaterItem = class _RepeaterItem {
|
|
2824
|
+
/**
|
|
2825
|
+
* Seeks upwards from `element` (previous siblings, then parent, repeated) for the nearest ancestor
|
|
2826
|
+
* placeholder tagged as a {@link RepeaterItem}, skipping `upLevels` matches before returning one -
|
|
2827
|
+
* this is how deeply-nested repeaters resolve which repetition (of which ancestor repeater) an
|
|
2828
|
+
* expression's `^item`/`^^item`/... token refers to.
|
|
2829
|
+
* @param element Element to start the upward search from.
|
|
2830
|
+
* @param upLevels 0-based number of matching ancestors to skip before returning one (`0` = nearest).
|
|
2831
|
+
* @param logFn Called with a warning message if no match is found and `element` is connected to the DOM.
|
|
2832
|
+
*/
|
|
2496
2833
|
static findUpwards(element, upLevels = 0, logFn = console.warn) {
|
|
2497
2834
|
if (Utils.isNull(element) || element.localName === "template" || element instanceof /* template-like element? */
|
|
2498
2835
|
TemplateElement) {
|
|
@@ -2506,16 +2843,20 @@ var RepeaterItem = class _RepeaterItem {
|
|
|
2506
2843
|
}
|
|
2507
2844
|
return item;
|
|
2508
2845
|
}
|
|
2846
|
+
/** Tests whether `node` is the placeholder of some {@link RepeaterItem}. */
|
|
2509
2847
|
static isRepeaterItem(node) {
|
|
2510
2848
|
return !Utils.isNull(GET_VAL(node, REPEATERITEM_PLACEHOLDER));
|
|
2511
2849
|
}
|
|
2850
|
+
/** Retrieves the {@link RepeaterItem} attached to `node`, if `node` is a repeater-item placeholder; see {@link isRepeaterItem}. */
|
|
2512
2851
|
static getRepeaterItem(node) {
|
|
2513
2852
|
return GET_VAL(node, REPEATERITEM_PLACEHOLDER);
|
|
2514
2853
|
}
|
|
2854
|
+
/** @param _placeholder DOM node (typically a comment) that stands in for this repetition and gets tagged so {@link getRepeaterItem} can retrieve this instance back from it. */
|
|
2515
2855
|
constructor(_placeholder) {
|
|
2516
2856
|
this._placeholder = _placeholder;
|
|
2517
2857
|
SET_VAL(_placeholder, REPEATERITEM_PLACEHOLDER, this);
|
|
2518
2858
|
}
|
|
2859
|
+
/** The DOM placeholder node standing in for this repetition. */
|
|
2519
2860
|
get placeholder() {
|
|
2520
2861
|
return this._placeholder;
|
|
2521
2862
|
}
|
|
@@ -2531,27 +2872,38 @@ var Expression = class _Expression {
|
|
|
2531
2872
|
this._pending = false;
|
|
2532
2873
|
this._independent = false;
|
|
2533
2874
|
}
|
|
2875
|
+
/** The resolved property dependencies (element + property + path) this expression re-evaluates on change. Empty for {@link independent} expressions. */
|
|
2534
2876
|
get dependencies() {
|
|
2535
2877
|
return this._dependencies;
|
|
2536
2878
|
}
|
|
2879
|
+
/** The compiled function body used by {@link evaluate}/{@link evaluateAsync} (a `return <expr>;` statement, guarded by a try/catch). */
|
|
2537
2880
|
get functionBody() {
|
|
2538
2881
|
return this._fnBody;
|
|
2539
2882
|
}
|
|
2883
|
+
/** The compiled function body used by {@link evaluatePlus} (a bare, non-`return`ing statement, guarded by a try/catch) - suited for expressions run for their side effects, e.g. `on-*` event handlers. */
|
|
2540
2884
|
get voidBody() {
|
|
2541
2885
|
return this._voidBody;
|
|
2542
2886
|
}
|
|
2887
|
+
/**
|
|
2888
|
+
* `true` when this expression couldn't be resolved against a scope yet (the element wasn't connected
|
|
2889
|
+
* to a document/shadow-root at parse time) - a shared, inert placeholder singleton returned by
|
|
2890
|
+
* {@link parse} in that case; evaluating it is a no-op. Callers should re-parse once the element is ready.
|
|
2891
|
+
*/
|
|
2543
2892
|
get pending() {
|
|
2544
2893
|
return this._pending;
|
|
2545
2894
|
}
|
|
2895
|
+
/** `true` when the expression has no dependencies (a constant) and can be evaluated immediately, without a resolved scope. */
|
|
2546
2896
|
get independent() {
|
|
2547
2897
|
return this._independent;
|
|
2548
2898
|
}
|
|
2899
|
+
/** Evaluates the expression and returns its result, swallowing any runtime error (returning `undefined`). */
|
|
2549
2900
|
evaluate() {
|
|
2550
2901
|
if (!this._fn) {
|
|
2551
2902
|
this._fn = new Function("$pacem", CONTEXT_PREFIX, this._fnBody);
|
|
2552
2903
|
}
|
|
2553
2904
|
return this._fn.apply(null, [Utils.core, this._args]);
|
|
2554
2905
|
}
|
|
2906
|
+
/** Promise-wrapped variant of {@link evaluate} (resolves synchronously with the same result - kept for call-site uniformity with genuinely async evaluation paths). */
|
|
2555
2907
|
evaluateAsync() {
|
|
2556
2908
|
const deferred = DeferPromise.defer();
|
|
2557
2909
|
if (!this._fn) {
|
|
@@ -2560,6 +2912,12 @@ var Expression = class _Expression {
|
|
|
2560
2912
|
deferred.resolve(this._fn.apply(null, [Utils.core, this._args]));
|
|
2561
2913
|
return deferred.promise;
|
|
2562
2914
|
}
|
|
2915
|
+
/**
|
|
2916
|
+
* Executes the expression for its side effects (using {@link voidBody}, so no value is returned),
|
|
2917
|
+
* with extra named variables merged into scope alongside the expression's own dependencies -
|
|
2918
|
+
* used to expose e.g. `$event` to `on-*` event handler expressions.
|
|
2919
|
+
* @param args Extra name/value pairs made available to the expression, in addition to its resolved dependencies.
|
|
2920
|
+
*/
|
|
2563
2921
|
evaluatePlus(args = {}) {
|
|
2564
2922
|
if (!this._fn) {
|
|
2565
2923
|
let argNames = [CONTEXT_PREFIX];
|
|
@@ -2586,6 +2944,15 @@ var Expression = class _Expression {
|
|
|
2586
2944
|
}
|
|
2587
2945
|
return _Expression._pendingExpression;
|
|
2588
2946
|
}
|
|
2947
|
+
/**
|
|
2948
|
+
* Parses a binding expression's source text (the bare content of a `{{ ... }}` attribute, without the
|
|
2949
|
+
* delimiters - see {@link CustomElementUtils.extractBindingAttributeExpression}) into an {@link Expression},
|
|
2950
|
+
* resolving its special tokens against `element`'s scope (see {@link CustomElementUtils.findScopeContext}).
|
|
2951
|
+
* Throws if the expression matches the unsafe-code guard (`new`, `window.`, `document.`, `eval(`).
|
|
2952
|
+
* @param expression Bare expression source text.
|
|
2953
|
+
* @param element Element the expression is bound to; provides the scope special tokens (`:host.`, `#id`, `^item`, ...) resolve against.
|
|
2954
|
+
* @returns A constant expression if it has no dependencies; a shared pending placeholder if `element` isn't attached to a scope yet; otherwise a fully resolved expression.
|
|
2955
|
+
*/
|
|
2589
2956
|
static parse(expression, element) {
|
|
2590
2957
|
var context = CustomElementUtils.findScopeContext(element);
|
|
2591
2958
|
var args = { "$this": element };
|
|
@@ -3973,6 +4340,10 @@ var PacemAdapter = class extends PacemElement {
|
|
|
3973
4340
|
const current = this._getAvailable();
|
|
3974
4341
|
return ndx === this._getNextAvailable(current);
|
|
3975
4342
|
}
|
|
4343
|
+
/**
|
|
4344
|
+
* Sets the master's index to the closest available item to the provided one.
|
|
4345
|
+
* @param ndx Desired index
|
|
4346
|
+
*/
|
|
3976
4347
|
select(ndx) {
|
|
3977
4348
|
this._element.index = this._getAvailable(ndx);
|
|
3978
4349
|
}
|
|
@@ -4096,6 +4467,10 @@ var PacemBroadcastChannelProxyElement = class PacemBroadcastChannelProxyElement2
|
|
|
4096
4467
|
this._disposeChannel();
|
|
4097
4468
|
super.disconnectedCallback();
|
|
4098
4469
|
}
|
|
4470
|
+
/**
|
|
4471
|
+
* Posts a message through the channel.
|
|
4472
|
+
* @param message Message to send; defaults to the current `message` property
|
|
4473
|
+
*/
|
|
4099
4474
|
send(message = this.message) {
|
|
4100
4475
|
if (this.disabled) {
|
|
4101
4476
|
return;
|
|
@@ -4161,9 +4536,11 @@ var PacemBrowserDetectElement = class PacemBrowserDetectElement2 extends PacemEv
|
|
|
4161
4536
|
}
|
|
4162
4537
|
#browser;
|
|
4163
4538
|
#version;
|
|
4539
|
+
/** @readonly Gets the detected browser name. */
|
|
4164
4540
|
get browser() {
|
|
4165
4541
|
return this.#browser;
|
|
4166
4542
|
}
|
|
4543
|
+
/** @readonly Gets the detected browser version. */
|
|
4167
4544
|
get version() {
|
|
4168
4545
|
return this.#version;
|
|
4169
4546
|
}
|
|
@@ -4221,15 +4598,22 @@ var Storage = class {
|
|
|
4221
4598
|
storage = this._getStorage(!persistent);
|
|
4222
4599
|
storage.removeItem(name);
|
|
4223
4600
|
}
|
|
4601
|
+
/**
|
|
4602
|
+
* Retrieves a previously stored value by `name`, checking session storage first, then local storage.
|
|
4603
|
+
* Returns `null` if not found, or if found but past its expiration.
|
|
4604
|
+
* @param name The unique key.
|
|
4605
|
+
*/
|
|
4224
4606
|
getPropertyValue(name) {
|
|
4225
4607
|
return this._parseValue(this._getStorage(false), name) || this._parseValue(this._getStorage(true), name);
|
|
4226
4608
|
}
|
|
4609
|
+
/** Clears both session and local storage entirely. */
|
|
4227
4610
|
clear() {
|
|
4228
4611
|
var storage = this._getStorage(true);
|
|
4229
4612
|
storage.clear();
|
|
4230
4613
|
storage = this._getStorage(false);
|
|
4231
4614
|
storage.clear();
|
|
4232
4615
|
}
|
|
4616
|
+
/** Removes a single entry by `name` from both session and local storage. */
|
|
4233
4617
|
removeProperty(name) {
|
|
4234
4618
|
var storage = this._getStorage(true);
|
|
4235
4619
|
storage.removeItem(name);
|
|
@@ -4882,6 +5266,7 @@ var PacemHistoryElement = class PacemHistoryElement2 extends PacemEventTarget {
|
|
|
4882
5266
|
this.#history = new HistoryService(val, this.maxlength);
|
|
4883
5267
|
}
|
|
4884
5268
|
}
|
|
5269
|
+
/** Moves the state forward one step, if `canRedo` is `true`. */
|
|
4885
5270
|
redo() {
|
|
4886
5271
|
const h = this.#history;
|
|
4887
5272
|
if (!Utils.isNull(h)) {
|
|
@@ -4890,6 +5275,7 @@ var PacemHistoryElement = class PacemHistoryElement2 extends PacemEventTarget {
|
|
|
4890
5275
|
this._synchronize("redo");
|
|
4891
5276
|
}
|
|
4892
5277
|
}
|
|
5278
|
+
/** Clears the history stack, keeping only the current state. */
|
|
4893
5279
|
reset() {
|
|
4894
5280
|
const h = this.#history;
|
|
4895
5281
|
if (!Utils.isNull(h)) {
|
|
@@ -4898,6 +5284,7 @@ var PacemHistoryElement = class PacemHistoryElement2 extends PacemEventTarget {
|
|
|
4898
5284
|
this._synchronize("reset");
|
|
4899
5285
|
}
|
|
4900
5286
|
}
|
|
5287
|
+
/** Moves the state back one step, if `canUndo` is `true`. */
|
|
4901
5288
|
undo() {
|
|
4902
5289
|
const h = this.#history;
|
|
4903
5290
|
if (!Utils.isNull(h)) {
|
|
@@ -5445,6 +5832,7 @@ var PacemRepeaterElement = PacemRepeaterElement_1 = class PacemRepeaterElement2
|
|
|
5445
5832
|
this._databind();
|
|
5446
5833
|
};
|
|
5447
5834
|
}
|
|
5835
|
+
/** Removes the rendered item at the given index. */
|
|
5448
5836
|
removeItem(index) {
|
|
5449
5837
|
this._removeItems(index, index);
|
|
5450
5838
|
}
|
|
@@ -5472,6 +5860,7 @@ var PacemRepeaterElement = PacemRepeaterElement_1 = class PacemRepeaterElement2
|
|
|
5472
5860
|
item.remove();
|
|
5473
5861
|
}
|
|
5474
5862
|
}
|
|
5863
|
+
/** Forces a full re-render of the items against the current `datasource`. */
|
|
5475
5864
|
databind() {
|
|
5476
5865
|
this._databind();
|
|
5477
5866
|
}
|
|
@@ -5750,6 +6139,7 @@ var PacemResizeElement = class PacemResizeElement2 extends PacemEventTarget {
|
|
|
5750
6139
|
this._dispatchResize();
|
|
5751
6140
|
}
|
|
5752
6141
|
}
|
|
6142
|
+
/** @readonly Gets the last measured size (and position, if `watchPosition` is set) of the observed target. */
|
|
5753
6143
|
get currentSize() {
|
|
5754
6144
|
var args = { height: this._previousHeight, width: this._previousWidth };
|
|
5755
6145
|
if (this.watchPosition) {
|
|
@@ -5787,30 +6177,31 @@ var __decorate24 = function(decorators, target, key2, desc) {
|
|
|
5787
6177
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key2, r) : d(target, key2)) || r;
|
|
5788
6178
|
return c > 3 && r && Object.defineProperty(target, key2, r), r;
|
|
5789
6179
|
};
|
|
5790
|
-
var RouterNavigatingEventName = "navigating";
|
|
5791
|
-
var RouterNavigateEventName = "navigate";
|
|
5792
|
-
var RouterNavigateEvent = class extends CustomTypedEvent {
|
|
5793
|
-
constructor(path) {
|
|
5794
|
-
super(RouterNavigateEventName, typeof path === "string" ? { path } : path, { cancelable: false, bubbles: false });
|
|
5795
|
-
}
|
|
5796
|
-
};
|
|
5797
|
-
var RouterNavigatingEvent = class extends CustomTypedEvent {
|
|
5798
|
-
constructor(path) {
|
|
5799
|
-
super(RouterNavigatingEventName, path, { cancelable: true, bubbles: false });
|
|
5800
|
-
}
|
|
5801
|
-
};
|
|
5802
6180
|
var CHECK_PATTERN = /^([\w\.]:)?\/\/[^\/]+/;
|
|
5803
6181
|
var PacemRouterElement = class PacemRouterElement2 extends PacemEventTarget {
|
|
5804
6182
|
constructor() {
|
|
5805
6183
|
super(...arguments);
|
|
6184
|
+
this._onScroll = (e) => {
|
|
6185
|
+
const scrollRestoration = this.scrollRestoration ?? true;
|
|
6186
|
+
if (!scrollRestoration) {
|
|
6187
|
+
return;
|
|
6188
|
+
}
|
|
6189
|
+
const y = Math.floor(Utils.scrollTop);
|
|
6190
|
+
window.history.replaceState(Utils.extend({}, window.history.state, { $scrollY: y }), document.title);
|
|
6191
|
+
};
|
|
5806
6192
|
this._onPopState = (evt) => {
|
|
5807
6193
|
if (!Utils.isNull(evt.state) && !this.#cancelingNavigation) {
|
|
5808
|
-
|
|
6194
|
+
const state = evt.state;
|
|
6195
|
+
this.path = state.$path;
|
|
5809
6196
|
}
|
|
5810
6197
|
};
|
|
5811
6198
|
}
|
|
5812
6199
|
#cancelingNavigation;
|
|
5813
6200
|
#template;
|
|
6201
|
+
/**
|
|
6202
|
+
* Merges the provided partial state into the current one and returns the resulting parsed {@link RouterState}, without navigating.
|
|
6203
|
+
* @param state Piece of new state to be merged
|
|
6204
|
+
*/
|
|
5814
6205
|
parseState(state = {}) {
|
|
5815
6206
|
const path = this._stringifyMergedState(state);
|
|
5816
6207
|
const segments = this._segmentateUrl(path);
|
|
@@ -5848,12 +6239,13 @@ var PacemRouterElement = class PacemRouterElement2 extends PacemEventTarget {
|
|
|
5848
6239
|
this.path = from;
|
|
5849
6240
|
return;
|
|
5850
6241
|
}
|
|
5851
|
-
|
|
6242
|
+
const newState = !poppingState ? Utils.extend({ $scrollY: 0 }, state) : Utils.extend({ $scrollY: 0 }, window.history.state, state);
|
|
6243
|
+
this.state = newState;
|
|
6244
|
+
window.history.scrollRestoration = this.scrollRestoration ?? true ? "manual" : "auto";
|
|
5852
6245
|
if (poppingState) {
|
|
5853
|
-
window.history.
|
|
5854
|
-
window.history.replaceState(state, title);
|
|
6246
|
+
window.history.replaceState(newState, document.title);
|
|
5855
6247
|
} else {
|
|
5856
|
-
window.history.pushState(
|
|
6248
|
+
window.history.pushState(newState, title, path);
|
|
5857
6249
|
}
|
|
5858
6250
|
if (!Utils.isNullOrEmpty(title)) {
|
|
5859
6251
|
document.title = title;
|
|
@@ -5878,6 +6270,7 @@ var PacemRouterElement = class PacemRouterElement2 extends PacemEventTarget {
|
|
|
5878
6270
|
connectedCallback() {
|
|
5879
6271
|
super.connectedCallback();
|
|
5880
6272
|
window.addEventListener("popstate", this._onPopState, false);
|
|
6273
|
+
document.addEventListener("scroll", this._onScroll, false);
|
|
5881
6274
|
}
|
|
5882
6275
|
viewActivatedCallback() {
|
|
5883
6276
|
super.viewActivatedCallback();
|
|
@@ -5887,6 +6280,7 @@ var PacemRouterElement = class PacemRouterElement2 extends PacemEventTarget {
|
|
|
5887
6280
|
}
|
|
5888
6281
|
}
|
|
5889
6282
|
disconnectedCallback() {
|
|
6283
|
+
document.removeEventListener("scroll", this._onScroll, false);
|
|
5890
6284
|
window.removeEventListener("popstate", this._onPopState, false);
|
|
5891
6285
|
super.disconnectedCallback();
|
|
5892
6286
|
}
|
|
@@ -5940,6 +6334,9 @@ __decorate24([
|
|
|
5940
6334
|
__decorate24([
|
|
5941
6335
|
Watch({ emit: false, converter: PropertyConverters.String })
|
|
5942
6336
|
], PacemRouterElement.prototype, "path", void 0);
|
|
6337
|
+
__decorate24([
|
|
6338
|
+
Watch({ emit: false, reflectBack: true, converter: PropertyConverters.Boolean })
|
|
6339
|
+
], PacemRouterElement.prototype, "scrollRestoration", void 0);
|
|
5943
6340
|
PacemRouterElement = __decorate24([
|
|
5944
6341
|
CustomElement({ tagName: P + "-router" })
|
|
5945
6342
|
], PacemRouterElement);
|
|
@@ -6089,6 +6486,10 @@ var PacemServiceWorkerProxyElement = class PacemServiceWorkerProxyElement2 exten
|
|
|
6089
6486
|
}
|
|
6090
6487
|
});
|
|
6091
6488
|
}
|
|
6489
|
+
/**
|
|
6490
|
+
* Unsubscribes from push notifications.
|
|
6491
|
+
* @param subscription Subscription to cancel; defaults to the current `pushSubscription`
|
|
6492
|
+
*/
|
|
6092
6493
|
unsubscribe(subscription = this.pushSubscription) {
|
|
6093
6494
|
return new Promise((resolve, reject) => {
|
|
6094
6495
|
if (!Utils.isNull(subscription)) {
|
|
@@ -6104,6 +6505,10 @@ var PacemServiceWorkerProxyElement = class PacemServiceWorkerProxyElement2 exten
|
|
|
6104
6505
|
}
|
|
6105
6506
|
});
|
|
6106
6507
|
}
|
|
6508
|
+
/**
|
|
6509
|
+
* Subscribes to push notifications through the registered service worker.
|
|
6510
|
+
* @param publicKey VAPID public key (base64url or raw bytes); defaults to `publicKey`
|
|
6511
|
+
*/
|
|
6107
6512
|
subscribe(publicKey = this.publicKey) {
|
|
6108
6513
|
return new Promise((resolve, reject) => {
|
|
6109
6514
|
if (typeof publicKey === "string") {
|
|
@@ -6482,6 +6887,7 @@ var PacemTweenElement = class PacemTweenElement2 extends PacemEventTarget {
|
|
|
6482
6887
|
this._animate();
|
|
6483
6888
|
}
|
|
6484
6889
|
}
|
|
6890
|
+
/** Starts the animation programmatically and returns a promise resolved once it completes. */
|
|
6485
6891
|
run() {
|
|
6486
6892
|
return this._animate();
|
|
6487
6893
|
}
|
|
@@ -6658,6 +7064,10 @@ var PacemWebWorkerProxyElement = class PacemWebWorkerProxyElement2 extends Pacem
|
|
|
6658
7064
|
this._disposeWorker();
|
|
6659
7065
|
super.disconnectedCallback();
|
|
6660
7066
|
}
|
|
7067
|
+
/**
|
|
7068
|
+
* Posts a message to the worker.
|
|
7069
|
+
* @param message Message to send; defaults to the current `message` property
|
|
7070
|
+
*/
|
|
6661
7071
|
send(message = this.message) {
|
|
6662
7072
|
if (this.disabled) {
|
|
6663
7073
|
return;
|
|
@@ -6707,6 +7117,10 @@ import { Matrix2D } from "@pacem/pacem-foundation";
|
|
|
6707
7117
|
// packages/core/dist/esm/components/behavior.js
|
|
6708
7118
|
var PacemBehavior = class extends PacemEventTarget {
|
|
6709
7119
|
#items = /* @__PURE__ */ new WeakSet();
|
|
7120
|
+
/**
|
|
7121
|
+
* Registers an element with this behavior, decorating it if it wasn't already registered.
|
|
7122
|
+
* @param element Element to register.
|
|
7123
|
+
*/
|
|
6710
7124
|
register(element) {
|
|
6711
7125
|
var container = this.#items;
|
|
6712
7126
|
if (!container.has(element)) {
|
|
@@ -6714,6 +7128,10 @@ var PacemBehavior = class extends PacemEventTarget {
|
|
|
6714
7128
|
this.decorate(element);
|
|
6715
7129
|
}
|
|
6716
7130
|
}
|
|
7131
|
+
/**
|
|
7132
|
+
* Unregisters a previously registered element, undecorating it.
|
|
7133
|
+
* @param element Element to unregister.
|
|
7134
|
+
*/
|
|
6717
7135
|
unregister(element) {
|
|
6718
7136
|
var container = this.#items;
|
|
6719
7137
|
if (container.has(element)) {
|
|
@@ -6721,6 +7139,7 @@ var PacemBehavior = class extends PacemEventTarget {
|
|
|
6721
7139
|
container.delete(element);
|
|
6722
7140
|
}
|
|
6723
7141
|
}
|
|
7142
|
+
/** @readonly Determines whether the given element is currently registered with this behavior. */
|
|
6724
7143
|
has(element) {
|
|
6725
7144
|
return this.#items.has(element);
|
|
6726
7145
|
}
|
|
@@ -7121,22 +7540,27 @@ var PacemDragDropElement = class PacemDragDropElement2 extends PacemBehavior {
|
|
|
7121
7540
|
this.dropTargets = [];
|
|
7122
7541
|
this.mode = DragDataMode.Self;
|
|
7123
7542
|
}
|
|
7543
|
+
/** Wires up the `mousedown`/`touchstart` listeners that arm the drag gesture on the given element. */
|
|
7124
7544
|
decorate(element) {
|
|
7125
7545
|
const options = { capture: false, passive: false };
|
|
7126
7546
|
element.addEventListener("mousedown", this._startHandler, false);
|
|
7127
7547
|
element.addEventListener("touchstart", this._startHandler, options);
|
|
7128
7548
|
}
|
|
7549
|
+
/** Removes the listeners set up by {@link decorate}. */
|
|
7129
7550
|
undecorate(element) {
|
|
7130
7551
|
const options = { capture: false, passive: false };
|
|
7131
7552
|
element.removeEventListener("mousedown", this._startHandler, false);
|
|
7132
7553
|
element.removeEventListener("touchstart", this._startHandler, options);
|
|
7133
7554
|
}
|
|
7555
|
+
/** Registers a listener for a {@link DragDropEventType} lifecycle event. */
|
|
7134
7556
|
addEventListener(type, listener, useCapture) {
|
|
7135
7557
|
super.addEventListener(type, listener, useCapture);
|
|
7136
7558
|
}
|
|
7559
|
+
/** Unregisters a listener previously added for a {@link DragDropEventType} lifecycle event. */
|
|
7137
7560
|
removeEventListener(type, listener, useCapture) {
|
|
7138
7561
|
super.removeEventListener(type, listener, useCapture);
|
|
7139
7562
|
}
|
|
7563
|
+
/** Dispatches a {@link DragDropEvent}, clearing internal per-element bookkeeping once the drag ends. */
|
|
7140
7564
|
dispatchEvent(evt) {
|
|
7141
7565
|
if (evt.type === DragDropEventType.End) {
|
|
7142
7566
|
DEL_VAL2(evt.detail.element, MOUSE_DOWN);
|
|
@@ -7343,11 +7767,13 @@ var PacemRescaleElement = class PacemRescaleElement2 extends PacemBehavior {
|
|
|
7343
7767
|
));
|
|
7344
7768
|
};
|
|
7345
7769
|
}
|
|
7770
|
+
/** Adds the resize-handle frame (see {@link RescaleHandle}) around the given element. */
|
|
7346
7771
|
decorate(element) {
|
|
7347
7772
|
const el = element, css = getComputedStyle(el);
|
|
7348
7773
|
Utils.addClass(el, PCSS + "-rescalable");
|
|
7349
7774
|
this._setFrame(el);
|
|
7350
7775
|
}
|
|
7776
|
+
/** Removes the resize-handle frame set up by {@link decorate}. */
|
|
7351
7777
|
undecorate(element) {
|
|
7352
7778
|
const el = element;
|
|
7353
7779
|
Utils.removeClass(el, PCSS + "-rescalable");
|
|
@@ -7576,6 +8002,7 @@ var PacemRotateElement = class PacemRotateElement2 extends PacemBehavior {
|
|
|
7576
8002
|
));
|
|
7577
8003
|
};
|
|
7578
8004
|
}
|
|
8005
|
+
/** Wires up the `mousedown`/`touchstart` listeners that arm the rotate gesture on the given element. */
|
|
7579
8006
|
decorate(element) {
|
|
7580
8007
|
const el = element;
|
|
7581
8008
|
Utils.addClass(el, PCSS + "-rotatable");
|
|
@@ -7583,6 +8010,7 @@ var PacemRotateElement = class PacemRotateElement2 extends PacemBehavior {
|
|
|
7583
8010
|
element.addEventListener("mousedown", this._startHandler, false);
|
|
7584
8011
|
element.addEventListener("touchstart", this._startHandler, options);
|
|
7585
8012
|
}
|
|
8013
|
+
/** Removes the listeners set up by {@link decorate}. */
|
|
7586
8014
|
undecorate(element) {
|
|
7587
8015
|
const el = element;
|
|
7588
8016
|
Utils.removeClass(el, PCSS + "-rotatable");
|
|
@@ -7843,12 +8271,14 @@ var PacemSwipeElement = class PacemSwipeElement2 extends PacemBehavior {
|
|
|
7843
8271
|
this._undo(el);
|
|
7844
8272
|
};
|
|
7845
8273
|
}
|
|
8274
|
+
/** Wires up the `pointerdown` listener that arms the swipe gesture on the given element. */
|
|
7846
8275
|
decorate(element) {
|
|
7847
8276
|
if (element instanceof HTMLElement || element instanceof SVGElement) {
|
|
7848
8277
|
Utils.addClass(element, PCSS + "-swipe");
|
|
7849
8278
|
}
|
|
7850
8279
|
element.addEventListener("pointerdown", this._prepareHandler, false);
|
|
7851
8280
|
}
|
|
8281
|
+
/** Removes the listener set up by {@link decorate}. */
|
|
7852
8282
|
undecorate(element) {
|
|
7853
8283
|
if (element instanceof HTMLElement || element instanceof SVGElement) {
|
|
7854
8284
|
Utils.removeClass(element, PCSS + "-swipe");
|
|
@@ -7942,10 +8372,12 @@ var TweenAnimationElement = class extends AnimationElement {
|
|
|
7942
8372
|
super();
|
|
7943
8373
|
this._tweener = _tweener;
|
|
7944
8374
|
}
|
|
8375
|
+
/** @readonly Gets the {@link TweenService} instance driving this animation. */
|
|
7945
8376
|
get tweener() {
|
|
7946
8377
|
return this._tweener;
|
|
7947
8378
|
}
|
|
7948
8379
|
#cancelToken = false;
|
|
8380
|
+
/** Starts (or restarts) the tween and returns a promise resolved once it completes. */
|
|
7949
8381
|
startAnimation() {
|
|
7950
8382
|
this.#cancelToken = false;
|
|
7951
8383
|
return new Promise((resolve, _) => {
|
|
@@ -7956,6 +8388,7 @@ var TweenAnimationElement = class extends AnimationElement {
|
|
|
7956
8388
|
}).then(resolve);
|
|
7957
8389
|
});
|
|
7958
8390
|
}
|
|
8391
|
+
/** Cancels the running tween. */
|
|
7959
8392
|
cancelAnimation() {
|
|
7960
8393
|
this.#cancelToken = true;
|
|
7961
8394
|
}
|
|
@@ -8013,6 +8446,7 @@ var PacemColorAnimationElement = class PacemColorAnimationElement2 extends Tween
|
|
|
8013
8446
|
_parseColor(clr) {
|
|
8014
8447
|
return Colors2.hsl(Colors2.parse(clr));
|
|
8015
8448
|
}
|
|
8449
|
+
/** @inheritdoc */
|
|
8016
8450
|
tweenInterpolationCallback(time, progress) {
|
|
8017
8451
|
const from = this.#from, to = this.#to;
|
|
8018
8452
|
const hsla = {
|
|
@@ -8044,6 +8478,7 @@ var __decorate42 = function(decorators, target, key2, desc) {
|
|
|
8044
8478
|
var DEFAULT_FROM2 = 0;
|
|
8045
8479
|
var DEFAULT_TO2 = 1;
|
|
8046
8480
|
var PacemNumberAnimationElement = class PacemNumberAnimationElement2 extends TweenAnimationElement {
|
|
8481
|
+
/** @inheritdoc */
|
|
8047
8482
|
tweenInterpolationCallback(time, progress) {
|
|
8048
8483
|
const to = this.to ?? DEFAULT_TO2, from = this.from ?? DEFAULT_FROM2;
|
|
8049
8484
|
return (to - from) * progress + from;
|
|
@@ -8069,6 +8504,7 @@ var __decorate43 = function(decorators, target, key2, desc) {
|
|
|
8069
8504
|
var DEFAULT_FROM3 = { x: 0, y: 0 };
|
|
8070
8505
|
var DEFAULT_TO3 = { x: 1, y: 1 };
|
|
8071
8506
|
var PacemPointAnimationElement = class PacemPointAnimationElement2 extends TweenAnimationElement {
|
|
8507
|
+
/** @inheritdoc */
|
|
8072
8508
|
tweenInterpolationCallback(time, progress) {
|
|
8073
8509
|
const to = this.to ?? DEFAULT_TO3, from = this.from ?? DEFAULT_FROM3;
|
|
8074
8510
|
return {
|
|
@@ -8095,6 +8531,7 @@ var __decorate44 = function(decorators, target, key2, desc) {
|
|
|
8095
8531
|
return c > 3 && r && Object.defineProperty(target, key2, r), r;
|
|
8096
8532
|
};
|
|
8097
8533
|
var PacemStoryboardElement = class PacemStoryboardElement2 extends PacemItemsContainerElement {
|
|
8534
|
+
/** @inheritdoc */
|
|
8098
8535
|
validate(item) {
|
|
8099
8536
|
return item instanceof AnimationElement;
|
|
8100
8537
|
}
|
|
@@ -8135,12 +8572,14 @@ var PacemStoryboardElement = class PacemStoryboardElement2 extends PacemItemsCon
|
|
|
8135
8572
|
}
|
|
8136
8573
|
return Promise.all(promises);
|
|
8137
8574
|
}
|
|
8575
|
+
/** Cancels every running {@link Timeline} in this storyboard. */
|
|
8138
8576
|
cancelAnimation() {
|
|
8139
8577
|
const ds = this._adaptedDatasource || [];
|
|
8140
8578
|
for (let timeline of ds) {
|
|
8141
8579
|
timeline.cancelAnimation();
|
|
8142
8580
|
}
|
|
8143
8581
|
}
|
|
8582
|
+
/** Starts (or restarts) every {@link Timeline} in this storyboard. */
|
|
8144
8583
|
startAnimation() {
|
|
8145
8584
|
return this._animate(true);
|
|
8146
8585
|
}
|
|
@@ -8237,6 +8676,13 @@ function buildDiffOptions(modeOrOutput, outputOrCssAdd, cssAddOrRemove, cssRemov
|
|
|
8237
8676
|
};
|
|
8238
8677
|
}
|
|
8239
8678
|
var Transforms2 = class {
|
|
8679
|
+
/**
|
|
8680
|
+
* Wraps every case-insensitive occurrence of each whitespace-separated token of `query` found in `src`
|
|
8681
|
+
* (skipping matches inside HTML tags) with a `<span class="{css}">` highlight wrapper.
|
|
8682
|
+
* @param src Source HTML/text to search within.
|
|
8683
|
+
* @param query Whitespace-separated search terms.
|
|
8684
|
+
* @param css CSS class applied to the highlight `<span>`. Defaults to `{PCSS}-highlight`.
|
|
8685
|
+
*/
|
|
8240
8686
|
static highlight(src, query, css = PCSS + "-highlight") {
|
|
8241
8687
|
if (!query || !src)
|
|
8242
8688
|
return src;
|
|
@@ -8278,9 +8724,11 @@ var Transforms2 = class {
|
|
|
8278
8724
|
return acc;
|
|
8279
8725
|
}, "");
|
|
8280
8726
|
}
|
|
8727
|
+
/** Left-pads `src` (stringified) to `length` characters using `pad`; see {@link Utils.leftPad}. */
|
|
8281
8728
|
static padleft(src, length, pad) {
|
|
8282
8729
|
return Utils.leftPad("" + src, length, pad);
|
|
8283
8730
|
}
|
|
8731
|
+
/** Formats a byte count `src` as a human-readable size string (`B`/`kB`/`MB`/`GB`), or `'-'` if not a positive number. */
|
|
8284
8732
|
static size(src) {
|
|
8285
8733
|
if (!(src > 0))
|
|
8286
8734
|
return "-";
|
|
@@ -8292,12 +8740,25 @@ var Transforms2 = class {
|
|
|
8292
8740
|
return (src / 1048576).toFixed(2) + " MB";
|
|
8293
8741
|
return (src / 1073741824).toFixed(2) + " GB";
|
|
8294
8742
|
}
|
|
8743
|
+
/**
|
|
8744
|
+
* Formats a decimal-degrees number `src` as degrees/minutes/seconds (e.g. `41° 53' 24"`).
|
|
8745
|
+
* @param src Decimal degrees value (sign indicates direction).
|
|
8746
|
+
* @param degSeparator Text following the degrees component.
|
|
8747
|
+
* @param minSeparator Text following the minutes component.
|
|
8748
|
+
* @param secSeparator Text following the seconds component.
|
|
8749
|
+
*/
|
|
8295
8750
|
static decToDeg(src, degSeparator = "\xB0 ", minSeparator = "' ", secSeparator = '"') {
|
|
8296
8751
|
const sign = Math.sign(src);
|
|
8297
8752
|
src = Math.abs(src);
|
|
8298
8753
|
const deg = Math.floor(src), min0 = (src - deg) * 60, min = Math.floor(min0), sec0 = (min0 - min) * 60, sec = Math.floor(sec0);
|
|
8299
8754
|
return (sign < 0 ? "-" : "") + deg + degSeparator + min + minSeparator + sec + secSeparator;
|
|
8300
8755
|
}
|
|
8756
|
+
/**
|
|
8757
|
+
* Formats a date-like value `src` (parsed via {@link Utils.parseDate}) as text.
|
|
8758
|
+
* @param src Date, timestamp, or parseable date string.
|
|
8759
|
+
* @param format Either a named shorthand (`'iso'`, `'isodate'`, `'localdate'`, `'time'`/`'localtime'`, `'full'`, or the default locale date format) or an `Intl.DateTimeFormatOptions` object.
|
|
8760
|
+
* @param culture BCP 47 locale to format with. Defaults to the browser's language.
|
|
8761
|
+
*/
|
|
8301
8762
|
static date(src, format, culture) {
|
|
8302
8763
|
var date = Utils.parseDate(src), lang = culture || navigator.language;
|
|
8303
8764
|
if (Utils.isNull(format) || typeof format === "string") {
|
|
@@ -8324,6 +8785,13 @@ var Transforms2 = class {
|
|
|
8324
8785
|
return date.toLocaleString(culture, format);
|
|
8325
8786
|
}
|
|
8326
8787
|
}
|
|
8788
|
+
/**
|
|
8789
|
+
* Formats the elapsed time between `start` and `end`.
|
|
8790
|
+
* @param start Start date-like value.
|
|
8791
|
+
* @param end End date-like value.
|
|
8792
|
+
* @param format Either an `Intl.DateTimeFormatOptions` (formatted as a UTC duration, optionally sign-prefixed via `sign: true`), or omitted for the legacy `"{d}d {h}h {m}m {s}s {ms}ms"` textual format.
|
|
8793
|
+
* @param culture BCP 47 locale to format with (only used with `Intl.DateTimeFormatOptions`). Defaults to the browser's language.
|
|
8794
|
+
*/
|
|
8327
8795
|
static timespan(start, end, format, culture) {
|
|
8328
8796
|
const startDate = Utils.parseDate(start), endDate = Utils.parseDate(end), span = endDate.valueOf() - startDate.valueOf(), sign = span < 0 ? "-" : "", elapsed = Math.abs(span);
|
|
8329
8797
|
if (typeof format === "object") {
|
|
@@ -8333,18 +8801,26 @@ var Transforms2 = class {
|
|
|
8333
8801
|
const msecsPerDay = 864e5, msecsPerHr = 36e5, msecsPerMin = 6e4, days = Math.floor(elapsed / msecsPerDay), hrs = Math.floor(elapsed % msecsPerDay / msecsPerHr), mins = Math.floor(elapsed % msecsPerHr / msecsPerMin), secs = Math.floor(elapsed % msecsPerMin / 1e3), msecs = Math.floor(elapsed % 1e3);
|
|
8334
8802
|
return `${sign}${days}d ${hrs}h ${mins}m ${secs}s ${msecs}ms`;
|
|
8335
8803
|
}
|
|
8804
|
+
/** Formats `src` as a currency amount using `Intl.NumberFormat`. @param currency ISO 4217 currency code. @param culture BCP 47 locale. Defaults to the browser's language. */
|
|
8336
8805
|
static currency(src, currency, culture) {
|
|
8337
8806
|
return new Intl.NumberFormat(culture ?? navigator.language, { style: "currency", currency }).format(src);
|
|
8338
8807
|
}
|
|
8808
|
+
/**
|
|
8809
|
+
* Formats `src` as a number using `Intl.NumberFormat`.
|
|
8810
|
+
* @param formatOrCulture Either a BCP 47 locale string, or `Intl.NumberFormatOptions` (in which case `culture` supplies the locale).
|
|
8811
|
+
* @param culture BCP 47 locale, used only when `formatOrCulture` is a format-options object. Defaults to the browser's language.
|
|
8812
|
+
*/
|
|
8339
8813
|
static number(src, formatOrCulture, culture) {
|
|
8340
8814
|
if (typeof formatOrCulture === "string") {
|
|
8341
8815
|
return new Intl.NumberFormat(formatOrCulture || navigator.language).format(src);
|
|
8342
8816
|
}
|
|
8343
8817
|
return new Intl.NumberFormat(culture ?? navigator.language, formatOrCulture).format(src);
|
|
8344
8818
|
}
|
|
8819
|
+
/** Filters `src` with `filter`; a thin wrapper over `Array.prototype.filter` usable from template expressions. */
|
|
8345
8820
|
static filter(src, filter) {
|
|
8346
8821
|
return src.filter(filter);
|
|
8347
8822
|
}
|
|
8823
|
+
/** Sorts `src` in place (ascending, via `>`/`<` comparison), optionally by a property path when items are objects. @param prop Property name to sort by; omit to compare items directly. */
|
|
8348
8824
|
static orderby(src, prop) {
|
|
8349
8825
|
return src.sort((a, b) => {
|
|
8350
8826
|
if (!Utils.isNullOrEmpty(prop)) {
|
|
@@ -8355,31 +8831,39 @@ var Transforms2 = class {
|
|
|
8355
8831
|
});
|
|
8356
8832
|
}
|
|
8357
8833
|
// #region RegExp
|
|
8834
|
+
/** Tests `input` against a `RegExp` built from `pattern`/`flags`. Registered as `regex.isMatch`. */
|
|
8358
8835
|
static isMatch(input, pattern, flags) {
|
|
8359
8836
|
return new RegExp(pattern, flags).test(input);
|
|
8360
8837
|
}
|
|
8361
8838
|
// #endregion
|
|
8362
8839
|
// #region shortcuts from 'Utils'
|
|
8840
|
+
/** Template-expression shortcut for {@link Utils.isEmpty}. */
|
|
8363
8841
|
static isEmpty(obj2) {
|
|
8364
8842
|
return Utils.isEmpty(obj2);
|
|
8365
8843
|
}
|
|
8844
|
+
/** Template-expression shortcut for {@link Utils.isNull}. */
|
|
8366
8845
|
static isNull(obj2) {
|
|
8367
8846
|
return Utils.isNull(obj2);
|
|
8368
8847
|
}
|
|
8848
|
+
/** Template-expression shortcut for {@link Utils.isNullOrEmpty}. */
|
|
8369
8849
|
static isNullOrEmpty(obj2) {
|
|
8370
8850
|
return Utils.isNullOrEmpty(obj2);
|
|
8371
8851
|
}
|
|
8852
|
+
/** Reads a CSS custom property's value off the document; see {@link Utils.Css.getVariableValue}. Registered as `cssvar`. */
|
|
8372
8853
|
static getCssVariable(name) {
|
|
8373
8854
|
return Utils.Css.getVariableValue(name);
|
|
8374
8855
|
}
|
|
8856
|
+
/** Reads a query-string parameter's value off the current URL; see {@link Utils.URIs.parseQuery}. Registered as `querystring`. */
|
|
8375
8857
|
static getQuerystring(name) {
|
|
8376
8858
|
return Utils.URIs.parseQuery()[name];
|
|
8377
8859
|
}
|
|
8378
8860
|
// #endregion
|
|
8379
8861
|
// #region shortcuts from 'CustomElementUtils'
|
|
8862
|
+
/** Template-expression shortcut for {@link CustomElementUtils.Theme}'s `importWebFonts`. */
|
|
8380
8863
|
static importThemeWebFonts() {
|
|
8381
8864
|
return CustomElementUtils.Theme.importWebFonts();
|
|
8382
8865
|
}
|
|
8866
|
+
/** Template-expression shortcut for {@link CustomElementUtils.findHostContext}. Registered as `host`. */
|
|
8383
8867
|
static findHostContext(element) {
|
|
8384
8868
|
return CustomElementUtils.findHostContext(element);
|
|
8385
8869
|
}
|
|
@@ -8480,6 +8964,10 @@ export {
|
|
|
8480
8964
|
Regex,
|
|
8481
8965
|
Repeater,
|
|
8482
8966
|
RepeaterItem,
|
|
8967
|
+
RouterNavigateEvent,
|
|
8968
|
+
RouterNavigateEventName,
|
|
8969
|
+
RouterNavigatingEvent,
|
|
8970
|
+
RouterNavigatingEventName,
|
|
8483
8971
|
Storage,
|
|
8484
8972
|
TemplateElement,
|
|
8485
8973
|
Throttle,
|