Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a safe, mostly-sound rooting rooting strategy. #2101

Merged
merged 16 commits into from May 3, 2014
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Fix up the virtual method unsoundness.

  • Loading branch information
jdm committed May 3, 2014
commit 46a33b4b38666252245af5dd3a38bb6f57ff8a8e
@@ -65,8 +65,8 @@ impl Attr {
}

pub fn set_value(&mut self, set_type: AttrSettingType, value: DOMString) {
let owner = self.owner.root();
let node: &JSRef<Node> = NodeCast::from_ref(&*owner);
let mut owner = self.owner.root();
let node: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut *owner);
let namespace_is_null = self.namespace == namespace::Null;

match set_type {
@@ -301,13 +301,14 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
None => (),
Some(idx) => {
{
let node: &JSRef<Node> = NodeCast::from_ref(self);
let node: &mut JSRef<Node> = NodeCast::from_mut_ref(self);
node.wait_until_safe_to_modify_dom();
}

if namespace == namespace::Null {
let removed_raw_value = self.get().attrs.get(idx).root().Value();
vtable_for(NodeCast::from_ref(self)).before_remove_attr(local_name.clone(), removed_raw_value);
vtable_for(NodeCast::from_mut_ref(self))
.before_remove_attr(local_name.clone(), removed_raw_value);
}

self.get_mut().attrs.remove(idx);
@@ -244,24 +244,25 @@ impl<'a> PrivateNodeHelpers for JSRef<'a, Node> {
let document = document_from_node(self).root();

if self.is_in_doc() {
for node in self.traverse_preorder() {
vtable_for(&node).bind_to_tree();
for mut node in self.traverse_preorder() {
vtable_for(&mut node).bind_to_tree();
}
}

self.parent_node().root().map(|parent| vtable_for(&*parent).child_inserted(self));
let mut parent = self.parent_node().root();
parent.as_mut().map(|parent| vtable_for(&mut **parent).child_inserted(self));

document.deref().content_changed();
}

// http://dom.spec.whatwg.org/#node-is-removed
// http://spec.whatwg.org/#node-is-removed
fn node_removed(&self) {
assert!(self.parent_node().is_none());
let document = document_from_node(self).root();

for node in self.traverse_preorder() {
for mut node in self.traverse_preorder() {
// XXX how about if the node wasn't in the tree in the first place?
vtable_for(&node).unbind_from_tree();
vtable_for(&mut node).unbind_from_tree();
}

document.deref().content_changed();
@@ -74,34 +74,34 @@ pub trait VirtualMethods {
/// method call on the trait object will invoke the corresponding method on the
/// concrete type, propagating up the parent hierarchy unless otherwise
/// interrupted.
pub fn vtable_for<'a>(node: &JSRef<Node>) -> ~VirtualMethods: {
pub fn vtable_for<'a>(node: &'a mut JSRef<Node>) -> &'a mut VirtualMethods: {
match node.get().type_id {
ElementNodeTypeId(HTMLImageElementTypeId) => {
let element: &JSRef<HTMLImageElement> = HTMLImageElementCast::to_ref(node).unwrap();
~element.clone() as ~VirtualMethods:
let element: &mut JSRef<HTMLImageElement> = HTMLImageElementCast::to_mut_ref(node).unwrap();
element as &mut VirtualMethods:
}
ElementNodeTypeId(HTMLIFrameElementTypeId) => {
let element: &JSRef<HTMLIFrameElement> = HTMLIFrameElementCast::to_ref(node).unwrap();
~element.clone() as ~VirtualMethods:
let element: &mut JSRef<HTMLIFrameElement> = HTMLIFrameElementCast::to_mut_ref(node).unwrap();
element as &mut VirtualMethods:
}
ElementNodeTypeId(HTMLObjectElementTypeId) => {
let element: &JSRef<HTMLObjectElement> = HTMLObjectElementCast::to_ref(node).unwrap();
~element.clone() as ~VirtualMethods:
let element: &mut JSRef<HTMLObjectElement> = HTMLObjectElementCast::to_mut_ref(node).unwrap();
element as &mut VirtualMethods:
}
ElementNodeTypeId(HTMLStyleElementTypeId) => {
let element: &JSRef<HTMLStyleElement> = HTMLStyleElementCast::to_ref(node).unwrap();
~element.clone() as ~VirtualMethods:
let element: &mut JSRef<HTMLStyleElement> = HTMLStyleElementCast::to_mut_ref(node).unwrap();
element as &mut VirtualMethods:
}
ElementNodeTypeId(ElementTypeId) => {
let element: &JSRef<Element> = ElementCast::to_ref(node).unwrap();
~element.clone() as ~VirtualMethods:
let element: &mut JSRef<Element> = ElementCast::to_mut_ref(node).unwrap();
element as &mut VirtualMethods:
}
ElementNodeTypeId(_) => {
let element: &JSRef<HTMLElement> = HTMLElementCast::to_ref(node).unwrap();
~element.clone() as ~VirtualMethods:
let element: &mut JSRef<HTMLElement> = HTMLElementCast::to_mut_ref(node).unwrap();
element as &mut VirtualMethods:
}
_ => {
~node.clone() as ~VirtualMethods:
node as &mut VirtualMethods:
}
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.