{"size": 2188, "ext": "js", "max_stars_repo_path": "src/SelectorFilter.js", "max_stars_repo_name": "blmage/rollup-purifycss", "max_stars_repo_stars_event_min_datetime": "2015-06-06T18:09:31.000Z", "max_stars_repo_stars_event_max_datetime": "2022-03-30T16:29:42.000Z", "max_issues_repo_path": "src/SelectorFilter.js", "max_issues_repo_name": "blmage/rollup-purifycss", "max_issues_repo_issues_event_min_datetime": "2019-06-17T13:55:22.000Z", "max_issues_repo_issues_event_max_datetime": "2021-07-30T05:42:46.000Z", "max_forks_repo_path": "src/SelectorFilter.js", "max_forks_repo_name": "blmage/rollup-purifycss", "max_forks_repo_forks_event_min_datetime": "2015-06-12T20:01:51.000Z", "max_forks_repo_forks_event_max_datetime": "2022-03-18T23:57:24.000Z"}
{"max_stars_count": 10814, "max_issues_count": 236, "max_forks_count": 557, "avg_line_length": 29.9726027397, "max_line_length": 77, "alphanum_fraction": 0.5877513711}
import { getAllWordsInSelector } from "./utils/ExtractWordsUtil"

const isWildcardWhitelistSelector = selector => {
    return selector[0] === "*" && selector[selector.length - 1] === "*"
}

const hasWhitelistMatch = (selector, whitelist) => {
    for (let el of whitelist) {
        if (selector.includes(el)) return true
    }
    return false
}

class SelectorFilter {
    constructor(contentWords, whitelist) {
        this.contentWords = contentWords
        this.rejectedSelectors = []
        this.wildcardWhitelist = []
        this.parseWhitelist(whitelist)
    }

    initialize(CssSyntaxTree) {
        CssSyntaxTree.on("readRule", this.parseRule.bind(this))
    }

    parseWhitelist(whitelist) {
        whitelist.forEach(whitelistSelector => {
            whitelistSelector = whitelistSelector.toLowerCase()

            if (isWildcardWhitelistSelector(whitelistSelector)) {
                // If '*button*' then push 'button' onto list.
                this.wildcardWhitelist.push(
                    whitelistSelector.substr(1, whitelistSelector.length - 2)
                )
            } else {
                getAllWordsInSelector(whitelistSelector).forEach(word => {
                    this.contentWords[word] = true
                })
            }
        })
    }

    parseRule(selectors, rule) {
        rule.selectors = this.filterSelectors(selectors)
    }

    filterSelectors(selectors) {
        let contentWords = this.contentWords,
            rejectedSelectors = this.rejectedSelectors,
            wildcardWhitelist = this.wildcardWhitelist,
            usedSelectors = []

        selectors.forEach(selector => {
            if (hasWhitelistMatch(selector, wildcardWhitelist)) {
                usedSelectors.push(selector)
                return
            }
            let words = getAllWordsInSelector(selector),
                usedWords = words.filter(word => contentWords[word])

            if (usedWords.length === words.length) {
                usedSelectors.push(selector)
            } else {
                rejectedSelectors.push(selector)
            }
        })

        return usedSelectors
    }
}

export default SelectorFilter
