Options
All
  • Public
  • Public/Protected
  • All
Menu

Package @css-blocks/core

CSS Blocks

@css-blocks/core

@css-blocks/core drives everything that happens between reading a Block file and outputting final CSS! This package nearly deserves to be a mono-repo in its own right. All BlockSyntax features, functionality for constructing BlockTrees, the base class for all Analyzers, the BlockFactory and BlockCompiler implementations, and more, live in this package. As such, this codebase is best described in "packages", as you'll see below.

Options

Option Default Description
rootDir process.cwd() The root directory from which all sources are relative.
outputMode "BEM" Block file output mode. One of OutputMode
preprocessors {} A preprocessor function can be declared by Syntax.
importer FilesystemImporter A custom importer to resolve identifiers passed to @block-reference.
importerData {} Additional data to make available to the importer.
maxConcurrentCompiles 4 Limits block parsing and compilation to this number of threads at any one time.
disablePreprocessChaining false If a preprocessor function is declared for css, all blocks will be ran through it, even those that were pre-processed for another syntax. This can be disabled by setting disablePreprocessChaining to true.

Packages

/src/BlockTree

A BlockTree is an in-memory data model that captures all the complexity represented in a single Block file and exposes APIs for querying and manipulating its attributes.

BlockTrees are strongly typed (read: children must be of a single type), N-Ary (read: every layer may have any number of child nodes) trees composed of four (4) possible node types. These nodes must be arranged in the following hierarchy:

Block => BlockClass => Attribute => AttrValue

The core implementation of BlockTree nodes, which every node type extends, lives in /src/BlockTree/Inheritable.ts. All nodes have common APIs concerning tree hierarchy and inheritance / resolution.

Inheritance Example Here.

These four (4) node types each fit in to one of two (2) classifications: Container Nodes and Style Nodes. These classifications and node types are described in detail below.

Container Nodes

Container Nodes...contain other nodes ;) These nodes contain logical groupings of like-nodes. Each container node type may implement convenience methods that make sense for the type of nodes it contains.

Block

A Block node is always the root of any BlockTree. A Block may be parent to any number of BlockClasses. The :scope selector is considered a special kind of BlockClass selector and is also stored as a child of Block.

Block nodes also store all data related to any @block-references, the block-name, implemented Blocks, the inherited Block, and any other metadata stored in the Block file. Blocks also have a special rootClass property that points directly to the child BlockClass that represents the parsed :scope selector .

Attribute

An Attribute node represents a single unique attribute namespace|name pair and is a parent to any number of AttrValue nodes, which represent all the possible attribute values for this Attribute discovered in the Block file. An Attribute node's parent is always a BlockClass. Attribute selectors where no value is specified are considered a special kind of AttrValue and is also stored as a child of Attribute.

Attribute nodes expose APIs suited for querying information about their children AttrValue.

Style Nodes

Style nodes represent fully resolved selectors that apply a CSS ruleset the the matching elements. For css-blocks these are BlockClass and AttrValue nodes.

Style nodes inherit from the abstract /src/BlockTree/Style.ts class and augment the base Inheritable class to store RulesetContainer objects to track property concerns and property resolutions from all rulesets that target this Style and its pseudo-elements, and possess methods to query own and inherited generated class names for the Style node.

BlockClass

BlockClass nodes represent class selectors discovered in a Block file. BlockClass nodes may contain one to many Attribute container nodes and have methods for querying own and inherited Attribute and their AttrValue nodes.

AttrValue

AttrValue nodes represent an fully qualified attribute selector (meaning namespace, name and value are all defined) discovered in a Block file. AttrValue nodes are leaf nodes and may have no children.

All Together Now

All these BlockTree objects, and the APIs they provide, enable css-blocks core to build an in-memory representation of any Block file, its dependencies, and all its data, in a format that is easily traversable and query-able.

For details on all the APIs available on BlockTrees and their constituent parts, I invite you to explore the API documentation.

/src/BlockCompiler

The BlockCompiler package delivers a single class: the BlockCompiler (go figure 😉).

BlockCompilers are responsible for taking a Block object, a postcss.Root (and an optional Analyzer to help guide final stylesheet output), and returning a transformed postcss.Root with all classes and states replaces with their globally unique output names, and all resolution and inheritance selectors emitted in the stylesheet.

Note: Currently in master we don't accept a whole Analyzer, just a single Analysis. We should.

Much of what currently goes in to Block compilation amounts to a find and replace of all classes and states with their generated, globally unique, class names. The format of these generated selectors are dictated by the OutputMode specified in the CSS Blocks' configuration, and defaults to BEM.

Block compilation becomes a little more complicated once we begin emitting conflict resolution selectors. In cases where explicit resolutions are provided, or when one Block inherits from another and re-defined an inherited CSS property, we need to emit a conflict resolution selector so the browser exhibits the expected behavior. This involves merging two, potentially complicated, selectors so the new selector will only match when both overridden selectors are applied. For example:

Input

/ other.css /
:scope { block-name: "other"; }
:scope[state|active] .bar { color: blue; }

/ main.css / @block-reference other from "./other.css"; :scope { block-name: "main"; } :scope:hover .foo { color: red; color: resolve("other.bar"); }

Output

/ Compiled "other.css" /
.other--active .other__bar { color: blue; }

/ Compiled "main.css" / .main:hover .main__foo { color: red; }

/ Emitted Resolution Selector / .other--active.main:hover .main__foo.other__bar { color: blue; }

/src/BlockParser

The BlockParser package contains all constructs that handle converting an Block file into a BlockTree, including preprocessor integrations.

BlockFactory

The primary class delivered by BlockParser is the BlockFactory. The BlockFactory is responsible for creating new Block objects and ensuring that every unique Block file is only parsed once. If the same file is re-requested, the BlockFactory will return the same promise as the previous parse request which will resolve with the same shared Block object. Like most Factory Pattern implementations, most consumers will exclusively interface with the BlockFactory when creating new Blocks and should not have to worry about the parser itself.

Preprocessor Support

It is also the responsibility of the BlockFactory to only start Block compilation after all user-provided preprocessor steps have been finished. The configuration options for preprocessor integration can be found in this package.

BlockParser

Under the hood, the BlockFactory uses a BlockParser to convert the provided postcss.Root into a new Block object. The BlockParser is modeled after something akin to the Builder Pattern and runs the newly minted Block through a series of feature-specific "middleware". Each middleware, found in src/BlockParser/features, is responsible for reading, and augmenting the new Block, with a single language feature concern.

It is important that the supplied postcss.Root is not transformed in any way during this parse phase. The postcss tree should be considered read-only in all BlockParser feature middleware and only be used to construct the resulting BlockTree.

Note: The only place that block-intermediates are used outside of BlockParser is one place in BlockTree. We should work to refactor block-intermediates out of BlockTree and make it a construct completely private to the package.

/src/BlockSyntax

The BlockSyntax package delivers CSS Blocks specific syntax constants, and a few simple parsing functions, used in Block files. [You can look at the API documentation][TODO] for details.

All CSS Blocks specific syntax used in Block files should be defined here. No other package should be re-defining these constants for parsing functions.

/src/Analyzer

Note: I'm writing this section, not as the Analyzer implementation is currently written, but how I'd like to see it implemented in the near future. I have this working as described here in a branch.

The Analyzer package delivers the classes, data models, and types that are required by a [Template Integration][TODO]. It is the Template Integrations' responsibility to, given a number of template entry-points, know how to crawl the template dependency tree and analyze every element of every template discovered.

There are three (3) core classes that drive every Template Analyzer integration:

Analyzer

The Analyzer class is the base class that all Template Integrations must derive from. It represents the project-wide analysis of all templates reachable from the list of entry-points provided. An extender of Analyzer is expected to implement the abstract analyze(...entry-points: string) method, as this is what will be called by Build Integrations to kick off analysis.

The Analyzer has a factory method, getAnalysis() to retrieve a new Analysis object (described below) for each template discovered. The Analyzer will then crawl the contents of the template and log all Block usage data for the template on that Analysis object.

Analyzers have a number of convenience methods for accessing and iterating over Analysis objects created after an analysis pass. Analysis objects may be re-used (ex: in dev rebuilds) by calling their reset() method to clear all caches and saved data from the previous analysis pass. These methods can be explored over in the [Analysis API documentation][TODO].

Analysis

The Analysis object represents a single template's Block usage data. These are created by the Analyzer during an analysis pass for every template discovered when crawling the template dependency tree.

It is the Template Integration's responsibility to assemble each Analysis to accurately represent the Block usage in the template. This includes adding all referenced Blocks to the Analysis object, and creating a new ElementAnalysis (described below) for every element in the template and registering all used Block styles with the ElementAnalysis.

Analysis objects function as factories for ElementAnalysis objects. When a new element is discovered, Template Integrations can call startElement() on the current template's Analysis, to create a new ElementAnalysis. The integration can then add discovered Block styles to the ElementAnalysis. Once all Block styles have been registered with the ElementAnalysis, the integration may then call endElement() to seal the ElementAnalysis.

ElementAnalysis

The ElementAnalysis object represents a single element's Block usage data and are retrieved from a template's Analysis object using the Analysis.startElement() factory function. The last returned ElementAnalysis object remains un-sealed until Analysis.endElement() is called.

Un-sealed ElementAnalysis objects may be used to store Block style usage data saved to them (read: BlockClass and AttrValues). Any given Block style used in a template may be either Static, Dynamic, or Mutually Exclusive.

For example, given the following Block file, we can determine the type of usage in the handlebars snippets below:

.my-class            { / ... / }
.other-class         { / ... / }
[state|active]       { / ... / }
[state|color="red"]  { / ... / }
[state|color="blue"] { / ... / }

Static styles are guaranteed to never change:

<div class="my-class" state:active="true"></div>

Dynamic styles may or may not be applied depending on application state:

<div class="{{style-if value 'my-class'}}" state:active={{isActive}}></div>

Mutually Exclusive styles are guaranteed to never be used on the element at the same time:

{{!-- my-<span class="hljs-keyword">class</span> and other-<span class="hljs-keyword">class</span> are mutually exclusive --}}
{{!-- [state|color=red] and [state|color=blue] are mutually exclusive --}}
<div class="{{style-if value 'my-class' 'other-class'}}" state:color={{color}}></div>

Every Template Integration's syntax for consuming Blocks will differ slightly. It is the responsibility of the integration to implement template parsing and Block object discovery to feed in to the ElementAnalysis APIs. You can read more about these style tracking methods on the [ElementAnalysis API documentation][https://css-blocks.com/api/classes/_css_blocks_core.elementanalysis.html].

Once an ElementAnalysis is sealed, a number of automatic validations run on it to ensure no template rules have been violated. These template validators are defined as independent plugins and may be enabled or disabled individually. By default, they are all enabled. These validations live under /src/Analyzer/validations and include:

  • attribute-group-validator: Verify that any given State attribute is only applied once to an element.
  • attribute-parent-validator: Ensure that State attributes are always applied with their owner class.
  • class-paris-validator: If two classes from the same block are applied to the same element, throw.
  • property-conflict-validator: If two styles might be applied at the same time on the same element, and they have an un-resolved conflicting property concern, throw.
  • root-class-validator: Prevent the :scope class and a BlockClass from being applied to the same element.

/src/TemplateRewriter

Because each Template Integration has to leverage whatever plugin / AST transform system is provided by the templating system, Rewriters are a little more free-form than Analyzers. As such, there is no single base class for Rewriters to extend from.

Instead, this package delivers data models that Template Integrations may leverage to query data about how to rewrite elements they encounter during the rewrite phase. It is the responsibility of the Build Integration to shuttle these rewrite data to the actual rewriter integration.

Note: We really need to standardize how data is handed off from the Analyzer to the Rewriter, agnostic of the Build Integration... This works for the limited number of template integrations we have today, but will not scale well. Aka: a Vue integration may need its own Broccoli build integration because Broccoli is currently very Glimmer specific. We have too tight a coupling between Template Integration and Build Integration.

TODO: Write more about TemplateRewriter data models and their APIs.

/src/configuration

The configuration package contains the CSS Blocks build configuration utilities, including Typescript types for the configuration hash, a configuration reader to normalize user-provided configuration hashes with default values.

See the options table at the top of this file for configuration object details.

/src/importing

CSS Blocks needs to know where to get a Block file's contents when provided a file FileIdentifier from an @block-reference. Most of the time, this file path will be a file on disk, in which case the default importer delivered with CSS Blocks will work out of the box. However, in cases where custom resolution of @block-references are required, consumers are able to provide their own implementation of the CSS Blocks Importer interface to deliver this custom behavior.

A custom importer may be passed to CSS Blocks via the importer options of the configuration object. Custom importers will understand how to resolve information about the FileIdentifier passed to @block-reference and are used to abstract application or platform specific path resolution logic.

Any CSS Blocks Importer must implement the interface defined for a CSS Blocks Importer in /src/importing/types.ts. Every importer is required to have a number of introspection methods that return standard metadata for a given FileIdentifier:

  • identifier: Return a globally unique identifier for the FileIdentifier
  • defaultName: Return the default Block name to use if no block-name is set.
  • filesystemPath: If this FileIdentifier is backed by the filesystem, return the absolute file path.
  • debugIdentifier: Returns a string meant for human consumption that identifies the file. Used for debug and error reporting.
  • syntax: Return the syntax type the contents of this file are written in. One of Syntax.

However, the primary method for any importer is its import() method. import() returns a promise that resolves with a metadata object which not only contains all the information outlined above, but also the stringified contents of the file. It is these contents that the BlockFactory will use to create a BlockTree.

For any custom importers that require extra data to be passed by the end-user, the importerData CSS BLocks config option has been specially reserved as a namespaced location for extra importer data to be passed. All importer methods are passsed the full CSS Blocks config object as their last argument.

CSS Blocks ships with two (2) pre-defined importers.

  1. FilesystemImporter: This is the default importer used by CSS Blocks if no other is provided. It enables @block-references to resolve relative and absolute file references
  2. PathAliasImporter: The PathAliasImporter is a replacement for the fileystem importer. Relative import paths are first checked to see if they match an existing file relative to the from identifier (when provided). Then if the relative import path has a first segment that is any of the aliases provided the path will be made absolute using that alias's path location. Finally any relative path is resolved against the rootDir specified in the CSS Block configuration options.

/src/util

Utilities used inside the CSS Blocks repo. These are:

  • PromiseQueue: Enqueue a series of tasks to run in parallel. If a task fails, it will wait for all running jobs to either finish or fail before rejecting.
  • unionInto: Like Object.assign, but for Sets.

Index

Enumerations

Classes

Interfaces

Type aliases

Variables

Functions

Object literals

Type aliases

AnyNode

AnyNode: Inheritable<any, any, any, any, any>

AttributeNode

BlockClassNode

BlockClassNode: object

Type declaration

  • Optional blockName?: undefined | string
  • blockType: class
  • node: selectorParser.ClassName

BlockNode

BlockNode: object

Type declaration

  • Optional blockName?: undefined | string
  • blockType: block
  • node: selectorParser.Tag

BooleanExpression

BooleanExpression: AndExpression<V> | OrExpression<V> | NotExpression<V>

ChoiceMapper

ChoiceMapper: function

Type declaration

    • (includeAbsent: boolean, ...styles: Style[]): AttributeValueChoice
    • Parameters

      • includeAbsent: boolean
      • Rest ...styles: Style[]

      Returns AttributeValueChoice

ClassAttributeNode

ClassAttributeNode: object

Type declaration

  • Optional blockName?: undefined | string
  • blockType: classAttribute
  • node: selectorParser.Attribute

ClassExpressionMap

ClassExpressionMap: ObjectDictionary<BooleanExpression<number> | undefined>

ClassMapper

ClassMapper: function

Type declaration

    • (style: Style): ValueConstant | AttributeValueSet
    • Parameters

      Returns ValueConstant | AttributeValueSet

ClassNode

ConditionalAttr

ConditionalAttr: Conditional<BooleanExpression> & HasAttrValue

An attribute value that is conditionally set

ConditionalAttrGroup

ConditionalAttrGroup: Switch<StringExpression> & HasGroup

An attribute group where one is set conditionally

ConditionalDependentAttr

ConditionalDependentAttr: Conditional<BooleanExpression> & Dependency & HasAttrValue

An attribute value that is only set when its condition is true and its dynamic class is set

ConditionalDependentAttrGroup

ConditionalDependentAttrGroup: Switch<StringExpression> & Dependency & HasGroup

An attribute group that are only set when its dynamic class is set and where one (or none) is selected at runtime.

ConfigurationObjectKeys

ConfigurationObjectKeys: "importerData" | "preprocessors"

ConfigurationSimpleKeys

ConfigurationSimpleKeys: "outputMode" | "importer" | "rootDir" | "disablePreprocessChaining" | "maxConcurrentCompiles"

Conflict

Conflict: [string, string]

ConflictMap

ConflictMap: MultiMap<Property, Ruleset>

DebugChannel

DebugChannel: "comment" | "stderr" | "stdout"

Declaration

Declaration: object

Type declaration

  • node: Declaration
  • value: string

DependentAttr

DependentAttr: Dependency & HasAttrValue

An attribute value that is only set when its dynamic class is set

DynamicAttr

DynamicAttr: ConditionalAttr<BooleanExpression> | DependentAttr | ConditionalDependentAttr<BooleanExpression>

An attribute value that is dynamic for any reason

DynamicAttrGroup

DynamicAttrGroup: ConditionalAttrGroup<StringExpression> | ConditionalDependentAttrGroup<StringExpression>

An attribute group that are dynamic for any reason

DynamicAttrs

DynamicAttrs: DynamicAttr<BooleanExpression> | DynamicAttrGroup<StringExpression>

Any type of dynamic attribute or group of attributes.

DynamicClasses

DynamicClasses: Conditional<TernaryExpression> & TrueCondition<BlockClass> | Conditional<TernaryExpression> & FalseCondition<BlockClass> | Conditional<TernaryExpression> & TrueCondition<BlockClass> & FalseCondition<BlockClass>

a ternary expression where different classes can be set when true or false

ErrorCallback

ErrorCallback: function

Type declaration

    • (str: string, loc?: undefined | null, details?: undefined | string): void
    • Parameters

      • str: string
      • Optional loc: undefined | null
      • Optional details: undefined | string

      Returns void

ExprItem

ExprItem: number | BooleanExpression<number>

FileIdentifier

FileIdentifier: string

A FileIdentifier is a string with a whatever internal encoding is needed to uniquely resolve a file or relative importPath against the identifier by an importer. FileIdentifiers may be serialized across processes and should not encode any transient state. If an importer wraps another importer, it is responsible for mangling and de-mangling the import identifier to ensure that the namespaces of the importers do not collide.

Care should be taken to ensure that the same block file is never returned with different identifiers. The identifier a returned on an ImportedFile should be different from the identifier that was requested if the requested identifier was not canonical. The block factory will ensure that all blocks returned to the consumer are unique to the canonical identifier.

ImporterData

ImporterData: ObjectDictionary<whatever>

Importers have a special importerData property on the CSS Blocks configuration options hash where custom importers can request for additional importer configuration to be passed. All Importer methods are passed the configuration hash.

NodeAndType

Options

Options: Partial<Readonly<Configuration>>

Valid user-provided options for the CSS Blocks plugin.

PathAliases

PathAliases: Alias[] | ObjectDictionary<string>

Preprocessor

Preprocessor: function

Type declaration

Preprocessors

Preprocessors: object

A map of supported syntaxes to the preprocessor function for that syntax. The keys must be one of the members of {Syntax}.

see

{Syntax}

Type declaration

PropMap

PropMap: TwoKeyMultiMap<Pseudo, Property, Ruleset>

Property

Property: string

Property

Property: string

Pseudo

Pseudo: string

Pseudo

Pseudo: string

Renumberer

Renumberer: function

Type declaration

Resolution

Resolution: object

Type declaration

  • node: Rule
  • property: string
  • resolution: S

ResolvedConfiguration

ResolvedConfiguration: Readonly<Configuration>

Options that can/will be read but not changed. Default values will have already been provided.

RootAttributeNode

RootAttributeNode: object

Type declaration

  • Optional blockName?: undefined | string
  • blockType: attribute
  • node: selectorParser.Attribute

RootClassNode

RootClassNode: object

Type declaration

  • Optional blockName?: undefined | string
  • blockType: root
  • node: selectorParser.Pseudo

SerializedConditionalAttr

SerializedConditionalAttr: Conditional<true> & HasAttrValue<number>

SerializedConditionalAttrGroup

SerializedConditionalAttrGroup: Switch<true> & HasGroup<number>

SerializedConditionalDependentAttr

SerializedConditionalDependentAttr: Conditional<true> & Dependency<number> & HasAttrValue<number>

SerializedConditionalDependentAttrGroup

SerializedConditionalDependentAttrGroup: Switch<true> & Dependency<number> & HasGroup<number>

SerializedDependentAttr

SerializedDependentAttr: Dependency<number> & HasAttrValue<number>

SerializedDependentAttrGroup

SerializedDependentAttrGroup: Dependency<number> & HasGroup<number>

SerializedDynamicAttr

SerializedDynamicAttrGroup

SerializedDynamicAttrs

SerializedDynamicContainer

SerializedDynamicContainer: Conditional<true> & TrueCondition<number> | FalseCondition<number> | TrueCondition<number> & FalseCondition<number>

Styles

TemplateValidatorOptions

TemplateValidatorOptions: object

Type declaration

Token

Validator

Validator: function

Type declaration

Variables

Const ATTR_BEGIN

ATTR_BEGIN: "[" = "["

Const ATTR_END

ATTR_END: "]" = "]"

Const ATTR_PRESENT

ATTR_PRESENT: "::attr-present" = "::attr-present"

Const BLOCK_AT_RULES

BLOCK_AT_RULES: Set<string> = new Set([BLOCK_DEBUG, BLOCK_GLOBAL, BLOCK_REFERENCE])

Const BLOCK_DEBUG

BLOCK_DEBUG: "block-debug" = "block-debug"

Const BLOCK_GLOBAL

BLOCK_GLOBAL: "block-global" = "block-global"

Const BLOCK_NAME

BLOCK_NAME: "block-name" = "block-name"

Const BLOCK_PROP_NAMES

BLOCK_PROP_NAMES: Set<string> = new Set([BLOCK_NAME, EXTENDS, IMPLEMENTS])

Const BLOCK_PROP_NAMES_RE

BLOCK_PROP_NAMES_RE: RegExp = /^(extends|implements|block-name)$/

Const BLOCK_REFERENCE

BLOCK_REFERENCE: "block-reference" = "block-reference"

Const CLASS_BEGIN

CLASS_BEGIN: "." = "."

Const CLASS_NAME_IDENT

CLASS_NAME_IDENT: RegExp = new RegExp(regexpu("^(-?(?:\\\\.|[A-Za-z_\\u{0080}-\\u{10ffff}])(?:\\\\.|[A-Za-z0-9_\\-\\u{0080}-\\u{10ffff}])*)$", "u"))

Const CONSTRAIN_RE

CONSTRAIN_RE: RegExp = /constrain\(("|')([^\2]*)\2\)/

Const CONTIGUOUS_COMBINATORS

CONTIGUOUS_COMBINATORS: Set<string> = new Set(["+", ">"])

Const DOUBLE_QUOTE

DOUBLE_QUOTE: """ = `"`

Const EXTENDS

EXTENDS: "extends" = "extends"

Const HIERARCHICAL_COMBINATORS

HIERARCHICAL_COMBINATORS: Set<string> = new Set([" ", ">"])

Const HIERARCHICAL_COMBINATORS

HIERARCHICAL_COMBINATORS: Set<string> = new Set([" ", ">"])

Const IMPLEMENTS

IMPLEMENTS: "implements" = "implements"

Const LEGAL_COMBINATORS

LEGAL_COMBINATORS: Set<string> = new Set(["+", "~", " ", ">"])

Const NAMESPACE_END

NAMESPACE_END: "|" = "|"

Const NONCONTIGUOUS_COMBINATORS

NONCONTIGUOUS_COMBINATORS: Set<string> = new Set(["~", " "])

Const OBJECT_KEYS

OBJECT_KEYS: Array<ConfigurationObjectKeys> = ["importerData","preprocessors",]

Const PSEUDO_BEGIN

PSEUDO_BEGIN: ":" = ":"

Const RESOLVE_RE

RESOLVE_RE: RegExp = /resolve(-inherited)?\(("|')([^\2]*)\2\)/

Const ROOT_CLASS

ROOT_CLASS: ":scope" = ":scope"

Const SELF_SELECTOR

SELF_SELECTOR: "::self" = "::self"

Const SEPARATORS

SEPARATORS: Set<string> = new Set([CLASS_BEGIN, ATTR_BEGIN, PSEUDO_BEGIN])

Const SIBLING_COMBINATORS

SIBLING_COMBINATORS: Set<string> = new Set(["+", "~"])

Const SIBLING_COMBINATORS

SIBLING_COMBINATORS: Set<string> = new Set(["+", "~"])

Const SIMPLE_KEYS

SIMPLE_KEYS: Array<ConfigurationSimpleKeys> = ["outputMode","importer","rootDir","disablePreprocessChaining","maxConcurrentCompiles",]

Const SINGLE_QUOTE

SINGLE_QUOTE: "'" = `'`

Const STATE_NAMESPACE

STATE_NAMESPACE: "state" = "state"

Const VALUE_START

VALUE_START: "=" = "="

Const WHITESPACE_REGEXP

WHITESPACE_REGEXP: RegExp = /\s/g

Const debug

debug: IDebugger = debugGenerator("css-blocks:analyzer")

Const debug

debug: IDebugger = debugGenerator("css-blocks:BlockFactory")

Const debug

debug: IDebugger = debugGenerator("css-blocks")

Const filesystemImporter

filesystemImporter: FilesystemImporter = new FilesystemImporter()

Default importer. Returns ImportedFile from disk

Const isClassNode

isClassNode: isClassName = selectorParser.isClassName

Let queueInstanceId

queueInstanceId: number = 1

Functions

add

addSourceLocations

  • Reduces multiple SourceLocation objects into a single object capturing the actual location of the source code on disk.

    Parameters

    • Rest ...locations: SourceLocation[]

      An array of SourceLoation objects.

    Returns SourceLocation

    An object containing the line number and column number.

addToSet

  • addToSet(setItems: Array<AttributeValueSetItem>, value: ValueConstant | AttributeValueSet): Array<AttributeValueSetItem>

annotateCssContentWithSourceMap

  • annotateCssContentWithSourceMap(content: string | Result, sourceMap: RawSourceMap | string): string
  • Postcss can only consume source maps if they are inline, this takes a sourcemap from preprocessor output and adds it to the file's contents. This should be called from within a css preprocessor function when an inline sourcemap is needed and is provided for convenience.

    Parameters

    • content: string | Result
    • sourceMap: RawSourceMap | string

    Returns string

assertBlockObject

  • assertBlockObject(block: Block, sel: CompoundSelector, rule: Rule, file: string): NodeAndType
  • Parses a CompoundSelector and returns the discovered Block Object. Validates the given selector is well-formed in the process.

    Parameters

    • block: Block

      The block that contains this selector we're validating.

    • sel: CompoundSelector

      The CompoundSelector in question.

    • rule: Rule

      The full postcss.Rule for nice error reporting.

    • file: string

    Returns NodeAndType

    Returns the block's name, type and node.

assertForeignGlobalAttribute

  • assertForeignGlobalAttribute(root: Root, block: Block, file: string): Promise<void>

assertStyle

assertValidSelector

  • assertValidSelector(block: Block, rule: Rule, selector: ParsedSelector, file: string): void
  • Assert that a provided selector follows all the combinator rules required of block declarations.

    Parameters

    • block: Block

      The block in this selector belongs to.

    • rule: Rule

      The PostCSS Rule.

    • selector: ParsedSelector

      The ParsedSelector to verify.

    • file: string

    Returns void

attrValue

  • attrValue(attr: selectorParser.Attribute): string

Const attributeGroupValidator

  • attributeGroupValidator(analysis: ElementAnalysis<undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object>, _templateAnalysis: Analysis<"Opticss.Template" | "GlimmerTemplates.ResolvedFile" | "Opticss.JSXTemplate">, err: function): void
  • Prevent Attribute from being applied to an element without their associated class.

    Parameters

    • analysis: ElementAnalysis<undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object>
    • _templateAnalysis: Analysis<"Opticss.Template" | "GlimmerTemplates.ResolvedFile" | "Opticss.JSXTemplate">
    • err: function

      Error callback.

        • (str: string, loc?: undefined | null, details?: undefined | string): void
        • Parameters

          • str: string
          • Optional loc: undefined | null
          • Optional details: undefined | string

          Returns void

    Returns void

Const attributeParentValidator

  • attributeParentValidator(analysis: ElementAnalysis<undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object>, _templateAnalysis: Analysis<"Opticss.Template" | "GlimmerTemplates.ResolvedFile" | "Opticss.JSXTemplate">, err: function): void
  • Prevent Attributes from being applied to an element without their associated class.

    Parameters

    • analysis: ElementAnalysis<undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object>
    • _templateAnalysis: Analysis<"Opticss.Template" | "GlimmerTemplates.ResolvedFile" | "Opticss.JSXTemplate">
    • err: function

      Error callback.

        • (str: string, loc?: undefined | null, details?: undefined | string): void
        • Parameters

          • str: string
          • Optional loc: undefined | null
          • Optional details: undefined | string

          Returns void

    Returns void

blockTypeName

  • blockTypeName(t: BlockType, options?: undefined | object): string
  • Internal method used to generate human readable error messages when parsing.

    Parameters

    • t: BlockType

      The block type we're generating a human readable name for.

    • Optional options: undefined | object

      Options for output, currently just to specify plurality.

    Returns string

    A human readable descriptor for the given BlockType.

checkExisting

Const classPairsValidator

  • classPairsValidator(analysis: ElementAnalysis<undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object>, _templateAnalysis: Analysis<"Opticss.Template" | "GlimmerTemplates.ResolvedFile" | "Opticss.JSXTemplate">, err: function): void
  • Prevent two BlockClasses from the same Block hierarchy from being applied together.

    Parameters

    • analysis: ElementAnalysis<undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object>
    • _templateAnalysis: Analysis<"Opticss.Template" | "GlimmerTemplates.ResolvedFile" | "Opticss.JSXTemplate">
    • err: function

      Error callback.

        • (str: string, loc?: undefined | null, details?: undefined | string): void
        • Parameters

          • str: string
          • Optional loc: undefined | null
          • Optional details: undefined | string

          Returns void

    Returns void

constructBlock

  • constructBlock(root: Root, block: Block, file: string): Promise<Block>

detectConflicts

detectPropertyConflicts

  • detectPropertyConflicts(props1: Set<string>, props2: Set<string>): Set<Conflict>
  • Given two sets representing property concerns, return a set containing the properties that conflict with each other

    Parameters

    • props1: Set<string>

      Style one.

    • props2: Set<string>

      Style two.

    Returns Set<Conflict>

    A Set that contains the full set of property conflicts.

disallowImportant

  • disallowImportant(root: Root, file: string): Promise<Root>

discoverName

  • discoverName(root: Root, defaultName: string, file: string): Promise<string>

dynamicClassAndDependentAttrs

ensureToken

ensureUniqueAttributeGroup

evaluate

expandProp

  • expandProp(prop: string, value: string): propParser.Declarations
  • Safely expand a property value pair into its constituent longhands, even if it is not a valid declaration.

    Parameters

    • prop: string
    • value: string

      A CSS property value.

    Returns propParser.Declarations

extendBlock

  • extendBlock(rule: Root, block: Block, sourceFile: string): Promise<void>
  • For each extends property found in the passed ruleset, set the block's base to the foreign block. If block is not found, throw.

    Parameters

    • rule: Root

      Ruleset to crawl.

    • block: Block

      Block object being processed.

    • sourceFile: string

      Source file name, used for error output.

    Returns Promise<void>

getConstraints

  • getConstraints(value: string): string[]

getParsedSelectors

  • getParsedSelectors(block: Block, rule: Rule, file: string): ParsedSelector[]
  • Pull getParsedSelectors try-catch out to prevent de-opt of main walkRules function.

    Parameters

    • block: Block

      Block The block to fetch ParsedSelectors from.

    • rule: Rule

      postcss.Rule The postcss rule to parse.

    • file: string

      string The filepath of the file we are parsing for error reporting.

    Returns ParsedSelector[]

    The ParsedSelector array.

getResolutions

  • getResolutions(value: string): string[]

globalAttributes

  • globalAttributes(root: Root, block: Block, file: string): Promise<Block>

hasDependency

  • hasDependency(o: object): boolean

Const hasName

  • hasName(token?: Partial<Token>): boolean

implementBlock

  • implementBlock(rule: Root, block: Block, sourceFile: string): Promise<void>
  • For each implements property found in the passed ruleset, track the foreign block. If block is not found, throw.

    Parameters

    • rule: Root

      Ruleset to crawl

    • block: Block

      Block object being processed

    • sourceFile: string

      Source file name, used for error output.

    Returns Promise<void>

indexesUsed

  • indexesUsed(indexes: Set<number>, expression: BooleanExpression<number> | number): void

isAttrGroup

  • isAttrGroup(o: object): boolean

isAttrValue

  • isAttrValue(o: object): boolean

isAttribute

  • isAttribute(o: object): boolean

Const isAttribute

  • isAttribute(token?: Partial<Token>): boolean

isAttributeNode

  • isAttributeNode(node: selectorParser.Node): boolean

Const isBlock

  • isBlock(token?: Partial<Token>): boolean

isBlock

  • isBlock(o?: undefined | object): boolean

isBlockClass

  • isBlockClass(o: object): boolean

isBooleanAttr

  • isBooleanAttr(o: object): boolean

Const isClass

  • isClass(token?: Partial<Token>): boolean

isClassLevelObject

isConditional

  • isConditional(o: object): boolean

isConstraint

  • isConstraint(value: string): boolean

isExternalBlock

isFalseCondition

  • isFalseCondition(o: object): boolean

Const isIdent

  • isIdent(ident?: undefined | string): boolean

Const isQuoted

  • isQuoted(token?: Partial<AttrToken>): boolean

isResolution

  • isResolution(value: string): boolean

isRootLevelObject

isRootNode

isStaticClass

  • isStaticClass(o: object): boolean

isStyle

isSwitch

  • isSwitch(o: object): boolean

isTrueCondition

  • isTrueCondition(o: object): boolean

Const isValidNamespace

  • isValidNamespace(token?: Partial<AttrToken>): boolean

mapChoiceClasses

mapClasses

parseBlockDebug

  • parseBlockDebug(atRule: AtRule, sourceFile: string, scope: Block): object

printRulesetConflict

  • printRulesetConflict(prop: string, rule: Ruleset): string

processDebugStatements

processExpression

processExpressionLiteral

  • processExpressionLiteral(expression: number, inputs: Array<SimpleTagname | SimpleAttribute>, classMap: Map<string, Style>): Style

Const propertyConflictValidator

  • propertyConflictValidator(elAnalysis: ElementAnalysis<undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object>, _templateAnalysis: Analysis<"Opticss.Template" | "GlimmerTemplates.ResolvedFile" | "Opticss.JSXTemplate">, err: function): void
  • Prevent conflicting styles from being applied to the same element without an explicit resolution.

    Parameters

    • elAnalysis: ElementAnalysis<undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object>
    • _templateAnalysis: Analysis<"Opticss.Template" | "GlimmerTemplates.ResolvedFile" | "Opticss.JSXTemplate">
    • err: function

      Error callback.

        • (str: string, loc?: undefined | null, details?: undefined | string): void
        • Parameters

          • str: string
          • Optional loc: undefined | null
          • Optional details: undefined | string

          Returns void

    Returns void

recursivelyPruneConflicts

renumber

resolveConfiguration

resolveReferences

returnDynamic

  • returnDynamic(dynamic: boolean | undefined): boolean

returnStatic

  • returnStatic(dynamic: boolean | undefined): boolean

Const rootClassValidator

  • rootClassValidator(analysis: ElementAnalysis<undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object>, templateAnalysis: Analysis<"Opticss.Template" | "GlimmerTemplates.ResolvedFile" | "Opticss.JSXTemplate">, err: function): void
  • Prevent BlockClasses from being applied to the same element is their Root.

    Parameters

    • analysis: ElementAnalysis<undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object, undefined | null | string | number | true | false | symbol | void | object>
    • templateAnalysis: Analysis<"Opticss.Template" | "GlimmerTemplates.ResolvedFile" | "Opticss.JSXTemplate">
    • err: function

      Error callback.

        • (str: string, loc?: undefined | null, details?: undefined | string): void
        • Parameters

          • str: string
          • Optional loc: undefined | null
          • Optional details: undefined | string

          Returns void

    Returns void

selectorSourceLocation

  • selectorSourceLocation(sourceFile: string, rule: Rule, selector: selectorParser.Node): SourceLocation | undefined
  • Logging utility function to fetch the filename, line number and column number of a given selector.

    Parameters

    • sourceFile: string

      The source file name that contains this rule.

    • rule: Rule

      The PostCSS Rule object containing this selector.

    • selector: selectorParser.Node

      The PostCSS selector node in question.

    Returns SourceLocation | undefined

    An object representing the filename, line number and column number.

serializeDynamicAttrs

serializeDynamicContainer

shouldBeParsedAsBlockSelector

  • shouldBeParsedAsBlockSelector(rule: Rule): boolean
  • Should this selector be parsed as a block selector? Right now, only ignore selectors in @keyframes blocks.

    Parameters

    • rule: Rule

      The postcss rule to evaluate.

    Returns boolean

    If this is a block selector or not.

sourceLocation

  • sourceLocation(sourceFile: string, node: postcss.Node): SourceLocation | undefined
  • Logging utility function to fetch the filename, line number and column number of a given postcss.Node.

    Parameters

    • sourceFile: string

      The source file name that contains this rule.

    • node: postcss.Node

      The PostCSS Node object in question.

    Returns SourceLocation | undefined

    An object representing the filename, line number and column number.

sourceMapFromProcessedFile

  • sourceMapFromProcessedFile(result: ProcessedFile): RawSourceMap | string | undefined

stringify

  • stringify(tokens: Token[]): string

syntaxName

  • syntaxName(syntax: Syntax): string

toAttrToken

  • toAttrToken(attr: selectorParser.Attribute): AttrToken

unionInto

  • unionInto<T>(target: Set<T>, ...sets: Iterable<T>[]): void

updateConflict

Object literals

Const DEFAULTS

DEFAULTS: object

disablePreprocessChaining

disablePreprocessChaining: false = false

importer

importer: FilesystemImporter = filesystemImporter

importerData

importerData: object

Type declaration

maxConcurrentCompiles

maxConcurrentCompiles: number = 4

outputMode

outputMode: BEM = OutputMode.BEM

preprocessors

preprocessors: object

Type declaration

rootDir

rootDir: string = process.cwd()

Const DEFAULT_VALIDATORS

DEFAULT_VALIDATORS: object

no-attribute-orphans

no-attribute-orphans: true = true

no-class-pairs

no-class-pairs: true = true

no-duplicate-attribute-groups

no-duplicate-attribute-groups: true = true

no-required-resolution

no-required-resolution: true = true

no-root-classes

no-root-classes: true = true

Const ERRORS

ERRORS: object

mismatchedQuote

mismatchedQuote: string = "No closing quote found in Block path"

namespace

namespace: string = "State attribute selectors are required to use a valid namespace."

noname

noname: string = "Block path segments must include a valid name"

unclosedAttribute

unclosedAttribute: string = "Unclosed attribute selector"

whitespace

whitespace: string = "Whitespace is only allowed in quoted attribute values"

expectsSepInsteadRec

  • expectsSepInsteadRec(c: string): string

illegalCharInAttribute

  • illegalCharInAttribute(c: string): string

illegalCharNotInAttribute

  • illegalCharNotInAttribute(c: string): string

invalidIdent

  • invalidIdent(i: string): string

multipleOfType

  • multipleOfType(t: string): string

Const VALIDATORS

VALIDATORS: object

no-attribute-orphans

no-attribute-orphans: function = attributeParentValidator

Type declaration

no-class-pairs

no-class-pairs: function = classPairsValidator

Type declaration

no-duplicate-attribute-groups

no-duplicate-attribute-groups: function = attributeGroupValidator

Type declaration

no-required-resolution

no-required-resolution: function = propertyConflictValidator

Type declaration

no-root-classes

no-root-classes: function = rootClassValidator

Type declaration

Generated using TypeDoc