@@ -6,9 +6,25 @@ import cache from '../base/cache';
6
6
7
7
const CACHE_KEY = 'DqElm.RunOptions' ;
8
8
9
+ /**
10
+ * Escapes a string for use in CSS selectors
11
+ * @param {String } str - The string to escape
12
+ * @returns {String } The escaped string
13
+ */
14
+ function escapeCSSSelector ( str ) {
15
+ // Use the CSS.escape method if available
16
+ if ( window . CSS && window . CSS . escape ) {
17
+ return window . CSS . escape ( str ) ;
18
+ }
19
+ // Simple fallback for browsers that don't support CSS.escape
20
+ return str
21
+ . replace ( / [ ! " # $ % & ' ( ) * + , . / : ; < = > ? @ [ \\ \] ^ ` { | } ~ ] / g, '\\$&' )
22
+ . replace ( / ^ \d / , '\\3$& ' ) ;
23
+ }
24
+
9
25
function getFullPathSelector ( elm ) {
10
- if ( elm . nodeName === 'BODY' ) {
11
- return 'BODY' ;
26
+ if ( elm . nodeName === 'HTML' || elm . nodeName === ' BODY') {
27
+ return elm . nodeName . toLowerCase ( ) ;
12
28
}
13
29
14
30
if ( cache . get ( 'getFullPathSelector' ) === undefined ) {
@@ -28,15 +44,29 @@ function getFullPathSelector(elm) {
28
44
names . unshift ( sourceCache . get ( elm ) ) ;
29
45
break ;
30
46
} else if ( elm . id ) {
31
- names . unshift ( '#' + elm . getAttribute ( 'id' ) ) ;
32
- break ;
47
+ // Check if the ID is unique in the document before using it
48
+ const escapedId = escapeCSSSelector ( elm . getAttribute ( 'id' ) ) ;
49
+ const elementsWithSameId = document . querySelectorAll ( `#${ escapedId } ` ) ;
50
+ if ( elementsWithSameId . length === 1 ) {
51
+ // ID is unique, safe to use
52
+ names . unshift ( '#' + escapedId ) ;
53
+ break ;
54
+ } else {
55
+ // ID is not unique, fallback to position-based selector
56
+ let c = 1 ;
57
+ let e = elm ;
58
+ for ( ; e . previousElementSibling ; e = e . previousElementSibling , c ++ ) {
59
+ // Increment counter for each previous sibling
60
+ }
61
+ names . unshift ( `${ elm . nodeName . toLowerCase ( ) } :nth-child(${ c } )` ) ;
62
+ }
33
63
} else {
34
- let c = 1 ,
35
- e = elm ;
64
+ let c = 1 ;
65
+ let e = elm ;
36
66
for ( ; e . previousElementSibling ; e = e . previousElementSibling , c ++ ) {
37
67
// Increment counter for each previous sibling
38
68
}
39
- names . unshift ( elm . nodeName + ' :nth-child(' + c + ')' ) ;
69
+ names . unshift ( ` ${ elm . nodeName . toLowerCase ( ) } :nth-child(${ c } )` ) ;
40
70
}
41
71
elm = elm . parentElement ;
42
72
}
0 commit comments