'use strict';
/**
* @author schukai GmbH
*/
import {getGlobalObject} from "../types/global.js";
import {Monster, validateFunction} from "../types/validate.js";
/**
* To define a new HTML element we need the power of CustomElement
*
* you can call the method via the monster namespace `new Monster.DOM.Element()`.
*
* important: after defining a `CustomElement`, the `registerCustomElement` method must be called
* with the new class name. only then will the tag defined via the `getTag` method be made known to the DOM.
*
* ```
* <script type="module">
* import {CustomElement} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.7.0/dist/modules/dom/customelement.js';
* console.log(new Monster.DOM.CustomElement())
* </script>
* ```
*
* Alternatively, you can also integrate this function individually.
*
* ```
* <script type="module">
* import {CustomElement} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.7.0/dist/modules/dom/customelement.js';
* console.log(new CustomElement())
* </script>
* ```
*
* ## Styling
*
* For optimal display of custom-elements the pseudo-class :defined can be used.
*
* ```html
* <style>
*
* my-custom-element:not(:defined) {
* display: none;
* }
*
* my-custom-element:defined {
* display: flex;
* }
*
* </style>
* ```
*
* * @example
* // returns 2
* globalNS.method1(5, 10);
* @example
* // returns 3
* globalNS.method(5, 15);
*
* @see https://github.com/WICG/webcomponents
* @see https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements
* @since 1.7.0
* @copyright schukai GmbH
* @memberOf Monster/DOM
*/
class CustomElement extends HTMLElement {
/**
*
*/
constructor() {
super();
}
/**
* Called every time the element is inserted into the DOM. Useful for running setup code, such as
* fetching resources or rendering. Generally, you should try to delay work until this time.
*
* @return {void}
*/
connectedCallback() {
}
/**
* Called every time the element is removed from the DOM. Useful for running clean up code.
*
* @return {void}
*/
disconnectedCallback() {
}
/**
* The custom element has been moved into a new document (e.g. someone called document.adoptNode(el)).
*
* @return {void}
*/
adoptedCallback() {
}
/**
* Called when an observed attribute has been added, removed, updated, or replaced. Also called for initial
* values when an element is created by the parser, or upgraded. Note: only attributes listed in the observedAttributes property will receive this callback.
*
* @param {string} attrName
* @param {string} oldVal
* @param {string} newVal
* @return {void}
*/
attributeChangedCallback(attrName, oldVal, newVal) {
}
/**
* there is no check on the name by this class. the developer is responsible for assigning an appropriate tag.
* if the name is not valid, registerCustomElement() will issue an erro
*
* @link https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
* @return {string}
* @throws {Error} the method getTag must be overwritten by the derived class.
*/
static getTag() {
throw new Error("the method getTag must be overwritten by the derived class.");
}
}
/**
* this method registers a new element. the string returned by `CustomElement.getTag()` is used as the tag.
*
* @param {CustomElement} element
* @return {void}
* @since 1.7.0
* @copyright schukai GmbH
* @memberOf Monster/DOM
* @throws {DOMException} Failed to execute 'define' on 'CustomElementRegistry': is not a valid custom element name
*/
function registerCustomElement(element) {
validateFunction(element);
let tag = element.getTag();
getGlobalObject('customElements').define(element.getTag(), element);
return;
}
Monster.assignToNamespace('Monster.DOM', CustomElement, registerCustomElement);
export {Monster, registerCustomElement, CustomElement}