import * as Bluebird from "bluebird" ; import * as css from "css" ; import * as html from "htmlparser2" ; import * as request from "request-promise" ; import CssClassDefinition from "../../common/css-class-definition" ; import CssClassExtractor from "../common/css-class-extractor" ; import IParseEngine from "../common/parse-engine" ; import ISimpleTextDocument from "../common/simple-text-document" ; class HtmlParseEngine implements IParseEngine { public languageId = "html" ; public extension = "html" ; public async parse ( textDocument ) { const definitions = [ ] ; const urls = [ ] ; let tag ; let isRelStylesheet = false ; let linkHref ; const parser = new html . Parser ( { onattribute : ( name , value ) => { if ( name === "rel" && value === "stylesheet" ) { isRelStylesheet = true ; } if ( tag === "link" && name === "href" && value . indexOf ( "http" ) === 0 ) { linkHref = value ; } } , onclosetag : ( ) => { if ( tag === "link" && isRelStylesheet && linkHref ) { urls . push ( linkHref ) ; } isRelStylesheet = false ; linkHref = null ; } , onopentagname : ( name ) => { tag = name ; } , ontext : ( text ) => { if ( tag === "style" ) { definitions . push ( ... CssClassExtractor . extract ( css . parse ( text ) ) ) ; } } , } ) ; parser . write ( textDocument . getText ( ) ) ; parser . end ( ) ; await Bluebird . map ( urls , async ( url ) => { const content = await request . get ( url ) ; definitions . push ( ... CssClassExtractor . extract ( css . parse ( content ) ) ) ; } , { concurrency : 10 } ) ; return definitions ; } } export default HtmlParseEngine ;