Spaces:
Configuration error
Configuration error
import { attributeRules } from "./attributes.js"; | |
import { compilePseudoSelector } from "./pseudo-selectors/index.js"; | |
import { SelectorType } from "css-what"; | |
function getElementParent(node, adapter) { | |
const parent = adapter.getParent(node); | |
if (parent && adapter.isTag(parent)) { | |
return parent; | |
} | |
return null; | |
} | |
/* | |
* All available rules | |
*/ | |
export function compileGeneralSelector(next, selector, options, context, compileToken) { | |
const { adapter, equals } = options; | |
switch (selector.type) { | |
case SelectorType.PseudoElement: { | |
throw new Error("Pseudo-elements are not supported by css-select"); | |
} | |
case SelectorType.ColumnCombinator: { | |
throw new Error("Column combinators are not yet supported by css-select"); | |
} | |
case SelectorType.Attribute: { | |
if (selector.namespace != null) { | |
throw new Error("Namespaced attributes are not yet supported by css-select"); | |
} | |
if (!options.xmlMode || options.lowerCaseAttributeNames) { | |
selector.name = selector.name.toLowerCase(); | |
} | |
return attributeRules[selector.action](next, selector, options); | |
} | |
case SelectorType.Pseudo: { | |
return compilePseudoSelector(next, selector, options, context, compileToken); | |
} | |
// Tags | |
case SelectorType.Tag: { | |
if (selector.namespace != null) { | |
throw new Error("Namespaced tag names are not yet supported by css-select"); | |
} | |
let { name } = selector; | |
if (!options.xmlMode || options.lowerCaseTags) { | |
name = name.toLowerCase(); | |
} | |
return function tag(elem) { | |
return adapter.getName(elem) === name && next(elem); | |
}; | |
} | |
// Traversal | |
case SelectorType.Descendant: { | |
if (options.cacheResults === false || | |
typeof WeakSet === "undefined") { | |
return function descendant(elem) { | |
let current = elem; | |
while ((current = getElementParent(current, adapter))) { | |
if (next(current)) { | |
return true; | |
} | |
} | |
return false; | |
}; | |
} | |
// @ts-expect-error `ElementNode` is not extending object | |
const isFalseCache = new WeakSet(); | |
return function cachedDescendant(elem) { | |
let current = elem; | |
while ((current = getElementParent(current, adapter))) { | |
if (!isFalseCache.has(current)) { | |
if (adapter.isTag(current) && next(current)) { | |
return true; | |
} | |
isFalseCache.add(current); | |
} | |
} | |
return false; | |
}; | |
} | |
case "_flexibleDescendant": { | |
// Include element itself, only used while querying an array | |
return function flexibleDescendant(elem) { | |
let current = elem; | |
do { | |
if (next(current)) | |
return true; | |
} while ((current = getElementParent(current, adapter))); | |
return false; | |
}; | |
} | |
case SelectorType.Parent: { | |
return function parent(elem) { | |
return adapter | |
.getChildren(elem) | |
.some((elem) => adapter.isTag(elem) && next(elem)); | |
}; | |
} | |
case SelectorType.Child: { | |
return function child(elem) { | |
const parent = adapter.getParent(elem); | |
return parent != null && adapter.isTag(parent) && next(parent); | |
}; | |
} | |
case SelectorType.Sibling: { | |
return function sibling(elem) { | |
const siblings = adapter.getSiblings(elem); | |
for (let i = 0; i < siblings.length; i++) { | |
const currentSibling = siblings[i]; | |
if (equals(elem, currentSibling)) | |
break; | |
if (adapter.isTag(currentSibling) && next(currentSibling)) { | |
return true; | |
} | |
} | |
return false; | |
}; | |
} | |
case SelectorType.Adjacent: { | |
if (adapter.prevElementSibling) { | |
return function adjacent(elem) { | |
const previous = adapter.prevElementSibling(elem); | |
return previous != null && next(previous); | |
}; | |
} | |
return function adjacent(elem) { | |
const siblings = adapter.getSiblings(elem); | |
let lastElement; | |
for (let i = 0; i < siblings.length; i++) { | |
const currentSibling = siblings[i]; | |
if (equals(elem, currentSibling)) | |
break; | |
if (adapter.isTag(currentSibling)) { | |
lastElement = currentSibling; | |
} | |
} | |
return !!lastElement && next(lastElement); | |
}; | |
} | |
case SelectorType.Universal: { | |
if (selector.namespace != null && selector.namespace !== "*") { | |
throw new Error("Namespaced universal selectors are not yet supported by css-select"); | |
} | |
return next; | |
} | |
} | |
} | |
//# sourceMappingURL=general.js.map |