From 3a8fb52ed2c8c63cbbd2007411b23012d341a52f Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Thu, 21 Feb 2019 15:19:36 +0300 Subject: [PATCH] fix: escaping in `id` selector --- src/__tests__/id.js | 214 ++++++++++++++++++++++++++++++++++++++++++++ src/parser.js | 2 +- 2 files changed, 215 insertions(+), 1 deletion(-) diff --git a/src/__tests__/id.js b/src/__tests__/id.js index f6c7510..e101eab 100644 --- a/src/__tests__/id.js +++ b/src/__tests__/id.js @@ -57,3 +57,217 @@ test('Less interpolation within an id', '#foo@{bar}', (t, tree) => { t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); t.deepEqual(tree.nodes[0].nodes[0].value, 'foo@{bar}'); }); + +test('id selector with escaping', '#\\#test', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '#test'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\#test'); +}); + +test('id selector with escaping (2)', '#-a-b-c-', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '-a-b-c-'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); +}); + +test('id selector with escaping (3)', '#u-m\\00002b', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, 'u-m+'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'u-m\\00002b'); +}); + +test('id selector with escaping (4)', '#♥', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '♥'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); +}); + +test('id selector with escaping (5)', '#©', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '©'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); +}); + +test('id selector with escaping (6)', '#“‘’”', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '“‘’”'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); +}); + +test('id selector with escaping (7)', '#☺☃', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '☺☃'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); +}); + +test('id selector with escaping (8)', '#⌘⌥', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '⌘⌥'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); +}); + +test('id selector with escaping (9)', '#𝄞♪♩♫♬', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '𝄞♪♩♫♬'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); +}); + +test('id selector with escaping (10)', '#💩', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '💩'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); +}); + +test('id selector with escaping (11)', '#\\?', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '?'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\?'); +}); + +test('id selector with escaping (12)', '#\\@', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '@'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\@'); +}); + +test('id selector with escaping (13)', '#\\.', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '.'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\.'); +}); + +test('id selector with escaping (14)', '#\\3A \\)', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, ':)'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\3A \\)'); +}); + +test('id selector with escaping (15)', '#\\3A \\`\\(', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, ':`('); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\3A \\`\\('); +}); + +test('id selector with escaping (16)', '#\\31 23', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '123'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\31 23'); +}); + +test('id selector with escaping (17)', '#\\31 a2b3c', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '1a2b3c'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\31 a2b3c'); +}); + +test('id selector with escaping (18)', '#\\', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '

'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\'); +}); + +test('id selector with escaping (19)', '#\\<\\>\\<\\<\\<\\>\\>\\<\\>', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '<><<<>><>'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\<\\>\\<\\<\\<\\>\\>\\<\\>'); +}); + +test('id selector with escaping (20)', '#\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\[\\>\\+\\+\\+\\+\\+\\+\\+\\>\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\>\\+\\+\\+\\>\\+\\<\\<\\<\\<\\-\\]\\>\\+\\+\\.\\>\\+\\.\\+\\+\\+\\+\\+\\+\\+\\.\\.\\+\\+\\+\\.\\>\\+\\+\\.\\<\\<\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\.\\>\\.\\+\\+\\+\\.\\-\\-\\-\\-\\-\\-\\.\\-\\-\\-\\-\\-\\-\\-\\-\\.\\>\\+\\.\\>\\.', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\[\\>\\+\\+\\+\\+\\+\\+\\+\\>\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\>\\+\\+\\+\\>\\+\\<\\<\\<\\<\\-\\]\\>\\+\\+\\.\\>\\+\\.\\+\\+\\+\\+\\+\\+\\+\\.\\.\\+\\+\\+\\.\\>\\+\\+\\.\\<\\<\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\.\\>\\.\\+\\+\\+\\.\\-\\-\\-\\-\\-\\-\\.\\-\\-\\-\\-\\-\\-\\-\\-\\.\\>\\+\\.\\>\\.'); +}); + +test('id selector with escaping (21)', '#\\#', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '#'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\#'); +}); + +test('id selector with escaping (22)', '#\\#\\#', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '##'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\#\\#'); +}); + +test('id selector with escaping (23)', '#\\#\\.\\#\\.\\#', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '#.#.#'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\#\\.\\#\\.\\#'); +}); + +test('id selector with escaping (24)', '#\\_', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '_'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\_'); +}); + +test('id selector with escaping (25)', '#\\{\\}', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '{}'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\{\\}'); +}); + +test('id selector with escaping (26)', '#\\.fake\\-class', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '.fake-class'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\.fake\\-class'); +}); + +test('id selector with escaping (27)', '#foo\\.bar', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, 'foo.bar'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'foo\\.bar'); +}); + +test('id selector with escaping (28)', '#\\3A hover', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, ':hover'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\3A hover'); +}); + +test('id selector with escaping (29)', '#\\3A hover\\3A focus\\3A active', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, ':hover:focus:active'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\3A hover\\3A focus\\3A active'); +}); + +test('id selector with escaping (30)', '#\\[attr\\=value\\]', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, '[attr=value]'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\[attr\\=value\\]'); +}); + +test('id selector with escaping (31)', '#f\\/o\\/o', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, 'f/o/o'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'f\\/o\\/o'); +}); + +test('id selector with escaping (32)', '#f\\\\o\\\\o', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, 'f\\o\\o'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'f\\\\o\\\\o'); +}); + +test('id selector with escaping (33)', '#f\\*o\\*o', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, 'f*o*o'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'f\\*o\\*o'); +}); + +test('id selector with escaping (34)', '#f\\!o\\!o', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, 'f!o!o'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'f\\!o\\!o'); +}); + +test('id selector with escaping (35)', '#f\\\'o\\\'o', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, 'f\'o\'o'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'f\\\'o\\\'o'); +}); + +test('id selector with escaping (36)', '#f\\~o\\~o', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, 'f~o~o'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'f\\~o\\~o'); +}); + +test('id selector with escaping (37)', '#f\\+o\\+o', (t, tree) => { + t.deepEqual(tree.nodes[0].nodes[0].value, 'f+o+o'); + t.deepEqual(tree.nodes[0].nodes[0].type, 'id'); + t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'f\\+o\\+o'); +}); diff --git a/src/parser.js b/src/parser.js index ae680b8..5bfd799 100644 --- a/src/parser.js +++ b/src/parser.js @@ -822,7 +822,7 @@ export default class Parser { nextToken = this.nextToken; } const hasClass = indexesOf(word, '.').filter(i => word[i - 1] !== '\\'); - let hasId = indexesOf(word, '#'); + let hasId = indexesOf(word, '#').filter(i => word[i - 1] !== '\\'); // Eliminate Sass interpolations from the list of id indexes const interpolations = indexesOf(word, '#{'); if (interpolations.length) {