diff options
20 files changed, 114 insertions, 44 deletions
diff --git a/Cargo.lock b/Cargo.lock index 01b372a631c..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", ] 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/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 33a22cdf438..023db6b07f1 100644 --- a/components/layout/style_ext.rs +++ b/components/layout/style_ext.rs @@ -845,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; } 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/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/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/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index 8ba5d8b0ff6..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": [ 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/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/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/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> |