import { ParsedSelector , postcss , postcssSelectorParser as selectorParser } from "opticss" ; import { ROOT_CLASS } from "../../BlockSyntax" ; import { Block } from "../../BlockTree" ; import { Configuration } from "../../configuration" ; import * as errors from "../../errors" ; import { selectorSourceRange as range , sourceRange } from "../../SourceLocation" ; import { isAttributeNode , toAttrToken } from "../block-intermediates" ; param block param rule param obj export function assertForeignGlobalAttribute ( configuration , root , block , file ) { root . walkRules ( ( rule ) => { let parsedSelectors ; try { parsedSelectors = block . getParsedSelectors ( rule ) ; } catch ( e ) { block . addError ( new errors . InvalidBlockSyntax ( e . message , sourceRange ( configuration , block . stylesheet , file , rule ) ) ) ; parsedSelectors = [ ] ; } parsedSelectors . forEach ( ( iSel ) => { iSel . eachCompoundSelector ( ( sel ) => { let blockName = sel . nodes . find ( n => isAttributeNode ( n ) && n . namespace ) as selectorParser . Attribute | undefined ; if ( ! blockName || ! blockName . namespace ) { return ; } if ( blockName . namespace === true ) { return ; } for ( let node of sel . nodes ) { if ( node . type === selectorParser . PSEUDO && node . value === ROOT_CLASS ) { continue ; } if ( ! isAttributeNode ( node ) ) { block . addError ( new errors . InvalidBlockSyntax ( `Illegal global state selector: ${ rule . selector }` , range ( configuration , block . stylesheet , file , rule , node ) ) ) ; } else { let otherBlock = block . getReferencedBlock ( blockName . namespace ) ; if ( ! otherBlock ) { block . addError ( new errors . InvalidBlockSyntax ( `No Block named "${ blockName . value }" found in scope: ${ rule . selector }` , range ( configuration , block . stylesheet , file , rule , node ) ) ) ; } else { let otherAttr = otherBlock . rootClass . getAttributeValue ( toAttrToken ( node ) ) ; if ( ! otherAttr ) { block . addError ( new errors . InvalidBlockSyntax ( `No state ${ node . toString ( ) } found in : ${ rule . selector }` , range ( configuration , block . stylesheet , file , rule , node ) ) ) ; } else if ( ! otherAttr . isGlobal ) { block . addError ( new errors . InvalidBlockSyntax ( `${ node . toString ( ) } is not global: ${ rule . selector }` , range ( configuration , block . stylesheet , file , rule , node ) ) ) ; } } } } } ) ; } ) ; } ) ; }