diff options
150 files changed, 1225 insertions, 513 deletions
diff --git a/Cargo.lock b/Cargo.lock index d0aeafa535f..06b4d0085d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,7 +29,7 @@ source = "git+https://github.com/servo/rust-azure#b357751c04a89a87e6ef1f0cebe5f2 dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#166a601ff3e0fc3a64ca1a9090d02c8d4f22b61a)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics#6a9919f8a912cc67571b891ba198d5325964a104)", - "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#1ad11072b31657eeccaf4879c6e98723d488bd3d)", + "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#967a97fa7e9ae47f96aee5e48f5fb0be1345d89e)", "egl 0.1.0 (git+https://github.com/servo/rust-egl#88f2a13812ddbce2bf2317221663a61c31b3e220)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype#0b03da276e4bdeae2300596dabc4ccb16733ad70)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#b001a76e907befaae1d0d6dd259418a22092da86)", @@ -60,7 +60,7 @@ dependencies = [ "alert 0.1.0 (git+https://github.com/servo/rust-alert#fdc24f13be8d8a2d15214ec228d166b3221b809e)", "azure 0.1.0 (git+https://github.com/servo/rust-azure#b357751c04a89a87e6ef1f0cebe5f20957dd112d)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics#6a9919f8a912cc67571b891ba198d5325964a104)", - "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#1ad11072b31657eeccaf4879c6e98723d488bd3d)", + "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#967a97fa7e9ae47f96aee5e48f5fb0be1345d89e)", "devtools 0.0.1", "devtools_traits 0.0.1", "geom 0.1.0 (git+https://github.com/servo/rust-geom#b001a76e907befaae1d0d6dd259418a22092da86)", @@ -92,7 +92,7 @@ dependencies = [ [[package]] name = "core_text" version = "0.1.0" -source = "git+https://github.com/servo/rust-core-text#1ad11072b31657eeccaf4879c6e98723d488bd3d" +source = "git+https://github.com/servo/rust-core-text#967a97fa7e9ae47f96aee5e48f5fb0be1345d89e" dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#166a601ff3e0fc3a64ca1a9090d02c8d4f22b61a)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics#6a9919f8a912cc67571b891ba198d5325964a104)", @@ -101,7 +101,7 @@ dependencies = [ [[package]] name = "cssparser" version = "0.1.0" -source = "git+https://github.com/servo/rust-cssparser#22146ce095cb62df39d459c3a79d1486041f96f6" +source = "git+https://github.com/servo/rust-cssparser#7b0549a5d122135848b8813ec401112ab588063c" dependencies = [ "encoding 0.1.0 (git+https://github.com/lifthrasiir/rust-encoding#28eafb604a92c7786685b46c0fc02682ba3ab265)", ] @@ -175,7 +175,7 @@ dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure#b357751c04a89a87e6ef1f0cebe5f20957dd112d)", "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#166a601ff3e0fc3a64ca1a9090d02c8d4f22b61a)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics#6a9919f8a912cc67571b891ba198d5325964a104)", - "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#1ad11072b31657eeccaf4879c6e98723d488bd3d)", + "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#967a97fa7e9ae47f96aee5e48f5fb0be1345d89e)", "fontconfig 0.1.0 (git+https://github.com/servo/rust-fontconfig#b16c1e12ecb74b1e4e9a9b23c2b98580a34cf201)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype#0b03da276e4bdeae2300596dabc4ccb16733ad70)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#b001a76e907befaae1d0d6dd259418a22092da86)", @@ -388,7 +388,7 @@ name = "script" version = "0.0.1" dependencies = [ "canvas 0.0.1", - "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser#22146ce095cb62df39d459c3a79d1486041f96f6)", + "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser#7b0549a5d122135848b8813ec401112ab588063c)", "devtools_traits 0.0.1", "encoding 0.1.0 (git+https://github.com/lifthrasiir/rust-encoding#28eafb604a92c7786685b46c0fc02682ba3ab265)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#b001a76e907befaae1d0d6dd259418a22092da86)", @@ -461,7 +461,7 @@ dependencies = [ name = "style" version = "0.0.1" dependencies = [ - "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser#22146ce095cb62df39d459c3a79d1486041f96f6)", + "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser#7b0549a5d122135848b8813ec401112ab588063c)", "encoding 0.1.0 (git+https://github.com/lifthrasiir/rust-encoding#28eafb604a92c7786685b46c0fc02682ba3ab265)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#b001a76e907befaae1d0d6dd259418a22092da86)", "lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs#e62a65372f1dd9019e37eb9381d819edff80e360)", diff --git a/README.md b/README.md index c544152555c..465e1bbbbfc 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,14 @@ script](etc/ci/travis.install.sh). On OS X (homebrew): ``` sh -brew install automake pkg-config python glfw3 +brew install automake pkg-config python glfw3 cmake pip install virtualenv ``` On OS X (MacPorts): ``` sh -sudo port install python27 py27-virtualenv +sudo port install python27 py27-virtualenv cmake ``` On Debian-based Linuxes: @@ -41,7 +41,7 @@ On Fedora: sudo yum install curl freeglut-devel libtool gcc-c++ libXi-devel \ freetype-devel mesa-libGL-devel glib2-devel libX11-devel libXrandr-devel gperf \ fontconfig-devel cabextract ttmkfdir python python-virtualenv expat-devel \ - rpm-build openssl-devel glfw-devel + rpm-build openssl-devel glfw-devel cmake pushd . cd /tmp wget http://corefonts.sourceforge.net/msttcorefonts-2.5-1.spec @@ -53,7 +53,7 @@ popd On Arch Linux: ``` sh -sudo pacman -S base-devel git python2 python2-virtualenv mesa glfw ttf-font +sudo pacman -S base-devel git python2 python2-virtualenv mesa glfw ttf-font cmake ``` Cross-compilation for Android: diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index a72f0b44d08..7f8975a2ca6 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -288,10 +288,10 @@ impl DisplayList { pub fn draw_into_context(&self, render_context: &mut RenderContext, current_transform: &Matrix2D<AzFloat>, - current_clip_rect: &Rect<Au>) { + current_clip_stack: &mut Vec<Rect<Au>>) { debug!("Beginning display list."); for item in self.list.iter() { - item.draw_into_context(render_context, current_transform, current_clip_rect) + item.draw_into_context(render_context, current_transform, current_clip_stack) } debug!("Ending display list."); } @@ -504,14 +504,19 @@ impl DisplayItem { fn draw_into_context(&self, render_context: &mut RenderContext, current_transform: &Matrix2D<AzFloat>, - current_clip_rect: &Rect<Au>) { + current_clip_stack: &mut Vec<Rect<Au>>) { // This should have been flattened to the content stacking level first. assert!(self.base().level == ContentStackingLevel); + // TODO(pcwalton): This will need some tweaking to deal with more complex clipping regions. let clip_rect = &self.base().clip_rect; - let need_to_clip = current_clip_rect != clip_rect; - if need_to_clip { + if current_clip_stack.len() == 0 || current_clip_stack.last().unwrap() != clip_rect { + while current_clip_stack.len() != 0 { + render_context.draw_pop_clip(); + drop(current_clip_stack.pop()); + } render_context.draw_push_clip(clip_rect); + current_clip_stack.push(*clip_rect); } match *self { @@ -608,10 +613,6 @@ impl DisplayItem { PseudoDisplayItemClass(_) => {} } - - if need_to_clip { - render_context.draw_pop_clip(); - } } pub fn base<'a>(&'a self) -> &'a BaseDisplayItem { diff --git a/components/gfx/font.rs b/components/gfx/font.rs index fe9445be107..f88d964b831 100644 --- a/components/gfx/font.rs +++ b/components/gfx/font.rs @@ -100,14 +100,19 @@ pub struct Font { } impl Font { - pub fn shape_text(&mut self, text: String, is_whitespace: bool) -> Arc<GlyphStore> { + pub fn shape_text(&mut self, text: &str, is_whitespace: bool) -> Arc<GlyphStore> { self.make_shaper(); let shaper = &self.shaper; - self.shape_cache.find_or_create(&text, |txt| { - let mut glyphs = GlyphStore::new(text.as_slice().char_len() as int, is_whitespace); - shaper.as_ref().unwrap().shape_text(txt.as_slice(), &mut glyphs); - Arc::new(glyphs) - }) + match self.shape_cache.find_equiv(&text) { + None => {} + Some(glyphs) => return (*glyphs).clone(), + } + + let mut glyphs = GlyphStore::new(text.char_len() as int, is_whitespace); + shaper.as_ref().unwrap().shape_text(text, &mut glyphs); + let glyphs = Arc::new(glyphs); + self.shape_cache.insert(text.to_string(), glyphs.clone()); + glyphs } fn make_shaper<'a>(&'a mut self) -> &'a Shaper { diff --git a/components/gfx/font_context.rs b/components/gfx/font_context.rs index efb40d16abd..adcd9810b88 100644 --- a/components/gfx/font_context.rs +++ b/components/gfx/font_context.rs @@ -43,7 +43,7 @@ static SMALL_CAPS_SCALE_FACTOR: f64 = 0.8; // Matches FireFox (see gfxFont. struct LayoutFontCacheEntry { family: String, - font: Rc<RefCell<Font>>, + font: Option<Rc<RefCell<Font>>>, } struct FallbackFontCacheEntry { @@ -132,13 +132,21 @@ impl FontContext { let mut cache_hit = false; for cached_font_entry in self.layout_font_cache.iter() { if cached_font_entry.family.as_slice() == family.name() { - let cached_font = cached_font_entry.font.borrow(); - if cached_font.descriptor == desc && - cached_font.requested_pt_size == style.font_size.to_subpx() && - cached_font.variant == style.font_variant { - fonts.push(cached_font_entry.font.clone()); - cache_hit = true; - break; + match cached_font_entry.font { + None => { + cache_hit = true; + break; + } + Some(ref cached_font_ref) => { + let cached_font = cached_font_ref.borrow(); + if cached_font.descriptor == desc && + cached_font.requested_pt_size == style.font_size.to_subpx() && + cached_font.variant == style.font_variant { + fonts.push((*cached_font_ref).clone()); + cache_hit = true; + break; + } + } } } } @@ -156,11 +164,16 @@ impl FontContext { let layout_font = Rc::new(RefCell::new(layout_font)); self.layout_font_cache.push(LayoutFontCacheEntry { family: family.name().to_string(), - font: layout_font.clone(), + font: Some(layout_font.clone()), }); fonts.push(layout_font); } - None => {} + None => { + self.layout_font_cache.push(LayoutFontCacheEntry { + family: family.name().to_string(), + font: None, + }); + } } } } diff --git a/components/gfx/platform/macos/font_list.rs b/components/gfx/platform/macos/font_list.rs index 74e22d0feb9..0974ce3bf46 100644 --- a/components/gfx/platform/macos/font_list.rs +++ b/components/gfx/platform/macos/font_list.rs @@ -23,12 +23,17 @@ pub fn get_variations_for_family(family_name: &str, callback: |String|) { let family_collection = core_text::font_collection::create_for_family(family_name.as_slice()); - let family_descriptors = family_collection.get_descriptors(); - for descref in family_descriptors.iter() { - let descref: CTFontDescriptorRef = unsafe { mem::transmute(descref) }; - let desc: CTFontDescriptor = unsafe { TCFType::wrap_under_get_rule(descref) }; - let postscript_name = desc.font_name(); - callback(postscript_name); + match family_collection { + Some(family_collection) => { + let family_descriptors = family_collection.get_descriptors(); + for descref in family_descriptors.iter() { + let descref: CTFontDescriptorRef = unsafe { mem::transmute(descref) }; + let desc: CTFontDescriptor = unsafe { TCFType::wrap_under_get_rule(descref) }; + let postscript_name = desc.font_name(); + callback(postscript_name); + } + } + None => {} } } diff --git a/components/gfx/render_task.rs b/components/gfx/render_task.rs index 53f50f95102..32c5d97c2b1 100644 --- a/components/gfx/render_task.rs +++ b/components/gfx/render_task.rs @@ -25,14 +25,13 @@ use servo_msg::compositor_msg::{LayerMetadata, RenderListener, RenderingRenderSt use servo_msg::constellation_msg::{ConstellationChan, Failure, FailureMsg, PipelineId}; use servo_msg::constellation_msg::{RendererReadyMsg}; use servo_msg::platform::surface::NativeSurfaceAzureMethods; -use servo_util::geometry::{Au, mod}; +use servo_util::geometry; use servo_util::opts; use servo_util::smallvec::{SmallVec, SmallVec1}; use servo_util::task::spawn_named_with_send_on_failure; use servo_util::time::{TimeProfilerChan, profile}; use servo_util::time; use std::comm::{Receiver, Sender, channel}; -use std::i32; use sync::Arc; use font_cache_task::FontCacheTask; @@ -359,9 +358,8 @@ impl<C:RenderListener + Send> RenderTask<C> { None, self.time_profiler_chan.clone(), || { - let clip_rect = Rect(Point2D(Au(i32::MIN), Au(i32::MIN)), - Size2D(Au(i32::MAX), Au(i32::MAX))); - display_list.draw_into_context(&mut ctx, &matrix, &clip_rect); + let mut clip_stack = Vec::new(); + display_list.draw_into_context(&mut ctx, &matrix, &mut clip_stack); ctx.draw_target.flush(); }); } diff --git a/components/gfx/text/text_run.rs b/components/gfx/text/text_run.rs index cdf7e5c9ddf..4ab5aed94e0 100644 --- a/components/gfx/text/text_run.rs +++ b/components/gfx/text/text_run.rs @@ -162,7 +162,7 @@ impl<'a> TextRun { // Create a glyph store for this slice if it's nonempty. if can_break_before && byte_i > byte_last_boundary { - let slice = text.slice(byte_last_boundary, byte_i).to_string(); + let slice = text.slice(byte_last_boundary, byte_i); debug!("creating glyph store for slice {} (ws? {}), {} - {} in run {}", slice, !cur_slice_is_whitespace, byte_last_boundary, byte_i, text); glyphs.push(GlyphRun { @@ -179,7 +179,7 @@ impl<'a> TextRun { // Create a glyph store for the final slice if it's nonempty. if byte_i > byte_last_boundary { - let slice = text.slice_from(byte_last_boundary).to_string(); + let slice = text.slice_from(byte_last_boundary); debug!("creating glyph store for final slice {} (ws? {}), {} - {} in run {}", slice, cur_slice_is_whitespace, byte_last_boundary, text.len(), text); glyphs.push(GlyphRun { diff --git a/components/gfx/text/util.rs b/components/gfx/text/util.rs index 23b8b029144..3c43b5d9b0f 100644 --- a/components/gfx/text/util.rs +++ b/components/gfx/text/util.rs @@ -17,15 +17,17 @@ pub enum CompressionMode { // High level TODOs: // // * Issue #113: consider incoming text state (arabic, etc) -// and propogate outgoing text state (dual of above) +// and propagate outgoing text state (dual of above) // // * Issue #114: record skipped and kept chars for mapping original to new text // // * Untracked: various edge cases for bidi, CJK, etc. -pub fn transform_text(text: &str, mode: CompressionMode, +pub fn transform_text(text: &str, + mode: CompressionMode, incoming_whitespace: bool, - new_line_pos: &mut Vec<CharIndex>) -> (String, bool) { - let mut out_str = String::new(); + output_text: &mut String, + new_line_pos: &mut Vec<CharIndex>) + -> bool { let out_whitespace = match mode { CompressNone | DiscardNewline => { let mut new_line_index = CharIndex(0); @@ -46,7 +48,7 @@ pub fn transform_text(text: &str, mode: CompressionMode, if ch != '\n' { new_line_index = new_line_index + CharIndex(1); } - out_str.push_char(ch); + output_text.push_char(ch); } } text.len() > 0 && is_in_whitespace(text.char_at_reverse(0), mode) @@ -65,14 +67,14 @@ pub fn transform_text(text: &str, mode: CompressionMode, // TODO: record skipped char } else { // TODO: record kept char - out_str.push_char(ch); + output_text.push_char(ch); } } else { /* next_in_whitespace; possibly add a space char */ if in_whitespace { // TODO: record skipped char } else { // TODO: record kept char - out_str.push_char(' '); + output_text.push_char(' '); } } // save whitespace context for next char @@ -82,7 +84,7 @@ pub fn transform_text(text: &str, mode: CompressionMode, } }; - return (out_str, out_whitespace); + return out_whitespace; fn is_in_whitespace(ch: char, mode: CompressionMode) -> bool { match (ch, mode) { @@ -155,7 +157,8 @@ fn test_transform_compress_none() { for test in test_strs.iter() { let mut new_line_pos = vec!(); - let (trimmed_str, _out) = transform_text(*test, mode, true, &mut new_line_pos); + let mut trimmed_str = String::new(); + transform_text(*test, mode, true, &mut trimmed_str, &mut new_line_pos); assert_eq!(trimmed_str.as_slice(), *test) } } @@ -187,7 +190,8 @@ fn test_transform_discard_newline() { for (test, oracle) in test_strs.iter().zip(oracle_strs.iter()) { let mut new_line_pos = vec!(); - let (trimmed_str, _out) = transform_text(*test, mode, true, &mut new_line_pos); + let mut trimmed_str = String::new(); + transform_text(*test, mode, true, &mut trimmed_str, &mut new_line_pos); assert_eq!(trimmed_str.as_slice(), *oracle) } } @@ -279,7 +283,8 @@ fn test_transform_compress_whitespace_newline_no_incoming() { for (test, oracle) in test_strs.iter().zip(oracle_strs.iter()) { let mut new_line_pos = vec!(); - let (trimmed_str, _out) = transform_text(*test, mode, false, &mut new_line_pos); + let mut trimmed_str = String::new(); + transform_text(*test, mode, false, &mut trimmed_str, &mut new_line_pos); assert_eq!(trimmed_str.as_slice(), *oracle) } } diff --git a/components/layout/construct.rs b/components/layout/construct.rs index c69d04d1d49..ca97d7e36b7 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -28,7 +28,7 @@ use fragment::{InlineBlockFragmentInfo, InputFragment, SpecificFragmentInfo, Tab use fragment::{TableColumnFragment, TableColumnFragmentInfo, TableFragment, TableRowFragment}; use fragment::{TableWrapperFragment, UnscannedTextFragment, UnscannedTextFragmentInfo}; use incremental::RestyleDamage; -use inline::{InlineFragments, InlineFlow}; +use inline::InlineFlow; use parallel; use table_wrapper::TableWrapperFlow; use table::TableFlow; @@ -53,6 +53,7 @@ use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, ProcessingInstruc use script::dom::node::{TextNodeTypeId}; use script::dom::htmlobjectelement::is_image_data; use servo_util::opts; +use std::collections::{DList, Deque}; use std::mem; use std::sync::atomics::Relaxed; use style::ComputedValues; @@ -115,7 +116,7 @@ pub struct InlineFragmentsConstructionResult { pub splits: Vec<InlineBlockSplit>, /// Any fragments that succeed the {ib} splits. - pub fragments: InlineFragments, + pub fragments: DList<Fragment>, /// Any absolute descendants that we're bubbling up. pub abs_descendants: AbsDescendants, @@ -150,7 +151,7 @@ pub struct InlineFragmentsConstructionResult { #[deriving(Clone)] pub struct InlineBlockSplit { /// The inline fragments that precede the flow. - pub predecessors: InlineFragments, + pub predecessors: DList<Fragment>, /// The flow that caused this {ib} split. pub flow: FlowRef, @@ -159,7 +160,7 @@ pub struct InlineBlockSplit { /// Holds inline fragments that we're gathering for children of an inline node. struct InlineFragmentsAccumulator { /// The list of fragments. - fragments: InlineFragments, + fragments: DList<Fragment>, /// Whether we've created a range to enclose all the fragments. This will be Some() if the outer node /// is an inline and None otherwise. @@ -169,20 +170,28 @@ struct InlineFragmentsAccumulator { impl InlineFragmentsAccumulator { fn new() -> InlineFragmentsAccumulator { InlineFragmentsAccumulator { - fragments: InlineFragments::new(), + fragments: DList::new(), enclosing_style: None, } } fn from_inline_node(node: &ThreadSafeLayoutNode) -> InlineFragmentsAccumulator { - let fragments = InlineFragments::new(); + let fragments = DList::new(); InlineFragmentsAccumulator { fragments: fragments, enclosing_style: Some(node.style().clone()), } } - fn finish(self) -> InlineFragments { + fn push_all(&mut self, fragments: DList<Fragment>) { + if fragments.len() == 0 { + return + } + + self.fragments.append(fragments) + } + + fn to_dlist(self) -> DList<Fragment> { let InlineFragmentsAccumulator { fragments: mut fragments, enclosing_style @@ -190,7 +199,7 @@ impl InlineFragmentsAccumulator { match enclosing_style { Some(enclosing_style) => { - for frag in fragments.fragments.iter_mut() { + for frag in fragments.iter_mut() { frag.add_inline_context_style(enclosing_style.clone()); } } @@ -289,7 +298,7 @@ impl<'a> FlowConstructor<'a> { flow_list: &mut Vec<FlowRef>, whitespace_stripping: WhitespaceStrippingMode, node: &ThreadSafeLayoutNode) { - let mut fragments = fragment_accumulator.finish(); + let mut fragments = fragment_accumulator.to_dlist(); if fragments.is_empty() { return }; @@ -298,14 +307,14 @@ impl<'a> FlowConstructor<'a> { NoWhitespaceStripping => {} StripWhitespaceFromStart => { flow::mut_base(flow.deref_mut()).restyle_damage.insert( - fragments.strip_ignorable_whitespace_from_start()); + strip_ignorable_whitespace_from_start(&mut fragments)); if fragments.is_empty() { return }; } StripWhitespaceFromEnd => { flow::mut_base(flow.deref_mut()).restyle_damage.insert( - fragments.strip_ignorable_whitespace_from_end()); + strip_ignorable_whitespace_from_end(&mut fragments)); if fragments.is_empty() { return }; @@ -314,7 +323,7 @@ impl<'a> FlowConstructor<'a> { // Build a list of all the inline-block fragments before fragments is moved. let mut inline_block_flows = vec!(); - for f in fragments.fragments.iter() { + for f in fragments.iter() { match f.specific { InlineBlockFragment(ref info) => inline_block_flows.push(info.flow_ref.clone()), InlineAbsoluteHypotheticalFragment(ref info) => { @@ -324,6 +333,12 @@ impl<'a> FlowConstructor<'a> { } } + // We must scan for runs before computing minimum ascent and descent because scanning + // for runs might collapse so much whitespace away that only hypothetical fragments + // remain. In that case the inline flow will compute its ascent and descent to be zero. + let fragments = TextRunScanner::new().scan_for_runs(self.layout_context.font_context(), + fragments); + let mut inline_flow_ref = FlowRef::new(box InlineFlow::from_fragments((*node).clone(), fragments)); @@ -335,10 +350,6 @@ impl<'a> FlowConstructor<'a> { { let inline_flow = inline_flow_ref.as_inline(); - // We must scan for runs before computing minimum ascent and descent because scanning - // for runs might collapse so much whitespace away that only hypothetical fragments - // remain. In that case the inline flow will compute its ascent and descent to be zero. - TextRunScanner::new().scan_for_runs(self.layout_context.font_context(), inline_flow); let (ascent, descent) = inline_flow.compute_minimum_ascent_and_descent(self.layout_context.font_context(), @@ -409,7 +420,7 @@ impl<'a> FlowConstructor<'a> { predecessors: predecessors, flow: kid_flow } = split; - inline_fragment_accumulator.fragments.push_all(predecessors); + inline_fragment_accumulator.push_all(predecessors); // If this is the first fragment in flow, then strip ignorable // whitespace per CSS 2.1 § 9.2.1.1. @@ -441,7 +452,7 @@ impl<'a> FlowConstructor<'a> { } // Add the fragments to the list we're maintaining. - inline_fragment_accumulator.fragments.push_all(successor_fragments); + inline_fragment_accumulator.push_all(successor_fragments); abs_descendants.push_descendants(kid_abs_descendants); } ConstructionItemConstructionResult(WhitespaceConstructionItem(whitespace_node, @@ -451,11 +462,11 @@ impl<'a> FlowConstructor<'a> { // between block elements, and retained when between inline elements. let fragment_info = UnscannedTextFragment(UnscannedTextFragmentInfo::from_text(" ".to_string())); - let mut fragment = Fragment::from_opaque_node_and_style(whitespace_node, - whitespace_style, - whitespace_damage, - fragment_info); - inline_fragment_accumulator.fragments.push(&mut fragment); + let fragment = Fragment::from_opaque_node_and_style(whitespace_node, + whitespace_style, + whitespace_damage, + fragment_info); + inline_fragment_accumulator.fragments.push(fragment); } ConstructionItemConstructionResult(TableColumnFragmentConstructionItem(_)) => { // TODO: Implement anonymous table objects for missing parents @@ -483,8 +494,8 @@ impl<'a> FlowConstructor<'a> { if node.get_pseudo_element_type() != Normal || node.type_id() == Some(ElementNodeTypeId(HTMLInputElementTypeId)) { let fragment_info = UnscannedTextFragment(UnscannedTextFragmentInfo::new(node)); - let mut fragment = Fragment::new_from_specific_info(node, fragment_info); - inline_fragment_accumulator.fragments.push(&mut fragment); + let fragment = Fragment::new_from_specific_info(node, fragment_info); + inline_fragment_accumulator.fragments.push(fragment); first_fragment = false; } @@ -577,7 +588,7 @@ impl<'a> FlowConstructor<'a> { predecessors: mem::replace( &mut fragment_accumulator, - InlineFragmentsAccumulator::from_inline_node(node)).finish(), + InlineFragmentsAccumulator::from_inline_node(node)).to_dlist(), flow: flow, }; opt_inline_block_splits.push(split); @@ -596,32 +607,34 @@ impl<'a> FlowConstructor<'a> { predecessors: predecessors, flow: kid_flow } = split; - fragment_accumulator.fragments.push_all(predecessors); + fragment_accumulator.push_all(predecessors); let split = InlineBlockSplit { predecessors: mem::replace(&mut fragment_accumulator, InlineFragmentsAccumulator::from_inline_node(node)) - .finish(), + .to_dlist(), flow: kid_flow, }; opt_inline_block_splits.push(split) } // Push residual fragments. - fragment_accumulator.fragments.push_all(successors); + fragment_accumulator.push_all(successors); abs_descendants.push_descendants(kid_abs_descendants); } - ConstructionItemConstructionResult(WhitespaceConstructionItem(whitespace_node, - whitespace_style, - whitespace_damage)) => { + ConstructionItemConstructionResult(WhitespaceConstructionItem( + whitespace_node, + whitespace_style, + whitespace_damage)) => { // Instantiate the whitespace fragment. - let fragment_info = UnscannedTextFragment(UnscannedTextFragmentInfo::from_text(" ".to_string())); - let mut fragment = Fragment::from_opaque_node_and_style(whitespace_node, + let fragment_info = UnscannedTextFragment(UnscannedTextFragmentInfo::from_text( + " ".to_string())); + let fragment = Fragment::from_opaque_node_and_style(whitespace_node, whitespace_style, whitespace_damage, fragment_info); - fragment_accumulator.fragments.push(&mut fragment) + fragment_accumulator.fragments.push(fragment) } ConstructionItemConstructionResult(TableColumnFragmentConstructionItem(_)) => { // TODO: Implement anonymous table objects for missing parents @@ -636,7 +649,7 @@ impl<'a> FlowConstructor<'a> { let construction_item = InlineFragmentsConstructionItem( InlineFragmentsConstructionResult { splits: opt_inline_block_splits, - fragments: fragment_accumulator.finish(), + fragments: fragment_accumulator.to_dlist(), abs_descendants: abs_descendants, }); ConstructionItemConstructionResult(construction_item) @@ -668,15 +681,15 @@ impl<'a> FlowConstructor<'a> { // If this is generated content, then we need to initialize the accumulator with the // fragment corresponding to that content. Otherwise, just initialize with the ordinary // fragment that needs to be generated for this inline node. - let mut fragment = if node.get_pseudo_element_type() != Normal { + let fragment = if node.get_pseudo_element_type() != Normal { let fragment_info = UnscannedTextFragment(UnscannedTextFragmentInfo::new(node)); Fragment::new_from_specific_info(node, fragment_info) } else { Fragment::new(self, node) }; - let mut fragments = InlineFragments::new(); - fragments.push(&mut fragment); + let mut fragments = DList::new(); + fragments.push(fragment); let construction_item = InlineFragmentsConstructionItem(InlineFragmentsConstructionResult { splits: Vec::new(), @@ -695,14 +708,14 @@ impl<'a> FlowConstructor<'a> { }; let fragment_info = InlineBlockFragment(InlineBlockFragmentInfo::new(block_flow)); - let mut fragment = Fragment::new_from_specific_info(node, fragment_info); + let fragment = Fragment::new_from_specific_info(node, fragment_info); let mut fragment_accumulator = InlineFragmentsAccumulator::from_inline_node(node); - fragment_accumulator.fragments.push(&mut fragment); + fragment_accumulator.fragments.push(fragment); let construction_item = InlineFragmentsConstructionItem(InlineFragmentsConstructionResult { splits: Vec::new(), - fragments: fragment_accumulator.finish(), + fragments: fragment_accumulator.to_dlist(), abs_descendants: abs_descendants, }); ConstructionItemConstructionResult(construction_item) @@ -720,14 +733,14 @@ impl<'a> FlowConstructor<'a> { let fragment_info = InlineAbsoluteHypotheticalFragment( InlineAbsoluteHypotheticalFragmentInfo::new(block_flow)); - let mut fragment = Fragment::new_from_specific_info(node, fragment_info); + let fragment = Fragment::new_from_specific_info(node, fragment_info); let mut fragment_accumulator = InlineFragmentsAccumulator::from_inline_node(node); - fragment_accumulator.fragments.push(&mut fragment); + fragment_accumulator.fragments.push(fragment); let construction_item = InlineFragmentsConstructionItem(InlineFragmentsConstructionResult { splits: Vec::new(), - fragments: fragment_accumulator.finish(), + fragments: fragment_accumulator.to_dlist(), abs_descendants: abs_descendants, }); ConstructionItemConstructionResult(construction_item) @@ -1217,3 +1230,38 @@ impl FlowConstructionUtils for FlowRef { } } } + +/// Strips ignorable whitespace from the start of a list of fragments. +/// +/// Returns some damage that must be added to the `InlineFlow`. +pub fn strip_ignorable_whitespace_from_start(this: &mut DList<Fragment>) -> RestyleDamage { + if this.is_empty() { + return RestyleDamage::empty() // Fast path. + } + + let mut damage = RestyleDamage::empty(); + while !this.is_empty() && this.front().as_ref().unwrap().is_ignorable_whitespace() { + debug!("stripping ignorable whitespace from start"); + damage = RestyleDamage::all(); + drop(this.pop_front()); + } + damage +} + +/// Strips ignorable whitespace from the end of a list of fragments. +/// +/// Returns some damage that must be added to the `InlineFlow`. +pub fn strip_ignorable_whitespace_from_end(this: &mut DList<Fragment>) -> RestyleDamage { + if this.is_empty() { + return RestyleDamage::empty(); + } + + let mut damage = RestyleDamage::empty(); + while !this.is_empty() && this.back().as_ref().unwrap().is_ignorable_whitespace() { + debug!("stripping ignorable whitespace from end"); + damage = RestyleDamage::all(); + drop(this.pop()); + } + damage +} + diff --git a/components/layout/flow.rs b/components/layout/flow.rs index aa434d63b1e..269aac1b81d 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -1022,7 +1022,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a { indent.push_str("| ") } - error!("{}+ {}", indent, self.to_string()); + println!("{}+ {}", indent, self.to_string()); for kid in imm_child_iter(self) { kid.dump_with_level(level + 1) diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 56b14754ca6..80d6c68be2a 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -42,6 +42,7 @@ use servo_net::local_image_cache::LocalImageCache; use servo_util::geometry::{Au, ZERO_RECT}; use servo_util::geometry; use servo_util::logical_geometry::{LogicalRect, LogicalSize, LogicalMargin, WritingMode}; +use servo_util::opts; use servo_util::range::*; use servo_util::smallvec::SmallVec; use servo_util::str::is_whitespace; @@ -386,7 +387,8 @@ pub struct ScannedTextFragmentInfo { impl ScannedTextFragmentInfo { /// Creates the information specific to a scanned text fragment from a range and a text run. - pub fn new(run: Arc<Box<TextRun>>, range: Range<CharIndex>, content_inline_size: Au) -> ScannedTextFragmentInfo { + pub fn new(run: Arc<Box<TextRun>>, range: Range<CharIndex>, content_inline_size: Au) + -> ScannedTextFragmentInfo { ScannedTextFragmentInfo { run: run, range: range, @@ -509,7 +511,9 @@ impl Fragment { } /// Constructs a new `Fragment` instance for an anonymous table object. - pub fn new_anonymous_table_fragment(node: &ThreadSafeLayoutNode, specific: SpecificFragmentInfo) -> Fragment { + pub fn new_anonymous_table_fragment(node: &ThreadSafeLayoutNode, + specific: SpecificFragmentInfo) + -> Fragment { // CSS 2.1 § 17.2.1 This is for non-inherited properties on anonymous table fragments // example: // @@ -517,7 +521,8 @@ impl Fragment { // Foo // </div> // - // Anonymous table fragments, TableRowFragment and TableCellFragment, are generated around `Foo`, but it shouldn't inherit the border. + // Anonymous table fragments, TableRowFragment and TableCellFragment, are generated around + // `Foo`, but they shouldn't inherit the border. let node_style = cascade_anonymous(&**node.style()); let writing_mode = node_style.writing_mode; @@ -587,14 +592,14 @@ impl Fragment { } } - /// Returns a debug ID of this fragment. This ID should not be considered stable across multiple - /// layouts or fragment manipulations. + /// Returns a debug ID of this fragment. This ID should not be considered stable across + /// multiple layouts or fragment manipulations. pub fn debug_id(&self) -> uint { self.debug_id } - /// Transforms this fragment into another fragment of the given type, with the given size, preserving all - /// the other data. + /// Transforms this fragment into another fragment of the given type, with the given size, + /// preserving all the other data. pub fn transform(&self, size: LogicalSize<Au>, mut info: ScannedTextFragmentInfo) -> Fragment { let new_border_box = LogicalRect::from_point_size(self.style.writing_mode, self.border_box.start, size); @@ -1335,24 +1340,21 @@ impl Fragment { }); } - // Draw debug frames for text bounds. - // - // FIXME(#2263, pcwalton): This is a bit of an abuse of the logging infrastructure. - // We should have a real `SERVO_DEBUG` system. - debug!("{:?}", self.build_debug_borders_around_text_fragments(display_list, - flow_origin, - text_fragment, - clip_rect)) + if opts::get().show_debug_fragment_borders { + self.build_debug_borders_around_text_fragments(display_list, + flow_origin, + text_fragment, + clip_rect); + } } GenericFragment | IframeFragment(..) | TableFragment | TableCellFragment | TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) | InputFragment | InlineAbsoluteHypotheticalFragment(_) => { - // FIXME(pcwalton): This is a bit of an abuse of the logging infrastructure. We - // should have a real `SERVO_DEBUG` system. - debug!("{:?}", - self.build_debug_borders_around_fragment(display_list, - flow_origin, - clip_rect)) + if opts::get().show_debug_fragment_borders { + self.build_debug_borders_around_fragment(display_list, + flow_origin, + clip_rect); + } } ImageFragment(ref mut image_fragment) => { let image_ref = &mut image_fragment.image; diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 0babaa46234..bdfc9474fe7 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -11,7 +11,6 @@ use flow::{BaseFlow, FlowClass, Flow, InlineFlowClass, MutableFlowUtils}; use flow; use fragment::{Fragment, InlineAbsoluteHypotheticalFragment, InlineBlockFragment}; use fragment::{ScannedTextFragment, ScannedTextFragmentInfo, SplitInfo}; -use incremental::RestyleDamage; use layout_debug; use model::IntrinsicISizesContribution; use text; @@ -620,57 +619,6 @@ impl InlineFragments { self.fragments.get_mut(index) } - /// Strips ignorable whitespace from the start of a list of fragments. - /// - /// Returns some damage that must be added to the `InlineFlow`. - pub fn strip_ignorable_whitespace_from_start(&mut self) -> RestyleDamage { - if self.is_empty() { return RestyleDamage::empty() } // Fast path - - // FIXME (rust#16151): This can be reverted back to using skip_while once - // the upstream bug is fixed. - let mut fragments = mem::replace(&mut self.fragments, vec![]).into_iter(); - let mut new_fragments = Vec::new(); - let mut skipping = true; - let mut damage = RestyleDamage::empty(); - - for fragment in fragments { - if skipping && fragment.is_ignorable_whitespace() { - damage = RestyleDamage::all(); - debug!("stripping ignorable whitespace from start"); - continue - } - - skipping = false; - new_fragments.push(fragment); - } - - self.fragments = new_fragments; - damage - } - - /// Strips ignorable whitespace from the end of a list of fragments. - /// - /// Returns some damage that must be added to the `InlineFlow`. - pub fn strip_ignorable_whitespace_from_end(&mut self) -> RestyleDamage { - if self.is_empty() { - return RestyleDamage::empty(); - } - - let mut damage = RestyleDamage::empty(); - - let mut new_fragments = self.fragments.clone(); - while new_fragments.len() > 0 && - new_fragments.as_slice().last().as_ref().unwrap().is_ignorable_whitespace() { - debug!("stripping ignorable whitespace from end"); - damage = RestyleDamage::all(); - drop(new_fragments.pop()); - } - - - self.fragments = new_fragments; - damage - } - /// This function merges previously-line-broken fragments back into their /// original, pre-line-breaking form. pub fn merge_broken_lines(&mut self) { diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index fbd840fdd9c..114f9b85e84 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -580,7 +580,7 @@ impl LayoutTask { let current_screen_size = Size2D(Au::from_frac32_px(viewport_size.width.get()), Au::from_frac32_px(viewport_size.height.get())); - let old_screen_size = mem::replace(&mut rw_data.screen_size, current_screen_size); + rw_data.screen_size = current_screen_size; // Create a layout context for use throughout the following passes. let mut shared_layout_ctx = @@ -591,8 +591,6 @@ impl LayoutTask { // Handle conditions where the entire flow tree is invalid. let mut needs_dirtying = false; - - needs_dirtying |= current_screen_size != old_screen_size; needs_dirtying |= rw_data.stylesheet_dirty; unsafe { diff --git a/components/layout/text.rs b/components/layout/text.rs index 19338d4c021..da5fd549697 100644 --- a/components/layout/text.rs +++ b/components/layout/text.rs @@ -6,78 +6,67 @@ #![deny(unsafe_block)] -use flow::Flow; use fragment::{Fragment, ScannedTextFragmentInfo, UnscannedTextFragment}; +use inline::InlineFragments; use gfx::font::{FontMetrics,RunMetrics}; use gfx::font_context::FontContext; use gfx::text::glyph::CharIndex; use gfx::text::text_run::TextRun; -use gfx::text::util::{CompressWhitespaceNewline, transform_text, CompressNone}; +use gfx::text::util::{mod, CompressWhitespaceNewline, CompressNone}; +use servo_util::dlist; use servo_util::geometry::Au; use servo_util::logical_geometry::{LogicalSize, WritingMode}; use servo_util::range::Range; -use servo_util::smallvec::SmallVec; +use servo_util::smallvec::{SmallVec, SmallVec1}; +use std::collections::{DList, Deque}; +use std::mem; use style::ComputedValues; use style::computed_values::{line_height, text_orientation, white_space}; use style::style_structs::Font as FontStyle; use sync::Arc; -struct NewLinePositions { - new_line_pos: Vec<CharIndex>, -} - -// A helper function. -fn can_coalesce_text_nodes(fragments: &[Fragment], left_i: uint, right_i: uint) -> bool { - assert!(left_i != right_i); - fragments[left_i].can_merge_with_fragment(&fragments[right_i]) -} - /// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextFragment`s. pub struct TextRunScanner { - pub clump: Range<CharIndex>, + pub clump: DList<Fragment>, } impl TextRunScanner { pub fn new() -> TextRunScanner { TextRunScanner { - clump: Range::empty(), + clump: DList::new(), } } - pub fn scan_for_runs(&mut self, font_context: &mut FontContext, flow: &mut Flow) { - { - let inline = flow.as_immutable_inline(); - debug!("TextRunScanner: scanning {:u} fragments for text runs...", inline.fragments.len()); - } - - let fragments = &mut flow.as_inline().fragments; + pub fn scan_for_runs(&mut self, font_context: &mut FontContext, mut fragments: DList<Fragment>) + -> InlineFragments { + debug!("TextRunScanner: scanning {:u} fragments for text runs...", fragments.len()); + // FIXME(pcwalton): We want to be sure not to allocate multiple times, since this is a + // performance-critical spot, but this may overestimate and allocate too much memory. + let mut new_fragments = Vec::with_capacity(fragments.len()); let mut last_whitespace = true; - let mut new_fragments = Vec::new(); - for fragment_i in range(0, fragments.fragments.len()) { - debug!("TextRunScanner: considering fragment: {:u}", fragment_i); - if fragment_i > 0 && !can_coalesce_text_nodes(fragments.fragments.as_slice(), fragment_i - 1, fragment_i) { - last_whitespace = self.flush_clump_to_list(font_context, - fragments.fragments.as_slice(), - &mut new_fragments, - last_whitespace); + while !fragments.is_empty() { + // Create a clump. + self.clump.append(dlist::split(&mut fragments)); + while !fragments.is_empty() && self.clump + .back() + .unwrap() + .can_merge_with_fragment(fragments.front() + .unwrap()) { + self.clump.append(dlist::split(&mut fragments)); } - self.clump.extend_by(CharIndex(1)); + // Flush that clump to the list of fragments we're building up. + last_whitespace = self.flush_clump_to_list(font_context, + &mut new_fragments, + last_whitespace); } - // Handle remaining clumps. - if self.clump.length() > CharIndex(0) { - drop(self.flush_clump_to_list(font_context, - fragments.fragments.as_slice(), - &mut new_fragments, - last_whitespace)) + debug!("TextRunScanner: complete."); + InlineFragments { + fragments: new_fragments, } - - debug!("TextRunScanner: swapping out fragments."); - - fragments.fragments = new_fragments; } /// A "clump" is a range of inline flow leaves that can be merged together into a single @@ -86,178 +75,109 @@ impl TextRunScanner { /// The flow keeps track of the fragments contained by all non-leaf DOM nodes. This is necessary /// for correct painting order. Since we compress several leaf fragments here, the mapping must /// be adjusted. - /// - /// FIXME(#2267, pcwalton): Stop cloning fragments. Instead we will need to replace each - /// `in_fragment` with some smaller stub. fn flush_clump_to_list(&mut self, font_context: &mut FontContext, - in_fragments: &[Fragment], out_fragments: &mut Vec<Fragment>, - last_whitespace: bool) + mut last_whitespace: bool) -> bool { - assert!(self.clump.length() > CharIndex(0)); - - debug!("TextRunScanner: flushing fragments in range={}", self.clump); - let is_singleton = self.clump.length() == CharIndex(1); - - let is_text_clump = match in_fragments[self.clump.begin().to_uint()].specific { - UnscannedTextFragment(_) => true, - _ => false, - }; - - let mut new_whitespace = last_whitespace; - match (is_singleton, is_text_clump) { - (false, false) => { - fail!("WAT: can't coalesce non-text nodes in flush_clump_to_list()!") + debug!("TextRunScanner: flushing {} fragments in range", self.clump.len()); + + debug_assert!(!self.clump.is_empty()); + match self.clump.front().unwrap().specific { + UnscannedTextFragment(_) => {} + _ => { + debug_assert!(self.clump.len() == 1, + "WAT: can't coalesce non-text nodes in flush_clump_to_list()!"); + out_fragments.push(self.clump.pop_front().unwrap()); + return last_whitespace } - (true, false) => { - // FIXME(pcwalton): Stop cloning fragments, as above. - debug!("TextRunScanner: pushing single non-text fragment in range: {}", self.clump); - let new_fragment = in_fragments[self.clump.begin().to_uint()].clone(); - out_fragments.push(new_fragment) - }, - (true, true) => { - let old_fragment = &in_fragments[self.clump.begin().to_uint()]; - let text = match old_fragment.specific { - UnscannedTextFragment(ref text_fragment_info) => &text_fragment_info.text, - _ => fail!("Expected an unscanned text fragment!"), - }; - - let font_style = old_fragment.style().get_font(); - - let compression = match old_fragment.white_space() { - white_space::normal | white_space::nowrap => CompressWhitespaceNewline, - white_space::pre => CompressNone, - }; - - let mut new_line_pos = vec![]; - - let (transformed_text, whitespace) = transform_text(text.as_slice(), - compression, - last_whitespace, - &mut new_line_pos); - - new_whitespace = whitespace; - - if transformed_text.len() > 0 { - // TODO(#177): Text run creation must account for the renderability of text by - // font group fonts. This is probably achieved by creating the font group above - // and then letting `FontGroup` decide which `Font` to stick into the text run. - let fontgroup = font_context.get_layout_font_group_for_style(font_style); - let run = box fontgroup.create_textrun( - transformed_text.clone()); + } - debug!("TextRunScanner: pushing single text fragment in range: {} ({})", - self.clump, - *text); - let range = Range::new(CharIndex(0), run.char_len()); - let new_metrics = run.metrics_for_range(&range); - let bounding_box_size = bounding_box_for_run_metrics( - &new_metrics, old_fragment.style.writing_mode); - let new_text_fragment_info = - ScannedTextFragmentInfo::new(Arc::new(run), range, old_fragment.border_box.size.inline); - let mut new_fragment = old_fragment.transform(bounding_box_size, new_text_fragment_info); - new_fragment.new_line_pos = new_line_pos; - out_fragments.push(new_fragment) - } - }, - (false, true) => { - // TODO(#177): Text run creation must account for the renderability of text by - // font group fonts. This is probably achieved by creating the font group above - // and then letting `FontGroup` decide which `Font` to stick into the text run. - let in_fragment = &in_fragments[self.clump.begin().to_uint()]; + // TODO(#177): Text run creation must account for the renderability of text by font group + // fonts. This is probably achieved by creating the font group above and then letting + // `FontGroup` decide which `Font` to stick into the text run. + // + // Concatenate all of the transformed strings together, saving the new character indices. + let mut new_ranges: SmallVec1<Range<CharIndex>> = SmallVec1::new(); + let mut new_line_positions: SmallVec1<NewLinePositions> = SmallVec1::new(); + let mut char_total = CharIndex(0); + let run = { + let fontgroup; + let compression; + { + let in_fragment = self.clump.front().unwrap(); let font_style = in_fragment.style().get_font(); - let fontgroup = font_context.get_layout_font_group_for_style(font_style); - - let compression = match in_fragment.white_space() { + fontgroup = font_context.get_layout_font_group_for_style(font_style); + compression = match in_fragment.white_space() { white_space::normal | white_space::nowrap => CompressWhitespaceNewline, white_space::pre => CompressNone, - }; - - let mut new_line_positions: Vec<NewLinePositions> = vec![]; - - // First, transform/compress text of all the nodes. - let mut last_whitespace_in_clump = new_whitespace; - let transformed_strs: Vec<String> = Vec::from_fn(self.clump.length().to_uint(), |i| { - let idx = CharIndex(i as int) + self.clump.begin(); - let in_fragment = match in_fragments[idx.to_uint()].specific { - UnscannedTextFragment(ref text_fragment_info) => &text_fragment_info.text, - _ => fail!("Expected an unscanned text fragment!"), - }; - - let mut new_line_pos = vec![]; - - let (new_str, new_whitespace) = transform_text(in_fragment.as_slice(), - compression, - last_whitespace_in_clump, - &mut new_line_pos); - new_line_positions.push(NewLinePositions { new_line_pos: new_line_pos }); - - last_whitespace_in_clump = new_whitespace; - new_str - }); - new_whitespace = last_whitespace_in_clump; - - // Next, concatenate all of the transformed strings together, saving the new - // character indices. - let mut run_str = String::new(); - - let mut new_ranges: Vec<Range<CharIndex>> = - Vec::with_capacity(transformed_strs.len()); - - let mut char_total = CharIndex(0); - for i in range(0, transformed_strs.len() as int) { - let added_chars = CharIndex(transformed_strs[i as uint].as_slice().char_len() as int); - new_ranges.push(Range::new(char_total, added_chars)); - run_str.push_str(transformed_strs[i as uint].as_slice()); - char_total = char_total + added_chars; } + } - // Now create the run. - // TextRuns contain a cycle which is usually resolved by the teardown - // sequence. If no clump takes ownership, however, it will leak. - let clump = self.clump; - let run = if clump.length() != CharIndex(0) && run_str.len() > 0 { - Some(Arc::new(box TextRun::new(&mut *fontgroup.fonts.get(0).borrow_mut(), - run_str.to_string()))) - } else { - None + // First, transform/compress text of all the nodes. + let mut run_text = String::new(); + for in_fragment in self.clump.iter() { + let in_fragment = match in_fragment.specific { + UnscannedTextFragment(ref text_fragment_info) => &text_fragment_info.text, + _ => fail!("Expected an unscanned text fragment!"), }; - // Make new fragments with the run and adjusted text indices. - debug!("TextRunScanner: pushing fragment(s) in range: {}", self.clump); - for i in clump.each_index() { - let logical_offset = i - self.clump.begin(); - let range = new_ranges[logical_offset.to_uint()]; - if range.length() == CharIndex(0) { - debug!("Elided an `UnscannedTextFragment` because it was zero-length after \ - compression; {}", in_fragments[i.to_uint()]); - continue - } + let mut new_line_pos = Vec::new(); + let old_length = CharIndex(run_text.as_slice().char_len() as int); + last_whitespace = util::transform_text(in_fragment.as_slice(), + compression, + last_whitespace, + &mut run_text, + &mut new_line_pos); + new_line_positions.push(NewLinePositions(new_line_pos)); + + let added_chars = CharIndex(run_text.as_slice().char_len() as int) - old_length; + new_ranges.push(Range::new(char_total, added_chars)); + char_total = char_total + added_chars; + } - let old_fragment = &in_fragments[i.to_uint()]; - let new_text_fragment_info = - ScannedTextFragmentInfo::new( - run.as_ref().unwrap().clone(), - range, - old_fragment.border_box.size.inline); - let new_metrics = new_text_fragment_info.run.metrics_for_range(&range); - let bounding_box_size = bounding_box_for_run_metrics( - &new_metrics, old_fragment.style.writing_mode); - let mut new_fragment = old_fragment.transform(bounding_box_size, new_text_fragment_info); - new_fragment.new_line_pos = new_line_positions[logical_offset.to_uint()].new_line_pos.clone(); - out_fragments.push(new_fragment) - } + // Now create the run. + // + // TextRuns contain a cycle which is usually resolved by the teardown sequence. + // If no clump takes ownership, however, it will leak. + if run_text.len() == 0 { + self.clump = DList::new(); + return last_whitespace + } + Arc::new(box TextRun::new(&mut *fontgroup.fonts.get(0).borrow_mut(), run_text)) + }; + + // Make new fragments with the run and adjusted text indices. + debug!("TextRunScanner: pushing {} fragment(s)", self.clump.len()); + for (logical_offset, old_fragment) in + mem::replace(&mut self.clump, DList::new()).into_iter().enumerate() { + let range = *new_ranges.get(logical_offset); + if range.is_empty() { + debug!("Elided an `UnscannedTextFragment` because it was zero-length after \ + compression; {}", + old_fragment); + continue } - } // End of match. - let end = self.clump.end(); // FIXME: borrow checker workaround - self.clump.reset(end, CharIndex(0)); + let text_inline_size = old_fragment.border_box.size.inline; + let new_text_fragment_info = + ScannedTextFragmentInfo::new(run.clone(), range, text_inline_size); + let new_metrics = new_text_fragment_info.run.metrics_for_range(&range); + let bounding_box_size = bounding_box_for_run_metrics(&new_metrics, + old_fragment.style.writing_mode); + let mut new_fragment = old_fragment.transform(bounding_box_size, + new_text_fragment_info); + let &NewLinePositions(ref mut new_line_positions) = + new_line_positions.get_mut(logical_offset); + new_fragment.new_line_pos = mem::replace(new_line_positions, Vec::new()); + out_fragments.push(new_fragment) + } - new_whitespace - } // End of `flush_clump_to_list`. + last_whitespace + } } +struct NewLinePositions(Vec<CharIndex>); #[inline] fn bounding_box_for_run_metrics(metrics: &RunMetrics, writing_mode: WritingMode) @@ -303,3 +223,5 @@ pub fn line_height_from_style(style: &ComputedValues, metrics: &FontMetrics) -> line_height::Length(l) => l } } + + diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index c4085522692..3abc146e496 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -36,8 +36,9 @@ use util::{LayoutDataAccess, LayoutDataWrapper, PrivateLayoutData, OpaqueNodeMet use gfx::display_list::OpaqueNode; use script::dom::bindings::cell::{Ref, RefMut}; -use script::dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElementCast, HTMLImageElementCast}; -use script::dom::bindings::codegen::InheritTypes::{HTMLInputElementCast, TextCast}; +use script::dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElementCast}; +use script::dom::bindings::codegen::InheritTypes::{HTMLImageElementCast, HTMLInputElementCast}; +use script::dom::bindings::codegen::InheritTypes::{TextCast}; use script::dom::bindings::js::JS; use script::dom::element::{Element, HTMLAreaElementTypeId, HTMLAnchorElementTypeId}; use script::dom::element::{HTMLLinkElementTypeId, LayoutElementHelpers, RawLayoutElementHelpers}; @@ -213,28 +214,36 @@ impl<'ln> LayoutNode<'ln> { } } - /// Iterates over this node and all its descendants, in preorder. - /// - /// FIXME(pcwalton): Terribly inefficient. We should use parallelism. pub fn traverse_preorder(self) -> LayoutTreeIterator<'ln> { - let mut nodes = vec!(); - gather_layout_nodes(self, &mut nodes, false); - LayoutTreeIterator::new(nodes) + LayoutTreeIterator::new(self) + } + + fn last_child(self) -> Option<LayoutNode<'ln>> { + unsafe { + self.get_jsmanaged().last_child_ref().map(|node| self.new_with_this_lifetime(&node)) + } } /// Returns an iterator over this node's children. pub fn children(self) -> LayoutNodeChildrenIterator<'ln> { // FIXME(zwarich): Remove this when UFCS lands and there is a better way // of disambiguating methods. - fn first_child<T: TLayoutNode>(this: &T) -> Option<T> { + fn first_child<T: TLayoutNode>(this: T) -> Option<T> { this.first_child() } LayoutNodeChildrenIterator { - current_node: first_child(&self), + current: first_child(self), } } + pub fn rev_children(self) -> LayoutNodeReverseChildrenIterator<'ln> { + LayoutNodeReverseChildrenIterator { + current: self.last_child() + } + + } + pub unsafe fn get_jsmanaged<'a>(&'a self) -> &'a JS<Node> { &self.node } @@ -290,6 +299,12 @@ impl<'ln> TNode<'ln, LayoutElement<'ln>> for LayoutNode<'ln> { } } + fn last_child(self) -> Option<LayoutNode<'ln>> { + unsafe { + self.node.last_child_ref().map(|node| self.new_with_this_lifetime(&node)) + } + } + fn prev_sibling(self) -> Option<LayoutNode<'ln>> { unsafe { self.node.prev_sibling_ref().map(|node| self.new_with_this_lifetime(&node)) @@ -389,59 +404,48 @@ impl<'ln> TNode<'ln, LayoutElement<'ln>> for LayoutNode<'ln> { } pub struct LayoutNodeChildrenIterator<'a> { - current_node: Option<LayoutNode<'a>>, + current: Option<LayoutNode<'a>>, } impl<'a> Iterator<LayoutNode<'a>> for LayoutNodeChildrenIterator<'a> { fn next(&mut self) -> Option<LayoutNode<'a>> { - let node = self.current_node.clone(); - self.current_node = node.clone().and_then(|node| { - node.next_sibling() - }); + let node = self.current; + self.current = node.and_then(|node| node.next_sibling()); + node + } +} + +pub struct LayoutNodeReverseChildrenIterator<'a> { + current: Option<LayoutNode<'a>>, +} + +impl<'a> Iterator<LayoutNode<'a>> for LayoutNodeReverseChildrenIterator<'a> { + fn next(&mut self) -> Option<LayoutNode<'a>> { + let node = self.current; + self.current = node.and_then(|node| node.prev_sibling()); node } } -// FIXME: Do this without precomputing a vector of refs. -// Easy for preorder; harder for postorder. -// -// FIXME(pcwalton): Parallelism! Eventually this should just be nuked. pub struct LayoutTreeIterator<'a> { - nodes: Vec<LayoutNode<'a>>, - index: uint, + stack: Vec<LayoutNode<'a>>, } impl<'a> LayoutTreeIterator<'a> { - fn new(nodes: Vec<LayoutNode<'a>>) -> LayoutTreeIterator<'a> { + fn new(root: LayoutNode<'a>) -> LayoutTreeIterator<'a> { + let mut stack = vec!(); + stack.push(root); LayoutTreeIterator { - nodes: nodes, - index: 0, + stack: stack } } } impl<'a> Iterator<LayoutNode<'a>> for LayoutTreeIterator<'a> { fn next(&mut self) -> Option<LayoutNode<'a>> { - if self.index >= self.nodes.len() { - None - } else { - let v = self.nodes[self.index].clone(); - self.index += 1; - Some(v) - } - } -} - -/// FIXME(pcwalton): This is super inefficient. -fn gather_layout_nodes<'a>(cur: LayoutNode<'a>, refs: &mut Vec<LayoutNode<'a>>, postorder: bool) { - if !postorder { - refs.push(cur.clone()); - } - for kid in cur.children() { - gather_layout_nodes(kid, refs, postorder) - } - if postorder { - refs.push(cur.clone()); + let ret = self.stack.pop(); + ret.map(|node| self.stack.extend(node.rev_children())); + ret } } @@ -498,6 +502,7 @@ impl<'le> TElement<'le> for LayoutElement<'le> { } } + #[inline] fn get_hover_state(self) -> bool { unsafe { self.element.node().get_hover_state_for_layout() @@ -511,18 +516,21 @@ impl<'le> TElement<'le> for LayoutElement<'le> { } } + #[inline] fn get_disabled_state(self) -> bool { unsafe { self.element.node().get_disabled_state_for_layout() } } + #[inline] fn get_enabled_state(self) -> bool { unsafe { self.element.node().get_enabled_state_for_layout() } } + #[inline] fn has_class(self, name: &Atom) -> bool { unsafe { self.element.has_class_for_layout(name) @@ -735,10 +743,12 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { } } + #[inline] pub fn get_pseudo_element_type(&self) -> PseudoElementType { self.pseudo } + #[inline] pub fn get_normal_display(&self) -> display::T { let mut layout_data_ref = self.mutate_layout_data(); let node_layout_data_wrapper = layout_data_ref.as_mut().unwrap(); @@ -746,6 +756,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { style.get_box().display } + #[inline] pub fn get_before_display(&self) -> display::T { let mut layout_data_ref = self.mutate_layout_data(); let node_layout_data_wrapper = layout_data_ref.as_mut().unwrap(); @@ -753,6 +764,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { style.get_box().display } + #[inline] pub fn get_after_display(&self) -> display::T { let mut layout_data_ref = self.mutate_layout_data(); let node_layout_data_wrapper = layout_data_ref.as_mut().unwrap(); @@ -760,12 +772,14 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { style.get_box().display } + #[inline] pub fn has_before_pseudo(&self) -> bool { let layout_data_wrapper = self.borrow_layout_data(); let layout_data_wrapper_ref = layout_data_wrapper.as_ref().unwrap(); layout_data_wrapper_ref.data.before_style.is_some() } + #[inline] pub fn has_after_pseudo(&self) -> bool { let layout_data_wrapper = self.borrow_layout_data(); let layout_data_wrapper_ref = layout_data_wrapper.as_ref().unwrap(); diff --git a/components/net/image_cache_task.rs b/components/net/image_cache_task.rs index e5fbf856fe7..878d6420c24 100644 --- a/components/net/image_cache_task.rs +++ b/components/net/image_cache_task.rs @@ -6,6 +6,7 @@ use image::base::{Image, load_from_memory}; use resource_task; use resource_task::{LoadData, ResourceTask}; +use servo_util::taskpool::TaskPool; use std::comm::{channel, Receiver, Sender}; use std::collections::hashmap::HashMap; use std::mem::replace; @@ -79,7 +80,7 @@ impl<E, S: Encoder<E>> Encodable<S, E> for ImageCacheTask { type DecoderFactory = fn() -> (proc(&[u8]) : 'static -> Option<Image>); impl ImageCacheTask { - pub fn new(resource_task: ResourceTask) -> ImageCacheTask { + pub fn new(resource_task: ResourceTask, task_pool: TaskPool) -> ImageCacheTask { let (chan, port) = channel(); let chan_clone = chan.clone(); @@ -90,7 +91,8 @@ impl ImageCacheTask { chan: chan_clone, state_map: HashMap::new(), wait_map: HashMap::new(), - need_exit: None + need_exit: None, + task_pool: task_pool, }; cache.run(); }); @@ -100,11 +102,11 @@ impl ImageCacheTask { } } - pub fn new_sync(resource_task: ResourceTask) -> ImageCacheTask { + pub fn new_sync(resource_task: ResourceTask, task_pool: TaskPool) -> ImageCacheTask { let (chan, port) = channel(); spawn(proc() { - let inner_cache = ImageCacheTask::new(resource_task); + let inner_cache = ImageCacheTask::new(resource_task, task_pool); loop { let msg: Msg = port.recv(); @@ -140,6 +142,7 @@ struct ImageCache { /// List of clients waiting on a WaitForImage response wait_map: HashMap<Url, Arc<Mutex<Vec<Sender<ImageResponseMsg>>>>>, need_exit: Option<Sender<()>>, + task_pool: TaskPool, } #[deriving(Clone)] @@ -314,7 +317,7 @@ impl ImageCache { let to_cache = self.chan.clone(); let url_clone = url.clone(); - spawn(proc() { + self.task_pool.execute(proc() { let url = url_clone; debug!("image_cache_task: started image decode for {:s}", url.serialize()); let image = load_from_memory(data.as_slice()); @@ -493,6 +496,7 @@ mod tests { use resource_task; use resource_task::{ResourceTask, Metadata, start_sending}; use image::base::test_image_bin; + use servo_util::taskpool::TaskPool; use std::comm; use url::Url; @@ -581,7 +585,7 @@ mod tests { fn should_exit_on_request() { let mock_resource_task = mock_resource_task(box DoesNothing); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4)); image_cache_task.exit(); mock_resource_task.send(resource_task::Exit); @@ -592,7 +596,7 @@ mod tests { fn should_fail_if_unprefetched_image_is_requested() { let mock_resource_task = mock_resource_task(box DoesNothing); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4)); let url = Url::parse("file:///").unwrap(); let (chan, port) = channel(); @@ -606,7 +610,7 @@ mod tests { let mock_resource_task = mock_resource_task(box JustSendOK { url_requested_chan: url_requested_chan}); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4)); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url)); @@ -621,7 +625,7 @@ mod tests { let mock_resource_task = mock_resource_task(box JustSendOK { url_requested_chan: url_requested_chan}); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4)); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url.clone())); @@ -641,7 +645,7 @@ mod tests { let mock_resource_task = mock_resource_task(box WaitSendTestImage{wait_port: wait_port}); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4)); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url.clone())); @@ -658,7 +662,7 @@ mod tests { fn should_return_decoded_image_data_if_data_has_arrived() { let mock_resource_task = mock_resource_task(box SendTestImage); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4)); let url = Url::parse("file:///").unwrap(); let join_port = image_cache_task.wait_for_store(); @@ -684,7 +688,7 @@ mod tests { fn should_return_decoded_image_data_for_multiple_requests() { let mock_resource_task = mock_resource_task(box SendTestImage); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4)); let url = Url::parse("file:///").unwrap(); let join_port = image_cache_task.wait_for_store(); @@ -732,7 +736,7 @@ mod tests { } }); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4)); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url.clone())); @@ -779,7 +783,7 @@ mod tests { } }); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4)); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url.clone())); @@ -808,7 +812,7 @@ mod tests { fn should_return_failed_if_image_bin_cannot_be_fetched() { let mock_resource_task = mock_resource_task(box SendTestImageErr); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4)); let url = Url::parse("file:///").unwrap(); let join_port = image_cache_task.wait_for_store_prefetched(); @@ -834,7 +838,7 @@ mod tests { fn should_return_failed_for_multiple_get_image_requests_if_image_bin_cannot_be_fetched() { let mock_resource_task = mock_resource_task(box SendTestImageErr); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4)); let url = Url::parse("file:///").unwrap(); let join_port = image_cache_task.wait_for_store_prefetched(); @@ -868,7 +872,7 @@ mod tests { fn should_return_failed_if_image_decode_fails() { let mock_resource_task = mock_resource_task(box SendBogusImage); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4)); let url = Url::parse("file:///").unwrap(); let join_port = image_cache_task.wait_for_store(); @@ -896,7 +900,7 @@ mod tests { fn should_return_image_on_wait_if_image_is_already_loaded() { let mock_resource_task = mock_resource_task(box SendTestImage); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4)); let url = Url::parse("file:///").unwrap(); let join_port = image_cache_task.wait_for_store(); @@ -924,7 +928,7 @@ mod tests { let mock_resource_task = mock_resource_task(box WaitSendTestImage {wait_port: wait_port}); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4)); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url.clone())); @@ -950,7 +954,7 @@ mod tests { let mock_resource_task = mock_resource_task(box WaitSendTestImageErr{wait_port: wait_port}); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4)); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url.clone())); @@ -974,7 +978,7 @@ mod tests { fn sync_cache_should_wait_for_images() { let mock_resource_task = mock_resource_task(box SendTestImage); - let image_cache_task = ImageCacheTask::new_sync(mock_resource_task.clone()); + let image_cache_task = ImageCacheTask::new_sync(mock_resource_task.clone(), TaskPool::new(4)); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url.clone())); diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 724f9423bb3..2743cf4b268 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -381,6 +381,7 @@ impl<'a> PrivateNodeHelpers for JSRef<'a, Node> { pub trait NodeHelpers<'a> { fn ancestors(self) -> AncestorIterator<'a>; fn children(self) -> AbstractNodeChildrenIterator<'a>; + fn rev_children(self) -> ReverseChildrenIterator<'a>; fn child_elements(self) -> ChildElementIterator<'a>; fn following_siblings(self) -> AbstractNodeChildrenIterator<'a>; fn is_in_doc(self) -> bool; @@ -441,7 +442,6 @@ pub trait NodeHelpers<'a> { fn debug_str(self) -> String; fn traverse_preorder(self) -> TreeIterator<'a>; - fn sequential_traverse_postorder(self) -> TreeIterator<'a>; fn inclusively_following_siblings(self) -> AbstractNodeChildrenIterator<'a>; fn to_trusted_node_address(self) -> TrustedNodeAddress; @@ -658,21 +658,12 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { /// Iterates over this node and all its descendants, in preorder. fn traverse_preorder(self) -> TreeIterator<'a> { - let mut nodes = vec!(); - gather_abstract_nodes(self, &mut nodes, false); - TreeIterator::new(nodes) - } - - /// Iterates over this node and all its descendants, in postorder. - fn sequential_traverse_postorder(self) -> TreeIterator<'a> { - let mut nodes = vec!(); - gather_abstract_nodes(self, &mut nodes, true); - TreeIterator::new(nodes) + TreeIterator::new(self) } fn inclusively_following_siblings(self) -> AbstractNodeChildrenIterator<'a> { AbstractNodeChildrenIterator { - current_node: Some(self.clone()), + current: Some(self.clone()), } } @@ -682,7 +673,7 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { fn following_siblings(self) -> AbstractNodeChildrenIterator<'a> { AbstractNodeChildrenIterator { - current_node: self.next_sibling().root().map(|next| next.clone()), + current: self.next_sibling().root().map(|next| next.clone()), } } @@ -774,7 +765,13 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { fn children(self) -> AbstractNodeChildrenIterator<'a> { AbstractNodeChildrenIterator { - current_node: self.first_child.get().map(|node| (*node.root()).clone()), + current: self.first_child.get().map(|node| (*node.root()).clone()), + } + } + + fn rev_children(self) -> ReverseChildrenIterator<'a> { + ReverseChildrenIterator { + current: self.last_child.get().map(|node| *node.root().deref()), } } @@ -974,15 +971,25 @@ pub type ChildElementIterator<'a> = Map<'a, JSRef<'a, Node>, Filter<'a, JSRef<'a, Node>, AbstractNodeChildrenIterator<'a>>>; pub struct AbstractNodeChildrenIterator<'a> { - current_node: Option<JSRef<'a, Node>>, + current: Option<JSRef<'a, Node>>, } impl<'a> Iterator<JSRef<'a, Node>> for AbstractNodeChildrenIterator<'a> { fn next(&mut self) -> Option<JSRef<'a, Node>> { - let node = self.current_node.clone(); - self.current_node = node.clone().and_then(|node| { - node.next_sibling().map(|node| (*node.root()).clone()) - }); + let node = self.current; + self.current = node.and_then(|node| node.next_sibling().map(|node| *node.root().deref())); + node + } +} + +pub struct ReverseChildrenIterator<'a> { + current: Option<JSRef<'a, Node>>, +} + +impl<'a> Iterator<JSRef<'a, Node>> for ReverseChildrenIterator<'a> { + fn next(&mut self) -> Option<JSRef<'a, Node>> { + let node = self.current; + self.current = node.and_then(|node| node.prev_sibling().map(|node| *node.root().deref())); node } } @@ -993,43 +1000,32 @@ pub struct AncestorIterator<'a> { impl<'a> Iterator<JSRef<'a, Node>> for AncestorIterator<'a> { fn next(&mut self) -> Option<JSRef<'a, Node>> { - if self.current.is_none() { - return None; - } - - // FIXME: Do we need two clones here? - let x = self.current.as_ref().unwrap().clone(); - self.current = x.parent_node().map(|node| (*node.root()).clone()); - Some(x) + let node = self.current; + self.current = node.and_then(|node| node.parent_node().map(|node| *node.root().deref())); + node } } -// FIXME: Do this without precomputing a vector of refs. -// Easy for preorder; harder for postorder. pub struct TreeIterator<'a> { - nodes: Vec<JSRef<'a, Node>>, - index: uint, + stack: Vec<JSRef<'a, Node>>, } impl<'a> TreeIterator<'a> { - fn new(nodes: Vec<JSRef<'a, Node>>) -> TreeIterator<'a> { + fn new(root: JSRef<'a, Node>) -> TreeIterator<'a> { + let mut stack = vec!(); + stack.push(root); + TreeIterator { - nodes: nodes, - index: 0, + stack: stack, } } } impl<'a> Iterator<JSRef<'a, Node>> for TreeIterator<'a> { fn next(&mut self) -> Option<JSRef<'a, Node>> { - if self.index >= self.nodes.len() { - None - } else { - let v = self.nodes[self.index]; - let v = v.clone(); - self.index += 1; - Some(v) - } + let ret = self.stack.pop(); + ret.map(|node| self.stack.extend(node.rev_children())); + ret } } @@ -1116,18 +1112,6 @@ impl<'a> Iterator<JSRef<'a, Node>> for NodeIterator { } } -fn gather_abstract_nodes<'a>(cur: JSRef<'a, Node>, refs: &mut Vec<JSRef<'a, Node>>, postorder: bool) { - if !postorder { - refs.push(cur.clone()); - } - for kid in cur.children() { - gather_abstract_nodes(kid, refs, postorder) - } - if postorder { - refs.push(cur.clone()); - } -} - /// Specifies whether children must be recursively cloned or not. #[deriving(PartialEq)] pub enum CloneChildrenFlag { @@ -2209,6 +2193,16 @@ impl<'a> style::TNode<'a, JSRef<'a, Element>> for JSRef<'a, Node> { first_child(self).map(|node| *node.root()) } + fn last_child(self) -> Option<JSRef<'a, Node>> { + // FIXME(zwarich): Remove this when UFCS lands and there is a better way + // of disambiguating methods. + fn last_child<'a, T: NodeHelpers<'a>>(this: T) -> Option<Temporary<Node>> { + this.last_child() + } + + last_child(self).map(|node| *node.root()) + } + fn prev_sibling(self) -> Option<JSRef<'a, Node>> { // FIXME(zwarich): Remove this when UFCS lands and there is a better way // of disambiguating methods. diff --git a/components/style/node.rs b/components/style/node.rs index ea0d8a614c0..cebac4bd6f8 100644 --- a/components/style/node.rs +++ b/components/style/node.rs @@ -13,6 +13,7 @@ use string_cache::{Atom, Namespace}; pub trait TNode<'a, E: TElement<'a>> : Clone + Copy { fn parent_node(self) -> Option<Self>; fn first_child(self) -> Option<Self>; + fn last_child(self) -> Option<Self>; fn prev_sibling(self) -> Option<Self>; fn next_sibling(self) -> Option<Self>; fn is_document(self) -> bool; @@ -57,4 +58,3 @@ pub trait TElementAttributes : Copy { fn get_length_attribute(self, attribute: LengthAttribute) -> LengthOrPercentageOrAuto; fn get_integer_attribute(self, attribute: IntegerAttribute) -> Option<i32>; } - diff --git a/components/util/cache.rs b/components/util/cache.rs index dd45ee98cc0..19f861a1d3c 100644 --- a/components/util/cache.rs +++ b/components/util/cache.rs @@ -49,6 +49,13 @@ impl<K: Clone + PartialEq + Eq + Hash, V: Clone> Cache<K,V> for HashCache<K,V> { fn evict_all(&mut self) { self.entries.clear(); } + +} + +impl<K,V> HashCache<K,V> where K: Clone + PartialEq + Eq + Hash, V: Clone { + pub fn find_equiv<'a,Q>(&'a self, key: &Q) -> Option<&'a V> where Q: Hash + Equiv<K> { + self.entries.find_equiv(key) + } } #[test] diff --git a/components/util/dlist.rs b/components/util/dlist.rs new file mode 100644 index 00000000000..14a1b5d4cdf --- /dev/null +++ b/components/util/dlist.rs @@ -0,0 +1,68 @@ +/* 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/. */ + +//! Utility functions for doubly-linked lists. + +use std::collections::DList; +use std::mem; +use std::ptr; + +struct RawDList<T> { + length: uint, + head: Option<Box<RawNode<T>>>, + tail: *mut RawNode<T>, +} + +#[allow(dead_code)] +struct RawNode<T> { + next: Option<Box<RawNode<T>>>, + prev: *mut RawNode<T>, + value: T, +} + +#[unsafe_destructor] +impl<T> Drop for RawDList<T> { + fn drop(&mut self) { + fail!("shouldn't happen") + } +} + +/// Workaround for a missing method on Rust's `DList` type. Splits the head off a list in O(1) +/// time. +pub fn split<T>(list: &mut DList<T>) -> DList<T> { + let list = unsafe { + mem::transmute::<&mut DList<T>,&mut RawDList<T>>(list) + }; + + if list.length == 0 { + fail!("split_dlist(): empty list") + } + let mut head_node = mem::replace(&mut list.head, None); + let head_node_ptr: *mut RawNode<T> = &mut **head_node.as_mut().unwrap(); + let mut head_list = RawDList { + length: 1, + head: head_node, + tail: head_node_ptr, + }; + debug_assert!(list.head.is_none()); + mem::swap(&mut head_list.head.as_mut().unwrap().next, &mut list.head); + debug_assert!(head_list.head.as_mut().unwrap().next.is_none()); + debug_assert!(head_list.head.as_mut().unwrap().prev.is_null()); + head_list.head.as_mut().unwrap().prev = ptr::null_mut(); + + list.length -= 1; + if list.length == 0 { + list.tail = ptr::null_mut() + } else { + if list.length == 1 { + list.tail = &mut **list.head.as_mut().unwrap() as *mut RawNode<T> + } + list.head.as_mut().unwrap().prev = ptr::null_mut() + } + + unsafe { + mem::transmute::<RawDList<T>,DList<T>>(head_list) + } +} + diff --git a/components/util/lib.rs b/components/util/lib.rs index f5fd08dc24e..a53f3a1c3d9 100644 --- a/components/util/lib.rs +++ b/components/util/lib.rs @@ -36,6 +36,7 @@ use std::sync::Arc; pub mod bloom; pub mod cache; pub mod debug_utils; +pub mod dlist; pub mod fnv; pub mod geometry; pub mod logical_geometry; @@ -50,6 +51,7 @@ pub mod str; pub mod task; pub mod tid; pub mod time; +pub mod taskpool; pub mod vec; pub mod workqueue; diff --git a/components/util/opts.rs b/components/util/opts.rs index 86eb383cbc7..3805a03ec04 100644 --- a/components/util/opts.rs +++ b/components/util/opts.rs @@ -74,6 +74,9 @@ pub struct Opts { /// debugging purposes (`--show-debug-borders`). pub show_debug_borders: bool, + /// True if we should show borders on all fragments for debugging purposes (`--show-debug-fragment-borders`). + pub show_debug_fragment_borders: bool, + /// If set with --disable-text-aa, disable antialiasing on fonts. This is primarily useful for reftests /// where pixel perfect results are required when using fonts such as the Ahem /// font for layout tests. @@ -140,6 +143,7 @@ pub fn from_cmdline_args(args: &[String]) -> bool { getopts::optflag("f", "hard-fail", "Exit on task failure instead of displaying about:failure"), getopts::optflag("b", "bubble-widths", "Bubble intrinsic widths separately like other engines"), getopts::optflag("", "show-debug-borders", "Show debugging borders on layers and tiles."), + getopts::optflag("", "show-debug-fragment-borders", "Show debugging borders on fragments."), getopts::optflag("", "disable-text-aa", "Disable antialiasing for text rendering."), getopts::optflag("", "trace-layout", "Write layout trace to external file for debugging."), getopts::optflagopt("", "devtools", "Start remote devtools server on port", "6000"), @@ -242,6 +246,7 @@ pub fn from_cmdline_args(args: &[String]) -> bool { hard_fail: opt_match.opt_present("f"), bubble_inline_sizes_separately: bubble_inline_sizes_separately, show_debug_borders: opt_match.opt_present("show-debug-borders"), + show_debug_fragment_borders: opt_match.opt_present("show-debug-fragment-borders"), enable_text_antialiasing: !opt_match.opt_present("disable-text-aa"), trace_layout: trace_layout, devtools_port: devtools_port, diff --git a/components/util/taskpool.rs b/components/util/taskpool.rs new file mode 100644 index 00000000000..0a2fafb2ab3 --- /dev/null +++ b/components/util/taskpool.rs @@ -0,0 +1,53 @@ +/* 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/. */ + +//! A load-balancing task pool. +//! +//! This differs in implementation from std::sync::TaskPool in that each job is +//! up for grabs by any of the child tasks in the pool. +//! + +// +// This is based on the cargo task pool. +// https://github.com/rust-lang/cargo/blob/master/src/cargo/util/pool.rs +// +// The only difference is that a normal channel is used instead of a sync_channel. +// + +use std::sync::{Arc, Mutex}; + +pub struct TaskPool { + tx: Sender<proc():Send>, +} + +impl TaskPool { + pub fn new(tasks: uint) -> TaskPool { + assert!(tasks > 0); + let (tx, rx) = channel(); + + let state = Arc::new(Mutex::new(rx)); + + for _ in range(0, tasks) { + let state = state.clone(); + spawn(proc() worker(&*state)); + } + + return TaskPool { tx: tx }; + + fn worker(rx: &Mutex<Receiver<proc():Send>>) { + loop { + let job = rx.lock().recv_opt(); + match job { + Ok(job) => job(), + Err(..) => break, + } + } + } + } + + pub fn execute(&self, job: proc():Send) { + self.tx.send(job); + } +} + diff --git a/ports/android/glut_app/Cargo.lock b/ports/android/glut_app/Cargo.lock index 5fad2d1bea9..ad9b312128a 100644 --- a/ports/android/glut_app/Cargo.lock +++ b/ports/android/glut_app/Cargo.lock @@ -28,7 +28,7 @@ source = "git+https://github.com/servo/rust-azure#b357751c04a89a87e6ef1f0cebe5f2 dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#166a601ff3e0fc3a64ca1a9090d02c8d4f22b61a)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics#6a9919f8a912cc67571b891ba198d5325964a104)", - "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#1ad11072b31657eeccaf4879c6e98723d488bd3d)", + "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#967a97fa7e9ae47f96aee5e48f5fb0be1345d89e)", "egl 0.1.0 (git+https://github.com/servo/rust-egl#88f2a13812ddbce2bf2317221663a61c31b3e220)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype#0b03da276e4bdeae2300596dabc4ccb16733ad70)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#90add8d65273c8a46aa16d73959e29a51d0c282d)", @@ -59,7 +59,7 @@ dependencies = [ "alert 0.1.0 (git+https://github.com/servo/rust-alert#fdc24f13be8d8a2d15214ec228d166b3221b809e)", "azure 0.1.0 (git+https://github.com/servo/rust-azure#b357751c04a89a87e6ef1f0cebe5f20957dd112d)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics#6a9919f8a912cc67571b891ba198d5325964a104)", - "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#1ad11072b31657eeccaf4879c6e98723d488bd3d)", + "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#967a97fa7e9ae47f96aee5e48f5fb0be1345d89e)", "devtools 0.0.1", "devtools_traits 0.0.1", "geom 0.1.0 (git+https://github.com/servo/rust-geom#90add8d65273c8a46aa16d73959e29a51d0c282d)", @@ -91,7 +91,7 @@ dependencies = [ [[package]] name = "core_text" version = "0.1.0" -source = "git+https://github.com/servo/rust-core-text#1ad11072b31657eeccaf4879c6e98723d488bd3d" +source = "git+https://github.com/servo/rust-core-text#967a97fa7e9ae47f96aee5e48f5fb0be1345d89e" dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#166a601ff3e0fc3a64ca1a9090d02c8d4f22b61a)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics#6a9919f8a912cc67571b891ba198d5325964a104)", @@ -100,7 +100,7 @@ dependencies = [ [[package]] name = "cssparser" version = "0.1.0" -source = "git+https://github.com/servo/rust-cssparser#22146ce095cb62df39d459c3a79d1486041f96f6" +source = "git+https://github.com/servo/rust-cssparser#7b0549a5d122135848b8813ec401112ab588063c" dependencies = [ "encoding 0.1.0 (git+https://github.com/lifthrasiir/rust-encoding#28eafb604a92c7786685b46c0fc02682ba3ab265)", ] @@ -174,7 +174,7 @@ dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure#b357751c04a89a87e6ef1f0cebe5f20957dd112d)", "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#166a601ff3e0fc3a64ca1a9090d02c8d4f22b61a)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics#6a9919f8a912cc67571b891ba198d5325964a104)", - "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#1ad11072b31657eeccaf4879c6e98723d488bd3d)", + "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#967a97fa7e9ae47f96aee5e48f5fb0be1345d89e)", "fontconfig 0.1.0 (git+https://github.com/servo/rust-fontconfig#b16c1e12ecb74b1e4e9a9b23c2b98580a34cf201)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype#0b03da276e4bdeae2300596dabc4ccb16733ad70)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#90add8d65273c8a46aa16d73959e29a51d0c282d)", @@ -382,7 +382,7 @@ name = "script" version = "0.0.1" dependencies = [ "canvas 0.0.1", - "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser#22146ce095cb62df39d459c3a79d1486041f96f6)", + "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser#7b0549a5d122135848b8813ec401112ab588063c)", "devtools_traits 0.0.1", "encoding 0.1.0 (git+https://github.com/lifthrasiir/rust-encoding#28eafb604a92c7786685b46c0fc02682ba3ab265)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#90add8d65273c8a46aa16d73959e29a51d0c282d)", @@ -469,7 +469,7 @@ dependencies = [ name = "style" version = "0.0.1" dependencies = [ - "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser#22146ce095cb62df39d459c3a79d1486041f96f6)", + "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser#7b0549a5d122135848b8813ec401112ab588063c)", "encoding 0.1.0 (git+https://github.com/lifthrasiir/rust-encoding#28eafb604a92c7786685b46c0fc02682ba3ab265)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#90add8d65273c8a46aa16d73959e29a51d0c282d)", "lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs#e62a65372f1dd9019e37eb9381d819edff80e360)", diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 545b0c192b0..7a17c954194 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -4,7 +4,7 @@ version = "0.0.1" dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure#b357751c04a89a87e6ef1f0cebe5f20957dd112d)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics#6a9919f8a912cc67571b891ba198d5325964a104)", - "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#1ad11072b31657eeccaf4879c6e98723d488bd3d)", + "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#967a97fa7e9ae47f96aee5e48f5fb0be1345d89e)", "devtools 0.0.1", "geom 0.1.0 (git+https://github.com/servo/rust-geom#b001a76e907befaae1d0d6dd259418a22092da86)", "gfx 0.0.1", @@ -40,7 +40,7 @@ source = "git+https://github.com/servo/rust-azure#b357751c04a89a87e6ef1f0cebe5f2 dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#166a601ff3e0fc3a64ca1a9090d02c8d4f22b61a)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics#6a9919f8a912cc67571b891ba198d5325964a104)", - "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#1ad11072b31657eeccaf4879c6e98723d488bd3d)", + "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#967a97fa7e9ae47f96aee5e48f5fb0be1345d89e)", "egl 0.1.0 (git+https://github.com/servo/rust-egl#88f2a13812ddbce2bf2317221663a61c31b3e220)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype#0b03da276e4bdeae2300596dabc4ccb16733ad70)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#b001a76e907befaae1d0d6dd259418a22092da86)", @@ -71,7 +71,7 @@ dependencies = [ "alert 0.1.0 (git+https://github.com/servo/rust-alert#fdc24f13be8d8a2d15214ec228d166b3221b809e)", "azure 0.1.0 (git+https://github.com/servo/rust-azure#b357751c04a89a87e6ef1f0cebe5f20957dd112d)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics#6a9919f8a912cc67571b891ba198d5325964a104)", - "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#1ad11072b31657eeccaf4879c6e98723d488bd3d)", + "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#967a97fa7e9ae47f96aee5e48f5fb0be1345d89e)", "devtools 0.0.1", "devtools_traits 0.0.1", "geom 0.1.0 (git+https://github.com/servo/rust-geom#b001a76e907befaae1d0d6dd259418a22092da86)", @@ -103,7 +103,7 @@ dependencies = [ [[package]] name = "core_text" version = "0.1.0" -source = "git+https://github.com/servo/rust-core-text#1ad11072b31657eeccaf4879c6e98723d488bd3d" +source = "git+https://github.com/servo/rust-core-text#967a97fa7e9ae47f96aee5e48f5fb0be1345d89e" dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#166a601ff3e0fc3a64ca1a9090d02c8d4f22b61a)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics#6a9919f8a912cc67571b891ba198d5325964a104)", @@ -112,7 +112,7 @@ dependencies = [ [[package]] name = "cssparser" version = "0.1.0" -source = "git+https://github.com/servo/rust-cssparser#22146ce095cb62df39d459c3a79d1486041f96f6" +source = "git+https://github.com/servo/rust-cssparser#7b0549a5d122135848b8813ec401112ab588063c" dependencies = [ "encoding 0.1.0 (git+https://github.com/lifthrasiir/rust-encoding#28eafb604a92c7786685b46c0fc02682ba3ab265)", ] @@ -186,7 +186,7 @@ dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure#b357751c04a89a87e6ef1f0cebe5f20957dd112d)", "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#166a601ff3e0fc3a64ca1a9090d02c8d4f22b61a)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics#6a9919f8a912cc67571b891ba198d5325964a104)", - "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#1ad11072b31657eeccaf4879c6e98723d488bd3d)", + "core_text 0.1.0 (git+https://github.com/servo/rust-core-text#967a97fa7e9ae47f96aee5e48f5fb0be1345d89e)", "fontconfig 0.1.0 (git+https://github.com/servo/rust-fontconfig#b16c1e12ecb74b1e4e9a9b23c2b98580a34cf201)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype#0b03da276e4bdeae2300596dabc4ccb16733ad70)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#b001a76e907befaae1d0d6dd259418a22092da86)", @@ -399,7 +399,7 @@ name = "script" version = "0.0.1" dependencies = [ "canvas 0.0.1", - "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser#22146ce095cb62df39d459c3a79d1486041f96f6)", + "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser#7b0549a5d122135848b8813ec401112ab588063c)", "devtools_traits 0.0.1", "encoding 0.1.0 (git+https://github.com/lifthrasiir/rust-encoding#28eafb604a92c7786685b46c0fc02682ba3ab265)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#b001a76e907befaae1d0d6dd259418a22092da86)", @@ -487,7 +487,7 @@ dependencies = [ name = "style" version = "0.0.1" dependencies = [ - "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser#22146ce095cb62df39d459c3a79d1486041f96f6)", + "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser#7b0549a5d122135848b8813ec401112ab588063c)", "encoding 0.1.0 (git+https://github.com/lifthrasiir/rust-encoding#28eafb604a92c7786685b46c0fc02682ba3ab265)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#b001a76e907befaae1d0d6dd259418a22092da86)", "lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs#e62a65372f1dd9019e37eb9381d819edff80e360)", diff --git a/ports/cef/core.rs b/ports/cef/core.rs index b427d8d85b7..cdde5e9a4bf 100644 --- a/ports/cef/core.rs +++ b/ports/cef/core.rs @@ -67,6 +67,7 @@ pub extern "C" fn cef_run_message_loop() { hard_fail: false, bubble_inline_sizes_separately: false, show_debug_borders: false, + show_debug_fragment_borders: false, enable_text_antialiasing: true, trace_layout: false, devtools_port: None, diff --git a/src/lib.rs b/src/lib.rs index 64411f478c8..43bb4760fda 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,6 +51,8 @@ use servo_util::time::TimeProfiler; use servo_util::memory::MemoryProfiler; #[cfg(not(test))] use servo_util::opts; +#[cfg(not(test))] +use servo_util::taskpool::TaskPool; #[cfg(not(test))] use green::GreenTaskBuilder; @@ -79,6 +81,7 @@ pub fn run<Window: WindowMethods>(window: Option<Rc<Window>>) { }); let time_profiler_chan_clone = time_profiler_chan.clone(); + let shared_task_pool = TaskPool::new(8); let (result_chan, result_port) = channel(); TaskBuilder::new() @@ -90,9 +93,9 @@ pub fn run<Window: WindowMethods>(window: Option<Rc<Window>>) { // image load or we risk emitting an output file missing the // image. let image_cache_task = if opts.output_file.is_some() { - ImageCacheTask::new_sync(resource_task.clone()) + ImageCacheTask::new_sync(resource_task.clone(), shared_task_pool) } else { - ImageCacheTask::new(resource_task.clone()) + ImageCacheTask::new(resource_task.clone(), shared_task_pool) }; let font_cache_task = FontCacheTask::new(resource_task.clone()); let constellation_chan = Constellation::<layout::layout_task::LayoutTask, diff --git a/tests/wpt/include.ini b/tests/wpt/include.ini index bb34afa4482..55e1f50c925 100644 --- a/tests/wpt/include.ini +++ b/tests/wpt/include.ini @@ -77,3 +77,11 @@ skip: true skip: true [XMLHttpRequest] skip: false +[old-tests] + skip: true + [submission] + skip: true + [Opera] + skip: true + [script_scheduling] + skip: false diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/005.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/005.html.ini new file mode 100644 index 00000000000..8b1d1c690e0 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/005.html.ini @@ -0,0 +1,5 @@ +[005.html] + type: testharness + [ scheduler: document.write inline in markup ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/006.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/006.html.ini new file mode 100644 index 00000000000..54af1212e5f --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/006.html.ini @@ -0,0 +1,5 @@ +[006.html] + type: testharness + [ scheduler: document.write inline - multiple] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/007.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/007.html.ini new file mode 100644 index 00000000000..7351254d579 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/007.html.ini @@ -0,0 +1,5 @@ +[007.html] + type: testharness + [ scheduler: document.write external] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/008.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/008.html.ini new file mode 100644 index 00000000000..f88a254e8ff --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/008.html.ini @@ -0,0 +1,5 @@ +[008.html] + type: testharness + [ scheduler: document.write external - multiple] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/009.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/009.html.ini new file mode 100644 index 00000000000..36a6b79c88f --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/009.html.ini @@ -0,0 +1,5 @@ +[009.html] + type: testharness + [ scheduler: document.write external - multiple with doc.write] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/010.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/010.html.ini new file mode 100644 index 00000000000..20732c52903 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/010.html.ini @@ -0,0 +1,5 @@ +[010.html] + type: testharness + [ scheduler: document.write external + inline - multiple with doc.write] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/011.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/011.html.ini new file mode 100644 index 00000000000..91ae46d456f --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/011.html.ini @@ -0,0 +1,5 @@ +[011.html] + type: testharness + [ scheduler: document.write external + inline - multiple with doc.write + subsequent markup] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/012.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/012.html.ini new file mode 100644 index 00000000000..97e1a8c2e66 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/012.html.ini @@ -0,0 +1,5 @@ +[012.html] + type: testharness + [ scheduler: document.write external and onload events ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/013.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/013.html.ini new file mode 100644 index 00000000000..ccb3f3090d7 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/013.html.ini @@ -0,0 +1,5 @@ +[013.html] + type: testharness + [ scheduler: DOM added inline script earlier in document] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/015.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/015.html.ini new file mode 100644 index 00000000000..0eb052e7dda --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/015.html.ini @@ -0,0 +1,5 @@ +[015.html] + type: testharness + [ scheduler: DOM added inline+external+inline script earlier in document] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/015a.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/015a.html.ini new file mode 100644 index 00000000000..f13a4ad5783 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/015a.html.ini @@ -0,0 +1,5 @@ +[015a.html] + type: testharness + [ scheduler: DOM added inline+external+inline script earlier in document] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/016.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/016.html.ini new file mode 100644 index 00000000000..bf00a2bf3f8 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/016.html.ini @@ -0,0 +1,5 @@ +[016.html] + type: testharness + [ scheduler: DOM added inline script later in document] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/017.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/017.html.ini new file mode 100644 index 00000000000..c53367410e5 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/017.html.ini @@ -0,0 +1,5 @@ +[017.html] + type: testharness + [ scheduler: multiple DOM added scripts later in document] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/018.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/018.html.ini new file mode 100644 index 00000000000..51779a58e20 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/018.html.ini @@ -0,0 +1,5 @@ +[018.html] + type: testharness + [ scheduler: DOM added scripts and doc.write] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/019.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/019.html.ini new file mode 100644 index 00000000000..d84f65ea52b --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/019.html.ini @@ -0,0 +1,5 @@ +[019.html] + type: testharness + [ scheduler: DOM added scripts and event handling ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/020.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/020.html.ini new file mode 100644 index 00000000000..5fe0007df72 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/020.html.ini @@ -0,0 +1,5 @@ +[020.html] + type: testharness + [ scheduler: DOM added script with data: URL ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/022.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/022.html.ini new file mode 100644 index 00000000000..86432e7f001 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/022.html.ini @@ -0,0 +1,5 @@ +[022.html] + type: testharness + [ scheduler: DOM added script, late .src ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/023.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/023.html.ini new file mode 100644 index 00000000000..f0fbd642ec7 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/023.html.ini @@ -0,0 +1,6 @@ +[023.html] + type: testharness + expected: TIMEOUT + [ scheduler: DOM added script, even later .src ] + expected: TIMEOUT + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/024.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/024.html.ini new file mode 100644 index 00000000000..34063b39d78 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/024.html.ini @@ -0,0 +1,5 @@ +[024.html] + type: testharness + [ scheduler: DOM added script, .src set twice] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/025.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/025.html.ini new file mode 100644 index 00000000000..4c6825d633a --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/025.html.ini @@ -0,0 +1,5 @@ +[025.html] + type: testharness + [ scheduler: DOM added script, .src set on script with content] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/026.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/026.html.ini new file mode 100644 index 00000000000..3d19bbb0ffd --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/026.html.ini @@ -0,0 +1,5 @@ +[026.html] + type: testharness + [ scheduler: doc write added script, .src set later] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/027.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/027.html.ini new file mode 100644 index 00000000000..754f603ba37 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/027.html.ini @@ -0,0 +1,5 @@ +[027.html] + type: testharness + [ scheduler: doc write added script with content, .src set later] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/028.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/028.html.ini new file mode 100644 index 00000000000..52f13d00053 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/028.html.ini @@ -0,0 +1,5 @@ +[028.html] + type: testharness + [ scheduler: javascript: URL] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/029.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/029.html.ini new file mode 100644 index 00000000000..a4e1f50fc71 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/029.html.ini @@ -0,0 +1,5 @@ +[029.html] + type: testharness + [ scheduler: javascript: URL in HREF] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/030.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/030.html.ini new file mode 100644 index 00000000000..3024520ff0f --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/030.html.ini @@ -0,0 +1,3 @@ +[030.html] + type: testharness + disabled: flaky diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/031.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/031.html.ini new file mode 100644 index 00000000000..3a3b16289bd --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/031.html.ini @@ -0,0 +1,5 @@ +[031.html] + type: testharness + [ scheduler: focus and blur events] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/033.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/033.html.ini new file mode 100644 index 00000000000..8a66ded9232 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/033.html.ini @@ -0,0 +1,5 @@ +[033.html] + type: testharness + [ scheduler: innerHTML and scripts moved in DOM] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/034.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/034.html.ini new file mode 100644 index 00000000000..b1b921d5860 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/034.html.ini @@ -0,0 +1,5 @@ +[034.html] + type: testharness + [ scheduler: innerHTML adding frames with JS in] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/035.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/035.html.ini new file mode 100644 index 00000000000..1f668433485 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/035.html.ini @@ -0,0 +1,5 @@ +[035.html] + type: testharness + [ scheduler: innerHTML adding frames with JS in and moving scripts] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/036.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/036.html.ini new file mode 100644 index 00000000000..f1f5fa4da38 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/036.html.ini @@ -0,0 +1,5 @@ +[036.html] + type: testharness + [ scheduler: DOM cloning] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/037.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/037.html.ini new file mode 100644 index 00000000000..52efbc68148 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/037.html.ini @@ -0,0 +1,5 @@ +[037.html] + type: testharness + [ scheduler: DOM movement with appendChild, inline] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/038.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/038.html.ini new file mode 100644 index 00000000000..174d761ea84 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/038.html.ini @@ -0,0 +1,5 @@ +[038.html] + type: testharness + [ scheduler: DOM movement with appendChild, external] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/039.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/039.html.ini new file mode 100644 index 00000000000..b4cf0682ffc --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/039.html.ini @@ -0,0 +1,3 @@ +[039.html] + type: testharness + expected: CRASH diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/040.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/040.html.ini new file mode 100644 index 00000000000..01208d5bb42 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/040.html.ini @@ -0,0 +1,5 @@ +[040.html] + type: testharness + [ scheduler: IFRAMEs added with DOM (innerHTML), javascript: URL] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/041.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/041.html.ini new file mode 100644 index 00000000000..1aa57a18d9c --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/041.html.ini @@ -0,0 +1,5 @@ +[041.html] + type: testharness + [ scheduler: document.write scripts that write scripts] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/042.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/042.html.ini new file mode 100644 index 00000000000..9a2d58fe39b --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/042.html.ini @@ -0,0 +1,5 @@ +[042.html] + type: testharness + [ scheduler: DOM mutation events when adding scripts: DOMNodeInserted ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/043.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/043.html.ini new file mode 100644 index 00000000000..be2fbd3b460 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/043.html.ini @@ -0,0 +1,5 @@ +[043.html] + type: testharness + [ scheduler: DOM mutation events when adding external scripts: DOMNodeInserted ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/044.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/044.html.ini new file mode 100644 index 00000000000..1e6f0d681d1 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/044.html.ini @@ -0,0 +1,5 @@ +[044.html] + type: testharness + [ scheduler: DOM mutation events when adding scripts: DOMNodeInsertedIntoDocument ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/045.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/045.html.ini new file mode 100644 index 00000000000..60286828854 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/045.html.ini @@ -0,0 +1,5 @@ +[045.html] + type: testharness + [ scheduler: DOM mutation events when adding external scripts: DOMNodeInsertedIntoDocument ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/046.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/046.html.ini new file mode 100644 index 00000000000..75d42b69a57 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/046.html.ini @@ -0,0 +1,5 @@ +[046.html] + type: testharness + [ scheduler: no readystatechange events when adding external scripts ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/047.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/047.html.ini new file mode 100644 index 00000000000..9c1ceeaa4d9 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/047.html.ini @@ -0,0 +1,5 @@ +[047.html] + type: testharness + [ scheduler: adding and removing external script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/048.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/048.html.ini new file mode 100644 index 00000000000..a62ede9a84a --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/048.html.ini @@ -0,0 +1,5 @@ +[048.html] + type: testharness + [ scheduler: adding inline script which sets its own .src ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/049.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/049.html.ini new file mode 100644 index 00000000000..fcc9435392a --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/049.html.ini @@ -0,0 +1,5 @@ +[049.html] + type: testharness + [ scheduler: adding external script but removeAttribute( src ) before it runs] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/050.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/050.html.ini new file mode 100644 index 00000000000..2bfc46d9285 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/050.html.ini @@ -0,0 +1,5 @@ +[050.html] + type: testharness + [ scheduler: adding external script that removes all scripts from document] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/051.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/051.html.ini new file mode 100644 index 00000000000..c524ee1bc17 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/051.html.ini @@ -0,0 +1,5 @@ +[051.html] + type: testharness + [ scheduler: interaction of parsing and script execution - script added through DOM] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/052.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/052.html.ini new file mode 100644 index 00000000000..ddda41aa5a3 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/052.html.ini @@ -0,0 +1,5 @@ +[052.html] + type: testharness + [ scheduler: interaction of parsing and script execution - external script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/053.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/053.html.ini new file mode 100644 index 00000000000..552647fe0a4 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/053.html.ini @@ -0,0 +1,5 @@ +[053.html] + type: testharness + [ scheduler: adding external script that removes itself from document when loading] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/054.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/054.html.ini new file mode 100644 index 00000000000..3e7b70542bf --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/054.html.ini @@ -0,0 +1,5 @@ +[054.html] + type: testharness + [ scheduler: removing newly inserted script from DOMNodeInserted handler - external script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/055.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/055.html.ini new file mode 100644 index 00000000000..9600b104f9d --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/055.html.ini @@ -0,0 +1,5 @@ +[055.html] + type: testharness + [ scheduler: removing newly inserted script from DOMNodeInserted handler - inline script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/056.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/056.html.ini new file mode 100644 index 00000000000..ef0e50bedb3 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/056.html.ini @@ -0,0 +1,5 @@ +[056.html] + type: testharness + [ scheduler: appending code to initially empty SCRIPT tag in DOM ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/068.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/068.html.ini new file mode 100644 index 00000000000..9cb8f043f41 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/068.html.ini @@ -0,0 +1,3 @@ +[068.html] + type: testharness + expected: TIMEOUT diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/069.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/069.html.ini new file mode 100644 index 00000000000..c0a3251892a --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/069.html.ini @@ -0,0 +1,6 @@ +[069.html] + type: testharness + expected: TIMEOUT + [scheduler: external files added through DOM should not block further parsing while loading] + expected: TIMEOUT + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/070.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/070.html.ini new file mode 100644 index 00000000000..34774a78439 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/070.html.ini @@ -0,0 +1,3 @@ +[070.html] + type: testharness + expected: TIMEOUT diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/071.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/071.html.ini new file mode 100644 index 00000000000..225469776b1 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/071.html.ini @@ -0,0 +1,3 @@ +[071.html] + type: testharness + expected: TIMEOUT diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/072.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/072.html.ini new file mode 100644 index 00000000000..5ad9d625a46 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/072.html.ini @@ -0,0 +1,3 @@ +[072.html] + type: testharness + expected: TIMEOUT diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/073.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/073.html.ini new file mode 100644 index 00000000000..537e3e7c333 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/073.html.ini @@ -0,0 +1,3 @@ +[073.html] + type: testharness + expected: TIMEOUT diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/074.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/074.html.ini new file mode 100644 index 00000000000..a894f1b162c --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/074.html.ini @@ -0,0 +1,3 @@ +[074.html] + type: testharness + expected: TIMEOUT diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/075.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/075.html.ini new file mode 100644 index 00000000000..bafaab9102f --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/075.html.ini @@ -0,0 +1,5 @@ +[075.html] + type: testharness + [dispatchEvent from child frame during document.write :-o ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/076.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/076.html.ini new file mode 100644 index 00000000000..6da81e6bb68 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/076.html.ini @@ -0,0 +1,5 @@ +[076.html] + type: testharness + [ scheduler: adding and removing external and inline scripts ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/077.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/077.html.ini new file mode 100644 index 00000000000..71077979c71 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/077.html.ini @@ -0,0 +1,5 @@ +[077.html] + type: testharness + [ adding several types of scripts through the DOM and removing some of them confuses scheduler ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/078.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/078.html.ini new file mode 100644 index 00000000000..6ce0192273a --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/078.html.ini @@ -0,0 +1,5 @@ +[078.html] + type: testharness + [ adding several types of scripts through the DOM and removing some of them confuses scheduler (slow-loading scripts) ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/079.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/079.html.ini new file mode 100644 index 00000000000..95f70e89e46 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/079.html.ini @@ -0,0 +1,6 @@ +[079.html] + type: testharness + expected: TIMEOUT + [ setting location to javascript URL from event handler ] + expected: TIMEOUT + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/080.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/080.html.ini new file mode 100644 index 00000000000..eec03d6e781 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/080.html.ini @@ -0,0 +1,3 @@ +[080.html] + type: testharness + disabled: flaky diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/081.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/081.html.ini new file mode 100644 index 00000000000..298e96afb43 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/081.html.ini @@ -0,0 +1,5 @@ +[081.html] + type: testharness + [ scheduler: slow loading external script added with DOM (appendChild)] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/082.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/082.html.ini new file mode 100644 index 00000000000..8b8e5f9f8c4 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/082.html.ini @@ -0,0 +1,5 @@ +[082.html] + type: testharness + [ scheduler: multiple slow loading external scripts added with DOM (appendChild)] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/083.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/083.html.ini new file mode 100644 index 00000000000..9272fa0716d --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/083.html.ini @@ -0,0 +1,5 @@ +[083.html] + type: testharness + [ scheduler: event listener defined by script in a document in history] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/084.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/084.html.ini new file mode 100644 index 00000000000..6268eb738fb --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/084.html.ini @@ -0,0 +1,5 @@ +[084.html] + type: testharness + [ scheduler: event listener defined by script in a removed IFRAME] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/085.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/085.html.ini new file mode 100644 index 00000000000..989c0d47974 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/085.html.ini @@ -0,0 +1,5 @@ +[085.html] + type: testharness + [ scheduler: async script and slow-loading defer script] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/086.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/086.html.ini new file mode 100644 index 00000000000..cd50dc032c5 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/086.html.ini @@ -0,0 +1,5 @@ +[086.html] + type: testharness + [ scheduler: async script and slow-loading async script] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/088.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/088.html.ini new file mode 100644 index 00000000000..aee34579ac2 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/088.html.ini @@ -0,0 +1,5 @@ +[088.html] + type: testharness + [ scheduler: multiple scripts with defer and async attributes] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/091.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/091.html.ini new file mode 100644 index 00000000000..0005354951a --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/091.html.ini @@ -0,0 +1,5 @@ +[091.html] + type: testharness + [ scheduler: force-async off on non-parser-inserted script] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/092.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/092.html.ini new file mode 100644 index 00000000000..53ace1e41ae --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/092.html.ini @@ -0,0 +1,5 @@ +[092.html] + type: testharness + [ scheduler: defer script and slow-loading non-async external script] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/094.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/094.html.ini new file mode 100644 index 00000000000..b89f6319d28 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/094.html.ini @@ -0,0 +1,5 @@ +[094.html] + type: testharness + [ scheduler: parser-created defer script after document load] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/095.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/095.html.ini new file mode 100644 index 00000000000..e932e6afebf --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/095.html.ini @@ -0,0 +1,5 @@ +[095.html] + type: testharness + [ scheduler: slow-loading script added from defer blocking load event] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/096.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/096.html.ini new file mode 100644 index 00000000000..7647c26e9f9 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/096.html.ini @@ -0,0 +1,5 @@ +[096.html] + type: testharness + [ scheduler: defer script added from document.write relative to DOMContentLoaded] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/097.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/097.html.ini new file mode 100644 index 00000000000..8bf7322803a --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/097.html.ini @@ -0,0 +1,5 @@ +[097.html] + type: testharness + [ scheduler: slow-loading async script added from document.write] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/098.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/098.html.ini new file mode 100644 index 00000000000..5b0aa1e5e0c --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/098.html.ini @@ -0,0 +1,5 @@ +[098.html] + type: testharness + [ scheduler: defer script added from document.write] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/099.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/099.html.ini new file mode 100644 index 00000000000..f6dd8734342 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/099.html.ini @@ -0,0 +1,3 @@ +[099.html] + type: testharness + disabled: flaky diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/100.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/100.html.ini new file mode 100644 index 00000000000..d0b686d15b6 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/100.html.ini @@ -0,0 +1,5 @@ +[100.html] + type: testharness + [ scheduler: defer adding iframe containing script] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/101.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/101.html.ini new file mode 100644 index 00000000000..19f83b1602e --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/101.html.ini @@ -0,0 +1,5 @@ +[101.html] + type: testharness + [ scheduler: defer script after initial onload event] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/103.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/103.html.ini new file mode 100644 index 00000000000..e14710c6d77 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/103.html.ini @@ -0,0 +1,5 @@ +[103.html] + type: testharness + [ scheduler: removing defer attribute at runtime] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/104.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/104.html.ini new file mode 100644 index 00000000000..7436c8d2d6c --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/104.html.ini @@ -0,0 +1,5 @@ +[104.html] + type: testharness + [ scheduler: adding defer attribute at runtime] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/105.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/105.html.ini new file mode 100644 index 00000000000..253a757e9a1 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/105.html.ini @@ -0,0 +1,5 @@ +[105.html] + type: testharness + [ scheduler: adding async attribute at runtime] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/106.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/106.html.ini new file mode 100644 index 00000000000..1c4607ae45a --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/106.html.ini @@ -0,0 +1,5 @@ +[106.html] + type: testharness + [ scheduler: stylesheets blocking scripts] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/107.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/107.html.ini new file mode 100644 index 00000000000..1ed3d334188 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/107.html.ini @@ -0,0 +1,5 @@ +[107.html] + type: testharness + [ scheduler: stylesheets blocking scripts document.write] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/108.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/108.html.ini new file mode 100644 index 00000000000..590c920a3d8 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/108.html.ini @@ -0,0 +1,5 @@ +[108.html] + type: testharness + [ scheduler: javascript URL in iframe] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/109.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/109.html.ini new file mode 100644 index 00000000000..1292ebc1fc4 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/109.html.ini @@ -0,0 +1,5 @@ +[109.html] + type: testharness + [ scheduler: javascript URL in iframe, src set via DOM] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/110.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/110.html.ini new file mode 100644 index 00000000000..6a6079d5481 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/110.html.ini @@ -0,0 +1,5 @@ +[110.html] + type: testharness + [ scheduler: removing defer script at runtime] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/111.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/111.html.ini new file mode 100644 index 00000000000..b48570d329b --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/111.html.ini @@ -0,0 +1,5 @@ +[111.html] + type: testharness + [ scheduler: removing async attribute at runtime] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/116.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/116.html.ini new file mode 100644 index 00000000000..adb954dc246 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/116.html.ini @@ -0,0 +1,6 @@ +[116.html] + type: testharness + expected: TIMEOUT + [scheduler: adding script to head of frameset document] + expected: TIMEOUT + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/117.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/117.html.ini new file mode 100644 index 00000000000..bb29063639b --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/117.html.ini @@ -0,0 +1,5 @@ +[117.html] + type: testharness + [scheduler: inline script created with createContextualFragment] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/118.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/118.html.ini new file mode 100644 index 00000000000..7d6683b9635 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/118.html.ini @@ -0,0 +1,5 @@ +[118.html] + type: testharness + [scheduler: external script created with createContextualFragment] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/119.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/119.html.ini new file mode 100644 index 00000000000..db2cb45f8db --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/119.html.ini @@ -0,0 +1,5 @@ +[119.html] + type: testharness + [scheduler: external defer script created with createContextualFragment] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/120.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/120.html.ini new file mode 100644 index 00000000000..522ce72d541 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/120.html.ini @@ -0,0 +1,6 @@ +[120.html] + type: testharness + expected: TIMEOUT + [scheduler: script created without a window ] + expected: NOTRUN + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/122.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/122.html.ini new file mode 100644 index 00000000000..941e581f20c --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/122.html.ini @@ -0,0 +1,8 @@ +[122.html] + type: testharness + [scheduler: altering the type attribute and adding/removing external script ] + expected: FAIL + + [Reinserted script async IDL attribute] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/123.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/123.html.ini new file mode 100644 index 00000000000..cb08c989a08 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/123.html.ini @@ -0,0 +1,5 @@ +[123.html] + type: testharness + [scheduler: altering the type attribute and adding/removing external script with async=false ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/124.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/124.html.ini new file mode 100644 index 00000000000..99948245ba0 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/124.html.ini @@ -0,0 +1,5 @@ +[124.html] + type: testharness + [scheduler: altering the type attribute and changing script data inline script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/125.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/125.html.ini new file mode 100644 index 00000000000..e6269fe2954 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/125.html.ini @@ -0,0 +1,5 @@ +[125.html] + type: testharness + [scheduler: altering the type attribute and changing script data external script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/126.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/126.html.ini new file mode 100644 index 00000000000..f4bb635c593 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/126.html.ini @@ -0,0 +1,5 @@ +[126.html] + type: testharness + [scheduler: altering the type attribute and changing script data external script async=false ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/127.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/127.html.ini new file mode 100644 index 00000000000..803e846492f --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/127.html.ini @@ -0,0 +1,5 @@ +[127.html] + type: testharness + [scheduler: appending non-text children to script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/128.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/128.html.ini new file mode 100644 index 00000000000..c89e48eb931 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/128.html.ini @@ -0,0 +1,5 @@ +[128.html] + type: testharness + [scheduler: appending script element to script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/129.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/129.html.ini new file mode 100644 index 00000000000..e18cfba0012 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/129.html.ini @@ -0,0 +1,5 @@ +[129.html] + type: testharness + [scheduler: appending multiple script elements] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/130.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/130.html.ini new file mode 100644 index 00000000000..07a5de2740e --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/130.html.ini @@ -0,0 +1,5 @@ +[130.html] + type: testharness + [scheduler: appending external script element to script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/132.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/132.html.ini new file mode 100644 index 00000000000..e5c91b0e530 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/132.html.ini @@ -0,0 +1,5 @@ +[132.html] + type: testharness + [scheduler: external svg script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/133.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/133.html.ini new file mode 100644 index 00000000000..91c80df2d42 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/133.html.ini @@ -0,0 +1,5 @@ +[133.html] + type: testharness + [scheduler: inline HTML script added by SVG script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/134.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/134.html.ini new file mode 100644 index 00000000000..a01a182559d --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/134.html.ini @@ -0,0 +1,5 @@ +[134.html] + type: testharness + [scheduler: external HTML script added by SVG script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/135.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/135.html.ini new file mode 100644 index 00000000000..377501f7778 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/135.html.ini @@ -0,0 +1,5 @@ +[135.html] + type: testharness + [scheduler: external SVG script added by SVG script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/136.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/136.html.ini new file mode 100644 index 00000000000..1b004e27442 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/136.html.ini @@ -0,0 +1,5 @@ +[136.html] + type: testharness + [scheduler: DOM added external SVG script, force-async? ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/137.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/137.html.ini new file mode 100644 index 00000000000..60d25da62d0 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/137.html.ini @@ -0,0 +1,5 @@ +[137.html] + type: testharness + [scheduler: SVG script empty xlink:href] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/138.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/138.html.ini new file mode 100644 index 00000000000..9ed9fac3f38 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/138.html.ini @@ -0,0 +1,5 @@ +[138.html] + type: testharness + [scheduler: SVG script nested inlines] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/139.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/139.html.ini new file mode 100644 index 00000000000..e25521e5d78 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/139.html.ini @@ -0,0 +1,5 @@ +[139.html] + type: testharness + [scheduler: SVG script nested external in inline] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/140.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/140.html.ini new file mode 100644 index 00000000000..0adde53fa01 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/140.html.ini @@ -0,0 +1,5 @@ +[140.html] + type: testharness + [scheduler: SVG script nested inline in external] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/141.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/141.html.ini new file mode 100644 index 00000000000..3a624abf612 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/141.html.ini @@ -0,0 +1,5 @@ +[141.html] + type: testharness + [scheduler: SVG inline script that document.writes inline script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/142.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/142.html.ini new file mode 100644 index 00000000000..ccbb572791f --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/142.html.ini @@ -0,0 +1,5 @@ +[142.html] + type: testharness + [scheduler: SVG inline script that document.writes external script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/143.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/143.html.ini new file mode 100644 index 00000000000..7d5beedc6c0 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/143.html.ini @@ -0,0 +1,5 @@ +[143.html] + type: testharness + [scheduler: SVG nested inline script that document.writes inline script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/144.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/144.html.ini new file mode 100644 index 00000000000..3ecec584b46 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/144.html.ini @@ -0,0 +1,5 @@ +[144.html] + type: testharness + [scheduler: SVG inline script changing the type attribute ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/145.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/145.html.ini new file mode 100644 index 00000000000..b4836dc60d5 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/145.html.ini @@ -0,0 +1,5 @@ +[145.html] + type: testharness + [scheduler: SVG inline script adding text to empty script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/146.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/146.html.ini new file mode 100644 index 00000000000..c5cde10199c --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/146.html.ini @@ -0,0 +1,5 @@ +[146.html] + type: testharness + [scheduler: SVG script adding src attribute ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/147.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/147.html.ini new file mode 100644 index 00000000000..a25122a5700 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/147.html.ini @@ -0,0 +1,5 @@ +[147.html] + type: testharness + [scheduler: insert multiple inline scripts; first script moves subsequent scripts ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/148.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/148.html.ini new file mode 100644 index 00000000000..ba194bd5e8a --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/148.html.ini @@ -0,0 +1,5 @@ +[148.html] + type: testharness + [scheduler: insert multiple inline scripts; first script deletes subsequent script ] + expected: FAIL + diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/149.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/149.html.ini new file mode 100644 index 00000000000..6169104f1ec --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/149.html.ini @@ -0,0 +1,20 @@ +[149.html] + type: testharness + [for=\'window\' event=\'onload()\' parser inserted executes immediately] + expected: FAIL + + [for=\'window\' event=\'onload\' parser inserted executes immediately] + expected: FAIL + + [for=\' WINdow\t\n\' event=\'ONload\t\n\' parser inserted executes immediately] + expected: FAIL + + [for=\'window\' event=\'onload()\' dom inserted executes immediately] + expected: FAIL + + [for=\'window\' event=\'onload\' dom inserted executes immediately] + expected: FAIL + + [for=\' WINdow\t\n\' event=\'ONload\t\n\' dom inserted executes immediately] + expected: FAIL + |