3 const _ = require("lodash");
4 const isStandardSyntaxRule = require("../../utils/isStandardSyntaxRule");
5 const isStandardSyntaxSelector = require("../../utils/isStandardSyntaxSelector");
6 const keywordSets = require("../../reference/keywordSets");
7 const optionsMatches = require("../../utils/optionsMatches");
8 const parseSelector = require("../../utils/parseSelector");
9 const postcss = require("postcss");
10 const report = require("../../utils/report");
11 const ruleMessages = require("../../utils/ruleMessages");
12 const validateOptions = require("../../utils/validateOptions");
14 const ruleName = "selector-pseudo-element-no-unknown";
16 const messages = ruleMessages(ruleName, {
18 `Unexpected unknown pseudo-element selector "${selector}"`
21 const rule = function(actual, options) {
22 return (root, result) => {
23 const validOptions = validateOptions(
30 ignorePseudoElements: [_.isString]
39 root.walkRules(rule => {
40 if (!isStandardSyntaxRule(rule)) {
43 const selector = rule.selector;
45 // Return early before parse if no pseudos for performance
47 if (selector.indexOf(":") === -1) {
51 parseSelector(selector, result, rule, selectorTree => {
52 selectorTree.walkPseudos(pseudoNode => {
53 const value = pseudoNode.value;
55 if (!isStandardSyntaxSelector(value)) {
59 // Ignore pseudo-classes
60 if (value.slice(0, 2) !== "::") {
67 "ignorePseudoElements",
68 pseudoNode.value.slice(2)
74 const name = value.slice(2);
77 postcss.vendor.prefix(name) ||
78 keywordSets.pseudoElements.has(name.toLowerCase())
84 message: messages.rejected(value),
86 index: pseudoNode.sourceIndex,
96 rule.ruleName = ruleName;
97 rule.messages = messages;
98 module.exports = rule;