Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
coopwire-hypothesis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙灵跃 Leon Sun
coopwire-hypothesis
Commits
5dfad22f
Commit
5dfad22f
authored
Apr 20, 2023
by
Alejandro Celaya
Committed by
Alejandro Celaya
Apr 20, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Migrate xpath module to TS
parent
5e58b586
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
22 additions
and
37 deletions
+22
-37
xpath.ts
src/annotator/anchoring/xpath.ts
+22
-37
No files found.
src/annotator/anchoring/xpath.
j
s
→
src/annotator/anchoring/xpath.
t
s
View file @
5dfad22f
/**
* Get the node name for use in generating an xpath expression.
*
* @param {Node} node
*/
function
getNodeName
(
node
)
{
function
getNodeName
(
node
:
Node
):
string
{
const
nodeName
=
node
.
nodeName
.
toLowerCase
();
let
result
=
nodeName
;
if
(
nodeName
===
'#text'
)
{
result
=
'text()'
;
}
return
result
;
return
nodeName
===
'#text'
?
'text()'
:
nodeName
;
}
/**
* Get the index of the node as it appears in its parent's child list
*
* @param {Node} node
*/
function
getNodePosition
(
node
)
{
function
getNodePosition
(
node
:
Node
):
number
{
let
pos
=
0
;
/** @type {Node|null} */
let
tmp
=
node
;
let
tmp
:
Node
|
null
=
node
;
while
(
tmp
)
{
if
(
tmp
.
nodeName
===
node
.
nodeName
)
{
pos
+=
1
;
...
...
@@ -30,8 +21,7 @@ function getNodePosition(node) {
return
pos
;
}
/** @param {Node} node */
function
getPathSegment
(
node
)
{
function
getPathSegment
(
node
:
Node
):
string
{
const
name
=
getNodeName
(
node
);
const
pos
=
getNodePosition
(
node
);
return
`
${
name
}
[
${
pos
}
]`
;
...
...
@@ -41,14 +31,13 @@ function getPathSegment(node) {
* A simple XPath generator which can generate XPaths of the form
* /tag[index]/tag[index].
*
* @param
{Node}
node - The node to generate a path to
* @param
{Node}
root - Root node to which the returned path is relative
* @param node - The node to generate a path to
* @param root - Root node to which the returned path is relative
*/
export
function
xpathFromNode
(
node
,
root
)
{
export
function
xpathFromNode
(
node
:
Node
,
root
:
Node
)
{
let
xpath
=
''
;
/** @type {Node|null} */
let
elem
=
node
;
let
elem
:
Node
|
null
=
node
;
while
(
elem
!==
root
)
{
if
(
!
elem
)
{
throw
new
Error
(
'Node is not a descendant of root'
);
...
...
@@ -65,12 +54,12 @@ export function xpathFromNode(node, root) {
/**
* Return the `index`'th immediate child of `element` whose tag name is
* `nodeName` (case insensitive).
*
* @param {Element} element
* @param {string} nodeName
* @param {number} index
*/
function
nthChildOfType
(
element
,
nodeName
,
index
)
{
function
nthChildOfType
(
element
:
Element
,
nodeName
:
string
,
index
:
number
):
Element
|
null
{
nodeName
=
nodeName
.
toUpperCase
();
let
matchIndex
=
-
1
;
...
...
@@ -99,16 +88,12 @@ function nthChildOfType(element, nodeName, index) {
* - Is not affected by the document's _type_ (HTML or XML/XHTML)
* - Ignores element namespaces when matching element names in the XPath against
* elements in the DOM tree
* - Is case
insensitive for all elements, not just HTML elements
* - Is case
-
insensitive for all elements, not just HTML elements
*
* The matching element is returned or `null` if no such element is found.
* An error is thrown if `xpath` is not a simple XPath.
*
* @param {string} xpath
* @param {Element} root
* @return {Element|null}
*/
function
evaluateSimpleXPath
(
xpath
,
root
)
{
function
evaluateSimpleXPath
(
xpath
:
string
,
root
:
Element
):
Element
|
null
{
const
isSimpleXPath
=
xpath
.
match
(
/^
(\/[
A-Za-z0-9-
]
+
(\[[
0-9
]
+
\])?)
+$/
)
!==
null
;
if
(
!
isSimpleXPath
)
{
...
...
@@ -122,7 +107,7 @@ function evaluateSimpleXPath(xpath, root) {
// has at least two segments, with the first being empty and the others non-empty.
segments
.
shift
();
for
(
le
t
segment
of
segments
)
{
for
(
cons
t
segment
of
segments
)
{
let
elementName
;
let
elementIndex
;
...
...
@@ -156,12 +141,12 @@ function evaluateSimpleXPath(xpath, root) {
*
* Example:
* node = nodeFromXPath('/main/article[1]/p[3]', document.body)
*
* @param {string} xpath
* @param {Element} [root]
* @return {Node|null}
*/
export
function
nodeFromXPath
(
xpath
,
root
=
document
.
body
)
{
export
function
nodeFromXPath
(
xpath
:
string
,
/* istanbul ignore next */
root
:
Element
=
document
.
body
):
Node
|
null
{
try
{
return
evaluateSimpleXPath
(
xpath
,
root
);
}
catch
(
err
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment