Store a LayoutJS<Element> in LayoutElement.

This commit is contained in:
Ms2ger 2015-07-04 12:14:31 +02:00
parent c7f1716ee1
commit 58a7c81530

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::{HTMLIFrameElementCast, HTMLCanvasElementCast};
use script::dom::bindings::codegen::InheritTypes::{HTMLImageElementCast, HTMLInputElementCast}; use script::dom::bindings::codegen::InheritTypes::{HTMLImageElementCast, HTMLInputElementCast};
use script::dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementCast, NodeCast, TextCast}; use script::dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementCast, NodeCast, TextCast};
use script::dom::bindings::js::{JS, LayoutJS}; use script::dom::bindings::js::LayoutJS;
use script::dom::characterdata::{CharacterDataTypeId, LayoutCharacterDataHelpers}; use script::dom::characterdata::{CharacterDataTypeId, LayoutCharacterDataHelpers};
use script::dom::element::{Element, ElementTypeId}; use script::dom::element::{Element, ElementTypeId};
use script::dom::element::{LayoutElementHelpers, RawLayoutElementHelpers}; use script::dom::element::{LayoutElementHelpers, RawLayoutElementHelpers};
@ -251,13 +251,12 @@ impl<'ln> ::selectors::Node<LayoutElement<'ln>> for LayoutNode<'ln> {
/// If this is an element, accesses the element data. /// If this is an element, accesses the element data.
#[inline] #[inline]
fn as_element(&self) -> Option<LayoutElement<'ln>> { fn as_element(&self) -> Option<LayoutElement<'ln>> {
unsafe { ElementCast::to_layout_js(&self.node).map(|element| {
ElementCast::to_layout_js(&self.node).map(|element| { LayoutElement {
LayoutElement { element: element,
element: &*element.unsafe_get(), chain: self.chain,
} }
}) })
}
} }
fn is_document(&self) -> bool { fn is_document(&self) -> bool {
@ -372,14 +371,15 @@ impl<'a> Iterator for LayoutTreeIterator<'a> {
/// A wrapper around elements that ensures layout can only ever access safe properties. /// A wrapper around elements that ensures layout can only ever access safe properties.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct LayoutElement<'le> { pub struct LayoutElement<'le> {
element: &'le Element, element: LayoutJS<Element>,
chain: PhantomData<&'le ()>,
} }
impl<'le> LayoutElement<'le> { impl<'le> LayoutElement<'le> {
pub fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock> { pub fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock> {
use script::dom::element::ElementHelpers; use script::dom::element::ElementHelpers;
let style: &Option<PropertyDeclarationBlock> = unsafe { let style: &Option<PropertyDeclarationBlock> = unsafe {
&*self.element.style_attribute().borrow_for_layout() &*(*self.element.unsafe_get()).style_attribute().borrow_for_layout()
}; };
style style
} }
@ -391,34 +391,36 @@ impl<'le> ::selectors::Element for LayoutElement<'le> {
#[inline] #[inline]
fn as_node(&self) -> LayoutNode<'le> { fn as_node(&self) -> LayoutNode<'le> {
LayoutNode { LayoutNode {
node: NodeCast::from_layout_js(unsafe { node: NodeCast::from_layout_js(&self.element),
&JS::from_ref(self.element).to_layout()
}),
chain: PhantomData, chain: PhantomData,
} }
} }
#[inline] #[inline]
fn get_local_name<'a>(&'a self) -> &'a Atom { fn get_local_name<'a>(&'a self) -> &'a Atom {
self.element.local_name() unsafe {
(*self.element.unsafe_get()).local_name()
}
} }
#[inline] #[inline]
fn get_namespace<'a>(&'a self) -> &'a Namespace { fn get_namespace<'a>(&'a self) -> &'a Namespace {
use script::dom::element::ElementHelpers; use script::dom::element::ElementHelpers;
self.element.namespace() unsafe {
(*self.element.unsafe_get()).namespace()
}
} }
fn is_link(&self) -> bool { fn is_link(&self) -> bool {
// FIXME: This is HTML only. // FIXME: This is HTML only.
let node: &Node = NodeCast::from_ref(self.element); let node = NodeCast::from_layout_js(&self.element);
match node.type_id_for_layout() { match unsafe { (*node.unsafe_get()).type_id_for_layout() } {
// https://html.spec.whatwg.org/multipage/#selector-link // https://html.spec.whatwg.org/multipage/#selector-link
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) | NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) | NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) => { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) => {
unsafe { unsafe {
self.element.get_attr_val_for_layout(&ns!(""), &atom!("href")).is_some() (*self.element.unsafe_get()).get_attr_val_for_layout(&ns!(""), &atom!("href")).is_some()
} }
} }
_ => false, _ => false,
@ -437,68 +439,68 @@ impl<'le> ::selectors::Element for LayoutElement<'le> {
#[inline] #[inline]
fn get_hover_state(&self) -> bool { fn get_hover_state(&self) -> bool {
let node = NodeCast::from_layout_js(&self.element);
unsafe { unsafe {
let node: &Node = NodeCast::from_ref(self.element); (*node.unsafe_get()).get_hover_state_for_layout()
node.get_hover_state_for_layout()
} }
} }
#[inline] #[inline]
fn get_focus_state(&self) -> bool { fn get_focus_state(&self) -> bool {
let node = NodeCast::from_layout_js(&self.element);
unsafe { unsafe {
let node: &Node = NodeCast::from_ref(self.element); (*node.unsafe_get()).get_focus_state_for_layout()
node.get_focus_state_for_layout()
} }
} }
#[inline] #[inline]
fn get_id(&self) -> Option<Atom> { fn get_id(&self) -> Option<Atom> {
unsafe { unsafe {
self.element.get_attr_atom_for_layout(&ns!(""), &atom!("id")) (*self.element.unsafe_get()).get_attr_atom_for_layout(&ns!(""), &atom!("id"))
} }
} }
#[inline] #[inline]
fn get_disabled_state(&self) -> bool { fn get_disabled_state(&self) -> bool {
let node = NodeCast::from_layout_js(&self.element);
unsafe { unsafe {
let node: &Node = NodeCast::from_ref(self.element); (*node.unsafe_get()).get_disabled_state_for_layout()
node.get_disabled_state_for_layout()
} }
} }
#[inline] #[inline]
fn get_enabled_state(&self) -> bool { fn get_enabled_state(&self) -> bool {
let node = NodeCast::from_layout_js(&self.element);
unsafe { unsafe {
let node: &Node = NodeCast::from_ref(self.element); (*node.unsafe_get()).get_enabled_state_for_layout()
node.get_enabled_state_for_layout()
} }
} }
#[inline] #[inline]
fn get_checked_state(&self) -> bool { fn get_checked_state(&self) -> bool {
unsafe { unsafe {
self.element.get_checked_state_for_layout() (*self.element.unsafe_get()).get_checked_state_for_layout()
} }
} }
#[inline] #[inline]
fn get_indeterminate_state(&self) -> bool { fn get_indeterminate_state(&self) -> bool {
unsafe { unsafe {
self.element.get_indeterminate_state_for_layout() (*self.element.unsafe_get()).get_indeterminate_state_for_layout()
} }
} }
#[inline] #[inline]
fn has_class(&self, name: &Atom) -> bool { fn has_class(&self, name: &Atom) -> bool {
unsafe { unsafe {
self.element.has_class_for_layout(name) (*self.element.unsafe_get()).has_class_for_layout(name)
} }
} }
#[inline(always)] #[inline(always)]
fn each_class<F>(&self, mut callback: F) where F: FnMut(&Atom) { fn each_class<F>(&self, mut callback: F) where F: FnMut(&Atom) {
unsafe { unsafe {
match self.element.get_classes_for_layout() { match (*self.element.unsafe_get()).get_classes_for_layout() {
None => {} None => {}
Some(ref classes) => { Some(ref classes) => {
for class in classes.iter() { for class in classes.iter() {
@ -512,7 +514,7 @@ impl<'le> ::selectors::Element for LayoutElement<'le> {
#[inline] #[inline]
fn has_servo_nonzero_border(&self) -> bool { fn has_servo_nonzero_border(&self) -> bool {
unsafe { unsafe {
match self.element.get_attr_for_layout(&ns!(""), &atom!("border")) { match (*self.element.unsafe_get()).get_attr_for_layout(&ns!(""), &atom!("border")) {
None | Some(&AttrValue::UInt(_, 0)) => false, None | Some(&AttrValue::UInt(_, 0)) => false,
_ => true, _ => true,
} }
@ -537,7 +539,7 @@ impl<'le> ::selectors::Element for LayoutElement<'le> {
fn is_html_element_in_html_document(&self) -> bool { fn is_html_element_in_html_document(&self) -> bool {
unsafe { unsafe {
JS::from_ref(self.element).to_layout().html_element_in_html_document_for_layout() self.element.html_element_in_html_document_for_layout()
} }
} }
} }
@ -547,25 +549,27 @@ impl<'le> TElementAttributes for LayoutElement<'le> {
where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>> where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>
{ {
unsafe { unsafe {
self.element.synthesize_presentational_hints_for_legacy_attributes(hints); (*self.element.unsafe_get()).synthesize_presentational_hints_for_legacy_attributes(hints);
} }
} }
fn get_unsigned_integer_attribute(&self, attribute: UnsignedIntegerAttribute) -> Option<u32> { fn get_unsigned_integer_attribute(&self, attribute: UnsignedIntegerAttribute) -> Option<u32> {
unsafe { unsafe {
self.element.get_unsigned_integer_attribute_for_layout(attribute) (*self.element.unsafe_get()).get_unsigned_integer_attribute_for_layout(attribute)
} }
} }
#[inline] #[inline]
fn get_attr<'a>(&'a self, namespace: &Namespace, name: &Atom) -> Option<&'a str> { fn get_attr<'a>(&'a self, namespace: &Namespace, name: &Atom) -> Option<&'a str> {
unsafe { self.element.get_attr_val_for_layout(namespace, name) } unsafe {
(*self.element.unsafe_get()).get_attr_val_for_layout(namespace, name)
}
} }
#[inline] #[inline]
fn get_attrs<'a>(&'a self, name: &Atom) -> Vec<&'a str> { fn get_attrs<'a>(&'a self, name: &Atom) -> Vec<&'a str> {
unsafe { unsafe {
self.element.get_attr_vals_for_layout(name) (*self.element.unsafe_get()).get_attr_vals_for_layout(name)
} }
} }
} }