aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock4
-rw-r--r--components/layout/flexbox/layout.rs9
-rw-r--r--components/layout/flow/float.rs3
-rw-r--r--components/layout/flow/inline/line.rs3
-rw-r--r--components/layout/flow/inline/mod.rs3
-rw-r--r--components/layout/flow/mod.rs4
-rw-r--r--components/layout/positioned.rs36
-rw-r--r--components/layout/style_ext.rs6
-rw-r--r--components/layout/table/layout.rs6
-rw-r--r--components/layout/taffy/layout.rs5
-rw-r--r--components/script/dom/document.rs4
-rw-r--r--components/script/dom/htmlformelement.rs10
-rw-r--r--components/script/script_thread.rs3
-rw-r--r--tests/wpt/meta/MANIFEST.json9
-rw-r--r--tests/wpt/meta/css/css-will-change/will-change-fixedpos-cb-003.html.ini2
-rw-r--r--tests/wpt/meta/css/filter-effects/filtered-html-is-not-container.html.ini2
-rw-r--r--tests/wpt/meta/dom/nodes/insertion-removing-steps/blur-event.window.js.ini2
-rw-r--r--tests/wpt/mozilla/meta/MANIFEST.json7
-rw-r--r--tests/wpt/mozilla/tests/mozilla/form_reset-crash.html7
-rw-r--r--tests/wpt/tests/focus/focus-element-crash.html33
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>