aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/compositing/compositor.rs68
-rw-r--r--components/compositing/compositor_task.rs3
-rw-r--r--components/compositing/constellation.rs75
-rw-r--r--components/compositing/headless.rs1
-rw-r--r--components/compositing/lib.rs1
-rw-r--r--components/compositing/pipeline.rs11
-rw-r--r--components/gfx/Cargo.toml3
-rw-r--r--components/gfx/font_cache_task.rs15
-rw-r--r--components/gfx/font_context.rs80
-rw-r--r--components/gfx/font_template.rs10
-rw-r--r--components/gfx/lib.rs1
-rw-r--r--components/gfx/paint_context.rs2
-rw-r--r--components/gfx/paint_task.rs10
-rw-r--r--components/gfx/text/glyph.rs46
-rw-r--r--components/layout/Cargo.toml4
-rw-r--r--components/layout/animation.rs104
-rw-r--r--components/layout/block.rs12
-rw-r--r--components/layout/construct.rs31
-rw-r--r--components/layout/context.rs22
-rw-r--r--components/layout/css/matching.rs90
-rw-r--r--components/layout/floats.rs2
-rw-r--r--components/layout/flow.rs24
-rw-r--r--components/layout/flow_list.rs6
-rw-r--r--components/layout/fragment.rs6
-rw-r--r--components/layout/inline.rs10
-rw-r--r--components/layout/layout_task.rs353
-rw-r--r--components/layout/lib.rs39
-rw-r--r--components/layout/parallel.rs2
-rw-r--r--components/layout/traversal.rs5
-rw-r--r--components/layout/wrapper.rs27
-rw-r--r--components/layout_traits/lib.rs1
-rw-r--r--components/msg/compositor_msg.rs4
-rw-r--r--components/msg/constellation_msg.rs12
-rw-r--r--components/msg/lib.rs2
-rw-r--r--components/net/cookie.rs25
-rw-r--r--components/net/image_cache_task.rs94
-rw-r--r--components/net/storage_task.rs35
-rw-r--r--components/profile/lib.rs1
-rw-r--r--components/profile/mem.rs51
-rw-r--r--components/script/cors.rs6
-rw-r--r--components/script/devtools.rs4
-rw-r--r--components/script/dom/attr.rs46
-rw-r--r--components/script/dom/bindings/js.rs7
-rw-r--r--components/script/dom/bindings/str.rs2
-rw-r--r--components/script/dom/bindings/trace.rs136
-rw-r--r--components/script/dom/canvasgradient.rs2
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs14
-rw-r--r--components/script/dom/cssstyledeclaration.rs81
-rw-r--r--components/script/dom/document.rs2
-rw-r--r--components/script/dom/domimplementation.rs2
-rw-r--r--components/script/dom/domrectlist.rs8
-rw-r--r--components/script/dom/domtokenlist.rs8
-rw-r--r--components/script/dom/element.rs62
-rw-r--r--components/script/dom/eventdispatcher.rs21
-rw-r--r--components/script/dom/htmlcollection.rs14
-rw-r--r--components/script/dom/htmlelement.rs8
-rw-r--r--components/script/dom/htmlscriptelement.rs35
-rw-r--r--components/script/dom/keyboardevent.rs4
-rw-r--r--components/script/dom/macros.rs1
-rw-r--r--components/script/dom/mod.rs1
-rw-r--r--components/script/dom/navigator.rs4
-rw-r--r--components/script/dom/navigatorinfo.rs4
-rw-r--r--components/script/dom/node.rs18
-rw-r--r--components/script/dom/nodelist.rs3
-rw-r--r--components/script/dom/storage.rs98
-rw-r--r--components/script/dom/textencoder.rs94
-rw-r--r--components/script/dom/treewalker.rs12
-rw-r--r--components/script/dom/uievent.rs3
-rw-r--r--components/script/dom/urlsearchparams.rs9
-rw-r--r--components/script/dom/validitystate.rs1
-rw-r--r--components/script/dom/webidls/CSSStyleDeclaration.webidl6
-rw-r--r--components/script/dom/webidls/CanvasRenderingContext2D.webidl1
-rw-r--r--components/script/dom/webidls/EventHandler.webidl1
-rw-r--r--components/script/dom/webidls/Navigator.webidl2
-rw-r--r--components/script/dom/webidls/TextEncoder.webidl12
-rw-r--r--components/script/dom/websocket.rs2
-rw-r--r--components/script/dom/window.rs28
-rw-r--r--components/script/dom/worker.rs1
-rw-r--r--components/script/dom/workerglobalscope.rs5
-rw-r--r--components/script/dom/workerlocation.rs1
-rw-r--r--components/script/dom/workernavigator.rs5
-rw-r--r--components/script/layout_interface.rs50
-rw-r--r--components/script/parse/html.rs4
-rw-r--r--components/script/script_task.rs37
-rw-r--r--components/script/textinput.rs36
-rw-r--r--components/script_traits/lib.rs2
-rw-r--r--components/servo/Cargo.lock11
-rw-r--r--components/servo/lib.rs6
-rw-r--r--components/style/animation.rs221
-rw-r--r--components/style/font_face.rs28
-rw-r--r--components/style/lib.rs1
-rw-r--r--components/style/parser.rs1
-rw-r--r--components/style/properties.mako.rs545
-rw-r--r--components/style/stylesheets.rs4
-rw-r--r--components/style/values.rs52
-rw-r--r--components/util/bezier.rs116
-rw-r--r--components/util/cache.rs2
-rw-r--r--components/util/debug_utils.rs3
-rw-r--r--components/util/lib.rs3
-rw-r--r--components/util/opts.rs6
-rw-r--r--components/util/range.rs24
-rw-r--r--ports/cef/Cargo.lock11
-rw-r--r--ports/gonk/Cargo.lock13
-rw-r--r--ports/gonk/build.rs11
-rw-r--r--ports/gonk/src/input.rs4
-rw-r--r--ports/gonk/src/lib.rs96
-rw-r--r--ports/gonk/src/main.rs5
-rw-r--r--ports/gonk/src/window.rs34
-rw-r--r--python/servo/post_build_commands.py2
-rw-r--r--python/tidy.py3
-rw-r--r--resources/rippy.jpgbin0 -> 35425 bytes
-rw-r--r--support/rust-task_info/src/task_basic_info.rs32
-rw-r--r--support/rust-task_info/src/task_info.c4
-rw-r--r--tests/content/test_interfaces.html1
-rw-r--r--tests/content/test_navigator.html1
-rw-r--r--tests/contenttest.rs46
-rw-r--r--tests/html/transition_all.html29
-rw-r--r--tests/html/transition_multiple.html28
-rw-r--r--tests/html/transition_simple.html96
-rw-r--r--tests/ref/basic.list1
-rw-r--r--tests/ref/no-image-ref.html1
-rw-r--r--tests/ref/no-image.html1
-rw-r--r--tests/ref/rippy.jpgbin0 -> 35425 bytes
-rw-r--r--tests/wpt/include.ini2
-rw-r--r--tests/wpt/metadata/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.html.ini2
-rw-r--r--tests/wpt/metadata/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.html.ini2
-rw-r--r--tests/wpt/metadata/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.html.ini2
-rw-r--r--tests/wpt/metadata/2dcontext/path-objects/2d.path.arc.negative.html.ini5
-rw-r--r--tests/wpt/metadata/DOMEvents/constructors.html.ini3
-rw-r--r--tests/wpt/metadata/DOMEvents/tests/approved/EventListener.dispatch.new.event.html.ini5
-rw-r--r--tests/wpt/metadata/FileAPI/FileReader/Progress_event_bubbles_cancelable.html.ini5
-rw-r--r--tests/wpt/metadata/MANIFEST.json731
-rw-r--r--tests/wpt/metadata/XMLHttpRequest/open-during-abort.htm.ini5
-rw-r--r--tests/wpt/metadata/dom/events/Event-dispatch-reenter.html.ini5
-rw-r--r--tests/wpt/metadata/encoding/api-basics.html.ini20
-rw-r--r--tests/wpt/metadata/encoding/api-replacement-encodings.html.ini20
-rw-r--r--tests/wpt/metadata/encoding/api-surrogates-utf8.html.ini20
-rw-r--r--tests/wpt/metadata/encoding/gb18030-encoder.html.ini20
-rw-r--r--tests/wpt/metadata/encoding/gbk-encoder.html.ini20
-rw-r--r--tests/wpt/metadata/encoding/idlharness.html.ini52
-rw-r--r--tests/wpt/metadata/encoding/iso-2022-jp-decoder.html.ini104
-rw-r--r--tests/wpt/metadata/encoding/iso-2022-jp-encoder.html.ini11
-rw-r--r--tests/wpt/metadata/encoding/single-byte-decoder.html.ini3
-rw-r--r--tests/wpt/metadata/encoding/textdecoder-byte-order-marks.html.ini11
-rw-r--r--tests/wpt/metadata/encoding/textdecoder-fatal-streaming.html.ini8
-rw-r--r--tests/wpt/metadata/encoding/textdecoder-fatal.html.ini107
-rw-r--r--tests/wpt/metadata/encoding/textdecoder-ignorebom.html.ini14
-rw-r--r--tests/wpt/metadata/encoding/textdecoder-labels.html.ini635
-rw-r--r--tests/wpt/metadata/encoding/textdecoder-streaming.html.ini47
-rw-r--r--tests/wpt/metadata/encoding/textdecoder-utf16-surrogates.html.ini32
-rw-r--r--tests/wpt/metadata/encoding/textencoder-constructor-non-utf.html.ini119
-rw-r--r--tests/wpt/metadata/encoding/textencoder-utf16-surrogates.html.ini19
-rw-r--r--tests/wpt/metadata/html/browsers/history/the-location-interface/security_location_0.sub.htm.ini5
-rw-r--r--tests/wpt/metadata/html/browsers/the-window-object/security-window/window-security.sub.html.ini5
-rw-r--r--tests/wpt/metadata/html/dom/interfaces.html.ini24
-rw-r--r--tests/wpt/metadata/html/dom/reflection-embedded.html.ini72
-rw-r--r--tests/wpt/metadata/html/dom/reflection-forms.html.ini90
-rw-r--r--tests/wpt/metadata/html/dom/reflection-grouping.html.ini84
-rw-r--r--tests/wpt/metadata/html/dom/reflection-metadata.html.ini36
-rw-r--r--tests/wpt/metadata/html/dom/reflection-misc.html.ini60
-rw-r--r--tests/wpt/metadata/html/dom/reflection-obsolete.html.ini36
-rw-r--r--tests/wpt/metadata/html/dom/reflection-sections.html.ini90
-rw-r--r--tests/wpt/metadata/html/dom/reflection-tabular.html.ini60
-rw-r--r--tests/wpt/metadata/html/dom/reflection-text.html.ini174
-rw-r--r--tests/wpt/metadata/html/semantics/grouping-content/the-li-element/grouping-li-novalue-MANUAL.html.ini3
-rw-r--r--tests/wpt/metadata/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002.html.ini1
-rw-r--r--tests/wpt/metadata/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-001.html.ini1
-rw-r--r--tests/wpt/metadata/html/semantics/interactive-elements/the-details-element/details.html.ini11
-rw-r--r--tests/wpt/metadata/html/semantics/scripting-1/the-script-element/script-for-event.html.ini8
-rw-r--r--tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/079.html.ini3
-rw-r--r--tests/wpt/metadata/webstorage/builtins.html.ini8
-rw-r--r--tests/wpt/metadata/webstorage/event_local_key.html.ini6
-rw-r--r--tests/wpt/metadata/webstorage/event_local_newvalue.html.ini6
-rw-r--r--tests/wpt/metadata/webstorage/event_local_oldvalue.html.ini6
-rw-r--r--tests/wpt/metadata/webstorage/event_local_storagearea.html.ini6
-rw-r--r--tests/wpt/metadata/webstorage/event_local_url.html.ini6
-rw-r--r--tests/wpt/metadata/webstorage/event_session_key.html.ini6
-rw-r--r--tests/wpt/metadata/webstorage/event_session_newvalue.html.ini6
-rw-r--r--tests/wpt/metadata/webstorage/event_session_oldvalue.html.ini6
-rw-r--r--tests/wpt/metadata/webstorage/event_session_storagearea.html.ini6
-rw-r--r--tests/wpt/metadata/webstorage/event_session_url.html.ini6
-rw-r--r--tests/wpt/metadata/webstorage/in.html.ini8
-rw-r--r--tests/wpt/metadata/webstorage/indexing.html.ini8
-rw-r--r--tests/wpt/metadata/webstorage/setitem.html.ini32
-rw-r--r--tests/wpt/metadata/webstorage/storage_local_builtins.html.ini5
-rw-r--r--tests/wpt/metadata/webstorage/storage_local_in_js.html.ini5
-rw-r--r--tests/wpt/metadata/webstorage/storage_local_index_js.html.ini5
-rw-r--r--tests/wpt/metadata/webstorage/storage_local_setitem_js.html.ini20
-rw-r--r--tests/wpt/metadata/webstorage/storage_session_builtins.html.ini5
-rw-r--r--tests/wpt/metadata/webstorage/storage_session_in_js.html.ini5
-rw-r--r--tests/wpt/metadata/webstorage/storage_session_index_js.html.ini5
-rw-r--r--tests/wpt/metadata/webstorage/storage_session_setitem_js.html.ini20
-rw-r--r--tests/wpt/metadata/workers/interfaces.worker.js.ini6
-rw-r--r--tests/wpt/metadata/workers/interfaces/WorkerUtils/importScripts/004.html.ini4
-rw-r--r--tests/wpt/metadata/workers/interfaces/WorkerUtils/importScripts/005.html.ini4
-rw-r--r--tests/wpt/metadata/workers/interfaces/WorkerUtils/importScripts/006.html.ini4
-rwxr-xr-xtests/wpt/run.sh2
m---------tests/wpt/web-platform-tests0
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
new file mode 100644
index 00000000000..a94649ae3f2
--- /dev/null
+++ b/resources/rippy.jpg
Binary files differ
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
new file mode 100644
index 00000000000..a94649ae3f2
--- /dev/null
+++ b/tests/ref/rippy.jpg
Binary files differ
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