mirror of
https://github.com/servo/servo.git
synced 2025-09-27 07:10:19 +01:00
Invalidate iterator over elements of a XPathResult when the document changes (#39411)
Also includes a fix to not throw a type error in `XPathResult.invalidIteratorState`. Testing: Includes a new web platform test Part of https://github.com/servo/servo/issues/34527 --------- Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
parent
9d7b438d6b
commit
2ccaf86ff6
4 changed files with 162 additions and 39 deletions
7
tests/wpt/meta/MANIFEST.json
vendored
7
tests/wpt/meta/MANIFEST.json
vendored
|
@ -643317,6 +643317,13 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"result-iterateNext.html": [
|
||||
"8c17f7ebc1c4292a0d8eb32b3d3503ca1e693eb9",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
]
|
||||
],
|
||||
"text-html-attributes.html": [
|
||||
"2157dcd2d68c5701b47ba907f7b1c3b2176f9239",
|
||||
[
|
||||
|
|
100
tests/wpt/tests/domxpath/result-iterateNext.html
vendored
Normal file
100
tests/wpt/tests/domxpath/result-iterateNext.html
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Invalidation of iterators over XPath results</title>
|
||||
<link rel="author" title="Simon Wülker" href="mailto:simon.wuelker@arcor.de">
|
||||
<link rel="help" href="https://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathResult-iterateNext">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<ul id="list">
|
||||
<li id="first-child"></li>
|
||||
<li id="second-child"></li>
|
||||
</ul>
|
||||
<script>
|
||||
function make_xpath_query(result_type) {
|
||||
return document.evaluate(
|
||||
"//li",
|
||||
document,
|
||||
null,
|
||||
result_type,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
function invalidate_iterator(test) {
|
||||
let new_element = document.createElement("li");
|
||||
document.getElementById("list").appendChild(new_element);
|
||||
test.add_cleanup(() => {
|
||||
new_element.remove();
|
||||
})
|
||||
}
|
||||
|
||||
test((t) => {
|
||||
let iterator = make_xpath_query(XPathResult.ORDERED_NODE_ITERATOR_TYPE);
|
||||
|
||||
assert_equals(iterator.iterateNext(), document.getElementById("first-child"));
|
||||
assert_equals(iterator.iterateNext(), document.getElementById("second-child"));
|
||||
assert_equals(iterator.iterateNext(), null);
|
||||
assert_false(iterator.invalidIteratorState);
|
||||
}, "Using an ordered iterator without modifying the dom should yield the expected elements in correct order without errors.");
|
||||
|
||||
test((t) => {
|
||||
let iterator = make_xpath_query(XPathResult.UNORDERED_NODE_ITERATOR_TYPE);
|
||||
|
||||
assert_not_equals(iterator.iterateNext(), null);
|
||||
assert_not_equals(iterator.iterateNext(), null);
|
||||
assert_equals(iterator.iterateNext(), null);
|
||||
assert_false(iterator.invalidIteratorState);
|
||||
}, "Using an unordered iterator without modifying the dom should yield the correct number of elements without errors.");
|
||||
|
||||
test((t) => {
|
||||
let non_iterator_query = make_xpath_query(XPathResult.BOOLEAN_TYPE);
|
||||
|
||||
assert_false(non_iterator_query.invalidIteratorState);
|
||||
invalidate_iterator(t);
|
||||
assert_false(non_iterator_query.invalidIteratorState);
|
||||
}, "invalidIteratorState should be false for non-iterable results.");
|
||||
|
||||
test((t) => {
|
||||
let non_iterator_query = make_xpath_query(XPathResult.BOOLEAN_TYPE);
|
||||
|
||||
assert_throws_js(TypeError, () => non_iterator_query.iterateNext());
|
||||
}, "Calling iterateNext on a non-iterable XPathResult should throw a TypeError.");
|
||||
|
||||
test((t) => {
|
||||
let non_iterator_query = make_xpath_query(XPathResult.BOOLEAN_TYPE);
|
||||
invalidate_iterator(t);
|
||||
assert_throws_js(TypeError, () => non_iterator_query.iterateNext());
|
||||
}, "Calling iterateNext on a non-iterable XPathResult after modifying the DOM should throw a TypeError.");
|
||||
|
||||
test((t) => {
|
||||
let iterator = make_xpath_query(XPathResult.ORDERED_NODE_ITERATOR_TYPE);
|
||||
|
||||
iterator.iterateNext();
|
||||
|
||||
invalidate_iterator(t);
|
||||
|
||||
assert_throws_dom(
|
||||
"InvalidStateError",
|
||||
() => iterator.iterateNext(),
|
||||
);
|
||||
}, "Calling iterateNext after having modified the DOM should throw an exception.");
|
||||
|
||||
test((t) => {
|
||||
let iterator = make_xpath_query(XPathResult.ORDERED_NODE_ITERATOR_TYPE);
|
||||
|
||||
iterator.iterateNext();
|
||||
iterator.iterateNext();
|
||||
|
||||
invalidate_iterator(t);
|
||||
|
||||
assert_throws_dom(
|
||||
"InvalidStateError",
|
||||
() => iterator.iterateNext(),
|
||||
);
|
||||
}, "Calling iterateNext after having modified the DOM should throw an exception even if the iterator is exhausted.");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue