|
- "use strict";
- var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- const Element_1 = __importDefault(require("../element/Element"));
- const CSSStyleDeclaration_1 = __importDefault(require("../../css/declaration/CSSStyleDeclaration"));
- const FocusEvent_1 = __importDefault(require("../../event/events/FocusEvent"));
- const PointerEvent_1 = __importDefault(require("../../event/events/PointerEvent"));
- const DatasetUtility_1 = __importDefault(require("./DatasetUtility"));
- const NodeTypeEnum_1 = __importDefault(require("../node/NodeTypeEnum"));
- const DOMException_1 = __importDefault(require("../../exception/DOMException"));
- /**
- * HTML Element.
- *
- * Reference:
- * https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.
- */
- class HTMLElement extends Element_1.default {
- constructor() {
- super(...arguments);
- this.accessKey = '';
- this.accessKeyLabel = '';
- this.contentEditable = 'inherit';
- this.isContentEditable = false;
- this.offsetHeight = 0;
- this.offsetWidth = 0;
- this.offsetLeft = 0;
- this.offsetTop = 0;
- this.clientHeight = 0;
- this.clientWidth = 0;
- this._style = null;
- this._dataset = null;
- // Events
- this.oncopy = null;
- this.oncut = null;
- this.onpaste = null;
- this.oninvalid = null;
- this.onanimationcancel = null;
- this.onanimationend = null;
- this.onanimationiteration = null;
- this.onanimationstart = null;
- this.onbeforeinput = null;
- this.oninput = null;
- this.onchange = null;
- this.ongotpointercapture = null;
- this.onlostpointercapture = null;
- this.onpointercancel = null;
- this.onpointerdown = null;
- this.onpointerenter = null;
- this.onpointerleave = null;
- this.onpointermove = null;
- this.onpointerout = null;
- this.onpointerover = null;
- this.onpointerup = null;
- this.ontransitioncancel = null;
- this.ontransitionend = null;
- this.ontransitionrun = null;
- this.ontransitionstart = null;
- }
- /**
- * Returns tab index.
- *
- * @returns Tab index.
- */
- get tabIndex() {
- const tabIndex = this.getAttributeNS(null, 'tabindex');
- return tabIndex !== null ? Number(tabIndex) : -1;
- }
- /**
- * Returns tab index.
- *
- * @param tabIndex Tab index.
- */
- set tabIndex(tabIndex) {
- if (tabIndex === -1) {
- this.removeAttributeNS(null, 'tabindex');
- }
- else {
- this.setAttributeNS(null, 'tabindex', String(tabIndex));
- }
- }
- /**
- * Returns inner text, which is the rendered appearance of text.
- *
- * @see https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute
- * @returns Inner text.
- */
- get innerText() {
- if (!this.isConnected) {
- return this.textContent;
- }
- let result = '';
- for (const childNode of this.childNodes) {
- if (childNode.nodeType === NodeTypeEnum_1.default.elementNode) {
- const childElement = childNode;
- const computedStyle = this.ownerDocument.defaultView.getComputedStyle(childElement);
- if (childElement.tagName !== 'SCRIPT' && childElement.tagName !== 'STYLE') {
- const display = computedStyle.display;
- if (display !== 'none') {
- const textTransform = computedStyle.textTransform;
- if ((display === 'block' || display === 'flex') && result) {
- result += '\n';
- }
- let text = childElement.innerText;
- switch (textTransform) {
- case 'uppercase':
- text = text.toUpperCase();
- break;
- case 'lowercase':
- text = text.toLowerCase();
- break;
- case 'capitalize':
- text = text.replace(/(^|\s)\S/g, (l) => l.toUpperCase());
- break;
- }
- result += text;
- }
- }
- }
- else if (childNode.nodeType === NodeTypeEnum_1.default.textNode) {
- result += childNode.textContent.replace(/[\n\r]/, '');
- }
- }
- return result;
- }
- /**
- * Sets the inner text, which is the rendered appearance of text.
- *
- * @see https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute
- * @param innerText Inner text.
- */
- set innerText(text) {
- for (const child of this.childNodes.slice()) {
- this.removeChild(child);
- }
- const texts = text.split(/[\n\r]/);
- for (let i = 0, max = texts.length; i < max; i++) {
- if (i !== 0) {
- this.appendChild(this.ownerDocument.createElement('br'));
- }
- this.appendChild(this.ownerDocument.createTextNode(texts[i]));
- }
- }
- /**
- * Returns outer text.
- *
- * @see https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute
- * @returns HTML.
- */
- get outerText() {
- return this.innerText;
- }
- /**
- * Sets outer text.
- *
- * @see https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute
- * @param text Text.
- */
- set outerText(text) {
- if (!this.parentNode) {
- throw new DOMException_1.default("Failed to set the 'outerHTML' property on 'Element': This element has no parent node.");
- }
- const texts = text.split(/[\n\r]/);
- for (let i = 0, max = texts.length; i < max; i++) {
- if (i !== 0) {
- this.parentNode.insertBefore(this.ownerDocument.createElement('br'), this);
- }
- this.parentNode.insertBefore(this.ownerDocument.createTextNode(texts[i]), this);
- }
- this.parentNode.removeChild(this);
- }
- /**
- * Returns style.
- *
- * @returns Style.
- */
- get style() {
- if (!this._style) {
- this._style = new CSSStyleDeclaration_1.default(this);
- }
- return this._style;
- }
- /**
- * Sets style.
- *
- * @param cssText Style as text.
- * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style#setting_styles
- */
- set style(cssText) {
- this.style.cssText = typeof cssText === 'string' ? cssText : '';
- }
- /**
- * Returns data set.
- *
- * @returns Data set.
- */
- get dataset() {
- if (this._dataset) {
- return this._dataset;
- }
- const dataset = {};
- const attributes = this._attributes;
- for (const name of Object.keys(attributes)) {
- if (name.startsWith('data-')) {
- const key = DatasetUtility_1.default.kebabToCamelCase(name.replace('data-', ''));
- dataset[key] = attributes[name].value;
- }
- }
- // Documentation for Proxy:
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
- this._dataset = new Proxy(dataset, {
- get: (dataset, key) => {
- const name = 'data-' + DatasetUtility_1.default.camelCaseToKebab(key);
- if (this._attributes[name]) {
- dataset[key] = this._attributes[name].value;
- return this._attributes[name].value;
- }
- if (dataset[key] !== undefined) {
- delete dataset[key];
- }
- return undefined;
- },
- set: (dataset, key, value) => {
- this.setAttribute('data-' + DatasetUtility_1.default.camelCaseToKebab(key), value);
- dataset[key] = value;
- return true;
- },
- deleteProperty: (dataset, key) => {
- const name = 'data-' + DatasetUtility_1.default.camelCaseToKebab(key);
- const result1 = delete attributes[name];
- const result2 = delete dataset[key];
- return result1 && result2;
- },
- ownKeys: (dataset) => {
- // According to Mozilla we have to update the dataset object (target) to contain the same keys as what we return:
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/ownKeys
- // "The result List must contain the keys of all non-configurable own properties of the target object."
- const keys = [];
- const deleteKeys = [];
- for (const name of Object.keys(attributes)) {
- if (name.startsWith('data-')) {
- const key = DatasetUtility_1.default.kebabToCamelCase(name.replace('data-', ''));
- keys.push(key);
- dataset[key] = attributes[name].value;
- if (!dataset[key]) {
- deleteKeys.push(key);
- }
- }
- }
- for (const key of deleteKeys) {
- delete dataset[key];
- }
- return keys;
- },
- has: (_dataset, key) => {
- return !!attributes['data-' + DatasetUtility_1.default.camelCaseToKebab(key)];
- }
- });
- return this._dataset;
- }
- /**
- * Returns direction.
- *
- * @returns Direction.
- */
- get dir() {
- return this.getAttributeNS(null, 'dir') || '';
- }
- /**
- * Returns direction.
- *
- * @param direction Direction.
- */
- set dir(direction) {
- this.setAttributeNS(null, 'dir', direction);
- }
- /**
- * Returns hidden.
- *
- * @returns Hidden.
- */
- get hidden() {
- return this.getAttributeNS(null, 'hidden') !== null;
- }
- /**
- * Returns hidden.
- *
- * @param hidden Hidden.
- */
- set hidden(hidden) {
- if (!hidden) {
- this.removeAttributeNS(null, 'hidden');
- }
- else {
- this.setAttributeNS(null, 'hidden', '');
- }
- }
- /**
- * Returns language.
- *
- * @returns Language.
- */
- get lang() {
- return this.getAttributeNS(null, 'lang') || '';
- }
- /**
- * Returns language.
- *
- * @param language Language.
- */
- set lang(lang) {
- this.setAttributeNS(null, 'lang', lang);
- }
- /**
- * Returns title.
- *
- * @returns Title.
- */
- get title() {
- return this.getAttributeNS(null, 'title') || '';
- }
- /**
- * Returns title.
- *
- * @param title Title.
- */
- set title(title) {
- this.setAttributeNS(null, 'title', title);
- }
- /**
- * Triggers a click event.
- */
- click() {
- const event = new PointerEvent_1.default('click', {
- bubbles: true,
- composed: true
- });
- event._target = this;
- event._currentTarget = this;
- this.dispatchEvent(event);
- }
- /**
- * Triggers a blur event.
- */
- blur() {
- if (this.ownerDocument['_activeElement'] !== this || !this.isConnected) {
- return;
- }
- this.ownerDocument['_activeElement'] = null;
- this.dispatchEvent(new FocusEvent_1.default('blur', {
- bubbles: false,
- composed: true
- }));
- this.dispatchEvent(new FocusEvent_1.default('focusout', {
- bubbles: true,
- composed: true
- }));
- }
- /**
- * Triggers a focus event.
- */
- focus() {
- if (this.ownerDocument['_activeElement'] === this || !this.isConnected) {
- return;
- }
- if (this.ownerDocument['_activeElement'] !== null) {
- this.ownerDocument['_activeElement'].blur();
- }
- this.ownerDocument['_activeElement'] = this;
- this.dispatchEvent(new FocusEvent_1.default('focus', {
- bubbles: false,
- composed: true
- }));
- this.dispatchEvent(new FocusEvent_1.default('focusin', {
- bubbles: true,
- composed: true
- }));
- }
- /**
- * @override
- */
- setAttributeNode(attribute) {
- const replacedAttribute = super.setAttributeNode(attribute);
- if (attribute.name === 'style' && this._style) {
- this._style.cssText = attribute.value;
- }
- return replacedAttribute;
- }
- /**
- * @override
- */
- removeAttributeNode(attribute) {
- super.removeAttributeNode(attribute);
- if (attribute.name === 'style' && this._style) {
- this._style.cssText = '';
- }
- return attribute;
- }
- /**
- * @override
- */
- cloneNode(deep = false) {
- const clone = super.cloneNode(deep);
- clone.accessKey = this.accessKey;
- clone.accessKeyLabel = this.accessKeyLabel;
- clone.contentEditable = this.contentEditable;
- clone.isContentEditable = this.isContentEditable;
- if (this._style) {
- clone.style.cssText = this._style.cssText;
- }
- return clone;
- }
- }
- exports.default = HTMLElement;
- //# sourceMappingURL=HTMLElement.js.map
|