Skip to content

Commit

Permalink
feat: finish first implementation of the matching rules interface
Browse files Browse the repository at this point in the history
  • Loading branch information
aug-dev committed Aug 9, 2024
1 parent 10234e8 commit 6556524
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 14 deletions.
31 changes: 23 additions & 8 deletions src/scripts/block-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ import type { InteractiveRuleset } from "./interactive-ruleset.ts";
import { translate } from "./locales.ts";
import { PathDepth } from "./path-depth.ts";
import type { LinkProps } from "./ruleset/ruleset.ts";
import type { DialogTheme } from "./types.ts";
import { makeAltURL, svgToDataURL } from "./utilities.ts";
import type { DialogTheme, MatchingRulesText } from "./types.ts";
import { getMatchingRulesText, makeAltURL, svgToDataURL } from "./utilities.ts";

type BlockDialogContentProps = {
blockWholeSite: boolean;
Expand Down Expand Up @@ -60,6 +60,7 @@ const BlockDialogContent: React.FC<BlockDialogContentProps> = ({
host: "",
detailsOpen: false,
matchingRulesOpen: false,
matchingRulesText: null as MatchingRulesText | null,
pathDepth: null as PathDepth | null,
depth: "",
rulesToAdd: "",
Expand All @@ -77,6 +78,8 @@ const BlockDialogContent: React.FC<BlockDialogContentProps> = ({
blockWholeSite ? tldts.getDomain(url.host) ?? url.host : url.host,
);
state.detailsOpen = false;
state.matchingRulesOpen = false;
state.matchingRulesText = null;
state.pathDepth = enablePathDepth ? new PathDepth(url) : null;
state.depth = "0";
state.rulesToAdd = patch.rulesToAdd;
Expand All @@ -87,6 +90,8 @@ const BlockDialogContent: React.FC<BlockDialogContentProps> = ({
state.unblock = false;
state.host = entryProps.url;
state.detailsOpen = false;
state.matchingRulesOpen = false;
state.matchingRulesText = null;
state.pathDepth = null;
state.depth = "";
state.rulesToAdd = "";
Expand Down Expand Up @@ -274,9 +279,13 @@ const BlockDialogContent: React.FC<BlockDialogContentProps> = ({
open={state.matchingRulesOpen}
onToggle={(e) => {
const { open } = e.currentTarget;
const matchingRulesText = open
? getMatchingRulesText(ruleset, entryProps)
: null;
setState((s) => ({
...s,
matchingRulesOpen: open,
matchingRulesText,
}));
}}
>
Expand All @@ -296,9 +305,11 @@ const BlockDialogContent: React.FC<BlockDialogContentProps> = ({
breakAll
id="blocking-rules-text"
readOnly
rows={2}
monospace
nowrap
rows={4}
resizable
value={""}
value={state.matchingRulesText?.blockRules}
/>
)}
</RowItem>
Expand All @@ -315,9 +326,11 @@ const BlockDialogContent: React.FC<BlockDialogContentProps> = ({
breakAll
id="unblocking-rules-text"
readOnly
rows={2}
monospace
nowrap
rows={4}
resizable
value={""}
value={state.matchingRulesText?.unblockRules}
/>
)}
</RowItem>
Expand All @@ -334,9 +347,11 @@ const BlockDialogContent: React.FC<BlockDialogContentProps> = ({
breakAll
id="highlight-rules-text"
readOnly
rows={2}
monospace
nowrap
rows={4}
resizable
value={""}
value={state.matchingRulesText?.highlightRules}
/>
)}
</RowItem>
Expand Down
15 changes: 14 additions & 1 deletion src/scripts/components/textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,21 @@ import { useClassName } from "./utilities.ts";
export type TextAreaProps = JSX.IntrinsicElements["textarea"] & {
breakAll?: boolean;
resizable?: boolean;
monospace?: boolean;
nowrap?: boolean;
};

export const TextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>(
function TextArea({ breakAll = false, resizable = false, ...props }, ref) {
function TextArea(
{
breakAll = false,
resizable = false,
monospace = false,
nowrap = false,
...props
},
ref,
) {
const className = useClassName(
(theme) => ({
background: "transparent",
Expand All @@ -23,6 +34,8 @@ export const TextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>(
? `calc(1.5em * ${props.rows} + 1em + 2px)`
: "auto",
lineHeight: "1.5",
fontFamily: monospace ? "monospace" : "inherit",
textWrap: nowrap ? "nowrap" : "wrap",
padding: "0.5em 0.625em",
resize: resizable ? "vertical" : "none",
width: "100%",
Expand Down
6 changes: 3 additions & 3 deletions src/scripts/interactive-ruleset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ type MatchingRule = {
lineContent: string | null;
};

type RulesetMatches = {
export type RulesetMatches = {
rulesetName: string;
blockRules: MatchingRule[];
unblockRules: MatchingRule[];
Expand Down Expand Up @@ -286,7 +286,7 @@ export class InteractiveRuleset {
// Get rules from user's personal blacklist
// Note: I need to internationalize this string later with translate() !!
const matches = getMatchesPerRuleset(
"Personal Blacklist",
"personal-blacklist",
this.userRuleset,
props,
);
Expand Down Expand Up @@ -345,7 +345,7 @@ function getMatchesPerRuleset(
// "Block this website" button.
// This ensures the line numbers are accurate without reloading.
const rulesetLines =
rulesetName === "Personal Blacklist" ? [...ruleset] : null;
rulesetName === "personal-blacklist" ? [...ruleset] : null;
const previousMatchIndexes = new Map<string, number>();

for (let { lineNumber, specifier } of rawResults) {
Expand Down
10 changes: 9 additions & 1 deletion src/scripts/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type dayjs from "dayjs";
import type { MessageName0 } from "../common/locales.ts";
import type { SearchEngine as _SearchEngine } from "../common/search-engines.ts";
import type { QueryResult } from "./interactive-ruleset.ts";
import type { QueryResult, RulesetMatches } from "./interactive-ruleset.ts";
import type { LinkProps } from "./ruleset/ruleset.ts";

export type {
Expand Down Expand Up @@ -205,3 +205,11 @@ export type Subscription = {

export type Subscriptions = Record<SubscriptionId, Subscription>;
// #endregion Subscriptions

// #region MatchingRules

export type MatchingRuleKind = keyof Omit<RulesetMatches, "rulesetName">;

export type MatchingRulesText = Record<MatchingRuleKind, string>;

// #endregion MatchingRules
62 changes: 61 additions & 1 deletion src/scripts/utilities.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import dayjs from "dayjs";
import { Ruleset, type RulesetJSON } from "./ruleset/ruleset.ts";
import type { InteractiveRuleset } from "./interactive-ruleset.ts";
import {
type LinkProps,
Ruleset,
type RulesetJSON,
} from "./ruleset/ruleset.ts";
import type {
ErrorResult,
MatchingRuleKind,
MatchingRulesText,
PlainRuleset,
Result,
SuccessResult,
Expand Down Expand Up @@ -140,6 +147,59 @@ export function numberEntries<Key extends number, Value>(
export function lines(s: string): string[] {
return s ? s.split("\n") : [];
}

export function getMatchingRulesText(
ruleset: InteractiveRuleset,
props: LinkProps,
): MatchingRulesText {
const ruleTypes: MatchingRuleKind[] = [
"blockRules",
"unblockRules",
"highlightRules",
];
const matchingRulesText: MatchingRulesText = {
blockRules: "",
unblockRules: "",
highlightRules: "",
};

const matchingRules = ruleset.getMatchingRules(props);
const biggestLineNumber = Math.max(
...matchingRules
.flatMap(({ blockRules, unblockRules, highlightRules }) => [
...blockRules,
...unblockRules,
...highlightRules,
])
.map(({ lineNumber }) => lineNumber),
);
const lineNumberLength = String(biggestLineNumber).length;

for (const ruleType of ruleTypes) {
for (const match of matchingRules) {
// Check whether the ruleset contains rules of the current rule type
if (match[ruleType].length === 0) continue;
// Add header with ruleset name
matchingRulesText[ruleType] += `# ${match.rulesetName}\n`;
// Add individual rules
matchingRulesText[ruleType] += match[ruleType]
.map(({ lineContent, lineNumber }) => {
const lineNumberStr = String(lineNumber);
const formattedLineNumber =
lineNumberStr.length < lineNumberLength
? // Add left padding in order to align all line numbers
" ".repeat(lineNumberLength - lineNumberStr.length) + lineNumber
: lineNumberStr;
return `${formattedLineNumber}: ${lineContent}`;
})
.join("\n");
matchingRulesText[ruleType] += "\n";
}
}

return matchingRulesText;
}

// #endregion string

export function downloadTextFile(
Expand Down

0 comments on commit 6556524

Please sign in to comment.