Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update dependency specificity to v1 #337

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
18 changes: 9 additions & 9 deletions src/common/selectorUtils.ts
Original file line number Diff line number Diff line change
@@ -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;
}

/**
Expand All @@ -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)
);
}
4 changes: 2 additions & 2 deletions src/content/hints/computeCustomSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { generatePossibleSelectors } from "../utils/generatePossibleSelectors";
import {
getSpecificityValue,
isValidSelector,
selectorToArray,
getSelectorParts,
} from "../../common/selectorUtils";
import { type SelectorAlternative } from "../../typings/SelectorAlternative";

Expand Down Expand Up @@ -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;
Expand Down
22 changes: 10 additions & 12 deletions src/content/utils/generatePossibleSelectors.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import combinations from "combinations";
import { calculate } from "specificity";
import { getSelectorParts } from "../../common/selectorUtils";
import { combineArrays } from "./combineArrays";

/**
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
}
Expand Down Expand Up @@ -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("")}`
);
}
Expand Down
Loading