import { isObject } from "@opticss/util" ; import * as postcss from "postcss" ; import * as selectorParser from "postcss-selector-parser" ; import { isClassName , isIdentifier } from "postcss-selector-parser" ; import { inspect } from "util" ; import { ParsedCssFile } from "../CssFile" ; import { ParsedSelector } from "../parseSelector" ; import { SelectorCache } from "../query" ; export type RuleScope = Array < postcss . AtRule > ; export type RuleIteratorWithScope = ( rule : postcss . Rule , scope : RuleScope ) => false | undefined | void ; export function walkRules ( container , eachRule ) { _walkRulesWithScope ( container , eachRule , [ ] ) ; } function _walkRulesWithScope ( container , eachRule , scope ) { container . each ( node => { if ( isRule ( node ) ) { eachRule ( node , scope ) ; } else if ( isAtRule ( node ) ) { if ( node . name . includes ( "keyframes" ) || node . name . includes ( "font-face" ) ) { } else { _walkRulesWithScope ( node , eachRule , scope . concat ( node ) ) ; } } else if ( isContainer ( node ) ) { console . log ( "warning: container that's not an AtRule encountered: " + inspect ( node ) ) ; _walkRulesWithScope ( node , eachRule , scope ) ; } } ) ; } export interface IdentTypes { id ? : boolean ; class ? : boolean ; } export type IdentNode = selectorParser . Identifier | selectorParser . ClassName ; param sel param idents param cb export function eachSelectorIdent ( sel , idents , cb ) { sel . eachSelectorNode ( ( node ) => { if ( idents . id && isIdentifier ( node ) ) { cb ( node ) ; } else if ( idents . class && isClassName ( node ) ) { cb ( node ) ; } } ) ; } param root param cache param idents param cb export function eachIdent ( root , cache , idents , cb ) { eachSelector ( root , cache , ( rule , sel ) => eachSelectorIdent ( sel , idents , ( node ) => cb ( node , rule , sel ) ) ) ; } param files param cache param idents param cb export function eachFileIdent ( files , cache , idents , cb ) { eachFileSelector ( files , cache , ( rule , sel ) => eachSelectorIdent ( sel , idents , ( node ) => cb ( node , rule , sel ) ) ) ; } param files param cache param cb export function eachFileSelector ( files , cache , cb ) { files . forEach ( file => eachSelector ( file . content . root ! , cache , cb ) ) ; } param root param cache param cb export function eachSelector ( root , cache , cb ) { walkRules ( root , ( rule ) => cache . getParsedSelectors ( rule ) . forEach ( ( sel ) => cb ( rule , sel ) ) ) ; } const NODE_TYPES = { "root" : true , "atrule" : true , "rule" : true , "decl" : true , "comment" : true , } ; type MaybeNode = { type ? : postcss . Node [ "type" ] ; } ; export function isNode ( node ) { let nodeType = isObject ( node ) && ( < MaybeNode > node ) . type || undefined ; return nodeType && NODE_TYPES [ nodeType ] || false ; } param node returns export function isAtRule ( node ) { return ( isObject ( node ) && ( < MaybeNode > node ) . type === "atrule" ) ; } param node returns export function isRule ( node ) { return ( isObject ( node ) && ( < MaybeNode > node ) . type === "rule" ) ; } /**
 * Test if a postcss node is a declaration.
 */ export function isDeclaration ( node ) { return ( isObject ( node ) && ( < MaybeNode > node ) . type === "decl" ) ; } param node returns export function isContainer ( node ) { return isNode ( node ) && ( < postcss . Container > node ) . each !== undefined ; }