Skip to content

Commit 268c9a7

Browse files
alexander-akaitjonathantneal
authored andcommitted
fix: escaping in id selector
1 parent f061075 commit 268c9a7

File tree

2 files changed

+215
-1
lines changed

2 files changed

+215
-1
lines changed

Diff for: src/__tests__/id.js

+214
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,217 @@ test('Less interpolation within an id', '#foo@{bar}', (t, tree) => {
5757
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
5858
t.deepEqual(tree.nodes[0].nodes[0].value, 'foo@{bar}');
5959
});
60+
61+
test('id selector with escaping', '#\\#test', (t, tree) => {
62+
t.deepEqual(tree.nodes[0].nodes[0].value, '#test');
63+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
64+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\#test');
65+
});
66+
67+
test('id selector with escaping (2)', '#-a-b-c-', (t, tree) => {
68+
t.deepEqual(tree.nodes[0].nodes[0].value, '-a-b-c-');
69+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
70+
});
71+
72+
test('id selector with escaping (3)', '#u-m\\00002b', (t, tree) => {
73+
t.deepEqual(tree.nodes[0].nodes[0].value, 'u-m+');
74+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
75+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'u-m\\00002b');
76+
});
77+
78+
test('id selector with escaping (4)', '#♥', (t, tree) => {
79+
t.deepEqual(tree.nodes[0].nodes[0].value, '♥');
80+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
81+
});
82+
83+
test('id selector with escaping (5)', '#©', (t, tree) => {
84+
t.deepEqual(tree.nodes[0].nodes[0].value, '©');
85+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
86+
});
87+
88+
test('id selector with escaping (6)', '#“‘’”', (t, tree) => {
89+
t.deepEqual(tree.nodes[0].nodes[0].value, '“‘’”');
90+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
91+
});
92+
93+
test('id selector with escaping (7)', '#☺☃', (t, tree) => {
94+
t.deepEqual(tree.nodes[0].nodes[0].value, '☺☃');
95+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
96+
});
97+
98+
test('id selector with escaping (8)', '#⌘⌥', (t, tree) => {
99+
t.deepEqual(tree.nodes[0].nodes[0].value, '⌘⌥');
100+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
101+
});
102+
103+
test('id selector with escaping (9)', '#𝄞♪♩♫♬', (t, tree) => {
104+
t.deepEqual(tree.nodes[0].nodes[0].value, '𝄞♪♩♫♬');
105+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
106+
});
107+
108+
test('id selector with escaping (10)', '#💩', (t, tree) => {
109+
t.deepEqual(tree.nodes[0].nodes[0].value, '💩');
110+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
111+
});
112+
113+
test('id selector with escaping (11)', '#\\?', (t, tree) => {
114+
t.deepEqual(tree.nodes[0].nodes[0].value, '?');
115+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
116+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\?');
117+
});
118+
119+
test('id selector with escaping (12)', '#\\@', (t, tree) => {
120+
t.deepEqual(tree.nodes[0].nodes[0].value, '@');
121+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
122+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\@');
123+
});
124+
125+
test('id selector with escaping (13)', '#\\.', (t, tree) => {
126+
t.deepEqual(tree.nodes[0].nodes[0].value, '.');
127+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
128+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\.');
129+
});
130+
131+
test('id selector with escaping (14)', '#\\3A \\)', (t, tree) => {
132+
t.deepEqual(tree.nodes[0].nodes[0].value, ':)');
133+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
134+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\3A \\)');
135+
});
136+
137+
test('id selector with escaping (15)', '#\\3A \\`\\(', (t, tree) => {
138+
t.deepEqual(tree.nodes[0].nodes[0].value, ':`(');
139+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
140+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\3A \\`\\(');
141+
});
142+
143+
test('id selector with escaping (16)', '#\\31 23', (t, tree) => {
144+
t.deepEqual(tree.nodes[0].nodes[0].value, '123');
145+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
146+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\31 23');
147+
});
148+
149+
test('id selector with escaping (17)', '#\\31 a2b3c', (t, tree) => {
150+
t.deepEqual(tree.nodes[0].nodes[0].value, '1a2b3c');
151+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
152+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\31 a2b3c');
153+
});
154+
155+
test('id selector with escaping (18)', '#\\<p\\>', (t, tree) => {
156+
t.deepEqual(tree.nodes[0].nodes[0].value, '<p>');
157+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
158+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\<p\\>');
159+
});
160+
161+
test('id selector with escaping (19)', '#\\<\\>\\<\\<\\<\\>\\>\\<\\>', (t, tree) => {
162+
t.deepEqual(tree.nodes[0].nodes[0].value, '<><<<>><>');
163+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
164+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\<\\>\\<\\<\\<\\>\\>\\<\\>');
165+
});
166+
167+
test('id selector with escaping (20)', '#\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\[\\>\\+\\+\\+\\+\\+\\+\\+\\>\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\>\\+\\+\\+\\>\\+\\<\\<\\<\\<\\-\\]\\>\\+\\+\\.\\>\\+\\.\\+\\+\\+\\+\\+\\+\\+\\.\\.\\+\\+\\+\\.\\>\\+\\+\\.\\<\\<\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\.\\>\\.\\+\\+\\+\\.\\-\\-\\-\\-\\-\\-\\.\\-\\-\\-\\-\\-\\-\\-\\-\\.\\>\\+\\.\\>\\.', (t, tree) => {
168+
t.deepEqual(tree.nodes[0].nodes[0].value, '++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.');
169+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
170+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\[\\>\\+\\+\\+\\+\\+\\+\\+\\>\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\>\\+\\+\\+\\>\\+\\<\\<\\<\\<\\-\\]\\>\\+\\+\\.\\>\\+\\.\\+\\+\\+\\+\\+\\+\\+\\.\\.\\+\\+\\+\\.\\>\\+\\+\\.\\<\\<\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\+\\.\\>\\.\\+\\+\\+\\.\\-\\-\\-\\-\\-\\-\\.\\-\\-\\-\\-\\-\\-\\-\\-\\.\\>\\+\\.\\>\\.');
171+
});
172+
173+
test('id selector with escaping (21)', '#\\#', (t, tree) => {
174+
t.deepEqual(tree.nodes[0].nodes[0].value, '#');
175+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
176+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\#');
177+
});
178+
179+
test('id selector with escaping (22)', '#\\#\\#', (t, tree) => {
180+
t.deepEqual(tree.nodes[0].nodes[0].value, '##');
181+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
182+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\#\\#');
183+
});
184+
185+
test('id selector with escaping (23)', '#\\#\\.\\#\\.\\#', (t, tree) => {
186+
t.deepEqual(tree.nodes[0].nodes[0].value, '#.#.#');
187+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
188+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\#\\.\\#\\.\\#');
189+
});
190+
191+
test('id selector with escaping (24)', '#\\_', (t, tree) => {
192+
t.deepEqual(tree.nodes[0].nodes[0].value, '_');
193+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
194+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\_');
195+
});
196+
197+
test('id selector with escaping (25)', '#\\{\\}', (t, tree) => {
198+
t.deepEqual(tree.nodes[0].nodes[0].value, '{}');
199+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
200+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\{\\}');
201+
});
202+
203+
test('id selector with escaping (26)', '#\\.fake\\-class', (t, tree) => {
204+
t.deepEqual(tree.nodes[0].nodes[0].value, '.fake-class');
205+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
206+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\.fake\\-class');
207+
});
208+
209+
test('id selector with escaping (27)', '#foo\\.bar', (t, tree) => {
210+
t.deepEqual(tree.nodes[0].nodes[0].value, 'foo.bar');
211+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
212+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'foo\\.bar');
213+
});
214+
215+
test('id selector with escaping (28)', '#\\3A hover', (t, tree) => {
216+
t.deepEqual(tree.nodes[0].nodes[0].value, ':hover');
217+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
218+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\3A hover');
219+
});
220+
221+
test('id selector with escaping (29)', '#\\3A hover\\3A focus\\3A active', (t, tree) => {
222+
t.deepEqual(tree.nodes[0].nodes[0].value, ':hover:focus:active');
223+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
224+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\3A hover\\3A focus\\3A active');
225+
});
226+
227+
test('id selector with escaping (30)', '#\\[attr\\=value\\]', (t, tree) => {
228+
t.deepEqual(tree.nodes[0].nodes[0].value, '[attr=value]');
229+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
230+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\[attr\\=value\\]');
231+
});
232+
233+
test('id selector with escaping (31)', '#f\\/o\\/o', (t, tree) => {
234+
t.deepEqual(tree.nodes[0].nodes[0].value, 'f/o/o');
235+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
236+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'f\\/o\\/o');
237+
});
238+
239+
test('id selector with escaping (32)', '#f\\\\o\\\\o', (t, tree) => {
240+
t.deepEqual(tree.nodes[0].nodes[0].value, 'f\\o\\o');
241+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
242+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'f\\\\o\\\\o');
243+
});
244+
245+
test('id selector with escaping (33)', '#f\\*o\\*o', (t, tree) => {
246+
t.deepEqual(tree.nodes[0].nodes[0].value, 'f*o*o');
247+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
248+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'f\\*o\\*o');
249+
});
250+
251+
test('id selector with escaping (34)', '#f\\!o\\!o', (t, tree) => {
252+
t.deepEqual(tree.nodes[0].nodes[0].value, 'f!o!o');
253+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
254+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'f\\!o\\!o');
255+
});
256+
257+
test('id selector with escaping (35)', '#f\\\'o\\\'o', (t, tree) => {
258+
t.deepEqual(tree.nodes[0].nodes[0].value, 'f\'o\'o');
259+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
260+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'f\\\'o\\\'o');
261+
});
262+
263+
test('id selector with escaping (36)', '#f\\~o\\~o', (t, tree) => {
264+
t.deepEqual(tree.nodes[0].nodes[0].value, 'f~o~o');
265+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
266+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'f\\~o\\~o');
267+
});
268+
269+
test('id selector with escaping (37)', '#f\\+o\\+o', (t, tree) => {
270+
t.deepEqual(tree.nodes[0].nodes[0].value, 'f+o+o');
271+
t.deepEqual(tree.nodes[0].nodes[0].type, 'id');
272+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'f\\+o\\+o');
273+
});

Diff for: src/parser.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ export default class Parser {
822822
nextToken = this.nextToken;
823823
}
824824
const hasClass = indexesOf(word, '.').filter(i => word[i - 1] !== '\\');
825-
let hasId = indexesOf(word, '#');
825+
let hasId = indexesOf(word, '#').filter(i => word[i - 1] !== '\\');
826826
// Eliminate Sass interpolations from the list of id indexes
827827
const interpolations = indexesOf(word, '#{');
828828
if (interpolations.length) {

0 commit comments

Comments
 (0)