import { ParsedSelector , postcss } from "opticss" ; import { isRule } from "opticss/dist/src/util/cssIntrospection" ; import { COMPOSES } from "../../BlockSyntax" ; import { Block } from "../../BlockTree" ; import { Configuration } from "../../configuration" ; import * as errors from "../../errors" ; import { sourceRange } from "../../SourceLocation" ; import { getStyleTargets } from "../block-intermediates" ; import { stripQuotes } from "../utils" ; param block param sourceFile param rule export function composeBlock ( configuration , root , block , sourceFile ) { root . walkDecls ( COMPOSES , ( decl ) => { if ( ! isRule ( decl . parent ) ) { block . addError ( new errors . InvalidBlockSyntax ( `The "composes" property may only be used in a rule set.` , sourceRange ( configuration , root , sourceFile , decl ) ) ) ; } let rule = decl . parent ; let refNames = decl . value . split ( /,\s*/ ) . map ( stripQuotes ) ; for ( let refName of refNames ) { let refStyle = block . lookup ( refName ) ; if ( ! refStyle ) { block . addError ( new errors . InvalidBlockSyntax ( `No style "${ refName }" found.` , sourceRange ( configuration , root , sourceFile , decl ) ) ) ; } else { if ( refStyle . block === block ) { block . addError ( new errors . InvalidBlockSyntax ( `Styles from the same Block may not be composed together.` , sourceRange ( configuration , root , sourceFile , decl ) ) ) ; } let parsedSel = [ ] ; try { parsedSel = block . getParsedSelectors ( rule as postcss . Rule ) ; } catch ( e ) { block . addError ( new errors . InvalidBlockSyntax ( e . message , sourceRange ( configuration , block . stylesheet , sourceFile , rule ) ) ) ; } for ( let sel of parsedSel ) { if ( sel . selector . next ) { block . addError ( new errors . InvalidBlockSyntax ( `Style composition is not allowed in rule sets with a context selector.` , sourceRange ( configuration , root , sourceFile , decl ) ) ) ; } let foundStyles = getStyleTargets ( block , sel . selector ) ; for ( let blockClass of foundStyles . blockClasses ) { blockClass . addComposedStyle ( refStyle , foundStyles . blockAttrs , refName ) ; } } } } decl . remove ( ) ; } ) ; }