@markuplint/selector 3.12.0 → 4.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,342 +0,0 @@
1
- const { JSDOM } = require('jsdom');
2
-
3
- const { matchSelector } = require('../lib/match-selector');
4
-
5
- function createTestElement(html) {
6
- if (/^<html>/i.test(html)) {
7
- const dom = new JSDOM(html);
8
- return dom.window.document.querySelector('html');
9
- }
10
- const fragment = JSDOM.fragment(html);
11
- return fragment.firstChild;
12
- }
13
-
14
- test('CSS Selector', () => {
15
- const el = createTestElement('<div id="hoge" class="foo bar"></div>');
16
- expect(matchSelector(el, '*')).toStrictEqual({ matched: true, selector: '*', specificity: [0, 0, 0] });
17
- expect(matchSelector(el, 'div')).toStrictEqual({ matched: true, selector: 'div', specificity: [0, 0, 1] });
18
- expect(matchSelector(el, 'div#hoge')).toStrictEqual({
19
- matched: true,
20
- selector: 'div#hoge',
21
- specificity: [1, 0, 1],
22
- });
23
- expect(matchSelector(el, 'div#fuga')).toStrictEqual({ matched: false });
24
- expect(matchSelector(el, '#hoge')).toStrictEqual({ matched: true, selector: '#hoge', specificity: [1, 0, 0] });
25
- expect(matchSelector(el, 'div.foo')).toStrictEqual({ matched: true, selector: 'div.foo', specificity: [0, 1, 1] });
26
- expect(matchSelector(el, 'div.bar')).toStrictEqual({ matched: true, selector: 'div.bar', specificity: [0, 1, 1] });
27
- expect(matchSelector(el, '.foo')).toStrictEqual({ matched: true, selector: '.foo', specificity: [0, 1, 0] });
28
- expect(matchSelector(el, '.foo.bar')).toStrictEqual({
29
- matched: true,
30
- selector: '.foo.bar',
31
- specificity: [0, 2, 0],
32
- });
33
- expect(matchSelector(el, '.any')).toStrictEqual({ matched: false });
34
- });
35
-
36
- test('nodeName case-sensitive', () => {
37
- expect(matchSelector(createTestElement('<DIV></DIV>'), 'div')).toStrictEqual({
38
- matched: true,
39
- selector: 'div',
40
- specificity: [0, 0, 1],
41
- });
42
-
43
- expect(matchSelector(createTestElement('<DIV></DIV>'), 'DIV')).toStrictEqual({
44
- matched: true,
45
- selector: 'DIV',
46
- specificity: [0, 0, 1],
47
- });
48
- });
49
-
50
- test('invisible tag', () => {
51
- const head = createTestElement('<html><head></head></html>').childNodes[0];
52
- expect(head.nodeName).toBe('HEAD');
53
- expect(matchSelector(head, 'head')).toStrictEqual({
54
- matched: true,
55
- selector: 'head',
56
- specificity: [0, 0, 1],
57
- });
58
- });
59
-
60
- test('nodeName', () => {
61
- const el = createTestElement('<div></div>');
62
- expect(
63
- matchSelector(el, {
64
- nodeName: '/^[a-z]+$/',
65
- }),
66
- ).toStrictEqual({
67
- matched: true,
68
- selector: 'div',
69
- specificity: [0, 0, 1],
70
- data: {},
71
- });
72
- });
73
-
74
- test('nodeName named group capture', () => {
75
- const el = createTestElement('<h6></h6>');
76
- expect(
77
- matchSelector(el, {
78
- nodeName: '/^h(?<level>[1-6])$/',
79
- }),
80
- ).toStrictEqual({
81
- matched: true,
82
- selector: 'h6',
83
- specificity: [0, 0, 1],
84
- data: {
85
- $1: '6',
86
- level: '6',
87
- },
88
- });
89
- });
90
-
91
- test('nodeName (No RegExp)', () => {
92
- const el = createTestElement('<div></div>');
93
- expect(
94
- matchSelector(el, {
95
- nodeName: 'div',
96
- }),
97
- ).toStrictEqual({
98
- matched: true,
99
- selector: 'div',
100
- specificity: [0, 0, 1],
101
- data: {},
102
- });
103
- });
104
-
105
- test('attrName', () => {
106
- const el = createTestElement('<div data-attr></div>');
107
- expect(
108
- matchSelector(el, {
109
- attrName: '/^data-([a-z]+)$/',
110
- }),
111
- ).toStrictEqual({
112
- matched: true,
113
- selector: '[data-attr]',
114
- specificity: [0, 1, 0],
115
- data: {
116
- $1: 'attr',
117
- },
118
- });
119
- });
120
-
121
- test('attrValue', () => {
122
- const el = createTestElement('<div data-attr="abc"></div>');
123
- expect(
124
- matchSelector(el, {
125
- attrValue: '/^[a-z]+$/',
126
- }),
127
- ).toStrictEqual({
128
- matched: true,
129
- selector: '[data-attr="abc"]',
130
- specificity: [0, 1, 0],
131
- data: {},
132
- });
133
- });
134
-
135
- test('No matched', () => {
136
- const el = createTestElement('<div data-attr="abc"></div>');
137
- expect(
138
- matchSelector(el, {
139
- nodeName: 'span',
140
- attrName: 'data-attr',
141
- attrValue: 'abc',
142
- }),
143
- ).toStrictEqual({
144
- matched: false,
145
- });
146
- });
147
-
148
- test('nodeName & attrName', () => {
149
- const el = createTestElement('<div data-attr="abc"></div>');
150
- expect(
151
- matchSelector(el, {
152
- nodeName: 'div',
153
- attrName: 'data-attr',
154
- }),
155
- ).toStrictEqual({
156
- matched: true,
157
- selector: 'div[data-attr]',
158
- specificity: [0, 1, 1],
159
- data: {},
160
- });
161
- });
162
-
163
- test('attrName & attrValue', () => {
164
- const el = createTestElement('<div data-attr="abc"></div>');
165
- expect(
166
- matchSelector(el, {
167
- attrName: 'data-attr',
168
- attrValue: '/^[a-z]+$/',
169
- }),
170
- ).toStrictEqual({
171
- matched: true,
172
- selector: '[data-attr="abc"]',
173
- specificity: [0, 1, 0],
174
- data: {},
175
- });
176
- });
177
-
178
- test('nodeName & attrName & attrValue', () => {
179
- const el = createTestElement('<div data-attr="abc"></div>');
180
- expect(
181
- matchSelector(el, {
182
- nodeName: 'div',
183
- attrName: 'data-attr',
184
- attrValue: 'abc',
185
- }),
186
- ).toStrictEqual({
187
- matched: true,
188
- selector: 'div[data-attr="abc"]',
189
- specificity: [0, 1, 1],
190
- data: {},
191
- });
192
- });
193
-
194
- test('combination " "', () => {
195
- const el = createTestElement('<div data-attr="abc"><span></span></div>');
196
- const span = el.children[0];
197
- expect(
198
- matchSelector(span, {
199
- nodeName: 'div',
200
- attrName: 'data-attr',
201
- attrValue: 'abc',
202
- combination: {
203
- combinator: ' ',
204
- nodeName: 'span',
205
- },
206
- }),
207
- ).toStrictEqual({
208
- matched: true,
209
- selector: 'div[data-attr="abc"] span',
210
- specificity: [0, 1, 2],
211
- data: {},
212
- });
213
- });
214
-
215
- test('combination >', () => {
216
- const el = createTestElement('<div data-attr="abc"><span><a></a></span></div>');
217
- const span = el.children[0];
218
- const a = span.children[0];
219
- expect(
220
- matchSelector(a, {
221
- nodeName: 'div',
222
- attrName: 'data-attr',
223
- attrValue: 'abc',
224
- combination: {
225
- combinator: '>',
226
- nodeName: 'span',
227
- combination: {
228
- combinator: '>',
229
- nodeName: '/^(?<EdgeNodeName>[a-z]+)$/',
230
- },
231
- },
232
- }),
233
- ).toStrictEqual({
234
- matched: true,
235
- selector: 'div[data-attr="abc"] > span > a',
236
- specificity: [0, 1, 3],
237
- data: {
238
- $1: 'a',
239
- EdgeNodeName: 'a',
240
- },
241
- });
242
- });
243
-
244
- test('combination +', () => {
245
- const el = createTestElement(`<ul>
246
- <li class="i1"><a class="a1">1</a></li>
247
- <li class="i2"><a class="a2">2</a></li>
248
- <li class="i3"><a class="a3">3</a></li>
249
- <li class="i4"><a class="a4">4</a></li>
250
- <li class="i5"><a class="a5">5</a></li>
251
- </ul>`);
252
- const i4 = el.children[3];
253
- expect(
254
- matchSelector(i4, {
255
- attrValue: 'i3',
256
- combination: {
257
- combinator: '+',
258
- nodeName: 'li',
259
- },
260
- }),
261
- ).toStrictEqual({
262
- matched: true,
263
- selector: '[class="i3"] + li',
264
- specificity: [0, 1, 1],
265
- data: {},
266
- });
267
- });
268
-
269
- test('combination ~', () => {
270
- const el = createTestElement(`<ul>
271
- <li class="i1"><a class="a1">1</a></li>
272
- <li class="i2"><a class="a2">2</a></li>
273
- <li class="i3"><a class="a3">3</a></li>
274
- <li class="i4"><a class="a4">4</a></li>
275
- <li class="i5"><a class="a5">5</a></li>
276
- </ul>`);
277
- const i5 = el.children[4];
278
- expect(
279
- matchSelector(i5, {
280
- attrValue: 'i3',
281
- combination: {
282
- combinator: '~',
283
- nodeName: 'li',
284
- },
285
- }),
286
- ).toStrictEqual({
287
- matched: true,
288
- selector: '[class="i3"] ~ li',
289
- specificity: [0, 1, 1],
290
- data: {},
291
- });
292
- });
293
-
294
- test('combination :has(+)', () => {
295
- const el = createTestElement(`<ul>
296
- <li class="i1"><a class="a1">1</a></li>
297
- <li class="i2"><a class="a2">2</a></li>
298
- <li class="i3"><a class="a3">3</a></li>
299
- <li class="i4"><a class="a4">4</a></li>
300
- <li class="i5"><a class="a5">5</a></li>
301
- </ul>`);
302
- const i3 = el.children[2];
303
- expect(
304
- matchSelector(i3, {
305
- attrValue: 'i4',
306
- combination: {
307
- combinator: ':has(+)',
308
- nodeName: 'li',
309
- },
310
- }),
311
- ).toStrictEqual({
312
- matched: true,
313
- selector: '[class="i4"]:has(+ li)',
314
- specificity: [0, 1, 1],
315
- data: {},
316
- });
317
- });
318
-
319
- test('combination :has(~)', () => {
320
- const el = createTestElement(`<ul>
321
- <li class="i1"><a class="a1">1</a></li>
322
- <li class="i2"><a class="a2">2</a></li>
323
- <li class="i3"><a class="a3">3</a></li>
324
- <li class="i4"><a class="a4">4</a></li>
325
- <li class="i5"><a class="a5">5</a></li>
326
- </ul>`);
327
- const i3 = el.children[2];
328
- expect(
329
- matchSelector(i3, {
330
- attrValue: 'i5',
331
- combination: {
332
- combinator: ':has(~)',
333
- nodeName: 'li',
334
- },
335
- }),
336
- ).toStrictEqual({
337
- matched: true,
338
- selector: '[class="i5"]:has(~ li)',
339
- specificity: [0, 1, 1],
340
- data: {},
341
- });
342
- });
@@ -1,16 +0,0 @@
1
- const { regexSelectorMatches } = require('../lib/regex-selector-matches');
2
-
3
- it('regexSelectorMatches', () => {
4
- expect(regexSelectorMatches('/^data-([a-z]+)/', 'data-hoge', true)).toStrictEqual({
5
- $0: 'data-hoge',
6
- $1: 'hoge',
7
- });
8
-
9
- expect(regexSelectorMatches('/^data-(?<dataName>[a-z]+)/', 'data-hoge', true)).toStrictEqual({
10
- $0: 'data-hoge',
11
- $1: 'hoge',
12
- dataName: 'hoge',
13
- });
14
-
15
- expect(regexSelectorMatches('/^data-(?<dataName>[a-z]+)/', 'noop', true)).toBeNull();
16
- });
@@ -1,284 +0,0 @@
1
- const { JSDOM } = require('jsdom');
2
-
3
- const { InvalidSelectorError } = require('../lib/invalid-selector-error');
4
- const { Selector } = require('../lib/selector');
5
-
6
- beforeEach(() => {
7
- const dom = new JSDOM();
8
- global.Element = dom.window.Element;
9
- });
10
-
11
- function createTestElement(html, selector) {
12
- if (/^<html>/i.test(html)) {
13
- const dom = new JSDOM(html);
14
- return dom.window.document.querySelector('html');
15
- }
16
- const fragment = JSDOM.fragment(html);
17
- if (selector) {
18
- const el = fragment.querySelector(selector);
19
- if (!el) {
20
- throw new Error('An element is not created');
21
- }
22
- return el;
23
- }
24
- if (!fragment.firstChild) {
25
- throw new Error('An element is not created');
26
- }
27
- return fragment.firstChild;
28
- }
29
-
30
- function createSelector(selector) {
31
- return new Selector(selector);
32
- }
33
-
34
- describe('selector matching', () => {
35
- it('Multiple selector', () => {
36
- const el = createTestElement('<div></div>');
37
- expect(createSelector('div, span').match(el)).toBeTruthy();
38
- });
39
-
40
- it('type / id / class', () => {
41
- const el = createTestElement('<div id="hoge" class="foo bar"></div>');
42
- expect(createSelector('*').match(el)).toBeTruthy();
43
- expect(createSelector('div').match(el)).toBeTruthy();
44
- expect(createSelector('div#hoge').match(el)).toBeTruthy();
45
- expect(createSelector('div#fuga').match(el)).toBe(false);
46
- expect(createSelector('#hoge').match(el)).toBeTruthy();
47
- expect(createSelector('div.foo').match(el)).toBeTruthy();
48
- expect(createSelector('div.bar').match(el)).toBeTruthy();
49
- expect(createSelector('.foo').match(el)).toBeTruthy();
50
- expect(createSelector('.foo.bar').match(el)).toBeTruthy();
51
- expect(createSelector('.any').match(el)).toBe(false);
52
- });
53
-
54
- it('attributes', () => {
55
- const el = createTestElement('<div a="ABC" b="1 2 3" c="あいうえお" d="en-US" e="" f></div>');
56
-
57
- expect(createSelector('[a]').match(el)).toBeTruthy();
58
- expect(createSelector('[a][b][c][d]').match(el)).toBeTruthy();
59
- expect(createSelector('[a][d]').match(el)).toBeTruthy();
60
- expect(createSelector('[g]').match(el)).toBe(false);
61
- expect(createSelector('[a=ABC]').match(el)).toBeTruthy();
62
- expect(createSelector('[a="ABC"]').match(el)).toBeTruthy();
63
- expect(createSelector('[a=ABC i]').match(el)).toBeTruthy();
64
- expect(createSelector('[a=abc i]').match(el)).toBeTruthy();
65
- expect(createSelector('[a=abC i]').match(el)).toBeTruthy();
66
- expect(createSelector('[a=abC]').match(el)).toBe(false);
67
- expect(createSelector('[b~=2]').match(el)).toBeTruthy();
68
- expect(createSelector('[b~=12]').match(el)).toBe(false);
69
- expect(createSelector('[d|=en]').match(el)).toBeTruthy();
70
- expect(createSelector('[d|=e]').match(el)).toBe(false);
71
- expect(createSelector('[d|=ja]').match(el)).toBe(false);
72
- expect(createSelector('[a*=B]').match(el)).toBeTruthy();
73
- expect(createSelector('[a*=D]').match(el)).toBe(false);
74
- expect(createSelector('[a^=A]').match(el)).toBeTruthy();
75
- expect(createSelector('[a^=AB]').match(el)).toBeTruthy();
76
- expect(createSelector('[a^=ABC]').match(el)).toBeTruthy();
77
- expect(createSelector('[a^=C]').match(el)).toBe(false);
78
- expect(createSelector('[a^=BC]').match(el)).toBe(false);
79
- expect(createSelector('[a$=A]').match(el)).toBe(false);
80
- expect(createSelector('[a$=AB]').match(el)).toBe(false);
81
- expect(createSelector('[a$=C]').match(el)).toBeTruthy();
82
- expect(createSelector('[a$=BC]').match(el)).toBeTruthy();
83
- expect(createSelector('[a$=ABC]').match(el)).toBeTruthy();
84
- expect(createSelector('[e]').match(el)).toBeTruthy();
85
- expect(createSelector('[e=""]').match(el)).toBeTruthy();
86
- expect(createSelector('[e="a"]').match(el)).toBe(false);
87
- expect(createSelector('[a=""]').match(el)).toBe(false);
88
- expect(createSelector('[f]').match(el)).toBeTruthy();
89
- expect(createSelector('[f=""]').match(el)).toBeTruthy();
90
- expect(createSelector('[f="f"]').match(el)).toBe(false);
91
- });
92
-
93
- it(':not', () => {
94
- const el = createTestElement('<div id="hoge" class="foo bar"></div>');
95
- expect(createSelector('*:not(a)').match(el)).toBeTruthy();
96
- expect(createSelector('*:not(div)').match(el)).toBe(false);
97
- expect(createSelector('div:not(.any)').match(el)).toBeTruthy();
98
- expect(createSelector('div:not(#fuga)').match(el)).toBeTruthy();
99
- expect(createSelector(':not(#hoge)').match(el)).toBe(false);
100
- });
101
-
102
- it(':is', () => {
103
- const el = createTestElement('<div id="hoge" class="foo bar"></div>');
104
- expect(createSelector(':is(a, div)').match(el)).toBeTruthy();
105
- expect(createSelector(':is(a, span)').match(el)).toBe(false);
106
- });
107
-
108
- it(':has', () => {
109
- const el = createTestElement('<header><div></div></header>');
110
- expect(createSelector(':has(div, span)').match(el)).toBeTruthy();
111
- expect(
112
- createSelector(
113
- ':has(article, aside, main, nav, section, [role=article], [role=complementary], [role=main], [role=navigation], [role=region])',
114
- ).match(el),
115
- ).toBe(false);
116
- });
117
-
118
- it(':scope', () => {
119
- const el = createTestElement('<div></div>');
120
- expect(createSelector(':scope').match(el)).toBeTruthy();
121
- });
122
-
123
- it(':root', () => {
124
- const el = createTestElement('<html><div id="hoge" class="foo bar"></div></html>');
125
- expect(createSelector(':root').match(el)).toBeTruthy();
126
- const el2 = createTestElement('<div id="hoge" class="foo bar"></div>');
127
- expect(createSelector(':root').match(el2)).toBe(false);
128
- });
129
-
130
- it('Descendant combinator', () => {
131
- const el = createTestElement('<div><span><a></a></span></div>');
132
- const a = el.children[0].children[0];
133
- expect(a.nodeName).toBe('A');
134
- expect(createSelector('div a').match(a)).toBeTruthy();
135
- expect(createSelector('div span a').match(a)).toBeTruthy();
136
- expect(createSelector('span a').match(a)).toBeTruthy();
137
- expect(createSelector('header a').match(a)).toBe(false);
138
- });
139
-
140
- it('Child combinator', () => {
141
- const el = createTestElement('<div><span><a></a></span></div>');
142
- const a = el.children[0].children[0];
143
- expect(createSelector('div > div').match(el)).toBe(false);
144
- expect(a.nodeName).toBe('A');
145
- expect(createSelector('span > a').match(a)).toBeTruthy();
146
- expect(createSelector('div span > a').match(a)).toBeTruthy();
147
- expect(createSelector('div > a').match(a)).toBe(false);
148
- expect(createSelector('header > a').match(a)).toBe(false);
149
- });
150
-
151
- it('Next-sibling combinator', () => {
152
- const el = createTestElement(`<ul>
153
- <li class="i1"><a class="a1">1</a></li>
154
- <li class="i2"><a class="a2">2</a></li>
155
- <li class="i3"><a class="a3">3</a></li>
156
- <li class="i4"><a class="a4">4</a></li>
157
- <li class="i5"><a class="a5">5</a></li>
158
- </ul>`);
159
- expect(createSelector('.i2 + li').match(el.children[0])).toBe(false);
160
- expect(createSelector('.i2 + li').match(el.children[1])).toBe(false);
161
- expect(createSelector('.i2 + li').match(el.children[2])).toBeTruthy();
162
- expect(createSelector('.i2 + li').match(el.children[3])).toBe(false);
163
- expect(createSelector('.i2 + li').match(el.children[4])).toBe(false);
164
- expect(createSelector('.i4 + li').match(el.children[0])).toBe(false);
165
- expect(createSelector('.i4 + li').match(el.children[1])).toBe(false);
166
- expect(createSelector('.i4 + li').match(el.children[2])).toBe(false);
167
- expect(createSelector('.i4 + li').match(el.children[3])).toBe(false);
168
- expect(createSelector('.i4 + li').match(el.children[4])).toBeTruthy();
169
- });
170
-
171
- it('Subsequent-sibling combinator', () => {
172
- const el = createTestElement(`<ul>
173
- <li class="i1"><a class="a1">1</a></li>
174
- <li class="i2"><a class="a2">2</a></li>
175
- <li class="i3"><a class="a3">3</a></li>
176
- <li class="i4"><a class="a4">4</a></li>
177
- <li class="i5"><a class="a5">5</a></li>
178
- </ul>`);
179
- expect(createSelector('.i2 ~ li').match(el.children[0])).toBe(false);
180
- expect(createSelector('.i2 ~ li').match(el.children[1])).toBe(false);
181
- expect(createSelector('.i2 ~ li').match(el.children[2])).toBeTruthy();
182
- expect(createSelector('.i2 ~ li').match(el.children[3])).toBeTruthy();
183
- expect(createSelector('.i2 ~ li').match(el.children[4])).toBeTruthy();
184
- });
185
-
186
- it('combinator start error', () => {
187
- const el = createTestElement('<div><a></a><span></span></div>', 'a');
188
- InvalidSelectorError;
189
- expect(() => createSelector('> a').match(el)).toThrow(InvalidSelectorError);
190
- expect(() => createSelector('+ a').match(el)).toThrow(InvalidSelectorError);
191
- expect(() => createSelector('~ a').match(el)).toThrow(InvalidSelectorError);
192
- });
193
-
194
- it(':has(+ E)', () => {
195
- const el = createTestElement('<figure><table></table><figcaption></figcaption></figure>', 'table');
196
- expect(createSelector('table:has(+ figcaption)').match(el)).toBeTruthy();
197
- });
198
-
199
- it(':has(~ E)', () => {
200
- const el = createTestElement('<figure><table></table><p></p><figcaption></figcaption></figure>', 'table');
201
- expect(createSelector('table:has(~ figcaption)').match(el)).toBeTruthy();
202
- });
203
-
204
- it(':closest', () => {
205
- const el = createTestElement('<table><tr><td></td></tr></table>');
206
- const td = el.children[0].children[0].children[0];
207
- expect(createSelector('td').match(td)).toBeTruthy();
208
- expect(createSelector(':closest(table)').match(td)).toBeTruthy();
209
- expect(createSelector(':closest(tr)').match(td)).toBeTruthy();
210
- expect(createSelector(':closest(tbody)').match(td)).toBeTruthy();
211
- expect(createSelector(':closest(div)').match(td)).toBe(false);
212
- });
213
-
214
- it('namespace', () => {
215
- const svgA = createTestElement('<svg><a></a></svg>', 'a');
216
- expect(createSelector('a').match(svgA)).toBeTruthy();
217
- expect(createSelector('|a').match(svgA)).toBeTruthy();
218
- expect(createSelector('*|a').match(svgA)).toBeTruthy();
219
- expect(createSelector('svg|a').match(svgA)).toBeTruthy();
220
- const htmlA = createTestElement('<div><a></a></div>', 'a');
221
- expect(createSelector('a').match(htmlA)).toBeTruthy();
222
- expect(createSelector('|a').match(htmlA)).toBeTruthy();
223
- expect(createSelector('*|a').match(htmlA)).toBeTruthy();
224
- expect(createSelector('svg|a').match(htmlA)).toBeFalsy();
225
- });
226
-
227
- it('namespaced attribute', () => {
228
- const svgA = createTestElement('<svg><a href></a></svg>', 'a');
229
- expect(createSelector('[href]').match(svgA)).toBeTruthy();
230
- expect(createSelector('[|href]').match(svgA)).toBeTruthy();
231
- expect(createSelector('[*|href]').match(svgA)).toBeTruthy();
232
- expect(createSelector('[xlink|href]').match(svgA)).toBeFalsy();
233
- const svgAx = createTestElement('<svg><a xlink:href></a></svg>', 'a');
234
- expect(createSelector('[href]').match(svgAx)).toBeTruthy();
235
- expect(createSelector('[|href]').match(svgAx)).toBeTruthy();
236
- expect(createSelector('[*|href]').match(svgAx)).toBeTruthy();
237
- expect(createSelector('[xlink|href]').match(svgAx)).toBeTruthy();
238
- });
239
-
240
- it('is invisible tags', () => {
241
- const el = createTestElement('<html><head><title></title></head></html>');
242
- const head = el.children[0];
243
- const title = head.children[0];
244
- expect(createSelector('head').match(head)).toBeTruthy();
245
- expect(createSelector('title').match(title)).toBeTruthy();
246
- });
247
- });
248
-
249
- describe('specificity', () => {
250
- it(':not', () => {
251
- const el = createTestElement('<div></div>');
252
- expect(createSelector('div').match(el)).toStrictEqual([0, 0, 1]);
253
- expect(createSelector(':not(span)').match(el)).toStrictEqual([0, 0, 1]);
254
- expect(createSelector(':not(span, a)').match(el)).toStrictEqual([0, 0, 1]);
255
- expect(createSelector(':not(span, #foo)').match(el)).toStrictEqual([1, 0, 0]);
256
- });
257
-
258
- it(':is', () => {
259
- const el = createTestElement('<div></div>');
260
- expect(createSelector('div').match(el)).toStrictEqual([0, 0, 1]);
261
- expect(createSelector(':is(div)').match(el)).toStrictEqual([0, 0, 1]);
262
- expect(createSelector(':is(div, span)').match(el)).toStrictEqual([0, 0, 1]);
263
- expect(createSelector(':is(div, #foo)').match(el)).toStrictEqual([1, 0, 0]);
264
- expect(createSelector(':is(div, #foo, .bar)').match(el)).toStrictEqual([1, 0, 0]);
265
- expect(createSelector(':is(div, #foo.bar)').match(el)).toStrictEqual([1, 1, 0]);
266
- });
267
-
268
- it(':where', () => {
269
- const el = createTestElement('<div></div>');
270
- expect(createSelector('div').match(el)).toStrictEqual([0, 0, 1]);
271
- expect(createSelector(':where(div)').match(el)).toStrictEqual([0, 0, 0]);
272
- expect(createSelector(':where(div, span)').match(el)).toStrictEqual([0, 0, 0]);
273
- expect(createSelector(':where(div, #foo)').match(el)).toStrictEqual([0, 0, 0]);
274
- expect(createSelector(':where(div, #foo, .bar)').match(el)).toStrictEqual([0, 0, 0]);
275
- expect(createSelector(':where(div, #foo.bar)').match(el)).toStrictEqual([0, 0, 0]);
276
- });
277
- });
278
-
279
- describe('search', () => {
280
- it('search', () => {
281
- const el = createTestElement('<a><div><button></button></div></a>');
282
- expect(createSelector(':has(button)').search(el)[0].has?.[0].nodes?.[0].nodeName).toBe('BUTTON');
283
- });
284
- });