/**
* Provides helper functions to traverse the DOM.
- *
- * @author Alexander Ebert
- * @copyright 2001-2019 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module Dom/Traverse (alias)
- * @module WoltLabSuite/Core/Dom/Traverse
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2019 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module Dom/Traverse (alias)
+ * @module WoltLabSuite/Core/Dom/Traverse
*/
-define([], function() {
- "use strict";
-
- /** @const */ var NONE = 0;
- /** @const */ var SELECTOR = 1;
- /** @const */ var CLASS_NAME = 2;
- /** @const */ var TAG_NAME = 3;
-
- var _probe = [
- function(el, none) { return true; },
- function(el, selector) { return el.matches(selector); },
- function(el, className) { return el.classList.contains(className); },
- function(el, tagName) { return el.nodeName === tagName; }
- ];
-
- var _children = function(el, type, value) {
- if (!(el instanceof Element)) {
- throw new TypeError("Expected a valid element as first argument.");
- }
-
- var children = [];
-
- for (var i = 0; i < el.childElementCount; i++) {
- if (_probe[type](el.children[i], value)) {
- children.push(el.children[i]);
- }
- }
-
- return children;
- };
-
- var _parent = function(el, type, value, untilElement) {
- if (!(el instanceof Element)) {
- throw new TypeError("Expected a valid element as first argument.");
- }
-
- el = el.parentNode;
-
- while (el instanceof Element) {
- if (el === untilElement) {
- return null;
- }
-
- if (_probe[type](el, value)) {
- return el;
- }
-
- el = el.parentNode;
- }
-
- return null;
- };
-
- var _sibling = function(el, siblingType, type, value) {
- if (!(el instanceof Element)) {
- throw new TypeError("Expected a valid element as first argument.");
- }
-
- if (el instanceof Element) {
- if (el[siblingType] !== null && _probe[type](el[siblingType], value)) {
- return el[siblingType];
- }
- }
-
- return null;
- };
-
- /**
- * @exports WoltLabSuite/Core/Dom/Traverse
- */
- return {
- /**
- * Examines child elements and returns the first child matching the given selector.
- *
- * @param {Element} el element
- * @param {string} selector CSS selector to match child elements against
- * @return {(Element|null)} null if there is no child node matching the selector
- */
- childBySel: function(el, selector) {
- return _children(el, SELECTOR, selector)[0] || null;
- },
-
- /**
- * Examines child elements and returns the first child that has the given CSS class set.
- *
- * @param {Element} el element
- * @param {string} className CSS class name
- * @return {(Element|null)} null if there is no child node with given CSS class
- */
- childByClass: function(el, className) {
- return _children(el, CLASS_NAME, className)[0] || null;
- },
-
- /**
- * Examines child elements and returns the first child which equals the given tag.
- *
- * @param {Element} el element
- * @param {string} tagName element tag name
- * @return {(Element|null)} null if there is no child node which equals given tag
- */
- childByTag: function(el, tagName) {
- return _children(el, TAG_NAME, tagName)[0] || null;
- },
-
- /**
- * Examines child elements and returns all children matching the given selector.
- *
- * @param {Element} el element
- * @param {string} selector CSS selector to match child elements against
- * @return {array<Element>} list of children matching the selector
- */
- childrenBySel: function(el, selector) {
- return _children(el, SELECTOR, selector);
- },
-
- /**
- * Examines child elements and returns all children that have the given CSS class set.
- *
- * @param {Element} el element
- * @param {string} className CSS class name
- * @return {array<Element>} list of children with the given class
- */
- childrenByClass: function(el, className) {
- return _children(el, CLASS_NAME, className);
- },
-
- /**
- * Examines child elements and returns all children which equal the given tag.
- *
- * @param {Element} el element
- * @param {string} tagName element tag name
- * @return {array<Element>} list of children equaling the tag name
- */
- childrenByTag: function(el, tagName) {
- return _children(el, TAG_NAME, tagName);
- },
-
- /**
- * Examines parent nodes and returns the first parent that matches the given selector.
- *
- * @param {Element} el child element
- * @param {string} selector CSS selector to match parent nodes against
- * @param {Element=} untilElement stop when reaching this element
- * @return {(Element|null)} null if no parent node matched the selector
- */
- parentBySel: function(el, selector, untilElement) {
- return _parent(el, SELECTOR, selector, untilElement);
- },
-
- /**
- * Examines parent nodes and returns the first parent that has the given CSS class set.
- *
- * @param {Element} el child element
- * @param {string} className CSS class name
- * @param {Element=} untilElement stop when reaching this element
- * @return {(Element|null)} null if there is no parent node with given class
- */
- parentByClass: function(el, className, untilElement) {
- return _parent(el, CLASS_NAME, className, untilElement);
- },
-
- /**
- * Examines parent nodes and returns the first parent which equals the given tag.
- *
- * @param {Element} el child element
- * @param {string} tagName element tag name
- * @param {Element=} untilElement stop when reaching this element
- * @return {(Element|null)} null if there is no parent node of given tag type
- */
- parentByTag: function(el, tagName, untilElement) {
- return _parent(el, TAG_NAME, tagName, untilElement);
- },
-
- /**
- * Returns the next element sibling.
- *
- * @param {Element} el element
- * @return {(Element|null)} null if there is no next sibling element
- */
- next: function(el) {
- return _sibling(el, 'nextElementSibling', NONE, null);
- },
-
- /**
- * Returns the next element sibling that matches the given selector.
- *
- * @param {Element} el element
- * @param {string} selector CSS selector to match parent nodes against
- * @return {(Element|null)} null if there is no next sibling element or it does not match the selector
- */
- nextBySel: function(el, selector) {
- return _sibling(el, 'nextElementSibling', SELECTOR, selector);
- },
-
- /**
- * Returns the next element sibling with given CSS class.
- *
- * @param {Element} el element
- * @param {string} className CSS class name
- * @return {(Element|null)} null if there is no next sibling element or it does not have the class set
- */
- nextByClass: function(el, className) {
- return _sibling(el, 'nextElementSibling', CLASS_NAME, className);
- },
-
- /**
- * Returns the next element sibling with given CSS class.
- *
- * @param {Element} el element
- * @param {string} tagName element tag name
- * @return {(Element|null)} null if there is no next sibling element or it does not have the class set
- */
- nextByTag: function(el, tagName) {
- return _sibling(el, 'nextElementSibling', TAG_NAME, tagName);
- },
-
- /**
- * Returns the previous element sibling.
- *
- * @param {Element} el element
- * @return {(Element|null)} null if there is no previous sibling element
- */
- prev: function(el) {
- return _sibling(el, 'previousElementSibling', NONE, null);
- },
-
- /**
- * Returns the previous element sibling that matches the given selector.
- *
- * @param {Element} el element
- * @param {string} selector CSS selector to match parent nodes against
- * @return {(Element|null)} null if there is no previous sibling element or it does not match the selector
- */
- prevBySel: function(el, selector) {
- return _sibling(el, 'previousElementSibling', SELECTOR, selector);
- },
-
- /**
- * Returns the previous element sibling with given CSS class.
- *
- * @param {Element} el element
- * @param {string} className CSS class name
- * @return {(Element|null)} null if there is no previous sibling element or it does not have the class set
- */
- prevByClass: function(el, className) {
- return _sibling(el, 'previousElementSibling', CLASS_NAME, className);
- },
-
- /**
- * Returns the previous element sibling with given CSS class.
- *
- * @param {Element} el element
- * @param {string} tagName element tag name
- * @return {(Element|null)} null if there is no previous sibling element or it does not have the class set
- */
- prevByTag: function(el, tagName) {
- return _sibling(el, 'previousElementSibling', TAG_NAME, tagName);
- }
- };
+define(["require", "exports"], function (require, exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.prevByTag = exports.prevByClass = exports.prevBySel = exports.prev = exports.nextByTag = exports.nextByClass = exports.nextBySel = exports.next = exports.parentByTag = exports.parentByClass = exports.parentBySel = exports.childrenByTag = exports.childrenByClass = exports.childrenBySel = exports.childByTag = exports.childByClass = exports.childBySel = void 0;
+ const _test = new Map([
+ [0 /* None */, () => true],
+ [1 /* Selector */, (element, selector) => element.matches(selector)],
+ [2 /* ClassName */, (element, className) => element.classList.contains(className)],
+ [3 /* TagName */, (element, tagName) => element.nodeName === tagName],
+ ]);
+ function _getChildren(element, type, value) {
+ if (!(element instanceof Element)) {
+ throw new TypeError('Expected a valid element as first argument.');
+ }
+ const children = [];
+ for (let i = 0; i < element.childElementCount; i++) {
+ if (_test[type](element.children[i], value)) {
+ children.push(element.children[i]);
+ }
+ }
+ return children;
+ }
+ function _getParent(element, type, value, untilElement) {
+ if (!(element instanceof Element)) {
+ throw new TypeError('Expected a valid element as first argument.');
+ }
+ let target = element.parentNode;
+ while (target instanceof Element) {
+ if (target === untilElement) {
+ return null;
+ }
+ if (_test[type](target, value)) {
+ return target;
+ }
+ target = target.parentNode;
+ }
+ return null;
+ }
+ function _getSibling(element, siblingType, type, value) {
+ if (!(element instanceof Element)) {
+ throw new TypeError('Expected a valid element as first argument.');
+ }
+ if (element instanceof Element) {
+ if (element[siblingType] !== null && _test[type](element[siblingType], value)) {
+ return element[siblingType];
+ }
+ }
+ return null;
+ }
+ /**
+ * Examines child elements and returns the first child matching the given selector.
+ */
+ function childBySel(element, selector) {
+ return _getChildren(element, 1 /* Selector */, selector)[0] || null;
+ }
+ exports.childBySel = childBySel;
+ /**
+ * Examines child elements and returns the first child that has the given CSS class set.
+ */
+ function childByClass(element, className) {
+ return _getChildren(element, 2 /* ClassName */, className)[0] || null;
+ }
+ exports.childByClass = childByClass;
+ /**
+ * Examines child elements and returns the first child which equals the given tag.
+ */
+ function childByTag(element, tagName) {
+ return _getChildren(element, 3 /* TagName */, tagName)[0] || null;
+ }
+ exports.childByTag = childByTag;
+ /**
+ * Examines child elements and returns all children matching the given selector.
+ */
+ function childrenBySel(element, selector) {
+ return _getChildren(element, 1 /* Selector */, selector);
+ }
+ exports.childrenBySel = childrenBySel;
+ /**
+ * Examines child elements and returns all children that have the given CSS class set.
+ */
+ function childrenByClass(element, className) {
+ return _getChildren(element, 2 /* ClassName */, className);
+ }
+ exports.childrenByClass = childrenByClass;
+ /**
+ * Examines child elements and returns all children which equal the given tag.
+ */
+ function childrenByTag(element, tagName) {
+ return _getChildren(element, 3 /* TagName */, tagName);
+ }
+ exports.childrenByTag = childrenByTag;
+ /**
+ * Examines parent nodes and returns the first parent that matches the given selector.
+ */
+ function parentBySel(element, selector, untilElement) {
+ return _getParent(element, 1 /* Selector */, selector, untilElement);
+ }
+ exports.parentBySel = parentBySel;
+ /**
+ * Examines parent nodes and returns the first parent that has the given CSS class set.
+ */
+ function parentByClass(element, className, untilElement) {
+ return _getParent(element, 2 /* ClassName */, className, untilElement);
+ }
+ exports.parentByClass = parentByClass;
+ /**
+ * Examines parent nodes and returns the first parent which equals the given tag.
+ */
+ function parentByTag(element, tagName, untilElement) {
+ return _getParent(element, 3 /* TagName */, tagName, untilElement);
+ }
+ exports.parentByTag = parentByTag;
+ /**
+ * Returns the next element sibling.
+ *
+ * @deprecated 5.4 Use `element.nextElementSibling` instead.
+ */
+ function next(element) {
+ return _getSibling(element, 'nextElementSibling', 0 /* None */, '');
+ }
+ exports.next = next;
+ /**
+ * Returns the next element sibling that matches the given selector.
+ */
+ function nextBySel(element, selector) {
+ return _getSibling(element, 'nextElementSibling', 1 /* Selector */, selector);
+ }
+ exports.nextBySel = nextBySel;
+ /**
+ * Returns the next element sibling with given CSS class.
+ */
+ function nextByClass(element, className) {
+ return _getSibling(element, 'nextElementSibling', 2 /* ClassName */, className);
+ }
+ exports.nextByClass = nextByClass;
+ /**
+ * Returns the next element sibling with given CSS class.
+ */
+ function nextByTag(element, tagName) {
+ return _getSibling(element, 'nextElementSibling', 3 /* TagName */, tagName);
+ }
+ exports.nextByTag = nextByTag;
+ /**
+ * Returns the previous element sibling.
+ *
+ * @deprecated 5.4 Use `element.previousElementSibling` instead.
+ */
+ function prev(element) {
+ return _getSibling(element, 'previousElementSibling', 0 /* None */, '');
+ }
+ exports.prev = prev;
+ /**
+ * Returns the previous element sibling that matches the given selector.
+ */
+ function prevBySel(element, selector) {
+ return _getSibling(element, 'previousElementSibling', 1 /* Selector */, selector);
+ }
+ exports.prevBySel = prevBySel;
+ /**
+ * Returns the previous element sibling with given CSS class.
+ */
+ function prevByClass(element, className) {
+ return _getSibling(element, 'previousElementSibling', 2 /* ClassName */, className);
+ }
+ exports.prevByClass = prevByClass;
+ /**
+ * Returns the previous element sibling with given CSS class.
+ */
+ function prevByTag(element, tagName) {
+ return _getSibling(element, 'previousElementSibling', 3 /* TagName */, tagName);
+ }
+ exports.prevByTag = prevByTag;
});
--- /dev/null
+/**
+ * Provides helper functions to traverse the DOM.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2019 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module Dom/Traverse (alias)
+ * @module WoltLabSuite/Core/Dom/Traverse
+ */
+
+const enum Type {
+ None,
+ Selector,
+ ClassName,
+ TagName,
+}
+
+const _test = new Map<Type, (...args: any[]) => boolean>([
+ [Type.None, () => true],
+ [Type.Selector, (element: Element, selector: string) => element.matches(selector)],
+ [Type.ClassName, (element: Element, className: string) => element.classList.contains(className)],
+ [Type.TagName, (element: Element, tagName: string) => element.nodeName === tagName],
+]);
+
+function _getChildren(element: Element, type: Type, value: string): Element[] {
+ if (!(element instanceof Element)) {
+ throw new TypeError('Expected a valid element as first argument.');
+ }
+
+ const children: Element[] = [];
+ for (let i = 0; i < element.childElementCount; i++) {
+ if (_test[type](element.children[i], value)) {
+ children.push(element.children[i]);
+ }
+ }
+
+ return children;
+}
+
+function _getParent(element: Element, type: Type, value: string, untilElement?: Element): Element | null {
+ if (!(element instanceof Element)) {
+ throw new TypeError('Expected a valid element as first argument.');
+ }
+
+ let target = element.parentNode;
+ while (target instanceof Element) {
+ if (target === untilElement) {
+ return null;
+ }
+
+ if (_test[type](target, value)) {
+ return target;
+ }
+
+ target = target.parentNode;
+ }
+
+ return null;
+}
+
+function _getSibling(element: Element, siblingType: string, type: Type, value: string): Element | null {
+ if (!(element instanceof Element)) {
+ throw new TypeError('Expected a valid element as first argument.');
+ }
+
+ if (element instanceof Element) {
+ if (element[siblingType] !== null && _test[type](element[siblingType], value)) {
+ return element[siblingType];
+ }
+ }
+
+ return null;
+}
+
+/**
+ * Examines child elements and returns the first child matching the given selector.
+ */
+export function childBySel(element: Element, selector: string): Element | null {
+ return _getChildren(element, Type.Selector, selector)[0] || null;
+}
+
+/**
+ * Examines child elements and returns the first child that has the given CSS class set.
+ */
+export function childByClass(element: Element, className: string): Element | null {
+ return _getChildren(element, Type.ClassName, className)[0] || null;
+}
+
+/**
+ * Examines child elements and returns the first child which equals the given tag.
+ */
+export function childByTag(element: Element, tagName: string): Element | null {
+ return _getChildren(element, Type.TagName, tagName)[0] || null;
+}
+
+/**
+ * Examines child elements and returns all children matching the given selector.
+ */
+export function childrenBySel(element, selector: string): Element[] {
+ return _getChildren(element, Type.Selector, selector);
+}
+
+/**
+ * Examines child elements and returns all children that have the given CSS class set.
+ */
+export function childrenByClass(element: Element, className: string): Element[] {
+ return _getChildren(element, Type.ClassName, className);
+}
+
+/**
+ * Examines child elements and returns all children which equal the given tag.
+ */
+export function childrenByTag(element: Element, tagName: string): Element[] {
+ return _getChildren(element, Type.TagName, tagName);
+}
+
+/**
+ * Examines parent nodes and returns the first parent that matches the given selector.
+ */
+export function parentBySel(element: Element, selector: string, untilElement?: Element): Element | null {
+ return _getParent(element, Type.Selector, selector, untilElement);
+}
+
+/**
+ * Examines parent nodes and returns the first parent that has the given CSS class set.
+ */
+export function parentByClass(element: Element, className: string, untilElement?: Element): Element | null {
+ return _getParent(element, Type.ClassName, className, untilElement);
+}
+
+/**
+ * Examines parent nodes and returns the first parent which equals the given tag.
+ */
+export function parentByTag(element: Element, tagName: string, untilElement?: Element): Element | null {
+ return _getParent(element, Type.TagName, tagName, untilElement);
+}
+
+/**
+ * Returns the next element sibling.
+ *
+ * @deprecated 5.4 Use `element.nextElementSibling` instead.
+ */
+export function next(element: Element): Element | null {
+ return _getSibling(element, 'nextElementSibling', Type.None, '');
+}
+
+/**
+ * Returns the next element sibling that matches the given selector.
+ */
+export function nextBySel(element: Element, selector: string): Element | null {
+ return _getSibling(element, 'nextElementSibling', Type.Selector, selector);
+}
+
+/**
+ * Returns the next element sibling with given CSS class.
+ */
+export function nextByClass(element: Element, className: string): Element | null {
+ return _getSibling(element, 'nextElementSibling', Type.ClassName, className);
+}
+
+/**
+ * Returns the next element sibling with given CSS class.
+ */
+export function nextByTag(element: Element, tagName: string): Element | null {
+ return _getSibling(element, 'nextElementSibling', Type.TagName, tagName);
+}
+
+/**
+ * Returns the previous element sibling.
+ *
+ * @deprecated 5.4 Use `element.previousElementSibling` instead.
+ */
+export function prev(element: Element): Element | null {
+ return _getSibling(element, 'previousElementSibling', Type.None, '');
+}
+
+/**
+ * Returns the previous element sibling that matches the given selector.
+ */
+export function prevBySel(element: Element, selector: string): Element | null {
+ return _getSibling(element, 'previousElementSibling', Type.Selector, selector);
+}
+
+/**
+ * Returns the previous element sibling with given CSS class.
+ */
+export function prevByClass(element: Element, className: string): Element | null {
+ return _getSibling(element, 'previousElementSibling', Type.ClassName, className);
+}
+
+/**
+ * Returns the previous element sibling with given CSS class.
+ */
+export function prevByTag(element: Element, tagName: string): Element | null {
+ return _getSibling(element, 'previousElementSibling', Type.TagName, tagName);
+}