Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 1.31
  • master
  • 1.10.0
  • 1.30.1
  • 1.31.0
  • 1.8.0
  • 1.9.0
  • 3.100.0
  • 3.100.1
  • 3.100.10
  • 3.100.11
  • 3.100.12
  • 3.100.13
  • 3.100.14
  • 3.100.15
  • 3.100.16
  • 3.100.17
  • 3.100.18
  • 3.100.19
  • 3.100.2
  • 3.100.20
  • 3.100.3
  • 3.100.4
  • 3.100.5
  • 3.100.6
  • 3.100.7
  • 3.100.8
  • 3.100.9
  • 3.101.0
  • 3.101.1
  • 3.101.2
  • 3.101.3
  • 3.102.0
  • 3.102.1
  • 3.102.2
  • 3.102.3
  • 3.102.4
  • 3.102.5
  • 3.102.6
  • 3.103.0
  • 3.103.1
  • 3.104.0
  • 3.104.1
  • 3.105.0
  • 3.105.1
  • 3.105.2
  • 3.106.0
  • 3.106.1
  • 3.107.0
  • 3.108.0
  • 3.108.1
  • 3.108.2
  • 3.108.3
  • 3.108.4
  • 3.108.5
  • 3.109.0
  • 3.110.0
  • 3.110.1
  • 3.110.2
  • 3.110.3
  • 3.110.4
  • 3.111.0
  • 3.112.0
  • 3.112.1
  • 3.112.2
  • 3.112.3
  • 3.112.4
  • 3.113.0
  • 3.114.0
  • 3.114.1
  • 3.114.2
  • 3.114.3
  • 3.114.4
  • 3.114.5
  • 3.114.6
  • 3.114.7
  • 3.115.0
  • 3.115.1
  • 3.115.2
  • 3.115.3
  • 3.115.4
  • 3.116.0
  • 3.116.1
  • 3.117.0
  • 3.117.1
  • 3.117.2
  • 3.117.3
  • 3.118.0
  • 3.118.1
  • 3.119.0
  • 3.120.0
  • 3.121.0
  • 3.51.5
  • 3.52.0
  • 3.52.1
  • 3.53.0
  • 3.54.0
  • 3.55.0
  • 3.55.1
  • 3.55.2
  • 3.55.3
  • 3.55.4
102 results

Target

Select target project
  • oss/libraries/javascript/monster
1 result
Select Git revision
  • 1.31
  • master
  • 1.10.0
  • 1.30.1
  • 1.31.0
  • 1.8.0
  • 1.9.0
  • 3.100.0
  • 3.100.1
  • 3.100.10
  • 3.100.11
  • 3.100.12
  • 3.100.13
  • 3.100.14
  • 3.100.15
  • 3.100.16
  • 3.100.17
  • 3.100.18
  • 3.100.19
  • 3.100.2
  • 3.100.20
  • 3.100.3
  • 3.100.4
  • 3.100.5
  • 3.100.6
  • 3.100.7
  • 3.100.8
  • 3.100.9
  • 3.101.0
  • 3.101.1
  • 3.101.2
  • 3.101.3
  • 3.102.0
  • 3.102.1
  • 3.102.2
  • 3.102.3
  • 3.102.4
  • 3.102.5
  • 3.102.6
  • 3.103.0
  • 3.103.1
  • 3.104.0
  • 3.104.1
  • 3.105.0
  • 3.105.1
  • 3.105.2
  • 3.106.0
  • 3.106.1
  • 3.107.0
  • 3.108.0
  • 3.108.1
  • 3.108.2
  • 3.108.3
  • 3.108.4
  • 3.108.5
  • 3.109.0
  • 3.110.0
  • 3.110.1
  • 3.110.2
  • 3.110.3
  • 3.110.4
  • 3.111.0
  • 3.112.0
  • 3.112.1
  • 3.112.2
  • 3.112.3
  • 3.112.4
  • 3.113.0
  • 3.114.0
  • 3.114.1
  • 3.114.2
  • 3.114.3
  • 3.114.4
  • 3.114.5
  • 3.114.6
  • 3.114.7
  • 3.115.0
  • 3.115.1
  • 3.115.2
  • 3.115.3
  • 3.115.4
  • 3.116.0
  • 3.116.1
  • 3.117.0
  • 3.117.1
  • 3.117.2
  • 3.117.3
  • 3.118.0
  • 3.118.1
  • 3.119.0
  • 3.120.0
  • 3.121.0
  • 3.51.5
  • 3.52.0
  • 3.52.1
  • 3.53.0
  • 3.54.0
  • 3.55.0
  • 3.55.1
  • 3.55.2
  • 3.55.3
  • 3.55.4
102 results
Show changes
Commits on Source (5)
Showing
with 384 additions and 247 deletions
<a name="v3.35.0"></a>
## [v3.35.0] - 2023-03-27
### Changes
- tidy and doc
### Documentation
- update
<a name="v3.34.0"></a>
## [v3.34.0] - 2023-03-27
### Add Features
......@@ -488,6 +497,7 @@
<a name="1.8.0"></a>
## 1.8.0 - 2021-08-15
[v3.35.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.34.0...v3.35.0
[v3.34.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.33.0...v3.34.0
[v3.33.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.32.0...v3.33.0
[v3.32.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.31.1...v3.32.0
......
{
"name": "@schukai/monster",
"version": "3.33.0",
"version": "3.34.0",
"description": "Monster is a simple library for creating fast, robust and lightweight websites.",
"keywords": [
"framework",
......
......@@ -19,27 +19,26 @@ export { buildMap, PARENT, assembleParts };
const PARENT = "^";
/**
* With the help of the function `buildMap()`, maps can be easily created from data objects.
* Maps can be easily created from data objects with the help of the function `buildMap()`.
*
* Either a simple definition `a.b.c` or a template `${a.b.c}` can be specified as the path.
* The path can be specified as either a simple definition a.b.c or a template ${a.b.c}.
* Key and value can be either a definition or a template. The key does not have to be defined.
*
* The templates determine the appearance of the keys and the value of the map. Either a single value
* `id` can be taken or a composite key `${id} ${name}` can be used.
* id can be taken or a composite key ${id} ${name} can be used.
*
* If you want to access values of the parent data set, you have to use the `^` character `${id} ${^.name}`.
* If you want to access values of the parent data set, you have to use the ^ character, for example ${id} ${^.name}.
*
* @externalExample ../../example/data/buildmap.mjs
* @param {*} subject
* @param {string|Monster.Data~exampleSelectorCallback} selector
* @param {string} [valueTemplate]
* @param {string} [keyTemplate]
* @param {Monster.Data~exampleFilterCallback} [filter]
* @return {*}
* @param {*} subject - The data object from which the map will be created
* @param {string|Monster.Data~exampleSelectorCallback} selector - The path to the data object, or a callback that returns a map.
* @param {string} [valueTemplate] - A template for the value of the map.
* @param {string} [keyTemplate] - A template for the key of the map.
* @param {Monster.Data~exampleFilterCallback} [filter] - A callback function to filter out values.
* @return {*} - The created map.
* @memberOf Monster.Data
* @throws {TypeError} value is neither a string nor a function
* @throws {TypeError} the selector callback must return a map
*/
* @throws {TypeError} - If the value is neither a string nor a function.
* @throws {TypeError} - If the selector callback does not return a map.
**/
function buildMap(subject, selector, valueTemplate, keyTemplate, filter) {
return assembleParts(subject, selector, filter, function (v, k, m) {
k = build(v, keyTemplate, k);
......@@ -49,13 +48,66 @@ function buildMap(subject, selector, valueTemplate, keyTemplate, filter) {
}
/**
* The assembleParts function is a private function that helps in building a map from a subject object based on a provided
* selector. The selector can either be a string or a callback function. This function is meant to be used as a
* helper function by other functions in the module.
*
* The function takes four parameters:
*
* subject: The subject object from which the map is to be built
* selector: The selector to determine the structure of the map. It can be a string or a callback function.
* filter (optional): A callback function that can be used to filter values based on some criteria.
* callback: A function to be called for each element in the map.
* If the selector parameter is a callback function, it is executed passing the subject as its argument,
* and the resulting value must be an instance of Map. Otherwise, if the selector parameter is a string,
* buildFlatMap is called to build a flat map with keys and values extracted from the subject object based on the selector.
*
* If the filter parameter is provided, it will be used to filter out certain elements from the map, based on some
* criteria. The callback will be passed the value, key, and map object, and if it returns false, the element will be skipped.
*
* For each element in the map, the callback function is called with the following parameters:
*
* v: The value of the element
* k: The key of the element
* m: The map object
* The function returns a new map with the processed values. If map is not an instance of Map, an empty map will be returned.
*
* Example Usage:
*
* ```javascript
* const obj = {
* name: "John",
* age: 30,
* address: {
* city: "New York",
* state: "NY",
* country: "USA",
* },
* };
*
* const selector = "address";
*
* const map = assembleParts(obj, selector, null, function (v, k, m) {
* this.set(k, v);
* });
*
* console.log(map);
* // Output: Map(3) {
* // "address.city" => "New York",
* // "address.state" => "NY",
* // "address.country" => "USA"
* // }
* ```
*
*
* @private
* @param {*} subject
* @param {string|Monster.Data~exampleSelectorCallback} selector
* @param {Monster.Data~exampleFilterCallback} [filter]
* @param {function} callback
* @return {Map}
* @throws {TypeError} selector is neither a string nor a function
* @param {*} subject - The subject object from which the map is to be built.
* @param {string|Monster.Data~exampleSelectorCallback} selector - The selector to determine the structure of the map. It can be a string or a callback function.
* @param {Monster.Data~exampleFilterCallback} [filter] - A callback function that can be used to filter values based on some criteria.
* @param {function} callback - A function to be called for each element in the map.
* @return {Map} - A new map with the processed values.
* @throws {TypeError} - When selector is neither a string nor a function.
* @memberOf Monster.Data
*/
function assembleParts(subject, selector, filter, callback) {
const result = new Map();
......
......@@ -33,19 +33,102 @@ const rootSymbol = Symbol("root");
*/
/**
* With the help of the function `buildTree()`, nodes can be easily created from data objects.
*
* @param {*} subject
* @param {string|Monster.Data~exampleSelectorCallback} selector
* @param {string} idKey
* @param {string} parentIDKey
* @param {buildTreeOptions} [options]
* @return {*}
* @memberOf Monster.Data
* @throws {TypeError} value is neither a string nor a function
* @throws {TypeError} the selector callback must return a map
* @throws {Error} the object has no value for the specified id
* Creates a tree structure from a given subject using a selector and specified ID and parent ID keys.
*
* The buildTree function is a powerful tool for creating tree-like data structures from plain JavaScript
* objects. It takes in four required parameters: the subject object that you want to turn into a tree, a
* selector that identifies which parts of the subject to use when building the tree, and two keys
* (idKey and parentIDKey) that specify which properties in the subject represent the unique identifiers
* and parent-child relationships between nodes in the tree.
*
* Optionally, you can also pass in an options object to further configure the behavior of the function,
* such as specifying which values should be treated as roots of the tree, or providing a custom filter
* function to only include certain nodes in the final output.
*
* The buildTree function works by first using the assembleParts helper function to extract the relevant
* parts of the subject based on the selector, and then iterates over the resulting map to create Node
* objects and organize them into parent-child relationships based on the values of the idKey and parentIDKey properties.
*
* The resulting NodeList represents the tree structure, with each Node object containing the original
* object data as well as additional metadata about its position in the tree. You can then use the childNodes
* property of each Node to access its children, or the parent property to access its parent.
*
* Overall, the buildTree function is a flexible and powerful way to transform flat data into hierarchical
* structures, and can be especially useful in scenarios such as displaying folder structures or
* visualizing complex data relationships.
*
* Let's say you have an array of data objects representing a file system directory structure, and you want
* to turn it into a tree-like structure where each node represents a folder or file, and child nodes
* represent the contents of the folder:
*
* ```javascript
* const fileSystem = [
* { id: 'folder1', name: 'Folder 1', type: 'folder', parent: null },
* { id: 'file1', name: 'File 1', type: 'file', parent: 'folder1' },
* { id: 'file2', name: 'File 2', type: 'file', parent: 'folder1' },
* { id: 'subfolder1', name: 'Subfolder 1', type: 'folder', parent: 'folder1' },
* { id: 'file3', name: 'File 3', type: 'file', parent: 'subfolder1' },
* { id: 'file4', name: 'File 4', type: 'file', parent: 'subfolder1' },
* { id: 'subfolder2', name: 'Subfolder 2', type: 'folder', parent: 'folder1' },
* { id: 'file5', name: 'File 5', type: 'file', parent: 'subfolder2' },
* { id: 'file6', name: 'File 6', type: 'file', parent: 'subfolder2' },
* { id: 'folder2', name: 'Folder 2', type: 'folder', parent: null },
* { id: 'file7', name: 'File 7', type: 'file', parent: 'folder2' },
* { id: 'file8', name: 'File 8', type: 'file', parent: 'folder2' },
* { id: 'subfolder3', name: 'Subfolder 3', type: 'folder', parent: 'folder2' },
* { id: 'file9', name: 'File 9', type: 'file', parent: 'subfolder3' },
* { id: 'file10', name: 'File 10', type: 'file', parent: 'subfolder3' },
* ];
*
* const tree = buildTree(fileSystem, 'id', 'id', 'parent', { rootReferences: [null] });
*
* console.log(tree.toString());
* ```
*
* The buildTree function takes in the array of data objects, as well as some configuration options specifying
* the keys to use for identifying nodes and their parent-child relationships. In this example, we use the id
* key to identify nodes, and the parent key to specify the parent of each node.
*
* The resulting tree object is a nested tree structure, where each node is an object representing a file or
* folder, and has child nodes representing its contents. The toString method of the tree object
* can be used to print out the tree in a readable format:
*
* ```markdown
* - Folder 1
* - File 1
* - File 2
* - Subfolder 1
* - File 3
* - File 4
* - Subfolder 2
* - File 5
* - File 6
* - Folder 2
* - File 7
* - File 8
* - Subfolder 3
* - File 9
* - File 10
* ```
*
* @memberof Monster.Data
*
* @param {*} subject - The object or array to build the tree from.
* @param {string|Monster.Data~exampleSelectorCallback} selector - Either a string to specify a property of each object to use as a selector, or a selector function to generate a map of objects.
* @param {string} idKey - The property key to use as the unique ID of each node.
* @param {string} parentIDKey - The property key to use as the parent ID of each node.
* @param {object} [options] - Additional options to modify the function behavior.
* @param {Array<*>} [options.rootReferences=[null, undefined]] - An array of values to treat as root references when creating the tree.
* @param {function} [options.filter] - A filter function to apply to each node.
*
* @return {*} The resulting tree structure as a NodeList.
*
* @throws {TypeError} selector is neither a string nor a function.
* @throws {TypeError} the selector callback must return a map.
* @throws {Error} the object has no value for the specified id.
*
* @license AGPLv3
*
* @since 1.26.0
*/
function buildTree(subject, selector, idKey, parentIDKey, options) {
......
......@@ -11,7 +11,6 @@ import { Datasource } from "../datasource.mjs";
export { DomStorage };
/**
* The DomStorage is a class that stores data in memory.
*
......@@ -53,7 +52,7 @@ class DomStorage extends Datasource {
},
write: {
selector: undefined,
}
},
});
}
......@@ -78,13 +77,12 @@ class DomStorage extends Datasource {
return new Promise((resolve, reject) => {
try {
let data = JSON.parse(storage.innerHTML);
self.set(data)
self.set(data);
resolve(data);
} catch (e) {
reject(e);
}
;
})
});
}
/**
......@@ -93,7 +91,6 @@ class DomStorage extends Datasource {
* @throws {Error} There are no storage element
*/
write() {
const self = this;
let selector = self.getOption("write.selector");
......@@ -113,10 +110,6 @@ class DomStorage extends Datasource {
} catch (e) {
reject(e);
}
})
});
}
}
......@@ -127,7 +127,8 @@ class RestAPI extends Server {
if (!init["method"]) init["method"] = "GET";
let callback = self.getOption("read.responseCallback");
if(!callback) callback = (obj) => {
if (!callback)
callback = (obj) => {
self.set(self.transformServerPayload.call(self, obj));
};
......@@ -199,7 +200,6 @@ function fetchData(init, key, callback) {
obj = JSON.parse(body);
response[rawDataSymbol] = obj;
} catch (e) {
if (body.length > 100) {
body = `${body.substring(0, 97)}...`;
......
......@@ -576,7 +576,6 @@ function transform(value) {
throw new Error("type not supported");
case "map":
map = new Map();
while (args.length > 0) {
......@@ -592,7 +591,6 @@ function transform(value) {
return map.get(value);
case "equals":
if (args.length === 0) {
throw new Error("missing value parameter");
}
......@@ -631,11 +629,10 @@ function transform(value) {
case "money":
case "currency":
try {
locale = getLocaleOfDocument();
} catch (e) {
throw new Error("unsupported locale or missing format (" + e.message + ")");
throw new Error(`unsupported locale or missing format (${e.message})`);
}
const currency = value.substring(0, 3);
......@@ -672,9 +669,8 @@ function transform(value) {
try {
locale = getLocaleOfDocument();
return date.toLocaleTimeString(locale);
} catch (e) {
throw new Error("unsupported locale or missing format (" + e.message + ")");
throw new Error(`unsupported locale or missing format (${e.message})`);
}
case "datetime":
......@@ -686,9 +682,8 @@ function transform(value) {
try {
locale = getLocaleOfDocument();
return date.toLocaleString(locale);
} catch (e) {
throw new Error("unsupported locale or missing format (" + e.message + ")");
throw new Error(`unsupported locale or missing format (${e.message})`);
}
case "date":
......@@ -700,12 +695,10 @@ function transform(value) {
try {
locale = getLocaleOfDocument();
return date.toLocaleDateString(locale);
} catch (e) {
throw new Error("unsupported locale or missing format (" + e.message + ")");
throw new Error(`unsupported locale or missing format (${e.message})`);
}
case "year":
date = new Date(value);
if (isNaN(date.getTime())) {
......
......@@ -286,7 +286,6 @@ class CustomElement extends HTMLElement {
};
}
/**
* This method updates the labels of the element.
* The labels are defined in the options object.
......@@ -315,7 +314,7 @@ class CustomElement extends HTMLElement {
if (isString(def)) {
const text = translations.getText(key, def);
if (text !== def) {
this.setOption("labels." + key, text);
this.setOption(`labels.${key}`, text);
}
continue;
} else if (isObject(def)) {
......@@ -327,14 +326,13 @@ class CustomElement extends HTMLElement {
throw new Error("Invalid labels definition");
}
if (text !== d) {
this.setOption("labels." + key + "." + k, text);
this.setOption(`labels.${key}.${k}`, text);
}
}
continue;
}
throw new Error("Invalid labels definition");
}
return this;
}
......@@ -352,7 +350,6 @@ class CustomElement extends HTMLElement {
throw new Error("the method getTag must be overwritten by the derived class.");
}
/**
* At this point a `CSSStyleSheet` object can be returned. If the environment does not
* support a constructor, then an object can also be built using the following detour.
......@@ -422,8 +419,7 @@ class CustomElement extends HTMLElement {
try {
value = new Pathfinder(this[internalSymbol].getRealSubject()["options"]).getVia(path);
} catch (e) {
}
} catch (e) {}
if (value === undefined) return defaultValue;
return value;
......@@ -493,8 +489,7 @@ class CustomElement extends HTMLElement {
try {
initShadowRoot.call(self);
elements = self.shadowRoot.childNodes;
} catch (e) {
}
} catch (e) {}
try {
initCSSStylesheet.call(this);
......@@ -545,8 +540,7 @@ class CustomElement extends HTMLElement {
* @return {void}
* @since 1.7.0
*/
disconnectedCallback() {
}
disconnectedCallback() {}
/**
* The custom element has been moved into a new document (e.g. someone called document.adoptNode(el)).
......@@ -554,8 +548,7 @@ class CustomElement extends HTMLElement {
* @return {void}
* @since 1.7.0
*/
adoptedCallback() {
}
adoptedCallback() {}
/**
* Called when an observed attribute has been added, removed, updated, or replaced. Also called for initial
......@@ -792,8 +785,7 @@ function parseOptionsJSON(data) {
try {
let dataUrl = parseDataURL(data);
data = dataUrl.content;
} catch (e) {
}
} catch (e) {}
try {
obj = JSON.parse(data);
......@@ -815,7 +807,6 @@ function initHtmlContent() {
} catch (e) {
let html = this.getOption("templates.main", "");
if (isString(html) && html.length > 0) {
const mapping = this.getOption("templateMapping", {});
if (isObject(mapping)) {
html = new Formatter(mapping).format(html);
......@@ -938,7 +929,7 @@ function initShadowRoot() {
*/
function registerCustomElement(element) {
validateFunction(element);
const customElements = getGlobalObject("customElements")
const customElements = getGlobalObject("customElements");
if (customElements === undefined) {
throw new Error("customElements is not supported.");
}
......
......@@ -5,21 +5,22 @@
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
*/
import {getWindow} from './util.mjs';
export {convertToPixels, getDeviceDPI}
import { getWindow } from "./util.mjs";
export { convertToPixels, getDeviceDPI };
/**
* Stores the DPI of the device.
*
* @private
* @returns {number}
* @type {number}
* @since 3.34.0
* @type {number|function}
*/
let CURRENT_DEVICE_DPI = function () {
let i = 0;
for (i = 56; i < 2000; i++) {
if (getWindow().matchMedia("(max-resolution: " + i + "dpi)").matches === true) {
if (getWindow().matchMedia(`(max-resolution: ${i}dpi)`).matches === true) {
return i;
}
}
......@@ -29,18 +30,19 @@ let CURRENT_DEVICE_DPI = function () {
/**
* Returns the DPI of the device.
*
* @since 3.34.0
* @memberOf Monster.DOM
* @returns {number}
*/
function getDeviceDPI() {
// only call the function once
if (typeof CURRENT_DEVICE_DPI === 'function') {
if (typeof CURRENT_DEVICE_DPI === "function") {
CURRENT_DEVICE_DPI = CURRENT_DEVICE_DPI();
}
return getWindow().devicePixelRatio * CURRENT_DEVICE_DPI;
}
/**
* Converts a CSS value to pixels.
*
......@@ -59,15 +61,15 @@ function getDeviceDPI() {
* - rem
* - %
*
* @param value
* @param parentElement
* @param fontSizeElement
* @param {string} value
* @param {HTMLElement} [parentElement=document.documentElement]
* @param {HTMLElement} [fontSizeElement=document.documentElement]
* @returns {number}
* @license AGPLv3
* @since 1.6.0
* @since 3.34.0
* @copyright schukai GmbH
* @memberOf Monster.DOM
* @throws {Error} Unsupported unit
* @memberOf Monster.DOM
*/
function convertToPixels(value, parentElement = document.documentElement, fontSizeElement = document.documentElement) {
......@@ -76,30 +78,28 @@ function convertToPixels(value, parentElement = document.documentElement, fontSi
const number = parseFloat(num);
const dpi = getDeviceDPI();
if (unit === 'px') {
if (unit === "px") {
return number;
} else if (unit === 'em') {
} else if (unit === "em") {
const fontSize = parseFloat(window.getComputedStyle(fontSizeElement).fontSize);
return number * fontSize;
} else if (unit === 'rem') {
} else if (unit === "rem") {
const rootFontSize = parseFloat(window.getComputedStyle(parentElement).fontSize);
return number * rootFontSize;
} else if (unit === '%') {
} else if (unit === "%") {
const parentWidth = parseFloat(window.getComputedStyle(parentElement).width);
return (number * parentWidth) / 100;
} else if (unit === 'in') {
} else if (unit === "in") {
return number * dpi;
} else if (unit === 'cm') {
} else if (unit === "cm") {
return (number * dpi) / 2.54;
} else if (unit === 'mm') {
} else if (unit === "mm") {
return (number * dpi) / 25.4;
} else if (unit === 'pt') {
} else if (unit === "pt") {
return (number * dpi) / 72;
} else if (unit === 'pc') {
} else if (unit === "pc") {
return (number * dpi) / 6;
} else {
throw new Error(`Unsupported unit: ${unit}`);
}
}
......@@ -74,14 +74,17 @@ class ResourceManager extends Base {
* @property {Array} resources.data=[] array with {@link Monster.DOM.Resource.Data} objects
*/
get internalDefaults() {
return Object.assign({}, {
return Object.assign(
{},
{
document: getGlobalObject("document"),
resources: {
scripts: [],
stylesheets: [],
data: [],
},
});
},
);
}
/**
......
......@@ -57,7 +57,6 @@ function getSlottedNodes(query, name) {
return result;
}
/**
* @private
* @param {String|undefined} query
......
......@@ -17,7 +17,7 @@ import {
ATTRIBUTE_UPDATER_INSERT_REFERENCE,
ATTRIBUTE_UPDATER_REMOVE,
ATTRIBUTE_UPDATER_REPLACE,
ATTRIBUTE_UPDATER_SELECT_THIS
ATTRIBUTE_UPDATER_SELECT_THIS,
} from "../dom/constants.mjs";
import { Base } from "../types/base.mjs";
......
......@@ -152,7 +152,6 @@ function getDocumentFragmentFromString(html) {
return template.content;
}
/**
* Recursively searches upwards from a given element to find an ancestor element
* with a specified ID, considering both normal DOM and shadow DOM.
......
......@@ -33,7 +33,6 @@ const translationsLinkSymbol = Symbol.for("@schukai/monster/i18n/translations@@l
* @see {@link https://datatracker.ietf.org/doc/html/rfc3066}
*/
class Provider extends BaseWithOptions {
/**
* This method is called by the `instanceof` operator.
* @returns {symbol}
......@@ -48,7 +47,6 @@ class Provider extends BaseWithOptions {
* @return {Promise}
*/
getTranslations(locale) {
if (locale === undefined) {
locale = getLocaleOfDocument();
}
......@@ -68,7 +66,6 @@ class Provider extends BaseWithOptions {
* @return {Provider}
*/
assignToElement(locale, element) {
if (locale === undefined) {
locale = getLocaleOfDocument();
}
......@@ -86,7 +83,6 @@ class Provider extends BaseWithOptions {
}
return this.getTranslations(locale).then((obj) => {
let translations = null;
if (hasObjectLink(element, translationsLinkSymbol)) {
const objects = getLinkedObjects(element, translationsLinkSymbol);
......@@ -102,15 +98,11 @@ class Provider extends BaseWithOptions {
}
translations.assignTranslations(obj);
} else {
addToObjectLink(element, translationsLinkSymbol, obj);
}
return obj;
});
}
}
......@@ -91,7 +91,6 @@ class Embed extends Provider {
}
return new Promise((resolve, reject) => {
if (this.translateElement === null) {
reject(new Error("Text not found"));
return;
......@@ -127,7 +126,6 @@ class Embed extends Provider {
});
}
/**
* Initializes the translations for the current document.
*
......@@ -137,7 +135,7 @@ class Embed extends Provider {
* @returns {Promise<unknown[]>}
*/
static assignTranslationsToElement(element) {
const d = getDocument()
const d = getDocument();
if (!(element instanceof HTMLElement)) {
element = d.querySelector("body");
......@@ -157,5 +155,4 @@ class Embed extends Provider {
return Promise.all(promises);
}
}
......@@ -15,7 +15,6 @@ import {validateInteger, validateObject, validateString} from "../types/validate
import { Locale, parseLocale } from "./locale.mjs";
import { translationsLinkSymbol } from "./provider.mjs";
export { Translations, getDocumentTranslations };
/**
......@@ -208,13 +207,13 @@ class Translations extends Base {
* @throws {Error} Cannot find element with translations. Add a translations object to the document.
* @throws {Error} This element has no translations.
* @throws {Error} Missing translations.
* @memberOf Monster.I18n
*/
function getDocumentTranslations(element) {
const d = getDocument()
const d = getDocument();
if (!(element instanceof HTMLElement)) {
element = d.querySelector('[' + ATTRIBUTE_OBJECTLINK + '~="' + translationsLinkSymbol.toString() + '"]');
element = d.querySelector(`[${ATTRIBUTE_OBJECTLINK}~="${translationsLinkSymbol.toString()}"]`);
if (element === null) {
throw new Error("Cannot find element with translations. Add a translations object to the document.");
}
......@@ -237,7 +236,4 @@ function getDocumentTranslations(element) {
}
throw new Error("Missing translations.");
}
export {generateRangeComparisonExpression}
export { generateRangeComparisonExpression };
/**
* Generates a comparison expression for a comma-separated string of ranges and single values.
* The `generateRangeComparisonExpression()` function is function that generates a string representation
* of a comparison expression based on a range of values. It takes three arguments:
*
* - expression (required): a string representation of a range of values in the format of start1-end1,start2-end2,value3....
* - valueName (required): a string representing the name of the value that is being compared to the range of values.
* - options (optional): an object containing additional options to customize the comparison expression.
*
* The generateRangeComparisonExpression() function returns a string representation of the comparison expression.
*
* ## Options
* The options parameter is an object that can have the following properties:
*
* urlEncode (boolean, default: false): if set to true, URL encodes the comparison operators.
* andOp (string, default: '&&'): the logical AND operator to use in the expression.
* orOp (string, default: '||'): the logical OR operator to use in the expression.
* eqOp (string, default: '=='): the equality operator to use in the expression.
* geOp (string, default: '>='): the greater than or equal to operator to use in the expression.
* leOp (string, default: '<='): the less than or equal to operator to use in the expression.
*
* Examples
*
* ```javascript
* const expression = '0-10,20-30';
* const valueName = 'age';
* const options = { urlEncode: true, andOp: 'and', orOp: 'or', eqOp: '=', geOp: '>=', leOp: '<=' };
* const comparisonExpression = generateRangeComparisonExpression(expression, valueName, options);
*
* console.log(comparisonExpression); // age%3E%3D0%20and%20age%3C%3D10%20or%20age%3E%3D20%20and%20age%3C%3D30
* ```
*
* In this example, the generateRangeComparisonExpression() function generates a string representation of the comparison
* expression for the expression and valueName parameters with the specified options. The resulting comparison
* expression is 'age>=0 and age<=10 or age>=20 and age<=30', URL encoded according to the urlEncode option.
*
* @param {string} expression - The string expression to generate the comparison for.
* @param {string} valueName - The name of the value to compare against.
* @param {Object} [options] - The optional parameters.
......@@ -13,33 +46,29 @@ export {generateRangeComparisonExpression}
* @param {string} [options.leOp='<='] - The comparison operator for less than or equal to to use.
* @returns {string} The generated comparison expression.
* @throws {Error} If the input is invalid.
* @memberOf Monster.Text
* @summary Generates a comparison expression based on a range of values.
*/
function generateRangeComparisonExpression(expression, valueName, options = {}) {
const {
urlEncode = false,
andOp = '&&',
orOp = '||',
eqOp = '==',
geOp = '>=',
leOp = '<=',
} = options;
const ranges = expression.split(',');
let comparison = '';
const { urlEncode = false, andOp = "&&", orOp = "||", eqOp = "==", geOp = ">=", leOp = "<=" } = options;
const ranges = expression.split(",");
let comparison = "";
for (let i = 0; i < ranges.length; i++) {
const range = ranges[i].trim();
if (range === '') {
if (range === "") {
throw new Error(`Invalid range '${range}'`);
} else if (range.includes('-')) {
const [start, end] = range.split('-').map(s => (s === '' ? null : parseFloat(s)));
} else if (range.includes("-")) {
const [start, end] = range.split("-").map((s) => (s === "" ? null : parseFloat(s)));
if ((start !== null && isNaN(start)) || (end !== null && isNaN(end))) {
throw new Error(`Invalid value in range '${range}'`);
}
if (start !== null && end !== null && start > end) {
throw new Error(`Invalid range '${range}'`);
}
const compStart = start !== null ? `${valueName}${urlEncode ? encodeURIComponent(geOp) : geOp}${start}` : '';
const compEnd = end !== null ? `${valueName}${urlEncode ? encodeURIComponent(leOp) : leOp}${end}` : '';
const compRange = `${compStart}${compStart && compEnd ? ` ${andOp} ` : ''}${compEnd}`;
const compStart =
start !== null ? `${valueName}${urlEncode ? encodeURIComponent(geOp) : geOp}${start}` : "";
const compEnd = end !== null ? `${valueName}${urlEncode ? encodeURIComponent(leOp) : leOp}${end}` : "";
const compRange = `${compStart}${compStart && compEnd ? ` ${andOp} ` : ""}${compEnd}`;
comparison += ranges.length > 1 ? `(${compRange})` : compRange;
} else {
const value = parseFloat(range);
......