From f487e8947216fdac6116a9392aaf532fd37a9929 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Wed, 21 Oct 2020 00:24:10 +0200 Subject: [PATCH] Added DomUtil.innerError() and code cleanup --- .../files/js/WoltLabSuite/Core/Dom/Util.js | 48 ++++++++++++++++-- .../files/ts/WoltLabSuite/Core/Dom/Util.ts | 50 +++++++++++++++++-- 2 files changed, 90 insertions(+), 8 deletions(-) diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Dom/Util.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Dom/Util.js index da13bbd283..526fca34ee 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Dom/Util.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Dom/Util.js @@ -198,7 +198,9 @@ define(["require", "exports", "../StringUtil"], function (require, exports, Stri */ setInnerHtml(element, innerHtml) { element.innerHTML = innerHtml; - let newScript, script, scripts = element.querySelectorAll('script'); + let newScript; + let script; + const scripts = element.querySelectorAll('script'); for (let i = 0, length = scripts.length; i < length; i++) { script = scripts[i]; newScript = document.createElement('script'); @@ -209,7 +211,7 @@ define(["require", "exports", "../StringUtil"], function (require, exports, Stri newScript.textContent = script.textContent; } element.appendChild(newScript); - script.parentNode.removeChild(script); + script.remove(); } }, /** @@ -308,7 +310,7 @@ define(["require", "exports", "../StringUtil"], function (require, exports, Stri while (element.childNodes.length) { parent.insertBefore(element.childNodes[0], element); } - element.parentNode.removeChild(element); + element.remove(); }, /** * Replaces an element by moving all child nodes into the new element @@ -323,7 +325,7 @@ define(["require", "exports", "../StringUtil"], function (require, exports, Stri newElement.appendChild(oldElement.childNodes[0]); } oldElement.parentNode.insertBefore(newElement, oldElement); - oldElement.parentNode.removeChild(oldElement); + oldElement.remove(); }, /** * Returns true if given element is the most left node of the ancestor, that is @@ -366,6 +368,44 @@ define(["require", "exports", "../StringUtil"], function (require, exports, Stri show(element) { element.style.removeProperty('display'); }, + /** + * Displays or removes an error message below the provided element. + */ + innerError(element, errorMessage, isHtml) { + const parent = element.parentNode; + if (parent === null) { + throw new Error('Only elements that have a parent element or document are valid.'); + } + if (typeof errorMessage !== 'string') { + if (!errorMessage) { + errorMessage = ''; + } + else { + throw new TypeError('The error message must be a string; `false`, `null` or `undefined` can be used as a substitute for an empty string.'); + } + } + let innerError = element.nextElementSibling; + if (innerError === null || innerError.nodeName !== 'SMALL' || !innerError.classList.contains('innerError')) { + if (errorMessage === '') { + innerError = null; + } + else { + innerError = document.createElement('small'); + innerError.className = 'innerError'; + parent.insertBefore(innerError, element.nextSibling); + } + } + if (errorMessage === '') { + if (innerError !== null) { + innerError.remove(); + innerError = null; + } + } + else { + innerError[isHtml ? 'innerHTML' : 'textContent'] = errorMessage; + } + return innerError; + }, }; // expose on window object for backward compatibility window.bc_wcfDomUtil = DomUtil; diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Dom/Util.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Dom/Util.ts index 1e5d4596c5..1d021a214a 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Dom/Util.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Dom/Util.ts @@ -213,7 +213,9 @@ const DomUtil = { setInnerHtml(element: Element, innerHtml: string): void { element.innerHTML = innerHtml; - let newScript, script, scripts = element.querySelectorAll('script'); + let newScript: HTMLScriptElement; + let script: HTMLScriptElement; + const scripts = element.querySelectorAll('script'); for (let i = 0, length = scripts.length; i < length; i++) { script = scripts[i]; newScript = document.createElement('script'); @@ -224,7 +226,7 @@ const DomUtil = { } element.appendChild(newScript); - script.parentNode.removeChild(script); + script.remove(); } }, @@ -341,7 +343,7 @@ const DomUtil = { parent.insertBefore(element.childNodes[0], element); } - element.parentNode.removeChild(element); + element.remove(); }, /** @@ -359,7 +361,7 @@ const DomUtil = { } oldElement.parentNode.insertBefore(newElement, oldElement); - oldElement.parentNode.removeChild(oldElement); + oldElement.remove(); }, /** @@ -409,6 +411,46 @@ const DomUtil = { show(element: HTMLElement): void { element.style.removeProperty('display'); }, + + /** + * Displays or removes an error message below the provided element. + */ + innerError(element: HTMLElement, errorMessage?: string | false | null, isHtml?: boolean): HTMLElement | null { + const parent = element.parentNode; + if (parent === null) { + throw new Error('Only elements that have a parent element or document are valid.'); + } + + if (typeof errorMessage !== 'string') { + if (!errorMessage) { + errorMessage = ''; + } else { + throw new TypeError('The error message must be a string; `false`, `null` or `undefined` can be used as a substitute for an empty string.'); + } + } + + let innerError = element.nextElementSibling; + if (innerError === null || innerError.nodeName !== 'SMALL' || !innerError.classList.contains('innerError')) { + if (errorMessage === '') { + innerError = null; + } else { + innerError = document.createElement('small'); + innerError.className = 'innerError'; + parent.insertBefore(innerError, element.nextSibling); + } + } + + if (errorMessage === '') { + if (innerError !== null) { + innerError.remove(); + innerError = null; + } + } else { + innerError![isHtml ? 'innerHTML' : 'textContent'] = errorMessage; + } + + return innerError as HTMLElement | null; + }, }; interface Dimensions { -- 2.20.1