| "use strict"; | |
| Object.defineProperty(exports, "__esModule", { value: true }); | |
| exports.pseudos = void 0; | |
| exports.verifyPseudoArgs = verifyPseudoArgs; | |
| /** | |
| * CSS limits the characters considered as whitespace to space, tab & line | |
| * feed. We add carriage returns as htmlparser2 doesn't normalize them to | |
| * line feeds. | |
| * | |
| * @see {@link https://www.w3.org/TR/css-text-3/#white-space} | |
| */ | |
| const isDocumentWhiteSpace = /^[ \t\r\n]*$/; | |
| // While filters are precompiled, pseudos get called when they are needed | |
| exports.pseudos = { | |
| empty(elem, { adapter }) { | |
| const children = adapter.getChildren(elem); | |
| return ( | |
| // First, make sure the tag does not have any element children. | |
| children.every((elem) => !adapter.isTag(elem)) && | |
| // Then, check that the text content is only whitespace. | |
| children.every((elem) => | |
| // FIXME: `getText` call is potentially expensive. | |
| isDocumentWhiteSpace.test(adapter.getText(elem)))); | |
| }, | |
| "first-child"(elem, { adapter, equals }) { | |
| if (adapter.prevElementSibling) { | |
| return adapter.prevElementSibling(elem) == null; | |
| } | |
| const firstChild = adapter | |
| .getSiblings(elem) | |
| .find((elem) => adapter.isTag(elem)); | |
| return firstChild != null && equals(elem, firstChild); | |
| }, | |
| "last-child"(elem, { adapter, equals }) { | |
| const siblings = adapter.getSiblings(elem); | |
| for (let i = siblings.length - 1; i >= 0; i--) { | |
| if (equals(elem, siblings[i])) { | |
| return true; | |
| } | |
| if (adapter.isTag(siblings[i])) { | |
| break; | |
| } | |
| } | |
| return false; | |
| }, | |
| "first-of-type"(elem, { adapter, equals }) { | |
| const siblings = adapter.getSiblings(elem); | |
| const elemName = adapter.getName(elem); | |
| for (let i = 0; i < siblings.length; i++) { | |
| const currentSibling = siblings[i]; | |
| if (equals(elem, currentSibling)) { | |
| return true; | |
| } | |
| if (adapter.isTag(currentSibling) && | |
| adapter.getName(currentSibling) === elemName) { | |
| break; | |
| } | |
| } | |
| return false; | |
| }, | |
| "last-of-type"(elem, { adapter, equals }) { | |
| const siblings = adapter.getSiblings(elem); | |
| const elemName = adapter.getName(elem); | |
| for (let i = siblings.length - 1; i >= 0; i--) { | |
| const currentSibling = siblings[i]; | |
| if (equals(elem, currentSibling)) { | |
| return true; | |
| } | |
| if (adapter.isTag(currentSibling) && | |
| adapter.getName(currentSibling) === elemName) { | |
| break; | |
| } | |
| } | |
| return false; | |
| }, | |
| "only-of-type"(elem, { adapter, equals }) { | |
| const elemName = adapter.getName(elem); | |
| return adapter | |
| .getSiblings(elem) | |
| .every((sibling) => equals(elem, sibling) || | |
| !adapter.isTag(sibling) || | |
| adapter.getName(sibling) !== elemName); | |
| }, | |
| "only-child"(elem, { adapter, equals }) { | |
| return adapter | |
| .getSiblings(elem) | |
| .every((sibling) => equals(elem, sibling) || !adapter.isTag(sibling)); | |
| }, | |
| }; | |
| function verifyPseudoArgs(func, name, subselect, argIndex) { | |
| if (subselect === null) { | |
| if (func.length > argIndex) { | |
| throw new Error(`Pseudo-class :${name} requires an argument`); | |
| } | |
| } | |
| else if (func.length === argIndex) { | |
| throw new Error(`Pseudo-class :${name} doesn't have any arguments`); | |
| } | |
| } | |
| //# sourceMappingURL=pseudos.js.map |