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.
* 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
();
const
nodeName
=
node
.
nodeName
.
toLowerCase
();
let
result
=
nodeName
;
return
nodeName
===
'#text'
?
'text()'
:
nodeName
;
if
(
nodeName
===
'#text'
)
{
result
=
'text()'
;
}
return
result
;
}
}
/**
/**
* Get the index of the node as it appears in its parent's child list
* 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
;
let
pos
=
0
;
/** @type {Node|null} */
let
tmp
:
Node
|
null
=
node
;
let
tmp
=
node
;
while
(
tmp
)
{
while
(
tmp
)
{
if
(
tmp
.
nodeName
===
node
.
nodeName
)
{
if
(
tmp
.
nodeName
===
node
.
nodeName
)
{
pos
+=
1
;
pos
+=
1
;
...
@@ -30,8 +21,7 @@ function getNodePosition(node) {
...
@@ -30,8 +21,7 @@ function getNodePosition(node) {
return
pos
;
return
pos
;
}
}
/** @param {Node} node */
function
getPathSegment
(
node
:
Node
):
string
{
function
getPathSegment
(
node
)
{
const
name
=
getNodeName
(
node
);
const
name
=
getNodeName
(
node
);
const
pos
=
getNodePosition
(
node
);
const
pos
=
getNodePosition
(
node
);
return
`
${
name
}
[
${
pos
}
]`
;
return
`
${
name
}
[
${
pos
}
]`
;
...
@@ -41,14 +31,13 @@ function getPathSegment(node) {
...
@@ -41,14 +31,13 @@ function getPathSegment(node) {
* A simple XPath generator which can generate XPaths of the form
* A simple XPath generator which can generate XPaths of the form
* /tag[index]/tag[index].
* /tag[index]/tag[index].
*
*
* @param
{Node}
node - The node to generate a path to
* @param node - The node to generate a path to
* @param
{Node}
root - Root node to which the returned path is relative
* @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
=
''
;
let
xpath
=
''
;
/** @type {Node|null} */
let
elem
:
Node
|
null
=
node
;
let
elem
=
node
;
while
(
elem
!==
root
)
{
while
(
elem
!==
root
)
{
if
(
!
elem
)
{
if
(
!
elem
)
{
throw
new
Error
(
'Node is not a descendant of root'
);
throw
new
Error
(
'Node is not a descendant of root'
);
...
@@ -65,12 +54,12 @@ export function xpathFromNode(node, root) {
...
@@ -65,12 +54,12 @@ export function xpathFromNode(node, root) {
/**
/**
* Return the `index`'th immediate child of `element` whose tag name is
* Return the `index`'th immediate child of `element` whose tag name is
* `nodeName` (case insensitive).
* `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
();
nodeName
=
nodeName
.
toUpperCase
();
let
matchIndex
=
-
1
;
let
matchIndex
=
-
1
;
...
@@ -99,16 +88,12 @@ function nthChildOfType(element, nodeName, index) {
...
@@ -99,16 +88,12 @@ function nthChildOfType(element, nodeName, index) {
* - Is not affected by the document's _type_ (HTML or XML/XHTML)
* - Is not affected by the document's _type_ (HTML or XML/XHTML)
* - Ignores element namespaces when matching element names in the XPath against
* - Ignores element namespaces when matching element names in the XPath against
* elements in the DOM tree
* 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.
* The matching element is returned or `null` if no such element is found.
* An error is thrown if `xpath` is not a simple XPath.
* 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
=
const
isSimpleXPath
=
xpath
.
match
(
/^
(\/[
A-Za-z0-9-
]
+
(\[[
0-9
]
+
\])?)
+$/
)
!==
null
;
xpath
.
match
(
/^
(\/[
A-Za-z0-9-
]
+
(\[[
0-9
]
+
\])?)
+$/
)
!==
null
;
if
(
!
isSimpleXPath
)
{
if
(
!
isSimpleXPath
)
{
...
@@ -122,7 +107,7 @@ function evaluateSimpleXPath(xpath, root) {
...
@@ -122,7 +107,7 @@ function evaluateSimpleXPath(xpath, root) {
// has at least two segments, with the first being empty and the others non-empty.
// has at least two segments, with the first being empty and the others non-empty.
segments
.
shift
();
segments
.
shift
();
for
(
le
t
segment
of
segments
)
{
for
(
cons
t
segment
of
segments
)
{
let
elementName
;
let
elementName
;
let
elementIndex
;
let
elementIndex
;
...
@@ -156,12 +141,12 @@ function evaluateSimpleXPath(xpath, root) {
...
@@ -156,12 +141,12 @@ function evaluateSimpleXPath(xpath, root) {
*
*
* Example:
* Example:
* node = nodeFromXPath('/main/article[1]/p[3]', document.body)
* 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
{
try
{
return
evaluateSimpleXPath
(
xpath
,
root
);
return
evaluateSimpleXPath
(
xpath
,
root
);
}
catch
(
err
)
{
}
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