feat(css-parser, formatter): font-face rule
ADD
internal/ast/css/font/CSSFontFace.ts
+import {CSSBlock, NodeBaseWithComments} from "@internal/ast";
+import {createBuilder} from "../../utils";
+
+export interface CSSFontFace extends NodeBaseWithComments {
+ readonly type: "CSSFontFace";
+ readonly value: CSSBlock;
+}
+
+export const cssFontFace = createBuilder<CSSFontFace>(
+ "CSSFontFace",
+ {
+ bindingKeys: {},
+ visitorKeys: {
+ value: true,
+ },
+ },
+);

MODIFY
internal/ast/css/unions.ts
internal/ast/css/unions.ts
@@ -6,6 +6,7 @@ import {
CSSComma,
CSSCustomProperty,
CSSDimension,
+ CSSFontFace,
CSSFunction,
CSSHash,
CSSIdentifier,
@@ -83,4 +84,8 @@ export type RangeValueLTValue = [
CSSMediaFeatureName
];
-export type CSSAtRuleValue = CSSBlock | CSSKeyframe | CSSMediaQueryList;
+export type CSSAtRuleValue =
+ | CSSBlock
+ | CSSKeyframe
+ | CSSMediaQueryList
+ | CSSFontFace;

MODIFY
internal/ast/index.ts
internal/ast/index.ts
@@ -12,7 +12,7 @@ export * from "./unions";
export {bindingKeys, nodeNames, visitorKeys} from "./utils";
export type AnyNodes = AnyNode | (AnyNode[]);
-/* GENERATED:START(hash:48235210905e08e9607d191d07f7ee16bf683916,id:main) Everything below is automatically generated. DO NOT MODIFY. Run `./rome run scripts/generated-files/ast` to update. */
+/* GENERATED:START(hash:6451ba35633a1ebbf85e8a824f4a8a29cbd05309,id:main) Everything below is automatically generated. DO NOT MODIFY. Run `./rome run scripts/generated-files/ast` to update. */
export * from "./common/comments/CommentBlock";
export * from "./common/comments/CommentLine";
export * from "./css/core/CSSAtRule";
@@ -32,6 +32,7 @@ export * from "./css/core/CSSComma";
export * from "./css/core/CSSCustomProperty";
export * from "./css/core/CSSDeclaration";
export * from "./css/core/CSSDimension";
+export * from "./css/font/CSSFontFace";
export * from "./css/core/CSSFunction";
export * from "./css/core/CSSHash";
export * from "./css/core/CSSIdentifier";
@@ -332,6 +333,7 @@ export type AnyNode =
| n.CSSCustomProperty
| n.CSSDeclaration
| n.CSSDimension
+ | n.CSSFontFace
| n.CSSFunction
| n.CSSHash
| n.CSSIdentifier

ADD
internal/css-parser/parser/font.ts
+import {CSSParser} from "@internal/css-parser/types";
+import {CSSFontFace} from "@internal/ast/css/font/CSSFontFace";
+import {matchToken, readToken} from "@internal/css-parser/tokenizer";
+import {parseDeclarationBlock} from "@internal/css-parser/parser/declaration";
+
+export function parseFontFace(parser: CSSParser): CSSFontFace | undefined {
+ const start = parser.getPosition();
+
+ while (matchToken(parser, "Whitespace")) {
+ readToken(parser, "Whitespace");
+ }
+
+ const block = parseDeclarationBlock(parser);
+
+ if (block) {
+ return parser.finishNode(
+ start,
+ {
+ type: "CSSFontFace",
+ value: block,
+ },
+ );
+ }
+
+ return undefined;
+}

MODIFY
internal/css-parser/parser/rules.ts
internal/css-parser/parser/rules.ts
@@ -5,10 +5,10 @@ import {parseSelectors} from "@internal/css-parser/parser/selectors";
import {descriptions} from "@internal/diagnostics";
import {parseKeyframe} from "@internal/css-parser/parser/keyframe";
import {parseDeclarationBlock} from "@internal/css-parser/parser/declaration";
-import {parseComplexBlock} from "@internal/css-parser/parser/block";
import {parseComponentValue} from "@internal/css-parser/parser/value";
import {parseMediaList} from "@internal/css-parser/parser/media";
import {parseAtSupports} from "@internal/css-parser/parser/supports";
+import {parseFontFace} from "@internal/css-parser/parser/font";
export function parseRules(
parser: CSSParser,
@@ -102,6 +102,12 @@ export function parseAtRule(parser: CSSParser): CSSAtRule {
block = parseKeyframe(parser);
break;
}
+
+ if (previousToken.value === "font-face") {
+ block = parseFontFace(parser);
+ break;
+ }
+
if (previousToken.value === "supports") {
const value = parseAtSupports(parser);
if (value) {
@@ -109,7 +115,7 @@ export function parseAtRule(parser: CSSParser): CSSAtRule {
}
}
if (matchToken(parser, "LeftCurlyBracket")) {
- block = parseComplexBlock(parser);
+ block = parseDeclarationBlock(parser);
break;
}
const parsedValue = parseComponentValue(parser);

ADD
internal/css-parser/test-fixtures/font/input.css
+@font-face {
+ src: url("");
+}

ADD
internal/css-parser/test-fixtures/font/input.test.md
+# `index.test.ts`
+
+**DO NOT MODIFY**. This file has been autogenerated. Run `rome test internal/css-parser/index.test.ts --update-snapshots` to update.
+
+## `font`
+
+```javascript
+CSSRoot {
+ body: [
+ CSSAtRule {
+ name: "font-face"
+ prelude: []
+ block: CSSFontFace {
+ value: CSSBlock {
+ value: [
+ CSSDeclaration {
+ name: "src"
+ value: [
+ CSSUrlFunction {
+ name: "url"
+ params: [
+ CSSString {
+ value: ""
+ loc: SourceLocation font/input.css 2:10-2:12
+ }
+ ]
+ loc: SourceLocation font/input.css 2:6-2:13
+ }
+ ]
+ important: false
+ loc: SourceLocation font/input.css 2:1-2:13
+ }
+ ]
+ startingTokenValue: "{"
+ loc: SourceLocation font/input.css 1:11-3:1
+ }
+ loc: SourceLocation font/input.css 1:10-3:1
+ }
+ loc: SourceLocation font/input.css 1:0-3:1
+ }
+ ]
+ comments: []
+ corrupt: false
+ diagnostics: []
+ path: RelativePath<font/input.css>
+ loc: SourceLocation font/input.css 1:0-3:1
+}
+```

ADD
internal/formatter/builders/css/font/CSSFontFace.ts
+import {CSSFontFace} from "@internal/ast";
+import {Builder, Token} from "@internal/formatter";
+
+export default function CSSFontFace(builder: Builder, node: CSSFontFace): Token {
+ return builder.tokenize(node.value, node);
+}

MODIFY
internal/formatter/builders/index.ts
internal/formatter/builders/index.ts
@@ -14,7 +14,7 @@ const builders: ExtendedMap<string, BuilderMethod<any>> = new ExtendedMap(
);
export default builders;
-/* GENERATED:START(hash:1e5cf35eff15de570c07db3b0ef5e94c8cce3ecd,id:main) Everything below is automatically generated. DO NOT MODIFY. Run `./rome run scripts/generated-files/ast` to update. */
+/* GENERATED:START(hash:7a8ec38bd9c62bb0b3bc19e881f1f3f2f1096159,id:main) Everything below is automatically generated. DO NOT MODIFY. Run `./rome run scripts/generated-files/ast` to update. */
import CommentBlock from "./common/comments/CommentBlock";
builders.set("CommentBlock", CommentBlock);
import CommentLine from "./common/comments/CommentLine";
@@ -53,6 +53,8 @@ import CSSDeclaration from "./css/core/CSSDeclaration";
builders.set("CSSDeclaration", CSSDeclaration);
import CSSDimension from "./css/core/CSSDimension";
builders.set("CSSDimension", CSSDimension);
+import CSSFontFace from "./css/font/CSSFontFace";
+builders.set("CSSFontFace", CSSFontFace);
import CSSFunction from "./css/core/CSSFunction";
builders.set("CSSFunction", CSSFunction);
import CSSHash from "./css/core/CSSHash";

ADD
internal/formatter/test-fixtures/css/font/input.css
+@font-face {
+ src: url("test");
+}

ADD
internal/formatter/test-fixtures/css/font/input.test.md
+# `index.test.ts`
+
+**DO NOT MODIFY**. This file has been autogenerated. Run `rome test internal/formatter/index.test.ts --update-snapshots` to update.
+
+## `css > font`
+
+### `Diagnostics`
+
+```
+
+```
+
+### `Input`
+
+```css
+@font-face {
+ src: url("test");
+}
+
+```
+
+### `Output`
+
+```css
+@font-face {
+ src: url("test");
+}
+
+
+```

feat(css-parser, formatter): font-face rule (#1414)