diff --git a/lib/parse.js b/lib/parse.js index c0c5dfa..9841107 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -169,7 +169,7 @@ var parser = new Parser({ "/\\*([\\s\\S]*?)\\*/": commentMatch, "\\.((?:\\\\.|[A-Za-z_\\-])(?:\\\\.|[A-Za-z_\\-0-9])*)": typeMatch("class"), "#((?:\\\\.|[A-Za-z_\\-])(?:\\\\.|[A-Za-z_\\-0-9])*)": typeMatch("id"), - ":(not|has|local|global)\\((\\s*)": nestedPseudoClassStartMatch, + ":(not|matches|has|local|global)\\((\\s*)": nestedPseudoClassStartMatch, ":((?:\\\\.|[A-Za-z_\\-0-9])+)\\(": pseudoClassStartMatch, ":((?:\\\\.|[A-Za-z_\\-0-9])+)": typeMatch("pseudo-class"), "::((?:\\\\.|[A-Za-z_\\-0-9])+)": typeMatch("pseudo-element"), @@ -179,7 +179,7 @@ var parser = new Parser({ "((?:\\\\.|[A-Za-z_\\-0-9])*\\|)?((?:\\\\.|[A-Za-z_\\-])(?:\\\\.|[A-Za-z_\\-0-9])*)": elementMatch, "\\[([^\\]]+)\\]": attributeMatch, "(\\s*)\\)": nestedEnd, - "(\\s*)([>+~])(\\s*)": operatorMatch, + "(\\s*)((?:\\|\\|)|(?:>>)|[>+~])(\\s*)": operatorMatch, "(\\s*),(\\s*)": nextSelectorMatch, "\\s+$": irrelevantSpacingEndMatch, "^\\s+": irrelevantSpacingStartMatch, diff --git a/lib/stringify.js b/lib/stringify.js index de02670..b97710a 100644 --- a/lib/stringify.js +++ b/lib/stringify.js @@ -6,7 +6,7 @@ function escape(str) { if(str === "*") { return "*"; } - return str.replace(/(^[^A-Za-z_\\-]|[^A-Za-z_0-9\\-])/g, "\\$1"); + return str.replace(/(^[^A-Za-z_\\-]|^\-\-|[^A-Za-z_0-9\\-])/g, "\\$1"); } function stringifyWithoutBeforeAfter(tree) { diff --git a/test/test-cases.js b/test/test-cases.js index c3055bb..61a4fe4 100644 --- a/test/test-cases.js +++ b/test/test-cases.js @@ -55,10 +55,13 @@ module.exports = { ]) ], - "class name starting with number": [ - ".\\5\\#-\\.5", + "class name starting with number or dash": [ + ".\\5\\#-\\.5 .\\--name.-name", singleSelector([ - { type: "class", name: "5#-.5" } + { type: "class", name: "5#-.5" }, + { type: "spacing", value: " " }, + { type: "class", name: "--name" }, + { type: "class", name: "-name" } ]) ], @@ -251,7 +254,7 @@ module.exports = { ], "pseudo class with difficult content": [ - ":--anything-new(/* here is difficult ')][ .content */\nurl('Hello)World'), \"Hello)\\\".World\")", + ":\\--anything-new(/* here is difficult ')][ .content */\nurl('Hello)World'), \"Hello)\\\".World\")", singleSelector([ { type: "pseudo-class", name: "--anything-new", content: "/* here is difficult ')][ .content */\nurl('Hello)World'), \"Hello)\\\".World\"" } ]) @@ -320,6 +323,28 @@ module.exports = { ]) ], + "available nested pseudo classes": [ + ":not(:active):matches(:focus)", + singleSelector([ + { type: "nested-pseudo-class", name: "not", nodes: [ + { + type: "selector", + nodes: [ + { type: "pseudo-class", name: "active" } + ] + } + ] }, + { type: "nested-pseudo-class", name: "matches", nodes: [ + { + type: "selector", + nodes: [ + { type: "pseudo-class", name: "focus" } + ] + } + ] } + ]) + ], + "nested pseudo class with nested selectors": [ ":has(h1:not(:has(:visited)))", singleSelector([