diff options
198 files changed, 4703 insertions, 1928 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 60bfbdc35e2..572ecfdb50d 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -13,32 +13,32 @@ use windowing::{MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg} use geom::point::{Point2D, TypedPoint2D}; use geom::rect::{Rect, TypedRect}; -use geom::size::{Size2D, TypedSize2D}; use geom::scale_factor::ScaleFactor; +use geom::size::{Size2D, TypedSize2D}; use gfx::color; use gfx::paint_task::Msg as PaintMsg; use gfx::paint_task::PaintRequest; +use gleam::gl::types::{GLint, GLsizei}; +use gleam::gl; use layers::geometry::{DevicePixel, LayerPixel}; use layers::layers::{BufferRequest, Layer, LayerBuffer, LayerBufferSet}; -use layers::rendergl; use layers::rendergl::RenderContext; +use layers::rendergl; use layers::scene::Scene; -use png; -use gleam::gl::types::{GLint, GLsizei}; -use gleam::gl; -use script_traits::{ConstellationControlMsg, ScriptControlChan}; use msg::compositor_msg::{Epoch, LayerId}; use msg::compositor_msg::{ReadyState, PaintState, ScrollPolicy}; -use msg::constellation_msg::{ConstellationChan, NavigationDirection}; use msg::constellation_msg::Msg as ConstellationMsg; +use msg::constellation_msg::{ConstellationChan, NavigationDirection}; use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData}; use msg::constellation_msg::{PipelineId, WindowSizeData}; +use png; use profile::mem; use profile::time::{self, ProfilerCategory, profile}; +use script_traits::{ConstellationControlMsg, ScriptControlChan}; use std::cmp; use std::collections::HashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; -use std::mem::replace; +use std::mem as std_mem; use std::num::Float; use std::rc::Rc; use std::slice::bytes::copy_memory; @@ -93,7 +93,7 @@ pub struct IOCompositor<Window: WindowMethods> { shutdown_state: ShutdownState, /// Tracks outstanding paint_msg's sent to the paint tasks. - outstanding_paint_msgs: uint, + outstanding_paint_msgs: u32, /// Tracks the last composite time. last_composite_time: u64, @@ -164,6 +164,9 @@ struct PipelineDetails { /// The status of this pipeline's PaintTask. paint_state: PaintState, + + /// Whether animations are running. + animations_running: bool, } impl PipelineDetails { @@ -172,6 +175,7 @@ impl PipelineDetails { pipeline: None, ready_state: ReadyState::Blank, paint_state: PaintState::Painting, + animations_running: false, } } } @@ -272,6 +276,11 @@ impl<Window: WindowMethods> IOCompositor<Window> { self.change_paint_state(pipeline_id, paint_state); } + (Msg::ChangeRunningAnimationsState(pipeline_id, running_animations), + ShutdownState::NotShuttingDown) => { + self.change_running_animations_state(pipeline_id, running_animations); + } + (Msg::ChangePageTitle(pipeline_id, title), ShutdownState::NotShuttingDown) => { self.change_page_title(pipeline_id, title); } @@ -311,7 +320,8 @@ impl<Window: WindowMethods> IOCompositor<Window> { self.set_layer_rect(pipeline_id, layer_id, &rect); } - (Msg::AssignPaintedBuffers(pipeline_id, epoch, replies), ShutdownState::NotShuttingDown) => { + (Msg::AssignPaintedBuffers(pipeline_id, epoch, replies), + ShutdownState::NotShuttingDown) => { for (layer_id, new_layer_buffer_set) in replies.into_iter() { self.assign_painted_buffers(pipeline_id, layer_id, new_layer_buffer_set, epoch); } @@ -399,6 +409,18 @@ impl<Window: WindowMethods> IOCompositor<Window> { self.window.set_paint_state(paint_state); } + /// Sets or unsets the animations-running flag for the given pipeline, and schedules a + /// recomposite if necessary. + fn change_running_animations_state(&mut self, + pipeline_id: PipelineId, + animations_running: bool) { + self.get_or_create_pipeline_details(pipeline_id).animations_running = animations_running; + + if animations_running { + self.composite_if_necessary(); + } + } + pub fn get_or_create_pipeline_details<'a>(&'a mut self, pipeline_id: PipelineId) -> &'a mut PipelineDetails { @@ -463,7 +485,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { self.has_paint_msg_tracking() && self.outstanding_paint_msgs > 0 } - fn add_outstanding_paint_msg(&mut self, count: uint) { + fn add_outstanding_paint_msg(&mut self, count: u32) { // return early if not tracking paint_msg's if !self.has_paint_msg_tracking() { return; @@ -867,15 +889,13 @@ impl<Window: WindowMethods> IOCompositor<Window> { fn process_pending_scroll_events(&mut self) { let had_scroll_events = self.pending_scroll_events.len() > 0; - for scroll_event in replace(&mut self.pending_scroll_events, Vec::new()).into_iter() { + for scroll_event in std_mem::replace(&mut self.pending_scroll_events, + Vec::new()).into_iter() { let delta = scroll_event.delta / self.scene.scale; let cursor = scroll_event.cursor.as_f32() / self.scene.scale; - match self.scene.root { - Some(ref mut layer) => { - layer.handle_scroll_event(delta, cursor); - } - None => {} + if let Some(ref mut layer) = self.scene.root { + layer.handle_scroll_event(delta, cursor); } self.start_scrolling_timer_if_necessary(); @@ -887,6 +907,16 @@ impl<Window: WindowMethods> IOCompositor<Window> { } } + /// If there are any animations running, dispatches appropriate messages to the constellation. + fn process_animations(&mut self) { + for (pipeline_id, pipeline_details) in self.pipeline_details.iter() { + if !pipeline_details.animations_running { + continue + } + self.constellation_chan.0.send(ConstellationMsg::TickAnimation(*pipeline_id)).unwrap(); + } + } + fn device_pixels_per_screen_px(&self) -> ScaleFactor<ScreenPx, DevicePixel, f32> { match opts::get().device_pixels_per_px { Some(device_pixels_per_px) => device_pixels_per_px, @@ -1086,7 +1116,8 @@ impl<Window: WindowMethods> IOCompositor<Window> { let mut framebuffer_ids = vec!(); let mut texture_ids = vec!(); - let (width, height) = (self.window_size.width.get() as usize, self.window_size.height.get() as usize); + let (width, height) = + (self.window_size.width.get() as usize, self.window_size.height.get() as usize); if output_image { framebuffer_ids = gl::gen_framebuffers(1); @@ -1172,6 +1203,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { self.composition_request = CompositionRequest::NoCompositingNecessary; self.process_pending_scroll_events(); + self.process_animations(); } fn composite_if_necessary(&mut self) { diff --git a/components/compositing/compositor_task.rs b/components/compositing/compositor_task.rs index f940ad820c5..c951f589965 100644 --- a/components/compositing/compositor_task.rs +++ b/components/compositing/compositor_task.rs @@ -201,6 +201,8 @@ pub enum Msg { ChangePageTitle(PipelineId, Option<String>), /// Alerts the compositor that the current page has changed its URL. ChangePageUrl(PipelineId, Url), + /// Alerts the compositor that the given pipeline has changed whether it is running animations. + ChangeRunningAnimationsState(PipelineId, bool), /// Alerts the compositor that a `PaintMsg` has been discarded. PaintMsgDiscarded, /// Replaces the current frame tree, typically called during main frame navigation. @@ -231,6 +233,7 @@ impl Debug for Msg { Msg::AssignPaintedBuffers(..) => write!(f, "AssignPaintedBuffers"), Msg::ChangeReadyState(..) => write!(f, "ChangeReadyState"), Msg::ChangePaintState(..) => write!(f, "ChangePaintState"), + Msg::ChangeRunningAnimationsState(..) => write!(f, "ChangeRunningAnimationsState"), Msg::ChangePageTitle(..) => write!(f, "ChangePageTitle"), Msg::ChangePageUrl(..) => write!(f, "ChangePageUrl"), Msg::PaintMsgDiscarded(..) => write!(f, "PaintMsgDiscarded"), diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs index 88e3a761cc5..f5cf8d1a0c8 100644 --- a/components/compositing/constellation.rs +++ b/components/compositing/constellation.rs @@ -11,33 +11,33 @@ use geom::point::Point2D; use geom::rect::{Rect, TypedRect}; use geom::scale_factor::ScaleFactor; use gfx::font_cache_task::FontCacheTask; -use layout_traits::LayoutTaskFactory; +use layout_traits::{LayoutControlMsg, LayoutTaskFactory}; use libc; -use script_traits::{CompositorEvent, ConstellationControlMsg}; -use script_traits::{ScriptControlChan, ScriptTaskFactory}; use msg::compositor_msg::LayerId; -use msg::constellation_msg::{self, ConstellationChan, Failure}; -use msg::constellation_msg::{IFrameSandboxState, NavigationDirection}; -use msg::constellation_msg::{Key, KeyState, KeyModifiers, LoadData}; -use msg::constellation_msg::{FrameId, PipelineExitType, PipelineId}; -use msg::constellation_msg::{SubpageId, WindowSizeData, MozBrowserEvent}; use msg::constellation_msg::Msg as ConstellationMsg; +use msg::constellation_msg::{FrameId, PipelineExitType, PipelineId}; +use msg::constellation_msg::{IFrameSandboxState, MozBrowserEvent, NavigationDirection}; +use msg::constellation_msg::{Key, KeyState, KeyModifiers, LoadData}; +use msg::constellation_msg::{SubpageId, WindowSizeData}; +use msg::constellation_msg::{self, ConstellationChan, Failure}; use net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient}; use net::resource_task::{self, ResourceTask}; use net::storage_task::{StorageTask, StorageTaskMsg}; use profile::mem; use profile::time; -use util::cursor::Cursor; -use util::geometry::PagePx; -use util::opts; -use util::task::spawn_named; +use script_traits::{CompositorEvent, ConstellationControlMsg}; +use script_traits::{ScriptControlChan, ScriptTaskFactory}; use std::borrow::ToOwned; use std::collections::HashMap; -use std::old_io as io; +use std::io::{self, Write}; use std::marker::PhantomData; use std::mem::replace; use std::sync::mpsc::{Receiver, channel}; use url::Url; +use util::cursor::Cursor; +use util::geometry::PagePx; +use util::opts; +use util::task::spawn_named; /// Maintains the pipelines and navigation context and grants permission to composite. pub struct Constellation<LTF, STF> { @@ -201,8 +201,10 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { time_profiler_chan: time_profiler_chan, mem_profiler_chan: mem_profiler_chan, window_size: WindowSizeData { - visible_viewport: opts::get().initial_window_size.as_f32() * ScaleFactor::new(1.0), - initial_viewport: opts::get().initial_window_size.as_f32() * ScaleFactor::new(1.0), + visible_viewport: opts::get().initial_window_size.as_f32() * + ScaleFactor::new(1.0), + initial_viewport: opts::get().initial_window_size.as_f32() * + ScaleFactor::new(1.0), device_pixel_ratio: ScaleFactor::new(1.0), }, phantom: PhantomData, @@ -321,7 +323,10 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { new_subpage_id, old_subpage_id, sandbox) => { - debug!("constellation got iframe URL load message {:?} {:?} {:?}", source_pipeline_id, old_subpage_id, new_subpage_id); + debug!("constellation got iframe URL load message {:?} {:?} {:?}", + source_pipeline_id, + old_subpage_id, + new_subpage_id); self.handle_script_loaded_url_in_iframe_msg(url, source_pipeline_id, new_subpage_id, @@ -329,6 +334,12 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { sandbox); } ConstellationMsg::SetCursor(cursor) => self.handle_set_cursor_msg(cursor), + ConstellationMsg::ChangeRunningAnimationsState(pipeline_id, animations_running) => { + self.handle_change_running_animations_state(pipeline_id, animations_running) + } + ConstellationMsg::TickAnimation(pipeline_id) => { + self.handle_tick_animation(pipeline_id) + } // Load a new page, usually -- but not always -- from a mouse click or typed url // If there is already a pending page (self.pending_frames), it will not be overridden; // However, if the id is not encompassed by another change, it will be. @@ -399,8 +410,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { // It's quite difficult to make Servo exit cleanly if some tasks have failed. // Hard fail exists for test runners so we crash and that's good enough. let mut stderr = io::stderr(); - stderr.write_str("Pipeline failed in hard-fail mode. Crashing!\n").unwrap(); - stderr.flush().unwrap(); + stderr.write_all("Pipeline failed in hard-fail mode. Crashing!\n".as_bytes()).unwrap(); unsafe { libc::exit(1); } } @@ -421,15 +431,19 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { debug!("creating replacement pipeline for about:failure"); let window_rect = self.pipeline(pipeline_id).rect; - let new_pipeline_id = self.new_pipeline(parent_info, window_rect, None, - LoadData::new(Url::parse("about:failure").unwrap())); + let new_pipeline_id = + self.new_pipeline(parent_info, + window_rect, + None, + LoadData::new(Url::parse("about:failure").unwrap())); self.push_pending_frame(new_pipeline_id, Some(pipeline_id)); } fn handle_init_load(&mut self, url: Url) { let window_rect = Rect(Point2D::zero(), self.window_size.visible_viewport); - let root_pipeline_id = self.new_pipeline(None, Some(window_rect), None, LoadData::new(url)); + let root_pipeline_id = + self.new_pipeline(None, Some(window_rect), None, LoadData::new(url)); self.push_pending_frame(root_pipeline_id, None); } @@ -510,6 +524,21 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { self.compositor_proxy.send(CompositorMsg::SetCursor(cursor)) } + fn handle_change_running_animations_state(&mut self, + pipeline_id: PipelineId, + animations_running: bool) { + self.compositor_proxy.send(CompositorMsg::ChangeRunningAnimationsState(pipeline_id, + animations_running)) + } + + fn handle_tick_animation(&mut self, pipeline_id: PipelineId) { + self.pipeline(pipeline_id) + .layout_chan + .0 + .send(LayoutControlMsg::TickAnimationsMsg) + .unwrap(); + } + fn handle_load_url_msg(&mut self, source_id: PipelineId, load_data: LoadData) { // If this load targets an iframe, its framing element may exist // in a separate script task than the framed document that initiated @@ -908,7 +937,9 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { } fn find_subpage(&mut self, containing_pipeline_id: PipelineId, subpage_id: SubpageId) -> &mut Pipeline { - let pipeline_id = *self.subpage_map.get(&(containing_pipeline_id, subpage_id)).expect("no subpage pipeline_id"); + let pipeline_id = *self.subpage_map + .get(&(containing_pipeline_id, subpage_id)) + .expect("no subpage pipeline_id"); self.mut_pipeline(pipeline_id) } } diff --git a/components/compositing/headless.rs b/components/compositing/headless.rs index 27cac151f31..72a5b0c961e 100644 --- a/components/compositing/headless.rs +++ b/components/compositing/headless.rs @@ -98,6 +98,7 @@ impl CompositorEventListener for NullCompositor { Msg::AssignPaintedBuffers(..) | Msg::ChangeReadyState(..) | Msg::ChangePaintState(..) | + Msg::ChangeRunningAnimationsState(..) | Msg::ScrollFragmentPoint(..) | Msg::LoadComplete | Msg::PaintMsgDiscarded(..) | diff --git a/components/compositing/lib.rs b/components/compositing/lib.rs index 11f702b71d1..d8e2a2a95b8 100644 --- a/components/compositing/lib.rs +++ b/components/compositing/lib.rs @@ -5,6 +5,7 @@ #![feature(box_syntax)] #![feature(core)] #![feature(int_uint)] +#![feature(io)] #![feature(old_io)] #![feature(rustc_private)] #![feature(std_misc)] diff --git a/components/compositing/pipeline.rs b/components/compositing/pipeline.rs index 4f9b54eed36..21c5c9460fb 100644 --- a/components/compositing/pipeline.rs +++ b/components/compositing/pipeline.rs @@ -31,6 +31,7 @@ pub struct Pipeline { pub id: PipelineId, pub parent_info: Option<(PipelineId, SubpageId)>, pub script_chan: ScriptControlChan, + /// A channel to layout, for performing reflows and shutdown. pub layout_chan: LayoutControlChan, pub paint_chan: PaintChan, pub layout_shutdown_port: Receiver<()>, @@ -40,6 +41,9 @@ pub struct Pipeline { /// The title of the most recently-loaded page. pub title: Option<String>, pub rect: Option<TypedRect<PagePx, f32>>, + /// Whether this pipeline is currently running animations. Pipelines that are running + /// animations cause composites to be continually scheduled. + pub running_animations: bool, pub children: Vec<FrameId>, } @@ -113,12 +117,14 @@ impl Pipeline { ScriptControlChan(script_chan) } Some(script_chan) => { - let (containing_pipeline_id, subpage_id) = parent_info.expect("script_pipeline != None but subpage_id == None"); + let (containing_pipeline_id, subpage_id) = + parent_info.expect("script_pipeline != None but subpage_id == None"); let new_layout_info = NewLayoutInfo { containing_pipeline_id: containing_pipeline_id, new_pipeline_id: id, subpage_id: subpage_id, - layout_chan: ScriptTaskFactory::clone_layout_channel(None::<&mut STF>, &layout_pair), + layout_chan: ScriptTaskFactory::clone_layout_channel(None::<&mut STF>, + &layout_pair), load_data: load_data.clone(), }; @@ -186,6 +192,7 @@ impl Pipeline { title: None, children: vec!(), rect: rect, + running_animations: false, } } diff --git a/components/gfx/Cargo.toml b/components/gfx/Cargo.toml index bb213624240..b012c92b6d8 100644 --- a/components/gfx/Cargo.toml +++ b/components/gfx/Cargo.toml @@ -66,6 +66,9 @@ branch = "upstream-2014-06-16" [dependencies.script_traits] path = "../script_traits" +[dependencies.string_cache] +git = "https://github.com/servo/string-cache" + [dependencies] url = "0.2.16" time = "0.1.12" diff --git a/components/gfx/font_cache_task.rs b/components/gfx/font_cache_task.rs index 8a87ed9fdb0..e22fe434f85 100644 --- a/components/gfx/font_cache_task.rs +++ b/components/gfx/font_cache_task.rs @@ -9,16 +9,17 @@ use platform::font_list::get_last_resort_font_families; use platform::font_context::FontContextHandle; use collections::str::Str; +use font_template::{FontTemplate, FontTemplateDescriptor}; +use net::resource_task::{ResourceTask, load_whole_resource}; +use platform::font_template::FontTemplateData; use std::borrow::ToOwned; use std::collections::HashMap; use std::sync::Arc; use std::sync::mpsc::{Sender, Receiver, channel}; -use font_template::{FontTemplate, FontTemplateDescriptor}; -use platform::font_template::FontTemplateData; -use net::resource_task::{ResourceTask, load_whole_resource}; -use util::task::spawn_named; -use util::str::LowercaseString; +use string_cache::Atom; use style::font_face::Source; +use util::str::LowercaseString; +use util::task::spawn_named; /// A list of font templates that make up a given font family. struct FontFamily { @@ -77,7 +78,7 @@ impl FontFamily { pub enum Command { GetFontTemplate(String, FontTemplateDescriptor, Sender<Reply>), GetLastResortFontTemplate(FontTemplateDescriptor, Sender<Reply>), - AddWebFont(String, Source, Sender<()>), + AddWebFont(Atom, Source, Sender<()>), Exit(Sender<()>), } @@ -315,7 +316,7 @@ impl FontCacheTask { } } - pub fn add_web_font(&self, family: String, src: Source) { + pub fn add_web_font(&self, family: Atom, src: Source) { let (response_chan, response_port) = channel(); self.chan.send(Command::AddWebFont(family, src, response_chan)).unwrap(); response_port.recv().unwrap(); diff --git a/components/gfx/font_context.rs b/components/gfx/font_context.rs index 24574676f65..fe9dbab2b12 100644 --- a/components/gfx/font_context.rs +++ b/components/gfx/font_context.rs @@ -7,19 +7,24 @@ use font::SpecifiedFontStyle; use platform::font_context::FontContextHandle; use style::computed_values::{font_style, font_variant}; +use font::FontHandleMethods; use font_cache_task::FontCacheTask; use font_template::FontTemplateDescriptor; -use platform::font_template::FontTemplateData; -use font::FontHandleMethods; use platform::font::FontHandle; +use platform::font_template::FontTemplateData; +use util::arc_ptr_eq; use util::cache::HashCache; -use util::smallvec::{SmallVec, SmallVec8}; +use util::fnv::FnvHasher; use util::geometry::Au; -use util::arc_ptr_eq; +use util::smallvec::{SmallVec, SmallVec8}; -use std::borrow::ToOwned; -use std::rc::Rc; +use std::borrow::{self, ToOwned}; use std::cell::RefCell; +use std::collections::HashMap; +use std::collections::hash_state::DefaultState; +use std::default::Default; +use std::hash::{Hash, Hasher}; +use std::rc::Rc; use std::sync::Arc; use azure::AzFloat; @@ -76,8 +81,8 @@ pub struct FontContext { /// per frame. TODO: Make this weak when incremental redraw is done. paint_font_cache: Vec<PaintFontCacheEntry>, - last_style: Option<Arc<SpecifiedFontStyle>>, - last_fontgroup: Option<Rc<FontGroup>>, + layout_font_group_cache: + HashMap<LayoutFontGroupCacheKey,Rc<FontGroup>,DefaultState<FnvHasher>>, } impl FontContext { @@ -89,8 +94,7 @@ impl FontContext { layout_font_cache: vec!(), fallback_font_cache: vec!(), paint_font_cache: vec!(), - last_style: None, - last_fontgroup: None, + layout_font_group_cache: HashMap::with_hash_state(Default::default()), } } @@ -132,14 +136,21 @@ impl FontContext { /// this context. pub fn get_layout_font_group_for_style(&mut self, style: Arc<SpecifiedFontStyle>) -> Rc<FontGroup> { - let matches = match self.last_style { - Some(ref last_style) => arc_ptr_eq(&style, last_style), - None => false, - }; - if matches { - return self.last_fontgroup.as_ref().unwrap().clone(); + let address = &*style as *const SpecifiedFontStyle as usize; + if let Some(ref cached_font_group) = self.layout_font_group_cache.get(&address) { + return (*cached_font_group).clone() } + let layout_font_group_cache_key = LayoutFontGroupCacheKey { + pointer: style.clone(), + size: style.font_size, + address: address, + }; + if let Some(ref cached_font_group) = + self.layout_font_group_cache.get(&layout_font_group_cache_key) { + return (*cached_font_group).clone() + } + // TODO: The font context holds a strong ref to the cached fonts // so they will never be released. Find out a good time to drop them. @@ -147,6 +158,7 @@ impl FontContext { style.font_stretch, style.font_style == font_style::T::italic || style.font_style == font_style::T::oblique); + let mut fonts = SmallVec8::new(); for family in style.font_family.iter() { @@ -160,7 +172,7 @@ impl FontContext { break; } Some(ref cached_font_ref) => { - let cached_font = cached_font_ref.borrow(); + let cached_font = (*cached_font_ref).borrow(); if cached_font.descriptor == desc && cached_font.requested_pt_size == style.font_size && cached_font.variant == style.font_variant { @@ -243,8 +255,7 @@ impl FontContext { } let font_group = Rc::new(FontGroup::new(fonts)); - self.last_style = Some(style); - self.last_fontgroup = Some(font_group.clone()); + self.layout_font_group_cache.insert(layout_font_group_cache_key, font_group.clone()); font_group } @@ -275,3 +286,34 @@ impl FontContext { self.font_cache_task.clone() } } + +struct LayoutFontGroupCacheKey { + pointer: Arc<SpecifiedFontStyle>, + size: Au, + address: usize, +} + +impl PartialEq for LayoutFontGroupCacheKey { + fn eq(&self, other: &LayoutFontGroupCacheKey) -> bool { + self.pointer.font_family == other.pointer.font_family && + self.pointer.font_stretch == other.pointer.font_stretch && + self.pointer.font_style == other.pointer.font_style && + self.pointer.font_weight as u16 == other.pointer.font_weight as u16 && + self.size == other.size + } +} + +impl Eq for LayoutFontGroupCacheKey {} + +impl Hash for LayoutFontGroupCacheKey { + fn hash<H>(&self, hasher: &mut H) where H: Hasher { + self.pointer.hash.hash(hasher) + } +} + +impl borrow::Borrow<usize> for LayoutFontGroupCacheKey { + fn borrow(&self) -> &usize { + &self.address + } +} + diff --git a/components/gfx/font_template.rs b/components/gfx/font_template.rs index 736c8dfad41..50cf8c57fee 100644 --- a/components/gfx/font_template.rs +++ b/components/gfx/font_template.rs @@ -11,11 +11,11 @@ use std::borrow::ToOwned; use std::sync::{Arc, Weak}; use style::computed_values::{font_stretch, font_weight}; -/// Describes how to select a font from a given family. -/// This is very basic at the moment and needs to be -/// expanded or refactored when we support more of the -/// font styling parameters. -#[derive(Clone, Copy)] +/// Describes how to select a font from a given family. This is very basic at the moment and needs +/// to be expanded or refactored when we support more of the font styling parameters. +/// +/// NB: If you change this, you will need to update `style::properties::compute_font_hash()`. +#[derive(Clone, Copy, Eq, Hash)] pub struct FontTemplateDescriptor { pub weight: font_weight::T, pub stretch: font_stretch::T, diff --git a/components/gfx/lib.rs b/components/gfx/lib.rs index 0be282fb8f6..e1183753d5e 100644 --- a/components/gfx/lib.rs +++ b/components/gfx/lib.rs @@ -35,6 +35,7 @@ extern crate net; #[macro_use] extern crate util; extern crate msg; +extern crate string_cache; extern crate style; extern crate skia; extern crate time; diff --git a/components/gfx/paint_context.rs b/components/gfx/paint_context.rs index 88c031a165f..da15dc6b2ae 100644 --- a/components/gfx/paint_context.rs +++ b/components/gfx/paint_context.rs @@ -1199,7 +1199,7 @@ impl ScaledFontExtensionMethods for ScaledFont { let mut origin = baseline_origin.clone(); let mut azglyphs = vec!(); - azglyphs.reserve(range.length().to_uint()); + azglyphs.reserve(range.length().to_usize()); for slice in run.natural_word_slices_in_range(range) { for (_i, glyph) in slice.glyphs.iter_glyphs_for_char_range(&slice.range) { diff --git a/components/gfx/paint_task.rs b/components/gfx/paint_task.rs index 470bea78e7b..d4a95b6e619 100644 --- a/components/gfx/paint_task.rs +++ b/components/gfx/paint_task.rs @@ -330,13 +330,13 @@ impl<C> PaintTask<C> where C: PaintListener + Send + 'static { }) } - /// Paints one layer and sends the tiles back to the layer. + /// Paints one layer and places the painted tiles in `replies`. fn paint(&mut self, replies: &mut Vec<(LayerId, Box<LayerBufferSet>)>, mut tiles: Vec<BufferRequest>, scale: f32, layer_id: LayerId) { - profile(time::ProfilerCategory::Painting, None, self.time_profiler_chan.clone(), || { + time::profile(time::ProfilerCategory::Painting, None, self.time_profiler_chan.clone(), || { // Bail out if there is no appropriate stacking context. let stacking_context = if let Some(ref stacking_context) = self.root_stacking_context { match display_list::find_stacking_context_with_layer_id(stacking_context, @@ -559,8 +559,10 @@ impl WorkerThread { paint_context.clear(); // Draw the display list. - profile(time::ProfilerCategory::PaintingPerTile, None, - self.time_profiler_sender.clone(), || { + time::profile(time::ProfilerCategory::PaintingPerTile, + None, + self.time_profiler_sender.clone(), + || { stacking_context.optimize_and_draw_into_context(&mut paint_context, &tile_bounds, &matrix, diff --git a/components/gfx/text/glyph.rs b/components/gfx/text/glyph.rs index 4ed96281a85..5ebd33916e8 100644 --- a/components/gfx/text/glyph.rs +++ b/components/gfx/text/glyph.rs @@ -455,7 +455,7 @@ pub enum GlyphInfo<'a> { impl<'a> GlyphInfo<'a> { pub fn id(self) -> GlyphId { match self { - GlyphInfo::Simple(store, entry_i) => store.entry_buffer[entry_i.to_uint()].id(), + GlyphInfo::Simple(store, entry_i) => store.entry_buffer[entry_i.to_usize()].id(), GlyphInfo::Detail(store, entry_i, detail_j) => { store.detail_store.get_detailed_glyph_with_index(entry_i, detail_j).id } @@ -466,7 +466,7 @@ impl<'a> GlyphInfo<'a> { // FIXME: Resolution conflicts with IteratorUtil trait so adding trailing _ pub fn advance(self) -> Au { match self { - GlyphInfo::Simple(store, entry_i) => store.entry_buffer[entry_i.to_uint()].advance(), + GlyphInfo::Simple(store, entry_i) => store.entry_buffer[entry_i.to_usize()].advance(), GlyphInfo::Detail(store, entry_i, detail_j) => { store.detail_store.get_detailed_glyph_with_index(entry_i, detail_j).advance } @@ -575,13 +575,13 @@ impl<'a> GlyphStore { }; // FIXME(pcwalton): Is this necessary? I think it's a no-op. - entry = entry.adapt_character_flags_of_entry(self.entry_buffer[i.to_uint()]); + entry = entry.adapt_character_flags_of_entry(self.entry_buffer[i.to_usize()]); if character == Some(' ') { entry = entry.set_char_is_space() } - self.entry_buffer[i.to_uint()] = entry; + self.entry_buffer[i.to_usize()] = entry; } pub fn add_glyphs_for_char_index(&mut self, i: CharIndex, data_for_glyphs: &[GlyphData]) { @@ -605,11 +605,11 @@ impl<'a> GlyphStore { first_glyph_data.ligature_start, glyph_count) } - }.adapt_character_flags_of_entry(self.entry_buffer[i.to_uint()]); + }.adapt_character_flags_of_entry(self.entry_buffer[i.to_usize()]); debug!("Adding multiple glyphs[idx={:?}, count={}]: {:?}", i, glyph_count, entry); - self.entry_buffer[i.to_uint()] = entry; + self.entry_buffer[i.to_usize()] = entry; } // used when a character index has no associated glyph---for example, a ligature continuation. @@ -619,7 +619,7 @@ impl<'a> GlyphStore { let entry = GlyphEntry::complex(cluster_start, ligature_start, 0); debug!("adding spacer for chracter without associated glyph[idx={:?}]", i); - self.entry_buffer[i.to_uint()] = entry; + self.entry_buffer[i.to_usize()] = entry; } pub fn iter_glyphs_for_char_index(&'a self, i: CharIndex) -> GlyphIterator<'a> { @@ -652,57 +652,57 @@ impl<'a> GlyphStore { // getter methods pub fn char_is_space(&self, i: CharIndex) -> bool { assert!(i < self.char_len()); - self.entry_buffer[i.to_uint()].char_is_space() + self.entry_buffer[i.to_usize()].char_is_space() } pub fn char_is_tab(&self, i: CharIndex) -> bool { assert!(i < self.char_len()); - self.entry_buffer[i.to_uint()].char_is_tab() + self.entry_buffer[i.to_usize()].char_is_tab() } pub fn char_is_newline(&self, i: CharIndex) -> bool { assert!(i < self.char_len()); - self.entry_buffer[i.to_uint()].char_is_newline() + self.entry_buffer[i.to_usize()].char_is_newline() } pub fn is_ligature_start(&self, i: CharIndex) -> bool { assert!(i < self.char_len()); - self.entry_buffer[i.to_uint()].is_ligature_start() + self.entry_buffer[i.to_usize()].is_ligature_start() } pub fn is_cluster_start(&self, i: CharIndex) -> bool { assert!(i < self.char_len()); - self.entry_buffer[i.to_uint()].is_cluster_start() + self.entry_buffer[i.to_usize()].is_cluster_start() } pub fn can_break_before(&self, i: CharIndex) -> BreakType { assert!(i < self.char_len()); - self.entry_buffer[i.to_uint()].can_break_before() + self.entry_buffer[i.to_usize()].can_break_before() } // setter methods pub fn set_char_is_space(&mut self, i: CharIndex) { assert!(i < self.char_len()); - let entry = self.entry_buffer[i.to_uint()]; - self.entry_buffer[i.to_uint()] = entry.set_char_is_space(); + let entry = self.entry_buffer[i.to_usize()]; + self.entry_buffer[i.to_usize()] = entry.set_char_is_space(); } pub fn set_char_is_tab(&mut self, i: CharIndex) { assert!(i < self.char_len()); - let entry = self.entry_buffer[i.to_uint()]; - self.entry_buffer[i.to_uint()] = entry.set_char_is_tab(); + let entry = self.entry_buffer[i.to_usize()]; + self.entry_buffer[i.to_usize()] = entry.set_char_is_tab(); } pub fn set_char_is_newline(&mut self, i: CharIndex) { assert!(i < self.char_len()); - let entry = self.entry_buffer[i.to_uint()]; - self.entry_buffer[i.to_uint()] = entry.set_char_is_newline(); + let entry = self.entry_buffer[i.to_usize()]; + self.entry_buffer[i.to_usize()] = entry.set_char_is_newline(); } pub fn set_can_break_before(&mut self, i: CharIndex, t: BreakType) { assert!(i < self.char_len()); - let entry = self.entry_buffer[i.to_uint()]; - self.entry_buffer[i.to_uint()] = entry.set_can_break_before(t); + let entry = self.entry_buffer[i.to_usize()]; + self.entry_buffer[i.to_usize()] = entry.set_can_break_before(t); } pub fn space_count_in_range(&self, range: &Range<CharIndex>) -> u32 { @@ -723,7 +723,7 @@ impl<'a> GlyphStore { for index in range.each_index() { // TODO(pcwalton): Handle spaces that are detailed glyphs -- these are uncommon but // possible. - let entry = &mut self.entry_buffer[index.to_uint()]; + let entry = &mut self.entry_buffer[index.to_usize()]; if entry.is_simple() && entry.char_is_space() { // FIXME(pcwalton): This can overflow for very large font-sizes. let advance = @@ -789,7 +789,7 @@ impl<'a> Iterator for GlyphIterator<'a> { self.char_range.next().and_then(|i| { self.char_index = i; assert!(i < self.store.char_len()); - let entry = self.store.entry_buffer[i.to_uint()]; + let entry = self.store.entry_buffer[i.to_usize()]; if entry.is_simple() { Some((self.char_index, GlyphInfo::Simple(self.store, i))) } else { diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml index 2eee5eb3d4a..88f28089a3f 100644 --- a/components/layout/Cargo.toml +++ b/components/layout/Cargo.toml @@ -61,9 +61,13 @@ git = "https://github.com/servo/string-cache" [dependencies.png] git = "https://github.com/servo/rust-png" +[dependencies.clock_ticks] +git = "https://github.com/tomaka/clock_ticks" + [dependencies] encoding = "0.2" url = "0.2.16" bitflags = "*" rustc-serialize = "0.3" libc = "*" + diff --git a/components/layout/animation.rs b/components/layout/animation.rs new file mode 100644 index 00000000000..571228afccb --- /dev/null +++ b/components/layout/animation.rs @@ -0,0 +1,104 @@ +/* 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/. */ + +//! CSS transitions and animations. + +use flow::{self, Flow}; +use incremental::{self, RestyleDamage}; + +use clock_ticks; +use gfx::display_list::OpaqueNode; +use layout_task::{LayoutTask, LayoutTaskData}; +use msg::constellation_msg::{Msg, PipelineId}; +use script::layout_interface::Animation; +use std::mem; +use std::sync::mpsc::Sender; +use style::animation::{GetMod, PropertyAnimation}; +use style::properties::ComputedValues; + +/// Inserts transitions into the queue of running animations as applicable for the given style +/// difference. This is called from the layout worker threads. +pub fn start_transitions_if_applicable(new_animations_sender: &Sender<Animation>, + node: OpaqueNode, + old_style: &ComputedValues, + new_style: &mut ComputedValues) { + for i in range(0, new_style.get_animation().transition_property.0.len()) { + // Create any property animations, if applicable. + let property_animations = PropertyAnimation::from_transition(i, old_style, new_style); + for property_animation in property_animations.into_iter() { + // Set the property to the initial value. + property_animation.update(new_style, 0.0); + + // Kick off the animation. + let now = clock_ticks::precise_time_s(); + let animation_style = new_style.get_animation(); + let start_time = now + animation_style.transition_delay.0.get_mod(i).seconds(); + new_animations_sender.send(Animation { + node: node.id(), + property_animation: property_animation, + start_time: start_time, + end_time: start_time + + animation_style.transition_duration.0.get_mod(i).seconds(), + }).unwrap() + } + } +} + +/// Processes any new animations that were discovered after style recalculation. +pub fn process_new_animations(rw_data: &mut LayoutTaskData, pipeline_id: PipelineId) { + while let Ok(animation) = rw_data.new_animations_receiver.try_recv() { + rw_data.running_animations.push(animation) + } + + let animations_are_running = !rw_data.running_animations.is_empty(); + rw_data.constellation_chan + .0 + .send(Msg::ChangeRunningAnimationsState(pipeline_id, animations_are_running)) + .unwrap(); +} + +/// Recalculates style for an animation. This does *not* run with the DOM lock held. +pub fn recalc_style_for_animation(flow: &mut Flow, animation: &Animation) { + let mut damage = RestyleDamage::empty(); + flow.mutate_fragments(&mut |fragment| { + if fragment.node.id() != animation.node { + return + } + + let now = clock_ticks::precise_time_s(); + let mut progress = (now - animation.start_time) / animation.duration(); + if progress > 1.0 { + progress = 1.0 + } + if progress <= 0.0 { + return + } + + let mut new_style = fragment.style.clone(); + animation.property_animation.update(&mut *new_style.make_unique(), progress); + damage.insert(incremental::compute_damage(&Some(fragment.style.clone()), &new_style)); + fragment.style = new_style + }); + + let base = flow::mut_base(flow); + base.restyle_damage.insert(damage); + for kid in base.children.iter_mut() { + recalc_style_for_animation(kid, animation) + } +} + +/// Handles animation updates. +pub fn tick_all_animations(layout_task: &LayoutTask, rw_data: &mut LayoutTaskData) { + let running_animations = mem::replace(&mut rw_data.running_animations, Vec::new()); + let now = clock_ticks::precise_time_s(); + for running_animation in running_animations.into_iter() { + layout_task.tick_animation(running_animation, rw_data); + + if now < running_animation.end_time { + // Keep running the animation if it hasn't expired. + rw_data.running_animations.push(running_animation) + } + } +} + diff --git a/components/layout/block.rs b/components/layout/block.rs index 231f406d25a..980bf6b5204 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -72,9 +72,6 @@ pub struct FloatedBlockInfo { /// box). pub float_ceiling: Au, - /// Index into the fragment list for inline floats - pub index: Option<uint>, - /// Left or right? pub float_kind: FloatKind, } @@ -84,7 +81,6 @@ impl FloatedBlockInfo { FloatedBlockInfo { containing_inline_size: Au(0), float_ceiling: Au(0), - index: None, float_kind: float_kind, } } @@ -1453,9 +1449,7 @@ impl BlockFlow { let info = PlacementInfo { size: LogicalSize::new(self.fragment.style.writing_mode, - self.base.position.size.inline + - self.fragment.margin.inline_start_end() + - self.fragment.border_padding.inline_start_end(), + self.base.position.size.inline, self.fragment.border_box.size.block), ceiling: self.base.position.start.b, max_inline_size: MAX_AU, @@ -1869,11 +1863,11 @@ impl Flow for BlockFlow { self.fragment.border_box - self.fragment.style().logical_border_width() } - fn layer_id(&self, fragment_index: uint) -> LayerId { + fn layer_id(&self, fragment_index: u32) -> LayerId { // FIXME(#2010, pcwalton): This is a hack and is totally bogus in the presence of pseudo- // elements. But until we have incremental reflow we can't do better--we recreate the flow // for every DOM node so otherwise we nuke layers on every reflow. - LayerId(self.fragment.node.id() as uint, fragment_index) + LayerId(self.fragment.node.id() as usize, fragment_index) } fn is_absolute_containing_block(&self) -> bool { diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 675f49a2be8..bf427dfbf99 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -19,7 +19,7 @@ use css::node_style::StyledNode; use data::{HAS_NEWLY_CONSTRUCTED_FLOW, LayoutDataAccess, LayoutDataWrapper}; use floats::FloatKind; use flow::{Descendants, AbsDescendants}; -use flow::{Flow, ImmutableFlowUtils, MutableOwnedFlowUtils}; +use flow::{Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils}; use flow::{IS_ABSOLUTELY_POSITIONED}; use flow; use flow_ref::FlowRef; @@ -85,10 +85,12 @@ impl ConstructionResult { return mem::replace(self, ConstructionResult::None) } + // FIXME(pcwalton): Stop doing this with inline fragments. Cloning fragments is very + // inefficient! (*self).clone() } - pub fn debug_id(&self) -> uint { + pub fn debug_id(&self) -> usize { match self { &ConstructionResult::None => 0u, &ConstructionResult::ConstructionItem(_) => 0u, @@ -1164,7 +1166,30 @@ impl<'a> FlowConstructor<'a> { // The node's flow is of the same type and has the same set of children and can // therefore be repaired by simply propagating damage and style to the flow. flow::mut_base(&mut *flow).restyle_damage.insert(node.restyle_damage()); - flow.repair_style(node.style()); + flow.repair_style_and_bubble_inline_sizes(node.style()); + true + } + ConstructionResult::ConstructionItem(ConstructionItem::InlineFragments( + mut inline_fragments_construction_result)) => { + if !inline_fragments_construction_result.splits.is_empty() { + return false + } + + let damage = node.restyle_damage(); + for fragment in inline_fragments_construction_result.fragments.iter_mut() { + match fragment.specific { + SpecificFragmentInfo::InlineBlock(ref mut inline_block_fragment) => { + flow::mut_base(&mut *inline_block_fragment.flow_ref).restyle_damage + .insert(damage); + // FIXME(pcwalton): Fragment restyle damage too? + inline_block_fragment.flow_ref.repair_style_and_bubble_inline_sizes( + node.style()); + } + _ => { + return false + } + } + } true } ConstructionResult::ConstructionItem(_) => { diff --git a/components/layout/context.rs b/components/layout/context.rs index 6c87ef63742..ae1c75e89e6 100644 --- a/components/layout/context.rs +++ b/components/layout/context.rs @@ -10,19 +10,20 @@ use css::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache}; use geom::{Rect, Size2D}; use gfx::display_list::OpaqueNode; -use gfx::font_context::FontContext; use gfx::font_cache_task::FontCacheTask; -use script::layout_interface::LayoutChan; -use script_traits::UntrustedNodeAddress; +use gfx::font_context::FontContext; use msg::constellation_msg::ConstellationChan; use net::local_image_cache::LocalImageCache; -use util::geometry::Au; +use script::layout_interface::{Animation, LayoutChan}; +use script_traits::UntrustedNodeAddress; use std::boxed; use std::cell::Cell; use std::ptr; +use std::sync::mpsc::Sender; use std::sync::{Arc, Mutex}; use style::selector_matching::Stylist; use url::Url; +use util::geometry::Au; struct LocalLayoutContext { font_context: FontContext, @@ -32,7 +33,8 @@ struct LocalLayoutContext { thread_local!(static LOCAL_CONTEXT_KEY: Cell<*mut LocalLayoutContext> = Cell::new(ptr::null_mut())); -fn create_or_get_local_context(shared_layout_context: &SharedLayoutContext) -> *mut LocalLayoutContext { +fn create_or_get_local_context(shared_layout_context: &SharedLayoutContext) + -> *mut LocalLayoutContext { LOCAL_CONTEXT_KEY.with(|ref r| { if r.get().is_null() { let context = box LocalLayoutContext { @@ -51,6 +53,7 @@ fn create_or_get_local_context(shared_layout_context: &SharedLayoutContext) -> * }) } +/// Layout information shared among all workers. This must be thread-safe. pub struct SharedLayoutContext { /// The local image cache. pub image_cache: Arc<Mutex<LocalImageCache<UntrustedNodeAddress>>>, @@ -76,7 +79,7 @@ pub struct SharedLayoutContext { pub stylist: *const Stylist, /// The root node at which we're starting the layout. - pub reflow_root: OpaqueNode, + pub reflow_root: Option<OpaqueNode>, /// The URL. pub url: Url, @@ -86,10 +89,15 @@ pub struct SharedLayoutContext { /// Starts at zero, and increased by one every time a layout completes. /// This can be used to easily check for invalid stale data. - pub generation: uint, + pub generation: u32, + + /// A channel on which new animations that have been triggered by style recalculation can be + /// sent. + pub new_animations_sender: Sender<Animation>, } pub struct SharedLayoutContextWrapper(pub *const SharedLayoutContext); + unsafe impl Send for SharedLayoutContextWrapper {} pub struct LayoutContext<'a> { diff --git a/components/layout/css/matching.rs b/components/layout/css/matching.rs index 8d25f7007f5..1c977c8081b 100644 --- a/components/layout/css/matching.rs +++ b/components/layout/css/matching.rs @@ -6,29 +6,33 @@ #![allow(unsafe_code)] +use animation; use context::SharedLayoutContext; use css::node_style::StyledNode; -use incremental::{self, RestyleDamage}; use data::{LayoutDataAccess, LayoutDataWrapper}; +use incremental::{self, RestyleDamage}; +use opaque_node::OpaqueNodeMethods; use wrapper::{LayoutElement, LayoutNode, TLayoutNode}; use script::dom::node::NodeTypeId; +use script::layout_interface::Animation; use selectors::bloom::BloomFilter; -use util::cache::{LRUCache, SimpleHashCache}; -use util::smallvec::{SmallVec, SmallVec16}; -use util::arc_ptr_eq; +use selectors::matching::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes}; +use selectors::matching::{common_style_affecting_attributes, rare_style_affecting_attributes}; +use selectors::parser::PseudoElement; use std::borrow::ToOwned; -use std::mem; use std::hash::{Hash, Hasher}; +use std::mem; use std::slice::Iter; +use std::sync::Arc; +use std::sync::mpsc::Sender; use string_cache::{Atom, Namespace}; -use selectors::parser::PseudoElement; -use style::selector_matching::{Stylist, DeclarationBlock}; use style::node::{TElement, TNode}; use style::properties::{ComputedValues, cascade}; -use selectors::matching::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes}; -use selectors::matching::{common_style_affecting_attributes, rare_style_affecting_attributes}; -use std::sync::Arc; +use style::selector_matching::{Stylist, DeclarationBlock}; +use util::arc_ptr_eq; +use util::cache::{LRUCache, SimpleHashCache}; +use util::smallvec::{SmallVec, SmallVec16}; pub struct ApplicableDeclarations { pub normal: SmallVec16<DeclarationBlock>, @@ -122,7 +126,7 @@ impl<'a> PartialEq<ApplicableDeclarationsCacheEntry> for ApplicableDeclarationsC impl<'a> Hash for ApplicableDeclarationsCacheQuery<'a> { fn hash<H: Hasher>(&self, state: &mut H) { for declaration in self.declarations.iter() { - let ptr: uint = unsafe { + let ptr: usize = unsafe { mem::transmute_copy(declaration) }; ptr.hash(state); @@ -130,7 +134,7 @@ impl<'a> Hash for ApplicableDeclarationsCacheQuery<'a> { } } -static APPLICABLE_DECLARATIONS_CACHE_SIZE: uint = 32; +static APPLICABLE_DECLARATIONS_CACHE_SIZE: usize = 32; pub struct ApplicableDeclarationsCache { cache: SimpleHashCache<ApplicableDeclarationsCacheEntry,Arc<ComputedValues>>, @@ -331,7 +335,7 @@ impl StyleSharingCandidate { } } -static STYLE_SHARING_CANDIDATE_CACHE_SIZE: uint = 40; +static STYLE_SHARING_CANDIDATE_CACHE_SIZE: usize = 40; impl StyleSharingCandidateCache { pub fn new() -> StyleSharingCandidateCache { @@ -351,7 +355,7 @@ impl StyleSharingCandidateCache { } } - pub fn touch(&mut self, index: uint) { + pub fn touch(&mut self, index: usize) { self.cache.touch(index) } } @@ -363,7 +367,7 @@ pub enum StyleSharingResult { CannotShare(bool), /// The node's style can be shared. The integer specifies the index in the LRU cache that was /// hit and the damage that was done. - StyleWasShared(uint, RestyleDamage), + StyleWasShared(usize, RestyleDamage), } pub trait MatchMethods { @@ -399,7 +403,8 @@ pub trait MatchMethods { layout_context: &SharedLayoutContext, parent: Option<LayoutNode>, applicable_declarations: &ApplicableDeclarations, - applicable_declarations_cache: &mut ApplicableDeclarationsCache); + applicable_declarations_cache: &mut ApplicableDeclarationsCache, + new_animations_sender: &Sender<Animation>); } trait PrivateMatchMethods { @@ -408,8 +413,9 @@ trait PrivateMatchMethods { parent_style: Option<&Arc<ComputedValues>>, applicable_declarations: &[DeclarationBlock], style: &mut Option<Arc<ComputedValues>>, - applicable_declarations_cache: &mut - ApplicableDeclarationsCache, + applicable_declarations_cache: + &mut ApplicableDeclarationsCache, + new_animations_sender: &Sender<Animation>, shareable: bool) -> RestyleDamage; @@ -425,11 +431,12 @@ impl<'ln> PrivateMatchMethods for LayoutNode<'ln> { parent_style: Option<&Arc<ComputedValues>>, applicable_declarations: &[DeclarationBlock], style: &mut Option<Arc<ComputedValues>>, - applicable_declarations_cache: &mut - ApplicableDeclarationsCache, + applicable_declarations_cache: + &mut ApplicableDeclarationsCache, + new_animations_sender: &Sender<Animation>, shareable: bool) -> RestyleDamage { - let this_style; + let mut this_style; let cacheable; match parent_style { Some(ref parent_style) => { @@ -444,7 +451,7 @@ impl<'ln> PrivateMatchMethods for LayoutNode<'ln> { Some(&***parent_style), cached_computed_values); cacheable = is_cacheable; - this_style = Arc::new(the_style); + this_style = the_style } None => { let (the_style, is_cacheable) = cascade(layout_context.screen_size, @@ -453,22 +460,39 @@ impl<'ln> PrivateMatchMethods for LayoutNode<'ln> { None, None); cacheable = is_cacheable; - this_style = Arc::new(the_style); + this_style = the_style } }; + // Trigger transitions if necessary. This will reset `this_style` back to its old value if + // it did trigger a transition. + match *style { + None => { + // This is a newly-created node; we've nothing to transition from! + } + Some(ref style) => { + let node = OpaqueNodeMethods::from_layout_node(self); + animation::start_transitions_if_applicable(new_animations_sender, + node, + &**style, + &mut this_style); + } + } + + // Calculate style difference. + let this_style = Arc::new(this_style); + let damage = incremental::compute_damage(style, &*this_style); + // Cache the resolved style if it was cacheable. if cacheable { applicable_declarations_cache.insert(applicable_declarations.to_vec(), this_style.clone()); } - // Calculate style difference and write. - let damage = incremental::compute_damage(style, &*this_style); + // Write in the final style and return the damage done to our caller. *style = Some(this_style); damage } - fn share_style_with_candidate_if_possible(&self, parent_node: Option<LayoutNode>, candidate: &StyleSharingCandidate) @@ -615,7 +639,8 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { layout_context: &SharedLayoutContext, parent: Option<LayoutNode>, applicable_declarations: &ApplicableDeclarations, - applicable_declarations_cache: &mut ApplicableDeclarationsCache) { + applicable_declarations_cache: &mut ApplicableDeclarationsCache, + new_animations_sender: &Sender<Animation>) { // Get our parent's style. This must be unsafe so that we don't touch the parent's // borrow flags. // @@ -625,8 +650,12 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { None => None, Some(parent_node) => { let parent_layout_data_ref = parent_node.borrow_layout_data_unchecked(); - let parent_layout_data = (&*parent_layout_data_ref).as_ref().expect("no parent data!?"); - let parent_style = parent_layout_data.shared_data.style.as_ref().expect("parent hasn't been styled yet!"); + let parent_layout_data = (&*parent_layout_data_ref).as_ref() + .expect("no parent data!?"); + let parent_style = parent_layout_data.shared_data + .style + .as_ref() + .expect("parent hasn't been styled yet!"); Some(parent_style) } }; @@ -651,6 +680,7 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { applicable_declarations.normal.as_slice(), &mut layout_data.shared_data.style, applicable_declarations_cache, + new_animations_sender, applicable_declarations.normal_shareable); if applicable_declarations.before.len() > 0 { damage = damage | self.cascade_node_pseudo_element( @@ -659,6 +689,7 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { &*applicable_declarations.before, &mut layout_data.data.before_style, applicable_declarations_cache, + new_animations_sender, false); } if applicable_declarations.after.len() > 0 { @@ -668,6 +699,7 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { &*applicable_declarations.after, &mut layout_data.data.after_style, applicable_declarations_cache, + new_animations_sender, false); } layout_data.data.restyle_damage = damage; diff --git a/components/layout/floats.rs b/components/layout/floats.rs index 9c83322c1c7..736b311bd57 100644 --- a/components/layout/floats.rs +++ b/components/layout/floats.rs @@ -153,7 +153,7 @@ impl Floats { } } - pub fn len(&self) -> uint { + pub fn len(&self) -> usize { self.list.floats.len() } diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 46b69e2deaa..74d3100f1f2 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -311,12 +311,9 @@ pub trait Flow: fmt::Debug + Sync { /// Returns a layer ID for the given fragment. #[allow(unsafe_code)] - fn layer_id(&self, fragment_id: uint) -> LayerId { - unsafe { - let obj = mem::transmute::<&&Self, &raw::TraitObject>(&self); - let pointer: uint = mem::transmute(obj.data); - LayerId(pointer, fragment_id) - } + fn layer_id(&self, fragment_id: u32) -> LayerId { + let obj = unsafe { mem::transmute::<&&Self, &raw::TraitObject>(&self) }; + LayerId(obj.data as usize, fragment_id) } /// Attempts to perform incremental fixup of this flow by replacing its fragment's style with @@ -438,6 +435,10 @@ pub trait MutableFlowUtils { /// So, kids have their flow origin already set. In the case of absolute flow kids, they have /// their hypothetical box position already set. fn collect_static_block_offsets_from_children(self); + + /// Calls `repair_style` and `bubble_inline_sizes`. You should use this method instead of + /// calling them individually, since there is no reason not to perform both operations. + fn repair_style_and_bubble_inline_sizes(self, style: &Arc<ComputedValues>); } pub trait MutableOwnedFlowUtils { @@ -994,9 +995,9 @@ impl BaseFlow { &self.weak_ref_count } - pub fn debug_id(&self) -> uint { + pub fn debug_id(&self) -> usize { let p = self as *const _; - p as uint + p as usize } /// Ensures that all display list items generated by this flow are within the flow's overflow @@ -1312,6 +1313,13 @@ impl<'a> MutableFlowUtils for &'a mut (Flow + 'a) { } mut_base(self).abs_descendants.static_block_offsets = absolute_descendant_block_offsets } + + /// Calls `repair_style` and `bubble_inline_sizes`. You should use this method instead of + /// calling them individually, since there is no reason not to perform both operations. + fn repair_style_and_bubble_inline_sizes(self, style: &Arc<ComputedValues>) { + self.repair_style(style); + self.bubble_inline_sizes(); + } } impl MutableOwnedFlowUtils for FlowRef { diff --git a/components/layout/flow_list.rs b/components/layout/flow_list.rs index 20c69b6081c..ea11b545dac 100644 --- a/components/layout/flow_list.rs +++ b/components/layout/flow_list.rs @@ -102,7 +102,7 @@ impl FlowList { /// O(1) #[inline] - pub fn len(&self) -> uint { + pub fn len(&self) -> usize { self.flows.len() } } @@ -115,7 +115,7 @@ impl<'a> Iterator for FlowListIterator<'a> { } #[inline] - fn size_hint(&self) -> (uint, Option<uint>) { + fn size_hint(&self) -> (usize, Option<usize>) { self.it.size_hint() } } @@ -128,7 +128,7 @@ impl<'a> Iterator for MutFlowListIterator<'a> { } #[inline] - fn size_hint(&self) -> (uint, Option<uint>) { + fn size_hint(&self) -> (usize, Option<usize>) { self.it.size_hint() } } diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 1fa36d7beea..0458c2bb738 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -1600,8 +1600,8 @@ impl Fragment { // FIXME(pcwalton): Is there a more clever (i.e. faster) way to do this? if let Some(ref mut inline_end_range) = inline_end_range { let inline_end_fragment_text = - text_fragment_info.run.text.slice_chars(inline_end_range.begin().to_uint(), - inline_end_range.end().to_uint()); + text_fragment_info.run.text.slice_chars(inline_end_range.begin().to_usize(), + inline_end_range.end().to_usize()); let mut leading_whitespace_character_count = 0i; for ch in inline_end_fragment_text.chars() { if ch.is_whitespace() { @@ -2128,7 +2128,7 @@ pub enum CoordinateSystem { /// if any modifications were made. fn strip_trailing_whitespace(text_run: &TextRun, range: &mut Range<CharIndex>) -> bool { // FIXME(pcwalton): Is there a more clever (i.e. faster) way to do this? - let text = text_run.text.slice_chars(range.begin().to_uint(), range.end().to_uint()); + let text = text_run.text.slice_chars(range.begin().to_usize(), range.end().to_usize()); let mut trailing_whitespace_character_count = 0i; for ch in text.chars().rev() { if ch.is_whitespace() { diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 0b645aa0971..5dd4ecf36e3 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -915,7 +915,7 @@ impl InlineFlow { } for fragment_index in range(line.range.begin(), line.range.end()) { - let fragment = fragments.get_mut(fragment_index.to_uint()); + let fragment = fragments.get_mut(fragment_index.to_usize()); let size = fragment.border_box.size; fragment.border_box = LogicalRect::new(fragment.style.writing_mode, inline_start_position_for_fragment, @@ -940,7 +940,7 @@ impl InlineFlow { // First, calculate the number of expansion opportunities (spaces, normally). let mut expansion_opportunities = 0i32; for fragment_index in line.range.each_index() { - let fragment = fragments.get(fragment_index.to_uint()); + let fragment = fragments.get(fragment_index.to_usize()); let scanned_text_fragment_info = if let SpecificFragmentInfo::ScannedText(ref info) = fragment.specific { info @@ -957,7 +957,7 @@ impl InlineFlow { let space_per_expansion_opportunity = slack_inline_size.to_subpx() / (expansion_opportunities as f64); for fragment_index in line.range.each_index() { - let fragment = fragments.get_mut(fragment_index.to_uint()); + let fragment = fragments.get_mut(fragment_index.to_usize()); let mut scanned_text_fragment_info = if let SpecificFragmentInfo::ScannedText(ref mut info) = fragment.specific { info @@ -1004,7 +1004,7 @@ impl InlineFlow { baseline_distance_from_block_start: Au, largest_depth_below_baseline: Au) { for fragment_index in range(line.range.begin(), line.range.end()) { - let fragment = fragments.get_mut(fragment_index.to_uint()); + let fragment = fragments.get_mut(fragment_index.to_usize()); match fragment.vertical_align() { vertical_align::T::top => { fragment.border_box.start.b = fragment.border_box.start.b + @@ -1221,7 +1221,7 @@ impl Flow for InlineFlow { mut largest_block_size_for_bottom_fragments) = (Au(0), Au(0)); for fragment_index in range(line.range.begin(), line.range.end()) { - let fragment = &mut self.fragments.fragments[fragment_index.to_uint()]; + let fragment = &mut self.fragments.fragments[fragment_index.to_usize()]; let InlineMetrics { mut block_size_above_baseline, diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 3a511033934..33bf00e837f 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -7,9 +7,9 @@ #![allow(unsafe_code)] +use animation; use construct::ConstructionResult; use context::{SharedLayoutContext, SharedLayoutContextWrapper}; -use css::node_style::StyledNode; use display_list_builder::ToGfxColor; use flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils}; use flow_ref::FlowRef; @@ -20,8 +20,9 @@ use layout_debug; use opaque_node::OpaqueNodeMethods; use parallel::{self, UnsafeFlow}; use sequential; -use wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode}; +use wrapper::{LayoutNode, TLayoutNode}; +use azure::azure::AzColor; use encoding::EncodingRef; use encoding::all::UTF_8; use geom::matrix2d::Matrix2D; @@ -47,14 +48,11 @@ use profile::mem::{self, Report, ReportsChan}; use profile::time::{self, ProfilerMetadata, profile}; use profile::time::{TimerMetadataFrameType, TimerMetadataReflowType}; use script::dom::bindings::js::LayoutJS; -use script::dom::element::ElementTypeId; -use script::dom::htmlelement::HTMLElementTypeId; -use script::dom::node::{LayoutData, Node, NodeTypeId}; -use script::layout_interface::ReflowQueryType; -use script::layout_interface::{ContentBoxResponse, ContentBoxesResponse}; +use script::dom::node::{LayoutData, Node}; +use script::layout_interface::{Animation, ContentBoxResponse, ContentBoxesResponse}; use script::layout_interface::{HitTestResponse, LayoutChan, LayoutRPC}; -use script::layout_interface::{MouseOverResponse, Msg}; -use script::layout_interface::{Reflow, ReflowGoal, ScriptLayoutChan, TrustedNodeAddress}; +use script::layout_interface::{MouseOverResponse, Msg, Reflow, ReflowGoal, ReflowQueryType}; +use script::layout_interface::{ScriptLayoutChan, ScriptReflow, TrustedNodeAddress}; use script_traits::{ConstellationControlMsg, CompositorEvent, OpaqueScriptLayoutChannel}; use script_traits::{ScriptControlChan, UntrustedNodeAddress}; use std::borrow::ToOwned; @@ -71,7 +69,7 @@ use style::selector_matching::Stylist; use style::stylesheets::{Origin, Stylesheet, iter_font_face_rules}; use url::Url; use util::cursor::Cursor; -use util::geometry::Au; +use util::geometry::{Au, MAX_RECT}; use util::logical_geometry::LogicalPoint; use util::mem::HeapSizeOf; use util::opts; @@ -84,6 +82,9 @@ use util::workqueue::WorkQueue; /// /// This needs to be protected by a mutex so we can do fast RPCs. pub struct LayoutTaskData { + /// The root of the flow tree. + pub root_flow: Option<FlowRef>, + /// The local image cache. pub local_image_cache: Arc<Mutex<LocalImageCache<UntrustedNodeAddress>>>, @@ -107,13 +108,23 @@ pub struct LayoutTaskData { /// Starts at zero, and increased by one every time a layout completes. /// This can be used to easily check for invalid stale data. - pub generation: uint, + pub generation: u32, /// A queued response for the union of the content boxes of a node. pub content_box_response: Rect<Au>, /// A queued response for the content boxes of a node. pub content_boxes_response: Vec<Rect<Au>>, + + /// The list of currently-running animations. + pub running_animations: Vec<Animation>, + + /// Receives newly-discovered animations. + pub new_animations_receiver: Receiver<Animation>, + + /// A channel on which new animations that have been triggered by style recalculation can be + /// sent. + pub new_animations_sender: Sender<Animation>, } /// Information needed by the layout task. @@ -130,7 +141,7 @@ pub struct LayoutTask { /// The port on which we receive messages from the constellation pub pipeline_port: Receiver<LayoutControlMsg>, - //// The channel to send messages to ourself. + /// The channel on which we or others can send messages to ourselves. pub chan: LayoutChan, /// The channel on which messages can be sent to the constellation. @@ -193,39 +204,37 @@ impl ImageResponder<UntrustedNodeAddress> for LayoutImageResponder { impl LayoutTaskFactory for LayoutTask { /// Spawns a new layout task. fn create(_phantom: Option<&mut LayoutTask>, - id: PipelineId, - url: Url, - chan: OpaqueScriptLayoutChannel, - pipeline_port: Receiver<LayoutControlMsg>, - constellation_chan: ConstellationChan, - failure_msg: Failure, - script_chan: ScriptControlChan, - paint_chan: PaintChan, - resource_task: ResourceTask, - img_cache_task: ImageCacheTask, - font_cache_task: FontCacheTask, - time_profiler_chan: time::ProfilerChan, - mem_profiler_chan: mem::ProfilerChan, - shutdown_chan: Sender<()>) { + id: PipelineId, + url: Url, + chan: OpaqueScriptLayoutChannel, + pipeline_port: Receiver<LayoutControlMsg>, + constellation_chan: ConstellationChan, + failure_msg: Failure, + script_chan: ScriptControlChan, + paint_chan: PaintChan, + resource_task: ResourceTask, + img_cache_task: ImageCacheTask, + font_cache_task: FontCacheTask, + time_profiler_chan: time::ProfilerChan, + memory_profiler_chan: mem::ProfilerChan, + shutdown_chan: Sender<()>) { let ConstellationChan(con_chan) = constellation_chan.clone(); spawn_named_with_send_on_failure("LayoutTask", task_state::LAYOUT, move || { { // Ensures layout task is destroyed before we send shutdown message let sender = chan.sender(); - let layout = - LayoutTask::new( - id, - url, - chan.receiver(), - LayoutChan(sender), - pipeline_port, - constellation_chan, - script_chan, - paint_chan, - resource_task, - img_cache_task, - font_cache_task, - time_profiler_chan, - mem_profiler_chan); + let layout = LayoutTask::new(id, + url, + chan.receiver(), + LayoutChan(sender), + pipeline_port, + constellation_chan, + script_chan, + paint_chan, + resource_task, + img_cache_task, + font_cache_task, + time_profiler_chan, + memory_profiler_chan); layout.start(); } shutdown_chan.send(()).unwrap(); @@ -294,10 +303,14 @@ impl LayoutTask { }; // Register this thread as a memory reporter, via its own channel. - let reporter = Box::new(chan.clone()); + let reporter = box chan.clone(); let reporter_name = format!("layout-reporter-{}", id.0); mem_profiler_chan.send(mem::ProfilerMsg::RegisterReporter(reporter_name.clone(), reporter)); + + // Create the channel on which new animations can be sent. + let (new_animations_sender, new_animations_receiver) = channel(); + LayoutTask { id: id, url: url, @@ -316,6 +329,7 @@ impl LayoutTask { first_reflow: Cell::new(true), rw_data: Arc::new(Mutex::new( LayoutTaskData { + root_flow: None, local_image_cache: local_image_cache, constellation_chan: constellation_chan, screen_size: screen_size, @@ -326,6 +340,9 @@ impl LayoutTask { generation: 0, content_box_response: Rect::zero(), content_boxes_response: Vec::new(), + running_animations: Vec::new(), + new_animations_receiver: new_animations_receiver, + new_animations_sender: new_animations_sender, })), } } @@ -342,7 +359,7 @@ impl LayoutTask { fn build_shared_layout_context(&self, rw_data: &LayoutTaskData, screen_size_changed: bool, - reflow_root: &LayoutNode, + reflow_root: Option<&LayoutNode>, url: &Url) -> SharedLayoutContext { SharedLayoutContext { @@ -354,9 +371,10 @@ impl LayoutTask { font_cache_task: self.font_cache_task.clone(), stylist: &*rw_data.stylist, url: (*url).clone(), - reflow_root: OpaqueNodeMethods::from_layout_node(reflow_root), + reflow_root: reflow_root.map(|node| OpaqueNodeMethods::from_layout_node(node)), dirty: Rect::zero(), generation: rw_data.generation, + new_animations_sender: rw_data.new_animations_sender.clone(), } } @@ -390,8 +408,12 @@ impl LayoutTask { match port_to_read { PortToRead::Pipeline => { match self.pipeline_port.recv().unwrap() { + LayoutControlMsg::TickAnimationsMsg => { + self.handle_request_helper(Msg::TickAnimations, possibly_locked_rw_data) + } LayoutControlMsg::ExitNowMsg(exit_type) => { - self.handle_request_helper(Msg::ExitNow(exit_type), possibly_locked_rw_data) + self.handle_request_helper(Msg::ExitNow(exit_type), + possibly_locked_rw_data) } } }, @@ -435,8 +457,12 @@ impl LayoutTask { LayoutTaskData>>) -> bool { match request { - Msg::AddStylesheet(sheet, mq) => self.handle_add_stylesheet(sheet, mq, possibly_locked_rw_data), - Msg::LoadStylesheet(url, mq) => self.handle_load_stylesheet(url, mq, possibly_locked_rw_data), + Msg::AddStylesheet(sheet, mq) => { + self.handle_add_stylesheet(sheet, mq, possibly_locked_rw_data) + } + Msg::LoadStylesheet(url, mq) => { + self.handle_load_stylesheet(url, mq, possibly_locked_rw_data) + } Msg::SetQuirksMode => self.handle_set_quirks_mode(possibly_locked_rw_data), Msg::GetRPC(response_chan) => { response_chan.send(box LayoutRPCImpl(self.rw_data.clone()) as @@ -444,10 +470,11 @@ impl LayoutTask { }, Msg::Reflow(data) => { profile(time::ProfilerCategory::LayoutPerform, - self.profiler_metadata(&*data), + self.profiler_metadata(&data.reflow_info), self.time_profiler_chan.clone(), || self.handle_reflow(&*data, possibly_locked_rw_data)); }, + Msg::TickAnimations => self.tick_all_animations(possibly_locked_rw_data), Msg::ReapLayoutData(dead_layout_data) => { unsafe { self.handle_reap_layout_data(dead_layout_data) @@ -481,15 +508,15 @@ impl LayoutTask { let stacking_context = rw_data.stacking_context.as_ref(); reports.push(Report { path: path!["pages", format!("url({})", self.url), "display-list"], - size: stacking_context.map_or(0, |sc| sc.heap_size_of_children() as u64), + size: stacking_context.map_or(0, |sc| sc.heap_size_of_children()), }); reports_chan.send(reports); } - /// Enters a quiescent state in which no new messages except for `layout_interface::Msg::ReapLayoutData` will be - /// processed until an `ExitNowMsg` is received. A pong is immediately sent on the given - /// response channel. + /// Enters a quiescent state in which no new messages except for + /// `layout_interface::Msg::ReapLayoutData` will be processed until an `ExitNowMsg` is + /// received. A pong is immediately sent on the given response channel. fn prepare_to_exit<'a>(&'a self, response_chan: Sender<()>, possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) { @@ -570,7 +597,7 @@ impl LayoutTask { if mq.evaluate(&rw_data.stylist.device) { iter_font_face_rules(&sheet, &rw_data.stylist.device, &|family, src| { - self.font_cache_task.add_web_font(family.to_owned(), (*src).clone()); + self.font_cache_task.add_web_font((*family).clone(), (*src).clone()); }); rw_data.stylist.add_stylesheet(sheet); } @@ -587,7 +614,6 @@ impl LayoutTask { LayoutTask::return_rw_data(possibly_locked_rw_data, rw_data); } - /// Retrieves the flow tree root from the root node. fn try_get_layout_root(&self, node: LayoutNode) -> Option<FlowRef> { let mut layout_data_ref = node.mutate_layout_data(); let layout_data = @@ -697,10 +723,9 @@ impl LayoutTask { fn build_display_list_for_reflow<'a>(&'a self, data: &Reflow, - node: &mut LayoutNode, layout_root: &mut FlowRef, shared_layout_context: &mut SharedLayoutContext, - rw_data: &mut RWGuard<'a>) { + rw_data: &mut LayoutTaskData) { let writing_mode = flow::base(&**layout_root).writing_mode; profile(time::ProfilerCategory::LayoutDispListBuild, self.profiler_metadata(data), @@ -716,7 +741,6 @@ impl LayoutTask { flow::mut_base(&mut **layout_root).clip = ClippingRegion::from_rect(&data.page_clip_rect); - let rw_data = &mut **rw_data; match rw_data.parallel_traversal { None => { sequential::build_display_list_for_subtree(layout_root, shared_layout_context); @@ -732,40 +756,7 @@ impl LayoutTask { debug!("Done building display list."); - // FIXME(pcwalton): This is really ugly and can't handle overflow: scroll. Refactor - // it with extreme prejudice. - - // The default computed value for background-color is transparent (see - // http://dev.w3.org/csswg/css-backgrounds/#background-color). However, we - // need to propagate the background color from the root HTML/Body - // element (http://dev.w3.org/csswg/css-backgrounds/#special-backgrounds) if - // it is non-transparent. The phrase in the spec "If the canvas background - // is not opaque, what shows through is UA-dependent." is handled by rust-layers - // clearing the frame buffer to white. This ensures that setting a background - // color on an iframe element, while the iframe content itself has a default - // transparent background color is handled correctly. - let mut color = color::transparent_black(); - for child in node.traverse_preorder() { - if child.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLHtmlElement))) || - child.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLBodyElement))) { - let element_bg_color = { - let thread_safe_child = ThreadSafeLayoutNode::new(&child); - thread_safe_child.style() - .resolve_color(thread_safe_child.style() - .get_background() - .background_color) - .to_gfx_color() - }; - - let black = color::transparent_black(); - if element_bg_color != black { - - color = element_bg_color; - break; - } - } - } - + let root_background_color = get_root_flow_background_color(&mut **layout_root); let root_size = { let root_flow = flow::base(&**layout_root); root_flow.position.size.to_physical(root_flow.writing_mode) @@ -774,7 +765,7 @@ impl LayoutTask { flow::mut_base(&mut **layout_root).display_list_building_result .add_to(&mut *display_list); let paint_layer = Arc::new(PaintLayer::new(layout_root.layer_id(0), - color, + root_background_color, ScrollPolicy::Scrollable)); let origin = Rect(Point2D(Au(0), Au(0)), root_size); @@ -802,7 +793,7 @@ impl LayoutTask { /// The high-level routine that performs layout tasks. fn handle_reflow<'a>(&'a self, - data: &Reflow, + data: &ScriptReflow, possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) { // FIXME: Isolate this transmutation into a "bridge" module. // FIXME(rust#16366): The following line had to be moved because of a @@ -814,8 +805,7 @@ impl LayoutTask { transmute(&mut node) }; - debug!("layout: received layout request for: {}", data.url.serialize()); - debug!("layout: parsed Node tree"); + debug!("layout: received layout request for: {}", data.reflow_info.url.serialize()); if log_enabled!(log::DEBUG) { node.dump(); } @@ -831,7 +821,6 @@ impl LayoutTask { // TODO: Calculate the "actual viewport": // http://www.w3.org/TR/css-device-adapt/#actual-viewport let viewport_size = data.window_size.initial_viewport; - let old_screen_size = rw_data.screen_size; let current_screen_size = Size2D(Au::from_frac32_px(viewport_size.width.get()), Au::from_frac32_px(viewport_size.height.get())); @@ -839,23 +828,19 @@ impl LayoutTask { // Handle conditions where the entire flow tree is invalid. let screen_size_changed = current_screen_size != old_screen_size; - if screen_size_changed { let device = Device::new(MediaType::Screen, data.window_size.initial_viewport); rw_data.stylist.set_device(device); } - let needs_dirtying = rw_data.stylist.update(); - // If the entire flow tree is invalid, then it will be reflowed anyhow. + let needs_dirtying = rw_data.stylist.update(); let needs_reflow = screen_size_changed && !needs_dirtying; - unsafe { if needs_dirtying { LayoutTask::dirty_all_nodes(node); } } - if needs_reflow { match self.try_get_layout_root(*node) { None => {} @@ -868,13 +853,14 @@ impl LayoutTask { // Create a layout context for use throughout the following passes. let mut shared_layout_context = self.build_shared_layout_context(&*rw_data, screen_size_changed, - node, - &data.url); + Some(&node), + &data.reflow_info.url); - let mut layout_root = profile(time::ProfilerCategory::LayoutStyleRecalc, - self.profiler_metadata(data), - self.time_profiler_chan.clone(), - || { + // Recalculate CSS styles and rebuild flows and fragments. + profile(time::ProfilerCategory::LayoutStyleRecalc, + self.profiler_metadata(&data.reflow_info), + self.time_profiler_chan.clone(), + || { // Perform CSS selector matching and flow construction. let rw_data = &mut *rw_data; match rw_data.parallel_traversal { @@ -882,39 +868,105 @@ impl LayoutTask { sequential::traverse_dom_preorder(*node, &shared_layout_context); } Some(ref mut traversal) => { - parallel::traverse_dom_preorder(*node, &shared_layout_context, traversal) + parallel::traverse_dom_preorder(*node, &shared_layout_context, traversal); } } - - self.get_layout_root((*node).clone()) }); + // Retrieve the (possibly rebuilt) root flow. + rw_data.root_flow = Some(self.get_layout_root((*node).clone())); + + // Kick off animations if any were triggered. + animation::process_new_animations(&mut *rw_data, self.id); + + // Perform post-style recalculation layout passes. + self.perform_post_style_recalc_layout_passes(&data.reflow_info, + &mut rw_data, + &mut shared_layout_context); + + let mut root_flow = (*rw_data.root_flow.as_ref().unwrap()).clone(); + match data.query_type { + ReflowQueryType::ContentBoxQuery(node) => { + self.process_content_box_request(node, &mut root_flow, &mut rw_data) + } + ReflowQueryType::ContentBoxesQuery(node) => { + self.process_content_boxes_request(node, &mut root_flow, &mut rw_data) + } + ReflowQueryType::NoQuery => {} + } + + + // Tell script that we're done. + // + // FIXME(pcwalton): This should probably be *one* channel, but we can't fix this without + // either select or a filtered recv() that only looks for messages of a given type. + data.script_join_chan.send(()).unwrap(); + let ScriptControlChan(ref chan) = data.script_chan; + chan.send(ConstellationControlMsg::ReflowComplete(self.id, data.id)).unwrap(); + } + + fn tick_all_animations<'a>(&'a self, + possibly_locked_rw_data: &mut Option<MutexGuard<'a, + LayoutTaskData>>) { + let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + animation::tick_all_animations(self, &mut rw_data) + } + + pub fn tick_animation<'a>(&'a self, animation: Animation, rw_data: &mut LayoutTaskData) { + // FIXME(#5466, pcwalton): These data are lies. + let reflow_info = Reflow { + goal: ReflowGoal::ForDisplay, + url: Url::parse("http://animation.com/").unwrap(), + iframe: false, + page_clip_rect: MAX_RECT, + }; + + // Perform an abbreviated style recalc that operates without access to the DOM. + let mut layout_context = self.build_shared_layout_context(&*rw_data, + false, + None, + &reflow_info.url); + let mut root_flow = (*rw_data.root_flow.as_ref().unwrap()).clone(); + profile(time::ProfilerCategory::LayoutStyleRecalc, + self.profiler_metadata(&reflow_info), + self.time_profiler_chan.clone(), + || animation::recalc_style_for_animation(root_flow.deref_mut(), &animation)); + + self.perform_post_style_recalc_layout_passes(&reflow_info, + &mut *rw_data, + &mut layout_context); + } + + fn perform_post_style_recalc_layout_passes<'a>(&'a self, + data: &Reflow, + rw_data: &mut LayoutTaskData, + layout_context: &mut SharedLayoutContext) { + let mut root_flow = (*rw_data.root_flow.as_ref().unwrap()).clone(); profile(time::ProfilerCategory::LayoutRestyleDamagePropagation, self.profiler_metadata(data), self.time_profiler_chan.clone(), || { - if opts::get().nonincremental_layout || layout_root.compute_layout_damage() - .contains(REFLOW_ENTIRE_DOCUMENT) { - layout_root.reflow_entire_document() + if opts::get().nonincremental_layout || root_flow.deref_mut() + .compute_layout_damage() + .contains(REFLOW_ENTIRE_DOCUMENT) { + root_flow.deref_mut().reflow_entire_document() } }); // Verification of the flow tree, which ensures that all nodes were either marked as leaves // or as non-leaves. This becomes a no-op in release builds. (It is inconsequential to // memory safety but is a useful debugging tool.) - self.verify_flow_tree(&mut layout_root); + self.verify_flow_tree(&mut root_flow); if opts::get().trace_layout { - layout_debug::begin_trace(layout_root.clone()); + layout_debug::begin_trace(root_flow.clone()); } // Resolve generated content. profile(time::ProfilerCategory::LayoutGeneratedContent, self.profiler_metadata(data), self.time_profiler_chan.clone(), - || { - sequential::resolve_generated_content(&mut layout_root, &shared_layout_context) - }); + || sequential::resolve_generated_content(&mut root_flow, &layout_context)); // Perform the primary layout passes over the flow tree to compute the locations of all // the boxes. @@ -922,18 +974,17 @@ impl LayoutTask { self.profiler_metadata(data), self.time_profiler_chan.clone(), || { - let rw_data = &mut *rw_data; match rw_data.parallel_traversal { None => { // Sequential mode. - self.solve_constraints(&mut layout_root, &shared_layout_context) + self.solve_constraints(&mut root_flow, &layout_context) } Some(_) => { // Parallel mode. self.solve_constraints_parallel(data, rw_data, - &mut layout_root, - &mut shared_layout_context); + &mut root_flow, + &mut *layout_context); } } }); @@ -942,24 +993,13 @@ impl LayoutTask { match data.goal { ReflowGoal::ForDisplay => { self.build_display_list_for_reflow(data, - node, - &mut layout_root, - &mut shared_layout_context, - &mut rw_data); + &mut root_flow, + &mut *layout_context, + rw_data); } ReflowGoal::ForScriptQuery => {} } - match data.query_type { - ReflowQueryType::ContentBoxQuery(node) => { - self.process_content_box_request(node, &mut layout_root, &mut rw_data) - } - ReflowQueryType::ContentBoxesQuery(node) => { - self.process_content_boxes_request(node, &mut layout_root, &mut rw_data) - } - ReflowQueryType::NoQuery => {} - } - self.first_reflow.set(false); if opts::get().trace_layout { @@ -967,18 +1007,10 @@ impl LayoutTask { } if opts::get().dump_flow_tree { - layout_root.dump(); + root_flow.dump(); } rw_data.generation += 1; - - // Tell script that we're done. - // - // FIXME(pcwalton): This should probably be *one* channel, but we can't fix this without - // either select or a filtered recv() that only looks for messages of a given type. - data.script_join_chan.send(()).unwrap(); - let ScriptControlChan(ref chan) = data.script_chan; - chan.send(ConstellationControlMsg::ReflowComplete(self.id, data.id)).unwrap(); } unsafe fn dirty_all_nodes(node: &mut LayoutNode) { @@ -1172,3 +1204,34 @@ impl FragmentBorderBoxIterator for CollectingFragmentBorderBoxIterator { self.node_address == fragment.node } } + +// The default computed value for background-color is transparent (see +// http://dev.w3.org/csswg/css-backgrounds/#background-color). However, we +// need to propagate the background color from the root HTML/Body +// element (http://dev.w3.org/csswg/css-backgrounds/#special-backgrounds) if +// it is non-transparent. The phrase in the spec "If the canvas background +// is not opaque, what shows through is UA-dependent." is handled by rust-layers +// clearing the frame buffer to white. This ensures that setting a background +// color on an iframe element, while the iframe content itself has a default +// transparent background color is handled correctly. +fn get_root_flow_background_color(flow: &mut Flow) -> AzColor { + if !flow.is_block_like() { + return color::transparent_black() + } + + let block_flow = flow.as_block(); + let kid = match block_flow.base.children.iter_mut().next() { + None => return color::transparent_black(), + Some(kid) => kid, + }; + if !kid.is_block_like() { + return color::transparent_black() + } + + let kid_block_flow = kid.as_block(); + kid_block_flow.fragment + .style + .resolve_color(kid_block_flow.fragment.style.get_background().background_color) + .to_gfx_color() +} + diff --git a/components/layout/lib.rs b/components/layout/lib.rs index d2a407a2a70..646daab0480 100644 --- a/components/layout/lib.rs +++ b/components/layout/lib.rs @@ -25,40 +25,45 @@ #[macro_use] extern crate log; -#[macro_use]extern crate bitflags; -extern crate azure; -extern crate cssparser; -extern crate canvas; -extern crate geom; -extern crate gfx; -extern crate layout_traits; -extern crate script; -extern crate script_traits; -extern crate "rustc-serialize" as rustc_serialize; -extern crate png; -extern crate style; +#[macro_use] +extern crate bitflags; + #[macro_use] #[no_link] extern crate "plugins" as servo_plugins; -extern crate net; -extern crate msg; + #[macro_use] extern crate profile; -extern crate selectors; + #[macro_use] extern crate util; -extern crate string_cache; - +extern crate "rustc-serialize" as rustc_serialize; extern crate alloc; +extern crate azure; +extern crate canvas; +extern crate clock_ticks; extern crate collections; +extern crate cssparser; extern crate encoding; +extern crate geom; +extern crate gfx; +extern crate layout_traits; extern crate libc; +extern crate msg; +extern crate net; +extern crate png; +extern crate script; +extern crate script_traits; +extern crate selectors; +extern crate string_cache; +extern crate style; extern crate url; // Listed first because of macro definitions pub mod layout_debug; +pub mod animation; pub mod block; pub mod construct; pub mod context; diff --git a/components/layout/parallel.rs b/components/layout/parallel.rs index ee076763c24..57b74ac66e4 100644 --- a/components/layout/parallel.rs +++ b/components/layout/parallel.rs @@ -35,7 +35,7 @@ fn static_assertion(node: UnsafeLayoutNode) { } /// Vtable + pointer representation of a Flow trait object. -pub type UnsafeFlow = (uint, uint); +pub type UnsafeFlow = (usize, usize); fn null_unsafe_flow() -> UnsafeFlow { (0, 0) diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index a206bf75b4a..72c1ade2062 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -28,7 +28,7 @@ use std::mem; /// Every time we do another layout, the old bloom filters are invalid. This is /// detected by ticking a generation number every layout. -type Generation = uint; +type Generation = u32; /// A pair of the bloom filter used for css selector matching, and the node to /// which it applies. This is used to efficiently do `Descendant` selector @@ -180,7 +180,8 @@ impl<'a> PreorderDomTraversal for RecalcStyleForNode<'a> { node.cascade_node(self.layout_context.shared, parent_opt, &applicable_declarations, - self.layout_context.applicable_declarations_cache()); + self.layout_context.applicable_declarations_cache(), + &self.layout_context.shared.new_animations_sender); } // Add ourselves to the LRU cache. diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index 101249b4747..a99dcebe187 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -248,7 +248,7 @@ impl<'ln> LayoutNode<'ln> { self.dump_indent(0); } - fn dump_indent(self, indent: uint) { + fn dump_indent(self, indent: u32) { let mut s = String::new(); for _ in range(0, indent) { s.push_str(" "); @@ -267,10 +267,10 @@ impl<'ln> LayoutNode<'ln> { self.type_id(), self.has_changed(), self.is_dirty(), self.has_dirty_descendants()) } - pub fn flow_debug_id(self) -> uint { + pub fn flow_debug_id(self) -> usize { let layout_data_ref = self.borrow_layout_data(); match *layout_data_ref { - None => 0u, + None => 0, Some(ref layout_data) => layout_data.data.flow_construction_result.debug_id() } } @@ -333,11 +333,16 @@ impl<'ln> LayoutNode<'ln> { /// While doing a reflow, the node at the root has no parent, as far as we're /// concerned. This method returns `None` at the reflow root. pub fn layout_parent_node(self, shared: &SharedLayoutContext) -> Option<LayoutNode<'ln>> { - let opaque_node: OpaqueNode = OpaqueNodeMethods::from_layout_node(&self); - if opaque_node == shared.reflow_root { - None - } else { - self.parent_node() + match shared.reflow_root { + None => panic!("layout_parent_node(): This layout has no access to the DOM!"), + Some(reflow_root) => { + let opaque_node: OpaqueNode = OpaqueNodeMethods::from_layout_node(&self); + if opaque_node == reflow_root { + None + } else { + self.parent_node() + } + } } } @@ -806,7 +811,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { self.node.debug_id() } - pub fn flow_debug_id(self) -> uint { + pub fn flow_debug_id(self) -> usize { self.node.flow_debug_id() } @@ -1135,11 +1140,11 @@ pub trait PostorderNodeMutTraversal { /// Opaque type stored in type-unsafe work queues for parallel layout. /// Must be transmutable to and from LayoutNode/ThreadSafeLayoutNode. -pub type UnsafeLayoutNode = (uint, uint); +pub type UnsafeLayoutNode = (usize, usize); pub fn layout_node_to_unsafe_layout_node(node: &LayoutNode) -> UnsafeLayoutNode { unsafe { - let ptr: uint = mem::transmute_copy(node); + let ptr: usize = mem::transmute_copy(node); (ptr, 0) } } diff --git a/components/layout_traits/lib.rs b/components/layout_traits/lib.rs index 966d940d4cb..c36de735d19 100644 --- a/components/layout_traits/lib.rs +++ b/components/layout_traits/lib.rs @@ -29,6 +29,7 @@ use url::Url; /// Messages sent to the layout task from the constellation pub enum LayoutControlMsg { ExitNowMsg(PipelineExitType), + TickAnimationsMsg, } /// A channel wrapper for constellation messages diff --git a/components/msg/compositor_msg.rs b/components/msg/compositor_msg.rs index 54dc125f589..d306af649a9 100644 --- a/components/msg/compositor_msg.rs +++ b/components/msg/compositor_msg.rs @@ -34,7 +34,7 @@ pub enum ReadyState { /// A newtype struct for denoting the age of messages; prevents race conditions. #[derive(PartialEq, Eq, Debug, Copy)] -pub struct Epoch(pub uint); +pub struct Epoch(pub u32); impl Epoch { pub fn next(&mut self) { @@ -44,7 +44,7 @@ impl Epoch { } #[derive(Clone, PartialEq, Eq, Copy)] -pub struct LayerId(pub uint, pub uint); +pub struct LayerId(pub usize, pub u32); impl Debug for LayerId { fn fmt(&self, f: &mut Formatter) -> fmt::Result { diff --git a/components/msg/constellation_msg.rs b/components/msg/constellation_msg.rs index 86904e0cd47..d1d2822e3fc 100644 --- a/components/msg/constellation_msg.rs +++ b/components/msg/constellation_msg.rs @@ -214,6 +214,10 @@ pub enum Msg { SetCursor(Cursor), /// Dispatch a mozbrowser event to a given iframe. Only available in experimental mode. MozBrowserEventMsg(PipelineId, SubpageId, MozBrowserEvent), + /// Indicates whether this pipeline is currently running animations. + ChangeRunningAnimationsState(PipelineId, bool), + /// Requests that the constellation instruct layout to begin a new tick of the animation. + TickAnimation(PipelineId), } // https://developer.mozilla.org/en-US/docs/Web/API/Using_the_Browser_API#Events @@ -309,16 +313,16 @@ pub enum NavigationDirection { } #[derive(Clone, PartialEq, Eq, Copy, Hash, Debug)] -pub struct FrameId(pub uint); +pub struct FrameId(pub u32); #[derive(Clone, PartialEq, Eq, Copy, Hash, Debug)] -pub struct WorkerId(pub uint); +pub struct WorkerId(pub u32); #[derive(Clone, PartialEq, Eq, Copy, Hash, Debug)] -pub struct PipelineId(pub uint); +pub struct PipelineId(pub u32); #[derive(Clone, PartialEq, Eq, Copy, Hash, Debug)] -pub struct SubpageId(pub uint); +pub struct SubpageId(pub u32); // The type of pipeline exit. During complete shutdowns, pipelines do not have to // release resources automatically released on process termination. diff --git a/components/msg/lib.rs b/components/msg/lib.rs index b4517b2fff9..7b52067c927 100644 --- a/components/msg/lib.rs +++ b/components/msg/lib.rs @@ -2,8 +2,6 @@ * 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/. */ -#![feature(int_uint)] - extern crate azure; #[macro_use] extern crate bitflags; extern crate geom; diff --git a/components/net/cookie.rs b/components/net/cookie.rs index 46094ac00a3..3c56fe8bac6 100644 --- a/components/net/cookie.rs +++ b/components/net/cookie.rs @@ -71,7 +71,7 @@ impl Cookie { if path.is_empty() || path.char_at(0) != '/' { let url_path = request.serialize_path(); let url_path = url_path.as_ref().map(|path| &**path); - path = Cookie::default_path(url_path.unwrap_or("")); + path = Cookie::default_path(url_path.unwrap_or("")).to_owned(); } cookie.path = Some(path); @@ -96,15 +96,21 @@ impl Cookie { } // http://tools.ietf.org/html/rfc6265#section-5.1.4 - fn default_path(request_path: &str) -> String { - if request_path == "" || request_path.char_at(0) != '/' || - request_path.chars().filter(|&c| c == '/').count() == 1 { - "/".to_owned() - } else if request_path.ends_with("/") { - request_path[..request_path.len() - 1].to_owned() - } else { - request_path.to_owned() + fn default_path(request_path: &str) -> &str { + // Step 2 + if request_path.is_empty() || !request_path.starts_with("/") { + return "/"; + } + + // Step 3 + let rightmost_slash_idx = request_path.rfind("/").unwrap(); + if rightmost_slash_idx == 0 { + // There's only one slash; it's the first character + return "/"; } + + // Step 4 + &request_path[..rightmost_slash_idx] } // http://tools.ietf.org/html/rfc6265#section-5.1.4 @@ -180,6 +186,7 @@ fn test_domain_match() { #[test] fn test_default_path() { assert!(&*Cookie::default_path("/foo/bar/baz/") == "/foo/bar/baz"); + assert!(&*Cookie::default_path("/foo/bar/baz") == "/foo/bar"); assert!(&*Cookie::default_path("/foo/") == "/foo"); assert!(&*Cookie::default_path("/foo") == "/"); assert!(&*Cookie::default_path("/") == "/"); diff --git a/components/net/image_cache_task.rs b/components/net/image_cache_task.rs index 4719a305485..e881e80dd41 100644 --- a/components/net/image_cache_task.rs +++ b/components/net/image_cache_task.rs @@ -15,6 +15,7 @@ use std::mem::replace; use std::sync::{Arc, Mutex}; use std::sync::mpsc::{channel, Receiver, Sender}; use url::Url; +use util::resource_files::resources_dir_path; use util::task::spawn_named; use util::taskpool::TaskPool; @@ -75,7 +76,8 @@ pub struct ImageCacheTask { impl ImageCacheTask { pub fn new(resource_task: ResourceTask, task_pool: TaskPool, - time_profiler_chan: time::ProfilerChan) -> ImageCacheTask { + time_profiler_chan: time::ProfilerChan, + load_placeholder: LoadPlaceholder) -> ImageCacheTask { let (chan, port) = channel(); let chan_clone = chan.clone(); @@ -89,8 +91,9 @@ impl ImageCacheTask { need_exit: None, task_pool: task_pool, time_profiler_chan: time_profiler_chan, + placeholder_data: Arc::new(vec!()), }; - cache.run(); + cache.run(load_placeholder); }); ImageCacheTask { @@ -99,12 +102,13 @@ impl ImageCacheTask { } pub fn new_sync(resource_task: ResourceTask, task_pool: TaskPool, - time_profiler_chan: time::ProfilerChan) -> ImageCacheTask { + time_profiler_chan: time::ProfilerChan, + load_placeholder: LoadPlaceholder) -> ImageCacheTask { let (chan, port) = channel(); spawn_named("ImageCacheTask (sync)".to_owned(), move || { let inner_cache = ImageCacheTask::new(resource_task, task_pool, - time_profiler_chan); + time_profiler_chan, load_placeholder); loop { let msg: Msg = port.recv().unwrap(); @@ -142,6 +146,8 @@ struct ImageCache { need_exit: Option<Sender<()>>, task_pool: TaskPool, time_profiler_chan: time::ProfilerChan, + // Default image used when loading fails. + placeholder_data: Arc<Vec<u8>>, } #[derive(Clone)] @@ -160,8 +166,32 @@ enum AfterPrefetch { DoNotDecode } +pub enum LoadPlaceholder { + Preload, + Ignore +} + impl ImageCache { - pub fn run(&mut self) { + // Used to preload the default placeholder. + fn init(&mut self) { + let mut placeholder_url = resources_dir_path(); + // TODO (Savago): replace for a prettier one. + placeholder_url.push("rippy.jpg"); + let image = load_image_data(Url::from_file_path(&*placeholder_url).unwrap(), self.resource_task.clone(), &self.placeholder_data); + + match image { + Err(..) => debug!("image_cache_task: failed loading the placeholder."), + Ok(image_data) => self.placeholder_data = Arc::new(image_data), + } + } + + pub fn run(&mut self, load_placeholder: LoadPlaceholder) { + // We have to load the placeholder before running. + match load_placeholder { + LoadPlaceholder::Preload => self.init(), + LoadPlaceholder::Ignore => debug!("image_cache_task: use old behavior."), + } + let mut store_chan: Option<Sender<()>> = None; let mut store_prefetched_chan: Option<Sender<()>> = None; @@ -245,12 +275,12 @@ impl ImageCache { let to_cache = self.chan.clone(); let resource_task = self.resource_task.clone(); let url_clone = url.clone(); - + let placeholder = self.placeholder_data.clone(); spawn_named("ImageCacheTask (prefetch)".to_owned(), move || { let url = url_clone; debug!("image_cache_task: started fetch for {}", url.serialize()); - let image = load_image_data(url.clone(), resource_task.clone()); + let image = load_image_data(url.clone(), resource_task.clone(), &placeholder); to_cache.send(Msg::StorePrefetchedImageData(url.clone(), image)).unwrap(); debug!("image_cache_task: ended fetch for {}", url.serialize()); }); @@ -446,9 +476,9 @@ impl ImageCacheTask { } } -fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<Vec<u8>, ()> { +fn load_image_data(url: Url, resource_task: ResourceTask, placeholder: &[u8]) -> Result<Vec<u8>, ()> { let (response_chan, response_port) = channel(); - resource_task.send(resource_task::ControlMsg::Load(LoadData::new(url, response_chan))).unwrap(); + resource_task.send(resource_task::ControlMsg::Load(LoadData::new(url.clone(), response_chan))).unwrap(); let mut image_data = vec!(); @@ -462,7 +492,19 @@ fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<Vec<u8>, ()> return Ok(image_data); } Done(Err(..)) => { - return Err(()); + // Failure to load the requested image will return the + // placeholder instead. In case it failed to load at init(), + // we still recover and return Err() but nothing will be drawn. + if placeholder.len() != 0 { + debug!("image_cache_task: failed to load {:?}, use placeholder instead.", url); + // Clean in case there was an error after started loading the image. + image_data.clear(); + image_data.push_all(&placeholder); + return Ok(image_data); + } else { + debug!("image_cache_task: invalid placeholder."); + return Err(()); + } } } } @@ -595,7 +637,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(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Ignore); image_cache_task.exit(); mock_resource_task.send(resource_task::ControlMsg::Exit); @@ -606,7 +648,7 @@ mod tests { fn should_panic_if_unprefetched_image_is_requested() { let mock_resource_task = mock_resource_task(box DoesNothing); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload); let url = Url::parse("file:///").unwrap(); let (chan, port) = channel(); @@ -620,7 +662,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(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url)); @@ -635,7 +677,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(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Ignore); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url.clone())); @@ -655,7 +697,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(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Ignore); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url.clone())); @@ -672,7 +714,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(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload); let url = Url::parse("file:///").unwrap(); let join_port = image_cache_task.wait_for_store(); @@ -698,7 +740,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(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload); let url = Url::parse("file:///").unwrap(); let join_port = image_cache_task.wait_for_store(); @@ -752,7 +794,7 @@ mod tests { } }); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Ignore); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url.clone())); @@ -804,7 +846,7 @@ mod tests { } }); - let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Ignore); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url.clone())); @@ -833,7 +875,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(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload); let url = Url::parse("file:///").unwrap(); let join_port = image_cache_task.wait_for_store_prefetched(); @@ -859,7 +901,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(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload); let url = Url::parse("file:///").unwrap(); let join_port = image_cache_task.wait_for_store_prefetched(); @@ -893,7 +935,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(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload); let url = Url::parse("file:///").unwrap(); let join_port = image_cache_task.wait_for_store(); @@ -921,7 +963,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(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload); let url = Url::parse("file:///").unwrap(); let join_port = image_cache_task.wait_for_store(); @@ -949,7 +991,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(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Ignore); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url.clone())); @@ -975,7 +1017,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(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Ignore); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url.clone())); @@ -999,7 +1041,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(), TaskPool::new(4), profiler()); + let image_cache_task = ImageCacheTask::new_sync(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload); let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url.clone())); diff --git a/components/net/storage_task.rs b/components/net/storage_task.rs index 658340b8bf3..4533a364f6a 100644 --- a/components/net/storage_task.rs +++ b/components/net/storage_task.rs @@ -30,10 +30,10 @@ pub enum StorageTaskMsg { /// sets the value of the given key in the associated storage data /// TODO throw QuotaExceededError in case of error - SetItem(Sender<bool>, Url, StorageType, DOMString, DOMString), + SetItem(Sender<(bool, Option<DOMString>)>, Url, StorageType, DOMString, DOMString), /// removes the key/value pair for the given key in the associated storage data - RemoveItem(Sender<bool>, Url, StorageType, DOMString), + RemoveItem(Sender<Option<DOMString>>, Url, StorageType, DOMString), /// clears the associated storage data by removing all the key/value pairs Clear(Sender<bool>, Url, StorageType), @@ -133,23 +133,25 @@ impl StorageManager { .map(|key| key.clone())).unwrap(); } - fn set_item(&mut self, sender: Sender<bool>, url: Url, storage_type: StorageType, name: DOMString, value: DOMString) { + /// Sends Some(old_value) in case there was a previous value with the same key name but with different + /// value name, otherwise sends None + fn set_item(&mut self, sender: Sender<(bool, Option<DOMString>)>, url: Url, storage_type: StorageType, name: DOMString, value: DOMString) { let origin = self.get_origin_as_string(url); let data = self.select_data_mut(storage_type); if !data.contains_key(&origin) { data.insert(origin.clone(), BTreeMap::new()); } - let updated = data.get_mut(&origin).map(|entry| { - if entry.get(&origin).map_or(true, |item| *item != value) { - entry.insert(name.clone(), value.clone()); - true - } else { - false - } + let (changed, old_value) = data.get_mut(&origin).map(|entry| { + entry.insert(name, value.clone()).map_or( + (true, None), + |old| if old == value { + (false, None) + } else { + (true, Some(old)) + }) }).unwrap(); - - sender.send(updated).unwrap(); + sender.send((changed, old_value)).unwrap(); } fn get_item(&self, sender: Sender<Option<DOMString>>, url: Url, storage_type: StorageType, name: DOMString) { @@ -160,11 +162,14 @@ impl StorageManager { .map(|value| value.to_string())).unwrap(); } - fn remove_item(&mut self, sender: Sender<bool>, url: Url, storage_type: StorageType, name: DOMString) { + /// Sends Some(old_value) in case there was a previous value with the key name, otherwise sends None + fn remove_item(&mut self, sender: Sender<Option<DOMString>>, url: Url, storage_type: StorageType, name: DOMString) { let origin = self.get_origin_as_string(url); let data = self.select_data_mut(storage_type); - sender.send(data.get_mut(&origin) - .map_or(false, |entry| entry.remove(&name).is_some())).unwrap(); + let old_value = data.get_mut(&origin).map(|entry| { + entry.remove(&name) + }).unwrap(); + sender.send(old_value).unwrap(); } fn clear(&mut self, sender: Sender<bool>, url: Url, storage_type: StorageType) { diff --git a/components/profile/lib.rs b/components/profile/lib.rs index c8ffdc72d17..55a59065a4e 100644 --- a/components/profile/lib.rs +++ b/components/profile/lib.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#![feature(box_syntax)] #![feature(collections)] #![feature(core)] #![cfg_attr(target_os="linux", feature(io))] diff --git a/components/profile/mem.rs b/components/profile/mem.rs index b6944b4ef59..38e4eb7088d 100644 --- a/components/profile/mem.rs +++ b/components/profile/mem.rs @@ -32,12 +32,13 @@ macro_rules! path { }} } +/// A single memory-related measurement. pub struct Report { /// The identifying path for this report. pub path: Vec<String>, /// The size, in bytes. - pub size: u64, + pub size: usize, } /// A channel through which memory reports can be sent. @@ -118,7 +119,7 @@ impl Profiler { // Register the system memory reporter, which will run on the memory profiler's own thread. // It never needs to be unregistered, because as long as the memory profiler is running the // system memory reporter can make measurements. - let system_reporter = Box::new(SystemReporter); + let system_reporter = box SystemReporter; mem_profiler_chan.send(ProfilerMsg::RegisterReporter("system".to_owned(), system_reporter)); mem_profiler_chan @@ -208,7 +209,7 @@ impl Profiler { struct ReportsTree { /// For leaf nodes, this is the sum of the sizes of all reports that mapped to this location. /// For interior nodes, this is the sum of the sizes of all its child nodes. - size: u64, + size: usize, /// For leaf nodes, this is the count of all reports that mapped to this location. /// For interor nodes, this is always zero. @@ -243,7 +244,7 @@ impl ReportsTree { } // Insert the path and size into the tree, adding any nodes as necessary. - fn insert(&mut self, path: &[String], size: u64) { + fn insert(&mut self, path: &[String], size: usize) { let mut t: &mut ReportsTree = self; for path_seg in path.iter() { let i = match t.find_child(&path_seg) { @@ -264,7 +265,7 @@ impl ReportsTree { // Fill in sizes for interior nodes. Should only be done once all the reports have been // inserted. - fn compute_interior_node_sizes(&mut self) -> u64 { + fn compute_interior_node_sizes(&mut self) -> usize { if !self.children.is_empty() { // Interior node. Derive its size from its children. if self.size != 0 { @@ -313,7 +314,7 @@ impl ReportsForest { } // Insert the path and size into the forest, adding any trees and nodes as necessary. - fn insert(&mut self, path: &[String], size: u64) { + fn insert(&mut self, path: &[String], size: usize) { // Get the right tree, creating it if necessary. if !self.trees.contains_key(&path[0]) { self.trees.insert(path[0].clone(), ReportsTree::new(path[0].clone())); @@ -440,7 +441,7 @@ mod system_reporter { } #[cfg(target_os="linux")] - fn get_system_heap_allocated() -> Option<u64> { + fn get_system_heap_allocated() -> Option<usize> { let mut info: struct_mallinfo; unsafe { info = mallinfo(); @@ -449,11 +450,11 @@ mod system_reporter { // would suffice, but that only gets the small allocations that are put in // the brk heap. We need |hblkhd| as well to get the larger allocations // that are mmapped. - Some((info.hblkhd + info.uordblks) as u64) + Some((info.hblkhd + info.uordblks) as usize) } #[cfg(not(target_os="linux"))] - fn get_system_heap_allocated() -> Option<u64> { + fn get_system_heap_allocated() -> Option<usize> { None } @@ -462,7 +463,7 @@ mod system_reporter { newp: *mut c_void, newlen: size_t) -> c_int; } - fn get_jemalloc_stat(value_name: &str) -> Option<u64> { + fn get_jemalloc_stat(value_name: &str) -> Option<usize> { // Before we request the measurement of interest, we first send an "epoch" // request. Without that jemalloc gives cached statistics(!) which can be // highly inaccurate. @@ -494,7 +495,7 @@ mod system_reporter { return None; } - Some(value as u64) + Some(value as usize) } // Like std::macros::try!, but for Option<>. @@ -503,7 +504,7 @@ mod system_reporter { ); #[cfg(target_os="linux")] - fn get_proc_self_statm_field(field: usize) -> Option<u64> { + fn get_proc_self_statm_field(field: usize) -> Option<usize> { use std::fs::File; use std::io::Read; @@ -511,42 +512,42 @@ mod system_reporter { let mut contents = String::new(); option_try!(f.read_to_string(&mut contents).ok()); let s = option_try!(contents.words().nth(field)); - let npages = option_try!(s.parse::<u64>().ok()); - Some(npages * (::std::env::page_size() as u64)) + let npages = option_try!(s.parse::<usize>().ok()); + Some(npages * ::std::env::page_size()) } #[cfg(target_os="linux")] - fn get_vsize() -> Option<u64> { + fn get_vsize() -> Option<usize> { get_proc_self_statm_field(0) } #[cfg(target_os="linux")] - fn get_resident() -> Option<u64> { + fn get_resident() -> Option<usize> { get_proc_self_statm_field(1) } #[cfg(target_os="macos")] - fn get_vsize() -> Option<u64> { + fn get_vsize() -> Option<usize> { virtual_size() } #[cfg(target_os="macos")] - fn get_resident() -> Option<u64> { + fn get_resident() -> Option<usize> { resident_size() } #[cfg(not(any(target_os="linux", target_os = "macos")))] - fn get_vsize() -> Option<u64> { + fn get_vsize() -> Option<usize> { None } #[cfg(not(any(target_os="linux", target_os = "macos")))] - fn get_resident() -> Option<u64> { + fn get_resident() -> Option<usize> { None } #[cfg(target_os="linux")] - fn get_resident_segments() -> Vec<(String, u64)> { + fn get_resident_segments() -> Vec<(String, usize)> { use regex::Regex; use std::collections::HashMap; use std::collections::hash_map::Entry; @@ -575,7 +576,7 @@ mod system_reporter { let rss_re = Regex::new(r"^Rss: +(\d+) kB").unwrap(); // We record each segment's resident size. - let mut seg_map: HashMap<String, u64> = HashMap::new(); + let mut seg_map: HashMap<String, usize> = HashMap::new(); #[derive(PartialEq)] enum LookingFor { Segment, Rss } @@ -620,7 +621,7 @@ mod system_reporter { Some(cap) => cap, None => continue, }; - let rss = cap.at(1).unwrap().parse::<u64>().unwrap() * 1024; + let rss = cap.at(1).unwrap().parse::<usize>().unwrap() * 1024; if rss > 0 { // Aggregate small segments into "other". @@ -639,7 +640,7 @@ mod system_reporter { } } - let mut segs: Vec<(String, u64)> = seg_map.into_iter().collect(); + let mut segs: Vec<(String, usize)> = seg_map.into_iter().collect(); // Note that the sum of all these segments' RSS values differs from the "resident" measurement // obtained via /proc/<pid>/statm in get_resident(). It's unclear why this difference occurs; @@ -650,7 +651,7 @@ mod system_reporter { } #[cfg(not(target_os="linux"))] - fn get_resident_segments() -> Vec<(String, u64)> { + fn get_resident_segments() -> Vec<(String, usize)> { vec![] } } diff --git a/components/script/cors.rs b/components/script/cors.rs index 6930848bb7c..c11f8233c4a 100644 --- a/components/script/cors.rs +++ b/components/script/cors.rs @@ -171,7 +171,7 @@ impl CORSRequest { }; // Substep 4 if methods.len() == 0 || preflight.mode == RequestMode::ForcedPreflight { - methods = methods_substep4.as_slice(); + methods = &methods_substep4; } // Substep 5 if !is_simple_method(&self.method) && @@ -183,7 +183,7 @@ impl CORSRequest { if is_simple_header(&h) { continue; } - if !headers.iter().any(|ref h2| h.name().eq_ignore_ascii_case(h2.as_slice())) { + if !headers.iter().any(|ref h2| h.name().eq_ignore_ascii_case(h2)) { return error; } } @@ -254,7 +254,7 @@ pub enum HeaderOrMethod { impl HeaderOrMethod { fn match_header(&self, header_name: &str) -> bool { match *self { - HeaderOrMethod::HeaderData(ref s) => s.as_slice().eq_ignore_ascii_case(header_name), + HeaderOrMethod::HeaderData(ref s) => s.eq_ignore_ascii_case(header_name), _ => false } } diff --git a/components/script/devtools.rs b/components/script/devtools.rs index 7071d2fa0f5..6f6bef0a7a2 100644 --- a/components/script/devtools.rs +++ b/components/script/devtools.rs @@ -26,7 +26,7 @@ pub fn handle_evaluate_js(page: &Rc<Page>, pipeline: PipelineId, eval: String, r let page = get_page(&*page, pipeline); let window = page.window().root(); let cx = window.r().get_cx(); - let rval = window.r().evaluate_js_on_global_with_result(eval.as_slice()); + let rval = window.r().evaluate_js_on_global_with_result(&eval); reply.send(if rval.is_undefined() { EvaluateJSReply::VoidValue @@ -69,7 +69,7 @@ fn find_node_by_unique_id(page: &Rc<Page>, pipeline: PipelineId, node_id: String let node: JSRef<Node> = NodeCast::from_ref(document.r()); for candidate in node.traverse_preorder() { - if candidate.get_unique_id().as_slice() == node_id.as_slice() { + if candidate.get_unique_id() == node_id { return Temporary::from_rooted(candidate); } } diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs index f201c768187..a2b8ac77afe 100644 --- a/components/script/dom/attr.rs +++ b/components/script/dom/attr.rs @@ -3,8 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::cell::DOMRefCell; -use dom::bindings::codegen::Bindings::AttrBinding; -use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods; +use dom::bindings::codegen::Bindings::AttrBinding::{self, AttrMethods}; use dom::bindings::codegen::InheritTypes::NodeCast; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, JSRef, Temporary}; @@ -41,7 +40,7 @@ pub enum AttrValue { impl AttrValue { pub fn from_serialized_tokenlist(tokens: DOMString) -> AttrValue { let mut atoms: Vec<Atom> = vec!(); - for token in split_html_space_chars(tokens.as_slice()).map(|slice| Atom::from_slice(slice)) { + for token in split_html_space_chars(&tokens).map(Atom::from_slice) { if !atoms.iter().any(|atom| *atom == token) { atoms.push(token); } @@ -50,10 +49,7 @@ impl AttrValue { } pub fn from_atomic_tokens(atoms: Vec<Atom>) -> AttrValue { - let tokens = { - let slices: Vec<&str> = atoms.iter().map(|atom| atom.as_slice()).collect(); - slices.connect("\x20") - }; + let tokens = atoms.iter().map(Atom::as_slice).collect::<Vec<_>>().connect("\x20"); AttrValue::TokenList(tokens, atoms) } @@ -64,7 +60,7 @@ impl AttrValue { } pub fn from_atomic(string: DOMString) -> AttrValue { - let value = Atom::from_slice(string.as_slice()); + let value = Atom::from_slice(&string); AttrValue::Atom(value) } @@ -80,13 +76,14 @@ impl Str for AttrValue { fn as_slice<'a>(&'a self) -> &'a str { match *self { AttrValue::String(ref value) | - AttrValue::TokenList(ref value, _) | - AttrValue::UInt(ref value, _) => value.as_slice(), - AttrValue::Atom(ref value) => value.as_slice(), + AttrValue::TokenList(ref value, _) | + AttrValue::UInt(ref value, _) => &value, + AttrValue::Atom(ref value) => &value, } } } +// https://dom.spec.whatwg.org/#interface-attr #[dom_struct] pub struct Attr { reflector_: Reflector, @@ -101,8 +98,7 @@ pub struct Attr { } impl Attr { - fn new_inherited(local_name: Atom, value: AttrValue, - name: Atom, namespace: Namespace, + fn new_inherited(local_name: Atom, value: AttrValue, name: Atom, namespace: Namespace, prefix: Option<DOMString>, owner: Option<JSRef<Element>>) -> Attr { Attr { reflector_: Reflector::new(), @@ -111,15 +107,17 @@ impl Attr { name: name, namespace: namespace, prefix: prefix, - owner: owner.map(|o| JS::from_rooted(o)), + owner: owner.map(JS::from_rooted), } } pub fn new(window: JSRef<Window>, local_name: Atom, value: AttrValue, name: Atom, namespace: Namespace, prefix: Option<DOMString>, owner: Option<JSRef<Element>>) -> Temporary<Attr> { - reflect_dom_object(box Attr::new_inherited(local_name, value, name, namespace, prefix, owner), - GlobalRef::Window(window), AttrBinding::Wrap) + reflect_dom_object( + box Attr::new_inherited(local_name, value, name, namespace, prefix, owner), + GlobalRef::Window(window), + AttrBinding::Wrap) } #[inline] @@ -139,19 +137,20 @@ impl Attr { } impl<'a> AttrMethods for JSRef<'a, Attr> { + // https://dom.spec.whatwg.org/#dom-attr-localname fn LocalName(self) -> DOMString { self.local_name().as_slice().to_owned() } + // https://dom.spec.whatwg.org/#dom-attr-value fn Value(self) -> DOMString { self.value().as_slice().to_owned() } + // https://dom.spec.whatwg.org/#dom-attr-value fn SetValue(self, value: DOMString) { match self.owner { - None => { - *self.value.borrow_mut() = AttrValue::String(value) - } + None => *self.value.borrow_mut() = AttrValue::String(value), Some(o) => { let owner = o.root(); let value = owner.r().parse_attribute(&self.namespace, self.local_name(), value); @@ -160,26 +159,32 @@ impl<'a> AttrMethods for JSRef<'a, Attr> { } } + // https://dom.spec.whatwg.org/#dom-attr-textcontent fn TextContent(self) -> DOMString { self.Value() } + // https://dom.spec.whatwg.org/#dom-attr-textcontent fn SetTextContent(self, value: DOMString) { self.SetValue(value) } + // https://dom.spec.whatwg.org/#dom-attr-nodevalue fn NodeValue(self) -> DOMString { self.Value() } + // https://dom.spec.whatwg.org/#dom-attr-nodevalue fn SetNodeValue(self, value: DOMString) { self.SetValue(value) } + // https://dom.spec.whatwg.org/#dom-attr-name fn Name(self) -> DOMString { self.name.as_slice().to_owned() } + // https://dom.spec.whatwg.org/#dom-attr-namespaceuri fn GetNamespaceURI(self) -> Option<DOMString> { let Namespace(ref atom) = self.namespace; match atom.as_slice() { @@ -188,14 +193,17 @@ impl<'a> AttrMethods for JSRef<'a, Attr> { } } + // https://dom.spec.whatwg.org/#dom-attr-prefix fn GetPrefix(self) -> Option<DOMString> { self.prefix.clone() } + // https://dom.spec.whatwg.org/#dom-attr-ownerelement fn GetOwnerElement(self) -> Option<Temporary<Element>> { self.owner.map(|o| Temporary::new(o)) } + // https://dom.spec.whatwg.org/#dom-attr-specified fn Specified(self) -> bool { true // Always returns true } diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index f390a6444ee..84644a8428f 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -57,7 +57,7 @@ use js::jsval::JSVal; use layout_interface::TrustedNodeAddress; use script_task::STACK_ROOTS; -use util::smallvec::{SmallVec, SmallVec16}; +use util::smallvec::{SmallVec, SmallVec24}; use core::nonzero::NonZero; use std::cell::{Cell, UnsafeCell}; @@ -610,7 +610,7 @@ impl<T: Assignable<U>, U: Reflectable> TemporaryPushable<T> for Vec<JS<U>> { /// See also [*Exact Stack Rooting - Storing a GCPointer on the CStack*] /// (https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/GC/Exact_Stack_Rooting). pub struct RootCollection { - roots: UnsafeCell<SmallVec16<*mut JSObject>>, + roots: UnsafeCell<SmallVec24<*mut JSObject>>, } /// A pointer to a RootCollection, for use in global variables. @@ -622,7 +622,7 @@ impl RootCollection { /// Create an empty collection of roots pub fn new() -> RootCollection { RootCollection { - roots: UnsafeCell::new(SmallVec16::new()), + roots: UnsafeCell::new(SmallVec24::new()), } } @@ -632,6 +632,7 @@ impl RootCollection { let roots = self.roots.get(); (*roots).push(untracked.js_ptr); debug!(" rooting {:?}", untracked.js_ptr); + assert!(!(*roots).spilled()); } } diff --git a/components/script/dom/bindings/str.rs b/components/script/dom/bindings/str.rs index 88561210617..95ee01d8517 100644 --- a/components/script/dom/bindings/str.rs +++ b/components/script/dom/bindings/str.rs @@ -24,7 +24,7 @@ impl ByteString { /// otherwise. pub fn as_str<'a>(&'a self) -> Option<&'a str> { let ByteString(ref vec) = *self; - str::from_utf8(vec.as_slice()).ok() + str::from_utf8(&vec).ok() } /// Returns the underlying vector as a slice. diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index fe3129dce07..0dbe3bd4c78 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -57,11 +57,13 @@ use msg::constellation_msg::ConstellationChan; use util::smallvec::{SmallVec1, SmallVec}; use util::str::{LengthOrPercentageOrAuto}; use std::cell::{Cell, RefCell}; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::collections::hash_state::HashState; use std::ffi::CString; use std::hash::{Hash, Hasher}; +use std::intrinsics::return_address; use std::old_io::timer::Timer; +use std::ops::{Deref, DerefMut}; use std::rc::Rc; use std::sync::mpsc::{Receiver, Sender}; use string_cache::{Atom, Namespace}; @@ -291,3 +293,135 @@ impl JSTraceable for Box<LayoutRPC+'static> { // Do nothing } } + +/// Holds a set of vectors that need to be rooted +pub struct RootedCollectionSet { + set: Vec<HashSet<*const RootedVec<()>>> +} + +/// TLV Holds a set of vectors that need to be rooted +thread_local!(pub static ROOTED_COLLECTIONS: Rc<RefCell<RootedCollectionSet>> = + Rc::new(RefCell::new(RootedCollectionSet::new()))); + +enum CollectionType { + DOMObjects, + JSVals, + JSObjects, +} + + +impl RootedCollectionSet { + fn new() -> RootedCollectionSet { + RootedCollectionSet { + set: vec!(HashSet::new(), HashSet::new(), HashSet::new()) + } + } + + fn remove<T: VecRootableType>(collection: &RootedVec<T>) { + ROOTED_COLLECTIONS.with(|ref collections| { + let type_ = VecRootableType::tag(None::<T>); + let mut collections = collections.borrow_mut(); + assert!(collections.set[type_ as uint].remove(&(collection as *const _ as *const _))); + }); + } + + fn add<T: VecRootableType>(collection: &RootedVec<T>) { + ROOTED_COLLECTIONS.with(|ref collections| { + let type_ = VecRootableType::tag(None::<T>); + let mut collections = collections.borrow_mut(); + collections.set[type_ as uint].insert(collection as *const _ as *const _); + }) + } + + unsafe fn trace(&self, tracer: *mut JSTracer) { + fn trace_collection_type<T: JSTraceable>(tracer: *mut JSTracer, + collections: &HashSet<*const RootedVec<()>>) { + for collection in collections { + let collection: *const RootedVec<()> = *collection; + let collection = collection as *const RootedVec<T>; + unsafe { + let _ = (*collection).trace(tracer); + } + } + } + + let dom_collections = &self.set[CollectionType::DOMObjects as uint] as *const _ as *const HashSet<*const RootedVec<*const Reflector>>; + for dom_collection in (*dom_collections).iter() { + for reflector in (**dom_collection).iter() { + trace_reflector(tracer, "", &**reflector); + } + } + + trace_collection_type::<JSVal>(tracer, &self.set[CollectionType::JSVals as uint]); + trace_collection_type::<*mut JSObject>(tracer, &self.set[CollectionType::JSObjects as uint]); + } +} + + +/// Trait implemented by all types that can be used with RootedVec +trait VecRootableType { + /// Return the type tag used to determine how to trace RootedVec + fn tag(_a: Option<Self>) -> CollectionType; +} + +impl<T: Reflectable> VecRootableType for JS<T> { + fn tag(_a: Option<JS<T>>) -> CollectionType { CollectionType::DOMObjects } +} + +impl VecRootableType for JSVal { + fn tag(_a: Option<JSVal>) -> CollectionType { CollectionType::JSVals } +} + +impl VecRootableType for *mut JSObject { + fn tag(_a: Option<*mut JSObject>) -> CollectionType { CollectionType::JSObjects } +} + +/// A vector of items that are rooted for the lifetime +/// of this struct +#[allow(unrooted_must_root)] +#[jstraceable] +pub struct RootedVec<T> { + v: Vec<T> +} + + +impl<T: VecRootableType> RootedVec<T> { + /// Create a vector of items of type T that is rooted for + /// the lifetime of this struct + pub fn new() -> RootedVec<T> { + unsafe { + RootedCollectionSet::add::<T>(&*(return_address() as *const _)); + } + RootedVec::<T> { v: vec!() } + } + +} + +#[unsafe_destructor] +impl<T: VecRootableType> Drop for RootedVec<T> { + fn drop(&mut self) { + RootedCollectionSet::remove(self); + } +} + +impl<T> Deref for RootedVec<T> { + type Target = Vec<T>; + fn deref(&self) -> &Vec<T> { + &self.v + } +} + +impl<T> DerefMut for RootedVec<T> { + fn deref_mut(&mut self) -> &mut Vec<T> { + &mut self.v + } +} + + +/// SM Callback that traces the rooted collections +pub unsafe extern fn trace_collections(tracer: *mut JSTracer, _data: *mut libc::c_void) { + ROOTED_COLLECTIONS.with(|ref collections| { + let collections = collections.borrow(); + collections.trace(tracer); + }); +} diff --git a/components/script/dom/canvasgradient.rs b/components/script/dom/canvasgradient.rs index 349d434114c..2b193697124 100644 --- a/components/script/dom/canvasgradient.rs +++ b/components/script/dom/canvasgradient.rs @@ -52,7 +52,7 @@ impl<'a> CanvasGradientMethods for JSRef<'a, CanvasGradient> { self.stops.borrow_mut().push(CanvasGradientStop { offset: (*offset) as f64, - color: parse_color(color.as_slice()).unwrap_or(default_black), + color: parse_color(&color).unwrap_or(default_black), }); } } diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 6a3689e1459..4145c8e28cc 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -460,15 +460,21 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> Point2D(x as f32, y as f32))).unwrap(); } - fn Arc(self, x: Finite<f64>, y: Finite<f64>, r: Finite<f64>, start: Finite<f64>, end: Finite<f64>, ccw: bool) { + fn Arc(self, x: Finite<f64>, y: Finite<f64>, r: Finite<f64>, + start: Finite<f64>, end: Finite<f64>, ccw: bool) -> Fallible<()> { let x = *x; let y = *y; let r = *r; let start = *start; let end = *end; + if r < 0.0 { + return Err(IndexSize); + } + self.renderer.send(CanvasMsg::Arc(Point2D(x as f32, y as f32), r as f32, start as f32, end as f32, ccw)).unwrap(); + Ok(()) } // https://html.spec.whatwg.org/#dom-context-2d-imagesmoothingenabled @@ -493,7 +499,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> fn SetStrokeStyle(self, value: StringOrCanvasGradientOrCanvasPattern) { match value { StringOrCanvasGradientOrCanvasPattern::eString(string) => { - match parse_color(string.as_slice()) { + match parse_color(&string) { Ok(rgba) => { self.stroke_color.set(rgba); self.renderer @@ -521,7 +527,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> fn SetFillStyle(self, value: StringOrCanvasGradientOrCanvasPattern) { match value { StringOrCanvasGradientOrCanvasPattern::eString(string) => { - match parse_color(string.as_slice()) { + match parse_color(&string) { Ok(rgba) => { self.fill_color.set(rgba); self.renderer @@ -640,7 +646,7 @@ impl Drop for CanvasRenderingContext2D { } pub fn parse_color(string: &str) -> Result<RGBA,()> { - match CSSColor::parse(&mut Parser::new(string.as_slice())) { + match CSSColor::parse(&mut Parser::new(&string)) { Ok(CSSColor::RGBA(rgba)) => Ok(rgba), _ => Err(()), } diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs index b41adcb8b06..c76ccee38fe 100644 --- a/components/script/dom/cssstyledeclaration.rs +++ b/components/script/dom/cssstyledeclaration.rs @@ -4,9 +4,7 @@ use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::{self, CSSStyleDeclarationMethods}; use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast}; -use dom::bindings::error::Error; -use dom::bindings::error::ErrorResult; -use dom::bindings::error::Fallible; +use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, JSRef, OptionalRootedRootable, Temporary}; use dom::bindings::utils::{Reflector, reflect_dom_object}; @@ -50,20 +48,14 @@ macro_rules! css_properties( ); fn serialize_list(list: &Vec<PropertyDeclaration>) -> DOMString { - let mut result = String::new(); - for declaration in list.iter() { - result.push_str(serialize_value(declaration).as_slice()); - result.push_str(" "); - } - result -} - -fn serialize_value(declaration: &PropertyDeclaration) -> DOMString { - declaration.value() + list.iter().fold(String::new(), |accum, ref declaration| { + accum + &declaration.value() + " " + }) } impl CSSStyleDeclaration { - pub fn new_inherited(owner: JSRef<HTMLElement>, modification_access: CSSModificationAccess) -> CSSStyleDeclaration { + pub fn new_inherited(owner: JSRef<HTMLElement>, + modification_access: CSSModificationAccess) -> CSSStyleDeclaration { CSSStyleDeclaration { reflector_: Reflector::new(), owner: JS::from_rooted(owner), @@ -71,7 +63,8 @@ impl CSSStyleDeclaration { } } - pub fn new(global: JSRef<Window>, owner: JSRef<HTMLElement>, modification_access: CSSModificationAccess) -> Temporary<CSSStyleDeclaration> { + pub fn new(global: JSRef<Window>, owner: JSRef<HTMLElement>, + modification_access: CSSModificationAccess) -> Temporary<CSSStyleDeclaration> { reflect_dom_object(box CSSStyleDeclaration::new_inherited(owner, modification_access), GlobalRef::Window(global), CSSStyleDeclarationBinding::Wrap) @@ -98,6 +91,7 @@ impl<'a> PrivateCSSStyleDeclarationHelpers for JSRef<'a, CSSStyleDeclaration> { } impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { + // http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-length fn Length(self) -> u32 { let owner = self.owner.root(); let elem: JSRef<Element> = ElementCast::from_ref(owner.r()); @@ -108,6 +102,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { len as u32 } + // http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-item fn Item(self, index: u32) -> DOMString { let index = index as usize; let owner = self.owner.root(); @@ -131,10 +126,10 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { // http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue fn GetPropertyValue(self, property: DOMString) -> DOMString { // Step 1 - let property = Atom::from_slice(property.as_slice().to_ascii_lowercase().as_slice()); + let property = Atom::from_slice(&property.to_ascii_lowercase()); // Step 2 - let longhand_properties = longhands_from_shorthand(property.as_slice()); + let longhand_properties = longhands_from_shorthand(&property); if let Some(longhand_properties) = longhand_properties { // Step 2.1 let mut list = vec!(); @@ -142,7 +137,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { // Step 2.2 for longhand in longhand_properties.iter() { // Step 2.2.1 - let declaration = self.get_declaration(&Atom::from_slice(longhand.as_slice())); + let declaration = self.get_declaration(&Atom::from_slice(&longhand)); // Step 2.2.2 & 2.2.3 match declaration { @@ -157,7 +152,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { // Step 3 & 4 if let Some(ref declaration) = self.get_declaration(&property) { - serialize_value(declaration) + declaration.value() } else { "".to_owned() } @@ -166,15 +161,15 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { // http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority fn GetPropertyPriority(self, property: DOMString) -> DOMString { // Step 1 - let property = Atom::from_slice(property.as_slice().to_ascii_lowercase().as_slice()); + let property = Atom::from_slice(&property.to_ascii_lowercase()); // Step 2 - let longhand_properties = longhands_from_shorthand(property.as_slice()); + let longhand_properties = longhands_from_shorthand(&property); if let Some(longhand_properties) = longhand_properties { // Step 2.1 & 2.2 & 2.3 if longhand_properties.iter() .map(|longhand| self.GetPropertyPriority(longhand.clone())) - .all(|priority| priority.as_slice() == "important") { + .all(|priority| priority == "important") { return "important".to_owned(); } @@ -196,10 +191,10 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { } // Step 2 - let property = property.as_slice().to_ascii_lowercase(); + let property = property.to_ascii_lowercase(); // Step 3 - if !is_supported_property(property.as_slice()) { + if !is_supported_property(&property) { return Ok(()); } @@ -209,20 +204,19 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { } // Step 5 - let priority = priority.as_slice().to_ascii_lowercase(); - if priority.as_slice() != "!important" && !priority.is_empty() { + let priority = priority.to_ascii_lowercase(); + if priority != "!important" && !priority.is_empty() { return Ok(()); } // Step 6 - let mut synthesized_declaration = String::from_str(property.as_slice()); + let mut synthesized_declaration = String::from_str(&property); synthesized_declaration.push_str(": "); - synthesized_declaration.push_str(value.as_slice()); + synthesized_declaration.push_str(&value); let owner = self.owner.root(); let window = window_from_node(owner.r()).root(); - let decl_block = parse_style_attribute(synthesized_declaration.as_slice(), - &window.r().get_url()); + let decl_block = parse_style_attribute(&synthesized_declaration, &window.r().get_url()); // Step 7 if decl_block.normal.len() == 0 { @@ -235,7 +229,11 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { // Step 8 for decl in decl_block.normal.iter() { // Step 9 - let style_priority = if priority.is_empty() { StylePriority::Normal } else { StylePriority::Important }; + let style_priority = if priority.is_empty() { + StylePriority::Normal + } else { + StylePriority::Important + }; element.update_inline_style(decl.clone(), style_priority); } @@ -253,29 +251,32 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { } // Step 2 - let property = property.as_slice().to_ascii_lowercase(); + let property = property.to_ascii_lowercase(); // Step 3 - if !is_supported_property(property.as_slice()) { + if !is_supported_property(&property) { return Ok(()); } // Step 4 - let priority = priority.as_slice().to_ascii_lowercase(); - if priority.as_slice() != "important" && !priority.is_empty() { + let priority = priority.to_ascii_lowercase(); + if priority != "important" && !priority.is_empty() { return Ok(()); } let owner = self.owner.root(); let window = window_from_node(owner.r()).root(); - let decl_block = parse_style_attribute(property.as_slice(), - &window.r().get_url()); + let decl_block = parse_style_attribute(&property, &window.r().get_url()); let element: JSRef<Element> = ElementCast::from_ref(owner.r()); // Step 5 for decl in decl_block.normal.iter() { // Step 6 - let style_priority = if priority.is_empty() { StylePriority::Normal } else { StylePriority::Important }; + let style_priority = if priority.is_empty() { + StylePriority::Normal + } else { + StylePriority::Important + }; element.update_inline_style(decl.clone(), style_priority); } @@ -298,12 +299,12 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { } // Step 2 - let property = property.as_slice().to_ascii_lowercase(); + let property = property.to_ascii_lowercase(); // Step 3 let value = self.GetPropertyValue(property.clone()); - let longhand_properties = longhands_from_shorthand(property.as_slice()); + let longhand_properties = longhands_from_shorthand(&property); match longhand_properties { Some(longhands) => { // Step 4 diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 8ceb6ace1f3..debd6c0831a 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -323,7 +323,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { let node: JSRef<Node> = NodeCast::from_ref(element); node.is_in_doc() }); - assert!(!id.as_slice().is_empty()); + assert!(!id.is_empty()); let mut idmap = self.idmap.borrow_mut(); diff --git a/components/script/dom/domimplementation.rs b/components/script/dom/domimplementation.rs index 3353e735dfd..2b5bc3870c1 100644 --- a/components/script/dom/domimplementation.rs +++ b/components/script/dom/domimplementation.rs @@ -53,7 +53,7 @@ impl DOMImplementation { impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> { // http://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype fn CreateDocumentType(self, qname: DOMString, pubid: DOMString, sysid: DOMString) -> Fallible<Temporary<DocumentType>> { - match xml_name_type(qname.as_slice()) { + match xml_name_type(&qname) { // Step 1. InvalidXMLName => Err(InvalidCharacter), // Step 2. diff --git a/components/script/dom/domrectlist.rs b/components/script/dom/domrectlist.rs index 8ef7b8fce52..ec70329e092 100644 --- a/components/script/dom/domrectlist.rs +++ b/components/script/dom/domrectlist.rs @@ -6,6 +6,7 @@ use dom::bindings::codegen::Bindings::DOMRectListBinding; use dom::bindings::codegen::Bindings::DOMRectListBinding::DOMRectListMethods; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, JSRef, Temporary}; +use dom::bindings::trace::RootedVec; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::domrect::DOMRect; use dom::window::Window; @@ -19,17 +20,16 @@ pub struct DOMRectList { impl DOMRectList { fn new_inherited(window: JSRef<Window>, - rects: Vec<JSRef<DOMRect>>) -> DOMRectList { - let rects = rects.iter().map(|rect| JS::from_rooted(*rect)).collect(); + rects: &RootedVec<JS<DOMRect>>) -> DOMRectList { DOMRectList { reflector_: Reflector::new(), - rects: rects, + rects: (**rects).clone(), window: JS::from_rooted(window), } } pub fn new(window: JSRef<Window>, - rects: Vec<JSRef<DOMRect>>) -> Temporary<DOMRectList> { + rects: &RootedVec<JS<DOMRect>>) -> Temporary<DOMRectList> { reflect_dom_object(box DOMRectList::new_inherited(window, rects), GlobalRef::Window(window), DOMRectListBinding::Wrap) } diff --git a/components/script/dom/domtokenlist.rs b/components/script/dom/domtokenlist.rs index 2d0a4338be5..7d28c067acc 100644 --- a/components/script/dom/domtokenlist.rs +++ b/components/script/dom/domtokenlist.rs @@ -94,7 +94,7 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> { // http://dom.spec.whatwg.org/#dom-domtokenlist-contains fn Contains(self, token: DOMString) -> Fallible<bool> { - self.check_token_exceptions(token.as_slice()).map(|token| { + self.check_token_exceptions(&token).map(|token| { self.attribute().root().map(|attr| { // FIXME(https://github.com/rust-lang/rust/issues/23338) let attr = attr.r(); @@ -112,7 +112,7 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> { let element = self.element.root(); let mut atoms = element.r().get_tokenlist_attribute(&self.local_name); for token in tokens.iter() { - let token = try!(self.check_token_exceptions(token.as_slice())); + let token = try!(self.check_token_exceptions(&token)); if !atoms.iter().any(|atom| *atom == token) { atoms.push(token); } @@ -126,7 +126,7 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> { let element = self.element.root(); let mut atoms = element.r().get_tokenlist_attribute(&self.local_name); for token in tokens.iter() { - let token = try!(self.check_token_exceptions(token.as_slice())); + let token = try!(self.check_token_exceptions(&token)); atoms.iter().position(|atom| *atom == token).map(|index| { atoms.remove(index) }); @@ -139,7 +139,7 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> { fn Toggle(self, token: DOMString, force: Option<bool>) -> Fallible<bool> { let element = self.element.root(); let mut atoms = element.r().get_tokenlist_attribute(&self.local_name); - let token = try!(self.check_token_exceptions(token.as_slice())); + let token = try!(self.check_token_exceptions(&token)); match atoms.iter().position(|atom| *atom == token) { Some(index) => match force { Some(true) => Ok(true), diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 016ba9a87c1..f69392a4126 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -28,7 +28,8 @@ use dom::bindings::codegen::InheritTypes::HTMLFormElementDerived; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{NamespaceError, InvalidCharacter, Syntax}; use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, TemporaryPushable}; -use dom::bindings::js::{OptionalRootable, Root}; +use dom::bindings::js::OptionalRootable; +use dom::bindings::trace::RootedVec; use dom::bindings::utils::xml_name_type; use dom::bindings::utils::XMLName::{QName, Name, InvalidXMLName}; use dom::create::create_element; @@ -566,7 +567,7 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> { declarations.normal .iter() .chain(declarations.important.iter()) - .find(|decl| decl.matches(property.as_slice())) + .find(|decl| decl.matches(&property)) .map(|decl| decl.clone()) }) } @@ -576,7 +577,7 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> { inline_declarations.as_ref().and_then(|declarations| { declarations.important .iter() - .find(|decl| decl.matches(property.as_slice())) + .find(|decl| decl.matches(&property)) .map(|decl| decl.clone()) }) } @@ -679,7 +680,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { None => qname.local.clone(), Some(ref prefix) => { let name = format!("{}:{}", *prefix, qname.local.as_slice()); - Atom::from_slice(name.as_slice()) + Atom::from_slice(&name) }, }; let value = self.parse_attribute(&qname.ns, &qname.local, value); @@ -687,8 +688,8 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } fn set_attribute(self, name: &Atom, value: AttrValue) { - assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice()); - assert!(!name.as_slice().contains(":")); + assert!(name.as_slice() == name.to_ascii_lowercase()); + assert!(!name.contains(":")); self.do_set_attribute(name.clone(), value, name.clone(), ns!(""), None, |attr| attr.local_name() == name); @@ -697,7 +698,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { // https://html.spec.whatwg.org/multipage/dom.html#attr-data-* fn set_custom_attribute(self, name: DOMString, value: DOMString) -> ErrorResult { // Step 1. - match xml_name_type(name.as_slice()) { + match xml_name_type(&name) { InvalidXMLName => return Err(InvalidCharacter), _ => {} } @@ -784,7 +785,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { }; let is_equal = |lhs: &Atom, rhs: &Atom| match quirks_mode { NoQuirks | LimitedQuirks => lhs == rhs, - Quirks => lhs.as_slice().eq_ignore_ascii_case(rhs.as_slice()) + Quirks => lhs.eq_ignore_ascii_case(&rhs) }; self.get_attribute(ns!(""), &atom!("class")).root().map(|attr| { // FIXME(https://github.com/rust-lang/rust/issues/23338) @@ -797,13 +798,13 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } fn set_atomic_attribute(self, name: &Atom, value: DOMString) { - assert!(name.as_slice().eq_ignore_ascii_case(name.as_slice())); + assert!(name.as_slice() == name.to_ascii_lowercase()); let value = AttrValue::from_atomic(value); self.set_attribute(name, value); } fn has_attribute(self, name: &Atom) -> bool { - assert!(name.as_slice().bytes().all(|b| b.to_ascii_lowercase() == b)); + assert!(name.bytes().all(|b| b.to_ascii_lowercase() == b)); // FIXME(https://github.com/rust-lang/rust/issues/23338) let attrs = self.attrs.borrow(); attrs.iter().map(|attr| attr.root()).any(|attr| { @@ -820,12 +821,12 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { if value { self.set_string_attribute(name, String::new()); } else { - self.remove_attribute(ns!(""), name.as_slice()); + self.remove_attribute(ns!(""), &name); } } fn get_url_attribute(self, name: &Atom) -> DOMString { - assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice()); + assert!(name.as_slice() == name.to_ascii_lowercase()); if !self.has_attribute(name) { return "".to_owned(); } @@ -834,7 +835,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { let base = doc.r().url(); // https://html.spec.whatwg.org/multipage/infrastructure.html#reflect // XXXManishearth this doesn't handle `javascript:` urls properly - match UrlParser::new().base_url(&base).parse(url.as_slice()) { + match UrlParser::new().base_url(&base).parse(&url) { Ok(parsed) => parsed.serialize(), Err(_) => "".to_owned() } @@ -850,7 +851,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } } fn set_string_attribute(self, name: &Atom, value: DOMString) { - assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice()); + assert!(name.as_slice() == name.to_ascii_lowercase()); self.set_attribute(name, AttrValue::String(value)); } @@ -866,17 +867,17 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } fn set_tokenlist_attribute(self, name: &Atom, value: DOMString) { - assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice()); + assert!(name.as_slice() == name.to_ascii_lowercase()); self.set_attribute(name, AttrValue::from_serialized_tokenlist(value)); } fn set_atomic_tokenlist_attribute(self, name: &Atom, tokens: Vec<Atom>) { - assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice()); + assert!(name.as_slice() == name.to_ascii_lowercase()); self.set_attribute(name, AttrValue::from_atomic_tokens(tokens)); } fn get_uint_attribute(self, name: &Atom) -> u32 { - assert!(name.as_slice().chars().all(|ch| { + assert!(name.chars().all(|ch| { !ch.is_ascii() || ch.to_ascii_lowercase() == ch })); let attribute = self.get_attribute(ns!(""), name).root(); @@ -892,7 +893,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } } fn set_uint_attribute(self, name: &Atom, value: u32) { - assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice()); + assert!(name.as_slice() == name.to_ascii_lowercase()); self.set_attribute(name, AttrValue::UInt(value.to_string(), value)); } } @@ -1114,17 +1115,18 @@ impl<'a> ElementMethods for JSRef<'a, Element> { fn GetClientRects(self) -> Temporary<DOMRectList> { let win = window_from_node(self).root(); let node: JSRef<Node> = NodeCast::from_ref(self); - let rects = node.get_content_boxes(); - let rects: Vec<Root<DOMRect>> = rects.iter().map(|r| { - DOMRect::new( - win.r(), - r.origin.y, - r.origin.y + r.size.height, - r.origin.x, - r.origin.x + r.size.width).root() - }).collect(); + let raw_rects = node.get_content_boxes(); + let mut rects = RootedVec::new(); + for rect in raw_rects.iter() { + let rect = DOMRect::new(win.r(), + rect.origin.y, + rect.origin.y + rect.size.height, + rect.origin.x, + rect.origin.x + rect.size.width); + rects.push(JS::from_rooted(rect)); + } - DOMRectList::new(win.r(), rects.iter().map(|rect| rect.r()).collect()) + DOMRectList::new(win.r(), &rects) } // http://dev.w3.org/csswg/cssom-view/#dom-element-getboundingclientrect @@ -1380,7 +1382,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> { let doc = document_from_node(*self).root(); let value = attr.r().Value(); if !value.is_empty() { - let value = Atom::from_slice(value.as_slice()); + let value = Atom::from_slice(&value); doc.r().register_named_element(*self, value); } } @@ -1397,7 +1399,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> { let doc = document_from_node(*self).root(); let value = attr.r().Value(); if !value.is_empty() { - let value = Atom::from_slice(value.as_slice()); + let value = Atom::from_slice(&value); doc.r().unregister_named_element(*self, value); } } diff --git a/components/script/dom/eventdispatcher.rs b/components/script/dom/eventdispatcher.rs index 3518ff20eb6..029691f702c 100644 --- a/components/script/dom/eventdispatcher.rs +++ b/components/script/dom/eventdispatcher.rs @@ -4,8 +4,9 @@ use dom::bindings::callback::ExceptionHandling::Report; use dom::bindings::codegen::Bindings::EventBinding::EventMethods; -use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, NodeDerived}; -use dom::bindings::js::{JS, JSRef, OptionalRootable, Root}; +use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast}; +use dom::bindings::js::{JS, JSRef, OptionalRootable}; +use dom::bindings::trace::RootedVec; use dom::eventtarget::{EventTarget, ListenerPhase}; use dom::event::{Event, EventPhase}; use dom::node::{Node, NodeHelpers}; @@ -27,15 +28,13 @@ pub fn dispatch_event<'a, 'b>(target: JSRef<'a, EventTarget>, let type_ = event.Type(); //TODO: no chain if not participating in a tree - let mut chain: Vec<Root<EventTarget>> = if target.is_node() { - let target_node: JSRef<Node> = NodeCast::to_ref(target).unwrap(); - target_node.ancestors().map(|ancestor| { + let mut chain: RootedVec<JS<EventTarget>> = RootedVec::new(); + if let Some(target_node) = NodeCast::to_ref(target) { + for ancestor in target_node.ancestors() { let ancestor_target: JSRef<EventTarget> = EventTargetCast::from_ref(ancestor); - JS::from_rooted(ancestor_target).root() - }).collect() - } else { - vec!() - }; + chain.push(JS::from_rooted(ancestor_target)) + } + } event.set_phase(EventPhase::Capturing); @@ -43,6 +42,7 @@ pub fn dispatch_event<'a, 'b>(target: JSRef<'a, EventTarget>, /* capturing */ for cur_target in chain.as_slice().iter().rev() { + let cur_target = cur_target.root(); let stopped = match cur_target.r().get_listeners_for(type_.as_slice(), ListenerPhase::Capturing) { Some(listeners) => { event.set_current_target(cur_target.r()); @@ -88,6 +88,7 @@ pub fn dispatch_event<'a, 'b>(target: JSRef<'a, EventTarget>, event.set_phase(EventPhase::Bubbling); for cur_target in chain.iter() { + let cur_target = cur_target.root(); let stopped = match cur_target.r().get_listeners_for(type_.as_slice(), ListenerPhase::Bubbling) { Some(listeners) => { event.set_current_target(cur_target.r()); diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs index 29cd1dfbb74..a6e216cffdb 100644 --- a/components/script/dom/htmlcollection.rs +++ b/components/script/dom/htmlcollection.rs @@ -76,7 +76,7 @@ impl HTMLCollection { pub fn by_tag_name(window: JSRef<Window>, root: JSRef<Node>, tag: DOMString) -> Temporary<HTMLCollection> { - if tag.as_slice() == "*" { + if tag == "*" { return HTMLCollection::all_elements(window, root, None); } @@ -95,8 +95,8 @@ impl HTMLCollection { } } let filter = TagNameFilter { - tag: Atom::from_slice(tag.as_slice()), - ascii_lower_tag: Atom::from_slice(tag.as_slice().to_ascii_lowercase().as_slice()), + tag: Atom::from_slice(&tag), + ascii_lower_tag: Atom::from_slice(&tag.to_ascii_lowercase()), }; HTMLCollection::create(window, root, box filter) } @@ -104,11 +104,11 @@ impl HTMLCollection { pub fn by_tag_name_ns(window: JSRef<Window>, root: JSRef<Node>, tag: DOMString, maybe_ns: Option<DOMString>) -> Temporary<HTMLCollection> { let namespace_filter = match maybe_ns { - Some(ref namespace) if namespace.as_slice() == "*" => None, + Some(ref namespace) if namespace == &"*" => None, ns => Some(namespace::from_domstring(ns)), }; - if tag.as_slice() == "*" { + if tag == "*" { return HTMLCollection::all_elements(window, root, namespace_filter); } #[jstraceable] @@ -128,7 +128,7 @@ impl HTMLCollection { } } let filter = TagNameNSFilter { - tag: Atom::from_slice(tag.as_slice()), + tag: Atom::from_slice(&tag), namespace_filter: namespace_filter }; HTMLCollection::create(window, root, box filter) @@ -146,7 +146,7 @@ impl HTMLCollection { } } let filter = ClassNameFilter { - classes: split_html_space_chars(classes.as_slice()).map(|class| { + classes: split_html_space_chars(&classes).map(|class| { Atom::from_slice(class) }).collect() }; diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index a134b26584a..a0d0adaf82b 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -146,7 +146,7 @@ pub trait HTMLElementCustomAttributeHelpers { fn to_snake_case(name: DOMString) -> DOMString { let mut attr_name = "data-".to_owned(); - for ch in name.as_slice().chars() { + for ch in name.chars() { if ch.is_uppercase() { attr_name.push('\x2d'); attr_name.push(ch.to_lowercase()); @@ -170,7 +170,7 @@ impl<'a> HTMLElementCustomAttributeHelpers for JSRef<'a, HTMLElement> { fn get_custom_attr(self, name: DOMString) -> Option<DOMString> { let element: JSRef<Element> = ElementCast::from_ref(self); - element.get_attribute(ns!(""), &Atom::from_slice(to_snake_case(name).as_slice())).map(|attr| { + element.get_attribute(ns!(""), &Atom::from_slice(&to_snake_case(name))).map(|attr| { let attr = attr.root(); // FIXME(https://github.com/rust-lang/rust/issues/23338) let attr = attr.r(); @@ -181,7 +181,7 @@ impl<'a> HTMLElementCustomAttributeHelpers for JSRef<'a, HTMLElement> { fn delete_custom_attr(self, name: DOMString) { let element: JSRef<Element> = ElementCast::from_ref(self); - element.remove_attribute(ns!(""), to_snake_case(name).as_slice()) + element.remove_attribute(ns!(""), &to_snake_case(name)) } } @@ -196,7 +196,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLElement> { s.after_set_attr(attr); } - let name = attr.local_name().as_slice(); + let name = attr.local_name(); if name.starts_with("on") { let window = window_from_node(*self).root(); let (cx, url, reflector) = (window.r().get_cx(), diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 5d8f06c276a..8dca04ec736 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -202,25 +202,26 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { } // Step 12. - match element.get_attribute(ns!(""), &atom!("for")).root() { - Some(for_script) => { - if for_script.r().Value().to_ascii_lowercase().trim_matches(HTML_SPACE_CHARACTERS) != "window" { + let for_attribute = element.get_attribute(ns!(""), &atom!("for")).root(); + let event_attribute = element.get_attribute(ns!(""), &Atom::from_slice("event")).root(); + match (for_attribute.r(), event_attribute.r()) { + (Some(for_attribute), Some(event_attribute)) => { + let for_value = for_attribute.Value() + .to_ascii_lowercase(); + let for_value = for_value.trim_matches(HTML_SPACE_CHARACTERS); + if for_value != "window" { return; } - } - _ => { } - } - match element.get_attribute(ns!(""), &Atom::from_slice("event")).root() { - Some(event) => { - let event = event.r().Value().to_ascii_lowercase(); - let event = event.trim_matches(HTML_SPACE_CHARACTERS); - if event != "onload" && event != "onload()" { + let event_value = event_attribute.Value().to_ascii_lowercase(); + let event_value = event_value.trim_matches(HTML_SPACE_CHARACTERS); + if event_value != "onload" && event_value != "onload()" { return; } - } - _ => { } + }, + (_, _) => (), } + // Step 13. if let Some(charset) = element.get_attribute(ns!(""), &Atom::from_slice("charset")).root() { if let Some(encodingRef) = encoding_from_whatwg_label(&charset.r().Value()) { @@ -359,10 +360,10 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { } else { let chan = window.r().script_chan(); let handler = Trusted::new(window.r().get_cx(), self, chan.clone()); - let dispatcher = Box::new(EventDispatcher { + let dispatcher = box EventDispatcher { element: handler, is_error: false, - }); + }; chan.send(ScriptMsg::RunnableMsg(dispatcher)).unwrap(); } } @@ -372,10 +373,10 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { let window = window.r(); let chan = window.script_chan(); let handler = Trusted::new(window.get_cx(), self, chan.clone()); - let dispatcher = Box::new(EventDispatcher { + let dispatcher = box EventDispatcher { element: handler, is_error: true, - }); + }; chan.send(ScriptMsg::RunnableMsg(dispatcher)).unwrap(); } diff --git a/components/script/dom/keyboardevent.rs b/components/script/dom/keyboardevent.rs index bd531cb61f2..d9ca779edc3 100644 --- a/components/script/dom/keyboardevent.rs +++ b/components/script/dom/keyboardevent.rs @@ -320,7 +320,7 @@ fn code_value(key: constellation_msg::Key) -> &'static str { constellation_msg::Key::Num8 => "Digit8", constellation_msg::Key::Num9 => "Digit9", constellation_msg::Key::Semicolon => "Semicolon", - constellation_msg::Key::Equal => "Equals", + constellation_msg::Key::Equal => "Equal", constellation_msg::Key::A => "KeyA", constellation_msg::Key::B => "KeyB", constellation_msg::Key::C => "KeyC", @@ -414,7 +414,7 @@ fn code_value(key: constellation_msg::Key) -> &'static str { constellation_msg::Key::KpSubtract => "NumpadSubtract", constellation_msg::Key::KpAdd => "NumpadAdd", constellation_msg::Key::KpEnter => "NumpadEnter", - constellation_msg::Key::KpEqual => "NumpadEquals", + constellation_msg::Key::KpEqual => "NumpadEqual", constellation_msg::Key::LeftShift | constellation_msg::Key::RightShift => "Shift", constellation_msg::Key::LeftControl | constellation_msg::Key::RightControl => "Control", constellation_msg::Key::LeftAlt | constellation_msg::Key::RightAlt => "Alt", diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs index 42f23b8c4b2..c29dede570d 100644 --- a/components/script/dom/macros.rs +++ b/components/script/dom/macros.rs @@ -227,5 +227,6 @@ macro_rules! global_event_handlers( event_handler!(click, GetOnclick, SetOnclick); event_handler!(input, GetOninput, SetOninput); event_handler!(change, GetOnchange, SetOnchange); + event_handler!(submit, GetOnsubmit, SetOnsubmit); ) ); diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 1e70c1f73b3..f1f9c58fad8 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -312,6 +312,7 @@ pub mod servohtmlparser; pub mod storage; pub mod storageevent; pub mod text; +pub mod textencoder; pub mod treewalker; pub mod uievent; pub mod urlhelper; diff --git a/components/script/dom/navigator.rs b/components/script/dom/navigator.rs index 257e1d2dfab..0b96e355a2f 100644 --- a/components/script/dom/navigator.rs +++ b/components/script/dom/navigator.rs @@ -54,5 +54,9 @@ impl<'a> NavigatorMethods for JSRef<'a, Navigator> { fn UserAgent(self) -> DOMString { navigatorinfo::UserAgent() } + + fn AppVersion(self) -> DOMString { + navigatorinfo::AppVersion() + } } diff --git a/components/script/dom/navigatorinfo.rs b/components/script/dom/navigatorinfo.rs index 7dc94d85374..d4aec6999ab 100644 --- a/components/script/dom/navigatorinfo.rs +++ b/components/script/dom/navigatorinfo.rs @@ -33,3 +33,7 @@ pub fn UserAgent() -> DOMString { None => "".to_owned(), } } + +pub fn AppVersion() -> DOMString { + "4.0".to_owned() +} diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 67bb5279f32..ae79327e7da 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -700,14 +700,16 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { // // TODO(cgaebel): This is a very conservative way to account for sibling // selectors. Maybe we can do something smarter in the future. - let parent = - match self.parent_node() { - None => return, - Some(parent) => parent, - }; - - for sibling in parent.root().r().children() { - sibling.set_has_dirty_siblings(true); + if !self.get_has_dirty_siblings() { + let parent = + match self.parent_node() { + None => return, + Some(parent) => parent, + }; + + for sibling in parent.root().r().children() { + sibling.set_has_dirty_siblings(true); + } } // 4. Dirty ancestors. diff --git a/components/script/dom/nodelist.rs b/components/script/dom/nodelist.rs index 319004e4b46..ec1e47caacb 100644 --- a/components/script/dom/nodelist.rs +++ b/components/script/dom/nodelist.rs @@ -17,6 +17,7 @@ pub enum NodeListType { Children(JS<Node>) } +// https://dom.spec.whatwg.org/#interface-nodelist #[dom_struct] pub struct NodeList { reflector_: Reflector, @@ -47,6 +48,7 @@ impl NodeList { } impl<'a> NodeListMethods for JSRef<'a, NodeList> { + // https://dom.spec.whatwg.org/#dom-nodelist-length fn Length(self) -> u32 { match self.list_type { NodeListType::Simple(ref elems) => elems.len() as u32, @@ -57,6 +59,7 @@ impl<'a> NodeListMethods for JSRef<'a, NodeList> { } } + // https://dom.spec.whatwg.org/#dom-nodelist-item fn Item(self, index: u32) -> Option<Temporary<Node>> { match self.list_type { _ if index >= self.Length() => None, diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs index d15bb12b14a..191482c39c1 100644 --- a/components/script/dom/storage.rs +++ b/components/script/dom/storage.rs @@ -5,15 +5,27 @@ use dom::bindings::codegen::Bindings::StorageBinding; use dom::bindings::codegen::Bindings::StorageBinding::StorageMethods; use dom::bindings::global::{GlobalRef, GlobalField}; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::{JSRef, Temporary, RootedReference}; +use dom::bindings::refcounted::Trusted; use dom::bindings::utils::{Reflector, reflect_dom_object}; +use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast}; +use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable}; +use dom::eventtarget::{EventTarget}; +use dom::storageevent::StorageEvent; +use dom::urlhelper::UrlHelper; +use dom::window::WindowHelpers; use util::str::DOMString; use net::storage_task::StorageTask; use net::storage_task::StorageType; use net::storage_task::StorageTaskMsg; +use page::IterablePage; use std::sync::mpsc::channel; use url::Url; +use script_task::{ScriptTask, ScriptMsg, MainThreadRunnable}; + +use collections::borrow::ToOwned; + #[dom_struct] pub struct Storage { reflector_: Reflector, @@ -79,9 +91,10 @@ impl<'a> StorageMethods for JSRef<'a, Storage> { fn SetItem(self, name: DOMString, value: DOMString) { let (sender, receiver) = channel(); - self.get_storage_task().send(StorageTaskMsg::SetItem(sender, self.get_url(), self.storage_type, name, value)).unwrap(); - if receiver.recv().unwrap() { - //TODO send notification + self.get_storage_task().send(StorageTaskMsg::SetItem(sender, self.get_url(), self.storage_type, name.clone(), value.clone())).unwrap(); + let (changed, old_value) = receiver.recv().unwrap(); + if changed { + self.broadcast_change_notification(Some(name), old_value, Some(value)); } } @@ -96,9 +109,9 @@ impl<'a> StorageMethods for JSRef<'a, Storage> { fn RemoveItem(self, name: DOMString) { let (sender, receiver) = channel(); - self.get_storage_task().send(StorageTaskMsg::RemoveItem(sender, self.get_url(), self.storage_type, name)).unwrap(); - if receiver.recv().unwrap() { - //TODO send notification + self.get_storage_task().send(StorageTaskMsg::RemoveItem(sender, self.get_url(), self.storage_type, name.clone())).unwrap(); + if let Some(old_value) = receiver.recv().unwrap() { + self.broadcast_change_notification(Some(name), Some(old_value), None); } } @@ -111,7 +124,76 @@ impl<'a> StorageMethods for JSRef<'a, Storage> { self.get_storage_task().send(StorageTaskMsg::Clear(sender, self.get_url(), self.storage_type)).unwrap(); if receiver.recv().unwrap() { - //TODO send notification + self.broadcast_change_notification(None, None, None); + } + } +} + +trait PrivateStorageHelpers { + fn broadcast_change_notification(self, key: Option<DOMString>, old_value: Option<DOMString>, + new_value: Option<DOMString>); +} + +impl<'a> PrivateStorageHelpers for JSRef<'a, Storage> { + /// https://html.spec.whatwg.org/multipage/webstorage.html#send-a-storage-notification + fn broadcast_change_notification(self, key: Option<DOMString>, old_value: Option<DOMString>, + new_value: Option<DOMString>){ + let global_root = self.global.root(); + let global_ref = global_root.r(); + let script_chan = global_ref.script_chan(); + let trusted_storage = Trusted::new(global_ref.get_cx(), self, + script_chan.clone()); + script_chan.send(ScriptMsg::MainThreadRunnableMsg( + box StorageEventRunnable::new(trusted_storage, key, + old_value, new_value))).unwrap(); + } +} + +pub struct StorageEventRunnable { + element: Trusted<Storage>, + key: Option<DOMString>, + old_value: Option<DOMString>, + new_value: Option<DOMString> +} + +impl StorageEventRunnable { + fn new(storage: Trusted<Storage>, key: Option<DOMString>, old_value: Option<DOMString>, + new_value: Option<DOMString>) -> StorageEventRunnable { + StorageEventRunnable { element: storage, key: key, old_value: old_value, new_value: new_value } + } +} + +impl MainThreadRunnable for StorageEventRunnable { + fn handler(self: Box<StorageEventRunnable>, script_task: &ScriptTask) { + let this = *self; + let storage_root = this.element.to_temporary().root(); + let storage = storage_root.r(); + let global_root = storage.global.root(); + let global_ref = global_root.r(); + let ev_window = global_ref.as_window(); + let ev_url = storage.get_url(); + + let storage_event = StorageEvent::new( + global_ref, + "storage".to_owned(), + EventBubbles::DoesNotBubble, EventCancelable::NotCancelable, + this.key, this.old_value, this.new_value, + ev_url.to_string(), + Some(storage) + ).root(); + let event: JSRef<Event> = EventCast::from_ref(storage_event.r()); + + let root_page = script_task.root_page(); + for it_page in root_page.iter() { + let it_window_root = it_page.window().root(); + let it_window = it_window_root.r(); + assert!(UrlHelper::SameOrigin(&ev_url, &it_window.get_url())); + // TODO: Such a Document object is not necessarily fully active, but events fired on such + // objects are ignored by the event loop until the Document becomes fully active again. + if ev_window.pipeline() != it_window.pipeline() { + let target: JSRef<EventTarget> = EventTargetCast::from_ref(it_window); + event.fire(target); + } } } } diff --git a/components/script/dom/textencoder.rs b/components/script/dom/textencoder.rs new file mode 100644 index 00000000000..e568a6dfa75 --- /dev/null +++ b/components/script/dom/textencoder.rs @@ -0,0 +1,94 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use dom::bindings::codegen::Bindings::TextEncoderBinding; +use dom::bindings::codegen::Bindings::TextEncoderBinding::TextEncoderMethods; +use dom::bindings::global::GlobalRef; +use dom::bindings::error::Fallible; +use dom::bindings::error::Error::IndexSize; +use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::str::USVString; +use dom::bindings::utils::{Reflector, reflect_dom_object}; + +use util::str::DOMString; + +use std::borrow::ToOwned; +use std::ascii::AsciiExt; +use std::ptr; + +use encoding::types::EncodingRef; +use encoding::{Encoding, EncoderTrap}; +use encoding::label::encoding_from_whatwg_label; + +use libc::uint8_t; +use js::jsapi::{JSContext, JSObject}; +use js::jsfriendapi::bindgen::{JS_NewUint8Array, JS_GetUint8ArrayData}; + +#[dom_struct] +pub struct TextEncoder { + reflector_: Reflector, + encoding: DOMString, + encoder: EncodingRef, +} + +impl TextEncoder { + fn new_inherited(encoding: DOMString, encoder: EncodingRef) -> TextEncoder { + TextEncoder { + reflector_: Reflector::new(), + encoding: encoding, + encoder: encoder, + } + } + + pub fn new(global: GlobalRef, encoding: DOMString, encoder: EncodingRef) -> Temporary<TextEncoder> { + reflect_dom_object(box TextEncoder::new_inherited(encoding, encoder), + global, + TextEncoderBinding::Wrap) + } + + // https://encoding.spec.whatwg.org/#dom-textencoder + pub fn Constructor(global: GlobalRef, + label: DOMString) -> Fallible<Temporary<TextEncoder>> { + let encoding = match encoding_from_whatwg_label(label.trim().as_slice().to_ascii_lowercase().as_slice()) { + Some(enc) => enc, + None => { + debug!("Encoding Label Not Supported"); + // TODO: should throw RangeError + return Err(IndexSize) + } + }; + + match encoding.name() { + "utf-8" | "utf-16be" | "utf-16le" => { + Ok(TextEncoder::new(global, encoding.name().to_owned(), encoding)) + } + _ => { + debug!("Encoding Not UTF"); + // TODO: should throw RangeError + Err(IndexSize) + } + } + } +} + +impl<'a> TextEncoderMethods for JSRef<'a, TextEncoder> { + // https://encoding.spec.whatwg.org/#dom-textencoder-encoding + fn Encoding(self) -> DOMString { + self.encoding.clone() + } + + // https://encoding.spec.whatwg.org/#dom-textencoder-encode + #[allow(unsafe_code)] + fn Encode(self, cx: *mut JSContext, input: USVString) -> *mut JSObject { + unsafe { + let output = self.encoder.encode(input.0.as_slice(), EncoderTrap::Strict).unwrap(); + let length = output.len() as u32; + let js_object: *mut JSObject = JS_NewUint8Array(cx, length); + + let js_object_data: *mut uint8_t = JS_GetUint8ArrayData(js_object, cx); + ptr::copy_nonoverlapping(js_object_data, output.as_ptr(), length as usize); + return js_object; + } + } +} diff --git a/components/script/dom/treewalker.rs b/components/script/dom/treewalker.rs index f74e5f975b0..d13b730af0d 100644 --- a/components/script/dom/treewalker.rs +++ b/components/script/dom/treewalker.rs @@ -64,14 +64,17 @@ impl TreeWalker { } impl<'a> TreeWalkerMethods for JSRef<'a, TreeWalker> { + // https://dom.spec.whatwg.org/#dom-treewalker-root fn Root(self) -> Temporary<Node> { Temporary::new(self.root_node) } + // https://dom.spec.whatwg.org/#dom-treewalker-whattoshow fn WhatToShow(self) -> u32 { self.what_to_show } + // https://dom.spec.whatwg.org/#dom-treewalker-filter fn GetFilter(self) -> Option<NodeFilter> { match self.filter { Filter::None => None, @@ -80,38 +83,47 @@ impl<'a> TreeWalkerMethods for JSRef<'a, TreeWalker> { } } + // https://dom.spec.whatwg.org/#dom-treewalker-currentnode fn CurrentNode(self) -> Temporary<Node> { Temporary::new(self.current_node.get()) } + // https://dom.spec.whatwg.org/#dom-treewalker-currentnode fn SetCurrentNode(self, node: JSRef<Node>) { self.current_node.set(JS::from_rooted(node)); } + // https://dom.spec.whatwg.org/#dom-treewalker-parentnode fn ParentNode(self) -> Fallible<Option<Temporary<Node>>> { self.parent_node() } + // https://dom.spec.whatwg.org/#dom-treewalker-firstchild fn FirstChild(self) -> Fallible<Option<Temporary<Node>>> { self.first_child() } + // https://dom.spec.whatwg.org/#dom-treewalker-lastchild fn LastChild(self) -> Fallible<Option<Temporary<Node>>> { self.last_child() } + // https://dom.spec.whatwg.org/#dom-treewalker-previoussibling fn PreviousSibling(self) -> Fallible<Option<Temporary<Node>>> { self.prev_sibling() } + // https://dom.spec.whatwg.org/#dom-treewalker-nextsibling fn NextSibling(self) -> Fallible<Option<Temporary<Node>>> { self.next_sibling() } + // https://dom.spec.whatwg.org/#dom-treewalker-previousnode fn PreviousNode(self) -> Fallible<Option<Temporary<Node>>> { self.prev_node() } + // https://dom.spec.whatwg.org/#dom-treewalker-nextnode fn NextNode(self) -> Fallible<Option<Temporary<Node>>> { self.next_node() } diff --git a/components/script/dom/uievent.rs b/components/script/dom/uievent.rs index c0f72600344..24d029cbce7 100644 --- a/components/script/dom/uievent.rs +++ b/components/script/dom/uievent.rs @@ -18,6 +18,7 @@ use util::str::DOMString; use std::cell::Cell; use std::default::Default; +// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#interface-UIEvent #[dom_struct] pub struct UIEvent { event: Event, @@ -70,10 +71,12 @@ impl UIEvent { } impl<'a> UIEventMethods for JSRef<'a, UIEvent> { + // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#widl-UIEvent-view fn GetView(self) -> Option<Temporary<Window>> { self.view.get() } + // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#widl-UIEvent-detail fn Detail(self) -> i32 { self.detail.get() } diff --git a/components/script/dom/urlsearchparams.rs b/components/script/dom/urlsearchparams.rs index 16f015554b0..0158b76a377 100644 --- a/components/script/dom/urlsearchparams.rs +++ b/components/script/dom/urlsearchparams.rs @@ -19,9 +19,8 @@ use encoding::types::{EncodingRef, EncoderTrap}; use std::collections::HashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; -use std::fmt::radix; -use std::ascii::OwnedAsciiExt; +// https://url.spec.whatwg.org/#interface-urlsearchparams #[dom_struct] pub struct URLSearchParams { reflector_: Reflector, @@ -41,6 +40,7 @@ impl URLSearchParams { URLSearchParamsBinding::Wrap) } + // https://url.spec.whatwg.org/#dom-urlsearchparams-urlsearchparams pub fn Constructor(global: GlobalRef, init: Option<StringOrURLSearchParams>) -> Fallible<Temporary<URLSearchParams>> { let usp = URLSearchParams::new(global).root(); @@ -67,6 +67,7 @@ impl URLSearchParams { } impl<'a> URLSearchParamsMethods for JSRef<'a, URLSearchParams> { + // https://url.spec.whatwg.org/#dom-urlsearchparams-append fn Append(self, name: DOMString, value: DOMString) { let mut data = self.data.borrow_mut(); @@ -80,23 +81,27 @@ impl<'a> URLSearchParamsMethods for JSRef<'a, URLSearchParams> { self.update_steps(); } + // https://url.spec.whatwg.org/#dom-urlsearchparams-delete fn Delete(self, name: DOMString) { self.data.borrow_mut().remove(&name); self.update_steps(); } + // https://url.spec.whatwg.org/#dom-urlsearchparams-get fn Get(self, name: DOMString) -> Option<DOMString> { // FIXME(https://github.com/rust-lang/rust/issues/23338) let data = self.data.borrow(); data.get(&name).map(|v| v[0].clone()) } + // https://url.spec.whatwg.org/#dom-urlsearchparams-has fn Has(self, name: DOMString) -> bool { // FIXME(https://github.com/rust-lang/rust/issues/23338) let data = self.data.borrow(); data.contains_key(&name) } + // https://url.spec.whatwg.org/#dom-urlsearchparams-set fn Set(self, name: DOMString, value: DOMString) { self.data.borrow_mut().insert(name, vec!(value)); self.update_steps(); diff --git a/components/script/dom/validitystate.rs b/components/script/dom/validitystate.rs index 5e87e9de2b1..6088279c980 100644 --- a/components/script/dom/validitystate.rs +++ b/components/script/dom/validitystate.rs @@ -8,6 +8,7 @@ use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::window::Window; +// https://html.spec.whatwg.org/#validitystate #[dom_struct] pub struct ValidityState { reflector_: Reflector, diff --git a/components/script/dom/webidls/CSSStyleDeclaration.webidl b/components/script/dom/webidls/CSSStyleDeclaration.webidl index 3be5abe1099..1da7946338b 100644 --- a/components/script/dom/webidls/CSSStyleDeclaration.webidl +++ b/components/script/dom/webidls/CSSStyleDeclaration.webidl @@ -186,4 +186,10 @@ partial interface CSSStyleDeclaration { [TreatNullAs=EmptyString] attribute DOMString zIndex; [TreatNullAs=EmptyString] attribute DOMString imageRendering; + + [TreatNullAs=EmptyString] attribute DOMString transition; + [TreatNullAs=EmptyString] attribute DOMString transitionDuration; + [TreatNullAs=EmptyString] attribute DOMString transitionTimingFunction; + [TreatNullAs=EmptyString] attribute DOMString transitionProperty; + [TreatNullAs=EmptyString] attribute DOMString transitionDelay; }; diff --git a/components/script/dom/webidls/CanvasRenderingContext2D.webidl b/components/script/dom/webidls/CanvasRenderingContext2D.webidl index a3d40dc7c52..96624deb0fa 100644 --- a/components/script/dom/webidls/CanvasRenderingContext2D.webidl +++ b/components/script/dom/webidls/CanvasRenderingContext2D.webidl @@ -150,6 +150,7 @@ interface CanvasPathMethods { //void rect(double x, double y, double w, double h); + [Throws] void arc(double x, double y, double radius, double startAngle, double endAngle, optional boolean anticlockwise = false); // NOT IMPLEMENTED [LenientFloat] void ellipse(double x, double y, double radiusX, double radiusY, double rotation, double startAngle, double endAngle, boolean anticlockwise); }; diff --git a/components/script/dom/webidls/EventHandler.webidl b/components/script/dom/webidls/EventHandler.webidl index de491455302..0ab01a113d4 100644 --- a/components/script/dom/webidls/EventHandler.webidl +++ b/components/script/dom/webidls/EventHandler.webidl @@ -25,6 +25,7 @@ interface GlobalEventHandlers { attribute EventHandler onload; attribute EventHandler oninput; attribute EventHandler onchange; + attribute EventHandler onsubmit; }; [NoInterfaceObject] diff --git a/components/script/dom/webidls/Navigator.webidl b/components/script/dom/webidls/Navigator.webidl index 0ce509f4c04..67b5cf95018 100644 --- a/components/script/dom/webidls/Navigator.webidl +++ b/components/script/dom/webidls/Navigator.webidl @@ -19,7 +19,7 @@ Navigator implements NavigatorID; interface NavigatorID { readonly attribute DOMString appCodeName; // constant "Mozilla" readonly attribute DOMString appName; - //readonly attribute DOMString appVersion; + readonly attribute DOMString appVersion; readonly attribute DOMString platform; readonly attribute DOMString product; // constant "Gecko" boolean taintEnabled(); // constant false diff --git a/components/script/dom/webidls/TextEncoder.webidl b/components/script/dom/webidls/TextEncoder.webidl new file mode 100644 index 00000000000..697f7ca9146 --- /dev/null +++ b/components/script/dom/webidls/TextEncoder.webidl @@ -0,0 +1,12 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +/* https://encoding.spec.whatwg.org/#interface-textencoder */ +[Constructor(optional DOMString utfLabel = "utf-8")/*, Exposed=Window,Worker */] +interface TextEncoder { + readonly attribute DOMString encoding; + [NewObject] + Uint8Array encode(optional USVString input = ""); +}; diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index da09b6bb767..1af70fa5f0b 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -11,6 +11,7 @@ use dom::bindings::utils::reflect_dom_object; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use util::str::DOMString; +// https://html.spec.whatwg.org/#the-websocket-interface #[dom_struct] pub struct WebSocket { eventtarget: EventTarget, @@ -37,6 +38,7 @@ impl WebSocket { } impl<'a> WebSocketMethods for JSRef<'a, WebSocket> { + // https://html.spec.whatwg.org/#dom-websocket-url fn Url(self) -> DOMString { self.url.clone() } diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index ce7dc34e77d..08e526df282 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -27,7 +27,7 @@ use dom::performance::Performance; use dom::screen::Screen; use dom::storage::Storage; use layout_interface::{ReflowGoal, ReflowQueryType, LayoutRPC, LayoutChan, Reflow, Msg}; -use layout_interface::{ContentBoxResponse, ContentBoxesResponse}; +use layout_interface::{ContentBoxResponse, ContentBoxesResponse, ScriptReflow}; use page::Page; use script_task::{TimerSource, ScriptChan}; use script_task::ScriptMsg; @@ -119,7 +119,7 @@ pub struct Window { parent_info: Option<(PipelineId, SubpageId)>, /// Unique id for last reflow request; used for confirming completion reply. - last_reflow_id: Cell<uint>, + last_reflow_id: Cell<u32>, /// Global static data related to the DOM. dom_static: GlobalStaticData, @@ -218,8 +218,7 @@ impl Window { } // http://www.whatwg.org/html/#atob -pub fn base64_btoa(btoa: DOMString) -> Fallible<DOMString> { - let input = btoa.as_slice(); +pub fn base64_btoa(input: DOMString) -> Fallible<DOMString> { // "The btoa() method must throw an InvalidCharacterError exception if // the method's first argument contains any character whose code point // is greater than U+00FF." @@ -239,10 +238,7 @@ pub fn base64_btoa(btoa: DOMString) -> Fallible<DOMString> { } // http://www.whatwg.org/html/#atob -pub fn base64_atob(atob: DOMString) -> Fallible<DOMString> { - // "Let input be the string being parsed." - let input = atob.as_slice(); - +pub fn base64_atob(input: DOMString) -> Fallible<DOMString> { // "Remove all space characters from input." // serialize::base64::from_base64 ignores \r and \n, // but it treats the other space characters as @@ -460,7 +456,7 @@ pub trait WindowHelpers { fn layout(&self) -> &LayoutRPC; fn content_box_query(self, content_box_request: TrustedNodeAddress) -> Rect<Au>; fn content_boxes_query(self, content_boxes_request: TrustedNodeAddress) -> Vec<Rect<Au>>; - fn handle_reflow_complete_msg(self, reflow_id: uint); + fn handle_reflow_complete_msg(self, reflow_id: u32); fn handle_resize_inactive_msg(self, new_size: WindowSizeData); fn set_fragment_name(self, fragment: Option<String>); fn steal_fragment_name(self) -> Option<String>; @@ -568,17 +564,19 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { } // Send new document and relevant styles to layout. - let reflow = box Reflow { + let reflow = box ScriptReflow { + reflow_info: Reflow { + goal: goal, + url: self.get_url(), + iframe: self.parent_info.is_some(), + page_clip_rect: self.page_clip_rect.get(), + }, document_root: root.to_trusted_node_address(), - url: self.get_url(), - iframe: self.parent_info.is_some(), - goal: goal, window_size: window_size, script_chan: self.control_chan.clone(), script_join_chan: join_chan, id: last_reflow_id.get(), query_type: query_type, - page_clip_rect: self.page_clip_rect.get(), }; let LayoutChan(ref chan) = self.layout_chan; @@ -631,7 +629,7 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { rects } - fn handle_reflow_complete_msg(self, reflow_id: uint) { + fn handle_reflow_complete_msg(self, reflow_id: u32) { let last_reflow_id = self.last_reflow_id.get(); if last_reflow_id == reflow_id { *self.layout_join_port.borrow_mut() = None; diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index 274d4c1d906..5d422edf7e7 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -36,6 +36,7 @@ use std::sync::mpsc::{channel, Sender}; pub type TrustedWorkerAddress = Trusted<Worker>; +// https://html.spec.whatwg.org/multipage/workers.html#worker #[dom_struct] pub struct Worker { eventtarget: EventTarget, diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index e0d8ae7aaa0..c24edd5ce36 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -39,6 +39,7 @@ pub enum WorkerGlobalScopeTypeId { DedicatedGlobalScope, } +// https://html.spec.whatwg.org/multipage/workers.html#the-workerglobalscope-common-interface #[dom_struct] pub struct WorkerGlobalScope { eventtarget: EventTarget, @@ -96,16 +97,19 @@ impl WorkerGlobalScope { } impl<'a> WorkerGlobalScopeMethods for JSRef<'a, WorkerGlobalScope> { + // https://html.spec.whatwg.org/multipage/workers.html#dom-workerglobalscope-self fn Self_(self) -> Temporary<WorkerGlobalScope> { Temporary::from_rooted(self) } + // https://html.spec.whatwg.org/multipage/workers.html#dom-workerglobalscope-location fn Location(self) -> Temporary<WorkerLocation> { self.location.or_init(|| { WorkerLocation::new(self, self.worker_url.clone()) }) } + // https://html.spec.whatwg.org/multipage/workers.html#dom-workerglobalscope-importscripts fn ImportScripts(self, url_strings: Vec<DOMString>) -> ErrorResult { let mut urls = Vec::with_capacity(url_strings.len()); for url in url_strings.into_iter() { @@ -138,6 +142,7 @@ impl<'a> WorkerGlobalScopeMethods for JSRef<'a, WorkerGlobalScope> { Ok(()) } + // https://html.spec.whatwg.org/multipage/workers.html#dom-worker-navigator fn Navigator(self) -> Temporary<WorkerNavigator> { self.navigator.or_init(|| WorkerNavigator::new(self)) } diff --git a/components/script/dom/workerlocation.rs b/components/script/dom/workerlocation.rs index 1f176e2c7d9..0d82fc79098 100644 --- a/components/script/dom/workerlocation.rs +++ b/components/script/dom/workerlocation.rs @@ -13,6 +13,7 @@ use dom::workerglobalscope::WorkerGlobalScope; use url::Url; +// https://html.spec.whatwg.org/multipage/workers.html#worker-locations #[dom_struct] pub struct WorkerLocation { reflector_: Reflector, diff --git a/components/script/dom/workernavigator.rs b/components/script/dom/workernavigator.rs index 203e2bd03fa..ea446f986cb 100644 --- a/components/script/dom/workernavigator.rs +++ b/components/script/dom/workernavigator.rs @@ -11,6 +11,7 @@ use dom::navigatorinfo; use dom::workerglobalscope::WorkerGlobalScope; use util::str::DOMString; +// https://html.spec.whatwg.org/multipage/workers.html#workernavigator #[dom_struct] pub struct WorkerNavigator { reflector_: Reflector, @@ -54,5 +55,9 @@ impl<'a> WorkerNavigatorMethods for JSRef<'a, WorkerNavigator> { fn UserAgent(self) -> DOMString { navigatorinfo::UserAgent() } + + fn AppVersion(self) -> DOMString { + navigatorinfo::AppVersion() + } } diff --git a/components/script/layout_interface.rs b/components/script/layout_interface.rs index e14475aa793..a0062a287b6 100644 --- a/components/script/layout_interface.rs +++ b/components/script/layout_interface.rs @@ -10,14 +10,16 @@ use dom::node::LayoutData; use geom::point::Point2D; use geom::rect::Rect; +use libc::uintptr_t; use msg::constellation_msg::{PipelineExitType, WindowSizeData}; use profile::mem::{Reporter, ReportsChan}; use script_traits::{ScriptControlChan, OpaqueScriptLayoutChannel, UntrustedNodeAddress}; use std::any::Any; use std::sync::mpsc::{channel, Receiver, Sender}; use std::boxed::BoxAny; -use style::stylesheets::Stylesheet; +use style::animation::PropertyAnimation; use style::media_queries::MediaQueryList; +use style::stylesheets::Stylesheet; use url::Url; use util::geometry::Au; @@ -35,11 +37,14 @@ pub enum Msg { SetQuirksMode, /// Requests a reflow. - Reflow(Box<Reflow>), + Reflow(Box<ScriptReflow>), /// Get an RPC interface. GetRPC(Sender<Box<LayoutRPC + Send>>), + /// Requests that the layout task render the next frame of all animations. + TickAnimations, + /// Destroys layout data associated with a DOM node. /// /// TODO(pcwalton): Maybe think about batching to avoid message traffic. @@ -100,14 +105,22 @@ pub enum ReflowQueryType { /// Information needed for a reflow. pub struct Reflow { - /// The document node. - pub document_root: TrustedNodeAddress, /// The goal of reflow: either to render to the screen or to flush layout info for script. pub goal: ReflowGoal, /// The URL of the page. pub url: Url, /// Is the current reflow of an iframe, as opposed to a root window? pub iframe: bool, + /// A clipping rectangle for the page, an enlarged rectangle containing the viewport. + pub page_clip_rect: Rect<Au>, +} + +/// Information needed for a script-initiated reflow. +pub struct ScriptReflow { + /// General reflow data. + pub reflow_info: Reflow, + /// The document node. + pub document_root: TrustedNodeAddress, /// The channel through which messages can be sent back to the script task. pub script_chan: ScriptControlChan, /// The current window size. @@ -115,11 +128,9 @@ pub struct Reflow { /// The channel that we send a notification to. pub script_join_chan: Sender<()>, /// Unique identifier - pub id: uint, + pub id: u32, /// The type of query if any to perform during this reflow. pub query_type: ReflowQueryType, - /// A clipping rectangle for the page, an enlarged rectangle containing the viewport. - pub page_clip_rect: Rect<Au>, } /// Encapsulates a channel to the layout task. @@ -165,3 +176,28 @@ impl ScriptLayoutChan for OpaqueScriptLayoutChannel { *receiver.downcast::<Receiver<Msg>>().unwrap() } } + +/// Type of an opaque node. +pub type OpaqueNode = uintptr_t; + +/// State relating to an animation. +#[derive(Copy, Clone)] +pub struct Animation { + /// An opaque reference to the DOM node participating in the animation. + pub node: OpaqueNode, + /// A description of the property animation that is occurring. + pub property_animation: PropertyAnimation, + /// The start time of the animation, as returned by `time::precise_time_s()`. + pub start_time: f64, + /// The end time of the animation, as returned by `time::precise_time_s()`. + pub end_time: f64, +} + +impl Animation { + /// Returns the duration of this animation in seconds. + #[inline] + pub fn duration(&self) -> f64 { + self.end_time - self.start_time + } +} + diff --git a/components/script/parse/html.rs b/components/script/parse/html.rs index ce7b75f9338..3fc60d8c7c8 100644 --- a/components/script/parse/html.rs +++ b/components/script/parse/html.rs @@ -274,7 +274,9 @@ pub fn parse_html(document: JSRef<Document>, parser.parse_chunk(data); } ProgressMsg::Done(Err(err)) => { - panic!("Failed to load page URL {}, error: {}", url.serialize(), err); + debug!("Failed to load page URL {}, error: {}", url.serialize(), err); + // TODO(Savago): we should send a notification to callers #5463. + break; } ProgressMsg::Done(Ok(())) => break, } diff --git a/components/script/script_task.rs b/components/script/script_task.rs index e5463285200..a891455c0de 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -28,7 +28,7 @@ use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable, RootedReference} use dom::bindings::js::{RootCollection, RootCollectionPtr, Unrooted}; use dom::bindings::refcounted::{LiveDOMReferences, Trusted, TrustedReference}; use dom::bindings::structuredclone::StructuredCloneData; -use dom::bindings::trace::JSTraceable; +use dom::bindings::trace::{JSTraceable, trace_collections}; use dom::bindings::utils::{wrap_for_same_compartment, pre_wrap}; use dom::document::{Document, IsHTMLDocument, DocumentHelpers, DocumentProgressHandler, DocumentProgressTask, DocumentSource}; use dom::element::{Element, AttributeHandlers}; @@ -461,6 +461,10 @@ impl ScriptTask { !ptr.is_null() }); + + unsafe { + JS_SetExtraGCRootsTracer((*js_runtime).ptr, Some(trace_collections), ptr::null_mut()); + } // Unconstrain the runtime's threshold on nominal heap size, to avoid // triggering GC too often if operating continuously near an arbitrary // finite threshold. This leaves the maximum-JS_malloc-bytes threshold @@ -494,7 +498,7 @@ impl ScriptTask { } // Return the root page in the frame tree. Panics if it doesn't exist. - fn root_page(&self) -> Rc<Page> { + pub fn root_page(&self) -> Rc<Page> { self.page.borrow().as_ref().unwrap().clone() } @@ -574,13 +578,15 @@ impl ScriptTask { } }; - // Squash any pending resize and reflow events in the queue. + // Squash any pending resize, reflow, and mouse-move events in the queue. + let mut mouse_move_event_index = None; loop { match event { // This has to be handled before the ResizeMsg below, // otherwise the page may not have been added to the // child list yet, causing the find() to fail. - MixedMessage::FromConstellation(ConstellationControlMsg::AttachLayout(new_layout_info)) => { + MixedMessage::FromConstellation(ConstellationControlMsg::AttachLayout( + new_layout_info)) => { self.handle_new_layout(new_layout_info); } MixedMessage::FromConstellation(ConstellationControlMsg::Resize(id, size)) => { @@ -589,6 +595,19 @@ impl ScriptTask { MixedMessage::FromConstellation(ConstellationControlMsg::Viewport(id, rect)) => { self.handle_viewport(id, rect); } + MixedMessage::FromConstellation(ConstellationControlMsg::SendEvent( + _, + MouseMoveEvent(_))) => { + match mouse_move_event_index { + None => { + mouse_move_event_index = Some(sequential.len()); + sequential.push(event); + } + Some(index) => { + sequential[index] = event + } + } + } _ => { sequential.push(event); } @@ -846,7 +865,7 @@ impl ScriptTask { } /// Handles a notification that reflow completed. - fn handle_reflow_complete_msg(&self, pipeline_id: PipelineId, reflow_id: uint) { + fn handle_reflow_complete_msg(&self, pipeline_id: PipelineId, reflow_id: u32) { debug!("Script: Reflow {:?} complete for {:?}", reflow_id, pipeline_id); let page = self.root_page(); let page = page.find(pipeline_id).expect( @@ -1070,7 +1089,7 @@ impl ScriptTask { window: JS::from_rooted(window.r()), })); - let is_javascript = incomplete.url.scheme.as_slice() == "javascript"; + let is_javascript = incomplete.url.scheme == "javascript"; let parse_input = if is_javascript { let evalstr = incomplete.url.non_relative_scheme_data().unwrap(); let jsval = window.r().evaluate_js_on_global_with_result(evalstr); @@ -1097,7 +1116,7 @@ impl ScriptTask { // https://html.spec.whatwg.org/multipage/#the-end step 4 let addr: Trusted<Document> = Trusted::new(self.get_cx(), document.r(), self.chan.clone()); - let handler = Box::new(DocumentProgressHandler::new(addr.clone(), DocumentProgressTask::DOMContentLoaded)); + let handler = box DocumentProgressHandler::new(addr.clone(), DocumentProgressTask::DOMContentLoaded); self.chan.send(ScriptMsg::RunnableMsg(handler)).unwrap(); // We have no concept of a document loader right now, so just dispatch the @@ -1105,7 +1124,7 @@ impl ScriptTask { // the initial load. // https://html.spec.whatwg.org/multipage/#the-end step 7 - let handler = Box::new(DocumentProgressHandler::new(addr, DocumentProgressTask::Load)); + let handler = box DocumentProgressHandler::new(addr, DocumentProgressTask::Load); self.chan.send(ScriptMsg::RunnableMsg(handler)).unwrap(); window.r().set_fragment_name(final_url.fragment.clone()); @@ -1301,7 +1320,7 @@ impl ScriptTask { let resource_task = self.resource_task.clone(); spawn_named(format!("fetch for {:?}", load_data.url.serialize()), move || { - if load_data.url.scheme.as_slice() == "javascript" { + if load_data.url.scheme == "javascript" { load_data.url = Url::parse("about:blank").unwrap(); } diff --git a/components/script/textinput.rs b/components/script/textinput.rs index 20b396d45d1..470257495b9 100644 --- a/components/script/textinput.rs +++ b/components/script/textinput.rs @@ -140,13 +140,13 @@ impl TextInput { let lines_suffix = &self.lines[end.line + 1..]; let mut insert_lines = if self.multiline { - insert.as_slice().split('\n').map(|s| s.to_owned()).collect() + insert.split('\n').map(|s| s.to_owned()).collect() } else { vec!(insert) }; let mut new_line = prefix.to_owned(); - new_line.push_str(insert_lines[0].as_slice()); + new_line.push_str(&insert_lines[0]); insert_lines[0] = new_line; let last_insert_lines_index = insert_lines.len() - 1; @@ -157,7 +157,7 @@ impl TextInput { let mut new_lines = vec!(); new_lines.push_all(lines_prefix); - new_lines.push_all(insert_lines.as_slice()); + new_lines.push_all(&insert_lines); new_lines.push_all(lines_suffix); new_lines }; @@ -341,7 +341,7 @@ impl TextInput { pub fn get_content(&self) -> DOMString { let mut content = "".to_owned(); for (i, line) in self.lines.iter().enumerate() { - content.push_str(line.as_slice()); + content.push_str(&line); if i < self.lines.len() - 1 { content.push('\n'); } @@ -353,7 +353,7 @@ impl TextInput { /// any \n encountered will be stripped and force a new logical line. pub fn set_content(&mut self, content: DOMString) { self.lines = if self.multiline { - content.as_slice().split('\n').map(|s| s.to_owned()).collect() + content.split('\n').map(|s| s.to_owned()).collect() } else { vec!(content) }; @@ -367,14 +367,14 @@ fn test_textinput_delete_char() { let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned()); textinput.adjust_horizontal(2, Selection::NotSelected); textinput.delete_char(DeleteDir::Backward); - assert_eq!(textinput.get_content().as_slice(), "acdefg"); + assert_eq!(textinput.get_content(), "acdefg"); textinput.delete_char(DeleteDir::Forward); - assert_eq!(textinput.get_content().as_slice(), "adefg"); + assert_eq!(textinput.get_content(), "adefg"); textinput.adjust_horizontal(2, Selection::Selected); textinput.delete_char(DeleteDir::Forward); - assert_eq!(textinput.get_content().as_slice(), "afg"); + assert_eq!(textinput.get_content(), "afg"); } #[test] @@ -382,11 +382,11 @@ fn test_textinput_insert_char() { let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned()); textinput.adjust_horizontal(2, Selection::NotSelected); textinput.insert_char('a'); - assert_eq!(textinput.get_content().as_slice(), "abacdefg"); + assert_eq!(textinput.get_content(), "abacdefg"); textinput.adjust_horizontal(2, Selection::Selected); textinput.insert_char('b'); - assert_eq!(textinput.get_content().as_slice(), "ababefg"); + assert_eq!(textinput.get_content(), "ababefg"); } #[test] @@ -413,7 +413,7 @@ fn test_textinput_replace_selection() { textinput.adjust_horizontal(2, Selection::Selected); textinput.replace_selection("xyz".to_owned()); - assert_eq!(textinput.get_content().as_slice(), "abxyzefg"); + assert_eq!(textinput.get_content(), "abxyzefg"); } #[test] @@ -470,12 +470,12 @@ fn test_textinput_handle_return() { let mut single_line_textinput = TextInput::new(Lines::Single, "abcdef".to_owned()); single_line_textinput.adjust_horizontal(3, Selection::NotSelected); single_line_textinput.handle_return(); - assert_eq!(single_line_textinput.get_content().as_slice(), "abcdef"); + assert_eq!(single_line_textinput.get_content(), "abcdef"); let mut multi_line_textinput = TextInput::new(Lines::Multiple, "abcdef".to_owned()); multi_line_textinput.adjust_horizontal(3, Selection::NotSelected); multi_line_textinput.handle_return(); - assert_eq!(multi_line_textinput.get_content().as_slice(), "abc\ndef"); + assert_eq!(multi_line_textinput.get_content(), "abc\ndef"); } #[test] @@ -492,19 +492,19 @@ fn test_textinput_select_all() { #[test] fn test_textinput_get_content() { let single_line_textinput = TextInput::new(Lines::Single, "abcdefg".to_owned()); - assert_eq!(single_line_textinput.get_content().as_slice(), "abcdefg"); + assert_eq!(single_line_textinput.get_content(), "abcdefg"); let multi_line_textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned()); - assert_eq!(multi_line_textinput.get_content().as_slice(), "abc\nde\nf"); + assert_eq!(multi_line_textinput.get_content(), "abc\nde\nf"); } #[test] fn test_textinput_set_content() { let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned()); - assert_eq!(textinput.get_content().as_slice(), "abc\nde\nf"); + assert_eq!(textinput.get_content(), "abc\nde\nf"); textinput.set_content("abc\nf".to_owned()); - assert_eq!(textinput.get_content().as_slice(), "abc\nf"); + assert_eq!(textinput.get_content(), "abc\nf"); assert_eq!(textinput.edit_point.line, 0); assert_eq!(textinput.edit_point.index, 0); @@ -512,7 +512,7 @@ fn test_textinput_set_content() { assert_eq!(textinput.edit_point.line, 0); assert_eq!(textinput.edit_point.index, 3); textinput.set_content("de".to_owned()); - assert_eq!(textinput.get_content().as_slice(), "de"); + assert_eq!(textinput.get_content(), "de"); assert_eq!(textinput.edit_point.line, 0); assert_eq!(textinput.edit_point.index, 2); } diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 5b4be3731b2..da93a143dc2 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -61,7 +61,7 @@ pub enum ConstellationControlMsg { /// Sends a DOM event. SendEvent(PipelineId, CompositorEvent), /// Notifies script that reflow is finished. - ReflowComplete(PipelineId, uint), + ReflowComplete(PipelineId, u32), /// Notifies script of the viewport. Viewport(PipelineId, Rect<f32>), /// Requests that the script task immediately send the constellation the title of a pipeline. diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 5c7cfa15cc4..4183d8627e9 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -69,6 +69,11 @@ dependencies = [ ] [[package]] +name = "clock_ticks" +version = "0.0.4" +source = "git+https://github.com/tomaka/clock_ticks#6a3005279bedc406b13eea09ff92447f05ca0de6" + +[[package]] name = "cocoa" version = "0.1.1" source = "git+https://github.com/servo/rust-cocoa#ca3441a14783aa0683e073f1a1f990ed21900718" @@ -315,6 +320,7 @@ dependencies = [ "script_traits 0.0.1", "skia 0.0.20130412 (git+https://github.com/servo/skia?branch=upstream-2014-06-16)", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", + "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "style 0.0.1", "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", @@ -503,6 +509,7 @@ dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "canvas 0.0.1", + "clock_ticks 0.0.4 (git+https://github.com/tomaka/clock_ticks)", "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", "encoding 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", @@ -815,7 +822,7 @@ source = "git+https://github.com/servo/rust-stb-image#b683cc9e7ba52a1bb65361347d [[package]] name = "string_cache" version = "0.0.0" -source = "git+https://github.com/servo/string-cache#8c05fdf456a0e4f884e85d7e3a7700b2e4ca91eb" +source = "git+https://github.com/servo/string-cache#124cb555651bd7838c5c6dc4788bc4f5350947a9" dependencies = [ "lazy_static 0.1.8 (git+https://github.com/Kimundi/lazy-static.rs)", "phf 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -827,7 +834,7 @@ dependencies = [ [[package]] name = "string_cache_plugin" version = "0.0.0" -source = "git+https://github.com/servo/string-cache#8c05fdf456a0e4f884e85d7e3a7700b2e4ca91eb" +source = "git+https://github.com/servo/string-cache#124cb555651bd7838c5c6dc4788bc4f5350947a9" dependencies = [ "lazy_static 0.1.8 (git+https://github.com/Kimundi/lazy-static.rs)", "mac 0.0.2 (git+https://github.com/reem/rust-mac)", diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 1afdbf8dca5..b197ad30e6f 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -33,7 +33,7 @@ use msg::constellation_msg::ConstellationChan; use script::dom::bindings::codegen::RegisterBindings; #[cfg(not(test))] -use net::image_cache_task::ImageCacheTask; +use net::image_cache_task::{ImageCacheTask, LoadPlaceholder}; #[cfg(not(test))] use net::resource_task::new_resource_task; #[cfg(not(test))] @@ -84,10 +84,10 @@ impl Browser { // image. let image_cache_task = if opts.output_file.is_some() { ImageCacheTask::new_sync(resource_task.clone(), shared_task_pool, - time_profiler_chan.clone()) + time_profiler_chan.clone(), LoadPlaceholder::Preload) } else { ImageCacheTask::new(resource_task.clone(), shared_task_pool, - time_profiler_chan.clone()) + time_profiler_chan.clone(), LoadPlaceholder::Preload) }; let font_cache_task = FontCacheTask::new(resource_task.clone()); diff --git a/components/style/animation.rs b/components/style/animation.rs new file mode 100644 index 00000000000..f1237c34650 --- /dev/null +++ b/components/style/animation.rs @@ -0,0 +1,221 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use properties::ComputedValues; +use properties::longhands::transition_property::computed_value::TransitionProperty; +use properties::longhands::transition_timing_function::computed_value::{StartEnd}; +use properties::longhands::transition_timing_function::computed_value::{TransitionTimingFunction}; +use properties::longhands::transition_property; +use values::computed::{LengthOrPercentageOrAuto, Time}; + +use std::num::Float; +use util::bezier::Bezier; +use util::geometry::Au; + +#[derive(Copy, Clone, Debug)] +pub struct PropertyAnimation { + property: AnimatedProperty, + timing_function: TransitionTimingFunction, + duration: Time, +} + +impl PropertyAnimation { + /// Creates a new property animation for the given transition index and old and new styles. + /// Any number of animations may be returned, from zero (if the property did not animate) to + /// one (for a single transition property) to arbitrarily many (for `all`). + pub fn from_transition(transition_index: usize, + old_style: &ComputedValues, + new_style: &mut ComputedValues) + -> Vec<PropertyAnimation> { + let mut result = Vec::new(); + let transition_property = + new_style.get_animation().transition_property.0[transition_index]; + if transition_property != TransitionProperty::All { + if let Some(property_animation) = + PropertyAnimation::from_transition_property(transition_property, + transition_index, + old_style, + new_style) { + result.push(property_animation) + } + return result + } + + for transition_property in + transition_property::computed_value::ALL_TRANSITION_PROPERTIES.iter() { + if let Some(property_animation) = + PropertyAnimation::from_transition_property(*transition_property, + transition_index, + old_style, + new_style) { + result.push(property_animation) + } + } + + result + } + + fn from_transition_property(transition_property: TransitionProperty, + transition_index: usize, + old_style: &ComputedValues, + new_style: &mut ComputedValues) + -> Option<PropertyAnimation> { + let animation_style = new_style.get_animation(); + let animated_property = match transition_property { + TransitionProperty::All => { + panic!("Don't use `TransitionProperty::All` with \ + `PropertyAnimation::from_transition_property`!") + } + TransitionProperty::Top => { + AnimatedProperty::Top(old_style.get_positionoffsets().top, + new_style.get_positionoffsets().top) + } + TransitionProperty::Right => { + AnimatedProperty::Right(old_style.get_positionoffsets().right, + new_style.get_positionoffsets().right) + } + TransitionProperty::Bottom => { + AnimatedProperty::Bottom(old_style.get_positionoffsets().bottom, + new_style.get_positionoffsets().bottom) + } + TransitionProperty::Left => { + AnimatedProperty::Left(old_style.get_positionoffsets().left, + new_style.get_positionoffsets().left) + } + }; + + let property_animation = PropertyAnimation { + property: animated_property, + timing_function: + *animation_style.transition_timing_function.0.get_mod(transition_index), + duration: *animation_style.transition_duration.0.get_mod(transition_index), + }; + if property_animation.does_not_animate() { + None + } else { + Some(property_animation) + } + } + + pub fn update(&self, style: &mut ComputedValues, time: f64) { + let progress = match self.timing_function { + TransitionTimingFunction::CubicBezier(p1, p2) => { + // See `WebCore::AnimationBase::solveEpsilon(double)` in WebKit. + let epsilon = 1.0 / (200.0 * self.duration.seconds()); + Bezier::new(p1, p2).solve(time, epsilon) + } + TransitionTimingFunction::Steps(steps, StartEnd::Start) => { + (time * (steps as f64)).ceil() / (steps as f64) + } + TransitionTimingFunction::Steps(steps, StartEnd::End) => { + (time * (steps as f64)).floor() / (steps as f64) + } + }; + match self.property { + AnimatedProperty::Top(ref start, ref end) => { + if let Some(value) = start.interpolate(end, progress) { + style.mutate_positionoffsets().top = value + } + } + AnimatedProperty::Right(ref start, ref end) => { + if let Some(value) = start.interpolate(end, progress) { + style.mutate_positionoffsets().right = value + } + } + AnimatedProperty::Bottom(ref start, ref end) => { + if let Some(value) = start.interpolate(end, progress) { + style.mutate_positionoffsets().bottom = value + } + } + AnimatedProperty::Left(ref start, ref end) => { + if let Some(value) = start.interpolate(end, progress) { + style.mutate_positionoffsets().left = value + } + } + } + } + + #[inline] + fn does_not_animate(&self) -> bool { + self.property.does_not_animate() || self.duration == Time(0.0) + } +} + +#[derive(Copy, Clone, Debug)] +enum AnimatedProperty { + Top(LengthOrPercentageOrAuto, LengthOrPercentageOrAuto), + Right(LengthOrPercentageOrAuto, LengthOrPercentageOrAuto), + Bottom(LengthOrPercentageOrAuto, LengthOrPercentageOrAuto), + Left(LengthOrPercentageOrAuto, LengthOrPercentageOrAuto), +} + +impl AnimatedProperty { + #[inline] + fn does_not_animate(&self) -> bool { + match *self { + AnimatedProperty::Top(ref a, ref b) | + AnimatedProperty::Right(ref a, ref b) | + AnimatedProperty::Bottom(ref a, ref b) | + AnimatedProperty::Left(ref a, ref b) => a == b, + } + } +} + +trait Interpolate { + fn interpolate(&self, other: &Self, time: f64) -> Option<Self>; +} + +impl Interpolate for Au { + #[inline] + fn interpolate(&self, other: &Au, time: f64) -> Option<Au> { + Some(Au((self.0 as f64 + (other.0 as f64 - self.0 as f64) * time).round() as i32)) + } +} + +impl Interpolate for f64 { + #[inline] + fn interpolate(&self, other: &f64, time: f64) -> Option<f64> { + Some(*self + (*other - *self) * time) + } +} + +impl Interpolate for LengthOrPercentageOrAuto { + #[inline] + fn interpolate(&self, other: &LengthOrPercentageOrAuto, time: f64) + -> Option<LengthOrPercentageOrAuto> { + match (*self, *other) { + (LengthOrPercentageOrAuto::Length(ref this), + LengthOrPercentageOrAuto::Length(ref other)) => { + this.interpolate(other, time).and_then(|value| { + Some(LengthOrPercentageOrAuto::Length(value)) + }) + } + (LengthOrPercentageOrAuto::Percentage(ref this), + LengthOrPercentageOrAuto::Percentage(ref other)) => { + this.interpolate(other, time).and_then(|value| { + Some(LengthOrPercentageOrAuto::Percentage(value)) + }) + } + (LengthOrPercentageOrAuto::Auto, LengthOrPercentageOrAuto::Auto) => { + Some(LengthOrPercentageOrAuto::Auto) + } + (_, _) => None, + } + } +} + +/// Accesses an element of an array, "wrapping around" using modular arithmetic. This is needed +/// to handle values of differing lengths according to CSS-TRANSITIONS § 2. +pub trait GetMod { + type Item; + fn get_mod(&self, i: usize) -> &Self::Item; +} + +impl<T> GetMod for Vec<T> { + type Item = T; + fn get_mod(&self, i: usize) -> &T { + &(*self)[i % self.len()] + } +} + diff --git a/components/style/font_face.rs b/components/style/font_face.rs index f10d2a4fa95..0c661745fb5 100644 --- a/components/style/font_face.rs +++ b/components/style/font_face.rs @@ -2,18 +2,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use computed_values::font_family::FontFamily; use cssparser::{Token, Parser, DeclarationListParser, AtRuleParser, DeclarationParser}; +use media_queries::Device; +use parser::{ParserContext, log_css_error}; +use properties::longhands::font_family::parse_one_family; use std::ascii::AsciiExt; +use string_cache::Atom; use stylesheets::CSSRule; -use properties::longhands::font_family::parse_one_family; -use computed_values::font_family::FontFamily; -use media_queries::Device; use url::{Url, UrlParser}; -use parser::{ParserContext, log_css_error}; - -pub fn iter_font_face_rules_inner<F>(rules: &[CSSRule], device: &Device, - callback: &F) where F: Fn(&str, &Source) { +pub fn iter_font_face_rules_inner<F>(rules: &[CSSRule], device: &Device, callback: &F) + where F: Fn(&Atom, &Source) { for rule in rules.iter() { match *rule { CSSRule::Style(..) | @@ -34,7 +34,7 @@ pub fn iter_font_face_rules_inner<F>(rules: &[CSSRule], device: &Device, #[derive(Clone, Debug, PartialEq, Eq)] pub enum Source { Url(UrlSource), - Local(String), + Local(Atom), } #[derive(Clone, Debug, PartialEq, Eq)] @@ -45,11 +45,10 @@ pub struct UrlSource { #[derive(Debug, PartialEq, Eq)] pub struct FontFaceRule { - pub family: String, + pub family: Atom, pub sources: Vec<Source>, } - pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser) -> Result<FontFaceRule, ()> { let mut family = None; @@ -83,7 +82,7 @@ pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser) } enum FontFaceDescriptorDeclaration { - Family(String), + Family(Atom), Src(Vec<Source>), } @@ -106,7 +105,8 @@ impl<'a, 'b> DeclarationParser for FontFaceRuleParser<'a, 'b> { fn parse_value(&self, name: &str, input: &mut Parser) -> Result<FontFaceDescriptorDeclaration, ()> { match_ignore_ascii_case! { name, "font-family" => { - Ok(FontFaceDescriptorDeclaration::Family(try!(parse_one_non_generic_family_name(input)))) + Ok(FontFaceDescriptorDeclaration::Family(try!( + parse_one_non_generic_family_name(input)))) }, "src" => { Ok(FontFaceDescriptorDeclaration::Src(try!(input.parse_comma_separated(|input| { @@ -118,9 +118,9 @@ impl<'a, 'b> DeclarationParser for FontFaceRuleParser<'a, 'b> { } } -fn parse_one_non_generic_family_name(input: &mut Parser) -> Result<String, ()> { +fn parse_one_non_generic_family_name(input: &mut Parser) -> Result<Atom, ()> { match parse_one_family(input) { - Ok(FontFamily::FamilyName(name)) => Ok(name), + Ok(FontFamily::FamilyName(name)) => Ok(name.clone()), _ => Err(()) } } diff --git a/components/style/lib.rs b/components/style/lib.rs index 4951242290b..e71828b6330 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -50,6 +50,7 @@ pub mod node; pub mod media_queries; pub mod font_face; pub mod legacy; +pub mod animation; macro_rules! reexport_computed_values { ( $( $name: ident )+ ) => { diff --git a/components/style/parser.rs b/components/style/parser.rs index 6fd821f3435..c9d1891d708 100644 --- a/components/style/parser.rs +++ b/components/style/parser.rs @@ -10,7 +10,6 @@ use log; use stylesheets::Origin; - pub struct ParserContext<'a> { pub base_url: &'a Url, pub selector_context: SelectorParserContext, diff --git a/components/style/properties.mako.rs b/components/style/properties.mako.rs index d3699ff710f..fbe09ac4dd4 100644 --- a/components/style/properties.mako.rs +++ b/components/style/properties.mako.rs @@ -8,10 +8,13 @@ use std::ascii::AsciiExt; use std::borrow::ToOwned; +use std::default::Default; use std::fmt; use std::fmt::Debug; +use std::hash::{Hash, Hasher}; use std::sync::Arc; +use util::fnv::FnvHasher; use util::logical_geometry::{WritingMode, LogicalMargin}; use util::geometry::Au; use url::Url; @@ -1456,18 +1459,20 @@ pub mod longhands { ${new_style_struct("Font", is_inherited=True)} <%self:longhand name="font-family"> - use std::borrow::ToOwned; use self::computed_value::FontFamily; + use std::borrow::ToOwned; + use string_cache::Atom; use values::computed::ComputedValueAsSpecified; impl ComputedValueAsSpecified for SpecifiedValue {} pub mod computed_value { use cssparser::ToCss; + use string_cache::Atom; use text_writer::{self, TextWriter}; - #[derive(PartialEq, Eq, Clone)] + #[derive(PartialEq, Eq, Clone, Hash)] pub enum FontFamily { - FamilyName(String), + FamilyName(Atom), // Generic // Serif, // SansSerif, @@ -1476,16 +1481,17 @@ pub mod longhands { // Monospace, } impl FontFamily { + #[inline] pub fn name(&self) -> &str { match *self { - FontFamily::FamilyName(ref name) => name, + FontFamily::FamilyName(ref name) => name.as_slice(), } } } impl ToCss for FontFamily { fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter { match self { - &FontFamily::FamilyName(ref name) => dest.write_str(&**name), + &FontFamily::FamilyName(ref name) => dest.write_str(name.as_slice()), } } } @@ -1506,7 +1512,7 @@ pub mod longhands { #[inline] pub fn get_initial_value() -> computed_value::T { - vec![FontFamily::FamilyName("serif".to_owned())] + vec![FontFamily::FamilyName(Atom::from_slice("serif"))] } /// <family-name># /// <family-name> = <string> | [ <ident>+ ] @@ -1516,7 +1522,7 @@ pub mod longhands { } pub fn parse_one_family(input: &mut Parser) -> Result<FontFamily, ()> { if let Ok(value) = input.try(|input| input.expect_string()) { - return Ok(FontFamily::FamilyName(value.into_owned())) + return Ok(FontFamily::FamilyName(Atom::from_slice(value.as_slice()))) } let first_ident = try!(input.expect_ident()); // match_ignore_ascii_case! { first_ident, @@ -1532,7 +1538,7 @@ pub mod longhands { value.push_str(" "); value.push_str(&ident); } - Ok(FontFamily::FamilyName(value)) + Ok(FontFamily::FamilyName(Atom::from_slice(value.as_slice()))) } </%self:longhand> @@ -1592,10 +1598,10 @@ pub mod longhands { } pub mod computed_value { use std::fmt; - #[derive(PartialEq, Eq, Copy, Clone)] + #[derive(PartialEq, Eq, Copy, Clone, Hash)] pub enum T { % for weight in range(100, 901, 100): - Weight${weight}, + Weight${weight} = ${weight}, % endfor } impl fmt::Debug for T { @@ -1608,6 +1614,7 @@ pub mod longhands { } } impl T { + #[inline] pub fn is_bold(self) -> bool { match self { T::Weight900 | T::Weight800 | @@ -3377,6 +3384,367 @@ pub mod longhands { } } </%self:longhand> + + ${new_style_struct("Animation", is_inherited=False)} + + // TODO(pcwalton): Multiple transitions. + <%self:longhand name="transition-duration"> + use values::specified::Time; + + pub use self::computed_value::T as SpecifiedValue; + pub use values::specified::Time as SingleSpecifiedValue; + + pub mod computed_value { + use cssparser::ToCss; + use text_writer::{self, TextWriter}; + use values::computed::{Context, ToComputedValue}; + + pub use values::computed::Time as SingleComputedValue; + + #[derive(Clone, PartialEq)] + pub struct T(pub Vec<SingleComputedValue>); + + impl ToComputedValue for T { + type ComputedValue = T; + + #[inline] + fn to_computed_value(&self, _: &Context) -> T { + (*self).clone() + } + } + + impl ToCss for T { + fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter { + if self.0.is_empty() { + return dest.write_str("none") + } + for (i, value) in self.0.iter().enumerate() { + if i != 0 { + try!(dest.write_str(", ")) + } + try!(value.to_css(dest)) + } + Ok(()) + } + } + } + + #[inline] + pub fn parse_one(input: &mut Parser) -> Result<SingleSpecifiedValue,()> { + Time::parse(input) + } + + #[inline] + pub fn get_initial_value() -> computed_value::T { + computed_value::T(vec![get_initial_single_value()]) + } + + #[inline] + pub fn get_initial_single_value() -> Time { + Time(0.0) + } + + pub fn parse(_: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> { + Ok(SpecifiedValue(try!(input.parse_comma_separated(parse_one)))) + } + </%self:longhand> + + // TODO(pcwalton): Lots more timing functions. + // TODO(pcwalton): Multiple transitions. + <%self:longhand name="transition-timing-function"> + use self::computed_value::{StartEnd, TransitionTimingFunction}; + use values::computed::{Context, ToComputedValue}; + + use geom::point::Point2D; + + pub use self::computed_value::SingleComputedValue as SingleSpecifiedValue; + pub use self::computed_value::T as SpecifiedValue; + + static EASE: TransitionTimingFunction = TransitionTimingFunction::CubicBezier(Point2D { + x: 0.25, + y: 0.1, + }, Point2D { + x: 0.25, + y: 1.0, + }); + static LINEAR: TransitionTimingFunction = TransitionTimingFunction::CubicBezier(Point2D { + x: 0.0, + y: 0.0, + }, Point2D { + x: 1.0, + y: 1.0, + }); + static EASE_IN: TransitionTimingFunction = TransitionTimingFunction::CubicBezier(Point2D { + x: 0.42, + y: 0.0, + }, Point2D { + x: 1.0, + y: 1.0, + }); + static EASE_OUT: TransitionTimingFunction = TransitionTimingFunction::CubicBezier(Point2D { + x: 0.0, + y: 0.0, + }, Point2D { + x: 0.58, + y: 1.0, + }); + static EASE_IN_OUT: TransitionTimingFunction = + TransitionTimingFunction::CubicBezier(Point2D { + x: 0.42, + y: 0.0, + }, Point2D { + x: 0.58, + y: 1.0, + }); + static STEP_START: TransitionTimingFunction = + TransitionTimingFunction::Steps(1, StartEnd::Start); + static STEP_END: TransitionTimingFunction = + TransitionTimingFunction::Steps(1, StartEnd::End); + + pub mod computed_value { + use cssparser::ToCss; + use geom::point::Point2D; + use text_writer::{self, TextWriter}; + + pub use self::TransitionTimingFunction as SingleComputedValue; + + #[derive(Copy, Clone, Debug, PartialEq)] + pub enum TransitionTimingFunction { + CubicBezier(Point2D<f64>, Point2D<f64>), + Steps(u32, StartEnd), + } + + impl ToCss for TransitionTimingFunction { + fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter { + match *self { + TransitionTimingFunction::CubicBezier(p1, p2) => { + try!(dest.write_str("cubic-bezier(")); + try!(p1.x.to_css(dest)); + try!(dest.write_str(", ")); + try!(p1.y.to_css(dest)); + try!(dest.write_str(", ")); + try!(p2.x.to_css(dest)); + try!(dest.write_str(", ")); + try!(p2.y.to_css(dest)); + dest.write_str(")") + } + TransitionTimingFunction::Steps(steps, start_end) => { + try!(dest.write_str("steps(")); + try!(steps.to_css(dest)); + try!(dest.write_str(", ")); + try!(start_end.to_css(dest)); + dest.write_str(")") + } + } + } + } + + #[derive(Copy, Clone, Debug, PartialEq)] + pub enum StartEnd { + Start, + End, + } + + impl ToCss for StartEnd { + fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter { + match *self { + StartEnd::Start => dest.write_str("start"), + StartEnd::End => dest.write_str("end"), + } + } + } + + #[derive(Clone, Debug, PartialEq)] + pub struct T(pub Vec<TransitionTimingFunction>); + + impl ToCss for T { + fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter { + if self.0.is_empty() { + return dest.write_str("none") + } + for (i, value) in self.0.iter().enumerate() { + if i != 0 { + try!(dest.write_str(", ")) + } + try!(value.to_css(dest)) + } + Ok(()) + } + } + } + + impl ToComputedValue for SpecifiedValue { + type ComputedValue = computed_value::T; + + #[inline] + fn to_computed_value(&self, _: &Context) -> computed_value::T { + (*self).clone() + } + } + + #[inline] + pub fn get_initial_value() -> computed_value::T { + computed_value::T(vec![get_initial_single_value()]) + } + + #[inline] + pub fn get_initial_single_value() -> TransitionTimingFunction { + EASE + } + + pub fn parse_one(input: &mut Parser) -> Result<SingleSpecifiedValue,()> { + if let Ok(function_name) = input.try(|input| input.expect_function()) { + return match_ignore_ascii_case! { + function_name, + "cubic-bezier" => { + let (mut p1x, mut p1y, mut p2x, mut p2y) = (0.0, 0.0, 0.0, 0.0); + try!(input.parse_nested_block(|input| { + p1x = try!(input.expect_number()); + try!(input.expect_comma()); + p1y = try!(input.expect_number()); + try!(input.expect_comma()); + p2x = try!(input.expect_number()); + try!(input.expect_comma()); + p2y = try!(input.expect_number()); + Ok(()) + })); + let (p1, p2) = (Point2D(p1x, p1y), Point2D(p2x, p2y)); + Ok(TransitionTimingFunction::CubicBezier(p1, p2)) + }, + "steps" => { + let (mut step_count, mut start_end) = (0, computed_value::StartEnd::Start); + try!(input.parse_nested_block(|input| { + step_count = try!(input.expect_integer()); + try!(input.expect_comma()); + start_end = try!(match_ignore_ascii_case! { + try!(input.expect_ident()), + "start" => Ok(computed_value::StartEnd::Start), + "end" => Ok(computed_value::StartEnd::End) + _ => Err(()) + }); + Ok(()) + })); + Ok(TransitionTimingFunction::Steps(step_count as u32, start_end)) + } + _ => Err(()) + } + } + match_ignore_ascii_case! { + try!(input.expect_ident()), + "ease" => Ok(EASE), + "linear" => Ok(LINEAR), + "ease-in" => Ok(EASE_IN), + "ease-out" => Ok(EASE_OUT), + "ease-in-out" => Ok(EASE_IN_OUT), + "step-start" => Ok(STEP_START), + "step-end" => Ok(STEP_END) + _ => Err(()) + } + } + + pub fn parse(_: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> { + Ok(SpecifiedValue(try!(input.parse_comma_separated(parse_one)))) + } + </%self:longhand> + + // TODO(pcwalton): Lots more properties. + <%self:longhand name="transition-property"> + use self::computed_value::TransitionProperty; + use values::computed::{ToComputedValue, Context}; + + pub use self::computed_value::SingleComputedValue as SingleSpecifiedValue; + pub use self::computed_value::T as SpecifiedValue; + + pub mod computed_value { + use cssparser::ToCss; + use text_writer::{self, TextWriter}; + + pub use self::TransitionProperty as SingleComputedValue; + + #[derive(Copy, Clone, Debug, PartialEq)] + pub enum TransitionProperty { + All, + Top, + Right, + Bottom, + Left, + } + + pub static ALL_TRANSITION_PROPERTIES: [TransitionProperty; 4] = [ + TransitionProperty::Top, + TransitionProperty::Right, + TransitionProperty::Bottom, + TransitionProperty::Left, + ]; + + impl ToCss for TransitionProperty { + fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter { + match *self { + TransitionProperty::All => dest.write_str("all"), + TransitionProperty::Top => dest.write_str("top"), + TransitionProperty::Right => dest.write_str("right"), + TransitionProperty::Bottom => dest.write_str("bottom"), + TransitionProperty::Left => dest.write_str("left"), + } + } + } + + #[derive(Clone, Debug, PartialEq)] + pub struct T(pub Vec<SingleComputedValue>); + + impl ToCss for T { + fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter { + if self.0.is_empty() { + return dest.write_str("none") + } + for (i, value) in self.0.iter().enumerate() { + if i != 0 { + try!(dest.write_str(", ")) + } + try!(value.to_css(dest)) + } + Ok(()) + } + } + } + + #[inline] + pub fn get_initial_value() -> computed_value::T { + computed_value::T(Vec::new()) + } + + pub fn parse_one(input: &mut Parser) -> Result<SingleSpecifiedValue,()> { + match_ignore_ascii_case! { + try!(input.expect_ident()), + "all" => Ok(TransitionProperty::All), + "top" => Ok(TransitionProperty::Top), + "right" => Ok(TransitionProperty::Right), + "bottom" => Ok(TransitionProperty::Bottom), + "left" => Ok(TransitionProperty::Left) + _ => Err(()) + } + } + + pub fn parse(_: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> { + Ok(SpecifiedValue(try!(input.parse_comma_separated(parse_one)))) + } + + impl ToComputedValue for SpecifiedValue { + type ComputedValue = computed_value::T; + + #[inline] + fn to_computed_value(&self, _: &Context) -> computed_value::T { + (*self).clone() + } + } + </%self:longhand> + + <%self:longhand name="transition-delay"> + pub use properties::longhands::transition_duration::{SingleSpecifiedValue, SpecifiedValue}; + pub use properties::longhands::transition_duration::{computed_value}; + pub use properties::longhands::transition_duration::{get_initial_single_value}; + pub use properties::longhands::transition_duration::{get_initial_value, parse, parse_one}; + </%self:longhand> } @@ -3401,6 +3769,8 @@ pub mod shorthands { Option<longhands::${sub_property.ident}::SpecifiedValue>, % endfor } + + #[allow(unused_variables)] pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> { ${caller.body()} } @@ -3879,6 +4249,99 @@ pub mod shorthands { overflow_y: Some(overflow_y::SpecifiedValue(overflow)), }) </%self:shorthand> + + <%self:shorthand name="transition" + sub_properties="transition-property transition-duration transition-timing-function transition-delay"> + use properties::longhands::{transition_delay, transition_duration, transition_property}; + use properties::longhands::{transition_timing_function}; + + struct SingleTransition { + transition_property: transition_property::SingleSpecifiedValue, + transition_duration: transition_duration::SingleSpecifiedValue, + transition_timing_function: transition_timing_function::SingleSpecifiedValue, + transition_delay: transition_delay::SingleSpecifiedValue, + } + + fn parse_one_transition(input: &mut Parser) -> Result<SingleTransition,()> { + let (mut property, mut duration) = (None, None); + let (mut timing_function, mut delay) = (None, None); + loop { + if property.is_none() { + if let Ok(value) = input.try(|input| transition_property::parse_one(input)) { + property = Some(value); + continue + } + } + + if duration.is_none() { + if let Ok(value) = input.try(|input| transition_duration::parse_one(input)) { + duration = Some(value); + continue + } + } + + if timing_function.is_none() { + if let Ok(value) = input.try(|input| { + transition_timing_function::parse_one(input) + }) { + timing_function = Some(value); + continue + } + } + + if delay.is_none() { + if let Ok(value) = input.try(|input| transition_delay::parse_one(input)) { + delay = Some(value); + continue; + } + } + + break + } + + if let Some(property) = property { + Ok(SingleTransition { + transition_property: property, + transition_duration: + duration.unwrap_or(transition_duration::get_initial_single_value()), + transition_timing_function: + timing_function.unwrap_or( + transition_timing_function::get_initial_single_value()), + transition_delay: + delay.unwrap_or(transition_delay::get_initial_single_value()), + }) + } else { + Err(()) + } + } + + if input.try(|input| input.expect_ident_matching("none")).is_ok() { + return Ok(Longhands { + transition_property: None, + transition_duration: None, + transition_timing_function: None, + transition_delay: None, + }) + } + + let results = try!(input.parse_comma_separated(parse_one_transition)); + let (mut properties, mut durations) = (Vec::new(), Vec::new()); + let (mut timing_functions, mut delays) = (Vec::new(), Vec::new()); + for result in results.into_iter() { + properties.push(result.transition_property); + durations.push(result.transition_duration); + timing_functions.push(result.transition_timing_function); + delays.push(result.transition_delay); + } + + Ok(Longhands { + transition_property: Some(transition_property::SpecifiedValue(properties)), + transition_duration: Some(transition_duration::SpecifiedValue(durations)), + transition_timing_function: + Some(transition_timing_function::SpecifiedValue(timing_functions)), + transition_delay: Some(transition_delay::SpecifiedValue(delays)), + }) + </%self:shorthand> } @@ -4207,6 +4670,9 @@ pub mod style_structs { % for longhand in style_struct.longhands: pub ${longhand.ident}: longhands::${longhand.ident}::computed_value::T, % endfor + % if style_struct.name == "Font": + pub hash: u64, + % endif } % endfor } @@ -4328,6 +4794,11 @@ impl ComputedValues { <'a>(&'a self) -> &'a style_structs::${style_struct.name} { &*self.${style_struct.ident} } + #[inline] + pub fn mutate_${style_struct.name.lower()} + <'a>(&'a mut self) -> &'a mut style_structs::${style_struct.name} { + &mut *self.${style_struct.ident}.make_unique() + } % endfor } @@ -4375,6 +4846,9 @@ lazy_static! { % for longhand in style_struct.longhands: ${longhand.ident}: longhands::${longhand.ident}::get_initial_value(), % endfor + % if style_struct.name == "Font": + hash: 0, + % endif }), % endfor shareable: true, @@ -4391,12 +4865,13 @@ fn initial_writing_mode_is_empty() { /// Fast path for the function below. Only computes new inherited styles. #[allow(unused_mut)] -fn cascade_with_cached_declarations(applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>], - shareable: bool, - parent_style: &ComputedValues, - cached_style: &ComputedValues, - context: &computed::Context) - -> ComputedValues { +fn cascade_with_cached_declarations( + applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>], + shareable: bool, + parent_style: &ComputedValues, + cached_style: &ComputedValues, + context: &computed::Context) + -> ComputedValues { % for style_struct in STYLE_STRUCTS: % if style_struct.inherited: let mut style_${style_struct.ident} = parent_style.${style_struct.ident}.clone(); @@ -4415,7 +4890,9 @@ fn cascade_with_cached_declarations(applicable_declarations: &[DeclarationBlock< % for style_struct in STYLE_STRUCTS: % for property in style_struct.longhands: % if property.derived_from is None: - PropertyDeclaration::${property.camel_case}(ref ${'_' if not style_struct.inherited else ''}declared_value) => { + PropertyDeclaration::${property.camel_case}(ref + ${'_' if not style_struct.inherited else ''}declared_value) + => { % if style_struct.inherited: if seen.get_${property.ident}() { continue @@ -4468,6 +4945,11 @@ fn cascade_with_cached_declarations(applicable_declarations: &[DeclarationBlock< } } + if seen.get_font_style() || seen.get_font_weight() || seen.get_font_stretch() || + seen.get_font_family() { + compute_font_hash(&mut *style_font.make_unique()) + } + ComputedValues { writing_mode: get_writing_mode(&*style_inheritedbox), % for style_struct in STYLE_STRUCTS: @@ -4556,9 +5038,13 @@ pub fn cascade(viewport_size: Size2D<Au>, context.font_size = match *value { DeclaredValue::SpecifiedValue(ref specified_value) => { match specified_value.0 { - Length::FontRelative(value) => value.to_computed_value(context.inherited_font_size, - context.root_font_size), - Length::ServoCharacterWidth(value) => value.to_computed_value(context.inherited_font_size), + Length::FontRelative(value) => { + value.to_computed_value(context.inherited_font_size, + context.root_font_size) + } + Length::ServoCharacterWidth(value) => { + value.to_computed_value(context.inherited_font_size) + } _ => specified_value.0.to_computed_value(&context) } } @@ -4568,7 +5054,9 @@ pub fn cascade(viewport_size: Size2D<Au>, } PropertyDeclaration::Color(ref value) => { context.color = match *value { - DeclaredValue::SpecifiedValue(ref specified_value) => specified_value.parsed, + DeclaredValue::SpecifiedValue(ref specified_value) => { + specified_value.parsed + } DeclaredValue::Initial => longhands::color::get_initial_value(), DeclaredValue::Inherit => inherited_style.get_color().color.clone(), }; @@ -4710,6 +5198,11 @@ pub fn cascade(viewport_size: Size2D<Au>, context.root_font_size = context.font_size; } + if seen.get_font_style() || seen.get_font_weight() || seen.get_font_stretch() || + seen.get_font_family() { + compute_font_hash(&mut *style_font.make_unique()) + } + (ComputedValues { writing_mode: get_writing_mode(&*style_inheritedbox), % for style_struct in STYLE_STRUCTS: @@ -4827,3 +5320,13 @@ pub fn longhands_from_shorthand(shorthand: &str) -> Option<Vec<String>> { _ => None, } } + +/// Corresponds to the fields in `gfx::font_template::FontTemplateDescriptor`. +fn compute_font_hash(font: &mut style_structs::Font) { + let mut hasher: FnvHasher = Default::default(); + hasher.write_u16(font.font_weight as u16); + font.font_stretch.hash(&mut hasher); + font.font_family.hash(&mut hasher); + font.hash = hasher.finish() +} + diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index 1e7e78ac9cc..11135ac580e 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -318,8 +318,8 @@ pub fn iter_stylesheet_style_rules<F>(stylesheet: &Stylesheet, device: &media_qu #[inline] -pub fn iter_font_face_rules<F>(stylesheet: &Stylesheet, device: &Device, - callback: &F) where F: Fn(&str, &Source) { +pub fn iter_font_face_rules<F>(stylesheet: &Stylesheet, device: &Device, callback: &F) + where F: Fn(&Atom, &Source) { iter_font_face_rules_inner(&stylesheet.rules, device, callback) } diff --git a/components/style/values.rs b/components/style/values.rs index 8cf1ca60d3a..80801af930a 100644 --- a/components/style/values.rs +++ b/components/style/values.rs @@ -13,7 +13,7 @@ macro_rules! define_css_keyword_enum { }; ($name: ident: $( $css: expr => $variant: ident ),+) => { #[allow(non_camel_case_types)] - #[derive(Clone, Eq, PartialEq, FromPrimitive, Copy)] + #[derive(Clone, Eq, PartialEq, FromPrimitive, Copy, Hash)] pub enum $name { $( $variant ),+ } @@ -862,11 +862,57 @@ pub mod specified { "inset" => inset, "outset" => outset, } -} + /// A time in seconds according to CSS-VALUES § 6.2. + #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] + pub struct Time(pub CSSFloat); + + impl Time { + /// Returns the time in fractional seconds. + pub fn seconds(self) -> f64 { + let Time(seconds) = self; + seconds + } + + /// Parses a time according to CSS-VALUES § 6.2. + fn parse_dimension(value: CSSFloat, unit: &str) -> Result<Time,()> { + if unit.eq_ignore_ascii_case("s") { + Ok(Time(value)) + } else if unit.eq_ignore_ascii_case("ms") { + Ok(Time(value / 1000.0)) + } else { + Err(()) + } + } + + pub fn parse(input: &mut Parser) -> Result<Time,()> { + match input.next() { + Ok(Token::Dimension(ref value, ref unit)) => { + Time::parse_dimension(value.value, unit.as_slice()) + } + _ => Err(()), + } + } + } + + impl super::computed::ToComputedValue for Time { + type ComputedValue = Time; + + #[inline] + fn to_computed_value(&self, _: &super::computed::Context) -> Time { + *self + } + } + + impl ToCss for Time { + fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter { + dest.write_str(format!("{}ms", self.0).as_slice()) + } + } +} pub mod computed { - pub use super::specified::BorderStyle; + pub use super::specified::{BorderStyle, Time}; use super::specified::{AngleOrCorner}; use super::{specified, CSSFloat}; pub use cssparser::Color as CSSColor; diff --git a/components/util/bezier.rs b/components/util/bezier.rs new file mode 100644 index 00000000000..7928a1cab4e --- /dev/null +++ b/components/util/bezier.rs @@ -0,0 +1,116 @@ +/* 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/. */ + +//! Parametric Bézier curves. +//! +//! This is based on `WebCore/platform/graphics/UnitBezier.h` in WebKit. + +use geom::point::Point2D; +use std::num::Float; + +const NEWTON_METHOD_ITERATIONS: u8 = 8; + +pub struct Bezier { + ax: f64, + bx: f64, + cx: f64, + ay: f64, + by: f64, + cy: f64, +} + +impl Bezier { + #[inline] + pub fn new(p1: Point2D<f64>, p2: Point2D<f64>) -> Bezier { + let cx = 3.0 * p1.x; + let bx = 3.0 * (p2.x - p1.x) - cx; + + let cy = 3.0 * p1.y; + let by = 3.0 * (p2.y - p1.y) - cy; + + Bezier { + ax: 1.0 - cx - bx, + bx: bx, + cx: cx, + ay: 1.0 - cy - by, + by: by, + cy: cy, + } + } + + #[inline] + fn sample_curve_x(&self, t: f64) -> f64 { + // ax * t^3 + bx * t^2 + cx * t + ((self.ax * t + self.bx) * t + self.cx) * t + } + + #[inline] + fn sample_curve_y(&self, t: f64) -> f64 { + ((self.ay * t + self.by) * t + self.cy) * t + } + + #[inline] + fn sample_curve_derivative_x(&self, t: f64) -> f64 { + (3.0 * self.ax * t + 2.0 * self.bx) * t + self.cx + } + + #[inline] + fn solve_curve_x(&self, x: f64, epsilon: f64) -> f64 { + // Fast path: Use Newton's method. + let mut t = x; + for _ in range(0, NEWTON_METHOD_ITERATIONS) { + let x2 = self.sample_curve_x(t); + if x2.approx_eq(x, epsilon) { + return t + } + let dx = self.sample_curve_derivative_x(t); + if dx.approx_eq(0.0, 1e-6) { + break + } + t -= (x2 - x) / dx; + } + + // Slow path: Use bisection. + let (mut lo, mut hi, mut t) = (0.0, 1.0, x); + + if t < lo { + return lo + } + if t > hi { + return hi + } + + while lo < hi { + let x2 = self.sample_curve_x(t); + if x2.approx_eq(x, epsilon) { + return t + } + if x > x2 { + lo = t + } else { + hi = t + } + t = (hi - lo) / 2.0 + lo + } + + t + } + + #[inline] + pub fn solve(&self, x: f64, epsilon: f64) -> f64 { + self.sample_curve_y(self.solve_curve_x(x, epsilon)) + } +} + +trait ApproxEq { + fn approx_eq(self, value: Self, epsilon: Self) -> bool; +} + +impl ApproxEq for f64 { + #[inline] + fn approx_eq(self, value: f64, epsilon: f64) -> bool { + (self - value).abs() < epsilon + } +} + diff --git a/components/util/cache.rs b/components/util/cache.rs index 2f4e88b5f0e..8719c176921 100644 --- a/components/util/cache.rs +++ b/components/util/cache.rs @@ -192,7 +192,7 @@ fn test_lru_cache() { let four = Cell::new("four"); // Test normal insertion. - let mut cache: LRUCache<uint,Cell<&str>> = LRUCache::new(2); // (_, _) (cache is empty) + let mut cache: LRUCache<usize,Cell<&str>> = LRUCache::new(2); // (_, _) (cache is empty) cache.insert(1, one); // (1, _) cache.insert(2, two); // (1, 2) cache.insert(3, three); // (2, 3) diff --git a/components/util/debug_utils.rs b/components/util/debug_utils.rs index f7c02b8068b..8c1954c78ba 100644 --- a/components/util/debug_utils.rs +++ b/components/util/debug_utils.rs @@ -2,8 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use std::old_io as io; -use std::old_io::Writer; +use std::io::{self, Write}; use std::mem; use std::mem::size_of; use std::slice; diff --git a/components/util/lib.rs b/components/util/lib.rs index 4eaf40b465f..28efc0e58e1 100644 --- a/components/util/lib.rs +++ b/components/util/lib.rs @@ -8,9 +8,7 @@ #![feature(core)] #![feature(exit_status)] #![feature(hash)] -#![feature(int_uint)] #![feature(io)] -#![feature(old_io)] #![feature(optin_builtin_traits)] #![feature(path)] #![cfg_attr(not(target_os = "android"), feature(path_ext))] @@ -43,6 +41,7 @@ pub use selectors::smallvec; use std::sync::Arc; +pub mod bezier; pub mod cache; pub mod cursor; pub mod debug_utils; diff --git a/components/util/opts.rs b/components/util/opts.rs index 3942ae0ff8e..f445359407e 100644 --- a/components/util/opts.rs +++ b/components/util/opts.rs @@ -14,7 +14,7 @@ use getopts; use std::collections::HashSet; use std::cmp; use std::env; -use std::old_io as io; +use std::io::{self, Write}; use std::mem; use std::ptr; use std::rt; @@ -160,7 +160,9 @@ pub fn print_debug_usage(app: &str) { } fn args_fail(msg: &str) { - io::stderr().write_line(msg).unwrap(); + let mut stderr = io::stderr(); + stderr.write_all(msg.as_bytes()).unwrap(); + stderr.write_all(b"\n").unwrap(); env::set_exit_status(1); } diff --git a/components/util/range.rs b/components/util/range.rs index 86d670d2f84..0df81a7b413 100644 --- a/components/util/range.rs +++ b/components/util/range.rs @@ -16,13 +16,13 @@ pub trait RangeIndex: Int + fmt::Debug { fn get(self) -> Self::Index; } -impl RangeIndex for int { - type Index = int; +impl RangeIndex for isize { + type Index = isize; #[inline] - fn new(x: int) -> int { x } + fn new(x: isize) -> isize { x } #[inline] - fn get(self) -> int { self } + fn get(self) -> isize { self } } /// Implements a range index type with operator overloads @@ -35,8 +35,8 @@ macro_rules! int_range_index { impl $Self_ { #[inline] - pub fn to_uint(self) -> uint { - self.get() as uint + pub fn to_usize(self) -> usize { + self.get() as usize } } @@ -172,16 +172,16 @@ macro_rules! int_range_index { } } - impl Shl<uint> for $Self_ { + impl Shl<usize> for $Self_ { type Output = $Self_; - fn shl(self, n: uint) -> $Self_ { + fn shl(self, n: usize) -> $Self_ { $Self_(self.get() << n) } } - impl Shr<uint> for $Self_ { + impl Shr<usize> for $Self_ { type Output = $Self_; - fn shr(self, n: uint) -> $Self_ { + fn shr(self, n: usize) -> $Self_ { $Self_(self.get() >> n) } } @@ -247,7 +247,7 @@ impl<T: Int, I: RangeIndex<Index=T>> Iterator for EachIndex<T, I> { } #[inline] - fn size_hint(&self) -> (uint, Option<uint>) { + fn size_hint(&self) -> (usize, Option<usize>) { self.it.size_hint() } } @@ -399,7 +399,7 @@ impl<T: Int, I: RangeIndex<Index=T>> Range<I> { #[inline] pub fn is_valid_for_string(&self, s: &str) -> bool { let s_len = s.len(); - match num::cast::<uint, T>(s_len) { + match num::cast::<usize, T>(s_len) { Some(len) => { let len = RangeIndex::new(len); self.begin() < len diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 2c5856bf549..30adc00a7b4 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -74,6 +74,11 @@ dependencies = [ ] [[package]] +name = "clock_ticks" +version = "0.0.4" +source = "git+https://github.com/tomaka/clock_ticks#6a3005279bedc406b13eea09ff92447f05ca0de6" + +[[package]] name = "cocoa" version = "0.1.1" source = "git+https://github.com/servo/rust-cocoa#ca3441a14783aa0683e073f1a1f990ed21900718" @@ -320,6 +325,7 @@ dependencies = [ "script_traits 0.0.1", "skia 0.0.20130412 (git+https://github.com/servo/skia?branch=upstream-2014-06-16)", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", + "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "style 0.0.1", "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", @@ -508,6 +514,7 @@ dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "canvas 0.0.1", + "clock_ticks 0.0.4 (git+https://github.com/tomaka/clock_ticks)", "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", "encoding 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", @@ -840,7 +847,7 @@ source = "git+https://github.com/servo/rust-stb-image#b683cc9e7ba52a1bb65361347d [[package]] name = "string_cache" version = "0.0.0" -source = "git+https://github.com/servo/string-cache#8c05fdf456a0e4f884e85d7e3a7700b2e4ca91eb" +source = "git+https://github.com/servo/string-cache#124cb555651bd7838c5c6dc4788bc4f5350947a9" dependencies = [ "lazy_static 0.1.8 (git+https://github.com/Kimundi/lazy-static.rs)", "phf 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -852,7 +859,7 @@ dependencies = [ [[package]] name = "string_cache_plugin" version = "0.0.0" -source = "git+https://github.com/servo/string-cache#8c05fdf456a0e4f884e85d7e3a7700b2e4ca91eb" +source = "git+https://github.com/servo/string-cache#124cb555651bd7838c5c6dc4788bc4f5350947a9" dependencies = [ "lazy_static 0.1.8 (git+https://github.com/Kimundi/lazy-static.rs)", "mac 0.0.2 (git+https://github.com/reem/rust-mac)", diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index 4e4be7bdd86..0ee174dbc67 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -13,6 +13,7 @@ dependencies = [ "libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net 0.0.1", + "profile 0.0.1", "script 0.0.1", "servo 0.0.1", "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -61,6 +62,11 @@ dependencies = [ ] [[package]] +name = "clock_ticks" +version = "0.0.4" +source = "git+https://github.com/tomaka/clock_ticks#6a3005279bedc406b13eea09ff92447f05ca0de6" + +[[package]] name = "compositing" version = "0.0.1" dependencies = [ @@ -290,6 +296,7 @@ dependencies = [ "script_traits 0.0.1", "skia 0.0.20130412 (git+https://github.com/servo/skia?branch=upstream-2014-06-16)", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", + "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "style 0.0.1", "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", @@ -432,6 +439,7 @@ dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "canvas 0.0.1", + "clock_ticks 0.0.4 (git+https://github.com/tomaka/clock_ticks)", "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", "encoding 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", @@ -763,7 +771,7 @@ source = "git+https://github.com/servo/rust-stb-image#b683cc9e7ba52a1bb65361347d [[package]] name = "string_cache" version = "0.0.0" -source = "git+https://github.com/servo/string-cache#8c05fdf456a0e4f884e85d7e3a7700b2e4ca91eb" +source = "git+https://github.com/servo/string-cache#124cb555651bd7838c5c6dc4788bc4f5350947a9" dependencies = [ "lazy_static 0.1.8 (git+https://github.com/Kimundi/lazy-static.rs)", "phf 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -775,7 +783,7 @@ dependencies = [ [[package]] name = "string_cache_plugin" version = "0.0.0" -source = "git+https://github.com/servo/string-cache#8c05fdf456a0e4f884e85d7e3a7700b2e4ca91eb" +source = "git+https://github.com/servo/string-cache#124cb555651bd7838c5c6dc4788bc4f5350947a9" dependencies = [ "lazy_static 0.1.8 (git+https://github.com/Kimundi/lazy-static.rs)", "mac 0.0.2 (git+https://github.com/reem/rust-mac)", @@ -838,6 +846,7 @@ dependencies = [ name = "util" version = "0.0.1" dependencies = [ + "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", diff --git a/ports/gonk/build.rs b/ports/gonk/build.rs index 1e3d07fa18c..ae700674ec0 100644 --- a/ports/gonk/build.rs +++ b/ports/gonk/build.rs @@ -2,18 +2,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use std::old_io::process::{Command, ProcessExit, StdioContainer}; -use std::os; - +use std::env; +use std::process::Command; fn main() { - let out_dir = os::getenv("OUT_DIR").unwrap(); + let out_dir = env::var("OUT_DIR").unwrap(); let result = Command::new("make") .args(&["-f", "makefile.cargo"]) - .stdout(StdioContainer::InheritFd(1)) - .stderr(StdioContainer::InheritFd(2)) .status() .unwrap(); - assert_eq!(result, ProcessExit::ExitStatus(0)); + assert!(result.success()); println!("cargo:rustc-flags=-L native={}", out_dir); } diff --git a/ports/gonk/src/input.rs b/ports/gonk/src/input.rs index a7ae4423633..44640316f3d 100644 --- a/ports/gonk/src/input.rs +++ b/ports/gonk/src/input.rs @@ -10,7 +10,7 @@ use std::os::errno; use std::os::unix::AsRawFd; use std::num::Float; use std::fs::File; -use std::thread::Thread; +use std::thread; use std::sync::mpsc::Sender; use std::io::Read; @@ -238,7 +238,7 @@ fn read_input_device(device_path: &Path, pub fn run_input_loop(event_sender: &Sender<WindowEvent>) { let sender = event_sender.clone(); - Thread::spawn(move || { + thread::spawn(move || { // XXX need to scan all devices and read every one. let touchinputdev = Path::new("/dev/input/event0"); read_input_device(&touchinputdev, &sender); diff --git a/ports/gonk/src/lib.rs b/ports/gonk/src/lib.rs index 42df54669a2..ca01f431ae0 100644 --- a/ports/gonk/src/lib.rs +++ b/ports/gonk/src/lib.rs @@ -5,7 +5,7 @@ #![feature(thread_local)] #![feature(box_syntax)] #![feature(int_uint)] -#![feature(core, path, rustc_private)] +#![feature(path, rustc_private)] // For FFI #![allow(non_snake_case, dead_code)] @@ -38,7 +38,7 @@ use msg::constellation_msg::ConstellationChan; use script::dom::bindings::codegen::RegisterBindings; #[cfg(not(test))] -use net::image_cache_task::ImageCacheTask; +use net::image_cache_task::{ImageCacheTask, LoadPlaceholder}; #[cfg(not(test))] use net::storage_task::StorageTaskFactory; #[cfg(not(test))] @@ -58,10 +58,6 @@ use util::taskpool::TaskPool; use std::env; #[cfg(not(test))] use std::rc::Rc; -#[cfg(not(test))] -use std::thread::Builder; -#[cfg(not(test))] -use std::sync::mpsc::channel; pub struct Browser { compositor: Box<CompositorEventListener + 'static>, @@ -85,59 +81,45 @@ impl Browser { devtools::start_server(port) }); - let opts_clone = opts.clone(); - let time_profiler_chan_clone = time_profiler_chan.clone(); - let mem_profiler_chan_clone = mem_profiler_chan.clone(); - - let (result_chan, result_port) = channel(); - let compositor_proxy_for_constellation = compositor_proxy.clone_compositor_proxy(); - Builder::new() - .spawn(move || { - let opts = &opts_clone; - // Create a Servo instance. - let resource_task = new_resource_task(opts.user_agent.clone()); - // If we are emitting an output file, then we need to block on - // 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(), shared_task_pool, - time_profiler_chan_clone.clone()) - } else { - ImageCacheTask::new(resource_task.clone(), shared_task_pool, - time_profiler_chan_clone.clone()) + // Create a Servo instance. + let resource_task = new_resource_task(opts.user_agent.clone()); + + // If we are emitting an output file, then we need to block on + // 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(), shared_task_pool, + time_profiler_chan.clone(), LoadPlaceholder::Preload) + } else { + ImageCacheTask::new(resource_task.clone(), shared_task_pool, + time_profiler_chan.clone(), LoadPlaceholder::Preload) + }; + let font_cache_task = FontCacheTask::new(resource_task.clone()); + let storage_task = StorageTaskFactory::new(); + let constellation_chan = Constellation::<layout::layout_task::LayoutTask, + script::script_task::ScriptTask>::start( + compositor_proxy.clone_compositor_proxy(), + resource_task, + image_cache_task, + font_cache_task, + time_profiler_chan.clone(), + mem_profiler_chan.clone(), + devtools_chan, + storage_task); + + // Send the URL command to the constellation. + let cwd = env::current_dir().unwrap(); + for url in opts.urls.iter() { + let url = match url::Url::parse(&*url) { + Ok(url) => url, + Err(url::ParseError::RelativeUrlWithoutBase) + => url::Url::from_file_path(&*cwd.join(&*url)).unwrap(), + Err(_) => panic!("URL parsing failed"), }; - let font_cache_task = FontCacheTask::new(resource_task.clone()); - let storage_task = StorageTaskFactory::new(); - let constellation_chan = Constellation::<layout::layout_task::LayoutTask, - script::script_task::ScriptTask>::start( - compositor_proxy_for_constellation, - resource_task, - image_cache_task, - font_cache_task, - time_profiler_chan_clone, - mem_profiler_chan_clone, - devtools_chan, - storage_task); - - // Send the URL command to the constellation. - let cwd = env::current_dir().unwrap(); - for url in opts.urls.iter() { - let url = match url::Url::parse(url.as_slice()) { - Ok(url) => url, - Err(url::ParseError::RelativeUrlWithoutBase) - => url::Url::from_file_path(&*cwd.join(url.as_slice())).unwrap(), - Err(_) => panic!("URL parsing failed"), - }; - - let ConstellationChan(ref chan) = constellation_chan; - chan.send(ConstellationMsg::InitLoadUrl(url)).ok().unwrap(); - } - - // Send the constallation Chan as the result - result_chan.send(constellation_chan).ok().unwrap(); - }); - let constellation_chan = result_port.recv().unwrap(); + let ConstellationChan(ref chan) = constellation_chan; + chan.send(ConstellationMsg::InitLoadUrl(url)).unwrap(); + } debug!("preparing to enter main loop"); let compositor = CompositorTask::create(window, diff --git a/ports/gonk/src/main.rs b/ports/gonk/src/main.rs index 4a50c729018..4aef94c4582 100644 --- a/ports/gonk/src/main.rs +++ b/ports/gonk/src/main.rs @@ -5,6 +5,7 @@ #![deny(unused_imports)] #![deny(unused_variables)] +#![feature(box_syntax)] #![feature(int_uint)] #![feature(core, os, path, io, std_misc)] // For FFI @@ -23,8 +24,10 @@ extern crate gleam; extern crate layers; extern crate egl; extern crate url; +extern crate net; use util::opts; +use net::resource_task; use servo::Browser; use compositing::windowing::WindowEvent; @@ -39,6 +42,8 @@ struct BrowserWrapper { fn main() { if opts::from_cmdline_args(env::args().collect::<Vec<_>>().as_slice()) { + resource_task::global_init(); + let window = if opts::get().headless { None } else { diff --git a/ports/gonk/src/window.rs b/ports/gonk/src/window.rs index 982a11aa7fe..da54a1eff57 100644 --- a/ports/gonk/src/window.rs +++ b/ports/gonk/src/window.rs @@ -91,13 +91,13 @@ pub struct ANativeWindow { //dequeueBuffer_DEPRECATED: extern fn(*mut ANativeWindow, *mut *mut ANativeWindowBuffer) -> c_int, //lockBuffer_DEPRECATED: extern fn(*mut ANativeWindow, *mut ANativeWindowBuffer) -> c_int, //queueBuffer_DEPRECATED: extern fn(*mut ANativeWindow, *mut ANativeWindowBuffer) -> c_int, - dequeueBuffer_DEPRECATED: int, - lockBuffer_DEPRECATED: int, - queueBuffer_DEPRECATED: int, + dequeueBuffer_DEPRECATED: *const c_void, + lockBuffer_DEPRECATED: *const c_void, + queueBuffer_DEPRECATED: *const c_void, query: extern fn(*const ANativeWindow, c_int, *mut c_int) -> c_int, perform: extern fn(*mut ANativeWindow, c_int, ...) -> c_int, //cancelBuffer_DEPRECATED: extern fn(*mut ANativeWindow, *mut ANativeWindowBuffer) -> c_int, - cancelBuffer_DEPRECATED: int, + cancelBuffer_DEPRECATED: *const c_void, dequeueBuffer: extern fn(*mut ANativeWindow, *mut *mut ANativeWindowBuffer, *mut c_int) -> c_int, queueBuffer: extern fn(*mut ANativeWindow, *mut ANativeWindowBuffer, c_int) -> c_int, cancelBuffer: extern fn(*mut ANativeWindow, *mut ANativeWindowBuffer, c_int) -> c_int, @@ -453,7 +453,7 @@ extern fn gnw_decRef(base: *mut ANativeBase) { impl GonkNativeWindow { pub fn new(alloc_dev: *mut alloc_device, hwc_dev: *mut hwc_composer_device, width: i32, height: i32, usage: c_int) -> *mut GonkNativeWindow { - let win = Box::new(GonkNativeWindow { + let win = box GonkNativeWindow { window: ANativeWindow { common: ANativeBase { magic: ANativeBase::magic('_', 'w', 'n', 'd'), @@ -469,12 +469,12 @@ impl GonkNativeWindow { ydpi: 0f32, oem: unsafe { zeroed() }, setSwapInterval: setSwapInterval, - dequeueBuffer_DEPRECATED: 0, - lockBuffer_DEPRECATED: 0, - queueBuffer_DEPRECATED: 0, + dequeueBuffer_DEPRECATED: ptr::null(), + lockBuffer_DEPRECATED: ptr::null(), + queueBuffer_DEPRECATED: ptr::null(), query: query, perform: unsafe { transmute(gnw_perform) }, - cancelBuffer_DEPRECATED: 0, + cancelBuffer_DEPRECATED: ptr::null(), dequeueBuffer: dequeueBuffer, queueBuffer: queueBuffer, cancelBuffer: cancelBuffer, @@ -496,7 +496,7 @@ impl GonkNativeWindow { last_idx: -1, bufs: unsafe { zeroed() }, fences: [-1, -1], - }); + }; unsafe { transmute(win) } } @@ -584,7 +584,7 @@ extern fn gnwb_decRef(base: *mut ANativeBase) { impl GonkNativeWindowBuffer { pub fn new(dev: *mut alloc_device, width: i32, height: i32, format: c_int, usage: c_int) -> *mut GonkNativeWindowBuffer { - let mut buf = Box::new(GonkNativeWindowBuffer { + let mut buf = box GonkNativeWindowBuffer { buffer: ANativeWindowBuffer { common: ANativeBase { magic: ANativeBase::magic('_', 'b', 'f', 'r'), @@ -603,7 +603,7 @@ impl GonkNativeWindowBuffer { reserved_proc: unsafe { zeroed() }, }, count: 1, - }); + }; let ret = unsafe { ((*dev).alloc)(dev, width, height, format, usage, &mut buf.buffer.handle, &mut buf.buffer.stride) }; assert!(ret == 0, "Failed to allocate gralloc buffer!"); @@ -822,11 +822,11 @@ impl WindowMethods for Window { fn create_compositor_channel(window: &Option<Rc<Window>>) -> (Box<CompositorProxy+Send>, Box<CompositorReceiver>) { let (sender, receiver) = channel(); - (Box::new(GonkCompositorProxy { + (box GonkCompositorProxy { sender: sender, event_sender: window.as_ref().unwrap().event_send.clone(), - }) as Box<CompositorProxy+Send>, - Box::new(receiver) as Box<CompositorReceiver>) + } as Box<CompositorProxy+Send>, + box receiver as Box<CompositorReceiver>) } fn set_cursor(&self, _: Cursor) { @@ -849,10 +849,10 @@ impl CompositorProxy for GonkCompositorProxy { self.event_sender.send(WindowEvent::Idle).ok().unwrap(); } fn clone_compositor_proxy(&self) -> Box<CompositorProxy+Send> { - Box::new(GonkCompositorProxy { + box GonkCompositorProxy { sender: self.sender.clone(), event_sender: self.event_sender.clone(), - }) as Box<CompositorProxy+Send> + } as Box<CompositorProxy+Send> } } diff --git a/python/servo/post_build_commands.py b/python/servo/post_build_commands.py index 7faf3a598cf..667e4c6ace5 100644 --- a/python/servo/post_build_commands.py +++ b/python/servo/post_build_commands.py @@ -67,7 +67,7 @@ class MachCommands(CommandBase): print("The %s profile is not built. Please run './mach build%s' " "and try again." % ("release" if release else "dev", - "--release" if release else "")) + " --release" if release else "")) sys.exit() @Command('run', diff --git a/python/tidy.py b/python/tidy.py index c6bb4931e2d..cb20dff1646 100644 --- a/python/tidy.py +++ b/python/tidy.py @@ -14,7 +14,7 @@ import fnmatch import itertools from licenseck import licenses -directories_to_check = ["ports/gonk", "components"] +directories_to_check = ["ports", "components"] filetypes_to_check = [".rs", ".rc", ".cpp", ".c", ".h", ".py"] reftest_directories = ["tests/ref"] reftest_filetype = ".list" @@ -30,6 +30,7 @@ ignored_files = [ "components/servo/target/*", "ports/gonk/target/*", "ports/gonk/src/native_window_glue.cpp", + "ports/cef/*", # MIT license "components/util/deque/mod.rs", diff --git a/resources/rippy.jpg b/resources/rippy.jpg Binary files differnew file mode 100644 index 00000000000..a94649ae3f2 --- /dev/null +++ b/resources/rippy.jpg diff --git a/support/rust-task_info/src/task_basic_info.rs b/support/rust-task_info/src/task_basic_info.rs index 85fd84954ed..78efca0fd4f 100644 --- a/support/rust-task_info/src/task_basic_info.rs +++ b/support/rust-task_info/src/task_basic_info.rs @@ -10,32 +10,30 @@ //! Interface to the measurements in the task_basic_info struct, gathered by //! invoking `task_info()` with the `TASK_BASIC_INFO` flavor. -use libc::{c_int,uint64_t}; +use libc::{c_int, size_t}; /// Obtains task_basic_info::virtual_size. -pub fn virtual_size() -> Option<u64> { - let mut virtual_size: u64 = 0; - let mut rv; - unsafe { - rv = TaskBasicInfoVirtualSize(&mut virtual_size); - } - if rv == 0 { Some(virtual_size) } else { None } +pub fn virtual_size() -> Option<usize> { + let mut virtual_size: size_t = 0; + let rv = unsafe { + TaskBasicInfoVirtualSize(&mut virtual_size) + }; + if rv == 0 { Some(virtual_size as usize) } else { None } } /// Obtains task_basic_info::resident_size. -pub fn resident_size() -> Option<u64> { - let mut resident_size: u64 = 0; - let mut rv; - unsafe { - rv = TaskBasicInfoResidentSize(&mut resident_size); - } - if rv == 0 { Some(resident_size) } else { None } +pub fn resident_size() -> Option<usize> { + let mut resident_size: size_t = 0; + let rv = unsafe { + TaskBasicInfoResidentSize(&mut resident_size) + }; + if rv == 0 { Some(resident_size as usize) } else { None } } #[link(name = "task_info", kind = "static")] extern { - fn TaskBasicInfoVirtualSize(virtual_size: *mut uint64_t) -> c_int; - fn TaskBasicInfoResidentSize(resident_size: *mut uint64_t) -> c_int; + fn TaskBasicInfoVirtualSize(virtual_size: *mut size_t) -> c_int; + fn TaskBasicInfoResidentSize(resident_size: *mut size_t) -> c_int; } #[cfg(test)] diff --git a/support/rust-task_info/src/task_info.c b/support/rust-task_info/src/task_info.c index e8f59082609..476551c063b 100644 --- a/support/rust-task_info/src/task_info.c +++ b/support/rust-task_info/src/task_info.c @@ -20,7 +20,7 @@ TaskBasicInfo(struct task_basic_info* info) } int -TaskBasicInfoVirtualSize(int64_t *virtualSize) +TaskBasicInfoVirtualSize(size_t* virtualSize) { struct task_basic_info ti; int rv = TaskBasicInfo(&ti); @@ -29,7 +29,7 @@ TaskBasicInfoVirtualSize(int64_t *virtualSize) } int -TaskBasicInfoResidentSize(int64_t *residentSize) +TaskBasicInfoResidentSize(size_t* residentSize) { struct task_basic_info ti; int rv = TaskBasicInfo(&ti); diff --git a/tests/content/test_interfaces.html b/tests/content/test_interfaces.html index 1e56c7fe262..cb566e4ce1a 100644 --- a/tests/content/test_interfaces.html +++ b/tests/content/test_interfaces.html @@ -166,6 +166,7 @@ var interfaceNamesInGlobalScope = [ "StorageEvent", "TestBinding", // XXX "Text", + "TextEncoder", "TreeWalker", "UIEvent", "URLSearchParams", diff --git a/tests/content/test_navigator.html b/tests/content/test_navigator.html index 0b8b048bb2e..72cd17ab8f1 100644 --- a/tests/content/test_navigator.html +++ b/tests/content/test_navigator.html @@ -14,6 +14,7 @@ is(nav.taintEnabled(), false); is(nav.appName, "Netscape"); is(nav.appCodeName, "Mozilla"); is(nav.platform, ""); +is(nav.appVersion, "4.0"); </script> </body> </html> diff --git a/tests/contenttest.rs b/tests/contenttest.rs index 3723bd30ee0..67e24187b96 100644 --- a/tests/contenttest.rs +++ b/tests/contenttest.rs @@ -8,9 +8,7 @@ // except according to those terms. #![feature(collections)] -#![feature(core)] #![feature(exit_status)] -#![feature(old_io)] #![feature(path)] #![feature(rustc_private)] #![feature(std_misc)] @@ -25,8 +23,7 @@ use getopts::{getopts, reqopt}; use std::{str, env}; use std::ffi::OsStr; use std::fs::read_dir; -use std::old_io::Reader; -use std::old_io::process::{Command, Ignored, CreatePipe, InheritFd, ExitStatus}; +use std::process::{Command, Stdio}; use std::thunk::Thunk; #[derive(Clone)] @@ -50,9 +47,9 @@ fn main() { fn parse_config(args: Vec<String>) -> Config { let args = args.tail(); let opts = vec!(reqopt("s", "source-dir", "source-dir", "source-dir")); - let matches = match getopts(args, opts.as_slice()) { - Ok(m) => m, - Err(f) => panic!(f.to_string()) + let matches = match getopts(args, &opts) { + Ok(m) => m, + Err(f) => panic!(f.to_string()) }; Config { @@ -99,38 +96,26 @@ fn run_test(file: String) { let path = env::current_dir().unwrap().join(&file); // FIXME (#1094): not the right way to transform a path let infile = format!("file://{}", path.display()); - let stdout = CreatePipe(false, true); - let stderr = InheritFd(2); - let args = ["-z", "-f", infile.as_slice()]; + let args = ["-z", "-f", &*infile]; let mut prc_arg = env::current_exe().unwrap(); let prc_arg = match prc_arg.pop() { true => prc_arg.join("servo"), _ => panic!("could not pop directory"), }; - let mut prc = match Command::new(prc_arg.to_str().unwrap()) - .args(args.as_slice()) - .stdin(Ignored) - .stdout(stdout) - .stderr(stderr) - .spawn() + let output = match Command::new(prc_arg.to_str().unwrap()) + .args(&args) + .stdin(Stdio::null()) + .stderr(Stdio::inherit()) + .output() { Ok(p) => p, _ => panic!("Unable to spawn process."), }; - let mut output = Vec::new(); - loop { - let byte = prc.stdout.as_mut().unwrap().read_byte(); - match byte { - Ok(byte) => { - print!("{}", byte as char); - output.push(byte); - } - _ => break - } - } - let out = str::from_utf8(output.as_slice()); + print!("{}", str::from_utf8(&output.stdout).unwrap()); + + let out = str::from_utf8(&output.stderr); let lines: Vec<&str> = out.unwrap().split('\n').collect(); for &line in lines.iter() { if line.contains("TEST-UNEXPECTED-FAIL") { @@ -138,8 +123,7 @@ fn run_test(file: String) { } } - let retval = prc.wait(); - if retval != Ok(ExitStatus(0)) { - panic!("Servo exited with non-zero status {:?}", retval); + if !output.status.success() { + panic!("Servo exited with non-zero status {:?}", output.status); } } diff --git a/tests/html/transition_all.html b/tests/html/transition_all.html new file mode 100644 index 00000000000..1d9a199d5ca --- /dev/null +++ b/tests/html/transition_all.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> +<style> +section { + position: absolute; + display: block; + left: 0; + width: 64px; + height: 64px; + background: cadetblue; + transition: all 3s ease; + -moz-transition: all 3s ease; +} +</style> +</head> +<body> +<section></section> +<script> +var sections = document.getElementsByTagName('section'); +sections[0].setAttribute('style', "left: 0; top: 0"); +setTimeout(function() { + sections[0].setAttribute('style', "left: 512px; top: 512px"); +}, 0); +</script> +</body> +</html> + + diff --git a/tests/html/transition_multiple.html b/tests/html/transition_multiple.html new file mode 100644 index 00000000000..14d99ddfeff --- /dev/null +++ b/tests/html/transition_multiple.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<head> +<style> +section { + position: absolute; + display: block; + left: 0; + width: 64px; + height: 64px; + background: cadetblue; + transition: left 3s ease, top 1500ms ease; +} +</style> +</head> +<body> +<section></section> +<script> +var sections = document.getElementsByTagName('section'); +sections[0].setAttribute('style', "left: 0; top: 0"); +setTimeout(function() { + sections[0].setAttribute('style', "left: 512px; top: 512px"); +}, 0); +</script> +</body> +</html> + + diff --git a/tests/html/transition_simple.html b/tests/html/transition_simple.html new file mode 100644 index 00000000000..0cfdb073152 --- /dev/null +++ b/tests/html/transition_simple.html @@ -0,0 +1,96 @@ +<!DOCTYPE html> +<html> +<head> +<style> +section { + position: absolute; + display: block; + left: 0; + width: 64px; + height: 64px; + background: firebrick; + transition-property: left; + transition-duration: 3s; + -moz-transition-property: left; + -moz-transition-duration: 3s; + -webkit-transition-property: left; + -webkit-transition-duration: 3s; +} +#a { + top: 0; + transition-timing-function: ease; + -moz-transition-timing-function: ease; + -webkit-transition-timing-function: ease; +} +#b { + top: 64px; + transition-timing-function: linear; + -moz-transition-timing-function: linear; + -webkit-transition-timing-function: linear; +} +#c { + top: 128px; + transition-timing-function: ease-in; + -moz-transition-timing-function: ease-in; + -webkit-transition-timing-function: ease-in; +} +#d { + top: 192px; + transition-timing-function: ease-out; + -moz-transition-timing-function: ease-out; + -webkit-transition-timing-function: ease-out; +} +#e { + top: 256px; + transition-timing-function: ease-in-out; + -moz-transition-timing-function: ease-in-out; + -webkit-transition-timing-function: ease-in-out; +} +#f { + top: 320px; + transition-timing-function: step-start; + -moz-transition-timing-function: step-start; + -webkit-transition-timing-function: step-start; +} +#g { + top: 356px; + transition-timing-function: step-end; + -moz-transition-timing-function: step-end; + -webkit-transition-timing-function: step-end; +} +#h { + top: 420px; + transition-timing-function: steps(3, start); + -moz-transition-timing-function: steps(3, start); + -webkit-transition-timing-function: steps(3, start); +} +#i { + top: 484px; + transition-timing-function: steps(3, end); + -moz-transition-timing-function: steps(3, end); + -webkit-transition-timing-function: steps(3, end); +} +</style> +</head> +<body> +<section id=a></section> +<section id=b></section> +<section id=c></section> +<section id=d></section> +<section id=e></section> +<section id=f></section> +<section id=g></section> +<section id=h></section> +<section id=i></section> +<script> +var sections = document.getElementsByTagName('section'); +for (var i = 0; i < sections.length; i++) + sections[i].setAttribute('style', "left: 0"); +setTimeout(function() { + for (var i = 0; i < sections.length; i++) + sections[i].setAttribute('style', "left: 512px"); +}, 0); +</script> +</body> +</html> + diff --git a/tests/ref/basic.list b/tests/ref/basic.list index 3d322ac5d8c..c66e6750ad5 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -193,6 +193,7 @@ flaky_cpu == linebreak_simple_a.html linebreak_simple_b.html == multiple_css_class_a.html multiple_css_class_b.html == negative_margin_uncle_a.html negative_margin_uncle_b.html == negative_margins_a.html negative_margins_b.html +== no-image.html no-image-ref.html == noscript.html noscript_ref.html != noteq_attr_exists_selector.html attr_exists_selector_ref.html == nth_child_pseudo_a.html nth_child_pseudo_b.html diff --git a/tests/ref/no-image-ref.html b/tests/ref/no-image-ref.html new file mode 100644 index 00000000000..40ce07f789e --- /dev/null +++ b/tests/ref/no-image-ref.html @@ -0,0 +1 @@ +<img width="100px" height="100px" src="rippy.jpg"> diff --git a/tests/ref/no-image.html b/tests/ref/no-image.html new file mode 100644 index 00000000000..972206b12f1 --- /dev/null +++ b/tests/ref/no-image.html @@ -0,0 +1 @@ +<img width="100px" height="100px" src="i-feel-a-disturbance-in-the-force.wtf"> diff --git a/tests/ref/rippy.jpg b/tests/ref/rippy.jpg Binary files differnew file mode 100644 index 00000000000..a94649ae3f2 --- /dev/null +++ b/tests/ref/rippy.jpg diff --git a/tests/wpt/include.ini b/tests/wpt/include.ini index 5e53cc937ab..6307f5538cf 100644 --- a/tests/wpt/include.ini +++ b/tests/wpt/include.ini @@ -95,3 +95,5 @@ skip: true skip: true [webstorage] skip: false +[encoding] + skip: false diff --git a/tests/wpt/metadata/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.html.ini b/tests/wpt/metadata/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.html.ini index 293c51f06ae..c555d152783 100644 --- a/tests/wpt/metadata/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.html.ini +++ b/tests/wpt/metadata/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.html.ini @@ -1,3 +1,3 @@ [2d.fillStyle.parse.rgb-clamp-3.html] type: testharness - expected: CRASH + disabled: 5285 and https://github.com/servo/rust-cssparser/issues/72 diff --git a/tests/wpt/metadata/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.html.ini b/tests/wpt/metadata/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.html.ini index def25383235..61a342cc709 100644 --- a/tests/wpt/metadata/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.html.ini +++ b/tests/wpt/metadata/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.html.ini @@ -1,3 +1,3 @@ [2d.fillStyle.parse.rgb-clamp-4.html] type: testharness - expected: CRASH + disabled: 5285 and https://github.com/servo/rust-cssparser/issues/72 diff --git a/tests/wpt/metadata/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.html.ini b/tests/wpt/metadata/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.html.ini index 29e71891ded..ed320feddc3 100644 --- a/tests/wpt/metadata/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.html.ini +++ b/tests/wpt/metadata/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.html.ini @@ -1,3 +1,3 @@ [2d.fillStyle.parse.rgb-clamp-5.html] type: testharness - expected: CRASH + disabled: 5285 and https://github.com/servo/rust-cssparser/issues/72 diff --git a/tests/wpt/metadata/2dcontext/path-objects/2d.path.arc.negative.html.ini b/tests/wpt/metadata/2dcontext/path-objects/2d.path.arc.negative.html.ini deleted file mode 100644 index f8014c1fcfc..00000000000 --- a/tests/wpt/metadata/2dcontext/path-objects/2d.path.arc.negative.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[2d.path.arc.negative.html] - type: testharness - [arc() with negative radius throws INDEX_SIZE_ERR] - expected: FAIL - diff --git a/tests/wpt/metadata/DOMEvents/constructors.html.ini b/tests/wpt/metadata/DOMEvents/constructors.html.ini new file mode 100644 index 00000000000..c184b4a6143 --- /dev/null +++ b/tests/wpt/metadata/DOMEvents/constructors.html.ini @@ -0,0 +1,3 @@ +[constructors.html] + type: testharness + disabled: issue 5340 diff --git a/tests/wpt/metadata/DOMEvents/tests/approved/EventListener.dispatch.new.event.html.ini b/tests/wpt/metadata/DOMEvents/tests/approved/EventListener.dispatch.new.event.html.ini deleted file mode 100644 index 778f1b788b3..00000000000 --- a/tests/wpt/metadata/DOMEvents/tests/approved/EventListener.dispatch.new.event.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[EventListener.dispatch.new.event.html] - type: testharness - [Test Description: Implementations of the DOM event model must be reentrant. Event listeners may perform actions that cause additional events to be dispatched. Such events are handled in a synchronous manner, the event propagation that causes the event listener to be triggered must resume only after the event dispatch of the new event is completed.] - expected: FAIL - diff --git a/tests/wpt/metadata/FileAPI/FileReader/Progress_event_bubbles_cancelable.html.ini b/tests/wpt/metadata/FileAPI/FileReader/Progress_event_bubbles_cancelable.html.ini new file mode 100644 index 00000000000..9e2248b63c8 --- /dev/null +++ b/tests/wpt/metadata/FileAPI/FileReader/Progress_event_bubbles_cancelable.html.ini @@ -0,0 +1,5 @@ +[Progress_event_bubbles_cancelable.html] + type: testharness + [Check the values of bubbles and cancelable are false when the progress event is dispatched] + expected: FAIL + diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 203089332c0..67335b2c749 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -710,6 +710,10 @@ "url": "/html/semantics/forms/the-input-element/file-manual.html" }, { + "path": "html/semantics/grouping-content/the-li-element/grouping-li-novalue-manual.html", + "url": "/html/semantics/grouping-content/the-li-element/grouping-li-novalue-manual.html" + }, + { "path": "mediacapture-streams/mediastreams-as-media-elements/video-assignment-manual.html", "url": "/mediacapture-streams/mediastreams-as-media-elements/video-assignment-manual.html" }, @@ -7856,6 +7860,10 @@ "url": "/DOMEvents/ClickFakeEvent.nondocument.html" }, { + "path": "DOMEvents/constructors.html", + "url": "/DOMEvents/constructors.html" + }, + { "path": "DOMEvents/event-phases-order.html", "url": "/DOMEvents/event-phases-order.html" }, @@ -7868,10 +7876,6 @@ "url": "/DOMEvents/tests/approved/DOM.event.flow.html" }, { - "path": "DOMEvents/tests/approved/EventListener.dispatch.new.event.html", - "url": "/DOMEvents/tests/approved/EventListener.dispatch.new.event.html" - }, - { "path": "DOMEvents/tests/approved/EventListener.eventHandler.html", "url": "/DOMEvents/tests/approved/EventListener.eventHandler.html" }, @@ -7960,6 +7964,10 @@ "url": "/DOMEvents/throwing-in-listener-when-all-have-not-run-yet.html" }, { + "path": "FileAPI/FileReader/Progress_event_bubbles_cancelable.html", + "url": "/FileAPI/FileReader/Progress_event_bubbles_cancelable.html" + }, + { "path": "FileAPI/FileReaderSync.worker.js", "url": "/FileAPI/FileReaderSync.worker" }, @@ -10216,6 +10224,10 @@ "url": "/dom/events/Event-dispatch-redispatch.html" }, { + "path": "dom/events/Event-dispatch-reenter.html", + "url": "/dom/events/Event-dispatch-reenter.html" + }, + { "path": "dom/events/Event-dispatch-target-moved.html", "url": "/dom/events/Event-dispatch-target-moved.html" }, @@ -13788,10 +13800,6 @@ "url": "/html/semantics/embedded-content/the-img-element/relevant-mutations.html" }, { - "path": "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html", - "url": "/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html" - }, - { "path": "html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html", "url": "/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html" }, @@ -14212,10 +14220,6 @@ "url": "/html/semantics/grouping-content/the-hr-element/grouping-hr.html" }, { - "path": "html/semantics/grouping-content/the-li-element/grouping-li-novalue-MANUAL.html", - "url": "/html/semantics/grouping-content/the-li-element/grouping-li-novalue-MANUAL.html" - }, - { "path": "html/semantics/grouping-content/the-li-element/grouping-li.html", "url": "/html/semantics/grouping-content/the-li-element/grouping-li.html" }, @@ -14244,6 +14248,10 @@ "url": "/html/semantics/grouping-content/the-ul-element/grouping-ul.html" }, { + "path": "html/semantics/interactive-elements/the-details-element/details.html", + "url": "/html/semantics/interactive-elements/the-details-element/details.html" + }, + { "path": "html/semantics/interactive-elements/the-details-element/toggleEvent.html", "url": "/html/semantics/interactive-elements/the-details-element/toggleEvent.html" }, @@ -17980,6 +17988,14 @@ "url": "/websockets/unload-a-document/003.html" }, { + "path": "webstorage/builtins.html", + "url": "/webstorage/builtins.html" + }, + { + "path": "webstorage/clear.html", + "url": "/webstorage/clear.html" + }, + { "path": "webstorage/event_constructor.html", "url": "/webstorage/event_constructor.html" }, @@ -18036,124 +18052,40 @@ "url": "/webstorage/event_session_url.html" }, { - "path": "webstorage/idlharness.html", - "url": "/webstorage/idlharness.html" - }, - { - "path": "webstorage/missing_arguments.html", - "url": "/webstorage/missing_arguments.html" - }, - { - "path": "webstorage/storage_local_builtins.html", - "url": "/webstorage/storage_local_builtins.html" - }, - { - "path": "webstorage/storage_local_clear.html", - "url": "/webstorage/storage_local_clear.html" - }, - { - "path": "webstorage/storage_local_clear_js.html", - "url": "/webstorage/storage_local_clear_js.html" - }, - { - "path": "webstorage/storage_local_getitem.html", - "url": "/webstorage/storage_local_getitem.html" - }, - { - "path": "webstorage/storage_local_getitem_js.html", - "url": "/webstorage/storage_local_getitem_js.html" - }, - { - "path": "webstorage/storage_local_in_js.html", - "url": "/webstorage/storage_local_in_js.html" - }, - { - "path": "webstorage/storage_local_index_js.html", - "url": "/webstorage/storage_local_index_js.html" - }, - { - "path": "webstorage/storage_local_key.html", - "url": "/webstorage/storage_local_key.html" - }, - { - "path": "webstorage/storage_local_length.html", - "url": "/webstorage/storage_local_length.html" - }, - { - "path": "webstorage/storage_local_length_js.html", - "url": "/webstorage/storage_local_length_js.html" - }, - { - "path": "webstorage/storage_local_removeitem.html", - "url": "/webstorage/storage_local_removeitem.html" - }, - { - "path": "webstorage/storage_local_removeitem_js.html", - "url": "/webstorage/storage_local_removeitem_js.html" - }, - { - "path": "webstorage/storage_local_setitem.html", - "url": "/webstorage/storage_local_setitem.html" - }, - { - "path": "webstorage/storage_local_setitem_js.html", - "url": "/webstorage/storage_local_setitem_js.html" - }, - { - "path": "webstorage/storage_session_builtins.html", - "url": "/webstorage/storage_session_builtins.html" - }, - { - "path": "webstorage/storage_session_clear.html", - "url": "/webstorage/storage_session_clear.html" - }, - { - "path": "webstorage/storage_session_clear_js.html", - "url": "/webstorage/storage_session_clear_js.html" - }, - { - "path": "webstorage/storage_session_getitem.html", - "url": "/webstorage/storage_session_getitem.html" + "path": "webstorage/getitem.html", + "url": "/webstorage/getitem.html" }, { - "path": "webstorage/storage_session_getitem_js.html", - "url": "/webstorage/storage_session_getitem_js.html" - }, - { - "path": "webstorage/storage_session_in_js.html", - "url": "/webstorage/storage_session_in_js.html" - }, - { - "path": "webstorage/storage_session_index_js.html", - "url": "/webstorage/storage_session_index_js.html" + "path": "webstorage/idlharness.html", + "url": "/webstorage/idlharness.html" }, { - "path": "webstorage/storage_session_key.html", - "url": "/webstorage/storage_session_key.html" + "path": "webstorage/in.html", + "url": "/webstorage/in.html" }, { - "path": "webstorage/storage_session_length.html", - "url": "/webstorage/storage_session_length.html" + "path": "webstorage/indexing.html", + "url": "/webstorage/indexing.html" }, { - "path": "webstorage/storage_session_length_js.html", - "url": "/webstorage/storage_session_length_js.html" + "path": "webstorage/key.html", + "url": "/webstorage/key.html" }, { - "path": "webstorage/storage_session_removeitem.html", - "url": "/webstorage/storage_session_removeitem.html" + "path": "webstorage/length.html", + "url": "/webstorage/length.html" }, { - "path": "webstorage/storage_session_removeitem_js.html", - "url": "/webstorage/storage_session_removeitem_js.html" + "path": "webstorage/missing_arguments.html", + "url": "/webstorage/missing_arguments.html" }, { - "path": "webstorage/storage_session_setitem.html", - "url": "/webstorage/storage_session_setitem.html" + "path": "webstorage/removeitem.html", + "url": "/webstorage/removeitem.html" }, { - "path": "webstorage/storage_session_setitem_js.html", - "url": "/webstorage/storage_session_setitem_js.html" + "path": "webstorage/setitem.html", + "url": "/webstorage/setitem.html" }, { "path": "webvtt/interfaces.html", @@ -19167,49 +19099,144 @@ "url": "/html/semantics/embedded-content/media-elements/video_loop_base.html" }, { + "path": "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html", + "timeout": "long", + "url": "/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html" + }, + { + "path": "html/syntax/parsing/html5lib_adoption01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_adoption01.html?run_type=uri" + }, + { "path": "html/syntax/parsing/html5lib_adoption01.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_adoption01.html" + "url": "/html/syntax/parsing/html5lib_adoption01.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_adoption01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_adoption01.html?run_type=write_single" }, { "path": "html/syntax/parsing/html5lib_adoption02.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_adoption02.html" + "url": "/html/syntax/parsing/html5lib_adoption02.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_adoption02.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_adoption02.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_adoption02.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_adoption02.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_comments01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_comments01.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_comments01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_comments01.html?run_type=write" }, { "path": "html/syntax/parsing/html5lib_comments01.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_comments01.html" + "url": "/html/syntax/parsing/html5lib_comments01.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_doctype01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_doctype01.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_doctype01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_doctype01.html?run_type=write" }, { "path": "html/syntax/parsing/html5lib_doctype01.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_doctype01.html" + "url": "/html/syntax/parsing/html5lib_doctype01.html?run_type=write_single" }, { "path": "html/syntax/parsing/html5lib_domjs-unsafe.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_domjs-unsafe.html" + "url": "/html/syntax/parsing/html5lib_domjs-unsafe.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_domjs-unsafe.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_domjs-unsafe.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_domjs-unsafe.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_domjs-unsafe.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_entities01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_entities01.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_entities01.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_entities01.html" + "url": "/html/syntax/parsing/html5lib_entities01.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_entities01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_entities01.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_entities02.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_entities02.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_entities02.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_entities02.html" + "url": "/html/syntax/parsing/html5lib_entities02.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_entities02.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_entities02.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_html5test-com.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_html5test-com.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_html5test-com.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_html5test-com.html" + "url": "/html/syntax/parsing/html5lib_html5test-com.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_html5test-com.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_html5test-com.html?run_type=write_single" }, { "path": "html/syntax/parsing/html5lib_inbody01.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_inbody01.html" + "url": "/html/syntax/parsing/html5lib_inbody01.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_inbody01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_inbody01.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_inbody01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_inbody01.html?run_type=write_single" }, { "path": "html/syntax/parsing/html5lib_innerHTML_tests4.html", @@ -19234,192 +19261,572 @@ { "path": "html/syntax/parsing/html5lib_isindex.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_isindex.html" + "url": "/html/syntax/parsing/html5lib_isindex.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_isindex.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_isindex.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_isindex.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_isindex.html?run_type=write_single" }, { "path": "html/syntax/parsing/html5lib_main-element.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_main-element.html" + "url": "/html/syntax/parsing/html5lib_main-element.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_main-element.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_main-element.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_main-element.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_main-element.html?run_type=write_single" }, { "path": "html/syntax/parsing/html5lib_pending-spec-changes-plain-text-unsafe.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_pending-spec-changes-plain-text-unsafe.html" + "url": "/html/syntax/parsing/html5lib_pending-spec-changes-plain-text-unsafe.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_pending-spec-changes-plain-text-unsafe.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_pending-spec-changes-plain-text-unsafe.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_pending-spec-changes-plain-text-unsafe.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_pending-spec-changes-plain-text-unsafe.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_pending-spec-changes.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_pending-spec-changes.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_pending-spec-changes.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_pending-spec-changes.html?run_type=write" }, { "path": "html/syntax/parsing/html5lib_pending-spec-changes.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_pending-spec-changes.html" + "url": "/html/syntax/parsing/html5lib_pending-spec-changes.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_plain-text-unsafe.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_plain-text-unsafe.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_plain-text-unsafe.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_plain-text-unsafe.html" + "url": "/html/syntax/parsing/html5lib_plain-text-unsafe.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_plain-text-unsafe.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_plain-text-unsafe.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_scriptdata01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_scriptdata01.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_scriptdata01.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_scriptdata01.html" + "url": "/html/syntax/parsing/html5lib_scriptdata01.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_scriptdata01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_scriptdata01.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_scripted_adoption01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_scripted_adoption01.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_scripted_adoption01.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_scripted_adoption01.html" + "url": "/html/syntax/parsing/html5lib_scripted_adoption01.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_scripted_adoption01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_scripted_adoption01.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_scripted_ark.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_scripted_ark.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_scripted_ark.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_scripted_ark.html?run_type=write" }, { "path": "html/syntax/parsing/html5lib_scripted_ark.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_scripted_ark.html" + "url": "/html/syntax/parsing/html5lib_scripted_ark.html?run_type=write_single" }, { "path": "html/syntax/parsing/html5lib_scripted_webkit01.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_scripted_webkit01.html" + "url": "/html/syntax/parsing/html5lib_scripted_webkit01.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_scripted_webkit01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_scripted_webkit01.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_scripted_webkit01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_scripted_webkit01.html?run_type=write_single" }, { "path": "html/syntax/parsing/html5lib_tables01.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tables01.html" + "url": "/html/syntax/parsing/html5lib_tables01.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_tables01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tables01.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tables01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tables01.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_template.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_template.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_template.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_template.html" + "url": "/html/syntax/parsing/html5lib_template.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_template.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_template.html?run_type=write_single" }, { "path": "html/syntax/parsing/html5lib_tests1.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests1.html" + "url": "/html/syntax/parsing/html5lib_tests1.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_tests1.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests1.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tests1.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests1.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests10.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests10.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_tests10.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests10.html" + "url": "/html/syntax/parsing/html5lib_tests10.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tests10.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests10.html?run_type=write_single" }, { "path": "html/syntax/parsing/html5lib_tests11.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests11.html" + "url": "/html/syntax/parsing/html5lib_tests11.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_tests11.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests11.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tests11.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests11.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests12.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests12.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_tests12.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests12.html" + "url": "/html/syntax/parsing/html5lib_tests12.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tests12.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests12.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests14.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests14.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_tests14.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests14.html?run_type=write" }, { "path": "html/syntax/parsing/html5lib_tests14.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests14.html" + "url": "/html/syntax/parsing/html5lib_tests14.html?run_type=write_single" }, { "path": "html/syntax/parsing/html5lib_tests15.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests15.html" + "url": "/html/syntax/parsing/html5lib_tests15.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_tests15.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests15.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tests15.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests15.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests16.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests16.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_tests16.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests16.html?run_type=write" }, { "path": "html/syntax/parsing/html5lib_tests16.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests16.html" + "url": "/html/syntax/parsing/html5lib_tests16.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests17.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests17.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_tests17.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests17.html?run_type=write" }, { "path": "html/syntax/parsing/html5lib_tests17.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests17.html" + "url": "/html/syntax/parsing/html5lib_tests17.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests18.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests18.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_tests18.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests18.html" + "url": "/html/syntax/parsing/html5lib_tests18.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tests18.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests18.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests19.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests19.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_tests19.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests19.html" + "url": "/html/syntax/parsing/html5lib_tests19.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tests19.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests19.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests2.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests2.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_tests2.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests2.html" + "url": "/html/syntax/parsing/html5lib_tests2.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tests2.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests2.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests20.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests20.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_tests20.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests20.html?run_type=write" }, { "path": "html/syntax/parsing/html5lib_tests20.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests20.html" + "url": "/html/syntax/parsing/html5lib_tests20.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests21.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests21.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_tests21.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests21.html?run_type=write" }, { "path": "html/syntax/parsing/html5lib_tests21.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests21.html" + "url": "/html/syntax/parsing/html5lib_tests21.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests22.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests22.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_tests22.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests22.html" + "url": "/html/syntax/parsing/html5lib_tests22.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tests22.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests22.html?run_type=write_single" }, { "path": "html/syntax/parsing/html5lib_tests23.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests23.html" + "url": "/html/syntax/parsing/html5lib_tests23.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_tests23.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests23.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tests23.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests23.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests24.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests24.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_tests24.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests24.html?run_type=write" }, { "path": "html/syntax/parsing/html5lib_tests24.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests24.html" + "url": "/html/syntax/parsing/html5lib_tests24.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests25.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests25.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_tests25.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests25.html" + "url": "/html/syntax/parsing/html5lib_tests25.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tests25.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests25.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests26.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests26.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_tests26.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests26.html" + "url": "/html/syntax/parsing/html5lib_tests26.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tests26.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests26.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests3.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests3.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_tests3.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests3.html" + "url": "/html/syntax/parsing/html5lib_tests3.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tests3.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests3.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests5.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests5.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_tests5.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests5.html?run_type=write" }, { "path": "html/syntax/parsing/html5lib_tests5.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests5.html" + "url": "/html/syntax/parsing/html5lib_tests5.html?run_type=write_single" }, { "path": "html/syntax/parsing/html5lib_tests6.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests6.html" + "url": "/html/syntax/parsing/html5lib_tests6.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_tests6.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests6.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tests6.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests6.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests7.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests7.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_tests7.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests7.html?run_type=write" }, { "path": "html/syntax/parsing/html5lib_tests7.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests7.html" + "url": "/html/syntax/parsing/html5lib_tests7.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests8.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests8.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_tests8.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests8.html?run_type=write" }, { "path": "html/syntax/parsing/html5lib_tests8.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests8.html" + "url": "/html/syntax/parsing/html5lib_tests8.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tests9.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests9.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_tests9.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tests9.html" + "url": "/html/syntax/parsing/html5lib_tests9.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tests9.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tests9.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_tricky01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tricky01.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_tricky01.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_tricky01.html" + "url": "/html/syntax/parsing/html5lib_tricky01.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_tricky01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_tricky01.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_webkit01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_webkit01.html?run_type=uri" }, { "path": "html/syntax/parsing/html5lib_webkit01.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_webkit01.html" + "url": "/html/syntax/parsing/html5lib_webkit01.html?run_type=write" + }, + { + "path": "html/syntax/parsing/html5lib_webkit01.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_webkit01.html?run_type=write_single" + }, + { + "path": "html/syntax/parsing/html5lib_webkit02.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_webkit02.html?run_type=uri" + }, + { + "path": "html/syntax/parsing/html5lib_webkit02.html", + "timeout": "long", + "url": "/html/syntax/parsing/html5lib_webkit02.html?run_type=write" }, { "path": "html/syntax/parsing/html5lib_webkit02.html", "timeout": "long", - "url": "/html/syntax/parsing/html5lib_webkit02.html" + "url": "/html/syntax/parsing/html5lib_webkit02.html?run_type=write_single" }, { "path": "media-source/mediasource-redundant-seek.html", @@ -24627,7 +25034,7 @@ } ] }, - "rev": "56db12eee9711048ea4c927a89b9e9e05fd97c1b", + "rev": "29dfb8944e535d439ca94cf7d1b1d9138a8ad11f", "url_base": "/", "version": 2 }
\ No newline at end of file diff --git a/tests/wpt/metadata/XMLHttpRequest/open-during-abort.htm.ini b/tests/wpt/metadata/XMLHttpRequest/open-during-abort.htm.ini deleted file mode 100644 index 0ba31ee4bbd..00000000000 --- a/tests/wpt/metadata/XMLHttpRequest/open-during-abort.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[open-during-abort.htm] - type: testharness - [XMLHttpRequest: open() during abort()] - expected: FAIL - diff --git a/tests/wpt/metadata/dom/events/Event-dispatch-reenter.html.ini b/tests/wpt/metadata/dom/events/Event-dispatch-reenter.html.ini new file mode 100644 index 00000000000..4d7f85c0779 --- /dev/null +++ b/tests/wpt/metadata/dom/events/Event-dispatch-reenter.html.ini @@ -0,0 +1,5 @@ +[Event-dispatch-reenter.html] + type: testharness + [ Dispatch additional events inside an event listener ] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/api-basics.html.ini b/tests/wpt/metadata/encoding/api-basics.html.ini new file mode 100644 index 00000000000..03947330276 --- /dev/null +++ b/tests/wpt/metadata/encoding/api-basics.html.ini @@ -0,0 +1,20 @@ +[api-basics.html] + type: testharness + [Default encodings] + expected: FAIL + + [Default inputs] + expected: FAIL + + [Encode/decode round trip: utf-8] + expected: FAIL + + [Encode/decode round trip: utf-16le] + expected: FAIL + + [Encode/decode round trip: utf-16be] + expected: FAIL + + [Encode/decode round trip: utf-16] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/api-replacement-encodings.html.ini b/tests/wpt/metadata/encoding/api-replacement-encodings.html.ini new file mode 100644 index 00000000000..94c7203d3c2 --- /dev/null +++ b/tests/wpt/metadata/encoding/api-replacement-encodings.html.ini @@ -0,0 +1,20 @@ +[api-replacement-encodings.html] + type: testharness + [The "replacement" label should not be a known encoding.] + expected: FAIL + + [Label for "replacement" should be rejected by API: csiso2022kr] + expected: FAIL + + [Label for "replacement" should be rejected by API: hz-gb-2312] + expected: FAIL + + [Label for "replacement" should be rejected by API: iso-2022-cn] + expected: FAIL + + [Label for "replacement" should be rejected by API: iso-2022-cn-ext] + expected: FAIL + + [Label for "replacement" should be rejected by API: iso-2022-kr] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/api-surrogates-utf8.html.ini b/tests/wpt/metadata/encoding/api-surrogates-utf8.html.ini new file mode 100644 index 00000000000..76324a435ae --- /dev/null +++ b/tests/wpt/metadata/encoding/api-surrogates-utf8.html.ini @@ -0,0 +1,20 @@ +[api-surrogates-utf8.html] + type: testharness + [Invalid surrogates encoded into UTF-8: Sanity check] + expected: FAIL + + [Invalid surrogates encoded into UTF-8: Surrogate half (low)] + expected: FAIL + + [Invalid surrogates encoded into UTF-8: Surrogate half (high)] + expected: FAIL + + [Invalid surrogates encoded into UTF-8: Surrogate half (low), in a string] + expected: FAIL + + [Invalid surrogates encoded into UTF-8: Surrogate half (high), in a string] + expected: FAIL + + [Invalid surrogates encoded into UTF-8: Wrong order] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/gb18030-encoder.html.ini b/tests/wpt/metadata/encoding/gb18030-encoder.html.ini new file mode 100644 index 00000000000..75992eb01e7 --- /dev/null +++ b/tests/wpt/metadata/encoding/gb18030-encoder.html.ini @@ -0,0 +1,20 @@ +[gb18030-encoder.html] + type: testharness + [gb18030 encoder: very basic] + expected: FAIL + + [gb18030 encoder: Euro] + expected: FAIL + + [gb18030 encoder: character] + expected: FAIL + + [gb18030 encoder: PUA] + expected: FAIL + + [gb18030 encoder: PUA #2] + expected: FAIL + + [gb18030 encoder: poo] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/gbk-encoder.html.ini b/tests/wpt/metadata/encoding/gbk-encoder.html.ini new file mode 100644 index 00000000000..05dda500d11 --- /dev/null +++ b/tests/wpt/metadata/encoding/gbk-encoder.html.ini @@ -0,0 +1,20 @@ +[gbk-encoder.html] + type: testharness + [gbk encoder: very basic] + expected: FAIL + + [gbk encoder: Euro] + expected: FAIL + + [gbk encoder: character] + expected: FAIL + + [gbk encoder: PUA] + expected: FAIL + + [gbk encoder: PUA #2] + expected: FAIL + + [gbk encoder: poo] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/idlharness.html.ini b/tests/wpt/metadata/encoding/idlharness.html.ini new file mode 100644 index 00000000000..f4ca82ffa3d --- /dev/null +++ b/tests/wpt/metadata/encoding/idlharness.html.ini @@ -0,0 +1,52 @@ +[idlharness.html] + type: testharness + [TextDecoder interface: existence and properties of interface object] + expected: FAIL + + [TextDecoder interface object length] + expected: FAIL + + [TextDecoder interface: existence and properties of interface prototype object] + expected: FAIL + + [TextDecoder interface: existence and properties of interface prototype object\'s "constructor" property] + expected: FAIL + + [TextDecoder interface: attribute encoding] + expected: FAIL + + [TextDecoder interface: attribute fatal] + expected: FAIL + + [TextDecoder interface: attribute ignoreBOM] + expected: FAIL + + [TextDecoder interface: operation decode(BufferSource,TextDecodeOptions)] + expected: FAIL + + [TextDecoder must be primary interface of new TextDecoder()] + expected: FAIL + + [Stringification of new TextDecoder()] + expected: FAIL + + [TextDecoder interface: new TextDecoder() must inherit property "encoding" with the proper type (0)] + expected: FAIL + + [TextDecoder interface: new TextDecoder() must inherit property "fatal" with the proper type (1)] + expected: FAIL + + [TextDecoder interface: new TextDecoder() must inherit property "ignoreBOM" with the proper type (2)] + expected: FAIL + + [TextDecoder interface: new TextDecoder() must inherit property "decode" with the proper type (3)] + expected: FAIL + + [TextDecoder interface: calling decode(BufferSource,TextDecodeOptions) on new TextDecoder() with too few arguments must throw TypeError] + expected: FAIL + + [TextEncoder interface object length] + expected: FAIL + + [TextEncoder interface: operation encode(USVString)] + expected: FAIL diff --git a/tests/wpt/metadata/encoding/iso-2022-jp-decoder.html.ini b/tests/wpt/metadata/encoding/iso-2022-jp-decoder.html.ini new file mode 100644 index 00000000000..4651cfad0d9 --- /dev/null +++ b/tests/wpt/metadata/encoding/iso-2022-jp-decoder.html.ini @@ -0,0 +1,104 @@ +[iso-2022-jp-decoder.html] + type: testharness + [iso-2022-jp decoder: Error ESC] + expected: FAIL + + [iso-2022-jp decoder: Error ESC, character] + expected: FAIL + + [iso-2022-jp decoder: ASCII ESC, character] + expected: FAIL + + [iso-2022-jp decoder: Double ASCII ESC, character] + expected: FAIL + + [iso-2022-jp decoder: character, ASCII ESC, character] + expected: FAIL + + [iso-2022-jp decoder: characters] + expected: FAIL + + [iso-2022-jp decoder: SO / SI] + expected: FAIL + + [iso-2022-jp decoder: Roman ESC, characters] + expected: FAIL + + [iso-2022-jp decoder: Roman ESC, SO / SI] + expected: FAIL + + [iso-2022-jp decoder: Roman ESC, error ESC, Katakana ESC] + expected: FAIL + + [iso-2022-jp decoder: Katakana ESC, character] + expected: FAIL + + [iso-2022-jp decoder: Katakana ESC, multibyte ESC, character] + expected: FAIL + + [iso-2022-jp decoder: Katakana ESC, error ESC, character] + expected: FAIL + + [iso-2022-jp decoder: Katakana ESC, error ESC #2, character] + expected: FAIL + + [iso-2022-jp decoder: Katakana ESC, character, Katakana ESC, character] + expected: FAIL + + [iso-2022-jp decoder: Katakana ESC, SO / SI] + expected: FAIL + + [iso-2022-jp decoder: Multibyte ESC, character] + expected: FAIL + + [iso-2022-jp decoder: Multibyte ESC #2, character] + expected: FAIL + + [iso-2022-jp decoder: Multibyte ESC, error ESC, character] + expected: FAIL + + [iso-2022-jp decoder: Double multibyte ESC] + expected: FAIL + + [iso-2022-jp decoder: Double multibyte ESC, character] + expected: FAIL + + [iso-2022-jp decoder: Double multibyte ESC #2, character] + expected: FAIL + + [iso-2022-jp decoder: Multibyte ESC, error ESC #2, character] + expected: FAIL + + [iso-2022-jp decoder: Multibyte ESC, single byte, multibyte ESC, character] + expected: FAIL + + [iso-2022-jp decoder: Multibyte ESC, lead error byte] + expected: FAIL + + [iso-2022-jp decoder: Multibyte ESC, trail error byte] + expected: FAIL + + [iso-2022-jp decoder: character, error ESC] + expected: FAIL + + [iso-2022-jp decoder: character, error ESC #2] + expected: FAIL + + [iso-2022-jp decoder: character, error ESC #3] + expected: FAIL + + [iso-2022-jp decoder: character, ASCII ESC] + expected: FAIL + + [iso-2022-jp decoder: character, Roman ESC] + expected: FAIL + + [iso-2022-jp decoder: character, Katakana ESC] + expected: FAIL + + [iso-2022-jp decoder: character, Multibyte ESC] + expected: FAIL + + [iso-2022-jp decoder: character, Multibyte ESC #2] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/iso-2022-jp-encoder.html.ini b/tests/wpt/metadata/encoding/iso-2022-jp-encoder.html.ini new file mode 100644 index 00000000000..867e2dd11ae --- /dev/null +++ b/tests/wpt/metadata/encoding/iso-2022-jp-encoder.html.ini @@ -0,0 +1,11 @@ +[iso-2022-jp-encoder.html] + type: testharness + [iso-2022-jp encoder: very basic] + expected: FAIL + + [iso-2022-jp encoder: basics] + expected: FAIL + + [iso-2022-jp encoder: SO/SI ESC] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/single-byte-decoder.html.ini b/tests/wpt/metadata/encoding/single-byte-decoder.html.ini new file mode 100644 index 00000000000..66ecfdda227 --- /dev/null +++ b/tests/wpt/metadata/encoding/single-byte-decoder.html.ini @@ -0,0 +1,3 @@ +[single-byte-decoder.html] + type: testharness + disabled: iframe thread issue 5247 diff --git a/tests/wpt/metadata/encoding/textdecoder-byte-order-marks.html.ini b/tests/wpt/metadata/encoding/textdecoder-byte-order-marks.html.ini new file mode 100644 index 00000000000..fa837cc8892 --- /dev/null +++ b/tests/wpt/metadata/encoding/textdecoder-byte-order-marks.html.ini @@ -0,0 +1,11 @@ +[textdecoder-byte-order-marks.html] + type: testharness + [Byte-order marks: utf-8] + expected: FAIL + + [Byte-order marks: utf-16le] + expected: FAIL + + [Byte-order marks: utf-16be] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/textdecoder-fatal-streaming.html.ini b/tests/wpt/metadata/encoding/textdecoder-fatal-streaming.html.ini new file mode 100644 index 00000000000..5491e6cad84 --- /dev/null +++ b/tests/wpt/metadata/encoding/textdecoder-fatal-streaming.html.ini @@ -0,0 +1,8 @@ +[textdecoder-fatal-streaming.html] + type: testharness + [Fatal flag, non-streaming cases] + expected: FAIL + + [Fatal flag, streaming cases] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/textdecoder-fatal.html.ini b/tests/wpt/metadata/encoding/textdecoder-fatal.html.ini new file mode 100644 index 00000000000..3f7dc6f45f6 --- /dev/null +++ b/tests/wpt/metadata/encoding/textdecoder-fatal.html.ini @@ -0,0 +1,107 @@ +[textdecoder-fatal.html] + type: testharness + [Fatal flag: utf-8 - invalid code] + expected: FAIL + + [Fatal flag: utf-8 - ends early] + expected: FAIL + + [Fatal flag: utf-8 - ends early 2] + expected: FAIL + + [Fatal flag: utf-8 - invalid trail] + expected: FAIL + + [Fatal flag: utf-8 - invalid trail 2] + expected: FAIL + + [Fatal flag: utf-8 - invalid trail 3] + expected: FAIL + + [Fatal flag: utf-8 - invalid trail 4] + expected: FAIL + + [Fatal flag: utf-8 - invalid trail 5] + expected: FAIL + + [Fatal flag: utf-8 - invalid trail 6] + expected: FAIL + + [Fatal flag: utf-8 - > 0x10FFFF] + expected: FAIL + + [Fatal flag: utf-8 - obsolete lead byte] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+0000 - 2 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+0000 - 3 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+0000 - 4 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+0000 - 5 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+0000 - 6 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+007F - 2 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+007F - 3 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+007F - 4 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+007F - 5 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+007F - 6 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+07FF - 3 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+07FF - 4 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+07FF - 5 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+07FF - 6 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+FFFF - 4 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+FFFF - 5 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+FFFF - 6 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+10FFFF - 5 bytes] + expected: FAIL + + [Fatal flag: utf-8 - overlong U+10FFFF - 6 bytes] + expected: FAIL + + [Fatal flag: utf-8 - lead surrogate] + expected: FAIL + + [Fatal flag: utf-8 - trail surrogate] + expected: FAIL + + [Fatal flag: utf-8 - surrogate pair] + expected: FAIL + + [Fatal flag: utf-16le - truncated code unit] + expected: FAIL + + [The fatal attribute of TextDecoder] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/textdecoder-ignorebom.html.ini b/tests/wpt/metadata/encoding/textdecoder-ignorebom.html.ini new file mode 100644 index 00000000000..dc08914054f --- /dev/null +++ b/tests/wpt/metadata/encoding/textdecoder-ignorebom.html.ini @@ -0,0 +1,14 @@ +[textdecoder-ignorebom.html] + type: testharness + [BOM is ignored if ignoreBOM option is specified: utf-8] + expected: FAIL + + [BOM is ignored if ignoreBOM option is specified: utf-16le] + expected: FAIL + + [BOM is ignored if ignoreBOM option is specified: utf-16be] + expected: FAIL + + [The ignoreBOM attribute of TextDecoder] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/textdecoder-labels.html.ini b/tests/wpt/metadata/encoding/textdecoder-labels.html.ini new file mode 100644 index 00000000000..61506476753 --- /dev/null +++ b/tests/wpt/metadata/encoding/textdecoder-labels.html.ini @@ -0,0 +1,635 @@ +[textdecoder-labels.html] + type: testharness + [name=utf-8 label=unicode-1-1-utf-8] + expected: FAIL + + [name=utf-8 label=utf-8] + expected: FAIL + + [name=utf-8 label=utf8] + expected: FAIL + + [name=ibm866 label=866] + expected: FAIL + + [name=ibm866 label=cp866] + expected: FAIL + + [name=ibm866 label=csibm866] + expected: FAIL + + [name=ibm866 label=ibm866] + expected: FAIL + + [name=iso-8859-2 label=csisolatin2] + expected: FAIL + + [name=iso-8859-2 label=iso-8859-2] + expected: FAIL + + [name=iso-8859-2 label=iso-ir-101] + expected: FAIL + + [name=iso-8859-2 label=iso8859-2] + expected: FAIL + + [name=iso-8859-2 label=iso88592] + expected: FAIL + + [name=iso-8859-2 label=iso_8859-2] + expected: FAIL + + [name=iso-8859-2 label=iso_8859-2:1987] + expected: FAIL + + [name=iso-8859-2 label=l2] + expected: FAIL + + [name=iso-8859-2 label=latin2] + expected: FAIL + + [name=iso-8859-3 label=csisolatin3] + expected: FAIL + + [name=iso-8859-3 label=iso-8859-3] + expected: FAIL + + [name=iso-8859-3 label=iso-ir-109] + expected: FAIL + + [name=iso-8859-3 label=iso8859-3] + expected: FAIL + + [name=iso-8859-3 label=iso88593] + expected: FAIL + + [name=iso-8859-3 label=iso_8859-3] + expected: FAIL + + [name=iso-8859-3 label=iso_8859-3:1988] + expected: FAIL + + [name=iso-8859-3 label=l3] + expected: FAIL + + [name=iso-8859-3 label=latin3] + expected: FAIL + + [name=iso-8859-4 label=csisolatin4] + expected: FAIL + + [name=iso-8859-4 label=iso-8859-4] + expected: FAIL + + [name=iso-8859-4 label=iso-ir-110] + expected: FAIL + + [name=iso-8859-4 label=iso8859-4] + expected: FAIL + + [name=iso-8859-4 label=iso88594] + expected: FAIL + + [name=iso-8859-4 label=iso_8859-4] + expected: FAIL + + [name=iso-8859-4 label=iso_8859-4:1988] + expected: FAIL + + [name=iso-8859-4 label=l4] + expected: FAIL + + [name=iso-8859-4 label=latin4] + expected: FAIL + + [name=iso-8859-5 label=csisolatincyrillic] + expected: FAIL + + [name=iso-8859-5 label=cyrillic] + expected: FAIL + + [name=iso-8859-5 label=iso-8859-5] + expected: FAIL + + [name=iso-8859-5 label=iso-ir-144] + expected: FAIL + + [name=iso-8859-5 label=iso8859-5] + expected: FAIL + + [name=iso-8859-5 label=iso88595] + expected: FAIL + + [name=iso-8859-5 label=iso_8859-5] + expected: FAIL + + [name=iso-8859-5 label=iso_8859-5:1988] + expected: FAIL + + [name=iso-8859-6 label=arabic] + expected: FAIL + + [name=iso-8859-6 label=asmo-708] + expected: FAIL + + [name=iso-8859-6 label=csiso88596e] + expected: FAIL + + [name=iso-8859-6 label=csiso88596i] + expected: FAIL + + [name=iso-8859-6 label=csisolatinarabic] + expected: FAIL + + [name=iso-8859-6 label=ecma-114] + expected: FAIL + + [name=iso-8859-6 label=iso-8859-6] + expected: FAIL + + [name=iso-8859-6 label=iso-8859-6-e] + expected: FAIL + + [name=iso-8859-6 label=iso-8859-6-i] + expected: FAIL + + [name=iso-8859-6 label=iso-ir-127] + expected: FAIL + + [name=iso-8859-6 label=iso8859-6] + expected: FAIL + + [name=iso-8859-6 label=iso88596] + expected: FAIL + + [name=iso-8859-6 label=iso_8859-6] + expected: FAIL + + [name=iso-8859-6 label=iso_8859-6:1987] + expected: FAIL + + [name=iso-8859-7 label=csisolatingreek] + expected: FAIL + + [name=iso-8859-7 label=ecma-118] + expected: FAIL + + [name=iso-8859-7 label=elot_928] + expected: FAIL + + [name=iso-8859-7 label=greek] + expected: FAIL + + [name=iso-8859-7 label=greek8] + expected: FAIL + + [name=iso-8859-7 label=iso-8859-7] + expected: FAIL + + [name=iso-8859-7 label=iso-ir-126] + expected: FAIL + + [name=iso-8859-7 label=iso8859-7] + expected: FAIL + + [name=iso-8859-7 label=iso88597] + expected: FAIL + + [name=iso-8859-7 label=iso_8859-7] + expected: FAIL + + [name=iso-8859-7 label=iso_8859-7:1987] + expected: FAIL + + [name=iso-8859-7 label=sun_eu_greek] + expected: FAIL + + [name=iso-8859-8 label=csiso88598e] + expected: FAIL + + [name=iso-8859-8 label=csisolatinhebrew] + expected: FAIL + + [name=iso-8859-8 label=hebrew] + expected: FAIL + + [name=iso-8859-8 label=iso-8859-8] + expected: FAIL + + [name=iso-8859-8 label=iso-8859-8-e] + expected: FAIL + + [name=iso-8859-8 label=iso-ir-138] + expected: FAIL + + [name=iso-8859-8 label=iso8859-8] + expected: FAIL + + [name=iso-8859-8 label=iso88598] + expected: FAIL + + [name=iso-8859-8 label=iso_8859-8] + expected: FAIL + + [name=iso-8859-8 label=iso_8859-8:1988] + expected: FAIL + + [name=iso-8859-8 label=visual] + expected: FAIL + + [name=iso-8859-8-i label=csiso88598i] + expected: FAIL + + [name=iso-8859-8-i label=iso-8859-8-i] + expected: FAIL + + [name=iso-8859-8-i label=logical] + expected: FAIL + + [name=iso-8859-10 label=csisolatin6] + expected: FAIL + + [name=iso-8859-10 label=iso-8859-10] + expected: FAIL + + [name=iso-8859-10 label=iso-ir-157] + expected: FAIL + + [name=iso-8859-10 label=iso8859-10] + expected: FAIL + + [name=iso-8859-10 label=iso885910] + expected: FAIL + + [name=iso-8859-10 label=l6] + expected: FAIL + + [name=iso-8859-10 label=latin6] + expected: FAIL + + [name=iso-8859-13 label=iso-8859-13] + expected: FAIL + + [name=iso-8859-13 label=iso8859-13] + expected: FAIL + + [name=iso-8859-13 label=iso885913] + expected: FAIL + + [name=iso-8859-14 label=iso-8859-14] + expected: FAIL + + [name=iso-8859-14 label=iso8859-14] + expected: FAIL + + [name=iso-8859-14 label=iso885914] + expected: FAIL + + [name=iso-8859-15 label=csisolatin9] + expected: FAIL + + [name=iso-8859-15 label=iso-8859-15] + expected: FAIL + + [name=iso-8859-15 label=iso8859-15] + expected: FAIL + + [name=iso-8859-15 label=iso885915] + expected: FAIL + + [name=iso-8859-15 label=iso_8859-15] + expected: FAIL + + [name=iso-8859-15 label=l9] + expected: FAIL + + [name=iso-8859-16 label=iso-8859-16] + expected: FAIL + + [name=koi8-r label=cskoi8r] + expected: FAIL + + [name=koi8-r label=koi] + expected: FAIL + + [name=koi8-r label=koi8] + expected: FAIL + + [name=koi8-r label=koi8-r] + expected: FAIL + + [name=koi8-r label=koi8_r] + expected: FAIL + + [name=koi8-u label=koi8-u] + expected: FAIL + + [name=macintosh label=csmacintosh] + expected: FAIL + + [name=macintosh label=mac] + expected: FAIL + + [name=macintosh label=macintosh] + expected: FAIL + + [name=macintosh label=x-mac-roman] + expected: FAIL + + [name=windows-874 label=dos-874] + expected: FAIL + + [name=windows-874 label=iso-8859-11] + expected: FAIL + + [name=windows-874 label=iso8859-11] + expected: FAIL + + [name=windows-874 label=iso885911] + expected: FAIL + + [name=windows-874 label=tis-620] + expected: FAIL + + [name=windows-874 label=windows-874] + expected: FAIL + + [name=windows-1250 label=cp1250] + expected: FAIL + + [name=windows-1250 label=windows-1250] + expected: FAIL + + [name=windows-1250 label=x-cp1250] + expected: FAIL + + [name=windows-1251 label=cp1251] + expected: FAIL + + [name=windows-1251 label=windows-1251] + expected: FAIL + + [name=windows-1251 label=x-cp1251] + expected: FAIL + + [name=windows-1252 label=ansi_x3.4-1968] + expected: FAIL + + [name=windows-1252 label=ascii] + expected: FAIL + + [name=windows-1252 label=cp1252] + expected: FAIL + + [name=windows-1252 label=cp819] + expected: FAIL + + [name=windows-1252 label=csisolatin1] + expected: FAIL + + [name=windows-1252 label=ibm819] + expected: FAIL + + [name=windows-1252 label=iso-8859-1] + expected: FAIL + + [name=windows-1252 label=iso-ir-100] + expected: FAIL + + [name=windows-1252 label=iso8859-1] + expected: FAIL + + [name=windows-1252 label=iso88591] + expected: FAIL + + [name=windows-1252 label=iso_8859-1] + expected: FAIL + + [name=windows-1252 label=iso_8859-1:1987] + expected: FAIL + + [name=windows-1252 label=l1] + expected: FAIL + + [name=windows-1252 label=latin1] + expected: FAIL + + [name=windows-1252 label=us-ascii] + expected: FAIL + + [name=windows-1252 label=windows-1252] + expected: FAIL + + [name=windows-1252 label=x-cp1252] + expected: FAIL + + [name=windows-1253 label=cp1253] + expected: FAIL + + [name=windows-1253 label=windows-1253] + expected: FAIL + + [name=windows-1253 label=x-cp1253] + expected: FAIL + + [name=windows-1254 label=cp1254] + expected: FAIL + + [name=windows-1254 label=csisolatin5] + expected: FAIL + + [name=windows-1254 label=iso-8859-9] + expected: FAIL + + [name=windows-1254 label=iso-ir-148] + expected: FAIL + + [name=windows-1254 label=iso8859-9] + expected: FAIL + + [name=windows-1254 label=iso88599] + expected: FAIL + + [name=windows-1254 label=iso_8859-9] + expected: FAIL + + [name=windows-1254 label=iso_8859-9:1989] + expected: FAIL + + [name=windows-1254 label=l5] + expected: FAIL + + [name=windows-1254 label=latin5] + expected: FAIL + + [name=windows-1254 label=windows-1254] + expected: FAIL + + [name=windows-1254 label=x-cp1254] + expected: FAIL + + [name=windows-1255 label=cp1255] + expected: FAIL + + [name=windows-1255 label=windows-1255] + expected: FAIL + + [name=windows-1255 label=x-cp1255] + expected: FAIL + + [name=windows-1256 label=cp1256] + expected: FAIL + + [name=windows-1256 label=windows-1256] + expected: FAIL + + [name=windows-1256 label=x-cp1256] + expected: FAIL + + [name=windows-1257 label=cp1257] + expected: FAIL + + [name=windows-1257 label=windows-1257] + expected: FAIL + + [name=windows-1257 label=x-cp1257] + expected: FAIL + + [name=windows-1258 label=cp1258] + expected: FAIL + + [name=windows-1258 label=windows-1258] + expected: FAIL + + [name=windows-1258 label=x-cp1258] + expected: FAIL + + [name=x-mac-cyrillic label=x-mac-cyrillic] + expected: FAIL + + [name=x-mac-cyrillic label=x-mac-ukrainian] + expected: FAIL + + [name=gbk label=chinese] + expected: FAIL + + [name=gbk label=csgb2312] + expected: FAIL + + [name=gbk label=csiso58gb231280] + expected: FAIL + + [name=gbk label=gb2312] + expected: FAIL + + [name=gbk label=gb_2312] + expected: FAIL + + [name=gbk label=gb_2312-80] + expected: FAIL + + [name=gbk label=gbk] + expected: FAIL + + [name=gbk label=iso-ir-58] + expected: FAIL + + [name=gbk label=x-gbk] + expected: FAIL + + [name=gb18030 label=gb18030] + expected: FAIL + + [name=big5 label=big5] + expected: FAIL + + [name=big5 label=big5-hkscs] + expected: FAIL + + [name=big5 label=cn-big5] + expected: FAIL + + [name=big5 label=csbig5] + expected: FAIL + + [name=big5 label=x-x-big5] + expected: FAIL + + [name=euc-jp label=cseucpkdfmtjapanese] + expected: FAIL + + [name=euc-jp label=euc-jp] + expected: FAIL + + [name=euc-jp label=x-euc-jp] + expected: FAIL + + [name=iso-2022-jp label=csiso2022jp] + expected: FAIL + + [name=iso-2022-jp label=iso-2022-jp] + expected: FAIL + + [name=shift_jis label=csshiftjis] + expected: FAIL + + [name=shift_jis label=ms_kanji] + expected: FAIL + + [name=shift_jis label=shift-jis] + expected: FAIL + + [name=shift_jis label=shift_jis] + expected: FAIL + + [name=shift_jis label=sjis] + expected: FAIL + + [name=shift_jis label=windows-31j] + expected: FAIL + + [name=shift_jis label=x-sjis] + expected: FAIL + + [name=euc-kr label=cseuckr] + expected: FAIL + + [name=euc-kr label=csksc56011987] + expected: FAIL + + [name=euc-kr label=euc-kr] + expected: FAIL + + [name=euc-kr label=iso-ir-149] + expected: FAIL + + [name=euc-kr label=korean] + expected: FAIL + + [name=euc-kr label=ks_c_5601-1987] + expected: FAIL + + [name=euc-kr label=ks_c_5601-1989] + expected: FAIL + + [name=euc-kr label=ksc5601] + expected: FAIL + + [name=euc-kr label=ksc_5601] + expected: FAIL + + [name=euc-kr label=windows-949] + expected: FAIL + + [name=utf-16be label=utf-16be] + expected: FAIL + + [name=utf-16le label=utf-16] + expected: FAIL + + [name=utf-16le label=utf-16le] + expected: FAIL + + [name=x-user-defined label=x-user-defined] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/textdecoder-streaming.html.ini b/tests/wpt/metadata/encoding/textdecoder-streaming.html.ini new file mode 100644 index 00000000000..8f34fafe58b --- /dev/null +++ b/tests/wpt/metadata/encoding/textdecoder-streaming.html.ini @@ -0,0 +1,47 @@ +[textdecoder-streaming.html] + type: testharness + [Streaming decode: utf-8, 1 byte window] + expected: FAIL + + [Streaming decode: utf-8, 2 byte window] + expected: FAIL + + [Streaming decode: utf-8, 3 byte window] + expected: FAIL + + [Streaming decode: utf-8, 4 byte window] + expected: FAIL + + [Streaming decode: utf-8, 5 byte window] + expected: FAIL + + [Streaming decode: utf-16le, 1 byte window] + expected: FAIL + + [Streaming decode: utf-16le, 2 byte window] + expected: FAIL + + [Streaming decode: utf-16le, 3 byte window] + expected: FAIL + + [Streaming decode: utf-16le, 4 byte window] + expected: FAIL + + [Streaming decode: utf-16le, 5 byte window] + expected: FAIL + + [Streaming decode: utf-16be, 1 byte window] + expected: FAIL + + [Streaming decode: utf-16be, 2 byte window] + expected: FAIL + + [Streaming decode: utf-16be, 3 byte window] + expected: FAIL + + [Streaming decode: utf-16be, 4 byte window] + expected: FAIL + + [Streaming decode: utf-16be, 5 byte window] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/textdecoder-utf16-surrogates.html.ini b/tests/wpt/metadata/encoding/textdecoder-utf16-surrogates.html.ini new file mode 100644 index 00000000000..0630043c8c7 --- /dev/null +++ b/tests/wpt/metadata/encoding/textdecoder-utf16-surrogates.html.ini @@ -0,0 +1,32 @@ +[textdecoder-utf16-surrogates.html] + type: testharness + [utf-16le - lone surrogate lead] + expected: FAIL + + [utf-16le - lone surrogate lead (fatal flag set)] + expected: FAIL + + [utf-16le - lone surrogate trail] + expected: FAIL + + [utf-16le - lone surrogate trail (fatal flag set)] + expected: FAIL + + [utf-16le - unmatched surrogate lead] + expected: FAIL + + [utf-16le - unmatched surrogate lead (fatal flag set)] + expected: FAIL + + [utf-16le - unmatched surrogate trail] + expected: FAIL + + [utf-16le - unmatched surrogate trail (fatal flag set)] + expected: FAIL + + [utf-16le - swapped surrogate pair] + expected: FAIL + + [utf-16le - swapped surrogate pair (fatal flag set)] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/textencoder-constructor-non-utf.html.ini b/tests/wpt/metadata/encoding/textencoder-constructor-non-utf.html.ini new file mode 100644 index 00000000000..1af7e7f02b9 --- /dev/null +++ b/tests/wpt/metadata/encoding/textencoder-constructor-non-utf.html.ini @@ -0,0 +1,119 @@ +[textencoder-constructor-non-utf.html] + type: testharness + [UTF encodings are supported for encode and decode: utf-8] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: ibm866] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: iso-8859-2] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: iso-8859-3] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: iso-8859-4] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: iso-8859-5] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: iso-8859-6] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: iso-8859-7] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: iso-8859-8] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: iso-8859-8-i] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: iso-8859-10] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: iso-8859-13] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: iso-8859-14] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: iso-8859-15] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: iso-8859-16] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: koi8-r] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: koi8-u] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: macintosh] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: windows-874] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: windows-1250] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: windows-1251] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: windows-1252] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: windows-1253] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: windows-1254] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: windows-1255] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: windows-1256] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: windows-1257] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: windows-1258] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: x-mac-cyrillic] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: gbk] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: gb18030] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: big5] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: euc-jp] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: iso-2022-jp] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: shift_jis] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: euc-kr] + expected: FAIL + + [UTF encodings are supported for encode and decode: utf-16be] + expected: FAIL + + [UTF encodings are supported for encode and decode: utf-16le] + expected: FAIL + + [Non-UTF encodings supported only for decode, not encode: x-user-defined] + expected: FAIL + diff --git a/tests/wpt/metadata/encoding/textencoder-utf16-surrogates.html.ini b/tests/wpt/metadata/encoding/textencoder-utf16-surrogates.html.ini new file mode 100644 index 00000000000..dd8f98def97 --- /dev/null +++ b/tests/wpt/metadata/encoding/textencoder-utf16-surrogates.html.ini @@ -0,0 +1,19 @@ +[textencoder-utf16-surrogates.html] + type: testharness + [USVString handling: lone surrogate lead] + expected: FAIL + + [USVString handling: lone surrogate trail] + expected: FAIL + + [USVString handling: unmatched surrogate lead] + expected: FAIL + + [USVString handling: unmatched surrogate trail] + expected: FAIL + + [USVString handling: swapped surrogate pair] + expected: FAIL + + [USVString handling: properly encoded MUSICAL SYMBOL G CLEF (U+1D11E)] + expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/history/the-location-interface/security_location_0.sub.htm.ini b/tests/wpt/metadata/html/browsers/history/the-location-interface/security_location_0.sub.htm.ini index 71a53f995de..a09e291d45b 100644 --- a/tests/wpt/metadata/html/browsers/history/the-location-interface/security_location_0.sub.htm.ini +++ b/tests/wpt/metadata/html/browsers/history/the-location-interface/security_location_0.sub.htm.ini @@ -1,3 +1,6 @@ [security_location_0.sub.htm] type: testharness - expected: CRASH + expected: TIMEOUT + [Accessing location object from different origins doesn\'t raise SECURITY_ERR exception] + expected: NOTRUN + diff --git a/tests/wpt/metadata/html/browsers/the-window-object/security-window/window-security.sub.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/security-window/window-security.sub.html.ini index 047d3a00e60..b5a20e9a276 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/security-window/window-security.sub.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/security-window/window-security.sub.html.ini @@ -1,3 +1,6 @@ [window-security.sub.html] type: testharness - expected: CRASH + expected: TIMEOUT + [Window Security testing] + expected: NOTRUN + diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index d1d1be10cf3..9ae1cc788db 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -246,9 +246,6 @@ [Document interface: attribute onstalled] expected: FAIL - [Document interface: attribute onsubmit] - expected: FAIL - [Document interface: attribute onsuspend] expected: FAIL @@ -1386,9 +1383,6 @@ [Document interface: document.implementation.createDocument(null, "", null) must inherit property "onstalled" with the proper type (149)] expected: FAIL - [Document interface: document.implementation.createDocument(null, "", null) must inherit property "onsubmit" with the proper type (150)] - expected: FAIL - [Document interface: document.implementation.createDocument(null, "", null) must inherit property "onsuspend" with the proper type (151)] expected: FAIL @@ -1920,9 +1914,6 @@ [HTMLElement interface: attribute onstalled] expected: FAIL - [HTMLElement interface: attribute onsubmit] - expected: FAIL - [HTMLElement interface: attribute onsuspend] expected: FAIL @@ -2178,9 +2169,6 @@ [HTMLElement interface: document.createElement("noscript") must inherit property "onstalled" with the proper type (88)] expected: FAIL - [HTMLElement interface: document.createElement("noscript") must inherit property "onsubmit" with the proper type (89)] - expected: FAIL - [HTMLElement interface: document.createElement("noscript") must inherit property "onsuspend" with the proper type (90)] expected: FAIL @@ -8241,9 +8229,6 @@ [Window interface: window must inherit property "onstalled" with the proper type (94)] expected: FAIL - [Window interface: window must inherit property "onsubmit" with the proper type (95)] - expected: FAIL - [Window interface: window must inherit property "onsuspend" with the proper type (96)] expected: FAIL @@ -8637,9 +8622,6 @@ [Navigator interface object length] expected: FAIL - [Navigator interface: attribute appVersion] - expected: FAIL - [Navigator interface: attribute language] expected: FAIL @@ -8682,9 +8664,6 @@ [Navigator interface: attribute javaEnabled] expected: FAIL - [Navigator interface: window.navigator must inherit property "appVersion" with the proper type (2)] - expected: FAIL - [Navigator interface: window.navigator must inherit property "language" with the proper type (7)] expected: FAIL @@ -9231,9 +9210,6 @@ [WorkerNavigator interface object length] expected: FAIL - [WorkerNavigator interface: attribute appVersion] - expected: FAIL - [WorkerNavigator interface: attribute language] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/reflection-embedded.html.ini b/tests/wpt/metadata/html/dom/reflection-embedded.html.ini index 9c6292089b1..d08babcf760 100644 --- a/tests/wpt/metadata/html/dom/reflection-embedded.html.ini +++ b/tests/wpt/metadata/html/dom/reflection-embedded.html.ini @@ -441,12 +441,6 @@ [img.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [img.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [img.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [img.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -2013,12 +2007,6 @@ [iframe.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [iframe.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [iframe.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [iframe.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -4401,12 +4389,6 @@ [embed.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [embed.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [embed.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [embed.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -5949,12 +5931,6 @@ [object.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [object.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [object.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [object.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -8895,12 +8871,6 @@ [param.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [param.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [param.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [param.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -10149,12 +10119,6 @@ [video.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [video.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [video.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [video.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -12483,12 +12447,6 @@ [audio.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [audio.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [audio.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [audio.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -14280,12 +14238,6 @@ [source.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [source.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [source.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [source.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -15441,12 +15393,6 @@ [track.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [track.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [track.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [track.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -17055,12 +17001,6 @@ [canvas.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [canvas.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [canvas.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [canvas.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -17817,12 +17757,6 @@ [map.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [map.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [map.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [map.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -18684,12 +18618,6 @@ [area.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [area.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [area.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [area.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/reflection-forms.html.ini b/tests/wpt/metadata/html/dom/reflection-forms.html.ini index 1c16757571f..6215c2315c6 100644 --- a/tests/wpt/metadata/html/dom/reflection-forms.html.ini +++ b/tests/wpt/metadata/html/dom/reflection-forms.html.ini @@ -441,12 +441,6 @@ [form.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [form.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [form.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [form.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -1179,12 +1173,6 @@ [fieldset.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [fieldset.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [fieldset.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [fieldset.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -2046,12 +2034,6 @@ [legend.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [legend.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [legend.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [legend.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -2913,12 +2895,6 @@ [label.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [label.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [label.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [label.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -3780,12 +3756,6 @@ [input.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [input.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [input.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [input.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -7233,12 +7203,6 @@ [button.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [button.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [button.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [button.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -8451,12 +8415,6 @@ [select.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [select.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [select.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [select.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -9828,12 +9786,6 @@ [datalist.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [datalist.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [datalist.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [datalist.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -10566,12 +10518,6 @@ [optgroup.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [optgroup.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [optgroup.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [optgroup.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -11433,12 +11379,6 @@ [option.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [option.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [option.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [option.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -12279,12 +12219,6 @@ [textarea.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [textarea.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [textarea.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [textarea.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -14118,12 +14052,6 @@ [keygen.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [keygen.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [keygen.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [keygen.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -15396,12 +15324,6 @@ [output.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [output.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [output.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [output.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -16263,12 +16185,6 @@ [progress.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [progress.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [progress.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [progress.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -17001,12 +16917,6 @@ [meter.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [meter.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [meter.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [meter.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/reflection-grouping.html.ini b/tests/wpt/metadata/html/dom/reflection-grouping.html.ini index 996d43e1001..cc7a22d6a53 100644 --- a/tests/wpt/metadata/html/dom/reflection-grouping.html.ini +++ b/tests/wpt/metadata/html/dom/reflection-grouping.html.ini @@ -441,12 +441,6 @@ [p.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [p.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [p.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [p.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -1308,12 +1302,6 @@ [hr.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [hr.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [hr.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [hr.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -2670,12 +2658,6 @@ [pre.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [pre.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [pre.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [pre.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -3591,12 +3573,6 @@ [blockquote.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [blockquote.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [blockquote.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [blockquote.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -4494,12 +4470,6 @@ [ol.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [ol.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [ol.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [ol.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -5760,12 +5730,6 @@ [ul.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [ul.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [ul.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [ul.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -6735,12 +6699,6 @@ [li.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [li.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [li.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [li.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -7785,12 +7743,6 @@ [dl.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [dl.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [dl.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [dl.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -8631,12 +8583,6 @@ [dt.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [dt.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [dt.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [dt.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -9369,12 +9315,6 @@ [dd.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [dd.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [dd.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [dd.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -10107,12 +10047,6 @@ [figure.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [figure.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [figure.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [figure.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -10845,12 +10779,6 @@ [figcaption.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [figcaption.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [figcaption.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [figcaption.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -11583,12 +11511,6 @@ [main.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [main.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [main.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [main.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -12321,12 +12243,6 @@ [div.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [div.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [div.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [div.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/reflection-metadata.html.ini b/tests/wpt/metadata/html/dom/reflection-metadata.html.ini index 8d80434519f..d4836ed1e26 100644 --- a/tests/wpt/metadata/html/dom/reflection-metadata.html.ini +++ b/tests/wpt/metadata/html/dom/reflection-metadata.html.ini @@ -426,12 +426,6 @@ [head.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [head.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [head.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [head.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -1149,12 +1143,6 @@ [title.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [title.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [title.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [title.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -1872,12 +1860,6 @@ [base.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [base.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [base.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [base.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -2724,12 +2706,6 @@ [link.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [link.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [link.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [link.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -4161,12 +4137,6 @@ [meta.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [meta.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [meta.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [meta.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -5400,12 +5370,6 @@ [style.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [style.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [style.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [style.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/reflection-misc.html.ini b/tests/wpt/metadata/html/dom/reflection-misc.html.ini index afe976ae17d..d7000629e79 100644 --- a/tests/wpt/metadata/html/dom/reflection-misc.html.ini +++ b/tests/wpt/metadata/html/dom/reflection-misc.html.ini @@ -441,12 +441,6 @@ [html.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [html.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [html.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [html.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -1308,12 +1302,6 @@ [script.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [script.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [script.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [script.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -2739,12 +2727,6 @@ [noscript.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [noscript.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [noscript.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [noscript.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -3477,12 +3459,6 @@ [ins.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [ins.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [ins.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [ins.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -4509,12 +4485,6 @@ [del.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [del.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [del.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [del.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -5541,12 +5511,6 @@ [details.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [details.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [details.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [details.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -6387,12 +6351,6 @@ [summary.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [summary.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [summary.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [summary.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -7125,12 +7083,6 @@ [menu.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [menu.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [menu.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [menu.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -8100,12 +8052,6 @@ [menuitem.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [menuitem.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [menuitem.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [menuitem.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -9846,12 +9792,6 @@ [undefinedelement.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [undefinedelement.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [undefinedelement.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [undefinedelement.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/reflection-obsolete.html.ini b/tests/wpt/metadata/html/dom/reflection-obsolete.html.ini index c4c6de02906..e4c997f9cd2 100644 --- a/tests/wpt/metadata/html/dom/reflection-obsolete.html.ini +++ b/tests/wpt/metadata/html/dom/reflection-obsolete.html.ini @@ -426,12 +426,6 @@ [applet.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [applet.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [applet.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [applet.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -2604,12 +2598,6 @@ [marquee.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [marquee.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [marquee.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [marquee.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -4524,12 +4512,6 @@ [frameset.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [frameset.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [frameset.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [frameset.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -5505,12 +5487,6 @@ [frame.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [frame.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [frame.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [frame.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -7311,12 +7287,6 @@ [dir.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [dir.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [dir.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [dir.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -8142,12 +8112,6 @@ [font.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [font.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [font.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [font.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/reflection-sections.html.ini b/tests/wpt/metadata/html/dom/reflection-sections.html.ini index cc1071c9c12..79ad8fe9bcb 100644 --- a/tests/wpt/metadata/html/dom/reflection-sections.html.ini +++ b/tests/wpt/metadata/html/dom/reflection-sections.html.ini @@ -441,12 +441,6 @@ [body.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [body.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [body.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [body.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -1953,12 +1947,6 @@ [article.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [article.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [article.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [article.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -2691,12 +2679,6 @@ [section.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [section.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [section.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [section.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -3429,12 +3411,6 @@ [nav.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [nav.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [nav.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [nav.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -4167,12 +4143,6 @@ [aside.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [aside.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [aside.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [aside.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -4905,12 +4875,6 @@ [h1.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [h1.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [h1.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [h1.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -5772,12 +5736,6 @@ [h2.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [h2.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [h2.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [h2.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -6639,12 +6597,6 @@ [h3.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [h3.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [h3.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [h3.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -7506,12 +7458,6 @@ [h4.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [h4.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [h4.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [h4.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -8373,12 +8319,6 @@ [h5.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [h5.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [h5.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [h5.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -9240,12 +9180,6 @@ [h6.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [h6.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [h6.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [h6.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -10107,12 +10041,6 @@ [hgroup.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [hgroup.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [hgroup.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [hgroup.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -10845,12 +10773,6 @@ [header.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [header.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [header.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [header.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -11583,12 +11505,6 @@ [footer.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [footer.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [footer.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [footer.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -12321,12 +12237,6 @@ [address.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [address.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [address.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [address.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/reflection-tabular.html.ini b/tests/wpt/metadata/html/dom/reflection-tabular.html.ini index b9a0a55f57a..8c5f2a870bb 100644 --- a/tests/wpt/metadata/html/dom/reflection-tabular.html.ini +++ b/tests/wpt/metadata/html/dom/reflection-tabular.html.ini @@ -441,12 +441,6 @@ [table.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [table.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [table.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [table.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -2448,12 +2442,6 @@ [caption.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [caption.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [caption.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [caption.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -3315,12 +3303,6 @@ [colgroup.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [colgroup.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [colgroup.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [colgroup.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -4872,12 +4854,6 @@ [col.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [col.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [col.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [col.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -6429,12 +6405,6 @@ [tbody.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [tbody.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [tbody.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [tbody.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -7683,12 +7653,6 @@ [thead.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [thead.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [thead.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [thead.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -8937,12 +8901,6 @@ [tfoot.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [tfoot.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [tfoot.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [tfoot.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -10191,12 +10149,6 @@ [tr.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [tr.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [tr.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [tr.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -11574,12 +11526,6 @@ [td.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [td.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [td.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [td.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -13953,12 +13899,6 @@ [th.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [th.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [th.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [th.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/reflection-text.html.ini b/tests/wpt/metadata/html/dom/reflection-text.html.ini index d9971b078af..8be17a80ae1 100644 --- a/tests/wpt/metadata/html/dom/reflection-text.html.ini +++ b/tests/wpt/metadata/html/dom/reflection-text.html.ini @@ -426,12 +426,6 @@ [a.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [a.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [a.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [a.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -2766,12 +2760,6 @@ [em.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [em.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [em.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [em.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -3489,12 +3477,6 @@ [strong.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [strong.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [strong.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [strong.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -4212,12 +4194,6 @@ [small.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [small.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [small.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [small.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -4935,12 +4911,6 @@ [s.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [s.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [s.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [s.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -5658,12 +5628,6 @@ [cite.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [cite.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [cite.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [cite.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -6381,12 +6345,6 @@ [q.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [q.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [q.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [q.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -7269,12 +7227,6 @@ [dfn.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [dfn.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [dfn.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [dfn.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -7992,12 +7944,6 @@ [abbr.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [abbr.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [abbr.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [abbr.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -8715,12 +8661,6 @@ [data.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [data.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [data.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [data.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -9567,12 +9507,6 @@ [time.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [time.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [time.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [time.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -10419,12 +10353,6 @@ [code.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [code.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [code.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [code.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -11142,12 +11070,6 @@ [var.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [var.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [var.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [var.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -11865,12 +11787,6 @@ [samp.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [samp.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [samp.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [samp.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -12588,12 +12504,6 @@ [kbd.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [kbd.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [kbd.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [kbd.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -13311,12 +13221,6 @@ [sub.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [sub.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [sub.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [sub.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -14034,12 +13938,6 @@ [sup.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [sup.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [sup.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [sup.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -14757,12 +14655,6 @@ [i.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [i.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [i.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [i.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -15480,12 +15372,6 @@ [b.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [b.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [b.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [b.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -16203,12 +16089,6 @@ [u.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [u.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [u.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [u.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -16926,12 +16806,6 @@ [mark.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [mark.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [mark.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [mark.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -17649,12 +17523,6 @@ [ruby.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [ruby.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [ruby.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [ruby.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -18372,12 +18240,6 @@ [rt.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [rt.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [rt.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [rt.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -19095,12 +18957,6 @@ [rp.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [rp.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [rp.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [rp.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -19818,12 +19674,6 @@ [bdi.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [bdi.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [bdi.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [bdi.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -20541,12 +20391,6 @@ [bdo.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [bdo.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [bdo.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [bdo.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -21264,12 +21108,6 @@ [span.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [span.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [span.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [span.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -21987,12 +21825,6 @@ [br.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [br.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [br.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [br.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL @@ -22839,12 +22671,6 @@ [wbr.tabIndex: setAttribute() to object "2" followed by IDL get] expected: FAIL - [wbr.tabIndex: setAttribute() to object "3" followed by getAttribute()] - expected: FAIL - - [wbr.tabIndex: setAttribute() to object "3" followed by IDL get] - expected: FAIL - [wbr.tabIndex: IDL set to -36 followed by getAttribute()] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/grouping-content/the-li-element/grouping-li-novalue-MANUAL.html.ini b/tests/wpt/metadata/html/semantics/grouping-content/the-li-element/grouping-li-novalue-MANUAL.html.ini deleted file mode 100644 index 319d725cde6..00000000000 --- a/tests/wpt/metadata/html/semantics/grouping-content/the-li-element/grouping-li-novalue-MANUAL.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[grouping-li-novalue-MANUAL.html] - type: testharness - expected: TIMEOUT diff --git a/tests/wpt/metadata/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002.html.ini b/tests/wpt/metadata/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002.html.ini index 091ee28df85..16889ec471c 100644 --- a/tests/wpt/metadata/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002.html.ini +++ b/tests/wpt/metadata/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002.html.ini @@ -2,4 +2,3 @@ type: reftest reftype: == refurl: /html/semantics/grouping-content/the-li-element/grouping-li-reftest-002-ref.html - expected: PASS diff --git a/tests/wpt/metadata/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-001.html.ini b/tests/wpt/metadata/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-001.html.ini index 0785f9e5b8c..03cf1572183 100644 --- a/tests/wpt/metadata/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-001.html.ini +++ b/tests/wpt/metadata/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-001.html.ini @@ -2,4 +2,3 @@ type: reftest reftype: == refurl: /html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-001-ref.html - expected: PASS diff --git a/tests/wpt/metadata/html/semantics/interactive-elements/the-details-element/details.html.ini b/tests/wpt/metadata/html/semantics/interactive-elements/the-details-element/details.html.ini new file mode 100644 index 00000000000..280f62d750a --- /dev/null +++ b/tests/wpt/metadata/html/semantics/interactive-elements/the-details-element/details.html.ini @@ -0,0 +1,11 @@ +[details.html] + type: testharness + [HTMLDetailsElement should be exposed for prototyping] + expected: FAIL + + [a dynamically created details element should be instanceof HTMLDetailsElement] + expected: FAIL + + [a details element from the parser should be instanceof HTMLDetailsElement] + expected: FAIL + diff --git a/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/script-for-event.html.ini b/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/script-for-event.html.ini deleted file mode 100644 index 8df84bb780e..00000000000 --- a/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/script-for-event.html.ini +++ /dev/null @@ -1,8 +0,0 @@ -[script-for-event.html] - type: testharness - [Script 15] - expected: FAIL - - [Script 16] - 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 index 95f70e89e46..27a1d473162 100644 --- 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 @@ -1,6 +1,5 @@ [079.html] type: testharness - expected: TIMEOUT [ setting location to javascript URL from event handler ] - expected: TIMEOUT + expected: FAIL diff --git a/tests/wpt/metadata/webstorage/builtins.html.ini b/tests/wpt/metadata/webstorage/builtins.html.ini new file mode 100644 index 00000000000..622ef53c3f1 --- /dev/null +++ b/tests/wpt/metadata/webstorage/builtins.html.ini @@ -0,0 +1,8 @@ +[builtins.html] + type: testharness + [Builtins in localStorage] + expected: FAIL + + [Builtins in sessionStorage] + expected: FAIL + diff --git a/tests/wpt/metadata/webstorage/event_local_key.html.ini b/tests/wpt/metadata/webstorage/event_local_key.html.ini deleted file mode 100644 index c5f2de2294c..00000000000 --- a/tests/wpt/metadata/webstorage/event_local_key.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[event_local_key.html] - type: testharness - expected: TIMEOUT - [key property test of local event] - expected: NOTRUN - diff --git a/tests/wpt/metadata/webstorage/event_local_newvalue.html.ini b/tests/wpt/metadata/webstorage/event_local_newvalue.html.ini deleted file mode 100644 index 794820e2cdc..00000000000 --- a/tests/wpt/metadata/webstorage/event_local_newvalue.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[event_local_newvalue.html] - type: testharness - expected: TIMEOUT - [newValue property test of local event] - expected: NOTRUN - diff --git a/tests/wpt/metadata/webstorage/event_local_oldvalue.html.ini b/tests/wpt/metadata/webstorage/event_local_oldvalue.html.ini deleted file mode 100644 index 2da1ccf1006..00000000000 --- a/tests/wpt/metadata/webstorage/event_local_oldvalue.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[event_local_oldvalue.html] - type: testharness - expected: TIMEOUT - [oldValue property test of local event] - expected: NOTRUN - diff --git a/tests/wpt/metadata/webstorage/event_local_storagearea.html.ini b/tests/wpt/metadata/webstorage/event_local_storagearea.html.ini deleted file mode 100644 index b06b363d151..00000000000 --- a/tests/wpt/metadata/webstorage/event_local_storagearea.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[event_local_storagearea.html] - type: testharness - expected: TIMEOUT - [storageArea property test of local event] - expected: NOTRUN - diff --git a/tests/wpt/metadata/webstorage/event_local_url.html.ini b/tests/wpt/metadata/webstorage/event_local_url.html.ini deleted file mode 100644 index 14e10bb843c..00000000000 --- a/tests/wpt/metadata/webstorage/event_local_url.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[event_local_url.html] - type: testharness - expected: TIMEOUT - [url property test of local event] - expected: NOTRUN - diff --git a/tests/wpt/metadata/webstorage/event_session_key.html.ini b/tests/wpt/metadata/webstorage/event_session_key.html.ini deleted file mode 100644 index 3b6f2521ce3..00000000000 --- a/tests/wpt/metadata/webstorage/event_session_key.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[event_session_key.html] - type: testharness - expected: TIMEOUT - [key property test of session event] - expected: NOTRUN - diff --git a/tests/wpt/metadata/webstorage/event_session_newvalue.html.ini b/tests/wpt/metadata/webstorage/event_session_newvalue.html.ini deleted file mode 100644 index a2bb72dd0be..00000000000 --- a/tests/wpt/metadata/webstorage/event_session_newvalue.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[event_session_newvalue.html] - type: testharness - expected: TIMEOUT - [newvalue property test of session event] - expected: NOTRUN - diff --git a/tests/wpt/metadata/webstorage/event_session_oldvalue.html.ini b/tests/wpt/metadata/webstorage/event_session_oldvalue.html.ini deleted file mode 100644 index c48ad25a449..00000000000 --- a/tests/wpt/metadata/webstorage/event_session_oldvalue.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[event_session_oldvalue.html] - type: testharness - expected: TIMEOUT - [oldvalue property test of session event] - expected: NOTRUN - diff --git a/tests/wpt/metadata/webstorage/event_session_storagearea.html.ini b/tests/wpt/metadata/webstorage/event_session_storagearea.html.ini deleted file mode 100644 index cba8ba656e6..00000000000 --- a/tests/wpt/metadata/webstorage/event_session_storagearea.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[event_session_storagearea.html] - type: testharness - expected: TIMEOUT - [storageArea property test of session event] - expected: NOTRUN - diff --git a/tests/wpt/metadata/webstorage/event_session_url.html.ini b/tests/wpt/metadata/webstorage/event_session_url.html.ini deleted file mode 100644 index f227f91c0dd..00000000000 --- a/tests/wpt/metadata/webstorage/event_session_url.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[event_session_url.html] - type: testharness - expected: TIMEOUT - [url property test of session event] - expected: NOTRUN - diff --git a/tests/wpt/metadata/webstorage/in.html.ini b/tests/wpt/metadata/webstorage/in.html.ini new file mode 100644 index 00000000000..87b23736206 --- /dev/null +++ b/tests/wpt/metadata/webstorage/in.html.ini @@ -0,0 +1,8 @@ +[in.html] + type: testharness + [The in operator in localStorage: method access] + expected: FAIL + + [The in operator in sessionStorage: method access] + expected: FAIL + diff --git a/tests/wpt/metadata/webstorage/indexing.html.ini b/tests/wpt/metadata/webstorage/indexing.html.ini new file mode 100644 index 00000000000..2dd7cd8d2b7 --- /dev/null +++ b/tests/wpt/metadata/webstorage/indexing.html.ini @@ -0,0 +1,8 @@ +[indexing.html] + type: testharness + [Getting existing number-valued properties on localStorage] + expected: FAIL + + [Getting existing number-valued properties on sessionStorage] + expected: FAIL + diff --git a/tests/wpt/metadata/webstorage/setitem.html.ini b/tests/wpt/metadata/webstorage/setitem.html.ini new file mode 100644 index 00000000000..ee5058c4723 --- /dev/null +++ b/tests/wpt/metadata/webstorage/setitem.html.ini @@ -0,0 +1,32 @@ +[setitem.html] + type: testharness + [localStorage[\] = null] + expected: FAIL + + [localStorage.setItem(_, undefined)] + expected: FAIL + + [localStorage[\] = undefined] + expected: FAIL + + [localStorage.setItem({ throws })] + expected: FAIL + + [localStorage[\] = { throws }] + expected: FAIL + + [sessionStorage[\] = null] + expected: FAIL + + [sessionStorage.setItem(_, undefined)] + expected: FAIL + + [sessionStorage[\] = undefined] + expected: FAIL + + [sessionStorage.setItem({ throws })] + expected: FAIL + + [sessionStorage[\] = { throws }] + expected: FAIL + diff --git a/tests/wpt/metadata/webstorage/storage_local_builtins.html.ini b/tests/wpt/metadata/webstorage/storage_local_builtins.html.ini deleted file mode 100644 index 592d6a2bc56..00000000000 --- a/tests/wpt/metadata/webstorage/storage_local_builtins.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[storage_local_builtins.html] - type: testharness - [Web Storage] - expected: FAIL - diff --git a/tests/wpt/metadata/webstorage/storage_local_in_js.html.ini b/tests/wpt/metadata/webstorage/storage_local_in_js.html.ini deleted file mode 100644 index 1e7897cf54b..00000000000 --- a/tests/wpt/metadata/webstorage/storage_local_in_js.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[storage_local_in_js.html] - type: testharness - [Web Storage 1] - expected: FAIL - diff --git a/tests/wpt/metadata/webstorage/storage_local_index_js.html.ini b/tests/wpt/metadata/webstorage/storage_local_index_js.html.ini deleted file mode 100644 index c9f3ef045ca..00000000000 --- a/tests/wpt/metadata/webstorage/storage_local_index_js.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[storage_local_index_js.html] - type: testharness - [Web Storage 3] - expected: FAIL - diff --git a/tests/wpt/metadata/webstorage/storage_local_setitem_js.html.ini b/tests/wpt/metadata/webstorage/storage_local_setitem_js.html.ini deleted file mode 100644 index f2117303cc4..00000000000 --- a/tests/wpt/metadata/webstorage/storage_local_setitem_js.html.ini +++ /dev/null @@ -1,20 +0,0 @@ -[storage_local_setitem_js.html] - type: testharness - [Web Storage 4] - expected: FAIL - - [Web Storage 6] - expected: FAIL - - [Web Storage 7] - expected: FAIL - - [Web Storage 8] - expected: FAIL - - [Web Storage 9] - expected: FAIL - - [Web Storage 10] - expected: FAIL - diff --git a/tests/wpt/metadata/webstorage/storage_session_builtins.html.ini b/tests/wpt/metadata/webstorage/storage_session_builtins.html.ini deleted file mode 100644 index 2f37223fd76..00000000000 --- a/tests/wpt/metadata/webstorage/storage_session_builtins.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[storage_session_builtins.html] - type: testharness - [Web Storage] - expected: FAIL - diff --git a/tests/wpt/metadata/webstorage/storage_session_in_js.html.ini b/tests/wpt/metadata/webstorage/storage_session_in_js.html.ini deleted file mode 100644 index 9f51d1c2155..00000000000 --- a/tests/wpt/metadata/webstorage/storage_session_in_js.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[storage_session_in_js.html] - type: testharness - [Web Storage 1] - expected: FAIL - diff --git a/tests/wpt/metadata/webstorage/storage_session_index_js.html.ini b/tests/wpt/metadata/webstorage/storage_session_index_js.html.ini deleted file mode 100644 index 3493e816e5a..00000000000 --- a/tests/wpt/metadata/webstorage/storage_session_index_js.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[storage_session_index_js.html] - type: testharness - [Web Storage 3] - expected: FAIL - diff --git a/tests/wpt/metadata/webstorage/storage_session_setitem_js.html.ini b/tests/wpt/metadata/webstorage/storage_session_setitem_js.html.ini deleted file mode 100644 index d28f5207ae3..00000000000 --- a/tests/wpt/metadata/webstorage/storage_session_setitem_js.html.ini +++ /dev/null @@ -1,20 +0,0 @@ -[storage_session_setitem_js.html] - type: testharness - [Web Storage 4] - expected: FAIL - - [Web Storage 6] - expected: FAIL - - [Web Storage 7] - expected: FAIL - - [Web Storage 8] - expected: FAIL - - [Web Storage 9] - expected: FAIL - - [Web Storage 10] - expected: FAIL - diff --git a/tests/wpt/metadata/workers/interfaces.worker.js.ini b/tests/wpt/metadata/workers/interfaces.worker.js.ini index 03f07afd004..97bda445b76 100644 --- a/tests/wpt/metadata/workers/interfaces.worker.js.ini +++ b/tests/wpt/metadata/workers/interfaces.worker.js.ini @@ -81,9 +81,6 @@ [WorkerNavigator interface object length] expected: FAIL - [WorkerNavigator interface: attribute appVersion] - expected: FAIL - [WorkerNavigator interface: attribute language] expected: FAIL @@ -93,9 +90,6 @@ [WorkerNavigator interface: attribute onLine] expected: FAIL - [WorkerNavigator interface: self.navigator must inherit property "appVersion" with the proper type (2)] - expected: FAIL - [WorkerNavigator interface: self.navigator must inherit property "language" with the proper type (7)] expected: FAIL diff --git a/tests/wpt/metadata/workers/interfaces/WorkerUtils/importScripts/004.html.ini b/tests/wpt/metadata/workers/interfaces/WorkerUtils/importScripts/004.html.ini index dc00ad0dfe0..fd8412fca70 100644 --- a/tests/wpt/metadata/workers/interfaces/WorkerUtils/importScripts/004.html.ini +++ b/tests/wpt/metadata/workers/interfaces/WorkerUtils/importScripts/004.html.ini @@ -1,7 +1,3 @@ [004.html] type: testharness - expected: TIMEOUT disabled: flaky crash detection - [importScripts broken script] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/workers/interfaces/WorkerUtils/importScripts/005.html.ini b/tests/wpt/metadata/workers/interfaces/WorkerUtils/importScripts/005.html.ini index 4186b89c589..7948040e5af 100644 --- a/tests/wpt/metadata/workers/interfaces/WorkerUtils/importScripts/005.html.ini +++ b/tests/wpt/metadata/workers/interfaces/WorkerUtils/importScripts/005.html.ini @@ -1,7 +1,3 @@ [005.html] type: testharness - expected: TIMEOUT disabled: flaky crash detection - [importScripts separate scripts] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/workers/interfaces/WorkerUtils/importScripts/006.html.ini b/tests/wpt/metadata/workers/interfaces/WorkerUtils/importScripts/006.html.ini index 11fe3bedc0d..6b4db8ef574 100644 --- a/tests/wpt/metadata/workers/interfaces/WorkerUtils/importScripts/006.html.ini +++ b/tests/wpt/metadata/workers/interfaces/WorkerUtils/importScripts/006.html.ini @@ -1,7 +1,3 @@ [006.html] type: testharness - expected: TIMEOUT disabled: flaky crash detection - [importScripts uncaught exception] - expected: TIMEOUT - diff --git a/tests/wpt/run.sh b/tests/wpt/run.sh index b2ee80395f0..a773aec35b9 100755 --- a/tests/wpt/run.sh +++ b/tests/wpt/run.sh @@ -23,7 +23,7 @@ source $wpt_root/_virtualenv/bin/activate if [[ $* == *--update-manifest* ]]; then (python -c "import html5lib" &>/dev/null) || pip install html5lib fi -(python -c "import wptrunner" &>/dev/null) || pip install 'wptrunner==1.13' +(python -c "import wptrunner" &>/dev/null) || pip install 'wptrunner==1.14' python $wpt_root/run.py \ --config $wpt_root/config.ini \ diff --git a/tests/wpt/web-platform-tests b/tests/wpt/web-platform-tests -Subproject 56db12eee9711048ea4c927a89b9e9e05fd97c1 +Subproject 29dfb8944e535d439ca94cf7d1b1d9138a8ad11 |