Use local svgo.cmd wrapper binary
Switch SVG optimizer resolution from bin/svgo-cli.exe to bin/svgo.cmd. Update unit tests to validate the new local binary path behavior. Co-Authored-By: Abacus.AI CLI <agent@abacus.ai>
This commit is contained in:
+5
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Aliases are pseudos that are expressed as selectors.
|
||||
*/
|
||||
export declare const aliases: Record<string, string>;
|
||||
//# sourceMappingURL=aliases.d.ts.map
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Aliases are pseudos that are expressed as selectors.
|
||||
*/
|
||||
export const aliases = {
|
||||
// Links
|
||||
"any-link": ":is(a, area, link)[href]",
|
||||
link: ":any-link:not(:visited)",
|
||||
// Forms
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#disabled-elements
|
||||
disabled: `:is(
|
||||
:is(button, input, select, textarea, optgroup, option)[disabled],
|
||||
optgroup[disabled] > option,
|
||||
fieldset[disabled]:not(fieldset[disabled] legend:first-of-type *)
|
||||
)`,
|
||||
enabled: ":not(:disabled)",
|
||||
checked: ":is(:is(input[type=radio], input[type=checkbox])[checked], option:selected)",
|
||||
required: ":is(input, select, textarea)[required]",
|
||||
optional: ":is(input, select, textarea):not([required])",
|
||||
// JQuery extensions
|
||||
// https://html.spec.whatwg.org/multipage/form-elements.html#concept-option-selectedness
|
||||
selected: "option:is([selected], select:not([multiple]):not(:has(> option[selected])) > :first-of-type)",
|
||||
checkbox: "[type=checkbox]",
|
||||
file: "[type=file]",
|
||||
password: "[type=password]",
|
||||
radio: "[type=radio]",
|
||||
reset: "[type=reset]",
|
||||
image: "[type=image]",
|
||||
submit: "[type=submit]",
|
||||
parent: ":not(:empty)",
|
||||
header: ":is(h1, h2, h3, h4, h5, h6)",
|
||||
button: ":is(button, input[type=button])",
|
||||
input: ":is(input, textarea, select, button)",
|
||||
text: "input:is(:not([type!='']), [type=text])",
|
||||
};
|
||||
//# sourceMappingURL=aliases.js.map
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import type { CompiledQuery, InternalOptions } from "../types.js";
|
||||
export declare type Filter = <Node, ElementNode extends Node>(next: CompiledQuery<ElementNode>, text: string, options: InternalOptions<Node, ElementNode>, context?: Node[]) => CompiledQuery<ElementNode>;
|
||||
export declare const filters: Record<string, Filter>;
|
||||
//# sourceMappingURL=filters.d.ts.map
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
import getNCheck from "nth-check";
|
||||
import boolbase from "boolbase";
|
||||
function getChildFunc(next, adapter) {
|
||||
return (elem) => {
|
||||
const parent = adapter.getParent(elem);
|
||||
return parent != null && adapter.isTag(parent) && next(elem);
|
||||
};
|
||||
}
|
||||
export const filters = {
|
||||
contains(next, text, { adapter }) {
|
||||
return function contains(elem) {
|
||||
return next(elem) && adapter.getText(elem).includes(text);
|
||||
};
|
||||
},
|
||||
icontains(next, text, { adapter }) {
|
||||
const itext = text.toLowerCase();
|
||||
return function icontains(elem) {
|
||||
return (next(elem) &&
|
||||
adapter.getText(elem).toLowerCase().includes(itext));
|
||||
};
|
||||
},
|
||||
// Location specific methods
|
||||
"nth-child"(next, rule, { adapter, equals }) {
|
||||
const func = getNCheck(rule);
|
||||
if (func === boolbase.falseFunc)
|
||||
return boolbase.falseFunc;
|
||||
if (func === boolbase.trueFunc)
|
||||
return getChildFunc(next, adapter);
|
||||
return function nthChild(elem) {
|
||||
const siblings = adapter.getSiblings(elem);
|
||||
let pos = 0;
|
||||
for (let i = 0; i < siblings.length; i++) {
|
||||
if (equals(elem, siblings[i]))
|
||||
break;
|
||||
if (adapter.isTag(siblings[i])) {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
return func(pos) && next(elem);
|
||||
};
|
||||
},
|
||||
"nth-last-child"(next, rule, { adapter, equals }) {
|
||||
const func = getNCheck(rule);
|
||||
if (func === boolbase.falseFunc)
|
||||
return boolbase.falseFunc;
|
||||
if (func === boolbase.trueFunc)
|
||||
return getChildFunc(next, adapter);
|
||||
return function nthLastChild(elem) {
|
||||
const siblings = adapter.getSiblings(elem);
|
||||
let pos = 0;
|
||||
for (let i = siblings.length - 1; i >= 0; i--) {
|
||||
if (equals(elem, siblings[i]))
|
||||
break;
|
||||
if (adapter.isTag(siblings[i])) {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
return func(pos) && next(elem);
|
||||
};
|
||||
},
|
||||
"nth-of-type"(next, rule, { adapter, equals }) {
|
||||
const func = getNCheck(rule);
|
||||
if (func === boolbase.falseFunc)
|
||||
return boolbase.falseFunc;
|
||||
if (func === boolbase.trueFunc)
|
||||
return getChildFunc(next, adapter);
|
||||
return function nthOfType(elem) {
|
||||
const siblings = adapter.getSiblings(elem);
|
||||
let pos = 0;
|
||||
for (let i = 0; i < siblings.length; i++) {
|
||||
const currentSibling = siblings[i];
|
||||
if (equals(elem, currentSibling))
|
||||
break;
|
||||
if (adapter.isTag(currentSibling) &&
|
||||
adapter.getName(currentSibling) === adapter.getName(elem)) {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
return func(pos) && next(elem);
|
||||
};
|
||||
},
|
||||
"nth-last-of-type"(next, rule, { adapter, equals }) {
|
||||
const func = getNCheck(rule);
|
||||
if (func === boolbase.falseFunc)
|
||||
return boolbase.falseFunc;
|
||||
if (func === boolbase.trueFunc)
|
||||
return getChildFunc(next, adapter);
|
||||
return function nthLastOfType(elem) {
|
||||
const siblings = adapter.getSiblings(elem);
|
||||
let pos = 0;
|
||||
for (let i = siblings.length - 1; i >= 0; i--) {
|
||||
const currentSibling = siblings[i];
|
||||
if (equals(elem, currentSibling))
|
||||
break;
|
||||
if (adapter.isTag(currentSibling) &&
|
||||
adapter.getName(currentSibling) === adapter.getName(elem)) {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
return func(pos) && next(elem);
|
||||
};
|
||||
},
|
||||
// TODO determine the actual root element
|
||||
root(next, _rule, { adapter }) {
|
||||
return (elem) => {
|
||||
const parent = adapter.getParent(elem);
|
||||
return (parent == null || !adapter.isTag(parent)) && next(elem);
|
||||
};
|
||||
},
|
||||
scope(next, rule, options, context) {
|
||||
const { equals } = options;
|
||||
if (!context || context.length === 0) {
|
||||
// Equivalent to :root
|
||||
return filters["root"](next, rule, options);
|
||||
}
|
||||
if (context.length === 1) {
|
||||
// NOTE: can't be unpacked, as :has uses this for side-effects
|
||||
return (elem) => equals(context[0], elem) && next(elem);
|
||||
}
|
||||
return (elem) => context.includes(elem) && next(elem);
|
||||
},
|
||||
hover: dynamicStatePseudo("isHovered"),
|
||||
visited: dynamicStatePseudo("isVisited"),
|
||||
active: dynamicStatePseudo("isActive"),
|
||||
};
|
||||
/**
|
||||
* Dynamic state pseudos. These depend on optional Adapter methods.
|
||||
*
|
||||
* @param name The name of the adapter method to call.
|
||||
* @returns Pseudo for the `filters` object.
|
||||
*/
|
||||
function dynamicStatePseudo(name) {
|
||||
return function dynamicPseudo(next, _rule, { adapter }) {
|
||||
const func = adapter[name];
|
||||
if (typeof func !== "function") {
|
||||
return boolbase.falseFunc;
|
||||
}
|
||||
return function active(elem) {
|
||||
return func(elem) && next(elem);
|
||||
};
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=filters.js.map
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import type { CompiledQuery, InternalOptions, CompileToken } from "../types.js";
|
||||
import { PseudoSelector } from "css-what";
|
||||
import { filters } from "./filters.js";
|
||||
import { pseudos } from "./pseudos.js";
|
||||
import { aliases } from "./aliases.js";
|
||||
export { filters, pseudos, aliases };
|
||||
export declare function compilePseudoSelector<Node, ElementNode extends Node>(next: CompiledQuery<ElementNode>, selector: PseudoSelector, options: InternalOptions<Node, ElementNode>, context: Node[] | undefined, compileToken: CompileToken<Node, ElementNode>): CompiledQuery<ElementNode>;
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
import { parse } from "css-what";
|
||||
import { filters } from "./filters.js";
|
||||
import { pseudos, verifyPseudoArgs } from "./pseudos.js";
|
||||
import { aliases } from "./aliases.js";
|
||||
import { subselects } from "./subselects.js";
|
||||
export { filters, pseudos, aliases };
|
||||
export function compilePseudoSelector(next, selector, options, context, compileToken) {
|
||||
var _a;
|
||||
const { name, data } = selector;
|
||||
if (Array.isArray(data)) {
|
||||
if (!(name in subselects)) {
|
||||
throw new Error(`Unknown pseudo-class :${name}(${data})`);
|
||||
}
|
||||
return subselects[name](next, data, options, context, compileToken);
|
||||
}
|
||||
const userPseudo = (_a = options.pseudos) === null || _a === void 0 ? void 0 : _a[name];
|
||||
const stringPseudo = typeof userPseudo === "string" ? userPseudo : aliases[name];
|
||||
if (typeof stringPseudo === "string") {
|
||||
if (data != null) {
|
||||
throw new Error(`Pseudo ${name} doesn't have any arguments`);
|
||||
}
|
||||
// The alias has to be parsed here, to make sure options are respected.
|
||||
const alias = parse(stringPseudo);
|
||||
return subselects["is"](next, alias, options, context, compileToken);
|
||||
}
|
||||
if (typeof userPseudo === "function") {
|
||||
verifyPseudoArgs(userPseudo, name, data, 1);
|
||||
return (elem) => userPseudo(elem, data) && next(elem);
|
||||
}
|
||||
if (name in filters) {
|
||||
return filters[name](next, data, options, context);
|
||||
}
|
||||
if (name in pseudos) {
|
||||
const pseudo = pseudos[name];
|
||||
verifyPseudoArgs(pseudo, name, data, 2);
|
||||
return (elem) => pseudo(elem, options, data) && next(elem);
|
||||
}
|
||||
throw new Error(`Unknown pseudo-class :${name}`);
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import type { PseudoSelector } from "css-what";
|
||||
import type { InternalOptions } from "../types.js";
|
||||
export declare type Pseudo = <Node, ElementNode extends Node>(elem: ElementNode, options: InternalOptions<Node, ElementNode>, subselect?: string | null) => boolean;
|
||||
export declare const pseudos: Record<string, Pseudo>;
|
||||
export declare function verifyPseudoArgs<T extends Array<unknown>>(func: (...args: T) => boolean, name: string, subselect: PseudoSelector["data"], argIndex: number): void;
|
||||
//# sourceMappingURL=pseudos.d.ts.map
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
// While filters are precompiled, pseudos get called when they are needed
|
||||
export const pseudos = {
|
||||
empty(elem, { adapter }) {
|
||||
return !adapter.getChildren(elem).some((elem) =>
|
||||
// FIXME: `getText` call is potentially expensive.
|
||||
adapter.isTag(elem) || 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));
|
||||
},
|
||||
};
|
||||
export 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
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import type { Selector } from "css-what";
|
||||
import type { CompiledQuery, InternalOptions, CompileToken, Adapter } from "../types.js";
|
||||
/** Used as a placeholder for :has. Will be replaced with the actual element. */
|
||||
export declare const PLACEHOLDER_ELEMENT: {};
|
||||
export declare function ensureIsTag<Node, ElementNode extends Node>(next: CompiledQuery<ElementNode>, adapter: Adapter<Node, ElementNode>): CompiledQuery<Node>;
|
||||
export declare type Subselect = <Node, ElementNode extends Node>(next: CompiledQuery<ElementNode>, subselect: Selector[][], options: InternalOptions<Node, ElementNode>, context: Node[] | undefined, compileToken: CompileToken<Node, ElementNode>) => CompiledQuery<ElementNode>;
|
||||
export declare function getNextSiblings<Node, ElementNode extends Node>(elem: Node, adapter: Adapter<Node, ElementNode>): ElementNode[];
|
||||
export declare const subselects: Record<string, Subselect>;
|
||||
//# sourceMappingURL=subselects.d.ts.map
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
import boolbase from "boolbase";
|
||||
import { isTraversal } from "../sort.js";
|
||||
/** Used as a placeholder for :has. Will be replaced with the actual element. */
|
||||
export const PLACEHOLDER_ELEMENT = {};
|
||||
export function ensureIsTag(next, adapter) {
|
||||
if (next === boolbase.falseFunc)
|
||||
return boolbase.falseFunc;
|
||||
return (elem) => adapter.isTag(elem) && next(elem);
|
||||
}
|
||||
export function getNextSiblings(elem, adapter) {
|
||||
const siblings = adapter.getSiblings(elem);
|
||||
if (siblings.length <= 1)
|
||||
return [];
|
||||
const elemIndex = siblings.indexOf(elem);
|
||||
if (elemIndex < 0 || elemIndex === siblings.length - 1)
|
||||
return [];
|
||||
return siblings.slice(elemIndex + 1).filter(adapter.isTag);
|
||||
}
|
||||
function copyOptions(options) {
|
||||
// Not copied: context, rootFunc
|
||||
return {
|
||||
xmlMode: !!options.xmlMode,
|
||||
lowerCaseAttributeNames: !!options.lowerCaseAttributeNames,
|
||||
lowerCaseTags: !!options.lowerCaseTags,
|
||||
quirksMode: !!options.quirksMode,
|
||||
cacheResults: !!options.cacheResults,
|
||||
pseudos: options.pseudos,
|
||||
adapter: options.adapter,
|
||||
equals: options.equals,
|
||||
};
|
||||
}
|
||||
const is = (next, token, options, context, compileToken) => {
|
||||
const func = compileToken(token, copyOptions(options), context);
|
||||
return func === boolbase.trueFunc
|
||||
? next
|
||||
: func === boolbase.falseFunc
|
||||
? boolbase.falseFunc
|
||||
: (elem) => func(elem) && next(elem);
|
||||
};
|
||||
/*
|
||||
* :not, :has, :is, :matches and :where have to compile selectors
|
||||
* doing this in src/pseudos.ts would lead to circular dependencies,
|
||||
* so we add them here
|
||||
*/
|
||||
export const subselects = {
|
||||
is,
|
||||
/**
|
||||
* `:matches` and `:where` are aliases for `:is`.
|
||||
*/
|
||||
matches: is,
|
||||
where: is,
|
||||
not(next, token, options, context, compileToken) {
|
||||
const func = compileToken(token, copyOptions(options), context);
|
||||
return func === boolbase.falseFunc
|
||||
? next
|
||||
: func === boolbase.trueFunc
|
||||
? boolbase.falseFunc
|
||||
: (elem) => !func(elem) && next(elem);
|
||||
},
|
||||
has(next, subselect, options, _context, compileToken) {
|
||||
const { adapter } = options;
|
||||
const opts = copyOptions(options);
|
||||
opts.relativeSelector = true;
|
||||
const context = subselect.some((s) => s.some(isTraversal))
|
||||
? // Used as a placeholder. Will be replaced with the actual element.
|
||||
[PLACEHOLDER_ELEMENT]
|
||||
: undefined;
|
||||
const compiled = compileToken(subselect, opts, context);
|
||||
if (compiled === boolbase.falseFunc)
|
||||
return boolbase.falseFunc;
|
||||
const hasElement = ensureIsTag(compiled, adapter);
|
||||
// If `compiled` is `trueFunc`, we can skip this.
|
||||
if (context && compiled !== boolbase.trueFunc) {
|
||||
/*
|
||||
* `shouldTestNextSiblings` will only be true if the query starts with
|
||||
* a traversal (sibling or adjacent). That means we will always have a context.
|
||||
*/
|
||||
const { shouldTestNextSiblings = false } = compiled;
|
||||
return (elem) => {
|
||||
if (!next(elem))
|
||||
return false;
|
||||
context[0] = elem;
|
||||
const childs = adapter.getChildren(elem);
|
||||
const nextElements = shouldTestNextSiblings
|
||||
? [...childs, ...getNextSiblings(elem, adapter)]
|
||||
: childs;
|
||||
return adapter.existsOne(hasElement, nextElements);
|
||||
};
|
||||
}
|
||||
return (elem) => next(elem) &&
|
||||
adapter.existsOne(hasElement, adapter.getChildren(elem));
|
||||
},
|
||||
};
|
||||
//# sourceMappingURL=subselects.js.map
|
||||
Reference in New Issue
Block a user