summaryrefslogtreecommitdiff
path: root/node_modules/posthtml-match-helper
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/posthtml-match-helper')
-rw-r--r--node_modules/posthtml-match-helper/LICENSE21
-rw-r--r--node_modules/posthtml-match-helper/README.md84
-rw-r--r--node_modules/posthtml-match-helper/lib/index.d.ts10
-rw-r--r--node_modules/posthtml-match-helper/lib/index.js149
-rw-r--r--node_modules/posthtml-match-helper/package.json41
5 files changed, 305 insertions, 0 deletions
diff --git a/node_modules/posthtml-match-helper/LICENSE b/node_modules/posthtml-match-helper/LICENSE
new file mode 100644
index 0000000..c2cf232
--- /dev/null
+++ b/node_modules/posthtml-match-helper/LICENSE
@@ -0,0 +1,21 @@
+MIT License (MIT)
+
+Copyright (c) Rasmus Fløe
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/node_modules/posthtml-match-helper/README.md b/node_modules/posthtml-match-helper/README.md
new file mode 100644
index 0000000..73463dd
--- /dev/null
+++ b/node_modules/posthtml-match-helper/README.md
@@ -0,0 +1,84 @@
+<div align="center">
+ <img width="150" height="150" title="PostHTML" src="https://posthtml.github.io/posthtml/logo.svg">
+ <h1>posthtml-match-helper</h1>
+
+ Expand CSS selectors into PostHTML matcher objects
+
+ [![Version][npm-version-shield]][npm]
+ [![Build][github-ci-shield]][github-ci]
+ [![License][license-shield]][license]
+ [![Downloads][npm-stats-shield]][npm-stats]
+</div>
+
+## Introduction
+
+This PostHTML plugin can turn simple CSS selectors into [matcher objects](https://github.com/posthtml/posthtml/blob/master/README.md#match).
+
+Supported features:
+
+* Tags: `"div"` returns `{tag: "div"}`.
+* Ids: `"#bar"` returns `{attrs: {id: "bar"}}`.
+* Classes: `.foo` returns `{attrs: { class: /(?:^|\s)foo(?:\\s|$)/ }}`. Any number of classnames supported.
+* Attribute selectors: any number of standard [attribute selectors](https://developer.mozilla.org/en/docs/Web/CSS/Attribute_selectors) can be used<sup><a href="#attribute_selectors_footnote">1</a></sup> including the following non-standard:
+ * `[attr!=value]`: matches attributes with values that do not contain `value`.
+* Multiple node selectors: `"div, span"` returns `[{tag: "div"}, {tag: "span"}]`.
+
+**<sup><a name="attribute_selectors_footnote">1</a></sup>** Multiple attribute selectors for the same attribute are not supported (this includes mixing classnames and attribute selectors matching `class`).
+
+The basic template for selectors (and order of features) looks like this:
+
+```js
+"tag#id.class.name[attr*=value][otherattr^='start']"
+```
+
+## Basic usage
+
+```js
+import matchHelper from "posthtml-match-helper";
+
+tree.match(matchHelper("div.class"), function (node) {
+ // do stuff with matched node...
+});
+```
+
+## Advanced usage
+
+```js
+import matchHelper from "posthtml-match-helper";
+
+tree.match(matchHelper("input.my-control[type!='radio'][checked], input[value^='foo'][checked]"), function (node) {
+ // do stuff with node that matched either of the selectors...
+});
+```
+
+## Classnames with escaped characters
+
+If you need to match nodes with classnames that use escaped characters, like those in Tailwind CSS utilities with arbitrary values, use the following syntax:
+
+```js
+import matchHelper from "posthtml-match-helper";
+
+tree.match(matchHelper("input.\\[display:none\\]"), function (node) {
+ // do stuff with node that matched either of the selectors...
+});
+```
+
+
+## The helper function
+
+#### Arguments
+
+* `matcher` (string) - A CSS selector that describes the node you want to match in PostHTML.
+
+#### Returns
+
+A matcher object or an array of matcher objects.
+
+[npm]: https://www.npmjs.com/package/posthtml-match-helper
+[npm-version-shield]: https://img.shields.io/npm/v/posthtml-match-helper.svg
+[npm-stats]: http://npm-stat.com/charts.html?package=posthtml-match-helper
+[npm-stats-shield]: https://img.shields.io/npm/dt/posthtml-match-helper.svg
+[github-ci]: https://github.com/posthtml/posthtml-match-helper/actions/workflows/nodejs.yml
+[github-ci-shield]: https://github.com/posthtml/posthtml-match-helper/actions/workflows/nodejs.yml/badge.svg
+[license]: ./LICENSE
+[license-shield]: https://img.shields.io/npm/l/posthtml-match-helper.svg
diff --git a/node_modules/posthtml-match-helper/lib/index.d.ts b/node_modules/posthtml-match-helper/lib/index.d.ts
new file mode 100644
index 0000000..9e9ef25
--- /dev/null
+++ b/node_modules/posthtml-match-helper/lib/index.d.ts
@@ -0,0 +1,10 @@
+import type { AttrMatcher, StringMatcher } from "posthtml";
+
+interface Matcher {
+ tag?: StringMatcher;
+ attrs: AttrMatcher;
+}
+
+declare function createMatcher(matcher: string | string[]): Matcher | Matcher[];
+
+export default createMatcher;
diff --git a/node_modules/posthtml-match-helper/lib/index.js b/node_modules/posthtml-match-helper/lib/index.js
new file mode 100644
index 0000000..6e7ca64
--- /dev/null
+++ b/node_modules/posthtml-match-helper/lib/index.js
@@ -0,0 +1,149 @@
+const selectorReg = /^([^#\.\[]+)?(?:#([^\.\[]+))?(?:\.((?:[^\[\]\\]|\\.)+))?((?:\[[^\]]*\])+)?$/; // eslint-disable-line
+const attributeReg = /^([a-zA-Z0-9_-]*[^~|^$*!=])(?:([~|^$*!]?)=['"]?([^'"]*)['"]?)?$/;
+const splitReg = /\s*,\s*/;
+
+function expandMatcher(matcher) {
+ if (typeof matcher === "string") {
+ const match = matcher.match(selectorReg);
+
+ if (match) {
+ matcher = {};
+ const tag = match[1];
+ const id = match[2];
+ const className = match[3];
+ const attrs = match[4];
+ let attributes;
+
+ if (tag) {
+ matcher.tag = tag;
+ }
+
+ if (attrs) {
+ attributes = expandAttributes(attrs);
+ } else if (id || className) {
+ attributes = {};
+ }
+
+ if (id) {
+ attributes.id = id;
+ }
+
+ if (className) {
+ attributes.class = new RegExp(getCombinations(className.split(".")).map((order) => {
+ return "(?:^|\\s)" + order.join("\\s(?:.*?\\s)?") + "(?:\\s|$)";
+ }).join("|"));
+ }
+
+ if (attributes) {
+ matcher.attrs = attributes;
+ }
+ } else {
+ matcher = {tag: matcher};
+ }
+ }
+
+ return matcher;
+}
+
+function cssAttrToRegExp(value, operator) {
+ let reg;
+
+ switch (operator) {
+ case "~":
+ reg = "(?:^|\\s)" + value + "(?:\\s|$)";
+ break;
+
+ case "|":
+ reg = "^" + value + "(?:-|$)";
+ break;
+
+ case "^":
+ reg = "^" + value;
+ break;
+
+ case "$":
+ reg = value + "$";
+ break;
+
+ case "*":
+ reg = value;
+ break;
+
+ case "!":
+ reg = "^((?!" + value + ")[\\s\\S])*$";
+ break;
+
+ default:
+ reg = "^" + value + "$";
+ break;
+ }
+
+ return new RegExp(reg);
+}
+
+function expandAttributes(attrs) {
+ attrs = attrs.slice(1, -1);
+
+ if (attrs.length > 0) {
+ attrs = attrs.split("][");
+ const attrObject = {};
+ let l = attrs.length;
+ let attrMatch;
+ let name;
+ let operator;
+ let value;
+
+ while (l--) {
+ attrMatch = attrs[l].match(attributeReg);
+
+ if (attrMatch) {
+ name = attrMatch[1];
+ operator = attrMatch[2];
+ value = attrMatch[3];
+
+ if (!value) {
+ value = true;
+ }
+
+ attrObject[name] = (operator) ? cssAttrToRegExp(value, operator) : value;
+ }
+ }
+
+ return attrObject;
+ }
+}
+
+function getCombinations(values, subresult) {
+ subresult = subresult || [];
+ let result = [];
+
+ for (const value of values) {
+ if (subresult.indexOf(value) < 0) {
+ const _subresult = subresult.concat([value]);
+
+ if (_subresult.length < values.length) {
+ result = result.concat(getCombinations(values, _subresult));
+ } else {
+ result.push(_subresult);
+ }
+ }
+ }
+
+ return result;
+}
+
+export default function (matcher) {
+ if (typeof matcher === "string") {
+ if (matcher.match(splitReg)) {
+ matcher = matcher.split(splitReg);
+ } else {
+ return expandMatcher(matcher);
+ }
+ }
+
+ if (Array.isArray(matcher)) {
+ return matcher.map(expandMatcher);
+ }
+
+ return matcher;
+}
diff --git a/node_modules/posthtml-match-helper/package.json b/node_modules/posthtml-match-helper/package.json
new file mode 100644
index 0000000..4193f97
--- /dev/null
+++ b/node_modules/posthtml-match-helper/package.json
@@ -0,0 +1,41 @@
+{
+ "name": "posthtml-match-helper",
+ "description": "A helper to expand CSS selectors into PostHTML matcher objects",
+ "version": "2.0.3",
+ "license": "MIT",
+ "author": "Rasmus Fløe (https://github.com/phloe)",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/posthtml/posthtml-match-helper.git"
+ },
+ "bugs": "https://github.com/posthtml/posthtml-match-helper/issues",
+ "type": "module",
+ "exports": "./lib/index.js",
+ "types": "./lib/index.d.ts",
+ "engines": {
+ "node": ">=18"
+ },
+ "scripts": {
+ "dev": "vitest",
+ "test": "vitest run --coverage",
+ "lint": "biome lint ./lib",
+ "pretest": "npm run lint",
+ "release": "npx np"
+ },
+ "files": [
+ "lib"
+ ],
+ "keywords": [
+ "posthtml",
+ "posthtml-helper",
+ "posthtml-matcher"
+ ],
+ "peerDependencies": {
+ "posthtml": "^0.16.6"
+ },
+ "devDependencies": {
+ "@biomejs/biome": "1.9.4",
+ "@vitest/coverage-v8": "^2.0.0",
+ "vitest": "^2.0.0"
+ }
+}