| 149 | * Mozilla-style XPath generation (more standardized approach) |
| 150 | */ |
| 151 | export function getElementInfo_Moz(element) { |
| 152 | if (element && element.id) { |
| 153 | return '//*[@id="' + element.id + '"]'; |
| 154 | } |
| 155 | |
| 156 | var paths = []; |
| 157 | for (; element && element.nodeType === Node.ELEMENT_NODE; element = element.parentNode) { |
| 158 | var index = 0; |
| 159 | var hasFollowingSiblings = false; |
| 160 | |
| 161 | for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) { |
| 162 | if (sibling.nodeType === Node.DOCUMENT_TYPE_NODE) continue; |
| 163 | if (sibling.nodeName === element.nodeName) ++index; |
| 164 | } |
| 165 | |
| 166 | for (var sibling = element.nextSibling; sibling && !hasFollowingSiblings; sibling = sibling.nextSibling) { |
| 167 | if (sibling.nodeName === element.nodeName) hasFollowingSiblings = true; |
| 168 | } |
| 169 | |
| 170 | var tagName = (element.prefix ? element.prefix + ":" : "") + element.localName; |
| 171 | var pathIndex = "[" + (index + 1) + "]"; |
| 172 | paths.splice(0, 0, tagName + pathIndex); |
| 173 | } |
| 174 | |
| 175 | return paths.length ? "/" + paths.join("/") : null; |
| 176 | } |
| 177 | |
| 178 | /** |
| 179 | * Validate XPath syntax and uniqueness |