Refactor language menu and dom utils (#32450)
1. Make `queryElem*` functions could correctly handle TS types 2. Remove some legacy jQuery $ calls (introduce fomanticQuery for Fomantic UI only) 3. Fix some TS typing problems
This commit is contained in:
parent
35bcd667b2
commit
0f397ae09b
10 changed files with 70 additions and 62 deletions
|
@ -5,7 +5,7 @@ import type $ from 'jquery';
|
|||
type ElementArg = Element | string | NodeListOf<Element> | Array<Element> | ReturnType<typeof $>;
|
||||
type ElementsCallback = (el: Element) => Promisable<any>;
|
||||
type ElementsCallbackWithArgs = (el: Element, ...args: any[]) => Promisable<any>;
|
||||
type IterableElements = NodeListOf<Element> | Array<Element>;
|
||||
type ArrayLikeIterable<T> = ArrayLike<T> & Iterable<T>; // for NodeListOf and Array
|
||||
|
||||
function elementsCall(el: ElementArg, func: ElementsCallbackWithArgs, ...args: any[]) {
|
||||
if (typeof el === 'string' || el instanceof String) {
|
||||
|
@ -15,7 +15,7 @@ function elementsCall(el: ElementArg, func: ElementsCallbackWithArgs, ...args: a
|
|||
func(el, ...args);
|
||||
} else if (el.length !== undefined) {
|
||||
// this works for: NodeList, HTMLCollection, Array, jQuery
|
||||
for (const e of (el as IterableElements)) {
|
||||
for (const e of (el as ArrayLikeIterable<Element>)) {
|
||||
func(e, ...args);
|
||||
}
|
||||
} else {
|
||||
|
@ -58,7 +58,7 @@ export function isElemHidden(el: ElementArg) {
|
|||
return res[0];
|
||||
}
|
||||
|
||||
function applyElemsCallback(elems: IterableElements, fn?: ElementsCallback) {
|
||||
function applyElemsCallback<T extends Element>(elems: ArrayLikeIterable<T>, fn?: ElementsCallback): ArrayLikeIterable<T> {
|
||||
if (fn) {
|
||||
for (const el of elems) {
|
||||
fn(el);
|
||||
|
@ -67,19 +67,22 @@ function applyElemsCallback(elems: IterableElements, fn?: ElementsCallback) {
|
|||
return elems;
|
||||
}
|
||||
|
||||
export function queryElemSiblings(el: Element, selector = '*', fn?: ElementsCallback) {
|
||||
return applyElemsCallback(Array.from(el.parentNode.children).filter((child: Element) => {
|
||||
export function queryElemSiblings<T extends Element>(el: Element, selector = '*', fn?: ElementsCallback): ArrayLikeIterable<T> {
|
||||
const elems = Array.from(el.parentNode.children) as T[];
|
||||
return applyElemsCallback<T>(elems.filter((child: Element) => {
|
||||
return child !== el && child.matches(selector);
|
||||
}), fn);
|
||||
}
|
||||
|
||||
// it works like jQuery.children: only the direct children are selected
|
||||
export function queryElemChildren(parent: Element | ParentNode, selector = '*', fn?: ElementsCallback) {
|
||||
return applyElemsCallback(parent.querySelectorAll(`:scope > ${selector}`), fn);
|
||||
export function queryElemChildren<T extends Element>(parent: Element | ParentNode, selector = '*', fn?: ElementsCallback): ArrayLikeIterable<T> {
|
||||
return applyElemsCallback<T>(parent.querySelectorAll(`:scope > ${selector}`), fn);
|
||||
}
|
||||
|
||||
export function queryElems(selector: string, fn?: ElementsCallback) {
|
||||
return applyElemsCallback(document.querySelectorAll(selector), fn);
|
||||
// it works like parent.querySelectorAll: all descendants are selected
|
||||
// in the future, all "queryElems(document, ...)" should be refactored to use a more specific parent
|
||||
export function queryElems<T extends Element>(parent: Element | ParentNode, selector: string, fn?: ElementsCallback): ArrayLikeIterable<T> {
|
||||
return applyElemsCallback<T>(parent.querySelectorAll(selector), fn);
|
||||
}
|
||||
|
||||
export function onDomReady(cb: () => Promisable<void>) {
|
||||
|
@ -92,7 +95,7 @@ export function onDomReady(cb: () => Promisable<void>) {
|
|||
|
||||
// checks whether an element is owned by the current document, and whether it is a document fragment or element node
|
||||
// if it is, it means it is a "normal" element managed by us, which can be modified safely.
|
||||
export function isDocumentFragmentOrElementNode(el: Element | Node) {
|
||||
export function isDocumentFragmentOrElementNode(el: Node) {
|
||||
try {
|
||||
return el.ownerDocument === document && el.nodeType === Node.ELEMENT_NODE || el.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
|
||||
} catch {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue