diff options
69 files changed, 1344 insertions, 449 deletions
diff --git a/Cargo.lock b/Cargo.lock index 2df4f2e8410..6ba344522cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -713,9 +713,9 @@ checksum = "28346c117b50270785fbc123bd6e4ecad20d0c6d5f43d081dc80a3abcc62be64" [[package]] name = "bytemuck" -version = "1.22.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" +checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c" dependencies = [ "bytemuck_derive", ] @@ -910,9 +910,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ "android-tzdata", "iana-time-zone", @@ -1074,7 +1074,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] @@ -3430,7 +3430,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.58.0", + "windows-core 0.57.0", ] [[package]] @@ -4252,7 +4252,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -6466,7 +6466,7 @@ dependencies = [ [[package]] name = "selectors" version = "0.27.0" -source = "git+https://github.com/servo/stylo?branch=2025-03-15#0eaeea3dfd4aa0415529700353075ad1e1e47e5b" +source = "git+https://github.com/servo/stylo?branch=2025-03-15#03ffc85c45f53a3b11994f7c14adce7b90aa9c34" dependencies = [ "bitflags 2.9.0", "cssparser", @@ -6760,8 +6760,8 @@ dependencies = [ [[package]] name = "servo_arc" -version = "0.4.0" -source = "git+https://github.com/servo/stylo?branch=2025-03-15#0eaeea3dfd4aa0415529700353075ad1e1e47e5b" +version = "0.4.1" +source = "git+https://github.com/servo/stylo?branch=2025-03-15#03ffc85c45f53a3b11994f7c14adce7b90aa9c34" dependencies = [ "serde", "stable_deref_trait", @@ -7221,7 +7221,7 @@ dependencies = [ [[package]] name = "stylo" version = "0.2.1" -source = "git+https://github.com/servo/stylo?branch=2025-03-15#0eaeea3dfd4aa0415529700353075ad1e1e47e5b" +source = "git+https://github.com/servo/stylo?branch=2025-03-15#03ffc85c45f53a3b11994f7c14adce7b90aa9c34" dependencies = [ "app_units", "arrayvec", @@ -7240,7 +7240,6 @@ dependencies = [ "lazy_static", "log", "malloc_size_of_derive", - "markup5ever", "matches", "mime", "new_debug_unreachable", @@ -7274,12 +7273,13 @@ dependencies = [ "url", "void", "walkdir", + "web_atoms", ] [[package]] name = "stylo_atoms" version = "0.2.0" -source = "git+https://github.com/servo/stylo?branch=2025-03-15#0eaeea3dfd4aa0415529700353075ad1e1e47e5b" +source = "git+https://github.com/servo/stylo?branch=2025-03-15#03ffc85c45f53a3b11994f7c14adce7b90aa9c34" dependencies = [ "string_cache", "string_cache_codegen", @@ -7288,12 +7288,12 @@ dependencies = [ [[package]] name = "stylo_config" version = "0.2.0" -source = "git+https://github.com/servo/stylo?branch=2025-03-15#0eaeea3dfd4aa0415529700353075ad1e1e47e5b" +source = "git+https://github.com/servo/stylo?branch=2025-03-15#03ffc85c45f53a3b11994f7c14adce7b90aa9c34" [[package]] name = "stylo_derive" version = "0.2.0" -source = "git+https://github.com/servo/stylo?branch=2025-03-15#0eaeea3dfd4aa0415529700353075ad1e1e47e5b" +source = "git+https://github.com/servo/stylo?branch=2025-03-15#03ffc85c45f53a3b11994f7c14adce7b90aa9c34" dependencies = [ "darling", "proc-macro2", @@ -7305,7 +7305,7 @@ dependencies = [ [[package]] name = "stylo_dom" version = "0.2.0" -source = "git+https://github.com/servo/stylo?branch=2025-03-15#0eaeea3dfd4aa0415529700353075ad1e1e47e5b" +source = "git+https://github.com/servo/stylo?branch=2025-03-15#03ffc85c45f53a3b11994f7c14adce7b90aa9c34" dependencies = [ "bitflags 2.9.0", "stylo_malloc_size_of", @@ -7314,7 +7314,7 @@ dependencies = [ [[package]] name = "stylo_malloc_size_of" version = "0.2.0" -source = "git+https://github.com/servo/stylo?branch=2025-03-15#0eaeea3dfd4aa0415529700353075ad1e1e47e5b" +source = "git+https://github.com/servo/stylo?branch=2025-03-15#03ffc85c45f53a3b11994f7c14adce7b90aa9c34" dependencies = [ "app_units", "cssparser", @@ -7331,12 +7331,12 @@ dependencies = [ [[package]] name = "stylo_static_prefs" version = "0.2.0" -source = "git+https://github.com/servo/stylo?branch=2025-03-15#0eaeea3dfd4aa0415529700353075ad1e1e47e5b" +source = "git+https://github.com/servo/stylo?branch=2025-03-15#03ffc85c45f53a3b11994f7c14adce7b90aa9c34" [[package]] name = "stylo_traits" version = "0.2.0" -source = "git+https://github.com/servo/stylo?branch=2025-03-15#0eaeea3dfd4aa0415529700353075ad1e1e47e5b" +source = "git+https://github.com/servo/stylo?branch=2025-03-15#03ffc85c45f53a3b11994f7c14adce7b90aa9c34" dependencies = [ "app_units", "bitflags 2.9.0", @@ -7719,7 +7719,7 @@ dependencies = [ [[package]] name = "to_shmem" version = "0.2.0" -source = "git+https://github.com/servo/stylo?branch=2025-03-15#0eaeea3dfd4aa0415529700353075ad1e1e47e5b" +source = "git+https://github.com/servo/stylo?branch=2025-03-15#03ffc85c45f53a3b11994f7c14adce7b90aa9c34" dependencies = [ "cssparser", "servo_arc", @@ -7732,7 +7732,7 @@ dependencies = [ [[package]] name = "to_shmem_derive" version = "0.1.0" -source = "git+https://github.com/servo/stylo?branch=2025-03-15#0eaeea3dfd4aa0415529700353075ad1e1e47e5b" +source = "git+https://github.com/servo/stylo?branch=2025-03-15#03ffc85c45f53a3b11994f7c14adce7b90aa9c34" dependencies = [ "darling", "proc-macro2", @@ -7834,9 +7834,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.25" +version = "0.22.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10558ed0bd2a1562e630926a2d1f0b98c827da99fabd3fe20920a59642504485" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" dependencies = [ "indexmap", "serde", @@ -8287,9 +8287,9 @@ checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" [[package]] name = "wayland-backend" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7208998eaa3870dad37ec8836979581506e0c5c64c20c9e79e9d2a10d6f47bf" +checksum = "c2bea670be0e24795f39416e5461ccef0185b47df2749ed2b226b8a7557ac871" dependencies = [ "cc", "downcast-rs", @@ -8527,9 +8527,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.8" +version = "0.26.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" +checksum = "29aad86cec885cafd03e8305fd727c418e970a521322c91688414d5b8efba16b" dependencies = [ "rustls-pki-types", ] @@ -8785,7 +8785,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index 99d6273813e..2667b7f6b44 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -28,6 +28,10 @@ use webrender_api::{ImageDescriptor, ImageDescriptorFlags, ImageFormat, ImageKey use crate::raqote_backend::Repetition; +// Asserts on WR texture cache update for zero sized image with raw data. +// https://github.com/servo/webrender/blob/main/webrender/src/texture_cache.rs#L1475 +const MIN_WR_IMAGE_SIZE: Size2D<u64> = Size2D::new(1, 1); + fn to_path(path: &[PathSegment], mut builder: Box<dyn GenericPathBuilder>) -> Path { let mut build_ref = PathBuilderRef { builder: &mut builder, @@ -595,6 +599,7 @@ impl<'a> CanvasData<'a> { compositor_api: CrossProcessCompositorApi, font_context: Arc<FontContext>, ) -> CanvasData<'a> { + let size = size.max(MIN_WR_IMAGE_SIZE); let backend = create_backend(); let draw_target = backend.create_drawtarget(size); let image_key = compositor_api.generate_image_key().unwrap(); @@ -1402,7 +1407,9 @@ impl<'a> CanvasData<'a> { } pub fn recreate(&mut self, size: Option<Size2D<u64>>) { - let size = size.unwrap_or_else(|| self.drawtarget.get_size().to_u64()); + let size = size + .unwrap_or_else(|| self.drawtarget.get_size().to_u64()) + .max(MIN_WR_IMAGE_SIZE); self.drawtarget = self .backend .create_drawtarget(Size2D::new(size.width, size.height)); diff --git a/components/devtools/actors/watcher.rs b/components/devtools/actors/watcher.rs index 6a84499b6dd..b0b2c755fd8 100644 --- a/components/devtools/actors/watcher.rs +++ b/components/devtools/actors/watcher.rs @@ -20,8 +20,10 @@ use serde_json::{Map, Value}; use self::network_parent::{NetworkParentActor, NetworkParentActorMsg}; use super::thread::ThreadActor; +use super::worker::WorkerMsg; use crate::actor::{Actor, ActorMessageStatus, ActorRegistry}; use crate::actors::browsing_context::{BrowsingContextActor, BrowsingContextActorMsg}; +use crate::actors::root::RootActor; use crate::actors::watcher::target_configuration::{ TargetConfigurationActor, TargetConfigurationActorMsg, }; @@ -29,8 +31,8 @@ use crate::actors::watcher::thread_configuration::{ ThreadConfigurationActor, ThreadConfigurationActorMsg, }; use crate::protocol::JsonPacketStream; -use crate::resource::ResourceAvailable; -use crate::{EmptyReplyMsg, StreamId}; +use crate::resource::{ResourceAvailable, ResourceAvailableReply}; +use crate::{EmptyReplyMsg, StreamId, WorkerActor}; pub mod network_parent; pub mod target_configuration; @@ -55,7 +57,7 @@ impl SessionContext { supported_targets: HashMap::from([ ("frame", true), ("process", false), - ("worker", false), + ("worker", true), ("service_worker", false), ("shared_worker", false), ]), @@ -103,11 +105,18 @@ pub enum SessionContextType { } #[derive(Serialize)] +#[serde(untagged)] +enum TargetActorMsg { + BrowsingContext(BrowsingContextActorMsg), + Worker(WorkerMsg), +} + +#[derive(Serialize)] struct WatchTargetsReply { from: String, #[serde(rename = "type")] type_: String, - target: BrowsingContextActorMsg, + target: TargetActorMsg, } #[derive(Serialize)] @@ -212,16 +221,38 @@ impl Actor for WatcherActor { _id: StreamId, ) -> Result<ActorMessageStatus, ()> { let target = registry.find::<BrowsingContextActor>(&self.browsing_context_actor); + let root = registry.find::<RootActor>("root"); Ok(match msg_type { "watchTargets" => { - let msg = WatchTargetsReply { - from: self.name(), - type_: "target-available-form".into(), - target: target.encodable(), - }; - let _ = stream.write_json_packet(&msg); + // As per logs we either get targetType as "frame" or "worker" + let target_type = msg + .get("targetType") + .and_then(Value::as_str) + .unwrap_or("frame"); // default to "frame" + + if target_type == "frame" { + let msg = WatchTargetsReply { + from: self.name(), + type_: "target-available-form".into(), + target: TargetActorMsg::BrowsingContext(target.encodable()), + }; + let _ = stream.write_json_packet(&msg); - target.frame_update(stream); + target.frame_update(stream); + } else if target_type == "worker" { + for worker_name in &root.workers { + let worker = registry.find::<WorkerActor>(worker_name); + let worker_msg = WatchTargetsReply { + from: self.name(), + type_: "target-available-form".into(), + target: TargetActorMsg::Worker(worker.encodable()), + }; + let _ = stream.write_json_packet(&worker_msg); + } + } else { + warn!("Unexpected target_type: {}", target_type); + return Ok(ActorMessageStatus::Ignored); + } // Messages that contain a `type` field are used to send event callbacks, but they // don't count as a reply. Since every message needs to be responded, we send an @@ -267,6 +298,22 @@ impl Actor for WatcherActor { let thread_actor = registry.find::<ThreadActor>(&target.thread); let sources = thread_actor.source_manager.sources(); target.resources_available(sources.iter().collect(), "source".into()); + + for worker_name in &root.workers { + let worker = registry.find::<WorkerActor>(worker_name); + let thread = registry.find::<ThreadActor>(&worker.thread); + let worker_sources = thread.source_manager.sources(); + + let msg = ResourceAvailableReply { + from: worker.name(), + type_: "resources-available-array".into(), + array: vec![( + "source".to_string(), + worker_sources.iter().cloned().collect(), + )], + }; + let _ = stream.write_json_packet(&msg); + } }, "console-message" | "error-message" => {}, _ => warn!("resource {} not handled yet", resource), diff --git a/components/devtools/actors/worker.rs b/components/devtools/actors/worker.rs index 42c9d9a9c28..68ff56fb3b2 100644 --- a/components/devtools/actors/worker.rs +++ b/components/devtools/actors/worker.rs @@ -17,7 +17,7 @@ use servo_url::ServoUrl; use crate::StreamId; use crate::actor::{Actor, ActorMessageStatus, ActorRegistry}; use crate::protocol::JsonPacketStream; -use crate::resource::ResourceAvailable; +use crate::resource::{ResourceAvailable, ResourceAvailableReply}; #[derive(Clone, Copy)] #[allow(dead_code)] @@ -48,8 +48,10 @@ impl WorkerActor { url: self.url.to_string(), traits: WorkerTraits { is_parent_intercept_enabled: false, + supports_top_level_target_flag: false, }, type_: self.type_ as u32, + target_type: "worker".to_string(), } } } @@ -131,6 +133,28 @@ impl Actor for WorkerActor { } } +impl WorkerActor { + pub(crate) fn resource_available<T: Serialize>(&self, resource: T, resource_type: String) { + self.resources_available(vec![resource], resource_type); + } + + pub(crate) fn resources_available<T: Serialize>( + &self, + resources: Vec<T>, + resource_type: String, + ) { + let msg = ResourceAvailableReply::<T> { + from: self.name(), + type_: "resources-available-array".into(), + array: vec![(resource_type, resources)], + }; + + for stream in self.streams.borrow_mut().values_mut() { + let _ = stream.write_json_packet(&msg); + } + } +} + #[derive(Serialize)] struct DetachedReply { from: String, @@ -160,6 +184,7 @@ struct ConnectReply { #[serde(rename_all = "camelCase")] struct WorkerTraits { is_parent_intercept_enabled: bool, + supports_top_level_target_flag: bool, } #[derive(Serialize)] @@ -173,4 +198,6 @@ pub(crate) struct WorkerMsg { traits: WorkerTraits, #[serde(rename = "type")] type_: u32, + #[serde(rename = "targetType")] + target_type: String, } diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs index 4d1e0222177..5fb9485e9d3 100644 --- a/components/devtools/lib.rs +++ b/components/devtools/lib.rs @@ -510,35 +510,54 @@ impl DevtoolsInstance { fn handle_script_source_info(&mut self, pipeline_id: PipelineId, source_info: SourceInfo) { let mut actors = self.actors.lock().unwrap(); - let browsing_context_id = match self.pipelines.get(&pipeline_id) { - Some(id) => id, - None => return, - }; + if let Some(worker_id) = source_info.worker_id { + let Some(worker_actor_name) = self.actor_workers.get(&worker_id) else { + return; + }; - let actor_name = match self.browsing_contexts.get(browsing_context_id) { - Some(name) => name, - None => return, - }; + let thread_actor_name = actors.find::<WorkerActor>(worker_actor_name).thread.clone(); - let thread_actor_name = actors - .find::<BrowsingContextActor>(actor_name) - .thread - .clone(); - - let thread_actor = actors.find_mut::<ThreadActor>(&thread_actor_name); - thread_actor - .source_manager - .add_source(source_info.url.clone()); - - let source = SourceData { - actor: thread_actor_name.clone(), - url: source_info.url.to_string(), - is_black_boxed: false, - }; + let thread_actor = actors.find_mut::<ThreadActor>(&thread_actor_name); + thread_actor + .source_manager + .add_source(source_info.url.clone()); + + let source = SourceData { + actor: thread_actor_name.clone(), + url: source_info.url.to_string(), + is_black_boxed: false, + }; - // Notify browsing context about the new source - let browsing_context = actors.find::<BrowsingContextActor>(actor_name); - browsing_context.resource_available(source, "source".into()); + let worker_actor = actors.find::<WorkerActor>(worker_actor_name); + worker_actor.resource_available(source, "source".into()); + } else { + let Some(browsing_context_id) = self.pipelines.get(&pipeline_id) else { + return; + }; + let Some(actor_name) = self.browsing_contexts.get(browsing_context_id) else { + return; + }; + + let thread_actor_name = actors + .find::<BrowsingContextActor>(actor_name) + .thread + .clone(); + + let thread_actor = actors.find_mut::<ThreadActor>(&thread_actor_name); + thread_actor + .source_manager + .add_source(source_info.url.clone()); + + let source = SourceData { + actor: thread_actor_name.clone(), + url: source_info.url.to_string(), + is_black_boxed: false, + }; + + // Notify browsing context about the new source + let browsing_context = actors.find::<BrowsingContextActor>(actor_name); + browsing_context.resource_available(source, "source".into()); + } } } diff --git a/components/layout/display_list/mod.rs b/components/layout/display_list/mod.rs index 912c69366bd..3908da69ce1 100644 --- a/components/layout/display_list/mod.rs +++ b/components/layout/display_list/mod.rs @@ -39,7 +39,7 @@ use webrender_api::{ use wr::units::LayoutVector2D; use crate::context::{LayoutContext, ResolvedImage}; -use crate::display_list::conversions::ToWebRender; +pub use crate::display_list::conversions::ToWebRender; use crate::display_list::stacking_context::StackingContextSection; use crate::fragment_tree::{ BackgroundMode, BoxFragment, Fragment, FragmentFlags, FragmentTree, SpecificLayoutInfo, Tag, @@ -711,7 +711,12 @@ impl<'a> BuilderForBoxFragment<'a> { fn build(&mut self, builder: &mut DisplayListBuilder, section: StackingContextSection) { if self.is_hit_test_for_scrollable_overflow { - self.build_hit_test(builder, self.fragment.scrollable_overflow().to_webrender()); + self.build_hit_test( + builder, + self.fragment + .reachable_scrollable_overflow_region() + .to_webrender(), + ); return; } diff --git a/components/layout/display_list/stacking_context.rs b/components/layout/display_list/stacking_context.rs index 9809e428d6e..b044b713260 100644 --- a/components/layout/display_list/stacking_context.rs +++ b/components/layout/display_list/stacking_context.rs @@ -1477,7 +1477,7 @@ impl BoxFragment { y: overflow.y.into(), }; - let content_rect = self.scrollable_overflow().to_webrender(); + let content_rect = self.reachable_scrollable_overflow_region().to_webrender(); let scroll_tree_node_id = display_list.define_scroll_frame( parent_scroll_node_id, diff --git a/components/layout/flexbox/layout.rs b/components/layout/flexbox/layout.rs index 77069236787..a5540123681 100644 --- a/components/layout/flexbox/layout.rs +++ b/components/layout/flexbox/layout.rs @@ -1774,7 +1774,9 @@ impl FlexItem<'_> { non_stretch_layout_result: Option<&mut FlexItemLayoutResult>, ) -> Option<FlexItemLayoutResult> { let containing_block = flex_context.containing_block; - let mut positioning_context = PositioningContext::new_for_style(self.box_.style()) + let independent_formatting_context = &self.box_.independent_formatting_context; + let mut positioning_context = independent_formatting_context + .new_positioning_context() .unwrap_or_else(|| { PositioningContext::new_for_subtree( flex_context @@ -1783,7 +1785,6 @@ impl FlexItem<'_> { ) }); - let independent_formatting_context = &self.box_.independent_formatting_context; let item_writing_mode = independent_formatting_context.style().writing_mode; let item_is_horizontal = item_writing_mode.is_horizontal(); let flex_axis = flex_context.config.flex_axis; @@ -2616,7 +2617,9 @@ impl FlexItemBox { cross_size_stretches_to_container_size: bool, intrinsic_sizing_mode: IntrinsicSizingMode, ) -> Au { - let mut positioning_context = PositioningContext::new_for_style(self.style()) + let mut positioning_context = self + .independent_formatting_context + .new_positioning_context() .unwrap_or_else(|| { PositioningContext::new_for_subtree( flex_context diff --git a/components/layout/flow/float.rs b/components/layout/flow/float.rs index 0570ce0d0f4..dbc50c07603 100644 --- a/components/layout/flow/float.rs +++ b/components/layout/flow/float.rs @@ -913,11 +913,10 @@ impl FloatBox { positioning_context: &mut PositioningContext, containing_block: &ContainingBlock, ) -> BoxFragment { - let style = self.contents.style().clone(); positioning_context.layout_maybe_position_relative_fragment( layout_context, containing_block, - &style, + &self.contents.base, |positioning_context| { self.contents .layout_float_or_atomic_inline( diff --git a/components/layout/flow/inline/line.rs b/components/layout/flow/inline/line.rs index c42f32c9242..e65eaed2367 100644 --- a/components/layout/flow/inline/line.rs +++ b/components/layout/flow/inline/line.rs @@ -326,13 +326,12 @@ impl LineItemLayout<'_, '_> { let inline_box = self.layout.ifc.inline_boxes.get(identifier); let inline_box = &*(inline_box.borrow()); - let style = &inline_box.base.style; let space_above_baseline = inline_box_state.calculate_space_above_baseline(); let block_start_offset = self.calculate_inline_box_block_start(inline_box_state, space_above_baseline); let positioning_context_or_start_offset_in_parent = - match PositioningContext::new_for_style(style) { + match inline_box.base.new_positioning_context() { Some(positioning_context) => Either::Left(positioning_context), None => Either::Right(self.current_positioning_context_mut().len()), }; diff --git a/components/layout/flow/inline/mod.rs b/components/layout/flow/inline/mod.rs index dabb9773410..25fbaa324b1 100644 --- a/components/layout/flow/inline/mod.rs +++ b/components/layout/flow/inline/mod.rs @@ -2004,7 +2004,8 @@ impl IndependentFormattingContext { bidi_level: Level, ) { // We need to know the inline size of the atomic before deciding whether to do the line break. - let mut child_positioning_context = PositioningContext::new_for_style(self.style()) + let mut child_positioning_context = self + .new_positioning_context() .unwrap_or_else(|| PositioningContext::new_for_subtree(true)); let IndependentFloatOrAtomicLayoutResult { mut fragment, diff --git a/components/layout/flow/mod.rs b/components/layout/flow/mod.rs index d983e8592c4..983282dc389 100644 --- a/components/layout/flow/mod.rs +++ b/components/layout/flow/mod.rs @@ -779,7 +779,7 @@ impl BlockLevelBox { ArcRefCell::new(positioning_context.layout_maybe_position_relative_fragment( layout_context, containing_block, - &base.style, + base, |positioning_context| { layout_in_flow_non_replaced_block_level_same_formatting_context( layout_context, @@ -798,7 +798,7 @@ impl BlockLevelBox { positioning_context.layout_maybe_position_relative_fragment( layout_context, containing_block, - independent.style(), + &independent.base, |positioning_context| { independent.layout_in_flow_block_level( layout_context, diff --git a/components/layout/flow/root.rs b/components/layout/flow/root.rs index 187726595f8..c6498eeed63 100644 --- a/components/layout/flow/root.rs +++ b/components/layout/flow/root.rs @@ -411,7 +411,7 @@ impl BoxTree { let scrollable_overflow = root_fragments .iter() .fold(PhysicalRect::zero(), |acc, child| { - let child_overflow = child.scrollable_overflow(); + let child_overflow = child.scrollable_overflow_for_parent(); // https://drafts.csswg.org/css-overflow/#scrolling-direction // We want to clip scrollable overflow on box-start and inline-start diff --git a/components/layout/fragment_tree/box_fragment.rs b/components/layout/fragment_tree/box_fragment.rs index e87826ec3ca..65ad1c4aa93 100644 --- a/components/layout/fragment_tree/box_fragment.rs +++ b/components/layout/fragment_tree/box_fragment.rs @@ -2,11 +2,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use app_units::Au; +use app_units::{Au, MAX_AU, MIN_AU}; use atomic_refcell::AtomicRefCell; use base::print_tree::PrintTree; use malloc_size_of_derive::MallocSizeOf; use servo_arc::Arc as ServoArc; +use servo_geometry::f32_rect_to_au_rect; use style::Zero; use style::computed_values::border_collapse::T as BorderCollapse; use style::computed_values::overflow_x::T as ComputedOverflow; @@ -16,6 +17,7 @@ use style::properties::ComputedValues; use style::values::specified::box_::DisplayOutside; use super::{BaseFragment, BaseFragmentInfo, CollapsedBlockMargins, Fragment}; +use crate::display_list::ToWebRender; use crate::formatting_contexts::Baselines; use crate::geom::{ AuOrAuto, LengthPercentageOrAuto, PhysicalPoint, PhysicalRect, PhysicalSides, ToLogical, @@ -116,7 +118,7 @@ impl BoxFragment { ) -> BoxFragment { let scrollable_overflow_from_children = children.iter().fold(PhysicalRect::zero(), |acc, child| { - acc.union(&child.scrollable_overflow()) + acc.union(&child.scrollable_overflow_for_parent()) }); BoxFragment { @@ -267,30 +269,96 @@ impl BoxFragment { pub fn scrollable_overflow_for_parent(&self) -> PhysicalRect<Au> { let mut overflow = self.border_rect(); - if self.style.establishes_scroll_container(self.base.flags) { - return overflow; + if !self.style.establishes_scroll_container(self.base.flags) { + // https://www.w3.org/TR/css-overflow-3/#scrollable + // Only include the scrollable overflow of a child box if it has overflow: visible. + let scrollable_overflow = self.scrollable_overflow(); + let bottom_right = PhysicalPoint::new( + overflow.max_x().max(scrollable_overflow.max_x()), + overflow.max_y().max(scrollable_overflow.max_y()), + ); + + let overflow_style = self.style.effective_overflow(self.base.flags); + if overflow_style.y == ComputedOverflow::Visible { + overflow.origin.y = overflow.origin.y.min(scrollable_overflow.origin.y); + overflow.size.height = bottom_right.y - overflow.origin.y; + } + + if overflow_style.x == ComputedOverflow::Visible { + overflow.origin.x = overflow.origin.x.min(scrollable_overflow.origin.x); + overflow.size.width = bottom_right.x - overflow.origin.x; + } } - // https://www.w3.org/TR/css-overflow-3/#scrollable - // Only include the scrollable overflow of a child box if it has overflow: visible. - let scrollable_overflow = self.scrollable_overflow(); - let bottom_right = PhysicalPoint::new( - overflow.max_x().max(scrollable_overflow.max_x()), - overflow.max_y().max(scrollable_overflow.max_y()), - ); + // <https://drafts.csswg.org/css-overflow-3/#scrollable-overflow-region> + // > ...accounting for transforms by projecting each box onto the plane of + // > the element that establishes its 3D rendering context. [CSS3-TRANSFORMS] + // Both boxes and its scrollable overflow (if it is included) should be transformed accordingly. + // + // TODO(stevennovaryo): We are supposed to handle perspective transform and 3d context, but it is yet to happen. + if self + .style + .has_effective_transform_or_perspective(self.base.flags) + { + if let Some(transform) = + self.calculate_transform_matrix(&self.border_rect().to_untyped()) + { + if let Some(transformed_overflow_box) = + transform.outer_transformed_rect(&overflow.to_webrender().to_rect()) + { + overflow = + f32_rect_to_au_rect(transformed_overflow_box.to_untyped()).cast_unit(); + } + } + } + + overflow + } - let overflow_style = self.style.effective_overflow(self.base.flags); - if overflow_style.y == ComputedOverflow::Visible { - overflow.origin.y = overflow.origin.y.min(scrollable_overflow.origin.y); - overflow.size.height = bottom_right.y - overflow.origin.y; + /// <https://drafts.csswg.org/css-overflow/#unreachable-scrollable-overflow-region> + /// > area beyond the scroll origin in either axis is considered the unreachable scrollable overflow region + /// + /// Return the clipped the scrollable overflow based on its scroll origin, determined by overflow direction. + /// For an element, the clip rect is the padding rect and for viewport, it is the initial containing block. + pub fn clip_unreachable_scrollable_overflow_region( + &self, + scrollable_overflow: PhysicalRect<Au>, + clipping_rect: PhysicalRect<Au>, + ) -> PhysicalRect<Au> { + let scrolling_direction = self.style.overflow_direction(); + let mut scrollable_overflow_box = scrollable_overflow.to_box2d(); + let mut clipping_box = clipping_rect.to_box2d(); + + if scrolling_direction.rightward { + clipping_box.max.x = MAX_AU; + } else { + clipping_box.min.x = MIN_AU; } - if overflow_style.x == ComputedOverflow::Visible { - overflow.origin.x = overflow.origin.x.min(scrollable_overflow.origin.x); - overflow.size.width = bottom_right.x - overflow.origin.x; + if scrolling_direction.downward { + clipping_box.max.y = MAX_AU; + } else { + clipping_box.min.y = MIN_AU; } - overflow + scrollable_overflow_box = scrollable_overflow_box.intersection_unchecked(&clipping_box); + + match scrollable_overflow_box.is_negative() { + true => PhysicalRect::zero(), + false => scrollable_overflow_box.to_rect(), + } + } + + /// <https://drafts.csswg.org/css-overflow/#unreachable-scrollable-overflow-region> + /// > area beyond the scroll origin in either axis is considered the unreachable scrollable overflow region + /// + /// Return the clipped the scrollable overflow based on its scroll origin, determined by overflow direction. + /// This will coincides with the scrollport if the fragment is a scroll container. + pub fn reachable_scrollable_overflow_region(&self) -> PhysicalRect<Au> { + self.clip_unreachable_scrollable_overflow_region( + self.scrollable_overflow(), + self.padding_rect(), + ) } pub(crate) fn calculate_resolved_insets_if_positioned(&self) -> PhysicalSides<AuOrAuto> { diff --git a/components/layout/fragment_tree/fragment.rs b/components/layout/fragment_tree/fragment.rs index 7708b0893ee..1c5324fa1c4 100644 --- a/components/layout/fragment_tree/fragment.rs +++ b/components/layout/fragment_tree/fragment.rs @@ -170,17 +170,28 @@ impl Fragment { } } - pub fn scrolling_area(&self) -> PhysicalRect<Au> { + pub fn unclipped_scrolling_area(&self) -> PhysicalRect<Au> { match self { Fragment::Box(fragment) | Fragment::Float(fragment) => { let fragment = fragment.borrow(); fragment.offset_by_containing_block(&fragment.scrollable_overflow()) }, - _ => self.scrollable_overflow(), + _ => self.scrollable_overflow_for_parent(), + } + } + + pub fn scrolling_area(&self) -> PhysicalRect<Au> { + match self { + Fragment::Box(fragment) | Fragment::Float(fragment) => { + let fragment = fragment.borrow(); + fragment + .offset_by_containing_block(&fragment.reachable_scrollable_overflow_region()) + }, + _ => self.scrollable_overflow_for_parent(), } } - pub fn scrollable_overflow(&self) -> PhysicalRect<Au> { + pub fn scrollable_overflow_for_parent(&self) -> PhysicalRect<Au> { match self { Fragment::Box(fragment) | Fragment::Float(fragment) => { fragment.borrow().scrollable_overflow_for_parent() diff --git a/components/layout/fragment_tree/fragment_tree.rs b/components/layout/fragment_tree/fragment_tree.rs index 3a082c99389..1499a50dacf 100644 --- a/components/layout/fragment_tree/fragment_tree.rs +++ b/components/layout/fragment_tree/fragment_tree.rs @@ -138,11 +138,26 @@ impl FragmentTree { .find_map(|child| child.find(&info, 0, &mut process_func)) } + /// <https://drafts.csswg.org/cssom-view/#scrolling-area> + /// + /// Scrolling area for a viewport that is clipped according to overflow direction of root element. pub fn get_scrolling_area_for_viewport(&self) -> PhysicalRect<Au> { let mut scroll_area = self.initial_containing_block; - for fragment in self.root_fragments.iter() { - scroll_area = fragment.scrolling_area().union(&scroll_area); + if let Some(root_fragment) = self.root_fragments.first() { + for fragment in self.root_fragments.iter() { + scroll_area = fragment.unclipped_scrolling_area().union(&scroll_area); + } + match root_fragment { + Fragment::Box(fragment) | Fragment::Float(fragment) => fragment + .borrow() + .clip_unreachable_scrollable_overflow_region( + scroll_area, + self.initial_containing_block, + ), + _ => scroll_area, + } + } else { + scroll_area } - scroll_area } } diff --git a/components/layout/fragment_tree/positioning_fragment.rs b/components/layout/fragment_tree/positioning_fragment.rs index 1fe968eb484..0cf525a3479 100644 --- a/components/layout/fragment_tree/positioning_fragment.rs +++ b/components/layout/fragment_tree/positioning_fragment.rs @@ -56,7 +56,7 @@ impl PositioningFragment { let scrollable_overflow = children.iter().fold(PhysicalRect::zero(), |acc, child| { acc.union( &child - .scrollable_overflow() + .scrollable_overflow_for_parent() .translate(content_origin.to_vector()), ) }); diff --git a/components/layout/positioned.rs b/components/layout/positioned.rs index 5f08e4e86c5..6bfe2af87ef 100644 --- a/components/layout/positioned.rs +++ b/components/layout/positioned.rs @@ -29,6 +29,7 @@ use crate::geom::{ PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize, PhysicalVec, Size, Sizes, ToLogical, ToLogicalWithContainingBlock, }; +use crate::layout_box_base::LayoutBoxBase; use crate::sizing::ContentSizes; use crate::style_ext::{Clamp, ComputedValuesExt, ContentBoxSizesAndPBM, DisplayInside}; use crate::{ @@ -103,6 +104,20 @@ impl AbsolutelyPositionedBox { } } +impl IndependentFormattingContext { + #[inline] + pub(crate) fn new_positioning_context(&self) -> Option<PositioningContext> { + self.base.new_positioning_context() + } +} + +impl LayoutBoxBase { + #[inline] + pub(crate) fn new_positioning_context(&self) -> Option<PositioningContext> { + PositioningContext::new_for_style(&self.style, &self.base_fragment_info.flags) + } +} + impl PositioningContext { pub(crate) fn new_for_containing_block_for_all_descendants() -> Self { Self { @@ -130,14 +145,10 @@ impl PositioningContext { self.for_nearest_positioned_ancestor.is_some() } - pub(crate) fn new_for_style(style: &ComputedValues) -> Option<Self> { - // NB: We never make PositioningContexts for replaced elements, which is why we always - // pass false here. - if style.establishes_containing_block_for_all_descendants(FragmentFlags::empty()) { + fn new_for_style(style: &ComputedValues, flags: &FragmentFlags) -> Option<Self> { + if style.establishes_containing_block_for_all_descendants(*flags) { Some(Self::new_for_containing_block_for_all_descendants()) - } else if style - .establishes_containing_block_for_absolute_descendants(FragmentFlags::empty()) - { + } else if style.establishes_containing_block_for_absolute_descendants(*flags) { Some(Self { for_nearest_positioned_ancestor: Some(Vec::new()), for_nearest_containing_block_for_all_descendants: Vec::new(), @@ -213,12 +224,12 @@ impl PositioningContext { &mut self, layout_context: &LayoutContext, containing_block: &ContainingBlock, - style: &ComputedValues, + base: &LayoutBoxBase, fragment_layout_fn: impl FnOnce(&mut Self) -> BoxFragment, ) -> BoxFragment { // Try to create a context, but if one isn't necessary, simply create the fragment // using the given closure and the current `PositioningContext`. - let mut new_context = match Self::new_for_style(style) { + let mut new_context = match base.new_positioning_context() { Some(new_context) => new_context, None => return fragment_layout_fn(self), }; @@ -229,9 +240,8 @@ impl PositioningContext { // If the new context has any hoisted boxes for the nearest containing block for // pass them up the tree. self.append(new_context); - - if style.clone_position() == Position::Relative { - new_fragment.content_rect.origin += relative_adjustement(style, containing_block) + if base.style.clone_position() == Position::Relative { + new_fragment.content_rect.origin += relative_adjustement(&base.style, containing_block) .to_physical_vector(containing_block.style.writing_mode) } @@ -586,7 +596,7 @@ impl HoistedAbsolutelyPositionedBox { .sizes })); - let mut positioning_context = PositioningContext::new_for_style(&style).unwrap(); + let mut positioning_context = context.new_positioning_context().unwrap(); let mut new_fragment = { let content_size: LogicalVec2<Au>; let fragments; diff --git a/components/layout/style_ext.rs b/components/layout/style_ext.rs index b157be914e0..023db6b07f1 100644 --- a/components/layout/style_ext.rs +++ b/components/layout/style_ext.rs @@ -12,7 +12,7 @@ use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode; use style::computed_values::position::T as ComputedPosition; use style::computed_values::transform_style::T as ComputedTransformStyle; use style::computed_values::unicode_bidi::T as UnicodeBidi; -use style::logical_geometry::{Direction as AxisDirection, WritingMode}; +use style::logical_geometry::{Direction as AxisDirection, PhysicalSide, WritingMode}; use style::properties::ComputedValues; use style::properties::longhands::backface_visibility::computed_value::T as BackfaceVisiblity; use style::properties::longhands::box_sizing::computed_value::T as BoxSizing; @@ -280,6 +280,16 @@ impl Default for BorderStyleColor { } } +/// <https://drafts.csswg.org/cssom-view/#overflow-directions> +/// > A scrolling box of a viewport or element has two overflow directions, +/// > which are the block-end and inline-end directions for that viewport or element. +pub(crate) struct OverflowDirection { + /// Whether block-end or inline-end direction is [PhysicalSide::Right]. + pub rightward: bool, + /// Whether block-end or inline-end direction is [PhysicalSide::Bottom]. + pub downward: bool, +} + pub(crate) trait ComputedValuesExt { fn physical_box_offsets(&self) -> PhysicalSides<LengthPercentageOrAuto<'_>>; fn box_offsets(&self, writing_mode: WritingMode) -> LogicalSides<LengthPercentageOrAuto<'_>>; @@ -354,6 +364,7 @@ pub(crate) trait ComputedValuesExt { writing_mode: WritingMode, ) -> bool; fn is_inline_box(&self, fragment_flags: FragmentFlags) -> bool; + fn overflow_direction(&self) -> OverflowDirection; } impl ComputedValuesExt for ComputedValues { @@ -834,9 +845,9 @@ impl ComputedValuesExt for ComputedValues { // > A value other than none for the filter property results in the creation of a containing // > block for absolute and fixed positioned descendants unless the element it applies to is // > a document root element in the current browsing context. - // FIXME(#35391): Need to check if this is the root element. - if !self.get_effects().filter.0.is_empty() || - will_change_bits.intersects(WillChangeBits::FIXPOS_CB_NON_SVG) + if !fragment_flags.contains(FragmentFlags::IS_ROOT_ELEMENT) && + (!self.get_effects().filter.0.is_empty() || + will_change_bits.intersects(WillChangeBits::FIXPOS_CB_NON_SVG)) { return true; } @@ -980,6 +991,23 @@ impl ComputedValuesExt for ComputedValues { }; has_percentage(box_offsets.block_start) || has_percentage(box_offsets.block_end) } + + // <https://drafts.csswg.org/cssom-view/#overflow-directions> + fn overflow_direction(&self) -> OverflowDirection { + let inline_end_direction = self.writing_mode.inline_end_physical_side(); + let block_end_direction = self.writing_mode.block_end_physical_side(); + + let rightward = inline_end_direction == PhysicalSide::Right || + block_end_direction == PhysicalSide::Right; + let downward = inline_end_direction == PhysicalSide::Bottom || + block_end_direction == PhysicalSide::Bottom; + + // TODO(stevennovaryo): We should consider the flex-container's CSS (e.g. flow-direction: column-reverse). + OverflowDirection { + rightward, + downward, + } + } } pub(crate) enum LayoutStyle<'a> { diff --git a/components/layout/table/layout.rs b/components/layout/table/layout.rs index 2261f7d165c..0cbe3e9ca76 100644 --- a/components/layout/table/layout.rs +++ b/components/layout/table/layout.rs @@ -1503,7 +1503,7 @@ impl<'a> TableLayout<'a> { layout_context: &LayoutContext, parent_positioning_context: &mut PositioningContext, ) -> BoxFragment { - let mut positioning_context = PositioningContext::new_for_style(caption.context.style()); + let mut positioning_context = caption.context.new_positioning_context(); let containing_block = &ContainingBlock { size: ContainingBlockSize { inline: self.table_width + self.pbm.padding_border_sums.inline, @@ -2325,7 +2325,7 @@ impl<'a> RowFragmentLayout<'a> { Self { row: table_row, rect, - positioning_context: PositioningContext::new_for_style(&table_row.base.style), + positioning_context: table_row.base.new_positioning_context(), containing_block, fragments: Vec::new(), } @@ -2410,7 +2410,7 @@ impl RowGroupFragmentLayout { let row_group = row_group.borrow(); ( dimensions.get_row_group_rect(&row_group), - PositioningContext::new_for_style(&row_group.base.style), + row_group.base.new_positioning_context(), ) }; Self { diff --git a/components/layout/taffy/layout.rs b/components/layout/taffy/layout.rs index a7581136bf2..3777c902053 100644 --- a/components/layout/taffy/layout.rs +++ b/components/layout/taffy/layout.rs @@ -251,8 +251,9 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> { style, }; let layout = { - let mut child_positioning_context = - PositioningContext::new_for_style(style).unwrap_or_else(|| { + let mut child_positioning_context = independent_context + .new_positioning_context() + .unwrap_or_else(|| { PositioningContext::new_for_subtree( self.positioning_context .collects_for_nearest_positioned_ancestor(), diff --git a/components/script/canvas_state.rs b/components/script/canvas_state.rs index 408c94c124a..e9892818e92 100644 --- a/components/script/canvas_state.rs +++ b/components/script/canvas_state.rs @@ -152,6 +152,8 @@ pub(crate) struct CanvasState { canvas_id: CanvasId, #[no_trace] image_key: ImageKey, + #[no_trace] + size: Cell<Size2D<u64>>, state: DomRefCell<CanvasContextState>, origin_clean: Cell<bool>, #[ignore_malloc_size_of = "Arc"] @@ -176,6 +178,7 @@ impl CanvasState { profiled_ipc::channel(global.time_profiler_chan().clone()).unwrap(); let script_to_constellation_chan = global.script_to_constellation_chan(); debug!("Asking constellation to create new canvas thread."); + let size = adjust_canvas_size(size); script_to_constellation_chan .send(ScriptToConstellationMessage::CreateCanvasPaintThread( size, sender, @@ -194,6 +197,7 @@ impl CanvasState { CanvasState { ipc_renderer, canvas_id, + size: Cell::new(size), state: DomRefCell::new(CanvasContextState::new()), origin_clean: Cell::new(true), image_cache: global.image_cache(), @@ -221,7 +225,15 @@ impl CanvasState { self.canvas_id } + pub(crate) fn is_paintable(&self) -> bool { + !self.size.get().is_empty() + } + pub(crate) fn send_canvas_2d_msg(&self, msg: Canvas2dMsg) { + if !self.is_paintable() { + return; + } + self.ipc_renderer .send(CanvasMsg::Canvas2d(msg, self.get_canvas_id())) .unwrap() @@ -229,6 +241,10 @@ impl CanvasState { /// Updates WR image and blocks on completion pub(crate) fn update_rendering(&self) { + if !self.is_paintable() { + return; + } + let (sender, receiver) = ipc::channel().unwrap(); self.ipc_renderer .send(CanvasMsg::Canvas2d( @@ -239,16 +255,27 @@ impl CanvasState { receiver.recv().unwrap(); } - // https://html.spec.whatwg.org/multipage/#concept-canvas-set-bitmap-dimensions + /// <https://html.spec.whatwg.org/multipage/#concept-canvas-set-bitmap-dimensions> pub(crate) fn set_bitmap_dimensions(&self, size: Size2D<u64>) { self.reset_to_initial_state(); + + self.size.replace(adjust_canvas_size(size)); + self.ipc_renderer - .send(CanvasMsg::Recreate(Some(size), self.get_canvas_id())) + .send(CanvasMsg::Recreate( + Some(self.size.get()), + self.get_canvas_id(), + )) .unwrap(); } pub(crate) fn reset(&self) { self.reset_to_initial_state(); + + if !self.is_paintable() { + return; + } + self.ipc_renderer .send(CanvasMsg::Recreate(None, self.get_canvas_id())) .unwrap(); @@ -347,7 +374,6 @@ impl CanvasState { pub(crate) fn get_rect(&self, canvas_size: Size2D<u64>, rect: Rect<u64>) -> Vec<u8> { assert!(self.origin_is_clean()); - assert!(Rect::from_size(canvas_size).contains_rect(&rect)); let (sender, receiver) = ipc::channel().unwrap(); @@ -398,18 +424,22 @@ impl CanvasState { dw: Option<f64>, dh: Option<f64>, ) -> ErrorResult { + if !self.is_paintable() { + return Ok(()); + } + let result = match image { CanvasImageSource::HTMLCanvasElement(ref canvas) => { - // https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument - if !canvas.is_valid() { + // <https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument> + if canvas.get_size().is_empty() { return Err(Error::InvalidState); } self.draw_html_canvas_element(canvas, htmlcanvas, sx, sy, sw, sh, dx, dy, dw, dh) }, CanvasImageSource::OffscreenCanvas(ref canvas) => { - // https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument - if !canvas.is_valid() { + // <https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument> + if canvas.get_size().is_empty() { return Err(Error::InvalidState); } @@ -528,11 +558,6 @@ impl CanvasState { dw: Option<f64>, dh: Option<f64>, ) -> ErrorResult { - // 1. Check the usability of the image argument - if !canvas.is_valid() { - return Err(Error::InvalidState); - } - let canvas_size = canvas.get_size(); let dw = dw.unwrap_or(canvas_size.width as f64); let dh = dh.unwrap_or(canvas_size.height as f64); @@ -1403,13 +1428,13 @@ impl CanvasState { }, }; - ImageData::new( - global, - size.width, - size.height, - Some(self.get_rect(canvas_size, read_rect)), - can_gc, - ) + let data = if self.is_paintable() { + Some(self.get_rect(canvas_size, read_rect)) + } else { + None + }; + + ImageData::new(global, size.width, size.height, data, can_gc) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata @@ -1445,6 +1470,10 @@ impl CanvasState { dirty_width: i32, dirty_height: i32, ) { + if !self.is_paintable() { + return; + } + // FIXME(nox): There are many arithmetic operations here that can // overflow or underflow, this should probably be audited. @@ -2013,3 +2042,23 @@ where style.font_family.to_css_string() ) } + +fn adjust_canvas_size(size: Size2D<u64>) -> Size2D<u64> { + // Firefox limits width/height to 32767 pixels and Chromium to 65535 pixels, + // but slows down dramatically before it reaches that limit. + // We limit by area instead, giving us larger maximum dimensions, + // in exchange for a smaller maximum canvas size. + const MAX_CANVAS_AREA: u64 = 32768 * 8192; + // Max width/height to 65535 in CSS pixels. + const MAX_CANVAS_SIZE: u64 = 65535; + + if !size.is_empty() && + size.greater_than(Size2D::new(MAX_CANVAS_SIZE, MAX_CANVAS_SIZE)) + .none() && + size.area() < MAX_CANVAS_AREA + { + size + } else { + Size2D::zero() + } +} diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 73052e6906e..38bd38ad511 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -4,7 +4,7 @@ use canvas_traits::canvas::{Canvas2dMsg, CanvasId, CanvasMsg, FromScriptMsg}; use dom_struct::dom_struct; -use euclid::default::{Point2D, Rect, Size2D}; +use euclid::default::Size2D; use profile_traits::ipc; use script_bindings::inheritance::Castable; use script_layout_interface::HTMLCanvasDataSource; @@ -74,23 +74,12 @@ impl CanvasRenderingContext2D { reflect_dom_object(boxed, global, can_gc) } - // https://html.spec.whatwg.org/multipage/#concept-canvas-set-bitmap-dimensions - pub(crate) fn set_bitmap_dimensions(&self, size: Size2D<u32>) { - self.reset_to_initial_state(); - self.canvas_state - .get_ipc_renderer() - .send(CanvasMsg::Recreate( - Some(size.to_u64()), - self.canvas_state.get_canvas_id(), - )) - .unwrap(); - } - // https://html.spec.whatwg.org/multipage/#reset-the-rendering-context-to-its-default-state fn reset_to_initial_state(&self) { self.canvas_state.reset_to_initial_state(); } + /// <https://html.spec.whatwg.org/multipage/#concept-canvas-set-bitmap-dimensions> pub(crate) fn set_canvas_bitmap_dimensions(&self, size: Size2D<u64>) { self.canvas_state.set_bitmap_dimensions(size); } @@ -106,20 +95,17 @@ impl CanvasRenderingContext2D { pub(crate) fn send_canvas_2d_msg(&self, msg: Canvas2dMsg) { self.canvas_state.send_canvas_2d_msg(msg) } - - pub(crate) fn get_rect(&self, rect: Rect<u32>) -> Vec<u8> { - let rect = Rect::new( - Point2D::new(rect.origin.x as u64, rect.origin.y as u64), - Size2D::new(rect.size.width as u64, rect.size.height as u64), - ); - self.canvas_state.get_rect(self.canvas.size(), rect) - } } impl LayoutCanvasRenderingContextHelpers for LayoutDom<'_, CanvasRenderingContext2D> { fn canvas_data_source(self) -> HTMLCanvasDataSource { let canvas_state = &self.unsafe_get().canvas_state; - HTMLCanvasDataSource::Image(canvas_state.image_key()) + + if canvas_state.is_paintable() { + HTMLCanvasDataSource::Image(canvas_state.image_key()) + } else { + HTMLCanvasDataSource::Empty + } } } @@ -139,13 +125,11 @@ impl CanvasContext for CanvasRenderingContext2D { } fn resize(&self) { - self.set_bitmap_dimensions(self.size().cast()) + self.set_canvas_bitmap_dimensions(self.size().cast()) } fn get_image_data(&self) -> Option<Snapshot> { - let size = self.size(); - - if size.is_empty() { + if !self.canvas_state.is_paintable() { return None; } diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 1e2a3747751..ec2ad98c464 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -1180,7 +1180,9 @@ impl Document { let node = elem.upcast::<Node>(); elem.set_focus_state(false); // FIXME: pass appropriate relatedTarget - self.fire_focus_event(FocusEventType::Blur, node, None, can_gc); + if node.is_connected() { + self.fire_focus_event(FocusEventType::Blur, node, None, can_gc); + } // Notify the embedder to hide the input method. if elem.input_method_type().is_some() { diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index ce6dcca66f3..2421b683bf7 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -1270,8 +1270,14 @@ impl HTMLFormElement { return; } - let controls = self.controls.borrow(); - for child in controls.iter() { + let controls: Vec<_> = self + .controls + .borrow() + .iter() + .map(|c| c.as_rooted()) + .collect(); + + for child in controls { let child = child.upcast::<Node>(); match child.type_id() { diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 9452dcb17a6..58853f600d2 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -1008,12 +1008,12 @@ impl HTMLScriptElement { Ok(script) => script, }; - // TODO: we need to handle this for worker if let Some(chan) = self.global().devtools_chan() { let pipeline_id = self.global().pipeline_id(); let source_info = SourceInfo { url: script.url.clone(), external: script.external, + worker_id: None, }; let _ = chan.send(ScriptToDevtoolsControlMsg::ScriptSourceLoaded( pipeline_id, diff --git a/components/script/dom/offscreencanvasrenderingcontext2d.rs b/components/script/dom/offscreencanvasrenderingcontext2d.rs index 2f9b52640e6..b2d0f3201ca 100644 --- a/components/script/dom/offscreencanvasrenderingcontext2d.rs +++ b/components/script/dom/offscreencanvasrenderingcontext2d.rs @@ -65,7 +65,7 @@ impl OffscreenCanvasRenderingContext2D { } pub(crate) fn set_canvas_bitmap_dimensions(&self, size: Size2D<u64>) { - self.context.set_bitmap_dimensions(size.cast()); + self.context.set_canvas_bitmap_dimensions(size.cast()); } pub(crate) fn send_canvas_2d_msg(&self, msg: Canvas2dMsg) { diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index 429234c7a8e..6ad56026db6 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -8,7 +8,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use constellation_traits::{StructuredSerializedData, WorkerScriptLoadOrigin}; use crossbeam_channel::{Sender, unbounded}; -use devtools_traits::{DevtoolsPageInfo, ScriptToDevtoolsControlMsg, WorkerId}; +use devtools_traits::{DevtoolsPageInfo, ScriptToDevtoolsControlMsg, SourceInfo, WorkerId}; use dom_struct::dom_struct; use ipc_channel::ipc; use js::jsapi::{Heap, JSObject}; @@ -213,6 +213,16 @@ impl WorkerMethods<crate::DomTypeHolder> for Worker { devtools_sender.clone(), page_info, )); + + let source_info = SourceInfo { + url: worker_url.clone(), + external: true, // Worker scripts are always external. + worker_id: Some(worker_id), + }; + let _ = chan.send(ScriptToDevtoolsControlMsg::ScriptSourceLoaded( + pipeline_id, + source_info, + )); } } diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index f78b5bf281b..9c93bef22df 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -331,8 +331,7 @@ pub struct ScriptThread { #[no_trace] layout_factory: Arc<dyn LayoutFactory>, - // Mouse down point. - // In future, this shall be mouse_down_point for primary button + /// The screen coordinates where the primary mouse button was pressed. #[no_trace] relative_mouse_down_point: Cell<Point2D<f32, DevicePixel>>, } diff --git a/components/shared/devtools/lib.rs b/components/shared/devtools/lib.rs index 59857dc0d00..0cf99d22658 100644 --- a/components/shared/devtools/lib.rs +++ b/components/shared/devtools/lib.rs @@ -551,4 +551,5 @@ impl fmt::Display for ShadowRootMode { pub struct SourceInfo { pub url: ServoUrl, pub external: bool, + pub worker_id: Option<WorkerId>, } diff --git a/deny.toml b/deny.toml index 80f02cc308e..b2e86b9e67e 100644 --- a/deny.toml +++ b/deny.toml @@ -34,6 +34,7 @@ allow = [ "BSD-3-Clause", "BSL-1.0", "CC0-1.0", + "CDLA-Permissive-2.0", "ISC", "MIT", "MPL-2.0", diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index b61673238d5..750266dc59c 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -7459,6 +7459,15 @@ } } }, + "focus": { + "focus-element-crash.html": [ + "27df1c0b13081827685fa96e0cba2f7b9b03c89a", + [ + null, + {} + ] + ] + }, "fullscreen": { "crashtests": { "backdrop-list-item.html": [ @@ -595710,6 +595719,55 @@ {} ] ], + "scrollable-overflow-transform-004.html": [ + "b398167fa309885658f044ccdd1df75bca880701", + [ + null, + {} + ] + ], + "scrollable-overflow-transform-005.tentative.html": [ + "837b95ba96db71e7d696edfe4bb6c7c489e7a411", + [ + null, + {} + ] + ], + "scrollable-overflow-transform-006.html": [ + "2eea759da6a1adad341b2145a8b29725e84c2db6", + [ + null, + {} + ] + ], + "scrollable-overflow-transform-007.html": [ + "8aa6e5f17d8633e759d5b52b5096057c367d7b58", + [ + null, + {} + ] + ], + "scrollable-overflow-transform-008.html": [ + "df1daeb842405ba6107be563e1652651ec232d58", + [ + null, + {} + ] + ], + "scrollable-overflow-transform-009.html": [ + "aca1b28418adf361a38f59bb10e6ba3cdabd3097", + [ + null, + {} + ] + ], + "scrollable-overflow-transform-010.tentative.html": [ + "e2c62cb4474ecbd486360fdd4aeb1c306a433f2d", + [ + null, + {} + ] + ], "scrollable-overflow-transform-dynamic-001.html": [ "a233376bdb222e5eeb45e3b5f646a84a665e6594", [ @@ -595752,6 +595810,13 @@ {} ] ], + "scrollable-overflow-transform-unreachable-region.html": [ + "91e987bf82654415f47500f9d6d7d568e4eefcbc", + [ + null, + {} + ] + ], "scrollable-overflow-vertical-rl-dynamic.html": [ "07f322901748c9709c3037d0223a546549cc9cff", [ diff --git a/tests/wpt/meta/css/css-flexbox/negative-overflow.html.ini b/tests/wpt/meta/css/css-flexbox/negative-overflow.html.ini index 38100976826..e483189946d 100644 --- a/tests/wpt/meta/css/css-flexbox/negative-overflow.html.ini +++ b/tests/wpt/meta/css/css-flexbox/negative-overflow.html.ini @@ -5,21 +5,9 @@ [.flexbox 11] expected: FAIL - [.flexbox 6] - expected: FAIL - - [.flexbox 7] - expected: FAIL - - [.flexbox 1] - expected: FAIL - [.flexbox 2] expected: FAIL - [.flexbox 3] - expected: FAIL - [.flexbox 8] expected: FAIL diff --git a/tests/wpt/meta/css/css-grid/alignment/grid-content-alignment-overflow-002.html.ini b/tests/wpt/meta/css/css-grid/alignment/grid-content-alignment-overflow-002.html.ini index bad0d70b3b5..794226f82ac 100644 --- a/tests/wpt/meta/css/css-grid/alignment/grid-content-alignment-overflow-002.html.ini +++ b/tests/wpt/meta/css/css-grid/alignment/grid-content-alignment-overflow-002.html.ini @@ -11,20 +11,11 @@ [.grid 4] expected: FAIL - [.grid 5] - expected: FAIL - - [.grid 6] - expected: FAIL - [.grid 7] expected: FAIL [.grid 8] expected: FAIL - [.grid 11] - expected: FAIL - [.grid 12] expected: FAIL diff --git a/tests/wpt/meta/css/css-overflow/overflow-inline-transform-relative.html.ini b/tests/wpt/meta/css/css-overflow/overflow-inline-transform-relative.html.ini deleted file mode 100644 index 0ba0b29e0f2..00000000000 --- a/tests/wpt/meta/css/css-overflow/overflow-inline-transform-relative.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[overflow-inline-transform-relative.html] - [#target used transform when computing scroll overflow] - expected: FAIL diff --git a/tests/wpt/meta/css/css-overflow/scroll-overflow-padding-block-001.html.ini b/tests/wpt/meta/css/css-overflow/scroll-overflow-padding-block-001.html.ini index b4b8f3830d9..1738329f50c 100644 --- a/tests/wpt/meta/css/css-overflow/scroll-overflow-padding-block-001.html.ini +++ b/tests/wpt/meta/css/css-overflow/scroll-overflow-padding-block-001.html.ini @@ -1,7 +1,4 @@ [scroll-overflow-padding-block-001.html] expected: ERROR - [undefined block-end] - expected: FAIL - [undefined block-start] expected: [PASS, FAIL] diff --git a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-001.html.ini b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-001.html.ini deleted file mode 100644 index e19232bb0b8..00000000000 --- a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-001.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[scrollable-overflow-transform-001.html] - [.container 1] - expected: FAIL - - [.container 2] - expected: FAIL - - [.container 3] - expected: FAIL diff --git a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-002.html.ini b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-002.html.ini deleted file mode 100644 index eae09f05def..00000000000 --- a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-002.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[scrollable-overflow-transform-002.html] - [.container 1] - expected: FAIL - - [.container 2] - expected: FAIL - - [.container 3] - expected: FAIL diff --git a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-003.html.ini b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-003.html.ini deleted file mode 100644 index 10ac7e63897..00000000000 --- a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-003.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[scrollable-overflow-transform-003.html] - [.container 1] - expected: FAIL - - [.container 2] - expected: FAIL - - [.container 3] - expected: FAIL diff --git a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-005.tentative.html.ini b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-005.tentative.html.ini new file mode 100644 index 00000000000..901184b8ed2 --- /dev/null +++ b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-005.tentative.html.ini @@ -0,0 +1,3 @@ +[scrollable-overflow-transform-005.tentative.html] + [.container 6] + expected: FAIL diff --git a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-009.html.ini b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-009.html.ini new file mode 100644 index 00000000000..cd8e986f634 --- /dev/null +++ b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-009.html.ini @@ -0,0 +1,6 @@ +[scrollable-overflow-transform-009.html] + [.container 2] + expected: FAIL + + [.container 3] + expected: FAIL diff --git a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-010.tentative.html.ini b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-010.tentative.html.ini new file mode 100644 index 00000000000..94ff7fba3fb --- /dev/null +++ b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-010.tentative.html.ini @@ -0,0 +1,6 @@ +[scrollable-overflow-transform-010.tentative.html] + [.container 1] + expected: FAIL + + [.container 2] + expected: FAIL diff --git a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-001.html.ini b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-001.html.ini deleted file mode 100644 index c4639b846ba..00000000000 --- a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-001.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[scrollable-overflow-transform-dynamic-001.html] - [Check scrollWidth before and after transform chage] - expected: FAIL - - [Check scrollHeight before and after transform chage] - expected: FAIL - - [Check scrollWidth and scrollHeight before and after transform chage] - expected: FAIL diff --git a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-002.html.ini b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-002.html.ini deleted file mode 100644 index ff8be1e2e49..00000000000 --- a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-002.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[scrollable-overflow-transform-dynamic-002.html] - [Check scrollWidth before and after transform chage] - expected: FAIL - - [Check scrollHeight before and after transform chage] - expected: FAIL - - [Check scrollWidth and scrollHeight before and after transform chage] - expected: FAIL diff --git a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-003.html.ini b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-003.html.ini deleted file mode 100644 index 227a2451b5e..00000000000 --- a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-003.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[scrollable-overflow-transform-dynamic-003.html] - [Check scrollWidth before and after transform chage] - expected: FAIL - - [Check scrollHeight before and after transform chage] - expected: FAIL - - [Check scrollWidth and scrollHeight before and after transform chage] - expected: FAIL diff --git a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-004.html.ini b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-004.html.ini deleted file mode 100644 index d346a0658c9..00000000000 --- a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-004.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[scrollable-overflow-transform-dynamic-004.html] - [Check scrollWidth before and after position and transform chage] - expected: FAIL - - [Check scrollHeight before and after position and transform chage] - expected: FAIL - - [Check scrollWidth and scrollHeight after position and transform chage] - expected: FAIL diff --git a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-005.html.ini b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-005.html.ini deleted file mode 100644 index 3561e692dab..00000000000 --- a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-005.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[scrollable-overflow-transform-dynamic-005.html] - [Check scrollWidth before and after appendChild() and transform chage] - expected: FAIL - - [Check scrollHeight before and after appendChild() and transform chage] - expected: FAIL - - [Check scrollWidth and scrollHeight before and after appendChild() and transform chage] - expected: FAIL diff --git a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-006.html.ini b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-006.html.ini deleted file mode 100644 index f8a8cae0ae5..00000000000 --- a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-dynamic-006.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[scrollable-overflow-transform-dynamic-006.html] - [Check scrollWidth before and after removeChild() and transform chage] - expected: FAIL - - [Check scrollHeight before and after removeChild() and transform chage] - expected: FAIL - - [Check scrollWidth and scrollHeight before and after removeChild() and transform chage] - expected: FAIL diff --git a/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-unreachable-region.html.ini b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-unreachable-region.html.ini new file mode 100644 index 00000000000..0a46e380a0b --- /dev/null +++ b/tests/wpt/meta/css/css-overflow/scrollable-overflow-transform-unreachable-region.html.ini @@ -0,0 +1,168 @@ +[scrollable-overflow-transform-unreachable-region.html] + [scrollWidth of display: flow-root; direction: ltr; writing-mode: vertical-rl; flex-direction: row; flex-wrap: nowrap;] + expected: FAIL + + [scrollWidth of display: flow-root; direction: rtl; writing-mode: vertical-lr; flex-direction: row; flex-wrap: nowrap;] + expected: FAIL + + [scrollHeight of display: flow-root; direction: rtl; writing-mode: vertical-lr; flex-direction: row; flex-wrap: nowrap;] + expected: FAIL + + [scrollHeight of display: flow-root; direction: rtl; writing-mode: vertical-rl; flex-direction: row; flex-wrap: nowrap;] + expected: FAIL + + [scrollWidth of display: flex; direction: ltr; writing-mode: vertical-rl; flex-direction: row; flex-wrap: nowrap;] + expected: FAIL + + [scrollWidth of display: flex; direction: rtl; writing-mode: vertical-lr; flex-direction: row; flex-wrap: nowrap;] + expected: FAIL + + [scrollHeight of display: flex; direction: rtl; writing-mode: vertical-lr; flex-direction: row; flex-wrap: nowrap;] + expected: FAIL + + [scrollHeight of display: flex; direction: rtl; writing-mode: vertical-rl; flex-direction: row; flex-wrap: nowrap;] + expected: FAIL + + [scrollHeight of display: flex; direction: ltr; writing-mode: horizontal-tb; flex-direction: row; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollWidth of display: flex; direction: ltr; writing-mode: vertical-lr; flex-direction: row; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollHeight of display: flex; direction: rtl; writing-mode: horizontal-tb; flex-direction: row; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollHeight of display: flex; direction: rtl; writing-mode: vertical-lr; flex-direction: row; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollWidth of display: flex; direction: rtl; writing-mode: vertical-rl; flex-direction: row; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollHeight of display: flex; direction: rtl; writing-mode: vertical-rl; flex-direction: row; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollWidth of display: flex; direction: ltr; writing-mode: horizontal-tb; flex-direction: row-reverse; flex-wrap: nowrap;] + expected: FAIL + + [scrollHeight of display: flex; direction: ltr; writing-mode: vertical-lr; flex-direction: row-reverse; flex-wrap: nowrap;] + expected: FAIL + + [scrollWidth of display: flex; direction: ltr; writing-mode: vertical-rl; flex-direction: row-reverse; flex-wrap: nowrap;] + expected: FAIL + + [scrollHeight of display: flex; direction: ltr; writing-mode: vertical-rl; flex-direction: row-reverse; flex-wrap: nowrap;] + expected: FAIL + + [scrollWidth of display: flex; direction: rtl; writing-mode: horizontal-tb; flex-direction: row-reverse; flex-wrap: nowrap;] + expected: FAIL + + [scrollWidth of display: flex; direction: rtl; writing-mode: vertical-lr; flex-direction: row-reverse; flex-wrap: nowrap;] + expected: FAIL + + [scrollWidth of display: flex; direction: ltr; writing-mode: horizontal-tb; flex-direction: row-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollHeight of display: flex; direction: ltr; writing-mode: horizontal-tb; flex-direction: row-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollWidth of display: flex; direction: ltr; writing-mode: vertical-lr; flex-direction: row-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollHeight of display: flex; direction: ltr; writing-mode: vertical-lr; flex-direction: row-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollHeight of display: flex; direction: ltr; writing-mode: vertical-rl; flex-direction: row-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollWidth of display: flex; direction: rtl; writing-mode: horizontal-tb; flex-direction: row-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollHeight of display: flex; direction: rtl; writing-mode: horizontal-tb; flex-direction: row-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollWidth of display: flex; direction: rtl; writing-mode: vertical-rl; flex-direction: row-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollWidth of display: flex; direction: ltr; writing-mode: vertical-rl; flex-direction: column; flex-wrap: nowrap;] + expected: FAIL + + [scrollWidth of display: flex; direction: rtl; writing-mode: vertical-lr; flex-direction: column; flex-wrap: nowrap;] + expected: FAIL + + [scrollHeight of display: flex; direction: rtl; writing-mode: vertical-lr; flex-direction: column; flex-wrap: nowrap;] + expected: FAIL + + [scrollHeight of display: flex; direction: rtl; writing-mode: vertical-rl; flex-direction: column; flex-wrap: nowrap;] + expected: FAIL + + [scrollWidth of display: flex; direction: ltr; writing-mode: horizontal-tb; flex-direction: column; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollHeight of display: flex; direction: ltr; writing-mode: vertical-lr; flex-direction: column; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollWidth of display: flex; direction: ltr; writing-mode: vertical-rl; flex-direction: column; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollHeight of display: flex; direction: ltr; writing-mode: vertical-rl; flex-direction: column; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollWidth of display: flex; direction: rtl; writing-mode: horizontal-tb; flex-direction: column; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollWidth of display: flex; direction: rtl; writing-mode: vertical-lr; flex-direction: column; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollHeight of display: flex; direction: ltr; writing-mode: horizontal-tb; flex-direction: column-reverse; flex-wrap: nowrap;] + expected: FAIL + + [scrollWidth of display: flex; direction: ltr; writing-mode: vertical-lr; flex-direction: column-reverse; flex-wrap: nowrap;] + expected: FAIL + + [scrollHeight of display: flex; direction: rtl; writing-mode: horizontal-tb; flex-direction: column-reverse; flex-wrap: nowrap;] + expected: FAIL + + [scrollHeight of display: flex; direction: rtl; writing-mode: vertical-lr; flex-direction: column-reverse; flex-wrap: nowrap;] + expected: FAIL + + [scrollWidth of display: flex; direction: rtl; writing-mode: vertical-rl; flex-direction: column-reverse; flex-wrap: nowrap;] + expected: FAIL + + [scrollHeight of display: flex; direction: rtl; writing-mode: vertical-rl; flex-direction: column-reverse; flex-wrap: nowrap;] + expected: FAIL + + [scrollWidth of display: flex; direction: ltr; writing-mode: horizontal-tb; flex-direction: column-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollHeight of display: flex; direction: ltr; writing-mode: horizontal-tb; flex-direction: column-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollWidth of display: flex; direction: ltr; writing-mode: vertical-lr; flex-direction: column-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollHeight of display: flex; direction: ltr; writing-mode: vertical-lr; flex-direction: column-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollHeight of display: flex; direction: ltr; writing-mode: vertical-rl; flex-direction: column-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollWidth of display: flex; direction: rtl; writing-mode: horizontal-tb; flex-direction: column-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollHeight of display: flex; direction: rtl; writing-mode: horizontal-tb; flex-direction: column-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollWidth of display: flex; direction: rtl; writing-mode: vertical-rl; flex-direction: column-reverse; flex-wrap: wrap-reverse;] + expected: FAIL + + [scrollWidth of display: grid; direction: ltr; writing-mode: vertical-rl; flex-direction: row; flex-wrap: nowrap;] + expected: FAIL + + [scrollWidth of display: grid; direction: rtl; writing-mode: vertical-lr; flex-direction: row; flex-wrap: nowrap;] + expected: FAIL + + [scrollHeight of display: grid; direction: rtl; writing-mode: vertical-lr; flex-direction: row; flex-wrap: nowrap;] + expected: FAIL + + [scrollHeight of display: grid; direction: rtl; writing-mode: vertical-rl; flex-direction: row; flex-wrap: nowrap;] + expected: FAIL diff --git a/tests/wpt/meta/css/css-will-change/will-change-fixedpos-cb-003.html.ini b/tests/wpt/meta/css/css-will-change/will-change-fixedpos-cb-003.html.ini deleted file mode 100644 index 77a5d26e728..00000000000 --- a/tests/wpt/meta/css/css-will-change/will-change-fixedpos-cb-003.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[will-change-fixedpos-cb-003.html] - expected: FAIL diff --git a/tests/wpt/meta/css/cssom-view/scrollWidthHeight-negative-margin-001.html.ini b/tests/wpt/meta/css/cssom-view/scrollWidthHeight-negative-margin-001.html.ini deleted file mode 100644 index 01bd97ce10d..00000000000 --- a/tests/wpt/meta/css/cssom-view/scrollWidthHeight-negative-margin-001.html.ini +++ /dev/null @@ -1,12 +0,0 @@ -[scrollWidthHeight-negative-margin-001.html] - [scrollWidth/Height with negative margins: overflow: visible;] - expected: FAIL - - [scrollWidth/Height with negative margins: overflow: hidden;] - expected: FAIL - - [scrollWidth/Height with negative margins: overflow: auto;] - expected: FAIL - - [scrollWidth/Height with negative margins: overflow: clip;] - expected: FAIL diff --git a/tests/wpt/meta/css/cssom-view/scrollWidthHeight-negative-margin-002.html.ini b/tests/wpt/meta/css/cssom-view/scrollWidthHeight-negative-margin-002.html.ini index e92445207b7..531b67bb161 100644 --- a/tests/wpt/meta/css/cssom-view/scrollWidthHeight-negative-margin-002.html.ini +++ b/tests/wpt/meta/css/cssom-view/scrollWidthHeight-negative-margin-002.html.ini @@ -121,97 +121,97 @@ expected: FAIL [scrollWidth with negative margins: display: flex; overflow: visible; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: visible; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: hidden; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: hidden; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: auto; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: auto; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: scroll; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: scroll; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: visible; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: visible; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: hidden; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: hidden; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: auto; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: auto; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: scroll; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: scroll; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: visible; direction: ltr; flex-flow: wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: visible; direction: ltr; flex-flow: wrap-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: hidden; direction: ltr; flex-flow: wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: hidden; direction: ltr; flex-flow: wrap-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: auto; direction: ltr; flex-flow: wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: auto; direction: ltr; flex-flow: wrap-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: scroll; direction: ltr; flex-flow: wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: scroll; direction: ltr; flex-flow: wrap-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: visible; direction: rtl; flex-flow: wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: visible; direction: rtl; flex-flow: wrap-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: hidden; direction: rtl; flex-flow: wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: hidden; direction: rtl; flex-flow: wrap-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: auto; direction: rtl; flex-flow: wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: auto; direction: rtl; flex-flow: wrap-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: scroll; direction: rtl; flex-flow: wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: scroll; direction: rtl; flex-flow: wrap-reverse;] expected: FAIL @@ -220,49 +220,49 @@ expected: FAIL [scrollHeight with negative margins: display: flex; overflow: visible; direction: ltr; flex-direction: row-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: hidden; direction: ltr; flex-direction: row-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: hidden; direction: ltr; flex-direction: row-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: auto; direction: ltr; flex-direction: row-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: auto; direction: ltr; flex-direction: row-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: scroll; direction: ltr; flex-direction: row-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: scroll; direction: ltr; flex-direction: row-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: visible; direction: rtl; flex-direction: row-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: visible; direction: rtl; flex-direction: row-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: hidden; direction: rtl; flex-direction: row-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: hidden; direction: rtl; flex-direction: row-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: auto; direction: rtl; flex-direction: row-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: auto; direction: rtl; flex-direction: row-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: scroll; direction: rtl; flex-direction: row-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: scroll; direction: rtl; flex-direction: row-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: visible; direction: ltr; flex-flow: row-reverse wrap-reverse;] expected: FAIL @@ -313,145 +313,145 @@ expected: FAIL [scrollWidth with negative margins: display: flex; overflow: visible; direction: ltr; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: visible; direction: ltr; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: hidden; direction: ltr; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: hidden; direction: ltr; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: auto; direction: ltr; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: auto; direction: ltr; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: scroll; direction: ltr; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: scroll; direction: ltr; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: visible; direction: rtl; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: visible; direction: rtl; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: hidden; direction: rtl; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: hidden; direction: rtl; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: auto; direction: rtl; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: auto; direction: rtl; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: scroll; direction: rtl; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: scroll; direction: rtl; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: visible; direction: ltr; flex-flow: column wrap-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: visible; direction: ltr; flex-flow: column wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: hidden; direction: ltr; flex-flow: column wrap-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: hidden; direction: ltr; flex-flow: column wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: auto; direction: ltr; flex-flow: column wrap-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: auto; direction: ltr; flex-flow: column wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: scroll; direction: ltr; flex-flow: column wrap-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: scroll; direction: ltr; flex-flow: column wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: visible; direction: rtl; flex-flow: column wrap-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: visible; direction: rtl; flex-flow: column wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: hidden; direction: rtl; flex-flow: column wrap-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: hidden; direction: rtl; flex-flow: column wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: auto; direction: rtl; flex-flow: column wrap-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: auto; direction: rtl; flex-flow: column wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: scroll; direction: rtl; flex-flow: column wrap-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: scroll; direction: rtl; flex-flow: column wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: visible; direction: ltr; flex-direction: column-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: visible; direction: ltr; flex-direction: column-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: hidden; direction: ltr; flex-direction: column-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: hidden; direction: ltr; flex-direction: column-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: auto; direction: ltr; flex-direction: column-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: auto; direction: ltr; flex-direction: column-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: scroll; direction: ltr; flex-direction: column-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: scroll; direction: ltr; flex-direction: column-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: visible; direction: rtl; flex-direction: column-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: visible; direction: rtl; flex-direction: column-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: hidden; direction: rtl; flex-direction: column-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: hidden; direction: rtl; flex-direction: column-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: auto; direction: rtl; flex-direction: column-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: auto; direction: rtl; flex-direction: column-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: scroll; direction: rtl; flex-direction: column-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: scroll; direction: rtl; flex-direction: column-reverse;] expected: FAIL @@ -505,85 +505,70 @@ expected: FAIL [scrollWidth with negative margins: display: flow-root; overflow: visible; direction: ltr; flex-direction: row;] - expected: FAIL - - [scrollHeight with negative margins: display: flow-root; overflow: visible; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flow-root; overflow: hidden; direction: ltr; flex-direction: row;] - expected: FAIL - - [scrollHeight with negative margins: display: flow-root; overflow: hidden; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flow-root; overflow: auto; direction: ltr; flex-direction: row;] - expected: FAIL - - [scrollHeight with negative margins: display: flow-root; overflow: auto; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flow-root; overflow: scroll; direction: ltr; flex-direction: row;] - expected: FAIL - - [scrollHeight with negative margins: display: flow-root; overflow: scroll; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flow-root; overflow: visible; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flow-root; overflow: visible; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flow-root; overflow: hidden; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flow-root; overflow: hidden; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flow-root; overflow: auto; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flow-root; overflow: auto; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flow-root; overflow: scroll; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flow-root; overflow: scroll; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flow-root; overflow: clip; direction: ltr; flex-direction: row;] - expected: FAIL - - [scrollHeight with negative margins: display: flow-root; overflow: clip; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flow-root; overflow: clip; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flow-root; overflow: clip; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: clip; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: clip; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: clip; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: clip; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: clip; direction: ltr; flex-flow: wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: clip; direction: ltr; flex-flow: wrap-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: clip; direction: rtl; flex-flow: wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: clip; direction: rtl; flex-flow: wrap-reverse;] expected: FAIL @@ -592,13 +577,13 @@ expected: FAIL [scrollHeight with negative margins: display: flex; overflow: clip; direction: ltr; flex-direction: row-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: clip; direction: rtl; flex-direction: row-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: clip; direction: rtl; flex-direction: row-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: clip; direction: ltr; flex-flow: row-reverse wrap-reverse;] expected: FAIL @@ -613,37 +598,37 @@ expected: FAIL [scrollWidth with negative margins: display: flex; overflow: clip; direction: ltr; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: clip; direction: ltr; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: clip; direction: rtl; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: clip; direction: rtl; flex-direction: column;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: clip; direction: ltr; flex-flow: column wrap-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: clip; direction: ltr; flex-flow: column wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: clip; direction: rtl; flex-flow: column wrap-reverse;] expected: FAIL [scrollHeight with negative margins: display: flex; overflow: clip; direction: rtl; flex-flow: column wrap-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: flex; overflow: clip; direction: ltr; flex-direction: column-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: clip; direction: ltr; flex-direction: column-reverse;] expected: FAIL [scrollWidth with negative margins: display: flex; overflow: clip; direction: rtl; flex-direction: column-reverse;] - expected: FAIL + expected: [FAIL, PASS] [scrollHeight with negative margins: display: flex; overflow: clip; direction: rtl; flex-direction: column-reverse;] expected: FAIL @@ -661,61 +646,46 @@ expected: FAIL [scrollWidth with negative margins: display: grid; overflow: visible; direction: ltr; flex-direction: row;] - expected: FAIL - - [scrollHeight with negative margins: display: grid; overflow: visible; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: grid; overflow: hidden; direction: ltr; flex-direction: row;] - expected: FAIL - - [scrollHeight with negative margins: display: grid; overflow: hidden; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: grid; overflow: auto; direction: ltr; flex-direction: row;] - expected: FAIL - - [scrollHeight with negative margins: display: grid; overflow: auto; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: grid; overflow: clip; direction: ltr; flex-direction: row;] - expected: FAIL - - [scrollHeight with negative margins: display: grid; overflow: clip; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: grid; overflow: scroll; direction: ltr; flex-direction: row;] - expected: FAIL - - [scrollHeight with negative margins: display: grid; overflow: scroll; direction: ltr; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: grid; overflow: visible; direction: rtl; flex-direction: row;] expected: FAIL [scrollHeight with negative margins: display: grid; overflow: visible; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: grid; overflow: hidden; direction: rtl; flex-direction: row;] expected: FAIL [scrollHeight with negative margins: display: grid; overflow: hidden; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: grid; overflow: auto; direction: rtl; flex-direction: row;] expected: FAIL [scrollHeight with negative margins: display: grid; overflow: auto; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: grid; overflow: clip; direction: rtl; flex-direction: row;] expected: FAIL [scrollHeight with negative margins: display: grid; overflow: clip; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] [scrollWidth with negative margins: display: grid; overflow: scroll; direction: rtl; flex-direction: row;] expected: FAIL [scrollHeight with negative margins: display: grid; overflow: scroll; direction: rtl; flex-direction: row;] - expected: FAIL + expected: [FAIL, PASS] diff --git a/tests/wpt/meta/css/cssom-view/table-scroll-props.html.ini b/tests/wpt/meta/css/cssom-view/table-scroll-props.html.ini new file mode 100644 index 00000000000..745c51cd4c7 --- /dev/null +++ b/tests/wpt/meta/css/cssom-view/table-scroll-props.html.ini @@ -0,0 +1,6 @@ +[table-scroll-props.html] + [Table with separated border] + expected: FAIL + + [Table with collapsed border] + expected: FAIL diff --git a/tests/wpt/meta/css/filter-effects/filtered-html-is-not-container.html.ini b/tests/wpt/meta/css/filter-effects/filtered-html-is-not-container.html.ini deleted file mode 100644 index b366310b98b..00000000000 --- a/tests/wpt/meta/css/filter-effects/filtered-html-is-not-container.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[filtered-html-is-not-container.html] - expected: FAIL diff --git a/tests/wpt/meta/dom/nodes/insertion-removing-steps/blur-event.window.js.ini b/tests/wpt/meta/dom/nodes/insertion-removing-steps/blur-event.window.js.ini deleted file mode 100644 index 9b57360d600..00000000000 --- a/tests/wpt/meta/dom/nodes/insertion-removing-steps/blur-event.window.js.ini +++ /dev/null @@ -1,2 +0,0 @@ -[blur-event.window.html] - expected: CRASH diff --git a/tests/wpt/meta/html/canvas/element/canvas-host/2d.canvas.host.size.large.html.ini b/tests/wpt/meta/html/canvas/element/canvas-host/2d.canvas.host.size.large.html.ini deleted file mode 100644 index f6455f9bd76..00000000000 --- a/tests/wpt/meta/html/canvas/element/canvas-host/2d.canvas.host.size.large.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[2d.canvas.host.size.large.html] - expected: CRASH diff --git a/tests/wpt/meta/html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.html.ini b/tests/wpt/meta/html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.html.ini deleted file mode 100644 index f6455f9bd76..00000000000 --- a/tests/wpt/meta/html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[2d.canvas.host.size.large.html] - expected: CRASH diff --git a/tests/wpt/meta/html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.worker.js.ini b/tests/wpt/meta/html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.worker.js.ini deleted file mode 100644 index d571dfa4cf9..00000000000 --- a/tests/wpt/meta/html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.worker.js.ini +++ /dev/null @@ -1,2 +0,0 @@ -[2d.canvas.host.size.large.worker.html] - expected: CRASH diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index d3a939eab57..4262fa5aca3 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -25,6 +25,13 @@ {} ] ], + "form_reset-crash.html": [ + "b23cbf6aefdef8231e2cc4cb0e6416195d5bdf71", + [ + null, + {} + ] + ], "global-enumerate-crash.html": [ "a77e79b1465bf7555340dd5e9bf94a4c8caa85f2", [ diff --git a/tests/wpt/mozilla/tests/mozilla/form_reset-crash.html b/tests/wpt/mozilla/tests/mozilla/form_reset-crash.html new file mode 100644 index 00000000000..b23cbf6aefd --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/form_reset-crash.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<form id="form"> + <output><textarea></textarea></output> +</form> +<script> +form.reset(); +</script> diff --git a/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-004.html b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-004.html new file mode 100644 index 00000000000..b398167fa30 --- /dev/null +++ b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-004.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Overflow: Scrollable Overflow Transform Scroll Container</title> +<link rel="author" title="Jo Steven Novaryo" href="mailto:steven.novaryo@gmail.com"> +<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable" /> +<meta name="assert" content="Checks that the box of scroll container with transform contribute to the scrollable overflow."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<style> + .container { + width: 100px; + height: 100px; + overflow: auto; + background: silver; + border: solid thick; + scrollbar-width: none; + } + + .element { + width: 50px; + height: 50px; + overflow: scroll; + background: lime; + } + + .element-content { + width: 500px; + height: 500px; + background: aqua; + } +</style> +<body onload="checkLayout('.container')"> + + <div class="container" data-expected-scroll-width="250"> + <div style="transform: translateX(200px);" class="element"> + <div class="element-content"></div> + </div> + </div> + + <div class="container" data-expected-scroll-height="350"> + <div style="transform: translateY(300px);" class="element"> + <div class="element-content"></div> + </div> + </div> + + <div class="container" data-expected-scroll-width="250" data-expected-scroll-height="350"> + <div style="transform: translate(200px, 300px);" class="element"> + <div class="element-content"></div> + </div> + </div> + +</body> diff --git a/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-005.tentative.html b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-005.tentative.html new file mode 100644 index 00000000000..837b95ba96d --- /dev/null +++ b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-005.tentative.html @@ -0,0 +1,68 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Overflow: Scrollable Overflow Transform Exclusion of Untransformed Child Box</title> +<link rel="author" title="Jo Steven Novaryo" href="mailto:steven.novaryo@gmail.com"> +<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable"/> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/12113"/> +<meta name="assert" content="Checks that the untransformed child box is not included in scrollable overflow."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<style> + .container { + width: 100px; + height: 100px; + overflow: scroll; + background: silver; + border: solid thick; + scrollbar-width: none; + } + + .element { + width: 200px; + height: 200px; + background: lime; + } + + .element-2 { + width: 100px; + height: 100px; + } +</style> +<body onload="checkLayout('.container')"> + + <div class="container" data-expected-scroll-width="100" data-expected-scroll-height="100"> + <div style="transform: translate(-200px, -200px);" class="element"> + </div> + </div> + + <div class="container" data-expected-scroll-width="150" data-expected-scroll-height="150"> + <div style="transform: translate(-25%, -25%);" class="element"> + </div> + </div> + + <div class="container" data-expected-scroll-height="100" data-expected-scroll-height="100"> + <div style="width: 100px; height: 100px;"> + <div style="transform: translate(-200px, -200px);" class="element"> + </div> + </div> + </div> + + <div class="container" data-expected-scroll-width="150" data-expected-scroll-height="150"> + <div style="width: 100px; height: 100px;"> + <div style="transform: translate(-25%, -25%);" class="element"> + </div> + </div> + </div> + + <div class="container" style="position: relative;" data-expected-scroll-width="100" data-expected-scroll-height="100"> + <div style="transform: translate(-200px, -200px); position: absolute;" class="element"> + </div> + </div> + + <div class="container" style="position: relative;" data-expected-scroll-width="150" data-expected-scroll-height="150"> + <div style="transform: translate(-25%, -25%); position: absolute;" class="element"> + </div> + </div> + +</body> diff --git a/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-006.html b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-006.html new file mode 100644 index 00000000000..2eea759da6a --- /dev/null +++ b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-006.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Overflow: Scrollable Overflow Transform Rotate</title> +<link rel="author" title="Jo Steven Novaryo" href="mailto:steven.novaryo@gmail.com"> +<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable" /> +<meta name="assert" content="Checks that the bounding rectangle of rotated element is included correctly in scrollable overflow."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<style> + .container { + width: 100px; + height: 100px; + overflow: scroll; + background: silver; + border: solid thick; + scrollbar-width: none; + } + + .element { + width: 200px; + height: 200px; + background: lime; + } + + .element-2 { + width: 200px; + height: 200px; + background: aqua; + } +</style> +<body onload="checkLayout('.container')"> + + <div class="container" data-expected-scroll-width="241" data-expected-scroll-height="241"> + <div style="transform: rotate(45deg);" class="element"> + </div> + </div> + + <div class="container" data-expected-scroll-width="241" data-expected-scroll-height="241"> + <div style="transform: rotate(-45deg);" class="element"> + </div> + </div> + +</body> diff --git a/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-007.html b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-007.html new file mode 100644 index 00000000000..8aa6e5f17d8 --- /dev/null +++ b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-007.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Overflow: Scrollable Overflow Transform Scale</title> +<link rel="author" title="Jo Steven Novaryo" href="mailto:steven.novaryo@gmail.com"> +<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable" /> +<meta name="assert" content="Checks that the bounding rectangle of scaled element is included correctly in scrollable overflow."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<style> + .container { + width: 100px; + height: 100px; + overflow: scroll; + background: silver; + border: solid thick; + scrollbar-width: none; + } + + .element { + width: 200px; + height: 200px; + background: lime; + } + + .element-2 { + width: 200px; + height: 200px; + background: aqua; + } +</style> +<body onload="checkLayout('.container')"> + + <div class="container" data-expected-scroll-width="300" data-expected-scroll-height="300"> + <div style="transform: scale(2);" class="element"> + </div> + </div> + + <div class="container" data-expected-scroll-height="250" data-expected-scroll-height="250"> + <div style="transform: scale(0.5);" class="element"> + <div style="transform: scale(3);" class="element-2"> + </div> + </div> + </div> + +</body> diff --git a/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-008.html b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-008.html new file mode 100644 index 00000000000..df1daeb8424 --- /dev/null +++ b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-008.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Overflow: Scrollable Overflow Transform Skew</title> +<link rel="author" title="Jo Steven Novaryo" href="mailto:steven.novaryo@gmail.com"> +<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable" /> +<meta name="assert" content="Checks that the bounding rectangle of skewed element is included correctly in scrollable overflow."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<style> + .container { + width: 100px; + height: 100px; + overflow: scroll; + background: silver; + border: solid thick; + scrollbar-width: none; + } + + .element { + width: 200px; + height: 200px; + background: lime; + } + + .element-2 { + width: 200px; + height: 200px; + background: aqua; + } +</style> +<body onload="checkLayout('.container')"> + + <div class="container" data-expected-scroll-width="227" data-expected-scroll-height="227"> + <div style="transform: skew(-15deg, -15deg);" class="element"> + </div> + </div> + + <div class="container" data-expected-scroll-width="227" data-expected-scroll-height="227"> + <div style="transform: skew(15deg, 15deg);" class="element"> + </div> + </div> + +</body> diff --git a/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-009.html b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-009.html new file mode 100644 index 00000000000..aca1b28418a --- /dev/null +++ b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-009.html @@ -0,0 +1,65 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Overflow: Scrollable Overflow Transform Unreachable Scrollable Overflow</title> +<link rel="author" title="Jo Steven Novaryo" href="mailto:steven.novaryo@gmail.com"> +<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable" /> +<meta name="assert" content="Checks that the box in unreachable scrollable overflow region with transform is not included in the calculation."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<style> + .container { + width: 100px; + height: 100px; + overflow: scroll; + background: silver; + border: solid thick; + scrollbar-width: none; + } + + .relative { + position: relative; + } + + .absolute { + position: absolute; + } + + .element { + width: 100px; + height: 100px; + background: lime; + } +</style> +<body onload="checkLayout('.container')"> + <div class="container" data-expected-scroll-width="100" data-expected-scroll-height="100"> + <div style="transform: translate(-300px, -300px);" class="element"> + </div> + </div> + + <div class="container" data-expected-scroll-width="100" data-expected-scroll-height="100"> + <div style="transform: translate(300px, -300px);" class="element"> + </div> + </div> + + <div class="container" data-expected-scroll-width="100" data-expected-scroll-height="100"> + <div style="transform: translate(-300px, 300px);" class="element"> + </div> + </div> + + <div class="container relative" data-expected-scroll-width="100" data-expected-scroll-height="100"> + <div style="transform: translate(-300px, -300px);" class="element absolute"> + </div> + </div> + + <div class="container relative" data-expected-scroll-width="100" data-expected-scroll-height="100"> + <div style="transform: translate(300px, -300px);" class="element absolute"> + </div> + </div> + + <div class="container relative" data-expected-scroll-width="100" data-expected-scroll-height="100"> + <div style="transform: translate(-300px, 300px);" class="element absolute"> + </div> + </div> + +</body> diff --git a/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-010.tentative.html b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-010.tentative.html new file mode 100644 index 00000000000..e2c62cb4474 --- /dev/null +++ b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-010.tentative.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Overflow: Scrollable Overflow Transform Rotate Nested Element</title> +<link rel="author" title="Jo Steven Novaryo" href="mailto:steven.novaryo@gmail.com"> +<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable"/> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/12112"/> +<meta name="assert" content="Checks that the bounding rectangle of nested rotated element is included correctly in scrollable overflow."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<style> + .container { + width: 100px; + height: 100px; + overflow: scroll; + background: silver; + border: solid thick; + scrollbar-width: none; + } + + .element { + width: 200px; + height: 200px; + background: lime; + } + + .element-2 { + width: 200px; + height: 200px; + background: aqua; + } +</style> +<body onload="checkLayout('.container')"> + + <div class="container" data-expected-scroll-height="241" data-expected-scroll-height="241"> + <div style="transform: rotate(-45deg);" class="element"> + <div style="transform: rotate(45deg);" class="element-2"> + </div> + </div> + </div> + + <div class="container" data-expected-scroll-height="222" data-expected-scroll-height="222"> + <div style="transform: rotate(30deg) rotate(-15deg);" class="element"> + <div style="transform: rotate(-30deg) rotate(105deg);" class="element-2"> + </div> + </div> + </div> + +</body> diff --git a/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-unreachable-region.html b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-unreachable-region.html new file mode 100644 index 00000000000..91e987bf826 --- /dev/null +++ b/tests/wpt/tests/css/css-overflow/scrollable-overflow-transform-unreachable-region.html @@ -0,0 +1,95 @@ +<!doctype html> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width,initial-scale=1"> +<title>Scrollable Overflow of a Scroll Container with Transformed Child in Unreachable Scrollable Overflow Region.</title> +<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#unreachable-scrollable-overflow-region"> +<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable"> +<link rel="author" title="Jo Steven Novaryo" href="mailto:steven.novaryo@gmail.com"> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<style> +body { margin: 0 } +.wrapper { + width: 100px; + height: 200px; + overflow: scroll; +} +.inner { + width: 100px; + height: 200px; + background-color: lime; + transform: translate(-3px, -6px) scale(1.10); +} +</style> +<div class="wrapper"> + <div class="inner"></div> +</div> +<script> +const wrapper = document.querySelector(".wrapper"); +const contentBox = { + width: 100, + height: 200, +}; + +function getCurrentTestName(display, direction, writingMode, flexDirection, flexWrap) { + return `display: ${display}; ` + + `direction: ${direction}; ` + + `writing-mode: ${writingMode}; ` + + `flex-direction: ${flexDirection}; ` + + `flex-wrap: ${flexWrap};`; +} + +for (let display of ["flow-root", "flex", "grid"]) { + for (let flexDirection of ["row", "row-reverse", "column", "column-reverse"]) { + if (flexDirection != "row" && display != "flex") { + // Don't bother retesting with all flexDirection values unless we're actually a flex container + continue; + } + for (let flexWrap of ["nowrap", "wrap-reverse"]) { + if (flexWrap != "nowrap" && display != "flex") { + // Don't bother retesting with all flexWrap values unless we're actually a flex container + continue; + } + for (let direction of ["ltr", "rtl"]) { + for (let writingMode of ["horizontal-tb", "vertical-lr", "vertical-rl"]) { + wrapper.style.display = display; + wrapper.style.direction = direction; + wrapper.style.writingMode = writingMode; + wrapper.style.flexDirection = flexDirection; + wrapper.style.flexWrap = flexWrap; + // Suppress scrollbars because they get added to the padding are + // and would need to account for them in flexbox. + wrapper.style.scrollbarWidth = display == "flex" ? "none" : ""; + let vertical = writingMode.startsWith("vertical"); + let scrollToTop = vertical && direction == "rtl"; + let scrollToLeft = (!vertical && direction == "rtl") || writingMode == "vertical-rl"; + let flexMainAxisIsVertical = flexDirection.startsWith("row") == vertical; + if (display == "flex") { + if (flexDirection.endsWith("-reverse")) { + if (flexMainAxisIsVertical) { + scrollToTop = !scrollToTop; + } else { + scrollToLeft = !scrollToLeft; + } + } + if (flexWrap == "wrap-reverse") { + if (flexMainAxisIsVertical) { + scrollToLeft = !scrollToLeft; + } else { + scrollToTop = !scrollToTop; + } + } + } + currentTestName = getCurrentTestName(display, direction, writingMode, flexDirection, flexWrap); + test(function() { + assert_equals(wrapper.scrollWidth, (scrollToLeft ? 108 : 102), "scrollWidth"); + }, "scrollWidth of " + currentTestName); + test(function() { + assert_equals(wrapper.scrollHeight, (scrollToTop ? 216 : 204), "scrollHeight"); + }, "scrollHeight of " + currentTestName); + } + } + } + } +} +</script> diff --git a/tests/wpt/tests/focus/focus-element-crash.html b/tests/wpt/tests/focus/focus-element-crash.html new file mode 100644 index 00000000000..27df1c0b130 --- /dev/null +++ b/tests/wpt/tests/focus/focus-element-crash.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<meta charset="utf-8"> +<meta name="assert" content="focus element adopted or remounted shouldn't crash."> + +<body> + +<!--focus element remounted test case--> +<audio onloadstart="select.focus()" src=""></audio> +<iframe id="iframe"></iframe> +<table id="table"> + <td> + <select id="select" onblur=";"></select> + </td> +</table> +<script> + window.addEventListener("load", _ => iframe.appendChild(table)); +</script> + +<!--focus element adopted test case--> +<input id="username" type="text" placeholder="username"> +<input id="password" type="text" placeholder="password"> +</body> +<script> + let search = document.getElementById("search"); + let username = document.getElementById("username"); + username.focus(); + window.onload = () => document.adoptNode(username); + username.addEventListener("blur", function (e) { + document.body.append(`event:${e.type} fire.`) + }); +</script> +</html> |