@schukai/monster 3.49.0 → 3.50.0
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +1 -1
- package/source/data/datasource/server/restapi/data-fetch-error.mjs +1 -2
- package/source/data/datasource/server/restapi.mjs +10 -7
- package/source/data/transformer.mjs +18 -0
- package/source/dom/constants.mjs +1 -1
- package/source/dom/customcontrol.mjs +9 -16
- package/source/dom/customelement.mjs +42 -54
- package/source/dom/dimension.mjs +1 -3
- package/source/dom/util/extract-keys.mjs +10 -6
- package/source/dom/util/init-options-from-attributes.mjs +14 -16
- package/source/dom/util/set-option-from-attribute.mjs +14 -16
- package/source/dom/util.mjs +11 -4
- package/source/logging/handler/console.mjs +0 -4
- package/source/text/bracketed-key-value-hash.mjs +23 -31
- package/source/text/util.mjs +1 -2
- package/source/types/version.mjs +1 -1
- package/test/cases/data/transformer.mjs +3 -0
- package/test/cases/monster.mjs +1 -1
package/package.json
CHANGED
@@ -27,7 +27,7 @@ class DataFetchError extends Error {
|
|
27
27
|
constructor(message, response) {
|
28
28
|
super(message);
|
29
29
|
this[internalSymbol] = {
|
30
|
-
response: response
|
30
|
+
response: response,
|
31
31
|
};
|
32
32
|
}
|
33
33
|
|
@@ -46,5 +46,4 @@ class DataFetchError extends Error {
|
|
46
46
|
getResponse() {
|
47
47
|
return this[internalSymbol]["response"];
|
48
48
|
}
|
49
|
-
|
50
49
|
}
|
@@ -5,13 +5,13 @@
|
|
5
5
|
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
|
6
6
|
*/
|
7
7
|
|
8
|
-
import {internalSymbol, instanceSymbol} from "../../../constants.mjs";
|
9
|
-
import {isObject, isFunction} from "../../../types/is.mjs";
|
10
|
-
import {Server} from "../server.mjs";
|
11
|
-
import {WriteError} from "./restapi/writeerror.mjs";
|
12
|
-
import {DataFetchError} from "./restapi/data-fetch-error.mjs";
|
8
|
+
import { internalSymbol, instanceSymbol } from "../../../constants.mjs";
|
9
|
+
import { isObject, isFunction } from "../../../types/is.mjs";
|
10
|
+
import { Server } from "../server.mjs";
|
11
|
+
import { WriteError } from "./restapi/writeerror.mjs";
|
12
|
+
import { DataFetchError } from "./restapi/data-fetch-error.mjs";
|
13
13
|
|
14
|
-
export {RestAPI};
|
14
|
+
export { RestAPI };
|
15
15
|
|
16
16
|
/**
|
17
17
|
* @type {symbol}
|
@@ -189,7 +189,10 @@ function fetchData(init, key, callback) {
|
|
189
189
|
const acceptedStatus = self.getOption(`${key}.acceptedStatus`, [200]);
|
190
190
|
|
191
191
|
if (acceptedStatus.indexOf(resp.status) === -1) {
|
192
|
-
throw new DataFetchError(
|
192
|
+
throw new DataFetchError(
|
193
|
+
`the response does not contain a accepted status (actual: ${resp.status}).`,
|
194
|
+
response,
|
195
|
+
);
|
193
196
|
}
|
194
197
|
|
195
198
|
return resp.text();
|
@@ -673,6 +673,24 @@ function transform(value) {
|
|
673
673
|
throw new Error(`unsupported locale or missing format (${e.message})`);
|
674
674
|
}
|
675
675
|
|
676
|
+
case "datetimeformat":
|
677
|
+
date = new Date(value);
|
678
|
+
if (isNaN(date.getTime())) {
|
679
|
+
throw new Error("invalid date");
|
680
|
+
}
|
681
|
+
|
682
|
+
const options = {
|
683
|
+
dateStyle: args.shift() || "medium",
|
684
|
+
timeStyle: args.shift() || "medium",
|
685
|
+
};
|
686
|
+
|
687
|
+
try {
|
688
|
+
locale = getLocaleOfDocument();
|
689
|
+
return new Intl.DateTimeFormat(locale, options).format(date);
|
690
|
+
} catch (e) {
|
691
|
+
throw new Error(`unsupported locale or missing format (${e.message})`);
|
692
|
+
}
|
693
|
+
|
676
694
|
case "datetime":
|
677
695
|
date = new Date(value);
|
678
696
|
if (isNaN(date.getTime())) {
|
package/source/dom/constants.mjs
CHANGED
@@ -5,13 +5,13 @@
|
|
5
5
|
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
|
6
6
|
*/
|
7
7
|
|
8
|
-
import {extend} from "../data/extend.mjs";
|
9
|
-
import {addAttributeToken} from "./attributes.mjs";
|
10
|
-
import {ATTRIBUTE_ERRORMESSAGE} from "./constants.mjs";
|
11
|
-
import {CustomElement, attributeObserverSymbol} from "./customelement.mjs";
|
12
|
-
import {instanceSymbol} from "../constants.mjs";
|
8
|
+
import { extend } from "../data/extend.mjs";
|
9
|
+
import { addAttributeToken } from "./attributes.mjs";
|
10
|
+
import { ATTRIBUTE_ERRORMESSAGE } from "./constants.mjs";
|
11
|
+
import { CustomElement, attributeObserverSymbol } from "./customelement.mjs";
|
12
|
+
import { instanceSymbol } from "../constants.mjs";
|
13
13
|
|
14
|
-
export {CustomControl};
|
14
|
+
export { CustomControl };
|
15
15
|
|
16
16
|
/**
|
17
17
|
* @private
|
@@ -42,19 +42,18 @@ const attachedInternalSymbol = Symbol("attachedInternal");
|
|
42
42
|
* Read the HTML specification for Custom Element Reactions: {@link https://html.spec.whatwg.org/dev/custom-elements.html#custom-element-reactions|Custom Element Reactions}.
|
43
43
|
*
|
44
44
|
* @summary A base class for custom controls based on CustomElement.
|
45
|
-
* @copyright schukai GmbH
|
45
|
+
* @copyright schukai GmbH
|
46
46
|
* @license AGPLv3
|
47
47
|
* @since 1.14.0
|
48
48
|
* @memberOf Monster.DOM
|
49
49
|
* @extends Monster.DOM.CustomElement
|
50
50
|
*/
|
51
51
|
class CustomControl extends CustomElement {
|
52
|
-
|
53
52
|
/**
|
54
53
|
* The constructor method of CustomControl, which is called when creating a new instance.
|
55
54
|
* It checks whether the element supports `attachInternals()` and initializes an internal form-associated element
|
56
55
|
* if supported. Additionally, it initializes a MutationObserver to watch for attribute changes.
|
57
|
-
*
|
56
|
+
*
|
58
57
|
* See the links below for more information:
|
59
58
|
* {@link https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-define|CustomElementRegistry.define()}
|
60
59
|
* {@link https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-get|CustomElementRegistry.get()}
|
@@ -79,7 +78,6 @@ class CustomControl extends CustomElement {
|
|
79
78
|
initObserver.call(this);
|
80
79
|
}
|
81
80
|
|
82
|
-
|
83
81
|
/**
|
84
82
|
* This method is called by the `instanceof` operator.
|
85
83
|
* @returns {symbol}
|
@@ -142,7 +140,6 @@ class CustomControl extends CustomElement {
|
|
142
140
|
throw Error("the value setter must be overwritten by the derived class");
|
143
141
|
}
|
144
142
|
|
145
|
-
|
146
143
|
/**
|
147
144
|
* This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
|
148
145
|
*
|
@@ -327,14 +324,11 @@ class CustomControl extends CustomElement {
|
|
327
324
|
}
|
328
325
|
}
|
329
326
|
|
330
|
-
|
331
327
|
/**
|
332
328
|
* @param {string} state
|
333
329
|
* @param {string} mode
|
334
330
|
*/
|
335
|
-
formStateRestoreCallback(state, mode) {
|
336
|
-
|
337
|
-
}
|
331
|
+
formStateRestoreCallback(state, mode) {}
|
338
332
|
|
339
333
|
/**
|
340
334
|
*
|
@@ -342,7 +336,6 @@ class CustomControl extends CustomElement {
|
|
342
336
|
formResetCallback() {
|
343
337
|
this.value = "";
|
344
338
|
}
|
345
|
-
|
346
339
|
}
|
347
340
|
|
348
341
|
/**
|
@@ -5,20 +5,20 @@
|
|
5
5
|
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
|
6
6
|
*/
|
7
7
|
|
8
|
-
import {findElementWithIdUpwards} from "./util.mjs";
|
9
|
-
import {internalSymbol} from "../constants.mjs";
|
10
|
-
import {extend} from "../data/extend.mjs";
|
11
|
-
import {Pathfinder} from "../data/pathfinder.mjs";
|
12
|
-
import {Formatter} from "../text/formatter.mjs";
|
13
|
-
|
14
|
-
import {parseDataURL} from "../types/dataurl.mjs";
|
15
|
-
import {getGlobalObject} from "../types/global.mjs";
|
16
|
-
import {isArray, isFunction, isIterable, isObject, isString} from "../types/is.mjs";
|
17
|
-
import {Observer} from "../types/observer.mjs";
|
18
|
-
import {ProxyObserver} from "../types/proxyobserver.mjs";
|
19
|
-
import {validateFunction, validateInstance, validateObject, validateString} from "../types/validate.mjs";
|
20
|
-
import {clone} from "../util/clone.mjs";
|
21
|
-
import {addAttributeToken, getLinkedObjects, hasObjectLink} from "./attributes.mjs";
|
8
|
+
import { findElementWithIdUpwards } from "./util.mjs";
|
9
|
+
import { internalSymbol } from "../constants.mjs";
|
10
|
+
import { extend } from "../data/extend.mjs";
|
11
|
+
import { Pathfinder } from "../data/pathfinder.mjs";
|
12
|
+
import { Formatter } from "../text/formatter.mjs";
|
13
|
+
|
14
|
+
import { parseDataURL } from "../types/dataurl.mjs";
|
15
|
+
import { getGlobalObject } from "../types/global.mjs";
|
16
|
+
import { isArray, isFunction, isIterable, isObject, isString } from "../types/is.mjs";
|
17
|
+
import { Observer } from "../types/observer.mjs";
|
18
|
+
import { ProxyObserver } from "../types/proxyobserver.mjs";
|
19
|
+
import { validateFunction, validateInstance, validateObject, validateString } from "../types/validate.mjs";
|
20
|
+
import { clone } from "../util/clone.mjs";
|
21
|
+
import { addAttributeToken, getLinkedObjects, hasObjectLink } from "./attributes.mjs";
|
22
22
|
import {
|
23
23
|
ATTRIBUTE_DISABLED,
|
24
24
|
ATTRIBUTE_ERRORMESSAGE,
|
@@ -27,15 +27,15 @@ import {
|
|
27
27
|
ATTRIBUTE_OPTIONS_SELECTOR,
|
28
28
|
ATTRIBUTE_SCRIPT_HOST,
|
29
29
|
customElementUpdaterLinkSymbol,
|
30
|
-
initControlCallbackName
|
30
|
+
initControlCallbackName,
|
31
31
|
} from "./constants.mjs";
|
32
|
-
import {findDocumentTemplate, Template} from "./template.mjs";
|
33
|
-
import {addObjectWithUpdaterToElement} from "./updater.mjs";
|
34
|
-
import {instanceSymbol} from "../constants.mjs";
|
35
|
-
import {getDocumentTranslations, Translations} from "../i18n/translations.mjs";
|
36
|
-
import {getSlottedElements} from "./slotted.mjs";
|
37
|
-
import {initOptionsFromAttributes} from "./util/init-options-from-attributes.mjs";
|
38
|
-
import {setOptionFromAttribute} from "./util/set-option-from-attribute.mjs";
|
32
|
+
import { findDocumentTemplate, Template } from "./template.mjs";
|
33
|
+
import { addObjectWithUpdaterToElement } from "./updater.mjs";
|
34
|
+
import { instanceSymbol } from "../constants.mjs";
|
35
|
+
import { getDocumentTranslations, Translations } from "../i18n/translations.mjs";
|
36
|
+
import { getSlottedElements } from "./slotted.mjs";
|
37
|
+
import { initOptionsFromAttributes } from "./util/init-options-from-attributes.mjs";
|
38
|
+
import { setOptionFromAttribute } from "./util/set-option-from-attribute.mjs";
|
39
39
|
|
40
40
|
export {
|
41
41
|
CustomElement,
|
@@ -188,7 +188,7 @@ const scriptHostElementSymbol = Symbol("scriptHostElement");
|
|
188
188
|
* display: flex;
|
189
189
|
* }
|
190
190
|
* ```
|
191
|
-
*
|
191
|
+
*
|
192
192
|
* More information about Custom Elements can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements).
|
193
193
|
* And in the [HTML Standard](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements) or in the [WHATWG Wiki](https://wiki.whatwg.org/wiki/Custom_Elements).
|
194
194
|
*
|
@@ -204,7 +204,7 @@ class CustomElement extends HTMLElement {
|
|
204
204
|
/**
|
205
205
|
* A new object is created. First the `initOptions` method is called. Here the
|
206
206
|
* options can be defined in derived classes. Subsequently, the shadowRoot is initialized.
|
207
|
-
*
|
207
|
+
*
|
208
208
|
* IMPORTANT: CustomControls instances are not created via the constructor, but either via a tag in the HTML or via <code>document.createElement()</code>.
|
209
209
|
*
|
210
210
|
* @throws {Error} the options attribute does not contain a valid json definition.
|
@@ -220,7 +220,6 @@ class CustomElement extends HTMLElement {
|
|
220
220
|
this[initMethodSymbol]();
|
221
221
|
initOptionObserver.call(this);
|
222
222
|
this[scriptHostElementSymbol] = [];
|
223
|
-
|
224
223
|
}
|
225
224
|
|
226
225
|
/**
|
@@ -279,7 +278,7 @@ class CustomElement extends HTMLElement {
|
|
279
278
|
* More information about the template element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template).
|
280
279
|
*
|
281
280
|
* More information about the slot element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot).
|
282
|
-
*
|
281
|
+
*
|
283
282
|
* @property {boolean} disabled=false Specifies whether the control is disabled. When present, it makes the element non-mutable, non-focusable, and non-submittable with the form.
|
284
283
|
* @property {string} shadowMode=open Specifies the mode of the shadow root. When set to `open`, elements in the shadow root are accessible from JavaScript outside the root, while setting it to `closed` denies access to the root's nodes from JavaScript outside it.
|
285
284
|
* @property {Boolean} delegatesFocus=true Specifies the behavior of the control with respect to focusability. When set to `true`, it mitigates custom element issues around focusability. When a non-focusable part of the shadow DOM is clicked, the first focusable part is given focus, and the shadow host is given any available :focus styling.
|
@@ -352,11 +351,11 @@ class CustomElement extends HTMLElement {
|
|
352
351
|
}
|
353
352
|
|
354
353
|
/**
|
355
|
-
* The `getTag()` method returns the tag name associated with the custom element. This method should be overwritten
|
354
|
+
* The `getTag()` method returns the tag name associated with the custom element. This method should be overwritten
|
356
355
|
* by the derived class.
|
357
356
|
*
|
358
|
-
* Note that there is no check on the name of the tag in this class. It is the responsibility of
|
359
|
-
* the developer to assign an appropriate tag name. If the name is not valid, the
|
357
|
+
* Note that there is no check on the name of the tag in this class. It is the responsibility of
|
358
|
+
* the developer to assign an appropriate tag name. If the name is not valid, the
|
360
359
|
* `registerCustomElement()` method will issue an error.
|
361
360
|
*
|
362
361
|
* @see https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
|
@@ -369,7 +368,7 @@ class CustomElement extends HTMLElement {
|
|
369
368
|
}
|
370
369
|
|
371
370
|
/**
|
372
|
-
* The `getCSSStyleSheet()` method returns a `CSSStyleSheet` object that defines the styles for the custom element.
|
371
|
+
* The `getCSSStyleSheet()` method returns a `CSSStyleSheet` object that defines the styles for the custom element.
|
373
372
|
* If the environment does not support the `CSSStyleSheet` constructor, then an object can be built using the provided detour.
|
374
373
|
*
|
375
374
|
* If `undefined` is returned, then the shadow root does not receive a stylesheet.
|
@@ -384,7 +383,7 @@ class CustomElement extends HTMLElement {
|
|
384
383
|
* }
|
385
384
|
* ```
|
386
385
|
*
|
387
|
-
* If the environment does not support the `CSSStyleSheet` constructor,
|
386
|
+
* If the environment does not support the `CSSStyleSheet` constructor,
|
388
387
|
* you can use the following workaround to create the stylesheet:
|
389
388
|
*
|
390
389
|
* ```js
|
@@ -445,8 +444,7 @@ class CustomElement extends HTMLElement {
|
|
445
444
|
|
446
445
|
try {
|
447
446
|
value = new Pathfinder(this[internalSymbol].getRealSubject()["options"]).getVia(path);
|
448
|
-
} catch (e) {
|
449
|
-
}
|
447
|
+
} catch (e) {}
|
450
448
|
|
451
449
|
if (value === undefined) return defaultValue;
|
452
450
|
return value;
|
@@ -574,22 +572,18 @@ class CustomElement extends HTMLElement {
|
|
574
572
|
|
575
573
|
// Check if the object has already been initialized
|
576
574
|
if (!hasObjectLink(self, customElementUpdaterLinkSymbol)) {
|
577
|
-
|
578
575
|
// If not, call the assembleMethod to initialize the object
|
579
576
|
self[assembleMethodSymbol]();
|
580
577
|
}
|
581
578
|
}
|
582
579
|
|
583
|
-
|
584
|
-
|
585
580
|
/**
|
586
581
|
* Called every time the element is removed from the DOM. Useful for running clean up code.
|
587
582
|
*
|
588
583
|
* @return {void}
|
589
584
|
* @since 1.7.0
|
590
585
|
*/
|
591
|
-
disconnectedCallback() {
|
592
|
-
}
|
586
|
+
disconnectedCallback() {}
|
593
587
|
|
594
588
|
/**
|
595
589
|
* The custom element has been moved into a new document (e.g. someone called document.adoptNode(el)).
|
@@ -597,8 +591,7 @@ class CustomElement extends HTMLElement {
|
|
597
591
|
* @return {void}
|
598
592
|
* @since 1.7.0
|
599
593
|
*/
|
600
|
-
adoptedCallback() {
|
601
|
-
}
|
594
|
+
adoptedCallback() {}
|
602
595
|
|
603
596
|
/**
|
604
597
|
* Called when an observed attribute has been added, removed, updated, or replaced. Also called for initial
|
@@ -615,7 +608,7 @@ class CustomElement extends HTMLElement {
|
|
615
608
|
const self = this;
|
616
609
|
|
617
610
|
if (attrName.startsWith("data-monster-option-")) {
|
618
|
-
setOptionFromAttribute(self, attrName, this[internalSymbol].getSubject()["options"])
|
611
|
+
setOptionFromAttribute(self, attrName, this[internalSymbol].getSubject()["options"]);
|
619
612
|
}
|
620
613
|
|
621
614
|
const callback = self[attributeObserverSymbol]?.[attrName];
|
@@ -625,7 +618,6 @@ class CustomElement extends HTMLElement {
|
|
625
618
|
} catch (e) {
|
626
619
|
addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
|
627
620
|
}
|
628
|
-
|
629
621
|
}
|
630
622
|
}
|
631
623
|
|
@@ -652,7 +644,7 @@ class CustomElement extends HTMLElement {
|
|
652
644
|
|
653
645
|
/**
|
654
646
|
* Calls a callback function if it exists.
|
655
|
-
*
|
647
|
+
*
|
656
648
|
* @param {string} name
|
657
649
|
* @param {*} args
|
658
650
|
* @returns {*}
|
@@ -661,8 +653,6 @@ class CustomElement extends HTMLElement {
|
|
661
653
|
const self = this;
|
662
654
|
return callControlCallback.call(self, name, ...args);
|
663
655
|
}
|
664
|
-
|
665
|
-
|
666
656
|
}
|
667
657
|
|
668
658
|
/**
|
@@ -679,7 +669,6 @@ function callControlCallback(callBackFunctionName, ...args) {
|
|
679
669
|
|
680
670
|
if (callBackFunctionName in self) {
|
681
671
|
return self[callBackFunctionName](self, ...args);
|
682
|
-
|
683
672
|
}
|
684
673
|
|
685
674
|
if (!self.hasAttribute(ATTRIBUTE_SCRIPT_HOST)) {
|
@@ -687,13 +676,12 @@ function callControlCallback(callBackFunctionName, ...args) {
|
|
687
676
|
}
|
688
677
|
|
689
678
|
if (self[scriptHostElementSymbol].length === 0) {
|
690
|
-
|
691
679
|
const targetId = self.getAttribute(ATTRIBUTE_SCRIPT_HOST);
|
692
680
|
if (!targetId) {
|
693
681
|
return;
|
694
682
|
}
|
695
683
|
|
696
|
-
const list = targetId.split(",")
|
684
|
+
const list = targetId.split(",");
|
697
685
|
for (const id of list) {
|
698
686
|
const host = findElementWithIdUpwards(self, targetId);
|
699
687
|
if (!(host instanceof HTMLElement)) {
|
@@ -715,7 +703,6 @@ function callControlCallback(callBackFunctionName, ...args) {
|
|
715
703
|
}
|
716
704
|
|
717
705
|
addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, `callback ${callBackFunctionName} not found`);
|
718
|
-
|
719
706
|
}
|
720
707
|
|
721
708
|
/**
|
@@ -746,7 +733,6 @@ function initFromCallbackHost() {
|
|
746
733
|
callControlCallback.call(self, callBackFunctionName);
|
747
734
|
}
|
748
735
|
|
749
|
-
|
750
736
|
/**
|
751
737
|
* This method is called when the element is first created.
|
752
738
|
*
|
@@ -763,7 +749,11 @@ function attachAttributeChangeMutationObserver() {
|
|
763
749
|
self[attributeMutationObserverSymbol] = new MutationObserver(function (mutations, observer) {
|
764
750
|
for (const mutation of mutations) {
|
765
751
|
if (mutation.type === "attributes") {
|
766
|
-
self.attributeChangedCallback(
|
752
|
+
self.attributeChangedCallback(
|
753
|
+
mutation.attributeName,
|
754
|
+
mutation.oldValue,
|
755
|
+
mutation.target.getAttribute(mutation.attributeName),
|
756
|
+
);
|
767
757
|
}
|
768
758
|
}
|
769
759
|
});
|
@@ -773,7 +763,6 @@ function attachAttributeChangeMutationObserver() {
|
|
773
763
|
attributes: true,
|
774
764
|
attributeOldValue: true,
|
775
765
|
});
|
776
|
-
|
777
766
|
} catch (e) {
|
778
767
|
addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
|
779
768
|
}
|
@@ -971,8 +960,7 @@ function parseOptionsJSON(data) {
|
|
971
960
|
try {
|
972
961
|
let dataUrl = parseDataURL(data);
|
973
962
|
data = dataUrl.content;
|
974
|
-
} catch (e) {
|
975
|
-
}
|
963
|
+
} catch (e) {}
|
976
964
|
|
977
965
|
try {
|
978
966
|
obj = JSON.parse(data);
|
package/source/dom/dimension.mjs
CHANGED
@@ -75,10 +75,8 @@ function getDeviceDPI() {
|
|
75
75
|
*/
|
76
76
|
|
77
77
|
function convertToPixels(value, parentElement = document.documentElement, fontSizeElement = document.documentElement) {
|
78
|
-
|
79
78
|
validateString(value);
|
80
|
-
|
81
|
-
|
79
|
+
|
82
80
|
const regex = /^(-?[\d.]+)(.*)$/;
|
83
81
|
const matchResult = value.match(regex);
|
84
82
|
|
@@ -5,7 +5,7 @@
|
|
5
5
|
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
|
6
6
|
*/
|
7
7
|
|
8
|
-
export {extractKeys}
|
8
|
+
export { extractKeys };
|
9
9
|
|
10
10
|
/**
|
11
11
|
* Extracts the keys from the given object and returns a map with the keys and values.
|
@@ -17,17 +17,21 @@ export {extractKeys}
|
|
17
17
|
* @param {string} valueSeparator
|
18
18
|
* @returns {Map<any, any>}
|
19
19
|
*/
|
20
|
-
function extractKeys(obj, keyPrefix =
|
20
|
+
function extractKeys(obj, keyPrefix = "", keySeparator = "-", valueSeparator = ".") {
|
21
21
|
const resultMap = new Map();
|
22
22
|
|
23
23
|
function helper(currentObj, currentKeyPrefix, currentValuePrefix) {
|
24
24
|
for (const key in currentObj) {
|
25
|
-
if (typeof currentObj[key] ===
|
26
|
-
const newKeyPrefix = currentKeyPrefix
|
25
|
+
if (typeof currentObj[key] === "object" && !Array.isArray(currentObj[key])) {
|
26
|
+
const newKeyPrefix = currentKeyPrefix
|
27
|
+
? currentKeyPrefix + keySeparator + key.toLowerCase()
|
28
|
+
: key.toLowerCase();
|
27
29
|
const newValuePrefix = currentValuePrefix ? currentValuePrefix + valueSeparator + key : key;
|
28
30
|
helper(currentObj[key], newKeyPrefix, newValuePrefix);
|
29
31
|
} else {
|
30
|
-
const finalKey = currentKeyPrefix
|
32
|
+
const finalKey = currentKeyPrefix
|
33
|
+
? currentKeyPrefix + keySeparator + key.toLowerCase()
|
34
|
+
: key.toLowerCase();
|
31
35
|
const finalValue = currentValuePrefix ? currentValuePrefix + valueSeparator + key : key;
|
32
36
|
resultMap.set(finalKey, finalValue);
|
33
37
|
}
|
@@ -36,4 +40,4 @@ function extractKeys(obj, keyPrefix = '', keySeparator = '-', valueSeparator = '
|
|
36
40
|
|
37
41
|
helper(obj, keyPrefix, keyPrefix);
|
38
42
|
return resultMap;
|
39
|
-
}
|
43
|
+
}
|
@@ -5,12 +5,12 @@
|
|
5
5
|
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
|
6
6
|
*/
|
7
7
|
|
8
|
-
import {Pathfinder} from
|
9
|
-
import {isFunction} from
|
10
|
-
import {attributeObserverSymbol} from "../customelement.mjs";
|
11
|
-
import {extractKeys} from "./extract-keys.mjs";
|
8
|
+
import { Pathfinder } from "../../data/pathfinder.mjs";
|
9
|
+
import { isFunction } from "../../types/is.mjs";
|
10
|
+
import { attributeObserverSymbol } from "../customelement.mjs";
|
11
|
+
import { extractKeys } from "./extract-keys.mjs";
|
12
12
|
|
13
|
-
export {initOptionsFromAttributes};
|
13
|
+
export { initOptionsFromAttributes };
|
14
14
|
|
15
15
|
/**
|
16
16
|
* Initializes the given options object based on the attributes of the current DOM element.
|
@@ -29,7 +29,7 @@ export {initOptionsFromAttributes};
|
|
29
29
|
* // e.g. <div data-monster-option-foo="foo"></div>
|
30
30
|
* 'bar.baz': (value) => value + 'bar'
|
31
31
|
* // the value of the attribute 'data-monster-option-bar-baz' is appended with 'bar'
|
32
|
-
* // and assigned to the 'bar.baz' property in the options object.
|
32
|
+
* // and assigned to the 'bar.baz' property in the options object.
|
33
33
|
* // e.g. <div data-monster-option-bar-baz="foo"></div>
|
34
34
|
* }
|
35
35
|
*
|
@@ -41,7 +41,7 @@ export {initOptionsFromAttributes};
|
|
41
41
|
* @returns {Object} - The initialized options object.
|
42
42
|
* @this HTMLElement - The context of the DOM element.
|
43
43
|
*/
|
44
|
-
function initOptionsFromAttributes(element, options, mapping = {}, prefix =
|
44
|
+
function initOptionsFromAttributes(element, options, mapping = {}, prefix = "data-monster-option-") {
|
45
45
|
if (!(element instanceof HTMLElement)) return options;
|
46
46
|
if (!element.hasAttributes()) return options;
|
47
47
|
|
@@ -52,7 +52,7 @@ function initOptionsFromAttributes(element, options, mapping = {}, prefix = 'dat
|
|
52
52
|
element.getAttributeNames().forEach((name) => {
|
53
53
|
if (!name.startsWith(prefix)) return;
|
54
54
|
|
55
|
-
// check if the attribute name is a valid option.
|
55
|
+
// check if the attribute name is a valid option.
|
56
56
|
// the mapping between the attribute is simple. The dash is replaced by a dot.
|
57
57
|
// e.g. data-monster-url => url
|
58
58
|
const optionName = keyMap.get(name.substring(prefix.length).toLowerCase());
|
@@ -65,21 +65,19 @@ function initOptionsFromAttributes(element, options, mapping = {}, prefix = 'dat
|
|
65
65
|
}
|
66
66
|
|
67
67
|
const typeOfOptionValue = typeof finder.getVia(optionName);
|
68
|
-
if (typeOfOptionValue ===
|
69
|
-
value = value ===
|
70
|
-
} else if (typeOfOptionValue ===
|
68
|
+
if (typeOfOptionValue === "boolean") {
|
69
|
+
value = value === "true";
|
70
|
+
} else if (typeOfOptionValue === "number") {
|
71
71
|
value = Number(value);
|
72
|
-
} else if (typeOfOptionValue ===
|
72
|
+
} else if (typeOfOptionValue === "string") {
|
73
73
|
value = String(value);
|
74
|
-
} else if (typeOfOptionValue ===
|
74
|
+
} else if (typeOfOptionValue === "object") {
|
75
75
|
value = JSON.parse(value);
|
76
76
|
}
|
77
77
|
|
78
78
|
finder.setVia(optionName, value);
|
79
79
|
}
|
80
|
-
})
|
80
|
+
});
|
81
81
|
|
82
82
|
return options;
|
83
83
|
}
|
84
|
-
|
85
|
-
|
@@ -5,12 +5,12 @@
|
|
5
5
|
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
|
6
6
|
*/
|
7
7
|
|
8
|
-
import {Pathfinder} from
|
9
|
-
import {isFunction} from
|
10
|
-
import {attributeObserverSymbol} from "../customelement.mjs";
|
11
|
-
import {extractKeys} from "./extract-keys.mjs";
|
8
|
+
import { Pathfinder } from "../../data/pathfinder.mjs";
|
9
|
+
import { isFunction } from "../../types/is.mjs";
|
10
|
+
import { attributeObserverSymbol } from "../customelement.mjs";
|
11
|
+
import { extractKeys } from "./extract-keys.mjs";
|
12
12
|
|
13
|
-
export {setOptionFromAttribute};
|
13
|
+
export { setOptionFromAttribute };
|
14
14
|
|
15
15
|
/**
|
16
16
|
* Set the given options object based on the attributes of the current DOM element.
|
@@ -29,7 +29,7 @@ export {setOptionFromAttribute};
|
|
29
29
|
* // e.g. <div data-monster-option-foo="foo"></div>
|
30
30
|
* 'bar.baz': (value) => value + 'bar'
|
31
31
|
* // the value of the attribute 'data-monster-option-bar-baz' is appended with 'bar'
|
32
|
-
* // and assigned to the 'bar.baz' property in the options object.
|
32
|
+
* // and assigned to the 'bar.baz' property in the options object.
|
33
33
|
* // e.g. <div data-monster-option-bar-baz="foo"></div>
|
34
34
|
* }
|
35
35
|
*
|
@@ -42,14 +42,14 @@ export {setOptionFromAttribute};
|
|
42
42
|
* @returns {Object} - The initialized options object.
|
43
43
|
* @this HTMLElement - The context of the DOM element.
|
44
44
|
*/
|
45
|
-
function setOptionFromAttribute(element, name, options, mapping = {}, prefix =
|
45
|
+
function setOptionFromAttribute(element, name, options, mapping = {}, prefix = "data-monster-option-") {
|
46
46
|
if (!(element instanceof HTMLElement)) return options;
|
47
47
|
if (!element.hasAttributes()) return options;
|
48
|
-
|
48
|
+
|
49
49
|
const keyMap = extractKeys(options);
|
50
50
|
const finder = new Pathfinder(options);
|
51
51
|
|
52
|
-
// check if the attribute name is a valid option.
|
52
|
+
// check if the attribute name is a valid option.
|
53
53
|
// the mapping between the attribute is simple. The dash is replaced by a dot.
|
54
54
|
// e.g. data-monster-url => url
|
55
55
|
const optionName = keyMap.get(name.substring(prefix.length).toLowerCase());
|
@@ -65,13 +65,13 @@ function setOptionFromAttribute(element, name, options, mapping = {}, prefix = '
|
|
65
65
|
}
|
66
66
|
|
67
67
|
const typeOfOptionValue = typeof finder.getVia(optionName);
|
68
|
-
if (typeOfOptionValue ===
|
69
|
-
value = value ===
|
70
|
-
} else if (typeOfOptionValue ===
|
68
|
+
if (typeOfOptionValue === "boolean") {
|
69
|
+
value = value === "true";
|
70
|
+
} else if (typeOfOptionValue === "number") {
|
71
71
|
value = Number(value);
|
72
|
-
} else if (typeOfOptionValue ===
|
72
|
+
} else if (typeOfOptionValue === "string") {
|
73
73
|
value = String(value);
|
74
|
-
} else if (typeOfOptionValue ===
|
74
|
+
} else if (typeOfOptionValue === "object") {
|
75
75
|
value = JSON.parse(value);
|
76
76
|
}
|
77
77
|
|
@@ -79,5 +79,3 @@ function setOptionFromAttribute(element, name, options, mapping = {}, prefix = '
|
|
79
79
|
|
80
80
|
return options;
|
81
81
|
}
|
82
|
-
|
83
|
-
|
package/source/dom/util.mjs
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
import { getGlobal } from "../types/global.mjs";
|
9
9
|
import { validateString } from "../types/validate.mjs";
|
10
10
|
|
11
|
-
export { getDocument, getWindow, getDocumentFragmentFromString, findElementWithIdUpwards,getContainingDocument };
|
11
|
+
export { getDocument, getWindow, getDocumentFragmentFromString, findElementWithIdUpwards, getContainingDocument };
|
12
12
|
|
13
13
|
/**
|
14
14
|
* This method fetches the document object
|
@@ -209,7 +209,11 @@ function traverseShadowRoots(element) {
|
|
209
209
|
let currentRoot = element.shadowRoot;
|
210
210
|
let currentParent = element.parentNode;
|
211
211
|
|
212
|
-
while (
|
212
|
+
while (
|
213
|
+
currentParent &&
|
214
|
+
currentParent.nodeType !== Node.DOCUMENT_NODE &&
|
215
|
+
currentParent.nodeType !== Node.DOCUMENT_FRAGMENT_NODE
|
216
|
+
) {
|
213
217
|
if (currentRoot && currentRoot.parentNode) {
|
214
218
|
currentParent = currentRoot.parentNode;
|
215
219
|
currentRoot = currentParent.shadowRoot;
|
@@ -238,8 +242,11 @@ function traverseShadowRoots(element) {
|
|
238
242
|
* @since 3.36.0
|
239
243
|
*/
|
240
244
|
function getContainingDocument(element) {
|
241
|
-
if (
|
242
|
-
|
245
|
+
if (
|
246
|
+
!element ||
|
247
|
+
!(element instanceof HTMLElement || element instanceof element.ownerDocument.defaultView.HTMLElement)
|
248
|
+
) {
|
249
|
+
throw new Error("Invalid argument. Expected an HTMLElement.");
|
243
250
|
}
|
244
251
|
|
245
252
|
return traverseShadowRoots(element) || null;
|
@@ -21,10 +21,6 @@ export { ConsoleHandler };
|
|
21
21
|
* @memberOf Monster.Logging.Handler
|
22
22
|
*/
|
23
23
|
class ConsoleHandler extends Handler {
|
24
|
-
constructor() {
|
25
|
-
super();
|
26
|
-
}
|
27
|
-
|
28
24
|
/**
|
29
25
|
* This is the central log function. this method must be
|
30
26
|
* overwritten by derived handlers with their own logic.
|
@@ -5,7 +5,7 @@
|
|
5
5
|
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
|
6
6
|
*/
|
7
7
|
|
8
|
-
export {parseBracketedKeyValueHash, createBracketedKeyValueHash}
|
8
|
+
export { parseBracketedKeyValueHash, createBracketedKeyValueHash };
|
9
9
|
|
10
10
|
/**
|
11
11
|
* Parses a string containing bracketed key-value pairs and returns an object representing the parsed result.
|
@@ -49,8 +49,7 @@ function parseBracketedKeyValueHash(hashString) {
|
|
49
49
|
//const keyValueStack = [];
|
50
50
|
|
51
51
|
const trimmedHashString = hashString.trim();
|
52
|
-
const cleanedHashString = trimmedHashString.charAt(0) ===
|
53
|
-
|
52
|
+
const cleanedHashString = trimmedHashString.charAt(0) === "#" ? trimmedHashString.slice(1) : trimmedHashString;
|
54
53
|
|
55
54
|
//const selectors = (keyValueStack.length > 0) ? result[selectorStack[selectorStack.length - 1]] : result;
|
56
55
|
let currentSelector = "";
|
@@ -65,20 +64,20 @@ function parseBracketedKeyValueHash(hashString) {
|
|
65
64
|
}
|
66
65
|
}
|
67
66
|
|
68
|
-
let currentKey =
|
69
|
-
let currentValue =
|
67
|
+
let currentKey = "";
|
68
|
+
let currentValue = "";
|
70
69
|
let inKey = true;
|
71
70
|
let inValue = false;
|
72
71
|
let inQuotedValue = false;
|
73
72
|
let inSelector = true;
|
74
73
|
let escaped = false;
|
75
|
-
let quotedValueStartChar =
|
74
|
+
let quotedValueStartChar = "";
|
76
75
|
|
77
76
|
for (let i = 0; i < cleanedHashString.length; i++) {
|
78
77
|
const c = cleanedHashString[i];
|
79
78
|
const nextChar = cleanedHashString?.[i + 1];
|
80
79
|
|
81
|
-
if (c ===
|
80
|
+
if (c === "\\" && !escaped) {
|
82
81
|
escaped = true;
|
83
82
|
continue;
|
84
83
|
}
|
@@ -96,7 +95,6 @@ function parseBracketedKeyValueHash(hashString) {
|
|
96
95
|
}
|
97
96
|
|
98
97
|
if (inQuotedValue && quotedValueStartChar !== c) {
|
99
|
-
|
100
98
|
if (inSelector) {
|
101
99
|
currentSelector += c;
|
102
100
|
} else if (inKey) {
|
@@ -108,19 +106,18 @@ function parseBracketedKeyValueHash(hashString) {
|
|
108
106
|
continue;
|
109
107
|
}
|
110
108
|
|
111
|
-
if (c ===
|
109
|
+
if (c === ";" && inSelector) {
|
112
110
|
inSelector = true;
|
113
111
|
currentSelector = "";
|
114
112
|
continue;
|
115
113
|
}
|
116
114
|
|
117
|
-
|
118
|
-
if (inSelector === true && c !== '(') {
|
115
|
+
if (inSelector === true && c !== "(") {
|
119
116
|
currentSelector += c;
|
120
117
|
continue;
|
121
118
|
}
|
122
119
|
|
123
|
-
if (c ===
|
120
|
+
if (c === "(" && inSelector) {
|
124
121
|
inSelector = false;
|
125
122
|
inKey = true;
|
126
123
|
|
@@ -128,13 +125,12 @@ function parseBracketedKeyValueHash(hashString) {
|
|
128
125
|
continue;
|
129
126
|
}
|
130
127
|
|
131
|
-
if (inKey === true && c !==
|
128
|
+
if (inKey === true && c !== "=") {
|
132
129
|
currentKey += c;
|
133
130
|
continue;
|
134
131
|
}
|
135
132
|
|
136
|
-
if (c ===
|
137
|
-
|
133
|
+
if (c === "=" && inKey) {
|
138
134
|
inKey = false;
|
139
135
|
inValue = true;
|
140
136
|
|
@@ -160,7 +156,7 @@ function parseBracketedKeyValueHash(hashString) {
|
|
160
156
|
continue;
|
161
157
|
}
|
162
158
|
|
163
|
-
if (c ===
|
159
|
+
if (c === ",") {
|
164
160
|
inValue = false;
|
165
161
|
inKey = true;
|
166
162
|
const decodedCurrentValue = decodeURIComponent(currentValue);
|
@@ -170,7 +166,7 @@ function parseBracketedKeyValueHash(hashString) {
|
|
170
166
|
continue;
|
171
167
|
}
|
172
168
|
|
173
|
-
if (c ===
|
169
|
+
if (c === ")") {
|
174
170
|
inValue = false;
|
175
171
|
//inKey = true;
|
176
172
|
inSelector = true;
|
@@ -189,14 +185,11 @@ function parseBracketedKeyValueHash(hashString) {
|
|
189
185
|
}
|
190
186
|
}
|
191
187
|
|
192
|
-
|
193
188
|
if (inSelector) {
|
194
189
|
return selectors;
|
195
190
|
}
|
196
191
|
|
197
|
-
|
198
192
|
return {};
|
199
|
-
|
200
193
|
}
|
201
194
|
|
202
195
|
/**
|
@@ -208,38 +201,37 @@ function parseBracketedKeyValueHash(hashString) {
|
|
208
201
|
* @since 3.37.0
|
209
202
|
*/
|
210
203
|
function createBracketedKeyValueHash(object, addHashPrefix = true) {
|
211
|
-
|
212
204
|
if (!object) {
|
213
|
-
return addHashPrefix ?
|
205
|
+
return addHashPrefix ? "#" : "";
|
214
206
|
}
|
215
|
-
|
216
|
-
let hashString =
|
207
|
+
|
208
|
+
let hashString = "";
|
217
209
|
|
218
210
|
function encodeKeyValue(key, value) {
|
219
|
-
return encodeURIComponent(key) +
|
211
|
+
return encodeURIComponent(key) + "=" + encodeURIComponent(value);
|
220
212
|
}
|
221
213
|
|
222
214
|
for (const selector in object) {
|
223
215
|
if (object.hasOwnProperty(selector)) {
|
224
216
|
const keyValuePairs = object[selector];
|
225
217
|
let selectorString = selector;
|
226
|
-
let keyValueString =
|
218
|
+
let keyValueString = "";
|
227
219
|
|
228
220
|
for (const key in keyValuePairs) {
|
229
221
|
if (keyValuePairs.hasOwnProperty(key)) {
|
230
222
|
const value = keyValuePairs[key];
|
231
|
-
keyValueString += keyValueString.length === 0 ?
|
223
|
+
keyValueString += keyValueString.length === 0 ? "" : ",";
|
232
224
|
keyValueString += encodeKeyValue(key, value);
|
233
225
|
}
|
234
226
|
}
|
235
227
|
|
236
228
|
if (keyValueString.length > 0) {
|
237
|
-
selectorString +=
|
238
|
-
hashString += hashString.length === 0 ?
|
229
|
+
selectorString += "(" + keyValueString + ")";
|
230
|
+
hashString += hashString.length === 0 ? "" : ";";
|
239
231
|
hashString += selectorString;
|
240
232
|
}
|
241
233
|
}
|
242
234
|
}
|
243
235
|
|
244
|
-
return addHashPrefix ?
|
245
|
-
}
|
236
|
+
return addHashPrefix ? "#" + hashString : hashString;
|
237
|
+
}
|
package/source/text/util.mjs
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
export { generateRangeComparisonExpression } from "./generate-range-comparison-expression.mjs"
|
2
|
-
|
1
|
+
export { generateRangeComparisonExpression } from "./generate-range-comparison-expression.mjs";
|
package/source/types/version.mjs
CHANGED
@@ -28,6 +28,9 @@ describe('Transformer', function () {
|
|
28
28
|
describe('Transformer.run()', function () {
|
29
29
|
|
30
30
|
[
|
31
|
+
['datetimeformat', "2023-02-04 08:02:01", "04.02.2023, 08:02:01"],
|
32
|
+
['datetimeformat:long:short', "2023-02-04 08:02:01","4. Februar 2023 um 08:02"],
|
33
|
+
['datetimeformat:short:short', "2023-02-04 08:02:01", "04.02.23, 08:02"],
|
31
34
|
['equals:a', "a", true],
|
32
35
|
['equals:a', "b", false],
|
33
36
|
['equals:3', 3, true],
|
package/test/cases/monster.mjs
CHANGED