Skip to content

Commit e8541a0

Browse files
committed
fix: Implement inline definitions in compiled blocks.
1 parent aa11e70 commit e8541a0

File tree

3 files changed

+58
-12
lines changed

3 files changed

+58
-12
lines changed

packages/@css-blocks/core/src/BlockCompiler/BlockDefinitionCompiler/index.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import { AttributeSelector, ClassSelector, Declaration, DefinitionAST, Definitio
55
import { AttrValue, Block, BlockClass, Style, isAttrValue, isBlockClass } from "../../BlockTree";
66
import { ResolvedConfiguration } from "../../configuration";
77

8-
import { PostcssASTBuilder } from "./PostcssASTBuilder";
98
import { CompiledDefinitionMapper, PathResolver } from "./CompiledDefinitionMapper";
9+
import { PostcssASTBuilder } from "./PostcssASTBuilder";
1010

1111
export { PathResolver } from "./CompiledDefinitionMapper";
1212

@@ -140,8 +140,11 @@ export class BlockDefinitionCompiler {
140140
css.append(comment);
141141
}
142142

143-
insertInlineBlockDefinitionURLComment(_css: postcss.Root, _definition: postcss.Root) {
144-
throw new Error("Method not implemented.");
143+
insertInlineBlockDefinitionURLComment(css: postcss.Root, definition: postcss.Root) {
144+
let cssText = definition.toResult().css;
145+
let base64EncodedText = Buffer.from(cssText).toString("base64");
146+
let url = `data:text/css;base64,${base64EncodedText}`;
147+
this.insertBlockDefinitionURLComment(css, url);
145148
}
146149
}
147150

packages/@css-blocks/core/src/BlockParser/BlockParser.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import { Options, ResolvedConfiguration, resolveConfiguration } from "../configu
66
import { CssBlockError } from "../errors";
77
import { FileIdentifier } from "../importing";
88

9+
import { builders } from "./ast";
910
import { addInterfaceIndexes } from "./features/add-interface-indexes";
1011
import { addPresetSelectors } from "./features/add-preset-selectors";
11-
import { builders } from "./ast";
1212
import { assertForeignGlobalAttribute } from "./features/assert-foreign-global-attribute";
1313
import { composeBlock } from "./features/composes-block";
1414
import { constructBlock } from "./features/construct-block";

packages/@css-blocks/core/test/block-definition-test.ts

+51-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { postcss } from "opticss";
44

55
import * as cssBlocks from "../src";
66
import { Block, BlockCompiler, BlockFactory } from "../src";
7-
import { BlockDefinitionCompiler } from "../src/BlockCompiler/BlockDefinitionCompiler";
7+
import { BlockDefinitionCompiler, INLINE_DEFINITION_FILE } from "../src/BlockCompiler/BlockDefinitionCompiler";
88

99
import { BEMProcessor } from "./util/BEMProcessor";
1010
import { setupImporting } from "./util/setupImporting";
@@ -17,19 +17,30 @@ function clean(text: string): string {
1717
return lines(text).join(" ").replace(/\s+/g, " ");
1818
}
1919

20-
async function compileBlockWithDefinition(factory: BlockFactory, blockFilename: string): Promise<{block: Block; cssResult: postcss.Result; definitionResult: postcss.Result}> {
20+
async function compileBlockWithDefinition(factory: BlockFactory, blockFilename: string, definitionFilename?: string ): Promise<{block: Block; cssResult: postcss.Result; definitionResult: postcss.Result}>;
21+
async function compileBlockWithDefinition(factory: BlockFactory, blockFilename: string, definitionFilename: typeof INLINE_DEFINITION_FILE): Promise<{block: Block; cssResult: postcss.Result; definitionResult: undefined}>;
22+
async function compileBlockWithDefinition(factory: BlockFactory, blockFilename: string, definitionFilename?: string | typeof INLINE_DEFINITION_FILE): Promise<{block: Block; cssResult: postcss.Result; definitionResult: postcss.Result | undefined}> {
2123
let config = factory.configuration;
2224
let importer = config.importer;
2325
let block = await factory.getBlock(importer.identifier(null, blockFilename, config));
2426
let definitionCompiler = new BlockDefinitionCompiler(postcss, (_b, p) => p.replace(".block", ""), config);
2527
let compiler = new BlockCompiler(postcss, config);
2628
compiler.setDefinitionCompiler(definitionCompiler);
27-
let definitionFilename = blockFilename.replace(".block", ".block.d");
28-
let {css, definition} = compiler.compileWithDefinition(block, block.stylesheet!, new Set(), definitionFilename);
29-
let cssFilename = blockFilename.replace(".block", "");
30-
let cssResult = css.toResult({to: cssFilename});
31-
let definitionResult = definition.toResult({to: definitionFilename});
32-
return {block, cssResult, definitionResult};
29+
if (typeof definitionFilename === "undefined") {
30+
definitionFilename = blockFilename.replace(".block", ".block.d");
31+
}
32+
if (typeof definitionFilename === "symbol") {
33+
let {css} = compiler.compileWithDefinition(block, block.stylesheet!, new Set(), definitionFilename);
34+
let cssFilename = blockFilename.replace(".block", "");
35+
let cssResult = css.toResult({to: cssFilename});
36+
return {block, cssResult, definitionResult: undefined};
37+
} else {
38+
let {css, definition} = compiler.compileWithDefinition(block, block.stylesheet!, new Set(), definitionFilename);
39+
let cssFilename = blockFilename.replace(".block", "");
40+
let cssResult = css.toResult({to: cssFilename});
41+
let definitionResult = definition.toResult({to: definitionFilename});
42+
return {block, cssResult, definitionResult};
43+
}
3344
}
3445

3546
@suite("Block Factory")
@@ -75,6 +86,38 @@ export class BlockFactoryTests extends BEMProcessor {
7586
.foo[size="small"] { block-class: test-block__foo--size-small; block-interface-index: 5 }
7687
`));
7788
}
89+
@test async "can generate an inline definition"() {
90+
let { imports, factory } = setupImporting();
91+
let filename = "test-block.block.css";
92+
imports.registerSource(
93+
filename,
94+
`:scope { color: purple; }
95+
:scope[large] { font-size: 20px; }
96+
.foo { float: left; block-alias: foo "another-foo"; }
97+
.foo[size=small] { font-size: 5px; }`,
98+
);
99+
let {block, cssResult} = await compileBlockWithDefinition(factory, filename, INLINE_DEFINITION_FILE);
100+
let css = cssResult.css.replace(/data:text\/css;base64,(.*)==/, "SNIP");
101+
let urlData = RegExp.$1;
102+
assert.deepEqual(
103+
clean(css),
104+
clean(`/*#css-blocks ${block.guid}*/
105+
.test-block { color: purple; }
106+
.test-block--large { font-size: 20px; }
107+
.test-block__foo { float: left; }
108+
.test-block__foo--size-small { font-size: 5px; }
109+
/*#blockDefinitionURL=SNIP*/
110+
/*#css-blocks end*/`),
111+
);
112+
assert.deepEqual(
113+
clean(Buffer.from(urlData, "base64").toString("utf8")),
114+
clean(`@block-syntax-version 1;
115+
:scope { block-id: "${block.guid}"; block-name: "test-block"; block-class: test-block; block-interface-index: 0 }
116+
:scope[large] { block-class: test-block--large; block-interface-index: 2 }
117+
.foo { block-class: test-block__foo; block-interface-index: 3; block-alias: foo another-foo }
118+
.foo[size="small"] { block-class: test-block__foo--size-small; block-interface-index: 5 }
119+
`));
120+
}
78121

79122
@test async "can generate a definition with block-global declarations."() {
80123
let { imports, factory } = setupImporting();

0 commit comments

Comments
 (0)