summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer')
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/select_type.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box_hot.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_break_token_data.h11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc90
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h14
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc127
-rw-r--r--chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image_to_video_frame_copier.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/runtime_enabled_features.json52
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,
&section_available_inline_size,
- &constraint_space_data, &sections,
- 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, &sections, 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, &section_space_builder,
- /* is_new_fc */ true,
+ ConstraintSpace(), section, fragmentainer_block_offset,
+ &section_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,
},