This repository has been archived by the owner on Sep 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
equal.ts
120 lines (106 loc) · 3.1 KB
/
equal.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import { namesEqual, NamespaceDef, QualifiedName } from '@frontmeans/namespace-aliaser';
import { arraysAreEqual } from '@proc7ts/primitives';
import { DoqryCombinator } from './combinator';
import { doqryPicker, DoqryPicker } from './picker';
import { DoqrySubSelector$isPseudo } from './picker.impl';
import { DoqryPureSelector } from './pure-selector';
import { DoqrySelector } from './selector';
import { DoqrySubPicker } from './sub-picker';
/**
* Tests whether two structured CSS selectors equal.
*
* @param first - First selector.
* @param second - Second selector.
*
* @returns `true` if selectors are equal, `false` otherwise.
*/
export function doqryEqual(
first: DoqrySelector | DoqryPureSelector,
second: DoqrySelector | DoqryPureSelector,
): boolean {
return arraysAreEqual(doqryPicker(first), doqryPicker(second), DoqryPicker$Part$equal);
}
function DoqryPicker$Part$equal(
first: DoqryPicker.Part | DoqryCombinator,
second: DoqryPicker.Part | DoqryCombinator,
): boolean {
if (typeof first === 'string') {
return first === second;
}
if (typeof second === 'string') {
return false;
}
return (
DoqryNamespace$equal(first.ns, second.ns)
&& DoqryName$equal(first.e, second.e)
&& DoqryName$equal(first.i, second.i)
&& DoqryClass$allEqual(first.c, second.c)
&& DoqrySubPicker$allEqual(first.u, second.u)
&& DoqryQualifier$allEqual(first.$, second.$)
);
}
function DoqryNamespace$equal(
first: string | NamespaceDef | undefined,
second: string | NamespaceDef | undefined,
): boolean {
if (!first || typeof first === 'string') {
return first === second;
}
if (!second || typeof second === 'string') {
return false;
}
return first.url === second.url;
}
function DoqryName$equal(
first: QualifiedName | undefined,
second: QualifiedName | undefined,
): boolean {
return first == null ? second == null : second != null && namesEqual(first, second);
}
function DoqryClass$allEqual(
first: readonly QualifiedName[] | undefined,
second: readonly QualifiedName[] | undefined,
): boolean {
if (!first) {
return !second;
}
if (!second) {
return false;
}
return arraysAreEqual(first, second, namesEqual);
}
function DoqrySubPicker$allEqual(
first: readonly DoqrySubPicker[] | undefined,
second: readonly DoqrySubPicker[] | undefined,
): boolean {
if (!first) {
return !second;
}
if (!second) {
return false;
}
return arraysAreEqual(first, second, DoqrySubPicker$equal);
}
function DoqrySubPicker$equal(first: DoqrySubPicker, second: DoqrySubPicker): boolean {
if (first.length !== second.length) {
return false;
}
if (DoqrySubSelector$isPseudo(first)) {
return first.every((p, i) => i < 2
? p === second[i]
: doqryEqual(p as DoqrySubPicker.Parameter, second[i] as DoqrySubPicker.Parameter));
}
return first.every((str, i) => str === second[i]);
}
function DoqryQualifier$allEqual(
first: readonly string[] | undefined,
second: readonly string[] | undefined,
): boolean {
if (!first) {
return !second;
}
if (!second) {
return false;
}
return arraysAreEqual(first, second);
}