diff --git a/package-lock.json b/package-lock.json index 911bb3b..fd52052 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "postcss-selector-parser", - "version": "7.1.4", + "version": "7.1.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "postcss-selector-parser", - "version": "7.1.4", + "version": "7.1.5", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", diff --git a/src/__tests__/classes.mjs b/src/__tests__/classes.mjs index 7e7786c..539d265 100644 --- a/src/__tests__/classes.mjs +++ b/src/__tests__/classes.mjs @@ -274,3 +274,22 @@ test("class selector with escaping (36)", ".not-pseudo\\:\\:focus", (t, tree) => t.deepEqual(tree.nodes[0].nodes[0].type, "class"); t.deepEqual(tree.nodes[0].nodes[0].raws.value, "not-pseudo\\:\\:focus"); }); + +test("class prefix selector", ".foo-*", (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].type, "class"); + t.deepEqual(tree.nodes[0].nodes[0].value, "foo-*"); +}); + +test("class prefix selector with tag", "div.foo-*", (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].type, "tag"); + t.deepEqual(tree.nodes[0].nodes[0].value, "div"); + t.deepEqual(tree.nodes[0].nodes[1].type, "class"); + t.deepEqual(tree.nodes[0].nodes[1].value, "foo-*"); +}); + +test("multiple class prefix selectors", ".foo-*.bar-*", (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].type, "class"); + t.deepEqual(tree.nodes[0].nodes[0].value, "foo-*"); + t.deepEqual(tree.nodes[0].nodes[1].type, "class"); + t.deepEqual(tree.nodes[0].nodes[1].value, "bar-*"); +}); diff --git a/src/parser.js b/src/parser.js index bcec5ac..3a37cf6 100644 --- a/src/parser.js +++ b/src/parser.js @@ -938,6 +938,17 @@ export default class Parser { } nextToken = this.nextToken; } + // Support class prefix selectors like .foo-* + const wordStartToken = this.currToken; + if ( + nextToken && + nextToken[TOKEN.TYPE] === tokens.asterisk && + word.endsWith("-") && + word.indexOf(".") !== -1 + ) { + this.position++; + word += "*"; + } const hasClass = indexesOf(word, ".").filter((i) => { // Allow escaped dot within class name const escapedDot = word[i - 1] === "\\"; @@ -959,7 +970,7 @@ export default class Parser { return firstCallback.call(this, value, indices.length); } let node; - const current = this.currToken; + const current = wordStartToken; const sourceIndex = current[TOKEN.START_POS] + indices[i]; const source = getSource(current[1], current[2] + ind, current[3], current[2] + (index - 1)); if (~hasClass.indexOf(ind)) {