@asamuzakjp/dom-selector 0.2.2 → 0.4.1

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.
package/README.md CHANGED
@@ -23,7 +23,7 @@ npm i @asamuzakjp/dom-selector
23
23
  ```javascript
24
24
  const {
25
25
  matches, closest, querySelector, querySelectorAll
26
- } = require('dom-selector');
26
+ } = require('@asamuzakjp/dom-selector');
27
27
  ```
28
28
 
29
29
  <!-- Generated by documentation.js. Update this documentation by updating the source code. -->
package/package.json CHANGED
@@ -19,7 +19,7 @@
19
19
  "types": "types/index.d.ts",
20
20
  "dependencies": {
21
21
  "@types/css-tree": "^2.3.1",
22
- "@types/node": "^20.1.0",
22
+ "@types/node": "^20.1.1",
23
23
  "css-tree": "^2.3.1"
24
24
  },
25
25
  "devDependencies": {
@@ -27,8 +27,8 @@
27
27
  "chai": "^4.3.7",
28
28
  "eslint": "^8.40.0",
29
29
  "eslint-config-standard": "^17.0.0",
30
- "eslint-plugin-jsdoc": "^43.2.0",
31
- "eslint-plugin-regexp": "^1.14.0",
30
+ "eslint-plugin-jsdoc": "^44.1.0",
31
+ "eslint-plugin-regexp": "^1.15.0",
32
32
  "eslint-plugin-unicorn": "^47.0.0",
33
33
  "jsdom": "^22.0.0",
34
34
  "mocha": "^10.2.0",
@@ -41,5 +41,5 @@
41
41
  "test": "c8 --reporter=text mocha --exit test/**/*.test.js",
42
42
  "tsc": "npx tsc"
43
43
  },
44
- "version": "0.2.2"
44
+ "version": "0.4.1"
45
45
  }
package/src/js/matcher.js CHANGED
@@ -999,6 +999,11 @@ class Matcher {
999
999
  firstItem = items.shift();
1000
1000
  itemLeaves.push(item, firstItem);
1001
1001
  }
1002
+ if (firstItem.type === PSEUDO_CLASS_SELECTOR &&
1003
+ firstItem.name === 'has') {
1004
+ matched = false;
1005
+ break;
1006
+ }
1002
1007
  const arr = this._matchCombinator(itemLeaves, node);
1003
1008
  if (arr.length) {
1004
1009
  matched = true;
@@ -1019,6 +1024,12 @@ class Matcher {
1019
1024
  let matched;
1020
1025
  for (const items of ast) {
1021
1026
  const item = items.shift();
1027
+ // NOTE: according to MDN, :not() can not contain :not()
1028
+ // but spec says nothing about that?
1029
+ if (item.type === PSEUDO_CLASS_SELECTOR && item.name === 'not') {
1030
+ matched = true;
1031
+ break;
1032
+ }
1022
1033
  const arr = this._matchArgumentLeaf(item, node);
1023
1034
  if (arr.length) {
1024
1035
  matched = true;
@@ -1081,81 +1092,94 @@ class Matcher {
1081
1092
  }
1082
1093
  const iterator = this._createIterator(iteratorLeaf, node);
1083
1094
  let nextNode = iterator.nextNode();
1084
- while (nextNode) {
1085
- const [...items] = children;
1086
- if (items.length) {
1087
- if (items.length === 1) {
1088
- const item = items.shift();
1089
- const { name: itemName, type: itemType } = item;
1090
- if (itemType === PSEUDO_CLASS_SELECTOR &&
1091
- REG_PSEUDO_FUNC.test(itemName)) {
1092
- nextNode = this._matchLogicalPseudoFunc(item, nextNode);
1093
- if (nextNode) {
1094
- res.add(nextNode);
1095
- nextNode = null;
1096
- }
1097
- } else {
1098
- const arr = this._match(item, nextNode);
1099
- if (arr.length) {
1100
- for (const i of arr) {
1101
- res.add(i);
1102
- }
1103
- }
1104
- }
1105
- } else {
1106
- do {
1095
+ if (nextNode) {
1096
+ while (nextNode) {
1097
+ const [...items] = children;
1098
+ if (items.length) {
1099
+ if (items.length === 1) {
1107
1100
  const item = items.shift();
1108
1101
  const { name: itemName, type: itemType } = item;
1109
1102
  if (itemType === PSEUDO_CLASS_SELECTOR &&
1110
1103
  REG_PSEUDO_FUNC.test(itemName)) {
1111
1104
  nextNode = this._matchLogicalPseudoFunc(item, nextNode);
1112
- } else if (itemType === COMBINATOR) {
1113
- const leaves = [];
1114
- leaves.push(item);
1115
- while (items.length) {
1116
- const [nextItem] = items;
1117
- if (nextItem.type === COMBINATOR ||
1118
- (nextItem.type === PSEUDO_CLASS_SELECTOR &&
1119
- REG_PSEUDO_NTH.test(nextItem.name)) ||
1120
- (nextItem.type === PSEUDO_CLASS_SELECTOR &&
1121
- REG_PSEUDO_FUNC.test(nextItem.name))) {
1122
- break;
1123
- } else {
1124
- leaves.push(items.shift());
1105
+ if (nextNode) {
1106
+ res.add(nextNode);
1107
+ nextNode = null;
1108
+ }
1109
+ } else {
1110
+ const arr = this._match(item, nextNode);
1111
+ if (arr.length) {
1112
+ for (const i of arr) {
1113
+ res.add(i);
1125
1114
  }
1126
1115
  }
1127
- const arr = this._matchCombinator(leaves, nextNode);
1128
- if (!arr.length || arr.length === 1) {
1129
- [nextNode] = arr;
1130
- } else {
1131
- if (items.length) {
1132
- for (const i of arr) {
1133
- const a = this._matchSelector(items, i);
1134
- if (a.length) {
1135
- for (const j of a) {
1136
- res.add(j);
1137
- }
1138
- }
1116
+ }
1117
+ } else {
1118
+ do {
1119
+ const item = items.shift();
1120
+ const { name: itemName, type: itemType } = item;
1121
+ if (itemType === PSEUDO_CLASS_SELECTOR &&
1122
+ REG_PSEUDO_FUNC.test(itemName)) {
1123
+ nextNode = this._matchLogicalPseudoFunc(item, nextNode);
1124
+ } else if (itemType === COMBINATOR) {
1125
+ const leaves = [];
1126
+ leaves.push(item);
1127
+ while (items.length) {
1128
+ const [nextItem] = items;
1129
+ if (nextItem.type === COMBINATOR ||
1130
+ (nextItem.type === PSEUDO_CLASS_SELECTOR &&
1131
+ REG_PSEUDO_NTH.test(nextItem.name)) ||
1132
+ (nextItem.type === PSEUDO_CLASS_SELECTOR &&
1133
+ REG_PSEUDO_FUNC.test(nextItem.name))) {
1134
+ break;
1135
+ } else {
1136
+ leaves.push(items.shift());
1139
1137
  }
1138
+ }
1139
+ const arr = this._matchCombinator(leaves, nextNode);
1140
+ if (!arr.length || arr.length === 1) {
1141
+ [nextNode] = arr;
1140
1142
  } else {
1141
- for (const i of arr) {
1142
- res.add(i);
1143
+ if (items.length) {
1144
+ for (const i of arr) {
1145
+ const a = this._matchSelector(items, i);
1146
+ if (a.length) {
1147
+ for (const j of a) {
1148
+ res.add(j);
1149
+ }
1150
+ }
1151
+ }
1152
+ } else {
1153
+ for (const i of arr) {
1154
+ res.add(i);
1155
+ }
1143
1156
  }
1157
+ nextNode = null;
1144
1158
  }
1145
- nextNode = null;
1159
+ } else {
1160
+ [nextNode] = this._match(item, nextNode);
1146
1161
  }
1147
- } else {
1148
- [nextNode] = this._match(item, nextNode);
1162
+ } while (items.length && nextNode);
1163
+ if (nextNode) {
1164
+ res.add(nextNode);
1149
1165
  }
1150
- } while (items.length && nextNode);
1151
- if (nextNode) {
1152
- res.add(nextNode);
1153
1166
  }
1167
+ } else if (nextNode) {
1168
+ res.add(nextNode);
1154
1169
  }
1155
- } else if (nextNode) {
1156
- res.add(nextNode);
1170
+ nextNode = iterator.nextNode();
1171
+ }
1172
+ } else if (firstChild.type === PSEUDO_CLASS_SELECTOR &&
1173
+ REG_PSEUDO_FUNC.test(firstChild.name) &&
1174
+ node.nodeType === ELEMENT_NODE) {
1175
+ nextNode = node;
1176
+ while (nextNode) {
1177
+ nextNode = this._matchLogicalPseudoFunc(firstChild, nextNode);
1178
+ if (nextNode) {
1179
+ res.add(nextNode);
1180
+ }
1181
+ nextNode = nextNode.nextElementSibling;
1157
1182
  }
1158
- nextNode = iterator.nextNode();
1159
1183
  }
1160
1184
  }
1161
1185
  return [...res];
@@ -1263,7 +1287,12 @@ class Matcher {
1263
1287
  const arr = this._match(this.#ast, this.#node);
1264
1288
  let res;
1265
1289
  if (arr.length) {
1266
- [res] = arr;
1290
+ const [i, j] = arr;
1291
+ if (i !== this.#node) {
1292
+ res = i;
1293
+ } else if (j) {
1294
+ res = j;
1295
+ }
1267
1296
  }
1268
1297
  return res || null;
1269
1298
  }
@@ -1278,7 +1307,9 @@ class Matcher {
1278
1307
  const res = new Set();
1279
1308
  if (arr.length) {
1280
1309
  for (const i of arr) {
1281
- res.add(i);
1310
+ if (i !== this.#node) {
1311
+ res.add(i);
1312
+ }
1282
1313
  }
1283
1314
  }
1284
1315
  return [...res];