@asamuzakjp/dom-selector 0.15.3 → 0.15.5

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/js/matcher.js +97 -16
package/package.json CHANGED
@@ -42,5 +42,5 @@
42
42
  "test": "c8 --reporter=text mocha --exit test/**/*.test.js",
43
43
  "tsc": "npx tsc"
44
44
  },
45
- "version": "0.15.3"
45
+ "version": "0.15.5"
46
46
  }
package/src/js/matcher.js CHANGED
@@ -26,8 +26,8 @@ const HEX_CAPTURE = /^([\da-f]{1,6}\s?)/i;
26
26
  const HTML_FORM_INPUT = /^(?:(?:inpu|selec)t|textarea)$/;
27
27
  const HTML_FORM_PARTS = /^(?:button|fieldset|opt(?:group|ion))$/;
28
28
  const HTML_INTERACT = /^d(?:etails|ialog)$/;
29
- const INPUT_PLACEHOLDER = /^(?:(?:emai|te|ur)l|number|password|search|text)$/;
30
29
  const INPUT_RANGE = /(?:(?:rang|tim)e|date(?:time-local)?|month|number|week)$/;
30
+ const INPUT_TEXT = /^(?:(?:emai|te|ur)l|password|search|text)$/;
31
31
  const PSEUDO_FUNC = /^(?:(?:ha|i)s|not|where)$/;
32
32
  const PSEUDO_NTH = /^nth-(?:last-)?(?:child|of-type)$/;
33
33
  const WHITESPACE = /^[\n\r\f]/;
@@ -1158,7 +1158,7 @@ const matchPseudoClassSelector = (
1158
1158
  if (HTML_FORM_INPUT.test(localName) ||
1159
1159
  HTML_FORM_PARTS.test(localName) ||
1160
1160
  isCustomElementName(localName)) {
1161
- if (node.hasAttribute('disabled')) {
1161
+ if (node.disabled || node.hasAttribute('disabled')) {
1162
1162
  matched.push(node);
1163
1163
  } else {
1164
1164
  let parent = parentNode;
@@ -1180,16 +1180,34 @@ const matchPseudoClassSelector = (
1180
1180
  if ((HTML_FORM_INPUT.test(localName) ||
1181
1181
  HTML_FORM_PARTS.test(localName) ||
1182
1182
  isCustomElementName(localName)) &&
1183
- !node.hasAttribute('disabled')) {
1183
+ !(node.disabled && node.hasAttribute('disabled'))) {
1184
1184
  matched.push(node);
1185
1185
  }
1186
1186
  break;
1187
1187
  }
1188
1188
  case 'read-only': {
1189
1189
  if (/^(?:input|textarea)$/.test(localName)) {
1190
- if (node.readonly || node.hasAttribute('readonly') ||
1191
- node.disabled || node.hasAttribute('disabled')) {
1192
- matched.push(node);
1190
+ let targetNode;
1191
+ if (localName === 'input') {
1192
+ if (node.hasAttribute('type')) {
1193
+ const inputType = node.getAttribute('type');
1194
+ if (INPUT_TEXT.test(inputType)) {
1195
+ targetNode = node;
1196
+ } else if (INPUT_RANGE.test(inputType) &&
1197
+ inputType !== 'range') {
1198
+ targetNode = node;
1199
+ }
1200
+ } else {
1201
+ targetNode = node;
1202
+ }
1203
+ } else if (localName === 'textarea') {
1204
+ targetNode = node;
1205
+ }
1206
+ if (targetNode) {
1207
+ if (node.readonly || node.hasAttribute('readonly') ||
1208
+ node.disabled || node.hasAttribute('disabled')) {
1209
+ matched.push(node);
1210
+ }
1193
1211
  }
1194
1212
  } else if (!isContentEditable(node)) {
1195
1213
  matched.push(node);
@@ -1198,9 +1216,27 @@ const matchPseudoClassSelector = (
1198
1216
  }
1199
1217
  case 'read-write': {
1200
1218
  if (/^(?:input|textarea)$/.test(localName)) {
1201
- if (!(node.readonly || node.hasAttribute('readonly') ||
1202
- node.disabled || node.hasAttribute('disabled'))) {
1203
- matched.push(node);
1219
+ let targetNode;
1220
+ if (localName === 'input') {
1221
+ if (node.hasAttribute('type')) {
1222
+ const inputType = node.getAttribute('type');
1223
+ if (INPUT_TEXT.test(inputType)) {
1224
+ targetNode = node;
1225
+ } else if (INPUT_RANGE.test(inputType) &&
1226
+ inputType !== 'range') {
1227
+ targetNode = node;
1228
+ }
1229
+ } else {
1230
+ targetNode = node;
1231
+ }
1232
+ } else if (localName === 'textarea') {
1233
+ targetNode = node;
1234
+ }
1235
+ if (targetNode) {
1236
+ if (!(node.readonly || node.hasAttribute('readonly') ||
1237
+ node.disabled || node.hasAttribute('disabled'))) {
1238
+ matched.push(node);
1239
+ }
1204
1240
  }
1205
1241
  } else if (isContentEditable(node)) {
1206
1242
  matched.push(node);
@@ -1208,11 +1244,20 @@ const matchPseudoClassSelector = (
1208
1244
  break;
1209
1245
  }
1210
1246
  case 'placeholder-shown': {
1211
- if (((localName === 'input' &&
1212
- (!node.hasAttribute('type') ||
1213
- INPUT_PLACEHOLDER.test(node.getAttribute('type')))) ||
1214
- localName === 'textarea') &&
1215
- node.hasAttribute('placeholder') &&
1247
+ let targetNode;
1248
+ if (localName === 'input') {
1249
+ if (node.hasAttribute('type')) {
1250
+ if (INPUT_TEXT.test(node.getAttribute('type')) ||
1251
+ node.getAttribute('type') === 'number') {
1252
+ targetNode = node;
1253
+ }
1254
+ } else {
1255
+ targetNode = node;
1256
+ }
1257
+ } else if (localName === 'textarea') {
1258
+ targetNode = node;
1259
+ }
1260
+ if (targetNode && node.hasAttribute('placeholder') &&
1216
1261
  node.getAttribute('placeholder').trim().length &&
1217
1262
  node.value === '') {
1218
1263
  matched.push(node);
@@ -1395,13 +1440,49 @@ const matchPseudoClassSelector = (
1395
1440
  break;
1396
1441
  }
1397
1442
  case 'required': {
1398
- if (HTML_FORM_INPUT.test(localName) && node.required) {
1443
+ let targetNode;
1444
+ if (localName === 'input') {
1445
+ if (node.hasAttribute('type')) {
1446
+ const inputType = node.getAttribute('type');
1447
+ if (INPUT_TEXT.test(inputType)) {
1448
+ targetNode = node;
1449
+ } else if (INPUT_RANGE.test(inputType) && inputType !== 'range') {
1450
+ targetNode = node;
1451
+ } else if (inputType === 'checkbox' || inputType === 'radio' ||
1452
+ inputType === 'file') {
1453
+ targetNode = node;
1454
+ }
1455
+ } else {
1456
+ targetNode = node;
1457
+ }
1458
+ } else if (/^(?:select|textarea)$/.test(localName)) {
1459
+ targetNode = node;
1460
+ }
1461
+ if (targetNode && (node.required || node.hasAttribute('required'))) {
1399
1462
  matched.push(node);
1400
1463
  }
1401
1464
  break;
1402
1465
  }
1403
1466
  case 'optional': {
1404
- if (HTML_FORM_INPUT.test(localName) && !node.required) {
1467
+ let targetNode;
1468
+ if (localName === 'input') {
1469
+ if (node.hasAttribute('type')) {
1470
+ const inputType = node.getAttribute('type');
1471
+ if (INPUT_TEXT.test(inputType)) {
1472
+ targetNode = node;
1473
+ } else if (INPUT_RANGE.test(inputType) && inputType !== 'range') {
1474
+ targetNode = node;
1475
+ } else if (inputType === 'checkbox' || inputType === 'radio' ||
1476
+ inputType === 'file') {
1477
+ targetNode = node;
1478
+ }
1479
+ } else {
1480
+ targetNode = node;
1481
+ }
1482
+ } else if (/^(?:select|textarea)$/.test(localName)) {
1483
+ targetNode = node;
1484
+ }
1485
+ if (targetNode && !(node.required || node.hasAttribute('required'))) {
1405
1486
  matched.push(node);
1406
1487
  }
1407
1488
  break;