Privatize Element

This commit is contained in:
Tim Taubert 2014-10-13 11:11:05 +02:00
parent cd9de05088
commit cbe50f1f14
8 changed files with 72 additions and 41 deletions

View file

@ -425,7 +425,7 @@ pub struct LayoutElement<'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> {
let style: &Option<PropertyDeclarationBlock> = unsafe { let style: &Option<PropertyDeclarationBlock> = unsafe {
let style: &RefCell<Option<PropertyDeclarationBlock>> = &self.element.style_attribute; let style: &RefCell<Option<PropertyDeclarationBlock>> = self.element.style_attribute();
// cast to the direct reference to T placed on the head of RefCell<T> // cast to the direct reference to T placed on the head of RefCell<T>
mem::transmute(style) mem::transmute(style)
}; };
@ -436,12 +436,12 @@ impl<'le> LayoutElement<'le> {
impl<'le> TElement<'le> for LayoutElement<'le> { impl<'le> TElement<'le> for LayoutElement<'le> {
#[inline] #[inline]
fn get_local_name(self) -> &'le Atom { fn get_local_name(self) -> &'le Atom {
&self.element.local_name self.element.local_name()
} }
#[inline] #[inline]
fn get_namespace(self) -> &'le Namespace { fn get_namespace(self) -> &'le Namespace {
&self.element.namespace self.element.namespace()
} }
#[inline] #[inline]
@ -456,7 +456,7 @@ impl<'le> TElement<'le> for LayoutElement<'le> {
fn get_link(self) -> Option<&'le str> { fn get_link(self) -> Option<&'le str> {
// FIXME: This is HTML only. // FIXME: This is HTML only.
match self.element.node.type_id_for_layout() { match self.element.node().type_id_for_layout() {
// http://www.whatwg.org/specs/web-apps/current-work/multipage/selectors.html# // http://www.whatwg.org/specs/web-apps/current-work/multipage/selectors.html#
// selector-link // selector-link
ElementNodeTypeId(HTMLAnchorElementTypeId) | ElementNodeTypeId(HTMLAnchorElementTypeId) |
@ -470,7 +470,7 @@ impl<'le> TElement<'le> for LayoutElement<'le> {
fn get_hover_state(self) -> bool { fn get_hover_state(self) -> bool {
unsafe { unsafe {
self.element.node.get_hover_state_for_layout() self.element.node().get_hover_state_for_layout()
} }
} }
@ -481,13 +481,13 @@ impl<'le> TElement<'le> for LayoutElement<'le> {
fn get_disabled_state(self) -> bool { fn get_disabled_state(self) -> bool {
unsafe { unsafe {
self.element.node.get_disabled_state_for_layout() self.element.node().get_disabled_state_for_layout()
} }
} }
fn get_enabled_state(self) -> bool { fn get_enabled_state(self) -> bool {
unsafe { unsafe {
self.element.node.get_enabled_state_for_layout() self.element.node().get_enabled_state_for_layout()
} }
} }

View file

@ -35,7 +35,7 @@ use servo_util::namespace;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use std::cell::RefCell; use std::cell::{Ref, RefMut, RefCell};
use std::default::Default; use std::default::Default;
use std::mem; use std::mem;
use std::slice::Items; use std::slice::Items;
@ -44,14 +44,15 @@ use url::UrlParser;
#[jstraceable] #[jstraceable]
#[must_root] #[must_root]
#[privatize]
pub struct Element { pub struct Element {
pub node: Node, node: Node,
pub local_name: Atom, local_name: Atom,
pub namespace: Namespace, namespace: Namespace,
pub prefix: Option<DOMString>, prefix: Option<DOMString>,
pub attrs: RefCell<Vec<JS<Attr>>>, attrs: RefCell<Vec<JS<Attr>>>,
pub style_attribute: RefCell<Option<style::PropertyDeclarationBlock>>, style_attribute: RefCell<Option<style::PropertyDeclarationBlock>>,
pub attr_list: MutNullableJS<NamedNodeMap>, attr_list: MutNullableJS<NamedNodeMap>,
class_list: MutNullableJS<DOMTokenList>, class_list: MutNullableJS<DOMTokenList>,
} }
@ -171,6 +172,36 @@ impl Element {
pub fn node<'a>(&'a self) -> &'a Node { pub fn node<'a>(&'a self) -> &'a Node {
&self.node &self.node
} }
#[inline]
pub fn local_name<'a>(&'a self) -> &'a Atom {
&self.local_name
}
#[inline]
pub fn namespace<'a>(&'a self) -> &'a Namespace {
&self.namespace
}
#[inline]
pub fn prefix<'a>(&'a self) -> &'a Option<DOMString> {
&self.prefix
}
#[inline]
pub fn attrs(&self) -> Ref<Vec<JS<Attr>>> {
self.attrs.borrow()
}
#[inline]
pub fn attrs_mut(&self) -> RefMut<Vec<JS<Attr>>> {
self.attrs.borrow_mut()
}
#[inline]
pub fn style_attribute<'a>(&'a self) -> &'a RefCell<Option<style::PropertyDeclarationBlock>> {
&self.style_attribute
}
} }
pub trait RawLayoutElementHelpers { pub trait RawLayoutElementHelpers {

View file

@ -67,7 +67,7 @@ impl HTMLCollection {
fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool {
match self.namespace_filter { match self.namespace_filter {
None => true, None => true,
Some(ref namespace) => elem.namespace == *namespace Some(ref namespace) => *elem.namespace() == *namespace
} }
} }
} }
@ -89,9 +89,9 @@ impl HTMLCollection {
impl CollectionFilter for TagNameFilter { impl CollectionFilter for TagNameFilter {
fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool {
if elem.html_element_in_html_document() { if elem.html_element_in_html_document() {
elem.local_name == self.ascii_lower_tag *elem.local_name() == self.ascii_lower_tag
} else { } else {
elem.local_name == self.tag *elem.local_name() == self.tag
} }
} }
} }
@ -121,11 +121,11 @@ impl HTMLCollection {
fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool {
let ns_match = match self.namespace_filter { let ns_match = match self.namespace_filter {
Some(ref namespace) => { Some(ref namespace) => {
elem.namespace == *namespace *elem.namespace() == *namespace
}, },
None => true None => true
}; };
ns_match && elem.local_name == self.tag ns_match && *elem.local_name() == self.tag
} }
} }
let filter = TagNameNSFilter { let filter = TagNameNSFilter {

View file

@ -58,7 +58,7 @@ impl<'a> HTMLFieldSetElementMethods for JSRef<'a, HTMLFieldSetElement> {
static tag_names: StaticStringVec = &["button", "fieldset", "input", static tag_names: StaticStringVec = &["button", "fieldset", "input",
"keygen", "object", "output", "select", "textarea"]; "keygen", "object", "output", "select", "textarea"];
let root: JSRef<Element> = ElementCast::to_ref(root).unwrap(); let root: JSRef<Element> = ElementCast::to_ref(root).unwrap();
elem != root && tag_names.iter().any(|&tag_name| tag_name == elem.local_name.as_slice()) elem != root && tag_names.iter().any(|&tag_name| tag_name == elem.local_name().as_slice())
} }
} }
let node: JSRef<Node> = NodeCast::from_ref(self); let node: JSRef<Node> = NodeCast::from_ref(self);

View file

@ -51,7 +51,7 @@ impl HTMLOptionElement {
fn collect_text(node: &JSRef<Node>, value: &mut DOMString) { fn collect_text(node: &JSRef<Node>, value: &mut DOMString) {
let elem: JSRef<Element> = ElementCast::to_ref(*node).unwrap(); let elem: JSRef<Element> = ElementCast::to_ref(*node).unwrap();
let svg_script = elem.namespace == ns!(SVG) && elem.local_name.as_slice() == "script"; let svg_script = *elem.namespace() == ns!(SVG) && elem.local_name().as_slice() == "script";
let html_script = node.is_htmlscriptelement(); let html_script = node.is_htmlscriptelement();
if svg_script || html_script { if svg_script || html_script {
return; return;

View file

@ -78,10 +78,10 @@ fn serialize_text(text: JSRef<Text>, html: &mut String) {
match text_node.parent_node().map(|node| node.root()) { match text_node.parent_node().map(|node| node.root()) {
Some(ref parent) if parent.is_element() => { Some(ref parent) if parent.is_element() => {
let elem: JSRef<Element> = ElementCast::to_ref(**parent).unwrap(); let elem: JSRef<Element> = ElementCast::to_ref(**parent).unwrap();
match elem.local_name.as_slice() { match elem.local_name().as_slice() {
"style" | "script" | "xmp" | "iframe" | "style" | "script" | "xmp" | "iframe" |
"noembed" | "noframes" | "plaintext" | "noembed" | "noframes" | "plaintext" |
"noscript" if elem.namespace == ns!(HTML) "noscript" if *elem.namespace() == ns!(HTML)
=> html.push_str(text.characterdata().data().as_slice()), => html.push_str(text.characterdata().data().as_slice()),
_ => escape(text.characterdata().data().as_slice(), false, html) _ => escape(text.characterdata().data().as_slice(), false, html)
} }
@ -107,15 +107,15 @@ fn serialize_doctype(doctype: JSRef<DocumentType>, html: &mut String) {
fn serialize_elem(elem: JSRef<Element>, open_elements: &mut Vec<String>, html: &mut String) { fn serialize_elem(elem: JSRef<Element>, open_elements: &mut Vec<String>, html: &mut String) {
html.push_char('<'); html.push_char('<');
html.push_str(elem.local_name.as_slice()); html.push_str(elem.local_name().as_slice());
for attr in elem.attrs.borrow().iter() { for attr in elem.attrs().iter() {
let attr = attr.root(); let attr = attr.root();
serialize_attr(*attr, html); serialize_attr(*attr, html);
}; };
html.push_char('>'); html.push_char('>');
match elem.local_name.as_slice() { match elem.local_name().as_slice() {
"pre" | "listing" | "textarea" if elem.namespace == ns!(HTML) => { "pre" | "listing" | "textarea" if *elem.namespace() == ns!(HTML) => {
let node: JSRef<Node> = NodeCast::from_ref(elem); let node: JSRef<Node> = NodeCast::from_ref(elem);
match node.first_child().map(|child| child.root()) { match node.first_child().map(|child| child.root()) {
Some(ref child) if child.is_text() => { Some(ref child) if child.is_text() => {
@ -131,7 +131,7 @@ fn serialize_elem(elem: JSRef<Element>, open_elements: &mut Vec<String>, html: &
} }
if !(elem.is_void()) { if !(elem.is_void()) {
open_elements.push(elem.local_name.as_slice().to_string()); open_elements.push(elem.local_name().as_slice().to_string());
} }
} }

View file

@ -35,11 +35,11 @@ impl NamedNodeMap {
impl<'a> NamedNodeMapMethods for JSRef<'a, NamedNodeMap> { impl<'a> NamedNodeMapMethods for JSRef<'a, NamedNodeMap> {
fn Length(self) -> u32 { fn Length(self) -> u32 {
self.owner.root().attrs.borrow().len() as u32 self.owner.root().attrs().len() as u32
} }
fn Item(self, index: u32) -> Option<Temporary<Attr>> { fn Item(self, index: u32) -> Option<Temporary<Attr>> {
self.owner.root().attrs.borrow().as_slice().get(index as uint).map(|x| Temporary::new(x.clone())) self.owner.root().attrs().as_slice().get(index as uint).map(|x| Temporary::new(x.clone()))
} }
fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Temporary<Attr>> { fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Temporary<Attr>> {

View file

@ -1501,8 +1501,8 @@ impl Node {
}, },
ElementNodeTypeId(..) => { ElementNodeTypeId(..) => {
let element: JSRef<Element> = ElementCast::to_ref(node).unwrap(); let element: JSRef<Element> = ElementCast::to_ref(node).unwrap();
let element = build_element_from_tag(element.local_name.as_slice().to_string(), let element = build_element_from_tag(element.local_name().as_slice().to_string(),
element.namespace.clone(), Some(element.prefix.as_slice().to_string()), *document); element.namespace().clone(), Some(element.prefix().as_slice().to_string()), *document);
NodeCast::from_temporary(element) NodeCast::from_temporary(element)
}, },
TextNodeTypeId => { TextNodeTypeId => {
@ -1541,8 +1541,8 @@ impl Node {
// FIXME: https://github.com/mozilla/servo/issues/1737 // FIXME: https://github.com/mozilla/servo/issues/1737
let window = document.window().root(); let window = document.window().root();
for attr in node_elem.attrs.borrow().iter().map(|attr| attr.root()) { for attr in node_elem.attrs().iter().map(|attr| attr.root()) {
copy_elem.attrs.borrow_mut().push_unrooted( copy_elem.attrs_mut().push_unrooted(
&Attr::new(*window, &Attr::new(*window,
attr.local_name().clone(), attr.value().clone(), attr.local_name().clone(), attr.value().clone(),
attr.name().clone(), attr.namespace().clone(), attr.name().clone(), attr.namespace().clone(),
@ -1983,9 +1983,9 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
let element: JSRef<Element> = ElementCast::to_ref(node).unwrap(); let element: JSRef<Element> = ElementCast::to_ref(node).unwrap();
let other_element: JSRef<Element> = ElementCast::to_ref(other).unwrap(); let other_element: JSRef<Element> = ElementCast::to_ref(other).unwrap();
// FIXME: namespace prefix // FIXME: namespace prefix
(element.namespace == other_element.namespace) && (*element.namespace() == *other_element.namespace()) &&
(element.local_name == other_element.local_name) && (*element.local_name() == *other_element.local_name()) &&
(element.attrs.borrow().len() == other_element.attrs.borrow().len()) (element.attrs().len() == other_element.attrs().len())
} }
fn is_equal_processinginstruction(node: JSRef<Node>, other: JSRef<Node>) -> bool { fn is_equal_processinginstruction(node: JSRef<Node>, other: JSRef<Node>) -> bool {
let pi: JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap(); let pi: JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap();
@ -2001,9 +2001,9 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
fn is_equal_element_attrs(node: JSRef<Node>, other: JSRef<Node>) -> bool { fn is_equal_element_attrs(node: JSRef<Node>, other: JSRef<Node>) -> bool {
let element: JSRef<Element> = ElementCast::to_ref(node).unwrap(); let element: JSRef<Element> = ElementCast::to_ref(node).unwrap();
let other_element: JSRef<Element> = ElementCast::to_ref(other).unwrap(); let other_element: JSRef<Element> = ElementCast::to_ref(other).unwrap();
assert!(element.attrs.borrow().len() == other_element.attrs.borrow().len()); assert!(element.attrs().len() == other_element.attrs().len());
element.attrs.borrow().iter().map(|attr| attr.root()).all(|attr| { element.attrs().iter().map(|attr| attr.root()).all(|attr| {
other_element.attrs.borrow().iter().map(|attr| attr.root()).any(|other_attr| { other_element.attrs().iter().map(|attr| attr.root()).any(|other_attr| {
(*attr.namespace() == *other_attr.namespace()) && (*attr.namespace() == *other_attr.namespace()) &&
(attr.local_name() == other_attr.local_name()) && (attr.local_name() == other_attr.local_name()) &&
(attr.value().as_slice() == other_attr.value().as_slice()) (attr.value().as_slice() == other_attr.value().as_slice())