@asamuzakjp/dom-selector 0.15.5 → 0.15.7
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/package.json +1 -1
- package/src/js/matcher.js +41 -45
- package/src/js/parser.js +2 -0
package/package.json
CHANGED
package/src/js/matcher.js
CHANGED
|
@@ -73,14 +73,16 @@ const isNamespaceDeclared = (ns = '', node = {}) => {
|
|
|
73
73
|
if (ns && typeof ns === 'string' && node.nodeType === ELEMENT_NODE) {
|
|
74
74
|
const attr = `xmlns:${ns}`;
|
|
75
75
|
const root = node.ownerDocument.documentElement;
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
let parent = node;
|
|
77
|
+
while (parent) {
|
|
78
|
+
if (typeof parent.hasAttribute === 'function' &&
|
|
79
|
+
parent.hasAttribute(attr)) {
|
|
78
80
|
res = true;
|
|
79
81
|
break;
|
|
80
|
-
} else if (
|
|
82
|
+
} else if (parent === root) {
|
|
81
83
|
break;
|
|
82
84
|
}
|
|
83
|
-
|
|
85
|
+
parent = parent.parentNode;
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
return !!res;
|
|
@@ -600,54 +602,56 @@ const matchAttributeSelector = (ast = {}, node = {}) => {
|
|
|
600
602
|
flags: astFlags, matcher: astMatcher, name: astName, type: astType,
|
|
601
603
|
value: astValue
|
|
602
604
|
} = ast;
|
|
603
|
-
|
|
605
|
+
if (typeof astFlags === 'string' && !/^[is]$/i.test(astFlags)) {
|
|
606
|
+
throw new DOMException('invalid attribute selector', 'SyntaxError');
|
|
607
|
+
}
|
|
608
|
+
const { attributes, nodeType, ownerDocument } = node;
|
|
604
609
|
let res;
|
|
605
610
|
if (astType === ATTRIBUTE_SELECTOR && nodeType === ELEMENT_NODE &&
|
|
606
611
|
attributes?.length) {
|
|
607
|
-
if (typeof astFlags === 'string' && !/^[is]$/i.test(astFlags)) {
|
|
608
|
-
throw new DOMException('invalid attribute selector', 'SyntaxError');
|
|
609
|
-
}
|
|
610
|
-
const caseInsensitive =
|
|
611
|
-
!(typeof astFlags === 'string' && /^s$/i.test(astFlags));
|
|
612
|
-
const attrValues = [];
|
|
613
|
-
const l = attributes.length;
|
|
614
612
|
let { name: astAttrName } = astName;
|
|
615
613
|
astAttrName = unescapeSelector(astAttrName);
|
|
614
|
+
let caseInsensitive;
|
|
615
|
+
if (ownerDocument?.contentType === 'text/html') {
|
|
616
|
+
if (typeof astFlags === 'string' && /^s$/i.test(astFlags)) {
|
|
617
|
+
caseInsensitive = false;
|
|
618
|
+
} else {
|
|
619
|
+
caseInsensitive = true;
|
|
620
|
+
}
|
|
621
|
+
} else if (typeof astFlags === 'string' && /^i$/i.test(astFlags)) {
|
|
622
|
+
caseInsensitive = true;
|
|
623
|
+
} else {
|
|
624
|
+
caseInsensitive = false;
|
|
625
|
+
}
|
|
616
626
|
if (caseInsensitive) {
|
|
617
627
|
astAttrName = astAttrName.toLowerCase();
|
|
618
628
|
}
|
|
629
|
+
const l = attributes.length;
|
|
630
|
+
const attrValues = [];
|
|
619
631
|
// namespaced
|
|
620
632
|
if (/\|/.test(astAttrName)) {
|
|
621
633
|
const [astAttrPrefix, astAttrLocalName] = astAttrName.split('|');
|
|
622
634
|
let i = 0;
|
|
623
635
|
while (i < l) {
|
|
624
|
-
|
|
636
|
+
let { name: itemName, value: itemValue } = attributes.item(i);
|
|
637
|
+
if (caseInsensitive) {
|
|
638
|
+
itemName = itemName.toLowerCase();
|
|
639
|
+
itemValue = itemValue.toLowerCase();
|
|
640
|
+
}
|
|
625
641
|
switch (astAttrPrefix) {
|
|
626
642
|
case '': {
|
|
627
643
|
if (astAttrLocalName === itemName) {
|
|
628
|
-
|
|
629
|
-
attrValues.push(itemValue.toLowerCase());
|
|
630
|
-
} else {
|
|
631
|
-
attrValues.push(itemValue);
|
|
632
|
-
}
|
|
644
|
+
attrValues.push(itemValue);
|
|
633
645
|
}
|
|
634
646
|
break;
|
|
635
647
|
}
|
|
636
648
|
case '*': {
|
|
637
649
|
if (/:/.test(itemName)) {
|
|
638
650
|
if (itemName.endsWith(`:${astAttrLocalName}`)) {
|
|
639
|
-
if (caseInsensitive) {
|
|
640
|
-
attrValues.push(itemValue.toLowerCase());
|
|
641
|
-
} else {
|
|
642
|
-
attrValues.push(itemValue);
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
} else if (astAttrLocalName === itemName) {
|
|
646
|
-
if (caseInsensitive) {
|
|
647
|
-
attrValues.push(itemValue.toLowerCase());
|
|
648
|
-
} else {
|
|
649
651
|
attrValues.push(itemValue);
|
|
650
652
|
}
|
|
653
|
+
} else if (astAttrLocalName === itemName) {
|
|
654
|
+
attrValues.push(itemValue);
|
|
651
655
|
}
|
|
652
656
|
break;
|
|
653
657
|
}
|
|
@@ -656,11 +660,7 @@ const matchAttributeSelector = (ast = {}, node = {}) => {
|
|
|
656
660
|
const [itemNamePrefix, itemNameLocalName] = itemName.split(':');
|
|
657
661
|
if (astAttrPrefix === itemNamePrefix &&
|
|
658
662
|
astAttrLocalName === itemNameLocalName) {
|
|
659
|
-
|
|
660
|
-
attrValues.push(itemValue.toLowerCase());
|
|
661
|
-
} else {
|
|
662
|
-
attrValues.push(itemValue);
|
|
663
|
-
}
|
|
663
|
+
attrValues.push(itemValue);
|
|
664
664
|
}
|
|
665
665
|
}
|
|
666
666
|
}
|
|
@@ -670,22 +670,18 @@ const matchAttributeSelector = (ast = {}, node = {}) => {
|
|
|
670
670
|
} else {
|
|
671
671
|
let i = 0;
|
|
672
672
|
while (i < l) {
|
|
673
|
-
|
|
673
|
+
let { name: itemName, value: itemValue } = attributes.item(i);
|
|
674
|
+
if (caseInsensitive) {
|
|
675
|
+
itemName = itemName.toLowerCase();
|
|
676
|
+
itemValue = itemValue.toLowerCase();
|
|
677
|
+
}
|
|
674
678
|
if (/:/.test(itemName)) {
|
|
675
679
|
const [, itemNameLocalName] = itemName.split(':');
|
|
676
680
|
if (astAttrName === itemNameLocalName) {
|
|
677
|
-
if (caseInsensitive) {
|
|
678
|
-
attrValues.push(itemValue.toLowerCase());
|
|
679
|
-
} else {
|
|
680
|
-
attrValues.push(itemValue);
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
} else if (astAttrName === itemName) {
|
|
684
|
-
if (caseInsensitive) {
|
|
685
|
-
attrValues.push(itemValue.toLowerCase());
|
|
686
|
-
} else {
|
|
687
681
|
attrValues.push(itemValue);
|
|
688
682
|
}
|
|
683
|
+
} else if (astAttrName === itemName) {
|
|
684
|
+
attrValues.push(itemValue);
|
|
689
685
|
}
|
|
690
686
|
i++;
|
|
691
687
|
}
|
|
@@ -722,7 +718,7 @@ const matchAttributeSelector = (ast = {}, node = {}) => {
|
|
|
722
718
|
break;
|
|
723
719
|
}
|
|
724
720
|
case '~=': {
|
|
725
|
-
if (typeof attrValue === 'string') {
|
|
721
|
+
if (attrValue && typeof attrValue === 'string') {
|
|
726
722
|
for (const item of attrValues) {
|
|
727
723
|
const arr = item.split(/\s+/);
|
|
728
724
|
if (arr.includes(attrValue)) {
|
package/src/js/parser.js
CHANGED
|
@@ -82,6 +82,8 @@ const parseSelector = selector => {
|
|
|
82
82
|
} catch (e) {
|
|
83
83
|
if (e.message === '"]" is expected' && !selector.endsWith(']')) {
|
|
84
84
|
res = parseSelector(`${selector}]`);
|
|
85
|
+
} else if (e.message === '")" is expected' && !selector.endsWith(')')) {
|
|
86
|
+
res = parseSelector(`${selector})`);
|
|
85
87
|
} else {
|
|
86
88
|
throw new DOMException(e.message, 'SyntaxError');
|
|
87
89
|
}
|