Merge master into this branch

This commit is contained in:
Sankha Narayan Guria 2014-02-27 03:31:05 +05:30
commit 1e9fec9172
163 changed files with 4714 additions and 3380 deletions

View file

@ -298,7 +298,7 @@ bindinggen_dependencies := $(addprefix $(BINDINGS_SRC)/, BindingGen.py Bindings.
$(AUTOGEN_SRC_script): $(BINDINGS_SRC)/%Binding.rs: $(bindinggen_dependencies) \ $(AUTOGEN_SRC_script): $(BINDINGS_SRC)/%Binding.rs: $(bindinggen_dependencies) \
$(addprefix $(WEBIDLS_SRC)/, %.webidl) $(addprefix $(WEBIDLS_SRC)/, %.webidl)
@$(call E, "Maybe generating $(shell basename $@)...") @$(call E, "Maybe generating $(shell basename $@)...")
$(Q)PYTHONDONTWRITEBYTECODE=1 $(CFG_PYTHON2) $(BINDINGS_SRC)/pythonpath.py \ $(Q) $(CFG_PYTHON2) $(BINDINGS_SRC)/pythonpath.py \
-I$(BINDINGS_SRC)/parser -I$(BINDINGS_SRC)/ply \ -I$(BINDINGS_SRC)/parser -I$(BINDINGS_SRC)/ply \
-D$(BINDINGS_SRC) \ -D$(BINDINGS_SRC) \
$(BINDINGS_SRC)/BindingGen.py rs \ $(BINDINGS_SRC)/BindingGen.py rs \
@ -317,7 +317,7 @@ $(CACHE_DIR)/.done:
$(BINDINGS_SRC)/ParserResults.pkl: $(globalgen_dependencies) \ $(BINDINGS_SRC)/ParserResults.pkl: $(globalgen_dependencies) \
$(WEBIDLS_script) $(WEBIDLS_script)
$(Q)PYTHONDONTWRITEBYTECODE=1 $(CFG_PYTHON2) $(BINDINGS_SRC)/pythonpath.py \ $(Q) $(CFG_PYTHON2) $(BINDINGS_SRC)/pythonpath.py \
-I$(BINDINGS_SRC)/parser -I$(BINDINGS_SRC)/ply \ -I$(BINDINGS_SRC)/parser -I$(BINDINGS_SRC)/ply \
-D$(BINDINGS_SRC) \ -D$(BINDINGS_SRC) \
$(BINDINGS_SRC)/GlobalGen.py $(BINDINGS_SRC)/Bindings.conf . \ $(BINDINGS_SRC)/GlobalGen.py $(BINDINGS_SRC)/Bindings.conf . \

View file

@ -43,7 +43,7 @@ clean-gfx:
clean-script: clean-script:
@$(call E, "cleaning script") @$(call E, "cleaning script")
$(Q)cd $(B)/src/components/script/ && rm -rf libscript*.dylib libscript*.dSYM libscript*.so $(DONE_script) $(Q)cd $(B)/src/components/script/ && rm -rf libscript*.dylib libscript*.dSYM libscript*.so $(DONE_script) && find $(S)/src/components/script/ -name \*.pyc -delete
clean-style: clean-style:
@$(call E, "cleaning style") @$(call E, "cleaning style")

View file

@ -54,7 +54,6 @@ pub mod font_context;
pub mod font_list; pub mod font_list;
// Misc. // Misc.
pub mod opts;
mod buffer_map; mod buffer_map;
// Platform-specific implementations. // Platform-specific implementations.

View file

@ -4,7 +4,6 @@
use font_context::FontContext; use font_context::FontContext;
use style::computed_values::border_style; use style::computed_values::border_style;
use opts::Opts;
use azure::azure_hl::{B8G8R8A8, Color, ColorPattern, DrawOptions}; use azure::azure_hl::{B8G8R8A8, Color, ColorPattern, DrawOptions};
use azure::azure_hl::{DrawSurfaceOptions, DrawTarget, Linear, StrokeOptions}; use azure::azure_hl::{DrawSurfaceOptions, DrawTarget, Linear, StrokeOptions};
@ -18,6 +17,7 @@ use geom::side_offsets::SideOffsets2D;
use servo_net::image::base::Image; use servo_net::image::base::Image;
use png::{RGBA8, K8, KA8}; use png::{RGBA8, K8, KA8};
use servo_util::geometry::Au; use servo_util::geometry::Au;
use servo_util::opts::Opts;
use std::libc::types::common::c99::uint16_t; use std::libc::types::common::c99::uint16_t;
use std::libc::size_t; use std::libc::size_t;

View file

@ -17,6 +17,7 @@ use servo_msg::compositor_msg::{RenderListener, RenderingRenderState};
use servo_msg::constellation_msg::{ConstellationChan, PipelineId, RendererReadyMsg}; use servo_msg::constellation_msg::{ConstellationChan, PipelineId, RendererReadyMsg};
use servo_msg::constellation_msg::{Failure, FailureMsg}; use servo_msg::constellation_msg::{Failure, FailureMsg};
use servo_msg::platform::surface::NativeSurfaceAzureMethods; use servo_msg::platform::surface::NativeSurfaceAzureMethods;
use servo_util::opts::Opts;
use servo_util::time::{ProfilerChan, profile}; use servo_util::time::{ProfilerChan, profile};
use servo_util::time; use servo_util::time;
use servo_util::task::send_on_failure; use servo_util::task::send_on_failure;
@ -28,7 +29,6 @@ use extra::arc::Arc;
use buffer_map::BufferMap; use buffer_map::BufferMap;
use display_list::DisplayListCollection; use display_list::DisplayListCollection;
use font_context::{FontContext, FontContextInfo}; use font_context::{FontContext, FontContextInfo};
use opts::Opts;
use render_context::RenderContext; use render_context::RenderContext;
pub struct RenderLayer<T> { pub struct RenderLayer<T> {

View file

@ -23,7 +23,6 @@ use geom::matrix::identity;
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
use gfx::opts::Opts;
use layers::layers::{ContainerLayer, ContainerLayerKind}; use layers::layers::{ContainerLayer, ContainerLayerKind};
use layers::platform::surface::NativeCompositingGraphicsContext; use layers::platform::surface::NativeCompositingGraphicsContext;
use layers::rendergl; use layers::rendergl;
@ -34,6 +33,7 @@ use png;
use servo_msg::compositor_msg::{Blank, Epoch, FinishedLoading, IdleRenderState, LayerBufferSet, ReadyState, RenderState}; use servo_msg::compositor_msg::{Blank, Epoch, FinishedLoading, IdleRenderState, LayerBufferSet, ReadyState, RenderState};
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, NavigateMsg, ResizedWindowMsg, LoadUrlMsg, PipelineId}; use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, NavigateMsg, ResizedWindowMsg, LoadUrlMsg, PipelineId};
use servo_msg::constellation_msg; use servo_msg::constellation_msg;
use servo_util::opts::Opts;
use servo_util::time::{profile, ProfilerChan, Timer}; use servo_util::time::{profile, ProfilerChan, Timer};
use servo_util::{time, url}; use servo_util::{time, url};
use std::comm::Port; use std::comm::Port;

View file

@ -12,11 +12,11 @@ use azure::azure_hl::{SourceSurfaceMethods, Color};
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
use gfx::opts::Opts;
use layers::platform::surface::{NativeCompositingGraphicsContext, NativeGraphicsMetadata}; use layers::platform::surface::{NativeCompositingGraphicsContext, NativeGraphicsMetadata};
use servo_msg::compositor_msg::{Epoch, RenderListener, LayerBufferSet, RenderState, ReadyState}; use servo_msg::compositor_msg::{Epoch, RenderListener, LayerBufferSet, RenderState, ReadyState};
use servo_msg::compositor_msg::{ScriptListener, Tile}; use servo_msg::compositor_msg::{ScriptListener, Tile};
use servo_msg::constellation_msg::{ConstellationChan, PipelineId}; use servo_msg::constellation_msg::{ConstellationChan, PipelineId};
use servo_util::opts::Opts;
use servo_util::time::ProfilerChan; use servo_util::time::ProfilerChan;
use std::comm::{Chan, SharedChan, Port}; use std::comm::{Chan, SharedChan, Port};
use std::num::Orderable; use std::num::Orderable;

View file

@ -7,7 +7,6 @@ use compositing::{CompositorChan, LoadComplete, SetIds, SetLayerClipRect, Shutdo
use extra::url::Url; use extra::url::Url;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
use gfx::opts::Opts;
use gfx::render_task; use gfx::render_task;
use pipeline::{Pipeline, CompositionPipeline}; use pipeline::{Pipeline, CompositionPipeline};
use script::script_task::{ResizeMsg, ResizeInactiveMsg, ExitPipelineMsg}; use script::script_task::{ResizeMsg, ResizeInactiveMsg, ExitPipelineMsg};
@ -21,6 +20,7 @@ use servo_msg::constellation_msg;
use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient}; use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient};
use servo_net::resource_task::ResourceTask; use servo_net::resource_task::ResourceTask;
use servo_net::resource_task; use servo_net::resource_task;
use servo_util::opts::Opts;
use servo_util::time::ProfilerChan; use servo_util::time::ProfilerChan;
use servo_util::url::parse_url; use servo_util::url::parse_url;
use servo_util::task::spawn_named; use servo_util::task::spawn_named;

View file

@ -5,12 +5,14 @@
// High-level interface to CSS selector matching. // High-level interface to CSS selector matching.
use css::node_style::StyledNode; use css::node_style::StyledNode;
use layout::construct::FlowConstructor;
use layout::context::LayoutContext;
use layout::extra::LayoutAuxMethods; use layout::extra::LayoutAuxMethods;
use layout::util::{LayoutDataAccess, LayoutDataWrapper}; use layout::util::{LayoutDataAccess, LayoutDataWrapper};
use layout::wrapper::{LayoutElement, LayoutNode}; use layout::wrapper::{LayoutElement, LayoutNode, PostorderNodeMutTraversal, ThreadSafeLayoutNode};
use extra::arc::Arc; use extra::arc::Arc;
use script::layout_interface::LayoutChan; use gfx::font_context::FontContext;
use servo_util::cache::{Cache, LRUCache, SimpleHashCache}; use servo_util::cache::{Cache, LRUCache, SimpleHashCache};
use servo_util::namespace::Null; use servo_util::namespace::Null;
use servo_util::smallvec::{SmallVec, SmallVec0, SmallVec16}; use servo_util::smallvec::{SmallVec, SmallVec0, SmallVec16};
@ -280,15 +282,17 @@ pub enum StyleSharingResult<'ln> {
} }
pub trait MatchMethods { pub trait MatchMethods {
/// Performs aux initialization, selector matching, and cascading sequentially. /// Performs aux initialization, selector matching, cascading, and flow construction
fn match_and_cascade_subtree(&self, /// sequentially.
fn recalc_style_for_subtree(&self,
stylist: &Stylist, stylist: &Stylist,
layout_chan: &LayoutChan, layout_context: &mut LayoutContext,
mut font_context: ~FontContext,
applicable_declarations: &mut ApplicableDeclarations, applicable_declarations: &mut ApplicableDeclarations,
initial_values: &ComputedValues,
applicable_declarations_cache: &mut ApplicableDeclarationsCache, applicable_declarations_cache: &mut ApplicableDeclarationsCache,
style_sharing_candidate_cache: &mut StyleSharingCandidateCache, style_sharing_candidate_cache: &mut StyleSharingCandidateCache,
parent: Option<LayoutNode>); parent: Option<LayoutNode>)
-> ~FontContext;
fn match_node(&self, fn match_node(&self,
stylist: &Stylist, stylist: &Stylist,
@ -381,7 +385,7 @@ impl<'ln> PrivateMatchMethods for LayoutNode<'ln> {
assert!(self.is_element()); assert!(self.is_element());
let parent_node = match parent_node { 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, Some(_) | None => return None,
}; };
@ -455,7 +459,7 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
} }
for (i, &(ref candidate, ())) in style_sharing_candidate_cache.iter().enumerate() { 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) => { Some(shared_style) => {
// Yay, cache hit. Share the style. // Yay, cache hit. Share the style.
let mut layout_data_ref = self.mutate_layout_data(); let mut layout_data_ref = self.mutate_layout_data();
@ -474,19 +478,20 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
CannotShare(true) CannotShare(true)
} }
fn match_and_cascade_subtree(&self, fn recalc_style_for_subtree(&self,
stylist: &Stylist, stylist: &Stylist,
layout_chan: &LayoutChan, layout_context: &mut LayoutContext,
mut font_context: ~FontContext,
applicable_declarations: &mut ApplicableDeclarations, applicable_declarations: &mut ApplicableDeclarations,
initial_values: &ComputedValues,
applicable_declarations_cache: &mut ApplicableDeclarationsCache, applicable_declarations_cache: &mut ApplicableDeclarationsCache,
style_sharing_candidate_cache: &mut StyleSharingCandidateCache, style_sharing_candidate_cache: &mut StyleSharingCandidateCache,
parent: Option<LayoutNode>) { parent: Option<LayoutNode>)
self.initialize_layout_data((*layout_chan).clone()); -> ~FontContext {
self.initialize_layout_data(layout_context.layout_chan.clone());
// First, check to see whether we can share a style with someone. // First, check to see whether we can share a style with someone.
let sharing_result = unsafe { 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. // Otherwise, match and cascade selectors.
@ -497,6 +502,7 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
} }
unsafe { unsafe {
let initial_values = layout_context.initial_css_values.get();
self.cascade_node(parent, self.cascade_node(parent,
initial_values, initial_values,
applicable_declarations, applicable_declarations,
@ -514,14 +520,20 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
} }
for kid in self.children() { for kid in self.children() {
kid.match_and_cascade_subtree(stylist, font_context = kid.recalc_style_for_subtree(stylist,
layout_chan, layout_context,
font_context,
applicable_declarations, applicable_declarations,
initial_values,
applicable_declarations_cache, applicable_declarations_cache,
style_sharing_candidate_cache, style_sharing_candidate_cache,
Some(*self)) Some(self.clone()))
} }
// Construct flows.
let layout_node = ThreadSafeLayoutNode::new(self);
let mut flow_constructor = FlowConstructor::new(layout_context, Some(font_context));
flow_constructor.process(&layout_node);
flow_constructor.unwrap_font_context().unwrap()
} }
unsafe fn cascade_node(&self, unsafe fn cascade_node(&self,

View file

@ -12,10 +12,10 @@ use style::ComputedValues;
pub trait NodeUtil { pub trait NodeUtil {
fn get_css_select_results<'a>(&'a self) -> &'a Arc<ComputedValues>; 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 get_restyle_damage(&self) -> RestyleDamage;
fn set_restyle_damage(self, damage: RestyleDamage); fn set_restyle_damage(&self, damage: RestyleDamage);
} }
impl<'ln> NodeUtil for ThreadSafeLayoutNode<'ln> { impl<'ln> NodeUtil for ThreadSafeLayoutNode<'ln> {
@ -36,14 +36,14 @@ impl<'ln> NodeUtil for ThreadSafeLayoutNode<'ln> {
} }
/// Does this node have a computed style yet? /// 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(); let layout_data_ref = self.borrow_layout_data();
layout_data_ref.get().get_ref().data.style.is_some() layout_data_ref.get().get_ref().data.style.is_some()
} }
/// Get the description of how to account for recent style changes. /// Get the description of how to account for recent style changes.
/// This is a simple bitfield and fine to copy by value. /// 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. // For DOM elements, if we haven't computed damage yet, assume the worst.
// Other nodes don't have styles. // Other nodes don't have styles.
let default = if self.node_is_element() { let default = if self.node_is_element() {
@ -63,7 +63,7 @@ impl<'ln> NodeUtil for ThreadSafeLayoutNode<'ln> {
} }
/// Set the restyle damage field. /// 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(); let mut layout_data_ref = self.mutate_layout_data();
match *layout_data_ref.get() { match *layout_data_ref.get() {
Some(ref mut layout_data) => layout_data.data.restyle_damage = Some(damage.to_int()), Some(ref mut layout_data) => layout_data.data.restyle_damage = Some(damage.to_int()),

View file

@ -68,10 +68,10 @@ pub struct BlockFlow {
} }
impl 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 {
BlockFlow { BlockFlow {
base: BaseFlow::new(constructor.next_flow_id(), node), base: BaseFlow::new((*node).clone()),
box_: Some(Box::new(constructor, node)), box_: Some(Box::new(constructor, node)),
is_root: false, is_root: false,
is_fixed: is_fixed, is_fixed: is_fixed,
@ -80,11 +80,11 @@ impl BlockFlow {
} }
pub fn float_from_node(constructor: &mut FlowConstructor, pub fn float_from_node(constructor: &mut FlowConstructor,
node: ThreadSafeLayoutNode, node: &ThreadSafeLayoutNode,
float_type: FloatType) float_type: FloatType)
-> BlockFlow { -> BlockFlow {
BlockFlow { BlockFlow {
base: BaseFlow::new(constructor.next_flow_id(), node), base: BaseFlow::new((*node).clone()),
box_: Some(Box::new(constructor, node)), box_: Some(Box::new(constructor, node)),
is_root: false, is_root: false,
is_fixed: false, is_fixed: false,
@ -688,13 +688,12 @@ impl Flow for BlockFlow {
/// Dual boxes consume some width first, and the remainder is assigned to all child (block) /// Dual boxes consume some width first, and the remainder is assigned to all child (block)
/// contexts. /// contexts.
fn assign_widths(&mut self, ctx: &mut LayoutContext) { fn assign_widths(&mut self, ctx: &mut LayoutContext) {
debug!("assign_widths({}): assigning width for flow {}", debug!("assign_widths({}): assigning width for flow",
if self.is_float() { if self.is_float() {
"float" "float"
} else { } else {
"block" "block"
}, });
self.base.id);
if self.is_root { if self.is_root {
debug!("Setting root position"); debug!("Setting root position");
@ -803,10 +802,10 @@ impl Flow for BlockFlow {
fn assign_height_inorder(&mut self, ctx: &mut LayoutContext) { fn assign_height_inorder(&mut self, ctx: &mut LayoutContext) {
if self.is_float() { if self.is_float() {
debug!("assign_height_inorder_float: assigning height for float {}", self.base.id); debug!("assign_height_inorder_float: assigning height for float");
self.assign_height_float_inorder(); self.assign_height_float_inorder();
} else { } else {
debug!("assign_height_inorder: assigning height for block {}", self.base.id); debug!("assign_height_inorder: assigning height for block");
self.assign_height_block_base(ctx, true); self.assign_height_block_base(ctx, true);
} }
} }
@ -818,10 +817,10 @@ impl Flow for BlockFlow {
} }
if self.is_float() { if self.is_float() {
debug!("assign_height_float: assigning height for float {}", self.base.id); debug!("assign_height_float: assigning height for float");
self.assign_height_float(ctx); self.assign_height_float(ctx);
} else { } else {
debug!("assign_height: assigning height for block {}", self.base.id); debug!("assign_height: assigning height for block");
// This is the only case in which a block flow can start an inorder // This is the only case in which a block flow can start an inorder
// subtraversal. // subtraversal.
if self.is_root && self.base.num_floats > 0 { if self.is_root && self.base.num_floats > 0 {

View file

@ -384,9 +384,9 @@ def_noncontent_horiz!(right, merge_noncontent_inline_right, clear_noncontent_inl
impl Box { impl Box {
/// Constructs a new `Box` instance. /// Constructs a new `Box` instance.
pub fn new(constructor: &mut FlowConstructor, node: ThreadSafeLayoutNode) -> Box { pub fn new(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode) -> Box {
Box { Box {
node: OpaqueNode::from_thread_safe_layout_node(&node), node: OpaqueNode::from_thread_safe_layout_node(node),
style: node.style().clone(), style: node.style().clone(),
border_box: RefCell::new(Au::zero_rect()), border_box: RefCell::new(Au::zero_rect()),
border: RefCell::new(Zero::zero()), border: RefCell::new(Zero::zero()),

View file

@ -27,17 +27,20 @@ use layout::box_::{InlineInfo, InlineParentInfo, SpecificBoxInfo, UnscannedTextB
use layout::box_::{UnscannedTextBoxInfo}; use layout::box_::{UnscannedTextBoxInfo};
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::float_context::FloatType; use layout::float_context::FloatType;
use layout::flow::{Flow, FlowLeafSet, ImmutableFlowUtils, MutableOwnedFlowUtils}; use layout::flow::{Flow, MutableOwnedFlowUtils};
use layout::inline::InlineFlow; use layout::inline::InlineFlow;
use layout::text::TextRunScanner; use layout::text::TextRunScanner;
use layout::util::{LayoutDataAccess, OpaqueNode}; use layout::util::{LayoutDataAccess, OpaqueNode};
use layout::wrapper::{PostorderNodeMutTraversal, TLayoutNode, ThreadSafeLayoutNode}; use layout::wrapper::{PostorderNodeMutTraversal, TLayoutNode, ThreadSafeLayoutNode};
use gfx::font_context::FontContext; 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::element::{HTMLIframeElementTypeId, HTMLImageElementTypeId, HTMLObjectElementTypeId};
use script::dom::node::{CommentNodeTypeId, DoctypeNodeTypeId, DocumentFragmentNodeTypeId}; use script::dom::node::{CommentNodeTypeId, DoctypeNodeTypeId, DocumentFragmentNodeTypeId};
use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, ProcessingInstructionNodeTypeId}; use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, ProcessingInstructionNodeTypeId};
use script::dom::node::{TextNodeTypeId}; use script::dom::node::{TextNodeTypeId};
use script::dom::text::Text;
use style::computed_values::{display, position, float, white_space}; use style::computed_values::{display, position, float, white_space};
use style::ComputedValues; use style::ComputedValues;
use servo_util::namespace; use servo_util::namespace;
@ -47,8 +50,6 @@ use servo_util::str::is_whitespace;
use extra::url::Url; use extra::url::Url;
use extra::arc::Arc; use extra::arc::Arc;
use std::cell::RefCell;
use std::util; use std::util;
use std::num::Zero; use std::num::Zero;
@ -68,11 +69,11 @@ pub enum ConstructionResult {
} }
impl ConstructionResult { impl ConstructionResult {
fn destroy(&mut self, leaf_set: &FlowLeafSet) { fn destroy(&mut self) {
match *self { match *self {
NoConstructionResult => {} NoConstructionResult => {}
FlowConstructionResult(ref mut flow) => flow.destroy(leaf_set), FlowConstructionResult(ref mut flow) => flow.destroy(),
ConstructionItemConstructionResult(ref mut item) => item.destroy(leaf_set), ConstructionItemConstructionResult(ref mut item) => item.destroy(),
} }
} }
} }
@ -88,12 +89,12 @@ enum ConstructionItem {
} }
impl ConstructionItem { impl ConstructionItem {
fn destroy(&mut self, leaf_set: &FlowLeafSet) { fn destroy(&mut self) {
match *self { match *self {
InlineBoxesConstructionItem(ref mut result) => { InlineBoxesConstructionItem(ref mut result) => {
for splits in result.splits.mut_iter() { for splits in result.splits.mut_iter() {
for split in splits.mut_iter() { for split in splits.mut_iter() {
split.destroy(leaf_set) split.destroy()
} }
} }
} }
@ -146,8 +147,8 @@ struct InlineBlockSplit {
} }
impl InlineBlockSplit { impl InlineBlockSplit {
fn destroy(&mut self, leaf_set: &FlowLeafSet) { fn destroy(&mut self) {
self.flow.destroy(leaf_set) self.flow.destroy()
} }
} }
@ -219,59 +220,66 @@ pub struct FlowConstructor<'a> {
/// The layout context. /// The layout context.
layout_context: &'a mut LayoutContext, layout_context: &'a mut LayoutContext,
/// The next flow ID to assign. /// An optional font context. If this is `None`, then we fetch the font context from the
/// layout context.
/// ///
/// FIXME(pcwalton): This is going to have to be atomic; can't we do something better? /// FIXME(pcwalton): This is pretty bogus and is basically just a workaround for libgreen
next_flow_id: RefCell<int>, /// having slow TLS.
font_context: Option<~FontContext>,
/// The font context.
font_context: ~FontContext,
/// The URL of the page.
url: &'a Url,
} }
impl<'fc> FlowConstructor<'fc> { impl<'a> FlowConstructor<'a> {
/// Creates a new flow constructor. /// Creates a new flow constructor.
pub fn init<'a>(layout_context: &'a mut LayoutContext, url: &'a Url) -> FlowConstructor<'a> { pub fn new(layout_context: &'a mut LayoutContext, font_context: Option<~FontContext>)
let font_context = ~FontContext::new(layout_context.font_context_info.clone()); -> FlowConstructor<'a> {
FlowConstructor { FlowConstructor {
layout_context: layout_context, layout_context: layout_context,
next_flow_id: RefCell::new(0),
font_context: font_context, font_context: font_context,
url: url,
} }
} }
/// Returns the next flow ID and bumps the internal counter. fn font_context<'a>(&'a mut self) -> &'a mut FontContext {
pub fn next_flow_id(&self) -> int { match self.font_context {
let id = self.next_flow_id.get(); Some(ref mut font_context) => {
self.next_flow_id.set(id + 1); let font_context: &mut FontContext = *font_context;
id font_context
}
None => self.layout_context.font_context(),
}
}
/// Destroys this flow constructor and retrieves the font context.
pub fn unwrap_font_context(self) -> Option<~FontContext> {
let FlowConstructor {
font_context,
..
} = self;
font_context
} }
/// Builds the `ImageBoxInfo` for the given image. This is out of line to guide inlining. /// 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 { match url {
None => GenericBox, None => GenericBox,
Some(url) => { Some(url) => {
// FIXME(pcwalton): The fact that image boxes store the cache within them makes // FIXME(pcwalton): The fact that image boxes store the cache within them makes
// little sense to me. // 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. /// 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 { -> SpecificBoxInfo {
match node.type_id() { match node.type_id() {
ElementNodeTypeId(HTMLImageElementTypeId) => self.build_box_info_for_image(node, node.image_url()), 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) => { ElementNodeTypeId(HTMLObjectElementTypeId) => {
self.build_box_info_for_image(node, node.get_object_data(self.url)) let data = node.get_object_data(&self.layout_context.url);
self.build_box_info_for_image(node, data)
} }
TextNodeTypeId => UnscannedTextBox(UnscannedTextBoxInfo::new(&node)), TextNodeTypeId => UnscannedTextBox(UnscannedTextBoxInfo::new(node)),
_ => GenericBox, _ => GenericBox,
} }
} }
@ -284,14 +292,14 @@ impl<'fc> FlowConstructor<'fc> {
fn flush_inline_boxes_to_flow(&mut self, fn flush_inline_boxes_to_flow(&mut self,
boxes: ~[Box], boxes: ~[Box],
flow: &mut ~Flow, flow: &mut ~Flow,
node: ThreadSafeLayoutNode) { node: &ThreadSafeLayoutNode) {
if boxes.len() == 0 { if boxes.len() == 0 {
return return
} }
let mut inline_flow = ~InlineFlow::from_boxes(self.next_flow_id(), node, boxes) as ~Flow; let mut inline_flow = ~InlineFlow::from_boxes((*node).clone(), boxes) as ~Flow;
inline_flow.mark_as_leaf(self.layout_context.flow_leaf_set.get()); TextRunScanner::new().scan_for_runs(self.font_context(), inline_flow);
TextRunScanner::new().scan_for_runs(self.font_context, inline_flow); inline_flow.finish(self.layout_context);
flow.add_new_child(inline_flow) flow.add_new_child(inline_flow)
} }
@ -301,7 +309,7 @@ impl<'fc> FlowConstructor<'fc> {
fn flush_inline_boxes_to_flow_if_necessary(&mut self, fn flush_inline_boxes_to_flow_if_necessary(&mut self,
opt_boxes: &mut Option<~[Box]>, opt_boxes: &mut Option<~[Box]>,
flow: &mut ~Flow, flow: &mut ~Flow,
node: ThreadSafeLayoutNode) { node: &ThreadSafeLayoutNode) {
let opt_boxes = util::replace(opt_boxes, None); let opt_boxes = util::replace(opt_boxes, None);
if opt_boxes.len() > 0 { if opt_boxes.len() > 0 {
self.flush_inline_boxes_to_flow(opt_boxes.to_vec(), flow, node) self.flush_inline_boxes_to_flow(opt_boxes.to_vec(), flow, node)
@ -311,7 +319,7 @@ impl<'fc> FlowConstructor<'fc> {
/// Builds the children flows underneath a node with `display: block`. After this call, /// 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 /// other `BlockFlow`s or `InlineFlow`s will be populated underneath this node, depending on
/// whether {ib} splits needed to happen. /// 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. // Gather up boxes for the inline flows we might need to create.
let mut opt_boxes_for_inline_flow = None; let mut opt_boxes_for_inline_flow = None;
let mut first_box = true; let mut first_box = true;
@ -396,17 +404,13 @@ impl<'fc> FlowConstructor<'fc> {
node); node);
// The flow is done. If it ended up with no kids, add the flow to the leaf set. // The flow is done. If it ended up with no kids, add the flow to the leaf set.
if flow.child_count() == 0 { flow.finish(self.layout_context)
flow.mark_as_leaf(self.layout_context.flow_leaf_set.get())
} else {
flow.mark_as_nonleaf()
}
} }
/// Builds a flow for a node with `display: block`. This yields a `BlockFlow` with possibly /// 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 /// other `BlockFlow`s or `InlineFlow`s underneath it, depending on whether {ib} splits needed
/// to happen. /// 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; let mut flow = ~BlockFlow::from_node(self, node, is_fixed) as ~Flow;
self.build_children_of_block_flow(&mut flow, node); self.build_children_of_block_flow(&mut flow, node);
flow flow
@ -414,7 +418,7 @@ impl<'fc> FlowConstructor<'fc> {
/// Builds the flow for a node with `float: {left|right}`. This yields a float `BlockFlow` with /// Builds the flow for a node with `float: {left|right}`. This yields a float `BlockFlow` with
/// a `BlockFlow` underneath it. /// 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 { -> ~Flow {
let mut flow = ~BlockFlow::float_from_node(self, node, float_type) as ~Flow; let mut flow = ~BlockFlow::float_from_node(self, node, float_type) as ~Flow;
self.build_children_of_block_flow(&mut flow, node); self.build_children_of_block_flow(&mut flow, node);
@ -425,7 +429,7 @@ impl<'fc> FlowConstructor<'fc> {
/// Concatenates the boxes of kids, adding in our own borders/padding/margins if necessary. /// Concatenates the boxes of kids, adding in our own borders/padding/margins if necessary.
/// Returns the `InlineBoxesConstructionResult`, if any. There will be no /// Returns the `InlineBoxesConstructionResult`, if any. There will be no
/// `InlineBoxesConstructionResult` if this node consisted entirely of ignorable whitespace. /// `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 { -> ConstructionResult {
let mut opt_inline_block_splits = None; let mut opt_inline_block_splits = None;
let mut opt_box_accumulator = None; let mut opt_box_accumulator = None;
@ -542,10 +546,10 @@ impl<'fc> FlowConstructor<'fc> {
fn set_inline_info_for_inline_child(&mut self, fn set_inline_info_for_inline_child(&mut self,
boxes: &~[&Box], boxes: &~[&Box],
parent_node: ThreadSafeLayoutNode) { parent_node: &ThreadSafeLayoutNode) {
let parent_box = Box::new(self, parent_node); let parent_box = Box::new(self, parent_node);
let font_style = parent_box.font_style(); let font_style = parent_box.font_style();
let font_group = self.font_context.get_resolved_font_for_style(&font_style); let font_group = self.font_context().get_resolved_font_for_style(&font_style);
let (font_ascent,font_descent) = font_group.borrow().with_mut( |fg| { let (font_ascent,font_descent) = font_group.borrow().with_mut( |fg| {
fg.fonts[0].borrow().with_mut( |font| { fg.fonts[0].borrow().with_mut( |font| {
(font.metrics.ascent,font.metrics.descent) (font.metrics.ascent,font.metrics.descent)
@ -580,7 +584,7 @@ impl<'fc> FlowConstructor<'fc> {
style: parent_box.style.clone(), style: parent_box.style.clone(),
font_ascent: font_ascent, font_ascent: font_ascent,
font_descent: font_descent, font_descent: font_descent,
node: OpaqueNode::from_thread_safe_layout_node(&parent_node), node: OpaqueNode::from_thread_safe_layout_node(parent_node),
}); });
}, },
&None => {} &None => {}
@ -589,7 +593,7 @@ impl<'fc> FlowConstructor<'fc> {
} }
/// Creates an `InlineBoxesConstructionResult` for replaced content. Replaced content doesn't /// 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`. /// 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 { -> ConstructionResult {
for kid in node.children() { for kid in node.children() {
kid.set_flow_construction_result(NoConstructionResult) kid.set_flow_construction_result(NoConstructionResult)
@ -597,7 +601,7 @@ impl<'fc> FlowConstructor<'fc> {
// If this node is ignorable whitespace, bail out now. // If this node is ignorable whitespace, bail out now.
if node.is_ignorable_whitespace() { 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( return ConstructionItemConstructionResult(WhitespaceConstructionItem(
opaque_node, opaque_node,
node.style().clone())) node.style().clone()))
@ -614,7 +618,7 @@ impl<'fc> FlowConstructor<'fc> {
/// Builds one or more boxes for a node with `display: inline`. This yields an /// Builds one or more boxes for a node with `display: inline`. This yields an
/// `InlineBoxesConstructionResult`. /// `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? // Is this node replaced content?
if !node.is_replaced_content() { if !node.is_replaced_content() {
// Go to a path that concatenates our kids' boxes. // Go to a path that concatenates our kids' boxes.
@ -630,7 +634,7 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
// `#[inline(always)]` because this is always called from the traversal function and for some // `#[inline(always)]` because this is always called from the traversal function and for some
// reason LLVM's inlining heuristics go awry here. // reason LLVM's inlining heuristics go awry here.
#[inline(always)] #[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. // Get the `display` property for this node, and determine whether this node is floated.
let (display, float, position) = match node.type_id() { let (display, float, position) = match node.type_id() {
ElementNodeTypeId(_) => { ElementNodeTypeId(_) => {
@ -641,7 +645,7 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
CommentNodeTypeId | CommentNodeTypeId |
DoctypeNodeTypeId | DoctypeNodeTypeId |
DocumentFragmentNodeTypeId | DocumentFragmentNodeTypeId |
DocumentNodeTypeId(_) | DocumentNodeTypeId |
ProcessingInstructionNodeTypeId => (display::none, float::none, position::static_), ProcessingInstructionNodeTypeId => (display::none, float::none, position::static_),
}; };
@ -654,7 +658,7 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
(display::none, _, _) => { (display::none, _, _) => {
for child in node.children() { for child in node.children() {
let mut old_result = child.swap_out_construction_result(); let mut old_result = child.swap_out_construction_result();
old_result.destroy(self.layout_context.flow_leaf_set.get()) old_result.destroy()
} }
} }
@ -693,39 +697,40 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
/// A utility trait with some useful methods for node queries. /// A utility trait with some useful methods for node queries.
trait NodeUtils { trait NodeUtils {
/// Returns true if this node doesn't render its kids and false otherwise. /// 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. /// 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. /// 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 /// Replaces the flow construction result in a node with `NoConstructionResult` and returns the
/// old value. /// old value.
fn swap_out_construction_result(self) -> ConstructionResult; fn swap_out_construction_result(&self) -> ConstructionResult;
} }
impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> { impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
fn is_replaced_content(self) -> bool { fn is_replaced_content(&self) -> bool {
match self.type_id() { match self.type_id() {
TextNodeTypeId | TextNodeTypeId |
ProcessingInstructionNodeTypeId | ProcessingInstructionNodeTypeId |
CommentNodeTypeId | CommentNodeTypeId |
DoctypeNodeTypeId | DoctypeNodeTypeId |
DocumentFragmentNodeTypeId | DocumentFragmentNodeTypeId |
DocumentNodeTypeId(_) | DocumentNodeTypeId |
ElementNodeTypeId(HTMLImageElementTypeId) => true, ElementNodeTypeId(HTMLImageElementTypeId) => true,
ElementNodeTypeId(HTMLObjectElementTypeId) => self.has_object_data(), ElementNodeTypeId(HTMLObjectElementTypeId) => self.has_object_data(),
ElementNodeTypeId(_) => false, ElementNodeTypeId(_) => false,
} }
} }
fn is_ignorable_whitespace(self) -> bool { fn is_ignorable_whitespace(&self) -> bool {
match self.type_id() { match self.type_id() {
TextNodeTypeId => { TextNodeTypeId => {
unsafe { 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 return false
} }
@ -746,7 +751,7 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
} }
#[inline(always)] #[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(); let mut layout_data_ref = self.mutate_layout_data();
match *layout_data_ref.get() { match *layout_data_ref.get() {
Some(ref mut layout_data) => layout_data.data.flow_construction_result = result, Some(ref mut layout_data) => layout_data.data.flow_construction_result = result,
@ -755,7 +760,7 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
} }
#[inline(always)] #[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(); let mut layout_data_ref = self.mutate_layout_data();
match *layout_data_ref.get() { match *layout_data_ref.get() {
Some(ref mut layout_data) => { Some(ref mut layout_data) => {
@ -769,29 +774,29 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
/// Methods for interacting with HTMLObjectElement nodes /// Methods for interacting with HTMLObjectElement nodes
trait ObjectElement { trait ObjectElement {
/// Returns None if this node is not matching attributes. /// 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. /// 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 /// 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> { 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, "type") } ),
self.with_element(|e| { e.get_attr(&namespace::Null, "data") } )) 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() { match self.get_type_and_data() {
(None, Some(uri)) => is_image_data(uri), (None, Some(uri)) => is_image_data(uri),
_ => false _ => 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() { match self.get_type_and_data() {
(None, Some(uri)) if is_image_data(uri) => Some(parse_url(uri, Some(base_url.clone()))), (None, Some(uri)) if is_image_data(uri) => Some(parse_url(uri, Some(base_url.clone()))),
_ => None _ => None

View file

@ -5,11 +5,10 @@
//! Data needed by the layout task. //! Data needed by the layout task.
use css::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache}; use css::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
use layout::flow::FlowLeafSet;
use layout::util::OpaqueNode; use layout::util::OpaqueNode;
use layout::wrapper::DomLeafSet;
use extra::arc::{Arc, MutexArc}; use extra::arc::{Arc, MutexArc};
use extra::url::Url;
use geom::size::Size2D; use geom::size::Size2D;
use gfx::font_context::{FontContext, FontContextInfo}; use gfx::font_context::{FontContext, FontContextInfo};
use green::task::GreenTask; use green::task::GreenTask;
@ -17,6 +16,7 @@ use script::layout_interface::LayoutChan;
use servo_msg::constellation_msg::ConstellationChan; use servo_msg::constellation_msg::ConstellationChan;
use servo_net::local_image_cache::LocalImageCache; use servo_net::local_image_cache::LocalImageCache;
use servo_util::geometry::Au; use servo_util::geometry::Au;
use servo_util::opts::Opts;
use std::cast; use std::cast;
use std::ptr; use std::ptr;
use std::rt::Runtime; use std::rt::Runtime;
@ -47,15 +47,9 @@ pub struct LayoutContext {
/// A channel up to the constellation. /// A channel up to the constellation.
constellation_chan: ConstellationChan, constellation_chan: ConstellationChan,
/// The set of leaf DOM nodes.
dom_leaf_set: Arc<DomLeafSet>,
/// A channel up to the layout task. /// A channel up to the layout task.
layout_chan: LayoutChan, layout_chan: LayoutChan,
/// The set of leaf flows.
flow_leaf_set: Arc<FlowLeafSet>,
/// Information needed to construct a font context. /// Information needed to construct a font context.
font_context_info: FontContextInfo, font_context_info: FontContextInfo,
@ -69,11 +63,18 @@ pub struct LayoutContext {
/// The root node at which we're starting the layout. /// The root node at which we're starting the layout.
reflow_root: OpaqueNode, reflow_root: OpaqueNode,
/// The URL.
url: Url,
/// The command line options.
opts: Opts,
} }
impl LayoutContext { impl LayoutContext {
pub fn font_context<'a>(&'a mut self) -> &'a mut FontContext { pub fn font_context<'a>(&'a mut self) -> &'a mut FontContext {
// Sanity check. // Sanity check.
{
let mut task = Local::borrow(None::<Task>); let mut task = Local::borrow(None::<Task>);
match task.get().maybe_take_runtime::<GreenTask>() { match task.get().maybe_take_runtime::<GreenTask>() {
Some(green) => { Some(green) => {
@ -82,6 +83,7 @@ impl LayoutContext {
} }
None => {} None => {}
} }
}
unsafe { unsafe {
if FONT_CONTEXT == ptr::mut_null() { if FONT_CONTEXT == ptr::mut_null() {

View file

@ -10,15 +10,15 @@ use script::layout_interface::LayoutChan;
/// Functionality useful for querying the layout-specific data on DOM nodes. /// Functionality useful for querying the layout-specific data on DOM nodes.
pub trait LayoutAuxMethods { pub trait LayoutAuxMethods {
fn initialize_layout_data(self, chan: LayoutChan); fn initialize_layout_data(&self, chan: LayoutChan);
fn initialize_style_for_subtree(self, chan: LayoutChan); fn initialize_style_for_subtree(&self, chan: LayoutChan);
} }
impl<'ln> LayoutAuxMethods for LayoutNode<'ln> { impl<'ln> LayoutAuxMethods for LayoutNode<'ln> {
/// Resets layout data and styles for the node. /// Resets layout data and styles for the node.
/// ///
/// FIXME(pcwalton): Do this as part of box building instead of in a traversal. /// 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(); let mut layout_data_ref = self.mutate_layout_data();
match *layout_data_ref.get() { match *layout_data_ref.get() {
None => { None => {
@ -34,7 +34,7 @@ impl<'ln> LayoutAuxMethods for LayoutNode<'ln> {
/// Resets layout data and styles for a Node tree. /// Resets layout data and styles for a Node tree.
/// ///
/// FIXME(pcwalton): Do this as part of box building instead of in a traversal. /// 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() { for n in self.traverse_preorder() {
n.initialize_layout_data(chan.clone()); n.initialize_layout_data(chan.clone());
} }

View file

@ -33,7 +33,7 @@ use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
use layout::float_context::{FloatContext, Invalid}; use layout::float_context::{FloatContext, Invalid};
use layout::incremental::RestyleDamage; use layout::incremental::RestyleDamage;
use layout::inline::InlineFlow; use layout::inline::InlineFlow;
use layout::parallel::{FlowParallelInfo, UnsafeFlow}; use layout::parallel::FlowParallelInfo;
use layout::parallel; use layout::parallel;
use layout::wrapper::ThreadSafeLayoutNode; use layout::wrapper::ThreadSafeLayoutNode;
use layout::flow_list::{FlowList, Link, Rawlink, FlowListIterator, MutFlowListIterator}; use layout::flow_list::{FlowList, Link, Rawlink, FlowListIterator, MutFlowListIterator};
@ -45,7 +45,6 @@ use geom::rect::Rect;
use gfx::display_list::{ClipDisplayItemClass, DisplayListCollection, DisplayList}; use gfx::display_list::{ClipDisplayItemClass, DisplayListCollection, DisplayList};
use layout::display_list_builder::ToGfxColor; use layout::display_list_builder::ToGfxColor;
use gfx::color::Color; use gfx::color::Color;
use servo_util::concurrentmap::{ConcurrentHashMap, ConcurrentHashMapIterator};
use servo_util::geometry::Au; use servo_util::geometry::Au;
use std::cast; use std::cast;
use std::cell::RefCell; use std::cell::RefCell;
@ -215,7 +214,7 @@ pub trait MutableFlowUtils {
-> bool; -> bool;
/// Destroys the flow. /// Destroys the flow.
fn destroy(self, leaf_set: &FlowLeafSet); fn destroy(self);
} }
pub trait MutableOwnedFlowUtils { pub trait MutableOwnedFlowUtils {
@ -223,15 +222,16 @@ pub trait MutableOwnedFlowUtils {
/// it's present. /// it's present.
fn add_new_child(&mut self, new_child: ~Flow); fn add_new_child(&mut self, new_child: ~Flow);
/// Marks the flow as a leaf. The flow must not have children and must not be marked as a /// Finishes a flow. Once a flow is finished, no more child flows or boxes may be added to it.
/// nonleaf. /// This will normally run the bubble-widths (minimum and preferred -- i.e. intrinsic -- width)
fn mark_as_leaf(&mut self, leaf_set: &FlowLeafSet); /// calculation, unless the global `bubble_widths_separately` flag is on.
///
/// Marks the flow as a nonleaf. The flow must not be marked as a leaf. /// All flows must be finished at some point, or they will not have their intrinsic widths
fn mark_as_nonleaf(&mut self); /// properly computed. (This is not, however, a memory safety problem.)
fn finish(&mut self, context: &mut LayoutContext);
/// Destroys the flow. /// Destroys the flow.
fn destroy(&mut self, leaf_set: &FlowLeafSet); fn destroy(&mut self);
} }
pub enum FlowClass { pub enum FlowClass {
@ -455,13 +455,6 @@ bitfield!(FlowFlags, override_overline, set_override_overline, 0b0000_0100)
// NB: If you update this, you need to update TEXT_DECORATION_OVERRIDE_BITMASK. // NB: If you update this, you need to update TEXT_DECORATION_OVERRIDE_BITMASK.
bitfield!(FlowFlags, override_line_through, set_override_line_through, 0b0000_1000) bitfield!(FlowFlags, override_line_through, set_override_line_through, 0b0000_1000)
// Whether this flow is marked as a leaf. Flows marked as leaves must not have any more kids added
// to them.
bitfield!(FlowFlags, is_leaf, set_is_leaf, 0b0100_0000)
// Whether this flow is marked as a nonleaf. Flows marked as nonleaves must have children.
bitfield!(FlowFlags, is_nonleaf, set_is_nonleaf, 0b1000_0000)
// The text alignment for this flow. // The text alignment for this flow.
impl FlowFlags { impl FlowFlags {
#[inline] #[inline]
@ -499,9 +492,6 @@ pub struct BaseFlow {
next_sibling: Link, next_sibling: Link,
prev_sibling: Rawlink, prev_sibling: Rawlink,
/* TODO (Issue #87): debug only */
id: int,
/* layout computations */ /* layout computations */
// TODO: min/pref and position are used during disjoint phases of // TODO: min/pref and position are used during disjoint phases of
// layout; maybe combine into a single enum to save space. // layout; maybe combine into a single enum to save space.
@ -563,7 +553,7 @@ impl Iterator<@Box> for BoxIterator {
impl BaseFlow { impl BaseFlow {
#[inline] #[inline]
pub fn new(id: int, node: ThreadSafeLayoutNode) -> BaseFlow { pub fn new(node: ThreadSafeLayoutNode) -> BaseFlow {
let style = node.style(); let style = node.style();
BaseFlow { BaseFlow {
restyle_damage: node.restyle_damage(), restyle_damage: node.restyle_damage(),
@ -572,8 +562,6 @@ impl BaseFlow {
next_sibling: None, next_sibling: None,
prev_sibling: Rawlink::none(), prev_sibling: Rawlink::none(),
id: id,
min_width: Au::new(0), min_width: Au::new(0),
pref_width: Au::new(0), pref_width: Au::new(0),
position: Au::zero_rect(), position: Au::zero_rect(),
@ -740,7 +728,7 @@ impl<'a> MutableFlowUtils for &'a mut Flow {
mut index: uint, mut index: uint,
lists: &RefCell<DisplayListCollection<E>>) lists: &RefCell<DisplayListCollection<E>>)
-> bool { -> bool {
debug!("Flow: building display list for f{}", base(self).id); debug!("Flow: building display list");
index = match self.class() { index = match self.class() {
BlockFlowClass => self.as_block().build_display_list_block(builder, container_block_size, dirty, index, lists), BlockFlowClass => self.as_block().build_display_list_block(builder, container_block_size, dirty, index, lists),
InlineFlowClass => self.as_inline().build_display_list_inline(builder, container_block_size, dirty, index, lists), InlineFlowClass => self.as_inline().build_display_list_inline(builder, container_block_size, dirty, index, lists),
@ -797,18 +785,9 @@ impl<'a> MutableFlowUtils for &'a mut Flow {
} }
/// Destroys the flow. /// Destroys the flow.
fn destroy(self, leaf_set: &FlowLeafSet) { fn destroy(self) {
let is_leaf = {
let base = mut_base(self);
base.children.len() == 0
};
if is_leaf {
leaf_set.remove(self);
} else {
for kid in child_iter(self) { for kid in child_iter(self) {
kid.destroy(leaf_set) kid.destroy()
}
} }
mut_base(self).destroyed = true mut_base(self).destroyed = true
@ -824,84 +803,26 @@ impl MutableOwnedFlowUtils for ~Flow {
} }
let base = mut_base(*self); let base = mut_base(*self);
assert!(!base.flags_info.flags.is_leaf());
base.children.push_back(new_child); base.children.push_back(new_child);
let _ = base.parallel.children_count.fetch_add(1, Relaxed); let _ = base.parallel.children_count.fetch_add(1, Relaxed);
} }
/// Marks the flow as a leaf. The flow must not have children and must not be marked as a /// Finishes a flow. Once a flow is finished, no more child flows or boxes may be added to it.
/// nonleaf. /// This will normally run the bubble-widths (minimum and preferred -- i.e. intrinsic -- width)
fn mark_as_leaf(&mut self, leaf_set: &FlowLeafSet) { /// calculation, unless the global `bubble_widths_separately` flag is on.
{ ///
let base = mut_base(*self); /// All flows must be finished at some point, or they will not have their intrinsic widths
if base.flags_info.flags.is_nonleaf() { /// properly computed. (This is not, however, a memory safety problem.)
fail!("attempted to mark a nonleaf flow as a leaf!") fn finish(&mut self, context: &mut LayoutContext) {
if !context.opts.bubble_widths_separately {
self.bubble_widths(context)
} }
if base.children.len() != 0 {
fail!("attempted to mark a flow with children as a leaf!")
}
base.flags_info.flags.set_is_leaf(true)
}
let self_borrowed: &Flow = *self;
leaf_set.insert(self_borrowed);
}
/// Marks the flow as a nonleaf. The flow must not be marked as a leaf.
fn mark_as_nonleaf(&mut self) {
let base = mut_base(*self);
if base.flags_info.flags.is_leaf() {
fail!("attempted to mark a leaf flow as a nonleaf!")
}
base.flags_info.flags.set_is_nonleaf(true)
// We don't check to make sure there are no children as they might be added later.
} }
/// Destroys the flow. /// Destroys the flow.
fn destroy(&mut self, leaf_set: &FlowLeafSet) { fn destroy(&mut self) {
let self_borrowed: &mut Flow = *self; let self_borrowed: &mut Flow = *self;
self_borrowed.destroy(leaf_set); self_borrowed.destroy();
} }
} }
/// Keeps track of the leaves of the flow tree. This is used to efficiently start bottom-up
/// parallel traversals.
pub struct FlowLeafSet {
priv set: ConcurrentHashMap<UnsafeFlow,()>,
}
impl FlowLeafSet {
/// Creates a new flow leaf set.
pub fn new() -> FlowLeafSet {
FlowLeafSet {
set: ConcurrentHashMap::with_locks_and_buckets(64, 256),
}
}
/// Inserts a newly-created flow into the leaf set.
fn insert(&self, flow: &Flow) {
self.set.insert(parallel::borrowed_flow_to_unsafe_flow(flow), ());
}
/// Removes a flow from the leaf set. Asserts that the flow was indeed in the leaf set. (This
/// invariant is needed for memory safety, as there must always be exactly one leaf set.)
fn remove(&self, flow: &Flow) {
if !self.contains(flow) {
fail!("attempted to remove a flow from the leaf set that wasn't in the set!")
}
let flow = parallel::borrowed_flow_to_unsafe_flow(flow);
self.set.remove(&flow);
}
pub fn contains(&self, flow: &Flow) -> bool {
let flow = parallel::borrowed_flow_to_unsafe_flow(flow);
self.set.contains_key(&flow)
}
pub fn clear(&self) {
self.set.clear()
}
pub fn iter<'a>(&'a self) -> ConcurrentHashMapIterator<'a,UnsafeFlow,()> {
self.set.iter()
}
}

View file

@ -84,8 +84,8 @@ impl LineboxScanner {
self.floats.clone() self.floats.clone()
} }
fn reset_scanner(&mut self, flow: &mut InlineFlow) { fn reset_scanner(&mut self) {
debug!("Resetting line box scanner's state for flow f{:d}.", flow.base.id); debug!("Resetting line box scanner's state for flow.");
self.lines = ~[]; self.lines = ~[];
self.new_boxes = ~[]; self.new_boxes = ~[];
self.cur_y = Au::new(0); self.cur_y = Au::new(0);
@ -99,7 +99,7 @@ impl LineboxScanner {
} }
pub fn scan_for_lines(&mut self, flow: &mut InlineFlow) { pub fn scan_for_lines(&mut self, flow: &mut InlineFlow) {
self.reset_scanner(flow); self.reset_scanner();
loop { loop {
// acquire the next box to lay out from work list or box list // acquire the next box to lay out from work list or box list
@ -142,9 +142,8 @@ impl LineboxScanner {
} }
fn swap_out_results(&mut self, flow: &mut InlineFlow) { fn swap_out_results(&mut self, flow: &mut InlineFlow) {
debug!("LineboxScanner: Propagating scanned lines[n={:u}] to inline flow f{:d}", debug!("LineboxScanner: Propagating scanned lines[n={:u}] to inline flow",
self.lines.len(), self.lines.len());
flow.base.id);
util::swap(&mut flow.boxes, &mut self.new_boxes); util::swap(&mut flow.boxes, &mut self.new_boxes);
util::swap(&mut flow.lines, &mut self.lines); util::swap(&mut flow.lines, &mut self.lines);
@ -466,9 +465,9 @@ pub struct InlineFlow {
} }
impl InlineFlow { impl InlineFlow {
pub fn from_boxes(id: int, node: ThreadSafeLayoutNode, boxes: ~[Box]) -> InlineFlow { pub fn from_boxes(node: ThreadSafeLayoutNode, boxes: ~[Box]) -> InlineFlow {
InlineFlow { InlineFlow {
base: BaseFlow::new(id, node), base: BaseFlow::new(node),
boxes: boxes, boxes: boxes,
lines: ~[], lines: ~[],
elems: ElementMapping::new(), elems: ElementMapping::new(),
@ -497,9 +496,7 @@ impl InlineFlow {
// TODO(#228): Once we form line boxes and have their cached bounds, we can be smarter and // TODO(#228): Once we form line boxes and have their cached bounds, we can be smarter and
// not recurse on a line if nothing in it can intersect the dirty region. // not recurse on a line if nothing in it can intersect the dirty region.
debug!("Flow[{:d}]: building display list for {:u} inline boxes", debug!("Flow: building display list for {:u} inline boxes", self.boxes.len());
self.base.id,
self.boxes.len());
for box_ in self.boxes.iter() { for box_ in self.boxes.iter() {
let rel_offset: Point2D<Au> = box_.relative_position(container_block_size); let rel_offset: Point2D<Au> = box_.relative_position(container_block_size);
@ -636,7 +633,7 @@ impl Flow for InlineFlow {
let mut pref_width = Au::new(0); let mut pref_width = Au::new(0);
for box_ in self.boxes.iter() { for box_ in self.boxes.iter() {
debug!("Flow[{:d}]: measuring {:s}", self.base.id, box_.debug_str()); debug!("Flow: measuring {:s}", box_.debug_str());
box_.compute_borders(box_.style()); box_.compute_borders(box_.style());
let (this_minimum_width, this_preferred_width) = let (this_minimum_width, this_preferred_width) =
box_.minimum_and_preferred_widths(); box_.minimum_and_preferred_widths();
@ -690,7 +687,7 @@ impl Flow for InlineFlow {
} }
fn assign_height(&mut self, _: &mut LayoutContext) { fn assign_height(&mut self, _: &mut LayoutContext) {
debug!("assign_height_inline: assigning height for flow {}", self.base.id); debug!("assign_height_inline: assigning height for flow");
// Divide the boxes into lines. // Divide the boxes into lines.
// //

View file

@ -9,18 +9,17 @@ use css::matching::{ApplicableDeclarations, ApplicableDeclarationsCache, MatchMe
use css::matching::{StyleSharingCandidateCache}; use css::matching::{StyleSharingCandidateCache};
use css::select::new_stylist; use css::select::new_stylist;
use css::node_style::StyledNode; use css::node_style::StyledNode;
use layout::construct::{FlowConstructionResult, FlowConstructor, NoConstructionResult}; use layout::construct::{FlowConstructionResult, NoConstructionResult};
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::display_list_builder::{DisplayListBuilder, ToGfxColor}; use layout::display_list_builder::{DisplayListBuilder, ToGfxColor};
use layout::flow::{Flow, FlowLeafSet, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils}; use layout::flow::{Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils};
use layout::flow::{PreorderFlowTraversal, PostorderFlowTraversal}; use layout::flow::{PreorderFlowTraversal, PostorderFlowTraversal};
use layout::flow; use layout::flow;
use layout::incremental::RestyleDamage; use layout::incremental::RestyleDamage;
use layout::parallel::{AssignHeightsAndStoreOverflowTraversalKind, BubbleWidthsTraversalKind}; use layout::parallel::PaddedUnsafeFlow;
use layout::parallel::{UnsafeFlow};
use layout::parallel; use layout::parallel;
use layout::util::{LayoutDataAccess, OpaqueNode, LayoutDataWrapper}; use layout::util::{LayoutDataAccess, OpaqueNode, LayoutDataWrapper};
use layout::wrapper::{DomLeafSet, LayoutNode, TLayoutNode, ThreadSafeLayoutNode}; use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode};
use extra::url::Url; use extra::url::Url;
use extra::arc::{Arc, MutexArc}; use extra::arc::{Arc, MutexArc};
@ -28,24 +27,25 @@ use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
use gfx::display_list::{ClipDisplayItemClass, DisplayItem, DisplayItemIterator}; use gfx::display_list::{ClipDisplayItemClass, DisplayItem, DisplayItemIterator};
use gfx::display_list::{DisplayList, DisplayListCollection}; use gfx::display_list::{DisplayList, DisplayListCollection};
use gfx::font_context::FontContextInfo; use gfx::font_context::{FontContext, FontContextInfo};
use gfx::opts::Opts;
use gfx::render_task::{RenderMsg, RenderChan, RenderLayer}; use gfx::render_task::{RenderMsg, RenderChan, RenderLayer};
use gfx::{render_task, color}; use gfx::{render_task, color};
use script::dom::bindings::js::JS;
use script::dom::event::ReflowEvent; 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::dom::element::{HTMLBodyElementTypeId, HTMLHtmlElementTypeId};
use script::layout_interface::{AddStylesheetMsg, ContentBoxQuery}; use script::layout_interface::{AddStylesheetMsg, ContentBoxQuery};
use script::layout_interface::{ContentBoxesQuery, ContentBoxesResponse, ExitNowMsg, LayoutQuery}; use script::layout_interface::{ContentBoxesQuery, ContentBoxesResponse, ExitNowMsg, LayoutQuery};
use script::layout_interface::{HitTestQuery, ContentBoxResponse, HitTestResponse, MouseOverQuery, MouseOverResponse}; use script::layout_interface::{HitTestQuery, ContentBoxResponse, HitTestResponse, MouseOverQuery, MouseOverResponse};
use script::layout_interface::{ContentChangedDocumentDamage, LayoutChan, Msg, PrepareToExitMsg}; use script::layout_interface::{ContentChangedDocumentDamage, LayoutChan, Msg, PrepareToExitMsg};
use script::layout_interface::{QueryMsg, ReapLayoutDataMsg, Reflow, ReflowDocumentDamage, UntrustedNodeAddress}; use script::layout_interface::{QueryMsg, ReapLayoutDataMsg, Reflow, UntrustedNodeAddress};
use script::layout_interface::{ReflowForDisplay, ReflowMsg}; use script::layout_interface::{ReflowForDisplay, ReflowMsg};
use script::script_task::{ReflowCompleteMsg, ScriptChan, SendEventMsg}; use script::script_task::{ReflowCompleteMsg, ScriptChan, SendEventMsg};
use servo_msg::constellation_msg::{ConstellationChan, PipelineId, Failure, FailureMsg}; use servo_msg::constellation_msg::{ConstellationChan, PipelineId, Failure, FailureMsg};
use servo_net::image_cache_task::{ImageCacheTask, ImageResponseMsg}; use servo_net::image_cache_task::{ImageCacheTask, ImageResponseMsg};
use servo_net::local_image_cache::{ImageResponder, LocalImageCache}; use servo_net::local_image_cache::{ImageResponder, LocalImageCache};
use servo_util::geometry::Au; use servo_util::geometry::Au;
use servo_util::opts::Opts;
use servo_util::time::{ProfilerChan, profile}; use servo_util::time::{ProfilerChan, profile};
use servo_util::time; use servo_util::time;
use servo_util::task::send_on_failure; use servo_util::task::send_on_failure;
@ -86,12 +86,6 @@ pub struct LayoutTask {
/// The local image cache. /// The local image cache.
local_image_cache: MutexArc<LocalImageCache>, local_image_cache: MutexArc<LocalImageCache>,
/// The set of leaves in the DOM tree.
dom_leaf_set: Arc<DomLeafSet>,
/// The set of leaves in the flow tree.
flow_leaf_set: Arc<FlowLeafSet>,
/// The size of the viewport. /// The size of the viewport.
screen_size: Size2D<Au>, screen_size: Size2D<Au>,
@ -104,7 +98,7 @@ pub struct LayoutTask {
initial_css_values: Arc<ComputedValues>, initial_css_values: Arc<ComputedValues>,
/// The workers that we use for parallel operation. /// 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. /// The channel on which messages can be sent to the profiler.
profiler_chan: ProfilerChan, profiler_chan: ProfilerChan,
@ -194,12 +188,14 @@ impl<'a> PostorderFlowTraversal for BubbleWidthsTraversal<'a> {
} }
/// The assign-widths traversal. In Gecko this corresponds to `Reflow`. /// The assign-widths traversal. In Gecko this corresponds to `Reflow`.
struct AssignWidthsTraversal<'a>(&'a mut LayoutContext); pub struct AssignWidthsTraversal<'a> {
layout_context: &'a mut LayoutContext,
}
impl<'a> PreorderFlowTraversal for AssignWidthsTraversal<'a> { impl<'a> PreorderFlowTraversal for AssignWidthsTraversal<'a> {
#[inline] #[inline]
fn process(&mut self, flow: &mut Flow) -> bool { fn process(&mut self, flow: &mut Flow) -> bool {
flow.assign_widths(**self); flow.assign_widths(self.layout_context);
true true
} }
} }
@ -303,8 +299,6 @@ impl LayoutTask {
image_cache_task: image_cache_task.clone(), image_cache_task: image_cache_task.clone(),
local_image_cache: local_image_cache, local_image_cache: local_image_cache,
screen_size: screen_size, screen_size: screen_size,
dom_leaf_set: Arc::new(DomLeafSet::new()),
flow_leaf_set: Arc::new(FlowLeafSet::new()),
display_list_collection: None, display_list_collection: None,
stylist: ~new_stylist(), stylist: ~new_stylist(),
@ -323,7 +317,7 @@ impl LayoutTask {
} }
// Create a layout context for use in building display lists, hit testing, &c. // Create a layout context for use in building display lists, hit testing, &c.
fn build_layout_context(&self, reflow_root: &LayoutNode) -> LayoutContext { fn build_layout_context(&self, reflow_root: &LayoutNode, url: &Url) -> LayoutContext {
let font_context_info = FontContextInfo { let font_context_info = FontContextInfo {
backend: self.opts.render_backend, backend: self.opts.render_backend,
needs_font_list: true, needs_font_list: true,
@ -334,13 +328,13 @@ impl LayoutTask {
image_cache: self.local_image_cache.clone(), image_cache: self.local_image_cache.clone(),
screen_size: self.screen_size.clone(), screen_size: self.screen_size.clone(),
constellation_chan: self.constellation_chan.clone(), constellation_chan: self.constellation_chan.clone(),
dom_leaf_set: self.dom_leaf_set.clone(),
flow_leaf_set: self.flow_leaf_set.clone(),
layout_chan: self.chan.clone(), layout_chan: self.chan.clone(),
font_context_info: font_context_info, font_context_info: font_context_info,
stylist: &*self.stylist, stylist: &*self.stylist,
initial_css_values: self.initial_css_values.clone(), initial_css_values: self.initial_css_values.clone(),
url: (*url).clone(),
reflow_root: OpaqueNode::from_layout_node(reflow_root), reflow_root: OpaqueNode::from_layout_node(reflow_root),
opts: self.opts.clone(),
} }
} }
@ -422,17 +416,8 @@ impl LayoutTask {
self.stylist.add_stylesheet(sheet, AuthorOrigin) self.stylist.add_stylesheet(sheet, AuthorOrigin)
} }
/// Builds the flow tree. /// Retrieves the flow tree root from the root node.
/// fn get_layout_root(&self, node: LayoutNode) -> ~Flow {
/// This corresponds to the various `nsCSSFrameConstructor` methods in Gecko or
/// `createRendererIfNeeded` in WebKit. Note, however that in WebKit `createRendererIfNeeded`
/// 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);
node.traverse_postorder_mut(&mut FlowConstructor::init(layout_context, url));
let mut layout_data_ref = node.mutate_layout_data(); let mut layout_data_ref = node.mutate_layout_data();
let result = match *layout_data_ref.get() { let result = match *layout_data_ref.get() {
Some(ref mut layout_data) => { Some(ref mut layout_data) => {
@ -456,7 +441,7 @@ impl LayoutTask {
fn solve_constraints(&mut self, fn solve_constraints(&mut self,
layout_root: &mut Flow, layout_root: &mut Flow,
layout_context: &mut LayoutContext) { layout_context: &mut LayoutContext) {
{ if layout_context.opts.bubble_widths_separately {
let mut traversal = BubbleWidthsTraversal { let mut traversal = BubbleWidthsTraversal {
layout_context: layout_context, layout_context: layout_context,
}; };
@ -468,7 +453,12 @@ impl LayoutTask {
// recompute them every time. // recompute them every time.
// NOTE: this currently computes borders, so any pruning should separate that operation // NOTE: this currently computes borders, so any pruning should separate that operation
// out. // out.
layout_root.traverse_preorder(&mut AssignWidthsTraversal(layout_context)); {
let mut traversal = AssignWidthsTraversal {
layout_context: layout_context,
};
layout_root.traverse_preorder(&mut traversal);
}
// FIXME(pcwalton): Prune this pass as well. // FIXME(pcwalton): Prune this pass as well.
{ {
@ -485,25 +475,21 @@ impl LayoutTask {
/// benchmarked against those two. It is marked `#[inline(never)]` to aid profiling. /// benchmarked against those two. It is marked `#[inline(never)]` to aid profiling.
#[inline(never)] #[inline(never)]
fn solve_constraints_parallel(&mut self, fn solve_constraints_parallel(&mut self,
layout_root: &mut Flow, layout_root: &mut ~Flow,
layout_context: &mut LayoutContext) { layout_context: &mut LayoutContext) {
if layout_context.opts.bubble_widths_separately {
let mut traversal = BubbleWidthsTraversal {
layout_context: layout_context,
};
layout_root.traverse_postorder(&mut traversal);
}
match self.parallel_traversal { match self.parallel_traversal {
None => fail!("solve_contraints_parallel() called with no parallel traversal ready"), None => fail!("solve_contraints_parallel() called with no parallel traversal ready"),
Some(ref mut traversal) => { Some(ref mut traversal) => {
parallel::traverse_flow_tree(BubbleWidthsTraversalKind,
&self.flow_leaf_set,
self.profiler_chan.clone(),
layout_context,
traversal);
// NOTE: this currently computes borders, so any pruning should separate that // NOTE: this currently computes borders, so any pruning should separate that
// operation out. // operation out.
// TODO(pcwalton): Run this in parallel as well. This will require a bit more work parallel::traverse_flow_tree_preorder(layout_root,
// because this is a top-down traversal, unlike the others.
layout_root.traverse_preorder(&mut AssignWidthsTraversal(layout_context));
parallel::traverse_flow_tree(AssignHeightsAndStoreOverflowTraversalKind,
&self.flow_leaf_set,
self.profiler_chan.clone(), self.profiler_chan.clone(),
layout_context, layout_context,
traversal); traversal);
@ -527,8 +513,9 @@ impl LayoutTask {
/// The high-level routine that performs layout tasks. /// The high-level routine that performs layout tasks.
fn handle_reflow(&mut self, data: &Reflow) { fn handle_reflow(&mut self, data: &Reflow) {
// FIXME: Isolate this transmutation into a "bridge" module. // FIXME: Isolate this transmutation into a "bridge" module.
let node: &LayoutNode = unsafe { let node: &mut LayoutNode = unsafe {
transmute(&data.document_root) 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()); debug!("layout: received layout request for: {:s}", data.url.to_str());
@ -558,45 +545,51 @@ impl LayoutTask {
self.screen_size = current_screen_size; self.screen_size = current_screen_size;
// Create a layout context for use throughout the following passes. // Create a layout context for use throughout the following passes.
let mut layout_ctx = self.build_layout_context(node); let mut layout_ctx = self.build_layout_context(node, &data.url);
// Create a font context, if this is sequential.
//
// FIXME(pcwalton): This is a pretty bogus thing to do. Essentially this is a workaround
// for libgreen having slow TLS.
let mut font_context_opt = if self.parallel_traversal.is_none() {
Some(~FontContext::new(layout_ctx.font_context_info.clone()))
} else {
None
};
// Create a font context, if this is sequential.
//
// FIXME(pcwalton): This is a pretty bogus thing to do. Essentially this is a workaround
// for libgreen having slow TLS.
let mut font_context_opt = if self.parallel_traversal.is_none() {
Some(~FontContext::new(layout_ctx.font_context_info.clone()))
} else {
None
};
let mut layout_root = profile(time::LayoutStyleRecalcCategory, let mut layout_root = profile(time::LayoutStyleRecalcCategory,
self.profiler_chan.clone(), self.profiler_chan.clone(),
|| { || {
// Perform CSS selector matching if necessary. // Perform CSS selector matching and flow construction.
match data.damage.level {
ReflowDocumentDamage => {}
_ => {
profile(time::LayoutSelectorMatchCategory, self.profiler_chan.clone(), || {
match self.parallel_traversal { match self.parallel_traversal {
None => { None => {
let mut applicable_declarations = ApplicableDeclarations::new(); let mut applicable_declarations = ApplicableDeclarations::new();
let mut applicable_declarations_cache = let mut applicable_declarations_cache = ApplicableDeclarationsCache::new();
ApplicableDeclarationsCache::new(); let mut style_sharing_candidate_cache = StyleSharingCandidateCache::new();
let mut style_sharing_candidate_cache = drop(node.recalc_style_for_subtree(self.stylist,
StyleSharingCandidateCache::new(); &mut layout_ctx,
node.match_and_cascade_subtree(self.stylist, font_context_opt.take_unwrap(),
&layout_ctx.layout_chan,
&mut applicable_declarations, &mut applicable_declarations,
layout_ctx.initial_css_values.get(),
&mut applicable_declarations_cache, &mut applicable_declarations_cache,
&mut style_sharing_candidate_cache, &mut style_sharing_candidate_cache,
None) None))
} }
Some(ref mut traversal) => { Some(ref mut traversal) => {
parallel::match_and_cascade_subtree(node, parallel::recalc_style_for_subtree(node, &mut layout_ctx, traversal)
&mut layout_ctx,
traversal)
}
}
})
} }
} }
// Construct the flow tree. self.get_layout_root((*node).clone())
profile(time::LayoutTreeBuilderCategory,
self.profiler_chan.clone(),
|| 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 // Verification of the flow tree, which ensures that all nodes were either marked as leaves
@ -622,7 +615,7 @@ impl LayoutTask {
} }
Some(_) => { Some(_) => {
// Parallel mode. // Parallel mode.
self.solve_constraints_parallel(layout_root, &mut layout_ctx) self.solve_constraints_parallel(&mut layout_root, &mut layout_ctx)
} }
} }
}); });
@ -648,7 +641,7 @@ impl LayoutTask {
if child.type_id() == ElementNodeTypeId(HTMLHtmlElementTypeId) || if child.type_id() == ElementNodeTypeId(HTMLHtmlElementTypeId) ||
child.type_id() == ElementNodeTypeId(HTMLBodyElementTypeId) { child.type_id() == ElementNodeTypeId(HTMLBodyElementTypeId) {
let element_bg_color = { let element_bg_color = {
let thread_safe_child = ThreadSafeLayoutNode::new(child); let thread_safe_child = ThreadSafeLayoutNode::new(&child);
thread_safe_child.style() thread_safe_child.style()
.get() .get()
.resolve_color(thread_safe_child.style() .resolve_color(thread_safe_child.style()
@ -683,7 +676,7 @@ impl LayoutTask {
}); });
} }
layout_root.destroy(self.flow_leaf_set.get()); layout_root.destroy();
// Tell script that we're done. // Tell script that we're done.
// //
@ -700,7 +693,7 @@ impl LayoutTask {
// The neat thing here is that in order to answer the following two queries we only // 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`. // need to compare nodes for equality. Thus we can safely work only with `OpaqueNode`.
ContentBoxQuery(node, reply_chan) => { ContentBoxQuery(node, reply_chan) => {
let node = OpaqueNode::from_script_node(&node); let node = OpaqueNode::from_script_node(node);
fn union_boxes_for_node<'a>( fn union_boxes_for_node<'a>(
accumulator: &mut Option<Rect<Au>>, accumulator: &mut Option<Rect<Au>>,
@ -724,7 +717,7 @@ impl LayoutTask {
reply_chan.send(ContentBoxResponse(rect.unwrap_or(Au::zero_rect()))) reply_chan.send(ContentBoxResponse(rect.unwrap_or(Au::zero_rect())))
} }
ContentBoxesQuery(node, reply_chan) => { ContentBoxesQuery(node, reply_chan) => {
let node = OpaqueNode::from_script_node(&node); let node = OpaqueNode::from_script_node(node);
fn add_boxes_for_node<'a>( fn add_boxes_for_node<'a>(
accumulator: &mut ~[Rect<Au>], accumulator: &mut ~[Rect<Au>],

View file

@ -7,15 +7,17 @@
//! This code is highly unsafe. Keep this file small and easy to audit. //! This code is highly unsafe. Keep this file small and easy to audit.
use css::matching::{ApplicableDeclarations, CannotShare, MatchMethods, StyleWasShared}; use css::matching::{ApplicableDeclarations, CannotShare, MatchMethods, StyleWasShared};
use layout::construct::FlowConstructor;
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::extra::LayoutAuxMethods; use layout::extra::LayoutAuxMethods;
use layout::flow::{Flow, FlowLeafSet, PostorderFlowTraversal}; use layout::flow::{Flow, PreorderFlowTraversal, PostorderFlowTraversal};
use layout::flow; use layout::flow;
use layout::layout_task::{AssignHeightsAndStoreOverflowTraversal, BubbleWidthsTraversal}; use layout::layout_task::{AssignHeightsAndStoreOverflowTraversal, AssignWidthsTraversal};
use layout::layout_task::{BubbleWidthsTraversal};
use layout::util::{LayoutDataAccess, OpaqueNode}; use layout::util::{LayoutDataAccess, OpaqueNode};
use layout::wrapper::{layout_node_to_unsafe_layout_node, LayoutNode, UnsafeLayoutNode}; use layout::wrapper::{layout_node_to_unsafe_layout_node, LayoutNode, PostorderNodeMutTraversal};
use layout::wrapper::{ThreadSafeLayoutNode, UnsafeLayoutNode};
use extra::arc::Arc;
use servo_util::time::{ProfilerChan, profile}; use servo_util::time::{ProfilerChan, profile};
use servo_util::time; use servo_util::time;
use servo_util::workqueue::{WorkQueue, WorkUnit, WorkerProxy}; use servo_util::workqueue::{WorkQueue, WorkUnit, WorkerProxy};
@ -24,11 +26,36 @@ use std::ptr;
use std::sync::atomics::{AtomicInt, Relaxed, SeqCst}; use std::sync::atomics::{AtomicInt, Relaxed, SeqCst};
use style::{Stylist, TNode}; use style::{Stylist, TNode};
pub enum TraversalKind { #[allow(dead_code)]
BubbleWidthsTraversalKind, fn static_assertion(node: UnsafeLayoutNode) {
AssignHeightsAndStoreOverflowTraversalKind, 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); pub type UnsafeFlow = (uint, uint);
fn null_unsafe_flow() -> UnsafeFlow { fn null_unsafe_flow() -> UnsafeFlow {
@ -92,7 +119,9 @@ impl FlowParallelInfo {
/// A parallel bottom-up flow traversal. /// A parallel bottom-up flow traversal.
trait ParallelPostorderFlowTraversal : PostorderFlowTraversal { trait ParallelPostorderFlowTraversal : PostorderFlowTraversal {
fn run_parallel(&mut self, mut unsafe_flow: UnsafeFlow) { fn run_parallel(&mut self,
mut unsafe_flow: UnsafeFlow,
_: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>) {
loop { loop {
unsafe { unsafe {
// Get a real flow. // Get a real flow.
@ -131,17 +160,69 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal {
} }
} }
/// A parallel top-down flow traversal.
trait ParallelPreorderFlowTraversal : PreorderFlowTraversal {
fn run_parallel(&mut self,
unsafe_flow: UnsafeFlow,
proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>);
fn run_parallel_helper(&mut self,
unsafe_flow: UnsafeFlow,
proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>,
top_down_func: extern "Rust" fn(PaddedUnsafeFlow,
&mut WorkerProxy<*mut LayoutContext,
PaddedUnsafeFlow>),
bottom_up_func: extern "Rust" fn(PaddedUnsafeFlow,
&mut WorkerProxy<*mut LayoutContext,
PaddedUnsafeFlow>)) {
let mut had_children = false;
unsafe {
// Get a real flow.
let flow: &mut ~Flow = cast::transmute(&unsafe_flow);
// Perform the appropriate traversal.
self.process(*flow);
// Possibly enqueue the children.
for kid in flow::child_iter(*flow) {
had_children = true;
proxy.push(WorkUnit {
fun: top_down_func,
data: UnsafeFlowConversions::from_flow(&borrowed_flow_to_unsafe_flow(kid)),
});
}
}
// If there were no more children, start assigning heights.
if !had_children {
bottom_up_func(UnsafeFlowConversions::from_flow(&unsafe_flow), proxy)
}
}
}
impl<'a> ParallelPostorderFlowTraversal for BubbleWidthsTraversal<'a> {} impl<'a> ParallelPostorderFlowTraversal for BubbleWidthsTraversal<'a> {}
impl<'a> ParallelPreorderFlowTraversal for AssignWidthsTraversal<'a> {
fn run_parallel(&mut self,
unsafe_flow: UnsafeFlow,
proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>) {
self.run_parallel_helper(unsafe_flow,
proxy,
assign_widths,
assign_heights_and_store_overflow)
}
}
impl<'a> ParallelPostorderFlowTraversal for AssignHeightsAndStoreOverflowTraversal<'a> {} impl<'a> ParallelPostorderFlowTraversal for AssignHeightsAndStoreOverflowTraversal<'a> {}
fn match_and_cascade_node(unsafe_layout_node: UnsafeLayoutNode, fn recalc_style_for_node(unsafe_layout_node: UnsafeLayoutNode,
proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeLayoutNode>) { proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeLayoutNode>) {
unsafe { unsafe {
let layout_context: &mut LayoutContext = cast::transmute(*proxy.user_data()); let layout_context: &mut LayoutContext = cast::transmute(*proxy.user_data());
// Get a real layout node. // 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. // Initialize layout data.
// //
@ -159,7 +240,7 @@ fn match_and_cascade_node(unsafe_layout_node: UnsafeLayoutNode,
// First, check to see whether we can share a style with someone. // First, check to see whether we can share a style with someone.
let style_sharing_candidate_cache = layout_context.style_sharing_candidate_cache(); let style_sharing_candidate_cache = layout_context.style_sharing_candidate_cache();
let sharing_result = node.share_style_if_possible(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. // Otherwise, match and cascade selectors.
match sharing_result { match sharing_result {
@ -186,24 +267,61 @@ fn match_and_cascade_node(unsafe_layout_node: UnsafeLayoutNode,
StyleWasShared(index) => style_sharing_candidate_cache.touch(index), StyleWasShared(index) => style_sharing_candidate_cache.touch(index),
} }
// Enqueue kids. // Prepare for flow construction by counting the node's children and storing that count.
let mut child_count = 0; let mut child_count = 0;
for kid in node.children() { for _ in node.children() {
child_count += 1; child_count += 1;
}
if child_count != 0 {
let mut layout_data_ref = node.mutate_layout_data();
match *layout_data_ref.get() {
Some(ref mut layout_data) => {
layout_data.data.parallel.children_count.store(child_count as int, Relaxed)
}
None => fail!("no layout data"),
}
// Enqueue kids.
for kid in node.children() {
proxy.push(WorkUnit { proxy.push(WorkUnit {
fun: match_and_cascade_node, fun: recalc_style_for_node,
data: layout_node_to_unsafe_layout_node(&kid), data: layout_node_to_unsafe_layout_node(&kid),
}); });
} }
return
}
// Prepare for flow construction by adding this node to the leaf set or counting its // If we got here, we're a leaf. Start construction of flows for this node.
// children. construct_flows(unsafe_layout_node, proxy)
if child_count == 0 { }
// We don't need set the `child_count` field here since that's only used by kids during }
// bottom-up traversals, and since this node is a leaf it has no kids.
layout_context.dom_leaf_set.get().insert(&node); fn construct_flows(mut unsafe_layout_node: UnsafeLayoutNode,
} else { proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeLayoutNode>) {
loop {
let layout_context: &mut LayoutContext = unsafe {
cast::transmute(*proxy.user_data())
};
// Get a real layout node.
let node: LayoutNode = unsafe {
cast::transmute(unsafe_layout_node)
};
// Construct flows for this node.
{
let mut flow_constructor = FlowConstructor::new(layout_context, None);
flow_constructor.process(&ThreadSafeLayoutNode::new(&node));
}
// Reset the count of children for the next traversal.
//
// FIXME(pcwalton): Use children().len() when the implementation of that is efficient.
let mut child_count = 0;
for _ in node.children() {
child_count += 1
}
{
let mut layout_data_ref = node.mutate_layout_data(); let mut layout_data_ref = node.mutate_layout_data();
match *layout_data_ref.get() { match *layout_data_ref.get() {
Some(ref mut layout_data) => { Some(ref mut layout_data) => {
@ -212,31 +330,66 @@ fn match_and_cascade_node(unsafe_layout_node: UnsafeLayoutNode,
None => fail!("no layout data"), None => fail!("no layout data"),
} }
} }
// If this is the reflow root, we're done.
if layout_context.reflow_root == OpaqueNode::from_layout_node(&node) {
break
}
// Otherwise, enqueue the parent.
match node.parent_node() {
Some(parent) => {
// No, we're not at the root yet. Then are we the last sibling of our parent?
// If so, we can continue on with our parent; otherwise, we've gotta wait.
unsafe {
match *parent.borrow_layout_data_unchecked() {
Some(ref parent_layout_data) => {
let parent_layout_data = cast::transmute_mut(parent_layout_data);
if parent_layout_data.data
.parallel
.children_count
.fetch_sub(1, SeqCst) == 1 {
// We were the last child of our parent. Construct flows for our
// parent.
unsafe_layout_node = layout_node_to_unsafe_layout_node(&parent)
} else {
// Get out of here and find another node to work on.
break
}
}
None => fail!("no layout data for parent?!"),
}
}
}
None => fail!("no parent and weren't at reflow root?!"),
}
} }
} }
fn bubble_widths(unsafe_flow: UnsafeFlow, proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeFlow>) { fn assign_widths(unsafe_flow: PaddedUnsafeFlow,
proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>) {
let layout_context: &mut LayoutContext = unsafe { let layout_context: &mut LayoutContext = unsafe {
cast::transmute(*proxy.user_data()) cast::transmute(*proxy.user_data())
}; };
let mut bubble_widths_traversal = BubbleWidthsTraversal { let mut assign_widths_traversal = AssignWidthsTraversal {
layout_context: layout_context, layout_context: layout_context,
}; };
bubble_widths_traversal.run_parallel(unsafe_flow) assign_widths_traversal.run_parallel(unsafe_flow.to_flow(), proxy)
} }
fn assign_heights_and_store_overflow(unsafe_flow: UnsafeFlow, fn assign_heights_and_store_overflow(unsafe_flow: PaddedUnsafeFlow,
proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeFlow>) { proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>) {
let layout_context: &mut LayoutContext = unsafe { let layout_context: &mut LayoutContext = unsafe {
cast::transmute(*proxy.user_data()) cast::transmute(*proxy.user_data())
}; };
let mut assign_heights_traversal = AssignHeightsAndStoreOverflowTraversal { let mut assign_heights_traversal = AssignHeightsAndStoreOverflowTraversal {
layout_context: layout_context, layout_context: layout_context,
}; };
assign_heights_traversal.run_parallel(unsafe_flow) assign_heights_traversal.run_parallel(unsafe_flow.to_flow(), proxy)
} }
pub fn match_and_cascade_subtree(root_node: &LayoutNode, pub fn recalc_style_for_subtree(root_node: &LayoutNode,
layout_context: &mut LayoutContext, layout_context: &mut LayoutContext,
queue: &mut WorkQueue<*mut LayoutContext,UnsafeLayoutNode>) { queue: &mut WorkQueue<*mut LayoutContext,UnsafeLayoutNode>) {
unsafe { unsafe {
@ -245,7 +398,7 @@ pub fn match_and_cascade_subtree(root_node: &LayoutNode,
// Enqueue the root node. // Enqueue the root node.
queue.push(WorkUnit { queue.push(WorkUnit {
fun: match_and_cascade_node, fun: recalc_style_for_node,
data: layout_node_to_unsafe_layout_node(root_node), data: layout_node_to_unsafe_layout_node(root_node),
}); });
@ -254,27 +407,19 @@ pub fn match_and_cascade_subtree(root_node: &LayoutNode,
queue.data = ptr::mut_null() queue.data = ptr::mut_null()
} }
pub fn traverse_flow_tree(kind: TraversalKind, pub fn traverse_flow_tree_preorder(root: &mut ~Flow,
leaf_set: &Arc<FlowLeafSet>,
profiler_chan: ProfilerChan, profiler_chan: ProfilerChan,
layout_context: &mut LayoutContext, layout_context: &mut LayoutContext,
queue: &mut WorkQueue<*mut LayoutContext,UnsafeFlow>) { queue: &mut WorkQueue<*mut LayoutContext,PaddedUnsafeFlow>) {
unsafe { unsafe {
queue.data = cast::transmute(layout_context) queue.data = cast::transmute(layout_context)
} }
let fun = match kind {
BubbleWidthsTraversalKind => bubble_widths,
AssignHeightsAndStoreOverflowTraversalKind => assign_heights_and_store_overflow,
};
profile(time::LayoutParallelWarmupCategory, profiler_chan, || { profile(time::LayoutParallelWarmupCategory, profiler_chan, || {
for (flow, _) in leaf_set.get().iter() {
queue.push(WorkUnit { queue.push(WorkUnit {
fun: fun, fun: assign_widths,
data: *flow, data: UnsafeFlowConversions::from_flow(&mut_owned_flow_to_unsafe_flow(root)),
}) })
}
}); });
queue.run(); queue.run();

View file

@ -8,9 +8,10 @@ use layout::parallel::DomParallelInfo;
use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode}; use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode};
use extra::arc::Arc; use extra::arc::Arc;
use script::dom::bindings::js::JS;
use script::dom::bindings::utils::Reflectable; use script::dom::bindings::utils::Reflectable;
use script::dom::node::AbstractNode; use script::dom::node::Node;
use script::layout_interface::{LayoutChan, UntrustedNodeAddress}; use script::layout_interface::{LayoutChan, UntrustedNodeAddress, TrustedNodeAddress};
use servo_util::range::Range; use servo_util::range::Range;
use std::cast; use std::cast;
use std::cell::{Ref, RefMut}; use std::cell::{Ref, RefMut};
@ -212,23 +213,28 @@ impl OpaqueNode {
/// Converts a DOM node (layout view) to an `OpaqueNode`. /// Converts a DOM node (layout view) to an `OpaqueNode`.
pub fn from_layout_node(node: &LayoutNode) -> OpaqueNode { pub fn from_layout_node(node: &LayoutNode) -> OpaqueNode {
unsafe { unsafe {
let abstract_node = node.get_abstract(); OpaqueNode::from_jsmanaged(node.get_jsmanaged())
let ptr: uintptr_t = cast::transmute(abstract_node.reflector().get_jsobject());
OpaqueNode(ptr)
} }
} }
/// Converts a thread-safe DOM node (layout view) to an `OpaqueNode`. /// Converts a thread-safe DOM node (layout view) to an `OpaqueNode`.
pub fn from_thread_safe_layout_node(node: &ThreadSafeLayoutNode) -> OpaqueNode { pub fn from_thread_safe_layout_node(node: &ThreadSafeLayoutNode) -> OpaqueNode {
unsafe { unsafe {
let abstract_node = node.get_abstract(); let abstract_node = node.get_jsmanaged();
let ptr: uintptr_t = cast::transmute(abstract_node.reflector().get_jsobject()); let ptr: uintptr_t = cast::transmute(abstract_node.reflector().get_jsobject());
OpaqueNode(ptr) OpaqueNode(ptr)
} }
} }
/// Converts a DOM node (script view) to an `OpaqueNode`. /// 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 { unsafe {
let ptr: uintptr_t = cast::transmute(node.reflector().get_jsobject()); let ptr: uintptr_t = cast::transmute(node.reflector().get_jsobject());
OpaqueNode(ptr) OpaqueNode(ptr)

View file

@ -11,18 +11,20 @@
//! //!
//! (1) Layout is not allowed to mutate the DOM. //! (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. //! onto these objects and cause use-after-free.
use extra::url::Url; 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::{Element, HTMLAreaElementTypeId, HTMLAnchorElementTypeId};
use script::dom::element::{HTMLLinkElementTypeId}; use script::dom::element::{HTMLLinkElementTypeId};
use script::dom::htmliframeelement::HTMLIFrameElement; use script::dom::htmliframeelement::HTMLIFrameElement;
use script::dom::htmlimageelement::HTMLImageElement; 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 script::dom::text::Text;
use servo_msg::constellation_msg::{PipelineId, SubpageId}; use servo_msg::constellation_msg::{PipelineId, SubpageId};
use servo_util::concurrentmap::{ConcurrentHashMap, ConcurrentHashMapIterator};
use servo_util::namespace; use servo_util::namespace;
use servo_util::namespace::Namespace; use servo_util::namespace::Namespace;
use std::cast; use std::cast;
@ -35,20 +37,20 @@ use layout::util::LayoutDataWrapper;
/// Allows some convenience methods on generic layout nodes. /// Allows some convenience methods on generic layout nodes.
pub trait TLayoutNode { pub trait TLayoutNode {
/// Creates a new layout node with the same lifetime as this layout node. /// 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. /// Returns the type ID of this node. Fails if this node is borrowed mutably.
fn type_id(&self) -> NodeTypeId; 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`. /// 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 /// Returns the interior of this node as a `Node`. This is highly unsafe for layout to call
/// and as such is marked `unsafe`. /// and as such is marked `unsafe`.
unsafe fn get<'a>(&'a self) -> &'a Node { unsafe fn get<'a>(&'a self) -> &'a Node {
let node = self.get_abstract(); self.get_jsmanaged().get()
cast::transmute(node.node())
} }
fn node_is_element(&self) -> bool { fn node_is_element(&self) -> bool {
@ -70,40 +72,18 @@ pub trait TLayoutNode {
/// FIXME(pcwalton): Don't copy URLs. /// FIXME(pcwalton): Don't copy URLs.
fn image_url(&self) -> Option<Url> { fn image_url(&self) -> Option<Url> {
unsafe { unsafe {
self.with_image_element(|image_element| { let image_element: JS<HTMLImageElement> = HTMLImageElementCast::to(self.get_jsmanaged());
image_element.image.as_ref().map(|url| (*url).clone()) image_element.get().extra.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");
}
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 /// If this node is an iframe element, returns its pipeline and subpage IDs. If this node is
/// not an iframe element, fails. /// not an iframe element, fails.
fn iframe_pipeline_and_subpage_ids(&self) -> (PipelineId, SubpageId) { fn iframe_pipeline_and_subpage_ids(&self) -> (PipelineId, SubpageId) {
unsafe { unsafe {
self.with_iframe_element(|iframe_element| { let iframe_element: JS<HTMLIFrameElement> = HTMLIFrameElementCast::to(self.get_jsmanaged());
let size = iframe_element.size.unwrap(); let size = iframe_element.get().size.unwrap();
(size.pipeline_id, size.subpage_id) (size.pipeline_id, size.subpage_id)
})
} }
} }
@ -112,45 +92,39 @@ pub trait TLayoutNode {
/// FIXME(pcwalton): Don't copy text. Atomically reference count instead. /// FIXME(pcwalton): Don't copy text. Atomically reference count instead.
fn text(&self) -> ~str { fn text(&self) -> ~str {
unsafe { 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. /// Returns the first child of this node.
fn first_child(&self) -> Option<Self> { fn first_child(&self) -> Option<Self> {
unsafe { 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. /// Dumps this node tree, for debugging.
fn dump(&self) { fn dump(&self) {
unsafe { 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 /// 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)] #[deriving(Clone, Eq)]
pub struct LayoutNode<'a> { pub struct LayoutNode<'a> {
/// The wrapped node. /// The wrapped node.
priv node: AbstractNode, priv node: JS<Node>,
/// Being chained to a value prevents `LayoutNode`s from escaping. /// Being chained to a value prevents `LayoutNode`s from escaping.
priv chain: &'a (), priv chain: &'a (),
} }
impl<'ln> TLayoutNode for LayoutNode<'ln> { 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 { LayoutNode {
node: node, node: node,
chain: self.chain, chain: self.chain,
@ -159,14 +133,14 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> {
fn type_id(&self) -> NodeTypeId { fn type_id(&self) -> NodeTypeId {
self.node.type_id() self.node.type_id()
} }
unsafe fn get_abstract(&self) -> AbstractNode { unsafe fn get_jsmanaged<'a>(&'a self) -> &'a JS<Node> {
self.node &self.node
} }
} }
impl<'ln> LayoutNode<'ln> { impl<'ln> LayoutNode<'ln> {
/// Creates a new layout node, scoped to the given closure. /// 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 = (); let heavy_iron_ball = ();
f(LayoutNode { f(LayoutNode {
node: node, node: node,
@ -194,26 +168,27 @@ impl<'ln> LayoutNode<'ln> {
impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> { impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> {
fn parent_node(&self) -> Option<LayoutNode<'ln>> { fn parent_node(&self) -> Option<LayoutNode<'ln>> {
unsafe { 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>> { fn prev_sibling(&self) -> Option<LayoutNode<'ln>> {
unsafe { 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>> { fn next_sibling(&self) -> Option<LayoutNode<'ln>> {
unsafe { 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. /// If this is an element, accesses the element data. Fails if this is not an element node.
#[inline] #[inline]
fn with_element<R>(&self, f: |&LayoutElement<'ln>| -> R) -> R { fn with_element<R>(&self, f: |&LayoutElement<'ln>| -> R) -> R {
self.node.with_imm_element(|element| { let elem: JS<Element> = ElementCast::to(&self.node);
let element = elem.get();
// FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on // FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on
// implementations. // implementations.
unsafe { unsafe {
@ -221,7 +196,6 @@ impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> {
element: cast::transmute_region(element), element: cast::transmute_region(element),
}) })
} }
})
} }
fn is_element(&self) -> bool { fn is_element(&self) -> bool {
@ -257,8 +231,8 @@ pub struct LayoutNodeChildrenIterator<'a> {
impl<'a> Iterator<LayoutNode<'a>> for LayoutNodeChildrenIterator<'a> { impl<'a> Iterator<LayoutNode<'a>> for LayoutNodeChildrenIterator<'a> {
fn next(&mut self) -> Option<LayoutNode<'a>> { fn next(&mut self) -> Option<LayoutNode<'a>> {
let node = self.current_node; let node = self.current_node.clone();
self.current_node = self.current_node.and_then(|node| { self.current_node = node.clone().and_then(|node| {
node.next_sibling() node.next_sibling()
}); });
node node
@ -358,7 +332,7 @@ impl<'le> TElement for LayoutElement<'le> {
/// node does not allow any parents or siblings of nodes to be accessed, to avoid races. /// node does not allow any parents or siblings of nodes to be accessed, to avoid races.
pub struct ThreadSafeLayoutNode<'ln> { pub struct ThreadSafeLayoutNode<'ln> {
/// The wrapped node. /// The wrapped node.
priv node: AbstractNode, priv node: JS<Node>,
/// Being chained to a value prevents `ThreadSafeLayoutNode`s from escaping. /// Being chained to a value prevents `ThreadSafeLayoutNode`s from escaping.
priv chain: &'ln (), priv chain: &'ln (),
@ -366,7 +340,7 @@ pub struct ThreadSafeLayoutNode<'ln> {
impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> { impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> {
/// Creates a new layout node with the same lifetime as this layout node. /// 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 { ThreadSafeLayoutNode {
node: node, node: node,
chain: self.chain, chain: self.chain,
@ -375,23 +349,32 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> {
fn type_id(&self) -> NodeTypeId { fn type_id(&self) -> NodeTypeId {
self.node.type_id() self.node.type_id()
} }
unsafe fn get_abstract(&self) -> AbstractNode { unsafe fn get_jsmanaged<'a>(&'a self) -> &'a JS<Node> {
self.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> { impl<'ln> ThreadSafeLayoutNode<'ln> {
/// Creates a new `ThreadSafeLayoutNode` from the given `LayoutNode`. /// 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 { ThreadSafeLayoutNode {
node: node.node, node: node.node.clone(),
chain: node.chain, chain: node.chain,
} }
} }
/// Returns the next sibling of this node. Unsafe and private because this can lead to races. /// Returns the next sibling of this node. Unsafe and private because this can lead to races.
unsafe fn next_sibling(&self) -> Option<ThreadSafeLayoutNode<'ln>> { 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. /// Returns an iterator over this node's children.
@ -405,13 +388,13 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
#[inline] #[inline]
pub fn with_element<R>(&self, f: |&ThreadSafeLayoutElement| -> R) -> R { pub fn with_element<R>(&self, f: |&ThreadSafeLayoutElement| -> R) -> R {
unsafe { unsafe {
self.get_abstract().with_imm_element(|element| { let elem: JS<Element> = ElementCast::to(&self.node);
let element = elem.get();
// FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on // FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on
// implementations. // implementations.
f(&ThreadSafeLayoutElement { f(&ThreadSafeLayoutElement {
element: cast::transmute_region(element), element: cast::transmute_region(element),
}) })
})
} }
} }
@ -434,7 +417,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
/// Traverses the tree in postorder. /// Traverses the tree in postorder.
/// ///
/// TODO(pcwalton): Offer a parallel version with a compatible API. /// 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 { -> bool {
if traversal.should_prune(self) { if traversal.should_prune(self) {
return true return true
@ -444,7 +427,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
loop { loop {
match opt_kid { match opt_kid {
None => break, None => break,
Some(kid) => { Some(mut kid) => {
if !kid.traverse_postorder_mut(traversal) { if !kid.traverse_postorder_mut(traversal) {
return false return false
} }
@ -465,8 +448,8 @@ pub struct ThreadSafeLayoutNodeChildrenIterator<'a> {
impl<'a> Iterator<ThreadSafeLayoutNode<'a>> for ThreadSafeLayoutNodeChildrenIterator<'a> { impl<'a> Iterator<ThreadSafeLayoutNode<'a>> for ThreadSafeLayoutNodeChildrenIterator<'a> {
fn next(&mut self) -> Option<ThreadSafeLayoutNode<'a>> { fn next(&mut self) -> Option<ThreadSafeLayoutNode<'a>> {
let node = self.current_node; let node = self.current_node.clone();
self.current_node = self.current_node.and_then(|node| { self.current_node = self.current_node.clone().and_then(|node| {
unsafe { unsafe {
node.next_sibling() node.next_sibling()
} }
@ -491,17 +474,19 @@ impl<'le> ThreadSafeLayoutElement<'le> {
/// A bottom-up, parallelizable traversal. /// A bottom-up, parallelizable traversal.
pub trait PostorderNodeMutTraversal { pub trait PostorderNodeMutTraversal {
/// The operation to perform. Return true to continue or false to stop. /// 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 /// 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 /// entirely and do not process any descendant nodes. This is called *before* child nodes are
/// visited. The default implementation never prunes any nodes. /// 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 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 { pub fn layout_node_to_unsafe_layout_node(node: &LayoutNode) -> UnsafeLayoutNode {
unsafe { unsafe {
@ -509,32 +494,3 @@ pub fn layout_node_to_unsafe_layout_node(node: &LayoutNode) -> UnsafeLayoutNode
} }
} }
/// Keeps track of the leaves of the DOM. This is used to efficiently start bottom-up traversals.
pub struct DomLeafSet {
priv set: ConcurrentHashMap<UnsafeLayoutNode,()>,
}
impl DomLeafSet {
/// Creates a new DOM leaf set.
pub fn new() -> DomLeafSet {
DomLeafSet {
set: ConcurrentHashMap::with_locks_and_buckets(64, 256),
}
}
/// Inserts a DOM node into the leaf set.
pub fn insert(&self, node: &LayoutNode) {
self.set.insert(layout_node_to_unsafe_layout_node(node), ());
}
/// Removes all DOM nodes from the set.
pub fn clear(&self) {
self.set.clear()
}
/// Iterates over the DOM nodes in the leaf set.
pub fn iter<'a>(&'a self) -> ConcurrentHashMapIterator<'a,UnsafeLayoutNode,()> {
self.set.iter()
}
}

View file

@ -7,7 +7,6 @@ use layout::layout_task::LayoutTask;
use extra::url::Url; use extra::url::Url;
use geom::size::Size2D; use geom::size::Size2D;
use gfx::opts::Opts;
use gfx::render_task::{PaintPermissionGranted, PaintPermissionRevoked}; use gfx::render_task::{PaintPermissionGranted, PaintPermissionRevoked};
use gfx::render_task::{RenderChan, RenderTask}; use gfx::render_task::{RenderChan, RenderTask};
use layout::util::OpaqueNode; use layout::util::OpaqueNode;
@ -18,6 +17,7 @@ use script::script_task;
use servo_msg::constellation_msg::{ConstellationChan, Failure, PipelineId, SubpageId}; use servo_msg::constellation_msg::{ConstellationChan, Failure, PipelineId, SubpageId};
use servo_net::image_cache_task::ImageCacheTask; use servo_net::image_cache_task::ImageCacheTask;
use servo_net::resource_task::ResourceTask; use servo_net::resource_task::ResourceTask;
use servo_util::opts::Opts;
use servo_util::time::ProfilerChan; use servo_util::time::ProfilerChan;
use std::cell::RefCell; use std::cell::RefCell;
//FIXME: switch to std::rc when we upgrade Rust //FIXME: switch to std::rc when we upgrade Rust

View file

@ -46,9 +46,6 @@ use constellation::Constellation;
#[cfg(not(test))] #[cfg(not(test))]
use servo_msg::constellation_msg::InitLoadUrlMsg; use servo_msg::constellation_msg::InitLoadUrlMsg;
#[cfg(not(test))]
use gfx::opts;
#[cfg(not(test))] #[cfg(not(test))]
use servo_net::image_cache_task::{ImageCacheTask, SyncImageCacheTask}; use servo_net::image_cache_task::{ImageCacheTask, SyncImageCacheTask};
#[cfg(not(test))] #[cfg(not(test))]
@ -56,9 +53,10 @@ use servo_net::resource_task::ResourceTask;
#[cfg(not(test))] #[cfg(not(test))]
use servo_util::time::Profiler; use servo_util::time::Profiler;
pub use gfx::opts::Opts; #[cfg(not(test))]
pub use gfx::text; use servo_util::opts;
pub use servo_util::url::parse_url; #[cfg(not(test))]
use servo_util::url::parse_url;
#[cfg(not(test))] #[cfg(not(test))]
use std::os; use std::os;
@ -138,7 +136,7 @@ pub extern "C" fn android_start(argc: int, argv: **u8) -> int {
} }
#[cfg(not(test))] #[cfg(not(test))]
fn run(opts: Opts) { fn run(opts: opts::Opts) {
let mut pool = green::SchedPool::new(green::PoolConfig::new()); let mut pool = green::SchedPool::new(green::PoolConfig::new());
let (compositor_port, compositor_chan) = CompositorChan::new(); let (compositor_port, compositor_chan) = CompositorChan::new();

View file

@ -11,6 +11,8 @@ use layers::platform::surface::{NativeSurface, NativeSurfaceMethods};
use constellation_msg::PipelineId; use constellation_msg::PipelineId;
use extra::serialize::{Encoder, Encodable};
pub struct LayerBuffer { pub struct LayerBuffer {
/// The native surface which can be shared between threads or processes. On Mac this is an /// 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`. /// `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); 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. /// The interface used by the quadtree and buffer map to get info about layer buffers.
pub trait Tile { pub trait Tile {
/// Returns the amount of memory used by the tile /// Returns the amount of memory used by the tile

View file

@ -60,8 +60,8 @@ pub enum NavigationDirection {
Back, Back,
} }
#[deriving(Clone, Eq, IterBytes)] #[deriving(Clone, Eq, IterBytes, Encodable)]
pub struct PipelineId(uint); pub struct PipelineId(uint);
#[deriving(Clone, Eq, IterBytes)] #[deriving(Clone, Eq, IterBytes, Encodable)]
pub struct SubpageId(uint); pub struct SubpageId(uint);

View file

@ -5,6 +5,8 @@
#[crate_id = "github.com/mozilla/servo#msg:0.1"]; #[crate_id = "github.com/mozilla/servo#msg:0.1"];
#[crate_type = "lib"]; #[crate_type = "lib"];
#[feature(managed_boxes)];
extern mod azure; extern mod azure;
extern mod extra; extern mod extra;
extern mod geom; extern mod geom;

View file

@ -14,6 +14,7 @@ use std::util::replace;
use std::result; use std::result;
use extra::arc::{Arc,MutexArc}; use extra::arc::{Arc,MutexArc};
use extra::url::Url; use extra::url::Url;
use extra::serialize::{Encoder, Encodable};
pub enum Msg { pub enum Msg {
/// Tell the cache that we may need a particular image soon. Must be posted /// Tell the cache that we may need a particular image soon. Must be posted
@ -80,6 +81,11 @@ pub struct ImageCacheTask {
chan: SharedChan<Msg>, chan: SharedChan<Msg>,
} }
impl<S: Encoder> Encodable<S> for ImageCacheTask {
fn encode(&self, _: &mut S) {
}
}
type DecoderFactory = fn() -> proc(&[u8]) -> Option<Image>; type DecoderFactory = fn() -> proc(&[u8]) -> Option<Image>;
pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask { pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {

View file

@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::AttrBinding; use dom::bindings::codegen::AttrBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::window::Window; use dom::window::Window;
use servo_util::namespace::{Namespace, Null}; use servo_util::namespace::{Namespace, Null};
@ -10,6 +11,7 @@ use servo_util::str::DOMString;
use std::util; use std::util;
#[deriving(Encodable)]
pub struct Attr { pub struct Attr {
reflector_: Reflector, reflector_: Reflector,
local_name: DOMString, 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(); let name = local_name.clone();
Attr::new_helper(window, local_name, value, name, Null, None) Attr::new_helper(window, local_name, value, name, Null, None)
} }
pub fn new_ns(window: &Window, local_name: DOMString, value: DOMString, pub fn new_ns(window: &Window, local_name: DOMString, value: DOMString,
name: DOMString, namespace: Namespace, name: DOMString, namespace: Namespace,
prefix: Option<DOMString>) -> @mut Attr { prefix: Option<DOMString>) -> JS<Attr> {
Attr::new_helper(window, local_name, value, name, namespace, prefix) Attr::new_helper(window, local_name, value, name, namespace, prefix)
} }
fn new_helper(window: &Window, local_name: DOMString, value: DOMString, fn new_helper(window: &Window, local_name: DOMString, value: DOMString,
name: DOMString, namespace: Namespace, 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); 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 { pub fn set_value(&mut self, mut value: DOMString) -> DOMString {

View file

@ -4,18 +4,20 @@
use dom::attr::Attr; use dom::attr::Attr;
use dom::bindings::codegen::AttrListBinding; use dom::bindings::codegen::AttrListBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::node::{AbstractNode}; use dom::element::Element;
use dom::window::Window; use dom::window::Window;
#[deriving(Encodable)]
pub struct AttrList { pub struct AttrList {
reflector_: Reflector, reflector_: Reflector,
window: @mut Window, window: JS<Window>,
owner: AbstractNode, owner: JS<Element>,
} }
impl AttrList { impl AttrList {
pub fn new_inherited(window: @mut Window, elem: AbstractNode) -> AttrList { pub fn new_inherited(window: JS<Window>, elem: JS<Element>) -> AttrList {
AttrList { AttrList {
reflector_: Reflector::new(), reflector_: Reflector::new(),
window: window, window: window,
@ -23,22 +25,20 @@ impl AttrList {
} }
} }
pub fn new(window: @mut Window, elem: AbstractNode) -> @mut AttrList { pub fn new(window: &JS<Window>, elem: &JS<Element>) -> JS<AttrList> {
reflect_dom_object(@mut AttrList::new_inherited(window, elem), reflect_dom_object(~AttrList::new_inherited(window.clone(), elem.clone()),
window, AttrListBinding::Wrap) window.get(), AttrListBinding::Wrap)
} }
pub fn Length(&self) -> u32 { 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> { pub fn Item(&self, index: u32) -> Option<JS<Attr>> {
self.owner.with_imm_element(|elem| { self.owner.get().attrs.get_opt(index as uint).map(|x| x.clone())
elem.attrs.get_opt(index as uint).map(|&x| x)
})
} }
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); let item = self.Item(index);
*found = item.is_some(); *found = item.is_some();
item item

View file

@ -4,12 +4,15 @@
use dom::bindings::utils::Reflectable; use dom::bindings::utils::Reflectable;
use js::jsapi::{JSContext, JSObject, JS_WrapObject, JSVal, JS_ObjectIsCallable}; use js::jsapi::{JSContext, JSObject, JS_WrapObject, JSVal, JS_ObjectIsCallable};
use js::jsapi::JS_GetProperty; use js::jsapi::{JS_GetProperty, JSTracer, JS_CallTracer};
use js::{JSVAL_IS_OBJECT, JSVAL_TO_OBJECT}; use js::{JSVAL_IS_OBJECT, JSVAL_TO_OBJECT, JSTRACE_OBJECT};
use std::cast;
use std::libc; use std::libc;
use std::ptr; use std::ptr;
use extra::serialize::{Encodable, Encoder};
pub enum ExceptionHandling { pub enum ExceptionHandling {
// Report any exception and don't throw it to the caller code. // Report any exception and don't throw it to the caller code.
eReportExceptions, eReportExceptions,
@ -26,6 +29,20 @@ pub struct CallbackInterface {
callback: *JSObject 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 { pub trait CallbackContainer {
fn callback(&self) -> *JSObject; 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, pub fn WrapCallThisObject<T: 'static + CallbackContainer + Reflectable>(cx: *JSContext,
_scope: *JSObject, _scope: *JSObject,
p: @mut T) -> *JSObject { p: ~T) -> *JSObject {
let obj = GetJSObjectFromCallback(p); let obj = GetJSObjectFromCallback(p);
assert!(obj.is_not_null()); assert!(obj.is_not_null());

View file

@ -96,7 +96,6 @@ DOMInterfaces = {
'Blob': [ 'Blob': [
{ {
'headerFile': 'nsIDOMFile.h',
}, },
#{ #{
# 'workers': True, # 'workers': True,
@ -121,19 +120,14 @@ DOMInterfaces = {
}], }],
'CharacterData': { 'CharacterData': {
'nativeType': 'AbstractNode',
'concreteType': 'CharacterData',
'pointerType': ''
}, },
'ClientRect': [ 'ClientRect': [
{ {
'nativeType': 'ClientRect',
}], }],
'ClientRectList': [ 'ClientRectList': [
{ {
'nativeType': 'ClientRectList',
}], }],
'Console': { 'Console': {
@ -150,8 +144,6 @@ DOMInterfaces = {
}, },
'Document': { 'Document': {
'nativeType': 'AbstractDocument',
'pointerType': '',
'customTrace': 'trace', 'customTrace': 'trace',
'needsAbstract': [ 'needsAbstract': [
'createComment', 'createComment',
@ -165,15 +157,12 @@ DOMInterfaces = {
}, },
'DOMException': { 'DOMException': {
'nativeType': 'DOMException',
}, },
'DOMImplementation': { 'DOMImplementation': {
'nativeType': 'DOMImplementation',
}, },
'DOMParser': { 'DOMParser': {
'nativeType': 'DOMParser',
}, },
'DOMSettableTokenList': [ 'DOMSettableTokenList': [
@ -195,15 +184,10 @@ DOMInterfaces = {
}], }],
'Element': { 'Element': {
'nativeType': 'AbstractNode',
'pointerType': '',
'needsAbstract': ['getClientRects', 'getBoundingClientRect', 'setAttribute', 'setAttributeNS', 'removeAttribute', 'removeAttributeNS', 'id', 'attributes', 'innerHTML', 'outerHTML'] 'needsAbstract': ['getClientRects', 'getBoundingClientRect', 'setAttribute', 'setAttributeNS', 'removeAttribute', 'removeAttributeNS', 'id', 'attributes', 'innerHTML', 'outerHTML']
}, },
'Event': { 'Event': {
'nativeType': 'AbstractEvent',
'concreteType': 'Event',
'pointerType': '',
}, },
'EventListener': { 'EventListener': {
@ -211,9 +195,6 @@ DOMInterfaces = {
}, },
'EventTarget': { 'EventTarget': {
'nativeType': 'AbstractEventTarget',
'concreteType': 'EventTarget',
'pointerType': '',
'needsAbstract': ['dispatchEvent'] 'needsAbstract': ['dispatchEvent']
}, },
@ -241,22 +222,8 @@ DOMInterfaces = {
'HTMLCollection': [ 'HTMLCollection': [
{ {
'nativeType': 'HTMLCollection',
'pointerType': '@mut '
}], }],
'HTMLDocument': {
'nativeType': 'AbstractDocument',
'pointerType': '',
'customTrace': 'trace'
},
'HTMLFormElement': {
'nativeType': 'AbstractNode',
'pointerType': '',
'register': False
},
'HTMLOptionsCollection': [ 'HTMLOptionsCollection': [
{ {
'nativeType': 'nsHTMLOptionCollection', 'nativeType': 'nsHTMLOptionCollection',
@ -306,27 +273,21 @@ DOMInterfaces = {
}], }],
'MouseEvent': { 'MouseEvent': {
'nativeType': 'AbstractEvent',
'concreteType': 'MouseEvent',
'pointerType': '',
}, },
'Navigator': { 'Navigator': {
}, },
'Node': { 'Node': {
'nativeType': 'AbstractNode',
'concreteType': 'Node',
'pointerType': '',
'needsAbstract': [ 'needsAbstract': [
'appendChild', 'appendChild',
'childNodes',
'insertBefore', 'insertBefore',
'replaceChild',
'nodeName', 'nodeName',
'nodeValue', 'nodeValue',
'removeChild', 'removeChild',
'replaceChild',
'textContent', 'textContent',
'childNodes',
'contains', 'contains',
'isEqualNode', 'isEqualNode',
] ]
@ -334,8 +295,6 @@ DOMInterfaces = {
'NodeList': [ 'NodeList': [
{ {
'nativeType': 'NodeList',
'pointerType': '@mut ',
'resultNotAddRefed': ['item'] 'resultNotAddRefed': ['item']
}], }],
@ -410,9 +369,6 @@ DOMInterfaces = {
}], }],
'UIEvent': { 'UIEvent': {
'nativeType': 'AbstractEvent',
'concreteType': 'UIEvent',
'pointerType': '',
}, },
'ValidityState': { 'ValidityState': {
@ -592,7 +548,7 @@ def addExternalIface(iface, nativeType=None, headerFile=None, pointerType=None):
# FIXME: This should be renamed: https://github.com/mozilla/servo/issues/1625 # FIXME: This should be renamed: https://github.com/mozilla/servo/issues/1625
def addHTMLElement(element, concrete=None, needsAbstract=[]): def addHTMLElement(element, concrete=None, needsAbstract=[]):
DOMInterfaces[element] = { DOMInterfaces[element] = {
'nativeType': 'AbstractNode', 'nativeType': 'JS<%s>' % element,
'pointerType': '', 'pointerType': '',
'concreteType': concrete if concrete else element, 'concreteType': concrete if concrete else element,
'customTrace': 'trace', 'customTrace': 'trace',

File diff suppressed because it is too large Load diff

View file

@ -158,10 +158,9 @@ class Descriptor(DescriptorProvider):
if self.workers: if self.workers:
nativeTypeDefault = "workers::" + ifaceName nativeTypeDefault = "workers::" + ifaceName
else: else:
nativeTypeDefault = ifaceName nativeTypeDefault = 'JS<%s>' % ifaceName
self.nativeType = desc.get('nativeType', nativeTypeDefault) self.nativeType = desc.get('nativeType', nativeTypeDefault)
self.pointerType = desc.get('pointerType', '@mut ')
self.concreteType = desc.get('concreteType', ifaceName) self.concreteType = desc.get('concreteType', ifaceName)
self.needsAbstract = desc.get('needsAbstract', []) self.needsAbstract = desc.get('needsAbstract', [])
self.hasInstanceInterface = desc.get('hasInstanceInterface', None) self.hasInstanceInterface = desc.get('hasInstanceInterface', None)
@ -253,7 +252,7 @@ class Descriptor(DescriptorProvider):
self.prefable = desc.get('prefable', False) self.prefable = desc.get('prefable', False)
self.nativeIsISupports = not self.workers 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.customFinalize = desc.get('customFinalize', self.workers)
self.wrapperCache = self.workers or desc.get('wrapperCache', True) self.wrapperCache = self.workers or desc.get('wrapperCache', True)

View file

@ -83,12 +83,14 @@ def main():
# Generate the type list. # Generate the type list.
generate_file(config, 'InterfaceTypes', 'declare+define') generate_file(config, 'InterfaceTypes', 'declare+define')
# Generate the type list.
generate_file(config, 'InheritTypes', 'declare+define')
# Generate the module declarations. # Generate the module declarations.
generate_file(config, 'BindingDeclarations', 'declare+define') generate_file(config, 'BindingDeclarations', 'declare+define')
#XXXjdm No union support yet generate_file(config, 'UnionTypes', 'declare+define')
#generate_file(config, 'UnionTypes', 'declare') generate_file(config, 'UnionConversions', 'declare+define')
#generate_file(config, 'UnionConversions', 'declare')
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View file

@ -95,7 +95,7 @@ CSS2Properties.webidl: $(topsrcdir)/layout/style/nsCSSPropList.h \
$(srcdir)/GenerateCSS2PropertiesWebIDL.py \ $(srcdir)/GenerateCSS2PropertiesWebIDL.py \
$(GLOBAL_DEPS) $(GLOBAL_DEPS)
$(CPP) $(DEFINES) $(ACDEFINES) -I$(topsrcdir)/layout/style $(webidl_base)/CSS2PropertiesProps.h | \ $(CPP) $(DEFINES) $(ACDEFINES) -I$(topsrcdir)/layout/style $(webidl_base)/CSS2PropertiesProps.h | \
PYTHONDONTWRITEBYTECODE=1 $(PYTHON) \ $(PYTHON) \
$(srcdir)/GenerateCSS2PropertiesWebIDL.py $(webidl_base)/CSS2Properties.webidl.in > CSS2Properties.webidl $(srcdir)/GenerateCSS2PropertiesWebIDL.py $(webidl_base)/CSS2Properties.webidl.in > CSS2Properties.webidl
$(webidl_files): %: $(webidl_base)/% $(webidl_files): %: $(webidl_base)/%
@ -107,7 +107,7 @@ $(test_webidl_files): %: $(srcdir)/test/%
$(binding_header_files): %Binding.h: $(bindinggen_dependencies) \ $(binding_header_files): %Binding.h: $(bindinggen_dependencies) \
%.webidl \ %.webidl \
$(NULL) $(NULL)
PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \ $(PYTHON) $(topsrcdir)/config/pythonpath.py \
$(PLY_INCLUDE) -I$(srcdir)/parser \ $(PLY_INCLUDE) -I$(srcdir)/parser \
$(srcdir)/BindingGen.py header \ $(srcdir)/BindingGen.py header \
$(srcdir)/Bindings.conf $*Binding \ $(srcdir)/Bindings.conf $*Binding \
@ -116,7 +116,7 @@ $(binding_header_files): %Binding.h: $(bindinggen_dependencies) \
$(binding_cpp_files): %Binding.cpp: $(bindinggen_dependencies) \ $(binding_cpp_files): %Binding.cpp: $(bindinggen_dependencies) \
%.webidl \ %.webidl \
$(NULL) $(NULL)
PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \ $(PYTHON) $(topsrcdir)/config/pythonpath.py \
$(PLY_INCLUDE) -I$(srcdir)/parser \ $(PLY_INCLUDE) -I$(srcdir)/parser \
$(srcdir)/BindingGen.py cpp \ $(srcdir)/BindingGen.py cpp \
$(srcdir)/Bindings.conf $*Binding \ $(srcdir)/Bindings.conf $*Binding \
@ -142,7 +142,7 @@ $(CACHE_DIR)/.done:
ParserResults.pkl: $(globalgen_dependencies) \ ParserResults.pkl: $(globalgen_dependencies) \
$(all_webidl_files) $(all_webidl_files)
PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \ $(PYTHON) $(topsrcdir)/config/pythonpath.py \
$(PLY_INCLUDE) -I$(srcdir)/parser \ $(PLY_INCLUDE) -I$(srcdir)/parser \
$(srcdir)/GlobalGen.py $(srcdir)/Bindings.conf . \ $(srcdir)/GlobalGen.py $(srcdir)/Bindings.conf . \
--cachedir=$(CACHE_DIR) \ --cachedir=$(CACHE_DIR) \

View file

@ -79,9 +79,9 @@ $(CPPSRCS): ../%Binding.cpp: $(bindinggen_dependencies) \
$(MAKE) -C .. $*Binding.cpp $(MAKE) -C .. $*Binding.cpp
check:: check::
PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \ $(PYTHON) $(topsrcdir)/config/pythonpath.py \
$(PLY_INCLUDE) $(srcdir)/../parser/runtests.py $(PLY_INCLUDE) $(srcdir)/../parser/runtests.py
check-interactive: check-interactive:
PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \ $(PYTHON) $(topsrcdir)/config/pythonpath.py \
$(PLY_INCLUDE) $(srcdir)/../parser/runtests.py -q $(PLY_INCLUDE) $(srcdir)/../parser/runtests.py -q

View file

@ -4,7 +4,9 @@
use js::jsapi::JSVal; use js::jsapi::JSVal;
use js::{JSVAL_FALSE, JSVAL_TRUE}; use js::{JSVAL_FALSE, JSVAL_TRUE};
use js::glue::{RUST_UINT_TO_JSVAL, RUST_JSVAL_TO_INT, RUST_DOUBLE_TO_JSVAL, RUST_JSVAL_TO_DOUBLE}; use js::glue::{RUST_UINT_TO_JSVAL, RUST_JSVAL_TO_INT, RUST_DOUBLE_TO_JSVAL};
use js::glue::{RUST_JSVAL_TO_DOUBLE, RUST_JSVAL_IS_INT, RUST_JSVAL_IS_DOUBLE};
use js::glue::{RUST_JSVAL_IS_BOOLEAN, RUST_JSVAL_TO_BOOLEAN};
pub trait JSValConvertible { pub trait JSValConvertible {
fn to_jsval(&self) -> JSVal; fn to_jsval(&self) -> JSVal;
@ -21,7 +23,11 @@ impl JSValConvertible for i64 {
fn from_jsval(val: JSVal) -> Option<i64> { fn from_jsval(val: JSVal) -> Option<i64> {
unsafe { unsafe {
if RUST_JSVAL_IS_INT(val) != 0 {
Some(RUST_JSVAL_TO_DOUBLE(val) as i64) Some(RUST_JSVAL_TO_DOUBLE(val) as i64)
} else {
None
}
} }
} }
} }
@ -35,7 +41,11 @@ impl JSValConvertible for u32 {
fn from_jsval(val: JSVal) -> Option<u32> { fn from_jsval(val: JSVal) -> Option<u32> {
unsafe { unsafe {
if RUST_JSVAL_IS_INT(val) != 0 {
Some(RUST_JSVAL_TO_INT(val) as u32) Some(RUST_JSVAL_TO_INT(val) as u32)
} else {
None
}
} }
} }
} }
@ -49,7 +59,11 @@ impl JSValConvertible for i32 {
fn from_jsval(val: JSVal) -> Option<i32> { fn from_jsval(val: JSVal) -> Option<i32> {
unsafe { unsafe {
if RUST_JSVAL_IS_INT(val) != 0 {
Some(RUST_JSVAL_TO_INT(val) as i32) Some(RUST_JSVAL_TO_INT(val) as i32)
} else {
None
}
} }
} }
} }
@ -63,7 +77,11 @@ impl JSValConvertible for u16 {
fn from_jsval(val: JSVal) -> Option<u16> { fn from_jsval(val: JSVal) -> Option<u16> {
unsafe { unsafe {
if RUST_JSVAL_IS_INT(val) != 0 {
Some(RUST_JSVAL_TO_INT(val) as u16) Some(RUST_JSVAL_TO_INT(val) as u16)
} else {
None
}
} }
} }
} }
@ -78,15 +96,15 @@ impl JSValConvertible for bool {
} }
fn from_jsval(val: JSVal) -> Option<bool> { fn from_jsval(val: JSVal) -> Option<bool> {
if val == JSVAL_TRUE { unsafe {
Some(true) if RUST_JSVAL_IS_BOOLEAN(val) != 0 {
} else if val == JSVAL_FALSE { Some(RUST_JSVAL_TO_BOOLEAN(val) != 0)
Some(false)
} else { } else {
None None
} }
} }
} }
}
impl JSValConvertible for f32 { impl JSValConvertible for f32 {
fn to_jsval(&self) -> JSVal { fn to_jsval(&self) -> JSVal {
@ -97,7 +115,11 @@ impl JSValConvertible for f32 {
fn from_jsval(val: JSVal) -> Option<f32> { fn from_jsval(val: JSVal) -> Option<f32> {
unsafe { unsafe {
if RUST_JSVAL_IS_DOUBLE(val) != 0 {
Some(RUST_JSVAL_TO_DOUBLE(val) as f32) Some(RUST_JSVAL_TO_DOUBLE(val) as f32)
} else {
None
}
} }
} }
} }
@ -111,7 +133,11 @@ impl JSValConvertible for f64 {
fn from_jsval(val: JSVal) -> Option<f64> { fn from_jsval(val: JSVal) -> Option<f64> {
unsafe { unsafe {
if RUST_JSVAL_IS_DOUBLE(val) != 0 {
Some(RUST_JSVAL_TO_DOUBLE(val) as f64) Some(RUST_JSVAL_TO_DOUBLE(val) as f64)
} else {
None
}
} }
} }
} }

View file

@ -3,9 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::types::*; use dom::types::*;
use dom::bindings::utils::{Reflectable, Reflector, Traceable}; use dom::bindings::utils::{Reflectable, Reflector};
use js::jsapi::JSTracer;
// generate_cacheable_wrapper // generate_cacheable_wrapper
macro_rules! 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_cacheable_wrapper_characterdata!(Comment, CommentBinding::Wrap)
generate_traceable_characterdata!(Comment)
generate_cacheable_wrapper_node!(DocumentFragment, DocumentFragmentBinding::Wrap) generate_cacheable_wrapper_node!(DocumentFragment, DocumentFragmentBinding::Wrap)
generate_traceable_node!(DocumentFragment)
generate_cacheable_wrapper_node!(DocumentType, DocumentTypeBinding::Wrap) generate_cacheable_wrapper_node!(DocumentType, DocumentTypeBinding::Wrap)
generate_traceable_node!(DocumentType)
generate_cacheable_wrapper_characterdata!(Text, TextBinding::Wrap) generate_cacheable_wrapper_characterdata!(Text, TextBinding::Wrap)
generate_traceable_characterdata!(Text)
generate_cacheable_wrapper_characterdata!(ProcessingInstruction, ProcessingInstruction::Wrap) generate_cacheable_wrapper_characterdata!(ProcessingInstruction, ProcessingInstruction::Wrap)
generate_traceable_characterdata!(ProcessingInstruction)
generate_cacheable_wrapper_htmlelement!(HTMLHeadElement, HTMLHeadElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLHeadElement, HTMLHeadElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLHeadElement)
generate_cacheable_wrapper_htmlelement!(HTMLAnchorElement, HTMLAnchorElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLAnchorElement, HTMLAnchorElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLAnchorElement)
generate_cacheable_wrapper_htmlelement!(HTMLAppletElement, HTMLAppletElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLAppletElement, HTMLAppletElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLAppletElement)
generate_cacheable_wrapper_htmlelement!(HTMLAreaElement, HTMLAreaElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLAreaElement, HTMLAreaElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLAreaElement)
generate_cacheable_wrapper_htmlmediaelement!(HTMLAudioElement, HTMLAudioElementBinding::Wrap) generate_cacheable_wrapper_htmlmediaelement!(HTMLAudioElement, HTMLAudioElementBinding::Wrap)
generate_traceable_htmlmediaelement!(HTMLAudioElement)
generate_cacheable_wrapper_htmlelement!(HTMLBaseElement, HTMLBaseElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLBaseElement, HTMLBaseElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLBaseElement)
generate_cacheable_wrapper_htmlelement!(HTMLBodyElement, HTMLBodyElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLBodyElement, HTMLBodyElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLBodyElement)
generate_cacheable_wrapper_htmlelement!(HTMLButtonElement, HTMLButtonElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLButtonElement, HTMLButtonElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLButtonElement)
generate_cacheable_wrapper_htmlelement!(HTMLCanvasElement, HTMLCanvasElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLCanvasElement, HTMLCanvasElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLCanvasElement)
generate_cacheable_wrapper_htmlelement!(HTMLDataListElement, HTMLDataListElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLDataListElement, HTMLDataListElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLDataListElement)
generate_cacheable_wrapper_htmlelement!(HTMLDListElement, HTMLDListElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLDListElement, HTMLDListElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLDListElement)
generate_cacheable_wrapper_htmlelement!(HTMLFormElement, HTMLFormElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLFormElement, HTMLFormElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLFormElement)
generate_cacheable_wrapper_htmlelement!(HTMLFrameElement, HTMLFrameElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLFrameElement, HTMLFrameElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLFrameElement)
generate_cacheable_wrapper_htmlelement!(HTMLFrameSetElement, HTMLFrameSetElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLFrameSetElement, HTMLFrameSetElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLFrameSetElement)
generate_cacheable_wrapper_htmlelement!(HTMLBRElement, HTMLBRElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLBRElement, HTMLBRElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLBRElement)
generate_cacheable_wrapper_htmlelement!(HTMLHRElement, HTMLHRElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLHRElement, HTMLHRElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLHRElement)
generate_cacheable_wrapper_htmlelement!(HTMLHtmlElement, HTMLHtmlElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLHtmlElement, HTMLHtmlElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLHtmlElement)
generate_cacheable_wrapper_htmlelement!(HTMLDataElement, HTMLDataElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLDataElement, HTMLDataElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLDataElement)
generate_cacheable_wrapper_htmlelement!(HTMLDirectoryElement, HTMLDirectoryElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLDirectoryElement, HTMLDirectoryElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLDirectoryElement)
generate_cacheable_wrapper_htmlelement!(HTMLDivElement, HTMLDivElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLDivElement, HTMLDivElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLDivElement)
generate_cacheable_wrapper_htmlelement!(HTMLEmbedElement, HTMLEmbedElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLEmbedElement, HTMLEmbedElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLEmbedElement)
generate_cacheable_wrapper_htmlelement!(HTMLFieldSetElement, HTMLFieldSetElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLFieldSetElement, HTMLFieldSetElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLFieldSetElement)
generate_cacheable_wrapper_htmlelement!(HTMLFontElement, HTMLFontElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLFontElement, HTMLFontElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLFontElement)
generate_cacheable_wrapper_htmlelement!(HTMLHeadingElement, HTMLHeadingElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLHeadingElement, HTMLHeadingElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLHeadingElement)
generate_cacheable_wrapper_htmlelement!(HTMLIFrameElement, HTMLIFrameElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLIFrameElement, HTMLIFrameElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLIFrameElement)
generate_cacheable_wrapper_htmlelement!(HTMLImageElement, HTMLImageElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLImageElement, HTMLImageElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLImageElement)
generate_cacheable_wrapper_htmlelement!(HTMLInputElement, HTMLInputElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLInputElement, HTMLInputElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLInputElement)
generate_cacheable_wrapper_htmlelement!(HTMLLabelElement, HTMLLabelElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLLabelElement, HTMLLabelElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLLabelElement)
generate_cacheable_wrapper_htmlelement!(HTMLLegendElement, HTMLLegendElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLLegendElement, HTMLLegendElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLLegendElement)
generate_cacheable_wrapper_htmlelement!(HTMLLIElement, HTMLLIElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLLIElement, HTMLLIElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLLIElement)
generate_cacheable_wrapper_htmlelement!(HTMLLinkElement, HTMLLinkElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLLinkElement, HTMLLinkElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLLinkElement)
generate_cacheable_wrapper_htmlelement!(HTMLMainElement, HTMLMainElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLMainElement, HTMLMainElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLMainElement)
generate_cacheable_wrapper_htmlelement!(HTMLMapElement, HTMLMapElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLMapElement, HTMLMapElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLMapElement)
generate_cacheable_wrapper_htmlelement!(HTMLMediaElement, HTMLMediaElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLMediaElement, HTMLMediaElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLMediaElement)
generate_cacheable_wrapper_htmlelement!(HTMLMetaElement, HTMLMetaElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLMetaElement, HTMLMetaElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLMetaElement)
generate_cacheable_wrapper_htmlelement!(HTMLMeterElement, HTMLMeterElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLMeterElement, HTMLMeterElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLMeterElement)
generate_cacheable_wrapper_htmlelement!(HTMLModElement, HTMLModElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLModElement, HTMLModElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLModElement)
generate_cacheable_wrapper_htmlelement!(HTMLObjectElement, HTMLObjectElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLObjectElement, HTMLObjectElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLObjectElement)
generate_cacheable_wrapper_htmlelement!(HTMLOListElement, HTMLOListElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLOListElement, HTMLOListElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLOListElement)
generate_cacheable_wrapper_htmlelement!(HTMLOptGroupElement, HTMLOptGroupElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLOptGroupElement, HTMLOptGroupElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLOptGroupElement)
generate_cacheable_wrapper_htmlelement!(HTMLOptionElement, HTMLOptionElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLOptionElement, HTMLOptionElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLOptionElement)
generate_cacheable_wrapper_htmlelement!(HTMLOutputElement, HTMLOutputElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLOutputElement, HTMLOutputElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLOutputElement)
generate_cacheable_wrapper_htmlelement!(HTMLParagraphElement, HTMLParagraphElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLParagraphElement, HTMLParagraphElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLParagraphElement)
generate_cacheable_wrapper_htmlelement!(HTMLParamElement, HTMLParamElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLParamElement, HTMLParamElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLParamElement)
generate_cacheable_wrapper_htmlelement!(HTMLPreElement, HTMLPreElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLPreElement, HTMLPreElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLPreElement)
generate_cacheable_wrapper_htmlelement!(HTMLProgressElement, HTMLProgressElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLProgressElement, HTMLProgressElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLProgressElement)
generate_cacheable_wrapper_htmlelement!(HTMLQuoteElement, HTMLQuoteElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLQuoteElement, HTMLQuoteElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLQuoteElement)
generate_cacheable_wrapper_htmlelement!(HTMLScriptElement, HTMLScriptElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLScriptElement, HTMLScriptElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLScriptElement)
generate_cacheable_wrapper_htmlelement!(HTMLSelectElement, HTMLSelectElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLSelectElement, HTMLSelectElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLSelectElement)
generate_cacheable_wrapper_htmlelement!(HTMLSourceElement, HTMLSourceElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLSourceElement, HTMLSourceElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLSourceElement)
generate_cacheable_wrapper_htmlelement!(HTMLSpanElement, HTMLSpanElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLSpanElement, HTMLSpanElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLSpanElement)
generate_cacheable_wrapper_htmlelement!(HTMLStyleElement, HTMLStyleElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLStyleElement, HTMLStyleElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLStyleElement)
generate_cacheable_wrapper_htmlelement!(HTMLTableElement, HTMLTableElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLTableElement, HTMLTableElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLTableElement)
generate_cacheable_wrapper_htmlelement!(HTMLTableCaptionElement, HTMLTableCaptionElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLTableCaptionElement, HTMLTableCaptionElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLTableCaptionElement)
generate_cacheable_wrapper_htmlelement!(HTMLTableCellElement, HTMLTableCellElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLTableCellElement, HTMLTableCellElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLTableCellElement)
generate_cacheable_wrapper_htmltablecellelement!(HTMLTableDataCellElement, HTMLTableDataCellElementBinding::Wrap) generate_cacheable_wrapper_htmltablecellelement!(HTMLTableDataCellElement, HTMLTableDataCellElementBinding::Wrap)
generate_traceable_htmltablecellelement!(HTMLTableDataCellElement)
generate_cacheable_wrapper_htmltablecellelement!(HTMLTableHeaderCellElement, HTMLTableHeaderCellElementBinding::Wrap) generate_cacheable_wrapper_htmltablecellelement!(HTMLTableHeaderCellElement, HTMLTableHeaderCellElementBinding::Wrap)
generate_traceable_htmltablecellelement!(HTMLTableHeaderCellElement)
generate_cacheable_wrapper_htmlelement!(HTMLTableColElement, HTMLTableColElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLTableColElement, HTMLTableColElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLTableColElement)
generate_cacheable_wrapper_htmlelement!(HTMLTableRowElement, HTMLTableRowElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLTableRowElement, HTMLTableRowElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLTableRowElement)
generate_cacheable_wrapper_htmlelement!(HTMLTableSectionElement, HTMLTableSectionElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLTableSectionElement, HTMLTableSectionElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLTableSectionElement)
generate_cacheable_wrapper_htmlelement!(HTMLTemplateElement, HTMLTemplateElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLTemplateElement, HTMLTemplateElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLTemplateElement)
generate_cacheable_wrapper_htmlelement!(HTMLTextAreaElement, HTMLTextAreaElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLTextAreaElement, HTMLTextAreaElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLTextAreaElement)
generate_cacheable_wrapper_htmlelement!(HTMLTitleElement, HTMLTitleElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLTitleElement, HTMLTitleElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLTitleElement)
generate_cacheable_wrapper_htmlelement!(HTMLTimeElement, HTMLTimeElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLTimeElement, HTMLTimeElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLTimeElement)
generate_cacheable_wrapper_htmlelement!(HTMLTrackElement, HTMLTrackElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLTrackElement, HTMLTrackElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLTrackElement)
generate_cacheable_wrapper_htmlelement!(HTMLUListElement, HTMLUListElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLUListElement, HTMLUListElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLUListElement)
generate_cacheable_wrapper_htmlelement!(HTMLUnknownElement, HTMLUnknownElementBinding::Wrap) generate_cacheable_wrapper_htmlelement!(HTMLUnknownElement, HTMLUnknownElementBinding::Wrap)
generate_traceable_htmlelement!(HTMLUnknownElement)
generate_cacheable_wrapper_htmlmediaelement!(HTMLVideoElement, HTMLVideoElementBinding::Wrap) generate_cacheable_wrapper_htmlmediaelement!(HTMLVideoElement, HTMLVideoElementBinding::Wrap)
generate_traceable_htmlmediaelement!(HTMLVideoElement)
generate_cacheable_wrapper!(HTMLElement, HTMLElementBinding::Wrap) generate_cacheable_wrapper!(HTMLElement, HTMLElementBinding::Wrap)
generate_traceable!(HTMLElement)
generate_traceable_node!(Element)
generate_traceable_node!(CharacterData)

View file

@ -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)
}
}

View file

@ -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());
}
}

View file

@ -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) {
}
}

View file

@ -4,11 +4,13 @@
use dom::bindings::codegen::PrototypeList; use dom::bindings::codegen::PrototypeList;
use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH; use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
use dom::bindings::js::JS;
use dom::window; use dom::window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use std::libc::c_uint; use std::libc::c_uint;
use std::cast; use std::cast;
use std::cmp::Eq;
use std::hashmap::HashMap; use std::hashmap::HashMap;
use std::libc; use std::libc;
use std::ptr; 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::{JSFunctionSpec, JSPropertySpec, JSVal, JSPropertyDescriptor};
use js::jsapi::{JS_NewGlobalObject, JS_InitStandardClasses}; use js::jsapi::{JS_NewGlobalObject, JS_InitStandardClasses};
use js::jsapi::{JSString, JS_CallTracer, JSTRACE_OBJECT}; 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::jsfriendapi::bindgen::JS_NewObjectWithUniqueType;
use js::{JSPROP_ENUMERATE, JSVAL_NULL, JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS}; use js::{JSPROP_ENUMERATE, JSVAL_NULL, JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS};
use js::{JSPROP_PERMANENT, JSID_VOID, JSPROP_NATIVE_ACCESSORS, JSPROP_GETTER}; 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, ()> { pub fn unwrap_value<T>(val: *JSVal, proto_id: PrototypeList::id::ID, proto_depth: uint) -> Result<T, ()> {
unsafe { unsafe {
let obj = RUST_JSVAL_TO_OBJECT(*val); 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> { pub unsafe fn squirrel_away<T>(x: @mut T) -> *Box<T> {
let y: *Box<T> = cast::transmute(x); cast::transmute(x)
y }
pub unsafe fn squirrel_away_unique<T>(x: ~T) -> *Box<T> {
cast::transmute(x)
} }
pub fn jsstring_to_str(cx: *JSContext, s: *JSString) -> DOMString { 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) { pub fn initialize_global(global: *JSObject) {
let protoArray = @mut ([0 as *JSObject, ..PrototypeList::id::_ID_Count as uint]); let protoArray = @mut ([0 as *JSObject, ..PrototypeList::id::_ID_Count as uint]);
unsafe { unsafe {
@ -579,21 +591,17 @@ pub trait Reflectable {
} }
pub fn reflect_dom_object<T: Reflectable> pub fn reflect_dom_object<T: Reflectable>
(obj: @mut T, (obj: ~T,
window: &window::Window, window: &window::Window,
wrap_fn: extern "Rust" fn(*JSContext, *JSObject, @mut T) -> *JSObject) wrap_fn: extern "Rust" fn(*JSContext, *JSObject, ~T) -> *JSObject)
-> @mut T { -> JS<T> {
let cx = window.get_cx(); JS::new(obj, window, wrap_fn)
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
} }
#[deriving(Eq)]
pub struct Reflector { pub struct Reflector {
object: *JSObject object: *JSObject,
force_box_layout: @int,
} }
impl Reflector { impl Reflector {
@ -610,7 +618,8 @@ impl Reflector {
pub fn new() -> Reflector { pub fn new() -> Reflector {
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. /// 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()) 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()) cx_for_dom_reflector(obj.reflector().get_jsobject())
} }
@ -870,6 +879,35 @@ pub fn throw_method_failed_with_details<T>(cx: *JSContext,
return 0; return 0;
} }
pub fn throw_not_in_union(cx: *JSContext, names: &'static str) -> JSBool {
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
let message = format!("argument could not be converted to any of: {}", names);
message.with_c_str(|string| {
unsafe { ReportError(cx, string) };
});
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 /// Check if an element name is valid. See http://www.w3.org/TR/xml/#NT-Name
/// for details. /// for details.
#[deriving(Eq)] #[deriving(Eq)]

View file

@ -2,32 +2,36 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::utils::Fallible; use dom::bindings::utils::Fallible;
use dom::bindings::codegen::BlobBinding; use dom::bindings::codegen::BlobBinding;
use dom::window::Window; use dom::window::Window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct Blob { pub struct Blob {
reflector_: Reflector, reflector_: Reflector,
window: @mut Window, window: JS<Window>
} }
impl Blob { impl Blob {
pub fn new_inherited(window: @mut Window) -> Blob { pub fn new_inherited(window: JS<Window>) -> Blob {
Blob { Blob {
reflector_: Reflector::new(), reflector_: Reflector::new(),
window: window, window: window
} }
} }
pub fn new(window: @mut Window) -> @mut Blob { pub fn new(window: &JS<Window>) -> JS<Blob> {
reflect_dom_object(@mut Blob::new_inherited(window), window, BlobBinding::Wrap) reflect_dom_object(~Blob::new_inherited(window.clone()),
window.get(),
BlobBinding::Wrap)
} }
} }
impl Blob { impl Blob {
pub fn Constructor(window: @mut Window) -> Fallible<@mut Blob> { pub fn Constructor(window: &JS<Window>) -> Fallible<JS<Blob>> {
Ok(Blob::new(window)) Ok(Blob::new(window))
} }
@ -39,8 +43,8 @@ impl Blob {
~"" ~""
} }
pub fn Slice(&self, _start: i64, _end: i64, _contentType: Option<DOMString>) -> @mut Blob { pub fn Slice(&self, _start: i64, _end: i64, _contentType: Option<DOMString>) -> JS<Blob> {
Blob::new(self.window) Blob::new(&self.window)
} }
pub fn Close(&self) {} pub fn Close(&self) {}

View file

@ -4,19 +4,34 @@
//! DOM bindings for `CharacterData`. //! 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::{Fallible, ErrorResult};
use dom::bindings::utils::{Reflectable, Reflector}; use dom::bindings::utils::{Reflectable, Reflector};
use dom::document::AbstractDocument; use dom::document::Document;
use dom::node::{Node, NodeTypeId}; use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::node::{CommentNodeTypeId, Node, NodeTypeId, TextNodeTypeId, ProcessingInstructionNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct CharacterData { pub struct CharacterData {
node: Node, node: Node,
data: DOMString, 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 { 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 { CharacterData {
node: Node::new_inherited(id, document), node: Node::new_inherited(id, document),
data: data data: data

View file

@ -3,21 +3,23 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::ClientRectBinding; use dom::bindings::codegen::ClientRectBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::window::Window; use dom::window::Window;
use servo_util::geometry::Au; use servo_util::geometry::Au;
#[deriving(Encodable)]
pub struct ClientRect { pub struct ClientRect {
reflector_: Reflector, reflector_: Reflector,
top: f32, top: f32,
bottom: f32, bottom: f32,
left: f32, left: f32,
right: f32, right: f32,
window: @mut Window, window: JS<Window>,
} }
impl ClientRect { impl ClientRect {
pub fn new_inherited(window: @mut Window, pub fn new_inherited(window: JS<Window>,
top: Au, bottom: Au, top: Au, bottom: Au,
left: Au, right: Au) -> ClientRect { left: Au, right: Au) -> ClientRect {
ClientRect { ClientRect {
@ -30,11 +32,11 @@ impl ClientRect {
} }
} }
pub fn new(window: @mut Window, pub fn new(window: &JS<Window>,
top: Au, bottom: Au, top: Au, bottom: Au,
left: Au, right: Au) -> @mut ClientRect { left: Au, right: Au) -> JS<ClientRect> {
let rect = ClientRect::new_inherited(window, top, bottom, left, right); let rect = ClientRect::new_inherited(window.clone(), top, bottom, left, right);
reflect_dom_object(@mut rect, window, ClientRectBinding::Wrap) reflect_dom_object(~rect, window.get(), ClientRectBinding::Wrap)
} }

View file

@ -3,19 +3,21 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::ClientRectListBinding; use dom::bindings::codegen::ClientRectListBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::clientrect::ClientRect; use dom::clientrect::ClientRect;
use dom::window::Window; use dom::window::Window;
#[deriving(Encodable)]
pub struct ClientRectList { pub struct ClientRectList {
reflector_: Reflector, reflector_: Reflector,
rects: ~[@mut ClientRect], rects: ~[JS<ClientRect>],
window: @mut Window, window: JS<Window>,
} }
impl ClientRectList { impl ClientRectList {
pub fn new_inherited(window: @mut Window, pub fn new_inherited(window: JS<Window>,
rects: ~[@mut ClientRect]) -> ClientRectList { rects: ~[JS<ClientRect>]) -> ClientRectList {
ClientRectList { ClientRectList {
reflector_: Reflector::new(), reflector_: Reflector::new(),
rects: rects, rects: rects,
@ -23,25 +25,25 @@ impl ClientRectList {
} }
} }
pub fn new(window: @mut Window, pub fn new(window: &JS<Window>,
rects: ~[@mut ClientRect]) -> @mut ClientRectList { rects: ~[JS<ClientRect>]) -> JS<ClientRectList> {
reflect_dom_object(@mut ClientRectList::new_inherited(window, rects), reflect_dom_object(~ClientRectList::new_inherited(window.clone(), rects),
window, ClientRectListBinding::Wrap) window.get(), ClientRectListBinding::Wrap)
} }
pub fn Length(&self) -> u32 { pub fn Length(&self) -> u32 {
self.rects.len() as 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 { if index < self.rects.len() as u32 {
Some(self.rects[index]) Some(self.rects[index].clone())
} else { } else {
None 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; *found = index < self.rects.len() as u32;
self.Item(index) self.Item(index)
} }

View file

@ -2,32 +2,45 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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::codegen::CommentBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::Fallible; use dom::bindings::utils::Fallible;
use dom::characterdata::CharacterData; use dom::characterdata::CharacterData;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::node::{AbstractNode, CommentNodeTypeId, Node}; use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::node::{CommentNodeTypeId, Node};
use dom::window::Window; use dom::window::Window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
/// An HTML comment. /// An HTML comment.
#[deriving(Encodable)]
pub struct Comment { pub struct Comment {
characterdata: CharacterData, characterdata: CharacterData,
} }
impl CommentDerived for EventTarget {
fn is_comment(&self) -> bool {
match self.type_id {
NodeTargetTypeId(CommentNodeTypeId) => true,
_ => false
}
}
}
impl Comment { impl Comment {
pub fn new_inherited(text: DOMString, document: AbstractDocument) -> Comment { pub fn new_inherited(text: DOMString, document: JS<Document>) -> Comment {
Comment { Comment {
characterdata: CharacterData::new_inherited(CommentNodeTypeId, text, document) characterdata: CharacterData::new_inherited(CommentNodeTypeId, text, document)
} }
} }
pub fn new(text: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(text: DOMString, document: &JS<Document>) -> JS<Comment> {
let node = Comment::new_inherited(text, document); let node = Comment::new_inherited(text, document.clone());
Node::reflect_node(@mut node, document, CommentBinding::Wrap) Node::reflect_node(~node, document, CommentBinding::Wrap)
} }
pub fn Constructor(owner: @mut Window, data: DOMString) -> Fallible<AbstractNode> { pub fn Constructor(owner: &JS<Window>, data: DOMString) -> Fallible<JS<Comment>> {
Ok(Comment::new(data, owner.Document())) Ok(Comment::new(data, &owner.get().Document()))
} }
} }

View file

@ -2,11 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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::codegen::ConsoleBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::window::Window; use dom::window::Window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct Console { pub struct Console {
reflector_: Reflector reflector_: Reflector
} }
@ -18,8 +20,8 @@ impl Console {
} }
} }
pub fn new(window: &Window) -> @mut Console { pub fn new(window: &Window) -> JS<Console> {
reflect_dom_object(@mut Console::new_inherited(), window, ConsoleBinding::Wrap) reflect_dom_object(~Console::new_inherited(), window, ConsoleBinding::Wrap)
} }
pub fn Log(&self, message: DOMString) { pub fn Log(&self, message: DOMString) {

View file

@ -2,25 +2,35 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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::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::{ErrorResult, Fallible, NotSupported, InvalidCharacter, HierarchyRequest};
use dom::bindings::utils::{xml_name_type, InvalidXMLName}; use dom::bindings::utils::{xml_name_type, InvalidXMLName};
use dom::comment::Comment;
use dom::documentfragment::DocumentFragment; use dom::documentfragment::DocumentFragment;
use dom::documenttype::DocumentType;
use dom::domimplementation::DOMImplementation; use dom::domimplementation::DOMImplementation;
use dom::element::{Element}; use dom::element::{Element};
use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElementTypeId, HTMLBodyElementTypeId, HTMLFrameSetElementTypeId}; use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElementTypeId};
use dom::event::{AbstractEvent, Event}; use dom::element::{HTMLBodyElementTypeId, HTMLFrameSetElementTypeId};
use dom::event::Event;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlcollection::HTMLCollection; 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::mouseevent::MouseEvent;
use dom::node::{AbstractNode, Node, ElementNodeTypeId, DocumentNodeTypeId}; use dom::node::{Node, ElementNodeTypeId, DocumentNodeTypeId, NodeHelpers, INode};
use dom::text::Text; use dom::text::Text;
use dom::processinginstruction::ProcessingInstruction; use dom::processinginstruction::ProcessingInstruction;
use dom::uievent::UIEvent; use dom::uievent::UIEvent;
use dom::window::Window; use dom::window::Window;
use dom::htmltitleelement::HTMLTitleElement;
use html::hubbub_html_parser::build_element_from_tag; use html::hubbub_html_parser::build_element_from_tag;
use hubbub::hubbub::{QuirksMode, NoQuirks, LimitedQuirks, FullQuirks}; use hubbub::hubbub::{QuirksMode, NoQuirks, LimitedQuirks, FullQuirks};
use layout_interface::{DocumentDamageLevel, ContentChangedDocumentDamage}; use layout_interface::{DocumentDamageLevel, ContentChangedDocumentDamage};
@ -28,154 +38,109 @@ use servo_util::namespace::Null;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use extra::url::{Url, from_str}; use extra::url::{Url, from_str};
use js::jsapi::{JSObject, JSContext, JSTracer}; use js::jsapi::{JSObject, JSContext};
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use std::cast;
use std::hashmap::HashMap; use std::hashmap::HashMap;
use std::unstable::raw::Box;
#[deriving(Eq)] use extra::serialize::{Encoder, Encodable};
pub enum DocumentTypeId {
PlainDocumentTypeId, #[deriving(Eq,Encodable)]
HTMLDocumentTypeId pub enum IsHTMLDocument {
} HTMLDocument,
NonHTMLDocument,
#[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)]
pub enum DocumentType {
HTML,
SVG,
XML
} }
#[deriving(Encodable)]
pub struct Document { pub struct Document {
node: Node, node: Node,
reflector_: Reflector, reflector_: Reflector,
window: @mut Window, window: JS<Window>,
doctype: DocumentType, idmap: HashMap<DOMString, JS<Element>>,
idmap: HashMap<DOMString, AbstractNode>, implementation: Option<JS<DOMImplementation>>,
implementation: Option<@mut DOMImplementation>,
content_type: DOMString, content_type: DOMString,
encoding_name: DOMString,
is_html_document: bool,
extra: Untraceable,
}
struct Untraceable {
url: Url, url: Url,
quirks_mode: QuirksMode, 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 { impl Document {
pub fn reflect_document<D: Reflectable> pub fn reflect_document<D: Reflectable+DocumentBase>
(document: @mut D, (document: ~D,
window: @mut Window, window: &JS<Window>,
wrap_fn: extern "Rust" fn(*JSContext, *JSObject, @mut D) -> *JSObject) wrap_fn: extern "Rust" fn(*JSContext, *JSObject, ~D) -> *JSObject)
-> AbstractDocument { -> JS<D> {
assert!(document.reflector().get_jsobject().is_null()); assert!(document.reflector().get_jsobject().is_null());
let document = reflect_dom_object(document, window, wrap_fn); let raw_doc = reflect_dom_object(document, window.get(), wrap_fn);
assert!(document.reflector().get_jsobject().is_not_null()); assert!(raw_doc.reflector().get_jsobject().is_not_null());
// JS object now owns the Document, so transmute_copy is needed let document = DocumentCast::from(&raw_doc);
let abstract = AbstractDocument { let mut node: JS<Node> = NodeCast::from(&document);
document: unsafe { cast::transmute_copy(&document) } node.get_mut().set_owner_doc(&document);
}; raw_doc
abstract.mut_document().node.set_owner_doc(abstract);
abstract
} }
pub fn new_inherited(window: @mut Window, url: Option<Url>, doctype: DocumentType, content_type: Option<DOMString>) -> Document { pub fn new_inherited(window: JS<Window>,
let node_type = match doctype { url: Option<Url>,
HTML => HTMLDocumentTypeId, is_html_document: IsHTMLDocument,
SVG | XML => PlainDocumentTypeId content_type: Option<DOMString>) -> Document {
};
Document { Document {
node: Node::new_without_doc(DocumentNodeTypeId(node_type)), node: Node::new_without_doc(DocumentNodeTypeId),
reflector_: Reflector::new(), reflector_: Reflector::new(),
window: window, window: window,
doctype: doctype,
idmap: HashMap::new(), idmap: HashMap::new(),
implementation: None, implementation: None,
content_type: match content_type { content_type: match content_type {
Some(string) => string.clone(), Some(string) => string.clone(),
None => match doctype { None => match is_html_document {
// http://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument // http://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
HTML => ~"text/html", HTMLDocument => ~"text/html",
// http://dom.spec.whatwg.org/#concept-document-content-type // http://dom.spec.whatwg.org/#concept-document-content-type
SVG | XML => ~"application/xml" NonHTMLDocument => ~"application/xml"
} }
}, },
extra: Untraceable {
url: match url { url: match url {
None => from_str("about:blank").unwrap(), None => from_str("about:blank").unwrap(),
Some(_url) => _url Some(_url) => _url
}, },
// http://dom.spec.whatwg.org/#concept-document-quirks // http://dom.spec.whatwg.org/#concept-document-quirks
quirks_mode: NoQuirks, quirks_mode: NoQuirks,
},
// http://dom.spec.whatwg.org/#concept-document-encoding // http://dom.spec.whatwg.org/#concept-document-encoding
encoding_name: ~"utf-8", encoding_name: ~"utf-8",
is_html_document: is_html_document == HTMLDocument,
} }
} }
pub fn new(window: @mut Window, url: Option<Url>, doctype: DocumentType, content_type: Option<DOMString>) -> AbstractDocument { pub fn new(window: &JS<Window>, url: Option<Url>, doctype: IsHTMLDocument, content_type: Option<DOMString>) -> JS<Document> {
let document = Document::new_inherited(window, url, doctype, content_type); let document = Document::new_inherited(window.clone(), url, doctype, content_type);
Document::reflect_document(@mut document, window, DocumentBinding::Wrap) Document::reflect_document(~document, window, DocumentBinding::Wrap)
} }
} }
impl Document { impl Document {
// http://dom.spec.whatwg.org/#dom-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)) Ok(Document::new(owner, None, NonHTMLDocument, 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()
} }
} }
@ -191,16 +156,16 @@ impl Reflectable for Document {
impl Document { impl Document {
// http://dom.spec.whatwg.org/#dom-document-implementation // 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() { 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 // http://dom.spec.whatwg.org/#dom-document-url
pub fn URL(&self) -> DOMString { pub fn URL(&self) -> DOMString {
self.url.to_str() self.extra.url.to_str()
} }
// http://dom.spec.whatwg.org/#dom-document-documenturi // http://dom.spec.whatwg.org/#dom-document-documenturi
@ -210,14 +175,14 @@ impl Document {
// http://dom.spec.whatwg.org/#dom-document-compatmode // http://dom.spec.whatwg.org/#dom-document-compatmode
pub fn CompatMode(&self) -> DOMString { pub fn CompatMode(&self) -> DOMString {
match self.quirks_mode { match self.extra.quirks_mode {
NoQuirks => ~"CSS1Compat", NoQuirks => ~"CSS1Compat",
LimitedQuirks | FullQuirks => ~"BackCompat" LimitedQuirks | FullQuirks => ~"BackCompat"
} }
} }
pub fn set_quirks_mode(&mut self, mode: QuirksMode) { 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 // http://dom.spec.whatwg.org/#dom-document-characterset
@ -235,43 +200,34 @@ impl Document {
} }
// http://dom.spec.whatwg.org/#dom-document-doctype // http://dom.spec.whatwg.org/#dom-document-doctype
pub fn GetDoctype(&self) -> Option<AbstractNode> { pub fn GetDoctype(&self) -> Option<JS<DocumentType>> {
self.node.children().find(|child| child.is_doctype()) self.node.children().find(|child| child.is_doctype())
.map(|node| DocumentTypeCast::to(&node))
} }
// http://dom.spec.whatwg.org/#dom-document-documentelement // 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() self.node.child_elements().next()
} }
// http://dom.spec.whatwg.org/#dom-document-getelementsbytagname // 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) 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, ~[])
}
// http://dom.spec.whatwg.org/#dom-document-getelementsbyclassname
pub fn GetElementsByClassName(&self, _class: DOMString) -> @mut HTMLCollection {
HTMLCollection::new(self.window, ~[])
}
// http://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid // 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" // TODO: "in tree order, within the context object's tree"
// http://dom.spec.whatwg.org/#dom-document-getelementbyid. // http://dom.spec.whatwg.org/#dom-document-getelementbyid.
match self.idmap.find_equiv(&id) { match self.idmap.find_equiv(&id) {
None => None, None => None,
Some(node) => Some(*node), Some(node) => Some(node.clone()),
} }
} }
// http://dom.spec.whatwg.org/#dom-document-createelement // http://dom.spec.whatwg.org/#dom-document-createelement
pub fn CreateElement(&self, abstract_self: AbstractDocument, local_name: DOMString) pub fn CreateElement(&self, abstract_self: &JS<Document>, local_name: DOMString)
-> Fallible<AbstractNode> { -> Fallible<JS<Element>> {
if xml_name_type(local_name) == InvalidXMLName { if xml_name_type(local_name) == InvalidXMLName {
debug!("Not a valid element name"); debug!("Not a valid element name");
return Err(InvalidCharacter); return Err(InvalidCharacter);
@ -281,24 +237,24 @@ impl Document {
} }
// http://dom.spec.whatwg.org/#dom-document-createdocumentfragment // 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) DocumentFragment::new(abstract_self)
} }
// http://dom.spec.whatwg.org/#dom-document-createtextnode // http://dom.spec.whatwg.org/#dom-document-createtextnode
pub fn CreateTextNode(&self, abstract_self: AbstractDocument, data: DOMString) pub fn CreateTextNode(&self, abstract_self: &JS<Document>, data: DOMString)
-> AbstractNode { -> JS<Text> {
Text::new(data, abstract_self) Text::new(data, abstract_self)
} }
// http://dom.spec.whatwg.org/#dom-document-createcomment // 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) Comment::new(data, abstract_self)
} }
// http://dom.spec.whatwg.org/#dom-document-createprocessinginstruction // http://dom.spec.whatwg.org/#dom-document-createprocessinginstruction
pub fn CreateProcessingInstruction(&self, abstract_self: AbstractDocument, target: DOMString, pub fn CreateProcessingInstruction(&self, abstract_self: &JS<Document>, target: DOMString,
data: DOMString) -> Fallible<AbstractNode> { data: DOMString) -> Fallible<JS<ProcessingInstruction>> {
// Step 1. // Step 1.
if xml_name_type(target) == InvalidXMLName { if xml_name_type(target) == InvalidXMLName {
return Err(InvalidCharacter); return Err(InvalidCharacter);
@ -314,43 +270,29 @@ impl Document {
} }
// http://dom.spec.whatwg.org/#dom-document-createevent // 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() { match interface.as_slice() {
"UIEvents" => Ok(UIEvent::new(self.window)), "UIEvents" => Ok(EventCast::from(&UIEvent::new(&self.window))),
"MouseEvents" => Ok(MouseEvent::new(self.window)), "MouseEvents" => Ok(EventCast::from(&MouseEvent::new(&self.window))),
"HTMLEvents" => Ok(Event::new(self.window)), "HTMLEvents" => Ok(Event::new(&self.window)),
_ => Err(NotSupported) _ => Err(NotSupported)
} }
} }
// http://www.whatwg.org/specs/web-apps/current-work/#document.title // 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 = ~""; let mut title = ~"";
match self.doctype { self.GetDocumentElement().map(|root| {
SVG => { let root: JS<Node> = NodeCast::from(&root);
fail!("no SVG document yet") root.traverse_preorder()
}, .find(|node| node.type_id() == ElementNodeTypeId(HTMLTitleElementTypeId))
_ => { .map(|title_elem| {
match self.GetDocumentElement() { for child in title_elem.children() {
None => {}, let text: JS<Text> = TextCast::to(&child);
Some(root) => { title.push_str(text.get().characterdata.data.as_slice());
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());
}); });
} });
}
break;
}
}
}
}
}
let v: ~[&str] = title.words().collect(); let v: ~[&str] = title.words().collect();
title = v.connect(" "); title = v.connect(" ");
title = title.trim().to_owned(); title = title.trim().to_owned();
@ -358,85 +300,74 @@ impl Document {
} }
// http://www.whatwg.org/specs/web-apps/current-work/#document.title // 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 { self.GetDocumentElement().map(|root| {
SVG => { let root: JS<Node> = NodeCast::from(&root);
fail!("no SVG document yet") let mut head_node = root.traverse_preorder().find(|child| {
}, child.get().type_id == ElementNodeTypeId(HTMLHeadElementTypeId)
_ => { });
match self.GetDocumentElement() { head_node.as_mut().map(|head| {
None => {},
Some(root) => { let mut title_node = head.children().find(|child| {
for node in root.traverse_preorder() { child.get().type_id == ElementNodeTypeId(HTMLTitleElementTypeId)
if node.type_id() != ElementNodeTypeId(HTMLHeadElementTypeId) { });
continue;
} title_node.as_mut().map(|title_node| {
let mut has_title = false; for mut title_child in title_node.children() {
for child in node.children() { title_node.RemoveChild(&mut title_child);
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);
}
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(()) Ok(())
} }
fn get_html_element(&self) -> Option<AbstractNode> { fn get_html_element(&self) -> Option<JS<HTMLHtmlElement>> {
self.GetDocumentElement().filtered(|root| { self.GetDocumentElement().filtered(|root| {
match root.type_id() { root.get().node.type_id == ElementNodeTypeId(HTMLHtmlElementTypeId)
ElementNodeTypeId(HTMLHtmlElementTypeId) => true, }).map(|elem| HTMLHtmlElementCast::to(&elem))
_ => false
}
})
} }
// http://www.whatwg.org/specs/web-apps/current-work/#dom-document-head // 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| { 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) child.type_id() == ElementNodeTypeId(HTMLHeadElementTypeId)
}) }).map(|node| HTMLHeadElementCast::to(&node))
}) })
} }
// http://www.whatwg.org/specs/web-apps/current-work/#dom-document-body // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-body
pub fn GetBody(&self, _: AbstractDocument) -> Option<AbstractNode> { pub fn GetBody(&self, _: &JS<Document>) -> Option<JS<HTMLElement>> {
match self.get_html_element() { self.get_html_element().and_then(|root| {
None => None, let node: JS<Node> = NodeCast::from(&root);
Some(root) => { node.children().find(|child| {
root.children().find(|child| {
match child.type_id() { match child.type_id() {
ElementNodeTypeId(HTMLBodyElementTypeId) | ElementNodeTypeId(HTMLBodyElementTypeId) |
ElementNodeTypeId(HTMLFrameSetElementTypeId) => true, ElementNodeTypeId(HTMLFrameSetElementTypeId) => true,
_ => false _ => false
} }
}).map(|node| HTMLElementCast::to(&node))
}) })
} }
}
}
// http://www.whatwg.org/specs/web-apps/current-work/#dom-document-body // 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. // Step 1.
match new_body { match new_body {
Some(node) => { Some(ref node) => {
match node.type_id() { match node.get().element.node.type_id {
ElementNodeTypeId(HTMLBodyElementTypeId) | ElementNodeTypeId(HTMLFrameSetElementTypeId) => {} ElementNodeTypeId(HTMLBodyElementTypeId) | ElementNodeTypeId(HTMLFrameSetElementTypeId) => {}
_ => return Err(HierarchyRequest) _ => return Err(HierarchyRequest)
} }
@ -445,7 +376,7 @@ impl Document {
} }
// Step 2. // 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 { if old_body == new_body {
return Ok(()); return Ok(());
} }
@ -455,41 +386,84 @@ impl Document {
// Step 4. // Step 4.
None => return Err(HierarchyRequest), None => return Err(HierarchyRequest),
Some(root) => { Some(root) => {
let mut new_body: JS<Node> = NodeCast::from(&new_body.unwrap());
let mut root: JS<Node> = NodeCast::from(&root);
match old_body { match old_body {
Some(child) => { root.ReplaceChild(new_body.unwrap(), child); } Some(child) => {
None => { root.AppendChild(new_body.unwrap()); } let mut child: JS<Node> = NodeCast::from(&child);
root.ReplaceChild(&mut new_body, &mut child)
} }
None => root.AppendChild(&mut new_body)
};
} }
} }
Ok(()) Ok(())
} }
// http://www.whatwg.org/specs/web-apps/current-work/#dom-document-getelementsbyname // 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| { self.createHTMLCollection(|elem| {
elem.get_attribute(Null, "name").map_default(false, |attr| { 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 Images(&self) -> JS<HTMLCollection> {
self.createHTMLCollection(|elem| "img" == elem.tag_name)
}
pub fn Embeds(&self) -> JS<HTMLCollection> {
self.createHTMLCollection(|elem| "embed" == elem.tag_name)
}
pub fn Plugins(&self) -> JS<HTMLCollection> {
self.Embeds()
}
pub fn Links(&self) -> JS<HTMLCollection> {
self.createHTMLCollection(|elem| {
("a" == elem.tag_name || "area" == elem.tag_name) &&
elem.get_attribute(Null, "href").is_some()
})
}
pub fn Forms(&self) -> JS<HTMLCollection> {
self.createHTMLCollection(|elem| "form" == elem.tag_name)
}
pub fn Scripts(&self) -> JS<HTMLCollection> {
self.createHTMLCollection(|elem| "script" == elem.tag_name)
}
pub fn Anchors(&self) -> JS<HTMLCollection> {
self.createHTMLCollection(|elem| {
"a" == elem.tag_name && elem.get_attribute(Null, "name").is_some()
})
}
pub fn Applets(&self) -> JS<HTMLCollection> {
// FIXME: This should be return OBJECT elements containing applets.
self.createHTMLCollection(|elem| "applet" == elem.tag_name)
}
pub fn createHTMLCollection(&self, callback: |elem: &Element| -> bool) -> JS<HTMLCollection> {
let mut elements = ~[]; let mut elements = ~[];
match self.GetDocumentElement() { match self.GetDocumentElement() {
None => {}, None => {},
Some(root) => { Some(root) => {
let root: JS<Node> = NodeCast::from(&root);
for child in root.traverse_preorder() { for child in root.traverse_preorder() {
if child.is_element() { if child.is_element() {
child.with_imm_element(|elem| { let elem: JS<Element> = ElementCast::to(&child);
if callback(elem) { if callback(elem.get()) {
elements.push(child); elements.push(elem);
}
});
} }
} }
} }
} }
HTMLCollection::new(self.window, elements) }
HTMLCollection::new(&self.window, elements)
} }
pub fn content_changed(&self) { pub fn content_changed(&self) {
@ -497,22 +471,22 @@ impl Document {
} }
pub fn damage_and_reflow(&self, damage: DocumentDamageLevel) { 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) { 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) { pub fn register_nodes_with_id(&mut self, root: &JS<Element>) {
foreach_ided_elements(root, |id: &DOMString, abstract_node: &AbstractNode| { foreach_ided_elements(root, |id: &DOMString, abstract_node: &JS<Element>| {
// TODO: "in tree order, within the context object's tree" // TODO: "in tree order, within the context object's tree"
// http://dom.spec.whatwg.org/#dom-document-getelementbyid. // 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, _| { foreach_ided_elements(root, |id: &DOMString, _| {
// TODO: "in tree order, within the context object's tree" // TODO: "in tree order, within the context object's tree"
// http://dom.spec.whatwg.org/#dom-document-getelementbyid. // http://dom.spec.whatwg.org/#dom-document-getelementbyid.
@ -521,7 +495,7 @@ impl Document {
} }
pub fn update_idmap(&mut self, pub fn update_idmap(&mut self,
abstract_self: AbstractNode, abstract_self: &JS<Element>,
new_id: Option<DOMString>, new_id: Option<DOMString>,
old_id: Option<DOMString>) { old_id: Option<DOMString>) {
// remove old ids: // remove old ids:
@ -539,11 +513,11 @@ impl Document {
Some(new_id) => { Some(new_id) => {
// TODO: support the case if multiple elements // TODO: support the case if multiple elements
// which haves same id are in the same document. // which haves same id are in the same document.
self.idmap.mangle(new_id, abstract_self, self.idmap.mangle(new_id, abstract_self.clone(),
|_, new_node: AbstractNode| -> AbstractNode { |_, new_node: JS<Element>| -> JS<Element> {
new_node new_node
}, },
|_, old_node: &mut AbstractNode, new_node: AbstractNode| { |_, old_node: &mut JS<Element>, new_node: JS<Element>| {
*old_node = new_node; *old_node = new_node;
}); });
} }
@ -553,25 +527,19 @@ impl Document {
} }
#[inline(always)] #[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() { for node in root.traverse_preorder() {
if !node.is_element() { if !node.is_element() {
continue; continue;
} }
node.with_imm_element(|element| { let element: JS<Element> = ElementCast::to(&node);
match element.get_attribute(Null, "id") { match element.get().get_attribute(Null, "id") {
Some(id) => { Some(id) => {
callback(&id.Value(), &node); callback(&id.get().Value(), &element);
} }
None => () None => ()
} }
});
}
}
impl Traceable for Document {
fn trace(&self, tracer: *mut JSTracer) {
self.node.trace(tracer);
} }
} }

View file

@ -2,32 +2,45 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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::codegen::DocumentFragmentBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::Fallible; use dom::bindings::utils::Fallible;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::node::{AbstractNode, DocumentFragmentNodeTypeId, Node}; use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::node::{DocumentFragmentNodeTypeId, Node};
use dom::window::Window; use dom::window::Window;
#[deriving(Encodable)]
pub struct DocumentFragment { pub struct DocumentFragment {
node: Node, node: Node,
} }
impl DocumentFragmentDerived for EventTarget {
fn is_documentfragment(&self) -> bool {
match self.type_id {
NodeTargetTypeId(DocumentFragmentNodeTypeId) => true,
_ => false
}
}
}
impl DocumentFragment { impl DocumentFragment {
/// Creates a new DocumentFragment. /// Creates a new DocumentFragment.
pub fn new_inherited(document: AbstractDocument) -> DocumentFragment { pub fn new_inherited(document: JS<Document>) -> DocumentFragment {
DocumentFragment { DocumentFragment {
node: Node::new_inherited(DocumentFragmentNodeTypeId, document), node: Node::new_inherited(DocumentFragmentNodeTypeId, document),
} }
} }
pub fn new(document: AbstractDocument) -> AbstractNode { pub fn new(document: &JS<Document>) -> JS<DocumentFragment> {
let node = DocumentFragment::new_inherited(document); let node = DocumentFragment::new_inherited(document.clone());
Node::reflect_node(@mut node, document, DocumentFragmentBinding::Wrap) Node::reflect_node(~node, document, DocumentFragmentBinding::Wrap)
} }
} }
impl DocumentFragment { impl DocumentFragment {
pub fn Constructor(owner: @mut Window) -> Fallible<AbstractNode> { pub fn Constructor(owner: &JS<Window>) -> Fallible<JS<DocumentFragment>> {
Ok(DocumentFragment::new(owner.Document())) Ok(DocumentFragment::new(&owner.get().Document()))
} }
} }

View file

@ -2,12 +2,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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::bindings::codegen::DocumentTypeBinding;
use dom::document::AbstractDocument; use dom::bindings::js::JS;
use dom::node::{AbstractNode, Node, DoctypeNodeTypeId}; use dom::document::Document;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::node::{Node, DoctypeNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
/// The `DOCTYPE` tag. /// The `DOCTYPE` tag.
#[deriving(Encodable)]
pub struct DocumentType { pub struct DocumentType {
node: Node, node: Node,
name: DOMString, name: DOMString,
@ -15,11 +19,20 @@ pub struct DocumentType {
system_id: DOMString, system_id: DOMString,
} }
impl DocumentTypeDerived for EventTarget {
fn is_documenttype(&self) -> bool {
match self.type_id {
NodeTargetTypeId(DoctypeNodeTypeId) => true,
_ => false
}
}
}
impl DocumentType { impl DocumentType {
pub fn new_inherited(name: DOMString, pub fn new_inherited(name: DOMString,
public_id: Option<DOMString>, public_id: Option<DOMString>,
system_id: Option<DOMString>, system_id: Option<DOMString>,
document: AbstractDocument) document: JS<Document>)
-> DocumentType { -> DocumentType {
DocumentType { DocumentType {
node: Node::new_inherited(DoctypeNodeTypeId, document), node: Node::new_inherited(DoctypeNodeTypeId, document),
@ -32,13 +45,13 @@ impl DocumentType {
pub fn new(name: DOMString, pub fn new(name: DOMString,
public_id: Option<DOMString>, public_id: Option<DOMString>,
system_id: Option<DOMString>, system_id: Option<DOMString>,
document: AbstractDocument) document: &JS<Document>)
-> AbstractNode { -> JS<DocumentType> {
let documenttype = DocumentType::new_inherited(name, let documenttype = DocumentType::new_inherited(name,
public_id, public_id,
system_id, system_id,
document); document.clone());
Node::reflect_node(@mut documenttype, document, DocumentTypeBinding::Wrap) Node::reflect_node(~documenttype, document, DocumentTypeBinding::Wrap)
} }
} }

View file

@ -3,12 +3,13 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::DOMExceptionBinding; use dom::bindings::codegen::DOMExceptionBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::window::Window; use dom::window::Window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[repr(uint)] #[repr(uint)]
#[deriving(ToStr)] #[deriving(ToStr, Encodable)]
enum DOMErrorName { enum DOMErrorName {
IndexSizeError = 1, IndexSizeError = 1,
HierarchyRequestError = 3, HierarchyRequestError = 3,
@ -33,6 +34,7 @@ enum DOMErrorName {
EncodingError EncodingError
} }
#[deriving(Encodable)]
pub struct DOMException { pub struct DOMException {
code: DOMErrorName, code: DOMErrorName,
reflector_: Reflector reflector_: Reflector
@ -46,8 +48,8 @@ impl DOMException {
} }
} }
pub fn new(window: &Window, code: DOMErrorName) -> @mut DOMException { pub fn new(window: &Window, code: DOMErrorName) -> JS<DOMException> {
reflect_dom_object(@mut DOMException::new_inherited(code), window, DOMExceptionBinding::Wrap) reflect_dom_object(~DOMException::new_inherited(code), window, DOMExceptionBinding::Wrap)
} }
} }
@ -67,7 +69,7 @@ impl DOMException {
match self.code { match self.code {
// http://dom.spec.whatwg.org/#concept-throw // http://dom.spec.whatwg.org/#concept-throw
EncodingError => 0, EncodingError => 0,
_ => self.code as u16 code => code as u16
} }
} }

View file

@ -3,36 +3,38 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::DOMImplementationBinding; use dom::bindings::codegen::DOMImplementationBinding;
use dom::bindings::codegen::InheritTypes::NodeCast;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflector, Reflectable, reflect_dom_object}; use dom::bindings::utils::{Reflector, Reflectable, reflect_dom_object};
use dom::bindings::utils::{Fallible, InvalidCharacter, NamespaceError}; use dom::bindings::utils::{Fallible, InvalidCharacter, NamespaceError};
use dom::bindings::utils::{QName, Name, InvalidXMLName, xml_name_type}; use dom::bindings::utils::{QName, Name, InvalidXMLName, xml_name_type};
use dom::document::{AbstractDocument, HTML, HTMLDocumentTypeId}; use dom::document::{Document, HTMLDocument};
use dom::documenttype::DocumentType; use dom::documenttype::DocumentType;
use dom::htmldocument::HTMLDocument;
use dom::htmlbodyelement::HTMLBodyElement; use dom::htmlbodyelement::HTMLBodyElement;
use dom::htmlheadelement::HTMLHeadElement; use dom::htmlheadelement::HTMLHeadElement;
use dom::htmlhtmlelement::HTMLHtmlElement; use dom::htmlhtmlelement::HTMLHtmlElement;
use dom::htmltitleelement::HTMLTitleElement; use dom::htmltitleelement::HTMLTitleElement;
use dom::node::{AbstractNode, DocumentNodeTypeId}; use dom::node::{Node, INode};
use dom::text::Text; use dom::text::Text;
use dom::window::Window; use dom::window::Window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct DOMImplementation { pub struct DOMImplementation {
owner: @mut Window, owner: JS<Window>,
reflector_: Reflector reflector_: Reflector,
} }
impl DOMImplementation { impl DOMImplementation {
pub fn new_inherited(owner: @mut Window) -> DOMImplementation { pub fn new_inherited(owner: JS<Window>) -> DOMImplementation {
DOMImplementation { DOMImplementation {
owner: owner, owner: owner,
reflector_: Reflector::new() reflector_: Reflector::new(),
} }
} }
pub fn new(owner: @mut Window) -> @mut DOMImplementation { pub fn new(owner: &JS<Window>) -> JS<DOMImplementation> {
reflect_dom_object(@mut DOMImplementation::new_inherited(owner), owner, reflect_dom_object(~DOMImplementation::new_inherited(owner.clone()), owner.get(),
DOMImplementationBinding::Wrap) DOMImplementationBinding::Wrap)
} }
} }
@ -50,66 +52,63 @@ impl Reflectable for DOMImplementation {
// http://dom.spec.whatwg.org/#domimplementation // http://dom.spec.whatwg.org/#domimplementation
impl DOMImplementation { impl DOMImplementation {
// http://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype // 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) { match xml_name_type(qname) {
// Step 1. // Step 1.
InvalidXMLName => Err(InvalidCharacter), InvalidXMLName => Err(InvalidCharacter),
// Step 2. // Step 2.
Name => Err(NamespaceError), Name => Err(NamespaceError),
// Step 3. // 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 // 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. // Step 1-2.
let abstract_doc = HTMLDocument::new(self.owner, None); let doc = Document::new(&self.owner, None, HTMLDocument, None);
assert!(abstract_doc.document().doctype == HTML); let mut doc_node: JS<Node> = NodeCast::from(&doc);
let abstract_node = AbstractNode::from_document(abstract_doc);
assert!(abstract_node.type_id() == DocumentNodeTypeId(HTMLDocumentTypeId));
{ {
// Step 3. // Step 3.
let doc_type = DocumentType::new(~"html", None, None, abstract_doc); let doc_type = DocumentType::new(~"html", None, None, &doc);
abstract_node.AppendChild(doc_type); doc_node.AppendChild(&mut NodeCast::from(&doc_type));
} }
{ {
// Step 4. // Step 4.
let doc_html = HTMLHtmlElement::new(~"html", abstract_doc); let mut doc_html = NodeCast::from(&HTMLHtmlElement::new(~"html", &doc));
abstract_node.AppendChild(doc_html); doc_node.AppendChild(&mut doc_html);
{ {
// Step 5. // Step 5.
let doc_head = HTMLHeadElement::new(~"head", abstract_doc); let mut doc_head = NodeCast::from(&HTMLHeadElement::new(~"head", &doc));
doc_html.AppendChild(doc_head); doc_html.AppendChild(&mut doc_head);
// Step 6. // Step 6.
match title { match title {
None => (), None => (),
Some(title_str) => { Some(title_str) => {
// Step 6.1. // Step 6.1.
let doc_title = HTMLTitleElement::new(~"title", abstract_doc); let mut doc_title = NodeCast::from(&HTMLTitleElement::new(~"title", &doc));
doc_head.AppendChild(doc_title); doc_head.AppendChild(&mut doc_title);
// Step 6.2. // Step 6.2.
let title_text = Text::new(title_str, abstract_doc); let title_text = Text::new(title_str, &doc);
doc_title.AppendChild(title_text); doc_title.AppendChild(&mut NodeCast::from(&title_text));
} }
} }
} }
// Step 7. // Step 7.
let doc_body = HTMLBodyElement::new(~"body", abstract_doc); let doc_body = HTMLBodyElement::new(~"body", &doc);
doc_html.AppendChild(doc_body); doc_html.AppendChild(&mut NodeCast::from(&doc_body));
} }
// Step 8. // Step 8.
// FIXME: https://github.com/mozilla/servo/issues/1522 // FIXME: https://github.com/mozilla/servo/issues/1522
// Step 9. // Step 9.
abstract_doc doc
} }
} }

View file

@ -4,46 +4,47 @@
use dom::bindings::codegen::DOMParserBinding; use dom::bindings::codegen::DOMParserBinding;
use dom::bindings::codegen::DOMParserBinding::SupportedTypeValues::{Text_html, Text_xml}; use dom::bindings::codegen::DOMParserBinding::SupportedTypeValues::{Text_html, Text_xml};
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflector, Reflectable, reflect_dom_object}; use dom::bindings::utils::{Reflector, Reflectable, reflect_dom_object};
use dom::bindings::utils::Fallible; use dom::bindings::utils::Fallible;
use dom::bindings::utils::FailureUnknown; use dom::bindings::utils::FailureUnknown;
use dom::document::{AbstractDocument, Document}; use dom::document::{Document, HTMLDocument};
use dom::htmldocument::HTMLDocument;
use dom::window::Window; use dom::window::Window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct DOMParser { pub struct DOMParser {
owner: @mut Window, //XXXjdm Document instead? owner: JS<Window>, //XXXjdm Document instead?
reflector_: Reflector reflector_: Reflector
} }
impl DOMParser { impl DOMParser {
pub fn new_inherited(owner: @mut Window) -> DOMParser { pub fn new_inherited(owner: JS<Window>) -> DOMParser {
DOMParser { DOMParser {
owner: owner, owner: owner,
reflector_: Reflector::new() reflector_: Reflector::new()
} }
} }
pub fn new(owner: @mut Window) -> @mut DOMParser { pub fn new(owner: &JS<Window>) -> JS<DOMParser> {
reflect_dom_object(@mut DOMParser::new_inherited(owner), owner, reflect_dom_object(~DOMParser::new_inherited(owner.clone()), owner.get(),
DOMParserBinding::Wrap) DOMParserBinding::Wrap)
} }
pub fn Constructor(owner: @mut Window) -> Fallible<@mut DOMParser> { pub fn Constructor(owner: &JS<Window>) -> Fallible<JS<DOMParser>> {
Ok(DOMParser::new(owner)) Ok(DOMParser::new(owner))
} }
pub fn ParseFromString(&self, pub fn ParseFromString(&self,
_s: DOMString, _s: DOMString,
ty: DOMParserBinding::SupportedType) ty: DOMParserBinding::SupportedType)
-> Fallible<AbstractDocument> { -> Fallible<JS<Document>> {
match ty { match ty {
Text_html => { Text_html => {
Ok(HTMLDocument::new(self.owner, None)) Ok(Document::new(&self.owner, None, HTMLDocument, None))
} }
Text_xml => { Text_xml => {
Document::Constructor(self.owner) Document::Constructor(&self.owner)
} }
_ => { _ => {
Err(FailureUnknown) Err(FailureUnknown)

View file

@ -6,15 +6,22 @@
use dom::attr::Attr; use dom::attr::Attr;
use dom::attrlist::AttrList; 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::{Reflectable, Reflector};
use dom::bindings::utils::{ErrorResult, Fallible, NamespaceError, InvalidCharacter}; use dom::bindings::utils::{ErrorResult, Fallible, NamespaceError, InvalidCharacter};
use dom::bindings::utils::{QName, Name, InvalidXMLName, xml_name_type}; use dom::bindings::utils::{QName, Name, InvalidXMLName, xml_name_type};
use dom::htmlcollection::HTMLCollection; use dom::htmlcollection::HTMLCollection;
use dom::clientrect::ClientRect; use dom::clientrect::ClientRect;
use dom::clientrectlist::ClientRectList; use dom::clientrectlist::ClientRectList;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::node::{AbstractNode, ElementNodeTypeId, Node, NodeIterator}; use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::document; use dom::htmlimageelement::HTMLImageElement;
use dom::htmliframeelement::HTMLIFrameElement;
use dom::htmlobjectelement::HTMLObjectElement;
use dom::node::{ElementNodeTypeId, Node, NodeHelpers, NodeIterator};
use dom::htmlserializer::serialize; use dom::htmlserializer::serialize;
use layout_interface::{ContentBoxQuery, ContentBoxResponse, ContentBoxesQuery}; use layout_interface::{ContentBoxQuery, ContentBoxResponse, ContentBoxesQuery};
use layout_interface::{ContentBoxesResponse, ContentChangedDocumentDamage}; use layout_interface::{ContentBoxesResponse, ContentChangedDocumentDamage};
@ -26,15 +33,24 @@ use servo_util::str::{DOMString, null_str_as_empty_ref};
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use std::cast; use std::cast;
use std::unstable::raw::Box;
#[deriving(Encodable)]
pub struct Element { pub struct Element {
node: Node, node: Node,
tag_name: DOMString, // TODO: This should be an atom, not a DOMString. tag_name: DOMString, // TODO: This should be an atom, not a DOMString.
namespace: Namespace, namespace: Namespace,
attrs: ~[@mut Attr], attrs: ~[JS<Attr>],
style_attribute: Option<style::PropertyDeclarationBlock>, 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 { impl Reflectable for Element {
@ -47,7 +63,7 @@ impl Reflectable for Element {
} }
} }
#[deriving(Eq)] #[deriving(Eq,Encodable)]
pub enum ElementTypeId { pub enum ElementTypeId {
HTMLElementTypeId, HTMLElementTypeId,
HTMLAnchorElementTypeId, HTMLAnchorElementTypeId,
@ -104,7 +120,6 @@ pub enum ElementTypeId {
HTMLStyleElementTypeId, HTMLStyleElementTypeId,
HTMLTableElementTypeId, HTMLTableElementTypeId,
HTMLTableCaptionElementTypeId, HTMLTableCaptionElementTypeId,
HTMLTableCellElementTypeId,
HTMLTableDataCellElementTypeId, HTMLTableDataCellElementTypeId,
HTMLTableHeaderCellElementTypeId, HTMLTableHeaderCellElementTypeId,
HTMLTableColElementTypeId, HTMLTableColElementTypeId,
@ -124,9 +139,8 @@ pub enum ElementTypeId {
// Element methods // Element methods
// //
impl Element { 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 { Element {
node: Node::new_inherited(ElementNodeTypeId(type_id), document), node: Node::new_inherited(ElementNodeTypeId(type_id), document),
tag_name: tag_name, tag_name: tag_name,
@ -138,41 +152,40 @@ impl Element {
} }
pub fn html_element_in_html_document(&self) -> bool { pub fn html_element_in_html_document(&self) -> bool {
let owner = self.node.owner_doc();
self.namespace == namespace::HTML && self.namespace == namespace::HTML &&
// FIXME: check that this matches what the spec calls "is in an HTML document" self.node.owner_doc().get().is_html_document
owner.document().doctype == document::HTML
} }
pub fn get_attribute(&self, pub fn get_attribute(&self,
namespace: Namespace, namespace: Namespace,
name: &str) -> Option<@mut Attr> { name: &str) -> Option<JS<Attr>> {
self.attrs.iter().find(|attr| { self.attrs.iter().find(|attr| {
let attr = attr.get();
name == attr.local_name && attr.namespace == namespace name == attr.local_name && attr.namespace == namespace
}).map(|&x| x) }).map(|x| x.clone())
} }
#[inline] #[inline]
pub unsafe fn get_attr_val_for_layout(&self, namespace: &Namespace, name: &str) pub unsafe fn get_attr_val_for_layout(&self, namespace: &Namespace, name: &str)
-> Option<&'static 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 // unsafely avoid a borrow because this is accessed by many tasks
// during parallel layout // during parallel layout
let attr: ***Box<Attr> = cast::transmute(attr); let attr: ***Attr = cast::transmute(attr);
name == (***attr).data.local_name && (***attr).data.namespace == *namespace name == (***attr).local_name && (***attr).namespace == *namespace
}).map(|attr| { }).map(|attr| {
let attr: **Box<Attr> = cast::transmute(attr); let attr: **Attr = cast::transmute(attr);
cast::transmute((**attr).data.value.as_slice()) 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 { -> ErrorResult {
self.set_attribute(abstract_self, namespace::Null, name, value) self.set_attribute(abstract_self, namespace::Null, name, value)
} }
pub fn set_attribute(&mut self, pub fn set_attribute(&mut self,
abstract_self: AbstractNode, abstract_self: &JS<Element>,
namespace: Namespace, namespace: Namespace,
name: DOMString, name: DOMString,
value: DOMString) -> ErrorResult { value: DOMString) -> ErrorResult {
@ -192,7 +205,8 @@ impl Element {
// FIXME: reduce the time of `value.clone()`. // FIXME: reduce the time of `value.clone()`.
let mut old_raw_value: Option<DOMString> = None; 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 { if attr.local_name == local_name {
old_raw_value = Some(attr.set_value(value.clone())); old_raw_value = Some(attr.set_value(value.clone()));
break; break;
@ -200,8 +214,9 @@ impl Element {
} }
if old_raw_value.is_none() { if old_raw_value.is_none() {
let win = self.node.owner_doc().document().window; let doc = self.node.owner_doc();
let new_attr = Attr::new_ns(win, local_name.clone(), value.clone(), let doc = doc.get();
let new_attr = Attr::new_ns(doc.window.get(), local_name.clone(), value.clone(),
name.clone(), namespace.clone(), name.clone(), namespace.clone(),
prefix); prefix);
self.attrs.push(new_attr); self.attrs.push(new_attr);
@ -214,7 +229,7 @@ impl Element {
} }
fn after_set_attr(&mut self, fn after_set_attr(&mut self,
abstract_self: AbstractNode, abstract_self: &JS<Element>,
local_name: DOMString, local_name: DOMString,
value: DOMString, value: DOMString,
old_value: Option<DOMString>) { old_value: Option<DOMString>) {
@ -222,36 +237,36 @@ impl Element {
match local_name.as_slice() { match local_name.as_slice() {
"style" => { "style" => {
let doc = self.node.owner_doc(); 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)) self.style_attribute = Some(style::parse_style_attribute(value, &base_url))
} }
"id" if abstract_self.is_in_doc() => { "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: // XXX: this dual declaration are workaround to avoid the compile error:
// "borrowed value does not live long enough" // "borrowed value does not live long enough"
let doc = self.node.owner_doc(); let mut doc = self.node.owner_doc();
let doc = doc.mut_document(); let doc = doc.get_mut();
doc.update_idmap(abstract_self, Some(value.clone()), old_value); doc.update_idmap(abstract_self, Some(value.clone()), old_value);
} }
}
_ => () _ => ()
} }
//XXXjdm We really need something like a vtable so we can call AfterSetAttr. //XXXjdm We really need something like a vtable so we can call AfterSetAttr.
// This hardcoding is awful. // This hardcoding is awful.
match abstract_self.type_id() { match abstract_self.get().node.type_id {
ElementNodeTypeId(HTMLImageElementTypeId) => { ElementNodeTypeId(HTMLImageElementTypeId) => {
abstract_self.with_mut_image_element(|image| { let mut elem: JS<HTMLImageElement> = HTMLImageElementCast::to(abstract_self);
image.AfterSetAttr(local_name.clone(), value.clone()); elem.get_mut().AfterSetAttr(local_name.clone(), value.clone());
});
} }
ElementNodeTypeId(HTMLIframeElementTypeId) => { ElementNodeTypeId(HTMLIframeElementTypeId) => {
abstract_self.with_mut_iframe_element(|iframe| { let mut elem: JS<HTMLIFrameElement> = HTMLIFrameElementCast::to(abstract_self);
iframe.AfterSetAttr(local_name.clone(), value.clone()); elem.get_mut().AfterSetAttr(local_name.clone(), value.clone());
});
} }
ElementNodeTypeId(HTMLObjectElementTypeId) => { ElementNodeTypeId(HTMLObjectElementTypeId) => {
abstract_self.with_mut_object_element(|object| { let mut elem: JS<HTMLObjectElement> = HTMLObjectElementCast::to(abstract_self);
object.AfterSetAttr(local_name.clone(), value.clone()); elem.get_mut().AfterSetAttr(local_name.clone(), value.clone());
});
} }
_ => () _ => ()
} }
@ -260,22 +275,22 @@ impl Element {
} }
pub fn remove_attribute(&mut self, pub fn remove_attribute(&mut self,
abstract_self: AbstractNode, abstract_self: &JS<Element>,
namespace: Namespace, namespace: Namespace,
name: DOMString) -> ErrorResult { name: DOMString) -> ErrorResult {
let (_, local_name) = get_attribute_parts(name.clone()); let (_, local_name) = get_attribute_parts(name.clone());
self.node.wait_until_safe_to_modify_dom(); self.node.wait_until_safe_to_modify_dom();
let idx = self.attrs.iter().position(|attr: &@mut Attr| -> bool { let idx = self.attrs.iter().position(|attr: &JS<Attr>| -> bool {
attr.local_name == local_name attr.get().local_name == local_name
}); });
match idx { match idx {
None => (), None => (),
Some(idx) => { Some(idx) => {
let removed = self.attrs.remove(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 { if namespace == namespace::Null {
self.after_remove_attr(abstract_self, local_name, removed_raw_value); self.after_remove_attr(abstract_self, local_name, removed_raw_value);
@ -287,35 +302,36 @@ impl Element {
} }
fn after_remove_attr(&mut self, fn after_remove_attr(&mut self,
abstract_self: AbstractNode, abstract_self: &JS<Element>,
local_name: DOMString, local_name: DOMString,
old_value: Option<DOMString>) { old_value: Option<DOMString>) {
match local_name.as_slice() { match local_name.as_slice() {
"style" => { "style" => {
self.style_attribute = None self.style_attribute = None
} }
"id" if abstract_self.is_in_doc() => { "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: // XXX: this dual declaration are workaround to avoid the compile error:
// "borrowed value does not live long enough" // "borrowed value does not live long enough"
let doc = self.node.owner_doc(); let mut doc = self.node.owner_doc();
let doc = doc.mut_document(); let doc = doc.get_mut();
doc.update_idmap(abstract_self, None, old_value); doc.update_idmap(abstract_self, None, old_value);
} }
}
_ => () _ => ()
} }
//XXXjdm We really need something like a vtable so we can call AfterSetAttr. //XXXjdm We really need something like a vtable so we can call AfterSetAttr.
// This hardcoding is awful. // This hardcoding is awful.
match abstract_self.type_id() { match abstract_self.get().node.type_id {
ElementNodeTypeId(HTMLImageElementTypeId) => { ElementNodeTypeId(HTMLImageElementTypeId) => {
abstract_self.with_mut_image_element(|image| { let mut elem: JS<HTMLImageElement> = HTMLImageElementCast::to(abstract_self);
image.AfterRemoveAttr(local_name.clone()); elem.get_mut().AfterRemoveAttr(local_name.clone());
});
} }
ElementNodeTypeId(HTMLIframeElementTypeId) => { ElementNodeTypeId(HTMLIframeElementTypeId) => {
abstract_self.with_mut_iframe_element(|iframe| { let mut elem: JS<HTMLIFrameElement> = HTMLIFrameElementCast::to(abstract_self);
iframe.AfterRemoveAttr(local_name.clone()); elem.get_mut().AfterRemoveAttr(local_name.clone());
});
} }
_ => () _ => ()
} }
@ -324,15 +340,16 @@ impl Element {
} }
fn notify_attribute_changed(&self, fn notify_attribute_changed(&self,
abstract_self: AbstractNode, abstract_self: &JS<Element>,
local_name: DOMString) { 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() { let damage = match local_name.as_slice() {
"style" | "id" | "class" => MatchSelectorsDocumentDamage, "style" | "id" | "class" => MatchSelectorsDocumentDamage,
_ => ContentChangedDocumentDamage _ => ContentChangedDocumentDamage
}; };
let document = self.node.owner_doc(); let document = self.node.owner_doc();
document.document().damage_and_reflow(damage); document.get().damage_and_reflow(damage);
} }
} }
@ -357,18 +374,18 @@ impl Element {
// XXX Resolve URL. // XXX Resolve URL.
self.get_string_attribute(name) 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) { name: &str, value: DOMString) {
self.set_string_attribute(abstract_self, name, value); self.set_string_attribute(abstract_self, name, value);
} }
pub fn get_string_attribute(&self, name: &str) -> DOMString { pub fn get_string_attribute(&self, name: &str) -> DOMString {
match self.get_attribute(Null, name) { match self.get_attribute(Null, name) {
Some(x) => x.Value(), Some(x) => x.get().Value(),
None => ~"" 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) { name: &str, value: DOMString) {
assert!(name == name.to_ascii_lower()); assert!(name == name.to_ascii_lower());
self.set_attribute(abstract_self, Null, name.to_owned(), value); self.set_attribute(abstract_self, Null, name.to_owned(), value);
@ -382,25 +399,26 @@ impl Element {
} }
// http://dom.spec.whatwg.org/#dom-element-id // 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") self.get_string_attribute("id")
} }
// http://dom.spec.whatwg.org/#dom-element-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); self.set_string_attribute(abstract_self, "id", id);
} }
// http://dom.spec.whatwg.org/#dom-element-attributes // 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 { match self.attr_list {
None => { None => {
let window = self.node.owner_doc().document().window; let doc = self.node.owner_doc();
let list = AttrList::new(window, abstract_self); let doc = doc.get();
self.attr_list = Some(list); let list = AttrList::new(&doc.window, abstract_self);
self.attr_list = Some(list.clone());
list list
} }
Some(list) => list Some(ref list) => list.clone()
} }
} }
@ -411,18 +429,18 @@ impl Element {
} else { } else {
name 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 // http://dom.spec.whatwg.org/#dom-element-getattributens
pub fn GetAttributeNS(&self, namespace: Option<DOMString>, local_name: DOMString) -> Option<DOMString> { pub fn GetAttributeNS(&self, namespace: Option<DOMString>, local_name: DOMString) -> Option<DOMString> {
let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace)); let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace));
self.get_attribute(namespace, local_name) 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 // 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 { -> ErrorResult {
// FIXME: If name does not match the Name production in XML, throw an "InvalidCharacterError" exception. // FIXME: If name does not match the Name production in XML, throw an "InvalidCharacterError" exception.
let name = if self.html_element_in_html_document() { let name = if self.html_element_in_html_document() {
@ -435,7 +453,7 @@ impl Element {
// http://dom.spec.whatwg.org/#dom-element-setattributens // http://dom.spec.whatwg.org/#dom-element-setattributens
pub fn SetAttributeNS(&mut self, pub fn SetAttributeNS(&mut self,
abstract_self: AbstractNode, abstract_self: &JS<Element>,
namespace_url: Option<DOMString>, namespace_url: Option<DOMString>,
name: DOMString, name: DOMString,
value: DOMString) -> ErrorResult { value: DOMString) -> ErrorResult {
@ -452,7 +470,7 @@ impl Element {
// http://dom.spec.whatwg.org/#dom-element-removeattribute // http://dom.spec.whatwg.org/#dom-element-removeattribute
pub fn RemoveAttribute(&mut self, pub fn RemoveAttribute(&mut self,
abstract_self: AbstractNode, abstract_self: &JS<Element>,
name: DOMString) -> ErrorResult { name: DOMString) -> ErrorResult {
let name = if self.html_element_in_html_document() { let name = if self.html_element_in_html_document() {
name.to_ascii_lower() name.to_ascii_lower()
@ -464,7 +482,7 @@ impl Element {
// http://dom.spec.whatwg.org/#dom-element-removeattributens // http://dom.spec.whatwg.org/#dom-element-removeattributens
pub fn RemoveAttributeNS(&mut self, pub fn RemoveAttributeNS(&mut self,
abstract_self: AbstractNode, abstract_self: &JS<Element>,
namespace: Option<DOMString>, namespace: Option<DOMString>,
localname: DOMString) -> ErrorResult { localname: DOMString) -> ErrorResult {
let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace)); let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace));
@ -482,21 +500,24 @@ impl Element {
} }
// http://dom.spec.whatwg.org/#dom-element-getelementsbytagname // 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 // 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 // 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 // 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 // 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 // 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 // http://dom.spec.whatwg.org/#dom-element-matches
@ -517,13 +538,14 @@ impl Element {
pub fn MozRequestPointerLock(&self) { pub fn MozRequestPointerLock(&self) {
} }
pub fn GetClientRects(&self, abstract_self: AbstractNode) -> @mut ClientRectList { pub fn GetClientRects(&self, abstract_self: &JS<Element>) -> JS<ClientRectList> {
let win = self.node.owner_doc().document().window; let doc = self.node.owner_doc();
let node = abstract_self; let win = &doc.get().window;
assert!(node.is_element()); let node: JS<Node> = NodeCast::from(abstract_self);
let (port, chan) = Chan::new(); let (port, chan) = Chan::new();
let addr = node.to_trusted_node_address();
let rects = let rects =
match win.page.query_layout(ContentBoxesQuery(node, chan), port) { match win.get().page.query_layout(ContentBoxesQuery(addr, chan), port) {
ContentBoxesResponse(rects) => { ContentBoxesResponse(rects) => {
rects.map(|r| { rects.map(|r| {
ClientRect::new( ClientRect::new(
@ -539,12 +561,13 @@ impl Element {
ClientRectList::new(win, rects) ClientRectList::new(win, rects)
} }
pub fn GetBoundingClientRect(&self, abstract_self: AbstractNode) -> @mut ClientRect { pub fn GetBoundingClientRect(&self, abstract_self: &JS<Element>) -> JS<ClientRect> {
let win = self.node.owner_doc().document().window; let doc = self.node.owner_doc();
let node = abstract_self; let win = &doc.get().window;
assert!(node.is_element()); let node: JS<Node> = NodeCast::from(abstract_self);
let (port, chan) = Chan::new(); 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) => { ContentBoxResponse(rect) => {
ClientRect::new( ClientRect::new(
win, win,
@ -597,20 +620,20 @@ impl Element {
0 0
} }
pub fn GetInnerHTML(&self, abstract_self: AbstractNode) -> Fallible<DOMString> { pub fn GetInnerHTML(&self, abstract_self: &JS<Element>) -> Fallible<DOMString> {
//XXX TODO: XML case //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(()) Ok(())
} }
pub fn GetOuterHTML(&self, abstract_self:AbstractNode) -> Fallible<DOMString> { pub fn GetOuterHTML(&self, abstract_self: &JS<Element>) -> Fallible<DOMString> {
Ok(serialize(&mut NodeIterator::new(abstract_self, true, false))) 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(()) Ok(())
} }
@ -618,7 +641,7 @@ impl Element {
Ok(()) Ok(())
} }
pub fn QuerySelector(&self, _selectors: DOMString) -> Fallible<Option<AbstractNode>> { pub fn QuerySelector(&self, _selectors: DOMString) -> Fallible<Option<JS<Element>>> {
Ok(None) Ok(None)
} }
} }

View file

@ -2,20 +2,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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::codegen::EventBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::utils::{Fallible, ErrorResult}; use dom::bindings::utils::{Fallible, ErrorResult};
use dom::mouseevent::MouseEvent; use dom::eventtarget::EventTarget;
use dom::uievent::UIEvent; use dom::window::Window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use geom::point::Point2D; use geom::point::Point2D;
use std::cast;
use std::unstable::raw::Box;
pub enum Event_ { pub enum Event_ {
ResizeEvent(uint, uint), ResizeEvent(uint, uint),
ReflowEvent, ReflowEvent,
@ -25,10 +21,7 @@ pub enum Event_ {
MouseMoveEvent(Point2D<f32>) MouseMoveEvent(Point2D<f32>)
} }
pub struct AbstractEvent { #[deriving(Encodable)]
event: *mut Box<Event>
}
pub enum EventPhase { pub enum EventPhase {
Phase_None = 0, Phase_None = 0,
Phase_Capturing, Phase_Capturing,
@ -36,91 +29,7 @@ pub enum EventPhase {
Phase_Bubbling Phase_Bubbling
} }
impl AbstractEvent { #[deriving(Eq, Encodable)]
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)]
pub enum EventTypeId { pub enum EventTypeId {
HTMLEventTypeId, HTMLEventTypeId,
UIEventTypeId, UIEventTypeId,
@ -128,11 +37,12 @@ pub enum EventTypeId {
KeyEventTypeId KeyEventTypeId
} }
#[deriving(Encodable)]
pub struct Event { pub struct Event {
type_id: EventTypeId, type_id: EventTypeId,
reflector_: Reflector, reflector_: Reflector,
current_target: Option<AbstractEventTarget>, current_target: Option<JS<EventTarget>>,
target: Option<AbstractEventTarget>, target: Option<JS<EventTarget>>,
type_: DOMString, type_: DOMString,
phase: EventPhase, phase: EventPhase,
default_prevented: bool, default_prevented: bool,
@ -142,7 +52,7 @@ pub struct Event {
bubbles: bool, bubbles: bool,
trusted: bool, trusted: bool,
dispatching: bool, dispatching: bool,
initialized: bool initialized: bool,
} }
impl Event { 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 new(window: &JS<Window>) -> JS<Event> {
pub fn as_abstract<E>(event: @mut E) -> AbstractEvent { reflect_dom_object(~Event::new_inherited(HTMLEventTypeId),
// This surrenders memory management of the event! window.get(),
AbstractEvent { EventBinding::Wrap)
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 EventPhase(&self) -> u16 { pub fn EventPhase(&self) -> u16 {
@ -187,12 +89,12 @@ impl Event {
self.type_.clone() self.type_.clone()
} }
pub fn GetTarget(&self) -> Option<AbstractEventTarget> { pub fn GetTarget(&self) -> Option<JS<EventTarget>> {
self.target self.target.clone()
} }
pub fn GetCurrentTarget(&self) -> Option<AbstractEventTarget> { pub fn GetCurrentTarget(&self) -> Option<JS<EventTarget>> {
self.current_target self.current_target.clone()
} }
pub fn DefaultPrevented(&self) -> bool { pub fn DefaultPrevented(&self) -> bool {
@ -241,11 +143,11 @@ impl Event {
self.trusted self.trusted
} }
pub fn Constructor(global: @mut Window, pub fn Constructor(global: &JS<Window>,
type_: DOMString, type_: DOMString,
init: &EventBinding::EventInit) -> Fallible<AbstractEvent> { init: &EventBinding::EventInit) -> Fallible<JS<Event>> {
let ev = Event::new(global); let mut ev = Event::new(global);
ev.mut_event().InitEvent(type_, init.bubbles, init.cancelable); ev.get_mut().InitEvent(type_, init.bubbles, init.cancelable);
Ok(ev) Ok(ev)
} }
} }

View file

@ -3,50 +3,57 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::callback::eReportExceptions; use dom::bindings::callback::eReportExceptions;
use dom::eventtarget::{AbstractEventTarget, Capturing, Bubbling}; use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, NodeDerived};
use dom::event::{AbstractEvent, Phase_At_Target, Phase_None, Phase_Bubbling, Phase_Capturing}; use dom::bindings::js::JS;
use dom::node::AbstractNode; 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 // See http://dom.spec.whatwg.org/#concept-event-dispatch for the full dispatch algorithm
pub fn dispatch_event(target: AbstractEventTarget, pub fn dispatch_event(target: &JS<EventTarget>,
pseudo_target: Option<AbstractEventTarget>, pseudo_target: Option<JS<EventTarget>>,
event: AbstractEvent) -> bool { event: &mut JS<Event>) -> bool {
assert!(!event.event().dispatching); assert!(!event.get().dispatching);
{ {
let event = event.mut_event(); let event = event.get_mut();
event.target = Some(pseudo_target.unwrap_or(target)); event.target = match pseudo_target {
Some(pseudo_target) => Some(pseudo_target),
None => Some(target.clone())
};
event.dispatching = true; event.dispatching = true;
} }
let type_ = event.event().type_.clone(); let type_ = event.get().type_.clone();
let mut chain = ~[]; let mut chain = ~[];
//TODO: no chain if not participating in a tree //TODO: no chain if not participating in a tree
if target.is_node() { if target.get().is_node() {
for ancestor in AbstractNode::from_eventtarget(target).ancestors() { let target_node: JS<Node> = NodeCast::to(target);
chain.push(AbstractEventTarget::from_node(ancestor)); 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 //FIXME: The "callback this value" should be currentTarget
/* capturing */ /* capturing */
for &cur_target in chain.rev_iter() { for cur_target in chain.rev_iter() {
let stopped = match cur_target.eventtarget().get_listeners_for(type_, Capturing) { let stopped = match cur_target.get().get_listeners_for(type_, Capturing) {
Some(listeners) => { Some(listeners) => {
event.mut_event().current_target = Some(cur_target); event.get_mut().current_target = Some(cur_target.clone());
for listener in listeners.iter() { for listener in listeners.iter() {
listener.HandleEvent__(event, eReportExceptions); listener.HandleEvent__(event, eReportExceptions);
if event.event().stop_immediate { if event.get().stop_immediate {
break; break;
} }
} }
event.propagation_stopped() event.get().stop_propagation
} }
None => false None => false
}; };
@ -57,18 +64,18 @@ pub fn dispatch_event(target: AbstractEventTarget,
} }
/* at target */ /* 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.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 listeners in opt_listeners.iter() {
for listener in listeners.iter() { for listener in listeners.iter() {
listener.HandleEvent__(event, eReportExceptions); listener.HandleEvent__(event, eReportExceptions);
if event.event().stop_immediate { if event.get().stop_immediate {
break; break;
} }
} }
@ -76,22 +83,22 @@ pub fn dispatch_event(target: AbstractEventTarget,
} }
/* bubbling */ /* bubbling */
if event.bubbles() && !event.propagation_stopped() { if event.get().bubbles && !event.get().stop_propagation {
event.mut_event().phase = Phase_Bubbling; event.get_mut().phase = Phase_Bubbling;
for &cur_target in chain.iter() { for cur_target in chain.iter() {
let stopped = match cur_target.eventtarget().get_listeners_for(type_, Bubbling) { let stopped = match cur_target.get().get_listeners_for(type_, Bubbling) {
Some(listeners) => { Some(listeners) => {
event.mut_event().current_target = Some(cur_target); event.get_mut().current_target = Some(cur_target.clone());
for listener in listeners.iter() { for listener in listeners.iter() {
listener.HandleEvent__(event, eReportExceptions); listener.HandleEvent__(event, eReportExceptions);
if event.event().stop_immediate { if event.get().stop_immediate {
break; break;
} }
} }
event.propagation_stopped() event.get().stop_propagation
} }
None => false 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.dispatching = false;
event.phase = Phase_None; event.phase = Phase_None;
event.current_target = None; event.current_target = None;

View file

@ -2,122 +2,42 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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::{Reflectable, Reflector};
use dom::bindings::utils::{Fallible, InvalidState}; use dom::bindings::utils::{Fallible, InvalidState};
use dom::bindings::codegen::EventListenerBinding::EventListener; use dom::bindings::codegen::EventListenerBinding::EventListener;
use dom::document::AbstractDocument; use dom::event::Event;
use dom::event::AbstractEvent;
use dom::eventdispatcher::dispatch_event; use dom::eventdispatcher::dispatch_event;
use dom::node::AbstractNode; use dom::node::NodeTypeId;
use dom::window::Window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use std::cast;
use std::hashmap::HashMap; use std::hashmap::HashMap;
use std::unstable::raw::Box;
#[deriving(Eq)] #[deriving(Eq,Encodable)]
pub enum ListenerPhase { pub enum ListenerPhase {
Capturing, Capturing,
Bubbling, Bubbling,
} }
#[deriving(Eq)] #[deriving(Eq,Encodable)]
pub enum EventTargetTypeId { pub enum EventTargetTypeId {
WindowTypeId, WindowTypeId,
NodeTypeId NodeTargetTypeId(NodeTypeId)
} }
#[deriving(Eq)] #[deriving(Eq,Encodable)]
struct EventListenerEntry { struct EventListenerEntry {
phase: ListenerPhase, phase: ListenerPhase,
listener: EventListener listener: EventListener
} }
#[deriving(Encodable)]
pub struct EventTarget { pub struct EventTarget {
type_id: EventTargetTypeId, type_id: EventTargetTypeId,
reflector_: Reflector, reflector_: Reflector,
handlers: HashMap<DOMString, ~[EventListenerEntry]>, 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 { impl EventTarget {
pub fn new_inherited(type_id: EventTargetTypeId) -> EventTarget { pub fn new_inherited(type_id: EventTargetTypeId) -> EventTarget {
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) self.dispatch_event_with_target(abstract_self, None, event)
} }
pub fn dispatch_event_with_target(&self, pub fn dispatch_event_with_target(&self,
abstract_self: AbstractEventTarget, abstract_self: &JS<EventTarget>,
abstract_target: Option<AbstractEventTarget>, abstract_target: Option<JS<EventTarget>>,
event: AbstractEvent) -> Fallible<bool> { event: &mut JS<Event>) -> Fallible<bool> {
if event.event().dispatching || !event.event().initialized { if event.get().dispatching || !event.get().initialized {
return Err(InvalidState); return Err(InvalidState);
} }
Ok(dispatch_event(abstract_self, abstract_target, event)) Ok(dispatch_event(abstract_self, abstract_target, event))

View file

@ -4,27 +4,30 @@
use dom::bindings::utils::{Fallible, Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::{Fallible, Reflectable, Reflector, reflect_dom_object};
use dom::bindings::codegen::FormDataBinding; use dom::bindings::codegen::FormDataBinding;
use dom::bindings::js::JS;
use dom::blob::Blob; use dom::blob::Blob;
use dom::node::AbstractNode; use dom::htmlformelement::HTMLFormElement;
use dom::window::Window; use dom::window::Window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use std::hashmap::HashMap; use std::hashmap::HashMap;
#[deriving(Encodable)]
enum FormDatum { enum FormDatum {
StringData(DOMString), StringData(DOMString),
BlobData { blob: @mut Blob, name: DOMString } BlobData { blob: JS<Blob>, name: DOMString }
} }
#[deriving(Encodable)]
pub struct FormData { pub struct FormData {
data: HashMap<DOMString, FormDatum>, data: HashMap<DOMString, FormDatum>,
reflector_: Reflector, reflector_: Reflector,
window: @mut Window, window: JS<Window>,
form: Option<AbstractNode> form: Option<JS<HTMLFormElement>>
} }
impl FormData { 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 { FormData {
data: HashMap::new(), data: HashMap::new(),
reflector_: Reflector::new(), reflector_: Reflector::new(),
@ -33,18 +36,18 @@ impl FormData {
} }
} }
pub fn new(form: Option<AbstractNode>, window: @mut Window) -> @mut FormData { pub fn new(form: Option<JS<HTMLFormElement>>, window: &JS<Window>) -> JS<FormData> {
reflect_dom_object(@mut FormData::new_inherited(form, window), window, FormDataBinding::Wrap) reflect_dom_object(~FormData::new_inherited(form, window.clone()), window.get(), FormDataBinding::Wrap)
} }
pub fn Constructor(window: @mut Window, form: Option<AbstractNode>) pub fn Constructor(window: &JS<Window>, form: Option<JS<HTMLFormElement>>)
-> Fallible<@mut FormData> { -> Fallible<JS<FormData>> {
Ok(FormData::new(form, window)) 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 { let blob = BlobData {
blob: value, blob: value.clone(),
name: filename.unwrap_or(~"default") name: filename.unwrap_or(~"default")
}; };
self.data.insert(name.clone(), blob); self.data.insert(name.clone(), blob);

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLAnchorElementBinding; use dom::bindings::codegen::HTMLAnchorElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLAnchorElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLAnchorElementTypeId; use dom::element::HTMLAnchorElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLAnchorElement { pub struct HTMLAnchorElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLAnchorElementDerived for EventTarget {
fn is_htmlanchorelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLAnchorElementTypeId)) => true,
_ => false
}
}
}
impl HTMLAnchorElement { impl HTMLAnchorElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLAnchorElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLAnchorElement {
HTMLAnchorElement { HTMLAnchorElement {
htmlelement: HTMLElement::new_inherited(HTMLAnchorElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLAnchorElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAnchorElement> {
let element = HTMLAnchorElement::new_inherited(localName, document); let element = HTMLAnchorElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLAnchorElementBinding::Wrap) Node::reflect_node(~element, document, HTMLAnchorElementBinding::Wrap)
} }
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLAppletElementBinding; use dom::bindings::codegen::HTMLAppletElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLAppletElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLAppletElementTypeId; use dom::element::HTMLAppletElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLAppletElement { pub struct HTMLAppletElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLAppletElementDerived for EventTarget {
fn is_htmlappletelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLAppletElementTypeId)) => true,
_ => false
}
}
}
impl HTMLAppletElement { impl HTMLAppletElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLAppletElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLAppletElement {
HTMLAppletElement { HTMLAppletElement {
htmlelement: HTMLElement::new_inherited(HTMLAppletElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLAppletElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAppletElement> {
let element = HTMLAppletElement::new_inherited(localName, document); let element = HTMLAppletElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLAppletElementBinding::Wrap) Node::reflect_node(~element, document, HTMLAppletElementBinding::Wrap)
} }
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLAreaElementBinding; use dom::bindings::codegen::HTMLAreaElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLAreaElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLAreaElementTypeId; use dom::element::HTMLAreaElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLAreaElement { pub struct HTMLAreaElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLAreaElementDerived for EventTarget {
fn is_htmlareaelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLAreaElementTypeId)) => true,
_ => false
}
}
}
impl HTMLAreaElement { impl HTMLAreaElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLAreaElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLAreaElement {
HTMLAreaElement { HTMLAreaElement {
htmlelement: HTMLElement::new_inherited(HTMLAreaElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLAreaElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAreaElement> {
let element = HTMLAreaElement::new_inherited(localName, document); let element = HTMLAreaElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLAreaElementBinding::Wrap) Node::reflect_node(~element, document, HTMLAreaElementBinding::Wrap)
} }
} }

View file

@ -3,25 +3,38 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLAudioElementBinding; 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::element::HTMLAudioElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlmediaelement::HTMLMediaElement; use dom::htmlmediaelement::HTMLMediaElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLAudioElement { pub struct HTMLAudioElement {
htmlmediaelement: HTMLMediaElement htmlmediaelement: HTMLMediaElement
} }
impl HTMLAudioElementDerived for EventTarget {
fn is_htmlaudioelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLAudioElementTypeId)) => true,
_ => false
}
}
}
impl HTMLAudioElement { impl HTMLAudioElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLAudioElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLAudioElement {
HTMLAudioElement { HTMLAudioElement {
htmlmediaelement: HTMLMediaElement::new_inherited(HTMLAudioElementTypeId, localName, document) htmlmediaelement: HTMLMediaElement::new_inherited(HTMLAudioElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAudioElement> {
let element = HTMLAudioElement::new_inherited(localName, document); let element = HTMLAudioElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLAudioElementBinding::Wrap) Node::reflect_node(~element, document, HTMLAudioElementBinding::Wrap)
} }
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLBaseElementBinding; use dom::bindings::codegen::HTMLBaseElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLBaseElementDerived;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::bindings::js::JS;
use dom::document::Document;
use dom::element::HTMLBaseElementTypeId; use dom::element::HTMLBaseElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLBaseElement { pub struct HTMLBaseElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLBaseElementDerived for EventTarget {
fn is_htmlbaseelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLBaseElementTypeId)) => true,
_ => false
}
}
}
impl HTMLBaseElement { impl HTMLBaseElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLBaseElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLBaseElement {
HTMLBaseElement { HTMLBaseElement {
htmlelement: HTMLElement::new_inherited(HTMLBaseElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLBaseElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLBaseElement> {
let element = HTMLBaseElement::new_inherited(localName, document); let element = HTMLBaseElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLBaseElementBinding::Wrap) Node::reflect_node(~element, document, HTMLBaseElementBinding::Wrap)
} }
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLBodyElementBinding; use dom::bindings::codegen::HTMLBodyElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLBodyElementDerived;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::bindings::js::JS;
use dom::document::Document;
use dom::element::HTMLBodyElementTypeId; use dom::element::HTMLBodyElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLBodyElement { pub struct HTMLBodyElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLBodyElementDerived for EventTarget {
fn is_htmlbodyelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLBodyElementTypeId)) => true,
_ => false
}
}
}
impl HTMLBodyElement { impl HTMLBodyElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLBodyElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLBodyElement {
HTMLBodyElement { HTMLBodyElement {
htmlelement: HTMLElement::new_inherited(HTMLBodyElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLBodyElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLBodyElement> {
let element = HTMLBodyElement::new_inherited(localName, document); let element = HTMLBodyElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLBodyElementBinding::Wrap) Node::reflect_node(~element, document, HTMLBodyElementBinding::Wrap)
} }
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLBRElementBinding; use dom::bindings::codegen::HTMLBRElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLBRElementDerived;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::bindings::js::JS;
use dom::document::Document;
use dom::element::HTMLBRElementTypeId; use dom::element::HTMLBRElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLBRElement { pub struct HTMLBRElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
} }
impl HTMLBRElementDerived for EventTarget {
fn is_htmlbrelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLBRElementTypeId)) => true,
_ => false
}
}
}
impl HTMLBRElement { impl HTMLBRElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLBRElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLBRElement {
HTMLBRElement { HTMLBRElement {
htmlelement: HTMLElement::new_inherited(HTMLBRElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLBRElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLBRElement> {
let element = HTMLBRElement::new_inherited(localName, document); let element = HTMLBRElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLBRElementBinding::Wrap) Node::reflect_node(~element, document, HTMLBRElementBinding::Wrap)
} }
} }

View file

@ -3,28 +3,42 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLButtonElementBinding; use dom::bindings::codegen::HTMLButtonElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLButtonElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLButtonElementTypeId; use dom::element::HTMLButtonElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::htmlformelement::HTMLFormElement;
use dom::node::{Node, ElementNodeTypeId};
use dom::validitystate::ValidityState; use dom::validitystate::ValidityState;
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLButtonElement { pub struct HTMLButtonElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLButtonElementDerived for EventTarget {
fn is_htmlbuttonelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLButtonElementTypeId)) => true,
_ => false
}
}
}
impl HTMLButtonElement { impl HTMLButtonElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLButtonElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLButtonElement {
HTMLButtonElement { HTMLButtonElement {
htmlelement: HTMLElement::new_inherited(HTMLButtonElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLButtonElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLButtonElement> {
let element = HTMLButtonElement::new_inherited(localName, document); let element = HTMLButtonElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLButtonElementBinding::Wrap) Node::reflect_node(~element, document, HTMLButtonElementBinding::Wrap)
} }
} }
@ -45,7 +59,7 @@ impl HTMLButtonElement {
Ok(()) Ok(())
} }
pub fn GetForm(&self) -> Option<AbstractNode> { pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> {
None None
} }
@ -120,12 +134,13 @@ impl HTMLButtonElement {
pub fn SetWillValidate(&mut self, _will_validate: bool) { pub fn SetWillValidate(&mut self, _will_validate: bool) {
} }
pub fn Validity(&self) -> @mut ValidityState { pub fn Validity(&self) -> JS<ValidityState> {
let global = self.htmlelement.element.node.owner_doc().document().window; let doc = self.htmlelement.element.node.owner_doc();
ValidityState::new(global) 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 { pub fn ValidationMessage(&self) -> DOMString {

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLCanvasElementBinding; use dom::bindings::codegen::HTMLCanvasElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLCanvasElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::{ErrorResult}; use dom::bindings::utils::{ErrorResult};
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLCanvasElementTypeId; use dom::element::HTMLCanvasElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLCanvasElement { pub struct HTMLCanvasElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
} }
impl HTMLCanvasElementDerived for EventTarget {
fn is_htmlcanvaselement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLCanvasElementTypeId)) => true,
_ => false
}
}
}
impl HTMLCanvasElement { impl HTMLCanvasElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLCanvasElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLCanvasElement {
HTMLCanvasElement { HTMLCanvasElement {
htmlelement: HTMLElement::new_inherited(HTMLCanvasElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLCanvasElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLCanvasElement> {
let element = HTMLCanvasElement::new_inherited(localName, document); let element = HTMLCanvasElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLCanvasElementBinding::Wrap) Node::reflect_node(~element, document, HTMLCanvasElementBinding::Wrap)
} }
} }

View file

@ -3,9 +3,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLCollectionBinding; use dom::bindings::codegen::HTMLCollectionBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::utils::Fallible; use dom::bindings::utils::Fallible;
use dom::node::AbstractNode; use dom::element::Element;
use dom::window::Window; use dom::window::Window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
@ -13,14 +14,15 @@ use js::jsapi::{JSObject, JSContext};
use std::ptr; use std::ptr;
#[deriving(Encodable)]
pub struct HTMLCollection { pub struct HTMLCollection {
elements: ~[AbstractNode], elements: ~[JS<Element>],
reflector_: Reflector, reflector_: Reflector,
window: @mut Window, window: JS<Window>,
} }
impl HTMLCollection { impl HTMLCollection {
pub fn new_inherited(window: @mut Window, elements: ~[AbstractNode]) -> HTMLCollection { pub fn new_inherited(window: JS<Window>, elements: ~[JS<Element>]) -> HTMLCollection {
HTMLCollection { HTMLCollection {
elements: elements, elements: elements,
reflector_: Reflector::new(), reflector_: Reflector::new(),
@ -28,18 +30,18 @@ impl HTMLCollection {
} }
} }
pub fn new(window: @mut Window, elements: ~[AbstractNode]) -> @mut HTMLCollection { pub fn new(window: &JS<Window>, elements: ~[JS<Element>]) -> JS<HTMLCollection> {
reflect_dom_object(@mut HTMLCollection::new_inherited(window, elements), reflect_dom_object(~HTMLCollection::new_inherited(window.clone(), elements),
window, HTMLCollectionBinding::Wrap) window.get(), HTMLCollectionBinding::Wrap)
} }
pub fn Length(&self) -> u32 { pub fn Length(&self) -> u32 {
self.elements.len() as 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() { if index < self.Length() {
Some(self.elements[index]) Some(self.elements[index].clone())
} else { } else {
None None
} }
@ -49,7 +51,7 @@ impl HTMLCollection {
Ok(ptr::null()) 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; *found = true;
self.Item(index) self.Item(index)
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLDataElementBinding; use dom::bindings::codegen::HTMLDataElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLDataElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLDataElementTypeId; use dom::element::HTMLDataElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLDataElement { pub struct HTMLDataElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLDataElementDerived for EventTarget {
fn is_htmldataelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLDataElementTypeId)) => true,
_ => false
}
}
}
impl HTMLDataElement { impl HTMLDataElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLDataElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLDataElement {
HTMLDataElement { HTMLDataElement {
htmlelement: HTMLElement::new_inherited(HTMLDataElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLDataElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDataElement> {
let element = HTMLDataElement::new_inherited(localName, document); let element = HTMLDataElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLDataElementBinding::Wrap) Node::reflect_node(~element, document, HTMLDataElementBinding::Wrap)
} }
} }

View file

@ -3,33 +3,47 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLDataListElementBinding; 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::element::HTMLDataListElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlcollection::HTMLCollection; use dom::htmlcollection::HTMLCollection;
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLDataListElement { pub struct HTMLDataListElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLDataListElementDerived for EventTarget {
fn is_htmldatalistelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLDataListElementTypeId)) => true,
_ => false
}
}
}
impl HTMLDataListElement { impl HTMLDataListElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLDataListElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLDataListElement {
HTMLDataListElement { HTMLDataListElement {
htmlelement: HTMLElement::new_inherited(HTMLDataListElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLDataListElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDataListElement> {
let element = HTMLDataListElement::new_inherited(localName, document); let element = HTMLDataListElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLDataListElementBinding::Wrap) Node::reflect_node(~element, document, HTMLDataListElementBinding::Wrap)
} }
} }
impl HTMLDataListElement { impl HTMLDataListElement {
pub fn Options(&self) -> @mut HTMLCollection { pub fn Options(&self) -> JS<HTMLCollection> {
let window = self.htmlelement.element.node.owner_doc().document().window; let doc = self.htmlelement.element.node.owner_doc();
HTMLCollection::new(window, ~[]) let doc = doc.get();
HTMLCollection::new(&doc.window, ~[])
} }
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLDirectoryElementBinding; use dom::bindings::codegen::HTMLDirectoryElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLDirectoryElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLDirectoryElementTypeId; use dom::element::HTMLDirectoryElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLDirectoryElement { pub struct HTMLDirectoryElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLDirectoryElementDerived for EventTarget {
fn is_htmldirectoryelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLDirectoryElementTypeId)) => true,
_ => false
}
}
}
impl HTMLDirectoryElement { impl HTMLDirectoryElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLDirectoryElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLDirectoryElement {
HTMLDirectoryElement { HTMLDirectoryElement {
htmlelement: HTMLElement::new_inherited(HTMLDirectoryElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLDirectoryElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDirectoryElement> {
let element = HTMLDirectoryElement::new_inherited(localName, document); let element = HTMLDirectoryElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLDirectoryElementBinding::Wrap) Node::reflect_node(~element, document, HTMLDirectoryElementBinding::Wrap)
} }
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLDivElementBinding; use dom::bindings::codegen::HTMLDivElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLDivElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLDivElementTypeId; use dom::element::HTMLDivElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLDivElement { pub struct HTMLDivElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLDivElementDerived for EventTarget {
fn is_htmldivelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLDivElementTypeId)) => true,
_ => false
}
}
}
impl HTMLDivElement { impl HTMLDivElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLDivElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLDivElement {
HTMLDivElement { HTMLDivElement {
htmlelement: HTMLElement::new_inherited(HTMLDivElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLDivElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDivElement> {
let element = HTMLDivElement::new_inherited(localName, document); let element = HTMLDivElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLDivElementBinding::Wrap) Node::reflect_node(~element, document, HTMLDivElementBinding::Wrap)
} }
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLDListElementBinding; use dom::bindings::codegen::HTMLDListElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLDListElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLDListElementTypeId; use dom::element::HTMLDListElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLDListElement { pub struct HTMLDListElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLDListElementDerived for EventTarget {
fn is_htmldlistelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLDListElementTypeId)) => true,
_ => false
}
}
}
impl HTMLDListElement { impl HTMLDListElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLDListElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLDListElement {
HTMLDListElement { HTMLDListElement {
htmlelement: HTMLElement::new_inherited(HTMLDListElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLDListElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDListElement> {
let element = HTMLDListElement::new_inherited(localName, document); let element = HTMLDListElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLDListElementBinding::Wrap) Node::reflect_node(~element, document, HTMLDListElementBinding::Wrap)
} }
} }

View file

@ -1,86 +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::codegen::HTMLDocumentBinding;
use dom::bindings::utils::{Reflectable, Reflector, Traceable};
use dom::document::{AbstractDocument, Document, HTML};
use dom::htmlcollection::HTMLCollection;
use dom::window::Window;
use servo_util::namespace::Null;
use extra::url::Url;
use js::jsapi::JSTracer;
pub struct HTMLDocument {
parent: Document
}
impl HTMLDocument {
pub fn new_inherited(window: @mut 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)
}
}
impl HTMLDocument {
pub fn Images(&self) -> @mut HTMLCollection {
self.parent.createHTMLCollection(|elem| "img" == elem.tag_name)
}
pub fn Embeds(&self) -> @mut HTMLCollection {
self.parent.createHTMLCollection(|elem| "embed" == elem.tag_name)
}
pub fn Plugins(&self) -> @mut HTMLCollection {
self.Embeds()
}
pub fn Links(&self) -> @mut 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 {
self.parent.createHTMLCollection(|elem| "form" == elem.tag_name)
}
pub fn Scripts(&self) -> @mut HTMLCollection {
self.parent.createHTMLCollection(|elem| "script" == elem.tag_name)
}
pub fn Anchors(&self) -> @mut HTMLCollection {
self.parent.createHTMLCollection(|elem| {
"a" == elem.tag_name && elem.get_attribute(Null, "name").is_some()
})
}
pub fn Applets(&self) -> @mut HTMLCollection {
// FIXME: This should be return OBJECT elements containing applets.
self.parent.createHTMLCollection(|elem| "applet" == elem.tag_name)
}
}
impl Reflectable for HTMLDocument {
fn reflector<'a>(&'a self) -> &'a Reflector {
self.parent.reflector()
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
self.parent.mut_reflector()
}
}
impl Traceable for HTMLDocument {
fn trace(&self, tracer: *mut JSTracer) {
self.parent.trace(tracer);
}
}

View file

@ -3,29 +3,42 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLElementBinding; use dom::bindings::codegen::HTMLElementBinding;
use dom::bindings::utils::{Fallible, ErrorResult}; use dom::bindings::codegen::InheritTypes::HTMLElementDerived;
use dom::document::AbstractDocument; use dom::bindings::js::JS;
use dom::bindings::utils::{ErrorResult, Fallible};
use dom::document::Document;
use dom::element::{Element, ElementTypeId, HTMLElementTypeId}; 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::jsapi::{JSContext, JSVal};
use js::JSVAL_NULL; use js::JSVAL_NULL;
use servo_util::namespace; use servo_util::namespace;
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLElement { pub struct HTMLElement {
element: Element element: Element
} }
impl HTMLElementDerived for EventTarget {
fn is_htmlelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(_)) => true,
_ => false
}
}
}
impl HTMLElement { 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 { HTMLElement {
element: Element::new_inherited(type_id, tag_name, namespace::HTML, document) element: Element::new_inherited(type_id, tag_name, namespace::HTML, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLElement> {
let element = HTMLElement::new_inherited(HTMLElementTypeId, localName, document); let element = HTMLElement::new_inherited(HTMLElementTypeId, localName, document.clone());
Node::reflect_node(@mut element, document, HTMLElementBinding::Wrap) Node::reflect_node(~element, document, HTMLElementBinding::Wrap)
} }
} }
@ -134,7 +147,7 @@ impl HTMLElement {
pub fn SetClassName(&self, _class: DOMString) { pub fn SetClassName(&self, _class: DOMString) {
} }
pub fn GetOffsetParent(&self) -> Option<AbstractNode> { pub fn GetOffsetParent(&self) -> Option<JS<Element>> {
None None
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLEmbedElementBinding; use dom::bindings::codegen::HTMLEmbedElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLEmbedElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLEmbedElementTypeId; use dom::element::HTMLEmbedElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLEmbedElement { pub struct HTMLEmbedElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLEmbedElementDerived for EventTarget {
fn is_htmlembedelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLEmbedElementTypeId)) => true,
_ => false
}
}
}
impl HTMLEmbedElement { impl HTMLEmbedElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLEmbedElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLEmbedElement {
HTMLEmbedElement { HTMLEmbedElement {
htmlelement: HTMLElement::new_inherited(HTMLEmbedElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLEmbedElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLEmbedElement> {
let element = HTMLEmbedElement::new_inherited(localName, document); let element = HTMLEmbedElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLEmbedElementBinding::Wrap) Node::reflect_node(~element, document, HTMLEmbedElementBinding::Wrap)
} }
} }
@ -76,7 +89,7 @@ impl HTMLEmbedElement {
Ok(()) Ok(())
} }
pub fn GetSVGDocument(&self) -> Option<AbstractDocument> { pub fn GetSVGDocument(&self) -> Option<JS<Document>> {
None None
} }
} }

View file

@ -3,29 +3,43 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLFieldSetElementBinding; use dom::bindings::codegen::HTMLFieldSetElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLFieldSetElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLFieldSetElementTypeId; use dom::element::HTMLFieldSetElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlformelement::HTMLFormElement;
use dom::htmlcollection::HTMLCollection; use dom::htmlcollection::HTMLCollection;
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use dom::validitystate::ValidityState; use dom::validitystate::ValidityState;
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLFieldSetElement { pub struct HTMLFieldSetElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLFieldSetElementDerived for EventTarget {
fn is_htmlfieldsetelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLFieldSetElementTypeId)) => true,
_ => false
}
}
}
impl HTMLFieldSetElement { impl HTMLFieldSetElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLFieldSetElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLFieldSetElement {
HTMLFieldSetElement { HTMLFieldSetElement {
htmlelement: HTMLElement::new_inherited(HTMLFieldSetElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLFieldSetElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFieldSetElement> {
let element = HTMLFieldSetElement::new_inherited(localName, document); let element = HTMLFieldSetElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLFieldSetElementBinding::Wrap) Node::reflect_node(~element, document, HTMLFieldSetElementBinding::Wrap)
} }
} }
@ -38,7 +52,7 @@ impl HTMLFieldSetElement {
Ok(()) Ok(())
} }
pub fn GetForm(&self) -> Option<AbstractNode> { pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> {
None None
} }
@ -54,18 +68,20 @@ impl HTMLFieldSetElement {
~"" ~""
} }
pub fn Elements(&self) -> @mut HTMLCollection { pub fn Elements(&self) -> JS<HTMLCollection> {
let window = self.htmlelement.element.node.owner_doc().document().window; let doc = self.htmlelement.element.node.owner_doc();
HTMLCollection::new(window, ~[]) let doc = doc.get();
HTMLCollection::new(&doc.window, ~[])
} }
pub fn WillValidate(&self) -> bool { pub fn WillValidate(&self) -> bool {
false false
} }
pub fn Validity(&self) -> @mut ValidityState { pub fn Validity(&self) -> JS<ValidityState> {
let global = self.htmlelement.element.node.owner_doc().document().window; let doc = self.htmlelement.element.node.owner_doc();
ValidityState::new(global) let doc = doc.get();
ValidityState::new(&doc.window)
} }
pub fn ValidationMessage(&self) -> DOMString { pub fn ValidationMessage(&self) -> DOMString {

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLFontElementBinding; use dom::bindings::codegen::HTMLFontElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLFontElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLFontElementTypeId; use dom::element::HTMLFontElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLFontElement { pub struct HTMLFontElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLFontElementDerived for EventTarget {
fn is_htmlfontelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLFontElementTypeId)) => true,
_ => false
}
}
}
impl HTMLFontElement { impl HTMLFontElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLFontElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLFontElement {
HTMLFontElement { HTMLFontElement {
htmlelement: HTMLElement::new_inherited(HTMLFontElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLFontElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFontElement> {
let element = HTMLFontElement::new_inherited(localName, document); let element = HTMLFontElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLFontElementBinding::Wrap) Node::reflect_node(~element, document, HTMLFontElementBinding::Wrap)
} }
} }

View file

@ -3,28 +3,41 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLFormElementBinding; use dom::bindings::codegen::HTMLFormElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLFormElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLFormElementTypeId; use dom::element::{Element, HTMLFormElementTypeId};
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlcollection::HTMLCollection; use dom::htmlcollection::HTMLCollection;
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLFormElement { pub struct HTMLFormElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLFormElementDerived for EventTarget {
fn is_htmlformelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLFormElementTypeId)) => true,
_ => false
}
}
}
impl HTMLFormElement { impl HTMLFormElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLFormElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLFormElement {
HTMLFormElement { HTMLFormElement {
htmlelement: HTMLElement::new_inherited(HTMLFormElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLFormElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFormElement> {
let element = HTMLFormElement::new_inherited(localName, document); let element = HTMLFormElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLFormElementBinding::Wrap) Node::reflect_node(~element, document, HTMLFormElementBinding::Wrap)
} }
} }
@ -101,9 +114,10 @@ impl HTMLFormElement {
Ok(()) Ok(())
} }
pub fn Elements(&self) -> @mut HTMLCollection { pub fn Elements(&self) -> JS<HTMLCollection> {
let window = self.htmlelement.element.node.owner_doc().document().window; let doc = self.htmlelement.element.node.owner_doc();
HTMLCollection::new(window, ~[]) let doc = doc.get();
HTMLCollection::new(&doc.window, ~[])
} }
pub fn Length(&self) -> i32 { pub fn Length(&self) -> i32 {
@ -121,7 +135,7 @@ impl HTMLFormElement {
false 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.") fail!("Not implemented.")
} }
} }

View file

@ -3,28 +3,41 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLFrameElementBinding; use dom::bindings::codegen::HTMLFrameElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLFrameElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLFrameElementTypeId; use dom::element::HTMLFrameElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use dom::windowproxy::WindowProxy; use dom::windowproxy::WindowProxy;
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLFrameElement { pub struct HTMLFrameElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLFrameElementDerived for EventTarget {
fn is_htmlframeelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLFrameElementTypeId)) => true,
_ => false
}
}
}
impl HTMLFrameElement { impl HTMLFrameElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLFrameElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLFrameElement {
HTMLFrameElement { HTMLFrameElement {
htmlelement: HTMLElement::new_inherited(HTMLFrameElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLFrameElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFrameElement> {
let element = HTMLFrameElement::new_inherited(localName, document); let element = HTMLFrameElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLFrameElementBinding::Wrap) Node::reflect_node(~element, document, HTMLFrameElementBinding::Wrap)
} }
} }
@ -77,11 +90,11 @@ impl HTMLFrameElement {
Ok(()) Ok(())
} }
pub fn GetContentDocument(&self) -> Option<AbstractDocument> { pub fn GetContentDocument(&self) -> Option<JS<Document>> {
None None
} }
pub fn GetContentWindow(&self) -> Option<@mut WindowProxy> { pub fn GetContentWindow(&self) -> Option<JS<WindowProxy>> {
None None
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLFrameSetElementBinding; use dom::bindings::codegen::HTMLFrameSetElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLFrameSetElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLFrameSetElementTypeId; use dom::element::HTMLFrameSetElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLFrameSetElement { pub struct HTMLFrameSetElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLFrameSetElementDerived for EventTarget {
fn is_htmlframesetelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLFrameSetElementTypeId)) => true,
_ => false
}
}
}
impl HTMLFrameSetElement { impl HTMLFrameSetElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLFrameSetElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLFrameSetElement {
HTMLFrameSetElement { HTMLFrameSetElement {
htmlelement: HTMLElement::new_inherited(HTMLFrameSetElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLFrameSetElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFrameSetElement> {
let element = HTMLFrameSetElement::new_inherited(localName, document); let element = HTMLFrameSetElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLFrameSetElementBinding::Wrap) Node::reflect_node(~element, document, HTMLFrameSetElementBinding::Wrap)
} }
} }

View file

@ -3,25 +3,38 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLHeadElementBinding; 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::element::HTMLHeadElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLHeadElement { pub struct HTMLHeadElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLHeadElementDerived for EventTarget {
fn is_htmlheadelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLHeadElementTypeId)) => true,
_ => false
}
}
}
impl HTMLHeadElement { impl HTMLHeadElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLHeadElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLHeadElement {
HTMLHeadElement { HTMLHeadElement {
htmlelement: HTMLElement::new_inherited(HTMLHeadElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLHeadElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLHeadElement> {
let element = HTMLHeadElement::new_inherited(localName, document); let element = HTMLHeadElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLHeadElementBinding::Wrap) Node::reflect_node(~element, document, HTMLHeadElementBinding::Wrap)
} }
} }

View file

@ -3,12 +3,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLHeadingElementBinding; 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::element::HTMLHeadingElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub enum HeadingLevel { pub enum HeadingLevel {
Heading1, Heading1,
Heading2, Heading2,
@ -18,22 +22,32 @@ pub enum HeadingLevel {
Heading6, Heading6,
} }
#[deriving(Encodable)]
pub struct HTMLHeadingElement { pub struct HTMLHeadingElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
level: HeadingLevel, level: HeadingLevel,
} }
impl HTMLHeadingElementDerived for EventTarget {
fn is_htmlheadingelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLHeadingElementTypeId)) => true,
_ => false
}
}
}
impl HTMLHeadingElement { 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 { HTMLHeadingElement {
htmlelement: HTMLElement::new_inherited(HTMLHeadingElementTypeId, localName, document), htmlelement: HTMLElement::new_inherited(HTMLHeadingElementTypeId, localName, document),
level: level, level: level,
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument, level: HeadingLevel) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>, level: HeadingLevel) -> JS<HTMLHeadingElement> {
let element = HTMLHeadingElement::new_inherited(localName, document, level); let element = HTMLHeadingElement::new_inherited(localName, document.clone(), level);
Node::reflect_node(@mut element, document, HTMLHeadingElementBinding::Wrap) Node::reflect_node(~element, document, HTMLHeadingElementBinding::Wrap)
} }
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLHRElementBinding; use dom::bindings::codegen::HTMLHRElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLHRElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLHRElementTypeId; use dom::element::HTMLHRElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLHRElement { pub struct HTMLHRElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
} }
impl HTMLHRElementDerived for EventTarget {
fn is_htmlhrelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLHRElementTypeId)) => true,
_ => false
}
}
}
impl HTMLHRElement { impl HTMLHRElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLHRElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLHRElement {
HTMLHRElement { HTMLHRElement {
htmlelement: HTMLElement::new_inherited(HTMLHRElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLHRElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLHRElement> {
let element = HTMLHRElement::new_inherited(localName, document); let element = HTMLHRElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLHRElementBinding::Wrap) Node::reflect_node(~element, document, HTMLHRElementBinding::Wrap)
} }
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLHtmlElementBinding; use dom::bindings::codegen::HTMLHtmlElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLHtmlElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLHtmlElementTypeId; use dom::element::HTMLHtmlElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLHtmlElement { pub struct HTMLHtmlElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLHtmlElementDerived for EventTarget {
fn is_htmlhtmlelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLHtmlElementTypeId)) => true,
_ => false
}
}
}
impl HTMLHtmlElement { impl HTMLHtmlElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLHtmlElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLHtmlElement {
HTMLHtmlElement { HTMLHtmlElement {
htmlelement: HTMLElement::new_inherited(HTMLHtmlElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLHtmlElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLHtmlElement> {
let element = HTMLHtmlElement::new_inherited(localName, document); let element = HTMLHtmlElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLHtmlElementBinding::Wrap) Node::reflect_node(~element, document, HTMLHtmlElementBinding::Wrap)
} }
} }

View file

@ -3,17 +3,21 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLIFrameElementBinding; use dom::bindings::codegen::HTMLIFrameElementBinding;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElementDerived};
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLIframeElementTypeId; use dom::element::HTMLIframeElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use dom::windowproxy::WindowProxy; use dom::windowproxy::WindowProxy;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use extra::url::Url; use extra::url::Url;
use servo_msg::constellation_msg::{PipelineId, SubpageId}; use servo_msg::constellation_msg::{PipelineId, SubpageId};
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use extra::serialize::{Encoder, Encodable};
enum SandboxAllowance { enum SandboxAllowance {
AllowNothing = 0x00, AllowNothing = 0x00,
@ -25,13 +29,33 @@ enum SandboxAllowance {
AllowPopups = 0x20 AllowPopups = 0x20
} }
#[deriving(Encodable)]
pub struct HTMLIFrameElement { pub struct HTMLIFrameElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
frame: Option<Url>, extra: Untraceable,
size: Option<IFrameSize>, size: Option<IFrameSize>,
sandbox: Option<u8> 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 { pub struct IFrameSize {
pipeline_id: PipelineId, pipeline_id: PipelineId,
subpage_id: SubpageId, subpage_id: SubpageId,
@ -44,18 +68,20 @@ impl HTMLIFrameElement {
} }
impl HTMLIFrameElement { impl HTMLIFrameElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLIFrameElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLIFrameElement {
HTMLIFrameElement { HTMLIFrameElement {
htmlelement: HTMLElement::new_inherited(HTMLIframeElementTypeId, localName, document), htmlelement: HTMLElement::new_inherited(HTMLIframeElementTypeId, localName, document),
frame: None, extra: Untraceable {
frame: None
},
size: None, size: None,
sandbox: None, sandbox: None,
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLIFrameElement> {
let element = HTMLIFrameElement::new_inherited(localName, document); let element = HTMLIFrameElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLIFrameElementBinding::Wrap) Node::reflect_node(~element, document, HTMLIFrameElementBinding::Wrap)
} }
} }
@ -84,12 +110,13 @@ impl HTMLIFrameElement {
Ok(()) 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") self.htmlelement.element.get_string_attribute("sandbox")
} }
pub fn SetSandbox(&mut self, abstract_self: AbstractNode, sandbox: DOMString) { pub fn SetSandbox(&mut self, abstract_self: &JS<HTMLIFrameElement>, sandbox: DOMString) {
self.htmlelement.element.set_string_attribute(abstract_self, "sandbox", self.htmlelement.element.set_string_attribute(&ElementCast::from(abstract_self),
"sandbox",
sandbox); sandbox);
} }
@ -143,11 +170,11 @@ impl HTMLIFrameElement {
Ok(()) Ok(())
} }
pub fn GetContentDocument(&self) -> Option<AbstractDocument> { pub fn GetContentDocument(&self) -> Option<JS<Document>> {
None None
} }
pub fn GetContentWindow(&self) -> Option<@mut WindowProxy> { pub fn GetContentWindow(&self) -> Option<JS<WindowProxy>> {
None None
} }
@ -199,7 +226,7 @@ impl HTMLIFrameElement {
Ok(()) Ok(())
} }
pub fn GetSVGDocument(&self) -> Option<AbstractDocument> { pub fn GetSVGDocument(&self) -> Option<JS<Document>> {
None None
} }
} }

View file

@ -3,11 +3,15 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLImageElementBinding; 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::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLImageElementTypeId; use dom::element::{Element, HTMLImageElementTypeId};
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId, NodeHelpers};
use extra::url::Url; use extra::url::Url;
use servo_util::geometry::to_px; use servo_util::geometry::to_px;
use layout_interface::{ContentBoxQuery, ContentBoxResponse}; use layout_interface::{ContentBoxQuery, ContentBoxResponse};
@ -17,22 +21,45 @@ use servo_util::url::parse_url;
use servo_util::namespace::Null; use servo_util::namespace::Null;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use extra::serialize::{Encoder, Encodable};
#[deriving(Encodable)]
pub struct HTMLImageElement { pub struct HTMLImageElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
extra: Untraceable,
}
struct Untraceable {
image: Option<Url>, image: Option<Url>,
} }
impl HTMLImageElement { impl<S: Encoder> Encodable<S> for Untraceable {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLImageElement { fn encode(&self, _s: &mut S) {
HTMLImageElement {
htmlelement: HTMLElement::new_inherited(HTMLImageElementTypeId, localName, document),
image: None,
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { impl HTMLImageElementDerived for EventTarget {
let element = HTMLImageElement::new_inherited(localName, document); fn is_htmlimageelement(&self) -> bool {
Node::reflect_node(@mut element, document, HTMLImageElementBinding::Wrap) match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLImageElementTypeId)) => true,
_ => false
}
}
}
impl HTMLImageElement {
pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLImageElement {
HTMLImageElement {
htmlelement: HTMLElement::new_inherited(HTMLImageElementTypeId, localName, document),
extra: Untraceable {
image: None,
}
}
}
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. /// prefetching the image. This method must be called after `src` is changed.
pub fn update_image(&mut self, image_cache: ImageCacheTask, url: Option<Url>) { pub fn update_image(&mut self, image_cache: ImageCacheTask, url: Option<Url>) {
let elem = &mut self.htmlelement.element; 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 { match src_opt {
None => {} None => {}
Some(src) => { Some(src) => {
let img_url = parse_url(src, url); 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 // inform the image cache to load this, but don't store a
// handle. // handle.
@ -61,7 +88,7 @@ impl HTMLImageElement {
pub fn AfterSetAttr(&mut self, name: DOMString, _value: DOMString) { pub fn AfterSetAttr(&mut self, name: DOMString, _value: DOMString) {
if "src" == name { if "src" == name {
let document = self.htmlelement.element.node.owner_doc(); 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()); let url = window.page.url.as_ref().map(|&(ref url, _)| url.clone());
self.update_image(window.image_cache_task.clone(), url); 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. // `self.update_image()` will see the missing src attribute and return early.
if "src" == name { if "src" == name {
let document = self.htmlelement.element.node.owner_doc(); 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); self.update_image(window.image_cache_task.clone(), None);
} }
} }
@ -86,13 +113,13 @@ impl HTMLImageElement {
Ok(()) 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; 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(()) Ok(())
} }
@ -120,37 +147,43 @@ impl HTMLImageElement {
Ok(()) Ok(())
} }
pub fn Width(&self, abstract_self: AbstractNode) -> u32 { pub fn Width(&self, abstract_self: &JS<HTMLImageElement>) -> u32 {
let node = &self.htmlelement.element.node; let node: JS<Node> = NodeCast::from(abstract_self);
let page = node.owner_doc().document().window.page; let doc = node.get().owner_doc();
let page = doc.get().window.get().page;
let (port, chan) = Chan::new(); 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) => { ContentBoxResponse(rect) => {
to_px(rect.size.width) as u32 to_px(rect.size.width) as u32
} }
} }
} }
pub fn SetWidth(&mut self, abstract_self: AbstractNode, width: u32) -> ErrorResult { pub fn SetWidth(&mut self, abstract_self: &JS<HTMLImageElement>, width: u32) -> ErrorResult {
let node = &mut self.htmlelement.element; let mut elem: JS<Element> = ElementCast::from(abstract_self);
node.set_attr(abstract_self, ~"width", width.to_str()); let mut elem_clone = elem.clone();
elem.get_mut().set_attr(&mut elem_clone, ~"width", width.to_str());
Ok(()) 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 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(); 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) => { ContentBoxResponse(rect) => {
to_px(rect.size.height) as u32 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; 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(()) Ok(())
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLInputElementBinding; use dom::bindings::codegen::HTMLInputElementBinding;
use dom::bindings::utils::{Fallible, ErrorResult}; use dom::bindings::codegen::InheritTypes::HTMLInputElementDerived;
use dom::document::AbstractDocument; use dom::bindings::js::JS;
use dom::bindings::utils::{ErrorResult, Fallible};
use dom::document::Document;
use dom::element::HTMLInputElementTypeId; use dom::element::HTMLInputElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLInputElement { pub struct HTMLInputElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
} }
impl HTMLInputElementDerived for EventTarget {
fn is_htmlinputelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLInputElementTypeId)) => true,
_ => false
}
}
}
impl HTMLInputElement { impl HTMLInputElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLInputElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLInputElement {
HTMLInputElement { HTMLInputElement {
htmlelement: HTMLElement::new_inherited(HTMLInputElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLInputElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLInputElement> {
let element = HTMLInputElement::new_inherited(localName, document); let element = HTMLInputElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLInputElementBinding::Wrap) Node::reflect_node(~element, document, HTMLInputElementBinding::Wrap)
} }
} }

View file

@ -3,26 +3,39 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLLabelElementBinding; 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::element::HTMLLabelElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLLabelElement { pub struct HTMLLabelElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
} }
impl HTMLLabelElementDerived for EventTarget {
fn is_htmllabelelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLLabelElementTypeId)) => true,
_ => false
}
}
}
impl HTMLLabelElement { impl HTMLLabelElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLLabelElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLLabelElement {
HTMLLabelElement { HTMLLabelElement {
htmlelement: HTMLElement::new_inherited(HTMLLabelElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLLabelElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLabelElement> {
let element = HTMLLabelElement::new_inherited(localName, document); let element = HTMLLabelElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLLabelElementBinding::Wrap) Node::reflect_node(~element, document, HTMLLabelElementBinding::Wrap)
} }
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLLegendElementBinding; use dom::bindings::codegen::HTMLLegendElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLLegendElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLLegendElementTypeId; use dom::element::HTMLLegendElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLLegendElement { pub struct HTMLLegendElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
} }
impl HTMLLegendElementDerived for EventTarget {
fn is_htmllegendelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLLegendElementTypeId)) => true,
_ => false
}
}
}
impl HTMLLegendElement { impl HTMLLegendElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLLegendElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLLegendElement {
HTMLLegendElement { HTMLLegendElement {
htmlelement: HTMLElement::new_inherited(HTMLLegendElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLLegendElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLegendElement> {
let element = HTMLLegendElement::new_inherited(localName, document); let element = HTMLLegendElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLLegendElementBinding::Wrap) Node::reflect_node(~element, document, HTMLLegendElementBinding::Wrap)
} }
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLLIElementBinding; use dom::bindings::codegen::HTMLLIElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLLIElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLLIElementTypeId; use dom::element::HTMLLIElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLLIElement { pub struct HTMLLIElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
} }
impl HTMLLIElementDerived for EventTarget {
fn is_htmllielement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLLIElementTypeId)) => true,
_ => false
}
}
}
impl HTMLLIElement { impl HTMLLIElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLLIElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLLIElement {
HTMLLIElement { HTMLLIElement {
htmlelement: HTMLElement::new_inherited(HTMLLIElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLLIElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLIElement> {
let element = HTMLLIElement::new_inherited(localName, document); let element = HTMLLIElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLLIElementBinding::Wrap) Node::reflect_node(~element, document, HTMLLIElementBinding::Wrap)
} }
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLLinkElementBinding; use dom::bindings::codegen::HTMLLinkElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLLinkElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLLinkElementTypeId; use dom::element::HTMLLinkElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLLinkElement { pub struct HTMLLinkElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
} }
impl HTMLLinkElementDerived for EventTarget {
fn is_htmllinkelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLLinkElementTypeId)) => true,
_ => false
}
}
}
impl HTMLLinkElement { impl HTMLLinkElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLLinkElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLLinkElement {
HTMLLinkElement { HTMLLinkElement {
htmlelement: HTMLElement::new_inherited(HTMLLinkElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLLinkElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLinkElement> {
let element = HTMLLinkElement::new_inherited(localName, document); let element = HTMLLinkElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLLinkElementBinding::Wrap) Node::reflect_node(~element, document, HTMLLinkElementBinding::Wrap)
} }
} }

View file

@ -3,25 +3,38 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLMainElementBinding; 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::element::HTMLMainElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLMainElement { pub struct HTMLMainElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLMainElementDerived for EventTarget {
fn is_htmlmainelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLMainElementTypeId)) => true,
_ => false
}
}
}
impl HTMLMainElement { impl HTMLMainElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLMainElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLMainElement {
HTMLMainElement { HTMLMainElement {
htmlelement: HTMLElement::new_inherited(HTMLMainElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLMainElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMainElement> {
let element = HTMLMainElement::new_inherited(localName, document); let element = HTMLMainElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLMainElementBinding::Wrap) Node::reflect_node(~element, document, HTMLMainElementBinding::Wrap)
} }
} }

View file

@ -3,28 +3,41 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLMapElementBinding; use dom::bindings::codegen::HTMLMapElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLMapElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::htmlcollection::HTMLCollection; use dom::document::Document;
use dom::document::AbstractDocument;
use dom::element::HTMLMapElementTypeId; use dom::element::HTMLMapElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlcollection::HTMLCollection;
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLMapElement { pub struct HTMLMapElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLMapElementDerived for EventTarget {
fn is_htmlmapelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLMapElementTypeId)) => true,
_ => false
}
}
}
impl HTMLMapElement { impl HTMLMapElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLMapElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLMapElement {
HTMLMapElement { HTMLMapElement {
htmlelement: HTMLElement::new_inherited(HTMLMapElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLMapElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMapElement> {
let element = HTMLMapElement::new_inherited(localName, document); let element = HTMLMapElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLMapElementBinding::Wrap) Node::reflect_node(~element, document, HTMLMapElementBinding::Wrap)
} }
} }
@ -37,8 +50,9 @@ impl HTMLMapElement {
Ok(()) Ok(())
} }
pub fn Areas(&self) -> @mut HTMLCollection { pub fn Areas(&self) -> JS<HTMLCollection> {
let window = self.htmlelement.element.node.owner_doc().document().window; let doc = self.htmlelement.element.node.owner_doc();
HTMLCollection::new(window, ~[]) let doc = doc.get();
HTMLCollection::new(&doc.window, ~[])
} }
} }

View file

@ -2,18 +2,33 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::ElementTypeId; use dom::element::{ElementTypeId, HTMLAudioElementTypeId, HTMLVideoElementTypeId};
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::ElementNodeTypeId;
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLMediaElement { pub struct HTMLMediaElement {
htmlelement: HTMLElement, 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 { 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 { HTMLMediaElement {
htmlelement: HTMLElement::new_inherited(type_id, tag_name, document) htmlelement: HTMLElement::new_inherited(type_id, tag_name, document)
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLMetaElementBinding; use dom::bindings::codegen::HTMLMetaElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLMetaElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLMetaElementTypeId; use dom::element::HTMLMetaElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLMetaElement { pub struct HTMLMetaElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
} }
impl HTMLMetaElementDerived for EventTarget {
fn is_htmlmetaelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLMetaElementTypeId)) => true,
_ => false
}
}
}
impl HTMLMetaElement { impl HTMLMetaElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLMetaElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLMetaElement {
HTMLMetaElement { HTMLMetaElement {
htmlelement: HTMLElement::new_inherited(HTMLMetaElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLMetaElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMetaElement> {
let element = HTMLMetaElement::new_inherited(localName, document); let element = HTMLMetaElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLMetaElementBinding::Wrap) Node::reflect_node(~element, document, HTMLMetaElementBinding::Wrap)
} }
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLMeterElementBinding; use dom::bindings::codegen::HTMLMeterElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLMeterElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLMeterElementTypeId; use dom::element::HTMLMeterElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLMeterElement { pub struct HTMLMeterElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLMeterElementDerived for EventTarget {
fn is_htmlmeterelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLMeterElementTypeId)) => true,
_ => false
}
}
}
impl HTMLMeterElement { impl HTMLMeterElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLMeterElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLMeterElement {
HTMLMeterElement { HTMLMeterElement {
htmlelement: HTMLElement::new_inherited(HTMLMeterElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLMeterElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMeterElement> {
let element = HTMLMeterElement::new_inherited(localName, document); let element = HTMLMeterElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLMeterElementBinding::Wrap) Node::reflect_node(~element, document, HTMLMeterElementBinding::Wrap)
} }
} }

View file

@ -3,27 +3,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLModElementBinding; use dom::bindings::codegen::HTMLModElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLModElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLModElementTypeId; use dom::element::HTMLModElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[deriving(Encodable)]
pub struct HTMLModElement { pub struct HTMLModElement {
htmlelement: HTMLElement htmlelement: HTMLElement
} }
impl HTMLModElementDerived for EventTarget {
fn is_htmlmodelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLModElementTypeId)) => true,
_ => false
}
}
}
impl HTMLModElement { impl HTMLModElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLModElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLModElement {
HTMLModElement { HTMLModElement {
htmlelement: HTMLElement::new_inherited(HTMLModElementTypeId, localName, document) htmlelement: HTMLElement::new_inherited(HTMLModElementTypeId, localName, document)
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLModElement> {
let element = HTMLModElement::new_inherited(localName, document); let element = HTMLModElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLModElementBinding::Wrap) Node::reflect_node(~element, document, HTMLModElementBinding::Wrap)
} }
} }

View file

@ -3,11 +3,15 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::HTMLObjectElementBinding; use dom::bindings::codegen::HTMLObjectElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLObjectElementDerived;
use dom::bindings::js::JS;
use dom::bindings::utils::ErrorResult; use dom::bindings::utils::ErrorResult;
use dom::document::AbstractDocument; use dom::document::Document;
use dom::element::HTMLObjectElementTypeId; use dom::element::HTMLObjectElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, Node}; use dom::htmlformelement::HTMLFormElement;
use dom::node::{Node, ElementNodeTypeId};
use dom::validitystate::ValidityState; use dom::validitystate::ValidityState;
use dom::windowproxy::WindowProxy; use dom::windowproxy::WindowProxy;
use servo_util::str::DOMString; use servo_util::str::DOMString;
@ -19,20 +23,30 @@ use servo_util::url::parse_url;
use servo_util::namespace::Null; use servo_util::namespace::Null;
use servo_util::url::is_image_data; use servo_util::url::is_image_data;
#[deriving(Encodable)]
pub struct HTMLObjectElement { pub struct HTMLObjectElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
} }
impl HTMLObjectElementDerived for EventTarget {
fn is_htmlobjectelement(&self) -> bool {
match self.type_id {
NodeTargetTypeId(ElementNodeTypeId(HTMLObjectElementTypeId)) => true,
_ => false
}
}
}
impl HTMLObjectElement { impl HTMLObjectElement {
pub fn new_inherited(localName: DOMString, document: AbstractDocument) -> HTMLObjectElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLObjectElement {
HTMLObjectElement { HTMLObjectElement {
htmlelement: HTMLElement::new_inherited(HTMLObjectElementTypeId, localName, document), htmlelement: HTMLElement::new_inherited(HTMLObjectElementTypeId, localName, document),
} }
} }
pub fn new(localName: DOMString, document: AbstractDocument) -> AbstractNode { pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLObjectElement> {
let element = HTMLObjectElement::new_inherited(localName, document); let element = HTMLObjectElement::new_inherited(localName, document.clone());
Node::reflect_node(@mut element, document, HTMLObjectElementBinding::Wrap) Node::reflect_node(~element, document, HTMLObjectElementBinding::Wrap)
} }
} }
@ -44,8 +58,8 @@ impl HTMLObjectElement {
let elem = &mut self.htmlelement.element; let elem = &mut self.htmlelement.element;
// TODO: support other values // TODO: support other values
match (elem.get_attribute(Null, "type").map(|x| x.Value()), match (elem.get_attribute(Null, "type").map(|x| x.get().Value()),
elem.get_attribute(Null, "data").map(|x| x.Value())) { elem.get_attribute(Null, "data").map(|x| x.get().Value())) {
(None, Some(uri)) => { (None, Some(uri)) => {
if is_image_data(uri) { if is_image_data(uri) {
let data_url = parse_url(uri, url); let data_url = parse_url(uri, url);
@ -60,9 +74,9 @@ impl HTMLObjectElement {
pub fn AfterSetAttr(&mut self, name: DOMString, _value: DOMString) { pub fn AfterSetAttr(&mut self, name: DOMString, _value: DOMString) {
if "data" == name { if "data" == name {
let document = self.htmlelement.element.node.owner_doc(); let document = self.htmlelement.element.node.owner_doc();
let window = document.document().window; let window = document.get().window.clone();
let url = window.page.url.as_ref().map(|&(ref url, _)| url.clone()); let url = window.get().page.url.as_ref().map(|&(ref url, _)| url.clone());
self.process_data_url(window.image_cache_task.clone(), url); self.process_data_url(window.get().image_cache_task.clone(), url);
} }
} }
@ -98,7 +112,7 @@ impl HTMLObjectElement {
Ok(()) Ok(())
} }
pub fn GetForm(&self) -> Option<AbstractNode> { pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> {
None None
} }
@ -118,11 +132,11 @@ impl HTMLObjectElement {
Ok(()) Ok(())
} }
pub fn GetContentDocument(&self) -> Option<AbstractDocument> { pub fn GetContentDocument(&self) -> Option<JS<Document>> {
None None
} }
pub fn GetContentWindow(&self) -> Option<@mut WindowProxy> { pub fn GetContentWindow(&self) -> Option<JS<WindowProxy>> {
None None
} }
@ -130,9 +144,10 @@ impl HTMLObjectElement {
false false
} }
pub fn Validity(&self) -> @mut ValidityState { pub fn Validity(&self) -> JS<ValidityState> {
let global = self.htmlelement.element.node.owner_doc().document().window; let doc = self.htmlelement.element.node.owner_doc();
ValidityState::new(global) let doc = doc.get();
ValidityState::new(&doc.window)
} }
pub fn ValidationMessage(&self) -> DOMString { pub fn ValidationMessage(&self) -> DOMString {
@ -226,7 +241,7 @@ impl HTMLObjectElement {
Ok(()) Ok(())
} }
pub fn GetSVGDocument(&self) -> Option<AbstractDocument> { pub fn GetSVGDocument(&self) -> Option<JS<Document>> {
None None
} }
} }

Some files were not shown because too many files have changed in this diff Show more