diff --git a/source/components/datatable/datatable.mjs b/source/components/datatable/datatable.mjs index 4fb1f3695b8cbb1eb437e73a43d4479989444993..8094a0513fd6c14dd06284a349176ebc6e2d2f9b 100644 --- a/source/components/datatable/datatable.mjs +++ b/source/components/datatable/datatable.mjs @@ -290,7 +290,19 @@ class DataTable extends CustomElement { updateGrid.call(self); }); - this[resizeObserverSymbol].observe(this.parentNode); + requestAnimationFrame(() => { + + let parent = this.parentNode; + while(!(parent instanceof HTMLElement) && parent !== null) { + parent = parent.parentNode; + } + + if (parent instanceof HTMLElement) { + this[resizeObserverSymbol].observe(parent); + } + + + }); } /** diff --git a/source/components/host/call-button.mjs b/source/components/host/call-button.mjs index 1ca0e2013e48e1a11ecdf9b922e91a66484aad9b..c73a449aea3628c51a114137723268df53f7a6e3 100644 --- a/source/components/host/call-button.mjs +++ b/source/components/host/call-button.mjs @@ -12,21 +12,20 @@ * SPDX-License-Identifier: AGPL-3.0 */ -import { instanceSymbol } from "../../constants.mjs"; +import {instanceSymbol} from "../../constants.mjs"; import { - assembleMethodSymbol, - CustomElement, - registerCustomElement, + assembleMethodSymbol, + CustomElement, + registerCustomElement, } from "../../dom/customelement.mjs"; -import { CallButtonStyleSheet } from "./stylesheet/call-button.mjs"; -import { isArray, isObject, isFunction } from "../../types/is.mjs"; +import {CallButtonStyleSheet} from "./stylesheet/call-button.mjs"; +import {isArray, isObject, isFunction} from "../../types/is.mjs"; import { - findElementWithSelectorUpwards, - getDocument, + findElementWithSelectorUpwards, } from "../../dom/util.mjs"; -import { ATTRIBUTE_PREFIX } from "../../dom/constants.mjs"; +import {ATTRIBUTE_PREFIX} from "../../dom/constants.mjs"; -export { CallButton }; +export {CallButton}; /** * @private @@ -46,109 +45,73 @@ const ATTRIBUTE_CALL = `${ATTRIBUTE_PREFIX}call`; /** * The call button component is used to call a method of another element. * - * <img src="./images/call-button.png"> - * - * Dependencies: the system uses functions of the [monsterjs](https://monsterjs.org/) library - * - * You can create this control either by specifying the HTML tag <monster-call-button />` directly in the HTML or using - * Javascript via the `document.createElement('monster-call-button');` method. - * - * ```html - * <monster-call-button></monster-call-button> - * ``` - * - * Or you can create this CustomControl directly in Javascript: - * - * ```js - * import '@schukai/component-host/source/filter.mjs'; - * document.createElement('monster-call-button'); - * ``` - * - * The Body should have a class "hidden" to ensure that the styles are applied correctly. - * - * ```css - * body.hidden { - * visibility: hidden; - * } - * ``` - * - * @startuml call-button.png - * skinparam monochrome true - * skinparam shadowing false - * HTMLElement <|-- CustomElement - * CustomElement <|-- CallButton - * @enduml - * * @copyright schukai GmbH - * @summary A toggle button + * @summary A call button component that can call a method of another element. */ class CallButton extends CustomElement { - /** - * This method is called by the `instanceof` operator. - * @return {symbol} - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/component-host/call-button@@instance"); - } - - /** - * To set the options via the HTML tag, the attribute `data-monster-options` must be used. - * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control} - * - * The individual configuration values can be found in the table. - * - * @property {Object} templates Template definitions - * @property {string} templates.main Main template - */ - get defaults() { - const obj = Object.assign( - {}, - super.defaults, - { - templates: { - main: getTemplate(), - }, - references: { - callableSelector: undefined, - }, - - call: undefined, - - labels: { - button: "<slot>Toggle</slot>", - }, - }, - initOptionsFromArguments.call(this), - ); - - return obj; - } - - /** - * - * @return {string} - */ - static getTag() { - return "monster-call-button"; - } - - /** - * - * @return {CallButton} - */ - [assembleMethodSymbol]() { - super[assembleMethodSymbol](); - - initControlReferences.call(this); - initEventHandler.call(this); - } - - /** - * @return {Array} - */ - static getCSSStyleSheet() { - return [CallButtonStyleSheet]; - } + /** + * This method is called by the `instanceof` operator. + * @return {symbol} + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/component-host/call-button@@instance"); + } + + /** + * To set the options via the HTML tag, the attribute `data-monster-options` must be used. + * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control} + * + * The individual configuration values can be found in the table. + * + * @property {Object} templates Template definitions + * @property {string} templates.main Main template + */ + get defaults() { + return Object.assign( + {}, + super.defaults, + { + templates: { + main: getTemplate(), + }, + references: { + callableSelector: undefined, + }, + + call: undefined, + + labels: { + button: "<slot>Toggle</slot>", + }, + }, + initOptionsFromArguments.call(this), + ); + } + + /** + * + * @return {string} + */ + static getTag() { + return "monster-call-button"; + } + + /** + * @return {CallButton} + */ + [assembleMethodSymbol]() { + super[assembleMethodSymbol](); + + initControlReferences.call(this); + initEventHandler.call(this); + } + + /** + * @return {Array} + */ + static getCSSStyleSheet() { + return [CallButtonStyleSheet]; + } } /** @@ -156,14 +119,14 @@ class CallButton extends CustomElement { * @return {CallButton} */ function initControlReferences() { - if (!this.shadowRoot) { - throw new Error("no shadow-root is defined"); - } - - this[callButtonElementSymbol] = this.shadowRoot.querySelector( - "[data-monster-role=control]", - ); - return this; + if (!this.shadowRoot) { + throw new Error("no shadow-root is defined"); + } + + this[callButtonElementSymbol] = this.shadowRoot.querySelector( + "[data-monster-role=control]", + ); + return this; } /** @@ -173,26 +136,26 @@ function initControlReferences() { * @throws {Error} the datasource could not be initialized */ function initOptionsFromArguments() { - const options = {}; - const value = this.getAttribute(ATTRIBUTE_REFERENCE); - if (value) { - if (!isObject(options.references)) { - options.references = {}; - } - const selectors = value.split(","); - if (isArray(selectors) && selectors.length === 0) { - throw new TypeError("incorrect arguments passed for the datasource"); - } - - options.references.callableSelector = selectors; - } - - const call = this.getAttribute(ATTRIBUTE_CALL); - if (call) { - options.call = call; - } - - return options; + const options = {}; + const value = this.getAttribute(ATTRIBUTE_REFERENCE); + if (value) { + if (!isObject(options.references)) { + options.references = {}; + } + const selectors = value.split(","); + if (isArray(selectors) && selectors.length === 0) { + throw new TypeError("incorrect arguments passed for the datasource"); + } + + options.references.callableSelector = selectors; + } + + const call = this.getAttribute(ATTRIBUTE_CALL); + if (call) { + options.call = call; + } + + return options; } /** @@ -200,28 +163,28 @@ function initOptionsFromArguments() { * @throws {Error} The option references.callableSelector must be an array */ function initEventHandler() { - this[callButtonElementSymbol].addEventListener("click", (event) => { - event.preventDefault(); - - const selectors = this.getOption("references.callableSelector"); - if (!isArray(selectors)) { - throw new Error( - "The option references.callableSelector must be an array", - ); - } - - const call = this.getOption("call"); - if (!call) { - throw new Error("The option call must be defined"); - } - - for (const selector of selectors) { - const element = findElementWithSelectorUpwards(this, selector); - if (element instanceof HTMLElement && isFunction(element?.[call])) { - element[call](); - } - } - }); + this[callButtonElementSymbol].addEventListener("click", (event) => { + event.preventDefault(); + + const selectors = this.getOption("references.callableSelector"); + if (!isArray(selectors)) { + throw new Error( + "The option references.callableSelector must be an array", + ); + } + + const call = this.getOption("call"); + if (!call) { + throw new Error("The option call must be defined"); + } + + for (const selector of selectors) { + const element = findElementWithSelectorUpwards(this, selector); + if (element instanceof HTMLElement && isFunction(element?.[call])) { + element[call](); + } + } + }); } /** @@ -229,8 +192,8 @@ function initEventHandler() { * @return {string} */ function getTemplate() { - // language=HTML - return ` + // language=HTML + return ` <div data-monster-role="control" part="control" data-monster-attributes="class path:references.callableSelector | ?::hidden"> <a href="#" data-monster-role="call-button" data-monster-replace="path:labels.button"></a> diff --git a/source/components/host/config-manager.mjs b/source/components/host/config-manager.mjs index bd6b3d34991cb7f7b89866010f880894d3ab1605..3432802b59d3b1661910718696be445f033bb51d 100644 --- a/source/components/host/config-manager.mjs +++ b/source/components/host/config-manager.mjs @@ -172,6 +172,10 @@ class ConfigManager extends CustomElement { } } +/** + * @private + * @returns {Promise<unknown>} + */ function openDatabase() { const window = getWindow(); @@ -280,6 +284,12 @@ function deleteBlob(key) { }); } +/** + * @private + * @param key + * @param blob + * @returns {Promise<unknown>} + */ function setBlob(key, blob) { const store = getObjectStore.call(this, MODE_READ_WRITE); diff --git a/source/components/host/host.mjs b/source/components/host/host.mjs index 78dd920bf5d914a643fc0b2b028be5b794ba86a3..3c70a9b0e7987fbab0eff1adb3bf09c7ca6d6b50 100644 --- a/source/components/host/host.mjs +++ b/source/components/host/host.mjs @@ -71,43 +71,10 @@ const resourceManagerSymbol = Symbol("resourceManager"); /** * The Host component is used to encapsulate the content of a web app. * - * <img src="./images/host.png"> - * - * Dependencies: the system uses functions of the [monsterjs](https://monsterjs.org/) library - * - * You can create this control either by specifying the HTML tag <monster-host />` directly in the HTML or using - * Javascript via the `document.createElement('monster-host');` method. - * - * ```html - * <monster-host></monster-host> - * ``` - * - * Or you can create this CustomControl directly in Javascript: - * - * ```js - * import '@schukai/component-state/source/host.mjs'; - * document.createElement('monster-host'); - * ``` - * - * The Body should have a class "hidden" to ensure that the styles are applied correctly. - * - * ```css - * body.hidden { - * visibility: hidden; - * } - * ``` - * - * @startuml host.png - * skinparam monochrome true - * skinparam shadowing false - * HTMLElement <|-- CustomElement - * CustomElement <|-- Host - * @enduml - * * @copyright schukai GmbH * @summary A simple host component - * @fires Monster.Components.Host.Host#monster-host-connected - * @fires Monster.Components.Host.Host#monster-host-disconnected + * @fires monster-host-connected + * @fires monster-host-disconnected */ class Host extends CustomElement { /** @@ -119,9 +86,6 @@ class Host extends CustomElement { } /** - * To set the options via the HTML tag, the attribute `data-monster-options` must be used. - * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control} - * * The individual configuration values can be found in the table. * * @property {Object} templates Template definitions @@ -147,6 +111,10 @@ class Host extends CustomElement { return this[configManagerElementSymbol].getConfig(key); } + /** + * @param {string} key + * @returns {*} + */ hasConfig(key) { if (this[configManagerElementSymbol] instanceof HTMLElement === false) { throw new Error("There is no config manager element"); @@ -154,6 +122,11 @@ class Host extends CustomElement { return this[configManagerElementSymbol].hasConfig(key); } + /** + * + * @param {key} key + * @returns {*} + */ deleteConfig(key) { if (this[configManagerElementSymbol] instanceof HTMLElement === false) { throw new Error("There is no config manager element"); @@ -177,7 +150,7 @@ class Host extends CustomElement { /** * @private - * @fires Monster.Components.Host.Host#monster-host-connected + * @fires Host#monster-host-connected */ connectedCallback() { super.connectedCallback(); @@ -199,7 +172,7 @@ class Host extends CustomElement { /** * @private - * @fires Monster.Components.Host.Host#monster-host-disconnected + * @fires Host#monster-host-disconnected */ disconnectedCallback() { super.disconnectedCallback(); @@ -231,7 +204,7 @@ class Host extends CustomElement { /** * - * @return {Monster.Components.Host.Host} + * @return {Host} */ [assembleMethodSymbol]() { this[promisesSymbol] = []; @@ -302,7 +275,7 @@ class Host extends CustomElement { /** * - * @return {Monster.Components.Host.Host} + * @return {Host} * @throws {Error} There is no overlay element defined. */ toggleOverlay() { @@ -341,7 +314,6 @@ class Host extends CustomElement { } /** - * * @return {string} */ static getTag() { @@ -356,8 +328,7 @@ class Host extends CustomElement { } /** - * - * @return {Monster.I18n.Locale} + * @return {Locale} */ get locale() { return getLocaleOfDocument(); @@ -402,6 +373,9 @@ function initControlReferences() { ); } +/** + * @private + */ function initTranslations() { if (isIterable(this[promisesSymbol]) === false) { this[promisesSymbol] = []; diff --git a/source/components/host/overlay.mjs b/source/components/host/overlay.mjs index d10823f0e3bc75afa3aa2d036383b88953f95243..3fb2bff2a0acd5e017b36f29a1c549054657bb28 100644 --- a/source/components/host/overlay.mjs +++ b/source/components/host/overlay.mjs @@ -67,40 +67,6 @@ const ATTRIBUTE_VALUE_OVERLAY_OPEN = "overlay-open"; /** * The Overlay component is used to show an overlay and a button to open the overlay. * - * <img src="./images/overlay.png"> - * - * Dependencies: the system uses functions of the [monsterjs](https://monsterjs.org/) library - * - * You can create this control either by specifying the HTML tag <monster-overlay />` directly in the HTML or using - * Javascript via the `document.createElement('monster-overlay');` method. - * - * ```html - * <monster-overlay></monster-overlay> - * ``` - * - * Or you can create this CustomControl directly in Javascript: - * - * ```js - * import '@schukai/component-state/source/overlay.mjs'; - * document.createElement('monster-overlay'); - * ``` - * - * The Body should have a class "hidden" to ensure that the styles are applied correctly. - * - * ```css - * body.hidden { - * visibility: hidden; - * } - * ``` - * - * @startuml overlay.png - * skinparam monochrome true - * skinparam shadowing false - * HTMLElement <|-- CustomElement - * CustomElement <|-- CustomControl - * CustomControl <|-- Overlay - * @enduml - * * @copyright schukai GmbH * @summary A simple overlay component * @fires monster-overlay-before-open diff --git a/source/components/host/toggle-button.mjs b/source/components/host/toggle-button.mjs index e17dd2e4346708935c6e497f7ae28a3a4f3e12b3..84eebc365f156f3c3501b8cbb1915283edd7ffdb 100644 --- a/source/components/host/toggle-button.mjs +++ b/source/components/host/toggle-button.mjs @@ -19,41 +19,7 @@ import { CallButton } from "./call-button.mjs"; export { ToggleButton }; /** - * The Toggle Button component is used toggle a other element witch has a method called toggle. - * - * <img src="./images/toggle-button.png"> - * - * Dependencies: the system uses functions of the [monsterjs](https://monsterjs.org/) library - * - * You can create this control either by specifying the HTML tag <monster-toggle-button />` directly in the HTML or using - * Javascript via the `document.createElement('monster-toggle-button');` method. - * - * ```html - * <monster-toggle-button></monster-toggle-button> - * ``` - * - * Or you can create this CustomControl directly in Javascript: - * - * ```js - * import '@schukai/component-host/source/filter.mjs'; - * document.createElement('monster-toggle-button'); - * ``` - * - * The Body should have a class "hidden" to ensure that the styles are applied correctly. - * - * ```css - * body.hidden { - * visibility: hidden; - * } - * ``` - * - * @startuml toggle-button.png - * skinparam monochrome true - * skinparam shadowing false - * HTMLElement <|-- CustomElement - * CustomElement <|-- CallButton - * CallButton <|-- ToggleButton - * @enduml + * The Toggle Button component is used toggle a other element wich has a method called toggle. * * @copyright schukai GmbH * @summary A toggle button diff --git a/source/components/host/viewer.mjs b/source/components/host/viewer.mjs index 52ae3bb8745ca9446faa9d2c04fb27371c9ad111..97a0a79e8ec80f5751917e6e16559168f802e543 100644 --- a/source/components/host/viewer.mjs +++ b/source/components/host/viewer.mjs @@ -34,32 +34,6 @@ const viewerElementSymbol = Symbol("viewerElement"); /** * The Viewer component is used to show a PDF, HTML or Image. * - * <img src="./images/viewer.png"> - * - * Dependencies: the system uses functions of the [monsterjs](https://monsterjs.org/) library - * - * You can create this control either by specifying the HTML tag <monster-viewer />` directly in the HTML or using - * Javascript via the `document.createElement('monster-viewer');` method. - * - * ```html - * <monster-viewer></monster-viewer> - * ``` - * - * Or you can create this CustomControl directly in Javascript: - * - * ```js - * import '@schukai/monster/components/host/viewer.mjs'; - * document.createElement('monster-viewer'); - * ``` - * - * @startuml viewer.png - * skinparam monochrome true - * skinparam shadowing false - * HTMLElement <|-- CustomElement - * CustomElement <|-- CustomControl - * CustomControl <|-- Viewer - * @enduml - * * @copyright schukai GmbH * @summary A simple viewer component */ @@ -96,6 +70,11 @@ class Viewer extends CustomElement { }); } + /** + * + * @param html + * @returns {Viewer} + */ setContent(html) { this.setOption("content", html); return this; @@ -208,7 +187,7 @@ class Viewer extends CustomElement { /** * - * @return {Monster.Components.Host.Viewer} + * @return {Viewer} */ [assembleMethodSymbol]() { super[assembleMethodSymbol]();