mirror of
https://github.com/servo/servo.git
synced 2025-08-02 12:10:29 +01:00
Refactor the locate a namespace algorithm
This commit is contained in:
parent
fb206e2b10
commit
0c64bd766a
5 changed files with 60 additions and 60 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -2110,6 +2110,11 @@ dependencies = [
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ref_filter_map"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ref_slice"
|
name = "ref_slice"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -2200,6 +2205,7 @@ dependencies = [
|
||||||
"profile_traits 0.0.1",
|
"profile_traits 0.0.1",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"range 0.0.1",
|
"range 0.0.1",
|
||||||
|
"ref_filter_map 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ref_slice 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ref_slice 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -3356,6 +3362,7 @@ dependencies = [
|
||||||
"checksum quote 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1e0c9bc6bfb0a60d539aab6e338207c1a5456e62f5bd5375132cee119aa4b3"
|
"checksum quote 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1e0c9bc6bfb0a60d539aab6e338207c1a5456e62f5bd5375132cee119aa4b3"
|
||||||
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
||||||
"checksum rayon 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b6a6e05e0e6b703e9f2ad266eb63f3712e693a17a2702b95a23de14ce8defa9"
|
"checksum rayon 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b6a6e05e0e6b703e9f2ad266eb63f3712e693a17a2702b95a23de14ce8defa9"
|
||||||
|
"checksum ref_filter_map 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b5ceb840e4009da4841ed22a15eb49f64fdd00a2138945c5beacf506b2fb5ed"
|
||||||
"checksum ref_slice 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "546bb4aa91c85f232732cc5b3c8097ea97ae9a77304f9ab4df8b203ff7672dad"
|
"checksum ref_slice 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "546bb4aa91c85f232732cc5b3c8097ea97ae9a77304f9ab4df8b203ff7672dad"
|
||||||
"checksum regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)" = "63b49f873f36ddc838d773972511e5fed2ef7350885af07d58e2f48ce8073dcd"
|
"checksum regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)" = "63b49f873f36ddc838d773972511e5fed2ef7350885af07d58e2f48ce8073dcd"
|
||||||
"checksum regex-syntax 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279401017ae31cf4e15344aa3f085d0e2e5c1e70067289ef906906fdbe92c8fd"
|
"checksum regex-syntax 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279401017ae31cf4e15344aa3f085d0e2e5c1e70067289ef906906fdbe92c8fd"
|
||||||
|
|
|
@ -61,6 +61,7 @@ plugins = {path = "../plugins"}
|
||||||
profile_traits = {path = "../profile_traits"}
|
profile_traits = {path = "../profile_traits"}
|
||||||
rand = "0.3"
|
rand = "0.3"
|
||||||
range = {path = "../range"}
|
range = {path = "../range"}
|
||||||
|
ref_filter_map = "1.0.1"
|
||||||
ref_slice = "1.0"
|
ref_slice = "1.0"
|
||||||
regex = "0.1.43"
|
regex = "0.1.43"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
|
|
|
@ -73,6 +73,7 @@ use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
|
||||||
use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks};
|
use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks};
|
||||||
use html5ever_atoms::{Prefix, LocalName, Namespace, QualName};
|
use html5ever_atoms::{Prefix, LocalName, Namespace, QualName};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
use ref_filter_map::ref_filter_map;
|
||||||
use selectors::matching::{ElementFlags, MatchingReason, matches};
|
use selectors::matching::{ElementFlags, MatchingReason, matches};
|
||||||
use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
|
use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
|
||||||
use selectors::parser::{AttrSelector, NamespaceConstraint};
|
use selectors::parser::{AttrSelector, NamespaceConstraint};
|
||||||
|
@ -722,6 +723,46 @@ impl Element {
|
||||||
Ref::map(self.attrs.borrow(), |attrs| &**attrs)
|
Ref::map(self.attrs.borrow(), |attrs| &**attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Element branch of https://dom.spec.whatwg.org/#locate-a-namespace
|
||||||
|
pub fn locate_namespace(&self, prefix: Option<DOMString>) -> Namespace {
|
||||||
|
let prefix = prefix.map(String::from).map(LocalName::from);
|
||||||
|
|
||||||
|
let inclusive_ancestor_elements =
|
||||||
|
self.upcast::<Node>()
|
||||||
|
.inclusive_ancestors()
|
||||||
|
.filter_map(Root::downcast::<Self>);
|
||||||
|
|
||||||
|
// Steps 3-4.
|
||||||
|
for element in inclusive_ancestor_elements {
|
||||||
|
// Step 1.
|
||||||
|
if element.namespace() != &ns!() && element.prefix().map(|p| &**p) == prefix.as_ref().map(|p| &**p) {
|
||||||
|
return element.namespace().clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2.
|
||||||
|
let attr = ref_filter_map(self.attrs(), |attrs| {
|
||||||
|
attrs.iter().find(|attr| {
|
||||||
|
if attr.namespace() != &ns!(xmlns) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
match (attr.prefix(), prefix.as_ref()) {
|
||||||
|
(Some(&namespace_prefix!("xmlns")), Some(prefix)) => {
|
||||||
|
attr.local_name() == prefix
|
||||||
|
},
|
||||||
|
(None, None) => attr.local_name() == &local_name!("xmlns"),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(attr) = attr {
|
||||||
|
return (**attr.value()).into();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ns!()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn style_attribute(&self) -> &DOMRefCell<Option<Arc<RwLock<PropertyDeclarationBlock>>>> {
|
pub fn style_attribute(&self) -> &DOMRefCell<Option<Arc<RwLock<PropertyDeclarationBlock>>>> {
|
||||||
&self.style_attribute
|
&self.style_attribute
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use devtools_traits::NodeInfo;
|
use devtools_traits::NodeInfo;
|
||||||
use document_loader::DocumentLoader;
|
use document_loader::DocumentLoader;
|
||||||
use dom::attr::Attr;
|
|
||||||
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
|
|
||||||
use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
|
use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
|
||||||
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
|
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
|
||||||
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
|
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
|
||||||
|
@ -60,7 +58,7 @@ use euclid::rect::Rect;
|
||||||
use euclid::size::Size2D;
|
use euclid::size::Size2D;
|
||||||
use heapsize::{HeapSizeOf, heap_size_of};
|
use heapsize::{HeapSizeOf, heap_size_of};
|
||||||
use html5ever::tree_builder::QuirksMode;
|
use html5ever::tree_builder::QuirksMode;
|
||||||
use html5ever_atoms::{Prefix, LocalName, Namespace, QualName};
|
use html5ever_atoms::{Prefix, Namespace, QualName};
|
||||||
use js::jsapi::{JSContext, JSObject, JSRuntime};
|
use js::jsapi::{JSContext, JSObject, JSRuntime};
|
||||||
use libc::{self, c_void, uintptr_t};
|
use libc::{self, c_void, uintptr_t};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
|
@ -1811,67 +1809,19 @@ impl Node {
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#locate-a-namespace
|
// https://dom.spec.whatwg.org/#locate-a-namespace
|
||||||
pub fn locate_namespace(node: &Node, prefix: Option<DOMString>) -> Namespace {
|
pub fn locate_namespace(node: &Node, prefix: Option<DOMString>) -> Namespace {
|
||||||
fn attr_defines_namespace(attr: &Attr,
|
|
||||||
defined_prefix: &Option<LocalName>) -> bool {
|
|
||||||
*attr.namespace() == ns!(xmlns) &&
|
|
||||||
match (attr.prefix(), defined_prefix) {
|
|
||||||
(Some(attr_prefix), &Some(ref defined_prefix)) =>
|
|
||||||
attr_prefix == &namespace_prefix!("xmlns") &&
|
|
||||||
attr.local_name() == defined_prefix,
|
|
||||||
(None, &None) => *attr.local_name() == local_name!("xmlns"),
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match node.type_id() {
|
match node.type_id() {
|
||||||
NodeTypeId::Element(_) => {
|
NodeTypeId::Element(_) => {
|
||||||
let element = node.downcast::<Element>().unwrap();
|
node.downcast::<Element>().unwrap().locate_namespace(prefix)
|
||||||
// Step 1.
|
|
||||||
if *element.namespace() != ns!() && element.prefix() == prefix.as_ref() {
|
|
||||||
return element.namespace().clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Even though this is conceptually a namespace prefix,
|
|
||||||
// in the `xmlns:foo="https://example.net/namespace" declaration
|
|
||||||
// it is a local name.
|
|
||||||
// FIXME(ajeffrey): directly convert DOMString to LocalName
|
|
||||||
let prefix_atom = prefix.as_ref().map(|s| LocalName::from(&**s));
|
|
||||||
|
|
||||||
// Step 2.
|
|
||||||
let attrs = element.attrs();
|
|
||||||
let namespace_attr = attrs.iter().find(|attr| {
|
|
||||||
attr_defines_namespace(attr, &prefix_atom)
|
|
||||||
});
|
|
||||||
|
|
||||||
// Steps 2.1-2.
|
|
||||||
if let Some(attr) = namespace_attr {
|
|
||||||
return namespace_from_domstring(Some(attr.Value()));
|
|
||||||
}
|
|
||||||
|
|
||||||
match node.GetParentElement() {
|
|
||||||
// Step 3.
|
|
||||||
None => ns!(),
|
|
||||||
// Step 4.
|
|
||||||
Some(parent) => Node::locate_namespace(parent.upcast(), prefix)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
NodeTypeId::Document(_) => {
|
NodeTypeId::Document(_) => {
|
||||||
match node.downcast::<Document>().unwrap().GetDocumentElement().r() {
|
node.downcast::<Document>().unwrap()
|
||||||
// Step 1.
|
.GetDocumentElement().as_ref()
|
||||||
None => ns!(),
|
.map_or(ns!(), |elem| elem.locate_namespace(prefix))
|
||||||
// Step 2.
|
|
||||||
Some(document_element) => {
|
|
||||||
Node::locate_namespace(document_element.upcast(), prefix)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
NodeTypeId::DocumentType => ns!(),
|
NodeTypeId::DocumentType | NodeTypeId::DocumentFragment => ns!(),
|
||||||
NodeTypeId::DocumentFragment => ns!(),
|
_ => {
|
||||||
_ => match node.GetParentElement() {
|
node.GetParentElement().as_ref()
|
||||||
// Step 1.
|
.map_or(ns!(), |elem| elem.locate_namespace(prefix))
|
||||||
None => ns!(),
|
|
||||||
// Step 2.
|
|
||||||
Some(parent) => Node::locate_namespace(parent.upcast(), prefix)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,7 @@ extern crate phf;
|
||||||
extern crate profile_traits;
|
extern crate profile_traits;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate range;
|
extern crate range;
|
||||||
|
extern crate ref_filter_map;
|
||||||
extern crate ref_slice;
|
extern crate ref_slice;
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue