diff options
author | Josh Matthews <josh@joshmatthews.net> | 2013-11-30 21:04:49 +0100 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2014-02-24 15:16:42 -0500 |
commit | 625325434b5c7dc72e784a592f7e014c16cf1018 (patch) | |
tree | 9078f192cd7f41132a64124b7f70a3bb51e0936d | |
parent | 061269f9639199a7419e2467ebbe3c28cac1e8ff (diff) | |
download | servo-625325434b5c7dc72e784a592f7e014c16cf1018.tar.gz servo-625325434b5c7dc72e784a592f7e014c16cf1018.zip |
Implement JSManaged for DOM objects.
137 files changed, 3624 insertions, 2758 deletions
diff --git a/src/components/main/css/matching.rs b/src/components/main/css/matching.rs index 0f56c74fdfc..687a08efdd4 100644 --- a/src/components/main/css/matching.rs +++ b/src/components/main/css/matching.rs @@ -381,7 +381,7 @@ impl<'ln> PrivateMatchMethods for LayoutNode<'ln> { assert!(self.is_element()); let parent_node = match parent_node { - Some(parent_node) if parent_node.is_element() => parent_node, + Some(ref parent_node) if parent_node.is_element() => parent_node, Some(_) | None => return None, }; @@ -455,7 +455,7 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { } for (i, &(ref candidate, ())) in style_sharing_candidate_cache.iter().enumerate() { - match self.share_style_with_candidate_if_possible(parent, candidate) { + match self.share_style_with_candidate_if_possible(parent.clone(), candidate) { Some(shared_style) => { // Yay, cache hit. Share the style. let mut layout_data_ref = self.mutate_layout_data(); @@ -486,7 +486,7 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { // First, check to see whether we can share a style with someone. let sharing_result = unsafe { - self.share_style_if_possible(style_sharing_candidate_cache, parent) + self.share_style_if_possible(style_sharing_candidate_cache, parent.clone()) }; // Otherwise, match and cascade selectors. @@ -520,7 +520,7 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { initial_values, applicable_declarations_cache, style_sharing_candidate_cache, - Some(*self)) + Some(self.clone())) } } diff --git a/src/components/main/css/node_util.rs b/src/components/main/css/node_util.rs index 7493281d5cc..a14c2901452 100644 --- a/src/components/main/css/node_util.rs +++ b/src/components/main/css/node_util.rs @@ -12,10 +12,10 @@ use style::ComputedValues; pub trait NodeUtil { fn get_css_select_results<'a>(&'a self) -> &'a Arc<ComputedValues>; - fn have_css_select_results(self) -> bool; + fn have_css_select_results(&self) -> bool; - fn get_restyle_damage(self) -> RestyleDamage; - fn set_restyle_damage(self, damage: RestyleDamage); + fn get_restyle_damage(&self) -> RestyleDamage; + fn set_restyle_damage(&self, damage: RestyleDamage); } impl<'ln> NodeUtil for ThreadSafeLayoutNode<'ln> { @@ -36,14 +36,14 @@ impl<'ln> NodeUtil for ThreadSafeLayoutNode<'ln> { } /// Does this node have a computed style yet? - fn have_css_select_results(self) -> bool { + fn have_css_select_results(&self) -> bool { let layout_data_ref = self.borrow_layout_data(); layout_data_ref.get().get_ref().data.style.is_some() } /// Get the description of how to account for recent style changes. /// This is a simple bitfield and fine to copy by value. - fn get_restyle_damage(self) -> RestyleDamage { + fn get_restyle_damage(&self) -> RestyleDamage { // For DOM elements, if we haven't computed damage yet, assume the worst. // Other nodes don't have styles. let default = if self.node_is_element() { @@ -63,7 +63,7 @@ impl<'ln> NodeUtil for ThreadSafeLayoutNode<'ln> { } /// Set the restyle damage field. - fn set_restyle_damage(self, damage: RestyleDamage) { + fn set_restyle_damage(&self, damage: RestyleDamage) { let mut layout_data_ref = self.mutate_layout_data(); match *layout_data_ref.get() { Some(ref mut layout_data) => layout_data.data.restyle_damage = Some(damage.to_int()), diff --git a/src/components/main/layout/block.rs b/src/components/main/layout/block.rs index 607a85c2b7b..94c8d2c3947 100644 --- a/src/components/main/layout/block.rs +++ b/src/components/main/layout/block.rs @@ -68,7 +68,7 @@ pub struct BlockFlow { } impl BlockFlow { - pub fn from_node(constructor: &mut FlowConstructor, node: ThreadSafeLayoutNode, is_fixed: bool) + pub fn from_node(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode, is_fixed: bool) -> BlockFlow { BlockFlow { base: BaseFlow::new(constructor.next_flow_id(), node), @@ -80,7 +80,7 @@ impl BlockFlow { } pub fn float_from_node(constructor: &mut FlowConstructor, - node: ThreadSafeLayoutNode, + node: &ThreadSafeLayoutNode, float_type: FloatType) -> BlockFlow { BlockFlow { diff --git a/src/components/main/layout/box_.rs b/src/components/main/layout/box_.rs index d0386cdb48a..ff6ccaf93b6 100644 --- a/src/components/main/layout/box_.rs +++ b/src/components/main/layout/box_.rs @@ -384,9 +384,9 @@ def_noncontent_horiz!(right, merge_noncontent_inline_right, clear_noncontent_inl impl Box { /// Constructs a new `Box` instance. - pub fn new(constructor: &mut FlowConstructor, node: ThreadSafeLayoutNode) -> Box { + pub fn new(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode) -> Box { Box { - node: OpaqueNode::from_thread_safe_layout_node(&node), + node: OpaqueNode::from_thread_safe_layout_node(node), style: node.style().clone(), border_box: RefCell::new(Au::zero_rect()), border: RefCell::new(Zero::zero()), diff --git a/src/components/main/layout/construct.rs b/src/components/main/layout/construct.rs index 41b38577599..7ca32d95f64 100644 --- a/src/components/main/layout/construct.rs +++ b/src/components/main/layout/construct.rs @@ -34,10 +34,13 @@ use layout::util::{LayoutDataAccess, OpaqueNode}; use layout::wrapper::{PostorderNodeMutTraversal, TLayoutNode, ThreadSafeLayoutNode}; use gfx::font_context::FontContext; +use script::dom::bindings::codegen::InheritTypes::TextCast; +use script::dom::bindings::js::JS; use script::dom::element::{HTMLIframeElementTypeId, HTMLImageElementTypeId, HTMLObjectElementTypeId}; use script::dom::node::{CommentNodeTypeId, DoctypeNodeTypeId, DocumentFragmentNodeTypeId}; use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, ProcessingInstructionNodeTypeId}; use script::dom::node::{TextNodeTypeId}; +use script::dom::text::Text; use style::computed_values::{display, position, float, white_space}; use style::ComputedValues; use servo_util::namespace; @@ -251,27 +254,27 @@ impl<'fc> FlowConstructor<'fc> { } /// Builds the `ImageBoxInfo` for the given image. This is out of line to guide inlining. - fn build_box_info_for_image(&mut self, node: ThreadSafeLayoutNode, url: Option<Url>) -> SpecificBoxInfo { + fn build_box_info_for_image(&mut self, node: &ThreadSafeLayoutNode, url: Option<Url>) -> SpecificBoxInfo { match url { None => GenericBox, Some(url) => { // FIXME(pcwalton): The fact that image boxes store the cache within them makes // little sense to me. - ImageBox(ImageBoxInfo::new(&node, url, self.layout_context.image_cache.clone())) + ImageBox(ImageBoxInfo::new(node, url, self.layout_context.image_cache.clone())) } } } /// Builds specific `Box` info for the given node. - pub fn build_specific_box_info_for_node(&mut self, node: ThreadSafeLayoutNode) + pub fn build_specific_box_info_for_node(&mut self, node: &ThreadSafeLayoutNode) -> SpecificBoxInfo { match node.type_id() { ElementNodeTypeId(HTMLImageElementTypeId) => self.build_box_info_for_image(node, node.image_url()), - ElementNodeTypeId(HTMLIframeElementTypeId) => IframeBox(IframeBoxInfo::new(&node)), + ElementNodeTypeId(HTMLIframeElementTypeId) => IframeBox(IframeBoxInfo::new(node)), ElementNodeTypeId(HTMLObjectElementTypeId) => { self.build_box_info_for_image(node, node.get_object_data(self.url)) } - TextNodeTypeId => UnscannedTextBox(UnscannedTextBoxInfo::new(&node)), + TextNodeTypeId => UnscannedTextBox(UnscannedTextBoxInfo::new(node)), _ => GenericBox, } } @@ -284,7 +287,7 @@ impl<'fc> FlowConstructor<'fc> { fn flush_inline_boxes_to_flow(&mut self, boxes: ~[Box], flow: &mut ~Flow, - node: ThreadSafeLayoutNode) { + node: &ThreadSafeLayoutNode) { if boxes.len() == 0 { return } @@ -301,7 +304,7 @@ impl<'fc> FlowConstructor<'fc> { fn flush_inline_boxes_to_flow_if_necessary(&mut self, opt_boxes: &mut Option<~[Box]>, flow: &mut ~Flow, - node: ThreadSafeLayoutNode) { + node: &ThreadSafeLayoutNode) { let opt_boxes = util::replace(opt_boxes, None); if opt_boxes.len() > 0 { self.flush_inline_boxes_to_flow(opt_boxes.to_vec(), flow, node) @@ -311,7 +314,7 @@ impl<'fc> FlowConstructor<'fc> { /// Builds the children flows underneath a node with `display: block`. After this call, /// other `BlockFlow`s or `InlineFlow`s will be populated underneath this node, depending on /// whether {ib} splits needed to happen. - fn build_children_of_block_flow(&mut self, flow: &mut ~Flow, node: ThreadSafeLayoutNode) { + fn build_children_of_block_flow(&mut self, flow: &mut ~Flow, node: &ThreadSafeLayoutNode) { // Gather up boxes for the inline flows we might need to create. let mut opt_boxes_for_inline_flow = None; let mut first_box = true; @@ -406,7 +409,7 @@ impl<'fc> FlowConstructor<'fc> { /// Builds a flow for a node with `display: block`. This yields a `BlockFlow` with possibly /// other `BlockFlow`s or `InlineFlow`s underneath it, depending on whether {ib} splits needed /// to happen. - fn build_flow_for_block(&mut self, node: ThreadSafeLayoutNode, is_fixed: bool) -> ~Flow { + fn build_flow_for_block(&mut self, node: &ThreadSafeLayoutNode, is_fixed: bool) -> ~Flow { let mut flow = ~BlockFlow::from_node(self, node, is_fixed) as ~Flow; self.build_children_of_block_flow(&mut flow, node); flow @@ -414,7 +417,7 @@ impl<'fc> FlowConstructor<'fc> { /// Builds the flow for a node with `float: {left|right}`. This yields a float `BlockFlow` with /// a `BlockFlow` underneath it. - fn build_flow_for_floated_block(&mut self, node: ThreadSafeLayoutNode, float_type: FloatType) + fn build_flow_for_floated_block(&mut self, node: &ThreadSafeLayoutNode, float_type: FloatType) -> ~Flow { let mut flow = ~BlockFlow::float_from_node(self, node, float_type) as ~Flow; self.build_children_of_block_flow(&mut flow, node); @@ -425,7 +428,7 @@ impl<'fc> FlowConstructor<'fc> { /// Concatenates the boxes of kids, adding in our own borders/padding/margins if necessary. /// Returns the `InlineBoxesConstructionResult`, if any. There will be no /// `InlineBoxesConstructionResult` if this node consisted entirely of ignorable whitespace. - fn build_boxes_for_nonreplaced_inline_content(&mut self, node: ThreadSafeLayoutNode) + fn build_boxes_for_nonreplaced_inline_content(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult { let mut opt_inline_block_splits = None; let mut opt_box_accumulator = None; @@ -542,7 +545,7 @@ impl<'fc> FlowConstructor<'fc> { fn set_inline_info_for_inline_child(&mut self, boxes: &~[&Box], - parent_node: ThreadSafeLayoutNode) { + parent_node: &ThreadSafeLayoutNode) { let parent_box = Box::new(self, parent_node); let font_style = parent_box.font_style(); let font_group = self.font_context.get_resolved_font_for_style(&font_style); @@ -580,7 +583,7 @@ impl<'fc> FlowConstructor<'fc> { style: parent_box.style.clone(), font_ascent: font_ascent, font_descent: font_descent, - node: OpaqueNode::from_thread_safe_layout_node(&parent_node), + node: OpaqueNode::from_thread_safe_layout_node(parent_node), }); }, &None => {} @@ -589,7 +592,7 @@ impl<'fc> FlowConstructor<'fc> { } /// Creates an `InlineBoxesConstructionResult` for replaced content. Replaced content doesn't /// render its children, so this just nukes a child's boxes and creates a `Box`. - fn build_boxes_for_replaced_inline_content(&mut self, node: ThreadSafeLayoutNode) + fn build_boxes_for_replaced_inline_content(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult { for kid in node.children() { kid.set_flow_construction_result(NoConstructionResult) @@ -597,7 +600,7 @@ impl<'fc> FlowConstructor<'fc> { // If this node is ignorable whitespace, bail out now. if node.is_ignorable_whitespace() { - let opaque_node = OpaqueNode::from_thread_safe_layout_node(&node); + let opaque_node = OpaqueNode::from_thread_safe_layout_node(node); return ConstructionItemConstructionResult(WhitespaceConstructionItem( opaque_node, node.style().clone())) @@ -614,7 +617,7 @@ impl<'fc> FlowConstructor<'fc> { /// Builds one or more boxes for a node with `display: inline`. This yields an /// `InlineBoxesConstructionResult`. - fn build_boxes_for_inline(&mut self, node: ThreadSafeLayoutNode) -> ConstructionResult { + fn build_boxes_for_inline(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult { // Is this node replaced content? if !node.is_replaced_content() { // Go to a path that concatenates our kids' boxes. @@ -630,7 +633,7 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> { // `#[inline(always)]` because this is always called from the traversal function and for some // reason LLVM's inlining heuristics go awry here. #[inline(always)] - fn process(&mut self, node: ThreadSafeLayoutNode) -> bool { + fn process(&mut self, node: &ThreadSafeLayoutNode) -> bool { // Get the `display` property for this node, and determine whether this node is floated. let (display, float, position) = match node.type_id() { ElementNodeTypeId(_) => { @@ -693,21 +696,21 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> { /// A utility trait with some useful methods for node queries. trait NodeUtils { /// Returns true if this node doesn't render its kids and false otherwise. - fn is_replaced_content(self) -> bool; + fn is_replaced_content(&self) -> bool; /// Returns true if this node is ignorable whitespace. - fn is_ignorable_whitespace(self) -> bool; + fn is_ignorable_whitespace(&self) -> bool; /// Sets the construction result of a flow. - fn set_flow_construction_result(self, result: ConstructionResult); + fn set_flow_construction_result(&self, result: ConstructionResult); /// Replaces the flow construction result in a node with `NoConstructionResult` and returns the /// old value. - fn swap_out_construction_result(self) -> ConstructionResult; + fn swap_out_construction_result(&self) -> ConstructionResult; } impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> { - fn is_replaced_content(self) -> bool { + fn is_replaced_content(&self) -> bool { match self.type_id() { TextNodeTypeId | ProcessingInstructionNodeTypeId | @@ -721,11 +724,12 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> { } } - fn is_ignorable_whitespace(self) -> bool { + fn is_ignorable_whitespace(&self) -> bool { match self.type_id() { TextNodeTypeId => { unsafe { - if !self.with_text(|text| is_whitespace(text.characterdata.data)) { + let text: JS<Text> = TextCast::to(self.get_jsmanaged()); + if !is_whitespace(text.get().characterdata.data) { return false } @@ -746,7 +750,7 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> { } #[inline(always)] - fn set_flow_construction_result(self, result: ConstructionResult) { + fn set_flow_construction_result(&self, result: ConstructionResult) { let mut layout_data_ref = self.mutate_layout_data(); match *layout_data_ref.get() { Some(ref mut layout_data) => layout_data.data.flow_construction_result = result, @@ -755,7 +759,7 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> { } #[inline(always)] - fn swap_out_construction_result(self) -> ConstructionResult { + fn swap_out_construction_result(&self) -> ConstructionResult { let mut layout_data_ref = self.mutate_layout_data(); match *layout_data_ref.get() { Some(ref mut layout_data) => { @@ -769,29 +773,29 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> { /// Methods for interacting with HTMLObjectElement nodes trait ObjectElement { /// Returns None if this node is not matching attributes. - fn get_type_and_data(self) -> (Option<&'static str>, Option<&'static str>); + fn get_type_and_data(&self) -> (Option<&'static str>, Option<&'static str>); /// Returns true if this node has object data that is correct uri. - fn has_object_data(self) -> bool; + fn has_object_data(&self) -> bool; /// Returns the "data" attribute value parsed as a URL - fn get_object_data(self, base_url: &Url) -> Option<Url>; + fn get_object_data(&self, base_url: &Url) -> Option<Url>; } impl<'ln> ObjectElement for ThreadSafeLayoutNode<'ln> { - fn get_type_and_data(self) -> (Option<&'static str>, Option<&'static str>) { + fn get_type_and_data(&self) -> (Option<&'static str>, Option<&'static str>) { (self.with_element(|e| { e.get_attr(&namespace::Null, "type") } ), self.with_element(|e| { e.get_attr(&namespace::Null, "data") } )) } - fn has_object_data(self) -> bool { + fn has_object_data(&self) -> bool { match self.get_type_and_data() { (None, Some(uri)) => is_image_data(uri), _ => false } } - fn get_object_data(self, base_url: &Url) -> Option<Url> { + fn get_object_data(&self, base_url: &Url) -> Option<Url> { match self.get_type_and_data() { (None, Some(uri)) if is_image_data(uri) => Some(parse_url(uri, Some(base_url.clone()))), _ => None diff --git a/src/components/main/layout/extra.rs b/src/components/main/layout/extra.rs index ba7cf8a2595..a5724aaabcd 100644 --- a/src/components/main/layout/extra.rs +++ b/src/components/main/layout/extra.rs @@ -10,15 +10,15 @@ use script::layout_interface::LayoutChan; /// Functionality useful for querying the layout-specific data on DOM nodes. pub trait LayoutAuxMethods { - fn initialize_layout_data(self, chan: LayoutChan); - fn initialize_style_for_subtree(self, chan: LayoutChan); + fn initialize_layout_data(&self, chan: LayoutChan); + fn initialize_style_for_subtree(&self, chan: LayoutChan); } impl<'ln> LayoutAuxMethods for LayoutNode<'ln> { /// Resets layout data and styles for the node. /// /// FIXME(pcwalton): Do this as part of box building instead of in a traversal. - fn initialize_layout_data(self, chan: LayoutChan) { + fn initialize_layout_data(&self, chan: LayoutChan) { let mut layout_data_ref = self.mutate_layout_data(); match *layout_data_ref.get() { None => { @@ -34,7 +34,7 @@ impl<'ln> LayoutAuxMethods for LayoutNode<'ln> { /// Resets layout data and styles for a Node tree. /// /// FIXME(pcwalton): Do this as part of box building instead of in a traversal. - fn initialize_style_for_subtree(self, chan: LayoutChan) { + fn initialize_style_for_subtree(&self, chan: LayoutChan) { for n in self.traverse_preorder() { n.initialize_layout_data(chan.clone()); } diff --git a/src/components/main/layout/flow.rs b/src/components/main/layout/flow.rs index 1cc1a1cf075..8f86bd9545c 100644 --- a/src/components/main/layout/flow.rs +++ b/src/components/main/layout/flow.rs @@ -563,7 +563,7 @@ impl Iterator<@Box> for BoxIterator { impl BaseFlow { #[inline] - pub fn new(id: int, node: ThreadSafeLayoutNode) -> BaseFlow { + pub fn new(id: int, node: &ThreadSafeLayoutNode) -> BaseFlow { let style = node.style(); BaseFlow { restyle_damage: node.restyle_damage(), diff --git a/src/components/main/layout/inline.rs b/src/components/main/layout/inline.rs index 8332c7adb7d..9343804366c 100644 --- a/src/components/main/layout/inline.rs +++ b/src/components/main/layout/inline.rs @@ -466,7 +466,7 @@ pub struct InlineFlow { } impl InlineFlow { - pub fn from_boxes(id: int, node: ThreadSafeLayoutNode, boxes: ~[Box]) -> InlineFlow { + pub fn from_boxes(id: int, node: &ThreadSafeLayoutNode, boxes: ~[Box]) -> InlineFlow { InlineFlow { base: BaseFlow::new(id, node), boxes: boxes, diff --git a/src/components/main/layout/layout_task.rs b/src/components/main/layout/layout_task.rs index f9856724659..fd141434b2f 100644 --- a/src/components/main/layout/layout_task.rs +++ b/src/components/main/layout/layout_task.rs @@ -17,7 +17,7 @@ use layout::flow::{PreorderFlowTraversal, PostorderFlowTraversal}; use layout::flow; use layout::incremental::RestyleDamage; use layout::parallel::{AssignHeightsAndStoreOverflowTraversalKind, BubbleWidthsTraversalKind}; -use layout::parallel::{UnsafeFlow}; +use layout::parallel::{PaddedUnsafeFlow}; use layout::parallel; use layout::util::{LayoutDataAccess, OpaqueNode, LayoutDataWrapper}; use layout::wrapper::{DomLeafSet, LayoutNode, TLayoutNode, ThreadSafeLayoutNode}; @@ -32,8 +32,9 @@ use gfx::font_context::FontContextInfo; use gfx::opts::Opts; use gfx::render_task::{RenderMsg, RenderChan, RenderLayer}; use gfx::{render_task, color}; +use script::dom::bindings::js::JS; use script::dom::event::ReflowEvent; -use script::dom::node::{ElementNodeTypeId, LayoutDataRef}; +use script::dom::node::{ElementNodeTypeId, LayoutDataRef, Node}; use script::dom::element::{HTMLBodyElementTypeId, HTMLHtmlElementTypeId}; use script::layout_interface::{AddStylesheetMsg, ContentBoxQuery}; use script::layout_interface::{ContentBoxesQuery, ContentBoxesResponse, ExitNowMsg, LayoutQuery}; @@ -104,7 +105,7 @@ pub struct LayoutTask { initial_css_values: Arc<ComputedValues>, /// The workers that we use for parallel operation. - parallel_traversal: Option<WorkQueue<*mut LayoutContext,UnsafeFlow>>, + parallel_traversal: Option<WorkQueue<*mut LayoutContext,PaddedUnsafeFlow>>, /// The channel on which messages can be sent to the profiler. profiler_chan: ProfilerChan, @@ -429,8 +430,8 @@ impl LayoutTask { /// is intertwined with selector matching, making it difficult to compare directly. It is /// marked `#[inline(never)]` to aid benchmarking in sampling profilers. #[inline(never)] - fn construct_flow_tree(&self, layout_context: &mut LayoutContext, node: LayoutNode, url: &Url) -> ~Flow { - let node = ThreadSafeLayoutNode::new(node); + fn construct_flow_tree(&self, layout_context: &mut LayoutContext, node: &mut LayoutNode, url: &Url) -> ~Flow { + let mut node = ThreadSafeLayoutNode::new(node); node.traverse_postorder_mut(&mut FlowConstructor::init(layout_context, url)); let mut layout_data_ref = node.mutate_layout_data(); @@ -527,8 +528,9 @@ impl LayoutTask { /// The high-level routine that performs layout tasks. fn handle_reflow(&mut self, data: &Reflow) { // FIXME: Isolate this transmutation into a "bridge" module. - let node: &LayoutNode = unsafe { - transmute(&data.document_root) + let node: &mut LayoutNode = unsafe { + let mut node: JS<Node> = JS::from_trusted_node_address(data.document_root); + transmute(&mut node) }; debug!("layout: received layout request for: {:s}", data.url.to_str()); @@ -596,7 +598,7 @@ impl LayoutTask { // Construct the flow tree. profile(time::LayoutTreeBuilderCategory, self.profiler_chan.clone(), - || self.construct_flow_tree(&mut layout_ctx, *node, &data.url)) + || self.construct_flow_tree(&mut layout_ctx, node, &data.url)) }); // Verification of the flow tree, which ensures that all nodes were either marked as leaves @@ -648,7 +650,7 @@ impl LayoutTask { if child.type_id() == ElementNodeTypeId(HTMLHtmlElementTypeId) || child.type_id() == ElementNodeTypeId(HTMLBodyElementTypeId) { let element_bg_color = { - let thread_safe_child = ThreadSafeLayoutNode::new(child); + let thread_safe_child = ThreadSafeLayoutNode::new(&child); thread_safe_child.style() .get() .resolve_color(thread_safe_child.style() @@ -700,7 +702,7 @@ impl LayoutTask { // The neat thing here is that in order to answer the following two queries we only // need to compare nodes for equality. Thus we can safely work only with `OpaqueNode`. ContentBoxQuery(node, reply_chan) => { - let node = OpaqueNode::from_script_node(&node); + let node = OpaqueNode::from_script_node(node); fn union_boxes_for_node<'a>( accumulator: &mut Option<Rect<Au>>, @@ -724,7 +726,7 @@ impl LayoutTask { reply_chan.send(ContentBoxResponse(rect.unwrap_or(Au::zero_rect()))) } ContentBoxesQuery(node, reply_chan) => { - let node = OpaqueNode::from_script_node(&node); + let node = OpaqueNode::from_script_node(node); fn add_boxes_for_node<'a>( accumulator: &mut ~[Rect<Au>], diff --git a/src/components/main/layout/parallel.rs b/src/components/main/layout/parallel.rs index f6ddc27cce4..f601c3a5dd7 100644 --- a/src/components/main/layout/parallel.rs +++ b/src/components/main/layout/parallel.rs @@ -29,6 +29,36 @@ pub enum TraversalKind { AssignHeightsAndStoreOverflowTraversalKind, } +#[allow(dead_code)] +fn static_assertion(node: UnsafeLayoutNode) { + unsafe { + let _: PaddedUnsafeFlow = ::std::unstable::intrinsics::transmute(node); + } +} + +/// Memory representation that is at least as large as UnsafeLayoutNode, as it must be +/// safely transmutable to and from that type to accommodate the type-unsafe parallel work +/// queue usage that stores both flows and nodes. +pub type PaddedUnsafeFlow = (uint, uint, uint); + +trait UnsafeFlowConversions { + fn to_flow(&self) -> UnsafeFlow; + fn from_flow(flow: &UnsafeFlow) -> Self; +} + +impl UnsafeFlowConversions for PaddedUnsafeFlow { + fn to_flow(&self) -> UnsafeFlow { + let (vtable, ptr, _padding) = *self; + (vtable, ptr) + } + + fn from_flow(flow: &UnsafeFlow) -> PaddedUnsafeFlow { + let &(vtable, ptr) = flow; + (vtable, ptr, 0) + } +} + +/// Vtable + pointer representation of a Flow trait object. pub type UnsafeFlow = (uint, uint); fn null_unsafe_flow() -> UnsafeFlow { @@ -141,7 +171,7 @@ fn match_and_cascade_node(unsafe_layout_node: UnsafeLayoutNode, let layout_context: &mut LayoutContext = cast::transmute(*proxy.user_data()); // Get a real layout node. - let node: LayoutNode = cast::transmute(unsafe_layout_node); + let node: LayoutNode = ::std::unstable::intrinsics::transmute(unsafe_layout_node); // Initialize layout data. // @@ -159,7 +189,7 @@ fn match_and_cascade_node(unsafe_layout_node: UnsafeLayoutNode, // First, check to see whether we can share a style with someone. let style_sharing_candidate_cache = layout_context.style_sharing_candidate_cache(); let sharing_result = node.share_style_if_possible(style_sharing_candidate_cache, - parent_opt); + parent_opt.clone()); // Otherwise, match and cascade selectors. match sharing_result { @@ -215,25 +245,25 @@ fn match_and_cascade_node(unsafe_layout_node: UnsafeLayoutNode, } } -fn bubble_widths(unsafe_flow: UnsafeFlow, proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeFlow>) { +fn bubble_widths(unsafe_flow: PaddedUnsafeFlow, proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>) { let layout_context: &mut LayoutContext = unsafe { cast::transmute(*proxy.user_data()) }; let mut bubble_widths_traversal = BubbleWidthsTraversal { layout_context: layout_context, }; - bubble_widths_traversal.run_parallel(unsafe_flow) + bubble_widths_traversal.run_parallel(unsafe_flow.to_flow()) } -fn assign_heights_and_store_overflow(unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeFlow>) { +fn assign_heights_and_store_overflow(unsafe_flow: PaddedUnsafeFlow, + proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>) { let layout_context: &mut LayoutContext = unsafe { cast::transmute(*proxy.user_data()) }; let mut assign_heights_traversal = AssignHeightsAndStoreOverflowTraversal { layout_context: layout_context, }; - assign_heights_traversal.run_parallel(unsafe_flow) + assign_heights_traversal.run_parallel(unsafe_flow.to_flow()) } pub fn match_and_cascade_subtree(root_node: &LayoutNode, @@ -258,7 +288,7 @@ pub fn traverse_flow_tree(kind: TraversalKind, leaf_set: &Arc<FlowLeafSet>, profiler_chan: ProfilerChan, layout_context: &mut LayoutContext, - queue: &mut WorkQueue<*mut LayoutContext,UnsafeFlow>) { + queue: &mut WorkQueue<*mut LayoutContext,PaddedUnsafeFlow>) { unsafe { queue.data = cast::transmute(layout_context) } @@ -272,7 +302,7 @@ pub fn traverse_flow_tree(kind: TraversalKind, for (flow, _) in leaf_set.get().iter() { queue.push(WorkUnit { fun: fun, - data: *flow, + data: UnsafeFlowConversions::from_flow(flow), }) } }); diff --git a/src/components/main/layout/util.rs b/src/components/main/layout/util.rs index 7a2eeb8f805..de10f8a8d9a 100644 --- a/src/components/main/layout/util.rs +++ b/src/components/main/layout/util.rs @@ -8,9 +8,10 @@ use layout::parallel::DomParallelInfo; use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode}; use extra::arc::Arc; +use script::dom::bindings::js::JS; use script::dom::bindings::utils::Reflectable; -use script::dom::node::AbstractNode; -use script::layout_interface::{LayoutChan, UntrustedNodeAddress}; +use script::dom::node::Node; +use script::layout_interface::{LayoutChan, UntrustedNodeAddress, TrustedNodeAddress}; use servo_util::range::Range; use std::cast; use std::cell::{Ref, RefMut}; @@ -212,23 +213,28 @@ impl OpaqueNode { /// Converts a DOM node (layout view) to an `OpaqueNode`. pub fn from_layout_node(node: &LayoutNode) -> OpaqueNode { unsafe { - let abstract_node = node.get_abstract(); - let ptr: uintptr_t = cast::transmute(abstract_node.reflector().get_jsobject()); - OpaqueNode(ptr) + OpaqueNode::from_jsmanaged(node.get_jsmanaged()) } } /// Converts a thread-safe DOM node (layout view) to an `OpaqueNode`. pub fn from_thread_safe_layout_node(node: &ThreadSafeLayoutNode) -> OpaqueNode { unsafe { - let abstract_node = node.get_abstract(); + let abstract_node = node.get_jsmanaged(); let ptr: uintptr_t = cast::transmute(abstract_node.reflector().get_jsobject()); OpaqueNode(ptr) } } /// Converts a DOM node (script view) to an `OpaqueNode`. - pub fn from_script_node(node: &AbstractNode) -> OpaqueNode { + pub fn from_script_node(node: TrustedNodeAddress) -> OpaqueNode { + unsafe { + OpaqueNode::from_jsmanaged(&JS::from_trusted_node_address(node)) + } + } + + /// Converts a DOM node to an `OpaqueNode'. + fn from_jsmanaged(node: &JS<Node>) -> OpaqueNode { unsafe { let ptr: uintptr_t = cast::transmute(node.reflector().get_jsobject()); OpaqueNode(ptr) diff --git a/src/components/main/layout/wrapper.rs b/src/components/main/layout/wrapper.rs index 2e67eff3567..7fddf24f8e9 100644 --- a/src/components/main/layout/wrapper.rs +++ b/src/components/main/layout/wrapper.rs @@ -11,15 +11,18 @@ //! //! (1) Layout is not allowed to mutate the DOM. //! -//! (2) Layout is not allowed to see anything with `Abstract` in the name, because it could hang +//! (2) Layout is not allowed to see anything with `JS` in the name, because it could hang //! onto these objects and cause use-after-free. use extra::url::Url; +use script::dom::bindings::codegen::InheritTypes::{HTMLImageElementCast, HTMLIFrameElementCast}; +use script::dom::bindings::codegen::InheritTypes::{TextCast, ElementCast}; +use script::dom::bindings::js::JS; use script::dom::element::{Element, HTMLAreaElementTypeId, HTMLAnchorElementTypeId}; use script::dom::element::{HTMLLinkElementTypeId}; use script::dom::htmliframeelement::HTMLIFrameElement; use script::dom::htmlimageelement::HTMLImageElement; -use script::dom::node::{AbstractNode, DocumentNodeTypeId, ElementNodeTypeId, Node, NodeTypeId}; +use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, Node, NodeTypeId, NodeHelpers}; use script::dom::text::Text; use servo_msg::constellation_msg::{PipelineId, SubpageId}; use servo_util::concurrentmap::{ConcurrentHashMap, ConcurrentHashMapIterator}; @@ -35,20 +38,20 @@ use layout::util::LayoutDataWrapper; /// Allows some convenience methods on generic layout nodes. pub trait TLayoutNode { /// Creates a new layout node with the same lifetime as this layout node. - unsafe fn new_with_this_lifetime(&self, node: AbstractNode) -> Self; + unsafe fn new_with_this_lifetime(&self, node: JS<Node>) -> Self; /// Returns the type ID of this node. Fails if this node is borrowed mutably. fn type_id(&self) -> NodeTypeId; - /// Returns the interior of this node as an `AbstractNode`. This is highly unsafe for layout to + + /// Returns the interior of this node as a `JS`. This is highly unsafe for layout to /// call and as such is marked `unsafe`. - unsafe fn get_abstract(&self) -> AbstractNode; + unsafe fn get_jsmanaged<'a>(&'a self) -> &'a JS<Node>; /// Returns the interior of this node as a `Node`. This is highly unsafe for layout to call /// and as such is marked `unsafe`. unsafe fn get<'a>(&'a self) -> &'a Node { - let node = self.get_abstract(); - cast::transmute(node.node()) + self.get_jsmanaged().get() } fn node_is_element(&self) -> bool { @@ -70,40 +73,18 @@ pub trait TLayoutNode { /// FIXME(pcwalton): Don't copy URLs. fn image_url(&self) -> Option<Url> { unsafe { - self.with_image_element(|image_element| { - image_element.image.as_ref().map(|url| (*url).clone()) - }) - } - } - - /// Downcasts this node to an iframe element and calls the given closure. - /// - /// FIXME(pcwalton): RAII. - unsafe fn with_iframe_element<R>(&self, f: |&HTMLIFrameElement| -> R) -> R { - if !self.get_abstract().is_iframe_element() { - fail!(~"node is not an iframe element"); + let image_element: JS<HTMLImageElement> = HTMLImageElementCast::to(self.get_jsmanaged()); + image_element.get().extra.image.as_ref().map(|url| (*url).clone()) } - self.get_abstract().transmute(f) - } - - /// Downcasts this node to an image element and calls the given closure. - /// - /// FIXME(pcwalton): RAII. - unsafe fn with_image_element<R>(&self, f: |&HTMLImageElement| -> R) -> R { - if !self.get_abstract().is_image_element() { - fail!(~"node is not an image element"); - } - self.get_abstract().transmute(f) } /// If this node is an iframe element, returns its pipeline and subpage IDs. If this node is /// not an iframe element, fails. fn iframe_pipeline_and_subpage_ids(&self) -> (PipelineId, SubpageId) { unsafe { - self.with_iframe_element(|iframe_element| { - let size = iframe_element.size.unwrap(); - (size.pipeline_id, size.subpage_id) - }) + let iframe_element: JS<HTMLIFrameElement> = HTMLIFrameElementCast::to(self.get_jsmanaged()); + let size = iframe_element.get().size.unwrap(); + (size.pipeline_id, size.subpage_id) } } @@ -112,45 +93,39 @@ pub trait TLayoutNode { /// FIXME(pcwalton): Don't copy text. Atomically reference count instead. fn text(&self) -> ~str { unsafe { - self.with_text(|text| text.characterdata.data.to_str()) + let text: JS<Text> = TextCast::to(self.get_jsmanaged()); + text.get().characterdata.data.to_str() } } - /// Downcasts this node to a text node and calls the given closure. - /// - /// FIXME(pcwalton): RAII. - unsafe fn with_text<R>(&self, f: |&Text| -> R) -> R { - self.get_abstract().with_imm_text(f) - } - /// Returns the first child of this node. fn first_child(&self) -> Option<Self> { unsafe { - self.get_abstract().first_child().map(|node| self.new_with_this_lifetime(node)) + self.get_jsmanaged().first_child().map(|node| self.new_with_this_lifetime(node)) } } /// Dumps this node tree, for debugging. fn dump(&self) { unsafe { - self.get_abstract().dump() + self.get_jsmanaged().dump() } } } /// A wrapper so that layout can access only the methods that it should have access to. Layout must -/// only ever see these and must never see instances of `AbstractNode`. +/// only ever see these and must never see instances of `JS`. #[deriving(Clone, Eq)] pub struct LayoutNode<'a> { /// The wrapped node. - priv node: AbstractNode, + priv node: JS<Node>, /// Being chained to a value prevents `LayoutNode`s from escaping. priv chain: &'a (), } impl<'ln> TLayoutNode for LayoutNode<'ln> { - unsafe fn new_with_this_lifetime(&self, node: AbstractNode) -> LayoutNode<'ln> { + unsafe fn new_with_this_lifetime(&self, node: JS<Node>) -> LayoutNode<'ln> { LayoutNode { node: node, chain: self.chain, @@ -159,14 +134,14 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> { fn type_id(&self) -> NodeTypeId { self.node.type_id() } - unsafe fn get_abstract(&self) -> AbstractNode { - self.node + unsafe fn get_jsmanaged<'a>(&'a self) -> &'a JS<Node> { + &self.node } } impl<'ln> LayoutNode<'ln> { /// Creates a new layout node, scoped to the given closure. - pub unsafe fn with_layout_node<R>(node: AbstractNode, f: <'a> |LayoutNode<'a>| -> R) -> R { + pub unsafe fn with_layout_node<R>(node: JS<Node>, f: <'a> |LayoutNode<'a>| -> R) -> R { let heavy_iron_ball = (); f(LayoutNode { node: node, @@ -194,34 +169,34 @@ impl<'ln> LayoutNode<'ln> { impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> { fn parent_node(&self) -> Option<LayoutNode<'ln>> { unsafe { - self.node.node().parent_node.map(|node| self.new_with_this_lifetime(node)) + self.node.parent_node().map(|node| self.new_with_this_lifetime(node)) } } fn prev_sibling(&self) -> Option<LayoutNode<'ln>> { unsafe { - self.node.node().prev_sibling.map(|node| self.new_with_this_lifetime(node)) + self.node.prev_sibling().map(|node| self.new_with_this_lifetime(node)) } } fn next_sibling(&self) -> Option<LayoutNode<'ln>> { unsafe { - self.node.node().next_sibling.map(|node| self.new_with_this_lifetime(node)) + self.node.next_sibling().map(|node| self.new_with_this_lifetime(node)) } } /// If this is an element, accesses the element data. Fails if this is not an element node. #[inline] fn with_element<R>(&self, f: |&LayoutElement<'ln>| -> R) -> R { - self.node.with_imm_element(|element| { - // FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on - // implementations. - unsafe { - f(&LayoutElement { - element: cast::transmute_region(element), - }) - } - }) + let elem: JS<Element> = ElementCast::to(&self.node); + let element = elem.get(); + // FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on + // implementations. + unsafe { + f(&LayoutElement { + element: cast::transmute_region(element), + }) + } } fn is_element(&self) -> bool { @@ -257,8 +232,8 @@ pub struct LayoutNodeChildrenIterator<'a> { impl<'a> Iterator<LayoutNode<'a>> for LayoutNodeChildrenIterator<'a> { fn next(&mut self) -> Option<LayoutNode<'a>> { - let node = self.current_node; - self.current_node = self.current_node.and_then(|node| { + let node = self.current_node.clone(); + self.current_node = node.clone().and_then(|node| { node.next_sibling() }); node @@ -358,7 +333,7 @@ impl<'le> TElement for LayoutElement<'le> { /// node does not allow any parents or siblings of nodes to be accessed, to avoid races. pub struct ThreadSafeLayoutNode<'ln> { /// The wrapped node. - priv node: AbstractNode, + priv node: JS<Node>, /// Being chained to a value prevents `ThreadSafeLayoutNode`s from escaping. priv chain: &'ln (), @@ -366,7 +341,7 @@ pub struct ThreadSafeLayoutNode<'ln> { impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> { /// Creates a new layout node with the same lifetime as this layout node. - unsafe fn new_with_this_lifetime(&self, node: AbstractNode) -> ThreadSafeLayoutNode<'ln> { + unsafe fn new_with_this_lifetime(&self, node: JS<Node>) -> ThreadSafeLayoutNode<'ln> { ThreadSafeLayoutNode { node: node, chain: self.chain, @@ -375,23 +350,32 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> { fn type_id(&self) -> NodeTypeId { self.node.type_id() } - unsafe fn get_abstract(&self) -> AbstractNode { - self.node + unsafe fn get_jsmanaged<'a>(&'a self) -> &'a JS<Node> { + &self.node + } +} + +impl<'ln> Clone for ThreadSafeLayoutNode<'ln> { + fn clone(&self) -> ThreadSafeLayoutNode<'ln> { + ThreadSafeLayoutNode { + node: self.node.clone(), + chain: self.chain, + } } } impl<'ln> ThreadSafeLayoutNode<'ln> { /// Creates a new `ThreadSafeLayoutNode` from the given `LayoutNode`. - pub fn new<'a>(node: LayoutNode<'a>) -> ThreadSafeLayoutNode<'a> { + pub fn new<'a>(node: &LayoutNode<'a>) -> ThreadSafeLayoutNode<'a> { ThreadSafeLayoutNode { - node: node.node, + node: node.node.clone(), chain: node.chain, } } /// Returns the next sibling of this node. Unsafe and private because this can lead to races. unsafe fn next_sibling(&self) -> Option<ThreadSafeLayoutNode<'ln>> { - self.node.node().next_sibling.map(|node| self.new_with_this_lifetime(node)) + self.node.next_sibling().map(|node| self.new_with_this_lifetime(node)) } /// Returns an iterator over this node's children. @@ -405,12 +389,12 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { #[inline] pub fn with_element<R>(&self, f: |&ThreadSafeLayoutElement| -> R) -> R { unsafe { - self.get_abstract().with_imm_element(|element| { - // FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on - // implementations. - f(&ThreadSafeLayoutElement { - element: cast::transmute_region(element), - }) + let elem: JS<Element> = ElementCast::to(&self.node); + let element = elem.get(); + // FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on + // implementations. + f(&ThreadSafeLayoutElement { + element: cast::transmute_region(element), }) } } @@ -434,7 +418,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { /// Traverses the tree in postorder. /// /// TODO(pcwalton): Offer a parallel version with a compatible API. - pub fn traverse_postorder_mut<T:PostorderNodeMutTraversal>(mut self, traversal: &mut T) + pub fn traverse_postorder_mut<T:PostorderNodeMutTraversal>(&mut self, traversal: &mut T) -> bool { if traversal.should_prune(self) { return true @@ -444,7 +428,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { loop { match opt_kid { None => break, - Some(kid) => { + Some(mut kid) => { if !kid.traverse_postorder_mut(traversal) { return false } @@ -465,8 +449,8 @@ pub struct ThreadSafeLayoutNodeChildrenIterator<'a> { impl<'a> Iterator<ThreadSafeLayoutNode<'a>> for ThreadSafeLayoutNodeChildrenIterator<'a> { fn next(&mut self) -> Option<ThreadSafeLayoutNode<'a>> { - let node = self.current_node; - self.current_node = self.current_node.and_then(|node| { + let node = self.current_node.clone(); + self.current_node = self.current_node.clone().and_then(|node| { unsafe { node.next_sibling() } @@ -491,17 +475,19 @@ impl<'le> ThreadSafeLayoutElement<'le> { /// A bottom-up, parallelizable traversal. pub trait PostorderNodeMutTraversal { /// The operation to perform. Return true to continue or false to stop. - fn process<'a>(&'a mut self, node: ThreadSafeLayoutNode<'a>) -> bool; + fn process<'a>(&'a mut self, node: &ThreadSafeLayoutNode<'a>) -> bool; /// Returns true if this node should be pruned. If this returns true, we skip the operation /// entirely and do not process any descendant nodes. This is called *before* child nodes are /// visited. The default implementation never prunes any nodes. - fn should_prune<'a>(&'a self, _node: ThreadSafeLayoutNode<'a>) -> bool { + fn should_prune<'a>(&'a self, _node: &ThreadSafeLayoutNode<'a>) -> bool { false } } -pub type UnsafeLayoutNode = (uint, uint); +/// Opaque type stored in type-unsafe work queues for parallel layout. +/// Must be transmutable to and from LayoutNode/ThreadsafeLayoutNode/PaddedUnsafeFlow. +pub type UnsafeLayoutNode = (uint, uint, uint); pub fn layout_node_to_unsafe_layout_node(node: &LayoutNode) -> UnsafeLayoutNode { unsafe { diff --git a/src/components/msg/compositor_msg.rs b/src/components/msg/compositor_msg.rs index c1c28d9b467..4726f20e9a0 100644 --- a/src/components/msg/compositor_msg.rs +++ b/src/components/msg/compositor_msg.rs @@ -11,6 +11,8 @@ use layers::platform::surface::{NativeSurface, NativeSurfaceMethods}; use constellation_msg::PipelineId; +use extra::serialize::{Encoder, Encodable}; + pub struct LayerBuffer { /// The native surface which can be shared between threads or processes. On Mac this is an /// `IOSurface`; on Linux this is an X Pixmap; on Android this is an `EGLImageKHR`. @@ -94,6 +96,11 @@ pub trait ScriptListener : Clone { fn close(&self); } +impl<S: Encoder> Encodable<S> for @ScriptListener { + fn encode(&self, _s: &mut S) { + } +} + /// The interface used by the quadtree and buffer map to get info about layer buffers. pub trait Tile { /// Returns the amount of memory used by the tile diff --git a/src/components/msg/constellation_msg.rs b/src/components/msg/constellation_msg.rs index 9d3c1540066..a2197c26baa 100644 --- a/src/components/msg/constellation_msg.rs +++ b/src/components/msg/constellation_msg.rs @@ -60,8 +60,8 @@ pub enum NavigationDirection { Back, } -#[deriving(Clone, Eq, IterBytes)] +#[deriving(Clone, Eq, IterBytes, Encodable)] pub struct PipelineId(uint); -#[deriving(Clone, Eq, IterBytes)] +#[deriving(Clone, Eq, IterBytes, Encodable)] pub struct SubpageId(uint); diff --git a/src/components/msg/msg.rs b/src/components/msg/msg.rs index e27148b09d7..1315979ac18 100644 --- a/src/components/msg/msg.rs +++ b/src/components/msg/msg.rs @@ -5,6 +5,8 @@ #[crate_id = "github.com/mozilla/servo#msg:0.1"]; #[crate_type = "lib"]; +#[feature(managed_boxes)]; + extern mod azure; extern mod extra; extern mod geom; diff --git a/src/components/net/image_cache_task.rs b/src/components/net/image_cache_task.rs index fba676cbced..1212fa972c2 100644 --- a/src/components/net/image_cache_task.rs +++ b/src/components/net/image_cache_task.rs @@ -14,6 +14,7 @@ use std::util::replace; use std::result; use extra::arc::{Arc,MutexArc}; use extra::url::Url; +use extra::serialize::{Encoder, Encodable}; pub enum Msg { /// Tell the cache that we may need a particular image soon. Must be posted @@ -80,6 +81,11 @@ pub struct ImageCacheTask { chan: SharedChan<Msg>, } +impl<S: Encoder> Encodable<S> for ImageCacheTask { + fn encode(&self, _: &mut S) { + } +} + type DecoderFactory = fn() -> proc(&[u8]) -> Option<Image>; pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask { diff --git a/src/components/script/dom/attr.rs b/src/components/script/dom/attr.rs index 6ae8009bb5a..3cf978d69c4 100644 --- a/src/components/script/dom/attr.rs +++ b/src/components/script/dom/attr.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::AttrBinding; +use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::window::Window; use servo_util::namespace::{Namespace, Null}; @@ -10,6 +11,7 @@ use servo_util::str::DOMString; use std::util; +#[deriving(Encodable)] pub struct Attr { reflector_: Reflector, local_name: DOMString, @@ -43,22 +45,22 @@ impl Attr { } } - pub fn new(window: &Window, local_name: DOMString, value: DOMString) -> @mut Attr { + pub fn new(window: &Window, local_name: DOMString, value: DOMString) -> JS<Attr> { let name = local_name.clone(); Attr::new_helper(window, local_name, value, name, Null, None) } pub fn new_ns(window: &Window, local_name: DOMString, value: DOMString, name: DOMString, namespace: Namespace, - prefix: Option<DOMString>) -> @mut Attr { + prefix: Option<DOMString>) -> JS<Attr> { Attr::new_helper(window, local_name, value, name, namespace, prefix) } fn new_helper(window: &Window, local_name: DOMString, value: DOMString, name: DOMString, namespace: Namespace, - prefix: Option<DOMString>) -> @mut Attr { + prefix: Option<DOMString>) -> JS<Attr> { let attr = Attr::new_inherited(local_name, value, name, namespace, prefix); - reflect_dom_object(@mut attr, window, AttrBinding::Wrap) + reflect_dom_object(~attr, window, AttrBinding::Wrap) } pub fn set_value(&mut self, mut value: DOMString) -> DOMString { diff --git a/src/components/script/dom/attrlist.rs b/src/components/script/dom/attrlist.rs index 9b8634de26c..100f057fe8f 100644 --- a/src/components/script/dom/attrlist.rs +++ b/src/components/script/dom/attrlist.rs @@ -4,18 +4,20 @@ use dom::attr::Attr; use dom::bindings::codegen::AttrListBinding; +use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; -use dom::node::{AbstractNode}; +use dom::element::Element; use dom::window::Window; +#[deriving(Encodable)] pub struct AttrList { reflector_: Reflector, - window: @mut Window, - owner: AbstractNode, + window: JS<Window>, + owner: JS<Element>, } impl AttrList { - pub fn new_inherited(window: @mut Window, elem: AbstractNode) -> AttrList { + pub fn new_inherited(window: JS<Window>, elem: JS<Element>) -> AttrList { AttrList { reflector_: Reflector::new(), window: window, @@ -23,22 +25,20 @@ impl AttrList { } } - pub fn new(window: @mut Window, elem: AbstractNode) -> @mut AttrList { - reflect_dom_object(@mut AttrList::new_inherited(window, elem), - window, AttrListBinding::Wrap) + pub fn new(window: &JS<Window>, elem: &JS<Element>) -> JS<AttrList> { + reflect_dom_object(~AttrList::new_inherited(window.clone(), elem.clone()), + window.get(), AttrListBinding::Wrap) } pub fn Length(&self) -> u32 { - self.owner.with_imm_element(|elem| elem.attrs.len() as u32) + self.owner.get().attrs.len() as u32 } - pub fn Item(&self, index: u32) -> Option<@mut Attr> { - self.owner.with_imm_element(|elem| { - elem.attrs.get_opt(index as uint).map(|&x| x) - }) + pub fn Item(&self, index: u32) -> Option<JS<Attr>> { + self.owner.get().attrs.get_opt(index as uint).map(|x| x.clone()) } - pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<@mut Attr> { + pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Attr>> { let item = self.Item(index); *found = item.is_some(); item diff --git a/src/components/script/dom/bindings/callback.rs b/src/components/script/dom/bindings/callback.rs index 40b3bd7b5fa..10cb35c3af4 100644 --- a/src/components/script/dom/bindings/callback.rs +++ b/src/components/script/dom/bindings/callback.rs @@ -4,12 +4,15 @@ use dom::bindings::utils::Reflectable; use js::jsapi::{JSContext, JSObject, JS_WrapObject, JSVal, JS_ObjectIsCallable}; -use js::jsapi::JS_GetProperty; -use js::{JSVAL_IS_OBJECT, JSVAL_TO_OBJECT}; +use js::jsapi::{JS_GetProperty, JSTracer, JS_CallTracer}; +use js::{JSVAL_IS_OBJECT, JSVAL_TO_OBJECT, JSTRACE_OBJECT}; +use std::cast; use std::libc; use std::ptr; +use extra::serialize::{Encodable, Encoder}; + pub enum ExceptionHandling { // Report any exception and don't throw it to the caller code. eReportExceptions, @@ -26,6 +29,20 @@ pub struct CallbackInterface { callback: *JSObject } +impl<S: Encoder> Encodable<S> for CallbackInterface { + fn encode(&self, s: &mut S) { + unsafe { + let tracer: *mut JSTracer = cast::transmute(s); + "callback".to_c_str().with_ref(|name| { + (*tracer).debugPrinter = ptr::null(); + (*tracer).debugPrintIndex = -1; + (*tracer).debugPrintArg = name as *libc::c_void; + JS_CallTracer(tracer as *JSTracer, self.callback, JSTRACE_OBJECT as u32); + }); + } + } +} + pub trait CallbackContainer { fn callback(&self) -> *JSObject; } @@ -66,7 +83,7 @@ pub fn GetJSObjectFromCallback<T: CallbackContainer>(callback: &T) -> *JSObject pub fn WrapCallThisObject<T: 'static + CallbackContainer + Reflectable>(cx: *JSContext, _scope: *JSObject, - p: @mut T) -> *JSObject { + p: ~T) -> *JSObject { let obj = GetJSObjectFromCallback(p); assert!(obj.is_not_null()); diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf index b45eca71ba8..cc4a5996865 100644 --- a/src/components/script/dom/bindings/codegen/Bindings.conf +++ b/src/components/script/dom/bindings/codegen/Bindings.conf @@ -96,7 +96,6 @@ DOMInterfaces = { 'Blob': [ { - 'headerFile': 'nsIDOMFile.h', }, #{ # 'workers': True, @@ -121,19 +120,14 @@ DOMInterfaces = { }], 'CharacterData': { - 'nativeType': 'AbstractNode', - 'concreteType': 'CharacterData', - 'pointerType': '' }, 'ClientRect': [ { - 'nativeType': 'ClientRect', }], 'ClientRectList': [ { - 'nativeType': 'ClientRectList', }], 'Console': { @@ -150,8 +144,6 @@ DOMInterfaces = { }, 'Document': { - 'nativeType': 'AbstractDocument', - 'pointerType': '', 'customTrace': 'trace', 'needsAbstract': [ 'createComment', @@ -165,15 +157,12 @@ DOMInterfaces = { }, 'DOMException': { - 'nativeType': 'DOMException', }, 'DOMImplementation': { - 'nativeType': 'DOMImplementation', }, 'DOMParser': { - 'nativeType': 'DOMParser', }, 'DOMSettableTokenList': [ @@ -195,15 +184,10 @@ DOMInterfaces = { }], 'Element': { - 'nativeType': 'AbstractNode', - 'pointerType': '', 'needsAbstract': ['getClientRects', 'getBoundingClientRect', 'setAttribute', 'setAttributeNS', 'removeAttribute', 'removeAttributeNS', 'id', 'attributes', 'innerHTML', 'outerHTML'] }, 'Event': { - 'nativeType': 'AbstractEvent', - 'concreteType': 'Event', - 'pointerType': '', }, 'EventListener': { @@ -211,9 +195,6 @@ DOMInterfaces = { }, 'EventTarget': { - 'nativeType': 'AbstractEventTarget', - 'concreteType': 'EventTarget', - 'pointerType': '', 'needsAbstract': ['dispatchEvent'] }, @@ -241,22 +222,12 @@ DOMInterfaces = { 'HTMLCollection': [ { - 'nativeType': 'HTMLCollection', - 'pointerType': '@mut ' }], 'HTMLDocument': { - 'nativeType': 'AbstractDocument', - 'pointerType': '', 'customTrace': 'trace' }, -'HTMLFormElement': { - 'nativeType': 'AbstractNode', - 'pointerType': '', - 'register': False -}, - 'HTMLOptionsCollection': [ { 'nativeType': 'nsHTMLOptionCollection', @@ -306,27 +277,21 @@ DOMInterfaces = { }], 'MouseEvent': { - 'nativeType': 'AbstractEvent', - 'concreteType': 'MouseEvent', - 'pointerType': '', }, 'Navigator': { }, 'Node': { - 'nativeType': 'AbstractNode', - 'concreteType': 'Node', - 'pointerType': '', 'needsAbstract': [ 'appendChild', - 'insertBefore', - 'replaceChild', + 'childNodes', + 'insertBefore', 'nodeName', 'nodeValue', 'removeChild', + 'replaceChild', 'textContent', - 'childNodes', 'contains', 'isEqualNode', ] @@ -334,8 +299,6 @@ DOMInterfaces = { 'NodeList': [ { - 'nativeType': 'NodeList', - 'pointerType': '@mut ', 'resultNotAddRefed': ['item'] }], @@ -410,9 +373,6 @@ DOMInterfaces = { }], 'UIEvent': { - 'nativeType': 'AbstractEvent', - 'concreteType': 'UIEvent', - 'pointerType': '', }, 'ValidityState': { @@ -592,7 +552,7 @@ def addExternalIface(iface, nativeType=None, headerFile=None, pointerType=None): # FIXME: This should be renamed: https://github.com/mozilla/servo/issues/1625 def addHTMLElement(element, concrete=None, needsAbstract=[]): DOMInterfaces[element] = { - 'nativeType': 'AbstractNode', + 'nativeType': 'JS<%s>' % element, 'pointerType': '', 'concreteType': concrete if concrete else element, 'customTrace': 'trace', diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index cb367a585f6..da0ad3dd8df 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -102,7 +102,8 @@ class CastableObjectUnwrapper(): "source" : source, "target" : target, "codeOnFailure" : CGIndenter(CGGeneric(codeOnFailure), 4).define(), - "unwrapped_val" : "Some(val)" if isOptional else "val" } + "unwrapped_val" : "Some(val)" if isOptional else "val", + "unwrapFn": "unwrap_jsmanaged" if 'JS' in descriptor.nativeType else "unwrap_object"} if descriptor.hasXPConnectImpls: # We don't use xpc_qsUnwrapThis because it will always throw on # unwrap failure, whereas we want to control whether we throw or @@ -123,7 +124,7 @@ class CastableObjectUnwrapper(): def __str__(self): return string.Template( -"""match unwrap_object(${source}, ${prototype}, ${depth}) { +"""match ${unwrapFn}(${source}, ${prototype}, ${depth}) { Ok(val) => ${target} = ${unwrapped_val}, Err(()) => { ${codeOnFailure} @@ -406,8 +407,7 @@ class FakeCastableDescriptor(): def __init__(self, descriptor): self.castable = True self.workers = descriptor.workers - self.nativeType = descriptor.nativeType - self.pointerType = descriptor.pointerType + self.nativeType = "*Box<%s>" % descriptor.concreteType self.name = descriptor.name self.hasXPConnectImpls = descriptor.hasXPConnectImpls class FakeInterface: @@ -934,8 +934,7 @@ for (uint32_t i = 0; i < length; ++i) { forceOwningType = (descriptor.interface.isCallback() and not descriptor.workers) or isMember - typeName = descriptor.nativeType - typePtr = descriptor.pointerType + typeName + typePtr = descriptor.nativeType # Compute a few things: # - declType is the type we want to return as the first element of our @@ -1730,9 +1729,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider, returnType.unroll().inner.identifier.name) result = CGGeneric(descriptor.nativeType) if returnType.nullable(): - result = CGWrapper(result, pre=("Option<" + descriptor.pointerType), post=">") - else: - result = CGWrapper(result, pre=descriptor.pointerType) + result = CGWrapper(result, pre="Option<", post=">") return result, False if returnType.isCallback(): # XXXbz we're going to assume that callback types are always @@ -2497,33 +2494,40 @@ class CGAbstractMethod(CGThing): def definition_body(self): assert(False) # Override me! +def DOMObjectPointerType(descriptor): + return "~" + +def DOMObjectPointerArg(descriptor): + return DOMObjectPointerType(descriptor) + descriptor.concreteType + def CreateBindingJSObject(descriptor, parent=None): + create = " let raw: *mut %s = &mut *aObject;\n" % descriptor.concreteType; if descriptor.proxy: assert not descriptor.createGlobal handler = """ let page = page_from_context(aCx); let handler = (*page).js_info.get_ref().dom_static.proxy_handlers.get(&(PrototypeList::id::%s as uint)); """ % descriptor.name - create = handler + """ let obj = NewProxyObject(aCx, *handler, - ptr::to_unsafe_ptr(&RUST_PRIVATE_TO_JSVAL(squirrel_away(aObject) as *libc::c_void)), + create += handler + """ let obj = NewProxyObject(aCx, *handler, + ptr::to_unsafe_ptr(&RUST_PRIVATE_TO_JSVAL(squirrel_away_unique(aObject) as *libc::c_void)), proto, %s, ptr::null(), ptr::null()); if obj.is_null() { return ptr::null(); } -""" % parent +""" % (parent) else: if descriptor.createGlobal: - create = " let obj = CreateDOMGlobal(aCx, &Class.base);\n" + create += " let obj = CreateDOMGlobal(aCx, &Class.base);\n" else: - create = " let obj = JS_NewObject(aCx, &Class.base, proto, %s);\n" % parent + create += " let obj = JS_NewObject(aCx, &Class.base, proto, %s);\n" % parent create += """ if obj.is_null() { return ptr::null(); } JS_SetReservedSlot(obj, DOM_OBJECT_SLOT as u32, - RUST_PRIVATE_TO_JSVAL(squirrel_away(aObject) as *libc::c_void)); + RUST_PRIVATE_TO_JSVAL(squirrel_away_unique(aObject) as *libc::c_void)); """ return create @@ -2531,7 +2535,7 @@ class CGWrapWithCacheMethod(CGAbstractMethod): def __init__(self, descriptor): assert descriptor.interface.hasInterfacePrototypeObject() args = [Argument('*JSContext', 'aCx'), Argument('*JSObject', 'aScope'), - Argument('@mut ' + descriptor.concreteType, 'aObject')] + Argument(DOMObjectPointerArg(descriptor), 'aObject', mutable=True)] CGAbstractMethod.__init__(self, descriptor, 'Wrap_', '*JSObject', args) def definition_body(self): @@ -2548,20 +2552,20 @@ class CGWrapWithCacheMethod(CGAbstractMethod): if proto.is_null() { return ptr::null(); } -%s - //NS_ADDREF(aObject); +%s - aObject.mut_reflector().set_jsobject(obj); + (*raw).mut_reflector().set_jsobject(obj); - return obj;""" % (CreateBindingJSObject(self.descriptor, "aScope")) + return obj;""" % CreateBindingJSObject(self.descriptor, "aScope") else: return """ assert!(aScope.is_null()); + %s let proto = GetProtoObject(aCx, obj, obj); JS_SetPrototype(aCx, obj, proto); - aObject.mut_reflector().set_jsobject(obj); + (*raw).mut_reflector().set_jsobject(obj); return obj;""" % CreateBindingJSObject(self.descriptor) class CGWrapMethod(CGAbstractMethod): @@ -2569,7 +2573,7 @@ class CGWrapMethod(CGAbstractMethod): # XXX can we wrap if we don't have an interface prototype object? assert descriptor.interface.hasInterfacePrototypeObject() args = [Argument('*JSContext', 'aCx'), Argument('*JSObject', 'aScope'), - Argument('@mut ' + descriptor.concreteType, 'aObject')] + Argument(DOMObjectPointerArg(descriptor), 'aObject', mutable=True)] CGAbstractMethod.__init__(self, descriptor, 'Wrap', '*JSObject', args, inline=True, pub=True) def definition_body(self): @@ -2961,7 +2965,11 @@ class CGCallGenerator(CGThing): if a.type.isObject() and not a.type.nullable() and not a.optional: name = "(JSObject&)" + name #XXXjdm Perhaps we should pass all nontrivial types by borrowed pointer - if a.type.isDictionary(): + if a.type.isGeckoInterface(): + argDescriptor = descriptorProvider.getDescriptor(a.type.name) + if not (a.type.nullable() or a.optional): + name = "&mut " + name + elif a.type.isDictionary(): name = "&" + name args.append(CGGeneric(name)) @@ -3288,8 +3296,8 @@ class CGSpecializedMethod(CGAbstractExternMethod): argsPre = [] if name in self.descriptor.needsAbstract: abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType) - extraPre = ' let abstract_this = %s::from_box(this);\n' % abstractName - argsPre = ['abstract_this'] + extraPre = ' let mut abstract_this = %s::from_box(this);\n' % abstractName + argsPre = ['&mut abstract_this'] return CGWrapper(CGMethodCall(argsPre, nativeName, self.method.isStatic(), self.descriptor, self.method), pre=extraPre + @@ -3317,8 +3325,10 @@ class CGGenericGetter(CGAbstractBindingMethod): def generate_code(self): return CGIndenter(CGGeneric( - "let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, &*vp));\n" - "return CallJitPropertyOp(info, cx, obj, this as *libc::c_void, &*vp);")) + "return with_gc_disabled(cx, || {\n" + " let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, &*vp));\n" + " CallJitPropertyOp(info, cx, obj, this as *libc::c_void, &*vp)\n" + "});\n")) class CGSpecializedGetter(CGAbstractExternMethod): """ @@ -3348,8 +3358,8 @@ class CGSpecializedGetter(CGAbstractExternMethod): getter=True)) if name in self.descriptor.needsAbstract: abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType) - extraPre = ' let abstract_this = %s::from_box(this);\n' % abstractName - argsPre = ['abstract_this'] + extraPre = ' let mut abstract_this = %s::from_box(this);\n' % abstractName + argsPre = ['&mut abstract_this'] if resultOutParam or self.attr.type.nullable() or not infallible: nativeName = "Get" + nativeName return CGWrapper(CGIndenter(CGGetterCall(argsPre, self.attr.type, nativeName, @@ -3381,7 +3391,10 @@ class CGGenericSetter(CGAbstractBindingMethod): "let undef = JSVAL_VOID;\n" "let argv: *JSVal = if argc != 0 { JS_ARGV(cx, cast::transmute(vp)) } else { &undef as *JSVal };\n" "let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, cast::transmute(vp)));\n" - "if CallJitPropertyOp(info, cx, obj, this as *libc::c_void, argv) == 0 {" + "let ok = with_gc_disabled(cx, || {\n" + " CallJitPropertyOp(info, cx, obj, this as *libc::c_void, argv)\n" + "});\n" + "if ok == 0 {\n" " return 0;\n" "}\n" "*vp = JSVAL_VOID;\n" @@ -3408,8 +3421,8 @@ class CGSpecializedSetter(CGAbstractExternMethod): extraPre = '' if name in self.descriptor.needsAbstract: abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType) - extraPre = ' let abstract_this = %s::from_box(this);\n' % abstractName - argsPre = ['abstract_this'] + extraPre = ' let mut abstract_this = %s::from_box(this);\n' % abstractName + argsPre = ['&mut abstract_this'] return CGWrapper(CGIndenter(CGSetterCall(argsPre, self.attr.type, nativeName, self.descriptor, self.attr)), pre=extraPre + @@ -4482,9 +4495,9 @@ def finalizeHook(descriptor, hookName, context): else: assert descriptor.nativeIsISupports release = """let val = JS_GetReservedSlot(obj, dom_object_slot(obj)); -let _: @mut %s = cast::transmute(RUST_JSVAL_TO_PRIVATE(val)); +let _: %s %s = cast::transmute(RUST_JSVAL_TO_PRIVATE(val)); debug!("%s finalize: {:p}", this); -""" % (descriptor.concreteType, descriptor.concreteType) +""" % (DOMObjectPointerType(descriptor), descriptor.concreteType, descriptor.concreteType) #return clearWrapper + release return release @@ -4530,10 +4543,10 @@ class CGClassConstructHook(CGAbstractExternMethod): // or through unwrapping a slot or something). We'll punt and get the Window // from the context for now. let page = page_from_context(cx); - let global = (*page).frame.get_ref().window; + let global = (*page).frame.get_ref().window.clone(); let obj = global.reflector().get_jsobject(); """ - preArgs = ["global"] + preArgs = ["&global"] name = self._ctor.identifier.name nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name)) @@ -5151,6 +5164,7 @@ class CGBindingRoot(CGThing): 'js::jsfriendapi::bindgen::*', 'js::glue::*', 'dom::types::*', + 'dom::bindings::js::JS', 'dom::bindings::utils::*', 'dom::bindings::callback::*', 'dom::bindings::conversions::*', @@ -5158,10 +5172,6 @@ class CGBindingRoot(CGThing): 'script_task::{JSPageInfo, page_from_context}', 'dom::bindings::proxyhandler', 'dom::bindings::proxyhandler::*', - 'dom::document::AbstractDocument', - 'dom::node::AbstractNode', - 'dom::eventtarget::AbstractEventTarget', - 'dom::event::AbstractEvent', 'servo_util::str::DOMString', 'servo_util::vec::zip_copies', 'std::cast', @@ -5427,9 +5437,9 @@ class CGNativeMember(ClassMethod): else: typeDecl = "NonNull<%s>" else: - typeDecl = "%s%s" + typeDecl = "%s" descriptor = self.descriptorProvider.getDescriptor(iface.identifier.name) - return (typeDecl % (descriptor.pointerType, descriptor.nativeType), + return (typeDecl % descriptor.nativeType, False, False) if type.isSpiderMonkeyInterface(): @@ -5560,7 +5570,7 @@ class CGCallback(CGClass): bases=[ClassBase(baseName)], constructors=self.getConstructors(), methods=realMethods+getters+setters, - decorators="#[deriving(Eq,Clone)]") + decorators="#[deriving(Eq,Clone,Encodable)]") def getConstructors(self): return [ClassConstructor( @@ -5591,20 +5601,19 @@ class CGCallback(CGClass): args.append(Argument("ExceptionHandling", "aExceptionHandling", "eReportExceptions")) - # Ensure the first argument is mutable - args[0] = Argument(args[0].argType, args[0].name, args[0].default, mutable=True) + args[0] = Argument('&' + args[0].argType, args[0].name, args[0].default) method.args[2] = args[0] # And now insert our template argument. argsWithoutThis = list(args) - args.insert(0, Argument("@mut T", "thisObj")) + args.insert(0, Argument("~T", "thisObj")) # And the self argument method.args.insert(0, Argument(None, "&self")) args.insert(0, Argument(None, "&self")) argsWithoutThis.insert(0, Argument(None, "&self")) - setupCall = ("let s = CallSetup::new(cx_for_dom_object(&mut ${cxProvider}), aExceptionHandling);\n" + setupCall = ("let s = CallSetup::new(cx_for_dom_object(${cxProvider}), aExceptionHandling);\n" "if s.GetContext().is_null() {\n" " return${errorReturn};\n" "}\n") @@ -5619,7 +5628,7 @@ class CGCallback(CGClass): "errorReturn" : method.getDefaultRetval(), "callArgs" : ", ".join(argnamesWithThis), "methodName": 'self.' + method.name, - "cxProvider": '*thisObj' + "cxProvider": 'thisObj' }) bodyWithoutThis = string.Template( setupCall + @@ -5954,8 +5963,14 @@ class CallbackMethod(CallbackMember): replacements["argv"] = "nullptr" replacements["argc"] = "0" return string.Template("${getCallable}" - "if unsafe { JS_CallFunctionValue(cx, ${thisObj}, callable,\n" - " ${argc}, ${argv}, &rval) == 0 } {\n" + "let ok = unsafe {\n" + " //JS_AllowGC(cx); // It's unsafe to enable GC at arbitrary points during Rust execution; leave it disabled\n" + " let ok = JS_CallFunctionValue(cx, ${thisObj}, callable,\n" + " ${argc}, ${argv}, &rval);\n" + " //JS_InhibitGC(cx);\n" + " ok\n" + "};\n" + "if ok == 0 {\n" " return${errorReturn};\n" "}\n").substitute(replacements) @@ -6176,3 +6191,66 @@ class GlobalGenRoots(): curr = CGList([CGGeneric(declare="pub mod %sBinding;\n" % name) for name in descriptors]) curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT) return curr + + @staticmethod + def InheritTypes(config): + + descriptors = config.getDescriptors(register=True, hasInterfaceObject=True) + allprotos = [CGGeneric(declare="#[allow(unused_imports)];\n"), + CGGeneric(declare="use dom::types::*;\n"), + CGGeneric(declare="use dom::bindings::js::JS;\n"), + CGGeneric(declare="use dom::bindings::utils::Traceable;\n"), + CGGeneric(declare="use extra::serialize::{Encodable, Encoder};\n"), + CGGeneric(declare="use js::jsapi::JSTracer;\n\n")] + for descriptor in descriptors: + name = descriptor.name + protos = [CGGeneric(declare='pub trait %s {}\n' % (name + 'Base'))] + for proto in descriptor.prototypeChain: + protos += [CGGeneric(declare='impl %s for %s {}\n' % (proto + 'Base', + descriptor.concreteType))] + derived = [CGGeneric(declare='pub trait %s { fn %s(&self) -> bool; }\n' % + (name + 'Derived', 'is_' + name.lower()))] + for protoName in descriptor.prototypeChain[1:-1]: + protoDescriptor = config.getDescriptor(protoName, False) + delegate = string.Template('''impl ${selfName} for ${baseName} { + fn ${fname}(&self) -> bool { + self.${parentName}.${fname}() + } +} +''').substitute({'fname': 'is_' + name.lower(), + 'selfName': name + 'Derived', + 'baseName': protoDescriptor.concreteType, + 'parentName': protoDescriptor.prototypeChain[-2].lower()}) + derived += [CGGeneric(declare=delegate)] + derived += [CGGeneric(declare='\n')] + + cast = [CGGeneric(declare=string.Template('''pub trait ${castTraitName} { + fn from<T: ${fromBound}>(derived: &JS<T>) -> JS<Self> { + unsafe { derived.clone().transmute() } + } + + fn to<T: ${toBound}>(base: &JS<T>) -> JS<Self> { + assert!(base.get().${checkFn}()); + unsafe { base.clone().transmute() } + } +} +''').substitute({'checkFn': 'is_' + name.lower(), + 'castTraitName': name + 'Cast', + 'fromBound': name + 'Base', + 'toBound': name + 'Derived'})), + CGGeneric(declare="impl %s for %s {}\n\n" % (name + 'Cast', name))] + + trace = [CGGeneric(declare=string.Template('''impl Traceable for ${name} { + fn trace(&self, tracer: *mut JSTracer) { + unsafe { + self.encode(&mut *tracer); + } + } +} +''').substitute({'name': name}))] + + allprotos += protos + derived + cast + trace + + curr = CGList(allprotos) + curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT) + return curr diff --git a/src/components/script/dom/bindings/codegen/Configuration.py b/src/components/script/dom/bindings/codegen/Configuration.py index 0c87ead0259..e28e24bbcfa 100644 --- a/src/components/script/dom/bindings/codegen/Configuration.py +++ b/src/components/script/dom/bindings/codegen/Configuration.py @@ -158,10 +158,9 @@ class Descriptor(DescriptorProvider): if self.workers: nativeTypeDefault = "workers::" + ifaceName else: - nativeTypeDefault = ifaceName + nativeTypeDefault = 'JS<%s>' % ifaceName self.nativeType = desc.get('nativeType', nativeTypeDefault) - self.pointerType = desc.get('pointerType', '@mut ') self.concreteType = desc.get('concreteType', ifaceName) self.needsAbstract = desc.get('needsAbstract', []) self.hasInstanceInterface = desc.get('hasInstanceInterface', None) @@ -253,7 +252,7 @@ class Descriptor(DescriptorProvider): self.prefable = desc.get('prefable', False) self.nativeIsISupports = not self.workers - self.customTrace = desc.get('customTrace', self.workers) + self.customTrace = desc.get('customTrace', self.workers) or 'trace' self.customFinalize = desc.get('customFinalize', self.workers) self.wrapperCache = self.workers or desc.get('wrapperCache', True) diff --git a/src/components/script/dom/bindings/codegen/GlobalGen.py b/src/components/script/dom/bindings/codegen/GlobalGen.py index 9f46c786065..ffbf31a4b48 100644 --- a/src/components/script/dom/bindings/codegen/GlobalGen.py +++ b/src/components/script/dom/bindings/codegen/GlobalGen.py @@ -83,6 +83,9 @@ def main(): # Generate the type list. generate_file(config, 'InterfaceTypes', 'declare+define') + # Generate the type list. + generate_file(config, 'InheritTypes', 'declare+define') + # Generate the module declarations. generate_file(config, 'BindingDeclarations', 'declare+define') diff --git a/src/components/script/dom/bindings/element.rs b/src/components/script/dom/bindings/element.rs index 9bbaf08fc6e..64190409ef5 100644 --- a/src/components/script/dom/bindings/element.rs +++ b/src/components/script/dom/bindings/element.rs @@ -3,9 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::types::*; -use dom::bindings::utils::{Reflectable, Reflector, Traceable}; - -use js::jsapi::JSTracer; +use dom::bindings::utils::{Reflectable, Reflector}; // generate_cacheable_wrapper macro_rules! generate_cacheable_wrapper( @@ -58,277 +56,149 @@ macro_rules! generate_cacheable_wrapper_base( ) ) - -// generate_traceable -macro_rules! generate_traceable( - ($name: path) => ( - generate_traceable_base!($name, element) - ) -) - -macro_rules! generate_traceable_characterdata( - ($name: path) => ( - generate_traceable_base!($name, characterdata) - ) -) - -macro_rules! generate_traceable_htmlelement( - ($name: path) => ( - generate_traceable_base!($name, htmlelement) - ) -) - -macro_rules! generate_traceable_htmlmediaelement( - ($name: path) => ( - generate_traceable_base!($name, htmlmediaelement) - ) -) - -macro_rules! generate_traceable_htmltablecellelement( - ($name: path) => ( - generate_traceable_base!($name, htmltablecellelement) - ) -) - -macro_rules! generate_traceable_node( - ($name: path) => ( - generate_traceable_base!($name, node) - ) -) - -macro_rules! generate_traceable_base( - ($name: path, $parent: ident) => ( - impl Traceable for $name { - fn trace(&self, trc: *mut JSTracer) { - self.$parent.trace(trc); - } - } - ) -) - - generate_cacheable_wrapper_characterdata!(Comment, CommentBinding::Wrap) -generate_traceable_characterdata!(Comment) generate_cacheable_wrapper_node!(DocumentFragment, DocumentFragmentBinding::Wrap) -generate_traceable_node!(DocumentFragment) generate_cacheable_wrapper_node!(DocumentType, DocumentTypeBinding::Wrap) -generate_traceable_node!(DocumentType) generate_cacheable_wrapper_characterdata!(Text, TextBinding::Wrap) -generate_traceable_characterdata!(Text) generate_cacheable_wrapper_characterdata!(ProcessingInstruction, ProcessingInstruction::Wrap) -generate_traceable_characterdata!(ProcessingInstruction) generate_cacheable_wrapper_htmlelement!(HTMLHeadElement, HTMLHeadElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLHeadElement) generate_cacheable_wrapper_htmlelement!(HTMLAnchorElement, HTMLAnchorElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLAnchorElement) generate_cacheable_wrapper_htmlelement!(HTMLAppletElement, HTMLAppletElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLAppletElement) generate_cacheable_wrapper_htmlelement!(HTMLAreaElement, HTMLAreaElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLAreaElement) generate_cacheable_wrapper_htmlmediaelement!(HTMLAudioElement, HTMLAudioElementBinding::Wrap) -generate_traceable_htmlmediaelement!(HTMLAudioElement) generate_cacheable_wrapper_htmlelement!(HTMLBaseElement, HTMLBaseElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLBaseElement) generate_cacheable_wrapper_htmlelement!(HTMLBodyElement, HTMLBodyElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLBodyElement) generate_cacheable_wrapper_htmlelement!(HTMLButtonElement, HTMLButtonElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLButtonElement) generate_cacheable_wrapper_htmlelement!(HTMLCanvasElement, HTMLCanvasElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLCanvasElement) generate_cacheable_wrapper_htmlelement!(HTMLDataListElement, HTMLDataListElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLDataListElement) generate_cacheable_wrapper_htmlelement!(HTMLDListElement, HTMLDListElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLDListElement) generate_cacheable_wrapper_htmlelement!(HTMLFormElement, HTMLFormElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLFormElement) generate_cacheable_wrapper_htmlelement!(HTMLFrameElement, HTMLFrameElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLFrameElement) generate_cacheable_wrapper_htmlelement!(HTMLFrameSetElement, HTMLFrameSetElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLFrameSetElement) generate_cacheable_wrapper_htmlelement!(HTMLBRElement, HTMLBRElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLBRElement) generate_cacheable_wrapper_htmlelement!(HTMLHRElement, HTMLHRElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLHRElement) generate_cacheable_wrapper_htmlelement!(HTMLHtmlElement, HTMLHtmlElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLHtmlElement) generate_cacheable_wrapper_htmlelement!(HTMLDataElement, HTMLDataElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLDataElement) generate_cacheable_wrapper_htmlelement!(HTMLDirectoryElement, HTMLDirectoryElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLDirectoryElement) - generate_cacheable_wrapper_htmlelement!(HTMLDivElement, HTMLDivElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLDivElement) generate_cacheable_wrapper_htmlelement!(HTMLEmbedElement, HTMLEmbedElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLEmbedElement) generate_cacheable_wrapper_htmlelement!(HTMLFieldSetElement, HTMLFieldSetElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLFieldSetElement) generate_cacheable_wrapper_htmlelement!(HTMLFontElement, HTMLFontElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLFontElement) generate_cacheable_wrapper_htmlelement!(HTMLHeadingElement, HTMLHeadingElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLHeadingElement) generate_cacheable_wrapper_htmlelement!(HTMLIFrameElement, HTMLIFrameElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLIFrameElement) generate_cacheable_wrapper_htmlelement!(HTMLImageElement, HTMLImageElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLImageElement) generate_cacheable_wrapper_htmlelement!(HTMLInputElement, HTMLInputElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLInputElement) generate_cacheable_wrapper_htmlelement!(HTMLLabelElement, HTMLLabelElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLLabelElement) generate_cacheable_wrapper_htmlelement!(HTMLLegendElement, HTMLLegendElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLLegendElement) generate_cacheable_wrapper_htmlelement!(HTMLLIElement, HTMLLIElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLLIElement) generate_cacheable_wrapper_htmlelement!(HTMLLinkElement, HTMLLinkElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLLinkElement) generate_cacheable_wrapper_htmlelement!(HTMLMainElement, HTMLMainElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLMainElement) generate_cacheable_wrapper_htmlelement!(HTMLMapElement, HTMLMapElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLMapElement) generate_cacheable_wrapper_htmlelement!(HTMLMediaElement, HTMLMediaElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLMediaElement) generate_cacheable_wrapper_htmlelement!(HTMLMetaElement, HTMLMetaElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLMetaElement) generate_cacheable_wrapper_htmlelement!(HTMLMeterElement, HTMLMeterElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLMeterElement) generate_cacheable_wrapper_htmlelement!(HTMLModElement, HTMLModElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLModElement) generate_cacheable_wrapper_htmlelement!(HTMLObjectElement, HTMLObjectElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLObjectElement) generate_cacheable_wrapper_htmlelement!(HTMLOListElement, HTMLOListElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLOListElement) generate_cacheable_wrapper_htmlelement!(HTMLOptGroupElement, HTMLOptGroupElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLOptGroupElement) generate_cacheable_wrapper_htmlelement!(HTMLOptionElement, HTMLOptionElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLOptionElement) generate_cacheable_wrapper_htmlelement!(HTMLOutputElement, HTMLOutputElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLOutputElement) generate_cacheable_wrapper_htmlelement!(HTMLParagraphElement, HTMLParagraphElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLParagraphElement) generate_cacheable_wrapper_htmlelement!(HTMLParamElement, HTMLParamElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLParamElement) generate_cacheable_wrapper_htmlelement!(HTMLPreElement, HTMLPreElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLPreElement) generate_cacheable_wrapper_htmlelement!(HTMLProgressElement, HTMLProgressElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLProgressElement) generate_cacheable_wrapper_htmlelement!(HTMLQuoteElement, HTMLQuoteElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLQuoteElement) generate_cacheable_wrapper_htmlelement!(HTMLScriptElement, HTMLScriptElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLScriptElement) generate_cacheable_wrapper_htmlelement!(HTMLSelectElement, HTMLSelectElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLSelectElement) generate_cacheable_wrapper_htmlelement!(HTMLSourceElement, HTMLSourceElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLSourceElement) generate_cacheable_wrapper_htmlelement!(HTMLSpanElement, HTMLSpanElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLSpanElement) generate_cacheable_wrapper_htmlelement!(HTMLStyleElement, HTMLStyleElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLStyleElement) generate_cacheable_wrapper_htmlelement!(HTMLTableElement, HTMLTableElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLTableElement) generate_cacheable_wrapper_htmlelement!(HTMLTableCaptionElement, HTMLTableCaptionElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLTableCaptionElement) generate_cacheable_wrapper_htmlelement!(HTMLTableCellElement, HTMLTableCellElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLTableCellElement) generate_cacheable_wrapper_htmltablecellelement!(HTMLTableDataCellElement, HTMLTableDataCellElementBinding::Wrap) -generate_traceable_htmltablecellelement!(HTMLTableDataCellElement) generate_cacheable_wrapper_htmltablecellelement!(HTMLTableHeaderCellElement, HTMLTableHeaderCellElementBinding::Wrap) -generate_traceable_htmltablecellelement!(HTMLTableHeaderCellElement) generate_cacheable_wrapper_htmlelement!(HTMLTableColElement, HTMLTableColElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLTableColElement) generate_cacheable_wrapper_htmlelement!(HTMLTableRowElement, HTMLTableRowElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLTableRowElement) generate_cacheable_wrapper_htmlelement!(HTMLTableSectionElement, HTMLTableSectionElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLTableSectionElement) generate_cacheable_wrapper_htmlelement!(HTMLTemplateElement, HTMLTemplateElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLTemplateElement) generate_cacheable_wrapper_htmlelement!(HTMLTextAreaElement, HTMLTextAreaElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLTextAreaElement) generate_cacheable_wrapper_htmlelement!(HTMLTitleElement, HTMLTitleElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLTitleElement) generate_cacheable_wrapper_htmlelement!(HTMLTimeElement, HTMLTimeElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLTimeElement) generate_cacheable_wrapper_htmlelement!(HTMLTrackElement, HTMLTrackElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLTrackElement) generate_cacheable_wrapper_htmlelement!(HTMLUListElement, HTMLUListElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLUListElement) generate_cacheable_wrapper_htmlelement!(HTMLUnknownElement, HTMLUnknownElementBinding::Wrap) -generate_traceable_htmlelement!(HTMLUnknownElement) generate_cacheable_wrapper_htmlmediaelement!(HTMLVideoElement, HTMLVideoElementBinding::Wrap) -generate_traceable_htmlmediaelement!(HTMLVideoElement) generate_cacheable_wrapper!(HTMLElement, HTMLElementBinding::Wrap) -generate_traceable!(HTMLElement) - -generate_traceable_node!(Element) - -generate_traceable_node!(CharacterData) diff --git a/src/components/script/dom/bindings/js.rs b/src/components/script/dom/bindings/js.rs new file mode 100644 index 00000000000..aa7ba954a48 --- /dev/null +++ b/src/components/script/dom/bindings/js.rs @@ -0,0 +1,99 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use dom::bindings::utils::{Reflector, Reflectable}; +use dom::window; +use js::jsapi::{JSContext, JSObject}; +use layout_interface::TrustedNodeAddress; + +use std::cast; +use std::cell::RefCell; +use std::unstable::raw::Box; + +pub struct JS<T> { + priv ptr: RefCell<*mut T> +} + +impl<T> Eq for JS<T> { + fn eq(&self, other: &JS<T>) -> bool { + self.ptr == other.ptr + } +} + +impl <T> Clone for JS<T> { + fn clone(&self) -> JS<T> { + JS { + ptr: self.ptr.clone() + } + } +} + +impl<T: Reflectable> JS<T> { + pub fn new(mut obj: ~T, + window: &window::Window, + wrap_fn: extern "Rust" fn(*JSContext, *JSObject, ~T) -> *JSObject) -> JS<T> { + let cx = window.get_cx(); + let scope = window.reflector().get_jsobject(); + let raw: *mut T = &mut *obj; + if wrap_fn(cx, scope, obj).is_null() { + fail!("Could not eagerly wrap object"); + } + JS { + ptr: RefCell::new(raw) + } + } + + pub unsafe fn from_raw(raw: *mut T) -> JS<T> { + JS { + ptr: RefCell::new(raw) + } + } + + + pub unsafe fn from_box(box_: *mut Box<T>) -> JS<T> { + let raw: *mut T = &mut (*box_).data; + JS { + ptr: RefCell::new(raw) + } + } + + pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS<T> { + JS { + ptr: RefCell::new(inner as *mut T) + } + } +} + +impl<T: Reflectable> Reflectable for JS<T> { + fn reflector<'a>(&'a self) -> &'a Reflector { + self.get().reflector() + } + + fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { + self.get_mut().mut_reflector() + } +} + +impl<T> JS<T> { + pub fn get<'a>(&'a self) -> &'a T { + let borrowed = self.ptr.borrow(); + unsafe { + &(**borrowed.get()) + } + } + + pub fn get_mut<'a>(&'a mut self) -> &'a mut T { + let mut borrowed = self.ptr.borrow_mut(); + unsafe { + &mut (**borrowed.get()) + } + } +} + +impl<From, To> JS<From> { + //XXXjdm It would be lovely if this could be private. + pub unsafe fn transmute(self) -> JS<To> { + cast::transmute(self) + } +} diff --git a/src/components/script/dom/bindings/node.rs b/src/components/script/dom/bindings/node.rs deleted file mode 100644 index 8bf2ab8a565..00000000000 --- a/src/components/script/dom/bindings/node.rs +++ /dev/null @@ -1,52 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -use dom::bindings::utils::{Reflectable, Reflector, Traceable, trace_reflector}; -use dom::types::*; -use dom::node::AbstractNode; - -use std::cast; -use std::libc; -use std::ptr; -use js::jsapi::{JSTracer, JSTRACE_OBJECT, JS_CallTracer}; - -impl Reflectable for AbstractNode { - fn reflector<'a>(&'a self) -> &'a Reflector { - self.node().reflector() - } - - fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { - self.mut_node().mut_reflector() - } -} - -impl Traceable for Node { - fn trace(&self, tracer: *mut JSTracer) { - fn trace_node(tracer: *mut JSTracer, node: Option<AbstractNode>, name: &str) { - if node.is_none() { - return; - } - debug!("tracing {:s}", name); - let node = node.unwrap(); - let obj = node.reflector().get_jsobject(); - assert!(obj.is_not_null()); - unsafe { - (*tracer).debugPrinter = ptr::null(); - (*tracer).debugPrintIndex = -1; - name.to_c_str().with_ref(|name| { - (*tracer).debugPrintArg = name as *libc::c_void; - JS_CallTracer(cast::transmute(tracer), obj, JSTRACE_OBJECT as u32); - }); - } - } - debug!("tracing {:p}?:", self.reflector().get_jsobject()); - trace_node(tracer, self.parent_node, "parent"); - trace_node(tracer, self.first_child, "first child"); - trace_node(tracer, self.last_child, "last child"); - trace_node(tracer, self.next_sibling, "next sibling"); - trace_node(tracer, self.prev_sibling, "prev sibling"); - let owner_doc = self.owner_doc(); - trace_reflector(tracer, "document", owner_doc.reflector()); - } -} diff --git a/src/components/script/dom/bindings/trace.rs b/src/components/script/dom/bindings/trace.rs new file mode 100644 index 00000000000..6565bf8c2d9 --- /dev/null +++ b/src/components/script/dom/bindings/trace.rs @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use dom::bindings::js::JS; +use dom::bindings::utils::{Reflectable, trace_reflector, Reflector}; + +use js::jsapi::JSTracer; + +use std::cast; +use extra::serialize::{Encodable, Encoder}; + +// IMPORTANT: We rely on the fact that we never attempt to encode DOM objects using +// any encoder but JSTracer. Since we derive trace hooks automatically, +// we are unfortunately required to use generic types everywhere and +// unsafely cast to the concrete JSTracer we actually require. + +impl<T: Reflectable+Encodable<S>, S: Encoder> Encodable<S> for JS<T> { + fn encode(&self, s: &mut S) { + let s: &mut JSTracer = unsafe { cast::transmute(s) }; + trace_reflector(s, "", self.reflector()); + } +} + +impl<S: Encoder> Encodable<S> for Reflector { + fn encode(&self, _s: &mut S) { + } +} diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index 671f92e3766..595d131c80c 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -4,11 +4,13 @@ use dom::bindings::codegen::PrototypeList; use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH; +use dom::bindings::js::JS; use dom::window; use servo_util::str::DOMString; use std::libc::c_uint; use std::cast; +use std::cmp::Eq; use std::hashmap::HashMap; use std::libc; use std::ptr; @@ -32,7 +34,7 @@ use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass, JSNative, JSTracer}; use js::jsapi::{JSFunctionSpec, JSPropertySpec, JSVal, JSPropertyDescriptor}; use js::jsapi::{JS_NewGlobalObject, JS_InitStandardClasses}; use js::jsapi::{JSString, JS_CallTracer, JSTRACE_OBJECT}; -use js::jsapi::{JS_IsExceptionPending}; +use js::jsapi::{JS_IsExceptionPending, JS_AllowGC, JS_InhibitGC}; use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType; use js::{JSPROP_ENUMERATE, JSVAL_NULL, JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS}; use js::{JSPROP_PERMANENT, JSID_VOID, JSPROP_NATIVE_ACCESSORS, JSPROP_GETTER}; @@ -174,6 +176,17 @@ pub fn unwrap_object<T>(obj: *JSObject, proto_id: PrototypeList::id::ID, proto_d } } +pub fn unwrap_jsmanaged<T: Reflectable>(obj: *JSObject, + proto_id: PrototypeList::id::ID, + proto_depth: uint) -> Result<JS<T>, ()> { + let result: Result<*mut Box<T>, ()> = unwrap_object(obj, proto_id, proto_depth); + result.map(|unwrapped| { + unsafe { + JS::from_box(unwrapped) + } + }) +} + pub fn unwrap_value<T>(val: *JSVal, proto_id: PrototypeList::id::ID, proto_depth: uint) -> Result<T, ()> { unsafe { let obj = RUST_JSVAL_TO_OBJECT(*val); @@ -182,8 +195,11 @@ pub fn unwrap_value<T>(val: *JSVal, proto_id: PrototypeList::id::ID, proto_depth } pub unsafe fn squirrel_away<T>(x: @mut T) -> *Box<T> { - let y: *Box<T> = cast::transmute(x); - y + cast::transmute(x) +} + +pub unsafe fn squirrel_away_unique<T>(x: ~T) -> *Box<T> { + cast::transmute(x) } pub fn jsstring_to_str(cx: *JSContext, s: *JSString) -> DOMString { @@ -557,10 +573,6 @@ pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Ref } } -pub fn trace_option<T: Reflectable>(tracer: *mut JSTracer, description: &str, option: Option<@mut T>) { - option.map(|some| trace_reflector(tracer, description, some.reflector())); -} - pub fn initialize_global(global: *JSObject) { let protoArray = @mut ([0 as *JSObject, ..PrototypeList::id::_ID_Count as uint]); unsafe { @@ -579,21 +591,17 @@ pub trait Reflectable { } pub fn reflect_dom_object<T: Reflectable> - (obj: @mut T, + (obj: ~T, window: &window::Window, - wrap_fn: extern "Rust" fn(*JSContext, *JSObject, @mut T) -> *JSObject) - -> @mut T { - let cx = window.get_cx(); - let scope = window.reflector().get_jsobject(); - if wrap_fn(cx, scope, obj).is_null() { - fail!("Could not eagerly wrap object"); - } - assert!(obj.reflector().get_jsobject().is_not_null()); - obj + wrap_fn: extern "Rust" fn(*JSContext, *JSObject, ~T) -> *JSObject) + -> JS<T> { + JS::new(obj, window, wrap_fn) } +#[deriving(Eq)] pub struct Reflector { - object: *JSObject + object: *JSObject, + force_box_layout: @int, } impl Reflector { @@ -610,7 +618,8 @@ impl Reflector { pub fn new() -> Reflector { Reflector { - object: ptr::null() + object: ptr::null(), + force_box_layout: @1, } } } @@ -849,11 +858,11 @@ fn cx_for_dom_reflector(obj: *JSObject) -> *JSContext { } /// Returns the global object of the realm that the given DOM object was created in. -pub fn global_object_for_dom_object<T: Reflectable>(obj: &mut T) -> *Box<window::Window> { +pub fn global_object_for_dom_object<T: Reflectable>(obj: &T) -> *Box<window::Window> { global_object_for_js_object(obj.reflector().get_jsobject()) } -pub fn cx_for_dom_object<T: Reflectable>(obj: &mut T) -> *JSContext { +pub fn cx_for_dom_object<T: Reflectable>(obj: &T) -> *JSContext { cx_for_dom_reflector(obj.reflector().get_jsobject()) } @@ -870,6 +879,26 @@ pub fn throw_method_failed_with_details<T>(cx: *JSContext, return 0; } +/// Execute arbitrary code with the JS GC enabled, then disable it afterwards. +pub fn with_gc_enabled<R>(cx: *JSContext, f: || -> R) -> R { + unsafe { + JS_AllowGC(cx); + let rv = f(); + JS_InhibitGC(cx); + rv + } +} + +/// Execute arbitrary code with the JS GC disabled, then enable it afterwards. +pub fn with_gc_disabled<R>(cx: *JSContext, f: || -> R) -> R { + unsafe { + JS_InhibitGC(cx); + let rv = f(); + JS_AllowGC(cx); + rv + } +} + /// Check if an element name is valid. See http://www.w3.org/TR/xml/#NT-Name /// for details. #[deriving(Eq)] diff --git a/src/components/script/dom/blob.rs b/src/components/script/dom/blob.rs index 2bf0d0b7510..386b9447590 100644 --- a/src/components/script/dom/blob.rs +++ b/src/components/script/dom/blob.rs @@ -2,32 +2,36 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::Fallible; use dom::bindings::codegen::BlobBinding; use dom::window::Window; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct Blob { reflector_: Reflector, - window: @mut Window, + window: JS<Window> } impl Blob { - pub fn new_inherited(window: @mut Window) -> Blob { + pub fn new_inherited(window: JS<Window>) -> Blob { Blob { reflector_: Reflector::new(), - window: window, + window: window } } - pub fn new(window: @mut Window) -> @mut Blob { - reflect_dom_object(@mut Blob::new_inherited(window), window, BlobBinding::Wrap) + pub fn new(window: &JS<Window>) -> JS<Blob> { + reflect_dom_object(~Blob::new_inherited(window.clone()), + window.get(), + BlobBinding::Wrap) } } impl Blob { - pub fn Constructor(window: @mut Window) -> Fallible<@mut Blob> { + pub fn Constructor(window: &JS<Window>) -> Fallible<JS<Blob>> { Ok(Blob::new(window)) } @@ -39,8 +43,8 @@ impl Blob { ~"" } - pub fn Slice(&self, _start: i64, _end: i64, _contentType: Option<DOMString>) -> @mut Blob { - Blob::new(self.window) + pub fn Slice(&self, _start: i64, _end: i64, _contentType: Option<DOMString>) -> JS<Blob> { + Blob::new(&self.window) } pub fn Close(&self) {} diff --git a/src/components/script/dom/characterdata.rs b/src/components/script/dom/characterdata.rs index 0ad5f35bc78..f4bb567b5c6 100644 --- a/src/components/script/dom/characterdata.rs +++ b/src/components/script/dom/characterdata.rs @@ -4,19 +4,34 @@ //! DOM bindings for `CharacterData`. +use dom::bindings::codegen::InheritTypes::CharacterDataDerived; +use dom::bindings::js::JS; use dom::bindings::utils::{Fallible, ErrorResult}; use dom::bindings::utils::{Reflectable, Reflector}; -use dom::document::AbstractDocument; -use dom::node::{Node, NodeTypeId}; +use dom::document::Document; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; +use dom::node::{CommentNodeTypeId, Node, NodeTypeId, TextNodeTypeId, ProcessingInstructionNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct CharacterData { node: Node, data: DOMString, } +impl CharacterDataDerived for EventTarget { + fn is_characterdata(&self) -> bool { + match self.type_id { + NodeTargetTypeId(TextNodeTypeId) | + NodeTargetTypeId(CommentNodeTypeId) | + NodeTargetTypeId(ProcessingInstructionNodeTypeId) => true, + _ => false + } + } +} + impl CharacterData { - pub fn new_inherited(id: NodeTypeId, data: DOMString, document: AbstractDocument) -> CharacterData { + pub fn new_inherited(id: NodeTypeId, data: DOMString, document: JS<Document>) -> CharacterData { CharacterData { node: Node::new_inherited(id, document), data: data diff --git a/src/components/script/dom/clientrect.rs b/src/components/script/dom/clientrect.rs index 366c33fecbe..e4fd8716c26 100644 --- a/src/components/script/dom/clientrect.rs +++ b/src/components/script/dom/clientrect.rs @@ -3,21 +3,23 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::ClientRectBinding; +use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::window::Window; use servo_util::geometry::Au; +#[deriving(Encodable)] pub struct ClientRect { reflector_: Reflector, top: f32, bottom: f32, left: f32, right: f32, - window: @mut Window, + window: JS<Window>, } impl ClientRect { - pub fn new_inherited(window: @mut Window, + pub fn new_inherited(window: JS<Window>, top: Au, bottom: Au, left: Au, right: Au) -> ClientRect { ClientRect { @@ -30,11 +32,11 @@ impl ClientRect { } } - pub fn new(window: @mut Window, + pub fn new(window: &JS<Window>, top: Au, bottom: Au, - left: Au, right: Au) -> @mut ClientRect { - let rect = ClientRect::new_inherited(window, top, bottom, left, right); - reflect_dom_object(@mut rect, window, ClientRectBinding::Wrap) + left: Au, right: Au) -> JS<ClientRect> { + let rect = ClientRect::new_inherited(window.clone(), top, bottom, left, right); + reflect_dom_object(~rect, window.get(), ClientRectBinding::Wrap) } diff --git a/src/components/script/dom/clientrectlist.rs b/src/components/script/dom/clientrectlist.rs index 7d221754fa3..bae001379ae 100644 --- a/src/components/script/dom/clientrectlist.rs +++ b/src/components/script/dom/clientrectlist.rs @@ -3,19 +3,21 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::ClientRectListBinding; +use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::clientrect::ClientRect; use dom::window::Window; +#[deriving(Encodable)] pub struct ClientRectList { reflector_: Reflector, - rects: ~[@mut ClientRect], - window: @mut Window, + rects: ~[JS<ClientRect>], + window: JS<Window>, } impl ClientRectList { - pub fn new_inherited(window: @mut Window, - rects: ~[@mut ClientRect]) -> ClientRectList { + pub fn new_inherited(window: JS<Window>, + rects: ~[JS<ClientRect>]) -> ClientRectList { ClientRectList { reflector_: Reflector::new(), rects: rects, @@ -23,25 +25,25 @@ impl ClientRectList { } } - pub fn new(window: @mut Window, - rects: ~[@mut ClientRect]) -> @mut ClientRectList { - reflect_dom_object(@mut ClientRectList::new_inherited(window, rects), - window, ClientRectListBinding::Wrap) + pub fn new(window: &JS<Window>, + rects: ~[JS<ClientRect>]) -> JS<ClientRectList> { + reflect_dom_object(~ClientRectList::new_inherited(window.clone(), rects), + window.get(), ClientRectListBinding::Wrap) } pub fn Length(&self) -> u32 { self.rects.len() as u32 } - pub fn Item(&self, index: u32) -> Option<@mut ClientRect> { + pub fn Item(&self, index: u32) -> Option<JS<ClientRect>> { if index < self.rects.len() as u32 { - Some(self.rects[index]) + Some(self.rects[index].clone()) } else { None } } - pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<@mut ClientRect> { + pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<ClientRect>> { *found = index < self.rects.len() as u32; self.Item(index) } diff --git a/src/components/script/dom/comment.rs b/src/components/script/dom/comment.rs index a94c7bb2970..5dcfde7b418 100644 --- a/src/components/script/dom/comment.rs +++ b/src/components/script/dom/comment.rs @@ -2,32 +2,45 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::bindings::codegen::InheritTypes::CommentDerived; use dom::bindings::codegen::CommentBinding; +use dom::bindings::js::JS; use dom::bindings::utils::Fallible; use dom::characterdata::CharacterData; -use dom::document::AbstractDocument; -use dom::node::{AbstractNode, CommentNodeTypeId, Node}; +use dom::document::Document; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; +use dom::node::{CommentNodeTypeId, Node}; use dom::window::Window; use servo_util::str::DOMString; /// An HTML comment. +#[deriving(Encodable)] pub struct Comment { characterdata: CharacterData, } +impl CommentDerived for EventTarget { + fn is_comment(&self) -> bool { + match self.type_id { + NodeTargetTypeId(CommentNodeTypeId) => true, + _ => false + } + } +} + impl Comment { - pub fn new_inherited(text: DOMString, document: AbstractDocument) -> Comment { + pub fn new_inherited(text: DOMString, document: JS<Document>) -> Comment { Comment { characterdata: CharacterData::new_inherited(CommentNodeTypeId, text, document) } } - pub fn new(text: DOMString, document: AbstractDocument) -> AbstractNode { - let node = Comment::new_inherited(text, document); - Node::reflect_node(@mut node, document, CommentBinding::Wrap) + pub fn new(text: DOMString, document: &JS<Document>) -> JS<Comment> { + let node = Comment::new_inherited(text, document.clone()); + Node::reflect_node(~node, document, CommentBinding::Wrap) } - pub fn Constructor(owner: @mut Window, data: DOMString) -> Fallible<AbstractNode> { - Ok(Comment::new(data, owner.Document())) + pub fn Constructor(owner: &JS<Window>, data: DOMString) -> Fallible<JS<Comment>> { + Ok(Comment::new(data, &owner.get().Document())) } } diff --git a/src/components/script/dom/console.rs b/src/components/script/dom/console.rs index 98d12a17389..3c5a219b39c 100644 --- a/src/components/script/dom/console.rs +++ b/src/components/script/dom/console.rs @@ -2,11 +2,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::codegen::ConsoleBinding; +use dom::bindings::js::JS; +use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::window::Window; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct Console { reflector_: Reflector } @@ -18,8 +20,8 @@ impl Console { } } - pub fn new(window: &Window) -> @mut Console { - reflect_dom_object(@mut Console::new_inherited(), window, ConsoleBinding::Wrap) + pub fn new(window: &Window) -> JS<Console> { + reflect_dom_object(~Console::new_inherited(), window, ConsoleBinding::Wrap) } pub fn Log(&self, message: DOMString) { diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs index 37df96353a9..f699c859d74 100644 --- a/src/components/script/dom/document.rs +++ b/src/components/script/dom/document.rs @@ -2,25 +2,35 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::comment::Comment; +use dom::bindings::codegen::InheritTypes::{DocumentDerived, EventCast, HTMLElementCast}; +use dom::bindings::codegen::InheritTypes::{DocumentBase, NodeCast, DocumentCast}; +use dom::bindings::codegen::InheritTypes::{HTMLHeadElementCast, TextCast, ElementCast}; +use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, HTMLHtmlElementCast}; use dom::bindings::codegen::DocumentBinding; -use dom::bindings::utils::{Reflectable, Reflector, Traceable, reflect_dom_object}; +use dom::bindings::js::JS; +use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::{ErrorResult, Fallible, NotSupported, InvalidCharacter, HierarchyRequest}; use dom::bindings::utils::{xml_name_type, InvalidXMLName}; +use dom::comment::Comment; use dom::documentfragment::DocumentFragment; +use dom::documenttype; use dom::domimplementation::DOMImplementation; use dom::element::{Element}; -use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElementTypeId, HTMLBodyElementTypeId, HTMLFrameSetElementTypeId}; -use dom::event::{AbstractEvent, Event}; +use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElementTypeId}; +use dom::element::{HTMLBodyElementTypeId, HTMLFrameSetElementTypeId}; +use dom::event::Event; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlcollection::HTMLCollection; -use dom::htmldocument::HTMLDocument; +use dom::htmlelement::HTMLElement; +use dom::htmlheadelement::HTMLHeadElement; +use dom::htmlhtmlelement::HTMLHtmlElement; +use dom::htmltitleelement::HTMLTitleElement; use dom::mouseevent::MouseEvent; -use dom::node::{AbstractNode, Node, ElementNodeTypeId, DocumentNodeTypeId}; +use dom::node::{Node, ElementNodeTypeId, DocumentNodeTypeId, NodeHelpers, INode}; use dom::text::Text; use dom::processinginstruction::ProcessingInstruction; use dom::uievent::UIEvent; use dom::window::Window; -use dom::htmltitleelement::HTMLTitleElement; use html::hubbub_html_parser::build_element_from_tag; use hubbub::hubbub::{QuirksMode, NoQuirks, LimitedQuirks, FullQuirks}; use layout_interface::{DocumentDamageLevel, ContentChangedDocumentDamage}; @@ -28,103 +38,74 @@ use servo_util::namespace::Null; use servo_util::str::DOMString; use extra::url::{Url, from_str}; -use js::jsapi::{JSObject, JSContext, JSTracer}; +use js::jsapi::{JSObject, JSContext}; use std::ascii::StrAsciiExt; -use std::cast; use std::hashmap::HashMap; -use std::unstable::raw::Box; -#[deriving(Eq)] +use extra::serialize::{Encoder, Encodable}; + +#[deriving(Eq,Encodable)] pub enum DocumentTypeId { PlainDocumentTypeId, HTMLDocumentTypeId } -#[deriving(Eq)] -pub struct AbstractDocument { - document: *mut Box<Document> -} - -impl AbstractDocument { - pub fn document<'a>(&'a self) -> &'a Document { - unsafe { - &(*self.document).data - } - } - - pub fn mut_document<'a>(&'a self) -> &'a mut Document { - unsafe { - &mut (*self.document).data - } - } - - unsafe fn transmute<T, R>(&self, f: |&T| -> R) -> R { - let box_: *Box<T> = cast::transmute(self.document); - f(&(*box_).data) - } - - pub fn with_html<R>(&self, callback: |&HTMLDocument| -> R) -> R { - match self.document().doctype { - HTML => unsafe { self.transmute(callback) }, - _ => fail!("attempt to downcast a non-HTMLDocument to HTMLDocument") - } - } - - pub fn from_box<T>(ptr: *mut Box<T>) -> AbstractDocument { - AbstractDocument { - document: ptr as *mut Box<Document> - } - } - - pub fn from_node(node: AbstractNode) -> AbstractDocument { - if !node.is_document() { - fail!("node is not a document"); - } - unsafe { - cast::transmute(node) - } - } -} - -#[deriving(Eq)] +#[deriving(Eq,Encodable)] pub enum DocumentType { HTML, SVG, XML } +#[deriving(Encodable)] pub struct Document { node: Node, reflector_: Reflector, - window: @mut Window, + window: JS<Window>, doctype: DocumentType, - idmap: HashMap<DOMString, AbstractNode>, - implementation: Option<@mut DOMImplementation>, + idmap: HashMap<DOMString, JS<Element>>, + implementation: Option<JS<DOMImplementation>>, content_type: DOMString, + encoding_name: DOMString, + extra: Untraceable, +} + +struct Untraceable { url: Url, quirks_mode: QuirksMode, - encoding_name: DOMString, +} + +impl<S: Encoder> Encodable<S> for Untraceable { + fn encode(&self, _: &mut S) { + } +} + +impl DocumentDerived for EventTarget { + fn is_document(&self) -> bool { + match self.type_id { + NodeTargetTypeId(DocumentNodeTypeId(_)) => true, + _ => false + } + } } impl Document { - pub fn reflect_document<D: Reflectable> - (document: @mut D, - window: @mut Window, - wrap_fn: extern "Rust" fn(*JSContext, *JSObject, @mut D) -> *JSObject) - -> AbstractDocument { + pub fn reflect_document<D: Reflectable+DocumentBase> + (document: ~D, + window: &JS<Window>, + wrap_fn: extern "Rust" fn(*JSContext, *JSObject, ~D) -> *JSObject) + -> JS<D> { assert!(document.reflector().get_jsobject().is_null()); - let document = reflect_dom_object(document, window, wrap_fn); - assert!(document.reflector().get_jsobject().is_not_null()); + let raw_doc = reflect_dom_object(document, window.get(), wrap_fn); + assert!(raw_doc.reflector().get_jsobject().is_not_null()); - // JS object now owns the Document, so transmute_copy is needed - let abstract = AbstractDocument { - document: unsafe { cast::transmute_copy(&document) } - }; - abstract.mut_document().node.set_owner_doc(abstract); - abstract + let document = DocumentCast::from(&raw_doc); + let mut node: JS<Node> = NodeCast::from(&document); + node.get_mut().set_owner_doc(&document); + raw_doc } - pub fn new_inherited(window: @mut Window, url: Option<Url>, doctype: DocumentType, content_type: Option<DOMString>) -> Document { + pub fn new_inherited(window: JS<Window>, url: Option<Url>, doctype: DocumentType, content_type: Option<DOMString>) -> Document { let node_type = match doctype { HTML => HTMLDocumentTypeId, SVG | XML => PlainDocumentTypeId @@ -145,40 +126,32 @@ impl Document { SVG | XML => ~"application/xml" } }, - url: match url { - None => from_str("about:blank").unwrap(), - Some(_url) => _url + extra: Untraceable { + url: match url { + None => from_str("about:blank").unwrap(), + Some(_url) => _url + }, + // http://dom.spec.whatwg.org/#concept-document-quirks + quirks_mode: NoQuirks, }, - // http://dom.spec.whatwg.org/#concept-document-quirks - quirks_mode: NoQuirks, // http://dom.spec.whatwg.org/#concept-document-encoding encoding_name: ~"utf-8", } } - pub fn new(window: @mut Window, url: Option<Url>, doctype: DocumentType, content_type: Option<DOMString>) -> AbstractDocument { - let document = Document::new_inherited(window, url, doctype, content_type); - Document::reflect_document(@mut document, window, DocumentBinding::Wrap) + pub fn new(window: &JS<Window>, url: Option<Url>, doctype: DocumentType, content_type: Option<DOMString>) -> JS<Document> { + let document = Document::new_inherited(window.clone(), url, doctype, content_type); + Document::reflect_document(~document, window, DocumentBinding::Wrap) } } impl Document { // http://dom.spec.whatwg.org/#dom-document - pub fn Constructor(owner: @mut Window) -> Fallible<AbstractDocument> { + pub fn Constructor(owner: &JS<Window>) -> Fallible<JS<Document>> { Ok(Document::new(owner, None, XML, None)) } } -impl Reflectable for AbstractDocument { - fn reflector<'a>(&'a self) -> &'a Reflector { - self.document().reflector() - } - - fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { - self.mut_document().mut_reflector() - } -} - impl Reflectable for Document { fn reflector<'a>(&'a self) -> &'a Reflector { self.node.reflector() @@ -191,16 +164,16 @@ impl Reflectable for Document { impl Document { // http://dom.spec.whatwg.org/#dom-document-implementation - pub fn Implementation(&mut self) -> @mut DOMImplementation { + pub fn Implementation(&mut self) -> JS<DOMImplementation> { if self.implementation.is_none() { - self.implementation = Some(DOMImplementation::new(self.window)); + self.implementation = Some(DOMImplementation::new(&self.window)); } - self.implementation.unwrap() + self.implementation.get_ref().clone() } // http://dom.spec.whatwg.org/#dom-document-url pub fn URL(&self) -> DOMString { - self.url.to_str() + self.extra.url.to_str() } // http://dom.spec.whatwg.org/#dom-document-documenturi @@ -210,14 +183,14 @@ impl Document { // http://dom.spec.whatwg.org/#dom-document-compatmode pub fn CompatMode(&self) -> DOMString { - match self.quirks_mode { + match self.extra.quirks_mode { NoQuirks => ~"CSS1Compat", LimitedQuirks | FullQuirks => ~"BackCompat" } } pub fn set_quirks_mode(&mut self, mode: QuirksMode) { - self.quirks_mode = mode; + self.extra.quirks_mode = mode; } // http://dom.spec.whatwg.org/#dom-document-characterset @@ -235,43 +208,44 @@ impl Document { } // http://dom.spec.whatwg.org/#dom-document-doctype - pub fn GetDoctype(&self) -> Option<AbstractNode> { + pub fn GetDoctype(&self) -> Option<JS<documenttype::DocumentType>> { self.node.children().find(|child| child.is_doctype()) + .map(|node| DocumentTypeCast::to(&node)) } // http://dom.spec.whatwg.org/#dom-document-documentelement - pub fn GetDocumentElement(&self) -> Option<AbstractNode> { + pub fn GetDocumentElement(&self) -> Option<JS<Element>> { self.node.child_elements().next() } // http://dom.spec.whatwg.org/#dom-document-getelementsbytagname - pub fn GetElementsByTagName(&self, tag: DOMString) -> @mut HTMLCollection { + pub fn GetElementsByTagName(&self, tag: DOMString) -> JS<HTMLCollection> { self.createHTMLCollection(|elem| elem.tag_name == tag) } // http://dom.spec.whatwg.org/#dom-document-getelementsbytagnamens - pub fn GetElementsByTagNameNS(&self, _ns: Option<DOMString>, _tag: DOMString) -> @mut HTMLCollection { - HTMLCollection::new(self.window, ~[]) + pub fn GetElementsByTagNameNS(&self, _ns: Option<DOMString>, _tag: DOMString) -> JS<HTMLCollection> { + HTMLCollection::new(&self.window, ~[]) } // http://dom.spec.whatwg.org/#dom-document-getelementsbyclassname - pub fn GetElementsByClassName(&self, _class: DOMString) -> @mut HTMLCollection { - HTMLCollection::new(self.window, ~[]) + pub fn GetElementsByClassName(&self, _class: DOMString) -> JS<HTMLCollection> { + HTMLCollection::new(&self.window, ~[]) } // http://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid - pub fn GetElementById(&self, id: DOMString) -> Option<AbstractNode> { + pub fn GetElementById(&self, id: DOMString) -> Option<JS<Element>> { // TODO: "in tree order, within the context object's tree" // http://dom.spec.whatwg.org/#dom-document-getelementbyid. match self.idmap.find_equiv(&id) { None => None, - Some(node) => Some(*node), + Some(node) => Some(node.clone()), } } // http://dom.spec.whatwg.org/#dom-document-createelement - pub fn CreateElement(&self, abstract_self: AbstractDocument, local_name: DOMString) - -> Fallible<AbstractNode> { + pub fn CreateElement(&self, abstract_self: &JS<Document>, local_name: DOMString) + -> Fallible<JS<Element>> { if xml_name_type(local_name) == InvalidXMLName { debug!("Not a valid element name"); return Err(InvalidCharacter); @@ -281,24 +255,24 @@ impl Document { } // http://dom.spec.whatwg.org/#dom-document-createdocumentfragment - pub fn CreateDocumentFragment(&self, abstract_self: AbstractDocument) -> AbstractNode { + pub fn CreateDocumentFragment(&self, abstract_self: &JS<Document>) -> JS<DocumentFragment> { DocumentFragment::new(abstract_self) } // http://dom.spec.whatwg.org/#dom-document-createtextnode - pub fn CreateTextNode(&self, abstract_self: AbstractDocument, data: DOMString) - -> AbstractNode { + pub fn CreateTextNode(&self, abstract_self: &JS<Document>, data: DOMString) + -> JS<Text> { Text::new(data, abstract_self) } // http://dom.spec.whatwg.org/#dom-document-createcomment - pub fn CreateComment(&self, abstract_self: AbstractDocument, data: DOMString) -> AbstractNode { + pub fn CreateComment(&self, abstract_self: &JS<Document>, data: DOMString) -> JS<Comment> { Comment::new(data, abstract_self) } // http://dom.spec.whatwg.org/#dom-document-createprocessinginstruction - pub fn CreateProcessingInstruction(&self, abstract_self: AbstractDocument, target: DOMString, - data: DOMString) -> Fallible<AbstractNode> { + pub fn CreateProcessingInstruction(&self, abstract_self: &JS<Document>, target: DOMString, + data: DOMString) -> Fallible<JS<ProcessingInstruction>> { // Step 1. if xml_name_type(target) == InvalidXMLName { return Err(InvalidCharacter); @@ -314,41 +288,34 @@ impl Document { } // http://dom.spec.whatwg.org/#dom-document-createevent - pub fn CreateEvent(&self, interface: DOMString) -> Fallible<AbstractEvent> { + pub fn CreateEvent(&self, interface: DOMString) -> Fallible<JS<Event>> { match interface.as_slice() { - "UIEvents" => Ok(UIEvent::new(self.window)), - "MouseEvents" => Ok(MouseEvent::new(self.window)), - "HTMLEvents" => Ok(Event::new(self.window)), + "UIEvents" => Ok(EventCast::from(&UIEvent::new(&self.window))), + "MouseEvents" => Ok(EventCast::from(&MouseEvent::new(&self.window))), + "HTMLEvents" => Ok(Event::new(&self.window)), _ => Err(NotSupported) } } // http://www.whatwg.org/specs/web-apps/current-work/#document.title - pub fn Title(&self, _: AbstractDocument) -> DOMString { + pub fn Title(&self, _: &JS<Document>) -> DOMString { let mut title = ~""; match self.doctype { SVG => { fail!("no SVG document yet") }, _ => { - match self.GetDocumentElement() { - None => {}, - Some(root) => { - for node in root.traverse_preorder() { - if node.type_id() != ElementNodeTypeId(HTMLTitleElementTypeId) { - continue; - } - for child in node.children() { - if child.is_text() { - child.with_imm_text(|text| { - title.push_str(text.characterdata.data.as_slice()); - }); - } + self.GetDocumentElement().map(|root| { + let root: JS<Node> = NodeCast::from(&root); + root.traverse_preorder() + .find(|node| node.type_id() == ElementNodeTypeId(HTMLTitleElementTypeId)) + .map(|title_elem| { + for child in title_elem.children() { + let text: JS<Text> = TextCast::to(&child); + title.push_str(text.get().characterdata.data.as_slice()); } - break; - } - } - } + }); + }); } } let v: ~[&str] = title.words().collect(); @@ -358,85 +325,81 @@ impl Document { } // http://www.whatwg.org/specs/web-apps/current-work/#document.title - pub fn SetTitle(&self, abstract_self: AbstractDocument, title: DOMString) -> ErrorResult { + pub fn SetTitle(&self, abstract_self: &JS<Document>, title: DOMString) -> ErrorResult { match self.doctype { SVG => { fail!("no SVG document yet") }, _ => { - match self.GetDocumentElement() { - None => {}, - Some(root) => { - for node in root.traverse_preorder() { - if node.type_id() != ElementNodeTypeId(HTMLHeadElementTypeId) { - continue; - } - let mut has_title = false; - for child in node.children() { - if child.type_id() != ElementNodeTypeId(HTMLTitleElementTypeId) { - continue; - } - has_title = true; - for title_child in child.children() { - child.RemoveChild(title_child); - } - child.AppendChild(self.CreateTextNode(abstract_self, title.clone())); - break; - } - if !has_title { - let new_title = HTMLTitleElement::new(~"title", abstract_self); - new_title.AppendChild(self.CreateTextNode(abstract_self, title.clone())); - node.AppendChild(new_title); + self.GetDocumentElement().map(|root| { + let root: JS<Node> = NodeCast::from(&root); + let mut head_node = root.traverse_preorder().find(|child| { + child.get().type_id == ElementNodeTypeId(HTMLHeadElementTypeId) + }); + head_node.as_mut().map(|head| { + + let mut title_node = head.children().find(|child| { + child.get().type_id == ElementNodeTypeId(HTMLTitleElementTypeId) + }); + + title_node.as_mut().map(|title_node| { + for mut title_child in title_node.children() { + title_node.RemoveChild(&mut title_child); } - break; + let new_text = self.CreateTextNode(abstract_self, title.clone()); + title_node.AppendChild(&mut NodeCast::from(&new_text)); + }); + + if title_node.is_none() { + let mut new_title: JS<Node> = + NodeCast::from(&HTMLTitleElement::new(~"title", abstract_self)); + let new_text = self.CreateTextNode(abstract_self, title.clone()); + new_title.AppendChild(&mut NodeCast::from(&new_text)); + head.AppendChild(&mut new_title); } - } - } + }); + }); } } Ok(()) } - fn get_html_element(&self) -> Option<AbstractNode> { + fn get_html_element(&self) -> Option<JS<HTMLHtmlElement>> { self.GetDocumentElement().filtered(|root| { - match root.type_id() { - ElementNodeTypeId(HTMLHtmlElementTypeId) => true, - _ => false - } - }) + root.get().node.type_id == ElementNodeTypeId(HTMLHtmlElementTypeId) + }).map(|elem| HTMLHtmlElementCast::to(&elem)) } // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-head - pub fn GetHead(&self) -> Option<AbstractNode> { + pub fn GetHead(&self) -> Option<JS<HTMLHeadElement>> { self.get_html_element().and_then(|root| { - root.children().find(|child| { + let node: JS<Node> = NodeCast::from(&root); + node.children().find(|child| { child.type_id() == ElementNodeTypeId(HTMLHeadElementTypeId) - }) + }).map(|node| HTMLHeadElementCast::to(&node)) }) } // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-body - pub fn GetBody(&self, _: AbstractDocument) -> Option<AbstractNode> { - match self.get_html_element() { - None => None, - Some(root) => { - root.children().find(|child| { - match child.type_id() { - ElementNodeTypeId(HTMLBodyElementTypeId) | - ElementNodeTypeId(HTMLFrameSetElementTypeId) => true, - _ => false - } - }) - } - } + pub fn GetBody(&self, _: &JS<Document>) -> Option<JS<HTMLElement>> { + self.get_html_element().and_then(|root| { + let node: JS<Node> = NodeCast::from(&root); + node.children().find(|child| { + match child.type_id() { + ElementNodeTypeId(HTMLBodyElementTypeId) | + ElementNodeTypeId(HTMLFrameSetElementTypeId) => true, + _ => false + } + }).map(|node| HTMLElementCast::to(&node)) + }) } // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-body - pub fn SetBody(&self, abstract_self: AbstractDocument, new_body: Option<AbstractNode>) -> ErrorResult { + pub fn SetBody(&self, abstract_self: &JS<Document>, new_body: Option<JS<HTMLElement>>) -> ErrorResult { // Step 1. match new_body { - Some(node) => { - match node.type_id() { + Some(ref node) => { + match node.get().element.node.type_id { ElementNodeTypeId(HTMLBodyElementTypeId) | ElementNodeTypeId(HTMLFrameSetElementTypeId) => {} _ => return Err(HierarchyRequest) } @@ -445,7 +408,7 @@ impl Document { } // Step 2. - let old_body: Option<AbstractNode> = self.GetBody(abstract_self); + let old_body: Option<JS<HTMLElement>> = self.GetBody(abstract_self); if old_body == new_body { return Ok(()); } @@ -455,41 +418,46 @@ impl Document { // Step 4. None => return Err(HierarchyRequest), Some(root) => { + let mut new_body: JS<Node> = NodeCast::from(&new_body.unwrap()); + let mut root: JS<Node> = NodeCast::from(&root); match old_body { - Some(child) => { root.ReplaceChild(new_body.unwrap(), child); } - None => { root.AppendChild(new_body.unwrap()); } - } + Some(child) => { + let mut child: JS<Node> = NodeCast::from(&child); + root.ReplaceChild(&mut new_body, &mut child) + } + None => root.AppendChild(&mut new_body) + }; } } Ok(()) } // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-getelementsbyname - pub fn GetElementsByName(&self, name: DOMString) -> @mut HTMLCollection { + pub fn GetElementsByName(&self, name: DOMString) -> JS<HTMLCollection> { self.createHTMLCollection(|elem| { elem.get_attribute(Null, "name").map_default(false, |attr| { - attr.value_ref() == name + attr.get().value_ref() == name }) }) } - pub fn createHTMLCollection(&self, callback: |elem: &Element| -> bool) -> @mut HTMLCollection { + pub fn createHTMLCollection(&self, callback: |elem: &Element| -> bool) -> JS<HTMLCollection> { let mut elements = ~[]; match self.GetDocumentElement() { None => {}, Some(root) => { + let root: JS<Node> = NodeCast::from(&root); for child in root.traverse_preorder() { if child.is_element() { - child.with_imm_element(|elem| { - if callback(elem) { - elements.push(child); - } - }); + let elem: JS<Element> = ElementCast::to(&child); + if callback(elem.get()) { + elements.push(elem); + } } } } } - HTMLCollection::new(self.window, elements) + HTMLCollection::new(&self.window, elements) } pub fn content_changed(&self) { @@ -497,22 +465,22 @@ impl Document { } pub fn damage_and_reflow(&self, damage: DocumentDamageLevel) { - self.window.damage_and_reflow(damage); + self.window.get().damage_and_reflow(damage); } pub fn wait_until_safe_to_modify_dom(&self) { - self.window.wait_until_safe_to_modify_dom(); + self.window.get().wait_until_safe_to_modify_dom(); } - pub fn register_nodes_with_id(&mut self, root: &AbstractNode) { - foreach_ided_elements(root, |id: &DOMString, abstract_node: &AbstractNode| { + pub fn register_nodes_with_id(&mut self, root: &JS<Element>) { + foreach_ided_elements(root, |id: &DOMString, abstract_node: &JS<Element>| { // TODO: "in tree order, within the context object's tree" // http://dom.spec.whatwg.org/#dom-document-getelementbyid. - self.idmap.find_or_insert(id.clone(), *abstract_node); + self.idmap.find_or_insert(id.clone(), abstract_node.clone()); }); } - pub fn unregister_nodes_with_id(&mut self, root: &AbstractNode) { + pub fn unregister_nodes_with_id(&mut self, root: &JS<Element>) { foreach_ided_elements(root, |id: &DOMString, _| { // TODO: "in tree order, within the context object's tree" // http://dom.spec.whatwg.org/#dom-document-getelementbyid. @@ -521,7 +489,7 @@ impl Document { } pub fn update_idmap(&mut self, - abstract_self: AbstractNode, + abstract_self: &JS<Element>, new_id: Option<DOMString>, old_id: Option<DOMString>) { // remove old ids: @@ -539,11 +507,11 @@ impl Document { Some(new_id) => { // TODO: support the case if multiple elements // which haves same id are in the same document. - self.idmap.mangle(new_id, abstract_self, - |_, new_node: AbstractNode| -> AbstractNode { + self.idmap.mangle(new_id, abstract_self.clone(), + |_, new_node: JS<Element>| -> JS<Element> { new_node }, - |_, old_node: &mut AbstractNode, new_node: AbstractNode| { + |_, old_node: &mut JS<Element>, new_node: JS<Element>| { *old_node = new_node; }); } @@ -553,25 +521,19 @@ impl Document { } #[inline(always)] -fn foreach_ided_elements(root: &AbstractNode, callback: |&DOMString, &AbstractNode|) { +fn foreach_ided_elements(root: &JS<Element>, callback: |&DOMString, &JS<Element>|) { + let root: JS<Node> = NodeCast::from(root); for node in root.traverse_preorder() { if !node.is_element() { continue; } - node.with_imm_element(|element| { - match element.get_attribute(Null, "id") { - Some(id) => { - callback(&id.Value(), &node); - } - None => () + let element: JS<Element> = ElementCast::to(&node); + match element.get().get_attribute(Null, "id") { + Some(id) => { + callback(&id.get().Value(), &element); } - }); - } -} - -impl Traceable for Document { - fn trace(&self, tracer: *mut JSTracer) { - self.node.trace(tracer); + None => () + } } } diff --git a/src/components/script/dom/documentfragment.rs b/src/components/script/dom/documentfragment.rs index 0b4c56d2c92..0e38b72f8ea 100644 --- a/src/components/script/dom/documentfragment.rs +++ b/src/components/script/dom/documentfragment.rs @@ -2,32 +2,45 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::bindings::codegen::InheritTypes::DocumentFragmentDerived; use dom::bindings::codegen::DocumentFragmentBinding; +use dom::bindings::js::JS; use dom::bindings::utils::Fallible; -use dom::document::AbstractDocument; -use dom::node::{AbstractNode, DocumentFragmentNodeTypeId, Node}; +use dom::document::Document; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; +use dom::node::{DocumentFragmentNodeTypeId, Node}; use dom::window::Window; +#[deriving(Encodable)] pub struct DocumentFragment { node: Node, } +impl DocumentFragmentDerived for EventTarget { + fn is_documentfragment(&self) -> bool { + match self.type_id { + NodeTargetTypeId(DocumentFragmentNodeTypeId) => true, + _ => false + } + } +} + impl DocumentFragment { /// Creates a new DocumentFragment. - pub fn new_inherited(document: AbstractDocument) -> DocumentFragment { + pub fn new_inherited(document: JS<Document>) -> DocumentFragment { DocumentFragment { node: Node::new_inherited(DocumentFragmentNodeTypeId, document), } } - pub fn new(document: AbstractDocument) -> AbstractNode { - let node = DocumentFragment::new_inherited(document); - Node::reflect_node(@mut node, document, DocumentFragmentBinding::Wrap) + pub fn new(document: &JS<Document>) -> JS<DocumentFragment> { + let node = DocumentFragment::new_inherited(document.clone()); + Node::reflect_node(~node, document, DocumentFragmentBinding::Wrap) } } impl DocumentFragment { - pub fn Constructor(owner: @mut Window) -> Fallible<AbstractNode> { - Ok(DocumentFragment::new(owner.Document())) + pub fn Constructor(owner: &JS<Window>) -> Fallible<JS<DocumentFragment>> { + Ok(DocumentFragment::new(&owner.get().Document())) } } diff --git a/src/components/script/dom/documenttype.rs b/src/components/script/dom/documenttype.rs index f161b287702..3892f2a3235 100644 --- a/src/components/script/dom/documenttype.rs +++ b/src/components/script/dom/documenttype.rs @@ -2,12 +2,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::bindings::codegen::InheritTypes::DocumentTypeDerived; use dom::bindings::codegen::DocumentTypeBinding; -use dom::document::AbstractDocument; -use dom::node::{AbstractNode, Node, DoctypeNodeTypeId}; +use dom::bindings::js::JS; +use dom::document::Document; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; +use dom::node::{Node, DoctypeNodeTypeId}; use servo_util::str::DOMString; /// The `DOCTYPE` tag. +#[deriving(Encodable)] pub struct DocumentType { node: Node, name: DOMString, @@ -15,11 +19,20 @@ pub struct DocumentType { system_id: DOMString, } +impl DocumentTypeDerived for EventTarget { + fn is_documenttype(&self) -> bool { + match self.type_id { + NodeTargetTypeId(DoctypeNodeTypeId) => true, + _ => false + } + } +} + impl DocumentType { pub fn new_inherited(name: DOMString, public_id: Option<DOMString>, system_id: Option<DOMString>, - document: AbstractDocument) + document: JS<Document>) -> DocumentType { DocumentType { node: Node::new_inherited(DoctypeNodeTypeId, document), @@ -32,13 +45,13 @@ impl DocumentType { pub fn new(name: DOMString, public_id: Option<DOMString>, system_id: Option<DOMString>, - document: AbstractDocument) - -> AbstractNode { + document: &JS<Document>) + -> JS<DocumentType> { let documenttype = DocumentType::new_inherited(name, public_id, system_id, - document); - Node::reflect_node(@mut documenttype, document, DocumentTypeBinding::Wrap) + document.clone()); + Node::reflect_node(~documenttype, document, DocumentTypeBinding::Wrap) } } diff --git a/src/components/script/dom/domexception.rs b/src/components/script/dom/domexception.rs index f0801fee40f..f6eb1751adc 100644 --- a/src/components/script/dom/domexception.rs +++ b/src/components/script/dom/domexception.rs @@ -3,12 +3,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::DOMExceptionBinding; +use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::window::Window; use servo_util::str::DOMString; #[repr(uint)] -#[deriving(ToStr)] +#[deriving(ToStr, Encodable)] enum DOMErrorName { IndexSizeError = 1, HierarchyRequestError = 3, @@ -33,6 +34,7 @@ enum DOMErrorName { EncodingError } +#[deriving(Encodable)] pub struct DOMException { code: DOMErrorName, reflector_: Reflector @@ -46,8 +48,8 @@ impl DOMException { } } - pub fn new(window: &Window, code: DOMErrorName) -> @mut DOMException { - reflect_dom_object(@mut DOMException::new_inherited(code), window, DOMExceptionBinding::Wrap) + pub fn new(window: &Window, code: DOMErrorName) -> JS<DOMException> { + reflect_dom_object(~DOMException::new_inherited(code), window, DOMExceptionBinding::Wrap) } } @@ -67,7 +69,7 @@ impl DOMException { match self.code { // http://dom.spec.whatwg.org/#concept-throw EncodingError => 0, - _ => self.code as u16 + code => code as u16 } } diff --git a/src/components/script/dom/domimplementation.rs b/src/components/script/dom/domimplementation.rs index 8595d54c065..48c26ff4871 100644 --- a/src/components/script/dom/domimplementation.rs +++ b/src/components/script/dom/domimplementation.rs @@ -3,36 +3,39 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::DOMImplementationBinding; +use dom::bindings::codegen::InheritTypes::{NodeCast, DocumentCast}; +use dom::bindings::js::JS; use dom::bindings::utils::{Reflector, Reflectable, reflect_dom_object}; use dom::bindings::utils::{Fallible, InvalidCharacter, NamespaceError}; use dom::bindings::utils::{QName, Name, InvalidXMLName, xml_name_type}; -use dom::document::{AbstractDocument, HTML, HTMLDocumentTypeId}; +use dom::document::{Document, HTML, HTMLDocumentTypeId}; use dom::documenttype::DocumentType; use dom::htmldocument::HTMLDocument; use dom::htmlbodyelement::HTMLBodyElement; use dom::htmlheadelement::HTMLHeadElement; use dom::htmlhtmlelement::HTMLHtmlElement; use dom::htmltitleelement::HTMLTitleElement; -use dom::node::{AbstractNode, DocumentNodeTypeId}; +use dom::node::{Node, DocumentNodeTypeId, NodeHelpers, INode}; use dom::text::Text; use dom::window::Window; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct DOMImplementation { - owner: @mut Window, - reflector_: Reflector + owner: JS<Window>, + reflector_: Reflector, } impl DOMImplementation { - pub fn new_inherited(owner: @mut Window) -> DOMImplementation { + pub fn new_inherited(owner: JS<Window>) -> DOMImplementation { DOMImplementation { owner: owner, - reflector_: Reflector::new() + reflector_: Reflector::new(), } } - pub fn new(owner: @mut Window) -> @mut DOMImplementation { - reflect_dom_object(@mut DOMImplementation::new_inherited(owner), owner, + pub fn new(owner: &JS<Window>) -> JS<DOMImplementation> { + reflect_dom_object(~DOMImplementation::new_inherited(owner.clone()), owner.get(), DOMImplementationBinding::Wrap) } } @@ -50,66 +53,66 @@ impl Reflectable for DOMImplementation { // http://dom.spec.whatwg.org/#domimplementation impl DOMImplementation { // http://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype - pub fn CreateDocumentType(&self, qname: DOMString, pubid: DOMString, sysid: DOMString) -> Fallible<AbstractNode> { + pub fn CreateDocumentType(&self, qname: DOMString, pubid: DOMString, sysid: DOMString) -> Fallible<JS<DocumentType>> { match xml_name_type(qname) { // Step 1. InvalidXMLName => Err(InvalidCharacter), // Step 2. Name => Err(NamespaceError), // Step 3. - QName => Ok(DocumentType::new(qname, Some(pubid), Some(sysid), self.owner.Document())) + QName => Ok(DocumentType::new(qname, Some(pubid), Some(sysid), &self.owner.get().Document())) } } // http://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument - pub fn CreateHTMLDocument(&self, title: Option<DOMString>) -> AbstractDocument { + pub fn CreateHTMLDocument(&self, title: Option<DOMString>) -> JS<Document> { // Step 1-2. - let abstract_doc = HTMLDocument::new(self.owner, None); - assert!(abstract_doc.document().doctype == HTML); + let doc: JS<Document> = DocumentCast::from(&HTMLDocument::new(&self.owner, None)); + assert!(doc.get().doctype == HTML); - let abstract_node = AbstractNode::from_document(abstract_doc); - assert!(abstract_node.type_id() == DocumentNodeTypeId(HTMLDocumentTypeId)); + let mut doc_node: JS<Node> = NodeCast::from(&doc); + assert!(doc_node.type_id() == DocumentNodeTypeId(HTMLDocumentTypeId)); { // Step 3. - let doc_type = DocumentType::new(~"html", None, None, abstract_doc); - abstract_node.AppendChild(doc_type); + let doc_type = DocumentType::new(~"html", None, None, &doc); + doc_node.AppendChild(&mut NodeCast::from(&doc_type)); } { // Step 4. - let doc_html = HTMLHtmlElement::new(~"html", abstract_doc); - abstract_node.AppendChild(doc_html); + let mut doc_html = NodeCast::from(&HTMLHtmlElement::new(~"html", &doc)); + doc_node.AppendChild(&mut doc_html); { // Step 5. - let doc_head = HTMLHeadElement::new(~"head", abstract_doc); - doc_html.AppendChild(doc_head); + let mut doc_head = NodeCast::from(&HTMLHeadElement::new(~"head", &doc)); + doc_html.AppendChild(&mut doc_head); // Step 6. match title { None => (), Some(title_str) => { // Step 6.1. - let doc_title = HTMLTitleElement::new(~"title", abstract_doc); - doc_head.AppendChild(doc_title); + let mut doc_title = NodeCast::from(&HTMLTitleElement::new(~"title", &doc)); + doc_head.AppendChild(&mut doc_title); // Step 6.2. - let title_text = Text::new(title_str, abstract_doc); - doc_title.AppendChild(title_text); + let title_text = Text::new(title_str, &doc); + doc_title.AppendChild(&mut NodeCast::from(&title_text)); } } } // Step 7. - let doc_body = HTMLBodyElement::new(~"body", abstract_doc); - doc_html.AppendChild(doc_body); + let doc_body = HTMLBodyElement::new(~"body", &doc); + doc_html.AppendChild(&mut NodeCast::from(&doc_body)); } // Step 8. // FIXME: https://github.com/mozilla/servo/issues/1522 // Step 9. - abstract_doc + doc } } diff --git a/src/components/script/dom/domparser.rs b/src/components/script/dom/domparser.rs index 1dec0025e8a..3b545e0be62 100644 --- a/src/components/script/dom/domparser.rs +++ b/src/components/script/dom/domparser.rs @@ -4,46 +4,49 @@ use dom::bindings::codegen::DOMParserBinding; use dom::bindings::codegen::DOMParserBinding::SupportedTypeValues::{Text_html, Text_xml}; +use dom::bindings::codegen::InheritTypes::DocumentCast; +use dom::bindings::js::JS; use dom::bindings::utils::{Reflector, Reflectable, reflect_dom_object}; use dom::bindings::utils::Fallible; use dom::bindings::utils::FailureUnknown; -use dom::document::{AbstractDocument, Document}; +use dom::document::Document; use dom::htmldocument::HTMLDocument; use dom::window::Window; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct DOMParser { - owner: @mut Window, //XXXjdm Document instead? + owner: JS<Window>, //XXXjdm Document instead? reflector_: Reflector } impl DOMParser { - pub fn new_inherited(owner: @mut Window) -> DOMParser { + pub fn new_inherited(owner: JS<Window>) -> DOMParser { DOMParser { owner: owner, reflector_: Reflector::new() } } - pub fn new(owner: @mut Window) -> @mut DOMParser { - reflect_dom_object(@mut DOMParser::new_inherited(owner), owner, + pub fn new(owner: &JS<Window>) -> JS<DOMParser> { + reflect_dom_object(~DOMParser::new_inherited(owner.clone()), owner.get(), DOMParserBinding::Wrap) } - pub fn Constructor(owner: @mut Window) -> Fallible<@mut DOMParser> { + pub fn Constructor(owner: &JS<Window>) -> Fallible<JS<DOMParser>> { Ok(DOMParser::new(owner)) } pub fn ParseFromString(&self, _s: DOMString, ty: DOMParserBinding::SupportedType) - -> Fallible<AbstractDocument> { + -> Fallible<JS<Document>> { match ty { Text_html => { - Ok(HTMLDocument::new(self.owner, None)) + Ok(DocumentCast::from(&HTMLDocument::new(&self.owner, None))) } Text_xml => { - Document::Constructor(self.owner) + Document::Constructor(&self.owner) } _ => { Err(FailureUnknown) diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index 12361d7ec85..f9b7c67d372 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -6,14 +6,22 @@ use dom::attr::Attr; use dom::attrlist::AttrList; +use dom::bindings::codegen::InheritTypes::{ElementDerived, HTMLImageElementCast}; +use dom::bindings::codegen::InheritTypes::{HTMLIFrameElementCast, NodeCast}; +use dom::bindings::codegen::InheritTypes::HTMLObjectElementCast; +use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector}; use dom::bindings::utils::{ErrorResult, Fallible, NamespaceError, InvalidCharacter}; use dom::bindings::utils::{QName, Name, InvalidXMLName, xml_name_type}; use dom::htmlcollection::HTMLCollection; use dom::clientrect::ClientRect; use dom::clientrectlist::ClientRectList; -use dom::document::AbstractDocument; -use dom::node::{AbstractNode, ElementNodeTypeId, Node, NodeIterator}; +use dom::document::Document; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; +use dom::htmlimageelement::HTMLImageElement; +use dom::htmliframeelement::HTMLIFrameElement; +use dom::htmlobjectelement::HTMLObjectElement; +use dom::node::{ElementNodeTypeId, Node, NodeHelpers, NodeIterator}; use dom::document; use dom::htmlserializer::serialize; use layout_interface::{ContentBoxQuery, ContentBoxResponse, ContentBoxesQuery}; @@ -26,15 +34,24 @@ use servo_util::str::{DOMString, null_str_as_empty_ref}; use std::ascii::StrAsciiExt; use std::cast; -use std::unstable::raw::Box; +#[deriving(Encodable)] pub struct Element { node: Node, tag_name: DOMString, // TODO: This should be an atom, not a DOMString. namespace: Namespace, - attrs: ~[@mut Attr], + attrs: ~[JS<Attr>], style_attribute: Option<style::PropertyDeclarationBlock>, - attr_list: Option<@mut AttrList> + attr_list: Option<JS<AttrList>> +} + +impl ElementDerived for EventTarget { + fn is_element(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(_)) => true, + _ => false + } + } } impl Reflectable for Element { @@ -47,7 +64,7 @@ impl Reflectable for Element { } } -#[deriving(Eq)] +#[deriving(Eq,Encodable)] pub enum ElementTypeId { HTMLElementTypeId, HTMLAnchorElementTypeId, @@ -104,7 +121,6 @@ pub enum ElementTypeId { HTMLStyleElementTypeId, HTMLTableElementTypeId, HTMLTableCaptionElementTypeId, - HTMLTableCellElementTypeId, HTMLTableDataCellElementTypeId, HTMLTableHeaderCellElementTypeId, HTMLTableColElementTypeId, @@ -124,9 +140,8 @@ pub enum ElementTypeId { // Element methods // - impl Element { - pub fn new_inherited(type_id: ElementTypeId, tag_name: ~str, namespace: Namespace, document: AbstractDocument) -> Element { + pub fn new_inherited(type_id: ElementTypeId, tag_name: ~str, namespace: Namespace, document: JS<Document>) -> Element { Element { node: Node::new_inherited(ElementNodeTypeId(type_id), document), tag_name: tag_name, @@ -141,38 +156,39 @@ impl Element { let owner = self.node.owner_doc(); self.namespace == namespace::HTML && // FIXME: check that this matches what the spec calls "is in an HTML document" - owner.document().doctype == document::HTML + owner.get().doctype == document::HTML } pub fn get_attribute(&self, namespace: Namespace, - name: &str) -> Option<@mut Attr> { + name: &str) -> Option<JS<Attr>> { self.attrs.iter().find(|attr| { + let attr = attr.get(); name == attr.local_name && attr.namespace == namespace - }).map(|&x| x) + }).map(|x| x.clone()) } #[inline] pub unsafe fn get_attr_val_for_layout(&self, namespace: &Namespace, name: &str) -> Option<&'static str> { - self.attrs.iter().find(|attr: & &@mut Attr| { + self.attrs.iter().find(|attr: & &JS<Attr>| { // unsafely avoid a borrow because this is accessed by many tasks // during parallel layout - let attr: ***Box<Attr> = cast::transmute(attr); - name == (***attr).data.local_name && (***attr).data.namespace == *namespace + let attr: ***Attr = cast::transmute(attr); + name == (***attr).local_name && (***attr).namespace == *namespace }).map(|attr| { - let attr: **Box<Attr> = cast::transmute(attr); - cast::transmute((**attr).data.value.as_slice()) + let attr: **Attr = cast::transmute(attr); + cast::transmute((**attr).value.as_slice()) }) } - pub fn set_attr(&mut self, abstract_self: AbstractNode, name: DOMString, value: DOMString) + pub fn set_attr(&mut self, abstract_self: &JS<Element>, name: DOMString, value: DOMString) -> ErrorResult { self.set_attribute(abstract_self, namespace::Null, name, value) } pub fn set_attribute(&mut self, - abstract_self: AbstractNode, + abstract_self: &JS<Element>, namespace: Namespace, name: DOMString, value: DOMString) -> ErrorResult { @@ -192,7 +208,8 @@ impl Element { // FIXME: reduce the time of `value.clone()`. let mut old_raw_value: Option<DOMString> = None; - for attr in self.attrs.iter() { + for attr in self.attrs.mut_iter() { + let attr = attr.get_mut(); if attr.local_name == local_name { old_raw_value = Some(attr.set_value(value.clone())); break; @@ -200,8 +217,9 @@ impl Element { } if old_raw_value.is_none() { - let win = self.node.owner_doc().document().window; - let new_attr = Attr::new_ns(win, local_name.clone(), value.clone(), + let doc = self.node.owner_doc(); + let doc = doc.get(); + let new_attr = Attr::new_ns(doc.window.get(), local_name.clone(), value.clone(), name.clone(), namespace.clone(), prefix); self.attrs.push(new_attr); @@ -214,7 +232,7 @@ impl Element { } fn after_set_attr(&mut self, - abstract_self: AbstractNode, + abstract_self: &JS<Element>, local_name: DOMString, value: DOMString, old_value: Option<DOMString>) { @@ -222,36 +240,36 @@ impl Element { match local_name.as_slice() { "style" => { let doc = self.node.owner_doc(); - let base_url = doc.document().url.clone(); + let base_url = doc.get().extra.url.clone(); self.style_attribute = Some(style::parse_style_attribute(value, &base_url)) } - "id" if abstract_self.is_in_doc() => { - // XXX: this dual declaration are workaround to avoid the compile error: - // "borrowed value does not live long enough" - let doc = self.node.owner_doc(); - let doc = doc.mut_document(); - doc.update_idmap(abstract_self, Some(value.clone()), old_value); + "id" => { + let self_node: JS<Node> = NodeCast::from(abstract_self); + if self_node.is_in_doc() { + // XXX: this dual declaration are workaround to avoid the compile error: + // "borrowed value does not live long enough" + let mut doc = self.node.owner_doc(); + let doc = doc.get_mut(); + doc.update_idmap(abstract_self, Some(value.clone()), old_value); + } } _ => () } //XXXjdm We really need something like a vtable so we can call AfterSetAttr. // This hardcoding is awful. - match abstract_self.type_id() { + match abstract_self.get().node.type_id { ElementNodeTypeId(HTMLImageElementTypeId) => { - abstract_self.with_mut_image_element(|image| { - image.AfterSetAttr(local_name.clone(), value.clone()); - }); + let mut elem: JS<HTMLImageElement> = HTMLImageElementCast::to(abstract_self); + elem.get_mut().AfterSetAttr(local_name.clone(), value.clone()); } ElementNodeTypeId(HTMLIframeElementTypeId) => { - abstract_self.with_mut_iframe_element(|iframe| { - iframe.AfterSetAttr(local_name.clone(), value.clone()); - }); + let mut elem: JS<HTMLIFrameElement> = HTMLIFrameElementCast::to(abstract_self); + elem.get_mut().AfterSetAttr(local_name.clone(), value.clone()); } ElementNodeTypeId(HTMLObjectElementTypeId) => { - abstract_self.with_mut_object_element(|object| { - object.AfterSetAttr(local_name.clone(), value.clone()); - }); + let mut elem: JS<HTMLObjectElement> = HTMLObjectElementCast::to(abstract_self); + elem.get_mut().AfterSetAttr(local_name.clone(), value.clone()); } _ => () } @@ -260,22 +278,22 @@ impl Element { } pub fn remove_attribute(&mut self, - abstract_self: AbstractNode, + abstract_self: &JS<Element>, namespace: Namespace, name: DOMString) -> ErrorResult { let (_, local_name) = get_attribute_parts(name.clone()); self.node.wait_until_safe_to_modify_dom(); - let idx = self.attrs.iter().position(|attr: &@mut Attr| -> bool { - attr.local_name == local_name + let idx = self.attrs.iter().position(|attr: &JS<Attr>| -> bool { + attr.get().local_name == local_name }); match idx { None => (), Some(idx) => { let removed = self.attrs.remove(idx); - let removed_raw_value = Some(removed.Value()); + let removed_raw_value = Some(removed.get().Value()); if namespace == namespace::Null { self.after_remove_attr(abstract_self, local_name, removed_raw_value); @@ -287,35 +305,36 @@ impl Element { } fn after_remove_attr(&mut self, - abstract_self: AbstractNode, + abstract_self: &JS<Element>, local_name: DOMString, old_value: Option<DOMString>) { match local_name.as_slice() { "style" => { self.style_attribute = None } - "id" if abstract_self.is_in_doc() => { - // XXX: this dual declaration are workaround to avoid the compile error: - // "borrowed value does not live long enough" - let doc = self.node.owner_doc(); - let doc = doc.mut_document(); - doc.update_idmap(abstract_self, None, old_value); + "id" => { + let self_node: JS<Node> = NodeCast::from(abstract_self); + if self_node.is_in_doc() { + // XXX: this dual declaration are workaround to avoid the compile error: + // "borrowed value does not live long enough" + let mut doc = self.node.owner_doc(); + let doc = doc.get_mut(); + doc.update_idmap(abstract_self, None, old_value); + } } _ => () } //XXXjdm We really need something like a vtable so we can call AfterSetAttr. // This hardcoding is awful. - match abstract_self.type_id() { + match abstract_self.get().node.type_id { ElementNodeTypeId(HTMLImageElementTypeId) => { - abstract_self.with_mut_image_element(|image| { - image.AfterRemoveAttr(local_name.clone()); - }); + let mut elem: JS<HTMLImageElement> = HTMLImageElementCast::to(abstract_self); + elem.get_mut().AfterRemoveAttr(local_name.clone()); } ElementNodeTypeId(HTMLIframeElementTypeId) => { - abstract_self.with_mut_iframe_element(|iframe| { - iframe.AfterRemoveAttr(local_name.clone()); - }); + let mut elem: JS<HTMLIFrameElement> = HTMLIFrameElementCast::to(abstract_self); + elem.get_mut().AfterRemoveAttr(local_name.clone()); } _ => () } @@ -324,15 +343,16 @@ impl Element { } fn notify_attribute_changed(&self, - abstract_self: AbstractNode, + abstract_self: &JS<Element>, local_name: DOMString) { - if abstract_self.is_in_doc() { + let node: JS<Node> = NodeCast::from(abstract_self); + if node.is_in_doc() { let damage = match local_name.as_slice() { "style" | "id" | "class" => MatchSelectorsDocumentDamage, _ => ContentChangedDocumentDamage }; let document = self.node.owner_doc(); - document.document().damage_and_reflow(damage); + document.get().damage_and_reflow(damage); } } @@ -357,18 +377,18 @@ impl Element { // XXX Resolve URL. self.get_string_attribute(name) } - pub fn set_url_attribute(&mut self, abstract_self: AbstractNode, + pub fn set_url_attribute(&mut self, abstract_self: &JS<Element>, name: &str, value: DOMString) { self.set_string_attribute(abstract_self, name, value); } pub fn get_string_attribute(&self, name: &str) -> DOMString { match self.get_attribute(Null, name) { - Some(x) => x.Value(), + Some(x) => x.get().Value(), None => ~"" } } - pub fn set_string_attribute(&mut self, abstract_self: AbstractNode, + pub fn set_string_attribute(&mut self, abstract_self: &JS<Element>, name: &str, value: DOMString) { assert!(name == name.to_ascii_lower()); self.set_attribute(abstract_self, Null, name.to_owned(), value); @@ -382,25 +402,26 @@ impl Element { } // http://dom.spec.whatwg.org/#dom-element-id - pub fn Id(&self, _abstract_self: AbstractNode) -> DOMString { + pub fn Id(&self, _abstract_self: &JS<Element>) -> DOMString { self.get_string_attribute("id") } // http://dom.spec.whatwg.org/#dom-element-id - pub fn SetId(&mut self, abstract_self: AbstractNode, id: DOMString) { + pub fn SetId(&mut self, abstract_self: &JS<Element>, id: DOMString) { self.set_string_attribute(abstract_self, "id", id); } // http://dom.spec.whatwg.org/#dom-element-attributes - pub fn Attributes(&mut self, abstract_self: AbstractNode) -> @mut AttrList { + pub fn Attributes(&mut self, abstract_self: &JS<Element>) -> JS<AttrList> { match self.attr_list { None => { - let window = self.node.owner_doc().document().window; - let list = AttrList::new(window, abstract_self); - self.attr_list = Some(list); + let doc = self.node.owner_doc(); + let doc = doc.get(); + let list = AttrList::new(&doc.window, abstract_self); + self.attr_list = Some(list.clone()); list } - Some(list) => list + Some(ref list) => list.clone() } } @@ -411,18 +432,18 @@ impl Element { } else { name }; - self.get_attribute(Null, name).map(|s| s.Value()) + self.get_attribute(Null, name).map(|s| s.get().Value()) } // http://dom.spec.whatwg.org/#dom-element-getattributens pub fn GetAttributeNS(&self, namespace: Option<DOMString>, local_name: DOMString) -> Option<DOMString> { let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace)); self.get_attribute(namespace, local_name) - .map(|attr| attr.value.clone()) + .map(|attr| attr.get().value.clone()) } // http://dom.spec.whatwg.org/#dom-element-setattribute - pub fn SetAttribute(&mut self, abstract_self: AbstractNode, name: DOMString, value: DOMString) + pub fn SetAttribute(&mut self, abstract_self: &JS<Element>, name: DOMString, value: DOMString) -> ErrorResult { // FIXME: If name does not match the Name production in XML, throw an "InvalidCharacterError" exception. let name = if self.html_element_in_html_document() { @@ -435,7 +456,7 @@ impl Element { // http://dom.spec.whatwg.org/#dom-element-setattributens pub fn SetAttributeNS(&mut self, - abstract_self: AbstractNode, + abstract_self: &JS<Element>, namespace_url: Option<DOMString>, name: DOMString, value: DOMString) -> ErrorResult { @@ -452,7 +473,7 @@ impl Element { // http://dom.spec.whatwg.org/#dom-element-removeattribute pub fn RemoveAttribute(&mut self, - abstract_self: AbstractNode, + abstract_self: &JS<Element>, name: DOMString) -> ErrorResult { let name = if self.html_element_in_html_document() { name.to_ascii_lower() @@ -464,7 +485,7 @@ impl Element { // http://dom.spec.whatwg.org/#dom-element-removeattributens pub fn RemoveAttributeNS(&mut self, - abstract_self: AbstractNode, + abstract_self: &JS<Element>, namespace: Option<DOMString>, localname: DOMString) -> ErrorResult { let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace)); @@ -482,21 +503,24 @@ impl Element { } // http://dom.spec.whatwg.org/#dom-element-getelementsbytagname - pub fn GetElementsByTagName(&self, _localname: DOMString) -> @mut HTMLCollection { + pub fn GetElementsByTagName(&self, _localname: DOMString) -> JS<HTMLCollection> { // FIXME: stub - https://github.com/mozilla/servo/issues/1660 - HTMLCollection::new(self.node.owner_doc().document().window, ~[]) + let doc = self.node.owner_doc(); + HTMLCollection::new(&doc.get().window, ~[]) } // http://dom.spec.whatwg.org/#dom-element-getelementsbytagnamens - pub fn GetElementsByTagNameNS(&self, _namespace: Option<DOMString>, _localname: DOMString) -> Fallible<@mut HTMLCollection> { + pub fn GetElementsByTagNameNS(&self, _namespace: Option<DOMString>, _localname: DOMString) -> Fallible<JS<HTMLCollection>> { // FIXME: stub - https://github.com/mozilla/servo/issues/1660 - Ok(HTMLCollection::new(self.node.owner_doc().document().window, ~[])) + let doc = self.node.owner_doc(); + Ok(HTMLCollection::new(&doc.get().window, ~[])) } // http://dom.spec.whatwg.org/#dom-element-getelementsbyclassname - pub fn GetElementsByClassName(&self, _names: DOMString) -> @mut HTMLCollection { + pub fn GetElementsByClassName(&self, _names: DOMString) -> JS<HTMLCollection> { // FIXME: stub - https://github.com/mozilla/servo/issues/1660 - HTMLCollection::new(self.node.owner_doc().document().window, ~[]) + let doc = self.node.owner_doc(); + HTMLCollection::new(&doc.get().window, ~[]) } // http://dom.spec.whatwg.org/#dom-element-matches @@ -517,13 +541,14 @@ impl Element { pub fn MozRequestPointerLock(&self) { } - pub fn GetClientRects(&self, abstract_self: AbstractNode) -> @mut ClientRectList { - let win = self.node.owner_doc().document().window; - let node = abstract_self; - assert!(node.is_element()); + pub fn GetClientRects(&self, abstract_self: &JS<Element>) -> JS<ClientRectList> { + let doc = self.node.owner_doc(); + let win = &doc.get().window; + let node: JS<Node> = NodeCast::from(abstract_self); let (port, chan) = Chan::new(); + let addr = node.to_trusted_node_address(); let rects = - match win.page.query_layout(ContentBoxesQuery(node, chan), port) { + match win.get().page.query_layout(ContentBoxesQuery(addr, chan), port) { ContentBoxesResponse(rects) => { rects.map(|r| { ClientRect::new( @@ -539,12 +564,13 @@ impl Element { ClientRectList::new(win, rects) } - pub fn GetBoundingClientRect(&self, abstract_self: AbstractNode) -> @mut ClientRect { - let win = self.node.owner_doc().document().window; - let node = abstract_self; - assert!(node.is_element()); + pub fn GetBoundingClientRect(&self, abstract_self: &JS<Element>) -> JS<ClientRect> { + let doc = self.node.owner_doc(); + let win = &doc.get().window; + let node: JS<Node> = NodeCast::from(abstract_self); let (port, chan) = Chan::new(); - match win.page.query_layout(ContentBoxQuery(node, chan), port) { + let addr = node.to_trusted_node_address(); + match win.get().page.query_layout(ContentBoxQuery(addr, chan), port) { ContentBoxResponse(rect) => { ClientRect::new( win, @@ -597,20 +623,20 @@ impl Element { 0 } - pub fn GetInnerHTML(&self, abstract_self: AbstractNode) -> Fallible<DOMString> { + pub fn GetInnerHTML(&self, abstract_self: &JS<Element>) -> Fallible<DOMString> { //XXX TODO: XML case - Ok(serialize(&mut NodeIterator::new(abstract_self, false, false))) + Ok(serialize(&mut NodeIterator::new(NodeCast::from(abstract_self), false, false))) } - pub fn SetInnerHTML(&mut self, _abstract_self: AbstractNode, _value: DOMString) -> ErrorResult { + pub fn SetInnerHTML(&mut self, _abstract_self: &JS<Element>, _value: DOMString) -> ErrorResult { Ok(()) } - pub fn GetOuterHTML(&self, abstract_self:AbstractNode) -> Fallible<DOMString> { - Ok(serialize(&mut NodeIterator::new(abstract_self, true, false))) + pub fn GetOuterHTML(&self, abstract_self: &JS<Element>) -> Fallible<DOMString> { + Ok(serialize(&mut NodeIterator::new(NodeCast::from(abstract_self), true, false))) } - pub fn SetOuterHTML(&mut self, _abstract_self: AbstractNode, _value: DOMString) -> ErrorResult { + pub fn SetOuterHTML(&mut self, _abstract_self: &JS<Element>, _value: DOMString) -> ErrorResult { Ok(()) } @@ -618,7 +644,7 @@ impl Element { Ok(()) } - pub fn QuerySelector(&self, _selectors: DOMString) -> Fallible<Option<AbstractNode>> { + pub fn QuerySelector(&self, _selectors: DOMString) -> Fallible<Option<JS<Element>>> { Ok(None) } } diff --git a/src/components/script/dom/event.rs b/src/components/script/dom/event.rs index aef1b4270cd..a8fac4308ef 100644 --- a/src/components/script/dom/event.rs +++ b/src/components/script/dom/event.rs @@ -2,20 +2,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::eventtarget::AbstractEventTarget; -use dom::window::Window; use dom::bindings::codegen::EventBinding; +use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::{Fallible, ErrorResult}; -use dom::mouseevent::MouseEvent; -use dom::uievent::UIEvent; +use dom::eventtarget::EventTarget; +use dom::window::Window; use servo_util::str::DOMString; use geom::point::Point2D; -use std::cast; -use std::unstable::raw::Box; - pub enum Event_ { ResizeEvent(uint, uint), ReflowEvent, @@ -25,10 +21,7 @@ pub enum Event_ { MouseMoveEvent(Point2D<f32>) } -pub struct AbstractEvent { - event: *mut Box<Event> -} - +#[deriving(Encodable)] pub enum EventPhase { Phase_None = 0, Phase_Capturing, @@ -36,91 +29,7 @@ pub enum EventPhase { Phase_Bubbling } -impl AbstractEvent { - pub fn from_box(box_: *mut Box<Event>) -> AbstractEvent { - AbstractEvent { - event: box_ - } - } - - // - // Downcasting borrows - // - - fn transmute<'a, T>(&'a self) -> &'a T { - unsafe { - let box_: *Box<T> = self.event as *Box<T>; - &(*box_).data - } - } - - fn transmute_mut<'a, T>(&'a self) -> &'a mut T { - unsafe { - let box_: *mut Box<T> = self.event as *mut Box<T>; - &mut (*box_).data - } - } - - pub fn type_id(&self) -> EventTypeId { - self.event().type_id - } - - pub fn event<'a>(&'a self) -> &'a Event { - self.transmute() - } - - pub fn mut_event<'a>(&'a self) -> &'a mut Event { - self.transmute_mut() - } - - pub fn is_uievent(&self) -> bool { - self.type_id() == UIEventTypeId - } - - pub fn uievent<'a>(&'a self) -> &'a UIEvent { - assert!(self.is_uievent()); - self.transmute() - } - - pub fn mut_uievent<'a>(&'a self) -> &'a mut UIEvent { - assert!(self.is_uievent()); - self.transmute_mut() - } - - pub fn is_mouseevent(&self) -> bool { - self.type_id() == MouseEventTypeId - } - - pub fn mouseevent<'a>(&'a self) -> &'a MouseEvent { - assert!(self.is_mouseevent()); - self.transmute() - } - - pub fn mut_mouseevent<'a>(&'a self) -> &'a mut MouseEvent { - assert!(self.is_mouseevent()); - self.transmute_mut() - } - - pub fn propagation_stopped(&self) -> bool { - self.event().stop_propagation - } - - pub fn bubbles(&self) -> bool { - self.event().bubbles - } -} - -impl Reflectable for AbstractEvent { - fn reflector<'a>(&'a self) -> &'a Reflector { - self.event().reflector() - } - - fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { - self.mut_event().mut_reflector() - } -} - -#[deriving(Eq)] +#[deriving(Eq, Encodable)] pub enum EventTypeId { HTMLEventTypeId, UIEventTypeId, @@ -128,11 +37,12 @@ pub enum EventTypeId { KeyEventTypeId } +#[deriving(Encodable)] pub struct Event { type_id: EventTypeId, reflector_: Reflector, - current_target: Option<AbstractEventTarget>, - target: Option<AbstractEventTarget>, + current_target: Option<JS<EventTarget>>, + target: Option<JS<EventTarget>>, type_: DOMString, phase: EventPhase, default_prevented: bool, @@ -142,7 +52,7 @@ pub struct Event { bubbles: bool, trusted: bool, dispatching: bool, - initialized: bool + initialized: bool, } impl Event { @@ -165,18 +75,10 @@ impl Event { } } - //FIXME: E should be bounded by some trait that is only implemented for Event types - pub fn as_abstract<E>(event: @mut E) -> AbstractEvent { - // This surrenders memory management of the event! - AbstractEvent { - event: unsafe { cast::transmute(event) }, - } - } - - pub fn new(window: @mut Window) -> AbstractEvent { - let ev = reflect_dom_object(@mut Event::new_inherited(HTMLEventTypeId), - window, EventBinding::Wrap); - Event::as_abstract(ev) + pub fn new(window: &JS<Window>) -> JS<Event> { + reflect_dom_object(~Event::new_inherited(HTMLEventTypeId), + window.get(), + EventBinding::Wrap) } pub fn EventPhase(&self) -> u16 { @@ -187,12 +89,12 @@ impl Event { self.type_.clone() } - pub fn GetTarget(&self) -> Option<AbstractEventTarget> { - self.target + pub fn GetTarget(&self) -> Option<JS<EventTarget>> { + self.target.clone() } - pub fn GetCurrentTarget(&self) -> Option<AbstractEventTarget> { - self.current_target + pub fn GetCurrentTarget(&self) -> Option<JS<EventTarget>> { + self.current_target.clone() } pub fn DefaultPrevented(&self) -> bool { @@ -241,11 +143,11 @@ impl Event { self.trusted } - pub fn Constructor(global: @mut Window, + pub fn Constructor(global: &JS<Window>, type_: DOMString, - init: &EventBinding::EventInit) -> Fallible<AbstractEvent> { - let ev = Event::new(global); - ev.mut_event().InitEvent(type_, init.bubbles, init.cancelable); + init: &EventBinding::EventInit) -> Fallible<JS<Event>> { + let mut ev = Event::new(global); + ev.get_mut().InitEvent(type_, init.bubbles, init.cancelable); Ok(ev) } } diff --git a/src/components/script/dom/eventdispatcher.rs b/src/components/script/dom/eventdispatcher.rs index 5a1c09ce9f6..c22ef7716c1 100644 --- a/src/components/script/dom/eventdispatcher.rs +++ b/src/components/script/dom/eventdispatcher.rs @@ -3,50 +3,57 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::callback::eReportExceptions; -use dom::eventtarget::{AbstractEventTarget, Capturing, Bubbling}; -use dom::event::{AbstractEvent, Phase_At_Target, Phase_None, Phase_Bubbling, Phase_Capturing}; -use dom::node::AbstractNode; +use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, NodeDerived}; +use dom::bindings::js::JS; +use dom::eventtarget::{Capturing, Bubbling, EventTarget}; +use dom::event::{Event, Phase_At_Target, Phase_None, Phase_Bubbling, Phase_Capturing}; +use dom::node::{Node, NodeHelpers}; // See http://dom.spec.whatwg.org/#concept-event-dispatch for the full dispatch algorithm -pub fn dispatch_event(target: AbstractEventTarget, - pseudo_target: Option<AbstractEventTarget>, - event: AbstractEvent) -> bool { - assert!(!event.event().dispatching); +pub fn dispatch_event(target: &JS<EventTarget>, + pseudo_target: Option<JS<EventTarget>>, + event: &mut JS<Event>) -> bool { + assert!(!event.get().dispatching); { - let event = event.mut_event(); - event.target = Some(pseudo_target.unwrap_or(target)); + let event = event.get_mut(); + event.target = match pseudo_target { + Some(pseudo_target) => Some(pseudo_target), + None => Some(target.clone()) + }; event.dispatching = true; } - let type_ = event.event().type_.clone(); + let type_ = event.get().type_.clone(); let mut chain = ~[]; //TODO: no chain if not participating in a tree - if target.is_node() { - for ancestor in AbstractNode::from_eventtarget(target).ancestors() { - chain.push(AbstractEventTarget::from_node(ancestor)); + if target.get().is_node() { + let target_node: JS<Node> = NodeCast::to(target); + for ancestor in target_node.ancestors() { + let ancestor_target: JS<EventTarget> = EventTargetCast::from(&ancestor); + chain.push(ancestor_target); } } - event.mut_event().phase = Phase_Capturing; + event.get_mut().phase = Phase_Capturing; //FIXME: The "callback this value" should be currentTarget /* capturing */ - for &cur_target in chain.rev_iter() { - let stopped = match cur_target.eventtarget().get_listeners_for(type_, Capturing) { + for cur_target in chain.rev_iter() { + let stopped = match cur_target.get().get_listeners_for(type_, Capturing) { Some(listeners) => { - event.mut_event().current_target = Some(cur_target); + event.get_mut().current_target = Some(cur_target.clone()); for listener in listeners.iter() { listener.HandleEvent__(event, eReportExceptions); - if event.event().stop_immediate { + if event.get().stop_immediate { break; } } - event.propagation_stopped() + event.get().stop_propagation } None => false }; @@ -57,18 +64,18 @@ pub fn dispatch_event(target: AbstractEventTarget, } /* at target */ - if !event.propagation_stopped() { + if !event.get().stop_propagation { { - let event = event.mut_event(); + let event = event.get_mut(); event.phase = Phase_At_Target; - event.current_target = Some(target); + event.current_target = Some(target.clone()); } - let opt_listeners = target.eventtarget().get_listeners(type_); + let opt_listeners = target.get().get_listeners(type_); for listeners in opt_listeners.iter() { for listener in listeners.iter() { listener.HandleEvent__(event, eReportExceptions); - if event.event().stop_immediate { + if event.get().stop_immediate { break; } } @@ -76,22 +83,22 @@ pub fn dispatch_event(target: AbstractEventTarget, } /* bubbling */ - if event.bubbles() && !event.propagation_stopped() { - event.mut_event().phase = Phase_Bubbling; + if event.get().bubbles && !event.get().stop_propagation { + event.get_mut().phase = Phase_Bubbling; - for &cur_target in chain.iter() { - let stopped = match cur_target.eventtarget().get_listeners_for(type_, Bubbling) { + for cur_target in chain.iter() { + let stopped = match cur_target.get().get_listeners_for(type_, Bubbling) { Some(listeners) => { - event.mut_event().current_target = Some(cur_target); + event.get_mut().current_target = Some(cur_target.clone()); for listener in listeners.iter() { listener.HandleEvent__(event, eReportExceptions); - if event.event().stop_immediate { + if event.get().stop_immediate { break; } } - event.propagation_stopped() + event.get().stop_propagation } None => false }; @@ -101,7 +108,7 @@ pub fn dispatch_event(target: AbstractEventTarget, } } - let event = event.mut_event(); + let event = event.get_mut(); event.dispatching = false; event.phase = Phase_None; event.current_target = None; diff --git a/src/components/script/dom/eventtarget.rs b/src/components/script/dom/eventtarget.rs index dbc435ac012..07445b12de5 100644 --- a/src/components/script/dom/eventtarget.rs +++ b/src/components/script/dom/eventtarget.rs @@ -2,122 +2,42 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector}; use dom::bindings::utils::{Fallible, InvalidState}; use dom::bindings::codegen::EventListenerBinding::EventListener; -use dom::document::AbstractDocument; -use dom::event::AbstractEvent; +use dom::event::Event; use dom::eventdispatcher::dispatch_event; -use dom::node::AbstractNode; -use dom::window::Window; +use dom::node::NodeTypeId; use servo_util::str::DOMString; -use std::cast; use std::hashmap::HashMap; -use std::unstable::raw::Box; -#[deriving(Eq)] +#[deriving(Eq,Encodable)] pub enum ListenerPhase { Capturing, Bubbling, } -#[deriving(Eq)] +#[deriving(Eq,Encodable)] pub enum EventTargetTypeId { WindowTypeId, - NodeTypeId + NodeTargetTypeId(NodeTypeId) } -#[deriving(Eq)] +#[deriving(Eq,Encodable)] struct EventListenerEntry { phase: ListenerPhase, listener: EventListener } +#[deriving(Encodable)] pub struct EventTarget { type_id: EventTargetTypeId, reflector_: Reflector, handlers: HashMap<DOMString, ~[EventListenerEntry]>, } -pub struct AbstractEventTarget { - eventtarget: *mut Box<EventTarget> -} - -impl AbstractEventTarget { - pub fn from_box<T>(box_: *mut Box<T>) -> AbstractEventTarget { - AbstractEventTarget { - eventtarget: box_ as *mut Box<EventTarget> - } - } - - pub fn from_node(node: AbstractNode) -> AbstractEventTarget { - unsafe { - cast::transmute(node) - } - } - - pub fn from_window(window: @mut Window) -> AbstractEventTarget { - AbstractEventTarget { - eventtarget: unsafe { cast::transmute(window) } - } - } - - pub fn from_document(document: AbstractDocument) -> AbstractEventTarget { - unsafe { - cast::transmute(document) - } - } - - pub fn type_id(&self) -> EventTargetTypeId { - self.eventtarget().type_id - } - - pub fn is_window(&self) -> bool { - self.type_id() == WindowTypeId - } - - pub fn is_node(&self) -> bool { - self.type_id() == NodeTypeId - } - - // - // Downcasting borrows - // - - fn transmute<'a, T>(&'a self) -> &'a T { - unsafe { - let box_: *Box<T> = self.eventtarget as *Box<T>; - &(*box_).data - } - } - - fn transmute_mut<'a, T>(&'a mut self) -> &'a mut T { - unsafe { - let box_: *mut Box<T> = self.eventtarget as *mut Box<T>; - &mut (*box_).data - } - } - - pub fn eventtarget<'a>(&'a self) -> &'a EventTarget { - self.transmute() - } - - pub fn mut_eventtarget<'a>(&'a mut self) -> &'a mut EventTarget { - self.transmute_mut() - } -} - -impl Reflectable for AbstractEventTarget { - fn reflector<'a>(&'a self) -> &'a Reflector { - self.eventtarget().reflector() - } - - fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { - self.mut_eventtarget().mut_reflector() - } -} - impl EventTarget { pub fn new_inherited(type_id: EventTargetTypeId) -> EventTarget { EventTarget { @@ -178,15 +98,16 @@ impl EventTarget { } } - pub fn DispatchEvent(&self, abstract_self: AbstractEventTarget, event: AbstractEvent) -> Fallible<bool> { + pub fn DispatchEvent(&self, abstract_self: &JS<EventTarget>, + event: &mut JS<Event>) -> Fallible<bool> { self.dispatch_event_with_target(abstract_self, None, event) } pub fn dispatch_event_with_target(&self, - abstract_self: AbstractEventTarget, - abstract_target: Option<AbstractEventTarget>, - event: AbstractEvent) -> Fallible<bool> { - if event.event().dispatching || !event.event().initialized { + abstract_self: &JS<EventTarget>, + abstract_target: Option<JS<EventTarget>>, + event: &mut JS<Event>) -> Fallible<bool> { + if event.get().dispatching || !event.get().initialized { return Err(InvalidState); } Ok(dispatch_event(abstract_self, abstract_target, event)) diff --git a/src/components/script/dom/formdata.rs b/src/components/script/dom/formdata.rs index b446c44a7d7..3beb7e996aa 100644 --- a/src/components/script/dom/formdata.rs +++ b/src/components/script/dom/formdata.rs @@ -4,27 +4,30 @@ use dom::bindings::utils::{Fallible, Reflectable, Reflector, reflect_dom_object}; use dom::bindings::codegen::FormDataBinding; +use dom::bindings::js::JS; use dom::blob::Blob; -use dom::node::AbstractNode; +use dom::htmlformelement::HTMLFormElement; use dom::window::Window; use servo_util::str::DOMString; use std::hashmap::HashMap; +#[deriving(Encodable)] enum FormDatum { StringData(DOMString), - BlobData { blob: @mut Blob, name: DOMString } + BlobData { blob: JS<Blob>, name: DOMString } } +#[deriving(Encodable)] pub struct FormData { data: HashMap<DOMString, FormDatum>, reflector_: Reflector, - window: @mut Window, - form: Option<AbstractNode> + window: JS<Window>, + form: Option<JS<HTMLFormElement>> } impl FormData { - pub fn new_inherited(form: Option<AbstractNode>, window: @mut Window) -> FormData { + pub fn new_inherited(form: Option<JS<HTMLFormElement>>, window: JS<Window>) -> FormData { FormData { data: HashMap::new(), reflector_: Reflector::new(), @@ -33,18 +36,18 @@ impl FormData { } } - pub fn new(form: Option<AbstractNode>, window: @mut Window) -> @mut FormData { - reflect_dom_object(@mut FormData::new_inherited(form, window), window, FormDataBinding::Wrap) + pub fn new(form: Option<JS<HTMLFormElement>>, window: &JS<Window>) -> JS<FormData> { + reflect_dom_object(~FormData::new_inherited(form, window.clone()), window.get(), FormDataBinding::Wrap) } - pub fn Constructor(window: @mut Window, form: Option<AbstractNode>) - -> Fallible<@mut FormData> { + pub fn Constructor(window: &JS<Window>, form: Option<JS<HTMLFormElement>>) + -> Fallible<JS<FormData>> { Ok(FormData::new(form, window)) } - pub fn Append(&mut self, name: DOMString, value: @mut Blob, filename: Option<DOMString>) { + pub fn Append(&mut self, name: DOMString, value: &JS<Blob>, filename: Option<DOMString>) { let blob = BlobData { - blob: value, + blob: value.clone(), name: filename.unwrap_or(~"default") }; self.data.insert(name.clone(), blob); diff --git a/src/components/script/dom/htmlanchorelement.rs b/src/components/script/dom/htmlanchorelement.rs index d398a8cbe03..4b4bcf7c115 100644 --- a/src/components/script/dom/htmlanchorelement.rs +++ b/src/components/script/dom/htmlanchorelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLAnchorElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLAnchorElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLAnchorElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLAnchorElement { htmlelement: HTMLElement } +impl HTMLAnchorElementDerived for EventTarget { + fn is_htmlanchorelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLAnchorElementTypeId)) => true, + _ => false + } + } +} + impl HTMLAnchorElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLAnchorElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLAnchorElement { HTMLAnchorElement { htmlelement: HTMLElement::new_inherited(HTMLAnchorElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLAnchorElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLAnchorElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAnchorElement> { + let element = HTMLAnchorElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLAnchorElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlappletelement.rs b/src/components/script/dom/htmlappletelement.rs index babaeaaf1f0..463414890c8 100644 --- a/src/components/script/dom/htmlappletelement.rs +++ b/src/components/script/dom/htmlappletelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLAppletElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLAppletElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLAppletElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLAppletElement { htmlelement: HTMLElement } +impl HTMLAppletElementDerived for EventTarget { + fn is_htmlappletelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLAppletElementTypeId)) => true, + _ => false + } + } +} + impl HTMLAppletElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLAppletElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLAppletElement { HTMLAppletElement { htmlelement: HTMLElement::new_inherited(HTMLAppletElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLAppletElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLAppletElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAppletElement> { + let element = HTMLAppletElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLAppletElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlareaelement.rs b/src/components/script/dom/htmlareaelement.rs index 3d80090d2c4..91d89feed00 100644 --- a/src/components/script/dom/htmlareaelement.rs +++ b/src/components/script/dom/htmlareaelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLAreaElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLAreaElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLAreaElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLAreaElement { htmlelement: HTMLElement } +impl HTMLAreaElementDerived for EventTarget { + fn is_htmlareaelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLAreaElementTypeId)) => true, + _ => false + } + } +} + impl HTMLAreaElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLAreaElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLAreaElement { HTMLAreaElement { htmlelement: HTMLElement::new_inherited(HTMLAreaElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLAreaElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLAreaElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAreaElement> { + let element = HTMLAreaElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLAreaElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlaudioelement.rs b/src/components/script/dom/htmlaudioelement.rs index 6e753318cb7..0575d3a49f2 100644 --- a/src/components/script/dom/htmlaudioelement.rs +++ b/src/components/script/dom/htmlaudioelement.rs @@ -3,25 +3,38 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLAudioElementBinding; -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::HTMLAudioElementDerived; +use dom::bindings::js::JS; +use dom::document::Document; use dom::element::HTMLAudioElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlmediaelement::HTMLMediaElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLAudioElement { htmlmediaelement: HTMLMediaElement } +impl HTMLAudioElementDerived for EventTarget { + fn is_htmlaudioelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLAudioElementTypeId)) => true, + _ => false + } + } +} + impl HTMLAudioElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLAudioElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLAudioElement { HTMLAudioElement { htmlmediaelement: HTMLMediaElement::new_inherited(HTMLAudioElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLAudioElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLAudioElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAudioElement> { + let element = HTMLAudioElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLAudioElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlbaseelement.rs b/src/components/script/dom/htmlbaseelement.rs index cf71f76dfbd..4384d620e93 100644 --- a/src/components/script/dom/htmlbaseelement.rs +++ b/src/components/script/dom/htmlbaseelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLBaseElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLBaseElementDerived; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::bindings::js::JS; +use dom::document::Document; use dom::element::HTMLBaseElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLBaseElement { htmlelement: HTMLElement } +impl HTMLBaseElementDerived for EventTarget { + fn is_htmlbaseelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLBaseElementTypeId)) => true, + _ => false + } + } +} + impl HTMLBaseElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLBaseElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLBaseElement { HTMLBaseElement { htmlelement: HTMLElement::new_inherited(HTMLBaseElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLBaseElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLBaseElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLBaseElement> { + let element = HTMLBaseElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLBaseElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlbodyelement.rs b/src/components/script/dom/htmlbodyelement.rs index 32d133f6760..a12a0dcf68f 100644 --- a/src/components/script/dom/htmlbodyelement.rs +++ b/src/components/script/dom/htmlbodyelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLBodyElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLBodyElementDerived; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::bindings::js::JS; +use dom::document::Document; use dom::element::HTMLBodyElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLBodyElement { htmlelement: HTMLElement } +impl HTMLBodyElementDerived for EventTarget { + fn is_htmlbodyelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLBodyElementTypeId)) => true, + _ => false + } + } +} + impl HTMLBodyElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLBodyElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLBodyElement { HTMLBodyElement { htmlelement: HTMLElement::new_inherited(HTMLBodyElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLBodyElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLBodyElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLBodyElement> { + let element = HTMLBodyElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLBodyElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlbrelement.rs b/src/components/script/dom/htmlbrelement.rs index 67462d28abb..9da6651455d 100644 --- a/src/components/script/dom/htmlbrelement.rs +++ b/src/components/script/dom/htmlbrelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLBRElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLBRElementDerived; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::bindings::js::JS; +use dom::document::Document; use dom::element::HTMLBRElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLBRElement { htmlelement: HTMLElement, } +impl HTMLBRElementDerived for EventTarget { + fn is_htmlbrelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLBRElementTypeId)) => true, + _ => false + } + } +} + impl HTMLBRElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLBRElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLBRElement { HTMLBRElement { htmlelement: HTMLElement::new_inherited(HTMLBRElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLBRElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLBRElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLBRElement> { + let element = HTMLBRElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLBRElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlbuttonelement.rs b/src/components/script/dom/htmlbuttonelement.rs index 4847ce12394..83662da0340 100644 --- a/src/components/script/dom/htmlbuttonelement.rs +++ b/src/components/script/dom/htmlbuttonelement.rs @@ -3,28 +3,42 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLButtonElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLButtonElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLButtonElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::htmlformelement::HTMLFormElement; +use dom::node::{Node, ElementNodeTypeId}; use dom::validitystate::ValidityState; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLButtonElement { htmlelement: HTMLElement } +impl HTMLButtonElementDerived for EventTarget { + fn is_htmlbuttonelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLButtonElementTypeId)) => true, + _ => false + } + } +} + impl HTMLButtonElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLButtonElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLButtonElement { HTMLButtonElement { htmlelement: HTMLElement::new_inherited(HTMLButtonElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLButtonElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLButtonElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLButtonElement> { + let element = HTMLButtonElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLButtonElementBinding::Wrap) } } @@ -45,7 +59,7 @@ impl HTMLButtonElement { Ok(()) } - pub fn GetForm(&self) -> Option<AbstractNode> { + pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> { None } @@ -120,12 +134,13 @@ impl HTMLButtonElement { pub fn SetWillValidate(&mut self, _will_validate: bool) { } - pub fn Validity(&self) -> @mut ValidityState { - let global = self.htmlelement.element.node.owner_doc().document().window; - ValidityState::new(global) + pub fn Validity(&self) -> JS<ValidityState> { + let doc = self.htmlelement.element.node.owner_doc(); + let doc = doc.get(); + ValidityState::new(&doc.window) } - pub fn SetValidity(&mut self, _validity: @mut ValidityState) { + pub fn SetValidity(&mut self, _validity: JS<ValidityState>) { } pub fn ValidationMessage(&self) -> DOMString { diff --git a/src/components/script/dom/htmlcanvaselement.rs b/src/components/script/dom/htmlcanvaselement.rs index dcc75ea73f1..199f4ad8c5b 100644 --- a/src/components/script/dom/htmlcanvaselement.rs +++ b/src/components/script/dom/htmlcanvaselement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLCanvasElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLCanvasElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::{ErrorResult}; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLCanvasElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLCanvasElement { htmlelement: HTMLElement, } +impl HTMLCanvasElementDerived for EventTarget { + fn is_htmlcanvaselement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLCanvasElementTypeId)) => true, + _ => false + } + } +} + impl HTMLCanvasElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLCanvasElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLCanvasElement { HTMLCanvasElement { htmlelement: HTMLElement::new_inherited(HTMLCanvasElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLCanvasElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLCanvasElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLCanvasElement> { + let element = HTMLCanvasElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLCanvasElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlcollection.rs b/src/components/script/dom/htmlcollection.rs index 32cdd52280c..f14ecd05db7 100644 --- a/src/components/script/dom/htmlcollection.rs +++ b/src/components/script/dom/htmlcollection.rs @@ -3,9 +3,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLCollectionBinding; +use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::Fallible; -use dom::node::AbstractNode; +use dom::element::Element; use dom::window::Window; use servo_util::str::DOMString; @@ -13,14 +14,15 @@ use js::jsapi::{JSObject, JSContext}; use std::ptr; +#[deriving(Encodable)] pub struct HTMLCollection { - elements: ~[AbstractNode], + elements: ~[JS<Element>], reflector_: Reflector, - window: @mut Window, + window: JS<Window>, } impl HTMLCollection { - pub fn new_inherited(window: @mut Window, elements: ~[AbstractNode]) -> HTMLCollection { + pub fn new_inherited(window: JS<Window>, elements: ~[JS<Element>]) -> HTMLCollection { HTMLCollection { elements: elements, reflector_: Reflector::new(), @@ -28,18 +30,18 @@ impl HTMLCollection { } } - pub fn new(window: @mut Window, elements: ~[AbstractNode]) -> @mut HTMLCollection { - reflect_dom_object(@mut HTMLCollection::new_inherited(window, elements), - window, HTMLCollectionBinding::Wrap) + pub fn new(window: &JS<Window>, elements: ~[JS<Element>]) -> JS<HTMLCollection> { + reflect_dom_object(~HTMLCollection::new_inherited(window.clone(), elements), + window.get(), HTMLCollectionBinding::Wrap) } pub fn Length(&self) -> u32 { self.elements.len() as u32 } - pub fn Item(&self, index: u32) -> Option<AbstractNode> { + pub fn Item(&self, index: u32) -> Option<JS<Element>> { if index < self.Length() { - Some(self.elements[index]) + Some(self.elements[index].clone()) } else { None } @@ -49,7 +51,7 @@ impl HTMLCollection { Ok(ptr::null()) } - pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<AbstractNode> { + pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Element>> { *found = true; self.Item(index) } diff --git a/src/components/script/dom/htmldataelement.rs b/src/components/script/dom/htmldataelement.rs index cd8a99bd282..59eb30945c6 100644 --- a/src/components/script/dom/htmldataelement.rs +++ b/src/components/script/dom/htmldataelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLDataElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLDataElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLDataElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLDataElement { htmlelement: HTMLElement } +impl HTMLDataElementDerived for EventTarget { + fn is_htmldataelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLDataElementTypeId)) => true, + _ => false + } + } +} + impl HTMLDataElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLDataElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLDataElement { HTMLDataElement { htmlelement: HTMLElement::new_inherited(HTMLDataElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLDataElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLDataElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDataElement> { + let element = HTMLDataElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLDataElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmldatalistelement.rs b/src/components/script/dom/htmldatalistelement.rs index 41665545a48..6cd888029c2 100644 --- a/src/components/script/dom/htmldatalistelement.rs +++ b/src/components/script/dom/htmldatalistelement.rs @@ -3,33 +3,47 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLDataListElementBinding; -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::HTMLDataListElementDerived; +use dom::bindings::js::JS; +use dom::document::Document; use dom::element::HTMLDataListElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlcollection::HTMLCollection; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLDataListElement { htmlelement: HTMLElement } +impl HTMLDataListElementDerived for EventTarget { + fn is_htmldatalistelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLDataListElementTypeId)) => true, + _ => false + } + } +} + impl HTMLDataListElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLDataListElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLDataListElement { HTMLDataListElement { htmlelement: HTMLElement::new_inherited(HTMLDataListElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLDataListElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLDataListElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDataListElement> { + let element = HTMLDataListElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLDataListElementBinding::Wrap) } } impl HTMLDataListElement { - pub fn Options(&self) -> @mut HTMLCollection { - let window = self.htmlelement.element.node.owner_doc().document().window; - HTMLCollection::new(window, ~[]) + pub fn Options(&self) -> JS<HTMLCollection> { + let doc = self.htmlelement.element.node.owner_doc(); + let doc = doc.get(); + HTMLCollection::new(&doc.window, ~[]) } } diff --git a/src/components/script/dom/htmldirectoryelement.rs b/src/components/script/dom/htmldirectoryelement.rs index 137aaffd1a2..6847d7b1cf3 100644 --- a/src/components/script/dom/htmldirectoryelement.rs +++ b/src/components/script/dom/htmldirectoryelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLDirectoryElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLDirectoryElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLDirectoryElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLDirectoryElement { htmlelement: HTMLElement } +impl HTMLDirectoryElementDerived for EventTarget { + fn is_htmldirectoryelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLDirectoryElementTypeId)) => true, + _ => false + } + } +} + impl HTMLDirectoryElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLDirectoryElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLDirectoryElement { HTMLDirectoryElement { htmlelement: HTMLElement::new_inherited(HTMLDirectoryElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLDirectoryElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLDirectoryElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDirectoryElement> { + let element = HTMLDirectoryElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLDirectoryElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmldivelement.rs b/src/components/script/dom/htmldivelement.rs index 3e09183e5bd..3220a7c6e24 100644 --- a/src/components/script/dom/htmldivelement.rs +++ b/src/components/script/dom/htmldivelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLDivElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLDivElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLDivElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLDivElement { htmlelement: HTMLElement } +impl HTMLDivElementDerived for EventTarget { + fn is_htmldivelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLDivElementTypeId)) => true, + _ => false + } + } +} + impl HTMLDivElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLDivElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLDivElement { HTMLDivElement { htmlelement: HTMLElement::new_inherited(HTMLDivElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLDivElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLDivElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDivElement> { + let element = HTMLDivElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLDivElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmldlistelement.rs b/src/components/script/dom/htmldlistelement.rs index da9576fcb07..c1394c37bd8 100644 --- a/src/components/script/dom/htmldlistelement.rs +++ b/src/components/script/dom/htmldlistelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLDListElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLDListElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLDListElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLDListElement { htmlelement: HTMLElement } +impl HTMLDListElementDerived for EventTarget { + fn is_htmldlistelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLDListElementTypeId)) => true, + _ => false + } + } +} + impl HTMLDListElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLDListElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLDListElement { HTMLDListElement { htmlelement: HTMLElement::new_inherited(HTMLDListElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLDListElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLDListElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDListElement> { + let element = HTMLDListElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLDListElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmldocument.rs b/src/components/script/dom/htmldocument.rs index 8297fd3e90c..7b967d68bea 100644 --- a/src/components/script/dom/htmldocument.rs +++ b/src/components/script/dom/htmldocument.rs @@ -3,67 +3,80 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLDocumentBinding; -use dom::bindings::utils::{Reflectable, Reflector, Traceable}; -use dom::document::{AbstractDocument, Document, HTML}; +use dom::bindings::codegen::InheritTypes::HTMLDocumentDerived; +use dom::bindings::js::JS; +use dom::bindings::utils::{Reflectable, Reflector}; +use dom::document::{Document, HTML, HTMLDocumentTypeId}; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlcollection::HTMLCollection; +use dom::node::DocumentNodeTypeId; use dom::window::Window; use servo_util::namespace::Null; use extra::url::Url; -use js::jsapi::JSTracer; +#[deriving(Encodable)] pub struct HTMLDocument { parent: Document } +impl HTMLDocumentDerived for EventTarget { + fn is_htmldocument(&self) -> bool { + match self.type_id { + NodeTargetTypeId(DocumentNodeTypeId(HTMLDocumentTypeId)) => true, + _ => false + } + } +} + impl HTMLDocument { - pub fn new_inherited(window: @mut Window, url: Option<Url>) -> HTMLDocument { + pub fn new_inherited(window: JS<Window>, url: Option<Url>) -> HTMLDocument { HTMLDocument { parent: Document::new_inherited(window, url, HTML, None) } } - pub fn new(window: @mut Window, url: Option<Url>) -> AbstractDocument { - let document = HTMLDocument::new_inherited(window, url); - Document::reflect_document(@mut document, window, HTMLDocumentBinding::Wrap) + pub fn new(window: &JS<Window>, url: Option<Url>) -> JS<HTMLDocument> { + let document = HTMLDocument::new_inherited(window.clone(), url); + Document::reflect_document(~document, window, HTMLDocumentBinding::Wrap) } } impl HTMLDocument { - pub fn Images(&self) -> @mut HTMLCollection { + pub fn Images(&self) -> JS<HTMLCollection> { self.parent.createHTMLCollection(|elem| "img" == elem.tag_name) } - pub fn Embeds(&self) -> @mut HTMLCollection { + pub fn Embeds(&self) -> JS<HTMLCollection> { self.parent.createHTMLCollection(|elem| "embed" == elem.tag_name) } - pub fn Plugins(&self) -> @mut HTMLCollection { + pub fn Plugins(&self) -> JS<HTMLCollection> { self.Embeds() } - pub fn Links(&self) -> @mut HTMLCollection { + pub fn Links(&self) -> JS<HTMLCollection> { self.parent.createHTMLCollection(|elem| { ("a" == elem.tag_name || "area" == elem.tag_name) && elem.get_attribute(Null, "href").is_some() }) } - pub fn Forms(&self) -> @mut HTMLCollection { + pub fn Forms(&self) -> JS<HTMLCollection> { self.parent.createHTMLCollection(|elem| "form" == elem.tag_name) } - pub fn Scripts(&self) -> @mut HTMLCollection { + pub fn Scripts(&self) -> JS<HTMLCollection> { self.parent.createHTMLCollection(|elem| "script" == elem.tag_name) } - pub fn Anchors(&self) -> @mut HTMLCollection { + pub fn Anchors(&self) -> JS<HTMLCollection> { self.parent.createHTMLCollection(|elem| { "a" == elem.tag_name && elem.get_attribute(Null, "name").is_some() }) } - pub fn Applets(&self) -> @mut HTMLCollection { + pub fn Applets(&self) -> JS<HTMLCollection> { // FIXME: This should be return OBJECT elements containing applets. self.parent.createHTMLCollection(|elem| "applet" == elem.tag_name) } @@ -78,9 +91,3 @@ impl Reflectable for HTMLDocument { self.parent.mut_reflector() } } - -impl Traceable for HTMLDocument { - fn trace(&self, tracer: *mut JSTracer) { - self.parent.trace(tracer); - } -} diff --git a/src/components/script/dom/htmlelement.rs b/src/components/script/dom/htmlelement.rs index 06ab085f945..55c7c1141b6 100644 --- a/src/components/script/dom/htmlelement.rs +++ b/src/components/script/dom/htmlelement.rs @@ -3,29 +3,42 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLElementBinding; -use dom::bindings::utils::{Fallible, ErrorResult}; -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::HTMLElementDerived; +use dom::bindings::js::JS; +use dom::bindings::utils::{ErrorResult, Fallible}; +use dom::document::Document; use dom::element::{Element, ElementTypeId, HTMLElementTypeId}; -use dom::node::{AbstractNode, Node}; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; +use dom::node::{Node, ElementNodeTypeId}; use js::jsapi::{JSContext, JSVal}; use js::JSVAL_NULL; use servo_util::namespace; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLElement { element: Element } +impl HTMLElementDerived for EventTarget { + fn is_htmlelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(_)) => true, + _ => false + } + } +} + impl HTMLElement { - pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, document: AbstractDocument) -> HTMLElement { + pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, document: JS<Document>) -> HTMLElement { HTMLElement { element: Element::new_inherited(type_id, tag_name, namespace::HTML, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLElement::new_inherited(HTMLElementTypeId, localName, document); - Node::reflect_node(@mut element, document, HTMLElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLElement> { + let element = HTMLElement::new_inherited(HTMLElementTypeId, localName, document.clone()); + Node::reflect_node(~element, document, HTMLElementBinding::Wrap) } } @@ -134,7 +147,7 @@ impl HTMLElement { pub fn SetClassName(&self, _class: DOMString) { } - pub fn GetOffsetParent(&self) -> Option<AbstractNode> { + pub fn GetOffsetParent(&self) -> Option<JS<Element>> { None } diff --git a/src/components/script/dom/htmlembedelement.rs b/src/components/script/dom/htmlembedelement.rs index a7b5609bfd2..d2da7f540d1 100644 --- a/src/components/script/dom/htmlembedelement.rs +++ b/src/components/script/dom/htmlembedelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLEmbedElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLEmbedElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLEmbedElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLEmbedElement { htmlelement: HTMLElement } +impl HTMLEmbedElementDerived for EventTarget { + fn is_htmlembedelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLEmbedElementTypeId)) => true, + _ => false + } + } +} + impl HTMLEmbedElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLEmbedElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLEmbedElement { HTMLEmbedElement { htmlelement: HTMLElement::new_inherited(HTMLEmbedElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLEmbedElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLEmbedElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLEmbedElement> { + let element = HTMLEmbedElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLEmbedElementBinding::Wrap) } } @@ -76,7 +89,7 @@ impl HTMLEmbedElement { Ok(()) } - pub fn GetSVGDocument(&self) -> Option<AbstractDocument> { + pub fn GetSVGDocument(&self) -> Option<JS<Document>> { None } } diff --git a/src/components/script/dom/htmlfieldsetelement.rs b/src/components/script/dom/htmlfieldsetelement.rs index a9939b4c4c9..a67e3a8bc91 100644 --- a/src/components/script/dom/htmlfieldsetelement.rs +++ b/src/components/script/dom/htmlfieldsetelement.rs @@ -3,29 +3,43 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLFieldSetElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLFieldSetElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLFieldSetElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; +use dom::htmlformelement::HTMLFormElement; use dom::htmlcollection::HTMLCollection; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use dom::validitystate::ValidityState; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLFieldSetElement { htmlelement: HTMLElement } +impl HTMLFieldSetElementDerived for EventTarget { + fn is_htmlfieldsetelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLFieldSetElementTypeId)) => true, + _ => false + } + } +} + impl HTMLFieldSetElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLFieldSetElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLFieldSetElement { HTMLFieldSetElement { htmlelement: HTMLElement::new_inherited(HTMLFieldSetElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLFieldSetElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLFieldSetElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFieldSetElement> { + let element = HTMLFieldSetElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLFieldSetElementBinding::Wrap) } } @@ -38,7 +52,7 @@ impl HTMLFieldSetElement { Ok(()) } - pub fn GetForm(&self) -> Option<AbstractNode> { + pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> { None } @@ -54,18 +68,20 @@ impl HTMLFieldSetElement { ~"" } - pub fn Elements(&self) -> @mut HTMLCollection { - let window = self.htmlelement.element.node.owner_doc().document().window; - HTMLCollection::new(window, ~[]) + pub fn Elements(&self) -> JS<HTMLCollection> { + let doc = self.htmlelement.element.node.owner_doc(); + let doc = doc.get(); + HTMLCollection::new(&doc.window, ~[]) } pub fn WillValidate(&self) -> bool { false } - pub fn Validity(&self) -> @mut ValidityState { - let global = self.htmlelement.element.node.owner_doc().document().window; - ValidityState::new(global) + pub fn Validity(&self) -> JS<ValidityState> { + let doc = self.htmlelement.element.node.owner_doc(); + let doc = doc.get(); + ValidityState::new(&doc.window) } pub fn ValidationMessage(&self) -> DOMString { diff --git a/src/components/script/dom/htmlfontelement.rs b/src/components/script/dom/htmlfontelement.rs index b3ccf1a6f14..024d546cc41 100644 --- a/src/components/script/dom/htmlfontelement.rs +++ b/src/components/script/dom/htmlfontelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLFontElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLFontElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLFontElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLFontElement { htmlelement: HTMLElement } +impl HTMLFontElementDerived for EventTarget { + fn is_htmlfontelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLFontElementTypeId)) => true, + _ => false + } + } +} + impl HTMLFontElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLFontElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLFontElement { HTMLFontElement { htmlelement: HTMLElement::new_inherited(HTMLFontElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLFontElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLFontElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFontElement> { + let element = HTMLFontElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLFontElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlformelement.rs b/src/components/script/dom/htmlformelement.rs index 554cabd6090..d213c68dbdb 100644 --- a/src/components/script/dom/htmlformelement.rs +++ b/src/components/script/dom/htmlformelement.rs @@ -3,28 +3,41 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLFormElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLFormElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; -use dom::element::HTMLFormElementTypeId; +use dom::document::Document; +use dom::element::{Element, HTMLFormElementTypeId}; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlcollection::HTMLCollection; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLFormElement { htmlelement: HTMLElement } +impl HTMLFormElementDerived for EventTarget { + fn is_htmlformelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLFormElementTypeId)) => true, + _ => false + } + } +} + impl HTMLFormElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLFormElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLFormElement { HTMLFormElement { htmlelement: HTMLElement::new_inherited(HTMLFormElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLFormElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLFormElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFormElement> { + let element = HTMLFormElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLFormElementBinding::Wrap) } } @@ -101,9 +114,10 @@ impl HTMLFormElement { Ok(()) } - pub fn Elements(&self) -> @mut HTMLCollection { - let window = self.htmlelement.element.node.owner_doc().document().window; - HTMLCollection::new(window, ~[]) + pub fn Elements(&self) -> JS<HTMLCollection> { + let doc = self.htmlelement.element.node.owner_doc(); + let doc = doc.get(); + HTMLCollection::new(&doc.window, ~[]) } pub fn Length(&self) -> i32 { @@ -121,7 +135,7 @@ impl HTMLFormElement { false } - pub fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> AbstractNode { + pub fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> JS<Element> { fail!("Not implemented.") } } diff --git a/src/components/script/dom/htmlframeelement.rs b/src/components/script/dom/htmlframeelement.rs index 25e6feae0b6..26486c7cceb 100644 --- a/src/components/script/dom/htmlframeelement.rs +++ b/src/components/script/dom/htmlframeelement.rs @@ -3,28 +3,41 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLFrameElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLFrameElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLFrameElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use dom::windowproxy::WindowProxy; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLFrameElement { htmlelement: HTMLElement } +impl HTMLFrameElementDerived for EventTarget { + fn is_htmlframeelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLFrameElementTypeId)) => true, + _ => false + } + } +} + impl HTMLFrameElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLFrameElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLFrameElement { HTMLFrameElement { htmlelement: HTMLElement::new_inherited(HTMLFrameElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLFrameElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLFrameElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFrameElement> { + let element = HTMLFrameElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLFrameElementBinding::Wrap) } } @@ -77,11 +90,11 @@ impl HTMLFrameElement { Ok(()) } - pub fn GetContentDocument(&self) -> Option<AbstractDocument> { + pub fn GetContentDocument(&self) -> Option<JS<Document>> { None } - pub fn GetContentWindow(&self) -> Option<@mut WindowProxy> { + pub fn GetContentWindow(&self) -> Option<JS<WindowProxy>> { None } diff --git a/src/components/script/dom/htmlframesetelement.rs b/src/components/script/dom/htmlframesetelement.rs index 5b40a4b5fe1..252c17709c5 100644 --- a/src/components/script/dom/htmlframesetelement.rs +++ b/src/components/script/dom/htmlframesetelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLFrameSetElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLFrameSetElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLFrameSetElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLFrameSetElement { htmlelement: HTMLElement } +impl HTMLFrameSetElementDerived for EventTarget { + fn is_htmlframesetelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLFrameSetElementTypeId)) => true, + _ => false + } + } +} + impl HTMLFrameSetElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLFrameSetElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLFrameSetElement { HTMLFrameSetElement { htmlelement: HTMLElement::new_inherited(HTMLFrameSetElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLFrameSetElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLFrameSetElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFrameSetElement> { + let element = HTMLFrameSetElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLFrameSetElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlheadelement.rs b/src/components/script/dom/htmlheadelement.rs index f7459d0ac4f..91266180c27 100644 --- a/src/components/script/dom/htmlheadelement.rs +++ b/src/components/script/dom/htmlheadelement.rs @@ -3,25 +3,38 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLHeadElementBinding; -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::HTMLHeadElementDerived; +use dom::bindings::js::JS; +use dom::document::Document; use dom::element::HTMLHeadElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLHeadElement { htmlelement: HTMLElement } +impl HTMLHeadElementDerived for EventTarget { + fn is_htmlheadelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLHeadElementTypeId)) => true, + _ => false + } + } +} + impl HTMLHeadElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLHeadElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLHeadElement { HTMLHeadElement { htmlelement: HTMLElement::new_inherited(HTMLHeadElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLHeadElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLHeadElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLHeadElement> { + let element = HTMLHeadElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLHeadElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlheadingelement.rs b/src/components/script/dom/htmlheadingelement.rs index f15075f30cd..ecae9910b6d 100644 --- a/src/components/script/dom/htmlheadingelement.rs +++ b/src/components/script/dom/htmlheadingelement.rs @@ -3,12 +3,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLHeadingElementBinding; -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::HTMLHeadingElementDerived; +use dom::bindings::js::JS; +use dom::document::Document; use dom::element::HTMLHeadingElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub enum HeadingLevel { Heading1, Heading2, @@ -18,22 +22,32 @@ pub enum HeadingLevel { Heading6, } +#[deriving(Encodable)] pub struct HTMLHeadingElement { htmlelement: HTMLElement, level: HeadingLevel, } +impl HTMLHeadingElementDerived for EventTarget { + fn is_htmlheadingelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLHeadingElementTypeId)) => true, + _ => false + } + } +} + impl HTMLHeadingElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument, level: HeadingLevel) -> HTMLHeadingElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>, level: HeadingLevel) -> HTMLHeadingElement { HTMLHeadingElement { htmlelement: HTMLElement::new_inherited(HTMLHeadingElementTypeId, localName, document), level: level, } } - pub fn new(localName: DOMString, document: AbstractDocument, level: HeadingLevel) -> AbstractNode { - let element = HTMLHeadingElement::new_inherited(localName, document, level); - Node::reflect_node(@mut element, document, HTMLHeadingElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>, level: HeadingLevel) -> JS<HTMLHeadingElement> { + let element = HTMLHeadingElement::new_inherited(localName, document.clone(), level); + Node::reflect_node(~element, document, HTMLHeadingElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlhrelement.rs b/src/components/script/dom/htmlhrelement.rs index 1a239a30049..557a423787c 100644 --- a/src/components/script/dom/htmlhrelement.rs +++ b/src/components/script/dom/htmlhrelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLHRElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLHRElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLHRElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLHRElement { htmlelement: HTMLElement, } +impl HTMLHRElementDerived for EventTarget { + fn is_htmlhrelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLHRElementTypeId)) => true, + _ => false + } + } +} + impl HTMLHRElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLHRElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLHRElement { HTMLHRElement { htmlelement: HTMLElement::new_inherited(HTMLHRElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLHRElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLHRElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLHRElement> { + let element = HTMLHRElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLHRElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlhtmlelement.rs b/src/components/script/dom/htmlhtmlelement.rs index 2da7b45f40b..dcadd267abb 100644 --- a/src/components/script/dom/htmlhtmlelement.rs +++ b/src/components/script/dom/htmlhtmlelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLHtmlElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLHtmlElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLHtmlElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLHtmlElement { htmlelement: HTMLElement } +impl HTMLHtmlElementDerived for EventTarget { + fn is_htmlhtmlelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLHtmlElementTypeId)) => true, + _ => false + } + } +} + impl HTMLHtmlElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLHtmlElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLHtmlElement { HTMLHtmlElement { htmlelement: HTMLElement::new_inherited(HTMLHtmlElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLHtmlElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLHtmlElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLHtmlElement> { + let element = HTMLHtmlElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLHtmlElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmliframeelement.rs b/src/components/script/dom/htmliframeelement.rs index ca38c069d14..92e0c63dfc7 100644 --- a/src/components/script/dom/htmliframeelement.rs +++ b/src/components/script/dom/htmliframeelement.rs @@ -3,17 +3,21 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLIFrameElementBinding; +use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElementDerived}; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLIframeElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use dom::windowproxy::WindowProxy; use servo_util::str::DOMString; use extra::url::Url; use servo_msg::constellation_msg::{PipelineId, SubpageId}; use std::ascii::StrAsciiExt; +use extra::serialize::{Encoder, Encodable}; enum SandboxAllowance { AllowNothing = 0x00, @@ -25,13 +29,33 @@ enum SandboxAllowance { AllowPopups = 0x20 } +#[deriving(Encodable)] pub struct HTMLIFrameElement { htmlelement: HTMLElement, - frame: Option<Url>, + extra: Untraceable, size: Option<IFrameSize>, sandbox: Option<u8> } +struct Untraceable { + frame: Option<Url>, +} + +impl<S: Encoder> Encodable<S> for Untraceable { + fn encode(&self, _s: &mut S) { + } +} + +impl HTMLIFrameElementDerived for EventTarget { + fn is_htmliframeelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLIframeElementTypeId)) => true, + _ => false + } + } +} + +#[deriving(Encodable)] pub struct IFrameSize { pipeline_id: PipelineId, subpage_id: SubpageId, @@ -44,18 +68,20 @@ impl HTMLIFrameElement { } impl HTMLIFrameElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLIFrameElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLIFrameElement { HTMLIFrameElement { htmlelement: HTMLElement::new_inherited(HTMLIframeElementTypeId, localName, document), - frame: None, + extra: Untraceable { + frame: None + }, size: None, sandbox: None, } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLIFrameElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLIFrameElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLIFrameElement> { + let element = HTMLIFrameElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLIFrameElementBinding::Wrap) } } @@ -84,12 +110,13 @@ impl HTMLIFrameElement { Ok(()) } - pub fn Sandbox(&self, _abstract_self: AbstractNode) -> DOMString { + pub fn Sandbox(&self, _abstract_self: &JS<HTMLIFrameElement>) -> DOMString { self.htmlelement.element.get_string_attribute("sandbox") } - pub fn SetSandbox(&mut self, abstract_self: AbstractNode, sandbox: DOMString) { - self.htmlelement.element.set_string_attribute(abstract_self, "sandbox", + pub fn SetSandbox(&mut self, abstract_self: &JS<HTMLIFrameElement>, sandbox: DOMString) { + self.htmlelement.element.set_string_attribute(&ElementCast::from(abstract_self), + "sandbox", sandbox); } @@ -143,11 +170,11 @@ impl HTMLIFrameElement { Ok(()) } - pub fn GetContentDocument(&self) -> Option<AbstractDocument> { + pub fn GetContentDocument(&self) -> Option<JS<Document>> { None } - pub fn GetContentWindow(&self) -> Option<@mut WindowProxy> { + pub fn GetContentWindow(&self) -> Option<JS<WindowProxy>> { None } @@ -199,7 +226,7 @@ impl HTMLIFrameElement { Ok(()) } - pub fn GetSVGDocument(&self) -> Option<AbstractDocument> { + pub fn GetSVGDocument(&self) -> Option<JS<Document>> { None } } diff --git a/src/components/script/dom/htmlimageelement.rs b/src/components/script/dom/htmlimageelement.rs index 5e041572537..d2304944eeb 100644 --- a/src/components/script/dom/htmlimageelement.rs +++ b/src/components/script/dom/htmlimageelement.rs @@ -3,11 +3,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLImageElementBinding; +use dom::bindings::codegen::InheritTypes::{NodeCast, HTMLImageElementDerived}; +use dom::bindings::codegen::InheritTypes::{ElementCast}; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; -use dom::element::HTMLImageElementTypeId; +use dom::document::Document; +use dom::element::{Element, HTMLImageElementTypeId}; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId, NodeHelpers}; use extra::url::Url; use servo_util::geometry::to_px; use layout_interface::{ContentBoxQuery, ContentBoxResponse}; @@ -17,22 +21,45 @@ use servo_util::url::parse_url; use servo_util::namespace::Null; use servo_util::str::DOMString; +use extra::serialize::{Encoder, Encodable}; + +#[deriving(Encodable)] pub struct HTMLImageElement { htmlelement: HTMLElement, + extra: Untraceable, +} + +struct Untraceable { image: Option<Url>, } +impl<S: Encoder> Encodable<S> for Untraceable { + fn encode(&self, _s: &mut S) { + } +} + +impl HTMLImageElementDerived for EventTarget { + fn is_htmlimageelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLImageElementTypeId)) => true, + _ => false + } + } +} + impl HTMLImageElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLImageElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLImageElement { HTMLImageElement { htmlelement: HTMLElement::new_inherited(HTMLImageElementTypeId, localName, document), - image: None, + extra: Untraceable { + image: None, + } } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLImageElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLImageElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLImageElement> { + let element = HTMLImageElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLImageElementBinding::Wrap) } } @@ -41,12 +68,12 @@ impl HTMLImageElement { /// prefetching the image. This method must be called after `src` is changed. pub fn update_image(&mut self, image_cache: ImageCacheTask, url: Option<Url>) { let elem = &mut self.htmlelement.element; - let src_opt = elem.get_attribute(Null, "src").map(|x| x.Value()); + let src_opt = elem.get_attribute(Null, "src").map(|x| x.get().Value()); match src_opt { None => {} Some(src) => { let img_url = parse_url(src, url); - self.image = Some(img_url.clone()); + self.extra.image = Some(img_url.clone()); // inform the image cache to load this, but don't store a // handle. @@ -61,7 +88,7 @@ impl HTMLImageElement { pub fn AfterSetAttr(&mut self, name: DOMString, _value: DOMString) { if "src" == name { let document = self.htmlelement.element.node.owner_doc(); - let window = document.document().window; + let window = document.get().window.get(); let url = window.page.url.as_ref().map(|&(ref url, _)| url.clone()); self.update_image(window.image_cache_task.clone(), url); } @@ -73,7 +100,7 @@ impl HTMLImageElement { // `self.update_image()` will see the missing src attribute and return early. if "src" == name { let document = self.htmlelement.element.node.owner_doc(); - let window = document.document().window; + let window = document.get().window.get(); self.update_image(window.image_cache_task.clone(), None); } } @@ -86,13 +113,13 @@ impl HTMLImageElement { Ok(()) } - pub fn Src(&self, _abstract_self: AbstractNode) -> DOMString { + pub fn Src(&self, _abstract_self: &JS<HTMLImageElement>) -> DOMString { ~"" } - pub fn SetSrc(&mut self, abstract_self: AbstractNode, src: DOMString) -> ErrorResult { + pub fn SetSrc(&mut self, abstract_self: &JS<HTMLImageElement>, src: DOMString) -> ErrorResult { let node = &mut self.htmlelement.element; - node.set_attr(abstract_self, ~"src", src.clone()); + node.set_attr(&ElementCast::from(abstract_self), ~"src", src.clone()); Ok(()) } @@ -120,37 +147,43 @@ impl HTMLImageElement { Ok(()) } - pub fn Width(&self, abstract_self: AbstractNode) -> u32 { - let node = &self.htmlelement.element.node; - let page = node.owner_doc().document().window.page; + pub fn Width(&self, abstract_self: &JS<HTMLImageElement>) -> u32 { + let node: JS<Node> = NodeCast::from(abstract_self); + let doc = node.get().owner_doc(); + let page = doc.get().window.get().page; let (port, chan) = Chan::new(); - match page.query_layout(ContentBoxQuery(abstract_self, chan), port) { + let addr = node.to_trusted_node_address(); + match page.query_layout(ContentBoxQuery(addr, chan), port) { ContentBoxResponse(rect) => { to_px(rect.size.width) as u32 } } } - pub fn SetWidth(&mut self, abstract_self: AbstractNode, width: u32) -> ErrorResult { - let node = &mut self.htmlelement.element; - node.set_attr(abstract_self, ~"width", width.to_str()); + pub fn SetWidth(&mut self, abstract_self: &JS<HTMLImageElement>, width: u32) -> ErrorResult { + let mut elem: JS<Element> = ElementCast::from(abstract_self); + let mut elem_clone = elem.clone(); + elem.get_mut().set_attr(&mut elem_clone, ~"width", width.to_str()); Ok(()) } - pub fn Height(&self, abstract_self: AbstractNode) -> u32 { + pub fn Height(&self, abstract_self: &JS<HTMLImageElement>) -> u32 { let node = &self.htmlelement.element.node; - let page = node.owner_doc().document().window.page; + let doc = node.owner_doc(); + let page = doc.get().window.get().page; let (port, chan) = Chan::new(); - match page.query_layout(ContentBoxQuery(abstract_self, chan), port) { + let this_node: JS<Node> = NodeCast::from(abstract_self); + let addr = this_node.to_trusted_node_address(); + match page.query_layout(ContentBoxQuery(addr, chan), port) { ContentBoxResponse(rect) => { to_px(rect.size.height) as u32 } } } - pub fn SetHeight(&mut self, abstract_self: AbstractNode, height: u32) -> ErrorResult { + pub fn SetHeight(&mut self, abstract_self: &JS<HTMLImageElement>, height: u32) -> ErrorResult { let node = &mut self.htmlelement.element; - node.set_attr(abstract_self, ~"height", height.to_str()); + node.set_attr(&ElementCast::from(abstract_self), ~"height", height.to_str()); Ok(()) } diff --git a/src/components/script/dom/htmlinputelement.rs b/src/components/script/dom/htmlinputelement.rs index d2f2acd0249..426f78b3e6b 100644 --- a/src/components/script/dom/htmlinputelement.rs +++ b/src/components/script/dom/htmlinputelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLInputElementBinding; -use dom::bindings::utils::{Fallible, ErrorResult}; -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::HTMLInputElementDerived; +use dom::bindings::js::JS; +use dom::bindings::utils::{ErrorResult, Fallible}; +use dom::document::Document; use dom::element::HTMLInputElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLInputElement { htmlelement: HTMLElement, } +impl HTMLInputElementDerived for EventTarget { + fn is_htmlinputelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLInputElementTypeId)) => true, + _ => false + } + } +} + impl HTMLInputElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLInputElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLInputElement { HTMLInputElement { htmlelement: HTMLElement::new_inherited(HTMLInputElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLInputElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLInputElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLInputElement> { + let element = HTMLInputElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLInputElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmllabelelement.rs b/src/components/script/dom/htmllabelelement.rs index 89cf6215ca9..e4da3eb661c 100644 --- a/src/components/script/dom/htmllabelelement.rs +++ b/src/components/script/dom/htmllabelelement.rs @@ -3,26 +3,39 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLLabelElementBinding; -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::HTMLLabelElementDerived; +use dom::bindings::js::JS; +use dom::document::Document; use dom::element::HTMLLabelElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLLabelElement { htmlelement: HTMLElement, } +impl HTMLLabelElementDerived for EventTarget { + fn is_htmllabelelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLLabelElementTypeId)) => true, + _ => false + } + } +} + impl HTMLLabelElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLLabelElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLLabelElement { HTMLLabelElement { htmlelement: HTMLElement::new_inherited(HTMLLabelElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLLabelElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLLabelElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLabelElement> { + let element = HTMLLabelElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLLabelElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmllegendelement.rs b/src/components/script/dom/htmllegendelement.rs index 43949db6e82..9c98a6b103a 100644 --- a/src/components/script/dom/htmllegendelement.rs +++ b/src/components/script/dom/htmllegendelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLLegendElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLLegendElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLLegendElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLLegendElement { htmlelement: HTMLElement, } +impl HTMLLegendElementDerived for EventTarget { + fn is_htmllegendelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLLegendElementTypeId)) => true, + _ => false + } + } +} + impl HTMLLegendElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLLegendElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLLegendElement { HTMLLegendElement { htmlelement: HTMLElement::new_inherited(HTMLLegendElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLLegendElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLLegendElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLegendElement> { + let element = HTMLLegendElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLLegendElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmllielement.rs b/src/components/script/dom/htmllielement.rs index 2079df20568..79a243c7fb2 100644 --- a/src/components/script/dom/htmllielement.rs +++ b/src/components/script/dom/htmllielement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLLIElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLLIElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLLIElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLLIElement { htmlelement: HTMLElement, } +impl HTMLLIElementDerived for EventTarget { + fn is_htmllielement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLLIElementTypeId)) => true, + _ => false + } + } +} + impl HTMLLIElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLLIElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLLIElement { HTMLLIElement { htmlelement: HTMLElement::new_inherited(HTMLLIElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLLIElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLLIElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLIElement> { + let element = HTMLLIElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLLIElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmllinkelement.rs b/src/components/script/dom/htmllinkelement.rs index d5fce888632..f8e6bdc73e7 100644 --- a/src/components/script/dom/htmllinkelement.rs +++ b/src/components/script/dom/htmllinkelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLLinkElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLLinkElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLLinkElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLLinkElement { htmlelement: HTMLElement, } +impl HTMLLinkElementDerived for EventTarget { + fn is_htmllinkelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLLinkElementTypeId)) => true, + _ => false + } + } +} + impl HTMLLinkElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLLinkElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLLinkElement { HTMLLinkElement { htmlelement: HTMLElement::new_inherited(HTMLLinkElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLLinkElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLLinkElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLinkElement> { + let element = HTMLLinkElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLLinkElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlmainelement.rs b/src/components/script/dom/htmlmainelement.rs index 550e0470efb..b0fc11c2781 100644 --- a/src/components/script/dom/htmlmainelement.rs +++ b/src/components/script/dom/htmlmainelement.rs @@ -3,25 +3,38 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLMainElementBinding; -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::HTMLMainElementDerived; +use dom::bindings::js::JS; +use dom::document::Document; use dom::element::HTMLMainElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLMainElement { htmlelement: HTMLElement } +impl HTMLMainElementDerived for EventTarget { + fn is_htmlmainelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLMainElementTypeId)) => true, + _ => false + } + } +} + impl HTMLMainElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLMainElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLMainElement { HTMLMainElement { htmlelement: HTMLElement::new_inherited(HTMLMainElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLMainElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLMainElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMainElement> { + let element = HTMLMainElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLMainElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlmapelement.rs b/src/components/script/dom/htmlmapelement.rs index d61278ce070..fcb09820fb1 100644 --- a/src/components/script/dom/htmlmapelement.rs +++ b/src/components/script/dom/htmlmapelement.rs @@ -3,28 +3,41 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLMapElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLMapElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::htmlcollection::HTMLCollection; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLMapElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; +use dom::htmlcollection::HTMLCollection; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLMapElement { htmlelement: HTMLElement } +impl HTMLMapElementDerived for EventTarget { + fn is_htmlmapelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLMapElementTypeId)) => true, + _ => false + } + } +} + impl HTMLMapElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLMapElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLMapElement { HTMLMapElement { htmlelement: HTMLElement::new_inherited(HTMLMapElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLMapElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLMapElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMapElement> { + let element = HTMLMapElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLMapElementBinding::Wrap) } } @@ -37,8 +50,9 @@ impl HTMLMapElement { Ok(()) } - pub fn Areas(&self) -> @mut HTMLCollection { - let window = self.htmlelement.element.node.owner_doc().document().window; - HTMLCollection::new(window, ~[]) + pub fn Areas(&self) -> JS<HTMLCollection> { + let doc = self.htmlelement.element.node.owner_doc(); + let doc = doc.get(); + HTMLCollection::new(&doc.window, ~[]) } } diff --git a/src/components/script/dom/htmlmediaelement.rs b/src/components/script/dom/htmlmediaelement.rs index 371374c4859..d28b38085de 100644 --- a/src/components/script/dom/htmlmediaelement.rs +++ b/src/components/script/dom/htmlmediaelement.rs @@ -2,18 +2,33 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::bindings::js::JS; +use dom::bindings::codegen::InheritTypes::HTMLMediaElementDerived; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; -use dom::element::ElementTypeId; +use dom::document::Document; +use dom::element::{ElementTypeId, HTMLAudioElementTypeId, HTMLVideoElementTypeId}; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; +use dom::node::ElementNodeTypeId; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLMediaElement { htmlelement: HTMLElement, } +impl HTMLMediaElementDerived for EventTarget { + fn is_htmlmediaelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLVideoElementTypeId)) | + NodeTargetTypeId(ElementNodeTypeId(HTMLAudioElementTypeId)) => true, + _ => false + } + } +} + impl HTMLMediaElement { - pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, document: AbstractDocument) -> HTMLMediaElement { + pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, document: JS<Document>) -> HTMLMediaElement { HTMLMediaElement { htmlelement: HTMLElement::new_inherited(type_id, tag_name, document) } diff --git a/src/components/script/dom/htmlmetaelement.rs b/src/components/script/dom/htmlmetaelement.rs index 254fe4c94f4..94639c05d0e 100644 --- a/src/components/script/dom/htmlmetaelement.rs +++ b/src/components/script/dom/htmlmetaelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLMetaElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLMetaElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLMetaElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLMetaElement { htmlelement: HTMLElement, } +impl HTMLMetaElementDerived for EventTarget { + fn is_htmlmetaelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLMetaElementTypeId)) => true, + _ => false + } + } +} + impl HTMLMetaElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLMetaElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLMetaElement { HTMLMetaElement { htmlelement: HTMLElement::new_inherited(HTMLMetaElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLMetaElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLMetaElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMetaElement> { + let element = HTMLMetaElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLMetaElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlmeterelement.rs b/src/components/script/dom/htmlmeterelement.rs index 3e179fa1743..ac7e4e04736 100644 --- a/src/components/script/dom/htmlmeterelement.rs +++ b/src/components/script/dom/htmlmeterelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLMeterElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLMeterElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLMeterElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLMeterElement { htmlelement: HTMLElement } +impl HTMLMeterElementDerived for EventTarget { + fn is_htmlmeterelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLMeterElementTypeId)) => true, + _ => false + } + } +} + impl HTMLMeterElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLMeterElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLMeterElement { HTMLMeterElement { htmlelement: HTMLElement::new_inherited(HTMLMeterElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLMeterElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLMeterElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMeterElement> { + let element = HTMLMeterElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLMeterElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlmodelement.rs b/src/components/script/dom/htmlmodelement.rs index eb765ed0120..bd1b00f30f4 100644 --- a/src/components/script/dom/htmlmodelement.rs +++ b/src/components/script/dom/htmlmodelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLModElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLModElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLModElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLModElement { htmlelement: HTMLElement } +impl HTMLModElementDerived for EventTarget { + fn is_htmlmodelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLModElementTypeId)) => true, + _ => false + } + } +} + impl HTMLModElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLModElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLModElement { HTMLModElement { htmlelement: HTMLElement::new_inherited(HTMLModElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLModElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLModElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLModElement> { + let element = HTMLModElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLModElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlobjectelement.rs b/src/components/script/dom/htmlobjectelement.rs index 74f40db40dd..d373a0e6df4 100644 --- a/src/components/script/dom/htmlobjectelement.rs +++ b/src/components/script/dom/htmlobjectelement.rs @@ -3,11 +3,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLObjectElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLObjectElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLObjectElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::htmlformelement::HTMLFormElement; +use dom::node::{Node, ElementNodeTypeId}; use dom::validitystate::ValidityState; use dom::windowproxy::WindowProxy; use servo_util::str::DOMString; @@ -19,20 +23,30 @@ use servo_util::url::parse_url; use servo_util::namespace::Null; use servo_util::url::is_image_data; +#[deriving(Encodable)] pub struct HTMLObjectElement { htmlelement: HTMLElement, } +impl HTMLObjectElementDerived for EventTarget { + fn is_htmlobjectelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLObjectElementTypeId)) => true, + _ => false + } + } +} + impl HTMLObjectElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLObjectElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLObjectElement { HTMLObjectElement { htmlelement: HTMLElement::new_inherited(HTMLObjectElementTypeId, localName, document), } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLObjectElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLObjectElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLObjectElement> { + let element = HTMLObjectElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLObjectElementBinding::Wrap) } } @@ -44,8 +58,8 @@ impl HTMLObjectElement { let elem = &mut self.htmlelement.element; // TODO: support other values - match (elem.get_attribute(Null, "type").map(|x| x.Value()), - elem.get_attribute(Null, "data").map(|x| x.Value())) { + match (elem.get_attribute(Null, "type").map(|x| x.get().Value()), + elem.get_attribute(Null, "data").map(|x| x.get().Value())) { (None, Some(uri)) => { if is_image_data(uri) { let data_url = parse_url(uri, url); @@ -60,9 +74,9 @@ impl HTMLObjectElement { pub fn AfterSetAttr(&mut self, name: DOMString, _value: DOMString) { if "data" == name { let document = self.htmlelement.element.node.owner_doc(); - let window = document.document().window; - let url = window.page.url.as_ref().map(|&(ref url, _)| url.clone()); - self.process_data_url(window.image_cache_task.clone(), url); + let window = document.get().window.clone(); + let url = window.get().page.url.as_ref().map(|&(ref url, _)| url.clone()); + self.process_data_url(window.get().image_cache_task.clone(), url); } } @@ -98,7 +112,7 @@ impl HTMLObjectElement { Ok(()) } - pub fn GetForm(&self) -> Option<AbstractNode> { + pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> { None } @@ -118,11 +132,11 @@ impl HTMLObjectElement { Ok(()) } - pub fn GetContentDocument(&self) -> Option<AbstractDocument> { + pub fn GetContentDocument(&self) -> Option<JS<Document>> { None } - pub fn GetContentWindow(&self) -> Option<@mut WindowProxy> { + pub fn GetContentWindow(&self) -> Option<JS<WindowProxy>> { None } @@ -130,9 +144,10 @@ impl HTMLObjectElement { false } - pub fn Validity(&self) -> @mut ValidityState { - let global = self.htmlelement.element.node.owner_doc().document().window; - ValidityState::new(global) + pub fn Validity(&self) -> JS<ValidityState> { + let doc = self.htmlelement.element.node.owner_doc(); + let doc = doc.get(); + ValidityState::new(&doc.window) } pub fn ValidationMessage(&self) -> DOMString { @@ -226,7 +241,7 @@ impl HTMLObjectElement { Ok(()) } - pub fn GetSVGDocument(&self) -> Option<AbstractDocument> { + pub fn GetSVGDocument(&self) -> Option<JS<Document>> { None } } diff --git a/src/components/script/dom/htmlolistelement.rs b/src/components/script/dom/htmlolistelement.rs index 6a762b31147..ea677919edb 100644 --- a/src/components/script/dom/htmlolistelement.rs +++ b/src/components/script/dom/htmlolistelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLOListElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLOListElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLOListElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLOListElement { htmlelement: HTMLElement, } +impl HTMLOListElementDerived for EventTarget { + fn is_htmlolistelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLOListElementTypeId)) => true, + _ => false + } + } +} + impl HTMLOListElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLOListElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLOListElement { HTMLOListElement { htmlelement: HTMLElement::new_inherited(HTMLOListElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLOListElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLOListElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLOListElement> { + let element = HTMLOListElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLOListElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmloptgroupelement.rs b/src/components/script/dom/htmloptgroupelement.rs index 020dd3a2471..d8a3d222cb3 100644 --- a/src/components/script/dom/htmloptgroupelement.rs +++ b/src/components/script/dom/htmloptgroupelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLOptGroupElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLOptGroupElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLOptGroupElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLOptGroupElement { htmlelement: HTMLElement } +impl HTMLOptGroupElementDerived for EventTarget { + fn is_htmloptgroupelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLOptGroupElementTypeId)) => true, + _ => false + } + } +} + impl HTMLOptGroupElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLOptGroupElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLOptGroupElement { HTMLOptGroupElement { htmlelement: HTMLElement::new_inherited(HTMLOptGroupElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLOptGroupElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLOptGroupElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLOptGroupElement> { + let element = HTMLOptGroupElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLOptGroupElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmloptionelement.rs b/src/components/script/dom/htmloptionelement.rs index d1761ecdd1a..d01de54a8bc 100644 --- a/src/components/script/dom/htmloptionelement.rs +++ b/src/components/script/dom/htmloptionelement.rs @@ -3,27 +3,41 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLOptionElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLOptionElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLOptionElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::htmlformelement::HTMLFormElement; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLOptionElement { htmlelement: HTMLElement } +impl HTMLOptionElementDerived for EventTarget { + fn is_htmloptionelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLOptionElementTypeId)) => true, + _ => false + } + } +} + impl HTMLOptionElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLOptionElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLOptionElement { HTMLOptionElement { htmlelement: HTMLElement::new_inherited(HTMLOptionElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLOptionElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLOptionElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLOptionElement> { + let element = HTMLOptionElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLOptionElementBinding::Wrap) } } @@ -36,7 +50,7 @@ impl HTMLOptionElement { Ok(()) } - pub fn GetForm(&self) -> Option<AbstractNode> { + pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> { None } diff --git a/src/components/script/dom/htmloutputelement.rs b/src/components/script/dom/htmloutputelement.rs index 174e9258ecf..95c03763c3c 100644 --- a/src/components/script/dom/htmloutputelement.rs +++ b/src/components/script/dom/htmloutputelement.rs @@ -3,33 +3,47 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLOutputElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLOutputElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLOutputElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::htmlformelement::HTMLFormElement; +use dom::node::{Node, ElementNodeTypeId}; use dom::validitystate::ValidityState; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLOutputElement { htmlelement: HTMLElement } +impl HTMLOutputElementDerived for EventTarget { + fn is_htmloutputelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLOutputElementTypeId)) => true, + _ => false + } + } +} + impl HTMLOutputElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLOutputElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLOutputElement { HTMLOutputElement { htmlelement: HTMLElement::new_inherited(HTMLOutputElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLOutputElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLOutputElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLOutputElement> { + let element = HTMLOutputElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLOutputElementBinding::Wrap) } } impl HTMLOutputElement { - pub fn GetForm(&self) -> Option<AbstractNode> { + pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> { None } @@ -68,12 +82,13 @@ impl HTMLOutputElement { pub fn SetWillValidate(&mut self, _will_validate: bool) { } - pub fn Validity(&self) -> @mut ValidityState { - let global = self.htmlelement.element.node.owner_doc().document().window; - ValidityState::new(global) + pub fn Validity(&self) -> JS<ValidityState> { + let doc = self.htmlelement.element.node.owner_doc(); + let doc = doc.get(); + ValidityState::new(&doc.window) } - pub fn SetValidity(&mut self, _validity: @mut ValidityState) { + pub fn SetValidity(&mut self, _validity: JS<ValidityState>) { } pub fn ValidationMessage(&self) -> DOMString { diff --git a/src/components/script/dom/htmlparagraphelement.rs b/src/components/script/dom/htmlparagraphelement.rs index 1132a496f26..a1aef4a7f5d 100644 --- a/src/components/script/dom/htmlparagraphelement.rs +++ b/src/components/script/dom/htmlparagraphelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLParagraphElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLParagraphElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLParagraphElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLParagraphElement { htmlelement: HTMLElement } +impl HTMLParagraphElementDerived for EventTarget { + fn is_htmlparagraphelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLParagraphElementTypeId)) => true, + _ => false + } + } +} + impl HTMLParagraphElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLParagraphElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLParagraphElement { HTMLParagraphElement { htmlelement: HTMLElement::new_inherited(HTMLParagraphElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLParagraphElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLParagraphElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLParagraphElement> { + let element = HTMLParagraphElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLParagraphElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlparamelement.rs b/src/components/script/dom/htmlparamelement.rs index 3cd242e0016..1e3e7785c0d 100644 --- a/src/components/script/dom/htmlparamelement.rs +++ b/src/components/script/dom/htmlparamelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLParamElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLParamElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLParamElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLParamElement { htmlelement: HTMLElement } +impl HTMLParamElementDerived for EventTarget { + fn is_htmlparamelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLParamElementTypeId)) => true, + _ => false + } + } +} + impl HTMLParamElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLParamElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLParamElement { HTMLParamElement { htmlelement: HTMLElement::new_inherited(HTMLParamElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLParamElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLParamElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLParamElement> { + let element = HTMLParamElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLParamElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlpreelement.rs b/src/components/script/dom/htmlpreelement.rs index c2bf04464f3..33f5b1a7247 100644 --- a/src/components/script/dom/htmlpreelement.rs +++ b/src/components/script/dom/htmlpreelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLPreElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLPreElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::{ErrorResult}; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLPreElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLPreElement { htmlelement: HTMLElement, } +impl HTMLPreElementDerived for EventTarget { + fn is_htmlpreelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLPreElementTypeId)) => true, + _ => false + } + } +} + impl HTMLPreElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLPreElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLPreElement { HTMLPreElement { htmlelement: HTMLElement::new_inherited(HTMLPreElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLPreElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLPreElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLPreElement> { + let element = HTMLPreElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLPreElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlprogresselement.rs b/src/components/script/dom/htmlprogresselement.rs index dca693fa9d3..ee6b3bff48b 100644 --- a/src/components/script/dom/htmlprogresselement.rs +++ b/src/components/script/dom/htmlprogresselement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLProgressElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLProgressElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::{ErrorResult, Fallible}; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLProgressElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLProgressElement { htmlelement: HTMLElement, } +impl HTMLProgressElementDerived for EventTarget { + fn is_htmlprogresselement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLProgressElementTypeId)) => true, + _ => false + } + } +} + impl HTMLProgressElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLProgressElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLProgressElement { HTMLProgressElement { htmlelement: HTMLElement::new_inherited(HTMLProgressElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLProgressElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLProgressElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLProgressElement> { + let element = HTMLProgressElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLProgressElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlquoteelement.rs b/src/components/script/dom/htmlquoteelement.rs index 3ad246f16c2..9fc115dcf9c 100644 --- a/src/components/script/dom/htmlquoteelement.rs +++ b/src/components/script/dom/htmlquoteelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLQuoteElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLQuoteElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLQuoteElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLQuoteElement { htmlelement: HTMLElement, } +impl HTMLQuoteElementDerived for EventTarget { + fn is_htmlquoteelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLQuoteElementTypeId)) => true, + _ => false + } + } +} + impl HTMLQuoteElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLQuoteElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLQuoteElement { HTMLQuoteElement { htmlelement: HTMLElement::new_inherited(HTMLQuoteElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLQuoteElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLQuoteElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLQuoteElement> { + let element = HTMLQuoteElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLQuoteElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlscriptelement.rs b/src/components/script/dom/htmlscriptelement.rs index 80513d5f649..191d588585b 100644 --- a/src/components/script/dom/htmlscriptelement.rs +++ b/src/components/script/dom/htmlscriptelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLScriptElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLScriptElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLScriptElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLScriptElement { htmlelement: HTMLElement, } +impl HTMLScriptElementDerived for EventTarget { + fn is_htmlscriptelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLScriptElementTypeId)) => true, + _ => false + } + } +} + impl HTMLScriptElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLScriptElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLScriptElement { HTMLScriptElement { htmlelement: HTMLElement::new_inherited(HTMLScriptElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLScriptElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLScriptElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLScriptElement> { + let element = HTMLScriptElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLScriptElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlselectelement.rs b/src/components/script/dom/htmlselectelement.rs index 61fb132dfe2..92925b4ce7c 100644 --- a/src/components/script/dom/htmlselectelement.rs +++ b/src/components/script/dom/htmlselectelement.rs @@ -3,28 +3,43 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLSelectElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLSelectElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; -use dom::element::HTMLSelectElementTypeId; +use dom::document::Document; +use dom::element::{Element, HTMLSelectElementTypeId}; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::htmlformelement::HTMLFormElement; +use dom::node::{Node, ElementNodeTypeId}; +use dom::htmloptionelement::HTMLOptionElement; use dom::validitystate::ValidityState; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLSelectElement { htmlelement: HTMLElement } +impl HTMLSelectElementDerived for EventTarget { + fn is_htmlselectelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLSelectElementTypeId)) => true, + _ => false + } + } +} + impl HTMLSelectElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLSelectElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLSelectElement { HTMLSelectElement { htmlelement: HTMLElement::new_inherited(HTMLSelectElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLSelectElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLSelectElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLSelectElement> { + let element = HTMLSelectElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLSelectElementBinding::Wrap) } } @@ -45,7 +60,7 @@ impl HTMLSelectElement { Ok(()) } - pub fn GetForm(&self) -> Option<AbstractNode> { + pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> { None } @@ -93,19 +108,19 @@ impl HTMLSelectElement { Ok(()) } - pub fn Item(&self, _index: u32) -> Option<AbstractNode> { + pub fn Item(&self, _index: u32) -> Option<JS<Element>> { None } - pub fn NamedItem(&self, _name: DOMString) -> Option<AbstractNode> { + pub fn NamedItem(&self, _name: DOMString) -> Option<JS<HTMLOptionElement>> { None } - pub fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<AbstractNode> { + pub fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<JS<Element>> { None } - pub fn IndexedSetter(&mut self, _index: u32, _option: Option<AbstractNode>) -> ErrorResult { + pub fn IndexedSetter(&mut self, _index: u32, _option: Option<JS<HTMLOptionElement>>) -> ErrorResult { Ok(()) } @@ -137,12 +152,13 @@ impl HTMLSelectElement { pub fn SetWillValidate(&mut self, _will_validate: bool) { } - pub fn Validity(&self) -> @mut ValidityState { - let global = self.htmlelement.element.node.owner_doc().document().window; - ValidityState::new(global) + pub fn Validity(&self) -> JS<ValidityState> { + let doc = self.htmlelement.element.node.owner_doc(); + let doc = doc.get(); + ValidityState::new(&doc.window) } - pub fn SetValidity(&mut self, _validity: @mut ValidityState) { + pub fn SetValidity(&mut self, _validity: JS<ValidityState>) { } pub fn ValidationMessage(&self) -> DOMString { diff --git a/src/components/script/dom/htmlserializer.rs b/src/components/script/dom/htmlserializer.rs index 97198b0ab79..17e1b099b41 100644 --- a/src/components/script/dom/htmlserializer.rs +++ b/src/components/script/dom/htmlserializer.rs @@ -4,10 +4,20 @@ use servo_util::namespace; use dom::attr::Attr; +use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, CommentCast}; +use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, CharacterDataCast}; +use dom::bindings::codegen::InheritTypes::ProcessingInstructionCast; +use dom::bindings::js::JS; +use dom::characterdata::CharacterData; +use dom::comment::Comment; +use dom::documenttype::DocumentType; +use dom::element::Element; use dom::node::NodeIterator; use dom::node::{DoctypeNodeTypeId, DocumentFragmentNodeTypeId, CommentNodeTypeId}; use dom::node::{DocumentNodeTypeId, ElementNodeTypeId, ProcessingInstructionNodeTypeId}; -use dom::node::{TextNodeTypeId, AbstractNode}; +use dom::node::{TextNodeTypeId, NodeHelpers}; +use dom::processinginstruction::ProcessingInstruction; +use dom::text::Text; pub fn serialize(iterator: &mut NodeIterator) -> ~str { let mut html = ~""; @@ -20,19 +30,24 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str { html.push_str( match node.type_id() { ElementNodeTypeId(..) => { - serialize_elem(node, &mut open_elements) + let elem: JS<Element> = ElementCast::to(&node); + serialize_elem(&elem, &mut open_elements) } CommentNodeTypeId => { - serialize_comment(node) + let comment: JS<Comment> = CommentCast::to(&node); + serialize_comment(&comment) } TextNodeTypeId => { - serialize_text(node) + let text: JS<Text> = TextCast::to(&node); + serialize_text(&text) } DoctypeNodeTypeId => { - serialize_doctype(node) + let doctype: JS<DocumentType> = DocumentTypeCast::to(&node); + serialize_doctype(&doctype) } ProcessingInstructionNodeTypeId => { - serialize_processing_instruction(node) + let processing_instruction: JS<ProcessingInstruction> = ProcessingInstructionCast::to(&node); + serialize_processing_instruction(&processing_instruction) } DocumentFragmentNodeTypeId => { ~"" @@ -41,7 +56,7 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str { fail!("It shouldn't be possible to serialize a document node") } } - ); + ); } while open_elements.len() > 0 { html.push_str(~"</" + open_elements.pop() + ">"); @@ -49,88 +64,75 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str { html } -fn serialize_comment(node: AbstractNode) -> ~str { - node.with_imm_characterdata(|comment| { - ~"<!--" + comment.data + "-->" - }) +fn serialize_comment(comment: &JS<Comment>) -> ~str { + ~"<!--" + comment.get().characterdata.data + "-->" } -fn serialize_text(node: AbstractNode) -> ~str { - node.with_imm_characterdata(|text| { - match node.parent_node() { - Some(parent) if parent.is_element() => { - parent.with_imm_element(|elem| { - match elem.tag_name.as_slice() { - "style" | "script" | "xmp" | "iframe" | - "noembed" | "noframes" | "plaintext" | - "noscript" if elem.namespace == namespace::HTML => { - text.data.clone() - }, - _ => escape(text.data, false) - } - }) - }, - _ => escape(text.data, false) +fn serialize_text(text: &JS<Text>) -> ~str { + match text.get().characterdata.node.parent_node { + Some(ref parent) if parent.is_element() => { + let elem: JS<Element> = ElementCast::to(parent); + match elem.get().tag_name.as_slice() { + "style" | "script" | "xmp" | "iframe" | + "noembed" | "noframes" | "plaintext" | + "noscript" if elem.get().namespace == namespace::HTML => { + text.get().characterdata.data.clone() + }, + _ => escape(text.get().characterdata.data, false) + } } - }) + _ => escape(text.get().characterdata.data, false) + } } -fn serialize_processing_instruction(node: AbstractNode) -> ~str { - node.with_imm_processing_instruction(|processing_instruction| { - ~"<?" + processing_instruction.target + " " + processing_instruction.characterdata.data + "?>" - }) +fn serialize_processing_instruction(processing_instruction: &JS<ProcessingInstruction>) -> ~str { + ~"<?" + processing_instruction.get().target + " " + processing_instruction.get().characterdata.data + "?>" } -fn serialize_doctype(node: AbstractNode) -> ~str { - node.with_imm_doctype(|doctype| { - ~"<!DOCTYPE" + doctype.name + ">" - }) +fn serialize_doctype(doctype: &JS<DocumentType>) -> ~str { + ~"<!DOCTYPE" + doctype.get().name + ">" } -fn serialize_elem(node: AbstractNode, open_elements: &mut ~[~str]) -> ~str { - node.with_imm_element(|elem| { - let mut rv = ~"<" + elem.tag_name; - for attr in elem.attrs.iter() { - rv.push_str(serialize_attr(attr)); - }; - rv.push_str(">"); - match elem.tag_name.as_slice() { - "pre" | "listing" | "textarea" if - elem.namespace == namespace::HTML => { - match node.first_child() { - Some(child) if child.is_text() => { - child.with_imm_characterdata(|text| { - if text.data[0] == 0x0A as u8 { - rv.push_str("\x0A"); - } - }) - }, - _ => {} +fn serialize_elem(elem: &JS<Element>, open_elements: &mut ~[~str]) -> ~str { + let mut rv = ~"<" + elem.get().tag_name; + for attr in elem.get().attrs.iter() { + rv.push_str(serialize_attr(attr)); + }; + rv.push_str(">"); + match elem.get().tag_name.as_slice() { + "pre" | "listing" | "textarea" if elem.get().namespace == namespace::HTML => { + match elem.get().node.first_child { + Some(ref child) if child.is_text() => { + let text: JS<CharacterData> = CharacterDataCast::to(child); + if text.get().data[0] == 0x0A as u8 { + rv.push_str("\x0A"); } - }, - _ => {} - } - if !elem.is_void() { - open_elements.push(elem.tag_name.clone()); - } - rv - }) + }, + _ => {} + } + }, + _ => {} + } + if !elem.get().is_void() { + open_elements.push(elem.get().tag_name.clone()); + } + rv } -fn serialize_attr(attr: &@mut Attr) -> ~str { - let attr_name = if attr.namespace == namespace::XML { - ~"xml:" + attr.local_name.clone() - } else if attr.namespace == namespace::XMLNS && - attr.local_name.as_slice() == "xmlns" { +fn serialize_attr(attr: &JS<Attr>) -> ~str { + let attr_name = if attr.get().namespace == namespace::XML { + ~"xml:" + attr.get().local_name.clone() + } else if attr.get().namespace == namespace::XMLNS && + attr.get().local_name.as_slice() == "xmlns" { ~"xmlns" - } else if attr.namespace == namespace::XMLNS { - ~"xmlns:" + attr.local_name.clone() - } else if attr.namespace == namespace::XLink { - ~"xlink:" + attr.local_name.clone() + } else if attr.get().namespace == namespace::XMLNS { + ~"xmlns:" + attr.get().local_name.clone() + } else if attr.get().namespace == namespace::XLink { + ~"xlink:" + attr.get().local_name.clone() } else { - attr.name.clone() + attr.get().name.clone() }; - ~" " + attr_name + "=\"" + escape(attr.value, true) + "\"" + ~" " + attr_name + "=\"" + escape(attr.get().value, true) + "\"" } fn escape(string: &str, attr_mode: bool) -> ~str { diff --git a/src/components/script/dom/htmlsourceelement.rs b/src/components/script/dom/htmlsourceelement.rs index 212ddd77850..c5c7beaec13 100644 --- a/src/components/script/dom/htmlsourceelement.rs +++ b/src/components/script/dom/htmlsourceelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLSourceElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLSourceElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLSourceElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLSourceElement { htmlelement: HTMLElement } +impl HTMLSourceElementDerived for EventTarget { + fn is_htmlsourceelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLSourceElementTypeId)) => true, + _ => false + } + } +} + impl HTMLSourceElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLSourceElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLSourceElement { HTMLSourceElement { htmlelement: HTMLElement::new_inherited(HTMLSourceElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLSourceElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLSourceElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLSourceElement> { + let element = HTMLSourceElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLSourceElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlspanelement.rs b/src/components/script/dom/htmlspanelement.rs index 47a47f3a17e..8b827bbf234 100644 --- a/src/components/script/dom/htmlspanelement.rs +++ b/src/components/script/dom/htmlspanelement.rs @@ -3,25 +3,38 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLSpanElementBinding; -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::HTMLSpanElementDerived; +use dom::bindings::js::JS; +use dom::document::Document; use dom::element::HTMLSpanElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLSpanElement { htmlelement: HTMLElement } +impl HTMLSpanElementDerived for EventTarget { + fn is_htmlspanelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLSpanElementTypeId)) => true, + _ => false + } + } +} + impl HTMLSpanElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLSpanElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLSpanElement { HTMLSpanElement { htmlelement: HTMLElement::new_inherited(HTMLSpanElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLSpanElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLSpanElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLSpanElement> { + let element = HTMLSpanElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLSpanElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlstyleelement.rs b/src/components/script/dom/htmlstyleelement.rs index 4a39f6bcf39..bc12ca5a291 100644 --- a/src/components/script/dom/htmlstyleelement.rs +++ b/src/components/script/dom/htmlstyleelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLStyleElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLStyleElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLStyleElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLStyleElement { htmlelement: HTMLElement, } +impl HTMLStyleElementDerived for EventTarget { + fn is_htmlstyleelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLStyleElementTypeId)) => true, + _ => false + } + } +} + impl HTMLStyleElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLStyleElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLStyleElement { HTMLStyleElement { htmlelement: HTMLElement::new_inherited(HTMLStyleElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLStyleElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLStyleElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLStyleElement> { + let element = HTMLStyleElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLStyleElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmltablecaptionelement.rs b/src/components/script/dom/htmltablecaptionelement.rs index 94d5faf5ffc..0599e2624bf 100644 --- a/src/components/script/dom/htmltablecaptionelement.rs +++ b/src/components/script/dom/htmltablecaptionelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLTableCaptionElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLTableCaptionElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLTableCaptionElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLTableCaptionElement { htmlelement: HTMLElement } +impl HTMLTableCaptionElementDerived for EventTarget { + fn is_htmltablecaptionelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLTableCaptionElementTypeId)) => true, + _ => false + } + } +} + impl HTMLTableCaptionElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLTableCaptionElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTableCaptionElement { HTMLTableCaptionElement { htmlelement: HTMLElement::new_inherited(HTMLTableCaptionElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLTableCaptionElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLTableCaptionElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableCaptionElement> { + let element = HTMLTableCaptionElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLTableCaptionElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmltablecellelement.rs b/src/components/script/dom/htmltablecellelement.rs index ddca4692373..04c745affd4 100644 --- a/src/components/script/dom/htmltablecellelement.rs +++ b/src/components/script/dom/htmltablecellelement.rs @@ -2,18 +2,33 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::bindings::codegen::InheritTypes::HTMLTableCellElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; -use dom::element::ElementTypeId; +use dom::document::Document; +use dom::element::{ElementTypeId, HTMLTableDataCellElementTypeId, HTMLTableHeaderCellElementTypeId}; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; +use dom::node::ElementNodeTypeId; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLTableCellElement { htmlelement: HTMLElement, } +impl HTMLTableCellElementDerived for EventTarget { + fn is_htmltablecellelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLTableDataCellElementTypeId)) | + NodeTargetTypeId(ElementNodeTypeId(HTMLTableHeaderCellElementTypeId)) => true, + _ => false + } + } +} + impl HTMLTableCellElement { - pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, document: AbstractDocument) -> HTMLTableCellElement { + pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, document: JS<Document>) -> HTMLTableCellElement { HTMLTableCellElement { htmlelement: HTMLElement::new_inherited(type_id, tag_name, document) } diff --git a/src/components/script/dom/htmltablecolelement.rs b/src/components/script/dom/htmltablecolelement.rs index 577718f5535..8fbdb208124 100644 --- a/src/components/script/dom/htmltablecolelement.rs +++ b/src/components/script/dom/htmltablecolelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLTableColElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLTableColElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLTableColElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLTableColElement { htmlelement: HTMLElement, } +impl HTMLTableColElementDerived for EventTarget { + fn is_htmltablecolelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLTableColElementTypeId)) => true, + _ => false + } + } +} + impl HTMLTableColElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLTableColElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTableColElement { HTMLTableColElement { htmlelement: HTMLElement::new_inherited(HTMLTableColElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLTableColElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLTableColElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableColElement> { + let element = HTMLTableColElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLTableColElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmltabledatacellelement.rs b/src/components/script/dom/htmltabledatacellelement.rs index edcfaae6053..f245f209513 100644 --- a/src/components/script/dom/htmltabledatacellelement.rs +++ b/src/components/script/dom/htmltabledatacellelement.rs @@ -3,25 +3,38 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLTableDataCellElementBinding; -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::HTMLTableDataCellElementDerived; +use dom::bindings::js::JS; +use dom::document::Document; use dom::element::HTMLTableDataCellElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmltablecellelement::HTMLTableCellElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLTableDataCellElement { htmltablecellelement: HTMLTableCellElement, } +impl HTMLTableDataCellElementDerived for EventTarget { + fn is_htmltabledatacellelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLTableDataCellElementTypeId)) => true, + _ => false + } + } +} + impl HTMLTableDataCellElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLTableDataCellElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTableDataCellElement { HTMLTableDataCellElement { htmltablecellelement: HTMLTableCellElement::new_inherited(HTMLTableDataCellElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLTableDataCellElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLTableDataCellElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableDataCellElement> { + let element = HTMLTableDataCellElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLTableDataCellElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmltableelement.rs b/src/components/script/dom/htmltableelement.rs index bf46faa3bcc..4ebd2cc4c97 100644 --- a/src/components/script/dom/htmltableelement.rs +++ b/src/components/script/dom/htmltableelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLTableElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLTableElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLTableElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLTableElement { htmlelement: HTMLElement, } +impl HTMLTableElementDerived for EventTarget { + fn is_htmltableelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLTableElementTypeId)) => true, + _ => false + } + } +} + impl HTMLTableElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLTableElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTableElement { HTMLTableElement { htmlelement: HTMLElement::new_inherited(HTMLTableElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLTableElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLTableElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableElement> { + let element = HTMLTableElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLTableElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmltableheadercellelement.rs b/src/components/script/dom/htmltableheadercellelement.rs index ed9475f3683..66b94da6b4c 100644 --- a/src/components/script/dom/htmltableheadercellelement.rs +++ b/src/components/script/dom/htmltableheadercellelement.rs @@ -3,25 +3,38 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLTableHeaderCellElementBinding; -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::HTMLTableHeaderCellElementDerived; +use dom::bindings::js::JS; +use dom::document::Document; use dom::element::HTMLTableHeaderCellElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmltablecellelement::HTMLTableCellElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLTableHeaderCellElement { htmltablecellelement: HTMLTableCellElement, } +impl HTMLTableHeaderCellElementDerived for EventTarget { + fn is_htmltableheadercellelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLTableHeaderCellElementTypeId)) => true, + _ => false + } + } +} + impl HTMLTableHeaderCellElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLTableHeaderCellElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTableHeaderCellElement { HTMLTableHeaderCellElement { htmltablecellelement: HTMLTableCellElement::new_inherited(HTMLTableHeaderCellElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLTableHeaderCellElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLTableHeaderCellElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableHeaderCellElement> { + let element = HTMLTableHeaderCellElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLTableHeaderCellElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmltablerowelement.rs b/src/components/script/dom/htmltablerowelement.rs index 53c5eaaa0b3..22ae9fa7071 100644 --- a/src/components/script/dom/htmltablerowelement.rs +++ b/src/components/script/dom/htmltablerowelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLTableRowElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLTableRowElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLTableRowElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLTableRowElement { htmlelement: HTMLElement, } +impl HTMLTableRowElementDerived for EventTarget { + fn is_htmltablerowelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLTableRowElementTypeId)) => true, + _ => false + } + } +} + impl HTMLTableRowElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLTableRowElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTableRowElement { HTMLTableRowElement { htmlelement: HTMLElement::new_inherited(HTMLTableRowElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLTableRowElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLTableRowElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableRowElement> { + let element = HTMLTableRowElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLTableRowElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmltablesectionelement.rs b/src/components/script/dom/htmltablesectionelement.rs index 7a3270197cb..f718e67586a 100644 --- a/src/components/script/dom/htmltablesectionelement.rs +++ b/src/components/script/dom/htmltablesectionelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLTableSectionElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLTableSectionElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLTableSectionElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLTableSectionElement { htmlelement: HTMLElement, } +impl HTMLTableSectionElementDerived for EventTarget { + fn is_htmltablesectionelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLTableSectionElementTypeId)) => true, + _ => false + } + } +} + impl HTMLTableSectionElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLTableSectionElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTableSectionElement { HTMLTableSectionElement { htmlelement: HTMLElement::new_inherited(HTMLTableSectionElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLTableSectionElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLTableSectionElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableSectionElement> { + let element = HTMLTableSectionElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLTableSectionElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmltemplateelement.rs b/src/components/script/dom/htmltemplateelement.rs index 1bfe4f0b236..ffb7cd7e771 100644 --- a/src/components/script/dom/htmltemplateelement.rs +++ b/src/components/script/dom/htmltemplateelement.rs @@ -3,25 +3,38 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLTemplateElementBinding; -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::HTMLTemplateElementDerived; +use dom::bindings::js::JS; +use dom::document::Document; use dom::element::HTMLTemplateElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLTemplateElement { htmlelement: HTMLElement, } +impl HTMLTemplateElementDerived for EventTarget { + fn is_htmltemplateelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLTemplateElementTypeId)) => true, + _ => false + } + } +} + impl HTMLTemplateElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLTemplateElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTemplateElement { HTMLTemplateElement { htmlelement: HTMLElement::new_inherited(HTMLTemplateElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLTemplateElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLTemplateElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTemplateElement> { + let element = HTMLTemplateElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLTemplateElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmltextareaelement.rs b/src/components/script/dom/htmltextareaelement.rs index 43da53af73b..b34dc05c3e3 100644 --- a/src/components/script/dom/htmltextareaelement.rs +++ b/src/components/script/dom/htmltextareaelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLTextAreaElementBinding; -use dom::bindings::utils::{Fallible, ErrorResult}; -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::HTMLTextAreaElementDerived; +use dom::bindings::js::JS; +use dom::bindings::utils::{ErrorResult, Fallible}; +use dom::document::Document; use dom::element::HTMLTextAreaElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLTextAreaElement { htmlelement: HTMLElement, } +impl HTMLTextAreaElementDerived for EventTarget { + fn is_htmltextareaelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLTextAreaElementTypeId)) => true, + _ => false + } + } +} + impl HTMLTextAreaElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLTextAreaElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTextAreaElement { HTMLTextAreaElement { htmlelement: HTMLElement::new_inherited(HTMLTextAreaElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLTextAreaElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLTextAreaElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTextAreaElement> { + let element = HTMLTextAreaElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLTextAreaElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmltimeelement.rs b/src/components/script/dom/htmltimeelement.rs index 23c48c71f70..baddd3bd908 100644 --- a/src/components/script/dom/htmltimeelement.rs +++ b/src/components/script/dom/htmltimeelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLTimeElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLTimeElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLTimeElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLTimeElement { htmlelement: HTMLElement } +impl HTMLTimeElementDerived for EventTarget { + fn is_htmltimeelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLTimeElementTypeId)) => true, + _ => false + } + } +} + impl HTMLTimeElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLTimeElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTimeElement { HTMLTimeElement { htmlelement: HTMLElement::new_inherited(HTMLTimeElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLTimeElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLTimeElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTimeElement> { + let element = HTMLTimeElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLTimeElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmltitleelement.rs b/src/components/script/dom/htmltitleelement.rs index b6466637181..61eebf793a5 100644 --- a/src/components/script/dom/htmltitleelement.rs +++ b/src/components/script/dom/htmltitleelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLTitleElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLTitleElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLTitleElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLTitleElement { htmlelement: HTMLElement, } +impl HTMLTitleElementDerived for EventTarget { + fn is_htmltitleelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLTitleElementTypeId)) => true, + _ => false + } + } +} + impl HTMLTitleElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLTitleElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTitleElement { HTMLTitleElement { htmlelement: HTMLElement::new_inherited(HTMLTitleElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLTitleElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLTitleElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTitleElement> { + let element = HTMLTitleElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLTitleElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmltrackelement.rs b/src/components/script/dom/htmltrackelement.rs index bf081d44918..24fcb38dd12 100644 --- a/src/components/script/dom/htmltrackelement.rs +++ b/src/components/script/dom/htmltrackelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLTrackElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLTrackElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLTrackElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLTrackElement { htmlelement: HTMLElement, } +impl HTMLTrackElementDerived for EventTarget { + fn is_htmltrackelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLTrackElementTypeId)) => true, + _ => false + } + } +} + impl HTMLTrackElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLTrackElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLTrackElement { HTMLTrackElement { htmlelement: HTMLElement::new_inherited(HTMLTrackElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLTrackElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLTrackElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTrackElement> { + let element = HTMLTrackElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLTrackElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlulistelement.rs b/src/components/script/dom/htmlulistelement.rs index 812144edf57..3533632b8a2 100644 --- a/src/components/script/dom/htmlulistelement.rs +++ b/src/components/script/dom/htmlulistelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLUListElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLUListElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLUListElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLUListElement { htmlelement: HTMLElement } +impl HTMLUListElementDerived for EventTarget { + fn is_htmlulistelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLUListElementTypeId)) => true, + _ => false + } + } +} + impl HTMLUListElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLUListElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLUListElement { HTMLUListElement { htmlelement: HTMLElement::new_inherited(HTMLUListElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLUListElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLUListElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLUListElement> { + let element = HTMLUListElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLUListElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlunknownelement.rs b/src/components/script/dom/htmlunknownelement.rs index 67aa56bc47c..3c353acdb25 100644 --- a/src/components/script/dom/htmlunknownelement.rs +++ b/src/components/script/dom/htmlunknownelement.rs @@ -3,25 +3,38 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLUnknownElementBinding; -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::HTMLUnknownElementDerived; +use dom::bindings::js::JS; +use dom::document::Document; use dom::element::HTMLUnknownElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLUnknownElement { htmlelement: HTMLElement } +impl HTMLUnknownElementDerived for EventTarget { + fn is_htmlunknownelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLUnknownElementTypeId)) => true, + _ => false + } + } +} + impl HTMLUnknownElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLUnknownElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLUnknownElement { HTMLUnknownElement { htmlelement: HTMLElement::new_inherited(HTMLUnknownElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLUnknownElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLUnknownElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLUnknownElement> { + let element = HTMLUnknownElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLUnknownElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlvideoelement.rs b/src/components/script/dom/htmlvideoelement.rs index c3c1ac9a9b4..437e3f8bfc1 100644 --- a/src/components/script/dom/htmlvideoelement.rs +++ b/src/components/script/dom/htmlvideoelement.rs @@ -3,27 +3,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLVideoElementBinding; +use dom::bindings::codegen::InheritTypes::HTMLVideoElementDerived; +use dom::bindings::js::JS; use dom::bindings::utils::ErrorResult; -use dom::document::AbstractDocument; +use dom::document::Document; use dom::element::HTMLVideoElementTypeId; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlmediaelement::HTMLMediaElement; -use dom::node::{AbstractNode, Node}; +use dom::node::{Node, ElementNodeTypeId}; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct HTMLVideoElement { htmlmediaelement: HTMLMediaElement } +impl HTMLVideoElementDerived for EventTarget { + fn is_htmlvideoelement(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ElementNodeTypeId(HTMLVideoElementTypeId)) => true, + _ => false + } + } +} + impl HTMLVideoElement { - pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLVideoElement { + pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLVideoElement { HTMLVideoElement { htmlmediaelement: HTMLMediaElement::new_inherited(HTMLVideoElementTypeId, localName, document) } } - pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { - let element = HTMLVideoElement::new_inherited(localName, document); - Node::reflect_node(@mut element, document, HTMLVideoElementBinding::Wrap) + pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLVideoElement> { + let element = HTMLVideoElement::new_inherited(localName, document.clone()); + Node::reflect_node(~element, document, HTMLVideoElementBinding::Wrap) } } diff --git a/src/components/script/dom/location.rs b/src/components/script/dom/location.rs index b59248346e5..442373fea90 100644 --- a/src/components/script/dom/location.rs +++ b/src/components/script/dom/location.rs @@ -2,17 +2,19 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::bindings::codegen::LocationBinding; +use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::Fallible; -use dom::bindings::codegen::LocationBinding; use dom::window::Window; use servo_util::str::DOMString; use script_task::{Page}; +#[deriving(Encodable)] pub struct Location { reflector_: Reflector, //XXXjdm cycle: window->Location->window - page: @mut Page + page: @mut Page, } impl Location { @@ -23,8 +25,10 @@ impl Location { } } - pub fn new(window: &Window, page: @mut Page) -> @mut Location { - reflect_dom_object(@mut Location::new_inherited(page), window, LocationBinding::Wrap) + pub fn new(window: &Window, page: @mut Page) -> JS<Location> { + reflect_dom_object(~Location::new_inherited(page), + window, + LocationBinding::Wrap) } pub fn Assign(&self, _url: DOMString) { diff --git a/src/components/script/dom/mouseevent.rs b/src/components/script/dom/mouseevent.rs index c61c5c1aee0..7f840877b30 100644 --- a/src/components/script/dom/mouseevent.rs +++ b/src/components/script/dom/mouseevent.rs @@ -3,17 +3,20 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::MouseEventBinding; +use dom::bindings::codegen::InheritTypes::MouseEventDerived; +use dom::bindings::js::JS; use dom::bindings::utils::{ErrorResult, Fallible}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; -use dom::event::{AbstractEvent, Event, MouseEventTypeId}; -use dom::eventtarget::AbstractEventTarget; +use dom::event::{Event, MouseEventTypeId}; +use dom::eventtarget::EventTarget; use dom::uievent::UIEvent; use dom::window::Window; use dom::windowproxy::WindowProxy; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct MouseEvent { - parent: UIEvent, + mouseevent: UIEvent, screen_x: i32, screen_y: i32, client_x: i32, @@ -23,13 +26,19 @@ pub struct MouseEvent { alt_key: bool, meta_key: bool, button: u16, - related_target: Option<AbstractEventTarget> + related_target: Option<JS<EventTarget>> +} + +impl MouseEventDerived for Event { + fn is_mouseevent(&self) -> bool { + self.type_id == MouseEventTypeId + } } impl MouseEvent { pub fn new_inherited() -> MouseEvent { MouseEvent { - parent: UIEvent::new_inherited(MouseEventTypeId), + mouseevent: UIEvent::new_inherited(MouseEventTypeId), screen_x: 0, screen_y: 0, client_x: 0, @@ -43,21 +52,21 @@ impl MouseEvent { } } - pub fn new(window: @mut Window) -> AbstractEvent { - Event::as_abstract(reflect_dom_object(@mut MouseEvent::new_inherited(), - window, - MouseEventBinding::Wrap)) + pub fn new(window: &JS<Window>) -> JS<MouseEvent> { + reflect_dom_object(~MouseEvent::new_inherited(), + window.get(), + MouseEventBinding::Wrap) } - pub fn Constructor(owner: @mut Window, + pub fn Constructor(owner: &JS<Window>, type_: DOMString, - init: &MouseEventBinding::MouseEventInit) -> Fallible<AbstractEvent> { - let ev = MouseEvent::new(owner); - ev.mut_mouseevent().InitMouseEvent(type_, init.bubbles, init.cancelable, init.view, - init.detail, init.screenX, init.screenY, - init.clientX, init.clientY, init.ctrlKey, - init.altKey, init.shiftKey, init.metaKey, - init.button, init.relatedTarget); + init: &MouseEventBinding::MouseEventInit) -> Fallible<JS<MouseEvent>> { + let mut ev = MouseEvent::new(owner); + ev.get_mut().InitMouseEvent(type_, init.bubbles, init.cancelable, init.view.clone(), + init.detail, init.screenX, init.screenY, + init.clientX, init.clientY, init.ctrlKey, + init.altKey, init.shiftKey, init.metaKey, + init.button, init.relatedTarget.clone()); Ok(ev) } @@ -102,8 +111,8 @@ impl MouseEvent { 0 } - pub fn GetRelatedTarget(&self) -> Option<AbstractEventTarget> { - self.related_target + pub fn GetRelatedTarget(&self) -> Option<JS<EventTarget>> { + self.related_target.clone() } pub fn GetModifierState(&self, _keyArg: DOMString) -> bool { @@ -115,7 +124,7 @@ impl MouseEvent { typeArg: DOMString, canBubbleArg: bool, cancelableArg: bool, - viewArg: Option<@mut WindowProxy>, + viewArg: Option<JS<WindowProxy>>, detailArg: i32, screenXArg: i32, screenYArg: i32, @@ -126,8 +135,8 @@ impl MouseEvent { shiftKeyArg: bool, metaKeyArg: bool, buttonArg: u16, - relatedTargetArg: Option<AbstractEventTarget>) -> ErrorResult { - self.parent.InitUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg); + relatedTargetArg: Option<JS<EventTarget>>) -> ErrorResult { + self.mouseevent.InitUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg); self.screen_x = screenXArg; self.screen_y = screenYArg; self.client_x = clientXArg; @@ -144,10 +153,10 @@ impl MouseEvent { impl Reflectable for MouseEvent { fn reflector<'a>(&'a self) -> &'a Reflector { - self.parent.reflector() + self.mouseevent.reflector() } fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { - self.parent.mut_reflector() + self.mouseevent.mut_reflector() } } diff --git a/src/components/script/dom/navigator.rs b/src/components/script/dom/navigator.rs index 0c011f9bd58..693e86cb23d 100644 --- a/src/components/script/dom/navigator.rs +++ b/src/components/script/dom/navigator.rs @@ -2,12 +2,14 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::bindings::codegen::NavigatorBinding; +use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::Fallible; -use dom::bindings::codegen::NavigatorBinding; use dom::window::Window; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct Navigator { reflector_: Reflector //XXXjdm cycle: window->navigator->window } @@ -19,8 +21,10 @@ impl Navigator { } } - pub fn new(window: &Window) -> @mut Navigator { - reflect_dom_object(@mut Navigator::new_inherited(), window, NavigatorBinding::Wrap) + pub fn new(window: &Window) -> JS<Navigator> { + reflect_dom_object(~Navigator::new_inherited(), + window, + NavigatorBinding::Wrap) } pub fn DoNotTrack(&self) -> DOMString { diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index 3f0649fbdac..4526b45dd8b 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -4,22 +4,23 @@ //! The core DOM types. Defines the basic DOM hierarchy as well as all the HTML elements. +use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, ElementCast, TextCast, NodeCast}; +use dom::bindings::codegen::InheritTypes::{CharacterDataCast, NodeBase, NodeDerived}; +use dom::bindings::codegen::InheritTypes::ProcessingInstructionCast; +use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::{ErrorResult, Fallible, NotFound, HierarchyRequest}; use dom::bindings::utils; use dom::characterdata::CharacterData; -use dom::document::{AbstractDocument, DocumentTypeId}; +use dom::document::{Document, DocumentTypeId}; use dom::documenttype::DocumentType; -use dom::element::{Element, ElementTypeId, HTMLImageElementTypeId, HTMLIframeElementTypeId, HTMLObjectElementTypeId}; -use dom::element::{HTMLAnchorElementTypeId, HTMLStyleElementTypeId}; -use dom::eventtarget::{AbstractEventTarget, EventTarget, NodeTypeId}; -use dom::htmliframeelement::HTMLIFrameElement; -use dom::htmlimageelement::HTMLImageElement; -use dom::htmlobjectelement::HTMLObjectElement; +use dom::element::{Element, ElementTypeId, HTMLAnchorElementTypeId}; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::nodelist::{NodeList}; use dom::text::Text; use dom::processinginstruction::ProcessingInstruction; use layout_interface::{LayoutChan, ReapLayoutDataMsg, UntrustedNodeAddress}; +use layout_interface::TrustedNodeAddress; use servo_util::str::{DOMString, null_str_as_empty}; use js::jsapi::{JSContext, JSObject, JSRuntime}; @@ -27,25 +28,19 @@ use js::jsfriendapi; use std::cast::transmute; use std::cast; use std::cell::{RefCell, Ref, RefMut}; -use std::iter::Filter; +use std::iter::{Map, Filter}; use std::libc::uintptr_t; -use std::util; use std::unstable::raw::Box; +use std::util; + +use extra::serialize::{Encoder, Encodable}; // // The basic Node structure // -/// This is what a Node looks like if you do not know what kind of node it is. To unpack it, use -/// downcast(). -/// -/// FIXME: This should be replaced with a trait once they can inherit from structs. -#[deriving(Eq)] -pub struct AbstractNode { - priv obj: *mut (), -} - /// An HTML node. +#[deriving(Encodable)] pub struct Node { /// The JavaScript reflector for this node. eventtarget: EventTarget, @@ -53,28 +48,26 @@ pub struct Node { /// The type of node that this is. type_id: NodeTypeId, - abstract: Option<AbstractNode>, - /// The parent of this node. - parent_node: Option<AbstractNode>, + parent_node: Option<JS<Node>>, /// The first child of this node. - first_child: Option<AbstractNode>, + first_child: Option<JS<Node>>, /// The last child of this node. - last_child: Option<AbstractNode>, + last_child: Option<JS<Node>>, /// The next sibling of this node. - next_sibling: Option<AbstractNode>, + next_sibling: Option<JS<Node>>, /// The previous sibling of this node. - prev_sibling: Option<AbstractNode>, + prev_sibling: Option<JS<Node>>, /// The document that this node belongs to. - priv owner_doc: Option<AbstractDocument>, + priv owner_doc: Option<JS<Document>>, /// The live list of children return by .childNodes. - child_list: Option<@mut NodeList>, + child_list: Option<JS<NodeList>>, /// A bitfield of flags for node items. priv flags: NodeFlags, @@ -86,7 +79,22 @@ pub struct Node { layout_data: LayoutDataRef, } +impl<S: Encoder> Encodable<S> for LayoutDataRef { + fn encode(&self, _s: &mut S) { + } +} + +impl NodeDerived for EventTarget { + fn is_node(&self) -> bool { + match self.type_id { + NodeTargetTypeId(_) => true, + _ => false + } + } +} + /// Flags for node items. +#[deriving(Encodable)] pub struct NodeFlags(u8); impl NodeFlags { @@ -195,7 +203,7 @@ impl LayoutDataRef { pub trait TLayoutData {} /// The different types of nodes. -#[deriving(Eq)] +#[deriving(Eq,Encodable)] pub enum NodeTypeId { DoctypeNodeTypeId, DocumentFragmentNodeTypeId, @@ -206,413 +214,209 @@ pub enum NodeTypeId { ProcessingInstructionNodeTypeId, } -impl Clone for AbstractNode { - fn clone(&self) -> AbstractNode { - *self - } +pub trait INode { + fn AppendChild(&mut self, node: &mut JS<Node>) -> Fallible<JS<Node>>; + fn ReplaceChild(&mut self, node: &mut JS<Node>, child: &mut JS<Node>) -> Fallible<JS<Node>>; + fn RemoveChild(&mut self, node: &mut JS<Node>) -> Fallible<JS<Node>>; } -impl AbstractNode { - #[inline] - pub fn node<'a>(&'a self) -> &'a Node { - unsafe { - let box_: *mut Box<Node> = cast::transmute(self.obj); - &(*box_).data - } - } - - #[inline] - pub fn mut_node<'a>(&'a self) -> &'a mut Node { - unsafe { - let box_: *mut Box<Node> = cast::transmute(self.obj); - &mut (*box_).data - } - } - - #[inline] - pub fn parent_node(&self) -> Option<AbstractNode> { - self.node().parent_node - } - - #[inline] - pub fn first_child(&self) -> Option<AbstractNode> { - self.node().first_child - } - - #[inline] - pub fn last_child(&self) -> Option<AbstractNode> { - self.node().last_child - } - - pub fn is_element(&self) -> bool { - match self.type_id() { - ElementNodeTypeId(..) => true, - _ => false - } - } - - pub fn is_document(&self) -> bool { - match self.type_id() { - DocumentNodeTypeId(..) => true, - _ => false - } - } - - /// If the given untrusted node address represents a valid DOM node in the given runtime, - /// returns it. - pub fn from_untrusted_node_address(runtime: *JSRuntime, candidate: UntrustedNodeAddress) - -> AbstractNode { - unsafe { - let candidate: uintptr_t = cast::transmute(candidate); - let object: *JSObject = jsfriendapi::bindgen::JS_GetAddressableObject(runtime, - candidate); - if object.is_null() { - fail!("Attempted to create an `AbstractNode` from an invalid pointer!") - } - let boxed_node: *mut Box<Node> = utils::unwrap(object); - AbstractNode::from_box(boxed_node) - } +impl INode for JS<Node> { + fn AppendChild(&mut self, node: &mut JS<Node>) -> Fallible<JS<Node>> { + let mut self_node = self.clone(); + self.get_mut().AppendChild(&mut self_node, node) } - pub fn is_inclusive_ancestor_of(&self, parent: AbstractNode) -> bool { - *self == parent || parent.ancestors().any(|ancestor| ancestor == *self) + fn ReplaceChild(&mut self, node: &mut JS<Node>, child: &mut JS<Node>) -> Fallible<JS<Node>> { + let mut self_node = self.clone(); + self.get_mut().ReplaceChild(&mut self_node, node, child) } - pub fn is_parent_of(&self, child: AbstractNode) -> bool { - child.parent_node() == Some(*self) + fn RemoveChild(&mut self, node: &mut JS<Node>) -> Fallible<JS<Node>> { + let mut self_node = self.clone(); + self.get_mut().RemoveChild(&mut self_node, node) } } -impl<'a> AbstractNode { - // Unsafe accessors +pub trait NodeHelpers { + fn ancestors(&self) -> AncestorIterator; + fn children(&self) -> AbstractNodeChildrenIterator; + fn child_elements(&self) -> ChildElementIterator; + fn following_siblings(&self) -> AbstractNodeChildrenIterator; + fn is_in_doc(&self) -> bool; + fn is_inclusive_ancestor_of(&self, parent: &JS<Node>) -> bool; + fn is_parent_of(&self, child: &JS<Node>) -> bool; + + fn type_id(&self) -> NodeTypeId; + + fn parent_node(&self) -> Option<JS<Node>>; + fn first_child(&self) -> Option<JS<Node>>; + fn last_child(&self) -> Option<JS<Node>>; + fn prev_sibling(&self) -> Option<JS<Node>>; + fn next_sibling(&self) -> Option<JS<Node>>; + + fn is_element(&self) -> bool; + fn is_document(&self) -> bool; + fn is_doctype(&self) -> bool; + fn is_text(&self) -> bool; + fn is_anchor_element(&self) -> bool; + + fn node_inserted(&self); + fn node_removed(&self); + fn add_child(&mut self, new_child: &mut JS<Node>, before: Option<JS<Node>>); + fn remove_child(&mut self, child: &mut JS<Node>); + + fn get_hover_state(&self) -> bool; + fn set_hover_state(&mut self, state: bool); + + fn dump(&self); + fn dump_indent(&self, indent: uint); + fn debug_str(&self) -> ~str; + + fn traverse_preorder(&self) -> TreeIterator; + fn sequential_traverse_postorder(&self) -> TreeIterator; + fn inclusively_following_siblings(&self) -> AbstractNodeChildrenIterator; + + fn from_untrusted_node_address(runtime: *JSRuntime, candidate: UntrustedNodeAddress) -> Self; + fn to_trusted_node_address(&self) -> TrustedNodeAddress; +} - pub unsafe fn as_cacheable_wrapper(&self) -> @mut Reflectable { - match self.type_id() { - TextNodeTypeId => { - let node: @mut Text = cast::transmute(self.obj); - node as @mut Reflectable - } - _ => { - fail!("unsupported node type") - } - } +impl NodeHelpers for JS<Node> { + /// Dumps the subtree rooted at this node, for debugging. + fn dump(&self) { + self.dump_indent(0); } - /// Allow consumers to recreate an AbstractNode from the raw boxed type. - /// Must only be used in situations where the boxed type is in the inheritance - /// chain for nodes. - /// - /// FIXME(pcwalton): Mark unsafe? - pub fn from_box<T>(ptr: *mut Box<T>) -> AbstractNode { - AbstractNode { - obj: ptr as *mut () + /// Dumps the node tree, for debugging, with indentation. + fn dump_indent(&self, indent: uint) { + let mut s = ~""; + for _ in range(0, indent) { + s.push_str(" "); } - } - /// Allow consumers to upcast from derived classes. - pub fn from_document(doc: AbstractDocument) -> AbstractNode { - unsafe { - cast::transmute(doc) - } - } + s.push_str(self.debug_str()); + debug!("{:s}", s); - pub fn from_eventtarget(target: AbstractEventTarget) -> AbstractNode { - assert!(target.is_node()); - unsafe { - cast::transmute(target) + // FIXME: this should have a pure version? + for kid in self.children() { + kid.dump_indent(indent + 1u) } } - // Convenience accessors - - /// Returns the type ID of this node. Fails if this node is borrowed mutably. - #[inline] - pub fn type_id(self) -> NodeTypeId { - self.node().type_id + /// Returns a string that describes this node. + fn debug_str(&self) -> ~str { + format!("{:?}", self.type_id()) } - /// Returns the previous sibling of this node. Fails if this node is borrowed mutably. - pub fn prev_sibling(self) -> Option<AbstractNode> { - self.node().prev_sibling + /// Iterates over all ancestors of this node. + fn ancestors(&self) -> AncestorIterator { + self.get().ancestors() } - /// Returns the next sibling of this node. Fails if this node is borrowed mutably. - pub fn next_sibling(self) -> Option<AbstractNode> { - self.node().next_sibling + fn children(&self) -> AbstractNodeChildrenIterator { + self.get().children() } - // - // Downcasting borrows - // - - pub fn transmute<'a, T, R>(self, f: |&'a T| -> R) -> R { - unsafe { - let node_box: *mut Box<Node> = transmute(self.obj); - let node = &mut (*node_box).data; - let old = node.abstract; - node.abstract = Some(self); - let box_: *Box<T> = transmute(self.obj); - let rv = f(&(*box_).data); - node.abstract = old; - rv - } + fn child_elements(&self) -> ChildElementIterator { + self.get().child_elements() } - pub fn transmute_mut<T, R>(self, f: |&mut T| -> R) -> R { - unsafe { - let node_box: *mut Box<Node> = transmute(self.obj); - let node = &mut (*node_box).data; - let old = node.abstract; - node.abstract = Some(self); - let box_: *Box<T> = transmute(self.obj); - let rv = f(cast::transmute(&(*box_).data)); - node.abstract = old; - rv - } + fn is_in_doc(&self) -> bool { + self.get().flags.is_in_doc() } - // FIXME: This should be doing dynamic borrow checking for safety. - pub fn is_characterdata(self) -> bool { - self.is_text() || self.is_comment() || self.is_processing_instruction() + /// Returns the type ID of this node. Fails if this node is borrowed mutably. + fn type_id(&self) -> NodeTypeId { + self.get().type_id } - pub fn with_imm_characterdata<R>(self, f: |&CharacterData| -> R) -> R { - if !self.is_characterdata() { - fail!(~"node is not characterdata"); - } - self.transmute(f) + fn parent_node(&self) -> Option<JS<Node>> { + self.get().parent_node.clone() } - pub fn with_mut_characterdata<R>(self, f: |&mut CharacterData| -> R) -> R { - if !self.is_characterdata() { - fail!(~"node is not characterdata"); - } - self.transmute_mut(f) + fn first_child(&self) -> Option<JS<Node>> { + self.get().first_child.clone() } - pub fn is_doctype(self) -> bool { - self.type_id() == DoctypeNodeTypeId + fn last_child(&self) -> Option<JS<Node>> { + self.get().last_child.clone() } - pub fn with_imm_doctype<R>(self, f: |&DocumentType| -> R) -> R { - if !self.is_doctype() { - fail!(~"node is not doctype"); - } - self.transmute(f) + /// Returns the previous sibling of this node. Fails if this node is borrowed mutably. + fn prev_sibling(&self) -> Option<JS<Node>> { + self.get().prev_sibling.clone() } - pub fn with_mut_doctype<R>(self, f: |&mut DocumentType| -> R) -> R { - if !self.is_doctype() { - fail!(~"node is not doctype"); - } - self.transmute_mut(f) + /// Returns the next sibling of this node. Fails if this node is borrowed mutably. + fn next_sibling(&self) -> Option<JS<Node>> { + self.get().next_sibling.clone() } #[inline] - pub fn is_comment(self) -> bool { - // FIXME(pcwalton): Temporary workaround for the lack of inlining of autogenerated `Eq` - // implementations in Rust. + fn is_element(&self) -> bool { match self.type_id() { - CommentNodeTypeId => true, - _ => false, + ElementNodeTypeId(..) => true, + _ => false } } #[inline] - pub fn is_text(self) -> bool { - // FIXME(pcwalton): Temporary workaround for the lack of inlining of autogenerated `Eq` - // implementations in Rust. + fn is_document(&self) -> bool { match self.type_id() { - TextNodeTypeId => true, - _ => false, - } - } - - pub fn with_imm_text<R>(self, f: |&Text| -> R) -> R { - if !self.is_text() { - fail!(~"node is not text"); - } - self.transmute(f) - } - - pub fn with_mut_text<R>(self, f: |&mut Text| -> R) -> R { - if !self.is_text() { - fail!(~"node is not text"); + DocumentNodeTypeId(..) => true, + _ => false } - self.transmute_mut(f) } #[inline] - pub fn is_processing_instruction(self) -> bool { - self.type_id() == ProcessingInstructionNodeTypeId - } - - pub fn with_imm_processing_instruction<R>(self, f: |&ProcessingInstruction| -> R) -> R { - if !self.is_processing_instruction() { - fail!("node is not processing instruction"); - } - self.transmute(f) - } - - // FIXME: This should be doing dynamic borrow checking for safety. - pub fn with_imm_element<R>(self, f: |&Element| -> R) -> R { - if !self.is_element() { - fail!(~"node is not an element"); - } - self.transmute(f) - } - - // FIXME: This should be doing dynamic borrow checking for safety. - pub fn as_mut_element<R>(self, f: |&mut Element| -> R) -> R { - if !self.is_element() { - fail!(~"node is not an element"); + fn is_anchor_element(&self) -> bool { + match self.type_id() { + ElementNodeTypeId(HTMLAnchorElementTypeId) => true, + _ => false } - self.transmute_mut(f) } #[inline] - pub fn is_image_element(self) -> bool { + fn is_doctype(&self) -> bool { match self.type_id() { - ElementNodeTypeId(HTMLImageElementTypeId) => true, - _ => false, - } - } - - pub fn with_mut_image_element<R>(self, f: |&mut HTMLImageElement| -> R) -> R { - if !self.is_image_element() { - fail!(~"node is not an image element"); + DoctypeNodeTypeId => true, + _ => false } - self.transmute_mut(f) - } - - pub fn is_iframe_element(self) -> bool { - self.type_id() == ElementNodeTypeId(HTMLIframeElementTypeId) } #[inline] - pub fn is_object_element(self) -> bool { - self.type_id() == ElementNodeTypeId(HTMLObjectElementTypeId) - } - - pub fn with_mut_object_element<R>(self, f: |&mut HTMLObjectElement| -> R) -> R { - if !self.is_object_element() { - fail!(~"node is not an image element"); - } - self.transmute_mut(f) - } - - pub fn with_mut_iframe_element<R>(self, f: |&mut HTMLIFrameElement| -> R) -> R { - if !self.is_iframe_element() { - fail!(~"node is not an iframe element"); - } - self.transmute_mut(f) - } - - pub fn is_style_element(self) -> bool { - self.type_id() == ElementNodeTypeId(HTMLStyleElementTypeId) - } - - pub fn is_anchor_element(self) -> bool { - self.type_id() == ElementNodeTypeId(HTMLAnchorElementTypeId) - } - - pub unsafe fn raw_object(self) -> *mut Box<Node> { - cast::transmute(self.obj) - } - - pub fn from_raw(raw: *mut Box<Node>) -> AbstractNode { - AbstractNode { - obj: raw as *mut () - } - } - - /// Dumps the subtree rooted at this node, for debugging. - pub fn dump(&self) { - self.dump_indent(0); - } - - /// Dumps the node tree, for debugging, with indentation. - pub fn dump_indent(&self, indent: uint) { - let mut s = ~""; - for _ in range(0, indent) { - s.push_str(" "); - } - - s.push_str(self.debug_str()); - debug!("{:s}", s); - - // FIXME: this should have a pure version? - for kid in self.children() { - kid.dump_indent(indent + 1u) + fn is_text(&self) -> bool { + // FIXME(pcwalton): Temporary workaround for the lack of inlining of autogenerated `Eq` + // implementations in Rust. + match self.type_id() { + TextNodeTypeId => true, + _ => false } } - /// Returns a string that describes this node. - pub fn debug_str(&self) -> ~str { - format!("{:?}", self.type_id()) - } - - // - // Convenience accessors - // - - pub fn children(&self) -> AbstractNodeChildrenIterator { - self.node().children() - } - - pub fn child_elements(&self) -> Filter<AbstractNode, AbstractNodeChildrenIterator> { - self.node().child_elements() - } - - pub fn is_in_doc(&self) -> bool { - self.node().flags.is_in_doc() - } - - pub fn get_hover_state(&self) -> bool { - self.node().flags.get_in_hover_state() - } - - pub fn set_hover_state(&self, state: bool) { - self.mut_node().flags.set_is_in_hover_state(state); - } -} - -impl AbstractNode { - // http://dom.spec.whatwg.org/#dom-node-appendchild - pub fn AppendChild(self, node: AbstractNode) -> Fallible<AbstractNode> { - self.node().AppendChild(self, node) - } - - // http://dom.spec.whatwg.org/#dom-node-replacechild - pub fn ReplaceChild(self, node: AbstractNode, child: AbstractNode) -> Fallible<AbstractNode> { - self.node().ReplaceChild(self, node, child) - } - - // http://dom.spec.whatwg.org/#dom-node-removechild - pub fn RemoveChild(self, node: AbstractNode) -> Fallible<AbstractNode> { - self.node().RemoveChild(self, node) - } - // http://dom.spec.whatwg.org/#node-is-inserted - fn node_inserted(self) { + fn node_inserted(&self) { assert!(self.parent_node().is_some()); - let document = self.node().owner_doc(); + let mut document = self.get().owner_doc(); // Register elements having "id" attribute to the owner doc. - document.mut_document().register_nodes_with_id(&self); + if self.is_element() { + document.get_mut().register_nodes_with_id(&ElementCast::to(self)); + } - document.document().content_changed(); + document.get().content_changed(); } // http://dom.spec.whatwg.org/#node-is-removed - fn node_removed(self) { + fn node_removed(&self) { assert!(self.parent_node().is_none()); - let document = self.node().owner_doc(); + let mut document = self.get().owner_doc(); // Unregister elements having "id". - document.mut_document().unregister_nodes_with_id(&self); + if self.is_element() { + document.get_mut().unregister_nodes_with_id(&ElementCast::to(self)); + } - document.document().content_changed(); + document.get().content_changed(); } // @@ -622,71 +426,66 @@ impl AbstractNode { /// Adds a new child to the end of this node's list of children. /// /// Fails unless `new_child` is disconnected from the tree. - fn add_child(&self, new_child: AbstractNode, before: Option<AbstractNode>) { - let this_node = self.mut_node(); - let new_child_node = new_child.mut_node(); - assert!(new_child_node.parent_node.is_none()); - assert!(new_child_node.prev_sibling.is_none()); - assert!(new_child_node.next_sibling.is_none()); + fn add_child(&mut self, new_child: &mut JS<Node>, before: Option<JS<Node>>) { + assert!(new_child.parent_node().is_none()); + assert!(new_child.prev_sibling().is_none()); + assert!(new_child.next_sibling().is_none()); match before { - Some(before) => { - let before_node = before.mut_node(); + Some(mut before) => { // XXX Should assert that parent is self. - assert!(before_node.parent_node.is_some()); - match before_node.prev_sibling { + assert!(before.parent_node().is_some()); + match before.prev_sibling() { None => { // XXX Should assert that before is the first child of // self. - this_node.set_first_child(Some(new_child.clone())); + self.get_mut().set_first_child(Some(new_child.clone())); }, - Some(prev_sibling) => { - let prev_sibling_node = prev_sibling.mut_node(); - prev_sibling_node.set_next_sibling(Some(new_child.clone())); - new_child_node.set_prev_sibling(Some(prev_sibling.clone())); + Some(mut prev_sibling) => { + prev_sibling.get_mut().set_next_sibling(Some(new_child.clone())); + new_child.get_mut().set_prev_sibling(Some(prev_sibling.clone())); }, } - before_node.set_prev_sibling(Some(new_child.clone())); - new_child_node.set_next_sibling(Some(before.clone())); + before.get_mut().set_prev_sibling(Some(new_child.clone())); + new_child.get_mut().set_next_sibling(Some(before.clone())); }, None => { - match this_node.last_child { - None => this_node.set_first_child(Some(new_child.clone())), - Some(last_child) => { - let last_child_node = last_child.mut_node(); - assert!(last_child_node.next_sibling.is_none()); - last_child_node.set_next_sibling(Some(new_child.clone())); - new_child_node.set_prev_sibling(Some(last_child.clone())); + match self.last_child() { + None => self.get_mut().set_first_child(Some(new_child.clone())), + Some(mut last_child) => { + assert!(last_child.next_sibling().is_none()); + last_child.get_mut().set_next_sibling(Some(new_child.clone())); + new_child.get_mut().set_prev_sibling(Some(last_child.clone())); } } - this_node.set_last_child(Some(new_child.clone())); + self.get_mut().set_last_child(Some(new_child.clone())); }, } - new_child_node.set_parent_node(Some((*self).clone())); + new_child.get_mut().set_parent_node(Some(self.clone())); } /// Removes the given child from this node's list of children. /// /// Fails unless `child` is a child of this node. (FIXME: This is not yet checked.) - fn remove_child(&self, child: AbstractNode) { - let this_node = self.mut_node(); - let child_node = child.mut_node(); + fn remove_child(&mut self, child: &mut JS<Node>) { + let this_node = self.get_mut(); + let child_node = child.get_mut(); assert!(child_node.parent_node.is_some()); match child_node.prev_sibling { - None => this_node.set_first_child(child_node.next_sibling), - Some(prev_sibling) => { - let prev_sibling_node = prev_sibling.mut_node(); - prev_sibling_node.set_next_sibling(child_node.next_sibling); + None => this_node.set_first_child(child_node.next_sibling.clone()), + Some(ref mut prev_sibling) => { + let prev_sibling_node = prev_sibling.get_mut(); + prev_sibling_node.set_next_sibling(child_node.next_sibling.clone()); } } match child_node.next_sibling { - None => this_node.set_last_child(child_node.prev_sibling), - Some(next_sibling) => { - let next_sibling_node = next_sibling.mut_node(); - next_sibling_node.set_prev_sibling(child_node.prev_sibling); + None => this_node.set_last_child(child_node.prev_sibling.clone()), + Some(ref mut next_sibling) => { + let next_sibling_node = next_sibling.get_mut(); + next_sibling_node.set_prev_sibling(child_node.prev_sibling.clone()); } } @@ -694,20 +493,89 @@ impl AbstractNode { child_node.set_next_sibling(None); child_node.set_parent_node(None); } + + fn get_hover_state(&self) -> bool { + self.get().flags.get_in_hover_state() + } + + fn set_hover_state(&mut self, state: bool) { + self.get_mut().flags.set_is_in_hover_state(state); + } + + /// Iterates over this node and all its descendants, in preorder. + fn traverse_preorder(&self) -> TreeIterator { + let mut nodes = ~[]; + gather_abstract_nodes(self, &mut nodes, false); + TreeIterator::new(nodes) + } + + /// Iterates over this node and all its descendants, in postorder. + fn sequential_traverse_postorder(&self) -> TreeIterator { + let mut nodes = ~[]; + gather_abstract_nodes(self, &mut nodes, true); + TreeIterator::new(nodes) + } + + fn inclusively_following_siblings(&self) -> AbstractNodeChildrenIterator { + AbstractNodeChildrenIterator { + current_node: Some(self.clone()), + } + } + + fn is_inclusive_ancestor_of(&self, parent: &JS<Node>) -> bool { + self == parent || parent.ancestors().any(|ancestor| ancestor == *self) + } + + fn following_siblings(&self) -> AbstractNodeChildrenIterator { + AbstractNodeChildrenIterator { + current_node: self.next_sibling(), + } + } + + fn is_parent_of(&self, child: &JS<Node>) -> bool { + match child.parent_node() { + Some(ref parent) if parent == self => true, + _ => false + } + } + + /// If the given untrusted node address represents a valid DOM node in the given runtime, + /// returns it. + fn from_untrusted_node_address(runtime: *JSRuntime, candidate: UntrustedNodeAddress) + -> JS<Node> { + unsafe { + let candidate: uintptr_t = cast::transmute(candidate); + let object: *JSObject = jsfriendapi::bindgen::JS_GetAddressableObject(runtime, + candidate); + if object.is_null() { + fail!("Attempted to create a `JS<Node>` from an invalid pointer!") + } + let boxed_node: *mut Box<Node> = utils::unwrap(object); + JS::from_box(boxed_node) + } + } + + fn to_trusted_node_address(&self) -> TrustedNodeAddress { + self.get() as *Node as TrustedNodeAddress + } } // // Iteration and traversal // +type ChildElementIterator<'a> = Map<'a, JS<Node>, + JS<Element>, + Filter<'a, JS<Node>, AbstractNodeChildrenIterator>>; + pub struct AbstractNodeChildrenIterator { - priv current_node: Option<AbstractNode>, + priv current_node: Option<JS<Node>>, } -impl Iterator<AbstractNode> for AbstractNodeChildrenIterator { - fn next(&mut self) -> Option<AbstractNode> { - let node = self.current_node; - self.current_node = self.current_node.and_then(|node| { +impl Iterator<JS<Node>> for AbstractNodeChildrenIterator { + fn next(&mut self) -> Option<JS<Node>> { + let node = self.current_node.clone(); + self.current_node = node.clone().and_then(|node| { node.next_sibling() }); node @@ -715,11 +583,11 @@ impl Iterator<AbstractNode> for AbstractNodeChildrenIterator { } pub struct AncestorIterator { - priv current: Option<AbstractNode>, + priv current: Option<JS<Node>>, } -impl Iterator<AbstractNode> for AncestorIterator { - fn next(&mut self) -> Option<AbstractNode> { +impl Iterator<JS<Node>> for AncestorIterator { + fn next(&mut self) -> Option<JS<Node>> { if self.current.is_none() { return None; } @@ -734,12 +602,12 @@ impl Iterator<AbstractNode> for AncestorIterator { // FIXME: Do this without precomputing a vector of refs. // Easy for preorder; harder for postorder. pub struct TreeIterator { - priv nodes: ~[AbstractNode], + priv nodes: ~[JS<Node>], priv index: uint, } impl TreeIterator { - fn new(nodes: ~[AbstractNode]) -> TreeIterator { + fn new(nodes: ~[JS<Node>]) -> TreeIterator { TreeIterator { nodes: nodes, index: 0, @@ -747,8 +615,8 @@ impl TreeIterator { } } -impl Iterator<AbstractNode> for TreeIterator { - fn next(&mut self) -> Option<AbstractNode> { +impl Iterator<JS<Node>> for TreeIterator { + fn next(&mut self) -> Option<JS<Node>> { if self.index >= self.nodes.len() { None } else { @@ -760,15 +628,15 @@ impl Iterator<AbstractNode> for TreeIterator { } pub struct NodeIterator { - start_node: AbstractNode, - current_node: Option<AbstractNode>, + start_node: JS<Node>, + current_node: Option<JS<Node>>, depth: uint, priv include_start: bool, priv include_descendants_of_void: bool } impl NodeIterator { - pub fn new(start_node: AbstractNode, include_start: bool, include_descendants_of_void: bool) -> NodeIterator { + pub fn new(start_node: JS<Node>, include_start: bool, include_descendants_of_void: bool) -> NodeIterator { NodeIterator { start_node: start_node, current_node: None, @@ -778,44 +646,42 @@ impl NodeIterator { } } - fn next_child(&self, node: AbstractNode) -> Option<AbstractNode> { - if !self.include_descendants_of_void && - node.is_element() { - node.with_imm_element(|elem| { - if elem.is_void() { - None - } else { - node.first_child() - } - }) + fn next_child(&self, node: &JS<Node>) -> Option<JS<Node>> { + if !self.include_descendants_of_void && node.is_element() { + let elem: JS<Element> = ElementCast::to(node); + if elem.get().is_void() { + None + } else { + node.first_child() + } } else { node.first_child() } } } -impl Iterator<AbstractNode> for NodeIterator { - fn next(&mut self) -> Option<AbstractNode> { +impl Iterator<JS<Node>> for NodeIterator { + fn next(&mut self) -> Option<JS<Node>> { self.current_node = match self.current_node { None => { if self.include_start { - Some(self.start_node) + Some(self.start_node.clone()) } else { - self.next_child(self.start_node) + self.next_child(&self.start_node) } }, - Some(node) => { + Some(ref node) => { match self.next_child(node) { Some(child) => { self.depth += 1; - Some(child) + Some(child.clone()) }, - None if node == self.start_node => None, + None if node == &self.start_node => None, None => { match node.next_sibling() { Some(sibling) => Some(sibling), None => { - let mut candidate = node; + let mut candidate = node.clone(); while candidate.next_sibling().is_none() { candidate = candidate.parent_node().expect("Got to root without reaching start node"); self.depth -= 1; @@ -834,11 +700,11 @@ impl Iterator<AbstractNode> for NodeIterator { } } }; - self.current_node + self.current_node.clone() } } -fn gather_abstract_nodes(cur: &AbstractNode, refs: &mut ~[AbstractNode], postorder: bool) { +fn gather_abstract_nodes(cur: &JS<Node>, refs: &mut ~[JS<Node>], postorder: bool) { if !postorder { refs.push(cur.clone()); } @@ -850,75 +716,48 @@ fn gather_abstract_nodes(cur: &AbstractNode, refs: &mut ~[AbstractNode], postord } } -impl AbstractNode { - /// Iterates over all ancestors of this node. +impl Node { pub fn ancestors(&self) -> AncestorIterator { AncestorIterator { - current: self.parent_node(), + current: self.parent_node.clone(), } } - pub fn inclusively_following_siblings(&self) -> AbstractNodeChildrenIterator { - AbstractNodeChildrenIterator { - current_node: Some(*self), - } + pub fn owner_doc(&self) -> JS<Document> { + self.owner_doc.clone().unwrap() } - pub fn following_siblings(&self) -> AbstractNodeChildrenIterator { - AbstractNodeChildrenIterator { - current_node: self.next_sibling(), - } - } - - /// Iterates over this node and all its descendants, in preorder. - pub fn traverse_preorder(&self) -> TreeIterator { - let mut nodes = ~[]; - gather_abstract_nodes(self, &mut nodes, false); - TreeIterator::new(nodes) - } - - /// Iterates over this node and all its descendants, in postorder. - pub fn sequential_traverse_postorder(&self) -> TreeIterator { - let mut nodes = ~[]; - gather_abstract_nodes(self, &mut nodes, true); - TreeIterator::new(nodes) - } -} - -impl Node { - pub fn owner_doc(&self) -> AbstractDocument { - self.owner_doc.unwrap() - } - - pub fn set_owner_doc(&mut self, document: AbstractDocument) { - self.owner_doc = Some(document); + pub fn set_owner_doc(&mut self, document: &JS<Document>) { + self.owner_doc = Some(document.clone()); } pub fn children(&self) -> AbstractNodeChildrenIterator { AbstractNodeChildrenIterator { - current_node: self.first_child, + current_node: self.first_child.clone(), } } - pub fn child_elements(&self) -> Filter<AbstractNode, AbstractNodeChildrenIterator> { - self.children().filter(|node| node.is_element()) + pub fn child_elements(&self) -> ChildElementIterator { + self.children() + .filter(|node| node.is_element()) + .map(|node| { + let elem: JS<Element> = ElementCast::to(&node); + elem + }) } - pub fn reflect_node<N: Reflectable> - (node: @mut N, - document: AbstractDocument, - wrap_fn: extern "Rust" fn(*JSContext, *JSObject, @mut N) -> *JSObject) - -> AbstractNode { + pub fn reflect_node<N: Reflectable+NodeBase> + (node: ~N, + document: &JS<Document>, + wrap_fn: extern "Rust" fn(*JSContext, *JSObject, ~N) -> *JSObject) + -> JS<N> { assert!(node.reflector().get_jsobject().is_null()); - let node = reflect_dom_object(node, document.document().window, wrap_fn); + let node = reflect_dom_object(node, document.get().window.get(), wrap_fn); assert!(node.reflector().get_jsobject().is_not_null()); - // JS owns the node now, so transmute_copy to not increase the refcount - AbstractNode { - obj: unsafe { cast::transmute_copy(&node) }, - } + node } - pub fn new_inherited(type_id: NodeTypeId, doc: AbstractDocument) -> Node { + pub fn new_inherited(type_id: NodeTypeId, doc: JS<Document>) -> Node { Node::new_(type_id, Some(doc)) } @@ -926,13 +765,11 @@ impl Node { Node::new_(type_id, None) } - fn new_(type_id: NodeTypeId, doc: Option<AbstractDocument>) -> Node { + fn new_(type_id: NodeTypeId, doc: Option<JS<Document>>) -> Node { Node { - eventtarget: EventTarget::new_inherited(NodeTypeId), + eventtarget: EventTarget::new_inherited(NodeTargetTypeId(type_id)), type_id: type_id, - abstract: None, - parent_node: None, first_child: None, last_child: None, @@ -974,24 +811,22 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-nodename - pub fn NodeName(&self, abstract_self: AbstractNode) -> DOMString { + pub fn NodeName(&self, abstract_self: &JS<Node>) -> DOMString { match self.type_id { ElementNodeTypeId(..) => { - abstract_self.with_imm_element(|element| { - element.TagName() - }) + let elem: JS<Element> = ElementCast::to(abstract_self); + elem.get().TagName() } TextNodeTypeId => ~"#text", ProcessingInstructionNodeTypeId => { - abstract_self.with_imm_processing_instruction(|processing_instruction| { - processing_instruction.Target() - }) + let processing_instruction: JS<ProcessingInstruction> = + ProcessingInstructionCast::to(abstract_self); + processing_instruction.get().Target() } CommentNodeTypeId => ~"#comment", DoctypeNodeTypeId => { - abstract_self.with_imm_doctype(|doctype| { - doctype.name.clone() - }) + let doctype: JS<DocumentType> = DocumentTypeCast::to(abstract_self); + doctype.get().name.clone() }, DocumentFragmentNodeTypeId => ~"#document-fragment", DocumentNodeTypeId(_) => ~"#document" @@ -1004,7 +839,7 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-ownerdocument - pub fn GetOwnerDocument(&self) -> Option<AbstractDocument> { + pub fn GetOwnerDocument(&self) -> Option<JS<Document>> { match self.type_id { ElementNodeTypeId(..) | CommentNodeTypeId | @@ -1017,13 +852,15 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-parentnode - pub fn GetParentNode(&self) -> Option<AbstractNode> { - self.parent_node + pub fn GetParentNode(&self) -> Option<JS<Node>> { + self.parent_node.clone() } // http://dom.spec.whatwg.org/#dom-node-parentelement - pub fn GetParentElement(&self) -> Option<AbstractNode> { - self.parent_node.filtered(|parent| parent.is_element()) + pub fn GetParentElement(&self) -> Option<JS<Element>> { + self.parent_node.clone() + .filtered(|parent| parent.is_element()) + .map(|node| ElementCast::to(&node)) } // http://dom.spec.whatwg.org/#dom-node-haschildnodes @@ -1032,34 +869,33 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-firstchild - pub fn GetFirstChild(&self) -> Option<AbstractNode> { - self.first_child + pub fn GetFirstChild(&self) -> Option<JS<Node>> { + self.first_child.clone() } // http://dom.spec.whatwg.org/#dom-node-lastchild - pub fn GetLastChild(&self) -> Option<AbstractNode> { - self.last_child + pub fn GetLastChild(&self) -> Option<JS<Node>> { + self.last_child.clone() } // http://dom.spec.whatwg.org/#dom-node-previoussibling - pub fn GetPreviousSibling(&self) -> Option<AbstractNode> { - self.prev_sibling + pub fn GetPreviousSibling(&self) -> Option<JS<Node>> { + self.prev_sibling.clone() } // http://dom.spec.whatwg.org/#dom-node-nextsibling - pub fn GetNextSibling(&self) -> Option<AbstractNode> { - self.next_sibling + pub fn GetNextSibling(&self) -> Option<JS<Node>> { + self.next_sibling.clone() } // http://dom.spec.whatwg.org/#dom-node-nodevalue - pub fn GetNodeValue(&self, abstract_self: AbstractNode) -> Option<DOMString> { + pub fn GetNodeValue(&self, abstract_self: &JS<Node>) -> Option<DOMString> { match self.type_id { CommentNodeTypeId | TextNodeTypeId | ProcessingInstructionNodeTypeId => { - abstract_self.with_imm_characterdata(|characterdata| { - Some(characterdata.Data()) - }) + let chardata: JS<CharacterData> = CharacterDataCast::to(abstract_self); + Some(chardata.get().Data()) } _ => { None @@ -1068,23 +904,22 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-nodevalue - pub fn SetNodeValue(&mut self, _abstract_self: AbstractNode, _val: Option<DOMString>) + pub fn SetNodeValue(&mut self, _abstract_self: &JS<Node>, _val: Option<DOMString>) -> ErrorResult { // FIXME: Stub - https://github.com/mozilla/servo/issues/1655 Ok(()) } // http://dom.spec.whatwg.org/#dom-node-textcontent - pub fn GetTextContent(&self, abstract_self: AbstractNode) -> Option<DOMString> { + pub fn GetTextContent(&self, abstract_self: &JS<Node>) -> Option<DOMString> { match self.type_id { DocumentFragmentNodeTypeId | ElementNodeTypeId(..) => { let mut content = ~""; for node in abstract_self.traverse_preorder() { if node.is_text() { - node.with_imm_text(|text| { - content.push_str(text.characterdata.data.as_slice()); - }) + let text: JS<Text> = TextCast::to(&node); + content.push_str(text.get().characterdata.data.as_slice()); } } Some(content) @@ -1092,9 +927,8 @@ impl Node { CommentNodeTypeId | TextNodeTypeId | ProcessingInstructionNodeTypeId => { - abstract_self.with_imm_characterdata(|characterdata| { - Some(characterdata.Data()) - }) + let characterdata: JS<CharacterData> = CharacterDataCast::to(abstract_self); + Some(characterdata.get().Data()) } DoctypeNodeTypeId | DocumentNodeTypeId(_) => { @@ -1104,30 +938,31 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-childnodes - pub fn ChildNodes(&mut self, abstract_self: AbstractNode) -> @mut NodeList { + pub fn ChildNodes(&mut self, abstract_self: &JS<Node>) -> JS<NodeList> { match self.child_list { None => { - let window = self.owner_doc().document().window; - let list = NodeList::new_child_list(window, abstract_self); - self.child_list = Some(list); + let doc = self.owner_doc(); + let doc = doc.get(); + let list = NodeList::new_child_list(&doc.window, abstract_self); + self.child_list = Some(list.clone()); list } - Some(list) => list + Some(ref list) => list.clone() } } // http://dom.spec.whatwg.org/#concept-node-adopt - fn adopt(node: AbstractNode, document: AbstractDocument) { + fn adopt(node: &mut JS<Node>, document: &JS<Document>) { // Step 1. match node.parent_node() { - Some(parent) => Node::remove(node, parent, Unsuppressed), + Some(ref mut parent) => Node::remove(node, parent, Unsuppressed), None => (), } // Step 2. - if node.node().owner_doc() != document { - for descendant in node.traverse_preorder() { - descendant.mut_node().set_owner_doc(document); + if node.get().owner_doc() != *document { + for mut descendant in node.traverse_preorder() { + descendant.get_mut().set_owner_doc(document); } } @@ -1136,8 +971,8 @@ impl Node { } // http://dom.spec.whatwg.org/#concept-node-pre-insert - fn pre_insert(node: AbstractNode, parent: AbstractNode, child: Option<AbstractNode>) - -> Fallible<AbstractNode> { + fn pre_insert(node: &mut JS<Node>, parent: &mut JS<Node>, child: Option<JS<Node>>) + -> Fallible<JS<Node>> { // Step 1. match parent.type_id() { DocumentNodeTypeId(..) | @@ -1153,7 +988,7 @@ impl Node { // Step 3. match child { - Some(child) if !parent.is_parent_of(child) => return Err(NotFound), + Some(ref child) if !parent.is_parent_of(child) => return Err(NotFound), _ => () } @@ -1161,13 +996,13 @@ impl Node { match node.type_id() { TextNodeTypeId => { match node.parent_node() { - Some(parent) if parent.is_document() => return Err(HierarchyRequest), + Some(ref parent) if parent.is_document() => return Err(HierarchyRequest), _ => () } } DoctypeNodeTypeId => { match node.parent_node() { - Some(parent) if !parent.is_document() => return Err(HierarchyRequest), + Some(ref parent) if !parent.is_document() => return Err(HierarchyRequest), _ => () } } @@ -1198,8 +1033,8 @@ impl Node { return Err(HierarchyRequest); } match child { - Some(child) if child.inclusively_following_siblings() - .any(|child| child.is_doctype()) => { + Some(ref child) if child.inclusively_following_siblings() + .any(|child| child.is_doctype()) => { return Err(HierarchyRequest); } _ => (), @@ -1217,8 +1052,8 @@ impl Node { return Err(HierarchyRequest); } match child { - Some(child) if child.inclusively_following_siblings() - .any(|child| child.is_doctype()) => { + Some(ref child) if child.inclusively_following_siblings() + .any(|child| child.is_doctype()) => { return Err(HierarchyRequest); } _ => (), @@ -1230,9 +1065,9 @@ impl Node { return Err(HierarchyRequest); } match child { - Some(child) => { + Some(ref child) => { if parent.children() - .take_while(|&c| c != child) + .take_while(|c| c != child) .any(|c| c.is_element()) { return Err(HierarchyRequest); } @@ -1256,41 +1091,40 @@ impl Node { } // Step 7-8. - let referenceChild = if child != Some(node) { - child - } else { - node.next_sibling() + let referenceChild = match child { + Some(ref child) if child == node => node.next_sibling(), + _ => child }; // Step 9. - Node::adopt(node, parent.node().owner_doc()); + Node::adopt(node, &parent.get().owner_doc()); // Step 10. Node::insert(node, parent, referenceChild, Unsuppressed); // Step 11. - return Ok(node) + return Ok(node.clone()) } // http://dom.spec.whatwg.org/#concept-node-insert - fn insert(node: AbstractNode, - parent: AbstractNode, - child: Option<AbstractNode>, + fn insert(node: &mut JS<Node>, + parent: &mut JS<Node>, + child: Option<JS<Node>>, suppress_observers: SuppressObserver) { // XXX assert owner_doc // Step 1-3: ranges. // Step 4. - let nodes = match node.type_id() { + let mut nodes = match node.type_id() { DocumentFragmentNodeTypeId => node.children().collect(), - _ => ~[node], + _ => ~[node.clone()], }; // Step 5: DocumentFragment, mutation records. // Step 6: DocumentFragment. match node.type_id() { DocumentFragmentNodeTypeId => { - for c in node.children() { - Node::remove(c, node, Suppressed); + for mut c in node.children() { + Node::remove(&mut c, node, Suppressed); } }, _ => (), @@ -1298,9 +1132,9 @@ impl Node { // Step 7: mutation records. // Step 8. - for node in nodes.iter() { - parent.add_child(*node, child); - node.mut_node().flags.set_is_in_doc(parent.is_in_doc()); + for node in nodes.mut_iter() { + parent.add_child(node, child.clone()); + node.get_mut().flags.set_is_in_doc(parent.is_in_doc()); } // Step 9. @@ -1315,33 +1149,33 @@ impl Node { } // http://dom.spec.whatwg.org/#concept-node-replace-all - pub fn replace_all(node: Option<AbstractNode>, parent: AbstractNode) { + pub fn replace_all(mut node: Option<JS<Node>>, parent: &mut JS<Node>) { // Step 1. match node { - Some(node) => Node::adopt(node, parent.node().owner_doc()), + Some(ref mut node) => Node::adopt(node, &parent.get().owner_doc()), None => (), } // Step 2. - let removedNodes: ~[AbstractNode] = parent.children().collect(); + let removedNodes: ~[JS<Node>] = parent.children().collect(); // Step 3. let addedNodes = match node { None => ~[], - Some(node) => match node.type_id() { + Some(ref node) => match node.type_id() { DocumentFragmentNodeTypeId => node.children().collect(), - _ => ~[node], + _ => ~[node.clone()], }, }; // Step 4. - for child in parent.children() { - Node::remove(child, parent, Suppressed); + for mut child in parent.children() { + Node::remove(&mut child, parent, Suppressed); } // Step 5. match node { - Some(node) => Node::insert(node, parent, None, Suppressed), + Some(ref mut node) => Node::insert(node, parent, None, Suppressed), None => (), } @@ -1357,28 +1191,29 @@ impl Node { } // http://dom.spec.whatwg.org/#concept-node-pre-remove - fn pre_remove(child: AbstractNode, parent: AbstractNode) -> Fallible<AbstractNode> { + fn pre_remove(child: &mut JS<Node>, parent: &mut JS<Node>) -> Fallible<JS<Node>> { // Step 1. - if child.parent_node() != Some(parent) { - return Err(NotFound); + match child.parent_node() { + Some(ref node) if node != parent => return Err(NotFound), + _ => () } // Step 2. Node::remove(child, parent, Unsuppressed); // Step 3. - Ok(child) + Ok(child.clone()) } // http://dom.spec.whatwg.org/#concept-node-remove - fn remove(node: AbstractNode, parent: AbstractNode, suppress_observers: SuppressObserver) { - assert!(node.parent_node() == Some(parent)); + fn remove(node: &mut JS<Node>, parent: &mut JS<Node>, suppress_observers: SuppressObserver) { + assert!(node.parent_node().map_default(false, |ref node_parent| node_parent == parent)); // Step 1-5: ranges. // Step 6-7: mutation observers. // Step 8. parent.remove_child(node); - node.mut_node().flags.set_is_in_doc(false); + node.get_mut().flags.set_is_in_doc(false); // Step 9. match suppress_observers { @@ -1388,7 +1223,7 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-textcontent - pub fn SetTextContent(&mut self, abstract_self: AbstractNode, value: Option<DOMString>) + pub fn SetTextContent(&mut self, abstract_self: &mut JS<Node>, value: Option<DOMString>) -> ErrorResult { let value = null_str_as_empty(&value); match self.type_id { @@ -1399,7 +1234,7 @@ impl Node { None } else { let document = self.owner_doc(); - Some(document.document().CreateTextNode(document, value)) + Some(NodeCast::from(&document.get().CreateTextNode(&document, value))) }; // Step 3. Node::replace_all(node, abstract_self); @@ -1409,13 +1244,12 @@ impl Node { ProcessingInstructionNodeTypeId => { self.wait_until_safe_to_modify_dom(); - abstract_self.with_mut_characterdata(|characterdata| { - characterdata.data = value.clone(); + let mut characterdata: JS<CharacterData> = CharacterDataCast::to(abstract_self); + characterdata.get_mut().data = value.clone(); - // Notify the document that the content of this node is different - let document = self.owner_doc(); - document.document().content_changed(); - }) + // Notify the document that the content of this node is different + let document = self.owner_doc(); + document.get().content_changed(); } DoctypeNodeTypeId | DocumentNodeTypeId(_) => {} @@ -1424,25 +1258,25 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-insertbefore - pub fn InsertBefore(&self, abstract_self: AbstractNode, node: AbstractNode, child: Option<AbstractNode>) - -> Fallible<AbstractNode> { + pub fn InsertBefore(&self, abstract_self: &mut JS<Node>, node: &mut JS<Node>, child: Option<JS<Node>>) + -> Fallible<JS<Node>> { Node::pre_insert(node, abstract_self, child) } pub fn wait_until_safe_to_modify_dom(&self) { let document = self.owner_doc(); - document.document().wait_until_safe_to_modify_dom(); + document.get().wait_until_safe_to_modify_dom(); } // http://dom.spec.whatwg.org/#dom-node-appendchild - pub fn AppendChild(&self, abstract_self: AbstractNode, node: AbstractNode) - -> Fallible<AbstractNode> { + pub fn AppendChild(&self, abstract_self: &mut JS<Node>, node: &mut JS<Node>) + -> Fallible<JS<Node>> { Node::pre_insert(node, abstract_self, None) } // http://dom.spec.whatwg.org/#concept-node-replace - pub fn ReplaceChild(&self, parent: AbstractNode, node: AbstractNode, child: AbstractNode) - -> Fallible<AbstractNode> { + pub fn ReplaceChild(&self, parent: &mut JS<Node>, node: &mut JS<Node>, child: &mut JS<Node>) + -> Fallible<JS<Node>> { // Step 1. match parent.type_id() { DocumentNodeTypeId(..) | @@ -1488,7 +1322,7 @@ impl Node { 0 => (), // Step 6.1.2 1 => { - if parent.child_elements().any(|c| c != child) { + if parent.child_elements().any(|c| &NodeCast::from(&c) != child) { return Err(HierarchyRequest); } if child.following_siblings() @@ -1502,7 +1336,7 @@ impl Node { }, // Step 6.2 ElementNodeTypeId(..) => { - if parent.child_elements().any(|c| c != child) { + if parent.child_elements().any(|c| &NodeCast::from(&c) != child) { return Err(HierarchyRequest); } if child.following_siblings() @@ -1512,11 +1346,11 @@ impl Node { }, // Step 6.3 DoctypeNodeTypeId => { - if parent.children().any(|c| c.is_doctype() && c != child) { + if parent.children().any(|c| c.is_doctype() && &c != child) { return Err(HierarchyRequest); } if parent.children() - .take_while(|&c| c != child) + .take_while(|c| c != child) .any(|c| c.is_element()) { return Err(HierarchyRequest); } @@ -1531,19 +1365,19 @@ impl Node { } // Ok if not caught by previous error checks. - if node == child { - return Ok(child); + if *node == *child { + return Ok(child.clone()); } // Step 7-8. - let reference_child = if child.next_sibling() != Some(node) { - child.next_sibling() - } else { - node.next_sibling() + let next_sibling = child.next_sibling(); + let reference_child = match next_sibling { + Some(ref sibling) if sibling == node => node.next_sibling(), + _ => next_sibling }; // Step 9. - Node::adopt(node, parent.node().owner_doc()); + Node::adopt(node, &parent.get().owner_doc()); { // Step 10. @@ -1565,12 +1399,12 @@ impl Node { } // Step 15. - Ok(child) + Ok(child.clone()) } // http://dom.spec.whatwg.org/#dom-node-removechild - pub fn RemoveChild(&self, abstract_self: AbstractNode, node: AbstractNode) - -> Fallible<AbstractNode> { + pub fn RemoveChild(&self, abstract_self: &mut JS<Node>, node: &mut JS<Node>) + -> Fallible<JS<Node>> { Node::pre_remove(node, abstract_self) } @@ -1580,62 +1414,52 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-clonenode - pub fn CloneNode(&self, _deep: bool) -> Fallible<AbstractNode> { + pub fn CloneNode(&self, _deep: bool) -> Fallible<JS<Node>> { // FIXME: stub - https://github.com/mozilla/servo/issues/1240 fail!("stub") } // http://dom.spec.whatwg.org/#dom-node-isequalnode - pub fn IsEqualNode(&self, abstract_self: AbstractNode, maybe_node: Option<AbstractNode>) -> bool { - fn is_equal_doctype(node: AbstractNode, other: AbstractNode) -> bool { - node.with_imm_doctype(|doctype| { - other.with_imm_doctype(|other_doctype| { - (doctype.name == other_doctype.name) && - (doctype.public_id == other_doctype.public_id) && - (doctype.system_id == other_doctype.system_id) - }) - }) - } - fn is_equal_element(node: AbstractNode, other: AbstractNode) -> bool { - node.with_imm_element(|element| { - other.with_imm_element(|other_element| { - // FIXME: namespace prefix - (element.namespace == other_element.namespace) && - (element.tag_name == other_element.tag_name) && - (element.attrs.len() == other_element.attrs.len()) - }) - }) - } - fn is_equal_processinginstruction(node: AbstractNode, other: AbstractNode) -> bool { - node.with_imm_processing_instruction(|pi| { - other.with_imm_processing_instruction(|other_pi| { - (pi.target == other_pi.target) && - (pi.characterdata.data == other_pi.characterdata.data) - }) - }) - } - fn is_equal_characterdata(node: AbstractNode, other: AbstractNode) -> bool { - node.with_imm_characterdata(|characterdata| { - other.with_imm_characterdata(|other_characterdata| { - characterdata.data == other_characterdata.data - }) - }) - } - fn is_equal_element_attrs(node: AbstractNode, other: AbstractNode) -> bool { - node.with_imm_element(|element| { - other.with_imm_element(|other_element| { - assert!(element.attrs.len() == other_element.attrs.len()); - element.attrs.iter().all(|attr| { - other_element.attrs.iter().any(|other_attr| { - (attr.namespace == other_attr.namespace) && - (attr.local_name == other_attr.local_name) && - (attr.value == other_attr.value) - }) - }) + pub fn IsEqualNode(&self, abstract_self: &JS<Node>, maybe_node: Option<JS<Node>>) -> bool { + fn is_equal_doctype(node: &JS<Node>, other: &JS<Node>) -> bool { + let doctype: JS<DocumentType> = DocumentTypeCast::to(node); + let other_doctype: JS<DocumentType> = DocumentTypeCast::to(other); + (doctype.get().name == other_doctype.get().name) && + (doctype.get().public_id == other_doctype.get().public_id) && + (doctype.get().system_id == other_doctype.get().system_id) + } + fn is_equal_element(node: &JS<Node>, other: &JS<Node>) -> bool { + let element: JS<Element> = ElementCast::to(node); + let other_element: JS<Element> = ElementCast::to(other); + // FIXME: namespace prefix + (element.get().namespace == other_element.get().namespace) && + (element.get().tag_name == other_element.get().tag_name) && + (element.get().attrs.len() == other_element.get().attrs.len()) + } + fn is_equal_processinginstruction(node: &JS<Node>, other: &JS<Node>) -> bool { + let pi: JS<ProcessingInstruction> = ProcessingInstructionCast::to(node); + let other_pi: JS<ProcessingInstruction> = ProcessingInstructionCast::to(other); + (pi.get().target == other_pi.get().target) && + (pi.get().characterdata.data == other_pi.get().characterdata.data) + } + fn is_equal_characterdata(node: &JS<Node>, other: &JS<Node>) -> bool { + let characterdata: JS<CharacterData> = CharacterDataCast::to(node); + let other_characterdata: JS<CharacterData> = CharacterDataCast::to(other); + characterdata.get().data == other_characterdata.get().data + } + fn is_equal_element_attrs(node: &JS<Node>, other: &JS<Node>) -> bool { + let element: JS<Element> = ElementCast::to(node); + let other_element: JS<Element> = ElementCast::to(other); + assert!(element.get().attrs.len() == other_element.get().attrs.len()); + element.get().attrs.iter().all(|attr| { + other_element.get().attrs.iter().any(|other_attr| { + (attr.get().namespace == other_attr.get().namespace) && + (attr.get().local_name == other_attr.get().local_name) && + (attr.get().value == other_attr.get().value) }) }) } - fn is_equal_node(this: AbstractNode, node: AbstractNode) -> bool { + fn is_equal_node(this: &JS<Node>, node: &JS<Node>) -> bool { // Step 2. if this.type_id() != node.type_id() { return false; @@ -1659,27 +1483,27 @@ impl Node { } // Step 6. - this.children().zip(node.children()).all(|(child, other_child)| is_equal_node(child, other_child)) + this.children().zip(node.children()).all(|(ref child, ref other_child)| is_equal_node(child, other_child)) } match maybe_node { // Step 1. None => false, // Step 2-6. - Some(node) => is_equal_node(abstract_self, node) + Some(ref node) => is_equal_node(abstract_self, node) } } // http://dom.spec.whatwg.org/#dom-node-comparedocumentposition - pub fn CompareDocumentPosition(&self, _other: AbstractNode) -> u16 { + pub fn CompareDocumentPosition(&self, _other: &JS<Node>) -> u16 { // FIXME: stub - https://github.com/mozilla/servo/issues/1655 0 } // http://dom.spec.whatwg.org/#dom-node-contains - pub fn Contains(&self, abstract_self: AbstractNode, maybe_other: Option<AbstractNode>) -> bool { + pub fn Contains(&self, abstract_self: &JS<Node>, maybe_other: Option<JS<Node>>) -> bool { match maybe_other { None => false, - Some(other) => abstract_self.is_inclusive_ancestor_of(other) + Some(ref other) => abstract_self.is_inclusive_ancestor_of(other) } } @@ -1725,33 +1549,33 @@ impl Node { // Low-level pointer stitching // - pub fn set_parent_node(&mut self, new_parent_node: Option<AbstractNode>) { + pub fn set_parent_node(&mut self, new_parent_node: Option<JS<Node>>) { let doc = self.owner_doc(); - doc.document().wait_until_safe_to_modify_dom(); + doc.get().wait_until_safe_to_modify_dom(); self.parent_node = new_parent_node } - pub fn set_first_child(&mut self, new_first_child: Option<AbstractNode>) { + pub fn set_first_child(&mut self, new_first_child: Option<JS<Node>>) { let doc = self.owner_doc(); - doc.document().wait_until_safe_to_modify_dom(); + doc.get().wait_until_safe_to_modify_dom(); self.first_child = new_first_child } - pub fn set_last_child(&mut self, new_last_child: Option<AbstractNode>) { + pub fn set_last_child(&mut self, new_last_child: Option<JS<Node>>) { let doc = self.owner_doc(); - doc.document().wait_until_safe_to_modify_dom(); + doc.get().wait_until_safe_to_modify_dom(); self.last_child = new_last_child } - pub fn set_prev_sibling(&mut self, new_prev_sibling: Option<AbstractNode>) { + pub fn set_prev_sibling(&mut self, new_prev_sibling: Option<JS<Node>>) { let doc = self.owner_doc(); - doc.document().wait_until_safe_to_modify_dom(); + doc.get().wait_until_safe_to_modify_dom(); self.prev_sibling = new_prev_sibling } - pub fn set_next_sibling(&mut self, new_next_sibling: Option<AbstractNode>) { + pub fn set_next_sibling(&mut self, new_next_sibling: Option<JS<Node>>) { let doc = self.owner_doc(); - doc.document().wait_until_safe_to_modify_dom(); + doc.get().wait_until_safe_to_modify_dom(); self.next_sibling = new_next_sibling } diff --git a/src/components/script/dom/nodelist.rs b/src/components/script/dom/nodelist.rs index 6857add6600..84de1a56d19 100644 --- a/src/components/script/dom/nodelist.rs +++ b/src/components/script/dom/nodelist.rs @@ -3,43 +3,46 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::NodeListBinding; +use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; -use dom::node::AbstractNode; +use dom::node::{Node, NodeHelpers}; use dom::window::Window; +#[deriving(Encodable)] enum NodeListType { - Simple(~[AbstractNode]), - Children(AbstractNode) + Simple(~[JS<Node>]), + Children(JS<Node>) } +#[deriving(Encodable)] pub struct NodeList { list_type: NodeListType, reflector_: Reflector, - window: @mut Window, + window: JS<Window> } impl NodeList { - pub fn new_inherited(window: @mut Window, + pub fn new_inherited(window: JS<Window>, list_type: NodeListType) -> NodeList { NodeList { list_type: list_type, reflector_: Reflector::new(), - window: window, + window: window } } - pub fn new(window: @mut Window, - list_type: NodeListType) -> @mut NodeList { - reflect_dom_object(@mut NodeList::new_inherited(window, list_type), - window, NodeListBinding::Wrap) + pub fn new(window: JS<Window>, + list_type: NodeListType) -> JS<NodeList> { + reflect_dom_object(~NodeList::new_inherited(window.clone(), list_type), + window.get(), NodeListBinding::Wrap) } - pub fn new_simple_list(window: @mut Window, elements: ~[AbstractNode]) -> @mut NodeList { - NodeList::new(window, Simple(elements)) + pub fn new_simple_list(window: &JS<Window>, elements: ~[JS<Node>]) -> JS<NodeList> { + NodeList::new(window.clone(), Simple(elements)) } - pub fn new_child_list(window: @mut Window, node: AbstractNode) -> @mut NodeList { - NodeList::new(window, Children(node)) + pub fn new_child_list(window: &JS<Window>, node: &JS<Node>) -> JS<NodeList> { + NodeList::new(window.clone(), Children(node.clone())) } pub fn Length(&self) -> u32 { @@ -49,15 +52,15 @@ impl NodeList { } } - pub fn Item(&self, index: u32) -> Option<AbstractNode> { + pub fn Item(&self, index: u32) -> Option<JS<Node>> { match self.list_type { _ if index >= self.Length() => None, - Simple(ref elems) => Some(elems[index]), + Simple(ref elems) => Some(elems[index].clone()), Children(ref node) => node.children().nth(index as uint) } } - pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<AbstractNode> { + pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Node>> { let item = self.Item(index); *found = item.is_some(); item diff --git a/src/components/script/dom/processinginstruction.rs b/src/components/script/dom/processinginstruction.rs index 0fd830be452..85d247fe94a 100644 --- a/src/components/script/dom/processinginstruction.rs +++ b/src/components/script/dom/processinginstruction.rs @@ -3,28 +3,41 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::ProcessingInstructionBinding; +use dom::bindings::codegen::InheritTypes::ProcessingInstructionDerived; +use dom::bindings::js::JS; use dom::characterdata::CharacterData; -use dom::document::AbstractDocument; -use dom::node::{AbstractNode, Node, ProcessingInstructionNodeTypeId}; +use dom::document::Document; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; +use dom::node::{Node, ProcessingInstructionNodeTypeId}; use servo_util::str::DOMString; /// An HTML processing instruction node. +#[deriving(Encodable)] pub struct ProcessingInstruction { characterdata: CharacterData, target: DOMString, } +impl ProcessingInstructionDerived for EventTarget { + fn is_processinginstruction(&self) -> bool { + match self.type_id { + NodeTargetTypeId(ProcessingInstructionNodeTypeId) => true, + _ => false + } + } +} + impl ProcessingInstruction { - pub fn new_inherited(target: DOMString, data: DOMString, document: AbstractDocument) -> ProcessingInstruction { + pub fn new_inherited(target: DOMString, data: DOMString, document: JS<Document>) -> ProcessingInstruction { ProcessingInstruction { characterdata: CharacterData::new_inherited(ProcessingInstructionNodeTypeId, data, document), target: target } } - pub fn new(target: DOMString, data: DOMString, document: AbstractDocument) -> AbstractNode { - let node = ProcessingInstruction::new_inherited(target, data, document); - Node::reflect_node(@mut node, document, ProcessingInstructionBinding::Wrap) + pub fn new(target: DOMString, data: DOMString, document: &JS<Document>) -> JS<ProcessingInstruction> { + let node = ProcessingInstruction::new_inherited(target, data, document.clone()); + Node::reflect_node(~node, document, ProcessingInstructionBinding::Wrap) } } diff --git a/src/components/script/dom/text.rs b/src/components/script/dom/text.rs index 9ed8ba7a8b6..2d81937849e 100644 --- a/src/components/script/dom/text.rs +++ b/src/components/script/dom/text.rs @@ -3,35 +3,48 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::TextBinding; +use dom::bindings::codegen::InheritTypes::TextDerived; +use dom::bindings::js::JS; use dom::bindings::utils::Fallible; use dom::characterdata::CharacterData; -use dom::document::AbstractDocument; -use dom::node::{AbstractNode, Node, TextNodeTypeId}; +use dom::document::Document; +use dom::eventtarget::{EventTarget, NodeTargetTypeId}; +use dom::node::{Node, TextNodeTypeId}; use dom::window::Window; use servo_util::str::DOMString; /// An HTML text node. +#[deriving(Encodable)] pub struct Text { characterdata: CharacterData, } +impl TextDerived for EventTarget { + fn is_text(&self) -> bool { + match self.type_id { + NodeTargetTypeId(TextNodeTypeId) => true, + _ => false + } + } +} + impl Text { - pub fn new_inherited(text: DOMString, document: AbstractDocument) -> Text { + pub fn new_inherited(text: DOMString, document: JS<Document>) -> Text { Text { characterdata: CharacterData::new_inherited(TextNodeTypeId, text, document) } } - pub fn new(text: DOMString, document: AbstractDocument) -> AbstractNode { - let node = Text::new_inherited(text, document); - Node::reflect_node(@mut node, document, TextBinding::Wrap) + pub fn new(text: DOMString, document: &JS<Document>) -> JS<Text> { + let node = Text::new_inherited(text, document.clone()); + Node::reflect_node(~node, document, TextBinding::Wrap) } - pub fn Constructor(owner: @mut Window, text: DOMString) -> Fallible<AbstractNode> { - Ok(Text::new(text.clone(), owner.Document())) + pub fn Constructor(owner: &JS<Window>, text: DOMString) -> Fallible<JS<Text>> { + Ok(Text::new(text.clone(), &owner.get().Document())) } - pub fn SplitText(&self, _offset: u32) -> Fallible<AbstractNode> { + pub fn SplitText(&self, _offset: u32) -> Fallible<JS<Text>> { fail!("unimplemented") } diff --git a/src/components/script/dom/uievent.rs b/src/components/script/dom/uievent.rs index 4ae1c6869b2..92e36edd6a5 100644 --- a/src/components/script/dom/uievent.rs +++ b/src/components/script/dom/uievent.rs @@ -3,47 +3,55 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::UIEventBinding; +use dom::bindings::codegen::InheritTypes::UIEventDerived; +use dom::bindings::js::JS; use dom::bindings::utils::Fallible; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; -use dom::node::AbstractNode; -use dom::event::{AbstractEvent, Event, EventTypeId, UIEventTypeId}; +use dom::event::{Event, EventTypeId, UIEventTypeId}; +use dom::node::Node; use dom::window::Window; use dom::windowproxy::WindowProxy; use servo_util::str::DOMString; +#[deriving(Encodable)] pub struct UIEvent { - parent: Event, - view: Option<@mut WindowProxy>, + event: Event, + view: Option<JS<WindowProxy>>, detail: i32 } +impl UIEventDerived for Event { + fn is_uievent(&self) -> bool { + self.type_id == UIEventTypeId + } +} + impl UIEvent { pub fn new_inherited(type_id: EventTypeId) -> UIEvent { UIEvent { - parent: Event::new_inherited(type_id), + event: Event::new_inherited(type_id), view: None, detail: 0 } } - pub fn new(window: @mut Window) -> AbstractEvent { - let ev = reflect_dom_object(@mut UIEvent::new_inherited(UIEventTypeId), - window, - UIEventBinding::Wrap); - Event::as_abstract(ev) + pub fn new(window: &JS<Window>) -> JS<UIEvent> { + reflect_dom_object(~UIEvent::new_inherited(UIEventTypeId), + window.get(), + UIEventBinding::Wrap) } - pub fn Constructor(owner: @mut Window, + pub fn Constructor(owner: &JS<Window>, type_: DOMString, - init: &UIEventBinding::UIEventInit) -> Fallible<AbstractEvent> { - let ev = UIEvent::new(owner); - ev.mut_uievent().InitUIEvent(type_, init.parent.bubbles, init.parent.cancelable, - init.view, init.detail); + init: &UIEventBinding::UIEventInit) -> Fallible<JS<UIEvent>> { + let mut ev = UIEvent::new(owner); + ev.get_mut().InitUIEvent(type_, init.parent.bubbles, init.parent.cancelable, + init.view.clone(), init.detail); Ok(ev) } - pub fn GetView(&self) -> Option<@mut WindowProxy> { - self.view + pub fn GetView(&self) -> Option<JS<WindowProxy>> { + self.view.clone() } pub fn Detail(&self) -> i32 { @@ -54,9 +62,9 @@ impl UIEvent { type_: DOMString, can_bubble: bool, cancelable: bool, - view: Option<@mut WindowProxy>, + view: Option<JS<WindowProxy>>, detail: i32) { - self.parent.InitEvent(type_, can_bubble, cancelable); + self.event.InitEvent(type_, can_bubble, cancelable); self.view = view; self.detail = detail; } @@ -86,7 +94,7 @@ impl UIEvent { 0 } - pub fn GetRangeParent(&self) -> Option<AbstractNode> { + pub fn GetRangeParent(&self) -> Option<JS<Node>> { //TODO None } @@ -113,10 +121,10 @@ impl UIEvent { impl Reflectable for UIEvent { fn reflector<'a>(&'a self) -> &'a Reflector { - self.parent.reflector() + self.event.reflector() } fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { - self.parent.mut_reflector() + self.event.mut_reflector() } } diff --git a/src/components/script/dom/validitystate.rs b/src/components/script/dom/validitystate.rs index 562b58a16c6..1d7a690ffab 100644 --- a/src/components/script/dom/validitystate.rs +++ b/src/components/script/dom/validitystate.rs @@ -2,18 +2,20 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::codegen::ValidityStateBinding; +use dom::bindings::js::JS; +use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::window::Window; +#[deriving(Encodable)] pub struct ValidityState { reflector_: Reflector, - window: @mut Window, + window: JS<Window>, state: u8, } impl ValidityState { - pub fn new_inherited(window: @mut Window) -> ValidityState { + pub fn new_inherited(window: JS<Window>) -> ValidityState { ValidityState { reflector_: Reflector::new(), window: window, @@ -21,8 +23,9 @@ impl ValidityState { } } - pub fn new(window: @mut Window) -> @mut ValidityState { - reflect_dom_object(@mut ValidityState::new_inherited(window), window, + pub fn new(window: &JS<Window>) -> JS<ValidityState> { + reflect_dom_object(~ValidityState::new_inherited(window.clone()), + window.get(), ValidityStateBinding::Wrap) } } diff --git a/src/components/script/dom/window.rs b/src/components/script/dom/window.rs index 3596c5de9f9..5c78af9f0d2 100644 --- a/src/components/script/dom/window.rs +++ b/src/components/script/dom/window.rs @@ -3,11 +3,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::WindowBinding; -use dom::bindings::utils::{Reflectable, Reflector, Traceable}; -use dom::bindings::utils::{trace_option, trace_reflector}; -use dom::document::AbstractDocument; +use dom::bindings::js::JS; +use dom::bindings::utils::{Reflectable, Reflector}; +use dom::document::Document; +use dom::element::Element; use dom::eventtarget::{EventTarget, WindowTypeId}; -use dom::node::AbstractNode; use dom::console::Console; use dom::location::Location; use dom::navigator::Navigator; @@ -20,7 +20,7 @@ use servo_util::str::DOMString; use servo_util::task::{spawn_named}; use js::glue::*; -use js::jsapi::{JSObject, JSContext, JS_DefineProperty, JSTracer, JSVal}; +use js::jsapi::{JSObject, JSContext, JS_DefineProperty, JSVal}; use js::{JSVAL_NULL, JSPROP_ENUMERATE}; use std::cast; @@ -32,6 +32,8 @@ use std::num; use std::ptr; use std::to_bytes::Cb; +use extra::serialize::{Encoder, Encodable}; + pub enum TimerControlMsg { TimerMessage_Fire(~TimerData), TimerMessage_Close, @@ -43,6 +45,11 @@ pub struct TimerHandle { cancel_chan: Option<Chan<()>>, } +impl<S: Encoder> Encodable<S> for TimerHandle { + fn encode(&self, _: &mut S) { + } +} + impl IterBytes for TimerHandle { fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { self.handle.iter_bytes(lsb0, f) @@ -61,18 +68,28 @@ impl TimerHandle { } } +#[deriving(Encodable)] pub struct Window { eventtarget: EventTarget, page: @mut Page, script_chan: ScriptChan, compositor: @ScriptListener, - console: Option<@mut Console>, - timer_chan: SharedChan<TimerControlMsg>, - location: Option<@mut Location>, - navigator: Option<@mut Navigator>, + console: Option<JS<Console>>, + location: Option<JS<Location>>, + navigator: Option<JS<Navigator>>, image_cache_task: ImageCacheTask, active_timers: ~HashSet<TimerHandle>, next_timer_handle: i32, + extra: Untraceable +} + +struct Untraceable { + timer_chan: SharedChan<TimerControlMsg>, +} + +impl<S: Encoder> Encodable<S> for Untraceable { + fn encode(&self, _: &mut S) { + } } impl Window { @@ -84,7 +101,7 @@ impl Window { #[unsafe_destructor] impl Drop for Window { fn drop(&mut self) { - self.timer_chan.send(TimerMessage_Close); + self.extra.timer_chan.send(TimerMessage_Close); for handle in self.active_timers.iter() { handle.cancel(); } @@ -107,11 +124,11 @@ impl Window { } pub fn Close(&self) { - self.timer_chan.send(TimerMessage_TriggerExit); + self.extra.timer_chan.send(TimerMessage_TriggerExit); } - pub fn Document(&self) -> AbstractDocument { - self.page.frame.unwrap().document + pub fn Document(&self) -> JS<Document> { + self.page.frame.get_ref().document.clone() } pub fn Name(&self) -> DOMString { @@ -141,29 +158,29 @@ impl Window { pub fn Blur(&self) { } - pub fn GetFrameElement(&self) -> Option<AbstractNode> { + pub fn GetFrameElement(&self) -> Option<JS<Element>> { None } - pub fn Location(&mut self) -> @mut Location { + pub fn Location(&mut self) -> JS<Location> { if self.location.is_none() { self.location = Some(Location::new(self, self.page)); } - self.location.unwrap() + self.location.get_ref().clone() } - pub fn Console(&mut self) -> @mut Console { + pub fn Console(&mut self) -> JS<Console> { if self.console.is_none() { self.console = Some(Console::new(self)); } - self.console.unwrap() + self.console.get_ref().clone() } - pub fn Navigator(&mut self) -> @mut Navigator { + pub fn Navigator(&mut self) -> JS<Navigator> { if self.navigator.is_none() { self.navigator = Some(Navigator::new(self)); } - self.navigator.unwrap() + self.navigator.get_ref().clone() } pub fn Confirm(&self, _message: DOMString) -> bool { @@ -202,7 +219,7 @@ impl Window { // to the relevant script handler that will deal with it. let tm = Timer::new().unwrap(); let (cancel_port, cancel_chan) = Chan::new(); - let chan = self.timer_chan.clone(); + let chan = self.extra.timer_chan.clone(); spawn_named("Window:SetTimeout", proc() { let mut tm = tm; let mut timeout_port = tm.oneshot(timeout); @@ -249,26 +266,28 @@ impl Window { script_chan: ScriptChan, compositor: @ScriptListener, image_cache_task: ImageCacheTask) - -> @mut Window { - let win = @mut Window { + -> JS<Window> { + let mut win = ~Window { eventtarget: EventTarget::new_inherited(WindowTypeId), page: page, script_chan: script_chan.clone(), compositor: compositor, console: None, - timer_chan: { - let (timer_port, timer_chan): (Port<TimerControlMsg>, SharedChan<TimerControlMsg>) = SharedChan::new(); - let id = page.id.clone(); - spawn_named("timer controller", proc() { - loop { - match timer_port.recv() { - TimerMessage_Close => break, - TimerMessage_Fire(td) => script_chan.send(FireTimerMsg(id, td)), - TimerMessage_TriggerExit => script_chan.send(ExitWindowMsg(id)), + extra: Untraceable { + timer_chan: { + let (timer_port, timer_chan): (Port<TimerControlMsg>, SharedChan<TimerControlMsg>) = SharedChan::new(); + let id = page.id.clone(); + spawn_named("timer controller", proc() { + loop { + match timer_port.recv() { + TimerMessage_Close => break, + TimerMessage_Fire(td) => script_chan.send(FireTimerMsg(id, td)), + TimerMessage_TriggerExit => script_chan.send(ExitWindowMsg(id)), + } } - } - }); - timer_chan + }); + timer_chan + } }, location: None, navigator: None, @@ -277,7 +296,9 @@ impl Window { next_timer_handle: 0 }; + let raw: *mut Window = &mut *win; let global = WindowBinding::Wrap(cx, ptr::null(), win); + assert!(global.is_not_null()); unsafe { let fn_names = ["window","self"]; for str in fn_names.iter() { @@ -291,17 +312,7 @@ impl Window { } + JS::from_raw(raw) } - win - } -} - -impl Traceable for Window { - fn trace(&self, tracer: *mut JSTracer) { - debug!("tracing window"); - - self.page.frame.map(|frame| trace_reflector(tracer, "document", frame.document.reflector())); - trace_option(tracer, "location", self.location); - trace_option(tracer, "navigator", self.navigator); } } diff --git a/src/components/script/dom/windowproxy.rs b/src/components/script/dom/windowproxy.rs index bae5c5b933f..35304d25d3c 100644 --- a/src/components/script/dom/windowproxy.rs +++ b/src/components/script/dom/windowproxy.rs @@ -2,17 +2,22 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::bindings::utils::{Reflectable, Reflector}; +use dom::bindings::codegen::WindowProxyBinding; +use dom::bindings::js::JS; +use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; +use dom::window::Window; +#[deriving(Encodable)] pub struct WindowProxy { reflector_: Reflector } impl WindowProxy { - pub fn new() -> @mut WindowProxy { - @mut WindowProxy { + pub fn new(owner: JS<Window>) -> JS<WindowProxy> { + let proxy = ~WindowProxy { reflector_: Reflector::new() - } + }; + reflect_dom_object(proxy, owner.get(), WindowProxyBinding::Wrap) } } diff --git a/src/components/script/html/hubbub_html_parser.rs b/src/components/script/html/hubbub_html_parser.rs index d388a77b0e3..cf692d43dfd 100644 --- a/src/components/script/html/hubbub_html_parser.rs +++ b/src/components/script/html/hubbub_html_parser.rs @@ -2,13 +2,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::{NodeBase, NodeCast, TextCast, ElementCast}; +use dom::bindings::codegen::InheritTypes::{HTMLIFrameElementCast, HTMLImageElementCast}; +use dom::bindings::js::JS; +use dom::bindings::utils::Reflectable; +use dom::document::Document; use dom::element::{HTMLLinkElementTypeId, HTMLIframeElementTypeId, HTMLImageElementTypeId}; use dom::htmlelement::HTMLElement; use dom::htmlheadingelement::{Heading1, Heading2, Heading3, Heading4, Heading5, Heading6}; use dom::htmliframeelement::IFrameSize; use dom::htmlformelement::HTMLFormElement; -use dom::node::{AbstractNode, ElementNodeTypeId}; +use dom::node::{ElementNodeTypeId, INode, NodeHelpers}; use dom::types::*; use html::cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser}; use script_task::page_from_context; @@ -36,7 +40,7 @@ macro_rules! handle_element( $ctor: ident $(, $arg:expr )*) => ( if $string == $localName { - return $ctor::new($localName, $document $(, $arg)*); + return ElementCast::from(&$ctor::new($localName, $document $(, $arg)*)); } ) ) @@ -72,16 +76,16 @@ pub struct HtmlParserResult { } trait NodeWrapping { - unsafe fn to_hubbub_node(self) -> hubbub::NodeDataPtr; + unsafe fn to_hubbub_node(&self) -> hubbub::NodeDataPtr; unsafe fn from_hubbub_node(n: hubbub::NodeDataPtr) -> Self; } -impl NodeWrapping for AbstractNode { - unsafe fn to_hubbub_node(self) -> hubbub::NodeDataPtr { - cast::transmute(self) +impl<T: NodeBase+Reflectable> NodeWrapping for JS<T> { + unsafe fn to_hubbub_node(&self) -> hubbub::NodeDataPtr { + cast::transmute(self.get()) } - unsafe fn from_hubbub_node(n: hubbub::NodeDataPtr) -> AbstractNode { - cast::transmute(n) + unsafe fn from_hubbub_node(n: hubbub::NodeDataPtr) -> JS<T> { + JS::from_raw(cast::transmute(n)) } } @@ -158,7 +162,7 @@ fn js_script_listener(to_parent: SharedChan<HtmlDiscoveryMessage>, // Silly macros to handle constructing DOM nodes. This produces bad code and should be optimized // via atomization (issue #85). -pub fn build_element_from_tag(tag: DOMString, document: AbstractDocument) -> AbstractNode { +pub fn build_element_from_tag(tag: DOMString, document: &JS<Document>) -> JS<Element> { // TODO (Issue #85): use atoms handle_element!(document, tag, "a", HTMLAnchorElement); handle_element!(document, tag, "applet", HTMLAppletElement); @@ -240,11 +244,11 @@ pub fn build_element_from_tag(tag: DOMString, document: AbstractDocument) -> Abs handle_element!(document, tag, "ul", HTMLUListElement); handle_element!(document, tag, "video", HTMLVideoElement); - return HTMLUnknownElement::new(tag, document); + return ElementCast::from(&HTMLUnknownElement::new(tag, document)); } pub fn parse_html(cx: *JSContext, - document: AbstractDocument, + document: &mut JS<Document>, url: Url, resource_task: ResourceTask, image_cache_task: ImageCacheTask, @@ -294,8 +298,7 @@ pub fn parse_html(cx: *JSContext, let mut parser = hubbub::Parser("UTF-8", false); debug!("created parser"); - let document_node = AbstractNode::from_document(document); - parser.set_document_node(unsafe { document_node.to_hubbub_node() }); + parser.set_document_node(unsafe { document.to_hubbub_node() }); parser.enable_scripting(true); parser.enable_styling(true); @@ -306,7 +309,7 @@ pub fn parse_html(cx: *JSContext, let tree_handler = hubbub::TreeHandler { create_comment: |data: ~str| { debug!("create comment"); - let comment = Comment::new(data, document); + let comment: JS<Node> = NodeCast::from(&Comment::new(data, document)); unsafe { comment.to_hubbub_node() } }, create_doctype: |doctype: ~hubbub::Doctype| { @@ -315,87 +318,81 @@ pub fn parse_html(cx: *JSContext, public_id: public_id, system_id: system_id, force_quirks: _ } = doctype; - let node = DocumentType::new(name, - public_id, - system_id, - document); + let doctype_node = DocumentType::new(name, public_id, system_id, document); unsafe { - node.to_hubbub_node() + doctype_node.to_hubbub_node() } }, create_element: |tag: ~hubbub::Tag| { debug!("create element"); - let node = build_element_from_tag(tag.name.clone(), document); + let mut element = build_element_from_tag(tag.name.clone(), document); debug!("-- attach attrs"); - node.as_mut_element(|element| { - for attr in tag.attributes.iter() { - element.set_attr(node, - attr.name.clone(), - attr.value.clone()); - } - }); + for attr in tag.attributes.iter() { + let elem = element.clone(); + element.get_mut().set_attr(&elem, + attr.name.clone(), + attr.value.clone()); + } // Spawn additional parsing, network loads, etc. from tag and attrs - match node.type_id() { + match element.get().node.type_id { // Handle CSS style sheets from <link> elements ElementNodeTypeId(HTMLLinkElementTypeId) => { - node.with_imm_element(|element| { - match (element.get_attribute(Null, "rel"), element.get_attribute(Null, "href")) { - (Some(rel), Some(href)) => { - if "stylesheet" == rel.value_ref() { - debug!("found CSS stylesheet: {:s}", href.value_ref()); - let url = parse_url(href.value_ref(), Some(url2.clone())); - css_chan2.send(CSSTaskNewFile(UrlProvenance(url))); - } + match (element.get().get_attribute(Null, "rel"), + element.get().get_attribute(Null, "href")) { + (Some(rel), Some(href)) => { + if "stylesheet" == rel.get().value_ref() { + debug!("found CSS stylesheet: {:s}", href.get().value_ref()); + let url = parse_url(href.get().value_ref(), Some(url2.clone())); + css_chan2.send(CSSTaskNewFile(UrlProvenance(url))); } - _ => {} } - }); + _ => {} + } } ElementNodeTypeId(HTMLIframeElementTypeId) => { let iframe_chan = discovery_chan.clone(); - node.with_mut_iframe_element(|iframe_element| { - let sandboxed = iframe_element.is_sandboxed(); - let elem = &mut iframe_element.htmlelement.element; - let src_opt = elem.get_attribute(Null, "src").map(|x| x.Value()); - for src in src_opt.iter() { - let iframe_url = parse_url(*src, Some(url2.clone())); - iframe_element.frame = Some(iframe_url.clone()); - - // Subpage Id - let subpage_id = next_subpage_id.get(); - next_subpage_id.set(SubpageId(*subpage_id + 1)); - - // Pipeline Id - let pipeline_id = { - let page = page_from_context(cx); - unsafe { (*page).id } - }; - - iframe_element.size = Some(IFrameSize { - pipeline_id: pipeline_id, - subpage_id: subpage_id, - }); - iframe_chan.send(HtmlDiscoveredIFrame((iframe_url, - subpage_id, - sandboxed))); - } - }); + let mut iframe_element: JS<HTMLIFrameElement> = + HTMLIFrameElementCast::to(&element); + let sandboxed = iframe_element.get().is_sandboxed(); + let elem: JS<Element> = ElementCast::from(&iframe_element); + let src_opt = elem.get().get_attribute(Null, "src").map(|x| x.get().Value()); + for src in src_opt.iter() { + let iframe_url = parse_url(*src, Some(url2.clone())); + iframe_element.get_mut().extra.frame = Some(iframe_url.clone()); + + // Subpage Id + let subpage_id = next_subpage_id.get(); + next_subpage_id.set(SubpageId(*subpage_id + 1)); + + // Pipeline Id + let pipeline_id = { + let page = page_from_context(cx); + unsafe { (*page).id } + }; + + iframe_element.get_mut().size = Some(IFrameSize { + pipeline_id: pipeline_id, + subpage_id: subpage_id, + }); + iframe_chan.send(HtmlDiscoveredIFrame((iframe_url, + subpage_id, + sandboxed))); + } } //FIXME: This should be taken care of by set_attr, but we don't have // access to a window so HTMLImageElement::AfterSetAttr bails. ElementNodeTypeId(HTMLImageElementTypeId) => { - node.with_mut_image_element(|image_element| { - image_element.update_image(image_cache_task.clone(), Some(url2.clone())); - }); + let mut image_element: JS<HTMLImageElement> = HTMLImageElementCast::to(&element); + image_element.get_mut().update_image(image_cache_task.clone(), Some(url2.clone())); } _ => {} } - unsafe { node.to_hubbub_node() } + unsafe { element.to_hubbub_node() } }, create_text: |data: ~str| { debug!("create text"); @@ -407,9 +404,9 @@ pub fn parse_html(cx: *JSContext, append_child: |parent: hubbub::NodeDataPtr, child: hubbub::NodeDataPtr| { unsafe { debug!("append child {:x} {:x}", parent, child); - let parent: AbstractNode = NodeWrapping::from_hubbub_node(parent); - let child: AbstractNode = NodeWrapping::from_hubbub_node(child); - parent.AppendChild(child); + let mut parent: JS<Node> = NodeWrapping::from_hubbub_node(parent); + let mut child: JS<Node> = NodeWrapping::from_hubbub_node(child); + parent.AppendChild(&mut child); } child }, @@ -446,51 +443,48 @@ pub fn parse_html(cx: *JSContext, }, set_quirks_mode: |mode| { debug!("set quirks mode"); - document.mut_document().set_quirks_mode(mode); + document.get_mut().set_quirks_mode(mode); }, encoding_change: |encname| { debug!("encoding change"); - document.mut_document().set_encoding_name(encname); + document.get_mut().set_encoding_name(encname); }, complete_script: |script| { unsafe { - let scriptnode: AbstractNode = NodeWrapping::from_hubbub_node(script); - scriptnode.with_imm_element(|script| { - match script.get_attribute(Null, "src") { - Some(src) => { - debug!("found script: {:s}", src.Value()); - let new_url = parse_url(src.value_ref(), Some(url3.clone())); - js_chan2.send(JSTaskNewFile(new_url)); + let script: JS<Element> = NodeWrapping::from_hubbub_node(script); + match script.get().get_attribute(Null, "src") { + Some(src) => { + debug!("found script: {:s}", src.get().Value()); + let new_url = parse_url(src.get().value_ref(), Some(url3.clone())); + js_chan2.send(JSTaskNewFile(new_url)); + } + None => { + let mut data = ~[]; + let scriptnode: JS<Node> = NodeCast::from(&script); + debug!("iterating over children {:?}", scriptnode.first_child()); + for child in scriptnode.children() { + debug!("child = {:?}", child); + let text: JS<Text> = TextCast::to(&child); + data.push(text.get().characterdata.data.to_str()); // FIXME: Bad copy. } - None => { - let mut data = ~[]; - debug!("iterating over children {:?}", scriptnode.first_child()); - for child in scriptnode.children() { - debug!("child = {:?}", child); - child.with_imm_text(|text| { - data.push(text.characterdata.data.to_str()); // FIXME: Bad copy. - }); - } - debug!("script data = {:?}", data); - js_chan2.send(JSTaskNewInlineScript(data.concat(), url3.clone())); - } + debug!("script data = {:?}", data); + js_chan2.send(JSTaskNewInlineScript(data.concat(), url3.clone())); } - }); + } } debug!("complete script"); }, complete_style: |style| { // We've reached the end of a <style> so we can submit all the text to the parser. unsafe { - let style: AbstractNode = NodeWrapping::from_hubbub_node(style); + let style: JS<Node> = NodeWrapping::from_hubbub_node(style); let mut data = ~[]; debug!("iterating over children {:?}", style.first_child()); for child in style.children() { debug!("child = {:?}", child); - child.with_imm_text(|text| { - data.push(text.characterdata.data.to_str()); // FIXME: Bad copy. - }); + let text: JS<Text> = TextCast::to(&child); + data.push(text.get().characterdata.data.to_str()); // FIXME: Bad copy. } debug!("style data = {:?}", data); diff --git a/src/components/script/layout_interface.rs b/src/components/script/layout_interface.rs index 8f6688b84aa..6ebea1809af 100644 --- a/src/components/script/layout_interface.rs +++ b/src/components/script/layout_interface.rs @@ -6,7 +6,7 @@ /// coupling between these two components, and enables the DOM to be placed in a separate crate /// from layout. -use dom::node::{AbstractNode, LayoutDataRef}; +use dom::node::LayoutDataRef; use extra::url::Url; use geom::point::Point2D; @@ -52,14 +52,18 @@ pub enum Msg { /// Synchronous messages that script can send to layout. pub enum LayoutQuery { /// Requests the dimensions of the content box, as in the `getBoundingClientRect()` call. - ContentBoxQuery(AbstractNode, Chan<ContentBoxResponse>), + ContentBoxQuery(TrustedNodeAddress, Chan<ContentBoxResponse>), /// Requests the dimensions of all the content boxes, as in the `getClientRects()` call. - ContentBoxesQuery(AbstractNode, Chan<ContentBoxesResponse>), + ContentBoxesQuery(TrustedNodeAddress, Chan<ContentBoxesResponse>), /// Requests the node containing the point of interest - HitTestQuery(AbstractNode, Point2D<f32>, Chan<Result<HitTestResponse, ()>>), - MouseOverQuery(AbstractNode, Point2D<f32>, Chan<Result<MouseOverResponse, ()>>), + HitTestQuery(TrustedNodeAddress, Point2D<f32>, Chan<Result<HitTestResponse, ()>>), + MouseOverQuery(TrustedNodeAddress, Point2D<f32>, Chan<Result<MouseOverResponse, ()>>), } +/// The address of a node known to be valid. These must only be sent from content -> layout, +/// because we do not trust layout. +pub type TrustedNodeAddress = *c_void; + /// The address of a node. Layout sends these back. They must be validated via /// `from_untrusted_node_address` before they can be used, because we do not trust layout. pub type UntrustedNodeAddress = *c_void; @@ -92,7 +96,7 @@ impl DocumentDamageLevel { /// Note that this is fairly coarse-grained and is separate from layout's notion of the document pub struct DocumentDamage { /// The topmost node in the tree that has changed. - root: AbstractNode, + root: TrustedNodeAddress, /// The amount of damage that occurred. level: DocumentDamageLevel, } @@ -109,7 +113,7 @@ pub enum ReflowGoal { /// Information needed for a reflow. pub struct Reflow { /// The document node. - document_root: AbstractNode, + document_root: TrustedNodeAddress, /// The style changes that need to be done. damage: DocumentDamage, /// The goal of reflow: either to render to the screen or to flush layout info for script. diff --git a/src/components/script/script.rs b/src/components/script/script.rs index 5d270cf2e36..d85df63ba08 100644 --- a/src/components/script/script.rs +++ b/src/components/script/script.rs @@ -26,15 +26,17 @@ mod macros; pub mod dom { pub mod bindings { + pub mod js; pub mod element; - pub mod node; pub mod utils; pub mod callback; pub mod conversions; pub mod proxyhandler; + pub mod trace; pub mod codegen { pub use self::BindingDeclarations::*; pub mod InterfaceTypes; + pub mod InheritTypes; pub mod PrototypeList; pub mod RegisterBindings; pub mod BindingDeclarations; diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index 8a56291b95f..d0c53384231 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -6,14 +6,16 @@ //! and layout tasks. use dom::bindings::codegen::RegisterBindings; -use dom::bindings::utils::{Reflectable, GlobalStaticData}; -use dom::document::AbstractDocument; +use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, DocumentCast, ElementCast}; +use dom::bindings::js::JS; +use dom::bindings::utils::{Reflectable, GlobalStaticData, with_gc_enabled}; +use dom::document::Document; use dom::element::Element; use dom::event::{Event_, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent}; use dom::event::Event; -use dom::eventtarget::AbstractEventTarget; +use dom::eventtarget::EventTarget; use dom::htmldocument::HTMLDocument; -use dom::node::AbstractNode; +use dom::node::{Node, NodeHelpers}; use dom::window::{TimerData, TimerHandle, Window}; use html::hubbub_html_parser::HtmlParserResult; use html::hubbub_html_parser::{HtmlDiscoveredStyle, HtmlDiscoveredIFrame, HtmlDiscoveredScript}; @@ -32,7 +34,7 @@ use geom::size::Size2D; use js::JSVAL_NULL; use js::global::debug_fns; use js::glue::RUST_JSVAL_TO_OBJECT; -use js::jsapi::{JSContext, JSObject}; +use js::jsapi::{JSContext, JSObject, JS_InhibitGC, JS_AllowGC}; use js::jsapi::{JS_CallFunctionValue, JS_GetContextPrivate}; use js::rust::{Compartment, Cx}; use js; @@ -52,6 +54,8 @@ use std::ptr; use std::task; use std::util::replace; +use extra::serialize::{Encoder, Encodable}; + /// Messages used to control the script task. pub enum ScriptMsg { /// Loads a new URL on the specified pipeline. @@ -86,6 +90,11 @@ pub struct NewLayoutInfo { #[deriving(Clone)] pub struct ScriptChan(SharedChan<ScriptMsg>); +impl<S: Encoder> Encodable<S> for ScriptChan { + fn encode(&self, _s: &mut S) { + } +} + impl ScriptChan { /// Creates a new script chan. pub fn new() -> (Port<ScriptMsg>, ScriptChan) { @@ -131,7 +140,13 @@ pub struct Page { resize_event: Option<Size2D<uint>>, /// Pending scroll to fragment event, if any - fragment_node: Option<AbstractNode> + fragment_node: Option<JS<Element>> +} + +impl<S: Encoder> Encodable<S> for Page { + fn encode(&self, s: &mut S) { + self.fragment_node.encode(s); + } } pub struct PageTree { @@ -223,23 +238,24 @@ impl Page { pub fn damage(&mut self, level: DocumentDamageLevel) { let root = match self.frame { None => return, - Some(ref frame) => frame.document.document().GetDocumentElement() + Some(ref frame) => frame.document.get().GetDocumentElement() }; match root { None => {}, Some(root) => { + let root: JS<Node> = NodeCast::from(&root); match self.damage { None => {} Some(ref mut damage) => { // FIXME(pcwalton): This is wrong. We should trace up to the nearest ancestor. - damage.root = root; + damage.root = root.to_trusted_node_address(); damage.level.add(level); return } } self.damage = Some(DocumentDamage { - root: root, + root: root.to_trusted_node_address(), level: level, }) } @@ -292,7 +308,7 @@ impl Page { let root = match self.frame { None => return, Some(ref frame) => { - frame.document.document().GetDocumentElement() + frame.document.get().GetDocumentElement() } }; @@ -314,8 +330,9 @@ impl Page { self.last_reflow_id += 1; // Send new document and relevant styles to layout. + let root: JS<Node> = NodeCast::from(&root); let reflow = ~Reflow { - document_root: root, + document_root: root.to_trusted_node_address(), url: self.url.get_ref().first().clone(), goal: goal, window_size: self.window_size, @@ -333,6 +350,8 @@ impl Page { } pub fn initialize_js_info(&mut self, js_context: @Cx, global: *JSObject) { + assert!(global.is_not_null()); + // Note that the order that these variables are initialized is _not_ arbitrary. Switching // them around can -- and likely will -- lead to things breaking. @@ -352,6 +371,8 @@ impl Page { unsafe { js_context.set_cx_private(page_ptr as *()); + + JS_InhibitGC(js_context.ptr); } self.js_info = Some(JSPageInfo { @@ -363,11 +384,12 @@ impl Page { } /// Information for one frame in the browsing context. +#[deriving(Encodable)] pub struct Frame { /// The document for this frame. - document: AbstractDocument, + document: JS<Document>, /// The window object for this frame. - window: @mut Window, + window: JS<Window>, } /// Encapsulation of the javascript information associated with each frame. @@ -406,7 +428,7 @@ pub struct ScriptTask { /// The JavaScript runtime. js_runtime: js::rust::rt, - mouse_over_targets:Option<~[AbstractNode]> + mouse_over_targets: Option<~[JS<Node>]> } /// Returns the relevant page from the associated JS Context. @@ -565,28 +587,27 @@ impl ScriptTask { fn handle_fire_timer_msg(&mut self, id: PipelineId, timer_data: ~TimerData) { let page = self.page_tree.find(id).expect("ScriptTask: received fire timer msg for a pipeline ID not associated with this script task. This is a bug.").page; - let window = page.frame.expect("ScriptTask: Expect a timeout to have a document").window; - if !window.active_timers.contains(&TimerHandle { handle: timer_data.handle, cancel_chan: None }) { + let mut window = page.frame.get_ref().window.clone(); + if !window.get().active_timers.contains(&TimerHandle { handle: timer_data.handle, cancel_chan: None }) { return; } - window.active_timers.remove(&TimerHandle { handle: timer_data.handle, cancel_chan: None }); - unsafe { - let this_value = if timer_data.args.len() > 0 { + window.get_mut().active_timers.remove(&TimerHandle { handle: timer_data.handle, cancel_chan: None }); + let this_value = if timer_data.args.len() > 0 { + unsafe { RUST_JSVAL_TO_OBJECT(timer_data.args[0]) - } else { - page.js_info.get_ref().js_compartment.global_obj.ptr - }; - - // TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`. - let rval = JSVAL_NULL; - JS_CallFunctionValue(page.js_info.get_ref().js_context.ptr, - this_value, - timer_data.funval, - 0, - ptr::null(), - &rval); + } + } else { + page.js_info.get_ref().js_compartment.global_obj.ptr + }; - } + // TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`. + let rval = JSVAL_NULL; + let cx = page.js_info.get_ref().js_context.ptr; + with_gc_enabled(cx, || { + unsafe { + JS_CallFunctionValue(cx, this_value, timer_data.funval, 0, ptr::null(), &rval); + } + }); } /// Handles a notification that reflow completed. @@ -697,9 +718,9 @@ impl ScriptTask { // Parse HTML. // // Note: We can parse the next document in parallel with any previous documents. - let document = HTMLDocument::new(window, Some(url.clone())); + let mut document = DocumentCast::from(&HTMLDocument::new(&window, Some(url.clone()))); let html_parsing_result = hubbub_html_parser::parse_html(cx.ptr, - document, + &mut document, url.clone(), self.resource_task.clone(), self.image_cache_task.clone(), @@ -711,8 +732,8 @@ impl ScriptTask { // Create the root frame. page.frame = Some(Frame { - document: document, - window: window, + document: document.clone(), + window: window.clone(), }); // Send style sheets over to layout. @@ -747,7 +768,7 @@ impl ScriptTask { } // Kick off the initial reflow of the page. - document.document().content_changed(); + document.get().content_changed(); let fragment = url.fragment.as_ref().map(|ref fragment| fragment.to_owned()); @@ -766,47 +787,50 @@ impl ScriptTask { // Evaluate every script in the document. for file in js_scripts.iter() { - let _ = cx.evaluate_script(compartment.global_obj, - file.data.clone(), - file.url.to_str(), - 1); + with_gc_enabled(cx.ptr, || { + cx.evaluate_script(compartment.global_obj, + file.data.clone(), + file.url.to_str(), + 1); + }); } // We have no concept of a document loader right now, so just dispatch the // "load" event as soon as we've finished executing all scripts parsed during // the initial load. - let event = Event::new(window); - event.mut_event().InitEvent(~"load", false, false); - let doctarget = AbstractEventTarget::from_document(document); - let wintarget = AbstractEventTarget::from_window(window); - window.eventtarget.dispatch_event_with_target(wintarget, Some(doctarget), event); + let mut event = Event::new(&window); + event.get_mut().InitEvent(~"load", false, false); + let doctarget = EventTargetCast::from(&document); + let mut wintarget: JS<EventTarget> = EventTargetCast::from(&window); + let winclone = wintarget.clone(); + wintarget.get_mut().dispatch_event_with_target(&winclone, Some(doctarget), &mut event); page.fragment_node = fragment.map_default(None, |fragid| self.find_fragment_node(page, fragid)); self.constellation_chan.send(LoadCompleteMsg(page.id, url)); } - fn find_fragment_node(&self, page: &mut Page, fragid: ~str) -> Option<AbstractNode> { - let document = page.frame.expect("root frame is None").document; - match document.document().GetElementById(fragid.to_owned()) { + fn find_fragment_node(&self, page: &mut Page, fragid: ~str) -> Option<JS<Element>> { + let document = page.frame.get_ref().document.clone(); + match document.get().GetElementById(fragid.to_owned()) { Some(node) => Some(node), None => { - let doc_node = AbstractNode::from_document(document); + let doc_node: JS<Node> = NodeCast::from(&document); let mut anchors = doc_node.traverse_preorder().filter(|node| node.is_anchor_element()); anchors.find(|node| { - node.with_imm_element(|elem| { - elem.get_attribute(Null, "name").map_default(false, |attr| { - attr.value_ref() == fragid - }) + let elem: JS<Element> = ElementCast::to(node); + elem.get().get_attribute(Null, "name").map_default(false, |attr| { + attr.get().value_ref() == fragid }) - }) + }).map(|node| ElementCast::to(&node)) } } } - fn scroll_fragment_point(&self, pipeline_id: PipelineId, page: &mut Page, node: AbstractNode) { + fn scroll_fragment_point(&self, pipeline_id: PipelineId, page: &mut Page, node: JS<Element>) { let (port, chan) = Chan::new(); - match page.query_layout(ContentBoxQuery(node, chan), port) { + let node: JS<Node> = NodeCast::from(&node); + match page.query_layout(ContentBoxQuery(node.to_trusted_node_address(), chan), port) { ContentBoxResponse(rect) => { let point = Point2D(to_frac_px(rect.origin.x).to_f32().unwrap(), to_frac_px(rect.origin.y).to_f32().unwrap()); @@ -852,18 +876,19 @@ impl ScriptTask { ClickEvent(_button, point) => { debug!("ClickEvent: clicked at {:?}", point); - let document = page.frame.expect("root frame is None").document; - let root = document.document().GetDocumentElement(); + let document = page.frame.get_ref().document.clone(); + let root = document.get().GetDocumentElement(); if root.is_none() { return; } let (port, chan) = Chan::new(); - match page.query_layout(HitTestQuery(root.unwrap(), point, chan), port) { + let root: JS<Node> = NodeCast::from(&root.unwrap()); + match page.query_layout(HitTestQuery(root.to_trusted_node_address(), point, chan), port) { Ok(HitTestResponse(node_address)) => { debug!("node address is {:?}", node_address); - let mut node = AbstractNode::from_untrusted_node_address(self.js_runtime - .ptr, - node_address); + let mut node: JS<Node> = + NodeHelpers::from_untrusted_node_address(self.js_runtime.ptr, + node_address); debug!("clicked on {:s}", node.debug_str()); // Traverse node generations until a node that is an element is @@ -876,11 +901,10 @@ impl ScriptTask { } if node.is_element() { - node.with_imm_element(|element| { - if "a" == element.tag_name { - self.load_url_from_element(page, element) - } - }) + let element: JS<Element> = ElementCast::to(&node); + if "a" == element.get().tag_name { + self.load_url_from_element(page, element.get()) + } } }, Err(()) => debug!("layout query error"), @@ -889,21 +913,22 @@ impl ScriptTask { MouseDownEvent(..) => {} MouseUpEvent(..) => {} MouseMoveEvent(point) => { - let document = page.frame.expect("root frame is None").document; - let root = document.document().GetDocumentElement(); + let document = page.frame.get_ref().document.clone(); + let root = document.get().GetDocumentElement(); if root.is_none() { return; } + let root: JS<Node> = NodeCast::from(&root.unwrap()); let (port, chan) = Chan::new(); - match page.query_layout(MouseOverQuery(root.unwrap(), point, chan), port) { + match page.query_layout(MouseOverQuery(root.to_trusted_node_address(), point, chan), port) { Ok(MouseOverResponse(node_address)) => { - let mut target_list:~[AbstractNode] = ~[]; + let mut target_list: ~[JS<Node>] = ~[]; let mut target_compare = false; match self.mouse_over_targets { Some(ref mut mouse_over_targets) => { - for node in mouse_over_targets.iter() { + for node in mouse_over_targets.mut_iter() { node.set_hover_state(false); } } @@ -911,9 +936,9 @@ impl ScriptTask { } for node_address in node_address.iter() { - let mut node = AbstractNode::from_untrusted_node_address(self.js_runtime - .ptr, - *node_address); + let mut node: JS<Node> = + NodeHelpers::from_untrusted_node_address( + self.js_runtime.ptr, *node_address); // Traverse node generations until a node that is an element is // found. while !node.is_element() { @@ -964,13 +989,13 @@ impl ScriptTask { // if the node's element is "a," load url from href attr let attr = element.get_attribute(Null, "href"); for href in attr.iter() { - debug!("ScriptTask: clicked on link to {:s}", href.Value()); - let click_frag = href.value_ref().starts_with("#"); + debug!("ScriptTask: clicked on link to {:s}", href.get().Value()); + let click_frag = href.get().value_ref().starts_with("#"); let base_url = page.url.as_ref().map(|&(ref url, _)| { url.clone() }); debug!("ScriptTask: current url is {:?}", base_url); - let url = parse_url(href.value_ref(), base_url); + let url = parse_url(href.get().value_ref(), base_url); if click_frag { match self.find_fragment_node(page, url.fragment.unwrap()) { @@ -995,6 +1020,11 @@ fn shut_down_layout(page: @mut Page) { // Destroy all nodes. Setting frame and js_info to None will trigger our // compartment to shutdown, run GC, etc. + + unsafe { + JS_AllowGC(page.js_info.get_ref().js_context.ptr); + } + page.frame = None; page.js_info = None; diff --git a/src/components/style/properties.rs.mako b/src/components/style/properties.rs.mako index 0f2d9cb63e3..a9e4c0b03fd 100644 --- a/src/components/style/properties.rs.mako +++ b/src/components/style/properties.rs.mako @@ -18,8 +18,9 @@ pub use parsing_utils::*; pub use self::common_types::*; use selector_matching::MatchedProperty; -pub mod common_types; +use extra::serialize::{Encodable, Encoder}; +pub mod common_types; <%! @@ -1025,6 +1026,11 @@ pub struct PropertyDeclarationBlock { normal: Arc<~[PropertyDeclaration]>, } +impl<S: Encoder> Encodable<S> for PropertyDeclarationBlock { + fn encode(&self, _: &mut S) { + } +} + pub fn parse_style_attribute(input: &str, base_url: &Url) -> PropertyDeclarationBlock { parse_property_declaration_list(tokenize(input), base_url) diff --git a/src/components/util/namespace.rs b/src/components/util/namespace.rs index ff9eda169c9..b23b235bad0 100644 --- a/src/components/util/namespace.rs +++ b/src/components/util/namespace.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#[deriving(Eq, Clone)] +#[deriving(Eq, Clone, Encodable)] pub enum Namespace { Null, HTML, diff --git a/src/support/spidermonkey/mozjs b/src/support/spidermonkey/mozjs -Subproject 3e633e7e498e64793cb2c75394ed78d507c383a +Subproject 6615c7e7d17a4f1a1c0c2adb39765082f5421b6 diff --git a/src/support/spidermonkey/rust-mozjs b/src/support/spidermonkey/rust-mozjs -Subproject c2f282d8762aec1a55007ff75ef85dfb34e61e7 +Subproject 6a9db14da31271868090963067e1e689904e515 diff --git a/src/test/html/content/test_prototypes.html b/src/test/html/content/test_prototypes.html index 11ee11242b5..cdcc0b9f4ab 100644 --- a/src/test/html/content/test_prototypes.html +++ b/src/test/html/content/test_prototypes.html @@ -5,6 +5,7 @@ <body> <foo-á>foo</foo-á> <script> +is_a(window.document, Node); gc(); // ensure that our document rooting works; subsequent accesses should be valid. is_a(window.document, Node); is(window.document.nodeType, Node.DOCUMENT_NODE); |