diff options
author | Tetsuharu OHZEKI <saneyuki.snyk@gmail.com> | 2014-05-28 05:15:00 +0900 |
---|---|---|
committer | Tetsuharu OHZEKI <saneyuki.snyk@gmail.com> | 2014-05-30 03:53:07 +0900 |
commit | b0239b5a5ade3723d08ec59c5ca6a03f561d26fd (patch) | |
tree | fb287feae5731d3ba6ecb1478c3eba414f89a07f /src | |
parent | 6d9dcd087a032ee2962d0e27223a076fcbc72298 (diff) | |
download | servo-b0239b5a5ade3723d08ec59c5ca6a03f561d26fd.tar.gz servo-b0239b5a5ade3723d08ec59c5ca6a03f561d26fd.zip |
Use Cell/RefCell for interior mutability of Element.
Diffstat (limited to 'src')
-rw-r--r-- | src/components/script/dom/element.rs | 33 | ||||
-rw-r--r-- | src/components/script/dom/htmlserializer.rs | 2 | ||||
-rw-r--r-- | src/components/script/dom/node.rs | 20 |
3 files changed, 31 insertions, 24 deletions
diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index 0a6320b5bb0..d694b3724fc 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -31,6 +31,7 @@ use servo_util::str::{DOMString, null_str_as_empty_ref, split_html_space_chars}; use std::ascii::StrAsciiExt; use std::cast; +use std::cell::{Cell, RefCell}; #[deriving(Encodable)] pub struct Element { @@ -38,9 +39,9 @@ pub struct Element { pub local_name: DOMString, // TODO: This should be an atom, not a DOMString. pub namespace: Namespace, pub prefix: Option<DOMString>, - pub attrs: Vec<JS<Attr>>, + pub attrs: RefCell<Vec<JS<Attr>>>, pub style_attribute: Option<style::PropertyDeclarationBlock>, - pub attr_list: Option<JS<AttrList>> + pub attr_list: Cell<Option<JS<AttrList>>> } impl ElementDerived for EventTarget { @@ -147,8 +148,8 @@ impl Element { local_name: local_name, namespace: namespace, prefix: prefix, - attrs: vec!(), - attr_list: None, + attrs: RefCell::new(vec!()), + attr_list: Cell::new(None), style_attribute: None, } } @@ -167,7 +168,9 @@ impl RawLayoutElementHelpers for Element { #[inline] unsafe fn get_attr_val_for_layout(&self, namespace: &Namespace, name: &str) -> Option<&'static str> { - self.attrs.iter().find(|attr: & &JS<Attr>| { + // cast to point to T in RefCell<T> directly + let attrs: *Vec<JS<Attr>> = cast::transmute(&self.attrs); + (*attrs).iter().find(|attr: & &JS<Attr>| { let attr = attr.unsafe_get(); name == (*attr).local_name && (*attr).namespace == *namespace }).map(|attr| { @@ -232,7 +235,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { let element: &Element = self.deref(); let is_html_element = self.html_element_in_html_document(); - element.attrs.iter().map(|attr| attr.root()).find(|attr| { + element.attrs.borrow().iter().map(|attr| attr.root()).find(|attr| { let same_name = if is_html_element { name.to_ascii_lower() == attr.local_name } else { @@ -284,7 +287,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { fn do_set_attribute(&mut self, local_name: DOMString, value: DOMString, name: DOMString, namespace: Namespace, prefix: Option<DOMString>, cb: |&JSRef<Attr>| -> bool) { - let idx = self.deref().attrs.iter() + let idx = self.deref().attrs.borrow().iter() .map(|attr| attr.root()) .position(|attr| cb(&*attr)); let (idx, set_type) = match idx { @@ -293,18 +296,18 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { let window = window_from_node(self).root(); let attr = Attr::new(&*window, local_name.clone(), value.clone(), name, namespace.clone(), prefix, self); - self.deref_mut().attrs.push_unrooted(&attr); - (self.deref().attrs.len() - 1, FirstSetAttr) + self.deref().attrs.borrow_mut().push_unrooted(&attr); + (self.deref().attrs.borrow().len() - 1, FirstSetAttr) } }; - self.deref_mut().attrs.get(idx).root().set_value(set_type, value); + self.deref().attrs.borrow().get(idx).root().set_value(set_type, value); } fn remove_attribute(&mut self, namespace: Namespace, name: DOMString) -> ErrorResult { let (_, local_name) = get_attribute_parts(name.clone()); - let idx = self.deref().attrs.iter().map(|attr| attr.root()).position(|attr| { + let idx = self.deref().attrs.borrow().iter().map(|attr| attr.root()).position(|attr| { attr.local_name == local_name }); @@ -317,12 +320,12 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } if namespace == namespace::Null { - let removed_raw_value = self.deref().attrs.get(idx).root().Value(); + let removed_raw_value = self.deref().attrs.borrow().get(idx).root().Value(); vtable_for(NodeCast::from_mut_ref(self)) .before_remove_attr(local_name.clone(), removed_raw_value); } - self.deref_mut().attrs.remove(idx); + self.deref().attrs.borrow_mut().remove(idx); } }; @@ -469,7 +472,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> { // http://dom.spec.whatwg.org/#dom-element-attributes fn Attributes(&mut self) -> Temporary<AttrList> { - match self.attr_list { + match self.attr_list.get() { None => (), Some(ref list) => return Temporary::new(list.clone()), } @@ -481,7 +484,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> { let window = doc.deref().window.root(); let list = AttrList::new(&*window, self); self.attr_list.assign(Some(list)); - Temporary::new(self.attr_list.get_ref().clone()) + Temporary::new(self.attr_list.get().get_ref().clone()) } // http://dom.spec.whatwg.org/#dom-element-getattribute diff --git a/src/components/script/dom/htmlserializer.rs b/src/components/script/dom/htmlserializer.rs index 817f84f91a6..ea33f79fee0 100644 --- a/src/components/script/dom/htmlserializer.rs +++ b/src/components/script/dom/htmlserializer.rs @@ -106,7 +106,7 @@ fn serialize_doctype(doctype: &JSRef<DocumentType>, html: &mut StrBuf) { fn serialize_elem(elem: &JSRef<Element>, open_elements: &mut Vec<~str>, html: &mut StrBuf) { html.push_char('<'); html.push_str(elem.deref().local_name); - for attr in elem.deref().attrs.iter() { + for attr in elem.deref().attrs.borrow().iter() { let attr = attr.root(); serialize_attr(&*attr, html); }; diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index 1a9c70f2806..9cf721d389d 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -1297,8 +1297,8 @@ impl Node { // FIXME: https://github.com/mozilla/servo/issues/1737 copy_elem.namespace = node_elem.namespace.clone(); let window = document.deref().window.root(); - for attr in node_elem.attrs.iter().map(|attr| attr.root()) { - copy_elem.attrs.push_unrooted( + for attr in node_elem.attrs.borrow().iter().map(|attr| attr.root()) { + copy_elem.attrs.borrow_mut().push_unrooted( &Attr::new(&*window, attr.deref().local_name.clone(), attr.deref().value.clone(), attr.deref().name.clone(), attr.deref().namespace.clone(), @@ -1766,9 +1766,11 @@ impl<'a> NodeMethods for JSRef<'a, Node> { let element: &JSRef<Element> = ElementCast::to_ref(node).unwrap(); let other_element: &JSRef<Element> = ElementCast::to_ref(other).unwrap(); // FIXME: namespace prefix - (element.deref().namespace == other_element.deref().namespace) && - (element.deref().local_name == other_element.deref().local_name) && - (element.deref().attrs.len() == other_element.deref().attrs.len()) + let element = element.deref(); + let other_element = other_element.deref(); + (element.namespace == other_element.namespace) && + (element.local_name == other_element.local_name) && + (element.attrs.borrow().len() == other_element.attrs.borrow().len()) } fn is_equal_processinginstruction(node: &JSRef<Node>, other: &JSRef<Node>) -> bool { let pi: &JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap(); @@ -1784,9 +1786,11 @@ impl<'a> NodeMethods for JSRef<'a, Node> { fn is_equal_element_attrs(node: &JSRef<Node>, other: &JSRef<Node>) -> bool { let element: &JSRef<Element> = ElementCast::to_ref(node).unwrap(); let other_element: &JSRef<Element> = ElementCast::to_ref(other).unwrap(); - assert!(element.deref().attrs.len() == other_element.deref().attrs.len()); - element.deref().attrs.iter().map(|attr| attr.root()).all(|attr| { - other_element.deref().attrs.iter().map(|attr| attr.root()).any(|other_attr| { + let element = element.deref(); + let other_element = other_element.deref(); + assert!(element.attrs.borrow().len() == other_element.attrs.borrow().len()); + element.attrs.borrow().iter().map(|attr| attr.root()).all(|attr| { + other_element.attrs.borrow().iter().map(|attr| attr.root()).any(|other_attr| { (attr.namespace == other_attr.namespace) && (attr.local_name == other_attr.local_name) && (attr.value == other_attr.value) |