import { AtomicStyleRule , AtomicStyleDeclaration , parseDeclaration , sortRulesBySpecificFirst , parseStylesheet } from './cssUtils' ; export function matches ( e , selector ) { return ( e . matches || e . msMatchesSelector ) . call ( e , selector ) ; } export function doesRuleApply ( element , rule ) { if ( rule . selector instanceof HTMLElement ) { return element === rule . selector ; } return matches ( element , < string > rule . selector ) ; } export function parseInlineStyle ( element ) { return parseDeclaration ( element . hasAttribute ( 'data-style' ) ? element . getAttribute ( 'data-style' ) : element . getAttribute ( 'style' ) ) . map ( ( { name , value } ) => ( { name , value , selector : element } ) ) ; } const loadedExternalStyles = new WeakMap < HTMLElement , string > ( ) ; function getStylesheetText ( e ) { switch ( e . tagName ) { case 'STYLE' : return e . innerHTML ; case 'LINK' : return loadedExternalStyles . get ( e ) ; } } export function getAllRules ( rootElement , filter = ( ) => true ) { const elementsWithStyleAttributes = rootElement . querySelectorAll ( '[style],[data-style]' ) ; const inlineStyleRules = [ ] . filter . call ( elementsWithStyleAttributes , filter ) . reduce ( ( agg , element ) => [ ... agg , ... parseInlineStyle ( element ) ] , [ ] ) . reverse ( ) ; const styleTags = [ ] . map . call ( document . styleSheets , s => s . ownerNode ) . filter ( ( n ) => n && ( rootElement . compareDocumentPosition ( rootElement ) | Node . DOCUMENT_POSITION_CONTAINS ) && filter ( n ) ) . reverse ( ) . reduce ( ( agg , e ) => [ ... agg , ... parseStylesheet ( getStylesheetText ( e ) ) ] , [ ] ) ; return [ ... inlineStyleRules , ... sortRulesBySpecificFirst ( styleTags ) ] ; } export function waitForStylesToBeLoaded ( rootElement ) { const links = rootElement . querySelectorAll ( 'link[rel="stylesheet"]' ) ; const linksWithoutStyles = [ ] . filter . call ( links , ( link ) => ! loadedExternalStyles . has ( link ) ) ; return Promise . all ( linksWithoutStyles . map ( async ( link ) => { const response = await fetch ( link . href , { headers : { 'Content-Type' : link . type } } ) ; loadedExternalStyles . set ( link , await response . text ( ) ) ; } ) ) ; } export function getRawComputedStyle ( rules , element ) { return rules . reduce ( ( style , rule ) => style [ rule . name ] || ! doesRuleApply ( element , rule ) ? style : { ... style , [ rule . name ] : rule . value } , { } ) ; } export function getMatchingElements ( rootElement , rule ) { return typeof ( rule . selector ) === 'string' ? [ ] . slice . call ( rootElement . querySelectorAll ( rule . selector ) ) : [ < HTMLElement > rule . selector ] ; }