aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTetsuharu OHZEKI <saneyuki.snyk@gmail.com>2014-05-28 05:15:00 +0900
committerTetsuharu OHZEKI <saneyuki.snyk@gmail.com>2014-05-30 03:53:07 +0900
commitb0239b5a5ade3723d08ec59c5ca6a03f561d26fd (patch)
treefb287feae5731d3ba6ecb1478c3eba414f89a07f /src
parent6d9dcd087a032ee2962d0e27223a076fcbc72298 (diff)
downloadservo-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.rs33
-rw-r--r--src/components/script/dom/htmlserializer.rs2
-rw-r--r--src/components/script/dom/node.rs20
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)