diff --git a/src/parse.spec.ts b/src/parse.spec.ts index b8bf86f5..de5cd4f9 100644 --- a/src/parse.spec.ts +++ b/src/parse.spec.ts @@ -61,4 +61,10 @@ describe("Parse", () => { expect(() => parse("/*/")).toThrowError("Comment was not terminated"); }); + + it("should support legacy pseudo-elements with single colon", () => { + expect(parse(":before")).toEqual([ + [{ name: "before", data: null, type: "pseudo-element" }], + ]); + }); }); diff --git a/src/parse.ts b/src/parse.ts index 3e277db1..5c48e283 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -67,6 +67,19 @@ const unpackPseudos = new Set([ "host-context", ]); +/** + * Pseudo elements defined in CSS Level 1 and CSS Level 2 can be written with + * a single colon; eg. :before will turn into ::before. + * + * @see {@link https://www.w3.org/TR/2018/WD-selectors-4-20181121/#pseudo-element-syntax} + */ +const pseudosToPseudoElements = new Set([ + "before", + "after", + "first-line", + "first-letter", +]); + /** * Checks whether a specific selector is a traversal. * This is useful eg. in swapping the order of elements that @@ -472,10 +485,20 @@ function parseSelector( ? readValueWithParenthesis() : null, }); - continue; + break; } const name = getName(1).toLowerCase(); + + if (pseudosToPseudoElements.has(name)) { + tokens.push({ + type: SelectorType.PseudoElement, + name, + data: null, + }); + break; + } + let data: DataType = null; if (