From 732ad837a78f55754b97726986ccbec668d71a51 Mon Sep 17 00:00:00 2001 From: David Tejada Date: Sat, 28 Sep 2024 10:06:07 +0200 Subject: [PATCH] Update dependency specificity to 1.0.0 --- package-lock.json | 18 +++++++-------- package.json | 2 +- src/common/selectorUtils.ts | 18 +++++++-------- src/content/hints/computeCustomSelectors.ts | 4 ++-- .../utils/generatePossibleSelectors.ts | 22 +++++++++---------- 5 files changed, 30 insertions(+), 34 deletions(-) diff --git a/package-lock.json b/package-lock.json index f988fd6d..c6a9df0c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "react-dom": "^18.2.0", "react-toastify": "^9.1.2", "requestidlecallback-polyfill": "^1.0.2", - "specificity": "^0.4.1", + "specificity": "^1.0.0", "tippy.js": "^6.3.7", "webextension-polyfill": "^0.12.0", "zod": "^3.22.4" @@ -6508,7 +6508,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dev": true, "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -12851,8 +12850,7 @@ "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" }, "node_modules/mem": { "version": "5.1.1", @@ -16306,7 +16304,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -16390,11 +16387,12 @@ "dev": true }, "node_modules/specificity": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", - "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", - "bin": { - "specificity": "bin/specificity" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/specificity/-/specificity-1.0.0.tgz", + "integrity": "sha512-nCtHb5/MTfZ1D36EpLLz03AcUf1v+PxWFFieW4O721MaJUo/anSMckB94Ylj5VQPrjdlx+4BXcKD+s1N0yT+ww==", + "license": "MIT", + "dependencies": { + "css-tree": "^2.3.1" } }, "node_modules/split": { diff --git a/package.json b/package.json index 3685b9de..c2fd7d7e 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "react-dom": "^18.2.0", "react-toastify": "^9.1.2", "requestidlecallback-polyfill": "^1.0.2", - "specificity": "^0.4.1", + "specificity": "^1.0.0", "tippy.js": "^6.3.7", "webextension-polyfill": "^0.12.0", "zod": "^3.22.4" diff --git a/src/common/selectorUtils.ts b/src/common/selectorUtils.ts index badcf6e6..4fde1dc3 100644 --- a/src/common/selectorUtils.ts +++ b/src/common/selectorUtils.ts @@ -1,12 +1,9 @@ -import { calculate } from "specificity"; +import { calculate, calculateWithDetails } from "specificity"; export function getSpecificityValue(selector: string) { - const { specificityArray } = calculate(selector)[0]!; + const specificity = calculate(selector); - return (specificityArray as number[]).reduce( - (accumulator, current, index, array) => - accumulator + current * 10 ** (array.length - index - 1) - ); + return specificity.A * 100 + specificity.B * 10 + specificity.C; } /** @@ -29,7 +26,10 @@ export function isValidSelector(selector: string) { return true; } -export function selectorToArray(selector: string) { - const specificity = calculate(selector); - return specificity[0]!.parts.map((part) => part.selector); +export function getSelectorParts(selector: string) { + const oneLiner = selector.replace("\n", " "); + + return calculateWithDetails(oneLiner).contributingParts.map((part) => + oneLiner.slice(part.start.column - 1, part.end.column - 1) + ); } diff --git a/src/content/hints/computeCustomSelectors.ts b/src/content/hints/computeCustomSelectors.ts index a45f0a39..1494dbb5 100644 --- a/src/content/hints/computeCustomSelectors.ts +++ b/src/content/hints/computeCustomSelectors.ts @@ -4,7 +4,7 @@ import { generatePossibleSelectors } from "../utils/generatePossibleSelectors"; import { getSpecificityValue, isValidSelector, - selectorToArray, + getSelectorParts, } from "../../common/selectorUtils"; import { type SelectorAlternative } from "../../typings/SelectorAlternative"; @@ -125,7 +125,7 @@ function getCommonSelectors(targets: Element[]) { let commonTargetSelectors: string[] | undefined; for (const selector of targetSelectors) { - const parts = selectorToArray(selector); + const parts = getSelectorParts(selector); commonTargetSelectors = commonTargetSelectors ? intersect(commonTargetSelectors, parts) : parts; diff --git a/src/content/utils/generatePossibleSelectors.ts b/src/content/utils/generatePossibleSelectors.ts index 51a7908b..dc61ceb3 100644 --- a/src/content/utils/generatePossibleSelectors.ts +++ b/src/content/utils/generatePossibleSelectors.ts @@ -1,5 +1,5 @@ import combinations from "combinations"; -import { calculate } from "specificity"; +import { getSelectorParts } from "../../common/selectorUtils"; import { combineArrays } from "./combineArrays"; /** @@ -38,15 +38,14 @@ export function generatePossibleSelectors( // We need to reverse the selectors because we want to keep the selector parts // closest to the target for (const selector of [...selectors].reverse()) { - const parts = calculate(selector)[0]!.parts; - const selectorParts = parts.map((part) => part.selector); + const parts = getSelectorParts(selector); // If the selector is just the tag we included it - if (selectorParts.length === 1) { - selectorsTrimmed.unshift(selectorParts[0]!); + if (parts.length === 1) { + selectorsTrimmed.unshift(parts[0]!); } else { let filteredSelector = ""; - for (const part of selectorParts) { + for (const part of parts) { if (/^[.:]/.test(part) && classesAdded < maxClasses) { classesAdded++; filteredSelector += part; @@ -55,7 +54,7 @@ export function generatePossibleSelectors( if (filteredSelector) { // We always include the tag - filteredSelector = selectorParts[0]! + filteredSelector; + filteredSelector = parts[0]! + filteredSelector; selectorsTrimmed.unshift(filteredSelector); } } @@ -92,20 +91,19 @@ export function generatePossibleSelectors( // (value that we get from selectorCombined) const selectorListCombined: string[][] = []; for (const [index, selector] of selectorList.entries()) { - const parts = calculate(selector)[0]!.parts; - const selectors = parts.map((part) => part.selector); + const parts = getSelectorParts(selector); let selectorCombined: string[]; // This will be true for the target selector. For this one we also want to // include the tag by itself, so that we get selectors like ".media a" if (index === selectorList.length - 1) { - selectorCombined = combinations(selectors).map((selectors) => + selectorCombined = combinations(parts).map((selectors) => selectors.join("") ); } else { - const tagName = selectors.shift(); - selectorCombined = combinations(selectors).map( + const tagName = parts.shift(); + selectorCombined = combinations(parts).map( (selectors) => `${tagName!}${selectors.join("")}` ); }