mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Upgrade rust-selectors.
This commit is contained in:
parent
364c8e2976
commit
1d8d1cb9d9
19 changed files with 280 additions and 174 deletions
|
@ -31,7 +31,7 @@ range = {path = "../range"}
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
script_layout_interface = {path = "../script_layout_interface"}
|
script_layout_interface = {path = "../script_layout_interface"}
|
||||||
script_traits = {path = "../script_traits"}
|
script_traits = {path = "../script_traits"}
|
||||||
selectors = {version = "0.6", features = ["heap_size"]}
|
selectors = {version = "0.7", features = ["heap_size"]}
|
||||||
serde_macros = "0.7.11"
|
serde_macros = "0.7.11"
|
||||||
smallvec = "0.1"
|
smallvec = "0.1"
|
||||||
string_cache = {version = "0.2.20", features = ["heap_size"]}
|
string_cache = {version = "0.2.20", features = ["heap_size"]}
|
||||||
|
|
|
@ -28,7 +28,7 @@ pub struct RecalcStyleAndConstructFlows<'lc> {
|
||||||
|
|
||||||
impl<'lc, N> DomTraversalContext<N> for RecalcStyleAndConstructFlows<'lc>
|
impl<'lc, N> DomTraversalContext<N> for RecalcStyleAndConstructFlows<'lc>
|
||||||
where N: LayoutNode + TNode<ConcreteComputedValues=ServoComputedValues>,
|
where N: LayoutNode + TNode<ConcreteComputedValues=ServoComputedValues>,
|
||||||
N::ConcreteElement: ::selectors::Element<Impl=ServoSelectorImpl>
|
N::ConcreteElement: ::selectors::Element<Impl=ServoSelectorImpl, AttrString=String>
|
||||||
|
|
||||||
{
|
{
|
||||||
type SharedContext = SharedLayoutContext;
|
type SharedContext = SharedLayoutContext;
|
||||||
|
|
|
@ -57,7 +57,7 @@ regex = "0.1.43"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
script_layout_interface = {path = "../script_layout_interface"}
|
script_layout_interface = {path = "../script_layout_interface"}
|
||||||
script_traits = {path = "../script_traits"}
|
script_traits = {path = "../script_traits"}
|
||||||
selectors = {version = "0.6", features = ["heap_size"]}
|
selectors = {version = "0.7", features = ["heap_size"]}
|
||||||
serde = "0.7.11"
|
serde = "0.7.11"
|
||||||
smallvec = "0.1"
|
smallvec = "0.1"
|
||||||
string_cache = {version = "0.2.20", features = ["heap_size", "unstable"]}
|
string_cache = {version = "0.2.20", features = ["heap_size", "unstable"]}
|
||||||
|
|
|
@ -2217,6 +2217,34 @@ impl VirtualMethods for Element {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> ::selectors::MatchAttrGeneric for Root<Element> {
|
||||||
|
fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool
|
||||||
|
where F: Fn(&str) -> bool
|
||||||
|
{
|
||||||
|
use ::selectors::Element;
|
||||||
|
let local_name = {
|
||||||
|
if self.is_html_element_in_html_document() {
|
||||||
|
&attr.lower_name
|
||||||
|
} else {
|
||||||
|
&attr.name
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match attr.namespace {
|
||||||
|
NamespaceConstraint::Specific(ref ns) => {
|
||||||
|
self.get_attribute(ns, local_name)
|
||||||
|
.map_or(false, |attr| {
|
||||||
|
test(&attr.value())
|
||||||
|
})
|
||||||
|
},
|
||||||
|
NamespaceConstraint::Any => {
|
||||||
|
self.attrs.borrow().iter().any(|attr| {
|
||||||
|
attr.local_name() == local_name && test(&attr.value())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> ::selectors::Element for Root<Element> {
|
impl<'a> ::selectors::Element for Root<Element> {
|
||||||
type Impl = ServoSelectorImpl;
|
type Impl = ServoSelectorImpl;
|
||||||
|
|
||||||
|
@ -2317,31 +2345,6 @@ impl<'a> ::selectors::Element for Root<Element> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool
|
|
||||||
where F: Fn(&str) -> bool
|
|
||||||
{
|
|
||||||
let local_name = {
|
|
||||||
if self.is_html_element_in_html_document() {
|
|
||||||
&attr.lower_name
|
|
||||||
} else {
|
|
||||||
&attr.name
|
|
||||||
}
|
|
||||||
};
|
|
||||||
match attr.namespace {
|
|
||||||
NamespaceConstraint::Specific(ref ns) => {
|
|
||||||
self.get_attribute(ns, local_name)
|
|
||||||
.map_or(false, |attr| {
|
|
||||||
test(&attr.value())
|
|
||||||
})
|
|
||||||
},
|
|
||||||
NamespaceConstraint::Any => {
|
|
||||||
self.attrs.borrow().iter().any(|attr| {
|
|
||||||
attr.local_name() == local_name && test(&attr.value())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_html_element_in_html_document(&self) -> bool {
|
fn is_html_element_in_html_document(&self) -> bool {
|
||||||
self.html_element_in_html_document()
|
self.html_element_in_html_document()
|
||||||
}
|
}
|
||||||
|
|
|
@ -418,6 +418,28 @@ fn as_element<'le>(node: LayoutJS<Node>) -> Option<ServoLayoutElement<'le>> {
|
||||||
node.downcast().map(ServoLayoutElement::from_layout_js)
|
node.downcast().map(ServoLayoutElement::from_layout_js)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'le> ::selectors::MatchAttrGeneric for ServoLayoutElement<'le> {
|
||||||
|
fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool where F: Fn(&str) -> bool {
|
||||||
|
use ::selectors::Element;
|
||||||
|
let name = if self.is_html_element_in_html_document() {
|
||||||
|
&attr.lower_name
|
||||||
|
} else {
|
||||||
|
&attr.name
|
||||||
|
};
|
||||||
|
match attr.namespace {
|
||||||
|
NamespaceConstraint::Specific(ref ns) => {
|
||||||
|
self.get_attr(ns, name).map_or(false, |attr| test(attr))
|
||||||
|
},
|
||||||
|
NamespaceConstraint::Any => {
|
||||||
|
let attrs = unsafe {
|
||||||
|
(*self.element.unsafe_get()).get_attr_vals_for_layout(name)
|
||||||
|
};
|
||||||
|
attrs.iter().any(|attr| test(*attr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
|
impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
|
||||||
type Impl = ServoSelectorImpl;
|
type Impl = ServoSelectorImpl;
|
||||||
|
|
||||||
|
@ -553,25 +575,6 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool where F: Fn(&str) -> bool {
|
|
||||||
let name = if self.is_html_element_in_html_document() {
|
|
||||||
&attr.lower_name
|
|
||||||
} else {
|
|
||||||
&attr.name
|
|
||||||
};
|
|
||||||
match attr.namespace {
|
|
||||||
NamespaceConstraint::Specific(ref ns) => {
|
|
||||||
self.get_attr(ns, name).map_or(false, |attr| test(attr))
|
|
||||||
},
|
|
||||||
NamespaceConstraint::Any => {
|
|
||||||
let attrs = unsafe {
|
|
||||||
(*self.element.unsafe_get()).get_attr_vals_for_layout(name)
|
|
||||||
};
|
|
||||||
attrs.iter().any(|attr| test(*attr))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_html_element_in_html_document(&self) -> bool {
|
fn is_html_element_in_html_document(&self) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.element.html_element_in_html_document_for_layout()
|
self.element.html_element_in_html_document_for_layout()
|
||||||
|
@ -906,7 +909,23 @@ impl<'le> ThreadSafeLayoutElement for ServoThreadSafeLayoutElement<'le> {
|
||||||
///
|
///
|
||||||
/// Note that the element implementation is needed only for selector matching,
|
/// Note that the element implementation is needed only for selector matching,
|
||||||
/// not for inheritance (styles are inherited appropiately).
|
/// not for inheritance (styles are inherited appropiately).
|
||||||
impl <'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
|
impl<'le> ::selectors::MatchAttrGeneric for ServoThreadSafeLayoutElement<'le> {
|
||||||
|
fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool
|
||||||
|
where F: Fn(&str) -> bool {
|
||||||
|
match attr.namespace {
|
||||||
|
NamespaceConstraint::Specific(ref ns) => {
|
||||||
|
self.get_attr(ns, &attr.name).map_or(false, |attr| test(attr))
|
||||||
|
},
|
||||||
|
NamespaceConstraint::Any => {
|
||||||
|
unsafe {
|
||||||
|
self.element.get_attr_vals_for_layout(&attr.name).iter()
|
||||||
|
.any(|attr| test(*attr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
|
||||||
type Impl = ServoSelectorImpl;
|
type Impl = ServoSelectorImpl;
|
||||||
|
|
||||||
fn parent_element(&self) -> Option<Self> {
|
fn parent_element(&self) -> Option<Self> {
|
||||||
|
@ -968,21 +987,6 @@ impl <'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool
|
|
||||||
where F: Fn(&str) -> bool {
|
|
||||||
match attr.namespace {
|
|
||||||
NamespaceConstraint::Specific(ref ns) => {
|
|
||||||
self.get_attr(ns, &attr.name).map_or(false, |attr| test(attr))
|
|
||||||
},
|
|
||||||
NamespaceConstraint::Any => {
|
|
||||||
unsafe {
|
|
||||||
self.element.get_attr_vals_for_layout(&attr.name).iter()
|
|
||||||
.any(|attr| test(*attr))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_empty(&self) -> bool {
|
fn is_empty(&self) -> bool {
|
||||||
warn!("ServoThreadSafeLayoutElement::is_empty called");
|
warn!("ServoThreadSafeLayoutElement::is_empty called");
|
||||||
false
|
false
|
||||||
|
|
|
@ -26,7 +26,7 @@ plugins = {path = "../plugins"}
|
||||||
profile_traits = {path = "../profile_traits"}
|
profile_traits = {path = "../profile_traits"}
|
||||||
range = {path = "../range"}
|
range = {path = "../range"}
|
||||||
script_traits = {path = "../script_traits"}
|
script_traits = {path = "../script_traits"}
|
||||||
selectors = {version = "0.6", features = ["heap_size"]}
|
selectors = {version = "0.7", features = ["heap_size"]}
|
||||||
string_cache = {version = "0.2.20", features = ["heap_size"]}
|
string_cache = {version = "0.2.20", features = ["heap_size"]}
|
||||||
style = {path = "../style"}
|
style = {path = "../style"}
|
||||||
url = {version = "1.0.0", features = ["heap_size"]}
|
url = {version = "1.0.0", features = ["heap_size"]}
|
||||||
|
|
|
@ -86,7 +86,7 @@ pub trait LayoutNode: TNode {
|
||||||
pub trait ThreadSafeLayoutNode: Clone + Copy + Sized + PartialEq {
|
pub trait ThreadSafeLayoutNode: Clone + Copy + Sized + PartialEq {
|
||||||
type ConcreteThreadSafeLayoutElement:
|
type ConcreteThreadSafeLayoutElement:
|
||||||
ThreadSafeLayoutElement<ConcreteThreadSafeLayoutNode = Self>
|
ThreadSafeLayoutElement<ConcreteThreadSafeLayoutNode = Self>
|
||||||
+ ::selectors::Element<Impl=ServoSelectorImpl>;
|
+ ::selectors::Element<Impl=ServoSelectorImpl, AttrString=String>;
|
||||||
type ChildrenIterator: Iterator<Item = Self> + Sized;
|
type ChildrenIterator: Iterator<Item = Self> + Sized;
|
||||||
|
|
||||||
/// Creates a new `ThreadSafeLayoutNode` for the same `LayoutNode`
|
/// Creates a new `ThreadSafeLayoutNode` for the same `LayoutNode`
|
||||||
|
@ -351,7 +351,7 @@ pub trait DangerousThreadSafeLayoutNode: ThreadSafeLayoutNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ThreadSafeLayoutElement: Clone + Copy + Sized +
|
pub trait ThreadSafeLayoutElement: Clone + Copy + Sized +
|
||||||
::selectors::Element<Impl=ServoSelectorImpl> +
|
::selectors::Element<Impl=ServoSelectorImpl, AttrString=String> +
|
||||||
PresentationalHintsSynthetizer {
|
PresentationalHintsSynthetizer {
|
||||||
type ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<ConcreteThreadSafeLayoutElement = Self>;
|
type ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<ConcreteThreadSafeLayoutElement = Self>;
|
||||||
|
|
||||||
|
|
12
components/servo/Cargo.lock
generated
12
components/servo/Cargo.lock
generated
|
@ -1159,7 +1159,7 @@ dependencies = [
|
||||||
"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)",
|
||||||
"script_layout_interface 0.0.1",
|
"script_layout_interface 0.0.1",
|
||||||
"script_traits 0.0.1",
|
"script_traits 0.0.1",
|
||||||
"selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1942,7 +1942,7 @@ dependencies = [
|
||||||
"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)",
|
||||||
"script_layout_interface 0.0.1",
|
"script_layout_interface 0.0.1",
|
||||||
"script_traits 0.0.1",
|
"script_traits 0.0.1",
|
||||||
"selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1978,7 +1978,7 @@ dependencies = [
|
||||||
"profile_traits 0.0.1",
|
"profile_traits 0.0.1",
|
||||||
"range 0.0.1",
|
"range 0.0.1",
|
||||||
"script_traits 0.0.1",
|
"script_traits 0.0.1",
|
||||||
"selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"style 0.0.1",
|
"style 0.0.1",
|
||||||
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2026,7 +2026,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "selectors"
|
name = "selectors"
|
||||||
version = "0.6.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2243,7 +2243,7 @@ dependencies = [
|
||||||
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"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)",
|
||||||
"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)",
|
||||||
"selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2263,7 +2263,7 @@ dependencies = [
|
||||||
"cssparser 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.7.1 (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)",
|
||||||
"selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"style 0.0.1",
|
"style 0.0.1",
|
||||||
"style_traits 0.0.1",
|
"style_traits 0.0.1",
|
||||||
|
|
|
@ -11,7 +11,7 @@ name = "style"
|
||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
gecko = ["gecko_bindings"]
|
gecko = ["gecko_bindings", "selectors/gecko"]
|
||||||
servo = ["serde", "serde/nightly", "serde_macros", "heapsize", "heapsize_plugin",
|
servo = ["serde", "serde/nightly", "serde_macros", "heapsize", "heapsize_plugin",
|
||||||
"style_traits/servo", "app_units/plugins", "euclid/plugins",
|
"style_traits/servo", "app_units/plugins", "euclid/plugins",
|
||||||
"cssparser/heap_size", "cssparser/serde-serialization",
|
"cssparser/heap_size", "cssparser/serde-serialization",
|
||||||
|
@ -36,7 +36,7 @@ matches = "0.1"
|
||||||
num-traits = "0.1.32"
|
num-traits = "0.1.32"
|
||||||
rand = "0.3"
|
rand = "0.3"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
selectors = "0.6"
|
selectors = "0.7"
|
||||||
serde = {version = "0.7.11", optional = true}
|
serde = {version = "0.7.11", optional = true}
|
||||||
serde_macros = {version = "0.7.11", optional = true}
|
serde_macros = {version = "0.7.11", optional = true}
|
||||||
smallvec = "0.1"
|
smallvec = "0.1"
|
||||||
|
|
|
@ -38,9 +38,8 @@ fn create_common_style_affecting_attributes_from_element<E: TElement>(element: &
|
||||||
flags.insert(flag)
|
flags.insert(flag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CommonStyleAffectingAttributeMode::IsEqual(target_value, flag) => {
|
CommonStyleAffectingAttributeMode::IsEqual(ref target_value, flag) => {
|
||||||
let atom = Atom::from(target_value); // FIXME(bholley): This goes away in the next patch.
|
if element.attr_equals(&ns!(), &attribute_info.atom, target_value) {
|
||||||
if element.attr_equals(&ns!(), &attribute_info.atom, &atom) {
|
|
||||||
flags.insert(flag)
|
flags.insert(flag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,11 +297,10 @@ impl<C: ComputedValues> StyleSharingCandidate<C> {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CommonStyleAffectingAttributeMode::IsEqual(target_value, flag) => {
|
CommonStyleAffectingAttributeMode::IsEqual(ref target_value, flag) => {
|
||||||
let atom = Atom::from(target_value); // FIXME(bholley): This goes away in the next patch.
|
|
||||||
let contains = self.common_style_affecting_attributes.contains(flag);
|
let contains = self.common_style_affecting_attributes.contains(flag);
|
||||||
if element.has_attr(&ns!(), &attribute_info.atom) {
|
if element.has_attr(&ns!(), &attribute_info.atom) {
|
||||||
if !contains || !element.attr_equals(&ns!(), &attribute_info.atom, &atom) {
|
if !contains || !element.attr_equals(&ns!(), &attribute_info.atom, target_value) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
} else if contains {
|
} else if contains {
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
use attr::{AttrIdentifier, AttrValue};
|
use attr::{AttrIdentifier, AttrValue};
|
||||||
use element_state::*;
|
use element_state::*;
|
||||||
use selector_impl::SelectorImplExt;
|
use selector_impl::SelectorImplExt;
|
||||||
use selectors::Element;
|
|
||||||
use selectors::matching::matches_compound_selector;
|
use selectors::matching::matches_compound_selector;
|
||||||
use selectors::parser::{AttrSelector, Combinator, CompoundSelector, SelectorImpl, SimpleSelector};
|
use selectors::parser::{AttrSelector, Combinator, CompoundSelector, SelectorImpl, SimpleSelector};
|
||||||
|
use selectors::{Element, MatchAttrGeneric};
|
||||||
use std::clone::Clone;
|
use std::clone::Clone;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace};
|
use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace};
|
||||||
|
@ -81,15 +81,21 @@ impl ElementSnapshot {
|
||||||
|
|
||||||
static EMPTY_SNAPSHOT: ElementSnapshot = ElementSnapshot { state: None, attrs: None };
|
static EMPTY_SNAPSHOT: ElementSnapshot = ElementSnapshot { state: None, attrs: None };
|
||||||
|
|
||||||
|
// FIXME(bholley): This implementation isn't going to work for geckolib, because
|
||||||
|
// it's fundamentally based on get_attr/match_attr, which we don't want to support
|
||||||
|
// that configuration due to the overhead of converting between UTF-16 and UTF-8.
|
||||||
|
// We'll need to figure something out when we start using restyle hints with
|
||||||
|
// geckolib, but in the mean time we can just use the trait parameters to
|
||||||
|
// specialize it to the Servo configuration.
|
||||||
struct ElementWrapper<'a, E>
|
struct ElementWrapper<'a, E>
|
||||||
where E: Element,
|
where E: Element<AttrString=String>,
|
||||||
E::Impl: SelectorImplExt {
|
E::Impl: SelectorImplExt {
|
||||||
element: E,
|
element: E,
|
||||||
snapshot: &'a ElementSnapshot,
|
snapshot: &'a ElementSnapshot,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> ElementWrapper<'a, E>
|
impl<'a, E> ElementWrapper<'a, E>
|
||||||
where E: Element,
|
where E: Element<AttrString=String>,
|
||||||
E::Impl: SelectorImplExt {
|
E::Impl: SelectorImplExt {
|
||||||
pub fn new(el: E) -> ElementWrapper<'a, E> {
|
pub fn new(el: E) -> ElementWrapper<'a, E> {
|
||||||
ElementWrapper { element: el, snapshot: &EMPTY_SNAPSHOT }
|
ElementWrapper { element: el, snapshot: &EMPTY_SNAPSHOT }
|
||||||
|
@ -100,8 +106,42 @@ impl<'a, E> ElementWrapper<'a, E>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "gecko"))]
|
||||||
|
impl<'a, E> MatchAttrGeneric for ElementWrapper<'a, E>
|
||||||
|
where E: Element<AttrString=String>,
|
||||||
|
E: MatchAttrGeneric,
|
||||||
|
E::Impl: SelectorImplExt {
|
||||||
|
fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool
|
||||||
|
where F: Fn(&str) -> bool {
|
||||||
|
use selectors::parser::NamespaceConstraint;
|
||||||
|
match self.snapshot.attrs {
|
||||||
|
Some(_) => {
|
||||||
|
let html = self.is_html_element_in_html_document();
|
||||||
|
let local_name = if html { &attr.lower_name } else { &attr.name };
|
||||||
|
match attr.namespace {
|
||||||
|
NamespaceConstraint::Specific(ref ns) => self.snapshot.get_attr(ns, local_name),
|
||||||
|
NamespaceConstraint::Any => self.snapshot.get_attr_ignore_ns(local_name),
|
||||||
|
}.map_or(false, |v| test(v))
|
||||||
|
},
|
||||||
|
None => self.element.match_attr(attr, test)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
impl<'a, E> MatchAttrGeneric for ElementWrapper<'a, E>
|
||||||
|
where E: Element<AttrString=String>,
|
||||||
|
E: MatchAttrGeneric,
|
||||||
|
E::Impl: SelectorImplExt {
|
||||||
|
fn match_attr<F>(&self, _: &AttrSelector, _: F) -> bool
|
||||||
|
where F: Fn(&str) -> bool {
|
||||||
|
panic!("Not implemented for Gecko - this system will need to be redesigned");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, E> Element for ElementWrapper<'a, E>
|
impl<'a, E> Element for ElementWrapper<'a, E>
|
||||||
where E: Element,
|
where E: Element<AttrString=String>,
|
||||||
|
E: MatchAttrGeneric,
|
||||||
E::Impl: SelectorImplExt {
|
E::Impl: SelectorImplExt {
|
||||||
type Impl = E::Impl;
|
type Impl = E::Impl;
|
||||||
|
|
||||||
|
@ -155,27 +195,6 @@ impl<'a, E> Element for ElementWrapper<'a, E>
|
||||||
None => self.element.has_class(name),
|
None => self.element.has_class(name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
fn match_attr<F>(&self, _: &AttrSelector, _: F) -> bool
|
|
||||||
where F: Fn(&str) -> bool {
|
|
||||||
panic!("Gecko can't borrow atoms as UTF-8.");
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "gecko"))]
|
|
||||||
fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool
|
|
||||||
where F: Fn(&str) -> bool {
|
|
||||||
use selectors::parser::NamespaceConstraint;
|
|
||||||
match self.snapshot.attrs {
|
|
||||||
Some(_) => {
|
|
||||||
let html = self.is_html_element_in_html_document();
|
|
||||||
let local_name = if html { &attr.lower_name } else { &attr.name };
|
|
||||||
match attr.namespace {
|
|
||||||
NamespaceConstraint::Specific(ref ns) => self.snapshot.get_attr(ns, local_name),
|
|
||||||
NamespaceConstraint::Any => self.snapshot.get_attr_ignore_ns(local_name),
|
|
||||||
}.map_or(false, |v| test(v))
|
|
||||||
},
|
|
||||||
None => self.element.match_attr(attr, test)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn is_empty(&self) -> bool {
|
fn is_empty(&self) -> bool {
|
||||||
self.element.is_empty()
|
self.element.is_empty()
|
||||||
}
|
}
|
||||||
|
@ -208,7 +227,7 @@ fn is_attr_selector<Impl: SelectorImpl>(sel: &SimpleSelector<Impl>) -> bool {
|
||||||
SimpleSelector::AttrExists(_) |
|
SimpleSelector::AttrExists(_) |
|
||||||
SimpleSelector::AttrEqual(_, _, _) |
|
SimpleSelector::AttrEqual(_, _, _) |
|
||||||
SimpleSelector::AttrIncludes(_, _) |
|
SimpleSelector::AttrIncludes(_, _) |
|
||||||
SimpleSelector::AttrDashMatch(_, _, _) |
|
SimpleSelector::AttrDashMatch(_, _) |
|
||||||
SimpleSelector::AttrPrefixMatch(_, _) |
|
SimpleSelector::AttrPrefixMatch(_, _) |
|
||||||
SimpleSelector::AttrSubstringMatch(_, _) |
|
SimpleSelector::AttrSubstringMatch(_, _) |
|
||||||
SimpleSelector::AttrSuffixMatch(_, _) => true,
|
SimpleSelector::AttrSuffixMatch(_, _) => true,
|
||||||
|
@ -285,28 +304,6 @@ impl<Impl: SelectorImplExt> DependencySet<Impl> {
|
||||||
DependencySet { deps: Vec::new() }
|
DependencySet { deps: Vec::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compute_hint<E>(&self, el: &E, snapshot: &ElementSnapshot, current_state: ElementState)
|
|
||||||
-> RestyleHint
|
|
||||||
where E: Element<Impl=Impl> + Clone {
|
|
||||||
let state_changes = snapshot.state.map_or(ElementState::empty(), |old_state| current_state ^ old_state);
|
|
||||||
let attrs_changed = snapshot.attrs.is_some();
|
|
||||||
let mut hint = RestyleHint::empty();
|
|
||||||
for dep in &self.deps {
|
|
||||||
if state_changes.intersects(dep.sensitivities.states) || (attrs_changed && dep.sensitivities.attrs) {
|
|
||||||
let old_el: ElementWrapper<E> = ElementWrapper::new_with_snapshot(el.clone(), snapshot);
|
|
||||||
let matched_then = matches_compound_selector(&*dep.selector, &old_el, None, &mut false);
|
|
||||||
let matches_now = matches_compound_selector(&*dep.selector, el, None, &mut false);
|
|
||||||
if matched_then != matches_now {
|
|
||||||
hint.insert(combinator_to_restyle_hint(dep.combinator));
|
|
||||||
if hint.is_all() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hint
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn note_selector(&mut self, selector: Arc<CompoundSelector<Impl>>) {
|
pub fn note_selector(&mut self, selector: Arc<CompoundSelector<Impl>>) {
|
||||||
let mut cur = selector;
|
let mut cur = selector;
|
||||||
let mut combinator: Option<Combinator> = None;
|
let mut combinator: Option<Combinator> = None;
|
||||||
|
@ -340,3 +337,27 @@ impl<Impl: SelectorImplExt> DependencySet<Impl> {
|
||||||
self.deps.clear();
|
self.deps.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Impl: SelectorImplExt<AttrString=String>> DependencySet<Impl> {
|
||||||
|
pub fn compute_hint<E>(&self, el: &E, snapshot: &ElementSnapshot, current_state: ElementState)
|
||||||
|
-> RestyleHint
|
||||||
|
where E: Element<Impl=Impl, AttrString=Impl::AttrString> + Clone + MatchAttrGeneric {
|
||||||
|
let state_changes = snapshot.state.map_or(ElementState::empty(), |old_state| current_state ^ old_state);
|
||||||
|
let attrs_changed = snapshot.attrs.is_some();
|
||||||
|
let mut hint = RestyleHint::empty();
|
||||||
|
for dep in &self.deps {
|
||||||
|
if state_changes.intersects(dep.sensitivities.states) || (attrs_changed && dep.sensitivities.attrs) {
|
||||||
|
let old_el: ElementWrapper<E> = ElementWrapper::new_with_snapshot(el.clone(), snapshot);
|
||||||
|
let matched_then = matches_compound_selector(&*dep.selector, &old_el, None, &mut false);
|
||||||
|
let matches_now = matches_compound_selector(&*dep.selector, el, None, &mut false);
|
||||||
|
if matched_then != matches_now {
|
||||||
|
hint.insert(combinator_to_restyle_hint(dep.combinator));
|
||||||
|
if hint.is_all() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -181,6 +181,7 @@ impl NonTSPseudoClass {
|
||||||
pub struct ServoSelectorImpl;
|
pub struct ServoSelectorImpl;
|
||||||
|
|
||||||
impl SelectorImpl for ServoSelectorImpl {
|
impl SelectorImpl for ServoSelectorImpl {
|
||||||
|
type AttrString = String;
|
||||||
type PseudoElement = PseudoElement;
|
type PseudoElement = PseudoElement;
|
||||||
type NonTSPseudoClass = NonTSPseudoClass;
|
type NonTSPseudoClass = NonTSPseudoClass;
|
||||||
|
|
||||||
|
@ -278,7 +279,7 @@ impl SelectorImplExt for ServoSelectorImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Element<Impl=ServoSelectorImpl>> ElementExt for E {
|
impl<E: Element<Impl=ServoSelectorImpl, AttrString=String>> ElementExt for E {
|
||||||
fn is_link(&self) -> bool {
|
fn is_link(&self) -> bool {
|
||||||
self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink)
|
self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,11 @@ use parser::ParserContextExtraData;
|
||||||
use properties::{self, PropertyDeclaration, PropertyDeclarationBlock};
|
use properties::{self, PropertyDeclaration, PropertyDeclarationBlock};
|
||||||
use restyle_hints::{ElementSnapshot, RestyleHint, DependencySet};
|
use restyle_hints::{ElementSnapshot, RestyleHint, DependencySet};
|
||||||
use selector_impl::{SelectorImplExt, ServoSelectorImpl};
|
use selector_impl::{SelectorImplExt, ServoSelectorImpl};
|
||||||
use selectors::Element;
|
|
||||||
use selectors::bloom::BloomFilter;
|
use selectors::bloom::BloomFilter;
|
||||||
use selectors::matching::DeclarationBlock as GenericDeclarationBlock;
|
use selectors::matching::DeclarationBlock as GenericDeclarationBlock;
|
||||||
use selectors::matching::{Rule, SelectorMap};
|
use selectors::matching::{Rule, SelectorMap};
|
||||||
use selectors::parser::SelectorImpl;
|
use selectors::parser::SelectorImpl;
|
||||||
|
use selectors::{Element, MatchAttrGeneric};
|
||||||
use sink::Push;
|
use sink::Push;
|
||||||
use smallvec::VecLike;
|
use smallvec::VecLike;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -311,7 +311,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
pseudo: &Impl::PseudoElement,
|
pseudo: &Impl::PseudoElement,
|
||||||
parent: &Arc<Impl::ComputedValues>)
|
parent: &Arc<Impl::ComputedValues>)
|
||||||
-> Option<Arc<Impl::ComputedValues>>
|
-> Option<Arc<Impl::ComputedValues>>
|
||||||
where E: Element<Impl=Impl> +
|
where E: Element<Impl=Impl, AttrString=Impl::AttrString> +
|
||||||
PresentationalHintsSynthetizer {
|
PresentationalHintsSynthetizer {
|
||||||
debug_assert!(Impl::pseudo_element_cascade_type(pseudo).is_lazy());
|
debug_assert!(Impl::pseudo_element_cascade_type(pseudo).is_lazy());
|
||||||
if self.pseudos_map.get(pseudo).is_none() {
|
if self.pseudos_map.get(pseudo).is_none() {
|
||||||
|
@ -336,18 +336,6 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
Some(Arc::new(computed))
|
Some(Arc::new(computed))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compute_restyle_hint<E>(&self, element: &E,
|
|
||||||
snapshot: &ElementSnapshot,
|
|
||||||
// NB: We need to pass current_state as an argument because
|
|
||||||
// selectors::Element doesn't provide access to ElementState
|
|
||||||
// directly, and computing it from the ElementState would be
|
|
||||||
// more expensive than getting it directly from the caller.
|
|
||||||
current_state: ElementState)
|
|
||||||
-> RestyleHint
|
|
||||||
where E: Element<Impl=Impl> + Clone {
|
|
||||||
self.state_deps.compute_hint(element, snapshot, current_state)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_device(&mut self, mut device: Device, stylesheets: &[Arc<Stylesheet<Impl>>]) {
|
pub fn set_device(&mut self, mut device: Device, stylesheets: &[Arc<Stylesheet<Impl>>]) {
|
||||||
let cascaded_rule = stylesheets.iter()
|
let cascaded_rule = stylesheets.iter()
|
||||||
.flat_map(|s| s.effective_rules(&self.device).viewport())
|
.flat_map(|s| s.effective_rules(&self.device).viewport())
|
||||||
|
@ -389,7 +377,8 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
pseudo_element: Option<&Impl::PseudoElement>,
|
pseudo_element: Option<&Impl::PseudoElement>,
|
||||||
applicable_declarations: &mut V)
|
applicable_declarations: &mut V)
|
||||||
-> bool
|
-> bool
|
||||||
where E: Element<Impl=Impl> + PresentationalHintsSynthetizer,
|
where E: Element<Impl=Impl, AttrString=Impl::AttrString> +
|
||||||
|
PresentationalHintsSynthetizer,
|
||||||
V: Push<DeclarationBlock> + VecLike<DeclarationBlock> {
|
V: Push<DeclarationBlock> + VecLike<DeclarationBlock> {
|
||||||
assert!(!self.is_device_dirty);
|
assert!(!self.is_device_dirty);
|
||||||
assert!(style_attribute.is_none() || pseudo_element.is_none(),
|
assert!(style_attribute.is_none() || pseudo_element.is_none(),
|
||||||
|
@ -474,6 +463,21 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Impl: SelectorImplExt<AttrString=String>> Stylist<Impl> {
|
||||||
|
pub fn compute_restyle_hint<E>(&self, element: &E,
|
||||||
|
snapshot: &ElementSnapshot,
|
||||||
|
// NB: We need to pass current_state as an argument because
|
||||||
|
// selectors::Element doesn't provide access to ElementState
|
||||||
|
// directly, and computing it from the ElementState would be
|
||||||
|
// more expensive than getting it directly from the caller.
|
||||||
|
current_state: ElementState)
|
||||||
|
-> RestyleHint
|
||||||
|
where E: Element<Impl=Impl, AttrString=String> + Clone + MatchAttrGeneric {
|
||||||
|
self.state_deps.compute_hint(element, snapshot, current_state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Map that contains the CSS rules for a given origin.
|
/// Map that contains the CSS rules for a given origin.
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
struct PerOriginSelectorMap<Impl: SelectorImpl> {
|
struct PerOriginSelectorMap<Impl: SelectorImpl> {
|
||||||
|
|
10
ports/cef/Cargo.lock
generated
10
ports/cef/Cargo.lock
generated
|
@ -1068,7 +1068,7 @@ dependencies = [
|
||||||
"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)",
|
||||||
"script_layout_interface 0.0.1",
|
"script_layout_interface 0.0.1",
|
||||||
"script_traits 0.0.1",
|
"script_traits 0.0.1",
|
||||||
"selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1796,7 +1796,7 @@ dependencies = [
|
||||||
"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)",
|
||||||
"script_layout_interface 0.0.1",
|
"script_layout_interface 0.0.1",
|
||||||
"script_traits 0.0.1",
|
"script_traits 0.0.1",
|
||||||
"selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1832,7 +1832,7 @@ dependencies = [
|
||||||
"profile_traits 0.0.1",
|
"profile_traits 0.0.1",
|
||||||
"range 0.0.1",
|
"range 0.0.1",
|
||||||
"script_traits 0.0.1",
|
"script_traits 0.0.1",
|
||||||
"selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"style 0.0.1",
|
"style 0.0.1",
|
||||||
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1870,7 +1870,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "selectors"
|
name = "selectors"
|
||||||
version = "0.6.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2128,7 +2128,7 @@ dependencies = [
|
||||||
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"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)",
|
||||||
"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)",
|
||||||
"selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
6
ports/geckolib/Cargo.lock
generated
6
ports/geckolib/Cargo.lock
generated
|
@ -12,7 +12,7 @@ dependencies = [
|
||||||
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"style 0.0.1",
|
"style 0.0.1",
|
||||||
|
@ -379,7 +379,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "selectors"
|
name = "selectors"
|
||||||
version = "0.6.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -465,7 +465,7 @@ dependencies = [
|
||||||
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"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)",
|
||||||
"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)",
|
||||||
"selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -37,7 +37,7 @@ lazy_static = "0.2"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log = {version = "0.3.5", features = ["release_max_level_info"]}
|
log = {version = "0.3.5", features = ["release_max_level_info"]}
|
||||||
num_cpus = "0.2.2"
|
num_cpus = "0.2.2"
|
||||||
selectors = "0.6"
|
selectors = "0.7"
|
||||||
smallvec = "0.1"
|
smallvec = "0.1"
|
||||||
string_cache = {version = "0.2.20", features = ["unstable"]}
|
string_cache = {version = "0.2.20", features = ["unstable"]}
|
||||||
style = {path = "../../components/style", features = ["gecko"]}
|
style = {path = "../../components/style", features = ["gecko"]}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
use properties::GeckoComputedValues;
|
use properties::GeckoComputedValues;
|
||||||
use selectors::parser::{ParserContext, SelectorImpl};
|
use selectors::parser::{ParserContext, SelectorImpl};
|
||||||
|
use string_cache::Atom;
|
||||||
use style;
|
use style;
|
||||||
use style::element_state::ElementState;
|
use style::element_state::ElementState;
|
||||||
use style::selector_impl::{PseudoElementCascadeType, SelectorImplExt};
|
use style::selector_impl::{PseudoElementCascadeType, SelectorImplExt};
|
||||||
|
@ -157,6 +158,7 @@ impl NonTSPseudoClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SelectorImpl for GeckoSelectorImpl {
|
impl SelectorImpl for GeckoSelectorImpl {
|
||||||
|
type AttrString = Atom;
|
||||||
type PseudoElement = PseudoElement;
|
type PseudoElement = PseudoElement;
|
||||||
type NonTSPseudoClass = NonTSPseudoClass;
|
type NonTSPseudoClass = NonTSPseudoClass;
|
||||||
fn parse_non_ts_pseudo_class(_context: &ParserContext,
|
fn parse_non_ts_pseudo_class(_context: &ParserContext,
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#![allow(unsafe_code)]
|
#![allow(unsafe_code)]
|
||||||
|
|
||||||
|
use gecko_bindings::bindings;
|
||||||
use gecko_bindings::bindings::Gecko_ChildrenCount;
|
use gecko_bindings::bindings::Gecko_ChildrenCount;
|
||||||
use gecko_bindings::bindings::Gecko_ClassOrClassList;
|
use gecko_bindings::bindings::Gecko_ClassOrClassList;
|
||||||
use gecko_bindings::bindings::Gecko_GetElementId;
|
use gecko_bindings::bindings::Gecko_GetElementId;
|
||||||
|
@ -521,26 +522,6 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool where F: Fn(&str) -> bool {
|
|
||||||
// FIXME(bholley): This is copy-pasted from the servo wrapper's version.
|
|
||||||
// We should find a way to share it.
|
|
||||||
let name = if self.is_html_element_in_html_document() {
|
|
||||||
&attr.lower_name
|
|
||||||
} else {
|
|
||||||
&attr.name
|
|
||||||
};
|
|
||||||
match attr.namespace {
|
|
||||||
NamespaceConstraint::Specific(ref ns) => {
|
|
||||||
self.get_attr(ns, name).map_or(false, |attr| test(attr))
|
|
||||||
},
|
|
||||||
NamespaceConstraint::Any => {
|
|
||||||
// We should probably pass the atom into gecko and let it match
|
|
||||||
// against attributes across namespaces.
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_html_element_in_html_document(&self) -> bool {
|
fn is_html_element_in_html_document(&self) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
Gecko_IsHTMLElementInHTMLDocument(self.element)
|
Gecko_IsHTMLElementInHTMLDocument(self.element)
|
||||||
|
@ -548,6 +529,98 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait AttrSelectorHelpers {
|
||||||
|
fn ns_or_null(&self) -> *mut nsIAtom;
|
||||||
|
fn select_name<'le>(&self, el: &GeckoElement<'le>) -> *mut nsIAtom;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AttrSelectorHelpers for AttrSelector {
|
||||||
|
fn ns_or_null(&self) -> *mut nsIAtom {
|
||||||
|
match self.namespace {
|
||||||
|
NamespaceConstraint::Any => ptr::null_mut(),
|
||||||
|
NamespaceConstraint::Specific(ref ns) => ns.0.as_ptr(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn select_name<'le>(&self, el: &GeckoElement<'le>) -> *mut nsIAtom {
|
||||||
|
if el.is_html_element_in_html_document() {
|
||||||
|
self.lower_name.as_ptr()
|
||||||
|
} else {
|
||||||
|
self.name.as_ptr()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'le> ::selectors::MatchAttr for GeckoElement<'le> {
|
||||||
|
type AttrString = Atom;
|
||||||
|
fn match_attr_has(&self, attr: &AttrSelector) -> bool {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_HasAttr(self.element,
|
||||||
|
attr.ns_or_null(),
|
||||||
|
attr.select_name(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn match_attr_equals(&self, attr: &AttrSelector, value: &Self::AttrString) -> bool {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_AttrEquals(self.element,
|
||||||
|
attr.ns_or_null(),
|
||||||
|
attr.select_name(self),
|
||||||
|
value.as_ptr(),
|
||||||
|
/* ignoreCase = */ false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn match_attr_equals_ignore_ascii_case(&self, attr: &AttrSelector, value: &Self::AttrString) -> bool {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_AttrEquals(self.element,
|
||||||
|
attr.ns_or_null(),
|
||||||
|
attr.select_name(self),
|
||||||
|
value.as_ptr(),
|
||||||
|
/* ignoreCase = */ false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn match_attr_includes(&self, attr: &AttrSelector, value: &Self::AttrString) -> bool {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_AttrIncludes(self.element,
|
||||||
|
attr.ns_or_null(),
|
||||||
|
attr.select_name(self),
|
||||||
|
value.as_ptr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn match_attr_dash(&self, attr: &AttrSelector, value: &Self::AttrString) -> bool {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_AttrDashEquals(self.element,
|
||||||
|
attr.ns_or_null(),
|
||||||
|
attr.select_name(self),
|
||||||
|
value.as_ptr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn match_attr_prefix(&self, attr: &AttrSelector, value: &Self::AttrString) -> bool {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_AttrHasPrefix(self.element,
|
||||||
|
attr.ns_or_null(),
|
||||||
|
attr.select_name(self),
|
||||||
|
value.as_ptr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn match_attr_substring(&self, attr: &AttrSelector, value: &Self::AttrString) -> bool {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_AttrHasSubstring(self.element,
|
||||||
|
attr.ns_or_null(),
|
||||||
|
attr.select_name(self),
|
||||||
|
value.as_ptr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn match_attr_suffix(&self, attr: &AttrSelector, value: &Self::AttrString) -> bool {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_AttrHasSuffix(self.element,
|
||||||
|
attr.ns_or_null(),
|
||||||
|
attr.select_name(self),
|
||||||
|
value.as_ptr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'le> ElementExt for GeckoElement<'le> {
|
impl<'le> ElementExt for GeckoElement<'le> {
|
||||||
fn is_link(&self) -> bool {
|
fn is_link(&self) -> bool {
|
||||||
self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink)
|
self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink)
|
||||||
|
|
|
@ -13,7 +13,7 @@ app_units = "0.2.5"
|
||||||
cssparser = {version = "0.5.4", features = ["heap_size"]}
|
cssparser = {version = "0.5.4", features = ["heap_size"]}
|
||||||
euclid = "0.7.1"
|
euclid = "0.7.1"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
selectors = {version = "0.6", features = ["heap_size"]}
|
selectors = {version = "0.7", features = ["heap_size"]}
|
||||||
string_cache = {version = "0.2", features = ["heap_size"]}
|
string_cache = {version = "0.2", features = ["heap_size"]}
|
||||||
style = {path = "../../../components/style"}
|
style = {path = "../../../components/style"}
|
||||||
style_traits = {path = "../../../components/style_traits"}
|
style_traits = {path = "../../../components/style_traits"}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue