8000 xpath: Let the parents of attribute nodes be their owner elements by simonwuelker · Pull Request #39749 · servo/servo · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions components/script/dom/attr.rs
10BC0
Original file line number Diff line numberDiff line change
Expand Up @@ -97,13 +97,13 @@ impl Attr {
}

impl AttrMethods<crate::DomTypeHolder> for Attr {
// https://dom.spec.whatwg.org/#dom-attr-localname
/// <https://dom.spec.whatwg.org/#dom-attr-localname>
fn LocalName(&self) -> DOMString {
// FIXME(ajeffrey): convert directly from LocalName to DOMString
DOMString::from(&**self.local_name())
}

// https://dom.spec.whatwg.org/#dom-attr-value
/// <https://dom.spec.whatwg.org/#dom-attr-value>
fn Value(&self) -> DOMString {
// FIXME(ajeffrey): convert directly from AttrValue to DOMString
DOMString::from(&**self.value())
Expand Down Expand Up @@ -146,32 +146,32 @@ impl AttrMethods<crate::DomTypeHolder> for Attr {
Ok(())
}

// https://dom.spec.whatwg.org/#dom-attr-name
/// <https://dom.spec.whatwg.org/#dom-attr-name>
fn Name(&self) -> DOMString {
// FIXME(ajeffrey): convert directly from LocalName to DOMString
DOMString::from(&**self.name())
}

// https://dom.spec.whatwg.org/#dom-attr-namespaceuri
/// <https://dom.spec.whatwg.org/#dom-attr-namespaceuri>
fn GetNamespaceURI(&self) -> Option<DOMString> {
match *self.namespace() {
ns!() => None,
ref url => Some(DOMString::from(&**url)),
}
}

// https://dom.spec.whatwg.org/#dom-attr-prefix
/// <https://dom.spec.whatwg.org/#dom-attr-prefix>
fn GetPrefix(&self) -> Option<DOMString> {
// FIXME(ajeffrey): convert directly from LocalName to DOMString
self.prefix().map(|p| DOMString::from(&**p))
}

// https://dom.spec.whatwg.org/#dom-attr-ownerelement
/// <https://dom.spec.whatwg.org/#dom-attr-ownerelement>
fn GetOwnerElement(&self) -> Option<DomRoot<Element>> {
self.owner()
}

// https://dom.spec.whatwg.org/#dom-attr-specified
/// <https://dom.spec.whatwg.org/#dom-attr-specified>
fn Specified(&self) -> bool {
true // Always returns true
}
Expand Down
15 changes: 15 additions & 0 deletions components/script/xpath.rs
10BC0
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use std::rc::Rc;

use html5ever::{LocalName, Namespace, Prefix};
use script_bindings::callback::ExceptionHandling;
use script_bindings::codegen::GenericBindings::AttrBinding::AttrMethods;
use script_bindings::codegen::GenericBindings::NodeBinding::NodeMethods;
use script_bindings::root::Dom;
use script_bindings::script_runtime::CanGc;
Expand Down Expand Up @@ -68,6 +69,15 @@ impl xpath::Node for XPathWrapper<DomRoot<Node>> {
}

fn parent(&self) -> Option<Self> {
// The parent of an attribute node is its owner, see
// https://www.w3.org/TR/1999/REC-xpath-19991116/#attribute-nodes
if let Some(attribute) = self.0.downcast::<Attr>() {
return attribute
.GetOwnerElement()
.map(DomRoot::upcast)
.map(XPathWrapper);
}

self.0.GetParentNode().map(XPathWrapper)
}

Expand Down Expand Up @@ -204,6 +214,11 @@ impl xpath::Element for XPathWrapper<DomRoot<Element>> {
self.position += 1;
Some(attribute.as_rooted().into())
}

fn size_hint(&self) -> (usize, Option<usize>) {
let exact_length = self.attributes.len() - self.position;
(exact_length, Some(exact_length))
}
}

AttributeIterator {
Expand Down
7 changes: 7 additions & 0 deletions tests/wpt/meta/MANIFEST.json
Original file line number Diff line number Diff line change
Expand Up @@ -648688,6 +648688,13 @@
{}
]
],
"elements-are-parents-of-their-attributes.html": [
"63e6cfe4cc586c799a1b7f625407e64260e44b55",
[
null,
{}
]
],
"evaluator-constructor.html": [
"8350ceb4499d570c577f9aec674435b415b6672b",
[
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<title>Relationship between elements and their attributes</title>
<link rel="author" title="Simon Wülker" href="mailto:simon.wuelker@arcor.de">
<link rel="help" href="https://www.w3.org/TR/1999/REC-xpath-19991116/#attribute-nodes">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id="context" foo="bar"></div>
<script>
const context = document.getElementById("context");

test(() => {
const result = document.evaluate(
"@foo/parent::*",
context,
null,
XPathResult.ORDERED_NODE_ITERATOR_TYPE,
null
);

assert_equals(result.iterateNext(), context);
assert_equals(result.iterateNext(), null);
}, "Elements are parents of their attributes");

test(() => {
const result = document.evaluate(
"node()",
context,
null,
XPathResult.ORDERED_NODE_ITERATOR_TYPE,
null
);

assert_equals(result.iterateNext(), null);
}, "Attributes are not children of their parents");
</script>
</body>
</html>
Loading
0