diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2023-01-11 13:41:06 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2023-01-11 14:02:23 +0000 |
commit | 01e89433adf2d5575b2089716217299519a9ce15 (patch) | |
tree | 5615c6e52f2016c227e6d936cb5005ee6f15418a /chromium/third_party/blink/renderer | |
parent | 2b11b39a6627d8c71636227374dd8f8ea78c3e6a (diff) | |
download | qtwebengine-chromium-01e89433adf2d5575b2089716217299519a9ce15.tar.gz |
BASELINE: Update Chromium to 108.0.5359.181
Change-Id: Iae2b9d190e7789ad5556dbf4c59498e05ce6e5d2
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/453305
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer')
17 files changed, 240 insertions, 122 deletions
diff --git a/chromium/third_party/blink/renderer/core/html/forms/select_type.cc b/chromium/third_party/blink/renderer/core/html/forms/select_type.cc index 838879ed33c..6a6ebf5b618 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/select_type.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/select_type.cc @@ -325,22 +325,23 @@ void MenuListSelectType::ShowPopup(PopupMenu::ShowEventType type) { gfx::Rect local_root_rect = select_->VisibleBoundsInLocalRoot(); - if (!document.GetFrame()->LocalFrameRoot().IsOutermostMainFrame()) { + if (document.GetFrame()->LocalFrameRoot().IsOutermostMainFrame()) { + gfx::Rect visual_viewport_rect = + document.GetPage()->GetVisualViewport().RootFrameToViewport( + local_root_rect); + visual_viewport_rect.Intersect( + gfx::Rect(document.GetPage()->GetVisualViewport().Size())); + if (visual_viewport_rect.IsEmpty()) + return; + } else { // TODO(bokan): If we're in a remote frame, we cannot access the active // visual viewport. VisibleBoundsInLocalRoot will clip to the outermost // main frame but if the user is pinch-zoomed this won't be accurate. + // https://crbug.com/840944. if (local_root_rect.IsEmpty()) return; } - gfx::Rect visual_viewport_rect = - document.GetPage()->GetVisualViewport().RootFrameToViewport( - local_root_rect); - visual_viewport_rect.Intersect( - gfx::Rect(document.GetPage()->GetVisualViewport().Size())); - if (visual_viewport_rect.IsEmpty()) - return; - if (!popup_) { popup_ = document.GetPage()->GetChromeClient().OpenPopupMenu( *document.GetFrame(), *select_); diff --git a/chromium/third_party/blink/renderer/core/layout/layout_box_hot.cc b/chromium/third_party/blink/renderer/core/layout/layout_box_hot.cc index 3c6534b8277..55ef128d653 100644 --- a/chromium/third_party/blink/renderer/core/layout/layout_box_hot.cc +++ b/chromium/third_party/blink/renderer/core/layout/layout_box_hot.cc @@ -312,6 +312,19 @@ const NGLayoutResult* LayoutBox::CachedLayoutResult( if (column_spanner_path || cached_layout_result->ColumnSpannerPath()) return nullptr; + // Break appeal may have been reduced because the fragment crosses the + // fragmentation line, to send a strong signal to break before it + // instead. If we actually ended up breaking before it, this break appeal + // may no longer be valid, since there could be more room in the next + // fragmentainer. Miss the cache. + // + // TODO(mstensho): Maybe this shouldn't be necessary. Look into how + // FinishFragmentation() clamps break appeal down to + // kBreakAppealLastResort. Maybe there are better ways. + if (break_token && break_token->IsBreakBefore() && + cached_layout_result->BreakAppeal() < kBreakAppealPerfect) + return nullptr; + // If the node didn't break into multiple fragments, we might be able to // re-use the result. If the fragmentainer block-size has changed, or if // the fragment's block-offset within the fragmentainer has changed, we diff --git a/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_break_token_data.h b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_break_token_data.h index 2f226d6a144..ab807d34fc0 100644 --- a/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_break_token_data.h +++ b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_break_token_data.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_BREAK_TOKEN_DATA_H_ #include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_data.h" +#include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_item.h" #include "third_party/blink/renderer/core/layout/ng/ng_block_break_token_data.h" #include "third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h" #include "third_party/blink/renderer/platform/geometry/layout_unit.h" @@ -34,6 +35,9 @@ struct NGGridBreakTokenData final : NGBlockBreakTokenData { const NGGridLayoutData& layout_data, LayoutUnit intrinsic_block_size, LayoutUnit consumed_grid_block_size, + Vector<GridItemIndices>&& column_range_indices, + Vector<GridItemIndices>&& row_range_indices, + Vector<GridArea>&& resolved_positions, const Vector<GridItemPlacementData>& grid_items_placement_data, const Vector<LayoutUnit>& row_offset_adjustments, const Vector<EBreakBetween>& row_break_between, @@ -42,6 +46,9 @@ struct NGGridBreakTokenData final : NGBlockBreakTokenData { layout_data(layout_data), intrinsic_block_size(intrinsic_block_size), consumed_grid_block_size(consumed_grid_block_size), + column_range_indices(std::move(column_range_indices)), + row_range_indices(std::move(row_range_indices)), + resolved_positions(std::move(resolved_positions)), grid_items_placement_data(grid_items_placement_data), row_offset_adjustments(row_offset_adjustments), row_break_between(row_break_between), @@ -59,7 +66,9 @@ struct NGGridBreakTokenData final : NGBlockBreakTokenData { // it isn't used for determining the final block-size of the fragment and // won't include any block-end padding (this prevents saturation bugs). LayoutUnit consumed_grid_block_size; - + Vector<GridItemIndices> column_range_indices; + Vector<GridItemIndices> row_range_indices; + Vector<GridArea> resolved_positions; Vector<GridItemPlacementData> grid_items_placement_data; Vector<LayoutUnit> row_offset_adjustments; Vector<EBreakBetween> row_break_between; diff --git a/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc index 5dd4688f0e7..aab3dfcd146 100644 --- a/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc +++ b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc @@ -116,7 +116,9 @@ NGGridProperties InitializeGridProperties( void CacheGridTrackSpanProperties( const NGGridLayoutTrackCollection& track_collection, GridItems* grid_items, - NGGridProperties* grid_properties = nullptr) { + NGGridProperties* grid_properties = nullptr, + const Vector<GridItemIndices>* range_indices = nullptr, + const Vector<GridArea>* resolved_positions = nullptr) { DCHECK(grid_items); const auto track_direction = track_collection.Direction(); @@ -144,16 +146,29 @@ void CacheGridTrackSpanProperties( CacheGridProperty(TrackSpanProperties::kIsDependentOnAvailableSize); } - auto CacheTrackSpanProperty = - [&](GridItemData& grid_item, const wtf_size_t range_index, - const TrackSpanProperties::PropertyId property) { - if (track_collection.RangeHasTrackSpanProperty(range_index, property)) - grid_item.SetTrackSpanProperty(property, track_direction); - }; - GridItems grid_items_spanning_multiple_ranges; - for (auto& grid_item : *grid_items) { - const auto& range_indices = grid_item.RangeIndices(track_direction); + for (wtf_size_t index = 0; index < grid_items->Size(); ++index) { + auto& grid_item = grid_items->At(index); + + // If positions range indices were provided, assign them before querying + // `RangeIndices` below. + if (resolved_positions && resolved_positions->size()) + grid_item.resolved_position = resolved_positions->at(index); + + if (range_indices && range_indices->size()) { + if (track_direction == kForColumns) + grid_item.column_range_indices = range_indices->at(index); + else + grid_item.row_range_indices = range_indices->at(index); + } + + const auto& item_range_indices = grid_item.RangeIndices(track_direction); + auto& track_span_properties = (track_direction == kForColumns) + ? grid_item.column_span_properties + : grid_item.row_span_properties; + + grid_item.ComputeSetIndices(track_collection); + track_span_properties.Reset(); // If a grid item spans only one range, then we can just cache the track // span properties directly. On the contrary, if a grid item spans multiple @@ -161,17 +176,9 @@ void CacheGridTrackSpanProperties( // to do more work to cache its track span properties. // // TODO(layout-dev): Investigate applying this concept to spans > 1. - if (range_indices.begin == range_indices.end) { - CacheTrackSpanProperty(grid_item, range_indices.begin, - TrackSpanProperties::kHasFlexibleTrack); - CacheTrackSpanProperty(grid_item, range_indices.begin, - TrackSpanProperties::kHasIntrinsicTrack); - CacheTrackSpanProperty(grid_item, range_indices.begin, - TrackSpanProperties::kHasAutoMinimumTrack); - CacheTrackSpanProperty(grid_item, range_indices.begin, - TrackSpanProperties::kHasFixedMinimumTrack); - CacheTrackSpanProperty(grid_item, range_indices.begin, - TrackSpanProperties::kHasFixedMaximumTrack); + if (item_range_indices.begin == item_range_indices.end) { + track_span_properties = + track_collection.RangeProperties(item_range_indices.begin); } else { grid_items_spanning_multiple_ranges.Append(&grid_item); } @@ -287,13 +294,17 @@ const NGLayoutResult* NGGridLayoutAlgorithm::LayoutInternal() { intrinsic_block_size = grid_data->intrinsic_block_size; layout_data = grid_data->layout_data; - for (auto& grid_item : grid_items) { - grid_item.ComputeSetIndices(*layout_data.Columns()); - grid_item.ComputeSetIndices(*layout_data.Rows()); - } - - CacheGridTrackSpanProperties(*layout_data.Columns(), &grid_items); - CacheGridTrackSpanProperties(*layout_data.Rows(), &grid_items); + // Update `grid_items` with resolved positions and range indices stored + // on the break token, as these are dependent on the `layout_data` above. + // + // TODO(kschmi): If these don't change between fragmentainers, we can store + // them (and Columns/Rows) on `NGGridBreakTokenData` and avoid recomputing. + CacheGridTrackSpanProperties( + *layout_data.Columns(), &grid_items, /* grid_properties */ nullptr, + &grid_data->column_range_indices, &grid_data->resolved_positions); + CacheGridTrackSpanProperties(*layout_data.Rows(), &grid_items, + /* grid_properties */ nullptr, + &grid_data->row_range_indices); } else { ComputeGridGeometry(node.CachedPlacementData(), &grid_items, &layout_data, &intrinsic_block_size); @@ -395,12 +406,21 @@ const NGLayoutResult* NGGridLayoutAlgorithm::LayoutInternal() { PlaceOutOfFlowItems(layout_data, block_size, oof_children); if (ConstraintSpace().HasBlockFragmentation()) { + Vector<GridItemIndices> column_range_indices; + Vector<GridItemIndices> row_range_indices; + Vector<GridArea> resolved_positions; + for (auto& grid_item : grid_items) { + column_range_indices.push_back(grid_item.column_range_indices); + row_range_indices.push_back(grid_item.row_range_indices); + resolved_positions.push_back(grid_item.resolved_position); + } container_builder_.SetBreakTokenData( MakeGarbageCollected<NGGridBreakTokenData>( container_builder_.GetBreakTokenData(), layout_data, intrinsic_block_size, consumed_grid_block_size, - grid_items_placement_data, row_offset_adjustments, - row_break_between, oof_children)); + std::move(column_range_indices), std::move(row_range_indices), + std::move(resolved_positions), grid_items_placement_data, + row_offset_adjustments, row_break_between, oof_children)); } // Copy grid layout data for use in computed style and devtools. @@ -442,11 +462,6 @@ MinMaxSizesResult NGGridLayoutAlgorithm::ComputeMinMaxSizes( LayoutTrackCollection(placement_data, kForColumns, &grid_items), LayoutTrackCollection(placement_data, kForRows, &grid_items)); - for (auto& grid_item : grid_items) { - grid_item.ComputeSetIndices(*layout_data.Columns()); - grid_item.ComputeSetIndices(*layout_data.Rows()); - } - auto grid_properties = InitializeGridProperties(grid_items, Style().GetWritingMode()); @@ -804,11 +819,6 @@ void NGGridLayoutAlgorithm::ComputeGridGeometry( *row_builder_collection, is_block_available_size_indefinite); } - for (auto& grid_item : *grid_items) { - grid_item.ComputeSetIndices(*layout_data->Columns()); - grid_item.ComputeSetIndices(*layout_data->Rows()); - } - auto grid_properties = InitializeGridProperties(*grid_items, container_style.GetWritingMode()); diff --git a/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc index 6d5e983c890..e6c6bd0592e 100644 --- a/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc +++ b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc @@ -517,6 +517,12 @@ wtf_size_t NGGridLayoutTrackCollection::RangeBeginSetIndex( return ranges_[range_index].begin_set_index; } +TrackSpanProperties NGGridLayoutTrackCollection::RangeProperties( + wtf_size_t range_index) const { + DCHECK_LT(range_index, ranges_.size()); + return ranges_[range_index].properties; +} + bool NGGridLayoutTrackCollection::RangeHasTrackSpanProperty( wtf_size_t range_index, TrackSpanProperties::PropertyId property_id) const { diff --git a/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h index 8070cf772b3..f0ed053a675 100644 --- a/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h +++ b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h @@ -191,6 +191,8 @@ class CORE_EXPORT NGGridLayoutTrackCollection wtf_size_t RangeSetCount(wtf_size_t range_index) const; // Return the index of the first set spanned by a given track range. wtf_size_t RangeBeginSetIndex(wtf_size_t range_index) const; + // Returns the track span properties of the range at position |range_index|. + TrackSpanProperties RangeProperties(wtf_size_t range_index) const; // Returns true if the specified property has been set in the track span // properties bitmask of the range at position |range_index|. diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h index 17b4d018433..b773e07908c 100644 --- a/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h +++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h @@ -133,14 +133,18 @@ class CORE_EXPORT NGConstraintSpaceBuilder final { space_.EnsureRareData()->fragmentainer_block_size = size; } - // Shrink the fragmentainer block-size, to reserve space at the end. This is - // needed for repeated table footers. - void ReserveSpaceAtFragmentainerEnd(LayoutUnit space) { + // Shrink the fragmentainer block-size, to reserve space for repeated table + // headers and footers. If there's a repeated header, the argument to + // SetFragmentainerOffset() also needs to be compensated for the block-size + // taken up by the repeated header, so that offset 0 is exactly where the + // non-repeated content starts / resumes after the repeated header. + void ReserveSpaceInFragmentainer(LayoutUnit space) { #if DCHECK_IS_ON() DCHECK(is_fragmentainer_block_size_set_); #endif - DCHECK_GE(space_.rare_data_->fragmentainer_block_size, space); space_.rare_data_->fragmentainer_block_size -= space; + space_.rare_data_->fragmentainer_block_size = + space_.rare_data_->fragmentainer_block_size.ClampNegativeToZero(); } void SetFragmentainerOffset(LayoutUnit offset) { diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc index e9a88ec394b..b836552378e 100644 --- a/chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc +++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc @@ -511,9 +511,9 @@ void NGContainerFragmentBuilder::PropagateOOFPositionedInfo( fixedpos_containing_block_offset = converter.ToLogical( multicol_info->fixedpos_containing_block.Offset(), fixedpos_containing_block_fragment->Size()); - fixedpos_containing_block_rel_offset = converter.ToLogical( + fixedpos_containing_block_rel_offset = RelativeInsetToLogical( multicol_info->fixedpos_containing_block.RelativeOffset(), - fixedpos_containing_block_fragment->Size()); + GetWritingDirection()); fixedpos_containing_block_rel_offset += relative_offset; // We want the fixedpos containing block offset to be the offset from // the containing block to the top of the fragmentation context root, @@ -611,9 +611,8 @@ void NGContainerFragmentBuilder::PropagateOOFFragmentainerDescendants( LogicalOffset containing_block_offset = converter.ToLogical(descendant.containing_block.Offset(), containing_block_fragment->Size()); - LogicalOffset containing_block_rel_offset = - converter.ToLogical(descendant.containing_block.RelativeOffset(), - containing_block_fragment->Size()); + LogicalOffset containing_block_rel_offset = RelativeInsetToLogical( + descendant.containing_block.RelativeOffset(), GetWritingDirection()); containing_block_rel_offset += relative_offset; if (!fragment.IsFragmentainerBox()) containing_block_offset += offset; @@ -657,9 +656,9 @@ void NGContainerFragmentBuilder::PropagateOOFFragmentainerDescendants( fixedpos_containing_block_offset = converter.ToLogical(descendant.fixedpos_containing_block.Offset(), fixedpos_containing_block_fragment->Size()); - fixedpos_containing_block_rel_offset = converter.ToLogical( + fixedpos_containing_block_rel_offset = RelativeInsetToLogical( descendant.fixedpos_containing_block.RelativeOffset(), - fixedpos_containing_block_fragment->Size()); + GetWritingDirection()); fixedpos_containing_block_rel_offset += relative_offset; if (!fragment.IsFragmentainerBox()) fixedpos_containing_block_offset += offset; diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc index 0346e37be9d..83dfd0f3c0f 100644 --- a/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc +++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc @@ -961,9 +961,9 @@ void NGOutOfFlowLayoutPart::LayoutOOFsInMulticol( fixedpos_containing_block_offset = converter.ToLogical(descendant.fixedpos_containing_block.Offset(), fixedpos_containing_block_fragment->Size()); - fixedpos_containing_block_rel_offset = converter.ToLogical( + fixedpos_containing_block_rel_offset = RelativeInsetToLogical( descendant.fixedpos_containing_block.RelativeOffset(), - fixedpos_containing_block_fragment->Size()); + writing_direction); } NGInlineContainer<LogicalOffset> inline_container( diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h index 7295d86d4d8..f1ffccc5169 100644 --- a/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h +++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h @@ -380,6 +380,20 @@ struct NGFragmentedOutOfFlowData final : NGPhysicalFragment::OutOfFlowData { MulticolCollection multicols_with_pending_oofs; }; +inline PhysicalOffset RelativeInsetToPhysical( + LogicalOffset relative_inset, + WritingDirectionMode writing_direction) { + return relative_inset.ConvertToPhysical(writing_direction, PhysicalSize(), + PhysicalSize()); +} + +inline LogicalOffset RelativeInsetToLogical( + PhysicalOffset relative_inset, + WritingDirectionMode writing_direction) { + return relative_inset.ConvertToLogical(writing_direction, PhysicalSize(), + PhysicalSize()); +} + } // namespace blink WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS( diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc index 6a920c0ec36..79b20d51a32 100644 --- a/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc +++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc @@ -102,8 +102,8 @@ NGContainingBlock<PhysicalOffset> PhysicalContainingBlock( return NGContainingBlock<PhysicalOffset>( containing_block.Offset().ConvertToPhysical( builder->Style().GetWritingDirection(), outer_size, inner_size), - containing_block.RelativeOffset().ConvertToPhysical( - builder->Style().GetWritingDirection(), outer_size, inner_size), + RelativeInsetToPhysical(containing_block.RelativeOffset(), + builder->Style().GetWritingDirection()), containing_block.Fragment(), containing_block.IsInsideColumnSpanner(), containing_block.RequiresContentBeforeBreaking()); } diff --git a/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc index c7f0000603b..92d8bfa1067 100644 --- a/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc +++ b/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc @@ -977,13 +977,12 @@ const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment( auto CreateSectionConstraintSpace = [&table_writing_direction, §ion_available_inline_size, - &constraint_space_data, §ions, - this](const NGBlockNode& section, - LayoutUnit block_offset, - wtf_size_t section_index, - absl::optional<LayoutUnit> - repeated_footer_block_size, - ESectionRepeatMode repeat_mode) { + &constraint_space_data, §ions, this]( + const NGBlockNode& section, + LayoutUnit fragmentainer_block_offset, + wtf_size_t section_index, + LayoutUnit reserved_space, + ESectionRepeatMode repeat_mode) { NGConstraintSpaceBuilder section_space_builder( ConstraintSpace(), table_writing_direction, /* is_new_fc */ true); @@ -1007,17 +1006,21 @@ const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment( section_space_builder.SetShouldRepeat(repeat_mode == kMayRepeatAgain); section_space_builder.SetIsInsideRepeatableContent(true); } else if (ConstraintSpace().HasBlockFragmentation()) { + // Note that, with fragmentainer_block_offset, we pretend that any + // repeated table header isn't there (since it doesn't really participate + // in block fragmentation anyway), so that the block-offset right after + // such a header will be at 0, as far as block fragmentation is concerned. + // This way the fragmentation engine will refuse to insert a break before + // having made some content progress (even if the first piece of content + // doesn't fit). SetupSpaceBuilderForFragmentation( - ConstraintSpace(), section, block_offset, §ion_space_builder, - /* is_new_fc */ true, + ConstraintSpace(), section, fragmentainer_block_offset, + §ion_space_builder, /* is_new_fc */ true, container_builder_.RequiresContentBeforeBreaking()); - if (repeated_footer_block_size) { - // Reserve space for the repeated footer at the block-end of the - // fragmentainer. No other section may extend into this area. - section_space_builder.ReserveSpaceAtFragmentainerEnd( - *repeated_footer_block_size); - } + // Reserve space for any repeated header / footer. + if (ConstraintSpace().HasKnownFragmentainerBlockSize()) + section_space_builder.ReserveSpaceInFragmentainer(reserved_space); } return section_space_builder.ToConstraintSpace(); @@ -1038,7 +1041,8 @@ const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment( absl::optional<LayoutUnit> last_baseline; bool has_repeated_header = false; - absl::optional<LayoutUnit> pending_repeated_footer_block_size; + bool has_pending_repeated_footer = false; + LayoutUnit repeated_footer_block_size; // Before fragmented layout we need to go through the table's children, to // look for repeatable headers and footers. This is especially important for @@ -1061,25 +1065,50 @@ const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment( if (child != grouped_children.header && child != grouped_children.footer) continue; - // Headers and footers may be repeated if their block-size is one quarter - // or less than that of the fragmentainer, AND 'break-inside' has an - // applicable avoid* value. Being repeated means that the section is - // monolithic, and nothing inside can break. - // - // See https://www.w3.org/TR/css-tables-3/#repeated-headers - LayoutUnit block_size = sections[entry.GetSectionIndex()].block_size; - if (block_size > max_section_block_size) - continue; if (!IsAvoidBreakValue(ConstraintSpace(), child.Style().BreakInside())) continue; + const NGBlockBreakToken* child_break_token = entry.GetBreakToken(); + // If we've already broken inside the section, it's not going to repeat, + // but rather perform regular fragmentation. + if (IsResumingLayout(child_break_token)) + continue; + + LayoutUnit block_size = sections[entry.GetSectionIndex()].block_size; + + // Unless we have already decided to repeat in a previous fragment, check + // if the block-size of the section is acceptable. + if (!child_break_token || !child_break_token->IsRepeated()) { + DCHECK(!child_break_token || child_break_token->IsBreakBefore()); + + // If this isn't the first fragment for the table box, and the section + // didn't repeat in the previous fragment, it doesn't make sense to + // start repeating now. If this is a header, we may already have + // finished (non-repeated) layout. If this is a footer, we have already + // laid out at least one fragment without it. + if (incoming_table_break_data && + incoming_table_break_data->has_entered_table_box) + continue; + + // Headers and footers may be repeated if their block-size is one + // quarter or less than that of the fragmentainer, AND 'break-inside' + // has an applicable avoid* value. Being repeated means that the section + // is monolithic, and nothing inside can break. + // + // See https://www.w3.org/TR/css-tables-3/#repeated-headers + if (block_size > max_section_block_size) + continue; + } + if (child == grouped_children.header) { has_repeated_header = true; } else { DCHECK_EQ(child, grouped_children.footer); + has_pending_repeated_footer = true; + // We need to reserve space for the repeated footer at the end of the // fragmentainer. - pending_repeated_footer_block_size = + repeated_footer_block_size = block_size + border_spacing.block_size + (has_collapsed_borders ? border_padding.block_end : LayoutUnit()); } @@ -1087,6 +1116,7 @@ const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment( } LayoutUnit grid_block_size_inflation; + LayoutUnit repeated_header_block_size; bool broke_inside = false; bool has_ended_table_box_layout = false; NGTableChildIterator child_iterator(grouped_children, BreakToken()); @@ -1105,7 +1135,7 @@ const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment( broke_inside = true; if (child == grouped_children.footer) - pending_repeated_footer_block_size.reset(); + has_pending_repeated_footer = false; break; } @@ -1114,6 +1144,7 @@ const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment( const NGBlockBreakToken* child_break_token = entry.GetBreakToken(); const NGLayoutResult* child_result; + absl::optional<LayoutUnit> offset_before_repeated_header; LayoutUnit child_inline_offset; LayoutUnit child_block_end_margin; // Captions allow margins. absl::optional<TableBoxExtent> new_table_box_extent; @@ -1167,6 +1198,9 @@ const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment( } child_result = caption.layout_result; child_inline_offset = caption.margins.inline_start; + + // Captions don't need to worry about repeated sections. + repeated_header_block_size = LayoutUnit(); } else { DCHECK(child.IsTableSection()); LayoutUnit collapsible_border_spacing; @@ -1187,7 +1221,6 @@ const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment( } LayoutUnit offset_for_childless_section = child_block_offset; - child_block_offset += collapsible_border_spacing; bool may_repeat_again = false; if (child == grouped_children.header) { @@ -1199,6 +1232,12 @@ const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment( // reach the end in this fragment, we need to abort and relayout. may_repeat_again = !is_known_to_be_last_table_box_; + // We need to measure the block-size of the repeated header, because + // this is something we have to subtract from available fragmentainer + // block-size, AND fragmentainer block-offset, when laying out + // non-repeated content (i.e. regular sections). + offset_before_repeated_header.emplace(child_block_offset); + // A header will share its collapsed border with the block-start of // the table. However when repeated it will draw the whole border // itself. We need to reserve additional space at the block-start for @@ -1208,26 +1247,34 @@ const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment( child_block_offset += border_padding.block_start; } } else if (child == grouped_children.footer) { - if (pending_repeated_footer_block_size) { + if (has_pending_repeated_footer) { is_repeated_section = true; // For footers it's easier, though. Since we got all the way to the // footer during layout, this means that this will be the last time // the footer is repeated. We can finish it right away, unless we have // a repeated header as well (which means that we're going to // relayout). - pending_repeated_footer_block_size.reset(); + has_pending_repeated_footer = false; may_repeat_again = !is_known_to_be_last_table_box_ && has_repeated_header; } } + child_block_offset += collapsible_border_spacing; + ESectionRepeatMode repeat_mode = kNotRepeated; if (is_repeated_section) repeat_mode = may_repeat_again ? kMayRepeatAgain : kRepeatedLast; + LayoutUnit reserved_space; + if (repeat_mode == kNotRepeated) { + reserved_space = + repeated_header_block_size + repeated_footer_block_size; + } + NGConstraintSpace child_space = CreateSectionConstraintSpace( - child, child_block_offset, entry.GetSectionIndex(), - pending_repeated_footer_block_size, repeat_mode); + child, child_block_offset - repeated_header_block_size, + entry.GetSectionIndex(), reserved_space, repeat_mode); if (is_repeated_section) { child_result = child.LayoutRepeatableRoot(child_space, child_break_token); @@ -1257,9 +1304,11 @@ const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment( child_block_offset = offset_for_childless_section; } } - if (ConstraintSpace().HasBlockFragmentation()) { + if (ConstraintSpace().HasBlockFragmentation() && + (!child_break_token || !is_repeated_section)) { LayoutUnit fragmentainer_block_offset = - ConstraintSpace().FragmentainerOffset() + child_block_offset; + ConstraintSpace().FragmentainerOffset() + child_block_offset - + repeated_header_block_size; NGBreakStatus break_status = BreakBeforeChildIfNeeded( ConstraintSpace(), child, *child_result, fragmentainer_block_offset, has_container_separation, &container_builder_); @@ -1291,6 +1340,12 @@ const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment( child_block_offset += fragment.BlockSize() + child_block_end_margin; if (child.IsTableSection()) { + if (offset_before_repeated_header) { + repeated_header_block_size = child_block_offset - + *offset_before_repeated_header + + border_spacing.block_size; + } + if (new_table_box_extent) { // The first section was added successfully. We're officially inside the // table box! @@ -1340,7 +1395,7 @@ const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment( NGLayoutResult::kNeedsRelayoutAsLastTableBox); } - if (pending_repeated_footer_block_size && table_box_extent) { + if (has_pending_repeated_footer && table_box_extent) { DCHECK(table_box_will_continue); // We broke before we got to the footer. Add it now. Before doing that, // though, also insert break tokens for the sections that we didn't get to @@ -1362,7 +1417,7 @@ const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment( LogicalOffset offset(section_inline_offset, child_block_offset); NGConstraintSpace child_space = CreateSectionConstraintSpace( grouped_children.footer, offset.block_offset, entry.GetSectionIndex(), - /* repeated_footer_block_size */ absl::nullopt, kMayRepeatAgain); + /* reserved_space */ LayoutUnit(), kMayRepeatAgain); const NGLayoutResult* result = grouped_children.footer.LayoutRepeatableRoot( child_space, entry.GetBreakToken()); diff --git a/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc b/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc index a6a0a234fd8..d4c250a7fa7 100644 --- a/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc +++ b/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc @@ -690,19 +690,19 @@ void PrePaintTreeWalk::WalkFragmentationContextRootChildren( containing_block_context = &fragment_context.current; containing_block_context->paint_offset += child.offset; - if (object.IsLayoutView()) { - // Out-of-flow positioned descendants are positioned relatively to this - // fragmentainer (page). - fragment_context.absolute_position = *containing_block_context; - fragment_context.fixed_position = *containing_block_context; - } - // Keep track of the paint offset at the fragmentainer. This is needed // when entering OOF descendants. OOFs have the nearest fragmentainer as // their containing block, so when entering them during LayoutObject tree // traversal, we have to compensate for this. containing_block_context->paint_offset_for_oof_in_fragmentainer = containing_block_context->paint_offset; + + if (object.IsLayoutView()) { + // Out-of-flow positioned descendants are positioned relatively to this + // fragmentainer (page). + fragment_context.absolute_position = *containing_block_context; + fragment_context.fixed_position = *containing_block_context; + } } WalkChildren(actual_parent, box_fragment, fragmentainer_context); diff --git a/chromium/third_party/blink/renderer/core/timing/performance.cc b/chromium/third_party/blink/renderer/core/timing/performance.cc index 466b9e145d7..b61ee46dce4 100644 --- a/chromium/third_party/blink/renderer/core/timing/performance.cc +++ b/chromium/third_party/blink/renderer/core/timing/performance.cc @@ -273,11 +273,12 @@ PerformanceEntryVector Performance::getEntriesByType( PerformanceEntry::ToEntryTypeEnum(entry_type); if (!PerformanceEntry::IsValidTimelineEntryType(type)) { PerformanceEntryVector empty_entries; - String message = "Deprecated API for given entry type."; - GetExecutionContext()->AddConsoleMessage( - MakeGarbageCollected<ConsoleMessage>( - mojom::ConsoleMessageSource::kJavaScript, - mojom::ConsoleMessageLevel::kWarning, message)); + if (ExecutionContext* execution_context = GetExecutionContext()) { + String message = "Deprecated API for given entry type."; + execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + mojom::ConsoleMessageSource::kJavaScript, + mojom::ConsoleMessageLevel::kWarning, message)); + } return empty_entries; } return getEntriesByTypeInternal(type); diff --git a/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image_to_video_frame_copier.cc b/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image_to_video_frame_copier.cc index 892983b886b..1a2a251d71d 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image_to_video_frame_copier.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image_to_video_frame_copier.cc @@ -57,13 +57,9 @@ void StaticBitmapImageToVideoFrameCopier::Convert( return; } - if (image->width() == 1 || image->height() == 1) { - // We might need to convert the frame into I420 pixel format, and 1x1 frame - // can't be read back into I420. Capturing such a slim target is not a - // very practical thing to do anyway, so we're okay to fail here. - return; - } - + // We might need to convert the frame into I420 pixel format, and 1x1 frame + // can't be read back into I420. + const bool too_small_for_i420 = image->width() == 1 || image->height() == 1; if (!image->IsTextureBacked()) { // Initially try accessing pixels directly if they are in memory. sk_sp<SkImage> sk_image = image->PaintImageForCurrentFrame().GetSwSkImage(); @@ -90,7 +86,8 @@ void StaticBitmapImageToVideoFrameCopier::Convert( } // Try async reading if image is texture backed. - if (image->CurrentFrameKnownToBeOpaque() || can_discard_alpha_) { + if (!too_small_for_i420 && + (image->CurrentFrameKnownToBeOpaque() || can_discard_alpha_)) { // Split the callback so it can be used for both the GMB frame pool copy and // ReadYUVPixelsAsync fallback paths. auto split_callback = base::SplitOnceCallback(std::move(callback)); diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc index 53ebd8e29fa..52c5839738f 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc @@ -31,6 +31,7 @@ #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "third_party/blink/renderer/platform/wtf/wtf.h" +#include "third_party/ced/src/compact_enc_det/compact_enc_det.h" namespace blink { namespace { @@ -421,6 +422,12 @@ void NavigationBodyLoader::StartLoadingBodyInBackground( if (!response_body_) return; + // Initializing the map used when detecting encodings is not thread safe. + // Initialize on the main thread here to avoid races. + // TODO(crbug.com/1384221): Consider making the map thread safe in + // third_party/ced/src/util/encodings/encodings.cc. + EncodingNameAliasToEncoding(""); + off_thread_body_reader_.reset(new OffThreadBodyReader( std::move(response_body_), std::move(decoder), weak_factory_.GetWeakPtr(), task_runner_, worker_pool::CreateSequencedTaskRunner({}), diff --git a/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 698cb83a921..4ab43d81cce 100644 --- a/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5 @@ -343,7 +343,7 @@ status: "experimental", origin_trial_feature_name: "BackForwardCacheNotRestoredReasons", base_feature: "BackForwardCacheSendNotRestoredReasons", - base_feature_status: "enabled", + base_feature_status: "disabled", copied_from_base_feature_if: "overridden", public: true, }, |