Skip to content

Commit e6c1ca7

Browse files
author
Timothy Lindvall
committed
feat: Merge rulesets from Compiled CSS into block.
- New Block method compiledClassesMap() creates a map of preset class names to its cooresponding Style node on the Block. - BlockFactory now traverses each rule from the Compiled CSS, finds the matching Style node from the Block, and merges in any declarations into its ruleset.
1 parent fa35c3d commit e6c1ca7

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

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

+25-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { Block } from "../BlockTree";
88
import { Options, ResolvedConfiguration, resolveConfiguration } from "../configuration";
99
import { CssBlockError } from "../errors";
1010
import { FileIdentifier, ImportedCompiledCssFile, ImportedFile, Importer } from "../importing";
11+
import { sourceRange } from "../SourceLocation";
1112
import { PromiseQueue } from "../util/PromiseQueue";
1213

1314
import { BlockParser, ParsedSource } from "./BlockParser";
@@ -313,6 +314,7 @@ export class BlockFactory {
313314

314315
// NOTE: If we had to upgrade the syntax version of a definition file, here's where'd we do that.
315316
// But this isn't a thing we need to do until we have multiple syntax versions.
317+
// TODO: Actually look at the declared version - error if it's greater than 1.
316318

317319
// NOTE: No need to run preprocessor - we assume that Compiled CSS has already been preprocessed.
318320
// Parse the definition file into an AST
@@ -339,10 +341,31 @@ export class BlockFactory {
339341
}
340342

341343
// Construct a Block out of the definition file.
342-
const block = this.parser.parseDefinitionSource(definitionAst, file.definitionIdentifier, file.blockId);
344+
const block = await this.parser.parseDefinitionSource(definitionAst, file.definitionIdentifier, file.blockId);
343345

344346
// Merge the rules from the CSS contents into the Block.
345-
// TODO: Actually merge the CSS rules in. (^_^")
347+
const styleNodesMap = block.compiledClassesMap(true);
348+
cssContentsAst.walkRules(rule => {
349+
rule.selectors.forEach(sel => {
350+
if (sel.split(".").length !== 1 || !sel.startsWith(".")) {
351+
// Skip it, we only care about selectors with only one class.
352+
return;
353+
}
354+
const styleNode = styleNodesMap[sel];
355+
if (!styleNode) {
356+
block.addError(
357+
new CssBlockError(
358+
`Selector ${sel} exists in Compiled CSS file but doesn't match any rules in definition file.`,
359+
sourceRange(this.configuration, cssContentsAst.root(), file.identifier, rule),
360+
),
361+
);
362+
return;
363+
}
364+
styleNode.rulesets.addRuleset(this.configuration, file.identifier, rule);
365+
});
366+
});
367+
368+
// TODO: Set the block's name from the block-name rule. (We skip this later for definition files.)
346369

347370
// And we're done!
348371
return block;

packages/@css-blocks/core/src/BlockTree/Block.ts

+22
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,28 @@ export class Block
434434
return result;
435435
}
436436

437+
/**
438+
* Fetch a dictionary of styles associated with this block, using any preset
439+
* selector as the key. If a given style doesn't have a preset selector, it
440+
* will be excluded from this dictionary.
441+
*
442+
* @param shallow - Pass true to exclude inherited objects.
443+
* @returns Collection of Styles objects, organized by preset selector value.
444+
*/
445+
compiledClassesMap(shallow?: boolean): ObjectDictionary<Styles> {
446+
const result = {};
447+
const all = this.all(shallow);
448+
449+
all.forEach(el => {
450+
const presetCssClass = el.presetCssClass;
451+
if (presetCssClass) {
452+
result[presetCssClass] = el;
453+
}
454+
});
455+
456+
return result;
457+
}
458+
437459
merged(): MultiMap<string, Styles> {
438460
let map = new MultiMap<string, Styles>(false);
439461
for (let obj of this.all()) {

0 commit comments

Comments
 (0)