mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Auto merge of #6468 - servo:update-selectors, r=Ms2ger
Update rust-selectors r? @Ms2ger https://github.com/servo/rust-selectors/pull/33 <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6468) <!-- Reviewable:end -->
This commit is contained in:
commit
c331db1623
12 changed files with 153 additions and 168 deletions
|
@ -17,6 +17,7 @@ use wrapper::{LayoutElement, LayoutNode};
|
|||
use script::dom::characterdata::CharacterDataTypeId;
|
||||
use script::dom::node::NodeTypeId;
|
||||
use script::layout_interface::Animation;
|
||||
use selectors::{Node, Element};
|
||||
use selectors::bloom::BloomFilter;
|
||||
use selectors::matching::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes};
|
||||
use selectors::matching::{common_style_affecting_attributes, rare_style_affecting_attributes};
|
||||
|
@ -28,7 +29,7 @@ use std::slice::Iter;
|
|||
use std::sync::Arc;
|
||||
use std::sync::mpsc::Sender;
|
||||
use string_cache::{Atom, Namespace};
|
||||
use style::node::{TElement, TElementAttributes, TNode};
|
||||
use style::node::TElementAttributes;
|
||||
use style::properties::{ComputedValues, cascade};
|
||||
use style::selector_matching::{Stylist, DeclarationBlock};
|
||||
use util::arc_ptr_eq;
|
||||
|
@ -226,9 +227,10 @@ impl StyleSharingCandidate {
|
|||
None => return None,
|
||||
Some(parent_node) => parent_node,
|
||||
};
|
||||
if !parent_node.is_element() {
|
||||
return None
|
||||
}
|
||||
let element = match parent_node.as_element() {
|
||||
Some(element) => element,
|
||||
None => return None
|
||||
};
|
||||
|
||||
let style = unsafe {
|
||||
match *node.borrow_layout_data_unchecked() {
|
||||
|
@ -253,7 +255,6 @@ impl StyleSharingCandidate {
|
|||
}
|
||||
};
|
||||
|
||||
let element = node.as_element();
|
||||
if element.style_attribute().is_some() {
|
||||
return None
|
||||
}
|
||||
|
@ -504,10 +505,10 @@ impl<'ln> PrivateMatchMethods for LayoutNode<'ln> {
|
|||
parent_node: Option<LayoutNode>,
|
||||
candidate: &StyleSharingCandidate)
|
||||
-> Option<Arc<ComputedValues>> {
|
||||
assert!(self.is_element());
|
||||
let element = self.as_element().unwrap();
|
||||
|
||||
let parent_node = match parent_node {
|
||||
Some(ref parent_node) if parent_node.is_element() => parent_node,
|
||||
Some(ref parent_node) if parent_node.as_element().is_some() => parent_node,
|
||||
Some(_) | None => return None,
|
||||
};
|
||||
|
||||
|
@ -523,7 +524,7 @@ impl<'ln> PrivateMatchMethods for LayoutNode<'ln> {
|
|||
}
|
||||
|
||||
// Check tag names, classes, etc.
|
||||
if !candidate.can_share_style_with(&self.as_element()) {
|
||||
if !candidate.can_share_style_with(&element) {
|
||||
return None
|
||||
}
|
||||
|
||||
|
@ -542,20 +543,21 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
|
|||
parent_bf: &Option<Box<BloomFilter>>,
|
||||
applicable_declarations: &mut ApplicableDeclarations,
|
||||
shareable: &mut bool) {
|
||||
let style_attribute = self.as_element().style_attribute().as_ref();
|
||||
let element = self.as_element().unwrap();
|
||||
let style_attribute = element.style_attribute().as_ref();
|
||||
|
||||
applicable_declarations.normal_shareable =
|
||||
stylist.push_applicable_declarations(self,
|
||||
stylist.push_applicable_declarations(&element,
|
||||
parent_bf,
|
||||
style_attribute,
|
||||
None,
|
||||
&mut applicable_declarations.normal);
|
||||
stylist.push_applicable_declarations(self,
|
||||
stylist.push_applicable_declarations(&element,
|
||||
parent_bf,
|
||||
None,
|
||||
Some(PseudoElement::Before),
|
||||
&mut applicable_declarations.before);
|
||||
stylist.push_applicable_declarations(self,
|
||||
stylist.push_applicable_declarations(&element,
|
||||
parent_bf,
|
||||
None,
|
||||
Some(PseudoElement::After),
|
||||
|
@ -574,13 +576,13 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
|
|||
if opts::get().disable_share_style_cache {
|
||||
return StyleSharingResult::CannotShare(false)
|
||||
}
|
||||
if !self.is_element() {
|
||||
return StyleSharingResult::CannotShare(false)
|
||||
}
|
||||
let ok = {
|
||||
let element = self.as_element();
|
||||
if let Some(element) = self.as_element() {
|
||||
element.style_attribute().is_none() &&
|
||||
element.get_attr(&ns!(""), &atom!("id")).is_none()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
if !ok {
|
||||
return StyleSharingResult::CannotShare(false)
|
||||
|
@ -621,9 +623,7 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
|
|||
|
||||
fn insert_into_bloom_filter(&self, bf: &mut BloomFilter) {
|
||||
// Only elements are interesting.
|
||||
if !self.is_element() { return; }
|
||||
let element = self.as_element();
|
||||
|
||||
if let Some(element) = self.as_element() {
|
||||
bf.insert(element.get_local_name());
|
||||
bf.insert(element.get_namespace());
|
||||
element.get_id().map(|id| bf.insert(&id));
|
||||
|
@ -631,12 +631,11 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
|
|||
// TODO: case-sensitivity depends on the document type and quirks mode
|
||||
element.each_class(|class| bf.insert(class));
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_from_bloom_filter(&self, bf: &mut BloomFilter) {
|
||||
// Only elements are interesting.
|
||||
if !self.is_element() { return; }
|
||||
let element = self.as_element();
|
||||
|
||||
if let Some(element) = self.as_element() {
|
||||
bf.remove(element.get_local_name());
|
||||
bf.remove(element.get_namespace());
|
||||
element.get_id().map(|id| bf.remove(&id));
|
||||
|
@ -644,6 +643,7 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
|
|||
// TODO: case-sensitivity depends on the document type and quirks mode
|
||||
element.each_class(|class| bf.remove(class));
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn cascade_node(&self,
|
||||
layout_context: &SharedLayoutContext,
|
||||
|
|
|
@ -41,7 +41,6 @@ use style::computed_values::content::ContentItem;
|
|||
use style::computed_values::{border_collapse, clear, mix_blend_mode, overflow_wrap, position};
|
||||
use style::computed_values::{text_align, text_decoration, white_space, word_break};
|
||||
use style::computed_values::transform_style;
|
||||
use style::node::TNode;
|
||||
use style::properties::{self, ComputedValues, cascade_anonymous};
|
||||
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
|
||||
use style::values::computed::{LengthOrPercentageOrNone};
|
||||
|
|
|
@ -19,9 +19,9 @@ use wrapper::{PostorderNodeMutTraversal, ThreadSafeLayoutNode, UnsafeLayoutNode}
|
|||
use wrapper::{PreorderDomTraversal, PostorderDomTraversal};
|
||||
|
||||
use selectors::bloom::BloomFilter;
|
||||
use selectors::Node;
|
||||
use util::opts;
|
||||
use util::tid::tid;
|
||||
use style::node::TNode;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::mem;
|
||||
|
@ -164,7 +164,7 @@ impl<'a> PreorderDomTraversal for RecalcStyleForNode<'a> {
|
|||
StyleSharingResult::CannotShare(mut shareable) => {
|
||||
let mut applicable_declarations = ApplicableDeclarations::new();
|
||||
|
||||
if node.is_element() {
|
||||
if node.as_element().is_some() {
|
||||
// Perform the CSS selector matching.
|
||||
let stylist = unsafe { &*self.layout_context.shared.stylist };
|
||||
node.match_node(stylist,
|
||||
|
|
|
@ -43,7 +43,7 @@ use script::dom::bindings::codegen::InheritTypes::{CharacterDataCast, ElementCas
|
|||
use script::dom::bindings::codegen::InheritTypes::{HTMLIFrameElementCast, HTMLCanvasElementCast};
|
||||
use script::dom::bindings::codegen::InheritTypes::{HTMLImageElementCast, HTMLInputElementCast};
|
||||
use script::dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementCast, NodeCast, TextCast};
|
||||
use script::dom::bindings::js::LayoutJS;
|
||||
use script::dom::bindings::js::{JS, LayoutJS};
|
||||
use script::dom::characterdata::{CharacterDataTypeId, LayoutCharacterDataHelpers};
|
||||
use script::dom::element::{Element, ElementTypeId};
|
||||
use script::dom::element::{LayoutElementHelpers, RawLayoutElementHelpers};
|
||||
|
@ -68,10 +68,11 @@ use std::sync::mpsc::Sender;
|
|||
use string_cache::{Atom, Namespace};
|
||||
use style::computed_values::content::ContentItem;
|
||||
use style::computed_values::{content, display, white_space};
|
||||
use selectors::Node as SelectorsNode;
|
||||
use selectors::matching::DeclarationBlock;
|
||||
use selectors::parser::{NamespaceConstraint, AttrSelector};
|
||||
use style::legacy::UnsignedIntegerAttribute;
|
||||
use style::node::{TElement, TElementAttributes, TNode};
|
||||
use style::node::TElementAttributes;
|
||||
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
|
||||
use url::Url;
|
||||
|
||||
|
@ -216,9 +217,7 @@ impl<'ln> LayoutNode<'ln> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ln> TNode for LayoutNode<'ln> {
|
||||
type Element = LayoutElement<'ln>;
|
||||
|
||||
impl<'ln> ::selectors::Node<LayoutElement<'ln>> for LayoutNode<'ln> {
|
||||
fn parent_node(&self) -> Option<LayoutNode<'ln>> {
|
||||
unsafe {
|
||||
self.node.parent_node_ref().map(|node| self.new_with_this_lifetime(&node))
|
||||
|
@ -249,25 +248,15 @@ impl<'ln> TNode for LayoutNode<'ln> {
|
|||
}
|
||||
}
|
||||
|
||||
/// If this is an element, accesses the element data. Fails if this is not an element node.
|
||||
/// If this is an element, accesses the element data.
|
||||
#[inline]
|
||||
fn as_element(&self) -> LayoutElement<'ln> {
|
||||
fn as_element(&self) -> Option<LayoutElement<'ln>> {
|
||||
unsafe {
|
||||
let elem: LayoutJS<Element> = match ElementCast::to_layout_js(&self.node) {
|
||||
Some(elem) => elem,
|
||||
None => panic!("not an element")
|
||||
};
|
||||
|
||||
ElementCast::to_layout_js(&self.node).map(|element| {
|
||||
LayoutElement {
|
||||
element: &*elem.unsafe_get(),
|
||||
element: &*element.unsafe_get(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_element(&self) -> bool {
|
||||
match self.type_id() {
|
||||
NodeTypeId::Element(..) => true,
|
||||
_ => false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,34 +266,6 @@ impl<'ln> TNode for LayoutNode<'ln> {
|
|||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool where F: Fn(&str) -> bool {
|
||||
assert!(self.is_element());
|
||||
let name = if self.is_html_element_in_html_document() {
|
||||
&attr.lower_name
|
||||
} else {
|
||||
&attr.name
|
||||
};
|
||||
match attr.namespace {
|
||||
NamespaceConstraint::Specific(ref ns) => {
|
||||
let element = self.as_element();
|
||||
element.get_attr(ns, name).map_or(false, |attr| test(attr))
|
||||
},
|
||||
NamespaceConstraint::Any => {
|
||||
let element = self.as_element();
|
||||
element.get_attrs(name).iter().any(|attr| test(*attr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_html_element_in_html_document(&self) -> bool {
|
||||
unsafe {
|
||||
match ElementCast::to_layout_js(&self.node) {
|
||||
Some(elem) => elem.html_element_in_html_document_for_layout(),
|
||||
None => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ln> LayoutNode<'ln> {
|
||||
|
@ -424,7 +385,19 @@ impl<'le> LayoutElement<'le> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'le> TElement for LayoutElement<'le> {
|
||||
impl<'le> ::selectors::Element for LayoutElement<'le> {
|
||||
type Node = LayoutNode<'le>;
|
||||
|
||||
#[inline]
|
||||
fn as_node(&self) -> LayoutNode<'le> {
|
||||
LayoutNode {
|
||||
node: NodeCast::from_layout_js(unsafe {
|
||||
&JS::from_ref(self.element).to_layout()
|
||||
}),
|
||||
chain: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_local_name<'a>(&'a self) -> &'a Atom {
|
||||
self.element.local_name()
|
||||
|
@ -545,6 +518,28 @@ impl<'le> TElement for LayoutElement<'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 => {
|
||||
self.get_attrs(name).iter().any(|attr| test(*attr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_html_element_in_html_document(&self) -> bool {
|
||||
unsafe {
|
||||
JS::from_ref(self.element).to_layout().html_element_in_html_document_for_layout()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'le> TElementAttributes for LayoutElement<'le> {
|
||||
|
|
|
@ -79,6 +79,7 @@ use html5ever::serialize::TraversalScope::{IncludeNode, ChildrenOnly};
|
|||
use html5ever::tree_builder::{NoQuirks, LimitedQuirks, Quirks};
|
||||
use selectors::matching::{matches, DeclarationBlock};
|
||||
use selectors::parser::parse_author_origin_selector_list_from_str;
|
||||
use selectors::parser::{AttrSelector, NamespaceConstraint};
|
||||
use string_cache::{Atom, Namespace, QualName};
|
||||
use url::UrlParser;
|
||||
|
||||
|
@ -1454,8 +1455,7 @@ impl<'a> ElementMethods for &'a Element {
|
|||
match parse_author_origin_selector_list_from_str(&selectors) {
|
||||
Err(()) => Err(Syntax),
|
||||
Ok(ref selectors) => {
|
||||
let root = NodeCast::from_ref(self);
|
||||
Ok(matches(selectors, &root, &mut None))
|
||||
Ok(matches(selectors, &self, &mut None))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1468,7 +1468,7 @@ impl<'a> ElementMethods for &'a Element {
|
|||
let root = NodeCast::from_ref(self);
|
||||
for element in root.inclusive_ancestors() {
|
||||
if let Some(element) = ElementCast::to_ref(element.r()) {
|
||||
if matches(selectors, &NodeCast::from_ref(element), &mut None) {
|
||||
if matches(selectors, &element, &mut None) {
|
||||
return Ok(Some(Root::from_ref(element)));
|
||||
}
|
||||
}
|
||||
|
@ -1621,7 +1621,13 @@ impl<'a> VirtualMethods for &'a Element {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> style::node::TElement for &'a Element {
|
||||
impl<'a> ::selectors::Element for &'a Element {
|
||||
type Node = &'a Node;
|
||||
|
||||
fn as_node(&self) -> &'a Node {
|
||||
NodeCast::from_ref(*self)
|
||||
}
|
||||
|
||||
fn is_link(&self) -> bool {
|
||||
// FIXME: This is HTML only.
|
||||
let node = NodeCast::from_ref(*self);
|
||||
|
@ -1740,6 +1746,43 @@ impl<'a> style::node::TElement for &'a 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| {
|
||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||
let attr = attr.r();
|
||||
let value = attr.value();
|
||||
test(&value)
|
||||
})
|
||||
},
|
||||
NamespaceConstraint::Any => {
|
||||
let mut attributes: RootedVec<JS<Attr>> = RootedVec::new();
|
||||
self.get_attributes(local_name, &mut attributes);
|
||||
attributes.iter().any(|attr| {
|
||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||
let attr = attr.root();
|
||||
let value = attr.r().value();
|
||||
test(&value)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_html_element_in_html_document(&self) -> bool {
|
||||
self.html_element_in_html_document()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ActivationElementHelpers<'a> {
|
||||
|
|
|
@ -54,7 +54,7 @@ use util::geometry::Au;
|
|||
use util::namespace;
|
||||
use util::str::DOMString;
|
||||
use util::task_state;
|
||||
use selectors::parser::{Selector, AttrSelector, NamespaceConstraint};
|
||||
use selectors::parser::Selector;
|
||||
use selectors::parser::parse_author_origin_selector_list_from_str;
|
||||
use selectors::matching::matches;
|
||||
use style::properties::ComputedValues;
|
||||
|
@ -423,7 +423,11 @@ impl<'a> Iterator for QuerySelectorIterator {
|
|||
// TODO(cgaebel): Is it worth it to build a bloom filter here
|
||||
// (instead of passing `None`)? Probably.
|
||||
self.iterator.find(|node| {
|
||||
node.r().is_element() && matches(selectors, &node.r(), &mut None)
|
||||
if let Some(element) = ElementCast::to_ref(node.r()) {
|
||||
matches(selectors, &element, &mut None)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -896,7 +900,7 @@ impl<'a> NodeHelpers for &'a Node {
|
|||
let root = self.ancestors().last();
|
||||
let root = root.r().unwrap_or(self.clone());
|
||||
Ok(root.traverse_preorder().filter_map(ElementCast::to_root).find(|element| {
|
||||
matches(selectors, &NodeCast::from_ref(element.r()), &mut None)
|
||||
matches(selectors, &element.r(), &mut None)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
@ -2506,9 +2510,7 @@ impl<'a> VirtualMethods for &'a Node {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> style::node::TNode for &'a Node {
|
||||
type Element = &'a Element;
|
||||
|
||||
impl<'a> ::selectors::Node<&'a Element> for &'a Node {
|
||||
fn parent_node(&self) -> Option<&'a Node> {
|
||||
(*self).parent_node.get()
|
||||
.map(|node| node.root().get_unsound_ref_forever())
|
||||
|
@ -2544,55 +2546,8 @@ impl<'a> style::node::TNode for &'a Node {
|
|||
is_document(*self)
|
||||
}
|
||||
|
||||
fn is_element(&self) -> bool {
|
||||
// FIXME(zwarich): Remove this when UFCS lands and there is a better way
|
||||
// of disambiguating methods.
|
||||
fn is_element<'a, T: ElementDerived>(this: &T) -> bool {
|
||||
this.is_element()
|
||||
}
|
||||
|
||||
is_element(*self)
|
||||
}
|
||||
|
||||
fn as_element(&self) -> &'a Element {
|
||||
ElementCast::to_ref(*self).unwrap()
|
||||
}
|
||||
|
||||
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.as_element().get_attribute(ns, local_name)
|
||||
.map_or(false, |attr| {
|
||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||
let attr = attr.r();
|
||||
let value = attr.value();
|
||||
test(&value)
|
||||
})
|
||||
},
|
||||
NamespaceConstraint::Any => {
|
||||
let mut attributes: RootedVec<JS<Attr>> = RootedVec::new();
|
||||
self.as_element().get_attributes(local_name, &mut attributes);
|
||||
attributes.iter().any(|attr| {
|
||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||
let attr = attr.root();
|
||||
let value = attr.r().value();
|
||||
test(&value)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_html_element_in_html_document(&self) -> bool {
|
||||
self.as_element().html_element_in_html_document()
|
||||
fn as_element(&self) -> Option<&'a Element> {
|
||||
ElementCast::to_ref(*self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
components/servo/Cargo.lock
generated
2
components/servo/Cargo.lock
generated
|
@ -1116,7 +1116,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "selectors"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/servo/rust-selectors#9c920bfff7e55dd67e8af45943270bcd71fd46c9"
|
||||
source = "git+https://github.com/servo/rust-selectors#a16e32540845548d46857f2896248c382ef34393"
|
||||
dependencies = [
|
||||
"bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use selectors::tree::TNode;
|
||||
use selectors::Element;
|
||||
use selectors::matching::DeclarationBlock;
|
||||
use node::TElementAttributes;
|
||||
use properties::PropertyDeclaration;
|
||||
|
@ -32,21 +32,17 @@ pub trait PresentationalHintSynthesis {
|
|||
/// `common_style_affecting_attributes` or `rare_style_affecting_attributes` as appropriate. If
|
||||
/// you don't, you risk strange random nondeterministic failures due to false positives in
|
||||
/// style sharing.
|
||||
fn synthesize_presentational_hints_for_legacy_attributes<N,V>(
|
||||
&self, node: &N, matching_rules_list: &mut V, shareable: &mut bool)
|
||||
where N: TNode,
|
||||
N::Element: TElementAttributes,
|
||||
fn synthesize_presentational_hints_for_legacy_attributes<E,V>(
|
||||
&self, element: &E, matching_rules_list: &mut V, shareable: &mut bool)
|
||||
where E: Element + TElementAttributes,
|
||||
V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>;
|
||||
}
|
||||
|
||||
impl PresentationalHintSynthesis for Stylist {
|
||||
fn synthesize_presentational_hints_for_legacy_attributes<N,V>(
|
||||
&self, node: &N, matching_rules_list: &mut V, shareable: &mut bool)
|
||||
where N: TNode,
|
||||
N::Element: TElementAttributes,
|
||||
fn synthesize_presentational_hints_for_legacy_attributes<E,V>(
|
||||
&self, element: &E, matching_rules_list: &mut V, shareable: &mut bool)
|
||||
where E: Element + TElementAttributes,
|
||||
V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>> {
|
||||
let element = node.as_element();
|
||||
|
||||
let length = matching_rules_list.len();
|
||||
element.synthesize_presentational_hints_for_legacy_attributes(matching_rules_list);
|
||||
if matching_rules_list.len() != length {
|
||||
|
|
|
@ -10,7 +10,6 @@ use properties::PropertyDeclaration;
|
|||
use smallvec::VecLike;
|
||||
|
||||
use selectors::matching::DeclarationBlock;
|
||||
pub use selectors::tree::{TNode, TElement};
|
||||
use string_cache::{Atom, Namespace};
|
||||
|
||||
pub trait TElementAttributes {
|
||||
|
|
|
@ -8,7 +8,7 @@ use selectors::bloom::BloomFilter;
|
|||
use selectors::matching::{SelectorMap, Rule};
|
||||
use selectors::matching::DeclarationBlock as GenericDeclarationBlock;
|
||||
use selectors::parser::PseudoElement;
|
||||
use selectors::tree::TNode;
|
||||
use selectors::Element;
|
||||
use std::process;
|
||||
use smallvec::VecLike;
|
||||
use util::resource_files::read_resource_file;
|
||||
|
@ -190,19 +190,17 @@ impl Stylist {
|
|||
/// The returned boolean indicates whether the style is *shareable*; that is, whether the
|
||||
/// matched selectors are simple enough to allow the matching logic to be reduced to the logic
|
||||
/// in `css::matching::PrivateMatchMethods::candidate_element_allows_for_style_sharing`.
|
||||
pub fn push_applicable_declarations<N,V>(
|
||||
pub fn push_applicable_declarations<E,V>(
|
||||
&self,
|
||||
element: &N,
|
||||
element: &E,
|
||||
parent_bf: &Option<Box<BloomFilter>>,
|
||||
style_attribute: Option<&PropertyDeclarationBlock>,
|
||||
pseudo_element: Option<PseudoElement>,
|
||||
applicable_declarations: &mut V)
|
||||
-> bool
|
||||
where N: TNode,
|
||||
N::Element: TElementAttributes,
|
||||
where E: Element + TElementAttributes,
|
||||
V: VecLike<DeclarationBlock> {
|
||||
assert!(!self.is_dirty);
|
||||
assert!(element.is_element());
|
||||
assert!(style_attribute.is_none() || pseudo_element.is_none(),
|
||||
"Style attributes do not apply to pseudo-elements");
|
||||
|
||||
|
|
2
ports/cef/Cargo.lock
generated
2
ports/cef/Cargo.lock
generated
|
@ -1088,7 +1088,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "selectors"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/servo/rust-selectors#9c920bfff7e55dd67e8af45943270bcd71fd46c9"
|
||||
source = "git+https://github.com/servo/rust-selectors#a16e32540845548d46857f2896248c382ef34393"
|
||||
dependencies = [
|
||||
"bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
2
ports/gonk/Cargo.lock
generated
2
ports/gonk/Cargo.lock
generated
|
@ -996,7 +996,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "selectors"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/servo/rust-selectors#9c920bfff7e55dd67e8af45943270bcd71fd46c9"
|
||||
source = "git+https://github.com/servo/rust-selectors#a16e32540845548d46857f2896248c382ef34393"
|
||||
dependencies = [
|
||||
"bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue