diff --git a/jest.config.ts b/jest.config.ts index ac0b2764..7c68f9ab 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -11,7 +11,7 @@ const config: JestConfigWithTsJest = { }, testMatch: ["/__tests__/**/*test.ts"], transform: { - "^.+.tsx?$": ["ts-jest",{}], + "^.+.tsx?$": ["ts-jest", {}], }, }; diff --git a/packages/purgecss-from-pug/__tests__/data.ts b/packages/purgecss-from-pug/__tests__/data.ts index 62dd593e..156cc178 100644 --- a/packages/purgecss-from-pug/__tests__/data.ts +++ b/packages/purgecss-from-pug/__tests__/data.ts @@ -30,3 +30,18 @@ export const TEST_1_CLASS = [ ]; export const TEST_1_ID = ["a-link", "blo"]; + +export const TEST_1_ATTRIBUTE_NAMES = ["class", "id", "type", "disabled"]; + +export const TEST_1_ATTRIBUTE_VALUES = [ + "test-container", + "test-footer", + "a-link", + "first-class", + "second-class", + "enabled", + "blo", + "text", + "true", + "false", +]; diff --git a/packages/purgecss-from-pug/__tests__/index.test.ts b/packages/purgecss-from-pug/__tests__/index.test.ts index 88bbcc1e..5d77e2f0 100644 --- a/packages/purgecss-from-pug/__tests__/index.test.ts +++ b/packages/purgecss-from-pug/__tests__/index.test.ts @@ -1,35 +1,48 @@ -import purgePug from "../src/index"; +import { purgeCSSFromPug } from "../src/index"; -import { TEST_1_CONTENT, TEST_1_TAG, TEST_1_CLASS, TEST_1_ID } from "./data"; +import { + TEST_1_CONTENT, + TEST_1_TAG, + TEST_1_CLASS, + TEST_1_ID, + TEST_1_ATTRIBUTE_NAMES, + TEST_1_ATTRIBUTE_VALUES, +} from "./data"; -describe("purgePug", () => { +describe("purgeCSSFromPug", () => { describe("from a normal html document", () => { it("finds tag selectors", () => { - const received = purgePug(TEST_1_CONTENT); + const received = purgeCSSFromPug(TEST_1_CONTENT); for (const item of TEST_1_TAG) { - expect(received.includes(item)).toBe(true); + expect(received.tags.includes(item)).toBe(true); } }); it("finds classes selectors", () => { - const received = purgePug(TEST_1_CONTENT); + const received = purgeCSSFromPug(TEST_1_CONTENT); for (const item of TEST_1_CLASS) { - expect(received.includes(item)).toBe(true); + expect(received.classes.includes(item)).toBe(true); } }); it("finds id selectors", () => { - const received = purgePug(TEST_1_CONTENT); + const received = purgeCSSFromPug(TEST_1_CONTENT); for (const item of TEST_1_ID) { - expect(received.includes(item)).toBe(true); + expect(received.ids.includes(item)).toBe(true); } }); - it("finds all selectors", () => { - const received = purgePug(TEST_1_CONTENT); - const selectors = [...TEST_1_TAG, ...TEST_1_CLASS, ...TEST_1_ID]; - for (const item of selectors) { - expect(received.includes(item)).toBe(true); + it("finds attributes names", () => { + const received = purgeCSSFromPug(TEST_1_CONTENT); + for (const item of TEST_1_ATTRIBUTE_NAMES) { + expect(received.attributes.names.includes(item)).toBe(true); + } + }); + + it("finds attributes values", () => { + const received = purgeCSSFromPug(TEST_1_CONTENT); + for (const item of TEST_1_ATTRIBUTE_VALUES) { + expect(received.attributes.values.includes(item)).toBe(true); } }); }); diff --git a/packages/purgecss-from-pug/src/index.ts b/packages/purgecss-from-pug/src/index.ts index e8228b4d..62da972d 100644 --- a/packages/purgecss-from-pug/src/index.ts +++ b/packages/purgecss-from-pug/src/index.ts @@ -1,5 +1,14 @@ import lex from "pug-lexer"; +import type { ExtractorResultDetailed } from "purgecss"; +const getAttributeTokenValues = (token: lex.AttributeToken): string[] => { + if (typeof token.val === "string") { + return (token.mustEscape ? token.val.replace(/"/g, "") : token.val).split( + " ", + ); + } + return []; +}; /** * Get the potential selectors from Pug code * @@ -8,32 +17,39 @@ import lex from "pug-lexer"; * * @public */ -const purgeFromPug = (content: string): string[] => { +export const purgeCSSFromPug = (content: string): ExtractorResultDetailed => { const tokens = lex(content); - const selectors: string[] = []; + const extractorResult: ExtractorResultDetailed = { + attributes: { + // always add to attributes, to handle things like [class*=foo] + names: ["class", "id"], + values: ["true", "false"], + }, + classes: [], + ids: [], + tags: [], + undetermined: [], + }; for (const token of tokens) { - switch (token.type) { - case "tag": - case "id": - case "class": - selectors.push(...token.val.split(" ")); - break; - case "attribute": - if (token.name === "class" || token.name === "id") { - if (typeof token.val !== "string") continue; - selectors.push( - ...(token.mustEscape - ? token.val.replace(/"/g, "") - : token.val - ).split(" "), - ); - } - break; - default: - break; + if (token.type === "tag") { + extractorResult.tags.push(token.val); + } else if (token.type === "class") { + extractorResult.classes.push(...token.val.split(" ")); + extractorResult.attributes.values.push(...token.val.split(" ")); + } else if (token.type === "id") { + extractorResult.ids.push(token.val); + extractorResult.attributes.values.push(token.val); + } else if (token.type === "attribute") { + const tokenValues = getAttributeTokenValues(token); + if (token.name === "class") { + extractorResult.classes.push(...tokenValues); + } else if (token.name === "id") { + extractorResult.ids.push(...tokenValues); + } else { + extractorResult.attributes.names.push(token.name); + } + extractorResult.attributes.values.push(...tokenValues); } } - return selectors; + return extractorResult; }; - -export default purgeFromPug;