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:
bors-servo 2015-06-26 14:50:01 -06:00
commit c331db1623
12 changed files with 153 additions and 168 deletions

View file

@ -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();
element.style_attribute().is_none() &&
element.get_attr(&ns!(""), &atom!("id")).is_none()
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,28 +623,26 @@ 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));
bf.insert(element.get_local_name());
bf.insert(element.get_namespace());
element.get_id().map(|id| bf.insert(&id));
// TODO: case-sensitivity depends on the document type and quirks mode
element.each_class(|class| bf.insert(class));
// 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));
bf.remove(element.get_local_name());
bf.remove(element.get_namespace());
element.get_id().map(|id| bf.remove(&id));
// TODO: case-sensitivity depends on the document type and quirks mode
element.each_class(|class| bf.remove(class));
// TODO: case-sensitivity depends on the document type and quirks mode
element.each_class(|class| bf.remove(class));
}
}
unsafe fn cascade_node(&self,

View file

@ -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};

View file

@ -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,

View file

@ -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")
};
LayoutElement {
element: &*elem.unsafe_get(),
}
}
}
fn is_element(&self) -> bool {
match self.type_id() {
NodeTypeId::Element(..) => true,
_ => false
ElementCast::to_layout_js(&self.node).map(|element| {
LayoutElement {
element: &*element.unsafe_get(),
}
})
}
}
@ -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> {