summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/third_party/blink/renderer/core
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-c30a6232df03e1efbd9f3b226777b07e087a1122.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/core')
-rw-r--r--chromium/third_party/blink/renderer/core/BUILD.gn26
-rw-r--r--chromium/third_party/blink/renderer/core/DEPS7
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/apply_dark_mode.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/ax_object_cache.h2
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.cc51
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animatable.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation.cc79
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation.h9
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_effect.cc41
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_effect.h7
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_effect_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_test.cc155
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_timeline.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_timeline.h7
-rw-r--r--chromium/third_party/blink/renderer/core/animation/compositor_animations.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/animation/compositor_animations.h7
-rw-r--r--chromium/third_party/blink/renderer/core/animation/compositor_animations_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_filter_operations.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animation.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animation_data.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animation_data.h8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animation_update.h8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animations.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animations.h10
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animations_test.cc292
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_transition.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc114
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.h40
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_length_pair_interpolation_type.h6
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_animations.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_animations.h6
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_animations_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_timeline.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_timeline.h10
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_timeline_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/effect_input.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/effect_model.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/effect_stack.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/effect_stack.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/element_animations.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/animation/element_animations.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/inert_effect.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/inert_effect.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/interpolation.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/interpolation_effect.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/interpolation_effect.h4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe.h4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_animation_options.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.h4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/length_list_property_functions.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/animation/length_property_functions.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/pending_animations.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/pending_animations.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/sampled_effect.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/sampled_effect.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/scroll_timeline.cc71
-rw-r--r--chromium/third_party/blink/renderer/core/animation/scroll_timeline.h20
-rw-r--r--chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.h12
-rw-r--r--chromium/third_party/blink/renderer/core/animation/scroll_timeline_test.cc101
-rw-r--r--chromium/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/string_keyframe.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/animation/string_keyframe.h4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_angle_interpolation_type.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/animation/timing.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/animation/timing.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/timing_calculations.h14
-rw-r--r--chromium/third_party/blink/renderer/core/animation/timing_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/animation/transition_interpolation.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/transition_keyframe.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/animation/transition_keyframe.h4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/worklet_animation_controller.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/worklet_animation_controller.h6
-rw-r--r--chromium/third_party/blink/renderer/core/animation_frame/worker_animation_frame_provider.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/animation_frame/worker_animation_frame_provider.h4
-rw-r--r--chromium/third_party/blink/renderer/core/aom/accessible_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/aom/accessible_node.h2
-rw-r--r--chromium/third_party/blink/renderer/core/aom/accessible_node_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/aom/accessible_node_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/aom/computed_accessible_node.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/aom/computed_accessible_node.h4
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_object.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_object.h2
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_object_item.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_object_item.h7
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_transfer.cc55
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_transfer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_transfer_item.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_transfer_item.h2
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_transfer_item_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_transfer_item_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/raw_system_clipboard.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/raw_system_clipboard.h2
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/system_clipboard.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/system_clipboard.h4
-rw-r--r--chromium/third_party/blink/renderer/core/content_capture/content_capture_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/content_capture/content_capture_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/core/content_capture/content_capture_task.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/content_capture/content_capture_task.h2
-rw-r--r--chromium/third_party/blink/renderer/core/content_capture/content_capture_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/content_capture/sent_nodes.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/content_capture/sent_nodes.h2
-rw-r--r--chromium/third_party/blink/renderer/core/content_capture/task_session.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/content_capture/task_session.h4
-rw-r--r--chromium/third_party/blink/renderer/core/context_features/context_feature_settings.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/context_features/context_feature_settings.h2
-rw-r--r--chromium/third_party/blink/renderer/core/core.gni11
-rw-r--r--chromium/third_party/blink/renderer/core/core_idl_files.gni2
-rw-r--r--chromium/third_party/blink/renderer/core/css/BUILD.gn13
-rw-r--r--chromium/third_party/blink/renderer/core/css/README.md2
-rw-r--r--chromium/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/active_style_sheets_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_computed_style_declaration.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_computed_style_declaration.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_crossfade_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_default_style_sheets.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_default_style_sheets.h10
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_face.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_face.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_face_rule.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_face_rule.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_face_source.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_face_src_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_selector.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_selector.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_global_rule_set.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_global_rule_set.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_gradient_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_gradient_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_grouping_rule.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_grouping_rule.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_id_selector_value.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_id_selector_value.h44
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_id_selector_value_test.cc36
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_identifier_value.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_image_set_value.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_image_value.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_import_rule.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_import_rule.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_initial_color_value.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_initial_color_value.h46
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_keyframe_rule.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_keyframe_rule.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_keyframes_rule.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_keyframes_rule.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_markup.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_math_expression_node.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_math_expression_node.h8
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_media_rule.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_media_rule.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_namespace_rule.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_namespace_rule.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_page_rule.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_page_rule.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_page_rule_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_paint_image_generator.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_paint_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_primitive_value_mappings.h42
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_properties.json5234
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_property_rule.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_property_rule.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_property_source_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_property_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_property_value_set.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_property_value_set.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_revert_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_rule.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_rule.h25
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_rule.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_rule_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_scroll_timeline_rule.cc67
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_scroll_timeline_rule.h50
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_scroll_timeline_rule.idl15
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_segmented_font_face.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_segmented_font_face.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_selector.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_selector.h3
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_selector_watch.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_selector_watch.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_string_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_declaration.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_declaration.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_declaration_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_rule.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_rule.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_sheet.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_sheet.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_supports_rule.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_syntax_definition.cc48
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_syntax_string_parser.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_test_helpers.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value.h9
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value_id_mappings.h18
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value_keywords.json516
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value_pool.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value_pool.h5
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/README.md2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/computed_style_property_map.h5
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_math_invert.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_math_negate.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_math_variadic.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_matrix_component.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_numeric_array.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_perspective.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_position_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_resource_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_rotate.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_scale.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_skew.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_skew_x.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_skew_y.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_style_image_value_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_style_variable_reference_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_transform_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_translate.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_url_image_value.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_url_image_value.h3
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/declared_style_property_map.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/inline_style_property_map.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/inline_style_property_map_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/document_style_sheet_collection.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/css/document_style_sheet_collection.h9
-rw-r--r--chromium/third_party/blink/renderer/core/css/element_rule_collector.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_display_auto_lcp_align_test.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_cache.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_cache.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_cache_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_set.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_set.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_set_document.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_set_document.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_set_load_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_set_load_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_set_worker.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_set_worker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_size_functions.cc45
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_size_functions.h3
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_size_functions_test.cc79
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_update_invalidation_test.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/css/inline_css_style_declaration.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/inline_css_style_declaration.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/local_font_face_source.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/local_font_face_source.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/marker.css4
-rw-r--r--chromium/third_party/blink/renderer/core/css/mathml.css35
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_feature_names.json52
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_evaluator.cc40
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_evaluator.h13
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_evaluator_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_exp.cc45
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_list_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_list_listener.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_list_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_matcher.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_matcher.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_set_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_values.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_values.h7
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_values_cached.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_values_cached.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_values_dynamic.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_values_dynamic.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/offscreen_font_selector.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/offscreen_font_selector.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/page_rule_collector.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/css/page_rule_collector.h9
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.cc130
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h7
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/at_rule_names.json512
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css.proto4
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_at_rule_id.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_at_rule_id.h1
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_context.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_context.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_impl.cc331
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_impl.h36
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_impl_test.cc194
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_property_parser.cc45
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc2206
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h250
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_property_parser_helpers_test.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_proto_converter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_selector_parser.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/font_variant_east_asian_parser.h10
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/font_variant_ligatures_parser.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/font_variant_numeric_parser.h12
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/computed_style_utils.cc83
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/computed_style_utils.h9
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/computed_style_utils_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc2963
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils.h284
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils_test.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/css_property_ref.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/css_property_test.cc71
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/custom_property.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc1129
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc812
-rw-r--r--chromium/third_party/blink/renderer/core/css/property_registration.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/property_registration.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/property_registry.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/property_registry.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/property_registry_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/property_set_css_style_declaration.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/property_set_css_style_declaration.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/pseudo_style_request.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/remote_font_face_source.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/css/remote_font_face_source.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_priority.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_resolver.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_resolver.h15
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/css_property_priority.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/css_to_style_map.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/match_result.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/match_result.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc83
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h21
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc345
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_adjuster.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_builder.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc129
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_builder_converter.h8
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_builder_test.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_cascade.cc77
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_cascade.h12
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc315
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_resolver.cc318
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_resolver.h27
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state.h101
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state_test.cc66
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc310
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/rule_feature_set_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/rule_set.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/css/rule_set.h8
-rw-r--r--chromium/third_party/blink/renderer/core/css/selector_checker.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/css/selector_filter.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/selector_filter.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/selector_query_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/css/shadow_tree_style_sheet_collection.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/css/shadow_tree_style_sheet_collection.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/style-calculation.md6
-rw-r--r--chromium/third_party/blink/renderer/core/css/style-invalidation.md2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_color.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_element.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_engine.cc214
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_engine.h40
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_engine_test.cc236
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_environment_variables.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_environment_variables.h10
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_media.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_media.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_property_serializer.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_property_serializer.h3
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_property_shorthand_custom.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_rule.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_rule.h35
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_rule_css_style_declaration.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_rule_css_style_declaration.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_rule_import.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_rule_import.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_sheet_collection.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_sheet_collection.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_sheet_contents.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_sheet_contents.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_sheet_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_sheet_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_traversal_root.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_traversal_root_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/svg.css2
-rw-r--r--chromium/third_party/blink/renderer/core/css/tree_scope_style_sheet_collection.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/tree_scope_style_sheet_collection.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/vision_deficiency.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_context.cc125
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_context.h31
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc295
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_document_state.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_document_state.h4
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities.h2
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/render_subtree_activation_event.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/render_subtree_activation_event.h32
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/render_subtree_activation_event.idl10
-rw-r--r--chromium/third_party/blink/renderer/core/dom/abort_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/abort_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/abort_signal.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/abort_signal.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/attr.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/attr.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/attr_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/attribute_collection.h94
-rw-r--r--chromium/third_party/blink/renderer/core/dom/beforeunload_event_listener.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/beforeunload_event_listener.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/child_list_mutation_scope.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/child_list_mutation_scope.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/child_node_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/child_node_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/collection_index_cache.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/container_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/container_node.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/context_features_client_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/create_element_flags.h31
-rw-r--r--chromium/third_party/blink/renderer/core/dom/dataset_dom_string_map.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/dataset_dom_string_map.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/distributed_nodes.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/distributed_nodes.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document.cc1062
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document.h176
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document.idl11
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_init.cc298
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_init.h68
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_lifecycle.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_parser.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_parser.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_parser_client.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_parser_timing.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_parser_timing.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_test.cc198
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_timing.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_timing.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/dom_implementation.cc143
-rw-r--r--chromium/third_party/blink/renderer/core/dom/dom_implementation.h9
-rw-r--r--chromium/third_party/blink/renderer/core/dom/dom_implementation_test.cc100
-rw-r--r--chromium/third_party/blink/renderer/core/dom/dom_token_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/dom_token_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element.cc80
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element.h3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element_data.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element_data_cache.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element_data_cache.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/empty_node_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/empty_node_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/custom_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/custom_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_listener.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_listener_map.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_listener_map.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_path.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_path.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_queue.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_queue.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_target.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_target.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_target_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_target_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/node_event_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/node_event_context.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/window_event_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/window_event_context.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc80
-rw-r--r--chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.h27
-rw-r--r--chromium/third_party/blink/renderer/core/dom/get_inner_html_options.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/dom/global_event_handlers.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/global_event_handlers.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/dom/id_target_observer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/id_target_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/live_node_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/live_node_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/live_node_list_base.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/live_node_list_registry.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/live_node_list_registry.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/live_node_list_registry_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/mutation_observer.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/mutation_observer.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/mutation_observer_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/mutation_record.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/named_node_map.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/named_node_map.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node.h6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_iterator.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_iterator.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_iterator_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_iterator_base.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_lists_node_data.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_lists_node_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_rare_data.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_rare_data.h10
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_traversal.h18
-rw-r--r--chromium/third_party/blink/renderer/core/dom/nth_index_cache.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/nth_index_cache.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/presentation_attribute_style.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/processing_instruction.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/processing_instruction.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/pseudo_element.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/dom/pseudo_element.h1
-rw-r--r--chromium/third_party/blink/renderer/core/dom/pseudo_element_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/range.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/range.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/range_boundary_point.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/range_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scriptable_document_parser.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scriptable_document_parser.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.cc36
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.h7
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/dom/shadow_root.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/shadow_root.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/shadow_root_v0.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/slot_assignment.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/slot_assignment.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/slot_assignment_engine.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/slot_assignment_engine.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/static_node_list.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/static_range.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/static_range.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/static_range_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/synchronous_mutation_observer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/synchronous_mutation_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/template_content_document_fragment.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/text.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/text.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_ordered_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_ordered_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_ordered_map.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_ordered_map.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_scope.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_scope.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_scope_adopter_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_scope_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_walker.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_walker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/user_action_element_set.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/user_action_element_set.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/v0_insertion_point.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/v0_insertion_point.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/visited_link_state.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/visited_link_state.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/weak_identifier_map.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/weak_identifier_map_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/append_node_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/append_node_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/apply_style_command.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/apply_style_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc43
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/delete_from_text_node_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/delete_from_text_node_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/edit_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/edit_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.h1
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_list_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_list_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_node_before_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_node_before_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/merge_identical_elements_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/merge_identical_elements_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/remove_css_property_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/remove_css_property_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/remove_node_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/remove_node_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/remove_node_preserving_children_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/remove_node_preserving_children_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/replace_node_with_span_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/replace_node_with_span_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/selection_for_undo_step.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/selection_for_undo_step.h4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/set_character_data_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/set_character_data_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/set_node_attribute_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/set_node_attribute_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/simplify_markup_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/simplify_markup_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/split_element_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/split_element_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/split_text_node_containing_element_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/split_text_node_containing_element_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/undo_stack.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/undo_stack.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/undo_step.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/undo_step.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/wrap_contents_in_dummy_span_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/wrap_contents_in_dummy_span_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/dom_selection.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/editing/dom_selection.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/drag_caret.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/drag_caret.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editing_style.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editing_style.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editing_utilities.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editing_utilities.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editor.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editor.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_buffer.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_options.h1
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/text_finder.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/text_finder.h4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/text_finder_test.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/editing/frame_caret.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/frame_caret.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/frame_selection.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/frame_selection.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/frame_selection_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/edit_context.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/edit_context.h22
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/ime_text_span.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/ime_text_span.h18
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_vector_builder.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_vector_builder.h6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/input_method_controller.cc378
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/input_method_controller.h36
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc72
-rw-r--r--chromium/third_party/blink/renderer/core/editing/inline_box_position_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/editing/layout_selection.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/layout_selection.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/document_marker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller.h5
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/document_marker_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/spell_check_marker_list_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/spell_check_marker_list_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker.h6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.h4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl_test.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/text_marker_base_list_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/text_marker_base_list_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/position.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/position.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/position_with_affinity.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/position_with_affinity.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/reveal_selection_scope.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/reveal_selection_scope.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_adjuster.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_controller.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_controller_test.cc133
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_editor.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_editor.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_modifier_line.cc99
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_modifier_test.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_template.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_template.h4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/markup_accumulator.h6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/serialization.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/serialization.h12
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.h5
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/state_machines/backward_code_point_state_machine.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/state_machines/forward_code_point_state_machine.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/state_machines/text_segmentation_machine_state.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/visible_position.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/visible_position.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/visible_position_test.cc126
-rw-r--r--chromium/third_party/blink/renderer/core/editing/visible_selection.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/visible_selection.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/visible_units.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/editing/visible_units_line.cc270
-rw-r--r--chromium/third_party/blink/renderer/core/editing/visible_units_line_test.cc149
-rw-r--r--chromium/third_party/blink/renderer/core/events/animation_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/animation_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/animation_playback_event.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/events/animation_playback_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/application_cache_error_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/application_cache_error_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/before_text_inserted_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/before_text_inserted_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/before_unload_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/before_unload_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/clipboard_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/clipboard_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/composition_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/composition_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/drag_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/drag_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/drag_event_init.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/events/error_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/error_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/event_type_names.json53
-rw-r--r--chromium/third_party/blink/renderer/core/events/focus_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/focus_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/gesture_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/gesture_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/hash_change_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/input_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/input_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/keyboard_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/keyboard_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/message_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/message_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/message_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/events/message_event_init.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/events/mouse_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/mouse_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/mutation_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/mutation_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/overscroll_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/overscroll_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/page_transition_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/page_transition_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/pointer_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/pointer_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/pop_state_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/pop_state_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/progress_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/progress_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/promise_rejection_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/promise_rejection_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/resource_progress_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/resource_progress_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/security_policy_violation_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/security_policy_violation_event_init.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/events/text_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/text_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/touch_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/touch_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/touch_event_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/touch_event_context.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/transition_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/transition_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/ui_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/ui_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/visual_viewport_resize_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/visual_viewport_scroll_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/wheel_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/wheel_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/agent.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/agent.h20
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/agent_metrics_collector.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/agent_metrics_collector.h30
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/execution_context.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/execution_context.h16
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h4
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/security_context.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/security_context.h9
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/security_context_init.cc273
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/security_context_init.h32
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/window_agent.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/window_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/window_agent_factory.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/window_agent_factory.h2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/BUILD.gn3
-rw-r--r--chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.h9
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_document.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_document_loader_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_document_loader_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_document_subresource_filter_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_dom_message_event.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_external_widget_impl.cc106
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_external_widget_impl.h36
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_form_element_observer_impl.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_form_element_observer_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_frame_test.cc471
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_hit_test_result.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_input_method_controller_impl.h18
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_navigation_params.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.cc202
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.h40
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_performance.cc56
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_plugin_container_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_plugin_container_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_remote_frame_impl.h3
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_savable_resources_test_support.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_settings_impl.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_settings_impl.h3
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_shared_worker_impl.h9
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_view_impl.cc237
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_view_impl.h27
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_view_test.cc140
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/document_policy_parser_test.cc676
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/dom_document_policy.h2
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/dom_feature_policy.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/dom_feature_policy.h2
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/feature_policy.dict2
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/feature_policy.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/feature_policy_attr_fuzzer.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/feature_policy_features.json523
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/feature_policy_fuzzer.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser.cc132
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser.h20
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/feature_policy_test.cc598
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/iframe_policy.h2
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/policy_helper.h10
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/policy_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/DEPS8
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body.h24
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.cc145
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.h36
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc112
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/bytes_consumer_tee.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/bytes_uploader.cc169
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/bytes_uploader.h67
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/bytes_uploader_test.cc238
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.h4
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_header_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_request_data.cc116
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_request_data.h12
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_request_data_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_response_data.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_response_data.h17
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_response_data_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/global_fetch.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/global_fetch.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/headers.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/headers.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/multipart_parser.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/multipart_parser.h4
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/request.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/request.h4
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/request_init.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/request_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/response.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/response.h9
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/trust_token.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_reader.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_reader.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_reader_loader_client.h1
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/public_url_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/public_url_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/BUILD.gn10
-rw-r--r--chromium/third_party/blink/renderer/core/frame/ad_tracker.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/frame/ad_tracker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/frame/bar_prop.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/bar_prop.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/browser_controls.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/browser_controls.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/browser_controls_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.cc109
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.h24
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc654
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/csp_directive.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc168
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.h25
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc275
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/csp_source.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/csp_source.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/source_list_directive.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/source_list_directive.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/string_list_directive.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/string_list_directive.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/string_list_directive_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dactyloscoper.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dactyloscoper.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/deprecation.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/frame/deprecation.h11
-rw-r--r--chromium/third_party/blink/renderer/core/frame/device_single_window_event_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/device_single_window_event_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/display_cutout_client_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/display_cutout_client_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dom_timer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dom_timer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dom_timer_coordinator.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dom_timer_coordinator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dom_visual_viewport.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dom_visual_viewport.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dom_window.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dom_window.h5
-rw-r--r--chromium/third_party/blink/renderer/core/frame/event_handler_registry.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/event_handler_registry.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/find_in_page.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/frame/find_in_page.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame.cc43
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame.h20
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_client.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_console.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_console.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_lifecycle.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_overlay.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_overlay_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_owner.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_serializer.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_serializer_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_test_helpers.cc85
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_test_helpers.h48
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_view.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_view.h13
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_view_auto_size_info.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_view_auto_size_info.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/history.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/frame/history.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/history.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_dom_window.cc403
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_dom_window.h53
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_dom_window_test.cc226
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame.cc415
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame.h119
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_back_forward_cache_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_client.h8
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_view.cc326
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_view.h73
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_view_test.cc166
-rw-r--r--chromium/third_party/blink/renderer/core/frame/location.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/frame/location.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/mhtml_loading_test.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigation_rate_limiter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigation_rate_limiter.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_device_memory.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_device_memory.h9
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_language.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_language.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_scheduling.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_scheduling.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_ua_data.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_ua_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_user_activation.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_user_activation.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_user_activation.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/overlay_interstitial_ad_detector.cc227
-rw-r--r--chromium/third_party/blink/renderer/core/frame/overlay_interstitial_ad_detector.h10
-rw-r--r--chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/pausable_script_executor.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/frame/pausable_script_executor.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/performance_monitor.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/performance_monitor.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/picture_in_picture_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/picture_in_picture_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/platform_event_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/platform_event_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/platform_event_dispatcher.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/platform_event_dispatcher.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_dom_window.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_dom_window.h6
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame.cc99
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame.h19
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_client.h15
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc52
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h9
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_owner.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_owner.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_view.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_view.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/report.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/reporting_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/reporting_context.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/reporting_observer.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/frame/reporting_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/resize_viewport_anchor.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/root_frame_viewport.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/frame/root_frame_viewport.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/savable_resources.cc174
-rw-r--r--chromium/third_party/blink/renderer/core/frame/savable_resources.h63
-rw-r--r--chromium/third_party/blink/renderer/core/frame/scheduling.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/frame/scheduling.h3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/scheduling.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/screen.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/frame/screen.h3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/screen.idl19
-rw-r--r--chromium/third_party/blink/renderer/core/frame/settings.json530
-rw-r--r--chromium/third_party/blink/renderer/core/frame/smart_clip.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/sticky_ad_detector.cc137
-rw-r--r--chromium/third_party/blink/renderer/core/frame/sticky_ad_detector.h61
-rw-r--r--chromium/third_party/blink/renderer/core/frame/sticky_frame_tracker.cc93
-rw-r--r--chromium/third_party/blink/renderer/core/frame/sticky_frame_tracker.h63
-rw-r--r--chromium/third_party/blink/renderer/core/frame/sticky_frame_tracker_test.cc67
-rw-r--r--chromium/third_party/blink/renderer/core/frame/use_counter_helper.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/use_counter_helper.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/use_counter_helper_test.cc125
-rw-r--r--chromium/third_party/blink/renderer/core/frame/user_activation.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/user_activation.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/user_activation.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/frame/viewport_data.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/viewport_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/virtual_keyboard_overlay_changed_observer.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/frame/virtual_keyboard_overlay_changed_observer.h43
-rw-r--r--chromium/third_party/blink/renderer/core/frame/visual_viewport.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/visual_viewport.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/visual_viewport_test.cc57
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.cc454
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.h148
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc221
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h46
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.h5
-rw-r--r--chromium/third_party/blink/renderer/core/frame/window.idl12
-rw-r--r--chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/fullscreen.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/fullscreen.h4
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/fullscreen_options.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.h4
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_quad.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_quad.h2
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_rect.h4
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_rect_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_rect_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/BUILD.gn5
-rw-r--r--chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc43
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h11
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator_test.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h9
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc236
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h20
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc269
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.h31
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/image_data.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/image_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/image_data_color_settings.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/text_metrics.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/text_metrics.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/ukm_parameters.h20
-rw-r--r--chromium/third_party/blink/renderer/core/html/collection_items_cache.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_test_helpers.h8
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_registry_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/element_internals.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/element_internals.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_exception.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_step.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_step.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/chooser_resource_loader.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/clear_button_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/clear_button_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_chooser.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_chooser_client.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_input_type.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_input_type.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_chooser.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_client.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc50
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.h3
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/file_input_type.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/file_input_type.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/file_input_type_test.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/form_controller.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/form_controller.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/form_controller_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/form_data.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/form_data.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/form_data_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/form_data_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_element.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_input_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_input_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_input_element_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_option_element.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_option_element.h9
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_output_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_output_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_output_element_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_select_element.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_select_element.h8
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_select_element_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/image_input_type.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/input_type.cc154
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/input_type.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/input_type_view.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/input_type_view.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/listed_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/listed_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/option_list_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/popup_menu.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/range_input_type.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/range_input_type.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/calendar_picker_refresh.css138
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.css39
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.js52
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/eye_dropper_icon.svg1
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.css13
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/time_picker.css20
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/select_type.cc195
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/select_type.h9
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/slider_thumb_element.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/spin_button_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/step_range.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/submit_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/submit_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_control_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_control_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/validity_state.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_anchor_element.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_anchor_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_attribute_names.json53
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_body_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_collection.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_collection.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_content_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_content_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_document.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_document.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_element.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_element.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_element.h3
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_element_base.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_element_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc77
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_owner_element.h17
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_set_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_html_element.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_iframe_element.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_iframe_element.h5
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_iframe_element.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_iframe_element_test.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_image_element.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_image_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_image_fallback_helper.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_link_element.cc79
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_link_element.h21
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_link_element.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_link_element_sizes_attribute_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_marquee_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_marquee_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_meta_element.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_meter_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_meter_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_no_script_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_object_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_object_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_plugin_element.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_plugin_element.h5
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_plugin_element_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_progress_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_progress_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_script_element.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_script_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_script_element_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_slot_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_slot_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_source_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_source_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_style_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_style_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_table_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_table_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_table_part_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_table_row_element_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_template_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_template_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_view_source_document.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_view_source_document.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/image_document.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/image_document.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/image_document_test.cc85
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/README.md2
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/html_import.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/html_import_child.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/html_import_child.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/html_import_child_client.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/html_import_loader.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/html_import_loader.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/link_import.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/link_import.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/keywords.json55
-rw-r--r--chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/link_rel_attribute.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/link_rel_attribute.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/link_rel_attribute_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/html/link_resource.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/link_resource.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/link_style.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/html/link_style.h5
-rw-r--r--chromium/third_party/blink/renderer/core/html/link_web_bundle.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/html/link_web_bundle.h37
-rw-r--r--chromium/third_party/blink/renderer/core/html/link_web_bundle_test.cc85
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/autoplay_policy.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/autoplay_policy.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_media_element.cc337
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_media_element.h26
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_media_element.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc123
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_media_element_test.cc179
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_video_element.cc84
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_video_element.h18
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_controls.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_controls.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_element_parser_helpers.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/video_wake_lock.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/video_wake_lock.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/BUILD.gn8
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/atomic_html_token.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/background_html_parser.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/compact_html_token.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_construction_site.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_construction_site.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_document_parser.cc393
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_document_parser.h25
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_document_parser_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_element_stack.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_element_stack.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_entity_parser.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.cc218
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_options.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_source_tracker.cc110
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_source_tracker.h67
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_stack_item.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.cc68
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.cc86
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.h13
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.cc (renamed from chromium/third_party/blink/renderer/core/loader/text_resource_decoder_builder.cc)7
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.h (renamed from chromium/third_party/blink/renderer/core/loader/text_resource_decoder_builder.h)6
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder_test.cc (renamed from chromium/third_party/blink/renderer/core/loader/text_resource_decoder_builder_test.cc)2
-rw-r--r--chromium/third_party/blink/renderer/core/html/plugin_document.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/plugin_document.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/document_portals.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/document_portals.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc89
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h22
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/html_portal_element_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/portal_contents.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/portal_contents.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/portal_host.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/portal_host.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/rel_list.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/html/resources/controls_refresh.css2
-rw-r--r--chromium/third_party/blink/renderer/core/html/resources/forced_colors.css18
-rw-r--r--chromium/third_party/blink/renderer/core/html/resources/images/calendar_icon_white.svg1
-rw-r--r--chromium/third_party/blink/renderer/core/html/shadow/details_marker_control.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.h3
-rw-r--r--chromium/third_party/blink/renderer/core/html/subresource_redirect_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/audio_track.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/audio_track.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/audio_track_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/cue_timeline.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/cue_timeline.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/html_track_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/html_track_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/loadable_text_track.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/loadable_text_track.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track_container.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track_container.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track_cue.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track_cue.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/track_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/track_base.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/track_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/track_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/track_list_base.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/video_track.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/video_track.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/video_track_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/vtt/vtt_tokenizer.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.h1
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h16
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_test.cc309
-rw-r--r--chromium/third_party/blink/renderer/core/input/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/input/event_handler.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/input/event_handler.h2
-rw-r--r--chromium/third_party/blink/renderer/core/input/event_handler_test.cc86
-rw-r--r--chromium/third_party/blink/renderer/core/input/event_handling_util.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/input/event_handling_util.h2
-rw-r--r--chromium/third_party/blink/renderer/core/input/gesture_manager.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/input/gesture_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/core/input/ime_on_focus_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/input/input_device_capabilities.h2
-rw-r--r--chromium/third_party/blink/renderer/core/input/keyboard_event_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/input/keyboard_event_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/core/input/mouse_event_manager.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/input/mouse_event_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/core/input/mouse_wheel_event_manager.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/input/mouse_wheel_event_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/core/input/pointer_event_manager.cc36
-rw-r--r--chromium/third_party/blink/renderer/core/input/pointer_event_manager.h4
-rw-r--r--chromium/third_party/blink/renderer/core/input/scroll_manager.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/input/scroll_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch.h2
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch_action_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch_event_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch_event_manager.h4
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/console_message.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/console_message.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/console_message_storage.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/console_message_storage.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/dev_tools_emulator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/dev_tools_host.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/dev_tools_host.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/devtools_agent.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/devtools_agent.h30
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/devtools_session.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/devtools_session.h21
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/dom_editor.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/dom_editor.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/dom_patch_support.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/dom_patch_support.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspect_tool_common.css41
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspect_tool_common.js110
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspect_tool_distances.html103
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspect_tool_highlight.html1112
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspect_tool_paused.html108
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspect_tool_screenshot.html102
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspect_tool_viewport_size.html32
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspect_tools.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspect_tools.h10
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspected_frames.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspected_frames.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_animation_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_audits_agent.cc78
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_audits_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_base_agent.h4
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_css_agent.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_css_agent.h3
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_agent.h4
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_debugger_agent.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_debugger_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc61
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h9
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_emulation_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_highlight.cc149
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_highlight.h4
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_history.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_history.h4
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_issue.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_issue.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_issue_reporter.cc61
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_issue_reporter.h47
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_issue_storage.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_issue_storage.h6
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.h5
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_log_agent.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_log_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_media_agent.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_media_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_media_context_impl.h4
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_memory_agent.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_memory_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_network_agent.cc101
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_network_agent.h13
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc80
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h10
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_overlay_host.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_overlay_host.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_page_agent.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_page_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_performance_agent.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_performance_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_resource_container.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_resource_container.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.cc36
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc177
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.h22
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_task_runner.h4
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_trace_events.cc95
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_trace_events.h12
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/main_thread_debugger.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/network_resources_data.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/network_resources_data.h18
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/worker_inspector_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc105
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_geometry.h3
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observation.h2
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc114
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.h36
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_delegate.h2
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h2
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_init.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc121
-rw-r--r--chromium/third_party/blink/renderer/core/layout/BUILD.gn31
-rw-r--r--chromium/third_party/blink/renderer/core/layout/api/line_layout_item.h9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/api/line_layout_list_marker.h14
-rw-r--r--chromium/third_party/blink/renderer/core/layout/api/selection_state.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/counter_node.cc45
-rw-r--r--chromium/third_party/blink/renderer/core/layout/counter_node.h28
-rw-r--r--chromium/third_party/blink/renderer/core/layout/custom_scrollbar.cc295
-rw-r--r--chromium/third_party/blink/renderer/core/layout/custom_scrollbar.h33
-rw-r--r--chromium/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/layout/flexible_box_algorithm.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/floating_objects.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/force_legacy_layout_test.cc43
-rw-r--r--chromium/third_party/blink/renderer/core/layout/geometry/logical_offset.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/layout/geometry/logical_offset.h10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/geometry/logical_offset_test.cc75
-rw-r--r--chromium/third_party/blink/renderer/core/layout/geometry/logical_rect.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/layout/geometry/logical_rect.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/geometry/physical_offset.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/layout/geometry/physical_offset.h15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/geometry/physical_offset_test.cc75
-rw-r--r--chromium/third_party/blink/renderer/core/layout/geometry/physical_rect.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/geometry/physical_rect.h10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/geometry/writing_mode_converter.cc90
-rw-r--r--chromium/third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h124
-rw-r--r--chromium/third_party/blink/renderer/core/layout/geometry/writing_mode_converter_test.cc130
-rw-r--r--chromium/third_party/blink/renderer/core/layout/grid.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/layout/grid.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/grid_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/layout/hit_test_cache.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/hit_test_cache.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/hit_test_canvas_result.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/hit_test_canvas_result.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/hit_test_result.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/hit_test_result.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/intrinsic_sizing_info.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block.h11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block_flow.cc167
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block_flow.h26
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block_flow_line.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box.cc137
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box.h24
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box_model_object.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box_model_object.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box_model_object_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box_test.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_counter.cc239
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_counter.h7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.cc196
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.h68
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_embedded_content.cc61
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_embedded_content.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_embedded_object.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_embedded_object.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_flexible_box.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_grid.cc66
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_grid.h7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_image.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_image_resource.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_image_resource_style_image.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_image_resource_style_image.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_inline.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_inline_test.cc43
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_inside_list_marker.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_inside_list_marker.h17
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_item.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_item.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_marker.cc217
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_marker.h37
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_marker_image.cc (renamed from chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.cc)36
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_marker_image.h36
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_multi_column_set.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_object.cc152
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_object.h146
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_object_factory.cc124
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_object_factory.h26
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_object_test.cc210
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_outside_list_marker.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_outside_list_marker.h15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_quote.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_replaced.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_ruby_run.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_ruby_text.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_ruby_text.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_shift_tracker.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_shift_tracker.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_state.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_state.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table.h15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_cell.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_cell.h12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_cell_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_row.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_row.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_section.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_section.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text.cc134
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_test.cc502
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_theme_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_theme_win.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_tree_as_text.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_video.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_video.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_view.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_view.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_view_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/inline_box.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/list_marker.cc (renamed from chromium/third_party/blink/renderer/core/layout/ng/list/list_marker.cc)327
-rw-r--r--chromium/third_party/blink/renderer/core/layout/list_marker.h (renamed from chromium/third_party/blink/renderer/core/layout/ng/list/list_marker.h)50
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/README.md2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_scope.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/document_layout_definition.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/document_layout_definition.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/pending_layout_registry.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/pending_layout_registry.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc246
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.cc (renamed from chromium/third_party/blink/renderer/core/layout/ng/layout_ng_grid.cc)2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.h (renamed from chromium/third_party/blink/renderer/core/layout/ng/layout_ng_grid.h)6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.h54
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator_test.cc98
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h (renamed from chromium/third_party/blink/renderer/core/layout/ng/ng_grid_layout_algorithm.h)27
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm_test.cc106
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc510
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h207
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection_test.cc248
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/README.md98
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_test.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.h30
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph_test.cc40
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_caret_rect.cc51
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc218
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h90
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc146
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h16
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc200
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h66
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc165
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h47
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc337
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h46
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor_test.cc186
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h21
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc59
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h22
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc59
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc196
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc108
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h43
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc55
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc91
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h258
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc156
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc219
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h47
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.cc121
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h301
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.cc305
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.h85
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.cc48
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.h19
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_offset.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.h31
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h31
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_mathml_paint_info.h28
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h37
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc506
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h36
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_node.cc127
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_node.h42
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_node_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h181
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_break_token.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc166
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.h12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h20
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h36
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc63
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc57
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_floats_utils.cc79
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h30
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_test.cc51
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc131
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h42
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_grid_layout_algorithm.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h27
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result.h36
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_utils.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc79
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils.h48
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc149
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc82
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h25
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h55
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h41
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_positioned_float.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.h10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc68
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc52
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc631
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h42
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc360
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h287
-rw-r--r--chromium/third_party/blink/renderer/core/layout/paint_containment_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/scroll_anchor.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/scroll_anchor.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/scroll_anchor_test.cc66
-rw-r--r--chromium/third_party/blink/renderer/core/layout/scrollbars_test.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/layout/shapes/shape_outside_info.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_block.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_resources.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_resources.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_attributes_builder.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_attributes_builder.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/text_autosizer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/text_autosizer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/text_decoration_offset.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/loader/BUILD.gn6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/appcache/application_cache.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/loader/appcache/application_cache.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host.h8
-rw-r--r--chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/base_fetch_context.cc43
-rw-r--r--chromium/third_party/blink/renderer/core/loader/base_fetch_context.h14
-rw-r--r--chromium/third_party/blink/renderer/core/loader/base_fetch_context_test.cc87
-rw-r--r--chromium/third_party/blink/renderer/core/loader/cookie_jar.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/loader/cookie_jar.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_load_timing.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_load_timing.h8
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_loader.cc326
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_loader.h63
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_loader_test.cc88
-rw-r--r--chromium/third_party/blink/renderer/core/loader/empty_clients.h15
-rw-r--r--chromium/third_party/blink/renderer/core/loader/font_preload_manager.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/font_preload_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/font_preload_manager_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/form_submission.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/form_submission.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_fetch_context.cc105
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_fetch_context.h14
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_load_request.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_loader.cc157
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_loader.h23
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_loader_state_machine.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_loader_test.cc111
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/history_item.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/history_item.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/http_equiv.cc60
-rw-r--r--chromium/third_party/blink/renderer/core/loader/http_equiv.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/http_refresh_scheduler.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/http_refresh_scheduler.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/idleness_detector.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/idleness_detector.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/image_loader.cc92
-rw-r--r--chromium/third_party/blink/renderer/core/loader/image_loader.h4
-rw-r--r--chromium/third_party/blink/renderer/core/loader/interactive_detector.cc115
-rw-r--r--chromium/third_party/blink/renderer/core/loader/interactive_detector.h34
-rw-r--r--chromium/third_party/blink/renderer/core/loader/interactive_detector_test.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/loader/lazy_image_helper.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/loader/link_loader.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/loader/link_loader.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/link_loader_client.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/link_loader_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/loader/loader_factory_for_frame.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/loader/loader_factory_for_frame.h8
-rw-r--r--chromium/third_party/blink/renderer/core/loader/loader_factory_for_worker.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/loader/loader_factory_for_worker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/long_task_detector.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/long_task_detector.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/mixed_content_checker.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/loader/mixed_content_checker.h3
-rw-r--r--chromium/third_party/blink/renderer/core/loader/mixed_content_checker_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetcher.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetcher.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/ping_loader.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/loader/ping_loader_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/preload_helper.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/private/prerender_client.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/private/prerender_handle.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/loader/private/prerender_handle.h22
-rw-r--r--chromium/third_party/blink/renderer/core/loader/progress_tracker.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/progress_tracker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/font_resource.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/font_resource.h15
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource_content.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource_content.h4
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource_info.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/link_fetch_resource.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/link_fetch_resource.h41
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/link_prefetch_resource.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/link_prefetch_resource.h35
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.h4
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/script_resource.cc395
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/script_resource.h107
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_worker.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_worker.h12
-rw-r--r--chromium/third_party/blink/renderer/core/loader/subresource_filter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/subresource_filter.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/text_track_loader.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/text_track_loader.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threadable_loader.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threadable_loader.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threaded_icon_loader.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threaded_icon_loader.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threaded_icon_loader_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/worker_fetch_context.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/loader/worker_fetch_context.h7
-rw-r--r--chromium/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/mathml/mathml_attribute_names.json51
-rw-r--r--chromium/third_party/blink/renderer/core/mathml/mathml_element.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.cc213
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.h16
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/message_channel.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/message_channel.h2
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/message_port.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/message_port.h2
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/post_message_options.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/mojo_watcher.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/mojo_watcher.h2
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h2
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h4
-rw-r--r--chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc151
-rw-r--r--chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.h35
-rw-r--r--chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context_test.cc124
-rw-r--r--chromium/third_party/blink/renderer/core/page/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/page/autoscroll_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/autoscroll_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client.h17
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client_impl.cc60
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client_impl.h13
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client_impl_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/page/context_menu_controller.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/page/context_menu_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/context_menu_provider.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/create_window.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/page/drag_controller.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/page/drag_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/drag_data.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/page/drag_data.h13
-rw-r--r--chromium/third_party/blink/renderer/core/page/drag_image_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/drag_state.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/focus_controller.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/page/focus_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/frame_tree.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/page/frame_tree.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/link_highlight.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/link_highlight.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/named_pages_mapper.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/page/named_pages_mapper.h5
-rw-r--r--chromium/third_party/blink/renderer/core/page/named_pages_mapper_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/page/page.cc101
-rw-r--r--chromium/third_party/blink/renderer/core/page/page.h28
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_animator.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_animator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_popup_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_popup_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_visibility_observer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_visibility_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/plugin_data.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/page/plugin_data.h6
-rw-r--r--chromium/third_party/blink/renderer/core/page/pointer_lock_controller.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/page/pointer_lock_controller.h4
-rw-r--r--chromium/third_party/blink/renderer/core/page/print_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/print_context.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/fragment_anchor.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/fragment_anchor.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc69
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/overscroll_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/overscroll_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc856
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scroll_customization_callbacks.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scroll_state_callback.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scroll_state_callback.h4
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scroll_state_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h3
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc205
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h14
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.cc52
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h15
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc329
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc175
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_finder.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/viewport_scroll_callback.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/viewport_scroll_callback.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/touch_adjustment.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/validation_message_client.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/validation_message_client_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/validation_message_client_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/zoom_test.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/paint/applied_decoration_painter.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/paint/applied_decoration_painter.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_border_painter.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter_base.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc749
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h125
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc244
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc98
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.h33
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner_test.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc103
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc145
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater_test.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_test.cc129
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc242
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h41
-rw-r--r--chromium/third_party/blink/renderer/core/paint/custom_scrollbar_theme.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/paint/custom_scrollbar_theme.h9
-rw-r--r--chromium/third_party/blink/renderer/core/paint/decoration_info.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/document_marker_painter.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/paint/document_marker_painter.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/fieldset_painter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/filter_effect_builder.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/html_canvas_painter.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_element_timing.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_element_timing.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_element_timing_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.h28
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc109
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_painter.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/inline_text_box_painter.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/line_box_list_painter.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/list_marker_painter.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc140
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_fieldset_painter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.cc48
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_mathml_painter.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_mathml_painter.h1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc193
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc57
-rw-r--r--chromium/third_party/blink/renderer/core/paint/nine_piece_image_grid.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.h3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc156
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_painter_base.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc48
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer.cc120
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer.h17
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_painter.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_painting_info.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc111
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc66
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_test.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc56
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc143
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_timing.cc68
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_timing.h43
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_timing_detector.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_timing_detector.h41
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_timing_test_helper.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/scrollable_area_painter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/table_section_painter.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/text_element_timing.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/text_element_timing.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.h6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc62
-rw-r--r--chromium/third_party/blink/renderer/core/paint/text_painter_base.cc276
-rw-r--r--chromium/third_party/blink/renderer/core/paint/text_painter_base.h8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/theme_painter_default.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/paint/video_painter.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/paint/video_painter.h3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/video_painter_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/view_painter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/probe/core_probes.json56
-rw-r--r--chromium/third_party/blink/renderer/core/probe/core_probes.pidl7
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observation.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observation.h2
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer.h4
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.h2
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/scheduler_integration_tests/frame_throttling_test.cc65
-rw-r--r--chromium/third_party/blink/renderer/core/script/classic_pending_script.cc93
-rw-r--r--chromium/third_party/blink/renderer/core/script/classic_pending_script.h11
-rw-r--r--chromium/third_party/blink/renderer/core/script/classic_script.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/script/classic_script.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/dynamic_module_resolver.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/script/dynamic_module_resolver.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/html_parser_script_runner.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/script/html_parser_script_runner.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/html_parser_script_runner_host.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/import_map.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/js_module_script.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/script/js_module_script.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/mock_script_element_base.h4
-rw-r--r--chromium/third_party/blink/renderer/core/script/modulator.h6
-rw-r--r--chromium/third_party/blink/renderer/core/script/modulator_impl_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/script/modulator_impl_base.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_map.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_map.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_map_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_pending_script.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_pending_script.h6
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_record_resolver.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_record_resolver_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_record_resolver_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_record_resolver_impl_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_script.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_script.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_script_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/script/pending_import_map.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/script/pending_import_map.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/pending_script.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/script/pending_script.h9
-rw-r--r--chromium/third_party/blink/renderer/core/script/script.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_element_base.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_element_base.h4
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_loader.cc41
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_loader.h22
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_runner.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_runner.h18
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_runner_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/xml_parser_script_runner.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/script/xml_parser_script_runner.h2
-rw-r--r--chromium/third_party/blink/renderer/core/script/xml_parser_script_runner_host.h2
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.h2
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.h4
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollable_area.cc51
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollable_area.h6
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar.h4
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h1
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_test_suite.h2
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.h1
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h1
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm104
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h4
-rw-r--r--chromium/third_party/blink/renderer/core/streams/.eslintrc.js163
-rw-r--r--chromium/third_party/blink/renderer/core/streams/PRESUBMIT.py36
-rw-r--r--chromium/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.h2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/count_queuing_strategy.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/count_queuing_strategy.h2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/miscellaneous_operations.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/streams/queue_with_sizes.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/streams/queue_with_sizes.h2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream.h28
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream_reader.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream_reader.h2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream_test.cc93
-rw-r--r--chromium/third_party/blink/renderer/core/streams/stream_algorithms.h6
-rw-r--r--chromium/third_party/blink/renderer/core/streams/stream_promise_resolver.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/stream_promise_resolver.h2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/stream_promise_resolver_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transferable_streams.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream.h2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream_transformer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/underlying_sink_base.h2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/underlying_source_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/underlying_source_base.h2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/writable_stream.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/streams/writable_stream.h2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/streams/writable_stream_default_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/style/BUILD.gn17
-rw-r--r--chromium/third_party/blink/renderer/core/style/applied_text_decoration.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/style/applied_text_decoration.h9
-rw-r--r--chromium/third_party/blink/renderer/core/style/border_value.h30
-rw-r--r--chromium/third_party/blink/renderer/core/style/border_value_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/style/cached_ua_style.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/style/cached_ua_style.h12
-rw-r--r--chromium/third_party/blink/renderer/core/style/computed_style.cc68
-rw-r--r--chromium/third_party/blink/renderer/core/style/computed_style.h269
-rw-r--r--chromium/third_party/blink/renderer/core/style/computed_style_constants.h18
-rw-r--r--chromium/third_party/blink/renderer/core/style/computed_style_diff_functions.json573
-rw-r--r--chromium/third_party/blink/renderer/core/style/computed_style_extra_fields.json5127
-rw-r--r--chromium/third_party/blink/renderer/core/style/computed_style_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/style/content_data.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/style/content_data.h4
-rw-r--r--chromium/third_party/blink/renderer/core/style/counter_directives.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/style/counter_directives.h69
-rw-r--r--chromium/third_party/blink/renderer/core/style/cursor_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/style/fill_layer.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/style/fill_layer.h14
-rw-r--r--chromium/third_party/blink/renderer/core/style/filter_operation.cc121
-rw-r--r--chromium/third_party/blink/renderer/core/style/filter_operation.h25
-rw-r--r--chromium/third_party/blink/renderer/core/style/filter_operations.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/style/filter_operations.h5
-rw-r--r--chromium/third_party/blink/renderer/core/style/gap_length.h43
-rw-r--r--chromium/third_party/blink/renderer/core/style/shadow_data.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/style/shadow_data.h3
-rw-r--r--chromium/third_party/blink/renderer/core/style/shape_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_difference.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_fetched_image.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_fetched_image.h2
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_fetched_image_set.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_fetched_image_set.h2
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_filter_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_generated_image.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_generated_image.h2
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_image.h2
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_name.h43
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_name_or_keyword.h48
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_name_or_keyword_test.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_name_test.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_pending_image.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_pending_image.h16
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_ray.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/style/svg_computed_style.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/style/svg_computed_style.h18
-rw-r--r--chromium/third_party/blink/renderer/core/style/svg_computed_style_defs.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/style/svg_computed_style_defs.h7
-rw-r--r--chromium/third_party/blink/renderer/core/style/text_decoration_thickness.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/style/text_decoration_thickness.h6
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/element_smil_animations.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/element_smil_animations.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/priority_queue.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/priority_queue_test.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/smil_repeat_count.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_fe_image.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_fe_image.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/svg_image.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/svg_image.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h9
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc100
-rw-r--r--chromium/third_party/blink/renderer/core/svg/linear_gradient_attributes.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/pattern_attributes.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.h6
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_helper.h7
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_tear_off_helper.h62
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_property.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/radial_gradient_attributes.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_a_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_a_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_angle.cc86
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_angle.h37
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animate_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animate_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_angle.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_angle.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_boolean.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_color.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration.h30
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration_base.h21
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_href.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_href.h8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_integer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_integer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_integer_optional_integer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_integer_optional_integer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_length.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_length.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_length_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_number.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_number.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_number_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_number_optional_number.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_number_optional_number.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_preserve_aspect_ratio.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_rect.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_string.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_string.h9
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_string.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_transform_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_circle_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_circle_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_clip_path_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_clip_path_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_component_transfer_function_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_component_transfer_function_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_document_extensions.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_document_extensions.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_element_rare_data.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_element_rare_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_ellipse_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_ellipse_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_enumeration.cc40
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_enumeration.h55
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_enumeration_map.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_external_document_cache.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_external_document_cache.h10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_blend_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_blend_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_composite_element.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_composite_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_light_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_light_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_merge_node_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_merge_node_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_morphology_element.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_morphology_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_offset_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_offset_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_tile_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_tile_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_filter_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_filter_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fit_to_view_box.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fit_to_view_box.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_geometry_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_geometry_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_gradient_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_gradient_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_graphics_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_graphics_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_image_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_image_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_integer_optional_integer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_integer_optional_integer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_length.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_length.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_line_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_line_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_linear_gradient_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_linear_gradient_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_marker_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_marker_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_mask_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_mask_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_matrix_tear_off.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_matrix_tear_off.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_mpath_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_mpath_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_number_optional_number.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_number_optional_number.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_parser_utilities.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_parsing_error.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_path.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_path.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_path_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_path_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_pattern_element.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_pattern_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_poly_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_poly_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_rect.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_rect_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_rect_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_resource.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_resource.h6
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_script_element.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_script_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_static_string_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_static_string_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_stop_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_stop_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_style_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_style_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_svg_element.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_svg_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_symbol_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_symbol_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_tests.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_tests.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_text_content_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_text_content_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_text_path_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_text_path_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_transform_list.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_transform_list.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_transform_list_tear_off.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_transform_tear_off.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_transform_tear_off.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_tree_scope_resources.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_uri_reference.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_uri_reference.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_use_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_use_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_view_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_view_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_view_spec.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_view_spec.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/unsafe_svg_attribute_sanitization_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/testing/color_scheme_helper.h2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/core_unit_test_helper.h4
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/MaterialIcons-Regular.woff2bin0 -> 44300 bytes
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/first-letter.html3
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/root-scroller-child.html13
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/root-scroller-iframe.html1
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/root-scroller.html1
-rw-r--r--chromium/third_party/blink/renderer/core/testing/death_aware_script_wrappable.h4
-rw-r--r--chromium/third_party/blink/renderer/core/testing/dictionary_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/dictionary_test.h2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/dummy_modulator.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/dummy_modulator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.h13
-rw-r--r--chromium/third_party/blink/renderer/core/testing/fake_remote_frame_host.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/testing/fake_remote_frame_host.h12
-rw-r--r--chromium/third_party/blink/renderer/core/testing/hit_test_layer_rect.h2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/hit_test_layer_rect_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/hit_test_layer_rect_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/internal_settings.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/internal_settings.h2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/internals.cc138
-rw-r--r--chromium/third_party/blink/renderer/core/testing/internals.h5
-rw-r--r--chromium/third_party/blink/renderer/core/testing/internals.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/testing/null_execution_context.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/testing/null_execution_context.h2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/origin_trials_test.h2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/origin_trials_test.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/testing/record_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/record_test.h2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/sequence_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/sequence_test.h2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/sim/sim_compositor.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/testing/sim/sim_test.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/testing/sim/sim_test.h6
-rw-r--r--chromium/third_party/blink/renderer/core/testing/static_selection.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/static_selection.h2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/v8/web_core_test_support.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/testing/wait_for_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/wait_for_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/dom_window_performance.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/dom_window_performance.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/event_counts.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/event_counts.h4
-rw-r--r--chromium/third_party/blink/renderer/core/timing/event_timing.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/timing/event_timing.h8
-rw-r--r--chromium/third_party/blink/renderer/core/timing/largest_contentful_paint.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/largest_contentful_paint.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/layout_shift.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/layout_shift.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.cc193
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance.cc61
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance.h20
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_element_timing.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_element_timing.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_event_timing.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_event_timing.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_mark.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_mark.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_measure.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_measure.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_navigation.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_navigation.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_observer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_observer_entry_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_observer_entry_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_resource_timing.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_resource_timing.h15
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_resource_timing_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_timing.cc115
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_timing.h32
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_user_timing.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_user_timing.h8
-rw-r--r--chromium/third_party/blink/renderer/core/timing/profiler.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/profiler.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/profiler_group.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/timing/profiler_group.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/task_attribution_timing.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/task_attribution_timing.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/window_performance.cc75
-rw-r--r--chromium/third_party/blink/renderer/core/timing/window_performance.h32
-rw-r--r--chromium/third_party/blink/renderer/core/timing/window_performance_test.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/timing/worker_global_scope_performance.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/worker_global_scope_performance.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/worker_performance.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/worker_performance.h2
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h2
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.h2
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h4
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h2
-rw-r--r--chromium/third_party/blink/renderer/core/url/dom_url.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/url/dom_url.h2
-rw-r--r--chromium/third_party/blink/renderer/core/url/url_search_params.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/url/url_search_params.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/abstract_worker.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/workers/abstract_worker.h9
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker.h5
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker_client_holder.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker_client_holder.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker_global_scope.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker_reporting_proxy.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker_reporting_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/threaded_worklet_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_classic_script_loader.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_clients.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_global_scope.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_global_scope.h3
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_module_tree_client.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_module_tree_client.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_navigator.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_navigator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h4
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_thread.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet_global_scope.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet_global_scope.h3
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet_module_responses_map.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet_module_responses_map_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet_module_tree_client.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet_module_tree_client.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet_pending_tasks.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet_pending_tasks.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/document_xpath_evaluator.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/document_xpath_evaluator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/document_xslt.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/xml/document_xslt.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/dom_parser.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/xml/dom_parser.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/native_xpath_ns_resolver.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/native_xpath_ns_resolver.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser.h3
-rw-r--r--chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/parser/xml_errors.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/xml/parser/xml_errors.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_expression.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_expression.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_expression_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_expression_node.h4
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_functions_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_node_set.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_path.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_path.h6
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_predicate.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_predicate.h6
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_result.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_result.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_step.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_step.h4
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_value.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_value.h4
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xsl_style_sheet.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xsl_style_sheet_libxslt.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xslt_processor.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xslt_processor.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h6
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.idl7
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.h2
2864 files changed, 44239 insertions, 28483 deletions
diff --git a/chromium/third_party/blink/renderer/core/BUILD.gn b/chromium/third_party/blink/renderer/core/BUILD.gn
index 432954cf39f..cdd49a53f81 100644
--- a/chromium/third_party/blink/renderer/core/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/BUILD.gn
@@ -247,7 +247,7 @@ jumbo_source_set("testing") {
":core",
":generated_testing_idls",
"//third_party/blink/renderer/bindings/core/v8:testing",
- "//ui/base/cursor",
+ "//ui/base/cursor:cursor_base",
"//ui/base/cursor/mojom:cursor_type_blink",
]
@@ -323,7 +323,6 @@ generate_event_interfaces("core_event_interfaces") {
sources = [
"css/font_face_set_load_event.idl",
"css/media_query_list_event.idl",
- "display_lock/render_subtree_activation_event.idl",
"dom/events/custom_event.idl",
"dom/events/event.idl",
"editing/ime/text_format_update_event.idl",
@@ -1058,7 +1057,6 @@ jumbo_source_set("unit_tests") {
"dom/attr_test.cc",
"dom/document_statistics_collector_test.cc",
"dom/document_test.cc",
- "dom/dom_implementation_test.cc",
"dom/dom_node_ids_test.cc",
"dom/element_test.cc",
"dom/events/event_path_test.cc",
@@ -1125,6 +1123,7 @@ jumbo_source_set("unit_tests") {
"fetch/bytes_consumer_tee_test.cc",
"fetch/bytes_consumer_test_util.cc",
"fetch/bytes_consumer_test_util.h",
+ "fetch/bytes_uploader_test.cc",
"fetch/fetch_data_loader_test.cc",
"fetch/fetch_header_list_test.cc",
"fetch/fetch_request_data_test.cc",
@@ -1154,6 +1153,7 @@ jumbo_source_set("unit_tests") {
"frame/frame_test_helpers.cc",
"frame/frame_test_helpers.h",
"frame/history_test.cc",
+ "frame/local_dom_window_test.cc",
"frame/local_frame_back_forward_cache_test.cc",
"frame/local_frame_test.cc",
"frame/local_frame_ukm_aggregator_test.cc",
@@ -1164,7 +1164,6 @@ jumbo_source_set("unit_tests") {
"frame/reporting_context_test.cc",
"frame/root_frame_viewport_test.cc",
"frame/rotation_viewport_anchor_test.cc",
- "frame/sticky_frame_tracker_test.cc",
"frame/use_counter_helper_test.cc",
"frame/visual_viewport_test.cc",
"fullscreen/scoped_allow_fullscreen_test.cc",
@@ -1185,11 +1184,10 @@ jumbo_source_set("unit_tests") {
"layout/api/selection_state_test.cc",
"layout/collapsed_border_value_test.cc",
"layout/force_legacy_layout_test.cc",
- "layout/geometry/logical_offset_test.cc",
"layout/geometry/logical_rect_test.cc",
- "layout/geometry/physical_offset_test.cc",
"layout/geometry/physical_rect_test.cc",
"layout/geometry/physical_size_test.cc",
+ "layout/geometry/writing_mode_converter_test.cc",
"layout/grid_test.cc",
"layout/hit_testing_test.cc",
"layout/layout_block_test.cc",
@@ -1230,7 +1228,11 @@ jumbo_source_set("unit_tests") {
"layout/ng/exclusions/ng_exclusion_space_test.cc",
"layout/ng/geometry/ng_box_strut_test.cc",
"layout/ng/geometry/ng_static_position_test.cc",
+ "layout/ng/grid/ng_grid_child_iterator_test.cc",
+ "layout/ng/grid/ng_grid_layout_algorithm_test.cc",
+ "layout/ng/grid/ng_grid_track_collection_test.cc",
"layout/ng/inline/layout_ng_text_test.cc",
+ "layout/ng/inline/ng_bidi_paragraph_test.cc",
"layout/ng/inline/ng_caret_position_test.cc",
"layout/ng/inline/ng_fragment_item_test.cc",
"layout/ng/inline/ng_inline_cursor_test.cc",
@@ -1278,6 +1280,7 @@ jumbo_source_set("unit_tests") {
"loader/document_loader_test.cc",
"loader/font_preload_manager_test.cc",
"loader/frame_fetch_context_test.cc",
+ "loader/frame_loader_test.cc",
"loader/frame_resource_fetcher_properties_test.cc",
"loader/idleness_detector_test.cc",
"loader/image_loader_test.cc",
@@ -1301,7 +1304,6 @@ jumbo_source_set("unit_tests") {
"loader/resource/mock_image_resource_observer.h",
"loader/resource/multipart_image_resource_parser_test.cc",
"loader/resource_load_observer_for_frame_test.cc",
- "loader/text_resource_decoder_builder_test.cc",
"loader/threadable_loader_test.cc",
"loader/threaded_icon_loader_test.cc",
"loader/web_associated_url_loader_impl_test.cc",
@@ -1337,7 +1339,6 @@ jumbo_source_set("unit_tests") {
"page/validation_message_overlay_delegate_test.cc",
"page/viewport_test.cc",
"page/window_features_test.cc",
- "page/zoom_test.cc",
"paint/block_painter_test.cc",
"paint/box_paint_invalidator_test.cc",
"paint/box_painter_test.cc",
@@ -1409,12 +1410,6 @@ jumbo_source_set("unit_tests") {
"streams/transferable_streams_test.cc",
"streams/transform_stream_test.cc",
"streams/writable_stream_test.cc",
- "style/border_value_test.cc",
- "style/computed_style_test.cc",
- "style/filter_operations_test.cc",
- "style/style_difference_test.cc",
- "style/style_variables_test.cc",
- "style/svg_computed_style_test.cc",
"svg/animation/priority_queue_test.cc",
"svg/animation/smil_time_container_test.cc",
"svg/animation/svg_smil_element_test.cc",
@@ -1488,7 +1483,8 @@ jumbo_source_set("unit_tests") {
"//third_party/blink/renderer/core/editing:unit_tests",
"//third_party/blink/renderer/core/fileapi:unit_tests",
"//third_party/blink/renderer/core/html:unit_tests",
- "//ui/base/cursor",
+ "//third_party/blink/renderer/core/style:unit_tests",
+ "//ui/base/cursor:cursor_base",
"//ui/base/cursor/mojom:cursor_type_blink",
]
diff --git a/chromium/third_party/blink/renderer/core/DEPS b/chromium/third_party/blink/renderer/core/DEPS
index ade19e141c6..1383ab13f1a 100644
--- a/chromium/third_party/blink/renderer/core/DEPS
+++ b/chromium/third_party/blink/renderer/core/DEPS
@@ -2,7 +2,6 @@ include_rules = [
"+base/atomic_sequence_num.h",
"+base/barrier_closure.h",
"+base/bits.h",
- "+base/callback_helpers.h",
"+base/files/file.h",
"+base/mac/foundation_util.h",
"+base/mac/mac_util.h",
@@ -35,6 +34,7 @@ include_rules = [
"+cc/input/layer_selection_bound.h",
"+cc/input/main_thread_scrolling_reason.h",
"+cc/input/overscroll_behavior.h",
+ "+cc/input/scroll_utils.h",
"+cc/input/scrollbar.h",
"+cc/input/scroll_snap_data.h",
"+cc/input/scroll_state.h",
@@ -96,12 +96,15 @@ include_rules = [
"+ui/accessibility/ax_event.h",
"+ui/accessibility/ax_event_intent.h",
"+ui/base/cursor/cursor.h",
+ "+ui/base/ime/ime_text_span.h",
"+ui/base/ime/mojom/ime_types.mojom-blink.h",
"+ui/base/ime/mojom/ime_types.mojom-blink-forward.h",
+ "+ui/base/ime/mojom/text_input_state.mojom-blink.h",
+ "+ui/base/ime/mojom/virtual_keyboard_types.mojom-blink.h",
+ "+ui/base/ime/mojom/virtual_keyboard_types.mojom-blink-forward.h",
"+ui/base/resource/scale_factor.h",
"+ui/base/ui_base_features.h",
"+ui/display/mojom/display.mojom-blink.h",
- "+ui/gfx/mac/cocoa_scrollbar_painter.h",
"+ui/gfx/geometry",
"+ui/gfx/range/range.h",
"+ui/gfx/skia_util.h",
diff --git a/chromium/third_party/blink/renderer/core/accessibility/apply_dark_mode.cc b/chromium/third_party/blink/renderer/core/accessibility/apply_dark_mode.cc
index 88164f47a8d..3746361eb1f 100644
--- a/chromium/third_party/blink/renderer/core/accessibility/apply_dark_mode.cc
+++ b/chromium/third_party/blink/renderer/core/accessibility/apply_dark_mode.cc
@@ -35,7 +35,7 @@ bool HasLightBackground(const LayoutView& root) {
if (color.Alpha() < kAlphaThreshold)
return true;
- return DarkModeColorClassifier::CalculateColorBrightness(color) >
+ return DarkModeColorClassifier::CalculateColorBrightness(color.Rgb()) >
kBrightnessThreshold;
}
diff --git a/chromium/third_party/blink/renderer/core/accessibility/ax_object_cache.h b/chromium/third_party/blink/renderer/core/accessibility/ax_object_cache.h
index db8a56963b0..f853e033516 100644
--- a/chromium/third_party/blink/renderer/core/accessibility/ax_object_cache.h
+++ b/chromium/third_party/blink/renderer/core/accessibility/ax_object_cache.h
@@ -57,7 +57,7 @@ class CORE_EXPORT AXObjectCache : public GarbageCollected<AXObjectCache> {
static AXObjectCache* Create(Document&);
virtual ~AXObjectCache() = default;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
virtual void Dispose() = 0;
diff --git a/chromium/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.cc b/chromium/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.cc
index 4e7b6e5a136..dcb82b185c5 100644
--- a/chromium/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.cc
+++ b/chromium/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.cc
@@ -24,7 +24,8 @@ BlinkAXEventIntent BlinkAXEventIntent::FromModifiedSelection(
const SelectionModifyDirection direction,
const TextGranularity granularity,
const SetSelectionBy set_selection_by,
- const TextDirection direction_of_selection) {
+ const TextDirection direction_of_selection,
+ const PlatformWordBehavior platform_word_behavior) {
ax::mojom::blink::Command command;
switch (alter) {
case SelectionModifyAlteration::kExtend:
@@ -66,14 +67,43 @@ BlinkAXEventIntent BlinkAXEventIntent::FromModifiedSelection(
case TextGranularity::kWord:
switch (move_direction) {
case ax::mojom::blink::MoveDirection::kBackward:
+ // All platforms behave the same when moving backward by word.
text_boundary = ax::mojom::blink::TextBoundary::kWordStart;
break;
case ax::mojom::blink::MoveDirection::kForward:
- text_boundary = ax::mojom::blink::TextBoundary::kWordEnd;
+ switch (platform_word_behavior) {
+ case PlatformWordBehavior::kWordSkipSpaces:
+ // Windows behavior is to always move to the beginning of the next
+ // word.
+ text_boundary = ax::mojom::blink::TextBoundary::kWordStart;
+ break;
+ case PlatformWordBehavior::kWordDontSkipSpaces:
+ // Mac, Linux and ChromeOS behavior is to move to the end of the
+ // current word.
+ text_boundary = ax::mojom::blink::TextBoundary::kWordEnd;
+ break;
+ }
break;
}
break;
case TextGranularity::kSentence:
+ // This granularity always moves to the start of the next or previous
+ // sentence.
+ text_boundary = ax::mojom::blink::TextBoundary::kSentenceStart;
+ break;
+ case TextGranularity::kLine:
+ // This granularity always moves to the start of the next or previous
+ // line.
+ text_boundary = ax::mojom::blink::TextBoundary::kLineStart;
+ break;
+ case TextGranularity::kParagraph:
+ // This granularity always moves to the start of the next or previous
+ // paragraph.
+ text_boundary = ax::mojom::blink::TextBoundary::kParagraphStart;
+ break;
+ case TextGranularity::kSentenceBoundary:
+ // This granularity moves either to the start or the end of the current
+ // sentence, depending on the direction.
switch (move_direction) {
case ax::mojom::blink::MoveDirection::kBackward:
text_boundary = ax::mojom::blink::TextBoundary::kSentenceStart;
@@ -83,7 +113,9 @@ BlinkAXEventIntent BlinkAXEventIntent::FromModifiedSelection(
break;
}
break;
- case TextGranularity::kLine:
+ case TextGranularity::kLineBoundary:
+ // This granularity moves either to the start or the end of the current
+ // line, depending on the direction.
switch (move_direction) {
case ax::mojom::blink::MoveDirection::kBackward:
text_boundary = ax::mojom::blink::TextBoundary::kLineStart;
@@ -93,7 +125,9 @@ BlinkAXEventIntent BlinkAXEventIntent::FromModifiedSelection(
break;
}
break;
- case TextGranularity::kParagraph:
+ case TextGranularity::kParagraphBoundary:
+ // This granularity moves either to the start or the end of the current
+ // paragraph, depending on the direction.
switch (move_direction) {
case ax::mojom::blink::MoveDirection::kBackward:
text_boundary = ax::mojom::blink::TextBoundary::kParagraphStart;
@@ -103,15 +137,6 @@ BlinkAXEventIntent BlinkAXEventIntent::FromModifiedSelection(
break;
}
break;
- case TextGranularity::kSentenceBoundary:
- text_boundary = ax::mojom::blink::TextBoundary::kSentenceStartOrEnd;
- break;
- case TextGranularity::kLineBoundary:
- text_boundary = ax::mojom::blink::TextBoundary::kLineStartOrEnd;
- break;
- case TextGranularity::kParagraphBoundary:
- text_boundary = ax::mojom::blink::TextBoundary::kParagraphStartOrEnd;
- break;
case TextGranularity::kDocumentBoundary:
text_boundary = ax::mojom::blink::TextBoundary::kWebPage;
break;
diff --git a/chromium/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h b/chromium/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h
index 7b4deacebdf..ee6aaa73424 100644
--- a/chromium/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h
+++ b/chromium/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/core/editing/selection_modifier.h"
#include "third_party/blink/renderer/core/editing/set_selection_options.h"
#include "third_party/blink/renderer/core/editing/text_granularity.h"
+#include "third_party/blink/renderer/core/editing/visible_units.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/wtf/hash_table_deleted_value_type.h"
#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
@@ -35,7 +36,8 @@ class CORE_EXPORT BlinkAXEventIntent final {
const SelectionModifyDirection direction,
const TextGranularity granularity,
const SetSelectionBy set_selection_by,
- const TextDirection direction_of_selection);
+ const TextDirection direction_of_selection,
+ const PlatformWordBehavior platform_word_behavior);
static BlinkAXEventIntent FromNewSelection(
const TextGranularity granularity,
bool is_base_first,
diff --git a/chromium/third_party/blink/renderer/core/animation/BUILD.gn b/chromium/third_party/blink/renderer/core/animation/BUILD.gn
index b2cd411ccd6..ff36b90143b 100644
--- a/chromium/third_party/blink/renderer/core/animation/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/animation/BUILD.gn
@@ -86,6 +86,8 @@ blink_core_sources("animation") {
"css_filter_list_interpolation_type.h",
"css_font_size_interpolation_type.cc",
"css_font_size_interpolation_type.h",
+ "css_font_stretch_interpolation_type.cc",
+ "css_font_stretch_interpolation_type.h",
"css_font_variation_settings_interpolation_type.cc",
"css_font_variation_settings_interpolation_type.h",
"css_font_weight_interpolation_type.cc",
diff --git a/chromium/third_party/blink/renderer/core/animation/animatable.cc b/chromium/third_party/blink/renderer/core/animation/animatable.cc
index 6d6466339df..01fee49eac1 100644
--- a/chromium/third_party/blink/renderer/core/animation/animatable.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animatable.cc
@@ -56,12 +56,17 @@ UnrestrictedDoubleOrKeyframeEffectOptions CoerceEffectOptions(
} // namespace
+// https://drafts.csswg.org/web-animations/#dom-animatable-animate
Animation* Animatable::animate(
ScriptState* script_state,
const ScriptValue& keyframes,
const UnrestrictedDoubleOrKeyframeAnimationOptions& options,
ExceptionState& exception_state) {
+ if (!script_state->ContextIsValid())
+ return nullptr;
Element* element = GetAnimationTarget();
+ if (!element->GetExecutionContext())
+ return nullptr;
KeyframeEffect* effect =
KeyframeEffect::Create(script_state, element, keyframes,
CoerceEffectOptions(options), exception_state);
@@ -70,16 +75,33 @@ Animation* Animatable::animate(
ReportFeaturePolicyViolationsIfNecessary(*element->GetExecutionContext(),
*effect->Model());
- Animation* animation = element->GetDocument().Timeline().Play(effect);
- if (options.IsKeyframeAnimationOptions())
- animation->setId(options.GetAsKeyframeAnimationOptions()->id());
+ if (!options.IsKeyframeAnimationOptions())
+ return element->GetDocument().Timeline().Play(effect);
+
+ Animation* animation;
+ const KeyframeAnimationOptions* options_dict =
+ options.GetAsKeyframeAnimationOptions();
+ if (!options_dict->hasTimeline()) {
+ animation = element->GetDocument().Timeline().Play(effect);
+ } else if (AnimationTimeline* timeline = options_dict->timeline()) {
+ animation = timeline->Play(effect);
+ } else {
+ animation = Animation::Create(element->GetExecutionContext(), effect,
+ nullptr, exception_state);
+ }
+
+ animation->setId(options_dict->id());
return animation;
}
Animation* Animatable::animate(ScriptState* script_state,
const ScriptValue& keyframes,
ExceptionState& exception_state) {
+ if (!script_state->ContextIsValid())
+ return nullptr;
Element* element = GetAnimationTarget();
+ if (!element->GetExecutionContext())
+ return nullptr;
KeyframeEffect* effect =
KeyframeEffect::Create(script_state, element, keyframes, exception_state);
if (exception_state.HadException())
diff --git a/chromium/third_party/blink/renderer/core/animation/animation.cc b/chromium/third_party/blink/renderer/core/animation/animation.cc
index b17d3bddbd4..12a68121610 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animation.cc
@@ -996,14 +996,6 @@ void Animation::ResetPendingTasks() {
// https://drafts.csswg.org/web-animations/#pausing-an-animation-section
void Animation::pause(ExceptionState& exception_state) {
- // TODO(crbug.com/916117): Implement pause for scroll-linked animations.
- if (timeline_ && timeline_->IsScrollTimeline()) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kNotSupportedError,
- "Scroll-linked WebAnimation currently does not support pause.");
- return;
- }
-
// 1. If animation has a pending pause task, abort these steps.
// 2. If the play state of animation is paused, abort these steps.
if (pending_pause_ || CalculateAnimationPlayState() == kPaused)
@@ -1186,6 +1178,12 @@ void Animation::PlayInternal(AutoRewind auto_rewind,
else
hold_time_ = 0;
}
+ // TODO(crbug.com/1081267): Update based on upcoming spec change.
+ // https://github.com/w3c/csswg-drafts/pull/5059
+ if (performed_seek && has_finite_timeline) {
+ hold_time_ = base::nullopt;
+ ApplyPendingPlaybackRate();
+ }
// 6. If animation has a pending play task or a pending pause task,
// 6.1 Cancel that task.
@@ -1233,14 +1231,6 @@ void Animation::PlayInternal(AutoRewind auto_rewind,
// https://drafts.csswg.org/web-animations/#reversing-an-animation-section
void Animation::reverse(ExceptionState& exception_state) {
- // TODO(crbug.com/916117): Implement reverse for scroll-linked animations.
- if (timeline_ && timeline_->IsScrollTimeline()) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kNotSupportedError,
- "Scroll-linked WebAnimation currently does not support reverse.");
- return;
- }
-
// 1. If there is no timeline associated with animation, or the associated
// timeline is inactive throw an "InvalidStateError" DOMException and abort
// these steps.
@@ -1371,6 +1361,11 @@ void Animation::UpdateFinishedState(UpdateType update_type,
ScheduleAsyncFinish();
}
} else {
+ // Previously finished animation may restart so they should be added to
+ // pending animations to make sure that a compositor animation is re-created
+ // during future PreCommit.
+ if (finished_)
+ SetCompositorPending();
// 6. If not finished but the current finished promise is already resolved,
// create a new promise.
finished_ = pending_finish_notification_ = committed_finish_notification_ =
@@ -1437,16 +1432,6 @@ void Animation::CommitFinishNotification() {
// https://drafts.csswg.org/web-animations/#setting-the-playback-rate-of-an-animation
void Animation::updatePlaybackRate(double playback_rate,
ExceptionState& exception_state) {
- // TODO(crbug.com/916117): Implement updatePlaybackRate for scroll-linked
- // animations.
- if (timeline_ && timeline_->IsScrollTimeline()) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kNotSupportedError,
- "Scroll-linked WebAnimation currently does not support"
- " updatePlaybackRate.");
- return;
- }
-
// 1. Let previous play state be animation’s play state.
// 2. Let animation’s pending playback rate be new playback rate.
AnimationPlayState play_state = CalculateAnimationPlayState();
@@ -1704,6 +1689,14 @@ Animation::CheckCanStartAnimationOnCompositorInternal() const {
To<DocumentTimeline>(*timeline_).PlaybackRate() != 1)
reasons |= CompositorAnimations::kInvalidAnimationOrEffect;
+ // If the scroll source is not composited, fall back to main thread.
+ // TODO(crbug.com/476553): Once all ScrollNodes including uncomposited ones
+ // are in the compositor, the animation should be composited.
+ if (timeline_->IsScrollTimeline() &&
+ !CompositorAnimations::CheckUsesCompositedScrolling(
+ To<ScrollTimeline>(*timeline_).ResolvedScrollSource()))
+ reasons |= CompositorAnimations::kTimelineSourceHasInvalidCompositingState;
+
// An Animation without an effect cannot produce a visual, so there is no
// reason to composite it.
if (!IsA<KeyframeEffect>(content_.Get()))
@@ -1840,15 +1833,20 @@ bool Animation::Update(TimingUpdateReason reason) {
UpdateFinishedState(UpdateType::kContinuous, NotificationType::kAsync);
if (content_) {
- base::Optional<double> inherited_time = idle || !timeline_->currentTime()
- ? base::nullopt
- : CurrentTimeInternal();
+ base::Optional<double> inherited_time;
+ base::Optional<TimelinePhase> timeline_phase;
+
+ if (!idle) {
+ inherited_time = CurrentTimeInternal();
+ // Special case for end-exclusivity when playing backwards.
+ if (inherited_time == 0 && EffectivePlaybackRate() < 0)
+ inherited_time = -1;
- // Special case for end-exclusivity when playing backwards.
- if (inherited_time == 0 && EffectivePlaybackRate() < 0)
- inherited_time = -1;
+ timeline_phase = timeline_->Phase();
+ }
+
+ content_->UpdateInheritedTime(inherited_time, timeline_phase, reason);
- content_->UpdateInheritedTime(inherited_time, reason);
// After updating the animation time if the animation is no longer current
// blink will no longer composite the element (see
// CompositingReasonFinder::RequiresCompositingFor*Animation). We cancel any
@@ -2034,19 +2032,6 @@ void Animation::DetachCompositorTimeline() {
compositor_timeline->AnimationDestroyed(*this);
}
-void Animation::UpdateCompositorScrollTimeline() {
- if (!compositor_animation_ || !timeline_)
- return;
- auto& timeline = To<ScrollTimeline>(*timeline_);
- Node* scroll_source = timeline.ResolvedScrollSource();
- auto start_scroll_offset = timeline.GetResolvedStartScrollOffset();
- auto end_scroll_offset = timeline.GetResolvedEndScrollOffset();
-
- compositor_animation_->GetAnimation()->UpdateScrollTimeline(
- scroll_timeline_util::GetCompositorScrollElementId(scroll_source),
- start_scroll_offset, end_scroll_offset);
-}
-
void Animation::AttachCompositedLayers() {
if (!compositor_animation_)
return;
@@ -2374,7 +2359,7 @@ void Animation::commitStyles(ExceptionState& exception_state) {
WrapWeakPersistent(inline_style), WrapWeakPersistent(target)));
}
-void Animation::Trace(Visitor* visitor) {
+void Animation::Trace(Visitor* visitor) const {
visitor->Trace(content_);
visitor->Trace(document_);
visitor->Trace(timeline_);
diff --git a/chromium/third_party/blink/renderer/core/animation/animation.h b/chromium/third_party/blink/renderer/core/animation/animation.h
index c9bb999fd50..f0e19050b79 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation.h
+++ b/chromium/third_party/blink/renderer/core/animation/animation.h
@@ -266,7 +266,7 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
void InvalidateKeyframeEffect(const TreeScope&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool CompositorPendingForTesting() const { return compositor_pending_; }
@@ -286,11 +286,6 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
// depends on computed values.
virtual void FlushPendingUpdates() const {}
- // TODO(yigu): This is a reverse dependency between AnimationTimeline and
- // Animation. We should move the update logic once snapshotting is
- // implemented. https://crbug.com/1060578.
- void UpdateCompositorScrollTimeline();
-
protected:
DispatchEventResult DispatchEventInternal(Event&) override;
void AddedEventListener(const AtomicString& event_type,
@@ -470,7 +465,7 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
void Detach();
- void Trace(Visitor* visitor) { visitor->Trace(animation_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(animation_); }
CompositorAnimation* GetAnimation() const {
return compositor_animation_.get();
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_effect.cc b/chromium/third_party/blink/renderer/core/animation/animation_effect.cc
index 4fb89c5c873..286f2d33216 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_effect.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animation_effect.cc
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h"
#include "third_party/blink/renderer/core/animation/animation.h"
#include "third_party/blink/renderer/core/animation/animation_input_helpers.h"
+#include "third_party/blink/renderer/core/animation/animation_timeline.h"
#include "third_party/blink/renderer/core/animation/keyframe_effect.h"
#include "third_party/blink/renderer/core/animation/timing_calculations.h"
#include "third_party/blink/renderer/core/animation/timing_input.h"
@@ -107,8 +108,32 @@ void AnimationEffect::updateTiming(OptionalEffectTiming* optional_timing,
InvalidateAndNotifyOwner();
}
-void AnimationEffect::UpdateInheritedTime(base::Optional<double> inherited_time,
- TimingUpdateReason reason) const {
+base::Optional<Timing::Phase> TimelinePhaseToTimingPhase(
+ base::Optional<TimelinePhase> phase) {
+ base::Optional<Timing::Phase> result;
+ if (phase) {
+ switch (phase.value()) {
+ case TimelinePhase::kBefore:
+ result = Timing::Phase::kPhaseBefore;
+ break;
+ case TimelinePhase::kActive:
+ result = Timing::Phase::kPhaseActive;
+ break;
+ case TimelinePhase::kAfter:
+ result = Timing::Phase::kPhaseAfter;
+ break;
+ case TimelinePhase::kInactive:
+ // Timing::Phase does not have an inactive phase.
+ break;
+ }
+ }
+ return result;
+}
+
+void AnimationEffect::UpdateInheritedTime(
+ base::Optional<double> inherited_time,
+ base::Optional<TimelinePhase> inherited_timeline_phase,
+ TimingUpdateReason reason) const {
base::Optional<double> playback_rate = base::nullopt;
if (GetAnimation())
playback_rate = GetAnimation()->playbackRate();
@@ -117,15 +142,21 @@ void AnimationEffect::UpdateInheritedTime(base::Optional<double> inherited_time,
? Timing::AnimationDirection::kBackwards
: Timing::AnimationDirection::kForwards;
+ base::Optional<Timing::Phase> timeline_phase =
+ TimelinePhaseToTimingPhase(inherited_timeline_phase);
+
bool needs_update = needs_update_ || last_update_time_ != inherited_time ||
- (owner_ && owner_->EffectSuppressed());
+ (owner_ && owner_->EffectSuppressed()) ||
+ last_update_phase_ != timeline_phase;
needs_update_ = false;
last_update_time_ = inherited_time;
+ last_update_phase_ = timeline_phase;
const base::Optional<double> local_time = inherited_time;
if (needs_update) {
Timing::CalculatedTiming calculated = SpecifiedTiming().CalculateTimings(
- local_time, direction, IsA<KeyframeEffect>(this), playback_rate);
+ local_time, timeline_phase, direction, IsA<KeyframeEffect>(this),
+ playback_rate);
const bool was_canceled = calculated.phase != calculated_.phase &&
calculated.phase == Timing::kPhaseNone;
@@ -179,7 +210,7 @@ const Animation* AnimationEffect::GetAnimation() const {
return owner_ ? owner_->GetAnimation() : nullptr;
}
-void AnimationEffect::Trace(Visitor* visitor) {
+void AnimationEffect::Trace(Visitor* visitor) const {
visitor->Trace(owner_);
visitor->Trace(event_delegate_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_effect.h b/chromium/third_party/blink/renderer/core/animation/animation_effect.h
index 8e25ca4cebb..a35b604bbe3 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_effect.h
+++ b/chromium/third_party/blink/renderer/core/animation/animation_effect.h
@@ -42,6 +42,7 @@
namespace blink {
class Animation;
+enum class TimelinePhase;
class AnimationEffectOwner;
class EffectTiming;
class ComputedEffectTiming;
@@ -74,7 +75,7 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable {
virtual void OnEventCondition(const AnimationEffect&, Timing::Phase) = 0;
virtual bool IsAnimationEventDelegate() const { return false; }
virtual bool IsTransitionEventDelegate() const { return false; }
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
~AnimationEffect() override = default;
@@ -125,7 +126,7 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable {
const Animation* GetAnimationForTesting() const { return GetAnimation(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit AnimationEffect(const Timing&, EventDelegate* = nullptr);
@@ -134,6 +135,7 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable {
// it will (if necessary) recalculate timings and (if necessary) call
// updateChildrenAndEffects.
void UpdateInheritedTime(base::Optional<double> inherited_time,
+ base::Optional<TimelinePhase> inherited_phase,
TimingUpdateReason) const;
void Invalidate() const { needs_update_ = true; }
void InvalidateAndNotifyOwner() const;
@@ -167,6 +169,7 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable {
mutable Timing::CalculatedTiming calculated_;
mutable bool needs_update_;
mutable base::Optional<double> last_update_time_;
+ mutable base::Optional<Timing::Phase> last_update_phase_;
double cancel_time_;
const Timing::CalculatedTiming& EnsureCalculated() const;
};
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_effect_test.cc b/chromium/third_party/blink/renderer/core/animation/animation_effect_test.cc
index 186961d7308..027ceaa7bf6 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_effect_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animation_effect_test.cc
@@ -86,7 +86,8 @@ class TestAnimationEffect : public AnimationEffect {
void UpdateInheritedTime(double time, TimingUpdateReason reason) {
event_delegate_->Reset();
- AnimationEffect::UpdateInheritedTime(time, reason);
+ AnimationEffect::UpdateInheritedTime(
+ time, /*inherited_phase*/ base::nullopt, reason);
}
void UpdateChildrenAndEffects() const override {}
@@ -117,7 +118,7 @@ class TestAnimationEffect : public AnimationEffect {
return result;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(event_delegate_);
AnimationEffect::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_test.cc b/chromium/third_party/blink/renderer/core/animation/animation_test.cc
index a141a63fe3a..97a53b05b8f 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animation_test.cc
@@ -1462,6 +1462,8 @@ TEST_F(AnimationAnimationTestCompositing,
model->SnapshotAllCompositorKeyframesIfNecessary(
*element, *ComputedStyle::Create(), nullptr);
+
+ UpdateAllLifecyclePhasesForTest();
scroll_animation->play();
EXPECT_EQ(scroll_animation->CheckCanStartAnimationOnCompositor(nullptr),
CompositorAnimations::kNoFailure);
@@ -1528,6 +1530,8 @@ TEST_F(AnimationAnimationTestCompositing,
model->SnapshotAllCompositorKeyframesIfNecessary(
*element, *ComputedStyle::Create(), nullptr);
+
+ UpdateAllLifecyclePhasesForTest();
const double TEST_START_TIME = 10;
scroll_animation->setStartTime(TEST_START_TIME);
scroll_animation->play();
@@ -1598,6 +1602,90 @@ TEST_F(AnimationAnimationTestNoCompositing, ScrollLinkedAnimationCreation) {
EXPECT_EQ(40, scroll_animation->currentTime());
}
+// Verifies that finished composited scroll-linked animations restart on
+// compositor upon reverse scrolling.
+TEST_F(AnimationAnimationTestCompositing,
+ FinishedScrollLinkedAnimationRestartsOnReverseScrolling) {
+ ResetWithCompositedAnimation();
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #scroller { will-change: transform; overflow: scroll; width: 100px; height: 100px; }
+ #target { width: 100px; height: 200px; will-change: opacity;}
+ #spacer { width: 200px; height: 700px; }
+ </style>
+ <div id ='scroller'>
+ <div id ='target'></div>
+ <div id ='spacer'></div>
+ </div>
+ )HTML");
+
+ LayoutBoxModelObject* scroller =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"));
+ ASSERT_TRUE(scroller->UsesCompositedScrolling());
+
+ // Create ScrollTimeline
+ ScrollTimelineOptions* options = ScrollTimelineOptions::Create();
+ DoubleOrScrollTimelineAutoKeyword time_range =
+ DoubleOrScrollTimelineAutoKeyword::FromDouble(100);
+ options->setTimeRange(time_range);
+ options->setScrollSource(GetElementById("scroller"));
+ ScrollTimeline* scroll_timeline =
+ ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
+
+ // Create KeyframeEffect
+ Timing timing;
+ timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
+ Persistent<StringKeyframe> start_keyframe =
+ MakeGarbageCollected<StringKeyframe>();
+ start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
+ SecureContextMode::kInsecureContext,
+ nullptr);
+ Persistent<StringKeyframe> end_keyframe =
+ MakeGarbageCollected<StringKeyframe>();
+ end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
+ SecureContextMode::kInsecureContext,
+ nullptr);
+
+ StringKeyframeVector keyframes;
+ keyframes.push_back(start_keyframe);
+ keyframes.push_back(end_keyframe);
+
+ Element* element = GetElementById("target");
+ auto* model = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes);
+
+ KeyframeEffect* keyframe_effect =
+ MakeGarbageCollected<KeyframeEffect>(element, model, timing);
+
+ // Create scroll-linked animation
+ NonThrowableExceptionState exception_state;
+ Animation* scroll_animation =
+ Animation::Create(keyframe_effect, scroll_timeline, exception_state);
+ model->SnapshotAllCompositorKeyframesIfNecessary(
+ *element, *ComputedStyle::Create(), nullptr);
+ UpdateAllLifecyclePhasesForTest();
+
+ scroll_animation->play();
+ EXPECT_EQ(scroll_animation->playState(), "running");
+ GetDocument().GetPendingAnimations().Update(nullptr, true);
+ EXPECT_TRUE(scroll_animation->HasActiveAnimationsOnCompositor());
+
+ // Advances the animation to "finished" state. The composited animation will
+ // be destroyed accordingly.
+ scroll_animation->setCurrentTime(50000);
+ EXPECT_EQ(scroll_animation->playState(), "finished");
+ scroll_animation->Update(kTimingUpdateForAnimationFrame);
+ GetDocument().GetPendingAnimations().Update(nullptr, true);
+ EXPECT_FALSE(scroll_animation->HasActiveAnimationsOnCompositor());
+
+ // Restarting the animation should create a new compositor animation.
+ scroll_animation->setCurrentTime(100);
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_EQ(scroll_animation->playState(), "running");
+ scroll_animation->Update(kTimingUpdateForAnimationFrame);
+ GetDocument().GetPendingAnimations().Update(nullptr, true);
+ EXPECT_TRUE(scroll_animation->HasActiveAnimationsOnCompositor());
+}
+
TEST_F(AnimationAnimationTestNoCompositing,
RemoveCanceledAnimationFromActiveSet) {
EXPECT_EQ("running", animation->playState());
@@ -1855,4 +1943,71 @@ TEST_F(AnimationPendingAnimationsTest,
EXPECT_FALSE(animD->pending());
}
+TEST_F(AnimationAnimationTestCompositing,
+ ScrollLinkedAnimationNotCompositedIfScrollSourceIsNotComposited) {
+ GetDocument().GetSettings()->SetPreferCompositingToLCDTextEnabled(false);
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #scroller { overflow: scroll; width: 100px; height: 100px; }
+ #target { width: 100px; height: 200px; will-change: transform; }
+ #spacer { width: 200px; height: 2000px; }
+ </style>
+ <div id ='scroller'>
+ <div id ='target'></div>
+ <div id ='spacer'></div>
+ </div>
+ )HTML");
+
+ // Create ScrollTimeline
+ LayoutBoxModelObject* scroller =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"));
+ PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
+ ASSERT_FALSE(scroller->UsesCompositedScrolling());
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 20),
+ mojom::blink::ScrollType::kProgrammatic);
+ ScrollTimelineOptions* options = ScrollTimelineOptions::Create();
+ DoubleOrScrollTimelineAutoKeyword time_range =
+ DoubleOrScrollTimelineAutoKeyword::FromDouble(100);
+ options->setTimeRange(time_range);
+ options->setScrollSource(GetElementById("scroller"));
+ ScrollTimeline* scroll_timeline =
+ ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
+
+ // Create KeyframeEffect
+ Timing timing;
+ timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
+
+ Persistent<StringKeyframe> start_keyframe =
+ MakeGarbageCollected<StringKeyframe>();
+ start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
+ SecureContextMode::kInsecureContext,
+ nullptr);
+ Persistent<StringKeyframe> end_keyframe =
+ MakeGarbageCollected<StringKeyframe>();
+ end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
+ SecureContextMode::kInsecureContext,
+ nullptr);
+
+ StringKeyframeVector keyframes;
+ keyframes.push_back(start_keyframe);
+ keyframes.push_back(end_keyframe);
+
+ Element* element = GetElementById("target");
+ auto* model = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes);
+
+ // Create scroll-linked animation
+ NonThrowableExceptionState exception_state;
+ Animation* scroll_animation = Animation::Create(
+ MakeGarbageCollected<KeyframeEffect>(element, model, timing),
+ scroll_timeline, exception_state);
+
+ model->SnapshotAllCompositorKeyframesIfNecessary(
+ *element, *ComputedStyle::Create(), nullptr);
+
+ UpdateAllLifecyclePhasesForTest();
+ scroll_animation->play();
+ EXPECT_EQ(scroll_animation->CheckCanStartAnimationOnCompositor(nullptr),
+ CompositorAnimations::kTimelineSourceHasInvalidCompositingState);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_timeline.cc b/chromium/third_party/blink/renderer/core/animation/animation_timeline.cc
index 365b6c84aac..8a2b92c08e9 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_timeline.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animation_timeline.cc
@@ -85,11 +85,10 @@ void AnimationTimeline::ServiceAnimations(TimingUpdateReason reason) {
TRACE_EVENT0("blink", "AnimationTimeline::serviceAnimations");
auto current_phase_and_time = CurrentPhaseAndTime();
- bool maybe_update_compositor_scroll_timeline = false;
if (IsScrollTimeline() &&
last_current_phase_and_time_ != current_phase_and_time) {
- maybe_update_compositor_scroll_timeline = true;
+ UpdateCompositorTimeline();
}
last_current_phase_and_time_ = current_phase_and_time;
@@ -102,12 +101,8 @@ void AnimationTimeline::ServiceAnimations(TimingUpdateReason reason) {
std::sort(animations.begin(), animations.end(), CompareAnimations);
for (Animation* animation : animations) {
- if (!animation->Update(reason)) {
+ if (!animation->Update(reason))
animations_needing_update_.erase(animation);
- continue;
- }
- if (maybe_update_compositor_scroll_timeline)
- animation->UpdateCompositorScrollTimeline();
}
DCHECK_EQ(outdated_animation_count_, 0U);
@@ -216,13 +211,23 @@ void AnimationTimeline::ScheduleServiceOnNextFrame() {
document_->View()->ScheduleAnimation();
}
+Animation* AnimationTimeline::Play(AnimationEffect* child) {
+ Animation* animation = Animation::Create(child, this);
+ DCHECK(animations_.Contains(animation));
+
+ animation->play();
+ DCHECK(animations_needing_update_.Contains(animation));
+
+ return animation;
+}
+
void AnimationTimeline::MarkAnimationsCompositorPending(bool source_changed) {
for (const auto& animation : animations_) {
animation->SetCompositorPending(source_changed);
}
}
-void AnimationTimeline::Trace(Visitor* visitor) {
+void AnimationTimeline::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(animations_needing_update_);
visitor->Trace(animations_);
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_timeline.h b/chromium/third_party/blink/renderer/core/animation/animation_timeline.h
index 6494c55f335..2d68a4af52c 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_timeline.h
+++ b/chromium/third_party/blink/renderer/core/animation/animation_timeline.h
@@ -6,7 +6,6 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_TIMELINE_H_
#include "third_party/blink/renderer/core/animation/animation.h"
-#include "third_party/blink/renderer/core/animation/animation_effect.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -39,6 +38,7 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable {
base::Optional<double> CurrentTimeSeconds();
String phase();
+ TimelinePhase Phase() { return CurrentPhaseAndTime().phase; }
virtual bool IsDocumentTimeline() const { return false; }
virtual bool IsScrollTimeline() const { return false; }
@@ -68,6 +68,8 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable {
// Schedules animation timing update on next frame.
virtual void ScheduleServiceOnNextFrame();
+ Animation* Play(AnimationEffect*);
+
virtual bool NeedsAnimationTimingUpdate();
virtual bool HasAnimations() const { return !animations_.IsEmpty(); }
virtual bool HasOutdatedAnimation() const {
@@ -87,10 +89,11 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable {
return compositor_timeline_.get();
}
virtual CompositorAnimationTimeline* EnsureCompositorTimeline() = 0;
+ virtual void UpdateCompositorTimeline() {}
void MarkAnimationsCompositorPending(bool source_changed = false);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
virtual PhaseAndTime CurrentPhaseAndTime() = 0;
diff --git a/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc b/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc
index bdb1f1b8a41..8440698e19e 100644
--- a/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc
+++ b/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc
@@ -775,4 +775,15 @@ void CompositorAnimations::GetAnimationOnCompositor(
DCHECK(!keyframe_models.IsEmpty());
}
+bool CompositorAnimations::CheckUsesCompositedScrolling(Node* target) {
+ if (!target)
+ return false;
+ DCHECK(target->GetDocument().Lifecycle().GetState() >=
+ DocumentLifecycle::kCompositingClean);
+ auto* layout_box_model_object = target->GetLayoutBoxModelObject();
+ if (!layout_box_model_object)
+ return false;
+ return layout_box_model_object->UsesCompositedScrolling();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/compositor_animations.h b/chromium/third_party/blink/renderer/core/animation/compositor_animations.h
index 85aa7a2c2e9..54420418c35 100644
--- a/chromium/third_party/blink/renderer/core/animation/compositor_animations.h
+++ b/chromium/third_party/blink/renderer/core/animation/compositor_animations.h
@@ -92,11 +92,14 @@ class CORE_EXPORT CompositorAnimations {
kMultipleTransformAnimationsOnSameTarget = 1 << 14,
kMixedKeyframeValueTypes = 1 << 15,
+ // Cases where the scroll timeline source is not composited.
+ kTimelineSourceHasInvalidCompositingState = 1 << 16,
+
// The maximum number of flags in this enum (excluding itself). New flags
// should increment this number but it should never be decremented because
// the values are used in UMA histograms. It should also be noted that it
// excludes the kNoFailure value.
- kFailureReasonCount = 16,
+ kFailureReasonCount = 17,
};
static FailureReasons CheckCanStartAnimationOnCompositor(
@@ -158,6 +161,8 @@ class CORE_EXPORT CompositorAnimations {
static CompositorElementIdNamespace CompositorElementNamespaceForProperty(
CSSPropertyID property);
+ static bool CheckUsesCompositedScrolling(Node* target);
+
private:
static FailureReasons CheckCanStartEffectOnCompositor(
const Timing&,
diff --git a/chromium/third_party/blink/renderer/core/animation/compositor_animations_test.cc b/chromium/third_party/blink/renderer/core/animation/compositor_animations_test.cc
index d0434ff195f..c76b836b11f 100644
--- a/chromium/third_party/blink/renderer/core/animation/compositor_animations_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/compositor_animations_test.cc
@@ -332,7 +332,7 @@ class AnimationCompositorAnimationsTest : public PaintTestConfigurations,
return property_specific_; // We know a shortcut.
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(property_specific_);
StringKeyframe::Trace(visitor);
}
@@ -371,7 +371,7 @@ class AnimationCompositorAnimationsTest : public PaintTestConfigurations,
return nullptr;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(compositor_keyframe_value_);
PropertySpecificKeyframe::Trace(visitor);
}
@@ -1953,9 +1953,6 @@ TEST_P(AnimationCompositorAnimationsTest, CompositedTransformAnimation) {
EXPECT_EQ(CheckCanStartElementOnCompositor(*target),
CompositorAnimations::kNoFailure);
EXPECT_EQ(document->Timeline().AnimationsNeedingUpdateCount(), 1u);
- cc::AnimationHost* host = document->View()->GetCompositorAnimationHost();
- EXPECT_EQ(host->MainThreadAnimationsCount(), 0u);
- EXPECT_EQ(host->CompositedAnimationsCount(), 1u);
}
TEST_P(AnimationCompositorAnimationsTest, CompositedScaleAnimation) {
@@ -1990,9 +1987,6 @@ TEST_P(AnimationCompositorAnimationsTest, CompositedScaleAnimation) {
EXPECT_EQ(CheckCanStartElementOnCompositor(*target),
CompositorAnimations::kNoFailure);
EXPECT_EQ(document->Timeline().AnimationsNeedingUpdateCount(), 1u);
- cc::AnimationHost* host = document->View()->GetCompositorAnimationHost();
- EXPECT_EQ(host->MainThreadAnimationsCount(), 0u);
- EXPECT_EQ(host->CompositedAnimationsCount(), 1u);
}
TEST_P(AnimationCompositorAnimationsTest,
@@ -2025,9 +2019,6 @@ TEST_P(AnimationCompositorAnimationsTest,
EXPECT_TRUE(cc_transform->is_currently_animating);
// Make sure the animation is started on the compositor.
EXPECT_EQ(document->Timeline().AnimationsNeedingUpdateCount(), 1u);
- cc::AnimationHost* host = document->View()->GetCompositorAnimationHost();
- EXPECT_EQ(host->MainThreadAnimationsCount(), 0u);
- EXPECT_EQ(host->CompositedAnimationsCount(), 1u);
// Make sure the backface-visibility is correctly set, both in blink and on
// the cc::Layer.
EXPECT_FALSE(transform->Matrix().IsIdentity()); // Rotated
@@ -2075,9 +2066,6 @@ TEST_P(AnimationCompositorAnimationsTest,
EXPECT_TRUE(CheckCanStartElementOnCompositor(*target) &
CompositorAnimations::kTargetHasInvalidCompositingState);
EXPECT_EQ(document->Timeline().AnimationsNeedingUpdateCount(), 4u);
- cc::AnimationHost* host = document->View()->GetCompositorAnimationHost();
- EXPECT_EQ(host->MainThreadAnimationsCount(), 4u);
- EXPECT_EQ(host->CompositedAnimationsCount(), 0u);
}
// Regression test for https://crbug.com/999333. We were relying on the Document
@@ -2091,7 +2079,7 @@ TEST_P(AnimationCompositorAnimationsTest,
// Move the target element to another Document, that does not have a frame
// (and thus no Settings).
- Document* another_document = MakeGarbageCollected<Document>();
+ Document* another_document = Document::CreateForTest();
ASSERT_FALSE(another_document->GetSettings());
another_document->adoptNode(target, ASSERT_NO_EXCEPTION);
diff --git a/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_filter_operations.h b/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_filter_operations.h
index 8c79da72aea..1070a9110be 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_filter_operations.h
+++ b/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_filter_operations.h
@@ -23,7 +23,7 @@ class CompositorKeyframeFilterOperations final
return operation_wrapper_->Operations();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(operation_wrapper_);
CompositorKeyframeValue::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h b/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h
index f45325902e1..ee5ba6410b1 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h
+++ b/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h
@@ -23,7 +23,7 @@ class CORE_EXPORT CompositorKeyframeValue
bool IsTransform() const { return GetType() == Type::kTransform; }
bool IsColor() const { return GetType() == Type::kColor; }
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
enum class Type {
kDouble,
diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animation.h b/chromium/third_party/blink/renderer/core/animation/css/css_animation.h
index 74d8594b83e..9cbd5f24825 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/css_animation.h
+++ b/chromium/third_party/blink/renderer/core/animation/css/css_animation.h
@@ -57,7 +57,7 @@ class CORE_EXPORT CSSAnimation : public Animation {
// https://drafts.csswg.org/css-animations-2/#interaction-between-animation-play-state-and-web-animations-API
bool getIgnoreCSSPlayState() { return ignore_css_play_state_; }
void resetIgnoreCSSPlayState() { ignore_css_play_state_ = false; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(blink::Visitor* visitor) const override {
Animation::Trace(visitor);
visitor->Trace(owning_element_);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animation_data.cc b/chromium/third_party/blink/renderer/core/animation/css/css_animation_data.cc
index 43fdebdad37..cb79e445d06 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/css_animation_data.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css/css_animation_data.cc
@@ -10,6 +10,7 @@ namespace blink {
CSSAnimationData::CSSAnimationData() {
name_list_.push_back(InitialName());
+ timeline_list_.push_back(InitialTimeline());
iteration_count_list_.push_back(InitialIterationCount());
direction_list_.push_back(InitialDirection());
fill_mode_list_.push_back(InitialFillMode());
@@ -23,9 +24,15 @@ const AtomicString& CSSAnimationData::InitialName() {
return name;
}
+const StyleNameOrKeyword& CSSAnimationData::InitialTimeline() {
+ DEFINE_STATIC_LOCAL(const StyleNameOrKeyword, name, (CSSValueID::kAuto));
+ return name;
+}
+
bool CSSAnimationData::AnimationsMatchForStyleRecalc(
const CSSAnimationData& other) const {
return name_list_ == other.name_list_ &&
+ timeline_list_ == other.timeline_list_ &&
play_state_list_ == other.play_state_list_ &&
iteration_count_list_ == other.iteration_count_list_ &&
direction_list_ == other.direction_list_ &&
diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animation_data.h b/chromium/third_party/blink/renderer/core/animation/css/css_animation_data.h
index 6466df5b258..eb90165db5b 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/css_animation_data.h
+++ b/chromium/third_party/blink/renderer/core/animation/css/css_animation_data.h
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/core/animation/css/css_timing_data.h"
#include "third_party/blink/renderer/core/animation/timing.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
+#include "third_party/blink/renderer/core/style/style_name_or_keyword.h"
namespace blink {
@@ -31,6 +32,10 @@ class CSSAnimationData final : public CSSTimingData {
Timing ConvertToTiming(size_t index) const;
const Vector<AtomicString>& NameList() const { return name_list_; }
+ const Vector<StyleNameOrKeyword>& TimelineList() const {
+ return timeline_list_;
+ }
+
const Vector<double>& IterationCountList() const {
return iteration_count_list_;
}
@@ -45,12 +50,14 @@ class CSSAnimationData final : public CSSTimingData {
}
Vector<AtomicString>& NameList() { return name_list_; }
+ Vector<StyleNameOrKeyword>& TimelineList() { return timeline_list_; }
Vector<double>& IterationCountList() { return iteration_count_list_; }
Vector<Timing::PlaybackDirection>& DirectionList() { return direction_list_; }
Vector<Timing::FillMode>& FillModeList() { return fill_mode_list_; }
Vector<EAnimPlayState>& PlayStateList() { return play_state_list_; }
static const AtomicString& InitialName();
+ static const StyleNameOrKeyword& InitialTimeline();
static Timing::PlaybackDirection InitialDirection() {
return Timing::PlaybackDirection::NORMAL;
}
@@ -60,6 +67,7 @@ class CSSAnimationData final : public CSSTimingData {
private:
Vector<AtomicString> name_list_;
+ Vector<StyleNameOrKeyword> timeline_list_;
Vector<double> iteration_count_list_;
Vector<Timing::PlaybackDirection> direction_list_;
Vector<Timing::FillMode> fill_mode_list_;
diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.h b/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.h
index 9f0ce355fbc..c5374d740ef 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.h
+++ b/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.h
@@ -42,7 +42,7 @@ class NewCSSAnimation {
style_rule_version(this->style_rule->Version()),
play_state_list(play_state_list) {}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(effect);
visitor->Trace(style_rule);
}
@@ -75,7 +75,7 @@ class UpdatedCSSAnimation {
style_rule_version(this->style_rule->Version()),
play_state_list(play_state_list) {}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(animation);
visitor->Trace(effect);
visitor->Trace(style_rule);
@@ -183,7 +183,7 @@ class CORE_EXPORT CSSAnimationUpdate final {
public:
NewTransition();
~NewTransition();
- void Trace(Visitor* visitor) { visitor->Trace(effect); }
+ void Trace(Visitor* visitor) const { visitor->Trace(effect); }
PropertyHandle property = HashTraits<blink::PropertyHandle>::EmptyValue();
scoped_refptr<const ComputedStyle> from;
@@ -255,7 +255,7 @@ class CORE_EXPORT CSSAnimationUpdate final {
updated_compositor_keyframes_.IsEmpty();
}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(new_transitions_);
visitor->Trace(new_animations_);
visitor->Trace(suppressed_animations_);
diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animations.cc b/chromium/third_party/blink/renderer/core/animation/css/css_animations.cc
index fd85f0af7a1..f482b77a4e5 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/css_animations.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -449,7 +449,7 @@ AnimationTimeDelta IterationElapsedTime(const AnimationEffect& effect,
: current_iteration;
const double iteration_start = effect.SpecifiedTiming().iteration_start;
const AnimationTimeDelta iteration_duration =
- effect.SpecifiedTiming().iteration_duration.value();
+ effect.SpecifiedTiming().IterationDuration();
return iteration_duration * (iteration_boundary - iteration_start);
}
@@ -854,6 +854,12 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) {
}
}
+ if (!pending_update_.NewTransitions().IsEmpty()) {
+ element->GetDocument()
+ .GetDocumentAnimations()
+ .IncrementTrasitionGeneration();
+ }
+
for (const auto& entry : pending_update_.NewTransitions()) {
const CSSAnimationUpdate::NewTransition& new_transition = entry.value;
@@ -1484,7 +1490,7 @@ void CSSAnimations::AnimationEventDelegate::OnEventCondition(
previous_phase_ = current_phase;
}
-void CSSAnimations::AnimationEventDelegate::Trace(Visitor* visitor) {
+void CSSAnimations::AnimationEventDelegate::Trace(Visitor* visitor) const {
visitor->Trace(animation_target_);
AnimationEffect::EventDelegate::Trace(visitor);
}
@@ -1498,13 +1504,6 @@ void CSSAnimations::TransitionEventDelegate::OnEventCondition(
Timing::Phase current_phase) {
if (current_phase == previous_phase_)
return;
- // Our implement of transition_generation is slightly different from the spec
- // We increment the transition_generation per transition event instead of per
- // style change event. A state transition would trigger one or more events.
- // Thus, the spec version increments more than is necessary to ensure a change
- // in transition generation. Spec defines style-change-event:
- // https://drafts.csswg.org/css-transitions-1/#style-change-event
- GetDocument().GetDocumentAnimations().IncrementTrasitionGeneration();
if (GetDocument().HasListenerType(Document::kTransitionRunListener)) {
if (previous_phase_ == Timing::kPhaseNone) {
@@ -1527,9 +1526,8 @@ void CSSAnimations::TransitionEventDelegate::OnEventCondition(
previous_phase_ == Timing::kPhaseAfter) {
// If the transition is progressing backwards it is considered to have
// started at the end position.
- DCHECK(animation_node.SpecifiedTiming().iteration_duration.has_value());
EnqueueEvent(event_type_names::kTransitionstart,
- animation_node.SpecifiedTiming().iteration_duration.value());
+ animation_node.SpecifiedTiming().IterationDuration());
}
}
@@ -1538,9 +1536,8 @@ void CSSAnimations::TransitionEventDelegate::OnEventCondition(
(previous_phase_ == Timing::kPhaseActive ||
previous_phase_ == Timing::kPhaseBefore ||
previous_phase_ == Timing::kPhaseNone)) {
- DCHECK(animation_node.SpecifiedTiming().iteration_duration.has_value());
EnqueueEvent(event_type_names::kTransitionend,
- animation_node.SpecifiedTiming().iteration_duration.value());
+ animation_node.SpecifiedTiming().IterationDuration());
} else if (current_phase == Timing::kPhaseBefore &&
(previous_phase_ == Timing::kPhaseActive ||
previous_phase_ == Timing::kPhaseAfter)) {
@@ -1590,7 +1587,7 @@ void CSSAnimations::TransitionEventDelegate::EnqueueEvent(
GetDocument().EnqueueAnimationFrameEvent(event);
}
-void CSSAnimations::TransitionEventDelegate::Trace(Visitor* visitor) {
+void CSSAnimations::TransitionEventDelegate::Trace(Visitor* visitor) const {
visitor->Trace(transition_target_);
AnimationEffect::EventDelegate::Trace(visitor);
}
@@ -1630,6 +1627,7 @@ bool CSSAnimations::IsAnimationAffectingProperty(const CSSProperty& property) {
case CSSPropertyID::kAnimationIterationCount:
case CSSPropertyID::kAnimationName:
case CSSPropertyID::kAnimationPlayState:
+ case CSSPropertyID::kAnimationTimeline:
case CSSPropertyID::kAnimationTimingFunction:
case CSSPropertyID::kContain:
case CSSPropertyID::kDirection:
@@ -1693,7 +1691,7 @@ bool CSSAnimations::IsAnimatingRevert(
return element_animations && element_animations->GetEffectStack().HasRevert();
}
-void CSSAnimations::Trace(Visitor* visitor) {
+void CSSAnimations::Trace(Visitor* visitor) const {
visitor->Trace(transitions_);
visitor->Trace(pending_update_);
visitor->Trace(running_animations_);
diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animations.h b/chromium/third_party/blink/renderer/core/animation/css/css_animations.h
index 57f29e16901..263ec779895 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/css_animations.h
+++ b/chromium/third_party/blink/renderer/core/animation/css/css_animations.h
@@ -115,7 +115,7 @@ class CORE_EXPORT CSSAnimations final {
}
void Cancel();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
class RunningAnimation final : public GarbageCollected<RunningAnimation> {
@@ -137,7 +137,7 @@ class CORE_EXPORT CSSAnimations final {
specified_timing = update.specified_timing;
}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(animation);
visitor->Trace(style_rule);
}
@@ -155,7 +155,7 @@ class CORE_EXPORT CSSAnimations final {
DISALLOW_NEW();
public:
- void Trace(Visitor* visitor) { visitor->Trace(animation); }
+ void Trace(Visitor* visitor) const { visitor->Trace(animation); }
Member<Animation> animation;
scoped_refptr<const ComputedStyle> from;
@@ -232,7 +232,7 @@ class CORE_EXPORT CSSAnimations final {
return previous_iteration_;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const Element& AnimationTarget() const { return *animation_target_; }
@@ -263,7 +263,7 @@ class CORE_EXPORT CSSAnimations final {
bool IsTransitionEventDelegate() const override { return true; }
Timing::Phase getPreviousPhase() const { return previous_phase_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void EnqueueEvent(const WTF::AtomicString& type,
diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animations_test.cc b/chromium/third_party/blink/renderer/core/animation/css/css_animations_test.cc
index 876df39501e..0857a0e4daa 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/css_animations_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css/css_animations_test.cc
@@ -3,6 +3,8 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/core/animation/css/css_animations.h"
+
+#include "cc/animation/animation.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/animation/animation.h"
#include "third_party/blink/renderer/core/animation/document_timeline.h"
@@ -10,8 +12,16 @@
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
+#include "third_party/blink/renderer/platform/animation/compositor_animation.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_delegate.h"
+namespace {
+
+const double kTolerance = 1e-5;
+
+const double kTimeToleranceMilliseconds = 0.1;
+}
+
namespace blink {
class CSSAnimationsTest : public RenderingTest {
@@ -36,13 +46,13 @@ class CSSAnimationsTest : public RenderingTest {
platform()->RunUntilIdle();
}
+ base::TimeTicks TimelineTime() {
+ return platform()->test_task_runner()->NowTicks();
+ }
+
void StartAnimationOnCompositor(Animation* animation) {
static_cast<CompositorAnimationDelegate*>(animation)
- ->NotifyAnimationStarted(platform()
- ->test_task_runner()
- ->NowTicks()
- .since_origin()
- .InSecondsF(),
+ ->NotifyAnimationStarted(TimelineTime().since_origin().InSecondsF(),
animation->CompositorGroup());
}
@@ -93,12 +103,12 @@ TEST_F(CSSAnimationsTest, RetargetedTransition) {
// Starting the second transition should retarget the active transition.
element->setAttribute(html_names::kClassAttr, "contrast2");
UpdateAllLifecyclePhasesForTest();
- EXPECT_NEAR(0.6, GetContrastFilterAmount(element), 0.0000000001);
+ EXPECT_NEAR(0.6, GetContrastFilterAmount(element), kTolerance);
// As it has been retargeted, advancing halfway should go to 0.3.
AdvanceClockSeconds(0.5);
UpdateAllLifecyclePhasesForTest();
- EXPECT_NEAR(0.3, GetContrastFilterAmount(element), 0.0000000001);
+ EXPECT_NEAR(0.3, GetContrastFilterAmount(element), kTolerance);
}
// Test that when an incompatible in progress compositor transition
@@ -137,4 +147,272 @@ TEST_F(CSSAnimationsTest, IncompatibleRetargetedTransition) {
EXPECT_EQ(0.2, GetContrastFilterAmount(element));
}
+// The following group of tests verify that composited CSS animations are
+// well behaved when updated via the web-animations API. Verifies that changes
+// are synced with the compositor.
+
+class CSSAnimationsCompositorSyncTest : public CSSAnimationsTest {
+ public:
+ CSSAnimationsCompositorSyncTest() = default;
+
+ void SetUp() override {
+ CSSAnimationsTest::SetUp();
+ CreateOpacityAnimation();
+ }
+
+ // Creates a composited animation for opacity, and advances to the midpoint
+ // of the animation. Verifies that the state of the animation is in sync
+ // between the main thread and compositor.
+ void CreateOpacityAnimation() {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #test { transition: opacity linear 1s; }
+ .fade { opacity: 0; }
+ </style>
+ <div id='test'></div>
+ )HTML");
+
+ element_ = GetDocument().getElementById("test");
+ UpdateAllLifecyclePhasesForTest();
+ ElementAnimations* animations = element_->GetElementAnimations();
+ EXPECT_FALSE(animations);
+
+ element_->setAttribute(html_names::kClassAttr, "fade");
+ UpdateAllLifecyclePhasesForTest();
+ SyncAnimationOnCompositor(/*needs_start_time*/ true);
+
+ Animation* animation = GetAnimation();
+ EXPECT_TRUE(animation->HasActiveAnimationsOnCompositor());
+ VerifyCompositorPlaybackRate(1.0);
+ VerifyCompositorTimeOffset(0.0);
+ VerifyCompositorIterationTime(0);
+ int compositor_group = animation->CompositorGroup();
+
+ AdvanceClockSeconds(0.5);
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_NEAR(0.5, element_->GetComputedStyle()->Opacity(), kTolerance);
+ EXPECT_EQ(compositor_group, animation->CompositorGroup());
+ VerifyCompositorPlaybackRate(1.0);
+ VerifyCompositorTimeOffset(0.0);
+ VerifyCompositorIterationTime(500);
+ VerifyCompositorOpacity(0.5);
+ }
+
+ Animation* GetAnimation() {
+ // Note that the animations are stored as weak references and we cannot
+ // persist the reference.
+ ElementAnimations* element_animations = element_->GetElementAnimations();
+ EXPECT_EQ(1u, element_animations->Animations().size());
+ return (*element_animations->Animations().begin()).key;
+ }
+
+ void NotifyStartTime() {
+ Animation* animation = GetAnimation();
+ cc::KeyframeModel* keyframe_model = GetCompositorKeyframeForOpacity();
+ base::TimeTicks start_time = keyframe_model->start_time();
+ static_cast<CompositorAnimationDelegate*>(animation)
+ ->NotifyAnimationStarted(start_time.since_origin().InSecondsF(),
+ animation->CompositorGroup());
+ }
+
+ void SyncAnimationOnCompositor(bool needs_start_time) {
+ // Verifies that the compositor animation requires a synchronization on the
+ // start time.
+ cc::KeyframeModel* keyframe_model = GetCompositorKeyframeForOpacity();
+ EXPECT_EQ(needs_start_time, !keyframe_model->has_set_start_time());
+ EXPECT_TRUE(keyframe_model->needs_synchronized_start_time());
+
+ // Set the opacity keyframe model into a running state and sync with
+ // blink::Animation.
+ base::TimeTicks timeline_time = TimelineTime();
+ keyframe_model->SetRunState(cc::KeyframeModel::RUNNING, TimelineTime());
+ if (needs_start_time)
+ keyframe_model->set_start_time(timeline_time);
+ keyframe_model->set_needs_synchronized_start_time(false);
+ NotifyStartTime();
+ }
+
+ cc::KeyframeModel* GetCompositorKeyframeForOpacity() {
+ cc::Animation* cc_animation =
+ GetAnimation()->GetCompositorAnimation()->CcAnimation();
+ return cc_animation->GetKeyframeModel(cc::TargetProperty::OPACITY);
+ }
+
+ void VerifyCompositorPlaybackRate(double expected_value) {
+ cc::KeyframeModel* keyframe_model = GetCompositorKeyframeForOpacity();
+ EXPECT_NEAR(expected_value, keyframe_model->playback_rate(), kTolerance);
+ }
+
+ void VerifyCompositorTimeOffset(double expected_value) {
+ cc::KeyframeModel* keyframe_model = GetCompositorKeyframeForOpacity();
+ EXPECT_NEAR(expected_value, keyframe_model->time_offset().InMillisecondsF(),
+ kTimeToleranceMilliseconds);
+ }
+
+ base::TimeDelta CompositorIterationTime() {
+ cc::KeyframeModel* keyframe_model = GetCompositorKeyframeForOpacity();
+ return keyframe_model->TrimTimeToCurrentIteration(TimelineTime());
+ }
+
+ void VerifyCompositorIterationTime(double expected_value) {
+ base::TimeDelta iteration_time = CompositorIterationTime();
+ EXPECT_NEAR(expected_value, iteration_time.InMillisecondsF(),
+ kTimeToleranceMilliseconds);
+ }
+
+ void VerifyCompositorOpacity(double expected_value) {
+ cc::KeyframeModel* keyframe_model = GetCompositorKeyframeForOpacity();
+ base::TimeDelta iteration_time = CompositorIterationTime();
+ const cc::FloatAnimationCurve* opacity_curve =
+ keyframe_model->curve()->ToFloatAnimationCurve();
+ EXPECT_NEAR(expected_value, opacity_curve->GetValue(iteration_time),
+ kTolerance);
+ }
+
+ Persistent<Element> element_;
+};
+
+// Verifies that changes to the playback rate are synced with the compositor.
+TEST_F(CSSAnimationsCompositorSyncTest, UpdatePlaybackRate) {
+ Animation* animation = GetAnimation();
+ int compositor_group = animation->CompositorGroup();
+
+ animation->updatePlaybackRate(0.5, ASSERT_NO_EXCEPTION);
+ UpdateAllLifecyclePhasesForTest();
+
+ // Compositor animation needs to restart and will have a new compositor group.
+ int post_update_compositor_group = animation->CompositorGroup();
+ EXPECT_NE(compositor_group, post_update_compositor_group);
+ SyncAnimationOnCompositor(/*needs_start_time*/ true);
+
+ // No jump in opacity after changing the playback rate.
+ EXPECT_NEAR(0.5, element_->GetComputedStyle()->Opacity(), kTolerance);
+ VerifyCompositorPlaybackRate(0.5);
+ // The time offset tells the compositor where to seek into the animation, and
+ // is calculated as follows:
+ // time_offset = current_time / playback_rate = 0.5 / 0.5 = 1.0.
+ VerifyCompositorTimeOffset(1000);
+ VerifyCompositorIterationTime(500);
+ VerifyCompositorOpacity(0.5);
+
+ // Advances the clock, and ensures that the compositor animation is not
+ // restarted and that it remains in sync.
+ AdvanceClockSeconds(0.5);
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_NEAR(0.25, element_->GetComputedStyle()->Opacity(), kTolerance);
+ EXPECT_EQ(post_update_compositor_group, animation->CompositorGroup());
+ VerifyCompositorTimeOffset(1000);
+ VerifyCompositorIterationTime(750);
+ VerifyCompositorOpacity(0.25);
+}
+
+// Verifies that reversing an animation is synced with the compositor.
+TEST_F(CSSAnimationsCompositorSyncTest, Reverse) {
+ Animation* animation = GetAnimation();
+ int compositor_group = animation->CompositorGroup();
+
+ animation->reverse(ASSERT_NO_EXCEPTION);
+ UpdateAllLifecyclePhasesForTest();
+
+ // Verify update in web-animation API.
+ EXPECT_NEAR(-1, animation->playbackRate(), kTolerance);
+
+ // Verify there is no jump in opacity after changing the play direction
+ EXPECT_NEAR(0.5, element_->GetComputedStyle()->Opacity(), kTolerance);
+
+ // Compositor animation needs to restart and will have a new compositor group.
+ int post_update_compositor_group = animation->CompositorGroup();
+ EXPECT_NE(compositor_group, post_update_compositor_group);
+ SyncAnimationOnCompositor(/*needs_start_time*/ true);
+
+ // Verify updates to cc Keyframe model.
+ VerifyCompositorPlaybackRate(-1.0);
+ VerifyCompositorTimeOffset(500);
+ VerifyCompositorIterationTime(500);
+ VerifyCompositorOpacity(0.5);
+
+ // Advances the clock, and ensures that the compositor animation is not
+ // restarted and that it remains in sync.
+ AdvanceClockSeconds(0.25);
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_NEAR(0.75, element_->GetComputedStyle()->Opacity(), kTolerance);
+ EXPECT_EQ(post_update_compositor_group, animation->CompositorGroup());
+ VerifyCompositorIterationTime(250);
+ VerifyCompositorOpacity(0.75);
+}
+
+// Verifies that setting the start time on a running animation restarts the
+// compositor animation in sync with blink.
+TEST_F(CSSAnimationsCompositorSyncTest, SetStartTime) {
+ Animation* animation = GetAnimation();
+ int compositor_group = animation->CompositorGroup();
+
+ // Partially rewind the animation via setStartTime.
+ double new_start_time =
+ animation->startTime().value() + animation->currentTime().value() / 2;
+ animation->setStartTime(new_start_time, ASSERT_NO_EXCEPTION);
+ UpdateAllLifecyclePhasesForTest();
+
+ // Verify blink updates.
+ EXPECT_NEAR(250, animation->currentTime().value(),
+ kTimeToleranceMilliseconds);
+ EXPECT_NEAR(0.75, element_->GetComputedStyle()->Opacity(), kTolerance);
+
+ // Compositor animation needs to restart and will have a new compositor group.
+ int post_update_compositor_group = animation->CompositorGroup();
+ EXPECT_NE(compositor_group, post_update_compositor_group);
+ SyncAnimationOnCompositor(/*needs_start_time*/ false);
+
+ // Verify updates to cc Keyframe model.
+ VerifyCompositorPlaybackRate(1.0);
+ VerifyCompositorTimeOffset(0.0);
+ VerifyCompositorIterationTime(250);
+ VerifyCompositorOpacity(0.75);
+
+ // Advances the clock, and ensures that the compositor animation is not
+ // restarted and that it remains in sync.
+ AdvanceClockSeconds(0.25);
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_NEAR(0.5, element_->GetComputedStyle()->Opacity(), kTolerance);
+ EXPECT_EQ(post_update_compositor_group, animation->CompositorGroup());
+ VerifyCompositorIterationTime(500);
+ VerifyCompositorOpacity(0.5);
+}
+
+// Verifies that setting the current time on a running animation restarts the
+// compositor animation in sync with blink.
+TEST_F(CSSAnimationsCompositorSyncTest, SetCurrentTime) {
+ Animation* animation = GetAnimation();
+ int compositor_group = animation->CompositorGroup();
+
+ // Advance current time.
+ animation->setCurrentTime(750, ASSERT_NO_EXCEPTION);
+ UpdateAllLifecyclePhasesForTest();
+
+ // Verify blink updates.
+ EXPECT_NEAR(750, animation->currentTime().value(),
+ kTimeToleranceMilliseconds);
+ EXPECT_NEAR(0.25, element_->GetComputedStyle()->Opacity(), kTolerance);
+
+ // Compositor animation needs to restart and will have a new compositor group.
+ int post_update_compositor_group = animation->CompositorGroup();
+ EXPECT_NE(compositor_group, post_update_compositor_group);
+ SyncAnimationOnCompositor(/*needs_start_time*/ false);
+
+ // Verify updates to cc Keyframe model.
+ VerifyCompositorPlaybackRate(1.0);
+ VerifyCompositorTimeOffset(0.0);
+ VerifyCompositorIterationTime(750);
+ VerifyCompositorOpacity(0.25);
+
+ // Advances the clock, and ensures that the compositor animation is not
+ // restarted and that it remains in sync.
+ AdvanceClockSeconds(0.2);
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_NEAR(0.05, element_->GetComputedStyle()->Opacity(), kTolerance);
+ EXPECT_EQ(post_update_compositor_group, animation->CompositorGroup());
+ VerifyCompositorIterationTime(950);
+ VerifyCompositorOpacity(0.05);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_transition.h b/chromium/third_party/blink/renderer/core/animation/css/css_transition.h
index 3cc07c039ab..b1858aff453 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/css_transition.h
+++ b/chromium/third_party/blink/renderer/core/animation/css/css_transition.h
@@ -43,7 +43,7 @@ class CORE_EXPORT CSSTransition : public Animation {
// display:none must update the play state.
// https://drafts.csswg.org/css-transitions-2/#requirements-on-pending-style-changes
String playState() const override;
- void Trace(blink::Visitor* visitor) override {
+ void Trace(blink::Visitor* visitor) const override {
Animation::Trace(visitor);
visitor->Trace(owning_element_);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc
new file mode 100644
index 00000000000..3dc54b266e6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc
@@ -0,0 +1,114 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.h"
+
+#include <memory>
+
+#include "base/memory/ptr_util.h"
+#include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h"
+#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/platform/wtf/math_extras.h"
+
+namespace blink {
+
+class InheritedFontStretchChecker
+ : public CSSInterpolationType::CSSConversionChecker {
+ public:
+ explicit InheritedFontStretchChecker(FontSelectionValue font_stretch)
+ : font_stretch_(font_stretch) {}
+
+ private:
+ bool IsValid(const StyleResolverState& state,
+ const InterpolationValue&) const final {
+ return font_stretch_ == state.ParentStyle()->GetFontStretch();
+ }
+
+ const double font_stretch_;
+};
+
+InterpolationValue CSSFontStretchInterpolationType::CreateFontStretchValue(
+ FontSelectionValue font_stretch) const {
+ return InterpolationValue(std::make_unique<InterpolableNumber>(font_stretch));
+}
+
+InterpolationValue CSSFontStretchInterpolationType::MaybeConvertNeutral(
+ const InterpolationValue&,
+ ConversionCheckers&) const {
+ return InterpolationValue(std::make_unique<InterpolableNumber>(0));
+}
+
+InterpolationValue CSSFontStretchInterpolationType::MaybeConvertInitial(
+ const StyleResolverState&,
+ ConversionCheckers& conversion_checkers) const {
+ return CreateFontStretchValue(NormalWidthValue());
+}
+
+InterpolationValue CSSFontStretchInterpolationType::MaybeConvertInherit(
+ const StyleResolverState& state,
+ ConversionCheckers& conversion_checkers) const {
+ if (!state.ParentStyle())
+ return nullptr;
+ FontSelectionValue inherited_font_stretch =
+ state.ParentStyle()->GetFontStretch();
+ conversion_checkers.push_back(
+ std::make_unique<InheritedFontStretchChecker>(inherited_font_stretch));
+ return CreateFontStretchValue(inherited_font_stretch);
+}
+
+InterpolationValue CSSFontStretchInterpolationType::MaybeConvertValue(
+ const CSSValue& value,
+ const StyleResolverState* state,
+ ConversionCheckers& conversion_checkers) const {
+ if (auto* primitive_value = DynamicTo<CSSPrimitiveValue>(value)) {
+ return CreateFontStretchValue(
+ FontSelectionValue(primitive_value->GetFloatValue()));
+ }
+
+ const auto& identifier_value = To<CSSIdentifierValue>(value);
+ CSSValueID keyword = identifier_value.GetValueID();
+
+ switch (keyword) {
+ case CSSValueID::kInvalid:
+ return nullptr;
+ case CSSValueID::kUltraCondensed:
+ return CreateFontStretchValue(UltraCondensedWidthValue());
+ case CSSValueID::kExtraCondensed:
+ return CreateFontStretchValue(ExtraCondensedWidthValue());
+ case CSSValueID::kCondensed:
+ return CreateFontStretchValue(CondensedWidthValue());
+ case CSSValueID::kSemiCondensed:
+ return CreateFontStretchValue(SemiCondensedWidthValue());
+ case CSSValueID::kNormal:
+ return CreateFontStretchValue(NormalWidthValue());
+ case CSSValueID::kSemiExpanded:
+ return CreateFontStretchValue(SemiExpandedWidthValue());
+ case CSSValueID::kExpanded:
+ return CreateFontStretchValue(ExpandedWidthValue());
+ case CSSValueID::kExtraExpanded:
+ return CreateFontStretchValue(ExtraExpandedWidthValue());
+ case CSSValueID::kUltraExpanded:
+ return CreateFontStretchValue(UltraExpandedWidthValue());
+ default:
+ NOTREACHED();
+ return nullptr;
+ }
+}
+
+InterpolationValue
+CSSFontStretchInterpolationType::MaybeConvertStandardPropertyUnderlyingValue(
+ const ComputedStyle& style) const {
+ return CreateFontStretchValue(style.GetFontStretch());
+}
+
+void CSSFontStretchInterpolationType::ApplyStandardPropertyValue(
+ const InterpolableValue& interpolable_value,
+ const NonInterpolableValue*,
+ StyleResolverState& state) const {
+ state.GetFontBuilder().SetStretch(FontSelectionValue(
+ clampTo(To<InterpolableNumber>(interpolable_value).Value(), 0.0)));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.h b/chromium/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.h
new file mode 100644
index 00000000000..8090c3d6f1a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.h
@@ -0,0 +1,40 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_FONT_STRETCH_INTERPOLATION_TYPE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_FONT_STRETCH_INTERPOLATION_TYPE_H_
+
+#include "third_party/blink/renderer/core/animation/css_interpolation_type.h"
+
+namespace blink {
+
+class CSSFontStretchInterpolationType : public CSSInterpolationType {
+ public:
+ explicit CSSFontStretchInterpolationType(PropertyHandle property)
+ : CSSInterpolationType(property) {
+ DCHECK_EQ(CssProperty().PropertyID(), CSSPropertyID::kFontStretch);
+ }
+
+ InterpolationValue MaybeConvertStandardPropertyUnderlyingValue(
+ const ComputedStyle&) const final;
+ void ApplyStandardPropertyValue(const InterpolableValue&,
+ const NonInterpolableValue*,
+ StyleResolverState&) const final;
+
+ private:
+ InterpolationValue CreateFontStretchValue(FontSelectionValue) const;
+ InterpolationValue MaybeConvertNeutral(const InterpolationValue& underlying,
+ ConversionCheckers&) const final;
+ InterpolationValue MaybeConvertInitial(const StyleResolverState&,
+ ConversionCheckers&) const final;
+ InterpolationValue MaybeConvertInherit(const StyleResolverState&,
+ ConversionCheckers&) const final;
+ InterpolationValue MaybeConvertValue(const CSSValue&,
+ const StyleResolverState*,
+ ConversionCheckers&) const final;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_FONT_STRETCH_INTERPOLATION_TYPE_H_
diff --git a/chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc b/chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc
index ca730627644..a5d107d1ef2 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc
@@ -18,6 +18,7 @@
#include "third_party/blink/renderer/core/animation/css_default_interpolation_type.h"
#include "third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.h"
#include "third_party/blink/renderer/core/animation/css_font_size_interpolation_type.h"
+#include "third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.h"
#include "third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.h"
#include "third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.h"
#include "third_party/blink/renderer/core/animation/css_image_interpolation_type.h"
@@ -46,6 +47,7 @@
#include "third_party/blink/renderer/core/animation/css_translate_interpolation_type.h"
#include "third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.h"
#include "third_party/blink/renderer/core/animation/css_visibility_interpolation_type.h"
+#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/css/css_syntax_definition.h"
#include "third_party/blink/renderer/core/css/properties/css_property.h"
#include "third_party/blink/renderer/core/css/property_registry.h"
@@ -58,7 +60,7 @@ CSSInterpolationTypesMap::CSSInterpolationTypesMap(
const PropertyRegistry* registry,
const Document& document)
: registry_(registry) {
- allow_all_animations_ = document.IsFeatureEnabled(
+ allow_all_animations_ = document.GetExecutionContext()->IsFeatureEnabled(
blink::mojom::blink::DocumentPolicyFeature::kLayoutAnimations);
}
@@ -155,6 +157,7 @@ const InterpolationTypes& CSSInterpolationTypesMap::Get(
case CSSPropertyID::kShapeMargin:
case CSSPropertyID::kStrokeDashoffset:
case CSSPropertyID::kStrokeWidth:
+ case CSSPropertyID::kTextDecorationThickness:
case CSSPropertyID::kTop:
case CSSPropertyID::kVerticalAlign:
case CSSPropertyID::kWebkitBorderHorizontalSpacing:
@@ -254,6 +257,10 @@ const InterpolationTypes& CSSInterpolationTypesMap::Get(
applicable_types->push_back(
std::make_unique<CSSFontWeightInterpolationType>(used_property));
break;
+ case CSSPropertyID::kFontStretch:
+ applicable_types->push_back(
+ std::make_unique<CSSFontStretchInterpolationType>(used_property));
+ break;
case CSSPropertyID::kFontVariationSettings:
applicable_types->push_back(
std::make_unique<CSSFontVariationSettingsInterpolationType>(
@@ -290,6 +297,7 @@ const InterpolationTypes& CSSInterpolationTypesMap::Get(
case CSSPropertyID::kBorderBottomRightRadius:
case CSSPropertyID::kBorderTopLeftRadius:
case CSSPropertyID::kBorderTopRightRadius:
+ case CSSPropertyID::kContainIntrinsicSize:
applicable_types->push_back(
std::make_unique<CSSLengthPairInterpolationType>(used_property));
break;
diff --git a/chromium/third_party/blink/renderer/core/animation/css_length_pair_interpolation_type.h b/chromium/third_party/blink/renderer/core/animation/css_length_pair_interpolation_type.h
index 6d964aab0cf..f4def5d9f9f 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_length_pair_interpolation_type.h
+++ b/chromium/third_party/blink/renderer/core/animation/css_length_pair_interpolation_type.h
@@ -21,9 +21,11 @@ class CSSLengthPairInterpolationType : public CSSLengthListInterpolationType {
InterpolationValue MaybeConvertValue(const CSSValue& value,
const StyleResolverState*,
ConversionCheckers&) const final {
- const auto& pair = To<CSSValuePair>(value);
+ const auto* pair = DynamicTo<CSSValuePair>(value);
+ if (!pair)
+ return nullptr;
return ListInterpolationFunctions::CreateList(2, [&pair](size_t index) {
- const CSSValue& item = index == 0 ? pair.First() : pair.Second();
+ const CSSValue& item = index == 0 ? pair->First() : pair->Second();
return InterpolationValue(InterpolableLength::MaybeConvertCSSValue(item));
});
}
diff --git a/chromium/third_party/blink/renderer/core/animation/document_animations.cc b/chromium/third_party/blink/renderer/core/animation/document_animations.cc
index b1df2494553..f3aff406f0f 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_animations.cc
+++ b/chromium/third_party/blink/renderer/core/animation/document_animations.cc
@@ -144,7 +144,7 @@ HeapVector<Member<Animation>> DocumentAnimations::getAnimations(
return animations;
}
-void DocumentAnimations::Trace(Visitor* visitor) {
+void DocumentAnimations::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(timelines_);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/document_animations.h b/chromium/third_party/blink/renderer/core/animation/document_animations.h
index 3bd3cd39073..2c5cf23a7fe 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_animations.h
+++ b/chromium/third_party/blink/renderer/core/animation/document_animations.h
@@ -68,8 +68,12 @@ class CORE_EXPORT DocumentAnimations final
void MarkAnimationsCompositorPending();
HeapVector<Member<Animation>> getAnimations(const TreeScope&);
+ const HeapHashSet<WeakMember<AnimationTimeline>>& GetTimelinesForTesting()
+ const {
+ return timelines_;
+ }
uint64_t current_transition_generation_;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<Document> document_;
diff --git a/chromium/third_party/blink/renderer/core/animation/document_animations_test.cc b/chromium/third_party/blink/renderer/core/animation/document_animations_test.cc
index 35c165f581c..e3b5a672557 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_animations_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/document_animations_test.cc
@@ -22,6 +22,7 @@ class MockAnimationTimeline : public AnimationTimeline {
public:
MockAnimationTimeline(Document* document) : AnimationTimeline(document) {}
+ MOCK_METHOD0(Phase, TimelinePhase());
MOCK_CONST_METHOD0(IsActive, bool());
MOCK_METHOD0(ZeroTimeInSeconds, double());
MOCK_METHOD0(InitialStartTimeForAnimations,
@@ -34,7 +35,9 @@ class MockAnimationTimeline : public AnimationTimeline {
MOCK_METHOD0(ScheduleNextService, void());
MOCK_METHOD0(EnsureCompositorTimeline, CompositorAnimationTimeline*());
- void Trace(Visitor* visitor) override { AnimationTimeline::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ AnimationTimeline::Trace(visitor);
+ }
protected:
MOCK_METHOD0(CurrentPhaseAndTime, PhaseAndTime());
diff --git a/chromium/third_party/blink/renderer/core/animation/document_timeline.cc b/chromium/third_party/blink/renderer/core/animation/document_timeline.cc
index d3857a4a86c..ce2592b9b9d 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_timeline.cc
+++ b/chromium/third_party/blink/renderer/core/animation/document_timeline.cc
@@ -106,16 +106,6 @@ DocumentTimeline::InitialStartTimeForAnimations() {
return base::nullopt;
}
-Animation* DocumentTimeline::Play(AnimationEffect* child) {
- Animation* animation = Animation::Create(child, this);
- DCHECK(animations_.Contains(animation));
-
- animation->play();
- DCHECK(animations_needing_update_.Contains(animation));
-
- return animation;
-}
-
void DocumentTimeline::ScheduleNextService() {
DCHECK_EQ(outdated_animation_count_, 0U);
@@ -150,7 +140,7 @@ void DocumentTimeline::DocumentTimelineTiming::WakeAfter(
timer_.StartOneShot(duration, FROM_HERE);
}
-void DocumentTimeline::DocumentTimelineTiming::Trace(Visitor* visitor) {
+void DocumentTimeline::DocumentTimelineTiming::Trace(Visitor* visitor) const {
visitor->Trace(timeline_);
DocumentTimeline::PlatformTiming::Trace(visitor);
}
@@ -225,7 +215,7 @@ CompositorAnimationTimeline* DocumentTimeline::EnsureCompositorTimeline() {
return compositor_timeline_.get();
}
-void DocumentTimeline::Trace(Visitor* visitor) {
+void DocumentTimeline::Trace(Visitor* visitor) const {
visitor->Trace(timing_);
AnimationTimeline::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/document_timeline.h b/chromium/third_party/blink/renderer/core/animation/document_timeline.h
index d98509a1e2e..a1392ecdb62 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_timeline.h
+++ b/chromium/third_party/blink/renderer/core/animation/document_timeline.h
@@ -40,8 +40,6 @@
namespace blink {
-class Animation;
-class AnimationEffect;
class DocumentTimelineOptions;
// DocumentTimeline is constructed and owned by Document, and tied to its
@@ -55,7 +53,7 @@ class CORE_EXPORT DocumentTimeline : public AnimationTimeline {
// Calls DocumentTimeline's wake() method after duration seconds.
virtual void WakeAfter(base::TimeDelta duration) = 0;
virtual ~PlatformTiming() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
// Web Animations API IDL constructor
@@ -71,8 +69,6 @@ class CORE_EXPORT DocumentTimeline : public AnimationTimeline {
void ScheduleNextService() override;
- Animation* Play(AnimationEffect*);
-
bool IsActive() const override;
base::Optional<base::TimeDelta> InitialStartTimeForAnimations() override;
bool HasPendingUpdates() const {
@@ -99,7 +95,7 @@ class CORE_EXPORT DocumentTimeline : public AnimationTimeline {
CompositorAnimationTimeline* EnsureCompositorTimeline() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
PhaseAndTime CurrentPhaseAndTime() override;
@@ -136,7 +132,7 @@ class CORE_EXPORT DocumentTimeline : public AnimationTimeline {
void TimerFired(TimerBase*) { timeline_->ScheduleServiceOnNextFrame(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<DocumentTimeline> timeline_;
diff --git a/chromium/third_party/blink/renderer/core/animation/document_timeline_test.cc b/chromium/third_party/blink/renderer/core/animation/document_timeline_test.cc
index abeeb524817..e29cbf4ef72 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_timeline_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/document_timeline_test.cc
@@ -61,7 +61,7 @@ class MockPlatformTiming : public DocumentTimeline::PlatformTiming {
public:
MOCK_METHOD1(WakeAfter, void(base::TimeDelta));
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
DocumentTimeline::PlatformTiming::Trace(visitor);
}
};
@@ -75,7 +75,9 @@ class TestDocumentTimeline : public DocumentTimeline {
DocumentTimeline::ScheduleServiceOnNextFrame();
schedule_next_service_called_ = true;
}
- void Trace(Visitor* visitor) override { DocumentTimeline::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ DocumentTimeline::Trace(visitor);
+ }
bool ScheduleNextServiceCalled() const {
return schedule_next_service_called_;
}
@@ -198,7 +200,7 @@ TEST_F(AnimationDocumentTimelineTest, CurrentTimeSeconds) {
EXPECT_EQ(2, timeline->CurrentTimeSeconds());
EXPECT_EQ(2000, timeline->currentTime());
- auto* document_without_frame = MakeGarbageCollected<Document>();
+ auto* document_without_frame = Document::CreateForTest();
auto* inactive_timeline = MakeGarbageCollected<DocumentTimeline>(
document_without_frame, base::TimeDelta(), platform_timing);
diff --git a/chromium/third_party/blink/renderer/core/animation/effect_input.cc b/chromium/third_party/blink/renderer/core/animation/effect_input.cc
index 27d54a63e4f..e27f91a3287 100644
--- a/chromium/third_party/blink/renderer/core/animation/effect_input.cc
+++ b/chromium/third_party/blink/renderer/core/animation/effect_input.cc
@@ -315,10 +315,10 @@ StringKeyframeVector ConvertArrayForm(Element* element,
double previous_offset = -std::numeric_limits<double>::infinity();
const wtf_size_t num_processed_keyframes = processed_base_keyframes.size();
for (wtf_size_t i = 0; i < num_processed_keyframes; ++i) {
- if (!processed_base_keyframes[i]->hasOffset())
+ if (!processed_base_keyframes[i]->hasOffsetNonNull())
continue;
- double offset = processed_base_keyframes[i]->offset();
+ double offset = processed_base_keyframes[i]->offsetNonNull();
if (offset < previous_offset) {
exception_state.ThrowTypeError(
"Offsets must be montonically non-decreasing.");
@@ -331,10 +331,10 @@ StringKeyframeVector ConvertArrayForm(Element* element,
// offset is non-null and less than zero or greater than one, throw a
// TypeError and abort these steps.
for (wtf_size_t i = 0; i < num_processed_keyframes; ++i) {
- if (!processed_base_keyframes[i]->hasOffset())
+ if (!processed_base_keyframes[i]->hasOffsetNonNull())
continue;
- double offset = processed_base_keyframes[i]->offset();
+ double offset = processed_base_keyframes[i]->offsetNonNull();
if (offset < 0 || offset > 1) {
exception_state.ThrowTypeError(
"Offsets must be null or in the range [0,1].");
diff --git a/chromium/third_party/blink/renderer/core/animation/effect_model.h b/chromium/third_party/blink/renderer/core/animation/effect_model.h
index 7b39d2cc016..8775f8742dc 100644
--- a/chromium/third_party/blink/renderer/core/animation/effect_model.h
+++ b/chromium/third_party/blink/renderer/core/animation/effect_model.h
@@ -68,7 +68,7 @@ class CORE_EXPORT EffectModel : public GarbageCollected<EffectModel> {
virtual bool IsTransformRelatedEffect() const { return false; }
virtual bool IsKeyframeEffectModel() const { return false; }
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/effect_stack.cc b/chromium/third_party/blink/renderer/core/animation/effect_stack.cc
index 9a2a31fc1e7..a3d51a451a3 100644
--- a/chromium/third_party/blink/renderer/core/animation/effect_stack.cc
+++ b/chromium/third_party/blink/renderer/core/animation/effect_stack.cc
@@ -210,7 +210,7 @@ void EffectStack::RemoveRedundantSampledEffects() {
sampled_effects_.Shrink(new_size);
}
-void EffectStack::Trace(Visitor* visitor) {
+void EffectStack::Trace(Visitor* visitor) const {
visitor->Trace(sampled_effects_);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/effect_stack.h b/chromium/third_party/blink/renderer/core/animation/effect_stack.h
index cf2b411b481..f97e0619a74 100644
--- a/chromium/third_party/blink/renderer/core/animation/effect_stack.h
+++ b/chromium/third_party/blink/renderer/core/animation/effect_stack.h
@@ -88,7 +88,7 @@ class CORE_EXPORT EffectStack {
PropertyHandleFilter property_handle_filter = nullptr,
KeyframeEffect* partial_effect_stack_cutoff = nullptr);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void RemoveRedundantSampledEffects();
diff --git a/chromium/third_party/blink/renderer/core/animation/element_animations.cc b/chromium/third_party/blink/renderer/core/animation/element_animations.cc
index b7968da8d3a..36116121a69 100644
--- a/chromium/third_party/blink/renderer/core/animation/element_animations.cc
+++ b/chromium/third_party/blink/renderer/core/animation/element_animations.cc
@@ -106,7 +106,7 @@ void ElementAnimations::RestartAnimationOnCompositor() {
entry.key->RestartAnimationOnCompositor();
}
-void ElementAnimations::Trace(Visitor* visitor) {
+void ElementAnimations::Trace(Visitor* visitor) const {
visitor->Trace(css_animations_);
visitor->Trace(effect_stack_);
visitor->Trace(animations_);
@@ -129,7 +129,6 @@ void ElementAnimations::UpdateBaseComputedStyle(
const ComputedStyle* computed_style,
std::unique_ptr<CSSBitset> base_important_set) {
DCHECK(computed_style);
- DCHECK(IsAnimationStyleChange());
base_computed_style_ = ComputedStyle::Clone(*computed_style);
base_important_set_ = std::move(base_important_set);
}
@@ -142,11 +141,10 @@ void ElementAnimations::ClearBaseComputedStyle() {
bool ElementAnimations::AnimationsPreserveAxisAlignment() const {
for (const auto& entry : animations_) {
const Animation& animation = *entry.key;
- DCHECK(animation.effect());
- DCHECK(IsA<KeyframeEffect>(animation.effect()));
- const auto& effect = *To<KeyframeEffect>(animation.effect());
- if (!effect.AnimationsPreserveAxisAlignment())
- return false;
+ if (const auto* effect = DynamicTo<KeyframeEffect>(animation.effect())) {
+ if (!effect->AnimationsPreserveAxisAlignment())
+ return false;
+ }
}
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/animation/element_animations.h b/chromium/third_party/blink/renderer/core/animation/element_animations.h
index 6d488127624..53b7eef7749 100644
--- a/chromium/third_party/blink/renderer/core/animation/element_animations.h
+++ b/chromium/third_party/blink/renderer/core/animation/element_animations.h
@@ -90,7 +90,7 @@ class CORE_EXPORT ElementAnimations final
bool AnimationsPreserveAxisAlignment() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
EffectStack effect_stack_;
diff --git a/chromium/third_party/blink/renderer/core/animation/inert_effect.cc b/chromium/third_party/blink/renderer/core/animation/inert_effect.cc
index 5ddff918d27..a3c29bfb79e 100644
--- a/chromium/third_party/blink/renderer/core/animation/inert_effect.cc
+++ b/chromium/third_party/blink/renderer/core/animation/inert_effect.cc
@@ -44,7 +44,7 @@ InertEffect::InertEffect(KeyframeEffectModelBase* model,
inherited_time_(inherited_time) {}
void InertEffect::Sample(HeapVector<Member<Interpolation>>& result) const {
- UpdateInheritedTime(inherited_time_, kTimingUpdateOnDemand);
+ UpdateInheritedTime(inherited_time_, base::nullopt, kTimingUpdateOnDemand);
if (!IsInEffect()) {
result.clear();
return;
@@ -64,7 +64,7 @@ AnimationTimeDelta InertEffect::CalculateTimeToEffectChange(
return AnimationTimeDelta::Max();
}
-void InertEffect::Trace(Visitor* visitor) {
+void InertEffect::Trace(Visitor* visitor) const {
visitor->Trace(model_);
AnimationEffect::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/inert_effect.h b/chromium/third_party/blink/renderer/core/animation/inert_effect.h
index 4be0330981b..4e8d8f49a8d 100644
--- a/chromium/third_party/blink/renderer/core/animation/inert_effect.h
+++ b/chromium/third_party/blink/renderer/core/animation/inert_effect.h
@@ -53,7 +53,7 @@ class CORE_EXPORT InertEffect final : public AnimationEffect {
bool IsInertEffect() const final { return true; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
void UpdateChildrenAndEffects() const override {}
diff --git a/chromium/third_party/blink/renderer/core/animation/interpolation.h b/chromium/third_party/blink/renderer/core/animation/interpolation.h
index 32690db1cc1..1f511cd341f 100644
--- a/chromium/third_party/blink/renderer/core/animation/interpolation.h
+++ b/chromium/third_party/blink/renderer/core/animation/interpolation.h
@@ -74,7 +74,7 @@ class CORE_EXPORT Interpolation : public GarbageCollected<Interpolation> {
// optimise away computing underlying values.
virtual bool DependsOnUnderlyingValue() const { return false; }
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
protected:
Interpolation() = default;
diff --git a/chromium/third_party/blink/renderer/core/animation/interpolation_effect.cc b/chromium/third_party/blink/renderer/core/animation/interpolation_effect.cc
index 814730f118f..24ee6aa04b9 100644
--- a/chromium/third_party/blink/renderer/core/animation/interpolation_effect.cc
+++ b/chromium/third_party/blink/renderer/core/animation/interpolation_effect.cc
@@ -44,7 +44,7 @@ void InterpolationEffect::AddInterpolationsFromKeyframes(
keyframe_b.Offset(), apply_from, apply_to);
}
-void InterpolationEffect::Trace(Visitor* visitor) {
+void InterpolationEffect::Trace(Visitor* visitor) const {
visitor->Trace(interpolations_);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/interpolation_effect.h b/chromium/third_party/blink/renderer/core/animation/interpolation_effect.h
index d8e0e3ac450..162ff4b09f3 100644
--- a/chromium/third_party/blink/renderer/core/animation/interpolation_effect.h
+++ b/chromium/third_party/blink/renderer/core/animation/interpolation_effect.h
@@ -49,7 +49,7 @@ class CORE_EXPORT InterpolationEffect
double apply_from,
double apply_to);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
class InterpolationRecord final
@@ -75,7 +75,7 @@ class CORE_EXPORT InterpolationEffect
double apply_from_;
double apply_to_;
- void Trace(Visitor* visitor) { visitor->Trace(interpolation_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(interpolation_); }
};
bool is_populated_;
diff --git a/chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.cc b/chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.cc
index ec3f4236565..59107805ffd 100644
--- a/chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.cc
+++ b/chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.cc
@@ -209,7 +209,7 @@ void InvalidatableInterpolation::SetFlagIfInheritUsed(
To<CSSPropertySpecificKeyframe>(*end_keyframe_).Value();
if ((start_value && start_value->IsInheritedValue()) ||
(end_value && end_value->IsInheritedValue())) {
- state.ParentStyle()->SetHasExplicitlyInheritedProperties();
+ state.ParentStyle()->SetChildHasExplicitInheritance();
}
}
diff --git a/chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.h b/chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.h
index 83e3f18f393..0e963dd8fed 100644
--- a/chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.h
+++ b/chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.h
@@ -55,7 +55,7 @@ class CORE_EXPORT InvalidatableInterpolation : public Interpolation {
return cached_value_.get();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(start_keyframe_);
visitor->Trace(end_keyframe_);
Interpolation::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe.h b/chromium/third_party/blink/renderer/core/animation/keyframe.h
index cb74faff5ae..fe695abdd47 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe.h
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe.h
@@ -114,7 +114,7 @@ class CORE_EXPORT Keyframe : public GarbageCollected<Keyframe> {
virtual bool IsStringKeyframe() const { return false; }
virtual bool IsTransitionKeyframe() const { return false; }
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
// Represents a property-specific keyframe as defined in the spec. Refer to
// the Keyframe class-level documentation for more details.
@@ -159,7 +159,7 @@ class CORE_EXPORT Keyframe : public GarbageCollected<Keyframe> {
const PropertyHandle&,
const Keyframe::PropertySpecificKeyframe& end) const;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
protected:
double offset_;
diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_animation_options.idl b/chromium/third_party/blink/renderer/core/animation/keyframe_animation_options.idl
index 1a62ca1a269..522308d1ea3 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe_animation_options.idl
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe_animation_options.idl
@@ -6,4 +6,5 @@
dictionary KeyframeAnimationOptions : KeyframeEffectOptions {
DOMString id = "";
+ AnimationTimeline? timeline;
};
diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc
index e7155c1c063..34dee962ca9 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc
@@ -122,8 +122,8 @@ KeyframeEffect* KeyframeEffect::Create(
effect->target_pseudo_ = pseudo;
if (element) {
element->GetDocument().UpdateStyleAndLayoutTreeForNode(element);
- effect->effect_target_ =
- element->GetPseudoElement(CSSSelector::ParsePseudoId(pseudo));
+ effect->effect_target_ = element->GetPseudoElement(
+ CSSSelector::ParsePseudoId(pseudo, element));
}
}
return effect;
@@ -208,7 +208,8 @@ void KeyframeEffect::RefreshTarget() {
} else {
target_element_->GetDocument().UpdateStyleAndLayoutTreeForNode(
target_element_);
- PseudoId pseudoId = CSSSelector::ParsePseudoId(target_pseudo_);
+ PseudoId pseudoId =
+ CSSSelector::ParsePseudoId(target_pseudo_, target_element_);
new_target = target_element_->GetPseudoElement(pseudoId);
}
@@ -423,7 +424,7 @@ bool KeyframeEffect::HasPlayingAnimation() const {
return owner_ && owner_->Playing();
}
-void KeyframeEffect::Trace(Visitor* visitor) {
+void KeyframeEffect::Trace(Visitor* visitor) const {
visitor->Trace(effect_target_);
visitor->Trace(target_element_);
visitor->Trace(model_);
@@ -591,9 +592,10 @@ AnimationTimeDelta KeyframeEffect::CalculateTimeToEffectChange(
case Timing::kPhaseNone:
return AnimationTimeDelta::Max();
case Timing::kPhaseBefore:
- DCHECK_GE(start_time, local_time.value());
- return forwards ? AnimationTimeDelta::FromSecondsD(start_time -
- local_time.value())
+ // Return value is clamped at 0 to prevent unexpected results that could
+ // be caused by returning negative values.
+ return forwards ? AnimationTimeDelta::FromSecondsD(std::max<double>(
+ start_time - local_time.value(), 0))
: AnimationTimeDelta::Max();
case Timing::kPhaseActive:
if (forwards) {
diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h
index 1fb72a9e3ab..08224be9420 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h
@@ -130,7 +130,7 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect {
bool HasAnimation() const;
bool HasPlayingAnimation() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool AnimationsPreserveAxisAlignment() const;
diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc
index fc823735f13..eebb5db929a 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc
@@ -287,7 +287,7 @@ bool KeyframeEffectModelBase::IsTransformRelatedEffect() const {
Affects(PropertyHandle(GetCSSPropertyTranslate()));
}
-void KeyframeEffectModelBase::Trace(Visitor* visitor) {
+void KeyframeEffectModelBase::Trace(Visitor* visitor) const {
visitor->Trace(keyframes_);
visitor->Trace(keyframe_groups_);
visitor->Trace(interpolation_effect_);
diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.h b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.h
index 498d7eb75e0..49699926518 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.h
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.h
@@ -67,7 +67,7 @@ class CORE_EXPORT KeyframeEffectModelBase : public EffectModel {
return keyframes_;
}
- void Trace(Visitor* visitor) { visitor->Trace(keyframes_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(keyframes_); }
private:
void RemoveRedundantKeyframes();
@@ -161,7 +161,7 @@ class CORE_EXPORT KeyframeEffectModelBase : public EffectModel {
virtual KeyframeEffectModelBase* Clone() = 0;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
KeyframeEffectModelBase(CompositeOperation composite,
diff --git a/chromium/third_party/blink/renderer/core/animation/length_list_property_functions.cc b/chromium/third_party/blink/renderer/core/animation/length_list_property_functions.cc
index 88c17d1a844..69d5a13fd8d 100644
--- a/chromium/third_party/blink/renderer/core/animation/length_list_property_functions.cc
+++ b/chromium/third_party/blink/renderer/core/animation/length_list_property_functions.cc
@@ -93,6 +93,7 @@ ValueRange LengthListPropertyFunctions::GetValueRange(
case CSSPropertyID::kBorderTopLeftRadius:
case CSSPropertyID::kBorderTopRightRadius:
case CSSPropertyID::kStrokeDasharray:
+ case CSSPropertyID::kContainIntrinsicSize:
return kValueRangeNonNegative;
default:
@@ -157,6 +158,8 @@ bool LengthListPropertyFunctions::GetLengthList(const CSSProperty& property,
return AppendToVector(style.BorderTopRightRadius(), result);
case CSSPropertyID::kTransformOrigin:
return AppendToVector(style.GetTransformOrigin(), result);
+ case CSSPropertyID::kContainIntrinsicSize:
+ return AppendToVector(style.ContainIntrinsicSize(), result);
case CSSPropertyID::kBackgroundPositionX:
case CSSPropertyID::kBackgroundPositionY:
@@ -236,6 +239,9 @@ void LengthListPropertyFunctions::SetLengthList(const CSSProperty& property,
case CSSPropertyID::kBorderTopRightRadius:
style.SetBorderTopRightRadius(SizeFromVector(length_list));
return;
+ case CSSPropertyID::kContainIntrinsicSize:
+ style.SetContainIntrinsicSize(SizeFromVector(length_list));
+ return;
case CSSPropertyID::kTransformOrigin:
style.SetTransformOrigin(TransformOriginFromVector(length_list));
diff --git a/chromium/third_party/blink/renderer/core/animation/length_property_functions.cc b/chromium/third_party/blink/renderer/core/animation/length_property_functions.cc
index 4e26d395244..04f82bdfce7 100644
--- a/chromium/third_party/blink/renderer/core/animation/length_property_functions.cc
+++ b/chromium/third_party/blink/renderer/core/animation/length_property_functions.cc
@@ -256,14 +256,14 @@ bool LengthPropertyFunctions::GetLength(const CSSProperty& property,
result = Length::Fixed(style.VerticalBorderSpacing());
return true;
case CSSPropertyID::kRowGap:
- if (style.RowGap().IsNormal())
+ if (!style.RowGap())
return false;
- result = style.RowGap().GetLength();
+ result = *style.RowGap();
return true;
case CSSPropertyID::kColumnGap:
- if (style.ColumnGap().IsNormal())
+ if (!style.ColumnGap())
return false;
- result = style.ColumnGap().GetLength();
+ result = *style.ColumnGap();
return true;
case CSSPropertyID::kColumnRuleWidth:
result = Length::Fixed(style.ColumnRuleWidth());
diff --git a/chromium/third_party/blink/renderer/core/animation/pending_animations.cc b/chromium/third_party/blink/renderer/core/animation/pending_animations.cc
index 0eb82a4c2b2..c21deb794bc 100644
--- a/chromium/third_party/blink/renderer/core/animation/pending_animations.cc
+++ b/chromium/third_party/blink/renderer/core/animation/pending_animations.cc
@@ -203,7 +203,7 @@ void PendingAnimations::FlushWaitingNonCompositedAnimations() {
}
}
-void PendingAnimations::Trace(Visitor* visitor) {
+void PendingAnimations::Trace(Visitor* visitor) const {
visitor->Trace(pending_);
visitor->Trace(waiting_for_compositor_animation_start_);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/pending_animations.h b/chromium/third_party/blink/renderer/core/animation/pending_animations.h
index 619c7720435..bc700e8b808 100644
--- a/chromium/third_party/blink/renderer/core/animation/pending_animations.h
+++ b/chromium/third_party/blink/renderer/core/animation/pending_animations.h
@@ -94,7 +94,7 @@ class CORE_EXPORT PendingAnimations final
void NotifyCompositorAnimationStarted(double monotonic_animation_start_time,
int compositor_group = 0);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void TimerFired(TimerBase*);
diff --git a/chromium/third_party/blink/renderer/core/animation/sampled_effect.cc b/chromium/third_party/blink/renderer/core/animation/sampled_effect.cc
index be5a56deb86..f4bf0734b7c 100644
--- a/chromium/third_party/blink/renderer/core/animation/sampled_effect.cc
+++ b/chromium/third_party/blink/renderer/core/animation/sampled_effect.cc
@@ -40,7 +40,7 @@ void SampledEffect::UpdateReplacedProperties(
}
}
-void SampledEffect::Trace(Visitor* visitor) {
+void SampledEffect::Trace(Visitor* visitor) const {
visitor->Trace(effect_);
visitor->Trace(interpolations_);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/sampled_effect.h b/chromium/third_party/blink/renderer/core/animation/sampled_effect.h
index 8ba125df07a..5f9a5dff41d 100644
--- a/chromium/third_party/blink/renderer/core/animation/sampled_effect.h
+++ b/chromium/third_party/blink/renderer/core/animation/sampled_effect.h
@@ -36,7 +36,7 @@ class SampledEffect final : public GarbageCollected<SampledEffect> {
void RemoveReplacedInterpolations(const HashSet<PropertyHandle>&);
void UpdateReplacedProperties(HashSet<PropertyHandle>&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
WeakMember<KeyframeEffect> effect_;
diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.cc
index 526519ef69c..c66c9a1af53 100644
--- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.cc
+++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/animation/scroll_timeline.h"
+#include <tuple>
+
#include "base/optional.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h"
#include "third_party/blink/renderer/core/animation/scroll_timeline_offset.h"
@@ -164,7 +166,7 @@ bool ScrollTimeline::IsActive() const {
}
void ScrollTimeline::Invalidate() {
- ScheduleNextService();
+ ScheduleNextServiceInternal(/* time_check = */ false);
}
bool ScrollTimeline::ComputeIsActive() const {
@@ -175,8 +177,8 @@ bool ScrollTimeline::ComputeIsActive() const {
layout_box->GetScrollableArea();
}
-void ScrollTimeline::ResolveScrollOffsets(double* start_offset,
- double* end_offset) const {
+std::tuple<base::Optional<double>, base::Optional<double>>
+ScrollTimeline::ResolveScrollOffsets() const {
DCHECK(ComputeIsActive());
LayoutBox* layout_box = resolved_scroll_source_->GetLayoutBox();
DCHECK(layout_box);
@@ -187,11 +189,13 @@ void ScrollTimeline::ResolveScrollOffsets(double* start_offset,
DCHECK(start_scroll_offset_ && end_scroll_offset_);
auto orientation = ToPhysicalScrollOrientation(orientation_, *layout_box);
- *start_offset = start_scroll_offset_->ResolveOffset(
+ auto start_offset = start_scroll_offset_->ResolveOffset(
resolved_scroll_source_, orientation, max_offset, 0);
- *end_offset = end_scroll_offset_->ResolveOffset(
+ auto end_offset = end_scroll_offset_->ResolveOffset(
resolved_scroll_source_, orientation, max_offset, max_offset);
+
+ return {start_offset, end_offset};
}
AnimationTimeline::PhaseAndTime ScrollTimeline::CurrentPhaseAndTime() {
@@ -215,9 +219,17 @@ ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const {
double max_offset;
GetCurrentAndMaxOffset(layout_box, current_offset, max_offset);
- double start_offset;
- double end_offset;
- ResolveScrollOffsets(&start_offset, &end_offset);
+ base::Optional<double> start;
+ base::Optional<double> end;
+ std::tie(start, end) = ResolveScrollOffsets();
+
+ if (!start || !end) {
+ return {TimelinePhase::kInactive, /*current_time*/ base::nullopt,
+ base::nullopt, base::nullopt};
+ }
+
+ double start_offset = start.value();
+ double end_offset = end.value();
// TODO(crbug.com/1060384): Once the spec has been updated to state what the
// expected result is when startScrollOffset >= endScrollOffset, we might need
@@ -273,14 +285,21 @@ void ScrollTimeline::ServiceAnimations(TimingUpdateReason reason) {
AnimationTimeline::ServiceAnimations(reason);
}
-void ScrollTimeline::ScheduleNextService() {
+void ScrollTimeline::ScheduleNextServiceInternal(bool time_check) {
if (AnimationsNeedingUpdateCount() == 0)
return;
- auto state = ComputeTimelineState();
- PhaseAndTime current_phase_and_time{state.phase, state.current_time};
- if (current_phase_and_time != last_current_phase_and_time_)
- ScheduleServiceOnNextFrame();
+ if (time_check) {
+ auto state = ComputeTimelineState();
+ PhaseAndTime current_phase_and_time{state.phase, state.current_time};
+ if (current_phase_and_time == last_current_phase_and_time_)
+ return;
+ }
+ ScheduleServiceOnNextFrame();
+}
+
+void ScrollTimeline::ScheduleNextService() {
+ ScheduleNextServiceInternal(/* time_check = */ true);
}
void ScrollTimeline::SnapshotState() {
@@ -366,6 +385,20 @@ void ScrollTimeline::GetCurrentAndMaxOffset(const LayoutBox* layout_box,
current_offset = std::abs(current_offset);
}
+void ScrollTimeline::AnimationAttached(Animation* animation) {
+ AnimationTimeline::AnimationAttached(animation);
+ if (resolved_scroll_source_ && scroll_animations_.IsEmpty())
+ resolved_scroll_source_->RegisterScrollTimeline(this);
+
+ scroll_animations_.insert(animation);
+}
+
+void ScrollTimeline::AnimationDetached(Animation* animation) {
+ AnimationTimeline::AnimationDetached(animation);
+ scroll_animations_.erase(animation);
+ if (resolved_scroll_source_ && scroll_animations_.IsEmpty())
+ resolved_scroll_source_->UnregisterScrollTimeline(this);
+}
void ScrollTimeline::WorkletAnimationAttached() {
if (!resolved_scroll_source_)
@@ -379,7 +412,8 @@ void ScrollTimeline::WorkletAnimationDetached() {
GetActiveScrollTimelineSet().erase(resolved_scroll_source_);
}
-void ScrollTimeline::Trace(Visitor* visitor) {
+void ScrollTimeline::Trace(Visitor* visitor) const {
+ visitor->Trace(scroll_animations_);
visitor->Trace(scroll_source_);
visitor->Trace(resolved_scroll_source_);
visitor->Trace(start_scroll_offset_);
@@ -428,4 +462,13 @@ CompositorAnimationTimeline* ScrollTimeline::EnsureCompositorTimeline() {
return compositor_timeline_.get();
}
+void ScrollTimeline::UpdateCompositorTimeline() {
+ if (!compositor_timeline_)
+ return;
+ compositor_timeline_->UpdateCompositorTimeline(
+ scroll_timeline_util::GetCompositorScrollElementId(
+ resolved_scroll_source_),
+ GetResolvedStartScrollOffset(), GetResolvedEndScrollOffset());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.h b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.h
index 6ddfaeb40ef..58396e2acc0 100644
--- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.h
+++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.h
@@ -97,6 +97,8 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline {
virtual void Invalidate();
CompositorAnimationTimeline* EnsureCompositorTimeline() override;
+ void UpdateCompositorTimeline() override;
+
// TODO(crbug.com/896249): These methods are temporary and currently required
// to support worklet animations. Once worklet animations become animations
// these methods will not be longer needed. They are used to keep track of
@@ -105,7 +107,10 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline {
void WorkletAnimationAttached();
void WorkletAnimationDetached();
- void Trace(Visitor*) override;
+ void AnimationAttached(Animation*) override;
+ void AnimationDetached(Animation*) override;
+
+ void Trace(Visitor*) const override;
static bool HasActiveScrollTimeline(Node* node);
// Invalidates scroll timelines with a given scroller node.
@@ -130,7 +135,8 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline {
// element-based values it computes the corresponding length value that maps
// to the particular element intersection. See
// |ScrollTimelineOffset::ResolveOffset()| for more details.
- void ResolveScrollOffsets(double* start_offset, double* end_offset) const;
+ std::tuple<base::Optional<double>, base::Optional<double>>
+ ResolveScrollOffsets() const;
struct TimelineState {
TimelinePhase phase;
@@ -149,6 +155,10 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline {
TimelineState ComputeTimelineState() const;
+ // Use time_check true to request next service if time has changed.
+ // false - regardless of time change.
+ void ScheduleNextServiceInternal(bool time_check);
+
// Use |scroll_source_| only to implement the web-exposed API but use
// resolved_scroll_source_ to actually access the scroll related properties.
Member<Element> scroll_source_;
@@ -164,6 +174,12 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline {
// Snapshotted value produced by the last SnapshotState call.
TimelineState timeline_state_snapshotted_;
+
+ // The only purpose of scroll_animations_ is keeping strong references to
+ // attached animations. This is required to keep attached animations alive
+ // as long as the timeline is alive. Scroll timeline is alive as long as its
+ // scroller is alive.
+ HeapHashSet<Member<Animation>> scroll_animations_;
};
template <>
diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc
index f839ede3f3e..5abe12051d8 100644
--- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc
+++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/animation/scroll_timeline_offset.h"
+#include "base/optional.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_scroll_timeline_element_based_offset.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_element_based_offset.h"
#include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
@@ -46,6 +47,25 @@ bool ValidateElementBasedOffset(ScrollTimelineElementBasedOffset* offset) {
return true;
}
+// TODO(majidvp): Dedup. This is a copy of the function in
+// third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
+// http://crbug.com/1023375
+
+// Return true if ancestor is in the containing block chain above descendant.
+bool IsContainingBlockChainDescendant(const LayoutObject* descendant,
+ const LayoutObject* ancestor) {
+ if (!ancestor || !descendant)
+ return false;
+ LocalFrame* ancestor_frame = ancestor->GetDocument().GetFrame();
+ LocalFrame* descendant_frame = descendant->GetDocument().GetFrame();
+ if (ancestor_frame != descendant_frame)
+ return false;
+
+ while (descendant && descendant != ancestor)
+ descendant = descendant->ContainingBlock();
+ return descendant;
+}
+
} // namespace
// static
@@ -71,10 +91,11 @@ ScrollTimelineOffset* ScrollTimelineOffset::Create(
}
}
-double ScrollTimelineOffset::ResolveOffset(Node* scroll_source,
- ScrollOrientation orientation,
- double max_offset,
- double default_offset) {
+base::Optional<double> ScrollTimelineOffset::ResolveOffset(
+ Node* scroll_source,
+ ScrollOrientation orientation,
+ double max_offset,
+ double default_offset) {
const LayoutBox* root_box = scroll_source->GetLayoutBox();
DCHECK(root_box);
Document& document = root_box->GetDocument();
@@ -110,12 +131,13 @@ double ScrollTimelineOffset::ResolveOffset(Node* scroll_source,
// It is possible for target to not have a layout box e.g., if it is an
// unattached element. In which case we return the default offset for now.
//
- // TODO(majidvp): Need to consider this case in the spec. Most likely we
- // should remain unresolved. See the spec discussion here:
+ // See the spec discussion here:
// https://github.com/w3c/csswg-drafts/issues/4337#issuecomment-610997231
- if (!target_box) {
- return default_offset;
- }
+ if (!target_box)
+ return base::nullopt;
+
+ if (!IsContainingBlockChainDescendant(target_box, root_box))
+ return base::nullopt;
PhysicalRect target_rect = target_box->PhysicalBorderBoxRect();
target_rect = target_box->LocalToAncestorRect(
@@ -200,7 +222,7 @@ ScrollTimelineOffset::ScrollTimelineOffset(
ScrollTimelineElementBasedOffset* offset)
: length_based_offset_(nullptr), element_based_offset_(offset) {}
-void ScrollTimelineOffset::Trace(blink::Visitor* visitor) {
+void ScrollTimelineOffset::Trace(blink::Visitor* visitor) const {
visitor->Trace(length_based_offset_);
visitor->Trace(element_based_offset_);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.h b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.h
index de2d55baff9..da37e45344e 100644
--- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.h
+++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.h
@@ -29,7 +29,7 @@ class CORE_EXPORT ScrollTimelineOffset final
// Create an element based offset.
explicit ScrollTimelineOffset(ScrollTimelineElementBasedOffset*);
- void Trace(blink::Visitor*);
+ void Trace(blink::Visitor*) const;
// Resolves this offset against the scroll source and in the given orientation
// returning eqiuvalent concrete scroll offset.
@@ -42,10 +42,12 @@ class CORE_EXPORT ScrollTimelineOffset final
//
// max offset is expected to be the maximum scroll offset in the scroll
// orientation.
- double ResolveOffset(Node* scroll_source,
- ScrollOrientation,
- double max_offset,
- double default_offset);
+ //
+ // Returns nullopt if the offset cannot be resolved.
+ base::Optional<double> ResolveOffset(Node* scroll_source,
+ ScrollOrientation,
+ double max_offset,
+ double default_offset);
StringOrScrollTimelineElementBasedOffset
ToStringOrScrollTimelineElementBasedOffset() const;
diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_test.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_test.cc
index 5c65bfe990b..2789161477f 100644
--- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_test.cc
@@ -6,6 +6,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h"
+#include "third_party/blink/renderer/core/animation/document_animations.h"
#include "third_party/blink/renderer/core/animation/keyframe_effect.h"
#include "third_party/blink/renderer/core/animation/keyframe_effect_model.h"
#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
@@ -41,6 +42,15 @@ class ScrollTimelineTest : public RenderingTest {
base::TimeDelta::FromMilliseconds(100);
GetPage().Animator().ServiceScriptedAnimations(new_time);
}
+
+ wtf_size_t AnimationsCount() const {
+ wtf_size_t count = 0;
+ for (auto timeline :
+ GetDocument().GetDocumentAnimations().GetTimelinesForTesting()) {
+ count += timeline->GetAnimations().size();
+ }
+ return count;
+ }
};
class TestScrollTimeline : public ScrollTimeline {
@@ -70,7 +80,9 @@ class TestScrollTimeline : public ScrollTimeline {
ScrollTimeline::ScheduleServiceOnNextFrame();
next_service_scheduled_ = true;
}
- void Trace(Visitor* visitor) override { ScrollTimeline::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ ScrollTimeline::Trace(visitor);
+ }
bool NextServiceScheduled() const { return next_service_scheduled_; }
void ResetNextServiceScheduled() { next_service_scheduled_ = false; }
@@ -362,8 +374,50 @@ TEST_F(ScrollTimelineTest, AttachOrDetachAnimationWithNullScrollSource) {
EXPECT_TRUE(scroll_timeline->GetAnimations().Contains(animation));
animation = nullptr;
+ scroll_timeline = nullptr;
+ ThreadState::Current()->CollectAllGarbageForTesting();
+ EXPECT_EQ(0u, AnimationsCount());
+}
+
+TEST_F(ScrollTimelineTest, AnimationIsGarbageCollectedWhenScrollerIsRemoved) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #scroller { overflow: scroll; width: 100px; height: 100px; }
+ #spacer { width: 200px; height: 200px; }
+ </style>
+ <div id='scroller'>
+ <div id ='spacer'></div>
+ </div>
+ )HTML");
+
+ TestScrollTimeline* scroll_timeline =
+ MakeGarbageCollected<TestScrollTimeline>(&GetDocument(),
+ GetElementById("scroller"));
+ NonThrowableExceptionState exception_state;
+ Timing timing;
+ timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
+ Animation* animation =
+ Animation::Create(MakeGarbageCollected<KeyframeEffect>(
+ nullptr,
+ MakeGarbageCollected<StringKeyframeEffectModel>(
+ StringKeyframeVector()),
+ timing),
+ scroll_timeline, exception_state);
+ animation->play();
+ UpdateAllLifecyclePhasesForTest();
+
+ animation->finish();
+ animation = nullptr;
+ scroll_timeline = nullptr;
ThreadState::Current()->CollectAllGarbageForTesting();
- EXPECT_EQ(0u, scroll_timeline->GetAnimations().size());
+ // Scroller is alive, animation is not GC'ed.
+ EXPECT_EQ(1u, AnimationsCount());
+
+ GetElementById("scroller")->remove();
+ UpdateAllLifecyclePhasesForTest();
+ ThreadState::Current()->CollectAllGarbageForTesting();
+ // Scroller is removed and unreachable, animation is GC'ed.
+ EXPECT_EQ(0u, AnimationsCount());
}
TEST_F(ScrollTimelineTest, ScheduleFrameOnlyWhenScrollOffsetChanges) {
@@ -463,6 +517,49 @@ TEST_F(ScrollTimelineTest, ScheduleFrameWhenScrollerLayoutChanges) {
EXPECT_TRUE(scroll_timeline->NextServiceScheduled());
}
+TEST_F(ScrollTimelineTest,
+ TimelineInvalidationWhenScrollerDisplayPropertyChanges) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #scroller { overflow: scroll; width: 100px; height: 100px; }
+ #spacer { width: 200px; height: 200px; }
+ </style>
+ <div id='scroller'>
+ <div id ='spacer'></div>
+ </div>
+ )HTML");
+ LayoutBoxModelObject* scroller =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"));
+ PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 20),
+ mojom::blink::ScrollType::kProgrammatic);
+ Element* scroller_element = GetElementById("scroller");
+
+ // Use empty offsets as 'auto'.
+ TestScrollTimeline* scroll_timeline =
+ MakeGarbageCollected<TestScrollTimeline>(
+ &GetDocument(), scroller_element,
+ MakeGarbageCollected<ScrollTimelineOffset>(),
+ MakeGarbageCollected<ScrollTimelineOffset>());
+ NonThrowableExceptionState exception_state;
+ Timing timing;
+ timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
+ Animation* scroll_animation =
+ Animation::Create(MakeGarbageCollected<KeyframeEffect>(
+ nullptr,
+ MakeGarbageCollected<StringKeyframeEffectModel>(
+ StringKeyframeVector()),
+ timing),
+ scroll_timeline, exception_state);
+ scroll_animation->play();
+ UpdateAllLifecyclePhasesForTest();
+
+ scroller_element->setAttribute(html_names::kStyleAttr, "display:table-cell;");
+ scroll_timeline->ResetNextServiceScheduled();
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_TRUE(scroll_timeline->NextServiceScheduled());
+}
+
// Verify that scroll timeline current time is updated once upon construction
// and at the top of every animation frame.
TEST_F(ScrollTimelineTest, CurrentTimeUpdateAfterNewAnimationFrame) {
diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc
index 9d146d046bd..f0e026c5ad1 100644
--- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc
@@ -81,7 +81,7 @@ TEST_F(ScrollTimelineUtilTest, ToCompositorScrollTimelineNullParameter) {
TEST_F(ScrollTimelineUtilTest,
ToCompositorScrollTimelineDocumentTimelineParameter) {
DocumentTimeline* timeline =
- MakeGarbageCollected<DocumentTimeline>(MakeGarbageCollected<Document>());
+ MakeGarbageCollected<DocumentTimeline>(Document::CreateForTest());
EXPECT_EQ(ToCompositorScrollTimeline(timeline), nullptr);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/string_keyframe.cc b/chromium/third_party/blink/renderer/core/animation/string_keyframe.cc
index e966397c81d..d2e77e8e0b1 100644
--- a/chromium/third_party/blink/renderer/core/animation/string_keyframe.cc
+++ b/chromium/third_party/blink/renderer/core/animation/string_keyframe.cc
@@ -214,7 +214,7 @@ void StringKeyframe::AddKeyframePropertiesToV8Object(
}
}
-void StringKeyframe::Trace(Visitor* visitor) {
+void StringKeyframe::Trace(Visitor* visitor) const {
visitor->Trace(input_properties_);
visitor->Trace(css_property_map_);
visitor->Trace(presentation_attribute_map_);
@@ -272,7 +272,8 @@ StringKeyframe::CSSPropertySpecificKeyframe::NeutralKeyframe(
offset, std::move(easing), nullptr, EffectModel::kCompositeAdd);
}
-void StringKeyframe::CSSPropertySpecificKeyframe::Trace(Visitor* visitor) {
+void StringKeyframe::CSSPropertySpecificKeyframe::Trace(
+ Visitor* visitor) const {
visitor->Trace(value_);
visitor->Trace(compositor_keyframe_value_cache_);
Keyframe::PropertySpecificKeyframe::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/animation/string_keyframe.h b/chromium/third_party/blink/renderer/core/animation/string_keyframe.h
index da68ab5f49f..87a7477d62d 100644
--- a/chromium/third_party/blink/renderer/core/animation/string_keyframe.h
+++ b/chromium/third_party/blink/renderer/core/animation/string_keyframe.h
@@ -86,7 +86,7 @@ class CORE_EXPORT StringKeyframe : public Keyframe {
Keyframe* Clone() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
class CSSPropertySpecificKeyframe
: public Keyframe::PropertySpecificKeyframe {
@@ -117,7 +117,7 @@ class CORE_EXPORT StringKeyframe : public Keyframe {
double offset,
scoped_refptr<TimingFunction> easing) const final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Keyframe::PropertySpecificKeyframe* CloneWithOffset(
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_angle_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/svg_angle_interpolation_type.cc
index e75b6a06490..77c3a51dd44 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_angle_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/svg_angle_interpolation_type.cc
@@ -19,8 +19,7 @@ InterpolationValue SVGAngleInterpolationType::MaybeConvertNeutral(
InterpolationValue SVGAngleInterpolationType::MaybeConvertSVGValue(
const SVGPropertyBase& svg_value) const {
- if (To<SVGAngle>(svg_value).OrientType()->EnumValue() !=
- kSVGMarkerOrientAngle)
+ if (!To<SVGAngle>(svg_value).IsNumeric())
return nullptr;
return InterpolationValue(
std::make_unique<InterpolableNumber>(To<SVGAngle>(svg_value).Value()));
diff --git a/chromium/third_party/blink/renderer/core/animation/timing.cc b/chromium/third_party/blink/renderer/core/animation/timing.cc
index ea3e60d22e3..27fa62737fd 100644
--- a/chromium/third_party/blink/renderer/core/animation/timing.cc
+++ b/chromium/third_party/blink/renderer/core/animation/timing.cc
@@ -153,13 +153,15 @@ ComputedEffectTiming* Timing::getComputedTiming(
Timing::CalculatedTiming Timing::CalculateTimings(
base::Optional<double> local_time,
+ base::Optional<Phase> timeline_phase,
AnimationDirection animation_direction,
bool is_keyframe_effect,
base::Optional<double> playback_rate) const {
const double active_duration = ActiveDuration();
- const Timing::Phase current_phase =
- CalculatePhase(active_duration, local_time, animation_direction, *this);
+ Timing::Phase current_phase = CalculatePhase(
+ active_duration, local_time, timeline_phase, animation_direction, *this);
+
const base::Optional<AnimationTimeDelta> active_time =
CalculateActiveTime(active_duration, ResolvedFillMode(is_keyframe_effect),
local_time, current_phase, *this);
diff --git a/chromium/third_party/blink/renderer/core/animation/timing.h b/chromium/third_party/blink/renderer/core/animation/timing.h
index 18cfd2127fc..300f8987c6d 100644
--- a/chromium/third_party/blink/renderer/core/animation/timing.h
+++ b/chromium/third_party/blink/renderer/core/animation/timing.h
@@ -44,6 +44,7 @@ namespace blink {
class EffectTiming;
class ComputedEffectTiming;
+enum class TimelinePhase;
struct CORE_EXPORT Timing {
USING_FAST_MALLOC(Timing);
@@ -174,6 +175,7 @@ struct CORE_EXPORT Timing {
};
CalculatedTiming CalculateTimings(base::Optional<double> local_time,
+ base::Optional<Phase> timeline_phase,
AnimationDirection animation_direction,
bool is_keyframe_effect,
base::Optional<double> playback_rate) const;
diff --git a/chromium/third_party/blink/renderer/core/animation/timing_calculations.h b/chromium/third_party/blink/renderer/core/animation/timing_calculations.h
index c33ac8cf3ba..731b461b252 100644
--- a/chromium/third_party/blink/renderer/core/animation/timing_calculations.h
+++ b/chromium/third_party/blink/renderer/core/animation/timing_calculations.h
@@ -73,10 +73,12 @@ static inline double MultiplyZeroAlwaysGivesZero(AnimationTimeDelta x,
}
// https://drafts.csswg.org/web-animations-1/#animation-effect-phases-and-states
-static inline Timing::Phase CalculatePhase(double active_duration,
- base::Optional<double> local_time,
- Timing::AnimationDirection direction,
- const Timing& specified) {
+static inline Timing::Phase CalculatePhase(
+ double active_duration,
+ base::Optional<double> local_time,
+ base::Optional<Timing::Phase> timeline_phase,
+ Timing::AnimationDirection direction,
+ const Timing& specified) {
DCHECK_GE(active_duration, 0);
if (!local_time)
return Timing::kPhaseNone;
@@ -85,6 +87,8 @@ static inline Timing::Phase CalculatePhase(double active_duration,
double before_active_boundary_time =
std::max(std::min(specified.start_delay, end_time), 0.0);
if (local_time.value() < before_active_boundary_time ||
+ (local_time.value() == before_active_boundary_time && timeline_phase &&
+ timeline_phase.value() == Timing::kPhaseBefore) ||
(local_time.value() == before_active_boundary_time &&
direction == Timing::AnimationDirection::kBackwards)) {
return Timing::kPhaseBefore;
@@ -92,6 +96,8 @@ static inline Timing::Phase CalculatePhase(double active_duration,
double active_after_boundary_time = std::max(
std::min(specified.start_delay + active_duration, end_time), 0.0);
if (local_time > active_after_boundary_time ||
+ (local_time.value() == active_after_boundary_time && timeline_phase &&
+ timeline_phase.value() == Timing::kPhaseAfter) ||
(local_time == active_after_boundary_time &&
direction == Timing::AnimationDirection::kForwards)) {
return Timing::kPhaseAfter;
diff --git a/chromium/third_party/blink/renderer/core/animation/timing_test.cc b/chromium/third_party/blink/renderer/core/animation/timing_test.cc
index 485daea9e27..84e0d7fc267 100644
--- a/chromium/third_party/blink/renderer/core/animation/timing_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/timing_test.cc
@@ -16,8 +16,9 @@ class AnimationTimingTest : public testing::Test {
Timing::AnimationDirection animation_direction =
playback_rate < 0 ? Timing::AnimationDirection::kBackwards
: Timing::AnimationDirection::kForwards;
- return timing_.CalculateTimings(local_time, animation_direction,
- is_keyframe_effect, playback_rate);
+ return timing_.CalculateTimings(
+ local_time, /*timeline_phase*/ base::nullopt, animation_direction,
+ is_keyframe_effect, playback_rate);
}
bool IsCurrent(base::Optional<double> local_time, double playback_rate) {
return CalculateTimings(local_time, playback_rate).is_current;
diff --git a/chromium/third_party/blink/renderer/core/animation/transition_interpolation.h b/chromium/third_party/blink/renderer/core/animation/transition_interpolation.h
index e87dd4ba911..49f9fa8a535 100644
--- a/chromium/third_party/blink/renderer/core/animation/transition_interpolation.h
+++ b/chromium/third_party/blink/renderer/core/animation/transition_interpolation.h
@@ -75,7 +75,7 @@ class CORE_EXPORT TransitionInterpolation : public Interpolation {
void Interpolate(int iteration, double fraction) final;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(compositor_start_);
visitor->Trace(compositor_end_);
Interpolation::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/animation/transition_keyframe.cc b/chromium/third_party/blink/renderer/core/animation/transition_keyframe.cc
index 7a42136093b..f506cef20dd 100644
--- a/chromium/third_party/blink/renderer/core/animation/transition_keyframe.cc
+++ b/chromium/third_party/blink/renderer/core/animation/transition_keyframe.cc
@@ -62,7 +62,7 @@ void TransitionKeyframe::AddKeyframePropertiesToV8Object(
object_builder.Add(property_name, property_value);
}
-void TransitionKeyframe::Trace(Visitor* visitor) {
+void TransitionKeyframe::Trace(Visitor* visitor) const {
visitor->Trace(compositor_value_);
Keyframe::Trace(visitor);
}
@@ -93,7 +93,8 @@ TransitionKeyframe::PropertySpecificKeyframe::CreateInterpolation(
other.compositor_value_);
}
-void TransitionKeyframe::PropertySpecificKeyframe::Trace(Visitor* visitor) {
+void TransitionKeyframe::PropertySpecificKeyframe::Trace(
+ Visitor* visitor) const {
visitor->Trace(compositor_value_);
Keyframe::PropertySpecificKeyframe::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/transition_keyframe.h b/chromium/third_party/blink/renderer/core/animation/transition_keyframe.h
index cbaa0db934c..e8c75ae0538 100644
--- a/chromium/third_party/blink/renderer/core/animation/transition_keyframe.h
+++ b/chromium/third_party/blink/renderer/core/animation/transition_keyframe.h
@@ -45,7 +45,7 @@ class CORE_EXPORT TransitionKeyframe : public Keyframe {
void AddKeyframePropertiesToV8Object(V8ObjectBuilder&,
Element*) const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
class PropertySpecificKeyframe : public Keyframe::PropertySpecificKeyframe {
public:
@@ -78,7 +78,7 @@ class CORE_EXPORT TransitionKeyframe : public Keyframe {
bool IsTransitionPropertySpecificKeyframe() const final { return true; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Keyframe::PropertySpecificKeyframe* CloneWithOffset(
diff --git a/chromium/third_party/blink/renderer/core/animation/worklet_animation_controller.cc b/chromium/third_party/blink/renderer/core/animation/worklet_animation_controller.cc
index b690076cf33..fd899c25b55 100644
--- a/chromium/third_party/blink/renderer/core/animation/worklet_animation_controller.cc
+++ b/chromium/third_party/blink/renderer/core/animation/worklet_animation_controller.cc
@@ -110,9 +110,9 @@ WorkletAnimationController::EnsureMainThreadMutatorDispatcher(
return mutator_dispatcher;
}
-// TODO(yigu): Currently one animator name is synced back per registration.
-// Eventually all registered names should be synced in batch once a module
-// completes its loading in the worklet scope. https://crbug.com/920722.
+// TODO(crbug.com/920722): Currently one animator name is synced back per
+// registration. Eventually all registered names should be synced in batch once
+// a module completes its loading in the worklet scope.
void WorkletAnimationController::SynchronizeAnimatorName(
const String& animator_name) {
animator_names_.insert(animator_name);
@@ -160,7 +160,7 @@ void WorkletAnimationController::ApplyAnimationTimings(
animation->Update(reason);
}
-void WorkletAnimationController::Trace(Visitor* visitor) {
+void WorkletAnimationController::Trace(Visitor* visitor) const {
visitor->Trace(pending_animations_);
visitor->Trace(animations_);
visitor->Trace(document_);
diff --git a/chromium/third_party/blink/renderer/core/animation/worklet_animation_controller.h b/chromium/third_party/blink/renderer/core/animation/worklet_animation_controller.h
index 175098293a2..b9f5cad9e1d 100644
--- a/chromium/third_party/blink/renderer/core/animation/worklet_animation_controller.h
+++ b/chromium/third_party/blink/renderer/core/animation/worklet_animation_controller.h
@@ -64,7 +64,7 @@ class CORE_EXPORT WorkletAnimationController
// AnimationWorkletGlobalScope.
bool IsAnimatorRegistered(const String& animator_name) const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void MutateAnimations();
@@ -76,8 +76,8 @@ class CORE_EXPORT WorkletAnimationController
WTF::HashSet<String> animator_names_;
- // TODO(yigu): The following proxy is needed for platform/ to access this
- // class. We should bypass it eventually.
+ // TODO(crbug.com/1090515): The following proxy is needed for platform/ to
+ // access this class. We should bypass it eventually.
std::unique_ptr<MainThreadMutatorClient> main_thread_mutator_client_;
scoped_refptr<base::SingleThreadTaskRunner> mutator_task_runner_;
diff --git a/chromium/third_party/blink/renderer/core/animation_frame/worker_animation_frame_provider.cc b/chromium/third_party/blink/renderer/core/animation_frame/worker_animation_frame_provider.cc
index 3d314f5d756..060b3e9e528 100644
--- a/chromium/third_party/blink/renderer/core/animation_frame/worker_animation_frame_provider.cc
+++ b/chromium/third_party/blink/renderer/core/animation_frame/worker_animation_frame_provider.cc
@@ -43,7 +43,7 @@ void WorkerAnimationFrameProvider::BeginFrame(const viz::BeginFrameArgs& args) {
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
Microtask::EnqueueMicrotask(WTF::Bind(
- [](base::WeakPtr<WorkerAnimationFrameProvider> provider,
+ [](WeakPersistent<WorkerAnimationFrameProvider> provider,
const viz::BeginFrameArgs& args) {
if (!provider)
return;
@@ -67,7 +67,7 @@ void WorkerAnimationFrameProvider::BeginFrame(const viz::BeginFrameArgs& args) {
}
provider->begin_frame_provider_->FinishBeginFrame(args);
},
- weak_factory_.GetWeakPtr(), args));
+ WrapWeakPersistent(this), args));
}
void WorkerAnimationFrameProvider::RegisterOffscreenCanvas(
@@ -81,7 +81,7 @@ void WorkerAnimationFrameProvider::DeregisterOffscreenCanvas(
offscreen_canvases_.erase(offscreen_canvas);
}
-void WorkerAnimationFrameProvider::Trace(Visitor* visitor) {
+void WorkerAnimationFrameProvider::Trace(Visitor* visitor) const {
visitor->Trace(begin_frame_provider_);
visitor->Trace(callback_collection_);
visitor->Trace(offscreen_canvases_);
diff --git a/chromium/third_party/blink/renderer/core/animation_frame/worker_animation_frame_provider.h b/chromium/third_party/blink/renderer/core/animation_frame/worker_animation_frame_provider.h
index d06b7d02dd3..ffba305c19e 100644
--- a/chromium/third_party/blink/renderer/core/animation_frame/worker_animation_frame_provider.h
+++ b/chromium/third_party/blink/renderer/core/animation_frame/worker_animation_frame_provider.h
@@ -39,7 +39,7 @@ class CORE_EXPORT WorkerAnimationFrameProvider
int RegisterCallback(FrameRequestCallbackCollection::FrameCallback* callback);
void CancelCallback(int id);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// BeginFrameProviderClient
void BeginFrame(const viz::BeginFrameArgs&) override;
@@ -57,8 +57,6 @@ class CORE_EXPORT WorkerAnimationFrameProvider
HeapLinkedHashSet<WeakMember<OffscreenCanvas>> offscreen_canvases_;
Member<ExecutionContext> context_;
-
- base::WeakPtrFactory<WorkerAnimationFrameProvider> weak_factory_{this};
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/aom/accessible_node.cc b/chromium/third_party/blink/renderer/core/aom/accessible_node.cc
index 198fabffe62..d1c1f59e004 100644
--- a/chromium/third_party/blink/renderer/core/aom/accessible_node.cc
+++ b/chromium/third_party/blink/renderer/core/aom/accessible_node.cc
@@ -1130,7 +1130,7 @@ AXObjectCache* AccessibleNode::GetAXObjectCache() {
return GetDocument()->ExistingAXObjectCache();
}
-void AccessibleNode::Trace(Visitor* visitor) {
+void AccessibleNode::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(document_);
visitor->Trace(relation_properties_);
diff --git a/chromium/third_party/blink/renderer/core/aom/accessible_node.h b/chromium/third_party/blink/renderer/core/aom/accessible_node.h
index 0ceaa645a36..e812ecd04d8 100644
--- a/chromium/third_party/blink/renderer/core/aom/accessible_node.h
+++ b/chromium/third_party/blink/renderer/core/aom/accessible_node.h
@@ -359,7 +359,7 @@ class CORE_EXPORT AccessibleNode : public EventTargetWithInlineData {
DEFINE_ATTRIBUTE_EVENT_LISTENER(accessiblescrollintoview,
kAccessiblescrollintoview)
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
friend class AccessibleNodeList;
diff --git a/chromium/third_party/blink/renderer/core/aom/accessible_node_list.cc b/chromium/third_party/blink/renderer/core/aom/accessible_node_list.cc
index de6ea7a0d26..092c163d430 100644
--- a/chromium/third_party/blink/renderer/core/aom/accessible_node_list.cc
+++ b/chromium/third_party/blink/renderer/core/aom/accessible_node_list.cc
@@ -106,7 +106,7 @@ void AccessibleNodeList::NotifyChanged() {
owner.second->OnRelationListChanged(owner.first);
}
-void AccessibleNodeList::Trace(Visitor* visitor) {
+void AccessibleNodeList::Trace(Visitor* visitor) const {
visitor->Trace(nodes_);
visitor->Trace(owners_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/aom/accessible_node_list.h b/chromium/third_party/blink/renderer/core/aom/accessible_node_list.h
index e6b5bd1be45..a048b24706c 100644
--- a/chromium/third_party/blink/renderer/core/aom/accessible_node_list.h
+++ b/chromium/third_party/blink/renderer/core/aom/accessible_node_list.h
@@ -39,7 +39,7 @@ class CORE_EXPORT AccessibleNodeList : public ScriptWrappable {
unsigned length() const;
void setLength(unsigned);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void NotifyChanged();
diff --git a/chromium/third_party/blink/renderer/core/aom/computed_accessible_node.cc b/chromium/third_party/blink/renderer/core/aom/computed_accessible_node.cc
index e62cbe358ba..b6a36be1146 100644
--- a/chromium/third_party/blink/renderer/core/aom/computed_accessible_node.cc
+++ b/chromium/third_party/blink/renderer/core/aom/computed_accessible_node.cc
@@ -33,7 +33,7 @@ class ComputedAccessibleNodePromiseResolver::RequestAnimationFrameCallback final
resolver_->UpdateTreeAndResolve();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(resolver_);
FrameRequestCallbackCollection::FrameCallback::Trace(visitor);
}
@@ -56,7 +56,7 @@ ScriptPromise ComputedAccessibleNodePromiseResolver::Promise() {
return resolver_->Promise();
}
-void ComputedAccessibleNodePromiseResolver::Trace(Visitor* visitor) {
+void ComputedAccessibleNodePromiseResolver::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(resolver_);
}
@@ -325,7 +325,7 @@ const String ComputedAccessibleNode::GetStringAttribute(
return String();
}
-void ComputedAccessibleNode::Trace(Visitor* visitor) {
+void ComputedAccessibleNode::Trace(Visitor* visitor) const {
visitor->Trace(document_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/aom/computed_accessible_node.h b/chromium/third_party/blink/renderer/core/aom/computed_accessible_node.h
index 35b87ee82e2..fae87d7e1ba 100644
--- a/chromium/third_party/blink/renderer/core/aom/computed_accessible_node.h
+++ b/chromium/third_party/blink/renderer/core/aom/computed_accessible_node.h
@@ -30,7 +30,7 @@ class ComputedAccessibleNodePromiseResolver final
ScriptPromise Promise();
void ComputeAccessibleNode();
void EnsureUpToDate();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void UpdateTreeAndResolve();
@@ -50,7 +50,7 @@ class ComputedAccessibleNode : public ScriptWrappable {
ComputedAccessibleNode(AXID, WebComputedAXTree*, Document*);
~ComputedAccessibleNode() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// TODO(meredithl): add accessors for state properties.
base::Optional<bool> atomic() const;
diff --git a/chromium/third_party/blink/renderer/core/clipboard/data_object.cc b/chromium/third_party/blink/renderer/core/clipboard/data_object.cc
index c285880a76f..ce28daa9fd4 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_object.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_object.cc
@@ -279,7 +279,7 @@ void DataObject::NotifyItemListChanged() const {
observer->OnItemListChanged();
}
-void DataObject::Trace(Visitor* visitor) {
+void DataObject::Trace(Visitor* visitor) const {
visitor->Trace(item_list_);
visitor->Trace(observers_);
Supplementable<DataObject>::Trace(visitor);
@@ -333,7 +333,6 @@ DataObject* DataObject::Create(WebDragData data) {
WebDragData DataObject::ToWebDragData() {
WebDragData data;
- data.Initialize();
data.SetModifierKeyState(modifiers_);
WebVector<WebDragData::Item> item_list(length());
diff --git a/chromium/third_party/blink/renderer/core/clipboard/data_object.h b/chromium/third_party/blink/renderer/core/clipboard/data_object.h
index aabc378fefa..65a4b0bf97a 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_object.h
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_object.h
@@ -124,7 +124,7 @@ class CORE_EXPORT DataObject : public GarbageCollected<DataObject>,
// whenever the underlying item_list_ changes.
void AddObserver(Observer*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
WebDragData ToWebDragData();
diff --git a/chromium/third_party/blink/renderer/core/clipboard/data_object_item.cc b/chromium/third_party/blink/renderer/core/clipboard/data_object_item.cc
index 8445a955220..bf0b10fa632 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_object_item.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_object_item.cc
@@ -120,7 +120,7 @@ DataObjectItem* DataObjectItem::CreateFromClipboard(
}
DataObjectItem::DataObjectItem(ItemKind kind, const String& type)
- : source_(kInternalSource),
+ : source_(DataSource::kInternalSource),
kind_(kind),
type_(type),
sequence_number_(0),
@@ -130,7 +130,7 @@ DataObjectItem::DataObjectItem(ItemKind kind,
const String& type,
uint64_t sequence_number,
SystemClipboard* system_clipboard)
- : source_(kClipboardSource),
+ : source_(DataSource::kClipboardSource),
kind_(kind),
type_(type),
sequence_number_(sequence_number),
@@ -142,7 +142,7 @@ File* DataObjectItem::GetAsFile() const {
if (Kind() != kFileKind)
return nullptr;
- if (source_ == kInternalSource) {
+ if (source_ == DataSource::kInternalSource) {
if (file_)
return file_.Get();
DCHECK(shared_buffer_);
@@ -152,7 +152,7 @@ File* DataObjectItem::GetAsFile() const {
return nullptr;
}
- DCHECK_EQ(source_, kClipboardSource);
+ DCHECK_EQ(source_, DataSource::kClipboardSource);
if (GetType() == kMimeTypeImagePng) {
SkBitmap bitmap =
system_clipboard_->ReadImage(mojom::ClipboardBuffer::kStandard);
@@ -184,10 +184,10 @@ File* DataObjectItem::GetAsFile() const {
String DataObjectItem::GetAsString() const {
DCHECK_EQ(kind_, kStringKind);
- if (source_ == kInternalSource)
+ if (source_ == DataSource::kInternalSource)
return data_;
- DCHECK_EQ(source_, kClipboardSource);
+ DCHECK_EQ(source_, DataSource::kClipboardSource);
String data;
// This is ugly but there's no real alternative.
@@ -222,7 +222,7 @@ String DataObjectItem::FileSystemId() const {
return file_system_id_;
}
-void DataObjectItem::Trace(Visitor* visitor) {
+void DataObjectItem::Trace(Visitor* visitor) const {
visitor->Trace(file_);
visitor->Trace(system_clipboard_);
}
diff --git a/chromium/third_party/blink/renderer/core/clipboard/data_object_item.h b/chromium/third_party/blink/renderer/core/clipboard/data_object_item.h
index 69843abb6d2..ce484f7ef1e 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_object_item.h
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_object_item.h
@@ -89,10 +89,10 @@ class CORE_EXPORT DataObjectItem final
bool HasFileSystemId() const;
String FileSystemId() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
- enum DataSource {
+ enum class DataSource {
kClipboardSource,
kInternalSource,
};
@@ -109,7 +109,8 @@ class CORE_EXPORT DataObjectItem final
String title_;
KURL base_url_;
- uint64_t sequence_number_; // Only valid when |source_| == PasteboardSource.
+ uint64_t sequence_number_; // Only valid when |source_| ==
+ // DataSource::kClipboardSource.
String file_system_id_; // Only valid when |file_| is backed by FileEntry.
// Access to the global system clipboard.
diff --git a/chromium/third_party/blink/renderer/core/clipboard/data_transfer.cc b/chromium/third_party/blink/renderer/core/clipboard/data_transfer.cc
index 047fb1945e0..b56cce6e27a 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_transfer.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_transfer.cc
@@ -27,6 +27,7 @@
#include <memory>
+#include "base/optional.h"
#include "build/build_config.h"
#include "third_party/blink/public/platform/web_screen_info.h"
#include "third_party/blink/renderer/core/clipboard/clipboard_mime_types.h"
@@ -103,7 +104,7 @@ class DraggedNodeImageBuilder {
// object contains transparency and there are other elements in the same
// stacking context which stacked below.
PaintLayer* layer = dragged_layout_object->EnclosingLayer();
- if (!layer->GetLayoutObject().StyleRef().IsStackingContext())
+ if (!layer->GetLayoutObject().IsStackingContext())
layer = layer->AncestorStackingContext();
IntRect absolute_bounding_box =
@@ -155,8 +156,11 @@ class DraggedNodeImageBuilder {
const uint64_t dom_tree_version_;
#endif
};
+
} // namespace
-static DragOperation ConvertEffectAllowedToDragOperation(const String& op) {
+
+static base::Optional<DragOperation> ConvertEffectAllowedToDragOperation(
+ const String& op) {
// Values specified in
// https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-effectallowed
if (op == "uninitialized")
@@ -168,33 +172,30 @@ static DragOperation ConvertEffectAllowedToDragOperation(const String& op) {
if (op == "link")
return kDragOperationLink;
if (op == "move")
- return (DragOperation)(kDragOperationGeneric | kDragOperationMove);
+ return kDragOperationMove;
if (op == "copyLink")
- return (DragOperation)(kDragOperationCopy | kDragOperationLink);
+ return static_cast<DragOperation>(kDragOperationCopy | kDragOperationLink);
if (op == "copyMove")
- return (DragOperation)(kDragOperationCopy | kDragOperationGeneric |
- kDragOperationMove);
+ return static_cast<DragOperation>(kDragOperationCopy | kDragOperationMove);
if (op == "linkMove")
- return (DragOperation)(kDragOperationLink | kDragOperationGeneric |
- kDragOperationMove);
+ return static_cast<DragOperation>(kDragOperationLink | kDragOperationMove);
if (op == "all")
return kDragOperationEvery;
- return kDragOperationPrivate; // really a marker for "no conversion"
+ return base::nullopt;
}
static String ConvertDragOperationToEffectAllowed(DragOperation op) {
- bool move_set = !!((kDragOperationGeneric | kDragOperationMove) & op);
-
- if ((move_set && (op & kDragOperationCopy) && (op & kDragOperationLink)) ||
+ if (((op & kDragOperationMove) && (op & kDragOperationCopy) &&
+ (op & kDragOperationLink)) ||
(op == kDragOperationEvery))
return "all";
- if (move_set && (op & kDragOperationCopy))
+ if ((op & kDragOperationMove) && (op & kDragOperationCopy))
return "copyMove";
- if (move_set && (op & kDragOperationLink))
+ if ((op & kDragOperationMove) && (op & kDragOperationLink))
return "linkMove";
if ((op & kDragOperationCopy) && (op & kDragOperationLink))
return "copyLink";
- if (move_set)
+ if (op & kDragOperationMove)
return "move";
if (op & kDragOperationCopy)
return "copy";
@@ -261,7 +262,7 @@ void DataTransfer::setEffectAllowed(const String& effect) {
if (!IsForDragAndDrop())
return;
- if (ConvertEffectAllowedToDragOperation(effect) == kDragOperationPrivate) {
+ if (!ConvertEffectAllowedToDragOperation(effect)) {
// This means that there was no conversion, and the effectAllowed that
// we are passed isn't a valid effectAllowed, so we should ignore it,
// and not set |effect_allowed_|.
@@ -561,18 +562,19 @@ bool DataTransfer::CanSetDragImage() const {
}
DragOperation DataTransfer::SourceOperation() const {
- DragOperation op = ConvertEffectAllowedToDragOperation(effect_allowed_);
- DCHECK_NE(op, kDragOperationPrivate);
- return op;
+ base::Optional<DragOperation> op =
+ ConvertEffectAllowedToDragOperation(effect_allowed_);
+ DCHECK(op);
+ return *op;
}
DragOperation DataTransfer::DestinationOperation() const {
- DragOperation op = ConvertEffectAllowedToDragOperation(drop_effect_);
+ base::Optional<DragOperation> op =
+ ConvertEffectAllowedToDragOperation(drop_effect_);
DCHECK(op == kDragOperationCopy || op == kDragOperationNone ||
- op == kDragOperationLink ||
- op == (DragOperation)(kDragOperationGeneric | kDragOperationMove) ||
+ op == kDragOperationLink || op == kDragOperationMove ||
op == kDragOperationEvery);
- return op;
+ return *op;
}
void DataTransfer::SetSourceOperation(DragOperation op) {
@@ -582,10 +584,7 @@ void DataTransfer::SetSourceOperation(DragOperation op) {
void DataTransfer::SetDestinationOperation(DragOperation op) {
DCHECK(op == kDragOperationCopy || op == kDragOperationNone ||
- op == kDragOperationLink || op == kDragOperationGeneric ||
- op == kDragOperationMove ||
- op == static_cast<DragOperation>(kDragOperationGeneric |
- kDragOperationMove));
+ op == kDragOperationLink || op == kDragOperationMove);
drop_effect_ = ConvertDragOperationToEffectAllowed(op);
}
@@ -680,7 +679,7 @@ String ConvertDragOperationToDropZoneOperation(DragOperation operation) {
}
}
-void DataTransfer::Trace(Visitor* visitor) {
+void DataTransfer::Trace(Visitor* visitor) const {
visitor->Trace(data_object_);
visitor->Trace(drag_image_);
visitor->Trace(drag_image_element_);
diff --git a/chromium/third_party/blink/renderer/core/clipboard/data_transfer.h b/chromium/third_party/blink/renderer/core/clipboard/data_transfer.h
index 06c596b39e7..4a15d999bb2 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_transfer.h
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_transfer.h
@@ -156,7 +156,7 @@ class CORE_EXPORT DataTransfer final : public ScriptWrappable,
const PropertyTreeState&);
static std::unique_ptr<DragImage> NodeImage(LocalFrame&, Node&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void setDragImage(ImageResourceContent*, Node*, const IntPoint&);
diff --git a/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item.cc b/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item.cc
index 459ace940b3..a1f7fed0cc3 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item.cc
@@ -106,7 +106,7 @@ void DataTransferItem::RunGetAsStringTask(
callback->InvokeAndReportException(nullptr, data);
}
-void DataTransferItem::Trace(Visitor* visitor) {
+void DataTransferItem::Trace(Visitor* visitor) const {
visitor->Trace(data_transfer_);
visitor->Trace(item_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item.h b/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item.h
index eb8bb1372dc..f055fb3c2b9 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item.h
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item.h
@@ -65,7 +65,7 @@ class CORE_EXPORT DataTransferItem final : public ScriptWrappable {
DataTransfer* GetDataTransfer() { return data_transfer_.Get(); }
DataObjectItem* GetDataObjectItem() { return item_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void RunGetAsStringTask(ExecutionContext*,
diff --git a/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item_list.cc b/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item_list.cc
index b7e0bbfcc3c..a0ae189e9d3 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item_list.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item_list.cc
@@ -93,7 +93,7 @@ DataTransferItemList::DataTransferItemList(DataTransfer* data_transfer,
DataObject* data_object)
: data_transfer_(data_transfer), data_object_(data_object) {}
-void DataTransferItemList::Trace(Visitor* visitor) {
+void DataTransferItemList::Trace(Visitor* visitor) const {
visitor->Trace(data_transfer_);
visitor->Trace(data_object_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item_list.h b/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item_list.h
index 40619a675b9..fb6fca1b5b7 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item_list.h
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_transfer_item_list.h
@@ -60,7 +60,7 @@ class CORE_EXPORT DataTransferItemList final : public ScriptWrappable {
ExceptionState&);
DataTransferItem* add(File*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<DataTransfer> data_transfer_;
diff --git a/chromium/third_party/blink/renderer/core/clipboard/raw_system_clipboard.cc b/chromium/third_party/blink/renderer/core/clipboard/raw_system_clipboard.cc
index 4f08821b9d0..73e8a755ede 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/raw_system_clipboard.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/raw_system_clipboard.cc
@@ -38,7 +38,7 @@ void RawSystemClipboard::CommitWrite() {
clipboard_->CommitWrite();
}
-void RawSystemClipboard::Trace(Visitor* visitor) {
+void RawSystemClipboard::Trace(Visitor* visitor) const {
visitor->Trace(clipboard_);
}
diff --git a/chromium/third_party/blink/renderer/core/clipboard/raw_system_clipboard.h b/chromium/third_party/blink/renderer/core/clipboard/raw_system_clipboard.h
index d65c89f3c43..61bf9c17322 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/raw_system_clipboard.h
+++ b/chromium/third_party/blink/renderer/core/clipboard/raw_system_clipboard.h
@@ -39,7 +39,7 @@ class CORE_EXPORT RawSystemClipboard final
void Write(const String& type, mojo_base::BigBuffer data);
void CommitWrite();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
HeapMojoRemote<mojom::blink::RawClipboardHost,
diff --git a/chromium/third_party/blink/renderer/core/clipboard/system_clipboard.cc b/chromium/third_party/blink/renderer/core/clipboard/system_clipboard.cc
index cecf0515695..906de118ace 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/system_clipboard.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/system_clipboard.cc
@@ -235,7 +235,7 @@ void SystemClipboard::CommitWrite() {
clipboard_->CommitWrite();
}
-void SystemClipboard::Trace(Visitor* visitor) {
+void SystemClipboard::Trace(Visitor* visitor) const {
visitor->Trace(clipboard_);
}
diff --git a/chromium/third_party/blink/renderer/core/clipboard/system_clipboard.h b/chromium/third_party/blink/renderer/core/clipboard/system_clipboard.h
index dfea6b765f6..5d64cf89ca6 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/system_clipboard.h
+++ b/chromium/third_party/blink/renderer/core/clipboard/system_clipboard.h
@@ -73,13 +73,13 @@ class CORE_EXPORT SystemClipboard final
// the OS clipboard.
void CommitWrite();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
bool IsValidBufferType(mojom::ClipboardBuffer);
HeapMojoRemote<mojom::blink::ClipboardHost,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
clipboard_;
// In X11, |buffer_| may equal ClipboardBuffer::kStandard or kSelection.
// Outside X11, |buffer_| always equals ClipboardBuffer::kStandard.
diff --git a/chromium/third_party/blink/renderer/core/content_capture/content_capture_manager.cc b/chromium/third_party/blink/renderer/core/content_capture/content_capture_manager.cc
index 082500fc4d4..433ec9722f0 100644
--- a/chromium/third_party/blink/renderer/core/content_capture/content_capture_manager.cc
+++ b/chromium/third_party/blink/renderer/core/content_capture/content_capture_manager.cc
@@ -59,7 +59,7 @@ void ContentCaptureManager::OnNodeTextChanged(Node& node) {
ScheduleTask(ContentCaptureTask::ScheduleReason::kContentChange);
}
-void ContentCaptureManager::Trace(Visitor* visitor) {
+void ContentCaptureManager::Trace(Visitor* visitor) const {
visitor->Trace(content_capture_idle_task_);
visitor->Trace(local_frame_root_);
visitor->Trace(task_session_);
diff --git a/chromium/third_party/blink/renderer/core/content_capture/content_capture_manager.h b/chromium/third_party/blink/renderer/core/content_capture/content_capture_manager.h
index c27016600e9..ad0819cb298 100644
--- a/chromium/third_party/blink/renderer/core/content_capture/content_capture_manager.h
+++ b/chromium/third_party/blink/renderer/core/content_capture/content_capture_manager.h
@@ -39,7 +39,7 @@ class CORE_EXPORT ContentCaptureManager
// Invokes when the local_frame_root shutdown.
void Shutdown();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
ContentCaptureTask* GetContentCaptureTaskForTesting() const {
return content_capture_idle_task_;
diff --git a/chromium/third_party/blink/renderer/core/content_capture/content_capture_task.cc b/chromium/third_party/blink/renderer/core/content_capture/content_capture_task.cc
index d637d2edade..1f9778868b6 100644
--- a/chromium/third_party/blink/renderer/core/content_capture/content_capture_task.cc
+++ b/chromium/third_party/blink/renderer/core/content_capture/content_capture_task.cc
@@ -267,7 +267,7 @@ void ContentCaptureTask::CancelTaskForTesting() {
delay_task_->Stop();
}
-void ContentCaptureTask::Trace(Visitor* visitor) {
+void ContentCaptureTask::Trace(Visitor* visitor) const {
visitor->Trace(local_frame_root_);
visitor->Trace(task_session_);
}
diff --git a/chromium/third_party/blink/renderer/core/content_capture/content_capture_task.h b/chromium/third_party/blink/renderer/core/content_capture/content_capture_task.h
index f00e9fb26b3..110fa78db57 100644
--- a/chromium/third_party/blink/renderer/core/content_capture/content_capture_task.h
+++ b/chromium/third_party/blink/renderer/core/content_capture/content_capture_task.h
@@ -68,7 +68,7 @@ class CORE_EXPORT ContentCaptureTask
base::TimeDelta GetTaskNextFireIntervalForTesting() const;
void CancelTaskForTesting();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
protected:
// All protected data and methods are for testing purpose.
diff --git a/chromium/third_party/blink/renderer/core/content_capture/content_capture_test.cc b/chromium/third_party/blink/renderer/core/content_capture/content_capture_test.cc
index 31ad8cd0501..6ab6dd7c2b7 100644
--- a/chromium/third_party/blink/renderer/core/content_capture/content_capture_test.cc
+++ b/chromium/third_party/blink/renderer/core/content_capture/content_capture_test.cc
@@ -128,7 +128,7 @@ class ContentCaptureManagerTestHelper : public ContentCaptureManager {
return content_capture_task_;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(content_capture_task_);
ContentCaptureManager::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/content_capture/sent_nodes.cc b/chromium/third_party/blink/renderer/core/content_capture/sent_nodes.cc
index d183c29ee79..24a6cbdbdd3 100644
--- a/chromium/third_party/blink/renderer/core/content_capture/sent_nodes.cc
+++ b/chromium/third_party/blink/renderer/core/content_capture/sent_nodes.cc
@@ -16,7 +16,7 @@ void SentNodes::OnSent(const Node& node) {
sent_nodes_.insert(WeakMember<const Node>(&node));
}
-void SentNodes::Trace(Visitor* visitor) {
+void SentNodes::Trace(Visitor* visitor) const {
visitor->Trace(sent_nodes_);
}
diff --git a/chromium/third_party/blink/renderer/core/content_capture/sent_nodes.h b/chromium/third_party/blink/renderer/core/content_capture/sent_nodes.h
index 7848cb6fa54..ca7b197b274 100644
--- a/chromium/third_party/blink/renderer/core/content_capture/sent_nodes.h
+++ b/chromium/third_party/blink/renderer/core/content_capture/sent_nodes.h
@@ -20,7 +20,7 @@ class SentNodes final : public GarbageCollected<SentNodes> {
bool HasSent(const Node& node);
void OnSent(const Node& node);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
HeapHashSet<WeakMember<const Node>> sent_nodes_;
diff --git a/chromium/third_party/blink/renderer/core/content_capture/task_session.cc b/chromium/third_party/blink/renderer/core/content_capture/task_session.cc
index c1f9585c76e..b42d04e3927 100644
--- a/chromium/third_party/blink/renderer/core/content_capture/task_session.cc
+++ b/chromium/third_party/blink/renderer/core/content_capture/task_session.cc
@@ -61,7 +61,7 @@ Node* TaskSession::DocumentSession::GetNextChangedNode() {
return nullptr;
}
-void TaskSession::DocumentSession::Trace(Visitor* visitor) {
+void TaskSession::DocumentSession::Trace(Visitor* visitor) const {
visitor->Trace(captured_content_);
visitor->Trace(sent_nodes_);
visitor->Trace(document_);
@@ -145,7 +145,7 @@ TaskSession::DocumentSession* TaskSession::GetDocumentSession(
return it->value;
}
-void TaskSession::Trace(Visitor* visitor) {
+void TaskSession::Trace(Visitor* visitor) const {
visitor->Trace(sent_nodes_);
visitor->Trace(changed_nodes_);
visitor->Trace(to_document_session_);
diff --git a/chromium/third_party/blink/renderer/core/content_capture/task_session.h b/chromium/third_party/blink/renderer/core/content_capture/task_session.h
index abf429fc29a..8580034a77c 100644
--- a/chromium/third_party/blink/renderer/core/content_capture/task_session.h
+++ b/chromium/third_party/blink/renderer/core/content_capture/task_session.h
@@ -79,7 +79,7 @@ class TaskSession final : public GarbageCollected<TaskSession> {
// WebContentCaptureClient for this document.
void Reset();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// The captured content that belongs to this document.
@@ -120,7 +120,7 @@ class TaskSession final : public GarbageCollected<TaskSession> {
callback_ = std::move(call_back);
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void ClearDocumentSessionsForTesting();
diff --git a/chromium/third_party/blink/renderer/core/context_features/context_feature_settings.cc b/chromium/third_party/blink/renderer/core/context_features/context_feature_settings.cc
index c48154d19be..6e06c8a54a9 100644
--- a/chromium/third_party/blink/renderer/core/context_features/context_feature_settings.cc
+++ b/chromium/third_party/blink/renderer/core/context_features/context_feature_settings.cc
@@ -28,7 +28,7 @@ ContextFeatureSettings* ContextFeatureSettings::From(
return settings;
}
-void ContextFeatureSettings::Trace(Visitor* visitor) {
+void ContextFeatureSettings::Trace(Visitor* visitor) const {
Supplement<ExecutionContext>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/context_features/context_feature_settings.h b/chromium/third_party/blink/renderer/core/context_features/context_feature_settings.h
index 174066de6c6..a40ae21c8a6 100644
--- a/chromium/third_party/blink/renderer/core/context_features/context_feature_settings.h
+++ b/chromium/third_party/blink/renderer/core/context_features/context_feature_settings.h
@@ -36,7 +36,7 @@ class CORE_EXPORT ContextFeatureSettings final
void enableMojoJS(bool enable) { enable_mojo_js_ = enable; }
bool isMojoJSEnabled() const { return enable_mojo_js_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool enable_mojo_js_ = false;
diff --git a/chromium/third_party/blink/renderer/core/core.gni b/chromium/third_party/blink/renderer/core/core.gni
index e9c5f45ac04..78304f43965 100644
--- a/chromium/third_party/blink/renderer/core/core.gni
+++ b/chromium/third_party/blink/renderer/core/core.gni
@@ -19,12 +19,11 @@ core_config_add = [
]
core_config_remove = []
-# Compute the optimization level. The GYP code sets "optimize: max" which sets
-# speed-over-size optimization for official builds on Windows only. The GN's
-# build optimize_max config applies this optimization on all platforms, so
-# compute how to modify the config list to duplicate the GYP behavior.
-# TODO revisit this behavior, as the Windows-specific part seems suspicious.
-if (is_win && is_official_build) {
+# Compute the optimization level. `optimize_max` ensures that speed is preferred
+# over size on all platforms.
+# TODO: It's unclear if the perf vs size win here is a good trade-off for
+# Android. Investigate that.
+if (!is_debug && !is_android) {
core_config_remove += [ "//build/config/compiler:default_optimization" ]
core_config_add += [ "//build/config/compiler:optimize_max" ]
}
diff --git a/chromium/third_party/blink/renderer/core/core_idl_files.gni b/chromium/third_party/blink/renderer/core/core_idl_files.gni
index be73ad34204..8c3cfc4dcf7 100644
--- a/chromium/third_party/blink/renderer/core/core_idl_files.gni
+++ b/chromium/third_party/blink/renderer/core/core_idl_files.gni
@@ -63,6 +63,7 @@ core_idl_files =
"css/css_style_declaration.idl",
"css/css_style_rule.idl",
"css/css_style_sheet.idl",
+ "css/css_scroll_timeline_rule.idl",
"css/css_supports_rule.idl",
"css/css_property_rule.idl",
"css/font_face.idl",
@@ -102,7 +103,6 @@ core_idl_files =
"css/cssom/css_variable_reference_value.idl",
"css/cssom/style_property_map.idl",
"css/cssom/style_property_map_read_only.idl",
- "display_lock/render_subtree_activation_event.idl",
"dom/abort_controller.idl",
"dom/abort_signal.idl",
"dom/attr.idl",
diff --git a/chromium/third_party/blink/renderer/core/css/BUILD.gn b/chromium/third_party/blink/renderer/core/css/BUILD.gn
index e65b9bcc1e6..0c1e1cb7bca 100644
--- a/chromium/third_party/blink/renderer/core/css/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/css/BUILD.gn
@@ -79,6 +79,8 @@ blink_core_sources("css") {
"css_grid_template_areas_value.h",
"css_grouping_rule.cc",
"css_grouping_rule.h",
+ "css_id_selector_value.cc",
+ "css_id_selector_value.h",
"css_identifier_value.cc",
"css_identifier_value.h",
"css_image_generator_value.cc",
@@ -91,6 +93,8 @@ blink_core_sources("css") {
"css_import_rule.h",
"css_inherited_value.cc",
"css_inherited_value.h",
+ "css_initial_color_value.cc",
+ "css_initial_color_value.h",
"css_initial_value.cc",
"css_initial_value.h",
"css_invalid_variable_value.cc",
@@ -160,6 +164,8 @@ blink_core_sources("css") {
"css_rule.cc",
"css_rule.h",
"css_rule_list.h",
+ "css_scroll_timeline_rule.cc",
+ "css_scroll_timeline_rule.h",
"css_segmented_font_face.cc",
"css_segmented_font_face.h",
"css_selector.cc",
@@ -411,8 +417,6 @@ blink_core_sources("css") {
"parser/css_parser_token_stream.h",
"parser/css_property_parser.cc",
"parser/css_property_parser.h",
- "parser/css_property_parser_helpers.cc",
- "parser/css_property_parser_helpers.h",
"parser/css_selector_parser.cc",
"parser/css_selector_parser.h",
"parser/css_supports_parser.cc",
@@ -602,6 +606,7 @@ blink_core_tests("unit_tests") {
"css_computed_style_declaration_test.cc",
"css_font_face_source_test.cc",
"css_gradient_value_test.cc",
+ "css_id_selector_value_test.cc",
"css_invalid_variable_value_test.cc",
"css_light_dark_value_pair_test.cc",
"css_math_expression_node_test.cc",
@@ -631,6 +636,7 @@ blink_core_tests("unit_tests") {
"cssom/style_property_map_test.cc",
"drag_update_test.cc",
"font_face_cache_test.cc",
+ "font_size_functions_test.cc",
"font_update_invalidation_test.cc",
"invalidation/invalidation_set_test.cc",
"invalidation/pending_invalidations_test.cc",
@@ -644,10 +650,10 @@ blink_core_tests("unit_tests") {
"media_values_test.cc",
"parser/css_lazy_parsing_test.cc",
"parser/css_parser_fast_paths_test.cc",
+ "parser/css_parser_impl_test.cc",
"parser/css_parser_local_context_test.cc",
"parser/css_parser_token_stream_test.cc",
"parser/css_parser_token_test.cc",
- "parser/css_property_parser_helpers_test.cc",
"parser/css_property_parser_test.cc",
"parser/css_selector_parser_test.cc",
"parser/css_supports_parser_test.cc",
@@ -678,6 +684,7 @@ blink_core_tests("unit_tests") {
"resolver/style_adjuster_test.cc",
"resolver/style_builder_test.cc",
"resolver/style_cascade_test.cc",
+ "resolver/style_resolver_state_test.cc",
"resolver/style_resolver_test.cc",
"rule_feature_set_test.cc",
"rule_set_test.cc",
diff --git a/chromium/third_party/blink/renderer/core/css/README.md b/chromium/third_party/blink/renderer/core/css/README.md
index c7d5356fc27..710c518cc6f 100644
--- a/chromium/third_party/blink/renderer/core/css/README.md
+++ b/chromium/third_party/blink/renderer/core/css/README.md
@@ -1,6 +1,6 @@
# CSS
-[Rendered](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/core/css/README.md)
+[Rendered](https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/renderer/core/css/README.md)
The `Source/core/css` directory contains the implementation of CSS.
diff --git a/chromium/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc b/chromium/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc
index 99fcc338130..e6c62983cff 100644
--- a/chromium/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc
+++ b/chromium/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc
@@ -55,12 +55,9 @@ void AbstractPropertySetCSSStyleDeclaration::setCSSText(
StyleAttributeMutationScope mutation_scope(this);
WillMutate();
- // A null execution_context may be passed in by the inspector, this shouldn't
- // occur normally.
const SecureContextMode mode = execution_context
? execution_context->GetSecureContextMode()
: SecureContextMode::kInsecureContext;
-
PropertySet().ParseDeclarationList(text, mode, ContextStyleSheet());
DidMutate(kPropertyChanged);
@@ -135,8 +132,10 @@ void AbstractPropertySetCSSStyleDeclaration::setProperty(
if (!important && !priority.IsEmpty())
return;
- SetPropertyInternal(property_id, property_name, value, important,
- execution_context->GetSecureContextMode(),
+ const SecureContextMode mode = execution_context
+ ? execution_context->GetSecureContextMode()
+ : SecureContextMode::kInsecureContext;
+ SetPropertyInternal(property_id, property_name, value, important, mode,
exception_state);
}
@@ -235,7 +234,7 @@ bool AbstractPropertySetCSSStyleDeclaration::CssPropertyMatches(
return PropertySet().PropertyMatches(property_id, property_value);
}
-void AbstractPropertySetCSSStyleDeclaration::Trace(Visitor* visitor) {
+void AbstractPropertySetCSSStyleDeclaration::Trace(Visitor* visitor) const {
CSSStyleDeclaration::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.h b/chromium/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.h
index 2d4ce8c5cc4..204e28c6be1 100644
--- a/chromium/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.h
+++ b/chromium/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.h
@@ -45,7 +45,7 @@ class AbstractPropertySetCSSStyleDeclaration : public CSSStyleDeclaration {
AbstractPropertySetCSSStyleDeclaration(ExecutionContext* context)
: CSSStyleDeclaration(context) {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
CSSRule* parentRule() const override { return nullptr; }
diff --git a/chromium/third_party/blink/renderer/core/css/active_style_sheets_test.cc b/chromium/third_party/blink/renderer/core/css/active_style_sheets_test.cc
index 9e5fa7c52ac..1874775efd3 100644
--- a/chromium/third_party/blink/renderer/core/css/active_style_sheets_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/active_style_sheets_test.cc
@@ -24,12 +24,12 @@ namespace blink {
class ActiveStyleSheetsTest : public PageTestBase {
protected:
- static CSSStyleSheet* CreateSheet(const String& css_text = String()) {
+ CSSStyleSheet* CreateSheet(const String& css_text = String()) {
auto* contents = MakeGarbageCollected<StyleSheetContents>(
MakeGarbageCollected<CSSParserContext>(
kHTMLStandardMode, SecureContextMode::kInsecureContext));
contents->ParseString(css_text);
- contents->EnsureRuleSet(MediaQueryEvaluator(),
+ contents->EnsureRuleSet(MediaQueryEvaluator(GetDocument().GetFrame()),
kRuleHasDocumentSecurityOrigin);
return MakeGarbageCollected<CSSStyleSheet>(contents);
}
@@ -123,8 +123,9 @@ TEST_F(ActiveStyleSheetsTest, CompareActiveStyleSheets_Mutated) {
std::make_pair(sheet3, &sheet3->Contents()->GetRuleSet()));
sheet2->Contents()->ClearRuleSet();
- sheet2->Contents()->EnsureRuleSet(MediaQueryEvaluator(),
- kRuleHasDocumentSecurityOrigin);
+ sheet2->Contents()->EnsureRuleSet(
+ MediaQueryEvaluator(GetDocument().GetFrame()),
+ kRuleHasDocumentSecurityOrigin);
EXPECT_NE(old_sheets[1].second, &sheet2->Contents()->GetRuleSet());
@@ -404,7 +405,7 @@ TEST_F(ActiveStyleSheetsTest, CompareActiveStyleSheets_AddRemoveNonMatchingMQ) {
scoped_refptr<MediaQuerySet> mq =
MediaQueryParser::ParseMediaQuerySet("(min-width: 9000px)", nullptr);
sheet1->SetMediaQueries(mq);
- sheet1->MatchesMediaQueries(MediaQueryEvaluator());
+ sheet1->MatchesMediaQueries(MediaQueryEvaluator(GetDocument().GetFrame()));
new_sheets.push_back(std::make_pair(sheet1, nullptr));
diff --git a/chromium/third_party/blink/renderer/core/css/css_computed_style_declaration.cc b/chromium/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
index e7f3444a197..a0f7d35c3bc 100644
--- a/chromium/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
@@ -61,12 +61,12 @@ const CSSPropertyID kComputedPropertyArray[] = {
CSSPropertyID::kAnimationDelay, CSSPropertyID::kAnimationDirection,
CSSPropertyID::kAnimationDuration, CSSPropertyID::kAnimationFillMode,
CSSPropertyID::kAnimationIterationCount, CSSPropertyID::kAnimationName,
- CSSPropertyID::kAnimationPlayState, CSSPropertyID::kAnimationTimingFunction,
- CSSPropertyID::kAppearance, CSSPropertyID::kBackdropFilter,
- CSSPropertyID::kBackfaceVisibility, CSSPropertyID::kBackgroundAttachment,
- CSSPropertyID::kBackgroundBlendMode, CSSPropertyID::kBackgroundClip,
- CSSPropertyID::kBackgroundColor, CSSPropertyID::kBackgroundImage,
- CSSPropertyID::kBackgroundOrigin,
+ CSSPropertyID::kAnimationPlayState, CSSPropertyID::kAnimationTimeline,
+ CSSPropertyID::kAnimationTimingFunction, CSSPropertyID::kAppearance,
+ CSSPropertyID::kBackdropFilter, CSSPropertyID::kBackfaceVisibility,
+ CSSPropertyID::kBackgroundAttachment, CSSPropertyID::kBackgroundBlendMode,
+ CSSPropertyID::kBackgroundClip, CSSPropertyID::kBackgroundColor,
+ CSSPropertyID::kBackgroundImage, CSSPropertyID::kBackgroundOrigin,
// more-specific background-position-x/y are non-standard
CSSPropertyID::kBackgroundPosition, CSSPropertyID::kBackgroundRepeat,
CSSPropertyID::kBackgroundSize, CSSPropertyID::kBaselineShift,
@@ -138,7 +138,6 @@ const CSSPropertyID kComputedPropertyArray[] = {
CSSPropertyID::kMarginLeft, CSSPropertyID::kMarginRight,
CSSPropertyID::kMarginTop, CSSPropertyID::kMarkerEnd,
CSSPropertyID::kMarkerMid, CSSPropertyID::kMarkerStart,
- CSSPropertyID::kMask, CSSPropertyID::kMaskSourceType,
CSSPropertyID::kMaskType, CSSPropertyID::kMathStyle,
CSSPropertyID::kMathSuperscriptShiftStyle, CSSPropertyID::kMaxBlockSize,
CSSPropertyID::kMaxHeight, CSSPropertyID::kMaxInlineSize,
@@ -173,7 +172,7 @@ const CSSPropertyID kComputedPropertyArray[] = {
CSSPropertyID::kScrollPaddingBlockEnd,
CSSPropertyID::kScrollPaddingBlockStart,
CSSPropertyID::kScrollPaddingInlineEnd,
- CSSPropertyID::kScrollPaddingInlineStart,
+ CSSPropertyID::kScrollPaddingInlineStart, CSSPropertyID::kScrollbarGutter,
CSSPropertyID::kShapeImageThreshold, CSSPropertyID::kShapeMargin,
CSSPropertyID::kShapeOutside, CSSPropertyID::kShapeRendering,
CSSPropertyID::kSpeak, CSSPropertyID::kStopColor,
@@ -273,7 +272,7 @@ CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(
: CSSStyleDeclaration(n ? n->GetExecutionContext() : nullptr),
node_(n),
pseudo_element_specifier_(
- CSSSelector::ParsePseudoId(pseudo_element_name)),
+ CSSSelector::ParsePseudoId(pseudo_element_name, n)),
allow_visited_style_(allow_visited_style) {}
CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration() = default;
@@ -620,7 +619,7 @@ void CSSComputedStyleDeclaration::SetPropertyInternal(
"' property is read-only.");
}
-void CSSComputedStyleDeclaration::Trace(Visitor* visitor) {
+void CSSComputedStyleDeclaration::Trace(Visitor* visitor) const {
visitor->Trace(node_);
CSSStyleDeclaration::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_computed_style_declaration.h b/chromium/third_party/blink/renderer/core/css/css_computed_style_declaration.h
index e0a5730871c..d6746059bbc 100644
--- a/chromium/third_party/blink/renderer/core/css/css_computed_style_declaration.h
+++ b/chromium/third_party/blink/renderer/core/css/css_computed_style_declaration.h
@@ -71,7 +71,7 @@ class CORE_EXPORT CSSComputedStyleDeclaration final
unsigned length() const override;
String item(unsigned index) const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// The styled node is either the node passed into getComputedStyle, or the
diff --git a/chromium/third_party/blink/renderer/core/css/css_crossfade_value.h b/chromium/third_party/blink/renderer/core/css/css_crossfade_value.h
index 35bc6bb011d..1d100f5d3af 100644
--- a/chromium/third_party/blink/renderer/core/css/css_crossfade_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_crossfade_value.h
@@ -84,7 +84,7 @@ class CORE_EXPORT CSSCrossfadeValue final : public CSSImageGeneratorValue {
: owner_value_(owner_value), ready_(false) {}
~CrossfadeSubimageObserverProxy() override = default;
- void Trace(Visitor* visitor) { visitor->Trace(owner_value_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(owner_value_); }
void ImageChanged(ImageResourceContent*, CanDeferInvalidation) override;
bool WillRenderImage() override;
diff --git a/chromium/third_party/blink/renderer/core/css/css_default_style_sheets.cc b/chromium/third_party/blink/renderer/core/css/css_default_style_sheets.cc
index 749dcb3ffb6..285d47e683c 100644
--- a/chromium/third_party/blink/renderer/core/css/css_default_style_sheets.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_default_style_sheets.cc
@@ -67,9 +67,11 @@ static const MediaQueryEvaluator& PrintEval() {
}
static const MediaQueryEvaluator& ForcedColorsEval() {
+ // We use "ua-forced-colors" here instead of "forced-colors" to indicate that
+ // this is a UA hack for the "forced-colors" media query.
DEFINE_STATIC_LOCAL(
Persistent<MediaQueryEvaluator>, forced_colors_eval,
- (MakeGarbageCollected<MediaQueryEvaluator>("forced-colors")));
+ (MakeGarbageCollected<MediaQueryEvaluator>("ua-forced-colors")));
return *forced_colors_eval;
}
@@ -133,6 +135,7 @@ void CSSDefaultStyleSheets::PrepareForLeakDetection() {
text_track_style_sheet_.Clear();
fullscreen_style_sheet_.Clear();
webxr_overlay_style_sheet_.Clear();
+ marker_style_sheet_.Clear();
// Recreate the default style sheet to clean up possible SVG resources.
String default_rules = UncompressResourceAsASCIIString(IDR_UASTYLE_HTML_CSS) +
LayoutTheme::GetTheme().ExtraDefaultStyleSheet();
@@ -151,6 +154,7 @@ void CSSDefaultStyleSheets::InitializeDefaultStyles() {
default_quirks_style_ = MakeGarbageCollected<RuleSet>();
default_print_style_ = MakeGarbageCollected<RuleSet>();
default_forced_color_style_ = MakeGarbageCollected<RuleSet>();
+ default_pseudo_element_style_.Clear();
default_style_->AddRulesFromSheet(DefaultStyleSheet(), ScreenEval());
default_quirks_style_->AddRulesFromSheet(QuirksStyleSheet(), ScreenEval());
@@ -284,6 +288,25 @@ bool CSSDefaultStyleSheets::EnsureDefaultStyleSheetsForElement(
return changed_default_style;
}
+bool CSSDefaultStyleSheets::EnsureDefaultStyleSheetsForPseudoElement(
+ PseudoId pseudo_id) {
+ switch (pseudo_id) {
+ case kPseudoIdMarker: {
+ if (marker_style_sheet_)
+ return false;
+ marker_style_sheet_ =
+ ParseUASheet(UncompressResourceAsASCIIString(IDR_UASTYLE_MARKER_CSS));
+ if (!default_pseudo_element_style_)
+ default_pseudo_element_style_ = MakeGarbageCollected<RuleSet>();
+ default_pseudo_element_style_->AddRulesFromSheet(MarkerStyleSheet(),
+ ScreenEval());
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
void CSSDefaultStyleSheets::SetMediaControlsStyleSheetLoader(
std::unique_ptr<UAStyleSheetLoader> loader) {
media_controls_style_sheet_loader_.swap(loader);
@@ -316,7 +339,7 @@ void CSSDefaultStyleSheets::EnsureDefaultStyleSheetForFullscreen() {
ScreenEval());
}
-void CSSDefaultStyleSheets::Trace(Visitor* visitor) {
+void CSSDefaultStyleSheets::Trace(Visitor* visitor) const {
visitor->Trace(default_style_);
visitor->Trace(default_mathml_style_);
visitor->Trace(default_svg_style_);
@@ -325,6 +348,7 @@ void CSSDefaultStyleSheets::Trace(Visitor* visitor) {
visitor->Trace(default_view_source_style_);
visitor->Trace(default_forced_color_style_);
visitor->Trace(default_style_sheet_);
+ visitor->Trace(default_pseudo_element_style_);
visitor->Trace(mobile_viewport_style_sheet_);
visitor->Trace(television_viewport_style_sheet_);
visitor->Trace(xhtml_mobile_profile_style_sheet_);
@@ -335,6 +359,7 @@ void CSSDefaultStyleSheets::Trace(Visitor* visitor) {
visitor->Trace(text_track_style_sheet_);
visitor->Trace(fullscreen_style_sheet_);
visitor->Trace(webxr_overlay_style_sheet_);
+ visitor->Trace(marker_style_sheet_);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/css_default_style_sheets.h b/chromium/third_party/blink/renderer/core/css/css_default_style_sheets.h
index 56040ac93c6..67596f00392 100644
--- a/chromium/third_party/blink/renderer/core/css/css_default_style_sheets.h
+++ b/chromium/third_party/blink/renderer/core/css/css_default_style_sheets.h
@@ -26,6 +26,7 @@
#include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/style/computed_style_constants.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -44,6 +45,7 @@ class CSSDefaultStyleSheets final
CSSDefaultStyleSheets();
bool EnsureDefaultStyleSheetsForElement(const Element&);
+ bool EnsureDefaultStyleSheetsForPseudoElement(PseudoId);
bool EnsureDefaultStyleSheetForXrOverlay();
void EnsureDefaultStyleSheetForFullscreen();
@@ -56,6 +58,9 @@ class CSSDefaultStyleSheets final
RuleSet* DefaultForcedColorStyle() {
return default_forced_color_style_.Get();
}
+ RuleSet* DefaultPseudoElementStyleOrNull() {
+ return default_pseudo_element_style_.Get();
+ }
StyleSheetContents* EnsureMobileViewportStyleSheet();
StyleSheetContents* EnsureTelevisionViewportStyleSheet();
@@ -71,6 +76,7 @@ class CSSDefaultStyleSheets final
StyleSheetContents* FullscreenStyleSheet() {
return fullscreen_style_sheet_.Get();
}
+ StyleSheetContents* MarkerStyleSheet() { return marker_style_sheet_.Get(); }
CORE_EXPORT void PrepareForLeakDetection();
@@ -90,7 +96,7 @@ class CSSDefaultStyleSheets final
return media_controls_style_sheet_loader_.get();
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void InitializeDefaultStyles();
@@ -102,6 +108,7 @@ class CSSDefaultStyleSheets final
Member<RuleSet> default_print_style_;
Member<RuleSet> default_view_source_style_;
Member<RuleSet> default_forced_color_style_;
+ Member<RuleSet> default_pseudo_element_style_;
Member<StyleSheetContents> default_style_sheet_;
Member<StyleSheetContents> mobile_viewport_style_sheet_;
@@ -114,6 +121,7 @@ class CSSDefaultStyleSheets final
Member<StyleSheetContents> text_track_style_sheet_;
Member<StyleSheetContents> fullscreen_style_sheet_;
Member<StyleSheetContents> webxr_overlay_style_sheet_;
+ Member<StyleSheetContents> marker_style_sheet_;
std::unique_ptr<UAStyleSheetLoader> media_controls_style_sheet_loader_;
DISALLOW_COPY_AND_ASSIGN(CSSDefaultStyleSheets);
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_face.cc b/chromium/third_party/blink/renderer/core/css/css_font_face.cc
index 8002ecb47d2..ed9b5a5d7ac 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_face.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_font_face.cc
@@ -239,7 +239,7 @@ bool CSSFontFace::UpdatePeriod() {
return changed;
}
-void CSSFontFace::Trace(Visitor* visitor) {
+void CSSFontFace::Trace(Visitor* visitor) const {
visitor->Trace(segmented_font_faces_);
visitor->Trace(sources_);
visitor->Trace(font_face_);
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_face.h b/chromium/third_party/blink/renderer/core/css/css_font_face.h
index 7727f1f7f98..90c2b68f1bb 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_face.h
+++ b/chromium/third_party/blink/renderer/core/css/css_font_face.h
@@ -87,7 +87,7 @@ class CORE_EXPORT CSSFontFace final : public GarbageCollected<CSSFontFace> {
bool HadBlankText() { return IsValid() && sources_.front()->HadBlankText(); }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void SetLoadStatus(FontFace::LoadStatusType);
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_face_rule.cc b/chromium/third_party/blink/renderer/core/css/css_font_face_rule.cc
index 5e01733b0ba..62dbd683c7c 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_face_rule.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_font_face_rule.cc
@@ -62,7 +62,7 @@ void CSSFontFaceRule::Reattach(StyleRuleBase* rule) {
properties_cssom_wrapper_->Reattach(font_face_rule_->MutableProperties());
}
-void CSSFontFaceRule::Trace(Visitor* visitor) {
+void CSSFontFaceRule::Trace(Visitor* visitor) const {
visitor->Trace(font_face_rule_);
visitor->Trace(properties_cssom_wrapper_);
CSSRule::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_face_rule.h b/chromium/third_party/blink/renderer/core/css/css_font_face_rule.h
index 6db949a54f4..e1b0ec015af 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_face_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/css_font_face_rule.h
@@ -46,10 +46,10 @@ class CSSFontFaceRule final : public CSSRule {
StyleRuleFontFace* StyleRule() const { return font_face_rule_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
- CSSRule::Type type() const override { return kFontFaceRule; }
+ CSSRule::Type GetType() const override { return kFontFaceRule; }
Member<StyleRuleFontFace> font_face_rule_;
mutable Member<StyleRuleCSSStyleDeclaration> properties_cssom_wrapper_;
@@ -58,7 +58,7 @@ class CSSFontFaceRule final : public CSSRule {
template <>
struct DowncastTraits<CSSFontFaceRule> {
static bool AllowFrom(const CSSRule& rule) {
- return rule.type() == CSSRule::kFontFaceRule;
+ return rule.GetType() == CSSRule::kFontFaceRule;
}
};
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_face_source.h b/chromium/third_party/blink/renderer/core/css/css_font_face_source.h
index 9ae4aa78d58..c3cc2a3fb71 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_face_source.h
+++ b/chromium/third_party/blink/renderer/core/css/css_font_face_source.h
@@ -78,7 +78,7 @@ class CORE_EXPORT CSSFontFaceSource
virtual bool HadBlankText() { return false; }
virtual void PaintRequested() {}
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
CSSFontFaceSource() = default;
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_face_src_value.h b/chromium/third_party/blink/renderer/core/css/css_font_face_src_value.h
index 00e9e461eef..276eda16b5f 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_face_src_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_font_face_src_value.h
@@ -122,7 +122,7 @@ class CORE_EXPORT CSSFontFaceSrcValue : public CSSValue {
SetResource(resource, task_runner);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
FontResourceClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_selector.cc b/chromium/third_party/blink/renderer/core/css/css_font_selector.cc
index fb466e3a2a3..5d36f4db6ed 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_selector.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_font_selector.cc
@@ -183,7 +183,7 @@ void CSSFontSelector::ReportFailedLocalFontMatch(
document_->GetFontMatchingMetrics()->ReportFailedLocalFontMatch(font_name);
}
-void CSSFontSelector::Trace(Visitor* visitor) {
+void CSSFontSelector::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(font_face_cache_);
visitor->Trace(clients_);
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_selector.h b/chromium/third_party/blink/renderer/core/css/css_font_selector.h
index fb07ea47607..259d794ab22 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_selector.h
+++ b/chromium/third_party/blink/renderer/core/css/css_font_selector.h
@@ -88,7 +88,7 @@ class CORE_EXPORT CSSFontSelector : public FontSelector {
}
void UpdateGenericFontFamilySettings(Document&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
void DispatchInvalidationCallbacks(FontInvalidationReason);
diff --git a/chromium/third_party/blink/renderer/core/css/css_global_rule_set.cc b/chromium/third_party/blink/renderer/core/css/css_global_rule_set.cc
index 6d2707464c7..0c3c15ed944 100644
--- a/chromium/third_party/blink/renderer/core/css/css_global_rule_set.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_global_rule_set.cc
@@ -60,7 +60,7 @@ void CSSGlobalRuleSet::Dispose() {
is_dirty_ = true;
}
-void CSSGlobalRuleSet::Trace(Visitor* visitor) {
+void CSSGlobalRuleSet::Trace(Visitor* visitor) const {
visitor->Trace(watched_selectors_rule_set_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_global_rule_set.h b/chromium/third_party/blink/renderer/core/css/css_global_rule_set.h
index db894a07540..c3826315d45 100644
--- a/chromium/third_party/blink/renderer/core/css/css_global_rule_set.h
+++ b/chromium/third_party/blink/renderer/core/css/css_global_rule_set.h
@@ -41,7 +41,7 @@ class CSSGlobalRuleSet final : public GarbageCollected<CSSGlobalRuleSet> {
}
bool HasFullscreenUAStyle() const { return has_fullscreen_ua_style_; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// Constructed from rules in all TreeScopes including UA style and style
diff --git a/chromium/third_party/blink/renderer/core/css/css_gradient_value.cc b/chromium/third_party/blink/renderer/core/css/css_gradient_value.cc
index 14af20c6624..b88b8b9b3f3 100644
--- a/chromium/third_party/blink/renderer/core/css/css_gradient_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_gradient_value.cc
@@ -108,7 +108,7 @@ bool CSSGradientColorStop::IsCacheable() const {
!To<CSSNumericLiteralValue>(*offset_).IsFontRelativeLength();
}
-void CSSGradientColorStop::Trace(Visitor* visitor) {
+void CSSGradientColorStop::Trace(Visitor* visitor) const {
visitor->Trace(offset_);
visitor->Trace(color_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_gradient_value.h b/chromium/third_party/blink/renderer/core/css/css_gradient_value.h
index 54f88df9102..eaae4a673f8 100644
--- a/chromium/third_party/blink/renderer/core/css/css_gradient_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_gradient_value.h
@@ -74,7 +74,7 @@ struct CSSGradientColorStop {
bool IsCacheable() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
Member<const CSSPrimitiveValue> offset_; // percentage | length | angle
Member<const CSSValue> color_;
diff --git a/chromium/third_party/blink/renderer/core/css/css_grouping_rule.cc b/chromium/third_party/blink/renderer/core/css/css_grouping_rule.cc
index 34a76e9d048..06bd226971e 100644
--- a/chromium/third_party/blink/renderer/core/css/css_grouping_rule.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_grouping_rule.cc
@@ -166,7 +166,7 @@ void CSSGroupingRule::Reattach(StyleRuleBase* rule) {
}
}
-void CSSGroupingRule::Trace(Visitor* visitor) {
+void CSSGroupingRule::Trace(Visitor* visitor) const {
CSSRule::Trace(visitor);
visitor->Trace(child_rule_cssom_wrappers_);
visitor->Trace(group_rule_);
diff --git a/chromium/third_party/blink/renderer/core/css/css_grouping_rule.h b/chromium/third_party/blink/renderer/core/css/css_grouping_rule.h
index a23859069c8..d8b7dc46788 100644
--- a/chromium/third_party/blink/renderer/core/css/css_grouping_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/css_grouping_rule.h
@@ -52,7 +52,7 @@ class CSSGroupingRule : public CSSRule {
unsigned length() const;
CSSRule* Item(unsigned index) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
CSSGroupingRule(StyleRuleGroup* group_rule, CSSStyleSheet* parent);
diff --git a/chromium/third_party/blink/renderer/core/css/css_id_selector_value.cc b/chromium/third_party/blink/renderer/core/css/css_id_selector_value.cc
new file mode 100644
index 00000000000..24c5c73623a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/css_id_selector_value.cc
@@ -0,0 +1,29 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/css/css_id_selector_value.h"
+
+#include "third_party/blink/renderer/core/css/css_markup.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+namespace cssvalue {
+
+CSSIdSelectorValue::CSSIdSelectorValue(const String& id)
+ : CSSValue(kIdSelectorClass), id_(id) {}
+
+String CSSIdSelectorValue::CustomCSSText() const {
+ StringBuilder builder;
+ builder.Append('#');
+ SerializeIdentifier(id_, builder);
+ return builder.ToString();
+}
+
+void CSSIdSelectorValue::TraceAfterDispatch(blink::Visitor* visitor) const {
+ CSSValue::TraceAfterDispatch(visitor);
+}
+
+} // namespace cssvalue
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/css_id_selector_value.h b/chromium/third_party/blink/renderer/core/css/css_id_selector_value.h
new file mode 100644
index 00000000000..cb9db1ab1ac
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/css_id_selector_value.h
@@ -0,0 +1,44 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_ID_SELECTOR_VALUE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_ID_SELECTOR_VALUE_H_
+
+#include "third_party/blink/renderer/core/css/css_value.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+namespace cssvalue {
+
+class CORE_EXPORT CSSIdSelectorValue : public CSSValue {
+ public:
+ explicit CSSIdSelectorValue(const String&);
+
+ const AtomicString& Id() const { return id_; }
+
+ String CustomCSSText() const;
+
+ bool Equals(const CSSIdSelectorValue& other) const {
+ return id_ == other.id_;
+ }
+
+ void TraceAfterDispatch(blink::Visitor*) const;
+
+ private:
+ AtomicString id_;
+};
+
+} // namespace cssvalue
+
+template <>
+struct DowncastTraits<cssvalue::CSSIdSelectorValue> {
+ static bool AllowFrom(const CSSValue& value) {
+ return value.IsIdSelectorValue();
+ }
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_ID_SELECTOR_VALUE_H_
diff --git a/chromium/third_party/blink/renderer/core/css/css_id_selector_value_test.cc b/chromium/third_party/blink/renderer/core/css/css_id_selector_value_test.cc
new file mode 100644
index 00000000000..c4e23d8d702
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/css_id_selector_value_test.cc
@@ -0,0 +1,36 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/css/css_id_selector_value.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+using CSSIdSelectorValue = cssvalue::CSSIdSelectorValue;
+
+TEST(CSSIdSelectorValueTest, Id) {
+ EXPECT_EQ("test", MakeGarbageCollected<CSSIdSelectorValue>("test")->Id());
+}
+
+TEST(CSSIdSelectorValueTest, Equals) {
+ EXPECT_EQ(*MakeGarbageCollected<CSSIdSelectorValue>("foo"),
+ *MakeGarbageCollected<CSSIdSelectorValue>("foo"));
+ EXPECT_NE(*MakeGarbageCollected<CSSIdSelectorValue>("foo"),
+ *MakeGarbageCollected<CSSIdSelectorValue>("bar"));
+ EXPECT_NE(*MakeGarbageCollected<CSSIdSelectorValue>("bar"),
+ *MakeGarbageCollected<CSSIdSelectorValue>("foo"));
+}
+
+TEST(CSSIdSelectorValueTest, CustomCSSText) {
+ EXPECT_EQ("#foo",
+ MakeGarbageCollected<CSSIdSelectorValue>("foo")->CustomCSSText());
+ // The identifier part must follow the serialization rules of:
+ // https://drafts.csswg.org/cssom/#serialize-an-identifier
+ EXPECT_EQ("#\\31 23",
+ MakeGarbageCollected<CSSIdSelectorValue>("123")->CustomCSSText());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/css_identifier_value.cc b/chromium/third_party/blink/renderer/core/css/css_identifier_value.cc
index 0498875affd..b1a26003f2d 100644
--- a/chromium/third_party/blink/renderer/core/css/css_identifier_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_identifier_value.cc
@@ -57,6 +57,7 @@ CSSIdentifierValue::CSSIdentifierValue(const Length& length)
case Length::kCalculated:
case Length::kDeviceWidth:
case Length::kDeviceHeight:
+ case Length::kMinIntrinsic:
case Length::kNone:
NOTREACHED();
break;
diff --git a/chromium/third_party/blink/renderer/core/css/css_image_set_value.cc b/chromium/third_party/blink/renderer/core/css/css_image_set_value.cc
index 3cc48f2f6b9..67f27c33f42 100644
--- a/chromium/third_party/blink/renderer/core/css/css_image_set_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_image_set_value.cc
@@ -178,8 +178,8 @@ String CSSImageSetValue::CustomCSSText() const {
bool CSSImageSetValue::HasFailedOrCanceledSubresources() const {
if (!cached_image_)
return false;
- if (ImageResourceContent* cached_resource = cached_image_->CachedImage())
- return cached_resource->LoadFailedOrCanceled();
+ if (ImageResourceContent* cached_content = cached_image_->CachedImage())
+ return cached_content->LoadFailedOrCanceled();
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_image_value.cc b/chromium/third_party/blink/renderer/core/css/css_image_value.cc
index 018ad1720cb..135da54563b 100644
--- a/chromium/third_party/blink/renderer/core/css/css_image_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_image_value.cc
@@ -114,11 +114,11 @@ void CSSImageValue::RestoreCachedResourceIfNeeded(
if (!cached_image_ || !document.Fetcher() || absolute_url_.IsNull())
return;
- ImageResourceContent* resource = cached_image_->CachedImage();
- if (!resource)
+ ImageResourceContent* cached_content = cached_image_->CachedImage();
+ if (!cached_content)
return;
- resource->EmulateLoadStartedForInspector(
+ cached_content->EmulateLoadStartedForInspector(
document.Fetcher(), KURL(absolute_url_),
initiator_name_.IsEmpty() ? fetch_initiator_type_names::kCSS
: initiator_name_);
@@ -127,8 +127,8 @@ void CSSImageValue::RestoreCachedResourceIfNeeded(
bool CSSImageValue::HasFailedOrCanceledSubresources() const {
if (!cached_image_)
return false;
- if (ImageResourceContent* cached_resource = cached_image_->CachedImage())
- return cached_resource->LoadFailedOrCanceled();
+ if (ImageResourceContent* cached_content = cached_image_->CachedImage())
+ return cached_content->LoadFailedOrCanceled();
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_import_rule.cc b/chromium/third_party/blink/renderer/core/css/css_import_rule.cc
index 685275588ec..dc3cea35de9 100644
--- a/chromium/third_party/blink/renderer/core/css/css_import_rule.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_import_rule.cc
@@ -84,7 +84,7 @@ void CSSImportRule::Reattach(StyleRuleBase*) {
NOTREACHED();
}
-void CSSImportRule::Trace(Visitor* visitor) {
+void CSSImportRule::Trace(Visitor* visitor) const {
visitor->Trace(import_rule_);
visitor->Trace(media_cssom_wrapper_);
visitor->Trace(style_sheet_cssom_wrapper_);
diff --git a/chromium/third_party/blink/renderer/core/css/css_import_rule.h b/chromium/third_party/blink/renderer/core/css/css_import_rule.h
index 9ea04d4d3d7..3755ec0fcf8 100644
--- a/chromium/third_party/blink/renderer/core/css/css_import_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/css_import_rule.h
@@ -45,10 +45,10 @@ class CSSImportRule final : public CSSRule {
MediaList* media() const;
CSSStyleSheet* styleSheet() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
- CSSRule::Type type() const override { return kImportRule; }
+ CSSRule::Type GetType() const override { return kImportRule; }
Member<StyleRuleImport> import_rule_;
mutable Member<MediaList> media_cssom_wrapper_;
@@ -58,7 +58,7 @@ class CSSImportRule final : public CSSRule {
template <>
struct DowncastTraits<CSSImportRule> {
static bool AllowFrom(const CSSRule& rule) {
- return rule.type() == CSSRule::kImportRule;
+ return rule.GetType() == CSSRule::kImportRule;
}
};
diff --git a/chromium/third_party/blink/renderer/core/css/css_initial_color_value.cc b/chromium/third_party/blink/renderer/core/css/css_initial_color_value.cc
new file mode 100644
index 00000000000..0771aed3b3b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/css_initial_color_value.cc
@@ -0,0 +1,20 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/css/css_initial_color_value.h"
+
+#include "third_party/blink/renderer/core/css/css_value_pool.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+CSSInitialColorValue* CSSInitialColorValue::Create() {
+ return CssValuePool().InitialColorValue();
+}
+
+String CSSInitialColorValue::CustomCSSText() const {
+ return "";
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/css_initial_color_value.h b/chromium/third_party/blink/renderer/core/css/css_initial_color_value.h
new file mode 100644
index 00000000000..e7ac1b064be
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/css_initial_color_value.h
@@ -0,0 +1,46 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_INITIAL_COLOR_VALUE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_INITIAL_COLOR_VALUE_H_
+
+#include "base/util/type_safety/pass_key.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/css/css_value.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
+
+namespace blink {
+
+class CSSValuePool;
+
+// TODO(crbug.com/1046753): Remove this class when canvastext is supported.
+class CORE_EXPORT CSSInitialColorValue : public CSSValue {
+ public:
+ static CSSInitialColorValue* Create();
+
+ explicit CSSInitialColorValue(util::PassKey<CSSValuePool>)
+ : CSSValue(kInitialColorValueClass) {}
+
+ String CustomCSSText() const;
+
+ bool Equals(const CSSInitialColorValue&) const { return true; }
+
+ void TraceAfterDispatch(blink::Visitor* visitor) const {
+ CSSValue::TraceAfterDispatch(visitor);
+ }
+
+ private:
+ friend class CSSValuePool;
+};
+
+template <>
+struct DowncastTraits<CSSInitialColorValue> {
+ static bool AllowFrom(const CSSValue& value) {
+ return value.IsInitialColorValue();
+ }
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_INITIAL_COLOR_VALUE_H_
diff --git a/chromium/third_party/blink/renderer/core/css/css_keyframe_rule.cc b/chromium/third_party/blink/renderer/core/css/css_keyframe_rule.cc
index 0887f7a2d14..51e48f4ca6e 100644
--- a/chromium/third_party/blink/renderer/core/css/css_keyframe_rule.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_keyframe_rule.cc
@@ -69,7 +69,7 @@ void CSSKeyframeRule::Reattach(StyleRuleBase*) {
NOTREACHED();
}
-void CSSKeyframeRule::Trace(Visitor* visitor) {
+void CSSKeyframeRule::Trace(Visitor* visitor) const {
visitor->Trace(keyframe_);
visitor->Trace(properties_cssom_wrapper_);
CSSRule::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/css_keyframe_rule.h b/chromium/third_party/blink/renderer/core/css/css_keyframe_rule.h
index 56fcc1053eb..98aa8887d7b 100644
--- a/chromium/third_party/blink/renderer/core/css/css_keyframe_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/css_keyframe_rule.h
@@ -52,10 +52,10 @@ class CSSKeyframeRule final : public CSSRule {
CSSStyleDeclaration* style() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
- CSSRule::Type type() const override { return kKeyframeRule; }
+ CSSRule::Type GetType() const override { return kKeyframeRule; }
Member<StyleRuleKeyframe> keyframe_;
mutable Member<KeyframeStyleRuleCSSStyleDeclaration>
@@ -67,7 +67,7 @@ class CSSKeyframeRule final : public CSSRule {
template <>
struct DowncastTraits<CSSKeyframeRule> {
static bool AllowFrom(const CSSRule& rule) {
- return rule.type() == CSSRule::kKeyframeRule;
+ return rule.GetType() == CSSRule::kKeyframeRule;
}
};
diff --git a/chromium/third_party/blink/renderer/core/css/css_keyframes_rule.cc b/chromium/third_party/blink/renderer/core/css/css_keyframes_rule.cc
index 734b890df4a..8b9498299c8 100644
--- a/chromium/third_party/blink/renderer/core/css/css_keyframes_rule.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_keyframes_rule.cc
@@ -200,7 +200,7 @@ void CSSKeyframesRule::Reattach(StyleRuleBase* rule) {
keyframes_rule_ = To<StyleRuleKeyframes>(rule);
}
-void CSSKeyframesRule::Trace(Visitor* visitor) {
+void CSSKeyframesRule::Trace(Visitor* visitor) const {
CSSRule::Trace(visitor);
visitor->Trace(child_rule_cssom_wrappers_);
visitor->Trace(keyframes_rule_);
diff --git a/chromium/third_party/blink/renderer/core/css/css_keyframes_rule.h b/chromium/third_party/blink/renderer/core/css/css_keyframes_rule.h
index 4313c2ea27a..e7a961412c0 100644
--- a/chromium/third_party/blink/renderer/core/css/css_keyframes_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/css_keyframes_rule.h
@@ -114,10 +114,10 @@ class CSSKeyframesRule final : public CSSRule {
void StyleChanged() { keyframes_rule_->StyleChanged(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
- CSSRule::Type type() const override { return kKeyframesRule; }
+ CSSRule::Type GetType() const override { return kKeyframesRule; }
Member<StyleRuleKeyframes> keyframes_rule_;
mutable HeapVector<Member<CSSKeyframeRule>> child_rule_cssom_wrappers_;
@@ -128,7 +128,7 @@ class CSSKeyframesRule final : public CSSRule {
template <>
struct DowncastTraits<CSSKeyframesRule> {
static bool AllowFrom(const CSSRule& rule) {
- return rule.type() == CSSRule::kKeyframesRule;
+ return rule.GetType() == CSSRule::kKeyframesRule;
}
};
diff --git a/chromium/third_party/blink/renderer/core/css/css_markup.cc b/chromium/third_party/blink/renderer/core/css/css_markup.cc
index ed23f82cf54..bcd56c629c3 100644
--- a/chromium/third_party/blink/renderer/core/css/css_markup.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_markup.cc
@@ -29,34 +29,12 @@
#include "third_party/blink/renderer/core/css/css_markup.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_idioms.h"
+#include "third_party/blink/renderer/platform/wtf/text/character_visitor.h"
#include "third_party/blink/renderer/platform/wtf/text/string_buffer.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
-template <typename CharacterType>
-static inline bool IsCSSTokenizerIdentifier(const CharacterType* characters,
- unsigned length) {
- const CharacterType* end = characters + length;
-
- // -?
- if (characters != end && characters[0] == '-')
- ++characters;
-
- // {nmstart}
- if (characters == end || !IsNameStartCodePoint(characters[0]))
- return false;
- ++characters;
-
- // {nmchar}*
- for (; characters != end; ++characters) {
- if (!IsNameCodePoint(characters[0]))
- return false;
- }
-
- return true;
-}
-
// "ident" from the CSS tokenizer, minus backslash-escape sequences
static bool IsCSSTokenizerIdentifier(const String& string) {
unsigned length = string.length();
@@ -64,9 +42,26 @@ static bool IsCSSTokenizerIdentifier(const String& string) {
if (!length)
return false;
- if (string.Is8Bit())
- return IsCSSTokenizerIdentifier(string.Characters8(), length);
- return IsCSSTokenizerIdentifier(string.Characters16(), length);
+ return WTF::VisitCharacters(string, [](const auto* chars, unsigned length) {
+ const auto* end = chars + length;
+
+ // -?
+ if (chars != end && chars[0] == '-')
+ ++chars;
+
+ // {nmstart}
+ if (chars == end || !IsNameStartCodePoint(chars[0]))
+ return false;
+ ++chars;
+
+ // {nmchar}*
+ for (; chars != end; ++chars) {
+ if (!IsNameCodePoint(chars[0]))
+ return false;
+ }
+
+ return true;
+ });
}
static void SerializeCharacter(UChar32 c, StringBuilder& append_to) {
diff --git a/chromium/third_party/blink/renderer/core/css/css_math_expression_node.cc b/chromium/third_party/blink/renderer/core/css/css_math_expression_node.cc
index b60c35e45f7..e74f5b731d0 100644
--- a/chromium/third_party/blink/renderer/core/css/css_math_expression_node.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_math_expression_node.cc
@@ -32,7 +32,7 @@
#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
#include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h"
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/platform/geometry/calculation_expression_node.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
@@ -268,7 +268,7 @@ bool CSSMathExpressionNumericLiteral::IsComputationallyIndependent() const {
return value_->IsComputationallyIndependent();
}
-void CSSMathExpressionNumericLiteral::Trace(Visitor* visitor) {
+void CSSMathExpressionNumericLiteral::Trace(Visitor* visitor) const {
visitor->Trace(value_);
CSSMathExpressionNode::Trace(visitor);
}
@@ -716,7 +716,7 @@ CSSPrimitiveValue::UnitType CSSMathExpressionBinaryOperation::ResolvedUnitType()
return CSSPrimitiveValue::UnitType::kUnknown;
}
-void CSSMathExpressionBinaryOperation::Trace(Visitor* visitor) {
+void CSSMathExpressionBinaryOperation::Trace(Visitor* visitor) const {
visitor->Trace(left_side_);
visitor->Trace(right_side_);
CSSMathExpressionNode::Trace(visitor);
@@ -803,7 +803,7 @@ CSSMathExpressionVariadicOperation::CSSMathExpressionVariadicOperation(
operands_(std::move(operands)),
operator_(op) {}
-void CSSMathExpressionVariadicOperation::Trace(Visitor* visitor) {
+void CSSMathExpressionVariadicOperation::Trace(Visitor* visitor) const {
visitor->Trace(operands_);
CSSMathExpressionNode::Trace(visitor);
}
@@ -1029,7 +1029,7 @@ class CSSMathExpressionNodeParser {
last_token_is_comma = false;
operands.push_back(operand);
- if (!css_property_parser_helpers::ConsumeCommaIncludingWhitespace(tokens))
+ if (!css_parsing_utils::ConsumeCommaIncludingWhitespace(tokens))
break;
last_token_is_comma = true;
}
@@ -1048,14 +1048,14 @@ class CSSMathExpressionNodeParser {
if (!min_operand)
return nullptr;
- if (!css_property_parser_helpers::ConsumeCommaIncludingWhitespace(tokens))
+ if (!css_parsing_utils::ConsumeCommaIncludingWhitespace(tokens))
return nullptr;
CSSMathExpressionNode* val_operand = ParseValueExpression(tokens, depth);
if (!val_operand)
return nullptr;
- if (!css_property_parser_helpers::ConsumeCommaIncludingWhitespace(tokens))
+ if (!css_parsing_utils::ConsumeCommaIncludingWhitespace(tokens))
return nullptr;
CSSMathExpressionNode* max_operand = ParseValueExpression(tokens, depth);
diff --git a/chromium/third_party/blink/renderer/core/css/css_math_expression_node.h b/chromium/third_party/blink/renderer/core/css/css_math_expression_node.h
index 1d1b76f0006..f7012a2c342 100644
--- a/chromium/third_party/blink/renderer/core/css/css_math_expression_node.h
+++ b/chromium/third_party/blink/renderer/core/css/css_math_expression_node.h
@@ -141,7 +141,7 @@ class CORE_EXPORT CSSMathExpressionNode
virtual bool InvolvesPercentageComparisons() const = 0;
#endif
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
CSSMathExpressionNode(CalculationCategory category,
@@ -192,7 +192,7 @@ class CORE_EXPORT CSSMathExpressionNumericLiteral final
bool IsComputationallyIndependent() const final;
bool operator==(const CSSMathExpressionNode& other) const final;
CSSPrimitiveValue::UnitType ResolvedUnitType() const final;
- void Trace(Visitor* visitor) final;
+ void Trace(Visitor* visitor) const final;
#if DCHECK_IS_ON()
bool InvolvesPercentageComparisons() const final;
@@ -250,7 +250,7 @@ class CORE_EXPORT CSSMathExpressionBinaryOperation final
String CustomCSSText() const final;
bool operator==(const CSSMathExpressionNode& exp) const final;
CSSPrimitiveValue::UnitType ResolvedUnitType() const final;
- void Trace(Visitor* visitor) final;
+ void Trace(Visitor* visitor) const final;
#if DCHECK_IS_ON()
bool InvolvesPercentageComparisons() const final;
@@ -318,7 +318,7 @@ class CSSMathExpressionVariadicOperation final : public CSSMathExpressionNode {
bool IsComputationallyIndependent() const final;
bool operator==(const CSSMathExpressionNode& other) const final;
CSSPrimitiveValue::UnitType ResolvedUnitType() const final;
- void Trace(Visitor* visitor) final;
+ void Trace(Visitor* visitor) const final;
#if DCHECK_IS_ON()
bool InvolvesPercentageComparisons() const final;
diff --git a/chromium/third_party/blink/renderer/core/css/css_media_rule.cc b/chromium/third_party/blink/renderer/core/css/css_media_rule.cc
index 5faf76aff09..91dd8024c7d 100644
--- a/chromium/third_party/blink/renderer/core/css/css_media_rule.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_media_rule.cc
@@ -71,7 +71,7 @@ void CSSMediaRule::Reattach(StyleRuleBase* rule) {
media_cssom_wrapper_->Reattach(MediaQueries());
}
-void CSSMediaRule::Trace(Visitor* visitor) {
+void CSSMediaRule::Trace(Visitor* visitor) const {
visitor->Trace(media_cssom_wrapper_);
CSSConditionRule::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_media_rule.h b/chromium/third_party/blink/renderer/core/css/css_media_rule.h
index 50f9702c144..ca7d228d133 100644
--- a/chromium/third_party/blink/renderer/core/css/css_media_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/css_media_rule.h
@@ -44,10 +44,10 @@ class CSSMediaRule final : public CSSConditionRule {
MediaList* media() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
- CSSRule::Type type() const override { return kMediaRule; }
+ CSSRule::Type GetType() const override { return kMediaRule; }
scoped_refptr<MediaQuerySet> MediaQueries() const;
@@ -57,7 +57,7 @@ class CSSMediaRule final : public CSSConditionRule {
template <>
struct DowncastTraits<CSSMediaRule> {
static bool AllowFrom(const CSSRule& rule) {
- return rule.type() == CSSRule::kMediaRule;
+ return rule.GetType() == CSSRule::kMediaRule;
}
};
diff --git a/chromium/third_party/blink/renderer/core/css/css_namespace_rule.cc b/chromium/third_party/blink/renderer/core/css/css_namespace_rule.cc
index 0a61e2ff288..7dcf4de291e 100644
--- a/chromium/third_party/blink/renderer/core/css/css_namespace_rule.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_namespace_rule.cc
@@ -36,7 +36,7 @@ AtomicString CSSNamespaceRule::prefix() const {
return namespace_rule_->Prefix();
}
-void CSSNamespaceRule::Trace(Visitor* visitor) {
+void CSSNamespaceRule::Trace(Visitor* visitor) const {
visitor->Trace(namespace_rule_);
CSSRule::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_namespace_rule.h b/chromium/third_party/blink/renderer/core/css/css_namespace_rule.h
index e0091f8399f..48fc08395dc 100644
--- a/chromium/third_party/blink/renderer/core/css/css_namespace_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/css_namespace_rule.h
@@ -25,10 +25,10 @@ class CSSNamespaceRule final : public CSSRule {
AtomicString namespaceURI() const;
AtomicString prefix() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
- CSSRule::Type type() const override { return kNamespaceRule; }
+ CSSRule::Type GetType() const override { return kNamespaceRule; }
Member<StyleRuleNamespace> namespace_rule_;
};
@@ -36,7 +36,7 @@ class CSSNamespaceRule final : public CSSRule {
template <>
struct DowncastTraits<CSSNamespaceRule> {
static bool AllowFrom(const CSSRule& rule) {
- return rule.type() == CSSRule::kNamespaceRule;
+ return rule.GetType() == CSSRule::kNamespaceRule;
}
};
diff --git a/chromium/third_party/blink/renderer/core/css/css_page_rule.cc b/chromium/third_party/blink/renderer/core/css/css_page_rule.cc
index 6367cb9ad82..94898bbd7fb 100644
--- a/chromium/third_party/blink/renderer/core/css/css_page_rule.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_page_rule.cc
@@ -97,7 +97,7 @@ void CSSPageRule::Reattach(StyleRuleBase* rule) {
properties_cssom_wrapper_->Reattach(page_rule_->MutableProperties());
}
-void CSSPageRule::Trace(Visitor* visitor) {
+void CSSPageRule::Trace(Visitor* visitor) const {
visitor->Trace(page_rule_);
visitor->Trace(properties_cssom_wrapper_);
CSSRule::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/css_page_rule.h b/chromium/third_party/blink/renderer/core/css/css_page_rule.h
index 036a147cbd7..161078e3b19 100644
--- a/chromium/third_party/blink/renderer/core/css/css_page_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/css_page_rule.h
@@ -49,10 +49,10 @@ class CORE_EXPORT CSSPageRule final : public CSSRule {
String selectorText() const;
void setSelectorText(const ExecutionContext*, const String&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
- CSSRule::Type type() const override { return kPageRule; }
+ CSSRule::Type GetType() const override { return kPageRule; }
Member<StyleRulePage> page_rule_;
mutable Member<StyleRuleCSSStyleDeclaration> properties_cssom_wrapper_;
@@ -61,7 +61,7 @@ class CORE_EXPORT CSSPageRule final : public CSSRule {
template <>
struct DowncastTraits<CSSPageRule> {
static bool AllowFrom(const CSSRule& rule) {
- return rule.type() == CSSRule::kPageRule;
+ return rule.GetType() == CSSRule::kPageRule;
}
};
diff --git a/chromium/third_party/blink/renderer/core/css/css_page_rule_test.cc b/chromium/third_party/blink/renderer/core/css/css_page_rule_test.cc
index 98332f42628..a9bcbd44e76 100644
--- a/chromium/third_party/blink/renderer/core/css/css_page_rule_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_page_rule_test.cc
@@ -20,7 +20,7 @@ TEST(CSSPageRule, Serializing) {
if (sheet.CssRules()) {
EXPECT_EQ(1u, sheet.CssRules()->length());
EXPECT_EQ(String(css_rule), sheet.CssRules()->item(0)->cssText());
- EXPECT_EQ(CSSRule::kPageRule, sheet.CssRules()->item(0)->type());
+ EXPECT_EQ(CSSRule::kPageRule, sheet.CssRules()->item(0)->GetType());
auto* page_rule = To<CSSPageRule>(sheet.CssRules()->item(0));
EXPECT_EQ(":left", page_rule->selectorText());
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_paint_image_generator.h b/chromium/third_party/blink/renderer/core/css/css_paint_image_generator.h
index 39e0a0839d0..c43970fac55 100644
--- a/chromium/third_party/blink/renderer/core/css/css_paint_image_generator.h
+++ b/chromium/third_party/blink/renderer/core/css/css_paint_image_generator.h
@@ -32,7 +32,7 @@ class CORE_EXPORT CSSPaintImageGenerator
virtual ~Observer() = default;
virtual void PaintImageGeneratorReady() = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
static CSSPaintImageGenerator* Create(const String& name,
@@ -62,7 +62,7 @@ class CORE_EXPORT CSSPaintImageGenerator
virtual bool IsImageGeneratorReady() const = 0;
virtual int WorkletId() const = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/css_paint_value.h b/chromium/third_party/blink/renderer/core/css/css_paint_value.h
index 06d1cced1e7..8e3c0861694 100644
--- a/chromium/third_party/blink/renderer/core/css/css_paint_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_paint_value.h
@@ -79,7 +79,7 @@ class CORE_EXPORT CSSPaintValue : public CSSImageGeneratorValue {
explicit Observer(CSSPaintValue* owner_value) : owner_value_(owner_value) {}
~Observer() override = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(owner_value_);
CSSPaintImageGenerator::Observer::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_primitive_value_mappings.h b/chromium/third_party/blink/renderer/core/css/css_primitive_value_mappings.h
index 21bba087219..da176f1ec5c 100644
--- a/chromium/third_party/blink/renderer/core/css/css_primitive_value_mappings.h
+++ b/chromium/third_party/blink/renderer/core/css/css_primitive_value_mappings.h
@@ -1992,6 +1992,48 @@ inline TextUnderlinePosition CSSIdentifierValue::ConvertTo() const {
return kTextUnderlinePositionAuto;
}
+template <>
+inline CSSIdentifierValue::CSSIdentifierValue(ScrollbarGutter scrollbar_gutter)
+ : CSSValue(kIdentifierClass) {
+ switch (scrollbar_gutter) {
+ case kScrollbarGutterAuto:
+ value_id_ = CSSValueID::kAuto;
+ break;
+ case kScrollbarGutterStable:
+ value_id_ = CSSValueID::kStable;
+ break;
+ case kScrollbarGutterAlways:
+ value_id_ = CSSValueID::kAlways;
+ break;
+ case kScrollbarGutterBoth:
+ value_id_ = CSSValueID::kBoth;
+ break;
+ case kScrollbarGutterForce:
+ value_id_ = CSSValueID::kForce;
+ break;
+ }
+}
+
+template <>
+inline ScrollbarGutter CSSIdentifierValue::ConvertTo() const {
+ switch (GetValueID()) {
+ case CSSValueID::kAuto:
+ return kScrollbarGutterAuto;
+ case CSSValueID::kStable:
+ return kScrollbarGutterStable;
+ case CSSValueID::kAlways:
+ return kScrollbarGutterAlways;
+ case CSSValueID::kBoth:
+ return kScrollbarGutterBoth;
+ case CSSValueID::kForce:
+ return kScrollbarGutterForce;
+ default:
+ break;
+ }
+ NOTREACHED();
+ return kScrollbarGutterAuto;
+}
+
} // namespace blink
#endif
diff --git a/chromium/third_party/blink/renderer/core/css/css_properties.json5 b/chromium/third_party/blink/renderer/core/css/css_properties.json5
index 4982b995445..79310bd12e4 100644
--- a/chromium/third_party/blink/renderer/core/css/css_properties.json5
+++ b/chromium/third_party/blink/renderer/core/css/css_properties.json5
@@ -598,6 +598,20 @@
valid_for_marker: true,
},
{
+ name: "animation-timeline",
+ property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "InitialValue"],
+ style_builder_template: "animation",
+ style_builder_template_args: {
+ attribute: "Timeline",
+ },
+ priority: "Animation",
+ keywords: ["none", "auto"],
+ typedom_types: ["Keyword"],
+ separator: ",",
+ valid_for_marker: true,
+ runtime_flag: "CSSScrollTimeline",
+ },
+ {
name: "animation-timing-function",
property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "InitialValue"],
style_builder_template: "animation",
@@ -797,6 +811,7 @@
name: "font-stretch",
property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
is_descriptor: true,
+ interpolable: true,
inherited: true,
font: true,
name_for_methods: "Stretch",
@@ -985,8 +1000,9 @@
property_methods: ["CSSValueFromComputedStyleInternal"],
inherited: true,
type_name: "TextOrientation",
- style_builder_custom_functions: ["value"],
+ style_builder_custom_functions: ["initial", "inherit", "value"],
priority: "High",
+ surrogate_for: "text-orientation",
},
{
name: "writing-mode",
@@ -1042,6 +1058,7 @@
default_value: "StyleContentAlignmentData(ContentPosition::kNormal, ContentDistributionType::kDefault, OverflowAlignment::kDefault)",
type_name: "StyleContentAlignmentData",
converter: "ConvertContentAlignmentData",
+ computed_value_comparable: true,
},
{
name: "align-items",
@@ -1052,6 +1069,7 @@
default_value: "StyleSelfAlignmentData(ItemPosition::kNormal, OverflowAlignment::kDefault)",
type_name: "StyleSelfAlignmentData",
converter: "ConvertSelfOrDefaultAlignmentData",
+ computed_value_comparable: true,
},
{
name: "alignment-baseline",
@@ -1069,6 +1087,7 @@
default_value: "StyleSelfAlignmentData(ItemPosition::kAuto, OverflowAlignment::kDefault)",
type_name: "StyleSelfAlignmentData",
converter: "ConvertSelfOrDefaultAlignmentData",
+ computed_value_comparable: true,
},
{
name: "aspect-ratio",
@@ -1171,7 +1190,6 @@
style_builder_template_args: {
initial_color: "ComputedStyleInitialValues::InitialBackgroundColor",
},
- affected_by_forced_colors: true,
valid_for_first_letter: true,
valid_for_cue: true,
is_background: true,
@@ -1188,6 +1206,7 @@
fill_type: "Image",
fill_type_getter: "GetImage",
},
+ affected_by_forced_colors: true,
valid_for_first_letter: true,
valid_for_cue: true,
is_background: true,
@@ -1278,9 +1297,9 @@
interpolable: true,
field_group: "surround",
field_template: "external",
- include_paths: ["third_party/blink/renderer/platform/graphics/color.h"],
- default_value: "0",
- type_name: "Color",
+ include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
+ default_value: "StyleColor::CurrentColor()",
+ type_name: "StyleColor",
computed_style_custom_functions: ["getter", "setter"],
keywords: ["currentcolor"],
typedom_types: ["Keyword"],
@@ -1304,6 +1323,7 @@
typedom_types: ["Length", "Percentage"],
valid_for_first_letter: true,
is_border: true,
+ computed_value_comparable: true,
},
{
name: "border-bottom-right-radius",
@@ -1318,6 +1338,7 @@
typedom_types: ["Length", "Percentage"],
valid_for_first_letter: true,
is_border: true,
+ computed_value_comparable: true,
},
{
name: "border-bottom-style",
@@ -1333,6 +1354,7 @@
type_name: "EBorderStyle",
valid_for_first_letter: true,
is_border: true,
+ computed_value_comparable: true,
},
{
name: "border-bottom-width",
@@ -1349,6 +1371,7 @@
converter: "ConvertBorderWidth",
valid_for_first_letter: true,
is_border: true,
+ computed_value_comparable: true,
},
{
name: "border-collapse",
@@ -1425,9 +1448,9 @@
interpolable: true,
field_group: "surround",
field_template: "external",
- include_paths: ["third_party/blink/renderer/platform/graphics/color.h"],
- default_value: "0",
- type_name: "Color",
+ include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
+ default_value: "StyleColor::CurrentColor()",
+ type_name: "StyleColor",
computed_style_custom_functions: ["getter", "setter"],
keywords: ["currentcolor"],
typedom_types: ["Keyword"],
@@ -1452,6 +1475,7 @@
type_name: "EBorderStyle",
valid_for_first_letter: true,
is_border: true,
+ computed_value_comparable: true,
},
{
name: "border-left-width",
@@ -1468,6 +1492,7 @@
converter: "ConvertBorderWidth",
valid_for_first_letter: true,
is_border: true,
+ computed_value_comparable: true,
},
{
name: "border-right-color",
@@ -1475,9 +1500,9 @@
interpolable: true,
field_group: "surround",
field_template: "external",
- include_paths: ["third_party/blink/renderer/platform/graphics/color.h"],
- default_value: "0",
- type_name: "Color",
+ include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
+ default_value: "StyleColor::CurrentColor()",
+ type_name: "StyleColor",
computed_style_custom_functions: ["getter", "setter"],
keywords: ["currentcolor"],
typedom_types: ["Keyword"],
@@ -1502,6 +1527,7 @@
type_name: "EBorderStyle",
valid_for_first_letter: true,
is_border: true,
+ computed_value_comparable: true,
},
{
name: "border-right-width",
@@ -1518,6 +1544,7 @@
converter: "ConvertBorderWidth",
valid_for_first_letter: true,
is_border: true,
+ computed_value_comparable: true,
},
{
name: "border-top-color",
@@ -1525,9 +1552,9 @@
interpolable: true,
field_group: "surround",
field_template: "external",
- include_paths: ["third_party/blink/renderer/platform/graphics/color.h"],
- default_value: "0",
- type_name: "Color",
+ include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
+ default_value: "StyleColor::CurrentColor()",
+ type_name: "StyleColor",
computed_style_custom_functions: ["getter", "setter"],
keywords: ["currentcolor"],
typedom_types: ["Keyword"],
@@ -1551,6 +1578,7 @@
typedom_types: ["Length", "Percentage"],
valid_for_first_letter: true,
is_border: true,
+ computed_value_comparable: true,
},
{
name: "border-top-right-radius",
@@ -1565,6 +1593,7 @@
typedom_types: ["Length", "Percentage"],
valid_for_first_letter: true,
is_border: true,
+ computed_value_comparable: true,
},
{
name: "border-top-style",
@@ -1580,6 +1609,7 @@
type_name: "EBorderStyle",
valid_for_first_letter: true,
is_border: true,
+ computed_value_comparable: true,
},
{
name: "border-top-width",
@@ -1596,6 +1626,7 @@
converter: "ConvertBorderWidth",
valid_for_first_letter: true,
is_border: true,
+ computed_value_comparable: true,
},
{
name: "bottom",
@@ -1820,7 +1851,6 @@
type_name: "LengthSize",
converter: "ConvertIntrinsicSize",
include_paths: ["third_party/blink/renderer/platform/geometry/length_size.h"],
- runtime_flag: "CSSIntrinsicSize"
},
{
name: "content",
@@ -1857,6 +1887,16 @@
typedom_types: ["Keyword"],
},
{
+ name: "counter-set",
+ property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+ style_builder_template: "counter",
+ style_builder_template_args: {
+ action: "Set",
+ },
+ keywords: ["none"],
+ typedom_types: ["Keyword"],
+ },
+ {
name: "cursor",
property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
inherited: true,
@@ -1985,7 +2025,8 @@
default_value: "Length::Auto()",
converter: "ConvertLengthOrAuto",
typedom_types: ["Keyword", "Length", "Percentage"],
- keywords: ["auto"]
+ keywords: ["auto"],
+ computed_value_comparable: true,
},
{
name: "flex-direction",
@@ -1995,6 +2036,7 @@
typedom_types: ["Keyword"],
keywords: ["row", "row-reverse", "column", "column-reverse"],
default_value: "row",
+ computed_value_comparable: true,
},
{
name: "flex-grow",
@@ -2005,6 +2047,7 @@
default_value: "0.0f",
type_name: "float",
typedom_types: ["Number"],
+ computed_value_comparable: true,
},
{
name: "flex-shrink",
@@ -2015,6 +2058,7 @@
default_value: "1.0f",
type_name: "float",
typedom_types: ["Number"],
+ computed_value_comparable: true,
},
{
name: "flex-wrap",
@@ -2024,6 +2068,7 @@
typedom_types: ["Keyword"],
keywords: ["nowrap", "wrap", "wrap-reverse"],
default_value: "nowrap",
+ computed_value_comparable: true,
},
{
name: "float",
@@ -2196,6 +2241,7 @@
default_value: "Length()",
typedom_types: ["Keyword", "Length", "Percentage"],
converter: "ConvertLengthSizing",
+ computed_value_comparable: true,
},
{
name: "hyphens",
@@ -2251,6 +2297,7 @@
default_value: "StyleContentAlignmentData(ContentPosition::kNormal, ContentDistributionType::kDefault, OverflowAlignment::kDefault)",
type_name: "StyleContentAlignmentData",
converter: "ConvertContentAlignmentData",
+ computed_value_comparable: true,
},
{
name: "justify-items",
@@ -2261,6 +2308,7 @@
default_value: "StyleSelfAlignmentData(ItemPosition::kLegacy, OverflowAlignment::kDefault)",
type_name: "StyleSelfAlignmentData",
converter: "ConvertSelfOrDefaultAlignmentData",
+ computed_value_comparable: true,
},
{
name: "justify-self",
@@ -2271,6 +2319,7 @@
default_value: "StyleSelfAlignmentData(ItemPosition::kAuto, OverflowAlignment::kDefault)",
type_name: "StyleSelfAlignmentData",
converter: "ConvertSelfOrDefaultAlignmentData",
+ computed_value_comparable: true,
},
{
name: "left",
@@ -2392,6 +2441,7 @@
keywords: ["auto"],
typedom_types: ["Keyword", "Length", "Percentage"],
valid_for_first_letter: true,
+ computed_value_comparable: true,
},
{
name: "margin-left",
@@ -2406,6 +2456,7 @@
keywords: ["auto"],
typedom_types: ["Keyword", "Length", "Percentage"],
valid_for_first_letter: true,
+ computed_value_comparable: true,
},
{
name: "margin-right",
@@ -2420,6 +2471,7 @@
keywords: ["auto"],
typedom_types: ["Keyword", "Length", "Percentage"],
valid_for_first_letter: true,
+ computed_value_comparable: true,
},
{
name: "margin-top",
@@ -2434,6 +2486,7 @@
keywords: ["auto"],
typedom_types: ["Keyword", "Length", "Percentage"],
valid_for_first_letter: true,
+ computed_value_comparable: true,
},
{
name: "marker-end",
@@ -2473,15 +2526,6 @@
converter: "ConvertElementReference",
},
{
- name: "mask-source-type",
- property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
- runtime_flag: "CSSMaskSourceType",
- style_builder_template: "mask_layer",
- style_builder_template_args: {
- fill_type: "MaskSourceType",
- },
- },
- {
name: "mask-type",
property_methods: ["CSSValueFromComputedStyleInternal"],
svg: true,
@@ -2519,7 +2563,8 @@
default_value: "Length::None()",
converter: "ConvertLengthMaxSizing",
keywords: ["none"],
- typedom_types: ["Keyword", "Length", "Percentage"]
+ typedom_types: ["Keyword", "Length", "Percentage"],
+ computed_value_comparable: true,
},
{
name: "max-width",
@@ -2531,7 +2576,8 @@
default_value: "Length::None()",
converter: "ConvertLengthMaxSizing",
keywords: ["none"],
- typedom_types: ["Keyword", "Length", "Percentage"]
+ typedom_types: ["Keyword", "Length", "Percentage"],
+ computed_value_comparable: true,
},
{
name: "min-height",
@@ -2542,7 +2588,8 @@
field_template: "<length>",
default_value: "Length()",
converter: "ConvertLengthSizing",
- typedom_types: ["Length", "Percentage"]
+ typedom_types: ["Length", "Percentage"],
+ computed_value_comparable: true,
},
{
name: "min-width",
@@ -2553,7 +2600,8 @@
field_template: "<length>",
default_value: "Length()",
converter: "ConvertLengthSizing",
- typedom_types: ["Length", "Percentage"]
+ typedom_types: ["Length", "Percentage"],
+ computed_value_comparable: true,
},
{
name: "mix-blend-mode",
@@ -2712,9 +2760,9 @@
interpolable: true,
field_group: "*",
field_template: "external",
- include_paths: ["third_party/blink/renderer/platform/graphics/color.h"],
- default_value: "0",
- type_name: "Color",
+ include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
+ default_value: "StyleColor::CurrentColor()",
+ type_name: "StyleColor",
computed_style_custom_functions: ["getter", "setter"],
keywords: ["currentcolor"],
typedom_types: ["Keyword"],
@@ -2869,6 +2917,7 @@
computed_style_custom_functions: ["setter"],
typedom_types: ["Keyword", "Length", "Percentage"],
valid_for_first_letter: true,
+ computed_value_comparable: true,
},
{
name: "padding-left",
@@ -2882,6 +2931,7 @@
computed_style_custom_functions: ["setter"],
typedom_types: ["Keyword", "Length", "Percentage"],
valid_for_first_letter: true,
+ computed_value_comparable: true,
},
{
name: "padding-right",
@@ -2895,6 +2945,7 @@
computed_style_custom_functions: ["setter"],
typedom_types: ["Keyword", "Length", "Percentage"],
valid_for_first_letter: true,
+ computed_value_comparable: true,
},
{
name: "padding-top",
@@ -2908,6 +2959,7 @@
computed_style_custom_functions: ["setter"],
typedom_types: ["Keyword", "Length", "Percentage"],
valid_for_first_letter: true,
+ computed_value_comparable: true,
},
{
name: "page",
@@ -3065,6 +3117,22 @@
converter: "ConvertLengthOrAuto",
},
{
+ name: "scrollbar-gutter",
+ property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+ inherited: true,
+ field_size: 4,
+ field_template: "primitive",
+ default_value: "kScrollbarGutterAuto",
+ name_for_methods: "ScrollbarGutter",
+ type_name: "unsigned",
+ converter: "ConvertScrollbarGutter",
+ keywords: [
+ "auto", "stable", "always"
+ ],
+ typedom_types: ["Keyword"],
+ runtime_flag: "ScrollbarGutter",
+ },
+ {
name: "scroll-behavior",
property_methods: ["CSSValueFromComputedStyleInternal"],
field_group: "*",
@@ -3534,6 +3602,7 @@
affected_by_forced_colors: true,
valid_for_first_letter: true,
valid_for_cue: true,
+ computed_value_comparable: true,
},
{
name: "text-decoration-line",
@@ -3548,6 +3617,7 @@
converter: "ConvertFlags<TextDecoration>",
valid_for_first_letter: true,
valid_for_cue: true,
+ computed_value_comparable: true,
},
{
name: "text-decoration-skip-ink",
@@ -3560,6 +3630,7 @@
default_value: "auto",
valid_for_first_letter: true,
valid_for_cue: true,
+ computed_value_comparable: true,
},
{
name: "text-decoration-style",
@@ -3571,12 +3642,12 @@
default_value: "solid",
valid_for_first_letter: true,
valid_for_cue: true,
+ computed_value_comparable: true,
},
{
name: "text-decoration-thickness",
runtime_flag: "UnderlineOffsetThickness",
property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
- # TODO: Move to core/style?
include_paths: ["third_party/blink/renderer/core/style/text_decoration_thickness.h"],
inherited: true,
field_group: "*",
@@ -3587,6 +3658,7 @@
keywords: ["auto", "from-font"],
typedom_types: ["Keyword", "Length", "Percentage"],
valid_for_first_letter: true,
+ computed_value_comparable: true,
},
{
name: "text-indent",
@@ -4020,9 +4092,9 @@
interpolable: true,
field_group: "*",
field_template: "external",
- include_paths: ["third_party/blink/renderer/core/style/gap_length.h"],
- default_value: "GapLength()",
- type_name: "GapLength",
+ include_paths: ["third_party/blink/renderer/platform/geometry/length.h"],
+ default_value: "base::nullopt",
+ type_name: "base::Optional<Length>",
converter: "ConvertGapLength",
keywords: ["normal"],
typedom_types: ["Keyword", "Length", "Percentage"],
@@ -4033,9 +4105,9 @@
interpolable: true,
field_group: "*",
field_template: "external",
- include_paths: ["third_party/blink/renderer/core/style/gap_length.h"],
- default_value: "GapLength()",
- type_name: "GapLength",
+ include_paths: ["third_party/blink/renderer/platform/geometry/length.h"],
+ default_value: "base::nullopt",
+ type_name: "base::Optional<Length>",
converter: "ConvertGapLength",
keywords: ["normal"],
typedom_types: ["Keyword", "Length", "Percentage"],
@@ -4046,9 +4118,9 @@
interpolable: true,
field_group: "*",
field_template: "external",
- include_paths: ["third_party/blink/renderer/platform/graphics/color.h"],
- default_value: "0",
- type_name: "Color",
+ include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
+ default_value: "StyleColor::CurrentColor()",
+ type_name: "StyleColor",
computed_style_custom_functions: ["getter","setter"],
keywords: ["currentcolor"],
typedom_types: ["Keyword"],
@@ -4347,9 +4419,9 @@
inherited: true,
field_group: "*",
field_template: "external",
- include_paths: ["third_party/blink/renderer/platform/graphics/color.h"],
- default_value: "Color()",
- type_name: "Color",
+ include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
+ default_value: "StyleColor::CurrentColor()",
+ type_name: "StyleColor",
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertStyleColor",
style_builder_template: "color",
@@ -4378,9 +4450,9 @@
inherited: true,
field_group: "*",
field_template: "external",
- include_paths: ["third_party/blink/renderer/platform/graphics/color.h"],
- default_value: "Color()",
- type_name: "Color",
+ include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
+ default_value: "StyleColor::CurrentColor()",
+ type_name: "StyleColor",
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertStyleColor",
style_builder_template: "color",
@@ -4401,9 +4473,9 @@
inherited: true,
field_group: "*",
field_template: "external",
- include_paths: ["third_party/blink/renderer/platform/graphics/color.h"],
- default_value: "Color()",
- type_name: "Color",
+ include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
+ default_value: "StyleColor::CurrentColor()",
+ type_name: "StyleColor",
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertStyleColor",
style_builder_template: "color",
@@ -4501,6 +4573,7 @@
default_value: "Length()",
typedom_types: ["Keyword", "Length", "Percentage"],
converter: "ConvertLengthSizing",
+ computed_value_comparable: true,
},
{
name: "will-change",
@@ -5026,6 +5099,30 @@
is_property: false,
runtime_flag: "CSSVariables2AtProperty",
},
+ {
+ name: "source",
+ is_descriptor: true,
+ is_property: false,
+ runtime_flag: "CSSScrollTimeline",
+ },
+ {
+ name: "start",
+ is_descriptor: true,
+ is_property: false,
+ runtime_flag: "CSSScrollTimeline",
+ },
+ {
+ name: "end",
+ is_descriptor: true,
+ is_property: false,
+ runtime_flag: "CSSScrollTimeline",
+ },
+ {
+ name: "time-range",
+ is_descriptor: true,
+ is_property: false,
+ runtime_flag: "CSSScrollTimeline",
+ },
// Shorthands
{
@@ -5483,7 +5580,7 @@
},
{
name: "text-decoration",
- longhands: ["text-decoration-line", "text-decoration-style", "text-decoration-color"],
+ longhands: ["text-decoration-line", "text-decoration-thickness", "text-decoration-style", "text-decoration-color"],
property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
},
{
@@ -5807,9 +5904,9 @@
inherited: true,
field_group: "*",
field_template: "external",
- include_paths: ["third_party/blink/renderer/platform/graphics/color.h"],
- default_value: "Color()",
- type_name: "Color",
+ include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
+ default_value: "StyleColor::CurrentColor()",
+ type_name: "StyleColor",
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertStyleColor",
style_builder_template: "visited_color",
@@ -5825,9 +5922,9 @@
inherited: true,
field_group: "*",
field_template: "external",
- include_paths: ["third_party/blink/renderer/platform/graphics/color.h"],
- default_value: "Color()",
- type_name: "Color",
+ include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
+ default_value: "StyleColor::CurrentColor()",
+ type_name: "StyleColor",
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertStyleColor",
style_builder_template: "visited_color",
@@ -5842,9 +5939,9 @@
inherited: true,
field_group: "*",
field_template: "external",
- include_paths: ["third_party/blink/renderer/platform/graphics/color.h"],
- default_value: "Color()",
- type_name: "Color",
+ include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
+ default_value: "StyleColor::CurrentColor()",
+ type_name: "StyleColor",
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertStyleColor",
style_builder_template: "visited_color",
@@ -5875,6 +5972,21 @@
converter: "ConvertInternalEmptyLineHeight",
},
+ // Stores the RGB portion of the background-color used during forced colors
+ // mode. The corresponding alpha channel is retrieved from the
+ // author-defined background-color.
+ {
+ name: "-internal-forced-background-color-rgb",
+ property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+ field_group: "*",
+ field_template: "external",
+ default_value: "CSSValueID::kCanvas",
+ type_name: "CSSValueID",
+ converter: "ConvertCSSValueID",
+ valid_for_first_letter: true,
+ valid_for_cue: true,
+ },
+
// Aliases; these map to the same CSSPropertyID
{
name: "-epub-caption-side",
diff --git a/chromium/third_party/blink/renderer/core/css/css_property_rule.cc b/chromium/third_party/blink/renderer/core/css/css_property_rule.cc
index 4309e861c73..c399823471e 100644
--- a/chromium/third_party/blink/renderer/core/css/css_property_rule.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_property_rule.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/css/css_property_rule.h"
#include "third_party/blink/renderer/core/css/css_identifier_value.h"
+#include "third_party/blink/renderer/core/css/css_markup.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/css_string_value.h"
#include "third_party/blink/renderer/core/css/style_rule.h"
@@ -24,7 +25,7 @@ String CSSPropertyRule::cssText() const {
// https://drafts.css-houdini.org/css-properties-values-api-1/#serialize-a-csspropertyrule
StringBuilder builder;
builder.Append("@property ");
- builder.Append(property_rule_->GetName());
+ SerializeIdentifier(property_rule_->GetName(), builder);
builder.Append(" { ");
if (const CSSValue* syntax = property_rule_->GetSyntax()) {
DCHECK(syntax->IsStringValue());
@@ -84,7 +85,7 @@ String CSSPropertyRule::initialValue() const {
return g_null_atom;
}
-void CSSPropertyRule::Trace(Visitor* visitor) {
+void CSSPropertyRule::Trace(Visitor* visitor) const {
visitor->Trace(property_rule_);
CSSRule::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_property_rule.h b/chromium/third_party/blink/renderer/core/css/css_property_rule.h
index ba5a0dafbf6..6a0c0c3a0fa 100644
--- a/chromium/third_party/blink/renderer/core/css/css_property_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/css_property_rule.h
@@ -28,10 +28,10 @@ class CSSPropertyRule final : public CSSRule {
bool inherits() const;
String initialValue() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
- CSSRule::Type type() const override { return kPropertyRule; }
+ CSSRule::Type GetType() const override { return kPropertyRule; }
Member<StyleRuleProperty> property_rule_;
};
@@ -39,7 +39,7 @@ class CSSPropertyRule final : public CSSRule {
template <>
struct DowncastTraits<CSSPropertyRule> {
static bool AllowFrom(const CSSRule& rule) {
- return rule.type() == CSSRule::kPropertyRule;
+ return rule.GetType() == CSSRule::kPropertyRule;
}
};
diff --git a/chromium/third_party/blink/renderer/core/css/css_property_source_data.h b/chromium/third_party/blink/renderer/core/css/css_property_source_data.h
index f33d3c6a593..0ba300fdbd8 100644
--- a/chromium/third_party/blink/renderer/core/css/css_property_source_data.h
+++ b/chromium/third_party/blink/renderer/core/css/css_property_source_data.h
@@ -86,7 +86,7 @@ namespace blink {
class CSSRuleSourceData final : public GarbageCollected<CSSRuleSourceData> {
public:
explicit CSSRuleSourceData(StyleRule::RuleType type) : type(type) {}
- void Trace(Visitor* visitor) { visitor->Trace(child_rules); }
+ void Trace(Visitor* visitor) const { visitor->Trace(child_rules); }
bool HasProperties() const {
return type == StyleRule::kStyle || type == StyleRule::kFontFace ||
diff --git a/chromium/third_party/blink/renderer/core/css/css_property_value.h b/chromium/third_party/blink/renderer/core/css/css_property_value.h
index dc8f65aebc0..69de2e04ce9 100644
--- a/chromium/third_party/blink/renderer/core/css/css_property_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_property_value.h
@@ -95,7 +95,7 @@ class CORE_EXPORT CSSPropertyValue {
bool operator==(const CSSPropertyValue& other) const;
- void Trace(Visitor* visitor) { visitor->Trace(value_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(value_); }
private:
CSSPropertyValueMetadata metadata_;
diff --git a/chromium/third_party/blink/renderer/core/css/css_property_value_set.cc b/chromium/third_party/blink/renderer/core/css/css_property_value_set.cc
index 94d083ccecb..aac2c30e481 100644
--- a/chromium/third_party/blink/renderer/core/css/css_property_value_set.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_property_value_set.cc
@@ -247,7 +247,7 @@ template CORE_EXPORT const CSSValue* CSSPropertyValueSet::GetPropertyCSSValue<
template CORE_EXPORT const CSSValue*
CSSPropertyValueSet::GetPropertyCSSValue<AtomicString>(AtomicString) const;
-void CSSPropertyValueSet::Trace(Visitor* visitor) {
+void CSSPropertyValueSet::Trace(Visitor* visitor) const {
if (is_mutable_)
To<MutableCSSPropertyValueSet>(this)->TraceAfterDispatch(visitor);
else
@@ -667,6 +667,6 @@ void CSSPropertyValueSet::ShowStyle() {
}
#endif
-void CSSLazyPropertyParser::Trace(Visitor* visitor) {}
+void CSSLazyPropertyParser::Trace(Visitor* visitor) const {}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/css_property_value_set.h b/chromium/third_party/blink/renderer/core/css/css_property_value_set.h
index 303fc5dccda..f4e48ea8e0d 100644
--- a/chromium/third_party/blink/renderer/core/css/css_property_value_set.h
+++ b/chromium/third_party/blink/renderer/core/css/css_property_value_set.h
@@ -138,7 +138,7 @@ class CORE_EXPORT CSSPropertyValueSet
bool PropertyMatches(CSSPropertyID, const CSSValue&) const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void TraceAfterDispatch(blink::Visitor* visitor) const {}
protected:
@@ -171,7 +171,7 @@ class CSSLazyPropertyParser : public GarbageCollected<CSSLazyPropertyParser> {
CSSLazyPropertyParser() = default;
virtual ~CSSLazyPropertyParser() = default;
virtual CSSPropertyValueSet* ParseProperties() = 0;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
DISALLOW_COPY_AND_ASSIGN(CSSLazyPropertyParser);
};
diff --git a/chromium/third_party/blink/renderer/core/css/css_revert_value.h b/chromium/third_party/blink/renderer/core/css/css_revert_value.h
index 5630c918a9a..b3dd5a8f721 100644
--- a/chromium/third_party/blink/renderer/core/css/css_revert_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_revert_value.h
@@ -27,7 +27,7 @@ class CORE_EXPORT CSSRevertValue : public CSSValue {
bool Equals(const CSSRevertValue&) const { return true; }
- void TraceAfterDispatch(blink::Visitor* visitor) {
+ void TraceAfterDispatch(blink::Visitor* visitor) const {
CSSValue::TraceAfterDispatch(visitor);
}
};
diff --git a/chromium/third_party/blink/renderer/core/css/css_rule.cc b/chromium/third_party/blink/renderer/core/css/css_rule.cc
index 9559c41c90f..5a123ed6e1f 100644
--- a/chromium/third_party/blink/renderer/core/css/css_rule.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_rule.cc
@@ -63,7 +63,7 @@ void CSSRule::SetParentRule(CSSRule* rule) {
parent_ = rule;
}
-void CSSRule::Trace(Visitor* visitor) {
+void CSSRule::Trace(Visitor* visitor) const {
visitor->Trace(parent_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_rule.h b/chromium/third_party/blink/renderer/core/css/css_rule.h
index c7e81d9efde..a43ec93e4db 100644
--- a/chromium/third_party/blink/renderer/core/css/css_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/css_rule.h
@@ -42,9 +42,8 @@ class CORE_EXPORT CSSRule : public ScriptWrappable {
public:
~CSSRule() override = default;
- // The values must match the table in [1]. See also css_rule.idl.
- // [1] https://wiki.csswg.org/spec/cssom-constants
enum Type {
+ // Web-exposed values, see css_rule.idl:
kStyleRule = 1,
kCharsetRule = 2,
kImportRule = 3,
@@ -56,12 +55,24 @@ class CORE_EXPORT CSSRule : public ScriptWrappable {
kNamespaceRule = 10,
kSupportsRule = 12,
kViewportRule = 15,
- kPropertyRule = 18,
- // Experimental features below. Such features must be greater than 1000:
- // the 0-1000 range is reserved by the CSS Working Group.
+ // CSSOM constants are deprecated [1], and there will be no new
+ // web-exposed values.
+ //
+ // [1] https://wiki.csswg.org/spec/cssom-constants
+
+ // Values for internal use, not web-exposed:
+ kPropertyRule = 16,
+ kScrollTimelineRule = 17,
};
- virtual Type type() const = 0;
+ virtual Type GetType() const = 0;
+
+ // https://drafts.csswg.org/cssom/#dom-cssrule-type
+ int type() const {
+ Type type = GetType();
+ return type > Type::kViewportRule ? 0 : static_cast<int>(type);
+ }
+
virtual String cssText() const = 0;
virtual void Reattach(StyleRuleBase*) = 0;
@@ -71,7 +82,7 @@ class CORE_EXPORT CSSRule : public ScriptWrappable {
void SetParentRule(CSSRule*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
CSSStyleSheet* parentStyleSheet() const {
if (parent_is_rule_)
diff --git a/chromium/third_party/blink/renderer/core/css/css_rule.idl b/chromium/third_party/blink/renderer/core/css/css_rule.idl
index 24c7dc13a96..00c3aec2090 100644
--- a/chromium/third_party/blink/renderer/core/css/css_rule.idl
+++ b/chromium/third_party/blink/renderer/core/css/css_rule.idl
@@ -45,8 +45,4 @@
// CSS Conditional Rules
// https://drafts.csswg.org/css-conditional/#extentions-to-cssrule-interface
const unsigned short SUPPORTS_RULE = 12;
-
- // CSS Properties and Values Level 1
- // https://drafts.css-houdini.org/css-properties-values-api/#extensions-to-css-rule-interface
- [RuntimeEnabled=CSSVariables2AtProperty] const unsigned short PROPERTY_RULE = 18;
};
diff --git a/chromium/third_party/blink/renderer/core/css/css_rule_list.h b/chromium/third_party/blink/renderer/core/css/css_rule_list.h
index 52fce745177..5b7d821a241 100644
--- a/chromium/third_party/blink/renderer/core/css/css_rule_list.h
+++ b/chromium/third_party/blink/renderer/core/css/css_rule_list.h
@@ -56,7 +56,7 @@ class LiveCSSRuleList final : public CSSRuleList {
public:
LiveCSSRuleList(Rule* rule) : rule_(rule) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(rule_);
CSSRuleList::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_scroll_timeline_rule.cc b/chromium/third_party/blink/renderer/core/css/css_scroll_timeline_rule.cc
new file mode 100644
index 00000000000..80f787d9ce8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/css_scroll_timeline_rule.cc
@@ -0,0 +1,67 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/css/css_scroll_timeline_rule.h"
+
+#include "third_party/blink/renderer/core/css/style_rule.h"
+
+namespace blink {
+
+CSSScrollTimelineRule::CSSScrollTimelineRule(
+ StyleRuleScrollTimeline* scroll_timeline_rule,
+ CSSStyleSheet* sheet)
+ : CSSRule(sheet), scroll_timeline_rule_(scroll_timeline_rule) {}
+
+CSSScrollTimelineRule::~CSSScrollTimelineRule() = default;
+
+String CSSScrollTimelineRule::cssText() const {
+ // TODO(crbug.com/1096420): Implement
+ return "";
+}
+
+void CSSScrollTimelineRule::Reattach(StyleRuleBase* rule) {
+ DCHECK(rule);
+ scroll_timeline_rule_ = To<StyleRuleScrollTimeline>(rule);
+}
+
+String CSSScrollTimelineRule::name() const {
+ return scroll_timeline_rule_->GetName();
+}
+
+String CSSScrollTimelineRule::source() const {
+ if (const CSSValue* source = scroll_timeline_rule_->GetSource())
+ return source->CssText();
+ return "none";
+}
+
+String CSSScrollTimelineRule::orientation() const {
+ if (const CSSValue* orientation = scroll_timeline_rule_->GetOrientation())
+ return orientation->CssText();
+ return "auto";
+}
+
+String CSSScrollTimelineRule::start() const {
+ if (const CSSValue* start = scroll_timeline_rule_->GetStart())
+ return start->CssText();
+ return "auto";
+}
+
+String CSSScrollTimelineRule::end() const {
+ if (const CSSValue* end = scroll_timeline_rule_->GetEnd())
+ return end->CssText();
+ return "auto";
+}
+
+String CSSScrollTimelineRule::timeRange() const {
+ if (const CSSValue* range = scroll_timeline_rule_->GetTimeRange())
+ return range->CssText();
+ return "auto";
+}
+
+void CSSScrollTimelineRule::Trace(Visitor* visitor) const {
+ visitor->Trace(scroll_timeline_rule_);
+ CSSRule::Trace(visitor);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/css_scroll_timeline_rule.h b/chromium/third_party/blink/renderer/core/css/css_scroll_timeline_rule.h
new file mode 100644
index 00000000000..0ed72c43648
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/css_scroll_timeline_rule.h
@@ -0,0 +1,50 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_SCROLL_TIMELINE_RULE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_SCROLL_TIMELINE_RULE_H_
+
+#include "third_party/blink/renderer/core/css/css_rule.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
+
+namespace blink {
+
+class StyleRuleScrollTimeline;
+
+class CSSScrollTimelineRule final : public CSSRule {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ CSSScrollTimelineRule(StyleRuleScrollTimeline*, CSSStyleSheet*);
+ ~CSSScrollTimelineRule() override;
+
+ String cssText() const override;
+ void Reattach(StyleRuleBase*) override;
+
+ String name() const;
+ String source() const;
+ String orientation() const;
+ String start() const;
+ String end() const;
+ String timeRange() const;
+
+ void Trace(Visitor*) const override;
+
+ private:
+ CSSRule::Type GetType() const override { return kScrollTimelineRule; }
+
+ Member<StyleRuleScrollTimeline> scroll_timeline_rule_;
+};
+
+template <>
+struct DowncastTraits<CSSScrollTimelineRule> {
+ static bool AllowFrom(const CSSRule& rule) {
+ return rule.GetType() == CSSRule::kScrollTimelineRule;
+ }
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_SCROLL_TIMELINE_RULE_H_
diff --git a/chromium/third_party/blink/renderer/core/css/css_scroll_timeline_rule.idl b/chromium/third_party/blink/renderer/core/css/css_scroll_timeline_rule.idl
new file mode 100644
index 00000000000..ed94826a594
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/css_scroll_timeline_rule.idl
@@ -0,0 +1,15 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ Exposed=Window,
+ RuntimeEnabled=CSSScrollTimeline
+] interface CSSScrollTimelineRule : CSSRule {
+ readonly attribute CSSOMString name;
+ readonly attribute CSSOMString source;
+ readonly attribute CSSOMString orientation;
+ readonly attribute CSSOMString start;
+ readonly attribute CSSOMString end;
+ readonly attribute CSSOMString timeRange;
+};
diff --git a/chromium/third_party/blink/renderer/core/css/css_segmented_font_face.cc b/chromium/third_party/blink/renderer/core/css/css_segmented_font_face.cc
index d905879ef94..815e0c4ffa7 100644
--- a/chromium/third_party/blink/renderer/core/css/css_segmented_font_face.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_segmented_font_face.cc
@@ -228,7 +228,7 @@ void CSSSegmentedFontFace::Match(const String& text,
text, WrapPersistent(faces)));
}
-void CSSSegmentedFontFace::Trace(Visitor* visitor) {
+void CSSSegmentedFontFace::Trace(Visitor* visitor) const {
visitor->Trace(font_faces_);
}
@@ -338,7 +338,7 @@ void FontFaceList::ForEachReverse(
ForEachReverseUntilTrue(false_returning_callback);
}
-void FontFaceList::Trace(Visitor* visitor) {
+void FontFaceList::Trace(Visitor* visitor) const {
visitor->Trace(css_connected_face_);
visitor->Trace(non_css_connected_face_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_segmented_font_face.h b/chromium/third_party/blink/renderer/core/css/css_segmented_font_face.h
index 84da73e58f2..3e4b7356b92 100644
--- a/chromium/third_party/blink/renderer/core/css/css_segmented_font_face.h
+++ b/chromium/third_party/blink/renderer/core/css/css_segmented_font_face.h
@@ -77,7 +77,7 @@ class FontFaceList : public GarbageCollected<FontFaceList> {
void ForEachReverse(
const base::RepeatingCallback<void(Member<FontFace>)>& callback) const;
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
private:
FontFaceListPart css_connected_face_;
@@ -112,7 +112,7 @@ class CSSSegmentedFontFace final
return approximate_character_count_;
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void PruneTable();
diff --git a/chromium/third_party/blink/renderer/core/css/css_selector.cc b/chromium/third_party/blink/renderer/core/css/css_selector.cc
index fdda0d6e98b..db4f189ea5e 100644
--- a/chromium/third_party/blink/renderer/core/css/css_selector.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_selector.cc
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/core/css/css_selector_list.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/pseudo_element.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -189,9 +190,7 @@ PseudoId CSSSelector::GetPseudoId(PseudoType type) {
case kPseudoAfter:
return kPseudoIdAfter;
case kPseudoMarker:
- return RuntimeEnabledFeatures::CSSMarkerPseudoElementEnabled()
- ? kPseudoIdMarker
- : kPseudoIdNone;
+ return kPseudoIdMarker;
case kPseudoBackdrop:
return kPseudoIdBackdrop;
case kPseudoScrollbar:
@@ -523,11 +522,14 @@ CSSSelector::PseudoType CSSSelector::ParsePseudoType(const AtomicString& name,
return kPseudoUnknown;
}
-PseudoId CSSSelector::ParsePseudoId(const String& name) {
+PseudoId CSSSelector::ParsePseudoId(const String& name, const Node* parent) {
unsigned name_without_colons_start =
name[0] == ':' ? (name[1] == ':' ? 2 : 1) : 0;
- return GetPseudoId(ParsePseudoType(
+ PseudoId pseudo_id = GetPseudoId(ParsePseudoType(
AtomicString(name.Substring(name_without_colons_start)), false));
+ if (!PseudoElement::IsWebExposed(pseudo_id, parent))
+ return kPseudoIdNone;
+ return pseudo_id;
}
void CSSSelector::UpdatePseudoPage(const AtomicString& value) {
@@ -1092,7 +1094,7 @@ bool CSSSelector::IsAllowedAfterPart() const {
if (Match() != CSSSelector::kPseudoElement) {
return false;
}
- // Everything that makes sense should work following ::part. This whitelist
+ // Everything that makes sense should work following ::part. This list
// restricts it to what has been tested.
switch (GetPseudoType()) {
case kPseudoBefore:
diff --git a/chromium/third_party/blink/renderer/core/css/css_selector.h b/chromium/third_party/blink/renderer/core/css/css_selector.h
index 4e63bd24291..a85d8ee4295 100644
--- a/chromium/third_party/blink/renderer/core/css/css_selector.h
+++ b/chromium/third_party/blink/renderer/core/css/css_selector.h
@@ -34,6 +34,7 @@ namespace blink {
class CSSParserContext;
class CSSSelectorList;
+class Node;
// This class represents a simple selector for a StyleRule.
@@ -272,7 +273,7 @@ class CORE_EXPORT CSSSelector {
void UpdatePseudoPage(const AtomicString&);
static PseudoType ParsePseudoType(const AtomicString&, bool has_arguments);
- static PseudoId ParsePseudoId(const String&);
+ static PseudoId ParsePseudoId(const String&, const Node*);
static PseudoId GetPseudoId(PseudoType);
// Selectors are kept in an array by CSSSelectorList. The next component of
diff --git a/chromium/third_party/blink/renderer/core/css/css_selector_watch.cc b/chromium/third_party/blink/renderer/core/css/css_selector_watch.cc
index 44e63a470b9..efb35dcaad3 100644
--- a/chromium/third_party/blink/renderer/core/css/css_selector_watch.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_selector_watch.cc
@@ -171,7 +171,7 @@ void CSSSelectorWatch::WatchCSSSelectors(const Vector<String>& selectors) {
GetSupplementable()->GetStyleEngine().WatchedSelectorsChanged();
}
-void CSSSelectorWatch::Trace(Visitor* visitor) {
+void CSSSelectorWatch::Trace(Visitor* visitor) const {
visitor->Trace(watched_callback_selectors_);
Supplement<Document>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_selector_watch.h b/chromium/third_party/blink/renderer/core/css/css_selector_watch.h
index 059fd4c0138..5f498a5efe9 100644
--- a/chromium/third_party/blink/renderer/core/css/css_selector_watch.h
+++ b/chromium/third_party/blink/renderer/core/css/css_selector_watch.h
@@ -64,7 +64,7 @@ class CORE_EXPORT CSSSelectorWatch final
void UpdateSelectorMatches(const Vector<String>& removed_selectors,
const Vector<String>& added_selectors);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void CallbackSelectorChangeTimerFired(TimerBase*);
diff --git a/chromium/third_party/blink/renderer/core/css/css_string_value.h b/chromium/third_party/blink/renderer/core/css/css_string_value.h
index 2641f37aa26..7c9d034c9d8 100644
--- a/chromium/third_party/blink/renderer/core/css/css_string_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_string_value.h
@@ -11,7 +11,7 @@
namespace blink {
-class CSSStringValue : public CSSValue {
+class CORE_EXPORT CSSStringValue : public CSSValue {
public:
CSSStringValue(const String&);
diff --git a/chromium/third_party/blink/renderer/core/css/css_style_declaration.cc b/chromium/third_party/blink/renderer/core/css/css_style_declaration.cc
index 5ab57f1fb4e..583eec44cc1 100644
--- a/chromium/third_party/blink/renderer/core/css/css_style_declaration.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_style_declaration.cc
@@ -151,7 +151,7 @@ CSSPropertyID CssPropertyInfo(const ExecutionContext* execution_context,
} // namespace
-void CSSStyleDeclaration::Trace(Visitor* visitor) {
+void CSSStyleDeclaration::Trace(Visitor* visitor) const {
ExecutionContextClient::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_style_declaration.h b/chromium/third_party/blink/renderer/core/css/css_style_declaration.h
index ad53e5b954a..a0872c9a73d 100644
--- a/chromium/third_party/blink/renderer/core/css/css_style_declaration.h
+++ b/chromium/third_party/blink/renderer/core/css/css_style_declaration.h
@@ -47,7 +47,7 @@ class CORE_EXPORT CSSStyleDeclaration : public ScriptWrappable,
public:
~CSSStyleDeclaration() override = default;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
virtual CSSRule* parentRule() const = 0;
String cssFloat() { return GetPropertyValueInternal(CSSPropertyID::kFloat); }
diff --git a/chromium/third_party/blink/renderer/core/css/css_style_declaration_test.cc b/chromium/third_party/blink/renderer/core/css/css_style_declaration_test.cc
index 5bfe780b1f9..9d01697e9d6 100644
--- a/chromium/third_party/blink/renderer/core/css/css_style_declaration_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_style_declaration_test.cc
@@ -20,7 +20,7 @@ TEST(CSSStyleDeclarationTest, getPropertyShorthand) {
sheet.AddCSSRules("div { padding: var(--p); }");
ASSERT_TRUE(sheet.CssRules());
ASSERT_EQ(1u, sheet.CssRules()->length());
- ASSERT_EQ(CSSRule::kStyleRule, sheet.CssRules()->item(0)->type());
+ ASSERT_EQ(CSSRule::kStyleRule, sheet.CssRules()->item(0)->GetType());
CSSStyleRule* style_rule = To<CSSStyleRule>(sheet.CssRules()->item(0));
CSSStyleDeclaration* style = style_rule->style();
ASSERT_TRUE(style);
diff --git a/chromium/third_party/blink/renderer/core/css/css_style_rule.cc b/chromium/third_party/blink/renderer/core/css/css_style_rule.cc
index 0cfed7f3602..60d8d0292b6 100644
--- a/chromium/third_party/blink/renderer/core/css/css_style_rule.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_style_rule.cc
@@ -110,7 +110,7 @@ void CSSStyleRule::Reattach(StyleRuleBase* rule) {
properties_cssom_wrapper_->Reattach(style_rule_->MutableProperties());
}
-void CSSStyleRule::Trace(Visitor* visitor) {
+void CSSStyleRule::Trace(Visitor* visitor) const {
visitor->Trace(style_rule_);
visitor->Trace(properties_cssom_wrapper_);
visitor->Trace(style_map_);
diff --git a/chromium/third_party/blink/renderer/core/css/css_style_rule.h b/chromium/third_party/blink/renderer/core/css/css_style_rule.h
index a4e648bb88a..3b0233f9ffc 100644
--- a/chromium/third_party/blink/renderer/core/css/css_style_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/css_style_rule.h
@@ -54,10 +54,10 @@ class CORE_EXPORT CSSStyleRule final : public CSSRule {
// FIXME: Not CSSOM. Remove.
StyleRule* GetStyleRule() const { return style_rule_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
- CSSRule::Type type() const override { return kStyleRule; }
+ CSSRule::Type GetType() const override { return kStyleRule; }
Member<StyleRule> style_rule_;
mutable Member<StyleRuleCSSStyleDeclaration> properties_cssom_wrapper_;
@@ -67,7 +67,7 @@ class CORE_EXPORT CSSStyleRule final : public CSSRule {
template <>
struct DowncastTraits<CSSStyleRule> {
static bool AllowFrom(const CSSRule& rule) {
- return rule.type() == CSSRule::kStyleRule;
+ return rule.GetType() == CSSRule::kStyleRule;
}
};
diff --git a/chromium/third_party/blink/renderer/core/css/css_style_sheet.cc b/chromium/third_party/blink/renderer/core/css/css_style_sheet.cc
index f3779c87812..c168b0a2448 100644
--- a/chromium/third_party/blink/renderer/core/css/css_style_sheet.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_style_sheet.cc
@@ -56,7 +56,7 @@ class StyleSheetCSSRuleList final : public CSSRuleList {
public:
StyleSheetCSSRuleList(CSSStyleSheet* sheet) : style_sheet_(sheet) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(style_sheet_);
CSSRuleList::Trace(visitor);
}
@@ -226,6 +226,8 @@ void CSSStyleSheet::DidMutateRules() {
resolver->InvalidateMatchedPropertiesCache();
}
}
+
+ probe::DidMutateStyleSheet(OwnerDocument(), this);
}
void CSSStyleSheet::DidMutate() {
@@ -632,7 +634,7 @@ bool CSSStyleSheet::CanBeActivated(
return true;
}
-void CSSStyleSheet::Trace(Visitor* visitor) {
+void CSSStyleSheet::Trace(Visitor* visitor) const {
visitor->Trace(contents_);
visitor->Trace(owner_node_);
visitor->Trace(owner_rule_);
diff --git a/chromium/third_party/blink/renderer/core/css/css_style_sheet.h b/chromium/third_party/blink/renderer/core/css/css_style_sheet.h
index 238b5d2ddcf..2b23c8ab4c7 100644
--- a/chromium/third_party/blink/renderer/core/css/css_style_sheet.h
+++ b/chromium/third_party/blink/renderer/core/css/css_style_sheet.h
@@ -205,7 +205,7 @@ class CORE_EXPORT CSSStyleSheet final : public StyleSheet {
bool IsConstructed() { return is_constructed_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool IsAlternate() const;
diff --git a/chromium/third_party/blink/renderer/core/css/css_supports_rule.h b/chromium/third_party/blink/renderer/core/css/css_supports_rule.h
index a946911c35d..a15d68b3e4a 100644
--- a/chromium/third_party/blink/renderer/core/css/css_supports_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/css_supports_rule.h
@@ -46,13 +46,13 @@ class CSSSupportsRule final : public CSSConditionRule {
String cssText() const override;
private:
- CSSRule::Type type() const override { return kSupportsRule; }
+ CSSRule::Type GetType() const override { return kSupportsRule; }
};
template <>
struct DowncastTraits<CSSSupportsRule> {
static bool AllowFrom(const CSSRule& rule) {
- return rule.type() == CSSRule::kSupportsRule;
+ return rule.GetType() == CSSRule::kSupportsRule;
}
};
diff --git a/chromium/third_party/blink/renderer/core/css/css_syntax_definition.cc b/chromium/third_party/blink/renderer/core/css/css_syntax_definition.cc
index a3dc48a5378..9a09c65ec41 100644
--- a/chromium/third_party/blink/renderer/core/css/css_syntax_definition.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_syntax_definition.cc
@@ -11,8 +11,8 @@
#include "third_party/blink/renderer/core/css/css_value_list.h"
#include "third_party/blink/renderer/core/css/css_variable_reference_value.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_idioms.h"
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
#include "third_party/blink/renderer/core/css/parser/css_variable_parser.h"
+#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -29,8 +29,8 @@ namespace {
bool IsReservedIdentToken(const CSSParserToken& token) {
if (token.GetType() != kIdentToken)
return false;
- return css_property_parser_helpers::IsRevertKeyword(token.Value()) ||
- css_property_parser_helpers::IsDefaultKeyword(token.Value());
+ return css_parsing_utils::IsRevertKeyword(token.Value()) ||
+ css_parsing_utils::IsDefaultKeyword(token.Value());
}
bool CouldConsumeReservedKeyword(CSSParserTokenRange range) {
@@ -55,51 +55,50 @@ const CSSValue* ConsumeSingleType(const CSSSyntaxComponent& syntax,
case CSSSyntaxType::kLength: {
CSSParserContext::ParserModeOverridingScope scope(context,
kHTMLStandardMode);
- return css_property_parser_helpers::ConsumeLength(
- range, context, ValueRange::kValueRangeAll);
+ return css_parsing_utils::ConsumeLength(range, context,
+ ValueRange::kValueRangeAll);
}
case CSSSyntaxType::kNumber:
- return css_property_parser_helpers::ConsumeNumber(
- range, context, ValueRange::kValueRangeAll);
+ return css_parsing_utils::ConsumeNumber(range, context,
+ ValueRange::kValueRangeAll);
case CSSSyntaxType::kPercentage:
- return css_property_parser_helpers::ConsumePercent(
- range, context, ValueRange::kValueRangeAll);
+ return css_parsing_utils::ConsumePercent(range, context,
+ ValueRange::kValueRangeAll);
case CSSSyntaxType::kLengthPercentage: {
CSSParserContext::ParserModeOverridingScope scope(context,
kHTMLStandardMode);
- return css_property_parser_helpers::ConsumeLengthOrPercent(
+ return css_parsing_utils::ConsumeLengthOrPercent(
range, context, ValueRange::kValueRangeAll);
}
case CSSSyntaxType::kColor: {
CSSParserContext::ParserModeOverridingScope scope(context,
kHTMLStandardMode);
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
case CSSSyntaxType::kImage:
- return css_property_parser_helpers::ConsumeImage(range, context);
+ return css_parsing_utils::ConsumeImage(range, context);
case CSSSyntaxType::kUrl:
- return css_property_parser_helpers::ConsumeUrl(range, context);
+ return css_parsing_utils::ConsumeUrl(range, context);
case CSSSyntaxType::kInteger:
- return css_property_parser_helpers::ConsumeIntegerOrNumberCalc(range,
- context);
+ return css_parsing_utils::ConsumeIntegerOrNumberCalc(range, context);
case CSSSyntaxType::kAngle:
- return css_property_parser_helpers::ConsumeAngle(
- range, context, base::Optional<WebFeature>());
+ return css_parsing_utils::ConsumeAngle(range, context,
+ base::Optional<WebFeature>());
case CSSSyntaxType::kTime:
- return css_property_parser_helpers::ConsumeTime(
- range, context, ValueRange::kValueRangeAll);
+ return css_parsing_utils::ConsumeTime(range, context,
+ ValueRange::kValueRangeAll);
case CSSSyntaxType::kResolution:
- return css_property_parser_helpers::ConsumeResolution(range);
+ return css_parsing_utils::ConsumeResolution(range);
case CSSSyntaxType::kTransformFunction:
- return css_property_parser_helpers::ConsumeTransformValue(range, context);
+ return css_parsing_utils::ConsumeTransformValue(range, context);
case CSSSyntaxType::kTransformList:
- return css_property_parser_helpers::ConsumeTransformList(range, context);
+ return css_parsing_utils::ConsumeTransformList(range, context);
case CSSSyntaxType::kCustomIdent:
// TODO(crbug.com/579788): Implement 'revert'.
// TODO(crbug.com/882285): Make 'default' invalid as <custom-ident>.
if (IsReservedIdentToken(range.Peek()))
return nullptr;
- return css_property_parser_helpers::ConsumeCustomIdent(range, context);
+ return css_parsing_utils::ConsumeCustomIdent(range, context);
default:
NOTREACHED();
return nullptr;
@@ -127,8 +126,7 @@ const CSSValue* ConsumeSyntaxComponent(const CSSSyntaxComponent& syntax,
if (!value)
return nullptr;
list->Append(*value);
- } while (
- css_property_parser_helpers::ConsumeCommaIncludingWhitespace(range));
+ } while (css_parsing_utils::ConsumeCommaIncludingWhitespace(range));
return list->length() ? list : nullptr;
}
const CSSValue* result = ConsumeSingleType(syntax, range, context);
diff --git a/chromium/third_party/blink/renderer/core/css/css_syntax_string_parser.cc b/chromium/third_party/blink/renderer/core/css/css_syntax_string_parser.cc
index a045ab45f32..de743baf7d8 100644
--- a/chromium/third_party/blink/renderer/core/css/css_syntax_string_parser.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_syntax_string_parser.cc
@@ -7,7 +7,7 @@
#include <utility>
#include "third_party/blink/renderer/core/css/css_syntax_component.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_idioms.h"
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -151,9 +151,9 @@ bool CSSSyntaxStringParser::ConsumeDataTypeName(CSSSyntaxType& type) {
bool CSSSyntaxStringParser::ConsumeIdent(String& ident) {
ident = ConsumeName(input_);
// TODO(crbug.com/882285): Make 'default' invalid as <custom-ident>.
- return !css_property_parser_helpers::IsCSSWideKeyword(ident) &&
- !css_property_parser_helpers::IsRevertKeyword(ident) &&
- !css_property_parser_helpers::IsDefaultKeyword(ident);
+ return !css_parsing_utils::IsCSSWideKeyword(ident) &&
+ !css_parsing_utils::IsRevertKeyword(ident) &&
+ !css_parsing_utils::IsDefaultKeyword(ident);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/css_test_helpers.cc b/chromium/third_party/blink/renderer/core/css/css_test_helpers.cc
index e0e74d3da07..51372b85e38 100644
--- a/chromium/third_party/blink/renderer/core/css/css_test_helpers.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_test_helpers.cc
@@ -34,7 +34,7 @@ namespace css_test_helpers {
TestStyleSheet::~TestStyleSheet() = default;
TestStyleSheet::TestStyleSheet() {
- document_ = MakeGarbageCollected<Document>();
+ document_ = Document::CreateForTest();
TextPosition position;
style_sheet_ = CSSStyleSheet::CreateInline(*document_, NullURL(), position,
UTF8Encoding());
@@ -49,7 +49,7 @@ CSSRuleList* TestStyleSheet::CssRules() {
RuleSet& TestStyleSheet::GetRuleSet() {
RuleSet& rule_set = style_sheet_->Contents()->EnsureRuleSet(
- MediaQueryEvaluator(), kRuleHasNoSpecialState);
+ MediaQueryEvaluator(document_->GetFrame()), kRuleHasNoSpecialState);
rule_set.CompactRulesIfNeeded();
return rule_set;
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_value.cc b/chromium/third_party/blink/renderer/core/css/css_value.cc
index 91576fbf13f..62d05415504 100644
--- a/chromium/third_party/blink/renderer/core/css/css_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_value.cc
@@ -47,10 +47,12 @@
#include "third_party/blink/renderer/core/css/css_grid_integer_repeat_value.h"
#include "third_party/blink/renderer/core/css/css_grid_line_names_value.h"
#include "third_party/blink/renderer/core/css/css_grid_template_areas_value.h"
+#include "third_party/blink/renderer/core/css/css_id_selector_value.h"
#include "third_party/blink/renderer/core/css/css_identifier_value.h"
#include "third_party/blink/renderer/core/css/css_image_set_value.h"
#include "third_party/blink/renderer/core/css/css_image_value.h"
#include "third_party/blink/renderer/core/css/css_inherited_value.h"
+#include "third_party/blink/renderer/core/css/css_initial_color_value.h"
#include "third_party/blink/renderer/core/css/css_initial_value.h"
#include "third_party/blink/renderer/core/css/css_invalid_variable_value.h"
#include "third_party/blink/renderer/core/css/css_keyframe_shorthand_value.h"
@@ -100,6 +102,7 @@ CSSValue* CSSValue::Create(const Length& value, float zoom) {
return CSSPrimitiveValue::CreateFromLength(value, zoom);
case Length::kDeviceWidth:
case Length::kDeviceHeight:
+ case Length::kMinIntrinsic:
case Length::kNone:
NOTREACHED();
break;
@@ -237,6 +240,8 @@ bool CSSValue::operator==(const CSSValue& other) const {
return CompareCSSValues<CSSIdentifierValue>(*this, other);
case kKeyframeShorthandClass:
return CompareCSSValues<CSSKeyframeShorthandValue>(*this, other);
+ case kInitialColorValueClass:
+ return CompareCSSValues<CSSInitialColorValue>(*this, other);
case kQuadClass:
return CompareCSSValues<CSSQuadValue>(*this, other);
case kReflectClass:
@@ -275,6 +280,8 @@ bool CSSValue::operator==(const CSSValue& other) const {
return CompareCSSValues<CSSInvalidVariableValue>(*this, other);
case kLightDarkValuePairClass:
return CompareCSSValues<CSSLightDarkValuePair>(*this, other);
+ case kIdSelectorClass:
+ return CompareCSSValues<cssvalue::CSSIdSelectorValue>(*this, other);
}
NOTREACHED();
return false;
@@ -358,6 +365,8 @@ String CSSValue::CssText() const {
return To<CSSIdentifierValue>(this)->CustomCSSText();
case kKeyframeShorthandClass:
return To<CSSKeyframeShorthandValue>(this)->CustomCSSText();
+ case kInitialColorValueClass:
+ return To<CSSInitialColorValue>(this)->CustomCSSText();
case kQuadClass:
return To<CSSQuadValue>(this)->CustomCSSText();
case kReflectClass:
@@ -393,6 +402,8 @@ String CSSValue::CssText() const {
return To<CSSInvalidVariableValue>(this)->CustomCSSText();
case kLightDarkValuePairClass:
return To<CSSLightDarkValuePair>(this)->CustomCSSText();
+ case kIdSelectorClass:
+ return To<cssvalue::CSSIdSelectorValue>(this)->CustomCSSText();
}
NOTREACHED();
return String();
@@ -515,6 +526,9 @@ void CSSValue::FinalizeGarbageCollectedObject() {
case kKeyframeShorthandClass:
To<CSSKeyframeShorthandValue>(this)->~CSSKeyframeShorthandValue();
return;
+ case kInitialColorValueClass:
+ To<CSSInitialColorValue>(this)->~CSSInitialColorValue();
+ return;
case kQuadClass:
To<CSSQuadValue>(this)->~CSSQuadValue();
return;
@@ -570,11 +584,14 @@ void CSSValue::FinalizeGarbageCollectedObject() {
case kLightDarkValuePairClass:
To<CSSLightDarkValuePair>(this)->~CSSLightDarkValuePair();
return;
+ case kIdSelectorClass:
+ To<cssvalue::CSSIdSelectorValue>(this)->~CSSIdSelectorValue();
+ return;
}
NOTREACHED();
}
-void CSSValue::Trace(Visitor* visitor) {
+void CSSValue::Trace(Visitor* visitor) const {
switch (GetClassType()) {
case kAxisClass:
To<cssvalue::CSSAxisValue>(this)->TraceAfterDispatch(visitor);
@@ -691,6 +708,9 @@ void CSSValue::Trace(Visitor* visitor) {
case kKeyframeShorthandClass:
To<CSSKeyframeShorthandValue>(this)->TraceAfterDispatch(visitor);
return;
+ case kInitialColorValueClass:
+ To<CSSInitialColorValue>(this)->TraceAfterDispatch(visitor);
+ return;
case kQuadClass:
To<CSSQuadValue>(this)->TraceAfterDispatch(visitor);
return;
@@ -746,6 +766,9 @@ void CSSValue::Trace(Visitor* visitor) {
case kLightDarkValuePairClass:
To<CSSLightDarkValuePair>(this)->TraceAfterDispatch(visitor);
return;
+ case kIdSelectorClass:
+ To<cssvalue::CSSIdSelectorValue>(this)->TraceAfterDispatch(visitor);
+ return;
}
NOTREACHED();
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_value.h b/chromium/third_party/blink/renderer/core/css/css_value.h
index 521575903e5..e7d01a74cdf 100644
--- a/chromium/third_party/blink/renderer/core/css/css_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_value.h
@@ -170,19 +170,24 @@ class CORE_EXPORT CSSValue : public GarbageCollected<CSSValue> {
bool IsShorthandWrapperValue() const {
return class_type_ == kKeyframeShorthandClass;
}
+ bool IsInitialColorValue() const {
+ return class_type_ == kInitialColorValueClass;
+ }
bool IsLightDarkValuePair() const {
return class_type_ == kLightDarkValuePairClass;
}
+ bool IsIdSelectorValue() const { return class_type_ == kIdSelectorClass; }
bool HasFailedOrCanceledSubresources() const;
bool MayContainUrl() const;
void ReResolveUrl(const Document&) const;
bool operator==(const CSSValue&) const;
+ bool operator!=(const CSSValue& o) const { return !(*this == o); }
void FinalizeGarbageCollectedObject();
void TraceAfterDispatch(blink::Visitor* visitor) const {}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// ~CSSValue should be public, because non-public ~CSSValue causes C2248
// error: 'blink::CSSValue::~CSSValue' : cannot access protected member
@@ -203,6 +208,7 @@ class CORE_EXPORT CSSValue : public GarbageCollected<CSSValue> {
kURIClass,
kValuePairClass,
kLightDarkValuePairClass,
+ kIdSelectorClass,
// Basic shape classes.
// TODO(sashab): Represent these as a single subclass, BasicShapeClass.
@@ -254,6 +260,7 @@ class CORE_EXPORT CSSValue : public GarbageCollected<CSSValue> {
kCSSContentDistributionClass,
kKeyframeShorthandClass,
+ kInitialColorValueClass,
// List class types must appear after ValueListClass.
kValueListClass,
diff --git a/chromium/third_party/blink/renderer/core/css/css_value_id_mappings.h b/chromium/third_party/blink/renderer/core/css/css_value_id_mappings.h
index ccc3d93dc50..3eb682851c7 100644
--- a/chromium/third_party/blink/renderer/core/css/css_value_id_mappings.h
+++ b/chromium/third_party/blink/renderer/core/css/css_value_id_mappings.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_VALUE_ID_MAPPINGS_H_
#include "third_party/blink/renderer/core/css/css_value_id_mappings_generated.h"
+#include "third_party/blink/renderer/core/style/computed_style_constants.h"
namespace blink {
@@ -502,6 +503,23 @@ inline PageOrientation CssValueIDToPlatformEnum(CSSValueID v) {
return PageOrientation::kUpright;
}
+template <>
+inline ScrollbarGutter CssValueIDToPlatformEnum(CSSValueID v) {
+ if (v == CSSValueID::kAuto)
+ return kScrollbarGutterAuto;
+ if (v == CSSValueID::kStable)
+ return kScrollbarGutterStable;
+ if (v == CSSValueID::kAlways)
+ return kScrollbarGutterAlways;
+ if (v == CSSValueID::kBoth)
+ return kScrollbarGutterBoth;
+ if (v == CSSValueID::kForce)
+ return kScrollbarGutterForce;
+
+ NOTREACHED();
+ return kScrollbarGutterAuto;
+}
+
} // namespace blink
#endif
diff --git a/chromium/third_party/blink/renderer/core/css/css_value_keywords.json5 b/chromium/third_party/blink/renderer/core/css/css_value_keywords.json5
index 66b6f044cd1..28dd7ff4c08 100644
--- a/chromium/third_party/blink/renderer/core/css/css_value_keywords.json5
+++ b/chromium/third_party/blink/renderer/core/css/css_value_keywords.json5
@@ -1185,15 +1185,15 @@
"verso",
"avoid-column",
- // shape
- // rect
- // round
-
// color-gamut
// srgb
"p3",
"rec2020",
+ // math-script-level
+ "add",
+ "scriptlevel",
+
// overscroll-behavior
// auto,
// contain
@@ -1224,6 +1224,7 @@
"only",
// (prefers-reduced-motion:) media feature
+ // (prefers-reduced-data:) media feature
"reduce",
// (forced-colors:) media feature
@@ -1249,5 +1250,12 @@
// none
"single-fold-vertical",
"single-fold-horizontal",
+
+ // scrollbar-gutter
+ // auto
+ "stable",
+ // always
+ // both
+ "force",
],
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_value_pool.cc b/chromium/third_party/blink/renderer/core/css/css_value_pool.cc
index fa730f16c4b..7fdee1b81d8 100644
--- a/chromium/third_party/blink/renderer/core/css/css_value_pool.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_value_pool.cc
@@ -47,6 +47,8 @@ CSSValuePool::CSSValuePool()
unset_value_(MakeGarbageCollected<CSSUnsetValue>(PassKey())),
revert_value_(MakeGarbageCollected<CSSRevertValue>(PassKey())),
invalid_variable_value_(MakeGarbageCollected<CSSInvalidVariableValue>()),
+ initial_color_value_(
+ MakeGarbageCollected<CSSInitialColorValue>(PassKey())),
color_transparent_(
MakeGarbageCollected<cssvalue::CSSColorValue>(Color::kTransparent)),
color_white_(
@@ -59,12 +61,13 @@ CSSValuePool::CSSValuePool()
number_value_cache_.resize(kMaximumCacheableIntegerValue + 1);
}
-void CSSValuePool::Trace(Visitor* visitor) {
+void CSSValuePool::Trace(Visitor* visitor) const {
visitor->Trace(inherited_value_);
visitor->Trace(initial_value_);
visitor->Trace(unset_value_);
visitor->Trace(revert_value_);
visitor->Trace(invalid_variable_value_);
+ visitor->Trace(initial_color_value_);
visitor->Trace(color_transparent_);
visitor->Trace(color_white_);
visitor->Trace(color_black_);
diff --git a/chromium/third_party/blink/renderer/core/css/css_value_pool.h b/chromium/third_party/blink/renderer/core/css/css_value_pool.h
index 7d978f1c6b8..79d8a792c35 100644
--- a/chromium/third_party/blink/renderer/core/css/css_value_pool.h
+++ b/chromium/third_party/blink/renderer/core/css/css_value_pool.h
@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/core/css/css_font_family_value.h"
#include "third_party/blink/renderer/core/css/css_identifier_value.h"
#include "third_party/blink/renderer/core/css/css_inherited_value.h"
+#include "third_party/blink/renderer/core/css/css_initial_color_value.h"
#include "third_party/blink/renderer/core/css/css_initial_value.h"
#include "third_party/blink/renderer/core/css/css_invalid_variable_value.h"
#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
@@ -77,6 +78,7 @@ class CORE_EXPORT CSSValuePool final : public GarbageCollected<CSSValuePool> {
CSSInvalidVariableValue* InvalidVariableValue() {
return invalid_variable_value_;
}
+ CSSInitialColorValue* InitialColorValue() { return initial_color_value_; }
// Vector caches.
CSSIdentifierValue* IdentifierCacheValue(CSSValueID ident) {
@@ -130,7 +132,7 @@ class CORE_EXPORT CSSValuePool final : public GarbageCollected<CSSValuePool> {
return font_face_value_cache_.insert(string, nullptr);
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// Cached individual values.
@@ -139,6 +141,7 @@ class CORE_EXPORT CSSValuePool final : public GarbageCollected<CSSValuePool> {
Member<CSSUnsetValue> unset_value_;
Member<CSSRevertValue> revert_value_;
Member<CSSInvalidVariableValue> invalid_variable_value_;
+ Member<CSSInitialColorValue> initial_color_value_;
Member<CSSColorValue> color_transparent_;
Member<CSSColorValue> color_white_;
Member<CSSColorValue> color_black_;
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/README.md b/chromium/third_party/blink/renderer/core/css/cssom/README.md
index 688d207c927..04bcfba387e 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/README.md
+++ b/chromium/third_party/blink/renderer/core/css/cssom/README.md
@@ -1,6 +1,6 @@
# CSS Typed OM
-[Rendered](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/core/css/cssom/README.md)
+[Rendered](https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/renderer/core/css/cssom/README.md)
The `Source/core/css/cssom` directory contains the implementation of [CSS Typed OM](https://drafts.css-houdini.org/css-typed-om).
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/computed_style_property_map.h b/chromium/third_party/blink/renderer/core/css/cssom/computed_style_property_map.h
index 53733de72fa..eb0cd77a249 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/computed_style_property_map.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/computed_style_property_map.h
@@ -26,11 +26,10 @@ class CORE_EXPORT ComputedStylePropertyMap
: public StylePropertyMapReadOnlyMainThread {
public:
ComputedStylePropertyMap(Node* node, const String& pseudo_element = String())
- : StylePropertyMapReadOnlyMainThread(),
- pseudo_id_(CSSSelector::ParsePseudoId(pseudo_element)),
+ : pseudo_id_(CSSSelector::ParsePseudoId(pseudo_element, node)),
node_(node) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(node_);
StylePropertyMapReadOnlyMainThread::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_math_invert.h b/chromium/third_party/blink/renderer/core/css/cssom/css_math_invert.h
index 23816cd17c3..d9b53e05a14 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_math_invert.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_math_invert.h
@@ -39,7 +39,7 @@ class CORE_EXPORT CSSMathInvert : public CSSMathValue {
// From CSSStyleValue.
StyleValueType GetType() const final { return CSSStyleValue::kInvertType; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(value_);
CSSMathValue::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_math_negate.h b/chromium/third_party/blink/renderer/core/css/cssom/css_math_negate.h
index 977a7cd7b7d..7e4ff5a1510 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_math_negate.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_math_negate.h
@@ -38,7 +38,7 @@ class CORE_EXPORT CSSMathNegate : public CSSMathValue {
// From CSSStyleValue.
StyleValueType GetType() const final { return CSSStyleValue::kNegateType; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(value_);
CSSMathValue::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_math_variadic.h b/chromium/third_party/blink/renderer/core/css/cssom/css_math_variadic.h
index e6f714d03d3..8d5938e8dc6 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_math_variadic.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_math_variadic.h
@@ -21,7 +21,7 @@ class CORE_EXPORT CSSMathVariadic : public CSSMathValue {
return values_->Values();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(values_);
CSSMathValue::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_matrix_component.h b/chromium/third_party/blink/renderer/core/css/cssom/css_matrix_component.h
index 4f6287a7f17..00b1d2183d3 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_matrix_component.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_matrix_component.h
@@ -41,7 +41,7 @@ class CORE_EXPORT CSSMatrixComponent final : public CSSTransformComponent {
TransformComponentType GetType() const final { return kMatrixType; }
const CSSFunctionValue* ToCSSValue() const final;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(matrix_);
CSSTransformComponent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_array.h b/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_array.h
index 181c3882d76..ab67ababe85 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_array.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_array.h
@@ -24,7 +24,7 @@ class CORE_EXPORT CSSNumericArray final : public ScriptWrappable {
explicit CSSNumericArray(CSSNumericValueVector values)
: values_(std::move(values)) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(values_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_perspective.h b/chromium/third_party/blink/renderer/core/css/cssom/css_perspective.h
index fed2a88ed39..62b527f0442 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_perspective.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_perspective.h
@@ -45,7 +45,7 @@ class CORE_EXPORT CSSPerspective final : public CSSTransformComponent {
TransformComponentType GetType() const final { return kPerspectiveType; }
const CSSFunctionValue* ToCSSValue() const final;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(length_);
CSSTransformComponent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_position_value.h b/chromium/third_party/blink/renderer/core/css/cssom/css_position_value.h
index 464e1e37700..182427e6603 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_position_value.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_position_value.h
@@ -42,7 +42,7 @@ class CORE_EXPORT CSSPositionValue final : public CSSStyleValue {
const CSSValue* ToCSSValue() const final;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(x_);
visitor->Trace(y_);
CSSStyleValue::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_resource_value.h b/chromium/third_party/blink/renderer/core/css/cssom/css_resource_value.h
index e7e3f46401e..0bb34d6d4bd 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_resource_value.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_resource_value.h
@@ -32,7 +32,7 @@ class CORE_EXPORT CSSResourceValue : public CSSStyleValue {
}
}
- void Trace(Visitor* visitor) override { CSSStyleValue::Trace(visitor); }
+ void Trace(Visitor* visitor) const override { CSSStyleValue::Trace(visitor); }
protected:
CSSResourceValue() = default;
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_rotate.h b/chromium/third_party/blink/renderer/core/css/cssom/css_rotate.h
index cf22fa2e433..f6366232a5b 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_rotate.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_rotate.h
@@ -60,7 +60,7 @@ class CORE_EXPORT CSSRotate final : public CSSTransformComponent {
TransformComponentType GetType() const final { return kRotationType; }
const CSSFunctionValue* ToCSSValue() const final;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(angle_);
visitor->Trace(x_);
visitor->Trace(y_);
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_scale.h b/chromium/third_party/blink/renderer/core/css/cssom/css_scale.h
index 43c1adf6c5d..27e411c467e 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_scale.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_scale.h
@@ -62,7 +62,7 @@ class CORE_EXPORT CSSScale final : public CSSTransformComponent {
TransformComponentType GetType() const final { return kScaleType; }
const CSSFunctionValue* ToCSSValue() const final;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(z_);
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_skew.h b/chromium/third_party/blink/renderer/core/css/cssom/css_skew.h
index 2b0bf78633f..7e18a969853 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_skew.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_skew.h
@@ -49,7 +49,7 @@ class CORE_EXPORT CSSSkew final : public CSSTransformComponent {
TransformComponentType GetType() const override { return kSkewType; }
const CSSFunctionValue* ToCSSValue() const override;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(ax_);
visitor->Trace(ay_);
CSSTransformComponent::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_skew_x.h b/chromium/third_party/blink/renderer/core/css/cssom/css_skew_x.h
index 73b55695173..70089dc31a6 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_skew_x.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_skew_x.h
@@ -47,7 +47,7 @@ class CORE_EXPORT CSSSkewX final : public CSSTransformComponent {
TransformComponentType GetType() const override { return kSkewXType; }
const CSSFunctionValue* ToCSSValue() const override;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(ax_);
CSSTransformComponent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_skew_y.h b/chromium/third_party/blink/renderer/core/css/cssom/css_skew_y.h
index 1d7bc3257d3..9d215862f59 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_skew_y.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_skew_y.h
@@ -47,7 +47,7 @@ class CORE_EXPORT CSSSkewY final : public CSSTransformComponent {
TransformComponentType GetType() const override { return kSkewYType; }
const CSSFunctionValue* ToCSSValue() const override;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(ay_);
CSSTransformComponent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_style_image_value_test.cc b/chromium/third_party/blink/renderer/core/css/cssom/css_style_image_value_test.cc
index 09dee59da01..d66e57b1206 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_style_image_value_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_style_image_value_test.cc
@@ -25,7 +25,6 @@ class FakeCSSStyleImageValue : public CSSStyleImageValue {
// CanvasImageSource
scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*,
- AccelerationHint,
const FloatSize&) final {
return nullptr;
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_style_variable_reference_value.h b/chromium/third_party/blink/renderer/core/css/cssom/css_style_variable_reference_value.h
index 74b8914e3c0..606d25e1a00 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_style_variable_reference_value.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_style_variable_reference_value.h
@@ -42,7 +42,7 @@ class CORE_EXPORT CSSStyleVariableReferenceValue final
CSSUnparsedValue* fallback() { return fallback_.Get(); }
const CSSUnparsedValue* fallback() const { return fallback_.Get(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(fallback_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_transform_value.h b/chromium/third_party/blink/renderer/core/css/cssom/css_transform_value.h
index 7cfb9f5e02b..cfe761426f2 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_transform_value.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_transform_value.h
@@ -53,7 +53,7 @@ class CORE_EXPORT CSSTransformValue final : public CSSStyleValue {
wtf_size_t length() const { return transform_components_.size(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(transform_components_);
CSSStyleValue::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_translate.h b/chromium/third_party/blink/renderer/core/css/cssom/css_translate.h
index 24bc55a7ff1..d139df50668 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_translate.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_translate.h
@@ -59,7 +59,7 @@ class CORE_EXPORT CSSTranslate final : public CSSTransformComponent {
TransformComponentType GetType() const final { return kTranslationType; }
const CSSFunctionValue* ToCSSValue() const final;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(z_);
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h b/chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
index f567216c372..2ae0cea2aff 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
@@ -63,7 +63,7 @@ class CORE_EXPORT CSSUnparsedValue final : public CSSStyleValue {
wtf_size_t length() const { return tokens_.size(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(tokens_);
CSSStyleValue::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_url_image_value.cc b/chromium/third_party/blink/renderer/core/css/cssom/css_url_image_value.cc
index 4130f1cca56..3408e48ce11 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_url_image_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_url_image_value.cc
@@ -34,7 +34,6 @@ ResourceStatus CSSURLImageValue::Status() const {
scoped_refptr<Image> CSSURLImageValue::GetSourceImageForCanvas(
SourceImageStatus*,
- AccelerationHint,
const FloatSize&) {
return GetImage();
}
@@ -59,7 +58,7 @@ const CSSValue* CSSURLImageValue::ToCSSValue() const {
return value_;
}
-void CSSURLImageValue::Trace(Visitor* visitor) {
+void CSSURLImageValue::Trace(Visitor* visitor) const {
visitor->Trace(value_);
CSSStyleImageValue::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_url_image_value.h b/chromium/third_party/blink/renderer/core/css/cssom/css_url_image_value.h
index a941d43fb33..f15f2fb3245 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_url_image_value.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_url_image_value.h
@@ -24,7 +24,6 @@ class CORE_EXPORT CSSURLImageValue final : public CSSStyleImageValue {
// CanvasImageSource
ResourceStatus Status() const final;
scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*,
- AccelerationHint,
const FloatSize&) final;
bool IsAccelerated() const final;
@@ -32,7 +31,7 @@ class CORE_EXPORT CSSURLImageValue final : public CSSStyleImageValue {
StyleValueType GetType() const final { return kURLImageType; }
const CSSValue* ToCSSValue() const final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
scoped_refptr<Image> GetImage() const;
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/declared_style_property_map.h b/chromium/third_party/blink/renderer/core/css/cssom/declared_style_property_map.h
index 4bb264af0b5..195cd30587f 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/declared_style_property_map.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/declared_style_property_map.h
@@ -24,7 +24,7 @@ class CORE_EXPORT DeclaredStylePropertyMap final : public StylePropertyMap {
public:
explicit DeclaredStylePropertyMap(CSSStyleRule* owner_rule);
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(owner_rule_);
StylePropertyMap::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/inline_style_property_map.h b/chromium/third_party/blink/renderer/core/css/cssom/inline_style_property_map.h
index 1c02dd570c5..a15f466cb99 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/inline_style_property_map.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/inline_style_property_map.h
@@ -16,7 +16,7 @@ class CORE_EXPORT InlineStylePropertyMap final : public StylePropertyMap {
explicit InlineStylePropertyMap(Element* owner_element)
: owner_element_(owner_element) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(owner_element_);
StylePropertyMap::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/inline_style_property_map_test.cc b/chromium/third_party/blink/renderer/core/css/cssom/inline_style_property_map_test.cc
index 6ee90aaba8d..dabf73f7084 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/inline_style_property_map_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/inline_style_property_map_test.cc
@@ -16,7 +16,7 @@ TEST(InlineStylePropertyMapTest, PendingSubstitutionValueCrash) {
// Test that trying to reify any longhands with a CSSPendingSubstitutionValue
// does not cause a crash.
- Document* document = MakeGarbageCollected<Document>();
+ Document* document = Document::CreateForTest();
Element* div = document->CreateRawElement(html_names::kDivTag);
InlineStylePropertyMap map(div);
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.cc b/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.cc
index d9259c4f9fd..fd973714f46 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.cc
@@ -46,7 +46,7 @@ class PaintWorkletStylePropertyMapIterationSource final
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(values_);
PairIterable<String, CSSStyleValueVector>::IterationSource::Trace(visitor);
}
@@ -209,7 +209,7 @@ PaintWorkletStylePropertyMap::StartIteration(ScriptState* script_state,
result);
}
-void PaintWorkletStylePropertyMap::Trace(Visitor* visitor) {
+void PaintWorkletStylePropertyMap::Trace(Visitor* visitor) const {
StylePropertyMapReadOnly::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.h b/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.h
index f76a0658c50..929536108db 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.h
@@ -65,7 +65,7 @@ class CORE_EXPORT PaintWorkletStylePropertyMap
unsigned int size() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const CrossThreadData& StyleMapDataForTest() const { return data_; }
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.cc b/chromium/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.cc
index f8699198e9a..4be98c2a783 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.cc
@@ -121,7 +121,7 @@ String PrepopulatedComputedStylePropertyMap::SerializationForShorthand(
return "";
}
-void PrepopulatedComputedStylePropertyMap::Trace(Visitor* visitor) {
+void PrepopulatedComputedStylePropertyMap::Trace(Visitor* visitor) const {
visitor->Trace(native_values_);
visitor->Trace(custom_values_);
StylePropertyMapReadOnlyMainThread::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h b/chromium/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h
index 6da8bd700df..73c34d53369 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h
@@ -39,7 +39,7 @@ class CORE_EXPORT PrepopulatedComputedStylePropertyMap
void UpdateStyle(const Document&, const ComputedStyle&);
unsigned size() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
const CSSValue* GetProperty(CSSPropertyID) const override;
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.cc b/chromium/third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.cc
index c5471a9b66b..79f7bd3d667 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.cc
@@ -45,7 +45,7 @@ class StylePropertyMapIterationSource final
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(values_);
PairIterable<String, CSSStyleValueVector>::IterationSource::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/document_style_sheet_collection.cc b/chromium/third_party/blink/renderer/core/css/document_style_sheet_collection.cc
index ae08df2c8ea..5e833f603b2 100644
--- a/chromium/third_party/blink/renderer/core/css/document_style_sheet_collection.cc
+++ b/chromium/third_party/blink/renderer/core/css/document_style_sheet_collection.cc
@@ -48,7 +48,7 @@ DocumentStyleSheetCollection::DocumentStyleSheetCollection(
}
void DocumentStyleSheetCollection::CollectStyleSheetsFromCandidates(
- StyleEngine& master_engine,
+ StyleEngine& engine,
DocumentStyleSheetCollector& collector) {
CHECK(ThreadState::Current()->IsOnThreadHeap(this));
for (Node* n : style_sheet_candidate_nodes_) {
@@ -64,7 +64,7 @@ void DocumentStyleSheetCollection::CollectStyleSheetsFromCandidates(
continue;
collector.WillVisit(document);
- document->GetStyleEngine().UpdateActiveStyleSheetsInImport(master_engine,
+ document->GetStyleEngine().UpdateActiveStyleSheetsInImport(engine,
collector);
continue;
}
@@ -83,7 +83,7 @@ void DocumentStyleSheetCollection::CollectStyleSheetsFromCandidates(
CSSStyleSheet* css_sheet = To<CSSStyleSheet>(sheet);
collector.AppendActiveStyleSheet(
- std::make_pair(css_sheet, master_engine.RuleSetForSheet(*css_sheet)));
+ std::make_pair(css_sheet, engine.RuleSetForSheet(*css_sheet)));
}
if (!GetTreeScope().HasAdoptedStyleSheets())
return;
@@ -96,12 +96,12 @@ void DocumentStyleSheetCollection::CollectStyleSheetsFromCandidates(
DCHECK_EQ(GetDocument(), sheet->AssociatedDocument());
collector.AppendSheetForList(sheet);
collector.AppendActiveStyleSheet(
- std::make_pair(sheet, master_engine.RuleSetForSheet(*sheet)));
+ std::make_pair(sheet, engine.RuleSetForSheet(*sheet)));
}
}
void DocumentStyleSheetCollection::CollectStyleSheets(
- StyleEngine& master_engine,
+ StyleEngine& engine,
DocumentStyleSheetCollector& collector) {
for (auto& sheet :
GetDocument().GetStyleEngine().InjectedAuthorStyleSheets()) {
@@ -109,7 +109,7 @@ void DocumentStyleSheetCollection::CollectStyleSheets(
sheet.second,
GetDocument().GetStyleEngine().RuleSetForSheet(*sheet.second)));
}
- CollectStyleSheetsFromCandidates(master_engine, collector);
+ CollectStyleSheetsFromCandidates(engine, collector);
if (CSSStyleSheet* inspector_sheet =
GetDocument().GetStyleEngine().InspectorStyleSheet()) {
collector.AppendActiveStyleSheet(std::make_pair(
@@ -119,11 +119,11 @@ void DocumentStyleSheetCollection::CollectStyleSheets(
}
void DocumentStyleSheetCollection::UpdateActiveStyleSheets(
- StyleEngine& master_engine) {
+ StyleEngine& engine) {
// StyleSheetCollection is GarbageCollected<>, allocate it on the heap.
auto* collection = MakeGarbageCollected<StyleSheetCollection>();
ActiveDocumentStyleSheetCollector collector(*collection);
- CollectStyleSheets(master_engine, collector);
+ CollectStyleSheets(engine, collector);
ApplyActiveStyleSheetChanges(*collection);
}
diff --git a/chromium/third_party/blink/renderer/core/css/document_style_sheet_collection.h b/chromium/third_party/blink/renderer/core/css/document_style_sheet_collection.h
index 881dfbb9c49..750d3b4abe9 100644
--- a/chromium/third_party/blink/renderer/core/css/document_style_sheet_collection.h
+++ b/chromium/third_party/blink/renderer/core/css/document_style_sheet_collection.h
@@ -45,17 +45,16 @@ class DocumentStyleSheetCollection final
public:
explicit DocumentStyleSheetCollection(TreeScope&);
- void UpdateActiveStyleSheets(StyleEngine& master_engine);
- void CollectStyleSheets(StyleEngine& master_engine,
- DocumentStyleSheetCollector&);
+ void UpdateActiveStyleSheets(StyleEngine&);
+ void CollectStyleSheets(StyleEngine&, DocumentStyleSheetCollector&);
void CollectViewportRules(ViewportStyleResolver&);
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
TreeScopeStyleSheetCollection::Trace(visitor);
}
private:
- void CollectStyleSheetsFromCandidates(StyleEngine& master_engine,
+ void CollectStyleSheetsFromCandidates(StyleEngine&,
DocumentStyleSheetCollector&);
DISALLOW_COPY_AND_ASSIGN(DocumentStyleSheetCollection);
};
diff --git a/chromium/third_party/blink/renderer/core/css/element_rule_collector.h b/chromium/third_party/blink/renderer/core/css/element_rule_collector.h
index a98fc111be3..6fa1e10e177 100644
--- a/chromium/third_party/blink/renderer/core/css/element_rule_collector.h
+++ b/chromium/third_party/blink/renderer/core/css/element_rule_collector.h
@@ -76,7 +76,7 @@ class MatchedRule {
return GetRuleData()->Specificity() + specificity_;
}
const CSSStyleSheet* ParentStyleSheet() const { return parent_style_sheet_; }
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(parent_style_sheet_);
visitor->Trace(rule_data_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/font_display_auto_lcp_align_test.cc b/chromium/third_party/blink/renderer/core/css/font_display_auto_lcp_align_test.cc
index 3845a9e7fc6..33b478ac279 100644
--- a/chromium/third_party/blink/renderer/core/css/font_display_auto_lcp_align_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/font_display_auto_lcp_align_test.cc
@@ -30,13 +30,21 @@ class FontDisplayAutoLCPAlignTestBase : public SimTest {
->CopyAs<Vector<char>>();
}
+ static Vector<char> ReadMaterialIconsWoff2() {
+ return test::ReadFromFile(
+ test::CoreTestDataPath("MaterialIcons-Regular.woff2"))
+ ->CopyAs<Vector<char>>();
+ }
+
protected:
Element* GetTarget() { return GetDocument().getElementById("target"); }
- const Font& GetTargetFont() {
- return GetTarget()->GetLayoutObject()->Style()->GetFont();
+ const Font& GetFont(const Element* element) {
+ return element->GetLayoutObject()->Style()->GetFont();
}
+ const Font& GetTargetFont() { return GetFont(GetTarget()); }
+
std::string intervention_mode_;
base::test::ScopedFeatureList scoped_feature_list_;
};
@@ -234,6 +242,70 @@ TEST_F(FontDisplayAutoLCPAlignFailureModeTest,
next_page_resource.Finish();
}
+TEST_F(FontDisplayAutoLCPAlignFailureModeTest, IconAndNonIconFonts) {
+ SimRequest main_resource("https://example.com", "text/html");
+ SimRequest icon_font_resource(
+ "https://example.com/MaterialIcons-Regular.woff2", "font/woff2");
+ SimRequest non_icon_font_resource("https://example.com/Ahem.woff2",
+ "font/woff2");
+
+ LoadURL("https://example.com");
+ main_resource.Complete(R"HTML(
+ <!doctype html>
+ <style>
+ @font-face {
+ font-family: custom-font;
+ src: url(https://example.com/Ahem.woff2) format("woff2");
+ }
+ @font-face {
+ font-family: icon-font;
+ font-style: normal;
+ font-weight: 400;
+ src: url(https://example.com/MaterialIcons-Regular.woff2) format("woff2");
+ }
+ #non-icon-text {
+ font: 25px/1 custom-font, monospace;
+ }
+ #icon-text {
+ font-family: icon-font;
+ font-weight: normal;
+ font-style: normal;
+ font-size: 24px; /* Preferred icon size */
+ display: inline-block;
+ line-height: 1;
+ }
+ </style>
+ <div><span id=icon-text>face</span></div>
+ <div><span id=non-icon-text>0123456789</span></div>
+ )HTML");
+
+ Element* icon_text = GetDocument().getElementById("icon-text");
+ Element* non_icon_text = GetDocument().getElementById("non-icon-text");
+
+ // The first frame is rendered with invisible fallback, as the web fonts are
+ // still loading, and are in the block display period.
+ Compositor().BeginFrame();
+ EXPECT_NE(24, icon_text->OffsetWidth());
+ EXPECT_TRUE(GetFont(icon_text).ShouldSkipDrawing());
+ EXPECT_GT(250, non_icon_text->OffsetWidth());
+ EXPECT_TRUE(GetFont(non_icon_text).ShouldSkipDrawing());
+
+ // Wait until we reach the LCP limit, and the relevant timeout fires.
+ test::RunDelayedTasks(base::TimeDelta::FromMilliseconds(
+ features::kAlignFontDisplayAutoTimeoutWithLCPGoalTimeoutParam.Get()));
+
+ icon_font_resource.Complete(ReadMaterialIconsWoff2());
+ non_icon_font_resource.Complete(ReadAhemWoff2());
+
+ // After reaching the LCP limit, the non-icon web font should reach the
+ // failure period, while the icon font should be used.
+ Compositor().BeginFrame();
+ EXPECT_EQ(24, icon_text->OffsetWidth());
+ EXPECT_FALSE(GetFont(icon_text).ShouldSkipDrawing());
+ EXPECT_GT(250, non_icon_text->OffsetWidth());
+ EXPECT_FALSE(GetFont(non_icon_text).ShouldSkipDrawing());
+}
+
class FontDisplayAutoLCPAlignSwapModeTest
: public FontDisplayAutoLCPAlignTestBase {
public:
diff --git a/chromium/third_party/blink/renderer/core/css/font_face.cc b/chromium/third_party/blink/renderer/core/css/font_face.cc
index 54d6631cca8..8132fb61ce1 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face.cc
+++ b/chromium/third_party/blink/renderer/core/css/font_face.cc
@@ -784,7 +784,7 @@ void FontFace::InitCSSFontFace(const unsigned char* data, size_t size) {
css_font_face_->AddSource(source);
}
-void FontFace::Trace(Visitor* visitor) {
+void FontFace::Trace(Visitor* visitor) const {
visitor->Trace(style_);
visitor->Trace(weight_);
visitor->Trace(stretch_);
diff --git a/chromium/third_party/blink/renderer/core/css/font_face.h b/chromium/third_party/blink/renderer/core/css/font_face.h
index b7eb9d0725e..dd7a6da797f 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face.h
+++ b/chromium/third_party/blink/renderer/core/css/font_face.h
@@ -115,7 +115,7 @@ class CORE_EXPORT FontFace : public ScriptWrappable,
size_t ApproximateBlankCharacterCount() const;
FontDisplay GetFontDisplay() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool HadBlankText() const;
@@ -124,7 +124,7 @@ class CORE_EXPORT FontFace : public ScriptWrappable,
virtual ~LoadFontCallback() = default;
virtual void NotifyLoaded(FontFace*) = 0;
virtual void NotifyError(FontFace*) = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
void LoadWithCallback(LoadFontCallback*);
void AddCallback(LoadFontCallback*);
diff --git a/chromium/third_party/blink/renderer/core/css/font_face_cache.cc b/chromium/third_party/blink/renderer/core/css/font_face_cache.cc
index 2f978936161..ecdd979a8b1 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face_cache.cc
+++ b/chromium/third_party/blink/renderer/core/css/font_face_cache.cc
@@ -214,7 +214,7 @@ size_t FontFaceCache::GetNumSegmentedFacesForTesting() {
return count;
}
-void FontFaceCache::Trace(Visitor* visitor) {
+void FontFaceCache::Trace(Visitor* visitor) const {
visitor->Trace(segmented_faces_);
visitor->Trace(font_selection_query_cache_);
visitor->Trace(style_rule_to_font_face_);
diff --git a/chromium/third_party/blink/renderer/core/css/font_face_cache.h b/chromium/third_party/blink/renderer/core/css/font_face_cache.h
index 3253979d209..f0551fe0809 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face_cache.h
+++ b/chromium/third_party/blink/renderer/core/css/font_face_cache.h
@@ -69,7 +69,7 @@ class CORE_EXPORT FontFaceCache final {
unsigned Version() const { return version_; }
void IncrementVersion();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// Two lookup accelerating cashes are needed: For the font selection
diff --git a/chromium/third_party/blink/renderer/core/css/font_face_cache_test.cc b/chromium/third_party/blink/renderer/core/css/font_face_cache_test.cc
index 0097034ec4d..f22a78bc0e8 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face_cache_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/font_face_cache_test.cc
@@ -43,7 +43,7 @@ class FontFaceCacheTest : public PageTestBase {
FontFaceCache cache_;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
protected:
const AtomicString kFontNameForTesting{"Arial"};
@@ -494,7 +494,7 @@ TEST_F(FontFaceCacheTest, ObliqueRangeMatching) {
FontSelectionRange({FontSelectionValue(30), FontSelectionValue(35)}));
}
-void FontFaceCacheTest::Trace(Visitor* visitor) {
+void FontFaceCacheTest::Trace(Visitor* visitor) const {
visitor->Trace(cache_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/font_face_set.cc b/chromium/third_party/blink/renderer/core/css/font_face_set.cc
index ce0dd906973..d0d148cef3b 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face_set.cc
+++ b/chromium/third_party/blink/renderer/core/css/font_face_set.cc
@@ -109,7 +109,7 @@ bool FontFaceSet::hasForBinding(ScriptState*,
IsCSSConnectedFontFace(font_face);
}
-void FontFaceSet::Trace(Visitor* visitor) {
+void FontFaceSet::Trace(Visitor* visitor) const {
visitor->Trace(non_css_connected_faces_);
visitor->Trace(loading_fonts_);
visitor->Trace(loaded_fonts_);
@@ -278,7 +278,7 @@ void FontFaceSet::LoadFontPromiseResolver::NotifyError(FontFace* font_face) {
}
}
-void FontFaceSet::LoadFontPromiseResolver::Trace(Visitor* visitor) {
+void FontFaceSet::LoadFontPromiseResolver::Trace(Visitor* visitor) const {
visitor->Trace(font_faces_);
visitor->Trace(resolver_);
LoadFontCallback::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/font_face_set.h b/chromium/third_party/blink/renderer/core/css/font_face_set.h
index 0ed6012f1fa..8d8115e6162 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face_set.h
+++ b/chromium/third_party/blink/renderer/core/css/font_face_set.h
@@ -68,7 +68,7 @@ class CORE_EXPORT FontFaceSet : public EventTargetWithInlineData,
wtf_size_t size() const;
virtual AtomicString status() const = 0;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
static const int kDefaultFontSize;
@@ -112,7 +112,7 @@ class CORE_EXPORT FontFaceSet : public EventTargetWithInlineData,
Member<FontFace>&,
ExceptionState&) override;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(font_faces_);
FontFaceSetIterable::IterationSource::Trace(visitor);
}
@@ -141,7 +141,7 @@ class CORE_EXPORT FontFaceSet : public EventTargetWithInlineData,
void NotifyLoaded(FontFace*) override;
void NotifyError(FontFace*) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<FontFace>> font_faces_;
diff --git a/chromium/third_party/blink/renderer/core/css/font_face_set_document.cc b/chromium/third_party/blink/renderer/core/css/font_face_set_document.cc
index 97626f2a4e3..7e9604ab4b1 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face_set_document.cc
+++ b/chromium/third_party/blink/renderer/core/css/font_face_set_document.cc
@@ -35,7 +35,7 @@
#include "third_party/blink/renderer/core/css/font_face_cache.h"
#include "third_party/blink/renderer/core/css/font_face_set_load_event.h"
#include "third_party/blink/renderer/core/css/parser/css_parser.h"
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
#include "third_party/blink/renderer/core/css/resolver/font_style_resolver.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
@@ -174,7 +174,7 @@ bool FontFaceSetDocument::ResolveFontStyle(const String& font_string,
return false;
String font_value = parsed_style->GetPropertyValue(CSSPropertyID::kFont);
- if (css_property_parser_helpers::IsCSSWideKeyword(font_value))
+ if (css_parsing_utils::IsCSSWideKeyword(font_value))
return false;
if (!GetDocument()->documentElement()) {
@@ -266,7 +266,7 @@ void FontFaceSetDocument::LCPLimitReached(TimerBase*) {
font_display_auto_align_histogram_.Record();
}
-void FontFaceSetDocument::Trace(Visitor* visitor) {
+void FontFaceSetDocument::Trace(Visitor* visitor) const {
Supplement<Document>::Trace(visitor);
FontFaceSet::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/font_face_set_document.h b/chromium/third_party/blink/renderer/core/css/font_face_set_document.h
index 3e59a7d1486..4ed7d1a4958 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face_set_document.h
+++ b/chromium/third_party/blink/renderer/core/css/font_face_set_document.h
@@ -77,7 +77,7 @@ class CORE_EXPORT FontFaceSetDocument final : public FontFaceSet,
static void DidLayout(Document&);
static size_t ApproximateBlankCharacterCount(Document&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
bool InActiveContext() const override;
diff --git a/chromium/third_party/blink/renderer/core/css/font_face_set_load_event.cc b/chromium/third_party/blink/renderer/core/css/font_face_set_load_event.cc
index f1b44491aa5..6b8f980708e 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face_set_load_event.cc
+++ b/chromium/third_party/blink/renderer/core/css/font_face_set_load_event.cc
@@ -50,7 +50,7 @@ const AtomicString& FontFaceSetLoadEvent::InterfaceName() const {
return event_interface_names::kFontFaceSetLoadEvent;
}
-void FontFaceSetLoadEvent::Trace(Visitor* visitor) {
+void FontFaceSetLoadEvent::Trace(Visitor* visitor) const {
visitor->Trace(fontfaces_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/font_face_set_load_event.h b/chromium/third_party/blink/renderer/core/css/font_face_set_load_event.h
index 4f332c15eb3..53f7e8348cd 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face_set_load_event.h
+++ b/chromium/third_party/blink/renderer/core/css/font_face_set_load_event.h
@@ -63,7 +63,7 @@ class FontFaceSetLoadEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
FontFaceArray fontfaces_;
diff --git a/chromium/third_party/blink/renderer/core/css/font_face_set_worker.cc b/chromium/third_party/blink/renderer/core/css/font_face_set_worker.cc
index 83299c5e9fe..2a12d3bd390 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face_set_worker.cc
+++ b/chromium/third_party/blink/renderer/core/css/font_face_set_worker.cc
@@ -12,7 +12,7 @@
#include "third_party/blink/renderer/core/css/font_face_set_load_event.h"
#include "third_party/blink/renderer/core/css/offscreen_font_selector.h"
#include "third_party/blink/renderer/core/css/parser/css_parser.h"
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
#include "third_party/blink/renderer/core/css/resolver/font_style_resolver.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -84,7 +84,7 @@ bool FontFaceSetWorker::ResolveFontStyle(const String& font_string,
return false;
String font_value = parsed_style->GetPropertyValue(CSSPropertyID::kFont);
- if (css_property_parser_helpers::IsCSSWideKeyword(font_value))
+ if (css_parsing_utils::IsCSSWideKeyword(font_value))
return false;
FontFamily font_family;
@@ -114,7 +114,7 @@ FontFaceSetWorker* FontFaceSetWorker::From(WorkerGlobalScope& worker) {
return fonts;
}
-void FontFaceSetWorker::Trace(Visitor* visitor) {
+void FontFaceSetWorker::Trace(Visitor* visitor) const {
Supplement<WorkerGlobalScope>::Trace(visitor);
FontFaceSet::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/font_face_set_worker.h b/chromium/third_party/blink/renderer/core/css/font_face_set_worker.h
index b2444902d45..34131a9f5cf 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face_set_worker.h
+++ b/chromium/third_party/blink/renderer/core/css/font_face_set_worker.h
@@ -45,7 +45,7 @@ class CORE_EXPORT FontFaceSetWorker final
static FontFaceSetWorker* From(WorkerGlobalScope&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
bool InActiveContext() const override { return true; }
diff --git a/chromium/third_party/blink/renderer/core/css/font_size_functions.cc b/chromium/third_party/blink/renderer/core/css/font_size_functions.cc
index 4fa47669829..29f44c40e45 100644
--- a/chromium/third_party/blink/renderer/core/css/font_size_functions.cc
+++ b/chromium/third_party/blink/renderer/core/css/font_size_functions.cc
@@ -49,44 +49,37 @@ float FontSizeFunctions::GetComputedSizeFromSpecifiedSize(
if (fabsf(specified_size) < std::numeric_limits<float>::epsilon())
return 0.0f;
- // We support two types of minimum font size. The first is a hard override
- // that applies to all fonts. This is "minSize." The second type of minimum
- // font size is a "smart minimum" that is applied only when the Web page can't
- // know what size it really asked for, e.g., when it uses logical sizes like
- // "small" or expresses the font-size as a percentage of the user's default
- // font setting.
-
- // With the smart minimum, we never want to get smaller than the minimum font
- // size to keep fonts readable. However we always allow the page to set an
- // explicit pixel size that is smaller, since sites will mis-render otherwise
- // (e.g., http://www.gamespot.com with a 9px minimum).
-
Settings* settings = document->GetSettings();
- if (!settings)
- return 1.0f;
+ if (apply_minimum_font_size && settings) {
+ // We support two types of minimum font size. The first is a hard override
+ // that applies to all fonts. This is "min_size." The second type of minimum
+ // font size is a "smart minimum" that is applied only when the Web page
+ // can't know what size it really asked for, e.g., when it uses logical
+ // sizes like "small" or expresses the font-size as a percentage of the
+ // user's default font setting.
+
+ // With the smart minimum, we never want to get smaller than the minimum
+ // font size to keep fonts readable. However we always allow the page to set
+ // an explicit pixel size that is smaller, since sites will mis-render
+ // otherwise (e.g., http://www.gamespot.com with a 9px minimum).
- float zoomed_size = specified_size * zoom_factor;
- if (apply_minimum_font_size) {
int min_size = settings->GetMinimumFontSize();
int min_logical_size = settings->GetMinimumLogicalFontSize();
- // Apply the hard minimum first. We only apply the hard minimum if after
- // zooming we're still too small.
- if (zoomed_size < min_size)
- zoomed_size = min_size;
+ // Apply the hard minimum first.
+ if (specified_size < min_size)
+ specified_size = min_size;
- // Now apply the "smart minimum." This minimum is also only applied if we're
- // still too small after zooming. The font size must either be relative to
+ // Now apply the "smart minimum". The font size must either be relative to
// the user default or the original size must have been acceptable. In other
// words, we only apply the smart minimum whenever we're positive doing so
// won't disrupt the layout.
- if (zoomed_size < min_logical_size &&
- (specified_size >= min_logical_size || !is_absolute_size))
- zoomed_size = min_logical_size;
+ if (specified_size < min_logical_size && !is_absolute_size)
+ specified_size = min_logical_size;
}
// Also clamp to a reasonable maximum to prevent insane font sizes from
// causing crashes on various platforms (I'm looking at you, Windows.)
- return std::min(kMaximumAllowedFontSize, zoomed_size);
+ return std::min(kMaximumAllowedFontSize, specified_size * zoom_factor);
}
const int kFontSizeTableMax = 16;
diff --git a/chromium/third_party/blink/renderer/core/css/font_size_functions.h b/chromium/third_party/blink/renderer/core/css/font_size_functions.h
index 994f391f25a..b2f930065a5 100644
--- a/chromium/third_party/blink/renderer/core/css/font_size_functions.h
+++ b/chromium/third_party/blink/renderer/core/css/font_size_functions.h
@@ -23,6 +23,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_FONT_SIZE_FUNCTIONS_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_FONT_SIZE_FUNCTIONS_H_
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -35,7 +36,7 @@ enum ApplyMinimumFontSize {
kApplyMinimumForFontSize
};
-class FontSizeFunctions {
+class CORE_EXPORT FontSizeFunctions {
STATIC_ONLY(FontSizeFunctions);
public:
diff --git a/chromium/third_party/blink/renderer/core/css/font_size_functions_test.cc b/chromium/third_party/blink/renderer/core/css/font_size_functions_test.cc
new file mode 100644
index 00000000000..a7783559ff0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/font_size_functions_test.cc
@@ -0,0 +1,79 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/css/font_size_functions.h"
+
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
+
+namespace blink {
+
+using FontSizeFunctionsTest = PageTestBase;
+
+TEST_F(FontSizeFunctionsTest, GetComputedSizeFromSpecifiedSize_NoMinFontSize) {
+ constexpr float zoom_factor = 2;
+ constexpr int min_font_size = 100;
+ constexpr bool is_absolute = true;
+ constexpr bool is_logical = false;
+
+ GetDocument().GetSettings()->SetMinimumFontSize(min_font_size);
+ GetDocument().GetSettings()->SetMinimumLogicalFontSize(min_font_size);
+
+ for (const int& font_size : {1, 10, 40, 120}) {
+ EXPECT_EQ(font_size * zoom_factor,
+ FontSizeFunctions::GetComputedSizeFromSpecifiedSize(
+ &GetDocument(), zoom_factor, is_absolute, font_size,
+ kDoNotApplyMinimumForFontSize));
+ EXPECT_EQ(font_size * zoom_factor,
+ FontSizeFunctions::GetComputedSizeFromSpecifiedSize(
+ &GetDocument(), zoom_factor, is_logical, font_size,
+ kDoNotApplyMinimumForFontSize));
+ }
+}
+
+TEST_F(FontSizeFunctionsTest, GetComputedSizeFromSpecifiedSize_MinFontSize) {
+ constexpr float zoom_factor = 2;
+ constexpr int min_font_size = 100;
+ constexpr bool is_absolute = true;
+ constexpr bool is_logical = false;
+
+ GetDocument().GetSettings()->SetMinimumFontSize(min_font_size);
+ GetDocument().GetSettings()->SetMinimumLogicalFontSize(0);
+
+ int test_cases[][2] = {
+ {1, min_font_size}, {10, min_font_size}, {40, min_font_size}, {120, 120}};
+ for (const auto* font_sizes : test_cases) {
+ EXPECT_EQ(font_sizes[1] * zoom_factor,
+ FontSizeFunctions::GetComputedSizeFromSpecifiedSize(
+ &GetDocument(), zoom_factor, is_absolute, font_sizes[0]));
+ EXPECT_EQ(font_sizes[1] * zoom_factor,
+ FontSizeFunctions::GetComputedSizeFromSpecifiedSize(
+ &GetDocument(), zoom_factor, is_logical, font_sizes[0]));
+ }
+}
+
+TEST_F(FontSizeFunctionsTest,
+ GetComputedSizeFromSpecifiedSize_MinLogicalFontSize) {
+ constexpr float zoom_factor = 2;
+ constexpr int min_font_size = 100;
+ constexpr bool is_absolute = true;
+ constexpr bool is_logical = false;
+
+ GetDocument().GetSettings()->SetMinimumFontSize(0);
+ GetDocument().GetSettings()->SetMinimumLogicalFontSize(min_font_size);
+
+ int test_cases[][2] = {
+ {1, min_font_size}, {10, min_font_size}, {40, min_font_size}, {120, 120}};
+ for (const auto* font_sizes : test_cases) {
+ EXPECT_EQ(font_sizes[0] * zoom_factor,
+ FontSizeFunctions::GetComputedSizeFromSpecifiedSize(
+ &GetDocument(), zoom_factor, is_absolute, font_sizes[0]));
+ EXPECT_EQ(font_sizes[1] * zoom_factor,
+ FontSizeFunctions::GetComputedSizeFromSpecifiedSize(
+ &GetDocument(), zoom_factor, is_logical, font_sizes[0]));
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/font_update_invalidation_test.cc b/chromium/third_party/blink/renderer/core/css/font_update_invalidation_test.cc
index 294eac07ea3..1bf60fcc9b0 100644
--- a/chromium/third_party/blink/renderer/core/css/font_update_invalidation_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/font_update_invalidation_test.cc
@@ -138,4 +138,46 @@ TEST_F(FontUpdateInvalidationTest,
main_resource.Finish();
}
+// https://crbug.com/1092411
+TEST_F(FontUpdateInvalidationTest, LayoutInvalidationOnModalDialog) {
+ SimRequest main_resource("https://example.com", "text/html");
+ SimRequest font_resource("https://example.com/Ahem.woff2", "font/woff2");
+
+ LoadURL("https://example.com");
+ main_resource.Write(R"HTML(
+ <!doctype html>
+ <style>
+ @font-face {
+ font-family: custom-font;
+ src: url(https://example.com/Ahem.woff2) format("woff2");
+ }
+ #target {
+ font: 25px/1 custom-font, monospace;
+ }
+ </style>
+ <dialog><span id=target>0123456789</span></dialog>
+ <script>document.querySelector('dialog').showModal();</script>
+ )HTML");
+
+ // First render the page without the custom font
+ Compositor().BeginFrame();
+
+ Element* target = GetDocument().getElementById("target");
+ EXPECT_GT(250, target->OffsetWidth());
+
+ // Then load the font and invalidate layout
+ font_resource.Complete(ReadAhemWoff2());
+ GetDocument().GetStyleEngine().InvalidateStyleAndLayoutForFontUpdates();
+
+ // <dialog> descendants should be invalidated
+ EXPECT_EQ(kNoStyleChange, target->GetStyleChangeType());
+ EXPECT_TRUE(target->GetLayoutObject()->NeedsLayout());
+
+ // <dialog> descendants should be re-rendered with the custom font
+ Compositor().BeginFrame();
+ EXPECT_EQ(250, target->OffsetWidth());
+
+ main_resource.Finish();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/inline_css_style_declaration.cc b/chromium/third_party/blink/renderer/core/css/inline_css_style_declaration.cc
index 08c14c61351..0aaf0a51d63 100644
--- a/chromium/third_party/blink/renderer/core/css/inline_css_style_declaration.cc
+++ b/chromium/third_party/blink/renderer/core/css/inline_css_style_declaration.cc
@@ -50,7 +50,7 @@ CSSStyleSheet* InlineCSSStyleDeclaration::ParentStyleSheet() const {
: nullptr;
}
-void InlineCSSStyleDeclaration::Trace(Visitor* visitor) {
+void InlineCSSStyleDeclaration::Trace(Visitor* visitor) const {
visitor->Trace(parent_element_);
AbstractPropertySetCSSStyleDeclaration::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/inline_css_style_declaration.h b/chromium/third_party/blink/renderer/core/css/inline_css_style_declaration.h
index 85f004cfdfa..867f34632b7 100644
--- a/chromium/third_party/blink/renderer/core/css/inline_css_style_declaration.h
+++ b/chromium/third_party/blink/renderer/core/css/inline_css_style_declaration.h
@@ -40,7 +40,7 @@ class InlineCSSStyleDeclaration final
parent_element ? parent_element->GetExecutionContext() : nullptr),
parent_element_(parent_element) {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
MutableCSSPropertyValueSet& PropertySet() const override;
diff --git a/chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations.h b/chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations.h
index 798d166581a..a5db37b549d 100644
--- a/chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations.h
+++ b/chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations.h
@@ -81,7 +81,9 @@ class CORE_EXPORT PendingInvalidations {
PendingInvalidationMap& GetPendingInvalidationMap() {
return pending_invalidation_map_;
}
- void Trace(Visitor* visitor) { visitor->Trace(pending_invalidation_map_); }
+ void Trace(Visitor* visitor) const {
+ visitor->Trace(pending_invalidation_map_);
+ }
private:
NodeInvalidationSets& EnsurePendingInvalidations(ContainerNode&);
diff --git a/chromium/third_party/blink/renderer/core/css/local_font_face_source.cc b/chromium/third_party/blink/renderer/core/css/local_font_face_source.cc
index c731222a995..61d03d519e7 100644
--- a/chromium/third_party/blink/renderer/core/css/local_font_face_source.cc
+++ b/chromium/third_party/blink/renderer/core/css/local_font_face_source.cc
@@ -142,7 +142,7 @@ void LocalFontFaceSource::LocalFontHistograms::Record(bool load_success) {
base::UmaHistogramBoolean("WebFont.LocalFontUsed", load_success);
}
-void LocalFontFaceSource::Trace(Visitor* visitor) {
+void LocalFontFaceSource::Trace(Visitor* visitor) const {
visitor->Trace(face_);
visitor->Trace(font_selector_);
CSSFontFaceSource::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/local_font_face_source.h b/chromium/third_party/blink/renderer/core/css/local_font_face_source.h
index 2e2dbe30b35..278c96faa18 100644
--- a/chromium/third_party/blink/renderer/core/css/local_font_face_source.h
+++ b/chromium/third_party/blink/renderer/core/css/local_font_face_source.h
@@ -44,7 +44,7 @@ class LocalFontFaceSource final : public CSSFontFaceSource,
void BeginLoadIfNeeded() override;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
void NotifyFontUniqueNameLookupReady();
diff --git a/chromium/third_party/blink/renderer/core/css/marker.css b/chromium/third_party/blink/renderer/core/css/marker.css
new file mode 100644
index 00000000000..58ec8f19bc0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/marker.css
@@ -0,0 +1,4 @@
+::marker {
+ unicode-bidi: isolate;
+ font-variant-numeric: tabular-nums;
+}
diff --git a/chromium/third_party/blink/renderer/core/css/mathml.css b/chromium/third_party/blink/renderer/core/css/mathml.css
index 68459f4d191..62bec54ee13 100644
--- a/chromium/third_party/blink/renderer/core/css/mathml.css
+++ b/chromium/third_party/blink/renderer/core/css/mathml.css
@@ -65,15 +65,45 @@ mspace {
overflow: hidden !important;
}
+/* Token elements */
+mi {
+ text-transform: math-auto;
+}
+
+/* Fractions */
mfrac {
padding-inline-start: 1px;
padding-inline-end: 1px;
}
+mfrac > * {
+ font-size: scriptlevel(auto);
+ math-style: inline;
+}
+
mfrac > :nth-child(2) {
math-superscript-shift-style: inline;
}
+/* Other rules for scriptlevel, displaystyle and math-superscript-shift-style */
+msub > :not(:first-child),
+msup > :not(:first-child),
+msubsup > :not(:first-child),
+mmultiscripts > :not(:first-child),
+munder > :not(:first-child),
+mover > :not(:first-child),
+munderover > :not(:first-child) {
+ font-size: scriptlevel(add(1));
+ math-style: inline;
+}
+
+munder[accentunder="true" i] > :nth-child(2),
+mover[accent="true" i] > :nth-child(2),
+munderover[accentunder="true" i] > :nth-child(2),
+munderover[accent="true" i] > :nth-child(3) {
+ font-size: inherit;
+}
+
munder > :nth-child(2),
munderover > :nth-child(2),
mover[accent="true" i] > :first-child,
@@ -81,8 +111,3 @@ munderover[accent="true" i] > :first-child {
math-superscript-shift-style: inline;
}
-/* Token elements */
-mi {
- text-transform: math-auto;
-}
-
diff --git a/chromium/third_party/blink/renderer/core/css/media_feature_names.json5 b/chromium/third_party/blink/renderer/core/css/media_feature_names.json5
index 388a58828e7..8d74260d553 100644
--- a/chromium/third_party/blink/renderer/core/css/media_feature_names.json5
+++ b/chromium/third_party/blink/renderer/core/css/media_feature_names.json5
@@ -54,10 +54,10 @@
"pointer",
"prefers-color-scheme",
"prefers-reduced-motion",
+ "prefers-reduced-data",
"resolution",
"-webkit-transform-3d",
"scan",
"screen-spanning",
- "shape",
],
}
diff --git a/chromium/third_party/blink/renderer/core/css/media_list.cc b/chromium/third_party/blink/renderer/core/css/media_list.cc
index 2e25f0fde73..a40187c7659 100644
--- a/chromium/third_party/blink/renderer/core/css/media_list.cc
+++ b/chromium/third_party/blink/renderer/core/css/media_list.cc
@@ -221,7 +221,7 @@ void MediaList::Reattach(scoped_refptr<MediaQuerySet> media_queries) {
media_queries_ = media_queries;
}
-void MediaList::Trace(Visitor* visitor) {
+void MediaList::Trace(Visitor* visitor) const {
visitor->Trace(parent_style_sheet_);
visitor->Trace(parent_rule_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/media_list.h b/chromium/third_party/blink/renderer/core/css/media_list.h
index 61781552ee5..9bce89760ba 100644
--- a/chromium/third_party/blink/renderer/core/css/media_list.h
+++ b/chromium/third_party/blink/renderer/core/css/media_list.h
@@ -100,7 +100,7 @@ class MediaList final : public ScriptWrappable {
void Reattach(scoped_refptr<MediaQuerySet>);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
scoped_refptr<MediaQuerySet> media_queries_;
diff --git a/chromium/third_party/blink/renderer/core/css/media_query_evaluator.cc b/chromium/third_party/blink/renderer/core/css/media_query_evaluator.cc
index a2a1cea57e5..4c117d36823 100644
--- a/chromium/third_party/blink/renderer/core/css/media_query_evaluator.cc
+++ b/chromium/third_party/blink/renderer/core/css/media_query_evaluator.cc
@@ -35,7 +35,6 @@
#include "third_party/blink/public/common/css/screen_spanning.h"
#include "third_party/blink/public/mojom/manifest/display_mode.mojom-shared.h"
#include "third_party/blink/public/platform/pointer_properties.h"
-#include "third_party/blink/public/platform/shape_properties.h"
#include "third_party/blink/renderer/core/css/css_primitive_value.h"
#include "third_party/blink/renderer/core/css/css_resolution_units.h"
#include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
@@ -85,7 +84,7 @@ MediaQueryEvaluator::MediaQueryEvaluator(
MediaQueryEvaluator::~MediaQueryEvaluator() = default;
-void MediaQueryEvaluator::Trace(Visitor* visitor) {
+void MediaQueryEvaluator::Trace(Visitor* visitor) const {
visitor->Trace(media_values_);
}
@@ -737,26 +736,18 @@ static bool PrefersReducedMotionMediaFeatureEval(
media_values.PrefersReducedMotion();
}
-static bool ShapeMediaFeatureEval(const MediaQueryExpValue& value,
- MediaFeaturePrefix,
- const MediaValues& media_values) {
+static bool PrefersReducedDataMediaFeatureEval(
+ const MediaQueryExpValue& value,
+ MediaFeaturePrefix,
+ const MediaValues& media_values) {
if (!value.IsValid())
- return true;
+ return media_values.PrefersReducedData();
if (!value.is_id)
return false;
- DisplayShape shape = media_values.GetDisplayShape();
-
- switch (value.id) {
- case CSSValueID::kRect:
- return shape == kDisplayShapeRect;
- case CSSValueID::kRound:
- return shape == kDisplayShapeRound;
- default:
- NOTREACHED();
- return false;
- }
+ return (value.id == CSSValueID::kNoPreference) ^
+ media_values.PrefersReducedData();
}
static bool AnyPointerMediaFeatureEval(const MediaQueryExpValue& value,
@@ -852,14 +843,12 @@ static bool PrefersColorSchemeMediaFeatureEval(
media_values.GetPreferredColorScheme();
if (!value.IsValid())
- return preferred_scheme != PreferredColorScheme::kNoPreference;
+ return true;
if (!value.is_id)
return false;
- return (preferred_scheme == PreferredColorScheme::kNoPreference &&
- value.id == CSSValueID::kNoPreference) ||
- (preferred_scheme == PreferredColorScheme::kDark &&
+ return (preferred_scheme == PreferredColorScheme::kDark &&
value.id == CSSValueID::kDark) ||
(preferred_scheme == PreferredColorScheme::kLight &&
value.id == CSSValueID::kLight);
@@ -933,8 +922,13 @@ void MediaQueryEvaluator::Init() {
}
bool MediaQueryEvaluator::Eval(const MediaQueryExp& expr) const {
- if (!media_values_ || !media_values_->HasValues())
- return true;
+ if (!media_values_ || !media_values_->HasValues()) {
+ // media_values_ should only be nullptr when parsing UA stylesheets. The
+ // only media queries we support in UA stylesheets are media type queries.
+ // If HasValues() return false, it means the document frame is nullptr.
+ NOTREACHED();
+ return false;
+ }
DCHECK(g_function_map);
diff --git a/chromium/third_party/blink/renderer/core/css/media_query_evaluator.h b/chromium/third_party/blink/renderer/core/css/media_query_evaluator.h
index 2d9e016d8fe..84fe011ee08 100644
--- a/chromium/third_party/blink/renderer/core/css/media_query_evaluator.h
+++ b/chromium/third_party/blink/renderer/core/css/media_query_evaluator.h
@@ -60,13 +60,12 @@ class CORE_EXPORT MediaQueryEvaluator final
public:
static void Init();
- // Creates evaluator which evaluates to true for all media queries.
- MediaQueryEvaluator() = default;
+ MediaQueryEvaluator() = delete;
- // Creates evaluator which evaluates only simple media queries
- // Evaluator returns true for acceptedMediaType and returns true for any media
- // features.
- MediaQueryEvaluator(const char* accepted_media_type);
+ // Creates evaluator to evaluate media types only. Evaluator returns true for
+ // accepted_media_type and triggers a NOTREACHED returning false for any media
+ // features. Should only be used for UA stylesheets.
+ explicit MediaQueryEvaluator(const char* accepted_media_type);
// Creates evaluator which evaluates full media queries.
explicit MediaQueryEvaluator(LocalFrame*);
@@ -98,7 +97,7 @@ class CORE_EXPORT MediaQueryEvaluator final
// evaluation.
bool DidResultsChange(const MediaQueryResultList& results) const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
const String MediaType() const;
diff --git a/chromium/third_party/blink/renderer/core/css/media_query_evaluator_test.cc b/chromium/third_party/blink/renderer/core/css/media_query_evaluator_test.cc
index bb2e9e00608..700583ceffe 100644
--- a/chromium/third_party/blink/renderer/core/css/media_query_evaluator_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/media_query_evaluator_test.cc
@@ -70,8 +70,6 @@ MediaQueryEvaluatorTestCase g_screen_test_cases[] = {
{"(display-mode: @browser)", 0},
{"(display-mode: 'browser')", 0},
{"(display-mode: @junk browser)", 0},
- {"(shape: rect)", 1},
- {"(shape: round)", 0},
{"(max-device-aspect-ratio: 4294967295/1)", 1},
{"(min-device-aspect-ratio: 1/4294967296)", 1},
{nullptr, 0} // Do not remove the terminator line.
@@ -265,7 +263,6 @@ TEST(MediaQueryEvaluatorTest, Cached) {
data.media_type = media_type_names::kScreen;
data.strict_mode = true;
data.display_mode = blink::mojom::DisplayMode::kBrowser;
- data.display_shape = kDisplayShapeRect;
data.immersive_mode = false;
// Default values.
diff --git a/chromium/third_party/blink/renderer/core/css/media_query_exp.cc b/chromium/third_party/blink/renderer/core/css/media_query_exp.cc
index e3ea62499d7..7c1d9b9c524 100644
--- a/chromium/third_party/blink/renderer/core/css/media_query_exp.cc
+++ b/chromium/third_party/blink/renderer/core/css/media_query_exp.cc
@@ -34,7 +34,7 @@
#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h"
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/decimal.h"
@@ -71,24 +71,22 @@ static inline bool FeatureWithValidIdent(const String& media_feature,
if (media_feature == media_feature_names::kScanMediaFeature)
return ident == CSSValueID::kInterlace || ident == CSSValueID::kProgressive;
- if (RuntimeEnabledFeatures::MediaQueryShapeEnabled()) {
- if (media_feature == media_feature_names::kShapeMediaFeature)
- return ident == CSSValueID::kRect || ident == CSSValueID::kRound;
- }
-
if (media_feature == media_feature_names::kColorGamutMediaFeature) {
return ident == CSSValueID::kSRGB || ident == CSSValueID::kP3 ||
ident == CSSValueID::kRec2020;
}
- if (media_feature == media_feature_names::kPrefersColorSchemeMediaFeature) {
- return ident == CSSValueID::kNoPreference || ident == CSSValueID::kDark ||
- ident == CSSValueID::kLight;
- }
+ if (media_feature == media_feature_names::kPrefersColorSchemeMediaFeature)
+ return ident == CSSValueID::kDark || ident == CSSValueID::kLight;
if (media_feature == media_feature_names::kPrefersReducedMotionMediaFeature)
return ident == CSSValueID::kNoPreference || ident == CSSValueID::kReduce;
+ if (RuntimeEnabledFeatures::PrefersReducedDataEnabled() &&
+ media_feature == media_feature_names::kPrefersReducedDataMediaFeature) {
+ return ident == CSSValueID::kNoPreference || ident == CSSValueID::kReduce;
+ }
+
if (RuntimeEnabledFeatures::ForcedColorsEnabled()) {
if (media_feature == media_feature_names::kForcedColorsMediaFeature) {
return ident == CSSValueID::kNone || ident == CSSValueID::kActive;
@@ -217,14 +215,15 @@ static inline bool FeatureWithoutValue(
media_feature == media_feature_names::kResolutionMediaFeature ||
media_feature == media_feature_names::kDisplayModeMediaFeature ||
media_feature == media_feature_names::kScanMediaFeature ||
- (media_feature == media_feature_names::kShapeMediaFeature &&
- RuntimeEnabledFeatures::MediaQueryShapeEnabled()) ||
media_feature == media_feature_names::kColorGamutMediaFeature ||
media_feature == media_feature_names::kImmersiveMediaFeature ||
media_feature ==
media_feature_names::kPrefersColorSchemeMediaFeature ||
media_feature ==
media_feature_names::kPrefersReducedMotionMediaFeature ||
+ (media_feature ==
+ media_feature_names::kPrefersReducedDataMediaFeature &&
+ RuntimeEnabledFeatures::PrefersReducedDataEnabled()) ||
(media_feature == media_feature_names::kForcedColorsMediaFeature &&
RuntimeEnabledFeatures::ForcedColorsEnabled()) ||
(media_feature ==
@@ -265,8 +264,7 @@ bool MediaQueryExp::IsDeviceDependent() const {
media_feature_ == media_feature_names::kMinDeviceHeightMediaFeature ||
media_feature_ == kMaxDeviceAspectRatioMediaFeature ||
media_feature_ == media_feature_names::kMaxDeviceWidthMediaFeature ||
- media_feature_ == media_feature_names::kMaxDeviceHeightMediaFeature ||
- media_feature_ == media_feature_names::kShapeMediaFeature;
+ media_feature_ == media_feature_names::kMaxDeviceHeightMediaFeature;
}
MediaQueryExp::MediaQueryExp(const MediaQueryExp& other)
@@ -289,22 +287,21 @@ MediaQueryExp MediaQueryExp::Create(const String& media_feature,
CSSParserContext::ParserModeOverridingScope scope(context, kHTMLStandardMode);
CSSPrimitiveValue* value =
- css_property_parser_helpers::ConsumeInteger(range, context, 0);
+ css_parsing_utils::ConsumeInteger(range, context, 0);
if (!value && !FeatureExpectingPositiveInteger(lower_media_feature) &&
!FeatureWithAspectRatio(lower_media_feature)) {
- value = css_property_parser_helpers::ConsumeNumber(range, context,
- kValueRangeNonNegative);
+ value = css_parsing_utils::ConsumeNumber(range, context,
+ kValueRangeNonNegative);
}
if (!value) {
- value = css_property_parser_helpers::ConsumeLength(range, context,
- kValueRangeNonNegative);
+ value = css_parsing_utils::ConsumeLength(range, context,
+ kValueRangeNonNegative);
}
if (!value)
- value = css_property_parser_helpers::ConsumeResolution(range);
+ value = css_parsing_utils::ConsumeResolution(range);
if (!value) {
- if (CSSIdentifierValue* ident =
- css_property_parser_helpers::ConsumeIdent(range)) {
+ if (CSSIdentifierValue* ident = css_parsing_utils::ConsumeIdent(range)) {
CSSValueID ident_id = ident->GetValueID();
if (!FeatureWithValidIdent(lower_media_feature, ident_id))
return Invalid();
@@ -324,10 +321,10 @@ MediaQueryExp MediaQueryExp::Create(const String& media_feature,
if (FeatureWithAspectRatio(lower_media_feature)) {
if (!value->IsInteger() || value->GetDoubleValue() == 0)
return Invalid();
- if (!css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range))
+ if (!css_parsing_utils::ConsumeSlashIncludingWhitespace(range))
return Invalid();
CSSPrimitiveValue* denominator =
- css_property_parser_helpers::ConsumePositiveInteger(range, context);
+ css_parsing_utils::ConsumePositiveInteger(range, context);
if (!denominator)
return Invalid();
diff --git a/chromium/third_party/blink/renderer/core/css/media_query_list.cc b/chromium/third_party/blink/renderer/core/css/media_query_list.cc
index 8bd1ff1f1ab..f51591ac1e6 100644
--- a/chromium/third_party/blink/renderer/core/css/media_query_list.cc
+++ b/chromium/third_party/blink/renderer/core/css/media_query_list.cc
@@ -102,7 +102,7 @@ bool MediaQueryList::matches() {
return matches_;
}
-void MediaQueryList::Trace(Visitor* visitor) {
+void MediaQueryList::Trace(Visitor* visitor) const {
visitor->Trace(matcher_);
visitor->Trace(listeners_);
EventTargetWithInlineData::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/media_query_list.h b/chromium/third_party/blink/renderer/core/css/media_query_list.h
index c09f4fcc05b..edec4af8bd1 100644
--- a/chromium/third_party/blink/renderer/core/css/media_query_list.h
+++ b/chromium/third_party/blink/renderer/core/css/media_query_list.h
@@ -74,7 +74,7 @@ class CORE_EXPORT MediaQueryList final
bool MediaFeaturesChanged(
HeapVector<Member<MediaQueryListListener>>* listeners_to_notify);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// From ScriptWrappable
bool HasPendingActivity() const final;
diff --git a/chromium/third_party/blink/renderer/core/css/media_query_list_event.h b/chromium/third_party/blink/renderer/core/css/media_query_list_event.h
index f9c0643b0b2..46e5225b9f6 100644
--- a/chromium/third_party/blink/renderer/core/css/media_query_list_event.h
+++ b/chromium/third_party/blink/renderer/core/css/media_query_list_event.h
@@ -65,7 +65,7 @@ class MediaQueryListEvent final : public Event {
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
Event::Trace(visitor);
visitor->Trace(media_query_list_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/media_query_list_listener.h b/chromium/third_party/blink/renderer/core/css/media_query_list_listener.h
index d448990a9ce..b4a13e2a751 100644
--- a/chromium/third_party/blink/renderer/core/css/media_query_list_listener.h
+++ b/chromium/third_party/blink/renderer/core/css/media_query_list_listener.h
@@ -32,7 +32,7 @@ class CORE_EXPORT MediaQueryListListener
public:
virtual void NotifyMediaQueryChanged() = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
MediaQueryListListener();
diff --git a/chromium/third_party/blink/renderer/core/css/media_query_list_test.cc b/chromium/third_party/blink/renderer/core/css/media_query_list_test.cc
index 85d8002d66b..09ea62775b2 100644
--- a/chromium/third_party/blink/renderer/core/css/media_query_list_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/media_query_list_test.cc
@@ -23,7 +23,7 @@ class TestListener : public MediaQueryListListener {
} // anonymous namespace
TEST(MediaQueryListTest, CrashInStop) {
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* list = MakeGarbageCollected<MediaQueryList>(
document->GetExecutionContext(),
MakeGarbageCollected<MediaQueryMatcher>(*document),
diff --git a/chromium/third_party/blink/renderer/core/css/media_query_matcher.cc b/chromium/third_party/blink/renderer/core/css/media_query_matcher.cc
index d3685e88d86..a5e6de996a2 100644
--- a/chromium/third_party/blink/renderer/core/css/media_query_matcher.cc
+++ b/chromium/third_party/blink/renderer/core/css/media_query_matcher.cc
@@ -128,7 +128,7 @@ void MediaQueryMatcher::ViewportChanged() {
document_->EnqueueMediaQueryChangeListeners(listeners_to_notify);
}
-void MediaQueryMatcher::Trace(Visitor* visitor) {
+void MediaQueryMatcher::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(evaluator_);
visitor->Trace(media_lists_);
diff --git a/chromium/third_party/blink/renderer/core/css/media_query_matcher.h b/chromium/third_party/blink/renderer/core/css/media_query_matcher.h
index 63412b1895d..7f803016bee 100644
--- a/chromium/third_party/blink/renderer/core/css/media_query_matcher.h
+++ b/chromium/third_party/blink/renderer/core/css/media_query_matcher.h
@@ -59,7 +59,7 @@ class CORE_EXPORT MediaQueryMatcher final
void ViewportChanged();
bool Evaluate(const MediaQuerySet*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
MediaQueryEvaluator* CreateEvaluator() const;
diff --git a/chromium/third_party/blink/renderer/core/css/media_query_set_test.cc b/chromium/third_party/blink/renderer/core/css/media_query_set_test.cc
index 1ccb196374f..6424fc352b7 100644
--- a/chromium/third_party/blink/renderer/core/css/media_query_set_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/media_query_set_test.cc
@@ -191,7 +191,6 @@ TEST(MediaQuerySetTest, Basic) {
}
TEST(MediaQuerySetTest, BehindRuntimeFlag) {
- ScopedMediaQueryShapeForTest shape_flag(false);
ScopedForcedColorsForTest forced_colors_flag(false);
ScopedMediaQueryNavigationControlsForTest navigation_controls_flag(false);
ScopedCSSFoldablesForTest foldables_flag(false);
@@ -199,7 +198,6 @@ TEST(MediaQuerySetTest, BehindRuntimeFlag) {
// The first string represents the input string, the second string represents
// the output string.
MediaQuerySetTestCase test_cases[] = {
- {"(shape)", "not all"},
{"(forced-colors)", "not all"},
{"(navigation-controls)", "not all"},
{"(screen-spanning)", "not all"},
diff --git a/chromium/third_party/blink/renderer/core/css/media_values.cc b/chromium/third_party/blink/renderer/core/css/media_values.cc
index b7ae26eeb2e..5eca5aab143 100644
--- a/chromium/third_party/blink/renderer/core/css/media_values.cc
+++ b/chromium/third_party/blink/renderer/core/css/media_values.cc
@@ -22,21 +22,20 @@
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/graphics/color_space_gamut.h"
+#include "third_party/blink/renderer/platform/network/network_state_notifier.h"
#include "third_party/blink/renderer/platform/widget/frame_widget.h"
namespace blink {
PreferredColorScheme CSSValueIDToPreferredColorScheme(CSSValueID id) {
switch (id) {
- case CSSValueID::kNoPreference:
- return PreferredColorScheme::kNoPreference;
case CSSValueID::kLight:
return PreferredColorScheme::kLight;
case CSSValueID::kDark:
return PreferredColorScheme::kDark;
default:
NOTREACHED();
- return PreferredColorScheme::kNoPreference;
+ return PreferredColorScheme::kLight;
}
}
@@ -174,15 +173,6 @@ int MediaValues::CalculateAvailableHoverTypes(LocalFrame* frame) {
return frame->GetSettings()->GetAvailableHoverTypes();
}
-DisplayShape MediaValues::CalculateDisplayShape(LocalFrame* frame) {
- DCHECK(frame);
- DCHECK(frame->GetPage());
- return frame->GetPage()
- ->GetChromeClient()
- .GetScreenInfo(*frame)
- .display_shape;
-}
-
ColorSpaceGamut MediaValues::CalculateColorGamut(LocalFrame* frame) {
DCHECK(frame);
DCHECK(frame->GetPage());
@@ -215,6 +205,18 @@ bool MediaValues::CalculatePrefersReducedMotion(LocalFrame* frame) {
return frame->GetSettings()->GetPrefersReducedMotion();
}
+bool MediaValues::CalculatePrefersReducedData(LocalFrame* frame) {
+ DCHECK(frame);
+ DCHECK(frame->GetSettings());
+ if (const auto* overrides = frame->GetPage()->GetMediaFeatureOverrides()) {
+ MediaQueryExpValue value = overrides->GetOverride("prefers-reduced-data");
+ if (value.IsValid())
+ return value.id == CSSValueID::kReduce;
+ }
+ return (GetNetworkStateNotifier().SaveDataEnabled() &&
+ !frame->GetSettings()->GetDataSaverHoldbackWebApi());
+}
+
ForcedColors MediaValues::CalculateForcedColors() {
if (Platform::Current() && Platform::Current()->ThemeEngine())
return Platform::Current()->ThemeEngine()->GetForcedColors();
diff --git a/chromium/third_party/blink/renderer/core/css/media_values.h b/chromium/third_party/blink/renderer/core/css/media_values.h
index 7098decff8d..f5d8b0c9350 100644
--- a/chromium/third_party/blink/renderer/core/css/media_values.h
+++ b/chromium/third_party/blink/renderer/core/css/media_values.h
@@ -7,7 +7,6 @@
#include "third_party/blink/public/mojom/manifest/display_mode.mojom-shared.h"
#include "third_party/blink/public/platform/pointer_properties.h"
-#include "third_party/blink/public/platform/shape_properties.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/css_primitive_value.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -29,7 +28,7 @@ PreferredColorScheme CSSValueIDToPreferredColorScheme(CSSValueID id);
class CORE_EXPORT MediaValues : public GarbageCollected<MediaValues> {
public:
virtual ~MediaValues() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
static MediaValues* CreateDynamicIfFrameExists(LocalFrame*);
virtual MediaValues* Copy() const = 0;
@@ -81,10 +80,10 @@ class CORE_EXPORT MediaValues : public GarbageCollected<MediaValues> {
virtual bool HasValues() const = 0;
virtual void OverrideViewportDimensions(double width, double height) = 0;
- virtual DisplayShape GetDisplayShape() const = 0;
virtual ColorSpaceGamut ColorGamut() const = 0;
virtual PreferredColorScheme GetPreferredColorScheme() const = 0;
virtual bool PrefersReducedMotion() const = 0;
+ virtual bool PrefersReducedData() const = 0;
virtual ForcedColors GetForcedColors() const = 0;
virtual NavigationControls GetNavigationControls() const = 0;
virtual ScreenSpanning GetScreenSpanning() const = 0;
@@ -107,10 +106,10 @@ class CORE_EXPORT MediaValues : public GarbageCollected<MediaValues> {
static int CalculateAvailablePointerTypes(LocalFrame*);
static HoverType CalculatePrimaryHoverType(LocalFrame*);
static int CalculateAvailableHoverTypes(LocalFrame*);
- static DisplayShape CalculateDisplayShape(LocalFrame*);
static ColorSpaceGamut CalculateColorGamut(LocalFrame*);
static PreferredColorScheme CalculatePreferredColorScheme(LocalFrame*);
static bool CalculatePrefersReducedMotion(LocalFrame*);
+ static bool CalculatePrefersReducedData(LocalFrame*);
static ForcedColors CalculateForcedColors();
static NavigationControls CalculateNavigationControls(LocalFrame*);
static ScreenSpanning CalculateScreenSpanning(LocalFrame*);
diff --git a/chromium/third_party/blink/renderer/core/css/media_values_cached.cc b/chromium/third_party/blink/renderer/core/css/media_values_cached.cc
index 725271ed49b..a5cf31eedff 100644
--- a/chromium/third_party/blink/renderer/core/css/media_values_cached.cc
+++ b/chromium/third_party/blink/renderer/core/css/media_values_cached.cc
@@ -33,9 +33,8 @@ MediaValuesCached::MediaValuesCachedData::MediaValuesCachedData()
immersive_mode(false),
strict_mode(true),
display_mode(blink::mojom::DisplayMode::kBrowser),
- display_shape(kDisplayShapeRect),
color_gamut(ColorSpaceGamut::kUnknown),
- preferred_color_scheme(PreferredColorScheme::kNoPreference),
+ preferred_color_scheme(PreferredColorScheme::kLight),
prefers_reduced_motion(false),
forced_colors(ForcedColors::kNone),
navigation_controls(NavigationControls::kNone),
@@ -45,7 +44,7 @@ MediaValuesCached::MediaValuesCachedData::MediaValuesCachedData(
Document& document)
: MediaValuesCached::MediaValuesCachedData() {
DCHECK(IsMainThread());
- LocalFrame* frame = document.GetFrameOfMasterDocument();
+ LocalFrame* frame = document.GetFrameOfTreeRootDocument();
// TODO(hiroshige): Clean up |frame->view()| conditions.
DCHECK(!frame || frame->View());
if (frame && frame->View()) {
@@ -76,10 +75,10 @@ MediaValuesCached::MediaValuesCachedData::MediaValuesCachedData(
strict_mode = MediaValues::CalculateStrictMode(frame);
display_mode = MediaValues::CalculateDisplayMode(frame);
media_type = MediaValues::CalculateMediaType(frame);
- display_shape = MediaValues::CalculateDisplayShape(frame);
color_gamut = MediaValues::CalculateColorGamut(frame);
preferred_color_scheme = MediaValues::CalculatePreferredColorScheme(frame);
prefers_reduced_motion = MediaValues::CalculatePrefersReducedMotion(frame);
+ prefers_reduced_data = MediaValues::CalculatePrefersReducedData(frame);
forced_colors = MediaValues::CalculateForcedColors();
navigation_controls = MediaValues::CalculateNavigationControls(frame);
screen_spanning = MediaValues::CalculateScreenSpanning(frame);
@@ -189,10 +188,6 @@ void MediaValuesCached::OverrideViewportDimensions(double width,
data_.viewport_height = height;
}
-DisplayShape MediaValuesCached::GetDisplayShape() const {
- return data_.display_shape;
-}
-
ColorSpaceGamut MediaValuesCached::ColorGamut() const {
return data_.color_gamut;
}
@@ -205,6 +200,10 @@ bool MediaValuesCached::PrefersReducedMotion() const {
return data_.prefers_reduced_motion;
}
+bool MediaValuesCached::PrefersReducedData() const {
+ return data_.prefers_reduced_data;
+}
+
ForcedColors MediaValuesCached::GetForcedColors() const {
return data_.forced_colors;
}
diff --git a/chromium/third_party/blink/renderer/core/css/media_values_cached.h b/chromium/third_party/blink/renderer/core/css/media_values_cached.h
index cb0a8965258..5c1efda0107 100644
--- a/chromium/third_party/blink/renderer/core/css/media_values_cached.h
+++ b/chromium/third_party/blink/renderer/core/css/media_values_cached.h
@@ -34,10 +34,10 @@ class CORE_EXPORT MediaValuesCached final : public MediaValues {
bool strict_mode;
String media_type;
blink::mojom::DisplayMode display_mode;
- DisplayShape display_shape;
ColorSpaceGamut color_gamut;
PreferredColorScheme preferred_color_scheme;
bool prefers_reduced_motion;
+ bool prefers_reduced_data = false;
ForcedColors forced_colors;
NavigationControls navigation_controls;
ScreenSpanning screen_spanning;
@@ -64,10 +64,10 @@ class CORE_EXPORT MediaValuesCached final : public MediaValues {
data.strict_mode = strict_mode;
data.media_type = media_type.IsolatedCopy();
data.display_mode = display_mode;
- data.display_shape = display_shape;
data.color_gamut = color_gamut;
data.preferred_color_scheme = preferred_color_scheme;
data.prefers_reduced_motion = prefers_reduced_motion;
+ data.prefers_reduced_data = prefers_reduced_data;
data.forced_colors = forced_colors;
data.navigation_controls = navigation_controls;
data.screen_spanning = screen_spanning;
@@ -105,10 +105,10 @@ class CORE_EXPORT MediaValuesCached final : public MediaValues {
bool HasValues() const override;
const String MediaType() const override;
blink::mojom::DisplayMode DisplayMode() const override;
- DisplayShape GetDisplayShape() const override;
ColorSpaceGamut ColorGamut() const override;
PreferredColorScheme GetPreferredColorScheme() const override;
bool PrefersReducedMotion() const override;
+ bool PrefersReducedData() const override;
ForcedColors GetForcedColors() const override;
NavigationControls GetNavigationControls() const override;
ScreenSpanning GetScreenSpanning() const override;
diff --git a/chromium/third_party/blink/renderer/core/css/media_values_dynamic.cc b/chromium/third_party/blink/renderer/core/css/media_values_dynamic.cc
index 1f1a000dc7f..775d71647fd 100644
--- a/chromium/third_party/blink/renderer/core/css/media_values_dynamic.cc
+++ b/chromium/third_party/blink/renderer/core/css/media_values_dynamic.cc
@@ -17,7 +17,7 @@
namespace blink {
MediaValues* MediaValuesDynamic::Create(Document& document) {
- return MediaValuesDynamic::Create(document.GetFrameOfMasterDocument());
+ return MediaValuesDynamic::Create(document.GetFrameOfTreeRootDocument());
}
MediaValues* MediaValuesDynamic::Create(LocalFrame* frame) {
@@ -136,10 +136,6 @@ bool MediaValuesDynamic::StrictMode() const {
return CalculateStrictMode(frame_);
}
-DisplayShape MediaValuesDynamic::GetDisplayShape() const {
- return CalculateDisplayShape(frame_);
-}
-
ColorSpaceGamut MediaValuesDynamic::ColorGamut() const {
return CalculateColorGamut(frame_);
}
@@ -152,6 +148,10 @@ bool MediaValuesDynamic::PrefersReducedMotion() const {
return CalculatePrefersReducedMotion(frame_);
}
+bool MediaValuesDynamic::PrefersReducedData() const {
+ return CalculatePrefersReducedData(frame_);
+}
+
ForcedColors MediaValuesDynamic::GetForcedColors() const {
return CalculateForcedColors();
}
@@ -172,7 +172,7 @@ bool MediaValuesDynamic::HasValues() const {
return frame_;
}
-void MediaValuesDynamic::Trace(Visitor* visitor) {
+void MediaValuesDynamic::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
MediaValues::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/media_values_dynamic.h b/chromium/third_party/blink/renderer/core/css/media_values_dynamic.h
index cc1c0f2f8f5..1604db3d98c 100644
--- a/chromium/third_party/blink/renderer/core/css/media_values_dynamic.h
+++ b/chromium/third_party/blink/renderer/core/css/media_values_dynamic.h
@@ -46,10 +46,10 @@ class CORE_EXPORT MediaValuesDynamic : public MediaValues {
bool StrictMode() const override;
const String MediaType() const override;
blink::mojom::DisplayMode DisplayMode() const override;
- DisplayShape GetDisplayShape() const override;
ColorSpaceGamut ColorGamut() const override;
PreferredColorScheme GetPreferredColorScheme() const override;
bool PrefersReducedMotion() const override;
+ bool PrefersReducedData() const override;
ForcedColors GetForcedColors() const override;
NavigationControls GetNavigationControls() const override;
ScreenSpanning GetScreenSpanning() const override;
@@ -57,7 +57,7 @@ class CORE_EXPORT MediaValuesDynamic : public MediaValues {
bool HasValues() const override;
void OverrideViewportDimensions(double width, double height) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
Member<LocalFrame> frame_;
diff --git a/chromium/third_party/blink/renderer/core/css/offscreen_font_selector.cc b/chromium/third_party/blink/renderer/core/css/offscreen_font_selector.cc
index 24a9d2e6242..1a4b6e34dc8 100644
--- a/chromium/third_party/blink/renderer/core/css/offscreen_font_selector.cc
+++ b/chromium/third_party/blink/renderer/core/css/offscreen_font_selector.cc
@@ -107,7 +107,7 @@ void OffscreenFontSelector::FontFaceInvalidated(FontInvalidationReason) {
FontCacheInvalidated();
}
-void OffscreenFontSelector::Trace(Visitor* visitor) {
+void OffscreenFontSelector::Trace(Visitor* visitor) const {
visitor->Trace(execution_context_);
visitor->Trace(font_face_cache_);
FontSelector::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/offscreen_font_selector.h b/chromium/third_party/blink/renderer/core/css/offscreen_font_selector.h
index e22ce48f1ba..24660bb4147 100644
--- a/chromium/third_party/blink/renderer/core/css/offscreen_font_selector.h
+++ b/chromium/third_party/blink/renderer/core/css/offscreen_font_selector.h
@@ -69,7 +69,7 @@ class CORE_EXPORT OffscreenFontSelector : public FontSelector {
return execution_context_;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
void DispatchInvalidationCallbacks();
diff --git a/chromium/third_party/blink/renderer/core/css/page_rule_collector.cc b/chromium/third_party/blink/renderer/core/css/page_rule_collector.cc
index 0b20fc696dc..f4818660c35 100644
--- a/chromium/third_party/blink/renderer/core/css/page_rule_collector.cc
+++ b/chromium/third_party/blink/renderer/core/css/page_rule_collector.cc
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/style_rule.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
namespace blink {
@@ -58,17 +59,13 @@ bool PageRuleCollector::IsFirstPage(int page_index) const {
return (!page_index);
}
-String PageRuleCollector::PageName(int /* pageIndex */) const {
- // FIXME: Implement page index to page name mapping.
- return "";
-}
-
PageRuleCollector::PageRuleCollector(const ComputedStyle* root_element_style,
int page_index,
+ const AtomicString& page_name,
MatchResult& match_result)
: is_left_page_(IsLeftPage(root_element_style, page_index)),
is_first_page_(IsFirstPage(page_index)),
- page_name_(PageName(page_index)),
+ page_name_(page_name),
result_(match_result) {}
void PageRuleCollector::MatchPageRules(RuleSet* rules) {
@@ -77,8 +74,7 @@ void PageRuleCollector::MatchPageRules(RuleSet* rules) {
rules->CompactRulesIfNeeded();
HeapVector<Member<StyleRulePage>> matched_page_rules;
- MatchPageRulesForList(matched_page_rules, rules->PageRules(), is_left_page_,
- is_first_page_, page_name_);
+ MatchPageRulesForList(matched_page_rules, rules->PageRules());
if (matched_page_rules.IsEmpty())
return;
@@ -92,7 +88,7 @@ void PageRuleCollector::MatchPageRules(RuleSet* rules) {
static bool CheckPageSelectorComponents(const CSSSelector* selector,
bool is_left_page,
bool is_first_page,
- const String& page_name) {
+ const AtomicString& page_name) {
for (const CSSSelector* component = selector; component;
component = component->TagHistory()) {
if (component->Match() == CSSSelector::kTag) {
@@ -114,15 +110,12 @@ static bool CheckPageSelectorComponents(const CSSSelector* selector,
void PageRuleCollector::MatchPageRulesForList(
HeapVector<Member<StyleRulePage>>& matched_rules,
- const HeapVector<Member<StyleRulePage>>& rules,
- bool is_left_page,
- bool is_first_page,
- const String& page_name) {
+ const HeapVector<Member<StyleRulePage>>& rules) {
for (unsigned i = 0; i < rules.size(); ++i) {
StyleRulePage* rule = rules[i];
- if (!CheckPageSelectorComponents(rule->Selector(), is_left_page,
- is_first_page, page_name))
+ if (!CheckPageSelectorComponents(rule->Selector(), is_left_page_,
+ is_first_page_, page_name_))
continue;
// If the rule has no properties to apply, then ignore it.
diff --git a/chromium/third_party/blink/renderer/core/css/page_rule_collector.h b/chromium/third_party/blink/renderer/core/css/page_rule_collector.h
index f8fe90eb998..57d8fbb71e1 100644
--- a/chromium/third_party/blink/renderer/core/css/page_rule_collector.h
+++ b/chromium/third_party/blink/renderer/core/css/page_rule_collector.h
@@ -36,6 +36,7 @@ class PageRuleCollector {
public:
PageRuleCollector(const ComputedStyle* root_element_style,
int page_index,
+ const AtomicString& page_name,
MatchResult&);
void MatchPageRules(RuleSet* rules);
@@ -49,17 +50,13 @@ class PageRuleCollector {
return !IsLeftPage(root_element_style, page_index);
}
bool IsFirstPage(int page_index) const;
- String PageName(int page_index) const;
void MatchPageRulesForList(HeapVector<Member<StyleRulePage>>& matched_rules,
- const HeapVector<Member<StyleRulePage>>& rules,
- bool is_left_page,
- bool is_first_page,
- const String& page_name);
+ const HeapVector<Member<StyleRulePage>>& rules);
const bool is_left_page_;
const bool is_first_page_;
- const String page_name_;
+ const AtomicString page_name_;
MatchResult& result_;
};
diff --git a/chromium/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.cc b/chromium/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.cc
index 05ff29080e3..fc299dd09c6 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.cc
@@ -6,6 +6,7 @@
#include "third_party/blink/renderer/core/css/css_custom_property_declaration.h"
#include "third_party/blink/renderer/core/css/css_font_face_src_value.h"
+#include "third_party/blink/renderer/core/css/css_id_selector_value.h"
#include "third_party/blink/renderer/core/css/css_string_value.h"
#include "third_party/blink/renderer/core/css/css_unicode_range_value.h"
#include "third_party/blink/renderer/core/css/css_value.h"
@@ -31,13 +32,13 @@ CSSValue* ConsumeFontVariantList(CSSParserTokenRange& range) {
// 'all' is only allowed in @font-face and with no other values.
if (values->length())
return nullptr;
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
}
CSSIdentifierValue* font_variant =
css_parsing_utils::ConsumeFontVariantCSS21(range);
if (font_variant)
values->Append(*font_variant);
- } while (css_property_parser_helpers::ConsumeCommaIncludingWhitespace(range));
+ } while (css_parsing_utils::ConsumeCommaIncludingWhitespace(range));
if (values->length())
return values;
@@ -46,7 +47,7 @@ CSSValue* ConsumeFontVariantList(CSSParserTokenRange& range) {
}
CSSIdentifierValue* ConsumeFontDisplay(CSSParserTokenRange& range) {
- return css_property_parser_helpers::ConsumeIdent<
+ return css_parsing_utils::ConsumeIdent<
CSSValueID::kAuto, CSSValueID::kBlock, CSSValueID::kSwap,
CSSValueID::kFallback, CSSValueID::kOptional>(range);
}
@@ -65,7 +66,7 @@ CSSValueList* ConsumeFontFaceUnicodeRange(CSSParserTokenRange& range) {
return nullptr;
values->Append(
*MakeGarbageCollected<cssvalue::CSSUnicodeRangeValue>(start, end));
- } while (css_property_parser_helpers::ConsumeCommaIncludingWhitespace(range));
+ } while (css_parsing_utils::ConsumeCommaIncludingWhitespace(range));
return values;
}
@@ -73,8 +74,7 @@ CSSValueList* ConsumeFontFaceUnicodeRange(CSSParserTokenRange& range) {
CSSValue* ConsumeFontFaceSrcURI(CSSParserTokenRange& range,
const CSSParserContext& context) {
String url =
- css_property_parser_helpers::ConsumeUrlAsStringView(range, context)
- .ToString();
+ css_parsing_utils::ConsumeUrlAsStringView(range, context).ToString();
if (url.IsNull())
return nullptr;
CSSFontFaceSrcValue* uri_value(CSSFontFaceSrcValue::Create(
@@ -89,8 +89,7 @@ CSSValue* ConsumeFontFaceSrcURI(CSSParserTokenRange& range,
// FIXME: https://drafts.csswg.org/css-fonts says that format() contains a
// comma-separated list of strings, but CSSFontFaceSrcValue stores only one
// format. Allowing one format for now.
- CSSParserTokenRange args =
- css_property_parser_helpers::ConsumeFunction(range);
+ CSSParserTokenRange args = css_parsing_utils::ConsumeFunction(range);
const CSSParserToken& arg = args.ConsumeIncludingWhitespace();
if ((arg.GetType() != kStringToken) || !args.AtEnd())
return nullptr;
@@ -100,8 +99,7 @@ CSSValue* ConsumeFontFaceSrcURI(CSSParserTokenRange& range,
CSSValue* ConsumeFontFaceSrcLocal(CSSParserTokenRange& range,
const CSSParserContext& context) {
- CSSParserTokenRange args =
- css_property_parser_helpers::ConsumeFunction(range);
+ CSSParserTokenRange args = css_parsing_utils::ConsumeFunction(range);
network::mojom::CSPDisposition should_check_content_security_policy =
context.ShouldCheckContentSecurityPolicy();
if (args.Peek().GetType() == kStringToken) {
@@ -140,10 +138,69 @@ CSSValueList* ConsumeFontFaceSrc(CSSParserTokenRange& range,
if (!parsed_value)
return nullptr;
values->Append(*parsed_value);
- } while (css_property_parser_helpers::ConsumeCommaIncludingWhitespace(range));
+ } while (css_parsing_utils::ConsumeCommaIncludingWhitespace(range));
return values;
}
+CSSValue* ConsumeScrollTimelineSource(CSSParserTokenRange& range) {
+ if (range.Peek().FunctionId() == CSSValueID::kSelector) {
+ auto block = css_parsing_utils::ConsumeFunction(range);
+ block.ConsumeWhitespace();
+ if (auto* id_value = css_parsing_utils::ConsumeIdSelector(block)) {
+ if (!block.AtEnd())
+ return nullptr;
+ auto* selector_function =
+ MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kSelector);
+ selector_function->Append(*id_value);
+ return selector_function;
+ }
+ return nullptr;
+ }
+ return css_parsing_utils::ConsumeIdent<CSSValueID::kNone>(range);
+}
+
+CSSValue* ConsumeScrollTimelineOrientation(CSSParserTokenRange& range) {
+ return css_parsing_utils::ConsumeIdent<
+ CSSValueID::kAuto, CSSValueID::kBlock, CSSValueID::kInline,
+ CSSValueID::kHorizontal, CSSValueID::kVertical>(range);
+}
+
+CSSValue* ConsumeTimeRange(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ if (auto* value = css_parsing_utils::ConsumeIdent<CSSValueID::kAuto>(range))
+ return value;
+ return css_parsing_utils::ConsumeTime(range, context, kValueRangeAll);
+}
+
+CSSValue* ConsumeDescriptor(StyleRule::RuleType rule_type,
+ AtRuleDescriptorID id,
+ CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ using Parser = AtRuleDescriptorParser;
+
+ switch (rule_type) {
+ case StyleRule::kFontFace:
+ return Parser::ParseFontFaceDescriptor(id, range, context);
+ case StyleRule::kProperty:
+ return Parser::ParseAtPropertyDescriptor(id, range, context);
+ case StyleRule::kScrollTimeline:
+ return Parser::ParseAtScrollTimelineDescriptor(id, range, context);
+ case StyleRule::kCharset:
+ case StyleRule::kStyle:
+ case StyleRule::kImport:
+ case StyleRule::kMedia:
+ case StyleRule::kPage:
+ case StyleRule::kKeyframes:
+ case StyleRule::kKeyframe:
+ case StyleRule::kNamespace:
+ case StyleRule::kSupports:
+ case StyleRule::kViewport:
+ // TODO(andruud): Handle other descriptor types here.
+ NOTREACHED();
+ return nullptr;
+ }
+}
+
} // namespace
CSSValue* AtRuleDescriptorParser::ParseFontFaceDescriptor(
@@ -234,7 +291,7 @@ CSSValue* AtRuleDescriptorParser::ParseAtPropertyDescriptor(
switch (id) {
case AtRuleDescriptorID::Syntax:
range.ConsumeWhitespace();
- parsed_value = css_property_parser_helpers::ConsumeString(range);
+ parsed_value = css_parsing_utils::ConsumeString(range);
break;
case AtRuleDescriptorID::InitialValue: {
// Note that we must retain leading whitespace here.
@@ -243,9 +300,40 @@ CSSValue* AtRuleDescriptorParser::ParseAtPropertyDescriptor(
}
case AtRuleDescriptorID::Inherits:
range.ConsumeWhitespace();
- parsed_value =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kTrue,
- CSSValueID::kFalse>(range);
+ parsed_value = css_parsing_utils::ConsumeIdent<CSSValueID::kTrue,
+ CSSValueID::kFalse>(range);
+ break;
+ default:
+ break;
+ }
+
+ if (!parsed_value || !range.AtEnd())
+ return nullptr;
+
+ return parsed_value;
+}
+
+CSSValue* AtRuleDescriptorParser::ParseAtScrollTimelineDescriptor(
+ AtRuleDescriptorID id,
+ CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ CSSValue* parsed_value = nullptr;
+
+ range.ConsumeWhitespace();
+
+ switch (id) {
+ case AtRuleDescriptorID::Source:
+ parsed_value = ConsumeScrollTimelineSource(range);
+ break;
+ case AtRuleDescriptorID::Orientation:
+ parsed_value = ConsumeScrollTimelineOrientation(range);
+ break;
+ case AtRuleDescriptorID::Start:
+ case AtRuleDescriptorID::End:
+ parsed_value = css_parsing_utils::ConsumeScrollOffset(range, context);
+ break;
+ case AtRuleDescriptorID::TimeRange:
+ parsed_value = ConsumeTimeRange(range, context);
break;
default:
break;
@@ -258,21 +346,13 @@ CSSValue* AtRuleDescriptorParser::ParseAtPropertyDescriptor(
}
bool AtRuleDescriptorParser::ParseAtRule(
+ StyleRule::RuleType rule_type,
AtRuleDescriptorID id,
CSSParserTokenRange& range,
const CSSParserContext& context,
HeapVector<CSSPropertyValue, 256>& parsed_descriptors) {
- const CSSParserTokenRange original_range = range;
+ CSSValue* result = ConsumeDescriptor(rule_type, id, range, context);
- // TODO(meade): Handle other descriptor types here.
- CSSValue* result =
- AtRuleDescriptorParser::ParseFontFaceDescriptor(id, range, context);
-
- if (!result) {
- range = original_range;
- result =
- AtRuleDescriptorParser::ParseAtPropertyDescriptor(id, range, context);
- }
if (!result)
return false;
// Convert to CSSPropertyID for legacy compatibility,
diff --git a/chromium/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h b/chromium/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h
index 9b275e7e0ad..3ff269fca25 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/css/css_property_value.h"
#include "third_party/blink/renderer/core/css/parser/at_rule_descriptors.h"
+#include "third_party/blink/renderer/core/css/style_rule.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -19,7 +20,8 @@ class AtRuleDescriptorParser {
STATIC_ONLY(AtRuleDescriptorParser);
public:
- static bool ParseAtRule(AtRuleDescriptorID,
+ static bool ParseAtRule(StyleRule::RuleType,
+ AtRuleDescriptorID,
CSSParserTokenRange&,
const CSSParserContext&,
HeapVector<CSSPropertyValue, 256>&);
@@ -34,6 +36,9 @@ class AtRuleDescriptorParser {
static CSSValue* ParseAtPropertyDescriptor(AtRuleDescriptorID,
CSSParserTokenRange&,
const CSSParserContext&);
+ static CSSValue* ParseAtScrollTimelineDescriptor(AtRuleDescriptorID,
+ CSSParserTokenRange&,
+ const CSSParserContext&);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/parser/at_rule_names.json5 b/chromium/third_party/blink/renderer/core/css/parser/at_rule_names.json5
index c5c1f0023d3..b5ada54f9c7 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/at_rule_names.json5
+++ b/chromium/third_party/blink/renderer/core/css/parser/at_rule_names.json5
@@ -15,6 +15,9 @@
data: [
{
+ name: "end",
+ },
+ {
name: "font-display",
},
{
@@ -67,12 +70,21 @@
name: "orientation",
},
{
+ name: "source",
+ },
+ {
name: "src",
},
{
+ name: "start",
+ },
+ {
name: "syntax"
},
{
+ name: "time-range",
+ },
+ {
name: "unicode-range",
},
{
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css.proto b/chromium/third_party/blink/renderer/core/css/parser/css.proto
index 973f7c865ad..56ae25de9f4 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css.proto
+++ b/chromium/third_party/blink/renderer/core/css/parser/css.proto
@@ -1441,7 +1441,9 @@ message Property {
OVERSCROLL_BEHAVIOR_BLOCK = 552;
OVERSCROLL_BEHAVIOR_X = 553;
OVERSCROLL_BEHAVIOR_Y = 554;
- INVALID_PROPERTY = 555;
+ ANIMATION_TIMELINE = 555;
+ COUNTER_SET = 556;
+ INVALID_PROPERTY = 557;
}
required NameId name_id = 1;
}
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_at_rule_id.cc b/chromium/third_party/blink/renderer/core/css/parser/css_at_rule_id.cc
index e9ed122eff4..c7f43940648 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_at_rule_id.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_at_rule_id.cc
@@ -27,6 +27,8 @@ CSSAtRuleID CssAtRuleID(StringView name) {
return kCSSAtRulePage;
if (EqualIgnoringASCIICase(name, "property"))
return kCSSAtRuleProperty;
+ if (EqualIgnoringASCIICase(name, "scroll-timeline"))
+ return kCSSAtRuleScrollTimeline;
if (EqualIgnoringASCIICase(name, "supports"))
return kCSSAtRuleSupports;
if (EqualIgnoringASCIICase(name, "viewport"))
@@ -63,7 +65,10 @@ void CountAtRule(const CSSParserContext* context, CSSAtRuleID rule_id) {
break;
case kCSSAtRuleProperty:
feature = WebFeature::kCSSAtRuleProperty;
- return;
+ break;
+ case kCSSAtRuleScrollTimeline:
+ feature = WebFeature::kCSSAtRuleScrollTimeline;
+ break;
case kCSSAtRuleSupports:
feature = WebFeature::kCSSAtRuleSupports;
break;
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_at_rule_id.h b/chromium/third_party/blink/renderer/core/css/parser/css_at_rule_id.h
index f15629e7dbb..a660027a447 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_at_rule_id.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_at_rule_id.h
@@ -21,6 +21,7 @@ enum CSSAtRuleID {
kCSSAtRuleNamespace,
kCSSAtRulePage,
kCSSAtRuleProperty,
+ kCSSAtRuleScrollTimeline,
kCSSAtRuleSupports,
kCSSAtRuleViewport,
kCSSAtRuleWebkitKeyframes,
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.cc b/chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.cc
index d4c77529916..aefc93ad18b 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.cc
@@ -36,7 +36,7 @@ const CSSParserContext* CSSLazyParsingState::Context() {
return context_;
}
-void CSSLazyParsingState::Trace(Visitor* visitor) {
+void CSSLazyParsingState::Trace(Visitor* visitor) const {
visitor->Trace(owning_contents_);
visitor->Trace(document_);
visitor->Trace(context_);
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.h b/chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.h
index f892be65c7b..0a0d1aa59a9 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.h
@@ -30,7 +30,7 @@ class CSSLazyParsingState final : public GarbageCollected<CSSLazyParsingState> {
const CSSParserContext* Context();
const String& SheetText() const { return sheet_text_; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<const CSSParserContext> context_;
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.h b/chromium/third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.h
index afbf2a9c6bc..0ee1caa8fc3 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.h
@@ -21,7 +21,7 @@ class CSSLazyPropertyParserImpl : public CSSLazyPropertyParser {
// CSSLazyPropertyParser:
CSSPropertyValueSet* ParseProperties() override;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(lazy_state_);
CSSLazyPropertyParser::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_parser.cc b/chromium/third_party/blink/renderer/core/css/parser/css_parser.cc
index 37d310b53ff..8a090999f7b 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_parser.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_parser.cc
@@ -11,11 +11,11 @@
#include "third_party/blink/renderer/core/css/parser/css_parser_fast_paths.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_impl.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser.h"
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
#include "third_party/blink/renderer/core/css/parser/css_selector_parser.h"
#include "third_party/blink/renderer/core/css/parser/css_supports_parser.h"
#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
#include "third_party/blink/renderer/core/css/parser/css_variable_parser.h"
+#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
#include "third_party/blink/renderer/core/css/style_color.h"
#include "third_party/blink/renderer/core/css/style_rule.h"
#include "third_party/blink/renderer/core/css/style_sheet_contents.h"
@@ -284,8 +284,8 @@ CSSPrimitiveValue* CSSParser::ParseLengthPercentage(
CSSTokenizer tokenizer(string);
const auto tokens = tokenizer.TokenizeToEOF();
CSSParserTokenRange range(tokens);
- return css_property_parser_helpers::ConsumeLengthOrPercent(range, *context,
- kValueRangeAll);
+ return css_parsing_utils::ConsumeLengthOrPercent(range, *context,
+ kValueRangeAll);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_parser_context.cc b/chromium/third_party/blink/renderer/core/css/parser/css_parser_context.cc
index 62ce75ba3d9..5c1292cf13b 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_parser_context.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_parser_context.cc
@@ -117,7 +117,7 @@ CSSParserContext::CSSParserContext(
charset,
document.InQuirksMode() ? kHTMLQuirksMode : kHTMLStandardMode,
document.ImportsController() && profile == kLiveProfile
- ? (document.ImportsController()->Master()->InQuirksMode()
+ ? (document.ImportsController()->TreeRoot()->InQuirksMode()
? kHTMLQuirksMode
: kHTMLStandardMode)
: document.InQuirksMode() ? kHTMLQuirksMode : kHTMLStandardMode,
@@ -242,8 +242,8 @@ void CSSParserContext::Count(WebFeature feature) const {
}
void CSSParserContext::CountDeprecation(WebFeature feature) const {
- if (IsUseCounterRecordingEnabled())
- Deprecation::CountDeprecation(*document_, feature);
+ if (IsUseCounterRecordingEnabled() && document_)
+ Deprecation::CountDeprecation(document_->GetExecutionContext(), feature);
}
void CSSParserContext::Count(CSSParserMode mode, CSSPropertyID property) const {
@@ -283,14 +283,15 @@ bool CSSParserContext::CustomElementsV0Enabled() const {
// Support features conservatively.
if (!document_)
return true;
- return RuntimeEnabledFeatures::CustomElementsV0Enabled(document_);
+ return RuntimeEnabledFeatures::CustomElementsV0Enabled(
+ document_->GetExecutionContext());
}
bool CSSParserContext::IsForMarkupSanitization() const {
return document_ && document_->IsForMarkupSanitization();
}
-void CSSParserContext::Trace(Visitor* visitor) {
+void CSSParserContext::Trace(Visitor* visitor) const {
visitor->Trace(document_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_parser_context.h b/chromium/third_party/blink/renderer/core/css/parser/css_parser_context.h
index 2dce736a757..33b458f2191 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_parser_context.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_parser_context.h
@@ -156,7 +156,7 @@ class CORE_EXPORT CSSParserContext final
base::AutoReset<CSSParserMode> mode_reset_;
};
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
friend class ParserModeOverridingScope;
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc b/chromium/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc
index 7f761601baa..aa61fdfda51 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc
@@ -21,6 +21,7 @@
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/wtf/text/character_visitor.h"
#include "third_party/blink/renderer/platform/wtf/text/string_to_number.h"
namespace blink {
@@ -120,17 +121,15 @@ static CSSValue* ParseSimpleLengthValue(CSSPropertyID property_id,
!IsSimpleLengthPropertyID(property_id, accepts_negative_numbers))
return nullptr;
- unsigned length = string.length();
double number;
CSSPrimitiveValue::UnitType unit = CSSPrimitiveValue::UnitType::kNumber;
- if (string.Is8Bit()) {
- if (!ParseSimpleLength(string.Characters8(), length, unit, number))
- return nullptr;
- } else {
- if (!ParseSimpleLength(string.Characters16(), length, unit, number))
- return nullptr;
- }
+ const bool parsed_simple_length =
+ WTF::VisitCharacters(string, [&](const auto* chars, unsigned length) {
+ return ParseSimpleLength(chars, length, unit, number);
+ });
+ if (!parsed_simple_length)
+ return nullptr;
if (unit == CSSPrimitiveValue::UnitType::kNumber) {
if (css_parser_mode == kSVGAttributeMode)
@@ -522,13 +521,10 @@ CSSValue* CSSParserFastPaths::ParseColor(const String& string,
bool quirks_mode = IsQuirksModeBehavior(parser_mode);
// Fast path for hex colors and rgb()/rgba() colors
- bool parse_result;
- if (string.Is8Bit())
- parse_result = FastParseColorInternal(color, string.Characters8(),
- string.length(), quirks_mode);
- else
- parse_result = FastParseColorInternal(color, string.Characters16(),
- string.length(), quirks_mode);
+ bool parse_result =
+ WTF::VisitCharacters(string, [&](const auto* chars, unsigned length) {
+ return FastParseColorInternal(color, chars, length, quirks_mode);
+ });
if (!parse_result)
return nullptr;
return cssvalue::CSSColorValue::Create(color);
@@ -912,8 +908,7 @@ bool CSSParserFastPaths::IsValidKeywordPropertyAndValue(
return value_id == CSSValueID::kAuto || value_id == CSSValueID::kLoose ||
value_id == CSSValueID::kNormal ||
value_id == CSSValueID::kStrict ||
- (RuntimeEnabledFeatures::CSS3TextBreakAnywhereEnabled() &&
- value_id == CSSValueID::kAnywhere);
+ value_id == CSSValueID::kAnywhere;
case CSSPropertyID::kWebkitLineBreak:
return value_id == CSSValueID::kAuto || value_id == CSSValueID::kLoose ||
value_id == CSSValueID::kNormal ||
@@ -1335,38 +1330,33 @@ static bool TransformCanLikelyUseFastPath(const CharType* chars,
return i == length;
}
-template <typename CharType>
-static CSSValueList* ParseSimpleTransformList(const CharType* chars,
- unsigned length) {
- if (!TransformCanLikelyUseFastPath(chars, length))
- return nullptr;
- const CharType*& pos = chars;
- const CharType* end = chars + length;
- CSSValueList* transform_list = nullptr;
- while (pos < end) {
- while (pos < end && IsCSSSpace(*pos))
- ++pos;
- if (pos >= end)
- break;
- auto* transform_value = ParseSimpleTransformValue(pos, end);
- if (!transform_value)
- return nullptr;
- if (!transform_list)
- transform_list = CSSValueList::CreateSpaceSeparated();
- transform_list->Append(*transform_value);
- }
- return transform_list;
-}
-
static CSSValue* ParseSimpleTransform(CSSPropertyID property_id,
const String& string) {
DCHECK(!string.IsEmpty());
if (property_id != CSSPropertyID::kTransform)
return nullptr;
- if (string.Is8Bit())
- return ParseSimpleTransformList(string.Characters8(), string.length());
- return ParseSimpleTransformList(string.Characters16(), string.length());
+
+ return WTF::VisitCharacters(
+ string, [&](const auto* pos, unsigned length) -> CSSValueList* {
+ if (!TransformCanLikelyUseFastPath(pos, length))
+ return nullptr;
+ const auto* end = pos + length;
+ CSSValueList* transform_list = nullptr;
+ while (pos < end) {
+ while (pos < end && IsCSSSpace(*pos))
+ ++pos;
+ if (pos >= end)
+ break;
+ auto* transform_value = ParseSimpleTransformValue(pos, end);
+ if (!transform_value)
+ return nullptr;
+ if (!transform_list)
+ transform_list = CSSValueList::CreateSpaceSeparated();
+ transform_list->Append(*transform_value);
+ }
+ return transform_list;
+ });
}
CSSValue* CSSParserFastPaths::MaybeParseValue(CSSPropertyID property_id,
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_parser_impl.cc b/chromium/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
index 8ea1249ab31..db3f54682fa 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
@@ -472,6 +472,43 @@ bool CSSParserImpl::ConsumeRuleList(CSSParserTokenStream& stream,
return first_rule_valid;
}
+CSSParserTokenRange ConsumeAtRulePrelude(CSSParserTokenStream& stream) {
+ return stream.ConsumeUntilPeekedTypeIs<kLeftBraceToken, kSemicolonToken>();
+}
+
+bool ConsumeEndOfPreludeForAtRuleWithoutBlock(CSSParserTokenStream& stream) {
+ if (stream.AtEnd() || stream.UncheckedPeek().GetType() == kSemicolonToken) {
+ if (!stream.UncheckedAtEnd())
+ stream.UncheckedConsume(); // kSemicolonToken
+ return true;
+ }
+
+ // Consume the erroneous block.
+ CSSParserTokenStream::BlockGuard guard(stream);
+ return false; // Parse error, we expected no block.
+}
+
+bool ConsumeEndOfPreludeForAtRuleWithBlock(CSSParserTokenStream& stream) {
+ if (stream.AtEnd() || stream.UncheckedPeek().GetType() == kSemicolonToken) {
+ if (!stream.UncheckedAtEnd())
+ stream.UncheckedConsume(); // kSemicolonToken
+ return false; // Parse error, we expected a block.
+ }
+
+ return true;
+}
+
+void ConsumeErroneousAtRule(CSSParserTokenStream& stream) {
+ // Consume the prelude and block if present.
+ ConsumeAtRulePrelude(stream);
+ if (!stream.AtEnd()) {
+ if (stream.UncheckedPeek().GetType() == kLeftBraceToken)
+ CSSParserTokenStream::BlockGuard guard(stream);
+ else
+ stream.UncheckedConsume(); // kSemicolonToken
+ }
+}
+
StyleRuleBase* CSSParserImpl::ConsumeAtRule(CSSParserTokenStream& stream,
AllowedRulesType allowed_rules) {
DCHECK_EQ(stream.Peek().GetType(), kAtKeywordToken);
@@ -484,63 +521,51 @@ StyleRuleBase* CSSParserImpl::ConsumeAtRule(CSSParserTokenStream& stream,
if (allowed_rules <= kAllowImportRules && id == kCSSAtRuleImport)
import_prelude_uri = ConsumeStringOrURI(stream);
- stream.EnsureLookAhead();
- const wtf_size_t prelude_offset_start = stream.LookAheadOffset();
- const CSSParserTokenRange prelude =
- stream.ConsumeUntilPeekedTypeIs<kLeftBraceToken, kSemicolonToken>();
- const RangeOffset prelude_offset(prelude_offset_start,
- stream.LookAheadOffset());
-
if (id != kCSSAtRuleInvalid && context_->IsUseCounterRecordingEnabled())
CountAtRule(context_, id);
- if (stream.AtEnd() || stream.UncheckedPeek().GetType() == kSemicolonToken) {
- if (!stream.UncheckedAtEnd())
- stream.UncheckedConsume(); // kSemicolonToken
-
- if (allowed_rules == kAllowCharsetRules && id == kCSSAtRuleCharset)
- return ConsumeCharsetRule(prelude);
- if (allowed_rules <= kAllowImportRules && id == kCSSAtRuleImport) {
- return ConsumeImportRule(std::move(import_prelude_uri), prelude,
- prelude_offset);
- }
- if (allowed_rules <= kAllowNamespaceRules && id == kCSSAtRuleNamespace)
- return ConsumeNamespaceRule(prelude);
- return nullptr; // Parse error, unrecognised at-rule without block
+ if (allowed_rules == kKeyframeRules || allowed_rules == kFontFeatureRules ||
+ allowed_rules == kNoRules) {
+ // Parse error, no at-rules supported inside @keyframes,
+ // @font-feature-values, or blocks supported inside declaration lists.
+ ConsumeErroneousAtRule(stream);
+ return nullptr;
}
- CSSParserTokenStream::BlockGuard guard(stream);
-
- if (allowed_rules == kKeyframeRules)
- return nullptr; // Parse error, no at-rules supported inside @keyframes
- // Parse error, no at-rules currently supported inside @font-feature-values
- if (allowed_rules == kFontFeatureRules)
- return nullptr;
- if (allowed_rules == kNoRules)
- return nullptr; // Parse error, no at-rules with blocks supported inside
- // declaration lists
-
- DCHECK_LE(allowed_rules, kRegularRules);
-
- switch (id) {
- case kCSSAtRuleMedia:
- return ConsumeMediaRule(prelude, prelude_offset, stream);
- case kCSSAtRuleSupports:
- return ConsumeSupportsRule(prelude, prelude_offset, stream);
- case kCSSAtRuleViewport:
- return ConsumeViewportRule(prelude, prelude_offset, stream);
- case kCSSAtRuleFontFace:
- return ConsumeFontFaceRule(prelude, prelude_offset, stream);
- case kCSSAtRuleWebkitKeyframes:
- return ConsumeKeyframesRule(true, prelude, prelude_offset, stream);
- case kCSSAtRuleKeyframes:
- return ConsumeKeyframesRule(false, prelude, prelude_offset, stream);
- case kCSSAtRulePage:
- return ConsumePageRule(prelude, prelude_offset, stream);
- case kCSSAtRuleProperty:
- return ConsumePropertyRule(prelude, prelude_offset, stream);
- default:
- return nullptr; // Parse error, unrecognised at-rule with block
+ stream.EnsureLookAhead();
+ if (allowed_rules == kAllowCharsetRules && id == kCSSAtRuleCharset) {
+ return ConsumeCharsetRule(stream);
+ } else if (allowed_rules <= kAllowImportRules && id == kCSSAtRuleImport) {
+ return ConsumeImportRule(std::move(import_prelude_uri), stream);
+ } else if (allowed_rules <= kAllowNamespaceRules &&
+ id == kCSSAtRuleNamespace) {
+ return ConsumeNamespaceRule(stream);
+ } else {
+ DCHECK_LE(allowed_rules, kRegularRules);
+
+ switch (id) {
+ case kCSSAtRuleMedia:
+ return ConsumeMediaRule(stream);
+ case kCSSAtRuleSupports:
+ return ConsumeSupportsRule(stream);
+ case kCSSAtRuleViewport:
+ return ConsumeViewportRule(stream);
+ case kCSSAtRuleFontFace:
+ return ConsumeFontFaceRule(stream);
+ case kCSSAtRuleWebkitKeyframes:
+ return ConsumeKeyframesRule(true, stream);
+ case kCSSAtRuleKeyframes:
+ return ConsumeKeyframesRule(false, stream);
+ case kCSSAtRulePage:
+ return ConsumePageRule(stream);
+ case kCSSAtRuleProperty:
+ return ConsumePropertyRule(stream);
+ case kCSSAtRuleScrollTimeline:
+ return ConsumeScrollTimelineRule(stream);
+ default:
+ ConsumeErroneousAtRule(stream);
+ return nullptr; // Parse error, unrecognised or not-allowed at-rule
+ }
}
}
@@ -616,7 +641,11 @@ static AtomicString ConsumeStringOrURI(CSSParserTokenRange& range) {
}
StyleRuleCharset* CSSParserImpl::ConsumeCharsetRule(
- CSSParserTokenRange prelude) {
+ CSSParserTokenStream& stream) {
+ CSSParserTokenRange prelude = ConsumeAtRulePrelude(stream);
+ if (!ConsumeEndOfPreludeForAtRuleWithoutBlock(stream))
+ return nullptr;
+
const CSSParserToken& string = prelude.ConsumeIncludingWhitespace();
if (string.GetType() != kStringToken || !prelude.AtEnd())
return nullptr; // Parse error, expected a single string
@@ -625,16 +654,21 @@ StyleRuleCharset* CSSParserImpl::ConsumeCharsetRule(
StyleRuleImport* CSSParserImpl::ConsumeImportRule(
AtomicString uri,
- CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset) {
+ CSSParserTokenStream& stream) {
+ wtf_size_t prelude_offset_start = stream.LookAheadOffset();
+ CSSParserTokenRange prelude = ConsumeAtRulePrelude(stream);
+ wtf_size_t prelude_offset_end = stream.LookAheadOffset();
+ if (!ConsumeEndOfPreludeForAtRuleWithoutBlock(stream))
+ return nullptr;
+
if (uri.IsNull())
return nullptr; // Parse error, expected string or URI
if (observer_) {
- observer_->StartRuleHeader(StyleRule::kImport, prelude_offset.start);
- observer_->EndRuleHeader(prelude_offset.end);
- observer_->StartRuleBody(prelude_offset.end);
- observer_->EndRuleBody(prelude_offset.end);
+ observer_->StartRuleHeader(StyleRule::kImport, prelude_offset_start);
+ observer_->EndRuleHeader(prelude_offset_end);
+ observer_->StartRuleBody(prelude_offset_end);
+ observer_->EndRuleBody(prelude_offset_end);
}
return MakeGarbageCollected<StyleRuleImport>(
@@ -645,7 +679,11 @@ StyleRuleImport* CSSParserImpl::ConsumeImportRule(
}
StyleRuleNamespace* CSSParserImpl::ConsumeNamespaceRule(
- CSSParserTokenRange prelude) {
+ CSSParserTokenStream& stream) {
+ CSSParserTokenRange prelude = ConsumeAtRulePrelude(stream);
+ if (!ConsumeEndOfPreludeForAtRuleWithoutBlock(stream))
+ return nullptr;
+
AtomicString namespace_prefix;
if (prelude.Peek().GetType() == kIdentToken)
namespace_prefix =
@@ -658,16 +696,20 @@ StyleRuleNamespace* CSSParserImpl::ConsumeNamespaceRule(
return MakeGarbageCollected<StyleRuleNamespace>(namespace_prefix, uri);
}
-StyleRuleMedia* CSSParserImpl::ConsumeMediaRule(
- const CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset,
- CSSParserTokenStream& block) {
+StyleRuleMedia* CSSParserImpl::ConsumeMediaRule(CSSParserTokenStream& stream) {
+ wtf_size_t prelude_offset_start = stream.LookAheadOffset();
+ CSSParserTokenRange prelude = ConsumeAtRulePrelude(stream);
+ wtf_size_t prelude_offset_end = stream.LookAheadOffset();
+ if (!ConsumeEndOfPreludeForAtRuleWithBlock(stream))
+ return nullptr;
+ CSSParserTokenStream::BlockGuard guard(stream);
+
HeapVector<Member<StyleRuleBase>> rules;
if (observer_) {
- observer_->StartRuleHeader(StyleRule::kMedia, prelude_offset.start);
- observer_->EndRuleHeader(prelude_offset.end);
- observer_->StartRuleBody(block.Offset());
+ observer_->StartRuleHeader(StyleRule::kMedia, prelude_offset_start);
+ observer_->EndRuleHeader(prelude_offset_end);
+ observer_->StartRuleBody(stream.Offset());
}
if (style_sheet_)
@@ -676,38 +718,43 @@ StyleRuleMedia* CSSParserImpl::ConsumeMediaRule(
const auto media = MediaQueryParser::ParseMediaQuerySet(
prelude, context_->GetExecutionContext());
- ConsumeRuleList(block, kRegularRuleList,
+ ConsumeRuleList(stream, kRegularRuleList,
[&rules](StyleRuleBase* rule) { rules.push_back(rule); });
if (observer_)
- observer_->EndRuleBody(block.Offset());
+ observer_->EndRuleBody(stream.Offset());
return MakeGarbageCollected<StyleRuleMedia>(media, rules);
}
StyleRuleSupports* CSSParserImpl::ConsumeSupportsRule(
- const CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset,
- CSSParserTokenStream& block) {
+ CSSParserTokenStream& stream) {
+ wtf_size_t prelude_offset_start = stream.LookAheadOffset();
+ CSSParserTokenRange prelude = ConsumeAtRulePrelude(stream);
+ wtf_size_t prelude_offset_end = stream.LookAheadOffset();
+ if (!ConsumeEndOfPreludeForAtRuleWithBlock(stream))
+ return nullptr;
+ CSSParserTokenStream::BlockGuard guard(stream);
+
CSSSupportsParser::Result supported = CSSSupportsParser::SupportsCondition(
prelude, *this, CSSSupportsParser::Mode::kForAtRule);
if (supported == CSSSupportsParser::Result::kParseFailure)
return nullptr; // Parse error, invalid @supports condition
if (observer_) {
- observer_->StartRuleHeader(StyleRule::kSupports, prelude_offset.start);
- observer_->EndRuleHeader(prelude_offset.end);
- observer_->StartRuleBody(block.Offset());
+ observer_->StartRuleHeader(StyleRule::kSupports, prelude_offset_start);
+ observer_->EndRuleHeader(prelude_offset_end);
+ observer_->StartRuleBody(stream.Offset());
}
const auto prelude_serialized = prelude.Serialize().StripWhiteSpace();
HeapVector<Member<StyleRuleBase>> rules;
- ConsumeRuleList(block, kRegularRuleList,
+ ConsumeRuleList(stream, kRegularRuleList,
[&rules](StyleRuleBase* rule) { rules.push_back(rule); });
if (observer_)
- observer_->EndRuleBody(block.Offset());
+ observer_->EndRuleBody(stream.Offset());
return MakeGarbageCollected<StyleRuleSupports>(
prelude_serialized, supported == CSSSupportsParser::Result::kSupported,
@@ -715,9 +762,14 @@ StyleRuleSupports* CSSParserImpl::ConsumeSupportsRule(
}
StyleRuleViewport* CSSParserImpl::ConsumeViewportRule(
- const CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset,
- CSSParserTokenStream& block) {
+ CSSParserTokenStream& stream) {
+ wtf_size_t prelude_offset_start = stream.LookAheadOffset();
+ const CSSParserTokenRange prelude = ConsumeAtRulePrelude(stream);
+ wtf_size_t prelude_offset_end = stream.LookAheadOffset();
+ if (!ConsumeEndOfPreludeForAtRuleWithBlock(stream))
+ return nullptr;
+ CSSParserTokenStream::BlockGuard guard(stream);
+
// Allow @viewport rules from UA stylesheets only.
if (!IsUASheetBehavior(context_->Mode()))
return nullptr;
@@ -726,32 +778,37 @@ StyleRuleViewport* CSSParserImpl::ConsumeViewportRule(
return nullptr; // Parser error; @viewport prelude should be empty
if (observer_) {
- observer_->StartRuleHeader(StyleRule::kViewport, prelude_offset.start);
- observer_->EndRuleHeader(prelude_offset.end);
- observer_->StartRuleBody(prelude_offset.end);
- observer_->EndRuleBody(prelude_offset.end);
+ observer_->StartRuleHeader(StyleRule::kViewport, prelude_offset_start);
+ observer_->EndRuleHeader(prelude_offset_end);
+ observer_->StartRuleBody(prelude_offset_end);
+ observer_->EndRuleBody(prelude_offset_end);
}
if (style_sheet_)
style_sheet_->SetHasViewportRule();
- ConsumeDeclarationList(block, StyleRule::kViewport);
+ ConsumeDeclarationList(stream, StyleRule::kViewport);
return MakeGarbageCollected<StyleRuleViewport>(
CreateCSSPropertyValueSet(parsed_properties_, kCSSViewportRuleMode));
}
StyleRuleFontFace* CSSParserImpl::ConsumeFontFaceRule(
- const CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset,
CSSParserTokenStream& stream) {
+ wtf_size_t prelude_offset_start = stream.LookAheadOffset();
+ CSSParserTokenRange prelude = ConsumeAtRulePrelude(stream);
+ wtf_size_t prelude_offset_end = stream.LookAheadOffset();
+ if (!ConsumeEndOfPreludeForAtRuleWithBlock(stream))
+ return nullptr;
+ CSSParserTokenStream::BlockGuard guard(stream);
+
if (!prelude.AtEnd())
return nullptr; // Parse error; @font-face prelude should be empty
if (observer_) {
- observer_->StartRuleHeader(StyleRule::kFontFace, prelude_offset.start);
- observer_->EndRuleHeader(prelude_offset.end);
- observer_->StartRuleBody(prelude_offset.end);
- observer_->EndRuleBody(prelude_offset.end);
+ observer_->StartRuleHeader(StyleRule::kFontFace, prelude_offset_start);
+ observer_->EndRuleHeader(prelude_offset_end);
+ observer_->StartRuleBody(prelude_offset_end);
+ observer_->EndRuleBody(prelude_offset_end);
}
if (style_sheet_)
@@ -764,9 +821,14 @@ StyleRuleFontFace* CSSParserImpl::ConsumeFontFaceRule(
StyleRuleKeyframes* CSSParserImpl::ConsumeKeyframesRule(
bool webkit_prefixed,
- CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset,
- CSSParserTokenStream& block) {
+ CSSParserTokenStream& stream) {
+ wtf_size_t prelude_offset_start = stream.LookAheadOffset();
+ CSSParserTokenRange prelude = ConsumeAtRulePrelude(stream);
+ wtf_size_t prelude_offset_end = stream.LookAheadOffset();
+ if (!ConsumeEndOfPreludeForAtRuleWithBlock(stream))
+ return nullptr;
+ CSSParserTokenStream::BlockGuard guard(stream);
+
const CSSParserToken& name_token = prelude.ConsumeIncludingWhitespace();
if (!prelude.AtEnd())
return nullptr; // Parse error; expected single non-whitespace token in
@@ -783,38 +845,43 @@ StyleRuleKeyframes* CSSParserImpl::ConsumeKeyframesRule(
}
if (observer_) {
- observer_->StartRuleHeader(StyleRule::kKeyframes, prelude_offset.start);
- observer_->EndRuleHeader(prelude_offset.end);
- observer_->StartRuleBody(block.Offset());
+ observer_->StartRuleHeader(StyleRule::kKeyframes, prelude_offset_start);
+ observer_->EndRuleHeader(prelude_offset_end);
+ observer_->StartRuleBody(stream.Offset());
}
auto* keyframe_rule = MakeGarbageCollected<StyleRuleKeyframes>();
ConsumeRuleList(
- block, kKeyframesRuleList, [keyframe_rule](StyleRuleBase* keyframe) {
+ stream, kKeyframesRuleList, [keyframe_rule](StyleRuleBase* keyframe) {
keyframe_rule->ParserAppendKeyframe(To<StyleRuleKeyframe>(keyframe));
});
keyframe_rule->SetName(name);
keyframe_rule->SetVendorPrefixed(webkit_prefixed);
if (observer_)
- observer_->EndRuleBody(block.Offset());
+ observer_->EndRuleBody(stream.Offset());
return keyframe_rule;
}
-StyleRulePage* CSSParserImpl::ConsumePageRule(const CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset,
- CSSParserTokenStream& block) {
+StyleRulePage* CSSParserImpl::ConsumePageRule(CSSParserTokenStream& stream) {
+ wtf_size_t prelude_offset_start = stream.LookAheadOffset();
+ CSSParserTokenRange prelude = ConsumeAtRulePrelude(stream);
+ wtf_size_t prelude_offset_end = stream.LookAheadOffset();
+ if (!ConsumeEndOfPreludeForAtRuleWithBlock(stream))
+ return nullptr;
+ CSSParserTokenStream::BlockGuard guard(stream);
+
CSSSelectorList selector_list = ParsePageSelector(prelude, style_sheet_);
if (!selector_list.IsValid())
return nullptr; // Parse error, invalid @page selector
if (observer_) {
- observer_->StartRuleHeader(StyleRule::kPage, prelude_offset.start);
- observer_->EndRuleHeader(prelude_offset.end);
+ observer_->StartRuleHeader(StyleRule::kPage, prelude_offset_start);
+ observer_->EndRuleHeader(prelude_offset_end);
}
- ConsumeDeclarationList(block, StyleRule::kStyle);
+ ConsumeDeclarationList(stream, StyleRule::kStyle);
return MakeGarbageCollected<StyleRulePage>(
std::move(selector_list),
@@ -822,9 +889,14 @@ StyleRulePage* CSSParserImpl::ConsumePageRule(const CSSParserTokenRange prelude,
}
StyleRuleProperty* CSSParserImpl::ConsumePropertyRule(
- CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset,
- CSSParserTokenStream& block) {
+ CSSParserTokenStream& stream) {
+ wtf_size_t prelude_offset_start = stream.LookAheadOffset();
+ CSSParserTokenRange prelude = ConsumeAtRulePrelude(stream);
+ wtf_size_t prelude_offset_end = stream.LookAheadOffset();
+ if (!ConsumeEndOfPreludeForAtRuleWithBlock(stream))
+ return nullptr;
+ CSSParserTokenStream::BlockGuard guard(stream);
+
if (!RuntimeEnabledFeatures::CSSVariables2AtPropertyEnabled())
return nullptr;
@@ -836,15 +908,45 @@ StyleRuleProperty* CSSParserImpl::ConsumePropertyRule(
String name = name_token.Value().ToString();
if (observer_) {
- observer_->StartRuleHeader(StyleRule::kProperty, prelude_offset.start);
- observer_->EndRuleHeader(prelude_offset.end);
+ observer_->StartRuleHeader(StyleRule::kProperty, prelude_offset_start);
+ observer_->EndRuleHeader(prelude_offset_end);
}
- ConsumeDeclarationList(block, StyleRule::kProperty);
+ ConsumeDeclarationList(stream, StyleRule::kProperty);
return MakeGarbageCollected<StyleRuleProperty>(
name, CreateCSSPropertyValueSet(parsed_properties_, context_->Mode()));
}
+StyleRuleScrollTimeline* CSSParserImpl::ConsumeScrollTimelineRule(
+ CSSParserTokenStream& stream) {
+ wtf_size_t prelude_offset_start = stream.LookAheadOffset();
+ CSSParserTokenRange prelude = ConsumeAtRulePrelude(stream);
+ wtf_size_t prelude_offset_end = stream.LookAheadOffset();
+ if (!ConsumeEndOfPreludeForAtRuleWithBlock(stream))
+ return nullptr;
+ CSSParserTokenStream::BlockGuard guard(stream);
+
+ if (!RuntimeEnabledFeatures::CSSScrollTimelineEnabled())
+ return nullptr;
+
+ const CSSParserToken& name_token = prelude.ConsumeIncludingWhitespace();
+ if (!prelude.AtEnd())
+ return nullptr;
+ if (!css_parsing_utils::IsTimelineName(name_token))
+ return nullptr;
+ String name = name_token.Value().ToString();
+
+ if (observer_) {
+ observer_->StartRuleHeader(StyleRule::kScrollTimeline,
+ prelude_offset_start);
+ observer_->EndRuleHeader(prelude_offset_end);
+ }
+
+ ConsumeDeclarationList(stream, StyleRule::kScrollTimeline);
+ return MakeGarbageCollected<StyleRuleScrollTimeline>(
+ name, CreateCSSPropertyValueSet(parsed_properties_, context_->Mode()));
+}
+
StyleRuleKeyframe* CSSParserImpl::ConsumeKeyframeStyleRule(
const CSSParserTokenRange prelude,
const RangeOffset& prelude_offset,
@@ -913,6 +1015,8 @@ void CSSParserImpl::ConsumeDeclarationList(CSSParserTokenStream& stream,
DCHECK(parsed_properties_.IsEmpty());
bool use_observer = observer_ && (rule_type == StyleRule::kStyle ||
+ rule_type == StyleRule::kProperty ||
+ rule_type == StyleRule::kScrollTimeline ||
rule_type == StyleRule::kKeyframe);
if (use_observer) {
observer_->StartRuleBody(stream.Offset());
@@ -1001,11 +1105,12 @@ void CSSParserImpl::ConsumeDeclaration(CSSParserTokenRange range,
CSSPropertyID unresolved_property = CSSPropertyID::kInvalid;
AtRuleDescriptorID atrule_id = AtRuleDescriptorID::Invalid;
- if (rule_type == StyleRule::kFontFace || rule_type == StyleRule::kProperty) {
+ if (rule_type == StyleRule::kFontFace || rule_type == StyleRule::kProperty ||
+ rule_type == StyleRule::kScrollTimeline) {
if (important) // Invalid
return;
atrule_id = lhs.ParseAsAtRuleDescriptorID();
- AtRuleDescriptorParser::ParseAtRule(atrule_id, range, *context_,
+ AtRuleDescriptorParser::ParseAtRule(rule_type, atrule_id, range, *context_,
parsed_properties_);
} else {
unresolved_property = lhs.ParseAsUnresolvedCSSPropertyID(
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_parser_impl.h b/chromium/third_party/blink/renderer/core/css/parser/css_parser_impl.h
index 055faedfc23..ef30c3fd293 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_parser_impl.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_parser_impl.h
@@ -147,33 +147,19 @@ class CORE_EXPORT CSSParserImpl {
StyleRuleBase* ConsumeAtRule(CSSParserTokenStream&, AllowedRulesType);
StyleRuleBase* ConsumeQualifiedRule(CSSParserTokenStream&, AllowedRulesType);
- static StyleRuleCharset* ConsumeCharsetRule(CSSParserTokenRange prelude);
+ static StyleRuleCharset* ConsumeCharsetRule(CSSParserTokenStream&);
StyleRuleImport* ConsumeImportRule(AtomicString prelude_uri,
- CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset);
- StyleRuleNamespace* ConsumeNamespaceRule(CSSParserTokenRange prelude);
- StyleRuleMedia* ConsumeMediaRule(CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset,
- CSSParserTokenStream& block);
- StyleRuleSupports* ConsumeSupportsRule(CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset,
- CSSParserTokenStream& block);
- StyleRuleViewport* ConsumeViewportRule(CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset,
- CSSParserTokenStream& block);
- StyleRuleFontFace* ConsumeFontFaceRule(CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset,
- CSSParserTokenStream& block);
+ CSSParserTokenStream&);
+ StyleRuleNamespace* ConsumeNamespaceRule(CSSParserTokenStream&);
+ StyleRuleMedia* ConsumeMediaRule(CSSParserTokenStream&);
+ StyleRuleSupports* ConsumeSupportsRule(CSSParserTokenStream&);
+ StyleRuleViewport* ConsumeViewportRule(CSSParserTokenStream&);
+ StyleRuleFontFace* ConsumeFontFaceRule(CSSParserTokenStream&);
StyleRuleKeyframes* ConsumeKeyframesRule(bool webkit_prefixed,
- CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset,
- CSSParserTokenStream& block);
- StyleRulePage* ConsumePageRule(CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset,
- CSSParserTokenStream& block);
- StyleRuleProperty* ConsumePropertyRule(CSSParserTokenRange prelude,
- const RangeOffset& prelude_offset,
- CSSParserTokenStream& block);
+ CSSParserTokenStream&);
+ StyleRulePage* ConsumePageRule(CSSParserTokenStream&);
+ StyleRuleProperty* ConsumePropertyRule(CSSParserTokenStream&);
+ StyleRuleScrollTimeline* ConsumeScrollTimelineRule(CSSParserTokenStream&);
StyleRuleKeyframe* ConsumeKeyframeStyleRule(CSSParserTokenRange prelude,
const RangeOffset& prelude_offset,
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_parser_impl_test.cc b/chromium/third_party/blink/renderer/core/css/parser/css_parser_impl_test.cc
new file mode 100644
index 00000000000..13b2595c3ec
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_parser_impl_test.cc
@@ -0,0 +1,194 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/css/parser/css_parser_impl.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include "third_party/blink/renderer/core/css/parser/css_parser_observer.h"
+#include "third_party/blink/renderer/core/css/style_sheet_contents.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
+
+namespace blink {
+
+class TestCSSParserObserver : public CSSParserObserver {
+ public:
+ void StartRuleHeader(StyleRule::RuleType rule_type,
+ unsigned offset) override {
+ rule_type_ = rule_type;
+ rule_header_start_ = offset;
+ }
+ void EndRuleHeader(unsigned offset) override { rule_header_end_ = offset; }
+
+ void ObserveSelector(unsigned start_offset, unsigned end_offset) override {}
+ void StartRuleBody(unsigned offset) override { rule_body_start_ = offset; }
+ void EndRuleBody(unsigned offset) override { rule_body_end_ = offset; }
+ void ObserveProperty(unsigned start_offset,
+ unsigned end_offset,
+ bool is_important,
+ bool is_parsed) override {}
+ void ObserveComment(unsigned start_offset, unsigned end_offset) override {}
+
+ StyleRule::RuleType rule_type_ = StyleRule::RuleType::kStyle;
+ unsigned rule_header_start_ = 0;
+ unsigned rule_header_end_ = 0;
+ unsigned rule_body_start_ = 0;
+ unsigned rule_body_end_ = 0;
+};
+
+TEST(CSSParserImplTest, AtImportOffsets) {
+ String sheet_text = "@import 'test.css';";
+ auto* context = MakeGarbageCollected<CSSParserContext>(
+ kHTMLStandardMode, SecureContextMode::kInsecureContext);
+ auto* style_sheet = MakeGarbageCollected<StyleSheetContents>(context);
+ TestCSSParserObserver test_css_parser_observer;
+ CSSParserImpl::ParseStyleSheetForInspector(sheet_text, context, style_sheet,
+ test_css_parser_observer);
+ EXPECT_EQ(style_sheet->ImportRules().size(), 1u);
+ EXPECT_EQ(test_css_parser_observer.rule_type_, StyleRule::RuleType::kImport);
+ EXPECT_EQ(test_css_parser_observer.rule_header_start_, 18u);
+ EXPECT_EQ(test_css_parser_observer.rule_header_end_, 18u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_start_, 18u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_end_, 18u);
+}
+
+TEST(CSSParserImplTest, AtMediaOffsets) {
+ String sheet_text = "@media screen { }";
+ auto* context = MakeGarbageCollected<CSSParserContext>(
+ kHTMLStandardMode, SecureContextMode::kInsecureContext);
+ auto* style_sheet = MakeGarbageCollected<StyleSheetContents>(context);
+ TestCSSParserObserver test_css_parser_observer;
+ CSSParserImpl::ParseStyleSheetForInspector(sheet_text, context, style_sheet,
+ test_css_parser_observer);
+ EXPECT_EQ(style_sheet->ChildRules().size(), 1u);
+ EXPECT_EQ(test_css_parser_observer.rule_type_, StyleRule::RuleType::kMedia);
+ EXPECT_EQ(test_css_parser_observer.rule_header_start_, 7u);
+ EXPECT_EQ(test_css_parser_observer.rule_header_end_, 14u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_start_, 15u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_end_, 16u);
+}
+
+TEST(CSSParserImplTest, AtSupportsOffsets) {
+ String sheet_text = "@supports (display:none) { }";
+ auto* context = MakeGarbageCollected<CSSParserContext>(
+ kHTMLStandardMode, SecureContextMode::kInsecureContext);
+ auto* style_sheet = MakeGarbageCollected<StyleSheetContents>(context);
+ TestCSSParserObserver test_css_parser_observer;
+ CSSParserImpl::ParseStyleSheetForInspector(sheet_text, context, style_sheet,
+ test_css_parser_observer);
+ EXPECT_EQ(style_sheet->ChildRules().size(), 1u);
+ EXPECT_EQ(test_css_parser_observer.rule_type_,
+ StyleRule::RuleType::kSupports);
+ EXPECT_EQ(test_css_parser_observer.rule_header_start_, 10u);
+ EXPECT_EQ(test_css_parser_observer.rule_header_end_, 25u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_start_, 26u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_end_, 27u);
+}
+
+TEST(CSSParserImplTest, AtViewportOffsets) {
+ String sheet_text = "@viewport { }";
+ auto* context = MakeGarbageCollected<CSSParserContext>(
+ kUASheetMode, SecureContextMode::kInsecureContext);
+ auto* style_sheet = MakeGarbageCollected<StyleSheetContents>(context);
+ TestCSSParserObserver test_css_parser_observer;
+ CSSParserImpl::ParseStyleSheetForInspector(sheet_text, context, style_sheet,
+ test_css_parser_observer);
+ EXPECT_EQ(style_sheet->ChildRules().size(), 1u);
+ EXPECT_EQ(test_css_parser_observer.rule_type_,
+ StyleRule::RuleType::kViewport);
+ EXPECT_EQ(test_css_parser_observer.rule_header_start_, 10u);
+ EXPECT_EQ(test_css_parser_observer.rule_header_end_, 10u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_start_, 10u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_end_, 10u);
+}
+
+TEST(CSSParserImplTest, AtFontFaceOffsets) {
+ String sheet_text = "@font-face { }";
+ auto* context = MakeGarbageCollected<CSSParserContext>(
+ kHTMLStandardMode, SecureContextMode::kInsecureContext);
+ auto* style_sheet = MakeGarbageCollected<StyleSheetContents>(context);
+ TestCSSParserObserver test_css_parser_observer;
+ CSSParserImpl::ParseStyleSheetForInspector(sheet_text, context, style_sheet,
+ test_css_parser_observer);
+ EXPECT_EQ(style_sheet->ChildRules().size(), 1u);
+ EXPECT_EQ(test_css_parser_observer.rule_type_,
+ StyleRule::RuleType::kFontFace);
+ EXPECT_EQ(test_css_parser_observer.rule_header_start_, 11u);
+ EXPECT_EQ(test_css_parser_observer.rule_header_end_, 11u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_start_, 11u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_end_, 11u);
+}
+
+TEST(CSSParserImplTest, AtKeyframesOffsets) {
+ String sheet_text = "@keyframes test { }";
+ auto* context = MakeGarbageCollected<CSSParserContext>(
+ kHTMLStandardMode, SecureContextMode::kInsecureContext);
+ auto* style_sheet = MakeGarbageCollected<StyleSheetContents>(context);
+ TestCSSParserObserver test_css_parser_observer;
+ CSSParserImpl::ParseStyleSheetForInspector(sheet_text, context, style_sheet,
+ test_css_parser_observer);
+ EXPECT_EQ(style_sheet->ChildRules().size(), 1u);
+ EXPECT_EQ(test_css_parser_observer.rule_type_,
+ StyleRule::RuleType::kKeyframes);
+ EXPECT_EQ(test_css_parser_observer.rule_header_start_, 11u);
+ EXPECT_EQ(test_css_parser_observer.rule_header_end_, 16u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_start_, 17u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_end_, 18u);
+}
+
+TEST(CSSParserImplTest, AtPageOffsets) {
+ String sheet_text = "@page :first { }";
+ auto* context = MakeGarbageCollected<CSSParserContext>(
+ kHTMLStandardMode, SecureContextMode::kInsecureContext);
+ auto* style_sheet = MakeGarbageCollected<StyleSheetContents>(context);
+ TestCSSParserObserver test_css_parser_observer;
+ CSSParserImpl::ParseStyleSheetForInspector(sheet_text, context, style_sheet,
+ test_css_parser_observer);
+ EXPECT_EQ(style_sheet->ChildRules().size(), 1u);
+ EXPECT_EQ(test_css_parser_observer.rule_type_, StyleRule::RuleType::kPage);
+ EXPECT_EQ(test_css_parser_observer.rule_header_start_, 6u);
+ EXPECT_EQ(test_css_parser_observer.rule_header_end_, 13u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_start_, 14u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_end_, 15u);
+}
+
+TEST(CSSParserImplTest, AtPropertyOffsets) {
+ ScopedCSSVariables2AtPropertyForTest scoped_feature(true);
+
+ String sheet_text = "@property --test { }";
+ auto* context = MakeGarbageCollected<CSSParserContext>(
+ kHTMLStandardMode, SecureContextMode::kInsecureContext);
+ auto* style_sheet = MakeGarbageCollected<StyleSheetContents>(context);
+ TestCSSParserObserver test_css_parser_observer;
+ CSSParserImpl::ParseStyleSheetForInspector(sheet_text, context, style_sheet,
+ test_css_parser_observer);
+ EXPECT_EQ(style_sheet->ChildRules().size(), 1u);
+ EXPECT_EQ(test_css_parser_observer.rule_type_,
+ StyleRule::RuleType::kProperty);
+ EXPECT_EQ(test_css_parser_observer.rule_header_start_, 10u);
+ EXPECT_EQ(test_css_parser_observer.rule_header_end_, 17u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_start_, 18u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_end_, 19u);
+}
+
+TEST(CSSParserImplTest, AtScrollTimelineOffsets) {
+ ScopedCSSScrollTimelineForTest scoped_feature(true);
+
+ String sheet_text = "@scroll-timeline test { }";
+ auto* context = MakeGarbageCollected<CSSParserContext>(
+ kHTMLStandardMode, SecureContextMode::kInsecureContext);
+ auto* style_sheet = MakeGarbageCollected<StyleSheetContents>(context);
+ TestCSSParserObserver test_css_parser_observer;
+ CSSParserImpl::ParseStyleSheetForInspector(sheet_text, context, style_sheet,
+ test_css_parser_observer);
+ EXPECT_EQ(style_sheet->ChildRules().size(), 1u);
+ EXPECT_EQ(test_css_parser_observer.rule_type_,
+ StyleRule::RuleType::kScrollTimeline);
+ EXPECT_EQ(test_css_parser_observer.rule_header_start_, 17u);
+ EXPECT_EQ(test_css_parser_observer.rule_header_end_, 22u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_start_, 23u);
+ EXPECT_EQ(test_css_parser_observer.rule_body_end_, 24u);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_property_parser.cc b/chromium/third_party/blink/renderer/core/css/parser/css_property_parser.cc
index 8fcf3c55272..6661655cb8c 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_property_parser.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_property_parser.cc
@@ -14,19 +14,20 @@
#include "third_party/blink/renderer/core/css/hash_tools.h"
#include "third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_local_context.h"
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/parser/css_parser_mode.h"
#include "third_party/blink/renderer/core/css/parser/css_variable_parser.h"
#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
#include "third_party/blink/renderer/core/css/properties/css_property.h"
#include "third_party/blink/renderer/core/css/properties/shorthand.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/wtf/text/character_visitor.h"
namespace blink {
-using css_property_parser_helpers::ConsumeIdent;
-using css_property_parser_helpers::IsImplicitProperty;
-using css_property_parser_helpers::ParseLonghand;
+using css_parsing_utils::ConsumeIdent;
+using css_parsing_utils::IsImplicitProperty;
+using css_parsing_utils::ParseLonghand;
class CSSIdentifierValue;
@@ -161,7 +162,7 @@ bool CSSPropertyParser::ParseValueStart(CSSPropertyID unresolved_property,
const cssvalue::CSSPendingSubstitutionValue& pending_value =
*MakeGarbageCollected<cssvalue::CSSPendingSubstitutionValue>(
property_id, variable);
- css_property_parser_helpers::AddExpandedPropertyForValue(
+ css_parsing_utils::AddExpandedPropertyForValue(
property_id, pending_value, important, *parsed_properties_);
} else {
AddProperty(property_id, CSSPropertyID::kInvalid, *variable, important,
@@ -216,24 +217,18 @@ static CSSPropertyID UnresolvedCSSPropertyID(
CSSPropertyID unresolvedCSSPropertyID(const ExecutionContext* execution_context,
const String& string) {
- unsigned length = string.length();
- CSSParserMode mode = kHTMLStandardMode;
- return string.Is8Bit()
- ? UnresolvedCSSPropertyID(execution_context, string.Characters8(),
- length, mode)
- : UnresolvedCSSPropertyID(execution_context, string.Characters16(),
- length, mode);
+ return WTF::VisitCharacters(string, [&](const auto* chars, unsigned length) {
+ return UnresolvedCSSPropertyID(execution_context, chars, length,
+ kHTMLStandardMode);
+ });
}
CSSPropertyID UnresolvedCSSPropertyID(const ExecutionContext* execution_context,
StringView string,
CSSParserMode mode) {
- unsigned length = string.length();
- return string.Is8Bit()
- ? UnresolvedCSSPropertyID(execution_context, string.Characters8(),
- length, mode)
- : UnresolvedCSSPropertyID(execution_context, string.Characters16(),
- length, mode);
+ return WTF::VisitCharacters(string, [&](const auto* chars, unsigned length) {
+ return UnresolvedCSSPropertyID(execution_context, chars, length, mode);
+ });
}
template <typename CharacterType>
@@ -281,8 +276,8 @@ bool CSSPropertyParser::ConsumeCSSWideKeyword(CSSPropertyID unresolved_property,
AddProperty(property, CSSPropertyID::kInvalid, *value, important,
IsImplicitProperty::kNotImplicit, *parsed_properties_);
} else {
- css_property_parser_helpers::AddExpandedPropertyForValue(
- property, *value, important, *parsed_properties_);
+ css_parsing_utils::AddExpandedPropertyForValue(property, *value, important,
+ *parsed_properties_);
}
range_ = range_copy;
return true;
@@ -300,19 +295,19 @@ static CSSValue* ConsumeSingleViewportDescriptor(
case CSSPropertyID::kMaxHeight:
if (id == CSSValueID::kAuto || id == CSSValueID::kInternalExtendToZoom)
return ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeLengthOrPercent(range, context,
+ kValueRangeNonNegative);
case CSSPropertyID::kMinZoom:
case CSSPropertyID::kMaxZoom:
case CSSPropertyID::kZoom: {
if (id == CSSValueID::kAuto)
return ConsumeIdent(range);
- CSSValue* parsed_value = css_property_parser_helpers::ConsumeNumber(
+ CSSValue* parsed_value = css_parsing_utils::ConsumeNumber(
range, context, kValueRangeNonNegative);
if (parsed_value)
return parsed_value;
- return css_property_parser_helpers::ConsumePercent(
- range, context, kValueRangeNonNegative);
+ return css_parsing_utils::ConsumePercent(range, context,
+ kValueRangeNonNegative);
}
case CSSPropertyID::kUserZoom:
return ConsumeIdent<CSSValueID::kZoom, CSSValueID::kFixed>(range);
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc b/chromium/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc
deleted file mode 100644
index cdf2b7aa8fb..00000000000
--- a/chromium/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc
+++ /dev/null
@@ -1,2206 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
-
-#include "third_party/blink/renderer/core/css/css_axis_value.h"
-#include "third_party/blink/renderer/core/css/css_color_value.h"
-#include "third_party/blink/renderer/core/css/css_crossfade_value.h"
-#include "third_party/blink/renderer/core/css/css_gradient_value.h"
-#include "third_party/blink/renderer/core/css/css_image_set_value.h"
-#include "third_party/blink/renderer/core/css/css_image_value.h"
-#include "third_party/blink/renderer/core/css/css_initial_value.h"
-#include "third_party/blink/renderer/core/css/css_light_dark_value_pair.h"
-#include "third_party/blink/renderer/core/css/css_math_expression_node.h"
-#include "third_party/blink/renderer/core/css/css_math_function_value.h"
-#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
-#include "third_party/blink/renderer/core/css/css_paint_value.h"
-#include "third_party/blink/renderer/core/css/css_property_value.h"
-#include "third_party/blink/renderer/core/css/css_shadow_value.h"
-#include "third_party/blink/renderer/core/css/css_string_value.h"
-#include "third_party/blink/renderer/core/css/css_uri_value.h"
-#include "third_party/blink/renderer/core/css/css_value_pair.h"
-#include "third_party/blink/renderer/core/css/css_variable_data.h"
-#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
-#include "third_party/blink/renderer/core/css/parser/css_parser_fast_paths.h"
-#include "third_party/blink/renderer/core/css/parser/css_parser_local_context.h"
-#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
-#include "third_party/blink/renderer/core/css/properties/css_property.h"
-#include "third_party/blink/renderer/core/css/properties/longhand.h"
-#include "third_party/blink/renderer/core/css/style_color.h"
-#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/frame/web_feature.h"
-#include "third_party/blink/renderer/core/inspector/console_message.h"
-#include "third_party/blink/renderer/core/style_property_shorthand.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
-#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-
-namespace blink {
-
-namespace css_property_parser_helpers {
-
-namespace {
-
-// Add CSSVariableData to variableData vector.
-bool AddCSSPaintArgument(
- const Vector<CSSParserToken>& tokens,
- Vector<scoped_refptr<CSSVariableData>>* const variable_data,
- const CSSParserContext& context) {
- CSSParserTokenRange token_range(tokens);
- if (!token_range.AtEnd()) {
- scoped_refptr<CSSVariableData> unparsed_css_variable_data =
- CSSVariableData::Create(token_range, false, false, context.BaseURL(),
- context.Charset());
- if (unparsed_css_variable_data.get()) {
- variable_data->push_back(std::move(unparsed_css_variable_data));
- return true;
- }
- }
- return false;
-}
-
-// Consume input arguments, if encounter function, will return the function
-// block as a Vector of CSSParserToken, otherwise, will just return a Vector of
-// a single CSSParserToken.
-Vector<CSSParserToken> ConsumeFunctionArgsOrNot(CSSParserTokenRange& args) {
- Vector<CSSParserToken> argument_tokens;
- if (args.Peek().GetBlockType() == CSSParserToken::kBlockStart) {
- // Function block.
- // Push the function name and initial right parenthesis.
- // Since we don't have any upfront knowledge about the input argument types
- // here, we should just leave the token as it is and resolve it later in
- // the variable parsing phase.
- argument_tokens.push_back(args.Peek());
- CSSParserTokenRange contents = args.ConsumeBlock();
- while (!contents.AtEnd()) {
- argument_tokens.push_back(contents.Consume());
- }
- argument_tokens.push_back(
- CSSParserToken(kRightParenthesisToken, CSSParserToken::kBlockEnd));
-
- } else {
- argument_tokens.push_back(args.ConsumeIncludingWhitespace());
- }
- return argument_tokens;
-}
-
-CSSFunctionValue* ConsumeFilterFunction(CSSParserTokenRange& range,
- const CSSParserContext& context) {
- CSSValueID filter_type = range.Peek().FunctionId();
- if (filter_type < CSSValueID::kInvert ||
- filter_type > CSSValueID::kDropShadow)
- return nullptr;
- CSSParserTokenRange args =
- css_property_parser_helpers::ConsumeFunction(range);
- CSSFunctionValue* filter_value =
- MakeGarbageCollected<CSSFunctionValue>(filter_type);
- CSSValue* parsed_value = nullptr;
-
- if (filter_type == CSSValueID::kDropShadow) {
- parsed_value = css_parsing_utils::ParseSingleShadow(
- args, context, css_parsing_utils::AllowInsetAndSpread::kForbid);
- } else {
- if (args.AtEnd()) {
- context.Count(WebFeature::kCSSFilterFunctionNoArguments);
- return filter_value;
- }
- if (filter_type == CSSValueID::kBrightness) {
- // FIXME (crbug.com/397061): Support calc expressions like calc(10% + 0.5)
- parsed_value = css_property_parser_helpers::ConsumePercent(
- args, context, kValueRangeAll);
- if (!parsed_value) {
- parsed_value = css_property_parser_helpers::ConsumeNumber(
- args, context, kValueRangeNonNegative);
- }
- } else if (filter_type == CSSValueID::kHueRotate) {
- parsed_value = css_property_parser_helpers::ConsumeAngle(
- args, context, WebFeature::kUnitlessZeroAngleFilter);
- } else if (filter_type == CSSValueID::kBlur) {
- CSSParserContext::ParserModeOverridingScope scope(context,
- kHTMLStandardMode);
- parsed_value = css_property_parser_helpers::ConsumeLength(
- args, context, kValueRangeNonNegative);
- } else {
- // FIXME (crbug.com/397061): Support calc expressions like calc(10% + 0.5)
- parsed_value = css_property_parser_helpers::ConsumePercent(
- args, context, kValueRangeNonNegative);
- if (!parsed_value) {
- parsed_value = css_property_parser_helpers::ConsumeNumber(
- args, context, kValueRangeNonNegative);
- }
- if (parsed_value && filter_type != CSSValueID::kSaturate &&
- filter_type != CSSValueID::kContrast) {
- bool is_percentage =
- To<CSSPrimitiveValue>(parsed_value)->IsPercentage();
- double max_allowed = is_percentage ? 100.0 : 1.0;
- if (To<CSSPrimitiveValue>(parsed_value)->GetDoubleValue() >
- max_allowed) {
- parsed_value = CSSNumericLiteralValue::Create(
- max_allowed, is_percentage
- ? CSSPrimitiveValue::UnitType::kPercentage
- : CSSPrimitiveValue::UnitType::kNumber);
- }
- }
- }
- }
- if (!parsed_value || !args.AtEnd())
- return nullptr;
- filter_value->Append(*parsed_value);
- return filter_value;
-}
-
-template <typename Func, typename... Args>
-CSSLightDarkValuePair* ConsumeInternalLightDark(Func consume_value,
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- Args&&... args) {
- if (range.Peek().FunctionId() != CSSValueID::kInternalLightDark)
- return nullptr;
- if (!isValueAllowedInMode(CSSValueID::kInternalLightDark, context.Mode()))
- return nullptr;
- CSSParserTokenRange range_copy = range;
- CSSParserTokenRange arg_range = ConsumeFunction(range_copy);
- CSSValue* light_value =
- consume_value(arg_range, context, std::forward<Args>(args)...);
- if (!light_value || !ConsumeCommaIncludingWhitespace(arg_range))
- return nullptr;
- CSSValue* dark_value =
- consume_value(arg_range, context, std::forward<Args>(args)...);
- if (!dark_value || !arg_range.AtEnd())
- return nullptr;
- range = range_copy;
- return MakeGarbageCollected<CSSLightDarkValuePair>(light_value, dark_value);
-}
-
-} // namespace
-
-void Complete4Sides(CSSValue* side[4]) {
- if (side[3])
- return;
- if (!side[2]) {
- if (!side[1])
- side[1] = side[0];
- side[2] = side[0];
- }
- side[3] = side[1];
-}
-
-bool ConsumeCommaIncludingWhitespace(CSSParserTokenRange& range) {
- CSSParserToken value = range.Peek();
- if (value.GetType() != kCommaToken)
- return false;
- range.ConsumeIncludingWhitespace();
- return true;
-}
-
-bool ConsumeSlashIncludingWhitespace(CSSParserTokenRange& range) {
- CSSParserToken value = range.Peek();
- if (value.GetType() != kDelimiterToken || value.Delimiter() != '/')
- return false;
- range.ConsumeIncludingWhitespace();
- return true;
-}
-
-CSSParserTokenRange ConsumeFunction(CSSParserTokenRange& range) {
- DCHECK_EQ(range.Peek().GetType(), kFunctionToken);
- CSSParserTokenRange contents = range.ConsumeBlock();
- range.ConsumeWhitespace();
- contents.ConsumeWhitespace();
- return contents;
-}
-
-// TODO(rwlbuis): consider pulling in the parsing logic from
-// css_math_expression_node.cc.
-class MathFunctionParser {
- STACK_ALLOCATED();
-
- public:
- MathFunctionParser(CSSParserTokenRange& range,
- const CSSParserContext& context,
- ValueRange value_range)
- : source_range_(range), range_(range) {
- const CSSParserToken& token = range.Peek();
- switch (token.FunctionId()) {
- case CSSValueID::kCalc:
- case CSSValueID::kWebkitCalc:
- calc_value_ = CSSMathFunctionValue::Create(
- CSSMathExpressionNode::ParseCalc(ConsumeFunction(range_)),
- value_range);
- break;
- case CSSValueID::kMin:
- calc_value_ = CSSMathFunctionValue::Create(
- CSSMathExpressionNode::ParseMin(ConsumeFunction(range_)),
- value_range);
- break;
- case CSSValueID::kMax:
- calc_value_ = CSSMathFunctionValue::Create(
- CSSMathExpressionNode::ParseMax(ConsumeFunction(range_)),
- value_range);
- break;
- case CSSValueID::kClamp:
- calc_value_ = CSSMathFunctionValue::Create(
- CSSMathExpressionNode::ParseClamp(ConsumeFunction(range_)),
- value_range);
- break;
- default:
- break;
- }
- if (calc_value_ && calc_value_->HasComparisons())
- context.Count(WebFeature::kCSSComparisonFunctions);
- }
-
- explicit MathFunctionParser(CSSParserTokenRange& range,
- const CSSParserContext& context)
- : MathFunctionParser(range, context, kValueRangeAll) {}
-
- const CSSMathFunctionValue* Value() const { return calc_value_; }
- CSSMathFunctionValue* ConsumeValue() {
- if (!calc_value_)
- return nullptr;
- source_range_ = range_;
- CSSMathFunctionValue* result = calc_value_;
- calc_value_ = nullptr;
- return result;
- }
-
- CSSPrimitiveValue* ConsumeRoundedInt() {
- if (!calc_value_)
- return nullptr;
- source_range_ = range_;
- CSSPrimitiveValue::UnitType unit_type =
- CSSPrimitiveValue::UnitType::kInteger;
- double rounded_value = floor(calc_value_->GetDoubleValue() + 0.5);
- return CSSNumericLiteralValue::Create(rounded_value, unit_type);
- }
-
- CSSPrimitiveValue* ConsumeNumber() {
- if (!calc_value_)
- return nullptr;
- source_range_ = range_;
- CSSPrimitiveValue::UnitType unit_type =
- calc_value_->IsInt() ? CSSPrimitiveValue::UnitType::kInteger
- : CSSPrimitiveValue::UnitType::kNumber;
- return CSSNumericLiteralValue::Create(calc_value_->GetDoubleValue(),
- unit_type);
- }
-
- bool ConsumeNumberRaw(double& result) {
- if (!calc_value_ || calc_value_->Category() != kCalcNumber)
- return false;
- source_range_ = range_;
- result = calc_value_->GetDoubleValue();
- return true;
- }
-
- private:
- CSSParserTokenRange& source_range_;
- CSSParserTokenRange range_;
- CSSMathFunctionValue* calc_value_ = nullptr;
-};
-
-CSSPrimitiveValue* ConsumeInteger(CSSParserTokenRange& range,
- const CSSParserContext& context,
- double minimum_value) {
- const CSSParserToken& token = range.Peek();
- if (token.GetType() == kNumberToken) {
- if (token.GetNumericValueType() == kNumberValueType ||
- token.NumericValue() < minimum_value)
- return nullptr;
- return CSSNumericLiteralValue::Create(
- range.ConsumeIncludingWhitespace().NumericValue(),
- CSSPrimitiveValue::UnitType::kInteger);
- }
- MathFunctionParser math_parser(range, context);
- if (const CSSMathFunctionValue* math_value = math_parser.Value()) {
- if (!RuntimeEnabledFeatures::CSSCalcAsIntEnabled() && !math_value->IsInt())
- return nullptr;
- if (math_value->Category() != kCalcNumber)
- return nullptr;
- double double_value = math_value->GetDoubleValue();
- if (double_value < minimum_value)
- return nullptr;
- if (!RuntimeEnabledFeatures::CSSCalcAsIntEnabled())
- return math_parser.ConsumeNumber();
- if (math_value->IsInt())
- return math_parser.ConsumeNumber();
- return math_parser.ConsumeRoundedInt();
- }
- return nullptr;
-}
-
-// This implements the behavior defined in [1], where calc() expressions
-// are valid when <integer> is expected, even if the calc()-expression does
-// not result in an integral value.
-//
-// TODO(andruud): Eventually this behavior should just be part of
-// ConsumeInteger, and this function can be removed. For now, having a separate
-// function with this behavior allows us to implement [1] gradually.
-//
-// [1] https://drafts.csswg.org/css-values-4/#calc-type-checking
-CSSPrimitiveValue* ConsumeIntegerOrNumberCalc(CSSParserTokenRange& range,
- const CSSParserContext& context) {
- CSSParserTokenRange int_range(range);
- if (CSSPrimitiveValue* value = ConsumeInteger(int_range, context)) {
- range = int_range;
- return value;
- }
- MathFunctionParser math_parser(range, context);
- if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
- if (calculation->Category() != kCalcNumber)
- return nullptr;
- return math_parser.ConsumeValue();
- }
- return nullptr;
-}
-
-CSSPrimitiveValue* ConsumePositiveInteger(CSSParserTokenRange& range,
- const CSSParserContext& context) {
- return ConsumeInteger(range, context, 1);
-}
-
-bool ConsumeNumberRaw(CSSParserTokenRange& range,
- const CSSParserContext& context,
- double& result) {
- if (range.Peek().GetType() == kNumberToken) {
- result = range.ConsumeIncludingWhitespace().NumericValue();
- return true;
- }
- MathFunctionParser math_parser(range, context, kValueRangeAll);
- return math_parser.ConsumeNumberRaw(result);
-}
-
-// TODO(timloh): Work out if this can just call consumeNumberRaw
-CSSPrimitiveValue* ConsumeNumber(CSSParserTokenRange& range,
- const CSSParserContext& context,
- ValueRange value_range) {
- const CSSParserToken& token = range.Peek();
- if (token.GetType() == kNumberToken) {
- if (value_range == kValueRangeNonNegative && token.NumericValue() < 0)
- return nullptr;
- return CSSNumericLiteralValue::Create(
- range.ConsumeIncludingWhitespace().NumericValue(), token.GetUnitType());
- }
- MathFunctionParser math_parser(range, context, kValueRangeAll);
- if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
- // TODO(rwlbuis) Calcs should not be subject to parse time range checks.
- // spec: https://drafts.csswg.org/css-values-3/#calc-range
- if (calculation->Category() != kCalcNumber ||
- (value_range == kValueRangeNonNegative && calculation->IsNegative()))
- return nullptr;
- return math_parser.ConsumeNumber();
- }
- return nullptr;
-}
-
-inline bool ShouldAcceptUnitlessLength(double value,
- CSSParserMode css_parser_mode,
- UnitlessQuirk unitless) {
- return value == 0 || css_parser_mode == kSVGAttributeMode ||
- (css_parser_mode == kHTMLQuirksMode &&
- unitless == UnitlessQuirk::kAllow);
-}
-
-CSSPrimitiveValue* ConsumeLength(CSSParserTokenRange& range,
- const CSSParserContext& context,
- ValueRange value_range,
- UnitlessQuirk unitless) {
- const CSSParserToken& token = range.Peek();
- if (token.GetType() == kDimensionToken) {
- switch (token.GetUnitType()) {
- case CSSPrimitiveValue::UnitType::kQuirkyEms:
- if (context.Mode() != kUASheetMode)
- return nullptr;
- FALLTHROUGH;
- case CSSPrimitiveValue::UnitType::kEms:
- case CSSPrimitiveValue::UnitType::kRems:
- case CSSPrimitiveValue::UnitType::kChs:
- case CSSPrimitiveValue::UnitType::kExs:
- case CSSPrimitiveValue::UnitType::kPixels:
- case CSSPrimitiveValue::UnitType::kCentimeters:
- case CSSPrimitiveValue::UnitType::kMillimeters:
- case CSSPrimitiveValue::UnitType::kQuarterMillimeters:
- case CSSPrimitiveValue::UnitType::kInches:
- case CSSPrimitiveValue::UnitType::kPoints:
- case CSSPrimitiveValue::UnitType::kPicas:
- case CSSPrimitiveValue::UnitType::kUserUnits:
- case CSSPrimitiveValue::UnitType::kViewportWidth:
- case CSSPrimitiveValue::UnitType::kViewportHeight:
- case CSSPrimitiveValue::UnitType::kViewportMin:
- case CSSPrimitiveValue::UnitType::kViewportMax:
- break;
- default:
- return nullptr;
- }
- if (value_range == kValueRangeNonNegative && token.NumericValue() < 0)
- return nullptr;
- return CSSNumericLiteralValue::Create(
- range.ConsumeIncludingWhitespace().NumericValue(), token.GetUnitType());
- }
- if (token.GetType() == kNumberToken) {
- if (!ShouldAcceptUnitlessLength(token.NumericValue(), context.Mode(),
- unitless) ||
- (value_range == kValueRangeNonNegative && token.NumericValue() < 0))
- return nullptr;
- CSSPrimitiveValue::UnitType unit_type =
- CSSPrimitiveValue::UnitType::kPixels;
- if (context.Mode() == kSVGAttributeMode)
- unit_type = CSSPrimitiveValue::UnitType::kUserUnits;
- return CSSNumericLiteralValue::Create(
- range.ConsumeIncludingWhitespace().NumericValue(), unit_type);
- }
- if (context.Mode() == kSVGAttributeMode)
- return nullptr;
- MathFunctionParser math_parser(range, context, value_range);
- if (math_parser.Value() && math_parser.Value()->Category() == kCalcLength)
- return math_parser.ConsumeValue();
- return nullptr;
-}
-
-CSSPrimitiveValue* ConsumePercent(CSSParserTokenRange& range,
- const CSSParserContext& context,
- ValueRange value_range) {
- const CSSParserToken& token = range.Peek();
- if (token.GetType() == kPercentageToken) {
- if (value_range == kValueRangeNonNegative && token.NumericValue() < 0)
- return nullptr;
- return CSSNumericLiteralValue::Create(
- range.ConsumeIncludingWhitespace().NumericValue(),
- CSSPrimitiveValue::UnitType::kPercentage);
- }
- MathFunctionParser math_parser(range, context, value_range);
- if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
- if (calculation->Category() == kCalcPercent)
- return math_parser.ConsumeValue();
- }
- return nullptr;
-}
-
-CSSPrimitiveValue* ConsumeAlphaValue(CSSParserTokenRange& range,
- const CSSParserContext& context) {
- if (CSSPrimitiveValue* value =
- ConsumeNumber(range, context, kValueRangeAll)) {
- return value;
- }
- if (CSSPrimitiveValue* value =
- ConsumePercent(range, context, kValueRangeAll)) {
- return CSSNumericLiteralValue::Create(value->GetDoubleValue() / 100.0,
- CSSPrimitiveValue::UnitType::kNumber);
- }
- return nullptr;
-}
-
-bool CanConsumeCalcValue(CalculationCategory category,
- CSSParserMode css_parser_mode) {
- return category == kCalcLength || category == kCalcPercent ||
- category == kCalcPercentLength ||
- (css_parser_mode == kSVGAttributeMode && category == kCalcNumber);
-}
-
-CSSPrimitiveValue* ConsumeLengthOrPercent(CSSParserTokenRange& range,
- const CSSParserContext& context,
- ValueRange value_range,
- UnitlessQuirk unitless) {
- const CSSParserToken& token = range.Peek();
- if (token.GetType() == kDimensionToken || token.GetType() == kNumberToken)
- return ConsumeLength(range, context, value_range, unitless);
- if (token.GetType() == kPercentageToken)
- return ConsumePercent(range, context, value_range);
- MathFunctionParser math_parser(range, context, value_range);
- if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
- if (CanConsumeCalcValue(calculation->Category(), context.Mode()))
- return math_parser.ConsumeValue();
- }
- return nullptr;
-}
-
-namespace {
-
-bool IsNonZeroUserUnitsValue(const CSSPrimitiveValue* value) {
- if (!value)
- return false;
- if (const auto* numeric_literal = DynamicTo<CSSNumericLiteralValue>(value)) {
- return numeric_literal->GetType() ==
- CSSPrimitiveValue::UnitType::kUserUnits &&
- value->GetDoubleValue() != 0;
- }
- const auto& math_value = To<CSSMathFunctionValue>(*value);
- return math_value.Category() == kCalcNumber && math_value.DoubleValue() != 0;
-}
-
-} // namespace
-
-CSSPrimitiveValue* ConsumeSVGGeometryPropertyLength(
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- ValueRange value_range) {
- CSSParserContext::ParserModeOverridingScope scope(context, kSVGAttributeMode);
- CSSPrimitiveValue* value = ConsumeLengthOrPercent(range, context, value_range,
- UnitlessQuirk::kForbid);
- if (IsNonZeroUserUnitsValue(value))
- context.Count(WebFeature::kSVGGeometryPropertyHasNonZeroUnitlessValue);
- return value;
-}
-
-CSSPrimitiveValue* ConsumeGradientLengthOrPercent(
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- ValueRange value_range,
- UnitlessQuirk unitless) {
- return ConsumeLengthOrPercent(range, context, value_range, unitless);
-}
-
-CSSPrimitiveValue* ConsumeAngle(
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- base::Optional<WebFeature> unitless_zero_feature,
- double minimum_value,
- double maximum_value) {
- const CSSParserToken& token = range.Peek();
- if (token.GetType() == kDimensionToken) {
- switch (token.GetUnitType()) {
- case CSSPrimitiveValue::UnitType::kDegrees:
- case CSSPrimitiveValue::UnitType::kRadians:
- case CSSPrimitiveValue::UnitType::kGradians:
- case CSSPrimitiveValue::UnitType::kTurns:
- return CSSNumericLiteralValue::Create(
- range.ConsumeIncludingWhitespace().NumericValue(),
- token.GetUnitType());
- default:
- return nullptr;
- }
- }
- if (token.GetType() == kNumberToken && token.NumericValue() == 0 &&
- unitless_zero_feature) {
- range.ConsumeIncludingWhitespace();
- context.Count(*unitless_zero_feature);
- return CSSNumericLiteralValue::Create(
- 0, CSSPrimitiveValue::UnitType::kDegrees);
- }
- MathFunctionParser math_parser(range, context, kValueRangeAll);
- if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
- if (calculation->Category() != kCalcAngle)
- return nullptr;
- if (CSSMathFunctionValue* result = math_parser.ConsumeValue()) {
- if (result->ComputeDegrees() < minimum_value) {
- return CSSNumericLiteralValue::Create(
- minimum_value, CSSPrimitiveValue::UnitType::kDegrees);
- }
- if (result->ComputeDegrees() > maximum_value) {
- return CSSNumericLiteralValue::Create(
- maximum_value, CSSPrimitiveValue::UnitType::kDegrees);
- }
- return result;
- }
- }
- return nullptr;
-}
-
-CSSPrimitiveValue* ConsumeAngle(
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- base::Optional<WebFeature> unitless_zero_feature) {
- return ConsumeAngle(range, context, std::move(unitless_zero_feature),
- std::numeric_limits<double>::lowest(),
- std::numeric_limits<double>::max());
-}
-
-CSSPrimitiveValue* ConsumeTime(CSSParserTokenRange& range,
- const CSSParserContext& context,
- ValueRange value_range) {
- const CSSParserToken& token = range.Peek();
- if (token.GetType() == kDimensionToken) {
- if (value_range == kValueRangeNonNegative && token.NumericValue() < 0)
- return nullptr;
- CSSPrimitiveValue::UnitType unit = token.GetUnitType();
- if (unit == CSSPrimitiveValue::UnitType::kMilliseconds ||
- unit == CSSPrimitiveValue::UnitType::kSeconds)
- return CSSNumericLiteralValue::Create(
- range.ConsumeIncludingWhitespace().NumericValue(),
- token.GetUnitType());
- return nullptr;
- }
- MathFunctionParser math_parser(range, context, value_range);
- if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
- if (calculation->Category() == kCalcTime)
- return math_parser.ConsumeValue();
- }
- return nullptr;
-}
-
-CSSPrimitiveValue* ConsumeResolution(CSSParserTokenRange& range) {
- const CSSParserToken& token = range.Peek();
- // Unlike the other types, calc() does not work with <resolution>.
- if (token.GetType() != kDimensionToken)
- return nullptr;
- CSSPrimitiveValue::UnitType unit = token.GetUnitType();
- if (unit == CSSPrimitiveValue::UnitType::kDotsPerPixel ||
- unit == CSSPrimitiveValue::UnitType::kDotsPerInch ||
- unit == CSSPrimitiveValue::UnitType::kDotsPerCentimeter) {
- return CSSNumericLiteralValue::Create(
- range.ConsumeIncludingWhitespace().NumericValue(), unit);
- }
- return nullptr;
-}
-
-CSSIdentifierValue* ConsumeIdent(CSSParserTokenRange& range) {
- if (range.Peek().GetType() != kIdentToken)
- return nullptr;
- return CSSIdentifierValue::Create(range.ConsumeIncludingWhitespace().Id());
-}
-
-CSSIdentifierValue* ConsumeIdentRange(CSSParserTokenRange& range,
- CSSValueID lower,
- CSSValueID upper) {
- if (range.Peek().Id() < lower || range.Peek().Id() > upper)
- return nullptr;
- return ConsumeIdent(range);
-}
-
-CSSCustomIdentValue* ConsumeCustomIdentWithToken(
- const CSSParserToken& token,
- const CSSParserContext& context) {
- if (token.GetType() != kIdentToken || IsCSSWideKeyword(token.Value()))
- return nullptr;
-
- if (EqualIgnoringASCIICase(token.Value(), "default"))
- context.Count(WebFeature::kDefaultInCustomIdent);
-
- return MakeGarbageCollected<CSSCustomIdentValue>(
- token.Value().ToAtomicString());
-}
-
-CSSCustomIdentValue* ConsumeCustomIdent(CSSParserTokenRange& range,
- const CSSParserContext& context) {
- if (range.Peek().GetType() != kIdentToken ||
- IsCSSWideKeyword(range.Peek().Value()))
- return nullptr;
-
- return ConsumeCustomIdentWithToken(range.ConsumeIncludingWhitespace(),
- context);
-}
-
-CSSStringValue* ConsumeString(CSSParserTokenRange& range) {
- if (range.Peek().GetType() != kStringToken)
- return nullptr;
- return MakeGarbageCollected<CSSStringValue>(
- range.ConsumeIncludingWhitespace().Value().ToString());
-}
-
-StringView ConsumeUrlAsStringView(CSSParserTokenRange& range,
- const CSSParserContext& context) {
- StringView url;
- const CSSParserToken& token = range.Peek();
- if (token.GetType() == kUrlToken) {
- range.ConsumeIncludingWhitespace();
- url = token.Value();
- } else if (token.FunctionId() == CSSValueID::kUrl) {
- CSSParserTokenRange url_range = range;
- CSSParserTokenRange url_args = url_range.ConsumeBlock();
- const CSSParserToken& next = url_args.ConsumeIncludingWhitespace();
- if (next.GetType() == kBadStringToken || !url_args.AtEnd())
- return StringView();
- DCHECK_EQ(next.GetType(), kStringToken);
- range = url_range;
- range.ConsumeWhitespace();
- url = next.Value();
- }
-
- // Invalidate the URL if only data URLs are allowed and the protocol is not
- // data.
- if (!url.IsNull() &&
- context.ResourceFetchRestriction() ==
- ResourceFetchRestriction::kOnlyDataUrls &&
- !ProtocolIs(url.ToString(), "data")) {
- // The StringView must be instantiated with an empty string otherwise the
- // URL will incorrectly be identified as null. The resource should behave as
- // if it failed to load.
- url = StringView("");
- }
-
- return url;
-}
-
-cssvalue::CSSURIValue* ConsumeUrl(CSSParserTokenRange& range,
- const CSSParserContext& context) {
- StringView url = ConsumeUrlAsStringView(range, context);
- if (url.IsNull())
- return nullptr;
- AtomicString url_string(url.ToString());
- return MakeGarbageCollected<cssvalue::CSSURIValue>(
- url_string, context.CompleteURL(url_string));
-}
-
-static int ClampRGBComponent(const CSSPrimitiveValue& value) {
- double result = value.GetDoubleValue();
- if (value.IsPercentage()) {
- // 2.55 cannot be precisely represented as a double
- result = (result / 100.0) * 255.0;
- }
- return clampTo<int>(round(result), 0, 255);
-}
-
-static bool ParseRGBParameters(CSSParserTokenRange& range,
- const CSSParserContext& context,
- RGBA32& result) {
- DCHECK(range.Peek().FunctionId() == CSSValueID::kRgb ||
- range.Peek().FunctionId() == CSSValueID::kRgba);
- CSSParserTokenRange args = ConsumeFunction(range);
- CSSPrimitiveValue* color_parameter =
- ConsumeNumber(args, context, kValueRangeAll);
- if (!color_parameter)
- color_parameter = ConsumePercent(args, context, kValueRangeAll);
- if (!color_parameter)
- return false;
- const bool is_percent = color_parameter->IsPercentage();
- int color_array[3];
- color_array[0] = ClampRGBComponent(*color_parameter);
- bool requires_commas = false;
- for (int i = 1; i < 3; i++) {
- if (ConsumeCommaIncludingWhitespace(args)) {
- if (i != 1 && !requires_commas)
- return false;
- requires_commas = true;
- } else if (requires_commas || args.AtEnd()) {
- return false;
- }
- color_parameter = is_percent ? ConsumePercent(args, context, kValueRangeAll)
- : ConsumeNumber(args, context, kValueRangeAll);
- if (!color_parameter)
- return false;
- color_array[i] = ClampRGBComponent(*color_parameter);
- }
-
- bool comma_consumed = ConsumeCommaIncludingWhitespace(args);
- bool slash_consumed = ConsumeSlashIncludingWhitespace(args);
- if ((comma_consumed && !requires_commas) ||
- (slash_consumed && requires_commas))
- return false;
- if (comma_consumed || slash_consumed) {
- double alpha;
- if (!ConsumeNumberRaw(args, context, alpha)) {
- CSSPrimitiveValue* alpha_percent =
- ConsumePercent(args, context, kValueRangeAll);
- if (!alpha_percent)
- return false;
- else
- alpha = alpha_percent->GetDoubleValue() / 100.0;
- }
- // W3 standard stipulates a 2.55 alpha value multiplication factor.
- int alpha_component =
- static_cast<int>(lround(clampTo<double>(alpha, 0.0, 1.0) * 255.0));
- result = MakeRGBA(color_array[0], color_array[1], color_array[2],
- alpha_component);
- } else {
- result = MakeRGB(color_array[0], color_array[1], color_array[2]);
- }
- return args.AtEnd();
-}
-
-static bool ParseHSLParameters(CSSParserTokenRange& range,
- const CSSParserContext& context,
- RGBA32& result) {
- DCHECK(range.Peek().FunctionId() == CSSValueID::kHsl ||
- range.Peek().FunctionId() == CSSValueID::kHsla);
- CSSParserTokenRange args = ConsumeFunction(range);
- CSSPrimitiveValue* hsl_value = ConsumeAngle(args, context, base::nullopt);
- double angle_value;
- if (!hsl_value) {
- hsl_value = ConsumeNumber(args, context, kValueRangeAll);
- if (!hsl_value)
- return false;
- angle_value = hsl_value->GetDoubleValue();
- } else {
- angle_value = hsl_value->ComputeDegrees();
- }
- double color_array[3];
- color_array[0] = fmod(fmod(angle_value, 360.0) + 360.0, 360.0) / 60.0;
- bool requires_commas = false;
- for (int i = 1; i < 3; i++) {
- if (ConsumeCommaIncludingWhitespace(args)) {
- if (i != 1 && !requires_commas)
- return false;
- requires_commas = true;
- } else if (requires_commas || args.AtEnd()) {
- return false;
- }
- hsl_value = ConsumePercent(args, context, kValueRangeAll);
- if (!hsl_value)
- return false;
- double double_value = hsl_value->GetDoubleValue();
- color_array[i] = clampTo<double>(double_value, 0.0, 100.0) /
- 100.0; // Needs to be value between 0 and 1.0.
- }
-
- double alpha = 1.0;
- bool comma_consumed = ConsumeCommaIncludingWhitespace(args);
- bool slash_consumed = ConsumeSlashIncludingWhitespace(args);
- if ((comma_consumed && !requires_commas) ||
- (slash_consumed && requires_commas))
- return false;
- if (comma_consumed || slash_consumed) {
- if (!ConsumeNumberRaw(args, context, alpha)) {
- CSSPrimitiveValue* alpha_percent =
- ConsumePercent(args, context, kValueRangeAll);
- if (!alpha_percent)
- return false;
- else
- alpha = alpha_percent->GetDoubleValue() / 100.0;
- }
- alpha = clampTo<double>(alpha, 0.0, 1.0);
- }
- result =
- MakeRGBAFromHSLA(color_array[0], color_array[1], color_array[2], alpha);
- return args.AtEnd();
-}
-
-static bool ParseHexColor(CSSParserTokenRange& range,
- RGBA32& result,
- bool accept_quirky_colors) {
- const CSSParserToken& token = range.Peek();
- if (token.GetType() == kHashToken) {
- if (!Color::ParseHexColor(token.Value(), result))
- return false;
- } else if (accept_quirky_colors) {
- String color;
- if (token.GetType() == kNumberToken || token.GetType() == kDimensionToken) {
- if (token.GetNumericValueType() != kIntegerValueType ||
- token.NumericValue() < 0. || token.NumericValue() >= 1000000.)
- return false;
- if (token.GetType() == kNumberToken) // e.g. 112233
- color = String::Format("%d", static_cast<int>(token.NumericValue()));
- else // e.g. 0001FF
- color = String::Number(static_cast<int>(token.NumericValue())) +
- token.Value().ToString();
- while (color.length() < 6)
- color = "0" + color;
- } else if (token.GetType() == kIdentToken) { // e.g. FF0000
- color = token.Value().ToString();
- }
- unsigned length = color.length();
- if (length != 3 && length != 6)
- return false;
- if (!Color::ParseHexColor(color, result))
- return false;
- } else {
- return false;
- }
- range.ConsumeIncludingWhitespace();
- return true;
-}
-
-static bool ParseColorFunction(CSSParserTokenRange& range,
- const CSSParserContext& context,
- RGBA32& result) {
- CSSValueID function_id = range.Peek().FunctionId();
- if (function_id < CSSValueID::kRgb || function_id > CSSValueID::kHsla)
- return false;
- CSSParserTokenRange color_range = range;
- if ((function_id <= CSSValueID::kRgba &&
- !ParseRGBParameters(color_range, context, result)) ||
- (function_id >= CSSValueID::kHsl &&
- !ParseHSLParameters(color_range, context, result)))
- return false;
- range = color_range;
- return true;
-}
-
-CSSValue* ConsumeColor(CSSParserTokenRange& range,
- const CSSParserContext& context,
- bool accept_quirky_colors) {
- CSSValueID id = range.Peek().Id();
- if (StyleColor::IsColorKeyword(id)) {
- if (!isValueAllowedInMode(id, context.Mode()))
- return nullptr;
- CSSIdentifierValue* color = ConsumeIdent(range);
- return color;
- }
- RGBA32 color = Color::kTransparent;
- if (!ParseHexColor(range, color, accept_quirky_colors) &&
- !ParseColorFunction(range, context, color)) {
- return ConsumeInternalLightDark(ConsumeColor, range, context,
- accept_quirky_colors);
- }
- return cssvalue::CSSColorValue::Create(color);
-}
-
-CSSValue* ConsumeLineWidth(CSSParserTokenRange& range,
- const CSSParserContext& context,
- UnitlessQuirk unitless) {
- CSSValueID id = range.Peek().Id();
- if (id == CSSValueID::kThin || id == CSSValueID::kMedium ||
- id == CSSValueID::kThick)
- return ConsumeIdent(range);
- return ConsumeLength(range, context, kValueRangeNonNegative, unitless);
-}
-
-static CSSValue* ConsumePositionComponent(CSSParserTokenRange& range,
- const CSSParserContext& context,
- UnitlessQuirk unitless,
- bool& horizontal_edge,
- bool& vertical_edge) {
- if (range.Peek().GetType() != kIdentToken)
- return ConsumeLengthOrPercent(range, context, kValueRangeAll, unitless);
-
- CSSValueID id = range.Peek().Id();
- if (id == CSSValueID::kLeft || id == CSSValueID::kRight) {
- if (horizontal_edge)
- return nullptr;
- horizontal_edge = true;
- } else if (id == CSSValueID::kTop || id == CSSValueID::kBottom) {
- if (vertical_edge)
- return nullptr;
- vertical_edge = true;
- } else if (id != CSSValueID::kCenter) {
- return nullptr;
- }
- return ConsumeIdent(range);
-}
-
-static bool IsHorizontalPositionKeywordOnly(const CSSValue& value) {
- auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
- if (!identifier_value)
- return false;
- CSSValueID value_id = identifier_value->GetValueID();
- return value_id == CSSValueID::kLeft || value_id == CSSValueID::kRight;
-}
-
-static bool IsVerticalPositionKeywordOnly(const CSSValue& value) {
- auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
- if (!identifier_value)
- return false;
- CSSValueID value_id = identifier_value->GetValueID();
- return value_id == CSSValueID::kTop || value_id == CSSValueID::kBottom;
-}
-
-static void PositionFromOneValue(CSSValue* value,
- CSSValue*& result_x,
- CSSValue*& result_y) {
- bool value_applies_to_y_axis_only = IsVerticalPositionKeywordOnly(*value);
- result_x = value;
- result_y = CSSIdentifierValue::Create(CSSValueID::kCenter);
- if (value_applies_to_y_axis_only)
- std::swap(result_x, result_y);
-}
-
-static void PositionFromTwoValues(CSSValue* value1,
- CSSValue* value2,
- CSSValue*& result_x,
- CSSValue*& result_y) {
- bool must_order_as_xy = IsHorizontalPositionKeywordOnly(*value1) ||
- IsVerticalPositionKeywordOnly(*value2) ||
- !value1->IsIdentifierValue() ||
- !value2->IsIdentifierValue();
- bool must_order_as_yx = IsVerticalPositionKeywordOnly(*value1) ||
- IsHorizontalPositionKeywordOnly(*value2);
- DCHECK(!must_order_as_xy || !must_order_as_yx);
- result_x = value1;
- result_y = value2;
- if (must_order_as_yx)
- std::swap(result_x, result_y);
-}
-
-static void PositionFromThreeOrFourValues(CSSValue** values,
- CSSValue*& result_x,
- CSSValue*& result_y) {
- CSSIdentifierValue* center = nullptr;
- for (int i = 0; values[i]; i++) {
- auto* current_value = To<CSSIdentifierValue>(values[i]);
- CSSValueID id = current_value->GetValueID();
-
- if (id == CSSValueID::kCenter) {
- DCHECK(!center);
- center = current_value;
- continue;
- }
-
- CSSValue* result = nullptr;
- if (values[i + 1] && !values[i + 1]->IsIdentifierValue()) {
- result = MakeGarbageCollected<CSSValuePair>(
- current_value, values[++i], CSSValuePair::kKeepIdenticalValues);
- } else {
- result = current_value;
- }
-
- if (id == CSSValueID::kLeft || id == CSSValueID::kRight) {
- DCHECK(!result_x);
- result_x = result;
- } else {
- DCHECK(id == CSSValueID::kTop || id == CSSValueID::kBottom);
- DCHECK(!result_y);
- result_y = result;
- }
- }
-
- if (center) {
- DCHECK(!!result_x != !!result_y);
- if (!result_x)
- result_x = center;
- else
- result_y = center;
- }
-
- DCHECK(result_x && result_y);
-}
-
-bool ConsumePosition(CSSParserTokenRange& range,
- const CSSParserContext& context,
- UnitlessQuirk unitless,
- base::Optional<WebFeature> three_value_position,
- CSSValue*& result_x,
- CSSValue*& result_y) {
- bool horizontal_edge = false;
- bool vertical_edge = false;
- CSSValue* value1 = ConsumePositionComponent(range, context, unitless,
- horizontal_edge, vertical_edge);
- if (!value1)
- return false;
- if (!value1->IsIdentifierValue())
- horizontal_edge = true;
-
- CSSParserTokenRange range_after_first_consume = range;
- CSSValue* value2 = ConsumePositionComponent(range, context, unitless,
- horizontal_edge, vertical_edge);
- if (!value2) {
- PositionFromOneValue(value1, result_x, result_y);
- return true;
- }
-
- CSSParserTokenRange range_after_second_consume = range;
- CSSValue* value3 = nullptr;
- auto* identifier_value1 = DynamicTo<CSSIdentifierValue>(value1);
- auto* identifier_value2 = DynamicTo<CSSIdentifierValue>(value2);
- // TODO(crbug.com/940442): Fix the strange comparison of a
- // CSSIdentifierValue instance against a specific "range peek" type check.
- if (identifier_value1 &&
- !!identifier_value2 != (range.Peek().GetType() == kIdentToken) &&
- (identifier_value2
- ? identifier_value2->GetValueID()
- : identifier_value1->GetValueID()) != CSSValueID::kCenter) {
- value3 = ConsumePositionComponent(range, context, unitless, horizontal_edge,
- vertical_edge);
- }
- if (!value3) {
- if (vertical_edge && !value2->IsIdentifierValue()) {
- range = range_after_first_consume;
- PositionFromOneValue(value1, result_x, result_y);
- return true;
- }
- PositionFromTwoValues(value1, value2, result_x, result_y);
- return true;
- }
-
- CSSValue* value4 = nullptr;
- auto* identifier_value3 = DynamicTo<CSSIdentifierValue>(value3);
- if (identifier_value3 &&
- identifier_value3->GetValueID() != CSSValueID::kCenter &&
- range.Peek().GetType() != kIdentToken) {
- value4 = ConsumePositionComponent(range, context, unitless, horizontal_edge,
- vertical_edge);
- }
-
- if (!value4) {
- if (!three_value_position) {
- // [top | bottom] <length-percentage> is not permitted
- if (vertical_edge && !value2->IsIdentifierValue()) {
- range = range_after_first_consume;
- PositionFromOneValue(value1, result_x, result_y);
- return true;
- }
- range = range_after_second_consume;
- PositionFromTwoValues(value1, value2, result_x, result_y);
- return true;
- }
- DCHECK_EQ(*three_value_position,
- WebFeature::kThreeValuedPositionBackground);
- context.Count(*three_value_position);
- }
-
- CSSValue* values[5];
- values[0] = value1;
- values[1] = value2;
- values[2] = value3;
- values[3] = value4;
- values[4] = nullptr;
- PositionFromThreeOrFourValues(values, result_x, result_y);
- return true;
-}
-
-CSSValuePair* ConsumePosition(CSSParserTokenRange& range,
- const CSSParserContext& context,
- UnitlessQuirk unitless,
- base::Optional<WebFeature> three_value_position) {
- CSSValue* result_x = nullptr;
- CSSValue* result_y = nullptr;
- if (ConsumePosition(range, context, unitless, three_value_position, result_x,
- result_y)) {
- return MakeGarbageCollected<CSSValuePair>(
- result_x, result_y, CSSValuePair::kKeepIdenticalValues);
- }
- return nullptr;
-}
-
-bool ConsumeOneOrTwoValuedPosition(CSSParserTokenRange& range,
- const CSSParserContext& context,
- UnitlessQuirk unitless,
- CSSValue*& result_x,
- CSSValue*& result_y) {
- bool horizontal_edge = false;
- bool vertical_edge = false;
- CSSValue* value1 = ConsumePositionComponent(range, context, unitless,
- horizontal_edge, vertical_edge);
- if (!value1)
- return false;
- if (!value1->IsIdentifierValue())
- horizontal_edge = true;
-
- if (vertical_edge &&
- ConsumeLengthOrPercent(range, context, kValueRangeAll, unitless)) {
- // <length-percentage> is not permitted after top | bottom.
- return false;
- }
- CSSValue* value2 = ConsumePositionComponent(range, context, unitless,
- horizontal_edge, vertical_edge);
- if (!value2) {
- PositionFromOneValue(value1, result_x, result_y);
- return true;
- }
- PositionFromTwoValues(value1, value2, result_x, result_y);
- return true;
-}
-
-bool ConsumeBorderShorthand(CSSParserTokenRange& range,
- const CSSParserContext& context,
- const CSSValue*& result_width,
- const CSSValue*& result_style,
- const CSSValue*& result_color) {
- while (!result_width || !result_style || !result_color) {
- if (!result_width) {
- result_width = css_property_parser_helpers::ConsumeLineWidth(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
- if (result_width)
- continue;
- }
- if (!result_style) {
- result_style = css_property_parser_helpers::ParseLonghand(
- CSSPropertyID::kBorderLeftStyle, CSSPropertyID::kBorder, context,
- range);
- if (result_style)
- continue;
- }
- if (!result_color) {
- result_color = css_property_parser_helpers::ConsumeColor(range, context);
- if (result_color)
- continue;
- }
- break;
- }
-
- if (!result_width && !result_style && !result_color)
- return false;
-
- if (!result_width)
- result_width = CSSInitialValue::Create();
- if (!result_style)
- result_style = CSSInitialValue::Create();
- if (!result_color)
- result_color = CSSInitialValue::Create();
- return true;
-}
-
-// This should go away once we drop support for -webkit-gradient
-static CSSPrimitiveValue* ConsumeDeprecatedGradientPoint(
- CSSParserTokenRange& args,
- const CSSParserContext& context,
- bool horizontal) {
- if (args.Peek().GetType() == kIdentToken) {
- if ((horizontal && ConsumeIdent<CSSValueID::kLeft>(args)) ||
- (!horizontal && ConsumeIdent<CSSValueID::kTop>(args)))
- return CSSNumericLiteralValue::Create(
- 0., CSSPrimitiveValue::UnitType::kPercentage);
- if ((horizontal && ConsumeIdent<CSSValueID::kRight>(args)) ||
- (!horizontal && ConsumeIdent<CSSValueID::kBottom>(args)))
- return CSSNumericLiteralValue::Create(
- 100., CSSPrimitiveValue::UnitType::kPercentage);
- if (ConsumeIdent<CSSValueID::kCenter>(args))
- return CSSNumericLiteralValue::Create(
- 50., CSSPrimitiveValue::UnitType::kPercentage);
- return nullptr;
- }
- CSSPrimitiveValue* result = ConsumePercent(args, context, kValueRangeAll);
- if (!result)
- result = ConsumeNumber(args, context, kValueRangeAll);
- return result;
-}
-
-// Used to parse colors for -webkit-gradient(...).
-static CSSValue* ConsumeDeprecatedGradientStopColor(
- CSSParserTokenRange& args,
- const CSSParserContext& context) {
- if (args.Peek().Id() == CSSValueID::kCurrentcolor)
- return nullptr;
- return ConsumeColor(args, context);
-}
-
-static bool ConsumeDeprecatedGradientColorStop(
- CSSParserTokenRange& range,
- cssvalue::CSSGradientColorStop& stop,
- const CSSParserContext& context) {
- CSSValueID id = range.Peek().FunctionId();
- if (id != CSSValueID::kFrom && id != CSSValueID::kTo &&
- id != CSSValueID::kColorStop)
- return false;
-
- CSSParserTokenRange args = ConsumeFunction(range);
- double position;
- if (id == CSSValueID::kFrom || id == CSSValueID::kTo) {
- position = (id == CSSValueID::kFrom) ? 0 : 1;
- } else {
- DCHECK(id == CSSValueID::kColorStop);
- if (CSSPrimitiveValue* percent_value =
- ConsumePercent(args, context, kValueRangeAll))
- position = percent_value->GetDoubleValue() / 100.0;
- else if (!ConsumeNumberRaw(args, context, position))
- return false;
-
- if (!ConsumeCommaIncludingWhitespace(args))
- return false;
- }
-
- stop.offset_ = CSSNumericLiteralValue::Create(
- position, CSSPrimitiveValue::UnitType::kNumber);
- stop.color_ = ConsumeDeprecatedGradientStopColor(args, context);
- return stop.color_ && args.AtEnd();
-}
-
-static CSSValue* ConsumeDeprecatedGradient(CSSParserTokenRange& args,
- const CSSParserContext& context) {
- CSSValueID id = args.ConsumeIncludingWhitespace().Id();
- if (id != CSSValueID::kRadial && id != CSSValueID::kLinear)
- return nullptr;
-
- if (!ConsumeCommaIncludingWhitespace(args))
- return nullptr;
-
- const CSSPrimitiveValue* first_x =
- ConsumeDeprecatedGradientPoint(args, context, true);
- if (!first_x)
- return nullptr;
- const CSSPrimitiveValue* first_y =
- ConsumeDeprecatedGradientPoint(args, context, false);
- if (!first_y)
- return nullptr;
- if (!ConsumeCommaIncludingWhitespace(args))
- return nullptr;
-
- // For radial gradients only, we now expect a numeric radius.
- const CSSPrimitiveValue* first_radius = nullptr;
- if (id == CSSValueID::kRadial) {
- first_radius = ConsumeNumber(args, context, kValueRangeNonNegative);
- if (!first_radius || !ConsumeCommaIncludingWhitespace(args))
- return nullptr;
- }
-
- const CSSPrimitiveValue* second_x =
- ConsumeDeprecatedGradientPoint(args, context, true);
- if (!second_x)
- return nullptr;
- const CSSPrimitiveValue* second_y =
- ConsumeDeprecatedGradientPoint(args, context, false);
- if (!second_y)
- return nullptr;
-
- // For radial gradients only, we now expect the second radius.
- const CSSPrimitiveValue* second_radius = nullptr;
- if (id == CSSValueID::kRadial) {
- if (!ConsumeCommaIncludingWhitespace(args))
- return nullptr;
- second_radius = ConsumeNumber(args, context, kValueRangeNonNegative);
- if (!second_radius)
- return nullptr;
- }
-
- cssvalue::CSSGradientValue* result;
- if (id == CSSValueID::kRadial) {
- result = MakeGarbageCollected<cssvalue::CSSRadialGradientValue>(
- first_x, first_y, first_radius, second_x, second_y, second_radius,
- cssvalue::kNonRepeating, cssvalue::kCSSDeprecatedRadialGradient);
- } else {
- result = MakeGarbageCollected<cssvalue::CSSLinearGradientValue>(
- first_x, first_y, second_x, second_y, nullptr, cssvalue::kNonRepeating,
- cssvalue::kCSSDeprecatedLinearGradient);
- }
- cssvalue::CSSGradientColorStop stop;
- while (ConsumeCommaIncludingWhitespace(args)) {
- if (!ConsumeDeprecatedGradientColorStop(args, stop, context))
- return nullptr;
- result->AddStop(stop);
- }
-
- return result;
-}
-
-static CSSPrimitiveValue* ConsumeGradientAngleOrPercent(
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- ValueRange value_range,
- UnitlessQuirk) {
- const CSSParserToken& token = range.Peek();
- if (token.GetType() == kDimensionToken || token.GetType() == kNumberToken) {
- return ConsumeAngle(range, context, WebFeature::kUnitlessZeroAngleGradient);
- }
- if (token.GetType() == kPercentageToken)
- return ConsumePercent(range, context, value_range);
- MathFunctionParser math_parser(range, context, value_range);
- if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
- CalculationCategory category = calculation->Category();
- // TODO(fs): Add and support kCalcPercentAngle?
- if (category == kCalcAngle || category == kCalcPercent)
- return math_parser.ConsumeValue();
- }
- return nullptr;
-}
-
-using PositionFunctor = CSSPrimitiveValue* (*)(CSSParserTokenRange&,
- const CSSParserContext&,
- ValueRange,
- UnitlessQuirk);
-
-static bool ConsumeGradientColorStops(CSSParserTokenRange& range,
- const CSSParserContext& context,
- cssvalue::CSSGradientValue* gradient,
- PositionFunctor consume_position_func) {
- bool supports_color_hints =
- gradient->GradientType() == cssvalue::kCSSLinearGradient ||
- gradient->GradientType() == cssvalue::kCSSRadialGradient ||
- gradient->GradientType() == cssvalue::kCSSConicGradient;
-
- // The first color stop cannot be a color hint.
- bool previous_stop_was_color_hint = true;
- do {
- cssvalue::CSSGradientColorStop stop;
- stop.color_ = ConsumeColor(range, context);
- // Two hints in a row are not allowed.
- if (!stop.color_ && (!supports_color_hints || previous_stop_was_color_hint))
- return false;
- previous_stop_was_color_hint = !stop.color_;
- stop.offset_ = consume_position_func(range, context, kValueRangeAll,
- UnitlessQuirk::kForbid);
- if (!stop.color_ && !stop.offset_)
- return false;
- gradient->AddStop(stop);
-
- if (!stop.color_ || !stop.offset_)
- continue;
-
- // Optional second position.
- stop.offset_ = consume_position_func(range, context, kValueRangeAll,
- UnitlessQuirk::kForbid);
- if (stop.offset_)
- gradient->AddStop(stop);
- } while (ConsumeCommaIncludingWhitespace(range));
-
- // The last color stop cannot be a color hint.
- if (previous_stop_was_color_hint)
- return false;
-
- // Must have 2 or more stops to be valid.
- return gradient->StopCount() >= 2;
-}
-
-static CSSValue* ConsumeDeprecatedRadialGradient(
- CSSParserTokenRange& args,
- const CSSParserContext& context,
- cssvalue::CSSGradientRepeat repeating) {
- CSSValue* center_x = nullptr;
- CSSValue* center_y = nullptr;
- ConsumeOneOrTwoValuedPosition(args, context, UnitlessQuirk::kForbid, center_x,
- center_y);
- if ((center_x || center_y) && !ConsumeCommaIncludingWhitespace(args))
- return nullptr;
-
- const CSSIdentifierValue* shape =
- ConsumeIdent<CSSValueID::kCircle, CSSValueID::kEllipse>(args);
- const CSSIdentifierValue* size_keyword =
- ConsumeIdent<CSSValueID::kClosestSide, CSSValueID::kClosestCorner,
- CSSValueID::kFarthestSide, CSSValueID::kFarthestCorner,
- CSSValueID::kContain, CSSValueID::kCover>(args);
- if (!shape)
- shape = ConsumeIdent<CSSValueID::kCircle, CSSValueID::kEllipse>(args);
-
- // Or, two lengths or percentages
- const CSSPrimitiveValue* horizontal_size = nullptr;
- const CSSPrimitiveValue* vertical_size = nullptr;
- if (!shape && !size_keyword) {
- horizontal_size =
- ConsumeLengthOrPercent(args, context, kValueRangeNonNegative);
- if (horizontal_size) {
- vertical_size =
- ConsumeLengthOrPercent(args, context, kValueRangeNonNegative);
- if (!vertical_size)
- return nullptr;
- ConsumeCommaIncludingWhitespace(args);
- }
- } else {
- ConsumeCommaIncludingWhitespace(args);
- }
-
- cssvalue::CSSGradientValue* result =
- MakeGarbageCollected<cssvalue::CSSRadialGradientValue>(
- center_x, center_y, shape, size_keyword, horizontal_size,
- vertical_size, repeating, cssvalue::kCSSPrefixedRadialGradient);
- return ConsumeGradientColorStops(args, context, result,
- ConsumeGradientLengthOrPercent)
- ? result
- : nullptr;
-}
-
-static CSSValue* ConsumeRadialGradient(CSSParserTokenRange& args,
- const CSSParserContext& context,
- cssvalue::CSSGradientRepeat repeating) {
- const CSSIdentifierValue* shape = nullptr;
- const CSSIdentifierValue* size_keyword = nullptr;
- const CSSPrimitiveValue* horizontal_size = nullptr;
- const CSSPrimitiveValue* vertical_size = nullptr;
-
- // First part of grammar, the size/shape clause:
- // [ circle || <length> ] |
- // [ ellipse || [ <length> | <percentage> ]{2} ] |
- // [ [ circle | ellipse] || <size-keyword> ]
- for (int i = 0; i < 3; ++i) {
- if (args.Peek().GetType() == kIdentToken) {
- CSSValueID id = args.Peek().Id();
- if (id == CSSValueID::kCircle || id == CSSValueID::kEllipse) {
- if (shape)
- return nullptr;
- shape = ConsumeIdent(args);
- } else if (id == CSSValueID::kClosestSide ||
- id == CSSValueID::kClosestCorner ||
- id == CSSValueID::kFarthestSide ||
- id == CSSValueID::kFarthestCorner) {
- if (size_keyword)
- return nullptr;
- size_keyword = ConsumeIdent(args);
- } else {
- break;
- }
- } else {
- CSSPrimitiveValue* center =
- ConsumeLengthOrPercent(args, context, kValueRangeNonNegative);
- if (!center)
- break;
- if (horizontal_size)
- return nullptr;
- horizontal_size = center;
- center = ConsumeLengthOrPercent(args, context, kValueRangeNonNegative);
- if (center) {
- vertical_size = center;
- ++i;
- }
- }
- }
-
- // You can specify size as a keyword or a length/percentage, not both.
- if (size_keyword && horizontal_size)
- return nullptr;
- // Circles must have 0 or 1 lengths.
- if (shape && shape->GetValueID() == CSSValueID::kCircle && vertical_size)
- return nullptr;
- // Ellipses must have 0 or 2 length/percentages.
- if (shape && shape->GetValueID() == CSSValueID::kEllipse && horizontal_size &&
- !vertical_size) {
- return nullptr;
- }
- // If there's only one size, it must be a length.
- if (!vertical_size && horizontal_size && horizontal_size->IsPercentage())
- return nullptr;
- if ((horizontal_size &&
- horizontal_size->IsCalculatedPercentageWithLength()) ||
- (vertical_size && vertical_size->IsCalculatedPercentageWithLength())) {
- return nullptr;
- }
-
- CSSValue* center_x = nullptr;
- CSSValue* center_y = nullptr;
- if (args.Peek().Id() == CSSValueID::kAt) {
- args.ConsumeIncludingWhitespace();
- ConsumePosition(args, context, UnitlessQuirk::kForbid,
- base::Optional<WebFeature>(), center_x, center_y);
- if (!(center_x && center_y))
- return nullptr;
- // Right now, CSS radial gradients have the same start and end centers.
- }
-
- if ((shape || size_keyword || horizontal_size || center_x || center_y) &&
- !ConsumeCommaIncludingWhitespace(args)) {
- return nullptr;
- }
-
- cssvalue::CSSGradientValue* result =
- MakeGarbageCollected<cssvalue::CSSRadialGradientValue>(
- center_x, center_y, shape, size_keyword, horizontal_size,
- vertical_size, repeating, cssvalue::kCSSRadialGradient);
- return ConsumeGradientColorStops(args, context, result,
- ConsumeGradientLengthOrPercent)
- ? result
- : nullptr;
-}
-
-static CSSValue* ConsumeLinearGradient(
- CSSParserTokenRange& args,
- const CSSParserContext& context,
- cssvalue::CSSGradientRepeat repeating,
- cssvalue::CSSGradientType gradient_type) {
- bool expect_comma = true;
- const CSSPrimitiveValue* angle =
- ConsumeAngle(args, context, WebFeature::kUnitlessZeroAngleGradient);
- const CSSIdentifierValue* end_x = nullptr;
- const CSSIdentifierValue* end_y = nullptr;
- if (!angle) {
- if (gradient_type == cssvalue::kCSSPrefixedLinearGradient ||
- ConsumeIdent<CSSValueID::kTo>(args)) {
- end_x = ConsumeIdent<CSSValueID::kLeft, CSSValueID::kRight>(args);
- end_y = ConsumeIdent<CSSValueID::kBottom, CSSValueID::kTop>(args);
- if (!end_x && !end_y) {
- if (gradient_type == cssvalue::kCSSLinearGradient)
- return nullptr;
- end_y = CSSIdentifierValue::Create(CSSValueID::kTop);
- expect_comma = false;
- } else if (!end_x) {
- end_x = ConsumeIdent<CSSValueID::kLeft, CSSValueID::kRight>(args);
- }
- } else {
- expect_comma = false;
- }
- }
-
- if (expect_comma && !ConsumeCommaIncludingWhitespace(args))
- return nullptr;
-
- cssvalue::CSSGradientValue* result =
- MakeGarbageCollected<cssvalue::CSSLinearGradientValue>(
- end_x, end_y, nullptr, nullptr, angle, repeating, gradient_type);
- return ConsumeGradientColorStops(args, context, result,
- ConsumeGradientLengthOrPercent)
- ? result
- : nullptr;
-}
-
-static CSSValue* ConsumeConicGradient(CSSParserTokenRange& args,
- const CSSParserContext& context,
- cssvalue::CSSGradientRepeat repeating) {
- const CSSPrimitiveValue* from_angle = nullptr;
- if (ConsumeIdent<CSSValueID::kFrom>(args)) {
- if (!(from_angle = ConsumeAngle(args, context,
- WebFeature::kUnitlessZeroAngleGradient)))
- return nullptr;
- }
-
- CSSValue* center_x = nullptr;
- CSSValue* center_y = nullptr;
- if (ConsumeIdent<CSSValueID::kAt>(args)) {
- if (!ConsumePosition(args, context, UnitlessQuirk::kForbid,
- base::Optional<WebFeature>(), center_x, center_y))
- return nullptr;
- }
-
- // Comma separator required when fromAngle or position is present.
- if ((from_angle || center_x || center_y) &&
- !ConsumeCommaIncludingWhitespace(args)) {
- return nullptr;
- }
-
- auto* result = MakeGarbageCollected<cssvalue::CSSConicGradientValue>(
- center_x, center_y, from_angle, repeating);
- return ConsumeGradientColorStops(args, context, result,
- ConsumeGradientAngleOrPercent)
- ? result
- : nullptr;
-}
-
-CSSValue* ConsumeImageOrNone(CSSParserTokenRange& range,
- const CSSParserContext& context) {
- if (range.Peek().Id() == CSSValueID::kNone)
- return ConsumeIdent(range);
- return ConsumeImage(range, context);
-}
-
-CSSValue* ConsumeAxis(CSSParserTokenRange& range,
- const CSSParserContext& context) {
- CSSValueID axis_id = range.Peek().Id();
- if (axis_id == CSSValueID::kX || axis_id == CSSValueID::kY ||
- axis_id == CSSValueID::kZ) {
- ConsumeIdent(range);
- return MakeGarbageCollected<cssvalue::CSSAxisValue>(axis_id);
- }
-
- CSSValue* x_dimension = css_property_parser_helpers::ConsumeNumber(
- range, context, kValueRangeAll);
- CSSValue* y_dimension = css_property_parser_helpers::ConsumeNumber(
- range, context, kValueRangeAll);
- CSSValue* z_dimension = css_property_parser_helpers::ConsumeNumber(
- range, context, kValueRangeAll);
- if (!x_dimension || !y_dimension || !z_dimension)
- return nullptr;
- double x = To<CSSPrimitiveValue>(x_dimension)->GetDoubleValue();
- double y = To<CSSPrimitiveValue>(y_dimension)->GetDoubleValue();
- double z = To<CSSPrimitiveValue>(z_dimension)->GetDoubleValue();
- return MakeGarbageCollected<cssvalue::CSSAxisValue>(x, y, z);
-}
-
-static CSSValue* ConsumeCrossFade(CSSParserTokenRange& args,
- const CSSParserContext& context) {
- CSSValue* from_image_value = ConsumeImageOrNone(args, context);
- if (!from_image_value || !ConsumeCommaIncludingWhitespace(args))
- return nullptr;
- CSSValue* to_image_value = ConsumeImageOrNone(args, context);
- if (!to_image_value || !ConsumeCommaIncludingWhitespace(args))
- return nullptr;
-
- CSSPrimitiveValue* percentage = nullptr;
- if (CSSPrimitiveValue* percent_value =
- ConsumePercent(args, context, kValueRangeAll))
- percentage = CSSNumericLiteralValue::Create(
- clampTo<double>(percent_value->GetDoubleValue() / 100.0, 0, 1),
- CSSPrimitiveValue::UnitType::kNumber);
- else if (CSSPrimitiveValue* number_value =
- ConsumeNumber(args, context, kValueRangeAll))
- percentage = CSSNumericLiteralValue::Create(
- clampTo<double>(number_value->GetDoubleValue(), 0, 1),
- CSSPrimitiveValue::UnitType::kNumber);
-
- if (!percentage)
- return nullptr;
- return MakeGarbageCollected<cssvalue::CSSCrossfadeValue>(
- from_image_value, to_image_value, percentage);
-}
-
-static CSSValue* ConsumePaint(CSSParserTokenRange& args,
- const CSSParserContext& context) {
- const CSSParserToken& name_token = args.ConsumeIncludingWhitespace();
- CSSCustomIdentValue* name = ConsumeCustomIdentWithToken(name_token, context);
- if (!name)
- return nullptr;
-
- if (args.AtEnd())
- return MakeGarbageCollected<CSSPaintValue>(name);
-
- if (!RuntimeEnabledFeatures::CSSPaintAPIArgumentsEnabled()) {
- // Arguments not enabled, but exists. Invalid.
- return nullptr;
- }
-
- // Begin parse paint arguments.
- if (!ConsumeCommaIncludingWhitespace(args))
- return nullptr;
-
- // Consume arguments.
- // TODO(renjieliu): We may want to optimize the implementation by resolve
- // variables early if paint function is registered.
- Vector<CSSParserToken> argument_tokens;
- Vector<scoped_refptr<CSSVariableData>> variable_data;
- while (!args.AtEnd()) {
- if (args.Peek().GetType() != kCommaToken) {
- argument_tokens.AppendVector(ConsumeFunctionArgsOrNot(args));
- } else {
- if (!AddCSSPaintArgument(argument_tokens, &variable_data, context))
- return nullptr;
- argument_tokens.clear();
- if (!ConsumeCommaIncludingWhitespace(args))
- return nullptr;
- }
- }
- if (!AddCSSPaintArgument(argument_tokens, &variable_data, context))
- return nullptr;
-
- return MakeGarbageCollected<CSSPaintValue>(name, variable_data);
-}
-
-static CSSValue* ConsumeGeneratedImage(CSSParserTokenRange& range,
- const CSSParserContext& context) {
- CSSValueID id = range.Peek().FunctionId();
- CSSParserTokenRange range_copy = range;
- CSSParserTokenRange args = ConsumeFunction(range_copy);
- CSSValue* result = nullptr;
- if (id == CSSValueID::kRadialGradient) {
- result = ConsumeRadialGradient(args, context, cssvalue::kNonRepeating);
- } else if (id == CSSValueID::kRepeatingRadialGradient) {
- result = ConsumeRadialGradient(args, context, cssvalue::kRepeating);
- } else if (id == CSSValueID::kWebkitLinearGradient) {
- context.Count(WebFeature::kDeprecatedWebKitLinearGradient);
- result = ConsumeLinearGradient(args, context, cssvalue::kNonRepeating,
- cssvalue::kCSSPrefixedLinearGradient);
- } else if (id == CSSValueID::kWebkitRepeatingLinearGradient) {
- context.Count(WebFeature::kDeprecatedWebKitRepeatingLinearGradient);
- result = ConsumeLinearGradient(args, context, cssvalue::kRepeating,
- cssvalue::kCSSPrefixedLinearGradient);
- } else if (id == CSSValueID::kRepeatingLinearGradient) {
- result = ConsumeLinearGradient(args, context, cssvalue::kRepeating,
- cssvalue::kCSSLinearGradient);
- } else if (id == CSSValueID::kLinearGradient) {
- result = ConsumeLinearGradient(args, context, cssvalue::kNonRepeating,
- cssvalue::kCSSLinearGradient);
- } else if (id == CSSValueID::kWebkitGradient) {
- context.Count(WebFeature::kDeprecatedWebKitGradient);
- result = ConsumeDeprecatedGradient(args, context);
- } else if (id == CSSValueID::kWebkitRadialGradient) {
- context.Count(WebFeature::kDeprecatedWebKitRadialGradient);
- result =
- ConsumeDeprecatedRadialGradient(args, context, cssvalue::kNonRepeating);
- } else if (id == CSSValueID::kWebkitRepeatingRadialGradient) {
- context.Count(WebFeature::kDeprecatedWebKitRepeatingRadialGradient);
- result =
- ConsumeDeprecatedRadialGradient(args, context, cssvalue::kRepeating);
- } else if (id == CSSValueID::kConicGradient) {
- result = ConsumeConicGradient(args, context, cssvalue::kNonRepeating);
- } else if (id == CSSValueID::kRepeatingConicGradient) {
- result = ConsumeConicGradient(args, context, cssvalue::kRepeating);
- } else if (id == CSSValueID::kWebkitCrossFade) {
- result = ConsumeCrossFade(args, context);
- } else if (id == CSSValueID::kPaint) {
- result = context.IsSecureContext() ? ConsumePaint(args, context) : nullptr;
- }
- if (!result || !args.AtEnd())
- return nullptr;
-
- WebFeature feature;
- if (id == CSSValueID::kWebkitCrossFade)
- feature = WebFeature::kWebkitCrossFade;
- else if (id == CSSValueID::kPaint)
- feature = WebFeature::kCSSPaintFunction;
- else
- feature = WebFeature::kCSSGradient;
- context.Count(feature);
-
- range = range_copy;
- return result;
-}
-
-static CSSValue* CreateCSSImageValueWithReferrer(
- const AtomicString& raw_value,
- const CSSParserContext& context) {
- CSSValue* image_value = MakeGarbageCollected<CSSImageValue>(
- raw_value, context.CompleteURL(raw_value), context.GetReferrer(),
- context.IsOriginClean() ? OriginClean::kTrue : OriginClean::kFalse,
- context.IsAdRelated());
- return image_value;
-}
-
-static CSSValue* ConsumeImageSet(CSSParserTokenRange& range,
- const CSSParserContext& context) {
- CSSParserTokenRange range_copy = range;
- CSSParserTokenRange args = ConsumeFunction(range_copy);
- auto* image_set = MakeGarbageCollected<CSSImageSetValue>(context.Mode());
- do {
- AtomicString url_value =
- ConsumeUrlAsStringView(args, context).ToAtomicString();
- if (url_value.IsNull())
- return nullptr;
-
- CSSValue* image = CreateCSSImageValueWithReferrer(url_value, context);
- image_set->Append(*image);
-
- const CSSParserToken& token = args.ConsumeIncludingWhitespace();
- if (token.GetType() != kDimensionToken)
- return nullptr;
- if (token.Value() != "x")
- return nullptr;
- DCHECK(token.GetUnitType() == CSSPrimitiveValue::UnitType::kDotsPerPixel);
- double image_scale_factor = token.NumericValue();
- if (image_scale_factor <= 0)
- return nullptr;
- image_set->Append(*CSSNumericLiteralValue::Create(
- image_scale_factor, CSSPrimitiveValue::UnitType::kNumber));
- } while (ConsumeCommaIncludingWhitespace(args));
- if (!args.AtEnd())
- return nullptr;
- range = range_copy;
- return image_set;
-}
-
-static bool IsGeneratedImage(CSSValueID id) {
- return id == CSSValueID::kLinearGradient ||
- id == CSSValueID::kRadialGradient ||
- id == CSSValueID::kConicGradient ||
- id == CSSValueID::kRepeatingLinearGradient ||
- id == CSSValueID::kRepeatingRadialGradient ||
- id == CSSValueID::kRepeatingConicGradient ||
- id == CSSValueID::kWebkitLinearGradient ||
- id == CSSValueID::kWebkitRadialGradient ||
- id == CSSValueID::kWebkitRepeatingLinearGradient ||
- id == CSSValueID::kWebkitRepeatingRadialGradient ||
- id == CSSValueID::kWebkitGradient ||
- id == CSSValueID::kWebkitCrossFade || id == CSSValueID::kPaint;
-}
-
-CSSValue* ConsumeImage(CSSParserTokenRange& range,
- const CSSParserContext& context,
- ConsumeGeneratedImagePolicy generated_image) {
- AtomicString uri = ConsumeUrlAsStringView(range, context).ToAtomicString();
- if (!uri.IsNull())
- return CreateCSSImageValueWithReferrer(uri, context);
- if (range.Peek().GetType() == kFunctionToken) {
- CSSValueID id = range.Peek().FunctionId();
- if (id == CSSValueID::kWebkitImageSet)
- return ConsumeImageSet(range, context);
- if (generated_image == ConsumeGeneratedImagePolicy::kAllow &&
- IsGeneratedImage(id)) {
- return ConsumeGeneratedImage(range, context);
- }
- return ConsumeInternalLightDark(ConsumeImageOrNone, range, context);
- }
- return nullptr;
-}
-
-// https://drafts.csswg.org/css-values-4/#css-wide-keywords
-bool IsCSSWideKeyword(StringView keyword) {
- return EqualIgnoringASCIICase(keyword, "initial") ||
- EqualIgnoringASCIICase(keyword, "inherit") ||
- EqualIgnoringASCIICase(keyword, "unset") ||
- (RuntimeEnabledFeatures::CSSRevertEnabled() &&
- EqualIgnoringASCIICase(keyword, "revert"));
-}
-
-// https://drafts.csswg.org/css-cascade/#default
-bool IsRevertKeyword(StringView keyword) {
- return EqualIgnoringASCIICase(keyword, "revert");
-}
-
-// https://drafts.csswg.org/css-values-4/#identifier-value
-bool IsDefaultKeyword(StringView keyword) {
- return EqualIgnoringASCIICase(keyword, "default");
-}
-
-// https://drafts.csswg.org/css-shapes-1/#typedef-shape-box
-CSSIdentifierValue* ConsumeShapeBox(CSSParserTokenRange& range) {
- return ConsumeIdent<CSSValueID::kContentBox, CSSValueID::kPaddingBox,
- CSSValueID::kBorderBox, CSSValueID::kMarginBox>(range);
-}
-
-void AddProperty(CSSPropertyID resolved_property,
- CSSPropertyID current_shorthand,
- const CSSValue& value,
- bool important,
- IsImplicitProperty implicit,
- HeapVector<CSSPropertyValue, 256>& properties) {
- DCHECK(!isPropertyAlias(resolved_property));
- DCHECK(implicit == IsImplicitProperty::kNotImplicit ||
- implicit == IsImplicitProperty::kImplicit);
-
- int shorthand_index = 0;
- bool set_from_shorthand = false;
-
- if (isValidCSSPropertyID(current_shorthand)) {
- Vector<StylePropertyShorthand, 4> shorthands;
- getMatchingShorthandsForLonghand(resolved_property, &shorthands);
- set_from_shorthand = true;
- if (shorthands.size() > 1) {
- shorthand_index =
- indexOfShorthandForLonghand(current_shorthand, shorthands);
- }
- }
-
- properties.push_back(CSSPropertyValue(
- CSSProperty::Get(resolved_property), value, important, set_from_shorthand,
- shorthand_index, implicit == IsImplicitProperty::kImplicit));
-}
-
-CSSValue* ConsumeTransformValue(CSSParserTokenRange& range,
- const CSSParserContext& context) {
- bool use_legacy_parsing = false;
- return css_parsing_utils::ConsumeTransformValue(range, context,
- use_legacy_parsing);
-}
-
-CSSValue* ConsumeTransformList(CSSParserTokenRange& range,
- const CSSParserContext& context) {
- return css_parsing_utils::ConsumeTransformList(range, context,
- CSSParserLocalContext());
-}
-
-CSSValue* ConsumeFilterFunctionList(CSSParserTokenRange& range,
- const CSSParserContext& context) {
- if (range.Peek().Id() == CSSValueID::kNone)
- return ConsumeIdent(range);
-
- CSSValueList* list = CSSValueList::CreateSpaceSeparated();
- do {
- CSSValue* filter_value = ConsumeUrl(range, context);
- if (!filter_value) {
- filter_value = ConsumeFilterFunction(range, context);
- if (!filter_value)
- return nullptr;
- }
- list->Append(*filter_value);
- } while (!range.AtEnd());
- return list;
-}
-
-void CountKeywordOnlyPropertyUsage(CSSPropertyID property,
- const CSSParserContext& context,
- CSSValueID value_id) {
- if (!context.IsUseCounterRecordingEnabled())
- return;
- switch (property) {
- case CSSPropertyID::kAppearance:
- if (value_id == CSSValueID::kInnerSpinButton ||
- value_id == CSSValueID::kMediaSlider ||
- value_id == CSSValueID::kMediaSliderthumb ||
- value_id == CSSValueID::kMediaVolumeSlider ||
- value_id == CSSValueID::kMediaVolumeSliderthumb ||
- value_id == CSSValueID::kSliderVertical ||
- value_id == CSSValueID::kSliderthumbHorizontal ||
- value_id == CSSValueID::kSliderthumbVertical ||
- value_id == CSSValueID::kSearchfieldCancelButton) {
- if (const auto* document = context.GetDocument()) {
- document->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
- mojom::blink::ConsoleMessageSource::kOther,
- mojom::blink::ConsoleMessageLevel::kWarning,
- String("The keyword '") + getValueName(value_id) +
- "' specified to an 'appearance' property is not "
- "standardized. It will be removed in the future."));
- }
- }
- FALLTHROUGH;
- // This function distinguishes 'appearance' and '-webkit-appearance'
- // though other property aliases are handles as their aliased properties.
- // See Appearance::ParseSingleValue().
- case CSSPropertyID::kAliasWebkitAppearance: {
- WebFeature feature;
- if (value_id == CSSValueID::kNone) {
- feature = WebFeature::kCSSValueAppearanceNone;
- } else {
- feature = WebFeature::kCSSValueAppearanceNotNone;
- if (value_id == CSSValueID::kButton)
- feature = WebFeature::kCSSValueAppearanceButton;
- else if (value_id == CSSValueID::kCheckbox)
- feature = WebFeature::kCSSValueAppearanceCheckbox;
- else if (value_id == CSSValueID::kInnerSpinButton)
- feature = WebFeature::kCSSValueAppearanceInnerSpinButton;
- else if (value_id == CSSValueID::kMenulist)
- feature = WebFeature::kCSSValueAppearanceMenulist;
- else if (value_id == CSSValueID::kMenulistButton)
- feature = WebFeature::kCSSValueAppearanceMenulistButton;
- else if (value_id == CSSValueID::kMeter)
- feature = WebFeature::kCSSValueAppearanceMeter;
- else if (value_id == CSSValueID::kListbox)
- feature = WebFeature::kCSSValueAppearanceListbox;
- else if (value_id == CSSValueID::kProgressBar)
- feature = WebFeature::kCSSValueAppearanceProgressBar;
- else if (value_id == CSSValueID::kPushButton)
- feature = WebFeature::kCSSValueAppearancePushButton;
- else if (value_id == CSSValueID::kRadio)
- feature = WebFeature::kCSSValueAppearanceRadio;
- else if (value_id == CSSValueID::kSearchfieldCancelButton)
- feature = WebFeature::kCSSValueAppearanceSearchCancel;
- else if (value_id == CSSValueID::kSquareButton)
- feature = WebFeature::kCSSValueAppearanceSquareButton;
- else if (value_id == CSSValueID::kSearchfield)
- feature = WebFeature::kCSSValueAppearanceSearchField;
- else if (value_id == CSSValueID::kTextarea)
- feature = WebFeature::kCSSValueAppearanceTextarea;
- else if (value_id == CSSValueID::kTextfield)
- feature = WebFeature::kCSSValueAppearanceTextField;
- else
- feature = WebFeature::kCSSValueAppearanceOthers;
- }
- context.Count(feature);
- break;
- }
-
- case CSSPropertyID::kWebkitUserModify: {
- switch (value_id) {
- case CSSValueID::kReadOnly:
- context.Count(WebFeature::kCSSValueUserModifyReadOnly);
- break;
- case CSSValueID::kReadWrite:
- context.Count(WebFeature::kCSSValueUserModifyReadWrite);
- break;
- case CSSValueID::kReadWritePlaintextOnly:
- context.Count(WebFeature::kCSSValueUserModifyReadWritePlaintextOnly);
- break;
- default:
- NOTREACHED();
- }
- break;
- }
- case CSSPropertyID::kDisplay:
- if (value_id == CSSValueID::kContents)
- context.Count(WebFeature::kCSSValueDisplayContents);
- break;
- case CSSPropertyID::kOverflowX:
- case CSSPropertyID::kOverflowY:
- if (value_id == CSSValueID::kOverlay)
- context.Count(WebFeature::kCSSValueOverflowOverlay);
- break;
- default:
- break;
- }
-}
-
-const CSSValue* ParseLonghand(CSSPropertyID unresolved_property,
- CSSPropertyID current_shorthand,
- const CSSParserContext& context,
- CSSParserTokenRange& range) {
- CSSPropertyID property_id = resolveCSSPropertyID(unresolved_property);
- DCHECK(!CSSProperty::Get(property_id).IsShorthand());
- if (CSSParserFastPaths::IsKeywordPropertyID(property_id)) {
- if (CSSParserFastPaths::IsValidKeywordPropertyAndValue(
- property_id, range.Peek().Id(), context.Mode())) {
- CountKeywordOnlyPropertyUsage(property_id, context, range.Peek().Id());
- return ConsumeIdent(range);
- }
-
- // Some properties need to fallback onto the regular parser.
- if (!CSSParserFastPaths::IsPartialKeywordPropertyID(property_id))
- return nullptr;
- }
-
- const auto local_context =
- CSSParserLocalContext()
- .WithAliasParsing(isPropertyAlias(unresolved_property))
- .WithCurrentShorthand(current_shorthand);
-
- const CSSValue* result = To<Longhand>(CSSProperty::Get(property_id))
- .ParseSingleValue(range, context, local_context);
- return result;
-}
-
-bool ConsumeShorthandVia2Longhands(
- const StylePropertyShorthand& shorthand,
- bool important,
- const CSSParserContext& context,
- CSSParserTokenRange& range,
- HeapVector<CSSPropertyValue, 256>& properties) {
- DCHECK_EQ(shorthand.length(), 2u);
- const CSSProperty** longhands = shorthand.properties();
-
- const CSSValue* start =
- ParseLonghand(longhands[0]->PropertyID(), shorthand.id(), context, range);
-
- if (!start)
- return false;
-
- const CSSValue* end =
- ParseLonghand(longhands[1]->PropertyID(), shorthand.id(), context, range);
-
- if (shorthand.id() == CSSPropertyID::kOverflow && start && end) {
- context.Count(WebFeature::kTwoValuedOverflow);
- }
-
- if (!end)
- end = start;
- AddProperty(longhands[0]->PropertyID(), shorthand.id(), *start, important,
- IsImplicitProperty::kNotImplicit, properties);
- AddProperty(longhands[1]->PropertyID(), shorthand.id(), *end, important,
- IsImplicitProperty::kNotImplicit, properties);
-
- return range.AtEnd();
-}
-
-bool ConsumeShorthandVia4Longhands(
- const StylePropertyShorthand& shorthand,
- bool important,
- const CSSParserContext& context,
- CSSParserTokenRange& range,
- HeapVector<CSSPropertyValue, 256>& properties) {
- DCHECK_EQ(shorthand.length(), 4u);
- const CSSProperty** longhands = shorthand.properties();
- const CSSValue* top =
- ParseLonghand(longhands[0]->PropertyID(), shorthand.id(), context, range);
-
- if (!top)
- return false;
-
- const CSSValue* right =
- ParseLonghand(longhands[1]->PropertyID(), shorthand.id(), context, range);
-
- const CSSValue* bottom = nullptr;
- const CSSValue* left = nullptr;
- if (right) {
- bottom = ParseLonghand(longhands[2]->PropertyID(), shorthand.id(), context,
- range);
- if (bottom) {
- left = ParseLonghand(longhands[3]->PropertyID(), shorthand.id(), context,
- range);
- }
- }
-
- if (!right)
- right = top;
- if (!bottom)
- bottom = top;
- if (!left)
- left = right;
-
- AddProperty(longhands[0]->PropertyID(), shorthand.id(), *top, important,
- IsImplicitProperty::kNotImplicit, properties);
- AddProperty(longhands[1]->PropertyID(), shorthand.id(), *right, important,
- IsImplicitProperty::kNotImplicit, properties);
- AddProperty(longhands[2]->PropertyID(), shorthand.id(), *bottom, important,
- IsImplicitProperty::kNotImplicit, properties);
- AddProperty(longhands[3]->PropertyID(), shorthand.id(), *left, important,
- IsImplicitProperty::kNotImplicit, properties);
-
- return range.AtEnd();
-}
-
-bool ConsumeShorthandGreedilyViaLonghands(
- const StylePropertyShorthand& shorthand,
- bool important,
- const CSSParserContext& context,
- CSSParserTokenRange& range,
- HeapVector<CSSPropertyValue, 256>& properties) {
- // Existing shorthands have at most 6 longhands.
- DCHECK_LE(shorthand.length(), 6u);
- const CSSValue* longhands[6] = {nullptr, nullptr, nullptr,
- nullptr, nullptr, nullptr};
- const CSSProperty** shorthand_properties = shorthand.properties();
- do {
- bool found_longhand = false;
- for (size_t i = 0; !found_longhand && i < shorthand.length(); ++i) {
- if (longhands[i])
- continue;
- longhands[i] = ParseLonghand(shorthand_properties[i]->PropertyID(),
- shorthand.id(), context, range);
-
- if (longhands[i])
- found_longhand = true;
- }
- if (!found_longhand)
- return false;
- } while (!range.AtEnd());
-
- for (size_t i = 0; i < shorthand.length(); ++i) {
- if (longhands[i]) {
- AddProperty(shorthand_properties[i]->PropertyID(), shorthand.id(),
- *longhands[i], important, IsImplicitProperty::kNotImplicit,
- properties);
- } else {
- AddProperty(shorthand_properties[i]->PropertyID(), shorthand.id(),
- *CSSInitialValue::Create(), important,
- IsImplicitProperty::kNotImplicit, properties);
- }
- }
- return true;
-}
-
-void AddExpandedPropertyForValue(
- CSSPropertyID property,
- const CSSValue& value,
- bool important,
- HeapVector<CSSPropertyValue, 256>& properties) {
- const StylePropertyShorthand& shorthand = shorthandForProperty(property);
- unsigned shorthand_length = shorthand.length();
- DCHECK(shorthand_length);
- const CSSProperty** longhands = shorthand.properties();
- for (unsigned i = 0; i < shorthand_length; ++i) {
- AddProperty(longhands[i]->PropertyID(), property, value, important,
- IsImplicitProperty::kNotImplicit, properties);
- }
-}
-
-} // namespace css_property_parser_helpers
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h b/chromium/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h
deleted file mode 100644
index 6c4ea21506f..00000000000
--- a/chromium/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_PROPERTY_PARSER_HELPERS_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_PROPERTY_PARSER_HELPERS_H_
-
-#include "base/optional.h"
-#include "third_party/blink/renderer/core/css/css_custom_ident_value.h"
-#include "third_party/blink/renderer/core/css/css_function_value.h"
-#include "third_party/blink/renderer/core/css/css_identifier_value.h"
-#include "third_party/blink/renderer/core/css/css_primitive_value.h"
-#include "third_party/blink/renderer/core/css/css_value_list.h"
-#include "third_party/blink/renderer/core/css/parser/css_parser_mode.h"
-#include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h"
-#include "third_party/blink/renderer/core/frame/web_feature_forward.h"
-#include "third_party/blink/renderer/platform/geometry/length.h" // For ValueRange
-#include "third_party/blink/renderer/platform/heap/handle.h"
-
-namespace blink {
-
-class CSSParserContext;
-class CSSPropertyValue;
-class CSSStringValue;
-class CSSValuePair;
-class StylePropertyShorthand;
-
-namespace cssvalue {
-
-class CSSURIValue;
-
-}
-
-// When these functions are successful, they will consume all the relevant
-// tokens from the range and also consume any whitespace which follows. When
-// the start of the range doesn't match the type we're looking for, the range
-// will not be modified.
-namespace css_property_parser_helpers {
-
-void Complete4Sides(CSSValue* side[4]);
-
-// TODO(timloh): These should probably just be consumeComma and consumeSlash.
-bool ConsumeCommaIncludingWhitespace(CSSParserTokenRange&);
-bool ConsumeSlashIncludingWhitespace(CSSParserTokenRange&);
-// consumeFunction expects the range starts with a FunctionToken.
-CSSParserTokenRange ConsumeFunction(CSSParserTokenRange&);
-
-enum class UnitlessQuirk { kAllow, kForbid };
-
-CSSPrimitiveValue* ConsumeInteger(
- CSSParserTokenRange&,
- const CSSParserContext&,
- double minimum_value = -std::numeric_limits<double>::max());
-CSSPrimitiveValue* ConsumeIntegerOrNumberCalc(CSSParserTokenRange&,
- const CSSParserContext&);
-CSSPrimitiveValue* ConsumePositiveInteger(CSSParserTokenRange&,
- const CSSParserContext&);
-bool ConsumeNumberRaw(CSSParserTokenRange&,
- const CSSParserContext& context,
- double& result);
-CSSPrimitiveValue* ConsumeNumber(CSSParserTokenRange&,
- const CSSParserContext&,
- ValueRange);
-CSSPrimitiveValue* ConsumeLength(CSSParserTokenRange&,
- const CSSParserContext&,
- ValueRange,
- UnitlessQuirk = UnitlessQuirk::kForbid);
-CSSPrimitiveValue* ConsumePercent(CSSParserTokenRange&,
- const CSSParserContext&,
- ValueRange);
-CSSPrimitiveValue* ConsumeAlphaValue(CSSParserTokenRange&,
- const CSSParserContext&);
-CSSPrimitiveValue* ConsumeLengthOrPercent(
- CSSParserTokenRange&,
- const CSSParserContext&,
- ValueRange,
- UnitlessQuirk = UnitlessQuirk::kForbid);
-CSSPrimitiveValue* ConsumeSVGGeometryPropertyLength(CSSParserTokenRange&,
- const CSSParserContext&,
- ValueRange);
-
-CSSPrimitiveValue* ConsumeAngle(
- CSSParserTokenRange&,
- const CSSParserContext&,
- base::Optional<WebFeature> unitless_zero_feature);
-CSSPrimitiveValue* ConsumeAngle(
- CSSParserTokenRange&,
- const CSSParserContext&,
- base::Optional<WebFeature> unitless_zero_feature,
- double minimum_value,
- double maximum_value);
-CSSPrimitiveValue* ConsumeTime(CSSParserTokenRange&,
- const CSSParserContext&,
- ValueRange);
-CSSPrimitiveValue* ConsumeResolution(CSSParserTokenRange&);
-
-CSSIdentifierValue* ConsumeIdent(CSSParserTokenRange&);
-CSSIdentifierValue* ConsumeIdentRange(CSSParserTokenRange&,
- CSSValueID lower,
- CSSValueID upper);
-template <CSSValueID, CSSValueID...>
-inline bool IdentMatches(CSSValueID id);
-template <CSSValueID... allowedIdents>
-CSSIdentifierValue* ConsumeIdent(CSSParserTokenRange&);
-
-CSSCustomIdentValue* ConsumeCustomIdent(CSSParserTokenRange&,
- const CSSParserContext&);
-CSSStringValue* ConsumeString(CSSParserTokenRange&);
-StringView ConsumeUrlAsStringView(CSSParserTokenRange&,
- const CSSParserContext&);
-cssvalue::CSSURIValue* ConsumeUrl(CSSParserTokenRange&,
- const CSSParserContext&);
-
-CSSValue* ConsumeColor(CSSParserTokenRange&,
- const CSSParserContext&,
- bool accept_quirky_colors = false);
-
-CSSValue* ConsumeLineWidth(CSSParserTokenRange&,
- const CSSParserContext&,
- UnitlessQuirk);
-
-CSSValuePair* ConsumePosition(CSSParserTokenRange&,
- const CSSParserContext&,
- UnitlessQuirk,
- base::Optional<WebFeature> three_value_position);
-bool ConsumePosition(CSSParserTokenRange&,
- const CSSParserContext&,
- UnitlessQuirk,
- base::Optional<WebFeature> three_value_position,
- CSSValue*& result_x,
- CSSValue*& result_y);
-bool ConsumeOneOrTwoValuedPosition(CSSParserTokenRange&,
- const CSSParserContext&,
- UnitlessQuirk,
- CSSValue*& result_x,
- CSSValue*& result_y);
-bool ConsumeBorderShorthand(CSSParserTokenRange&,
- const CSSParserContext&,
- const CSSValue*& result_width,
- const CSSValue*& result_style,
- const CSSValue*& result_color);
-
-enum class ConsumeGeneratedImagePolicy { kAllow, kForbid };
-
-CSSValue* ConsumeImage(
- CSSParserTokenRange&,
- const CSSParserContext&,
- ConsumeGeneratedImagePolicy = ConsumeGeneratedImagePolicy::kAllow);
-CSSValue* ConsumeImageOrNone(CSSParserTokenRange&, const CSSParserContext&);
-
-CSSValue* ConsumeAxis(CSSParserTokenRange&, const CSSParserContext& context);
-
-// See also css_parsing_utils::IsCSSWideKeyword.
-CORE_EXPORT bool IsCSSWideKeyword(StringView);
-bool IsRevertKeyword(StringView);
-bool IsDefaultKeyword(StringView);
-
-CSSIdentifierValue* ConsumeShapeBox(CSSParserTokenRange&);
-
-enum class IsImplicitProperty { kNotImplicit, kImplicit };
-
-void AddProperty(CSSPropertyID resolved_property,
- CSSPropertyID current_shorthand,
- const CSSValue&,
- bool important,
- IsImplicitProperty,
- HeapVector<CSSPropertyValue, 256>& properties);
-
-void CountKeywordOnlyPropertyUsage(CSSPropertyID,
- const CSSParserContext&,
- CSSValueID);
-
-const CSSValue* ParseLonghand(CSSPropertyID unresolved_property,
- CSSPropertyID current_shorthand,
- const CSSParserContext&,
- CSSParserTokenRange&);
-
-bool ConsumeShorthandVia2Longhands(
- const StylePropertyShorthand&,
- bool important,
- const CSSParserContext&,
- CSSParserTokenRange&,
- HeapVector<CSSPropertyValue, 256>& properties);
-
-bool ConsumeShorthandVia4Longhands(
- const StylePropertyShorthand&,
- bool important,
- const CSSParserContext&,
- CSSParserTokenRange&,
- HeapVector<CSSPropertyValue, 256>& properties);
-
-bool ConsumeShorthandGreedilyViaLonghands(
- const StylePropertyShorthand&,
- bool important,
- const CSSParserContext&,
- CSSParserTokenRange&,
- HeapVector<CSSPropertyValue, 256>& properties);
-
-void AddExpandedPropertyForValue(CSSPropertyID prop_id,
- const CSSValue&,
- bool,
- HeapVector<CSSPropertyValue, 256>& properties);
-
-// Template implementations are at the bottom of the file for readability.
-
-template <typename... emptyBaseCase>
-inline bool IdentMatches(CSSValueID id) {
- return false;
-}
-template <CSSValueID head, CSSValueID... tail>
-inline bool IdentMatches(CSSValueID id) {
- return id == head || IdentMatches<tail...>(id);
-}
-
-template <CSSValueID... names>
-CSSIdentifierValue* ConsumeIdent(CSSParserTokenRange& range) {
- if (range.Peek().GetType() != kIdentToken ||
- !IdentMatches<names...>(range.Peek().Id()))
- return nullptr;
- return CSSIdentifierValue::Create(range.ConsumeIncludingWhitespace().Id());
-}
-
-// ConsumeCommaSeparatedList takes a callback function to call on each item in
-// the list, followed by the arguments to pass to this callback.
-// The first argument to the callback must be the CSSParserTokenRange
-template <typename Func, typename... Args>
-CSSValueList* ConsumeCommaSeparatedList(Func callback,
- CSSParserTokenRange& range,
- Args&&... args) {
- CSSValueList* list = CSSValueList::CreateCommaSeparated();
- do {
- CSSValue* value = callback(range, std::forward<Args>(args)...);
- if (!value)
- return nullptr;
- list->Append(*value);
- } while (ConsumeCommaIncludingWhitespace(range));
- DCHECK(list->length());
- return list;
-}
-
-CSSValue* ConsumeTransformValue(CSSParserTokenRange&, const CSSParserContext&);
-CSSValue* ConsumeTransformList(CSSParserTokenRange&, const CSSParserContext&);
-CSSValue* ConsumeFilterFunctionList(CSSParserTokenRange&,
- const CSSParserContext&);
-
-} // namespace css_property_parser_helpers
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_PROPERTY_PARSER_HELPERS_H_
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_property_parser_helpers_test.cc b/chromium/third_party/blink/renderer/core/css/parser/css_property_parser_helpers_test.cc
deleted file mode 100644
index 2eb068af368..00000000000
--- a/chromium/third_party/blink/renderer/core/css/parser/css_property_parser_helpers_test.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-TEST(CSSPropertyParserHelpersTest, ParseRevert) {
- {
- ScopedCSSRevertForTest scoped_revert(true);
- EXPECT_TRUE(css_property_parser_helpers::IsCSSWideKeyword("revert"));
- }
-
- {
- ScopedCSSRevertForTest scoped_revert(false);
- EXPECT_FALSE(css_property_parser_helpers::IsCSSWideKeyword("revert"));
- }
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_proto_converter.cc b/chromium/third_party/blink/renderer/core/css/parser/css_proto_converter.cc
index 50fa91463a0..c03d5015b4e 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_proto_converter.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_proto_converter.cc
@@ -1517,6 +1517,8 @@ const std::string Converter::kPropertyLookupTable[] = {
"overscroll-behavior-block",
"overscroll-behavior-x",
"overscroll-behavior-y",
+ "animation-timeline",
+ "counter-set",
"INVALID_PROPERTY",
};
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_selector_parser.cc b/chromium/third_party/blink/renderer/core/css/parser/css_selector_parser.cc
index 4831273c13a..c3f74e7d1fc 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_selector_parser.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_selector_parser.cc
@@ -286,7 +286,8 @@ bool IsSimpleSelectorValidAfterPseudoElement(
return true;
case CSSSelector::kPseudoAfter:
case CSSSelector::kPseudoBefore:
- if (simple_selector.GetPseudoType() == CSSSelector::kPseudoMarker)
+ if (simple_selector.GetPseudoType() == CSSSelector::kPseudoMarker &&
+ RuntimeEnabledFeatures::CSSMarkerNestedPseudoElementEnabled())
return true;
break;
case CSSSelector::kPseudoContent:
@@ -553,9 +554,11 @@ std::unique_ptr<CSSParserSelector> CSSSelectorParser::ConsumePseudo(
context_->Count(WebFeature::kHasBeforeOrAfterPseudoElement);
break;
case CSSSelector::kPseudoMarker:
- context_->Count(WebFeature::kHasMarkerPseudoElement);
- if (!RuntimeEnabledFeatures::CSSMarkerPseudoElementEnabled())
- return nullptr;
+ if (context_->Mode() != kUASheetMode) {
+ context_->Count(WebFeature::kHasMarkerPseudoElement);
+ if (!RuntimeEnabledFeatures::CSSMarkerPseudoElementEnabled())
+ return nullptr;
+ }
break;
default:;
}
diff --git a/chromium/third_party/blink/renderer/core/css/parser/font_variant_east_asian_parser.h b/chromium/third_party/blink/renderer/core/css/parser/font_variant_east_asian_parser.h
index d8f4be1589d..ad052d3e691 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/font_variant_east_asian_parser.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/font_variant_east_asian_parser.h
@@ -7,7 +7,7 @@
#include "third_party/blink/renderer/core/css/css_value_list.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h"
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
namespace blink {
@@ -33,20 +33,18 @@ class FontVariantEastAsianParser {
case CSSValueID::kTraditional:
if (east_asian_form_value_)
return ParseResult::kDisallowedValue;
- east_asian_form_value_ =
- css_property_parser_helpers::ConsumeIdent(range);
+ east_asian_form_value_ = css_parsing_utils::ConsumeIdent(range);
return ParseResult::kConsumedValue;
case CSSValueID::kFullWidth:
case CSSValueID::kProportionalWidth:
if (east_asian_width_value_)
return ParseResult::kDisallowedValue;
- east_asian_width_value_ =
- css_property_parser_helpers::ConsumeIdent(range);
+ east_asian_width_value_ = css_parsing_utils::ConsumeIdent(range);
return ParseResult::kConsumedValue;
case CSSValueID::kRuby:
if (ruby_value_)
return ParseResult::kDisallowedValue;
- ruby_value_ = css_property_parser_helpers::ConsumeIdent(range);
+ ruby_value_ = css_parsing_utils::ConsumeIdent(range);
return ParseResult::kConsumedValue;
default:
return ParseResult::kUnknownValue;
diff --git a/chromium/third_party/blink/renderer/core/css/parser/font_variant_ligatures_parser.h b/chromium/third_party/blink/renderer/core/css/parser/font_variant_ligatures_parser.h
index 9da89771349..255833f9284 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/font_variant_ligatures_parser.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/font_variant_ligatures_parser.h
@@ -8,7 +8,7 @@
#include "third_party/blink/renderer/core/css/css_identifier_value.h"
#include "third_party/blink/renderer/core/css/css_value_list.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h"
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
namespace blink {
@@ -55,7 +55,7 @@ class FontVariantLigaturesParser {
default:
return ParseResult::kUnknownValue;
}
- result_->Append(*css_property_parser_helpers::ConsumeIdent(range));
+ result_->Append(*css_parsing_utils::ConsumeIdent(range));
return ParseResult::kConsumedValue;
}
diff --git a/chromium/third_party/blink/renderer/core/css/parser/font_variant_numeric_parser.h b/chromium/third_party/blink/renderer/core/css/parser/font_variant_numeric_parser.h
index f34b7ae000f..c6df51ab4bf 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/font_variant_numeric_parser.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/font_variant_numeric_parser.h
@@ -7,7 +7,7 @@
#include "third_party/blink/renderer/core/css/css_value_list.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h"
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
namespace blink {
@@ -26,29 +26,29 @@ class FontVariantNumericParser {
case CSSValueID::kOldstyleNums:
if (numeric_figure_)
return ParseResult::kDisallowedValue;
- numeric_figure_ = css_property_parser_helpers::ConsumeIdent(range);
+ numeric_figure_ = css_parsing_utils::ConsumeIdent(range);
return ParseResult::kConsumedValue;
case CSSValueID::kProportionalNums:
case CSSValueID::kTabularNums:
if (numeric_spacing_)
return ParseResult::kDisallowedValue;
- numeric_spacing_ = css_property_parser_helpers::ConsumeIdent(range);
+ numeric_spacing_ = css_parsing_utils::ConsumeIdent(range);
return ParseResult::kConsumedValue;
case CSSValueID::kDiagonalFractions:
case CSSValueID::kStackedFractions:
if (numeric_fraction_)
return ParseResult::kDisallowedValue;
- numeric_fraction_ = css_property_parser_helpers::ConsumeIdent(range);
+ numeric_fraction_ = css_parsing_utils::ConsumeIdent(range);
return ParseResult::kConsumedValue;
case CSSValueID::kOrdinal:
if (ordinal_)
return ParseResult::kDisallowedValue;
- ordinal_ = css_property_parser_helpers::ConsumeIdent(range);
+ ordinal_ = css_parsing_utils::ConsumeIdent(range);
return ParseResult::kConsumedValue;
case CSSValueID::kSlashedZero:
if (slashed_zero_)
return ParseResult::kDisallowedValue;
- slashed_zero_ = css_property_parser_helpers::ConsumeIdent(range);
+ slashed_zero_ = css_parsing_utils::ConsumeIdent(range);
return ParseResult::kConsumedValue;
default:
return ParseResult::kUnknownValue;
diff --git a/chromium/third_party/blink/renderer/core/css/properties/computed_style_utils.cc b/chromium/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
index 1346dd54d89..bfdcc9ca87b 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
@@ -1323,24 +1323,29 @@ void PopulateGridTrackList(CSSValueList* list,
OrderedNamedLinesCollector& collector,
const Vector<T>& tracks,
F getTrackSize,
- wtf_size_t start,
- wtf_size_t end,
- size_t offset = 0) {
- DCHECK_LE(end, tracks.size());
- for (wtf_size_t i = start; i < end; ++i) {
- AddValuesForNamedGridLinesAtIndex(collector, i + offset, *list);
+ int start,
+ int end,
+ int offset = 0) {
+ DCHECK_LE(0, start);
+ DCHECK_LE(start, end);
+ DCHECK_LE((unsigned)end, tracks.size());
+ for (int i = start; i < end; ++i) {
+ if (i + offset >= 0)
+ AddValuesForNamedGridLinesAtIndex(collector, i + offset, *list);
list->Append(*getTrackSize(tracks[i]));
}
- AddValuesForNamedGridLinesAtIndex(collector, end + offset, *list);
+ if (end + offset >= 0)
+ AddValuesForNamedGridLinesAtIndex(collector, end + offset, *list);
}
template <typename T, typename F>
void PopulateGridTrackList(CSSValueList* list,
OrderedNamedLinesCollector& collector,
const Vector<T>& tracks,
- F getTrackSize) {
+ F getTrackSize,
+ int offset = 0) {
PopulateGridTrackList<T>(list, collector, tracks, getTrackSize, 0,
- tracks.size());
+ tracks.size(), offset);
}
CSSValue* ComputedStyleUtils::ValueForGridTrackList(
@@ -1378,9 +1383,14 @@ CSSValue* ComputedStyleUtils::ValueForGridTrackList(
OrderedNamedLinesCollectorInGridLayout collector(
style, is_row_axis, grid->AutoRepeatCountForDirection(direction),
auto_repeat_track_sizes.size());
+ // Named grid line indices are relative to the explicit grid, but we are
+ // including all tracks. So we need to subtract the number of leading
+ // implicit tracks in order to get the proper line index.
+ int offset = -grid->ExplicitGridStartForDirection(direction);
PopulateGridTrackList(
list, collector, grid->TrackSizesForComputedStyle(direction),
- [&](const LayoutUnit& v) { return ZoomAdjustedPixelValue(v, style); });
+ [&](const LayoutUnit& v) { return ZoomAdjustedPixelValue(v, style); },
+ offset);
return list;
}
@@ -2075,21 +2085,42 @@ CSSValue* ComputedStyleUtils::ValueForContentData(const ComputedStyle& style,
CSSValue* ComputedStyleUtils::ValueForCounterDirectives(
const ComputedStyle& style,
- bool is_increment) {
+ CounterNode::Type type) {
const CounterDirectiveMap* map = style.GetCounterDirectives();
if (!map)
return CSSIdentifierValue::Create(CSSValueID::kNone);
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
for (const auto& item : *map) {
- bool is_valid_counter_value =
- is_increment ? item.value.IsIncrement() : item.value.IsReset();
+ bool is_valid_counter_value = false;
+ switch (type) {
+ case CounterNode::kIncrementType:
+ is_valid_counter_value = item.value.IsIncrement();
+ break;
+ case CounterNode::kResetType:
+ is_valid_counter_value = item.value.IsReset();
+ break;
+ case CounterNode::kSetType:
+ is_valid_counter_value = item.value.IsSet();
+ break;
+ }
+
if (!is_valid_counter_value)
continue;
list->Append(*MakeGarbageCollected<CSSCustomIdentValue>(item.key));
- int32_t number =
- is_increment ? item.value.IncrementValue() : item.value.ResetValue();
+ int32_t number = 0;
+ switch (type) {
+ case CounterNode::kIncrementType:
+ number = item.value.IncrementValue();
+ break;
+ case CounterNode::kResetType:
+ number = item.value.ResetValue();
+ break;
+ case CounterNode::kSetType:
+ number = item.value.SetValue();
+ break;
+ }
list->Append(*CSSNumericLiteralValue::Create(
(double)number, CSSPrimitiveValue::UnitType::kInteger));
}
@@ -2705,11 +2736,25 @@ CSSValue* ComputedStyleUtils::ScrollCustomizationFlagsToCSSValue(
return list;
}
-CSSValue* ComputedStyleUtils::ValueForGapLength(const GapLength& gap_length,
- const ComputedStyle& style) {
- if (gap_length.IsNormal())
+CSSValue* ComputedStyleUtils::ValueForGapLength(
+ const base::Optional<Length>& gap_length,
+ const ComputedStyle& style) {
+ if (!gap_length)
return CSSIdentifierValue::Create(CSSValueID::kNormal);
- return ZoomAdjustedPixelValueForLength(gap_length.GetLength(), style);
+ return ZoomAdjustedPixelValueForLength(*gap_length, style);
+}
+
+CSSValue* ComputedStyleUtils::ValueForStyleName(const StyleName& name) {
+ if (name.IsCustomIdent())
+ return MakeGarbageCollected<CSSCustomIdentValue>(name.GetValue());
+ return MakeGarbageCollected<CSSStringValue>(name.GetValue());
+}
+
+CSSValue* ComputedStyleUtils::ValueForStyleNameOrKeyword(
+ const StyleNameOrKeyword& value) {
+ if (value.IsKeyword())
+ return CSSIdentifierValue::Create(value.GetKeyword());
+ return ValueForStyleName(value.GetName());
}
std::unique_ptr<CrossThreadStyleValue>
diff --git a/chromium/third_party/blink/renderer/core/css/properties/computed_style_utils.h b/chromium/third_party/blink/renderer/core/css/properties/computed_style_utils.h
index 790aaf35b3b..232dc0b664f 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/computed_style_utils.h
+++ b/chromium/third_party/blink/renderer/core/css/properties/computed_style_utils.h
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/core/css/css_value_list.h"
#include "third_party/blink/renderer/core/css/css_value_pair.h"
#include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h"
+#include "third_party/blink/renderer/core/layout/counter_node.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -181,8 +182,9 @@ class CORE_EXPORT ComputedStyleUtils {
static CSSValue* ValueForTransitionProperty(const CSSTransitionData*);
static CSSValue* ValueForContentData(const ComputedStyle&,
bool allow_visited_style);
+
static CSSValue* ValueForCounterDirectives(const ComputedStyle&,
- bool is_increment);
+ CounterNode::Type type);
static CSSValue* ValueForShape(const ComputedStyle&,
bool allow_visited_style,
ShapeValue*);
@@ -238,7 +240,10 @@ class CORE_EXPORT ComputedStyleUtils {
bool allow_visited_style);
static CSSValue* ScrollCustomizationFlagsToCSSValue(
scroll_customization::ScrollDirection);
- static CSSValue* ValueForGapLength(const GapLength&, const ComputedStyle&);
+ static CSSValue* ValueForGapLength(const base::Optional<Length>&,
+ const ComputedStyle&);
+ static CSSValue* ValueForStyleName(const StyleName&);
+ static CSSValue* ValueForStyleNameOrKeyword(const StyleNameOrKeyword&);
static std::unique_ptr<CrossThreadStyleValue>
CrossThreadStyleValueFromCSSStyleValue(CSSStyleValue* style_value);
diff --git a/chromium/third_party/blink/renderer/core/css/properties/computed_style_utils_test.cc b/chromium/third_party/blink/renderer/core/css/properties/computed_style_utils_test.cc
index ff1582a6cbb..35490862fa3 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/computed_style_utils_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/computed_style_utils_test.cc
@@ -4,6 +4,11 @@
#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/css/css_custom_ident_value.h"
+#include "third_party/blink/renderer/core/css/css_identifier_value.h"
+#include "third_party/blink/renderer/core/css/css_string_value.h"
+#include "third_party/blink/renderer/core/style/style_name.h"
+#include "third_party/blink/renderer/core/style/style_name_or_keyword.h"
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
namespace blink {
@@ -41,4 +46,25 @@ TEST(ComputedStyleUtilsTest, MatrixZoom3D) {
"matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)");
}
+TEST(ComputedStyleUtilsTest, ValueForStyleName) {
+ EXPECT_EQ(*ComputedStyleUtils::ValueForStyleName(
+ StyleName("foo", StyleName::Type::kCustomIdent)),
+ *MakeGarbageCollected<CSSCustomIdentValue>("foo"));
+ EXPECT_EQ(*ComputedStyleUtils::ValueForStyleName(
+ StyleName("foo", StyleName::Type::kString)),
+ *MakeGarbageCollected<CSSStringValue>("foo"));
+}
+
+TEST(ComputedStyleUtilsTest, ValueForStyleNameOrKeyword) {
+ EXPECT_EQ(*ComputedStyleUtils::ValueForStyleNameOrKeyword(StyleNameOrKeyword(
+ StyleName("foo", StyleName::Type::kCustomIdent))),
+ *MakeGarbageCollected<CSSCustomIdentValue>("foo"));
+ EXPECT_EQ(*ComputedStyleUtils::ValueForStyleNameOrKeyword(
+ StyleNameOrKeyword(StyleName("foo", StyleName::Type::kString))),
+ *MakeGarbageCollected<CSSStringValue>("foo"));
+ EXPECT_EQ(*ComputedStyleUtils::ValueForStyleNameOrKeyword(
+ StyleNameOrKeyword(CSSValueID::kNone)),
+ *MakeGarbageCollected<CSSIdentifierValue>(CSSValueID::kNone));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
index c2e3c3a4d82..bb2d0b7bb5a 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -7,43 +7,59 @@
#include <memory>
#include <utility>
+#include "third_party/blink/renderer/core/css/css_axis_value.h"
#include "third_party/blink/renderer/core/css/css_basic_shape_values.h"
#include "third_party/blink/renderer/core/css/css_border_image.h"
+#include "third_party/blink/renderer/core/css/css_color_value.h"
#include "third_party/blink/renderer/core/css/css_content_distribution_value.h"
+#include "third_party/blink/renderer/core/css/css_crossfade_value.h"
#include "third_party/blink/renderer/core/css/css_custom_ident_value.h"
#include "third_party/blink/renderer/core/css/css_font_family_value.h"
#include "third_party/blink/renderer/core/css/css_font_feature_value.h"
#include "third_party/blink/renderer/core/css/css_font_style_range_value.h"
#include "third_party/blink/renderer/core/css/css_function_value.h"
+#include "third_party/blink/renderer/core/css/css_gradient_value.h"
#include "third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h"
#include "third_party/blink/renderer/core/css/css_grid_integer_repeat_value.h"
#include "third_party/blink/renderer/core/css/css_grid_line_names_value.h"
#include "third_party/blink/renderer/core/css/css_grid_template_areas_value.h"
+#include "third_party/blink/renderer/core/css/css_id_selector_value.h"
#include "third_party/blink/renderer/core/css/css_identifier_value.h"
+#include "third_party/blink/renderer/core/css/css_image_set_value.h"
+#include "third_party/blink/renderer/core/css/css_image_value.h"
#include "third_party/blink/renderer/core/css/css_initial_value.h"
+#include "third_party/blink/renderer/core/css/css_light_dark_value_pair.h"
+#include "third_party/blink/renderer/core/css/css_math_expression_node.h"
#include "third_party/blink/renderer/core/css/css_math_function_value.h"
#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
+#include "third_party/blink/renderer/core/css/css_paint_value.h"
#include "third_party/blink/renderer/core/css/css_path_value.h"
#include "third_party/blink/renderer/core/css/css_primitive_value.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
+#include "third_party/blink/renderer/core/css/css_property_value.h"
#include "third_party/blink/renderer/core/css/css_ray_value.h"
#include "third_party/blink/renderer/core/css/css_shadow_value.h"
+#include "third_party/blink/renderer/core/css/css_string_value.h"
#include "third_party/blink/renderer/core/css/css_timing_function_value.h"
#include "third_party/blink/renderer/core/css/css_uri_value.h"
#include "third_party/blink/renderer/core/css/css_value.h"
#include "third_party/blink/renderer/core/css/css_value_list.h"
#include "third_party/blink/renderer/core/css/css_value_pair.h"
+#include "third_party/blink/renderer/core/css/css_variable_data.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
+#include "third_party/blink/renderer/core/css/parser/css_parser_fast_paths.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_idioms.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_local_context.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_token.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h"
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
#include "third_party/blink/renderer/core/css/properties/css_property.h"
#include "third_party/blink/renderer/core/css/properties/longhand.h"
+#include "third_party/blink/renderer/core/css/style_color.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
#include "third_party/blink/renderer/core/svg/svg_parsing_error.h"
#include "third_party/blink/renderer/core/svg/svg_path_utilities.h"
@@ -64,34 +80,28 @@ namespace css_parsing_utils {
namespace {
bool IsLeftOrRightKeyword(CSSValueID id) {
- return css_property_parser_helpers::IdentMatches<CSSValueID::kLeft,
- CSSValueID::kRight>(id);
+ return IdentMatches<CSSValueID::kLeft, CSSValueID::kRight>(id);
}
bool IsAuto(CSSValueID id) {
- return css_property_parser_helpers::IdentMatches<CSSValueID::kAuto>(id);
+ return IdentMatches<CSSValueID::kAuto>(id);
}
bool IsNormalOrStretch(CSSValueID id) {
- return css_property_parser_helpers::IdentMatches<CSSValueID::kNormal,
- CSSValueID::kStretch>(id);
+ return IdentMatches<CSSValueID::kNormal, CSSValueID::kStretch>(id);
}
bool IsContentDistributionKeyword(CSSValueID id) {
- return css_property_parser_helpers::IdentMatches<
- CSSValueID::kSpaceBetween, CSSValueID::kSpaceAround,
- CSSValueID::kSpaceEvenly, CSSValueID::kStretch>(id);
+ return IdentMatches<CSSValueID::kSpaceBetween, CSSValueID::kSpaceAround,
+ CSSValueID::kSpaceEvenly, CSSValueID::kStretch>(id);
}
bool IsOverflowKeyword(CSSValueID id) {
- return css_property_parser_helpers::IdentMatches<CSSValueID::kUnsafe,
- CSSValueID::kSafe>(id);
+ return IdentMatches<CSSValueID::kUnsafe, CSSValueID::kSafe>(id);
}
CSSIdentifierValue* ConsumeOverflowPositionKeyword(CSSParserTokenRange& range) {
- return IsOverflowKeyword(range.Peek().Id())
- ? css_property_parser_helpers::ConsumeIdent(range)
- : nullptr;
+ return IsOverflowKeyword(range.Peek().Id()) ? ConsumeIdent(range) : nullptr;
}
CSSValueID GetBaselineKeyword(CSSValue& value) {
@@ -110,10 +120,8 @@ CSSValueID GetBaselineKeyword(CSSValue& value) {
CSSValue* ConsumeBaselineKeyword(CSSParserTokenRange& range) {
CSSIdentifierValue* preference =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kFirst,
- CSSValueID::kLast>(range);
- CSSIdentifierValue* baseline =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kBaseline>(range);
+ ConsumeIdent<CSSValueID::kFirst, CSSValueID::kLast>(range);
+ CSSIdentifierValue* baseline = ConsumeIdent<CSSValueID::kBaseline>(range);
if (!baseline)
return nullptr;
if (preference && preference->GetValueID() == CSSValueID::kLast) {
@@ -127,17 +135,15 @@ CSSValue* ConsumeSteps(CSSParserTokenRange& range,
const CSSParserContext& context) {
DCHECK_EQ(range.Peek().FunctionId(), CSSValueID::kSteps);
CSSParserTokenRange range_copy = range;
- CSSParserTokenRange args =
- css_property_parser_helpers::ConsumeFunction(range_copy);
+ CSSParserTokenRange args = ConsumeFunction(range_copy);
- CSSPrimitiveValue* steps =
- css_property_parser_helpers::ConsumePositiveInteger(args, context);
+ CSSPrimitiveValue* steps = ConsumePositiveInteger(args, context);
if (!steps)
return nullptr;
StepsTimingFunction::StepPosition position =
StepsTimingFunction::StepPosition::END;
- if (css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args)) {
+ if (ConsumeCommaIncludingWhitespace(args)) {
switch (args.ConsumeIncludingWhitespace().Id()) {
case CSSValueID::kStart:
position = StepsTimingFunction::StepPosition::START;
@@ -186,20 +192,16 @@ CSSValue* ConsumeCubicBezier(CSSParserTokenRange& range,
const CSSParserContext& context) {
DCHECK_EQ(range.Peek().FunctionId(), CSSValueID::kCubicBezier);
CSSParserTokenRange range_copy = range;
- CSSParserTokenRange args =
- css_property_parser_helpers::ConsumeFunction(range_copy);
+ CSSParserTokenRange args = ConsumeFunction(range_copy);
double x1, y1, x2, y2;
- if (css_property_parser_helpers::ConsumeNumberRaw(args, context, x1) &&
- x1 >= 0 && x1 <= 1 &&
- css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args) &&
- css_property_parser_helpers::ConsumeNumberRaw(args, context, y1) &&
- css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args) &&
- css_property_parser_helpers::ConsumeNumberRaw(args, context, x2) &&
- x2 >= 0 && x2 <= 1 &&
- css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args) &&
- css_property_parser_helpers::ConsumeNumberRaw(args, context, y2) &&
- args.AtEnd()) {
+ if (ConsumeNumberRaw(args, context, x1) && x1 >= 0 && x1 <= 1 &&
+ ConsumeCommaIncludingWhitespace(args) &&
+ ConsumeNumberRaw(args, context, y1) &&
+ ConsumeCommaIncludingWhitespace(args) &&
+ ConsumeNumberRaw(args, context, x2) && x2 >= 0 && x2 <= 1 &&
+ ConsumeCommaIncludingWhitespace(args) &&
+ ConsumeNumberRaw(args, context, y2) && args.AtEnd()) {
range = range_copy;
return MakeGarbageCollected<cssvalue::CSSCubicBezierTimingFunctionValue>(
x1, y1, x2, y2);
@@ -210,14 +212,12 @@ CSSValue* ConsumeCubicBezier(CSSParserTokenRange& range,
CSSIdentifierValue* ConsumeBorderImageRepeatKeyword(
CSSParserTokenRange& range) {
- return css_property_parser_helpers::ConsumeIdent<
- CSSValueID::kStretch, CSSValueID::kRepeat, CSSValueID::kSpace,
- CSSValueID::kRound>(range);
+ return ConsumeIdent<CSSValueID::kStretch, CSSValueID::kRepeat,
+ CSSValueID::kSpace, CSSValueID::kRound>(range);
}
bool ConsumeCSSValueId(CSSParserTokenRange& range, CSSValueID& value) {
- CSSIdentifierValue* keyword =
- css_property_parser_helpers::ConsumeIdent(range);
+ CSSIdentifierValue* keyword = ConsumeIdent(range);
if (!keyword || !range.AtEnd())
return false;
value = keyword->GetValueID();
@@ -226,12 +226,10 @@ bool ConsumeCSSValueId(CSSParserTokenRange& range, CSSValueID& value) {
CSSValue* ConsumeShapeRadius(CSSParserTokenRange& args,
const CSSParserContext& context) {
- if (css_property_parser_helpers::IdentMatches<CSSValueID::kClosestSide,
- CSSValueID::kFarthestSide>(
+ if (IdentMatches<CSSValueID::kClosestSide, CSSValueID::kFarthestSide>(
args.Peek().Id()))
- return css_property_parser_helpers::ConsumeIdent(args);
- return css_property_parser_helpers::ConsumeLengthOrPercent(
- args, context, kValueRangeNonNegative);
+ return ConsumeIdent(args);
+ return ConsumeLengthOrPercent(args, context, kValueRangeNonNegative);
}
cssvalue::CSSBasicShapeCircleValue* ConsumeBasicShapeCircle(
@@ -242,11 +240,10 @@ cssvalue::CSSBasicShapeCircleValue* ConsumeBasicShapeCircle(
auto* shape = MakeGarbageCollected<cssvalue::CSSBasicShapeCircleValue>();
if (CSSValue* radius = ConsumeShapeRadius(args, context))
shape->SetRadius(radius);
- if (css_property_parser_helpers::ConsumeIdent<CSSValueID::kAt>(args)) {
+ if (ConsumeIdent<CSSValueID::kAt>(args)) {
CSSValue* center_x = nullptr;
CSSValue* center_y = nullptr;
- if (!ConsumePosition(args, context,
- css_property_parser_helpers::UnitlessQuirk::kForbid,
+ if (!ConsumePosition(args, context, UnitlessQuirk::kForbid,
base::Optional<WebFeature>(), center_x, center_y))
return nullptr;
shape->SetCenterX(center_x);
@@ -264,18 +261,16 @@ cssvalue::CSSBasicShapeEllipseValue* ConsumeBasicShapeEllipse(
WebFeature feature = WebFeature::kBasicShapeEllipseNoRadius;
if (CSSValue* radius_x = ConsumeShapeRadius(args, context)) {
CSSValue* radius_y = ConsumeShapeRadius(args, context);
- if (!radius_y) {
+ if (!radius_y)
return nullptr;
- }
shape->SetRadiusX(radius_x);
shape->SetRadiusY(radius_y);
feature = WebFeature::kBasicShapeEllipseTwoRadius;
}
- if (css_property_parser_helpers::ConsumeIdent<CSSValueID::kAt>(args)) {
+ if (ConsumeIdent<CSSValueID::kAt>(args)) {
CSSValue* center_x = nullptr;
CSSValue* center_y = nullptr;
- if (!ConsumePosition(args, context,
- css_property_parser_helpers::UnitlessQuirk::kForbid,
+ if (!ConsumePosition(args, context, UnitlessQuirk::kForbid,
base::Optional<WebFeature>(), center_x, center_y))
return nullptr;
shape->SetCenterX(center_x);
@@ -289,30 +284,27 @@ cssvalue::CSSBasicShapePolygonValue* ConsumeBasicShapePolygon(
CSSParserTokenRange& args,
const CSSParserContext& context) {
auto* shape = MakeGarbageCollected<cssvalue::CSSBasicShapePolygonValue>();
- if (css_property_parser_helpers::IdentMatches<CSSValueID::kEvenodd,
- CSSValueID::kNonzero>(
+ if (IdentMatches<CSSValueID::kEvenodd, CSSValueID::kNonzero>(
args.Peek().Id())) {
shape->SetWindRule(args.ConsumeIncludingWhitespace().Id() ==
CSSValueID::kEvenodd
? RULE_EVENODD
: RULE_NONZERO);
- if (!css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args))
+ if (!ConsumeCommaIncludingWhitespace(args))
return nullptr;
}
do {
CSSPrimitiveValue* x_length =
- css_property_parser_helpers::ConsumeLengthOrPercent(args, context,
- kValueRangeAll);
+ ConsumeLengthOrPercent(args, context, kValueRangeAll);
if (!x_length)
return nullptr;
CSSPrimitiveValue* y_length =
- css_property_parser_helpers::ConsumeLengthOrPercent(args, context,
- kValueRangeAll);
+ ConsumeLengthOrPercent(args, context, kValueRangeAll);
if (!y_length)
return nullptr;
shape->AppendPoint(x_length, y_length);
- } while (css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args));
+ } while (ConsumeCommaIncludingWhitespace(args));
return shape;
}
@@ -320,22 +312,18 @@ cssvalue::CSSBasicShapeInsetValue* ConsumeBasicShapeInset(
CSSParserTokenRange& args,
const CSSParserContext& context) {
auto* shape = MakeGarbageCollected<cssvalue::CSSBasicShapeInsetValue>();
- CSSPrimitiveValue* top = css_property_parser_helpers::ConsumeLengthOrPercent(
- args, context, kValueRangeAll);
+ CSSPrimitiveValue* top =
+ ConsumeLengthOrPercent(args, context, kValueRangeAll);
if (!top)
return nullptr;
CSSPrimitiveValue* right =
- css_property_parser_helpers::ConsumeLengthOrPercent(args, context,
- kValueRangeAll);
+ ConsumeLengthOrPercent(args, context, kValueRangeAll);
CSSPrimitiveValue* bottom = nullptr;
CSSPrimitiveValue* left = nullptr;
if (right) {
- bottom = css_property_parser_helpers::ConsumeLengthOrPercent(
- args, context, kValueRangeAll);
- if (bottom) {
- left = css_property_parser_helpers::ConsumeLengthOrPercent(
- args, context, kValueRangeAll);
- }
+ bottom = ConsumeLengthOrPercent(args, context, kValueRangeAll);
+ if (bottom)
+ left = ConsumeLengthOrPercent(args, context, kValueRangeAll);
}
if (left)
shape->UpdateShapeSize4Values(top, right, bottom, left);
@@ -346,7 +334,7 @@ cssvalue::CSSBasicShapeInsetValue* ConsumeBasicShapeInset(
else
shape->UpdateShapeSize1Value(top);
- if (css_property_parser_helpers::ConsumeIdent<CSSValueID::kRound>(args)) {
+ if (ConsumeIdent<CSSValueID::kRound>(args)) {
CSSValue* horizontal_radii[4] = {nullptr};
CSSValue* vertical_radii[4] = {nullptr};
if (!ConsumeRadii(horizontal_radii, vertical_radii, args, context, false))
@@ -372,15 +360,12 @@ bool ConsumeNumbers(CSSParserTokenRange& args,
CSSFunctionValue*& transform_value,
unsigned number_of_arguments) {
do {
- CSSValue* parsed_value = css_property_parser_helpers::ConsumeNumber(
- args, context, kValueRangeAll);
+ CSSValue* parsed_value = ConsumeNumber(args, context, kValueRangeAll);
if (!parsed_value)
return false;
transform_value->Append(*parsed_value);
- if (--number_of_arguments &&
- !css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args)) {
+ if (--number_of_arguments && !ConsumeCommaIncludingWhitespace(args))
return false;
- }
} while (number_of_arguments);
return true;
}
@@ -389,15 +374,12 @@ bool ConsumePerspective(CSSParserTokenRange& args,
const CSSParserContext& context,
CSSFunctionValue*& transform_value,
bool use_legacy_parsing) {
- CSSPrimitiveValue* parsed_value = css_property_parser_helpers::ConsumeLength(
- args, context, kValueRangeNonNegative);
+ CSSPrimitiveValue* parsed_value =
+ ConsumeLength(args, context, kValueRangeNonNegative);
if (!parsed_value && use_legacy_parsing) {
double perspective;
- if (!css_property_parser_helpers::ConsumeNumberRaw(args, context,
- perspective) ||
- perspective < 0) {
+ if (!ConsumeNumberRaw(args, context, perspective) || perspective < 0)
return false;
- }
context.Count(WebFeature::kUnitlessPerspectiveInTransformProperty);
parsed_value = CSSNumericLiteralValue::Create(
perspective, CSSPrimitiveValue::UnitType::kPixels);
@@ -414,34 +396,2175 @@ bool ConsumeTranslate3d(CSSParserTokenRange& args,
unsigned number_of_arguments = 2;
CSSValue* parsed_value = nullptr;
do {
- parsed_value = css_property_parser_helpers::ConsumeLengthOrPercent(
- args, context, kValueRangeAll);
+ parsed_value = ConsumeLengthOrPercent(args, context, kValueRangeAll);
if (!parsed_value)
return false;
transform_value->Append(*parsed_value);
- if (!css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args))
+ if (!ConsumeCommaIncludingWhitespace(args))
return false;
} while (--number_of_arguments);
- parsed_value =
- css_property_parser_helpers::ConsumeLength(args, context, kValueRangeAll);
+ parsed_value = ConsumeLength(args, context, kValueRangeAll);
if (!parsed_value)
return false;
transform_value->Append(*parsed_value);
return true;
}
+// Add CSSVariableData to variableData vector.
+bool AddCSSPaintArgument(
+ const Vector<CSSParserToken>& tokens,
+ Vector<scoped_refptr<CSSVariableData>>* const variable_data,
+ const CSSParserContext& context) {
+ CSSParserTokenRange token_range(tokens);
+ if (!token_range.AtEnd()) {
+ scoped_refptr<CSSVariableData> unparsed_css_variable_data =
+ CSSVariableData::Create(token_range, false, false, context.BaseURL(),
+ context.Charset());
+ if (unparsed_css_variable_data.get()) {
+ variable_data->push_back(std::move(unparsed_css_variable_data));
+ return true;
+ }
+ }
+ return false;
+}
+
+// Consume input arguments, if encounter function, will return the function
+// block as a Vector of CSSParserToken, otherwise, will just return a Vector of
+// a single CSSParserToken.
+Vector<CSSParserToken> ConsumeFunctionArgsOrNot(CSSParserTokenRange& args) {
+ Vector<CSSParserToken> argument_tokens;
+ if (args.Peek().GetBlockType() == CSSParserToken::kBlockStart) {
+ // Function block.
+ // Push the function name and initial right parenthesis.
+ // Since we don't have any upfront knowledge about the input argument types
+ // here, we should just leave the token as it is and resolve it later in
+ // the variable parsing phase.
+ argument_tokens.push_back(args.Peek());
+ CSSParserTokenRange contents = args.ConsumeBlock();
+ while (!contents.AtEnd())
+ argument_tokens.push_back(contents.Consume());
+ argument_tokens.push_back(
+ CSSParserToken(kRightParenthesisToken, CSSParserToken::kBlockEnd));
+
+ } else {
+ argument_tokens.push_back(args.ConsumeIncludingWhitespace());
+ }
+ return argument_tokens;
+}
+
+CSSFunctionValue* ConsumeFilterFunction(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ CSSValueID filter_type = range.Peek().FunctionId();
+ if (filter_type < CSSValueID::kInvert ||
+ filter_type > CSSValueID::kDropShadow)
+ return nullptr;
+ CSSParserTokenRange args = ConsumeFunction(range);
+ CSSFunctionValue* filter_value =
+ MakeGarbageCollected<CSSFunctionValue>(filter_type);
+ CSSValue* parsed_value = nullptr;
+
+ if (filter_type == CSSValueID::kDropShadow) {
+ parsed_value =
+ ParseSingleShadow(args, context, AllowInsetAndSpread::kForbid);
+ } else {
+ if (args.AtEnd()) {
+ context.Count(WebFeature::kCSSFilterFunctionNoArguments);
+ return filter_value;
+ }
+ if (filter_type == CSSValueID::kBrightness) {
+ // FIXME (crbug.com/397061): Support calc expressions like calc(10% + 0.5)
+ parsed_value = ConsumePercent(args, context, kValueRangeAll);
+ if (!parsed_value)
+ parsed_value = ConsumeNumber(args, context, kValueRangeNonNegative);
+ } else if (filter_type == CSSValueID::kHueRotate) {
+ parsed_value =
+ ConsumeAngle(args, context, WebFeature::kUnitlessZeroAngleFilter);
+ } else if (filter_type == CSSValueID::kBlur) {
+ CSSParserContext::ParserModeOverridingScope scope(context,
+ kHTMLStandardMode);
+ parsed_value = ConsumeLength(args, context, kValueRangeNonNegative);
+ } else {
+ // FIXME (crbug.com/397061): Support calc expressions like calc(10% + 0.5)
+ parsed_value = ConsumePercent(args, context, kValueRangeNonNegative);
+ if (!parsed_value)
+ parsed_value = ConsumeNumber(args, context, kValueRangeNonNegative);
+ if (parsed_value && filter_type != CSSValueID::kSaturate &&
+ filter_type != CSSValueID::kContrast) {
+ bool is_percentage =
+ To<CSSPrimitiveValue>(parsed_value)->IsPercentage();
+ double max_allowed = is_percentage ? 100.0 : 1.0;
+ if (To<CSSPrimitiveValue>(parsed_value)->GetDoubleValue() >
+ max_allowed) {
+ parsed_value = CSSNumericLiteralValue::Create(
+ max_allowed, is_percentage
+ ? CSSPrimitiveValue::UnitType::kPercentage
+ : CSSPrimitiveValue::UnitType::kNumber);
+ }
+ }
+ }
+ }
+ if (!parsed_value || !args.AtEnd())
+ return nullptr;
+ filter_value->Append(*parsed_value);
+ return filter_value;
+}
+
+template <typename Func, typename... Args>
+CSSLightDarkValuePair* ConsumeInternalLightDark(Func consume_value,
+ CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ Args&&... args) {
+ if (range.Peek().FunctionId() != CSSValueID::kInternalLightDark)
+ return nullptr;
+ if (!isValueAllowedInMode(CSSValueID::kInternalLightDark, context.Mode()))
+ return nullptr;
+ CSSParserTokenRange range_copy = range;
+ CSSParserTokenRange arg_range = ConsumeFunction(range_copy);
+ CSSValue* light_value =
+ consume_value(arg_range, context, std::forward<Args>(args)...);
+ if (!light_value || !ConsumeCommaIncludingWhitespace(arg_range))
+ return nullptr;
+ CSSValue* dark_value =
+ consume_value(arg_range, context, std::forward<Args>(args)...);
+ if (!dark_value || !arg_range.AtEnd())
+ return nullptr;
+ range = range_copy;
+ return MakeGarbageCollected<CSSLightDarkValuePair>(light_value, dark_value);
+}
+
} // namespace
+void Complete4Sides(CSSValue* side[4]) {
+ if (side[3])
+ return;
+ if (!side[2]) {
+ if (!side[1])
+ side[1] = side[0];
+ side[2] = side[0];
+ }
+ side[3] = side[1];
+}
+
+bool ConsumeCommaIncludingWhitespace(CSSParserTokenRange& range) {
+ CSSParserToken value = range.Peek();
+ if (value.GetType() != kCommaToken)
+ return false;
+ range.ConsumeIncludingWhitespace();
+ return true;
+}
+
+bool ConsumeSlashIncludingWhitespace(CSSParserTokenRange& range) {
+ CSSParserToken value = range.Peek();
+ if (value.GetType() != kDelimiterToken || value.Delimiter() != '/')
+ return false;
+ range.ConsumeIncludingWhitespace();
+ return true;
+}
+
+CSSParserTokenRange ConsumeFunction(CSSParserTokenRange& range) {
+ DCHECK_EQ(range.Peek().GetType(), kFunctionToken);
+ CSSParserTokenRange contents = range.ConsumeBlock();
+ range.ConsumeWhitespace();
+ contents.ConsumeWhitespace();
+ return contents;
+}
+
+// TODO(rwlbuis): consider pulling in the parsing logic from
+// css_math_expression_node.cc.
+class MathFunctionParser {
+ STACK_ALLOCATED();
+
+ public:
+ MathFunctionParser(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ ValueRange value_range)
+ : source_range_(range), range_(range) {
+ const CSSParserToken& token = range.Peek();
+ switch (token.FunctionId()) {
+ case CSSValueID::kCalc:
+ case CSSValueID::kWebkitCalc:
+ calc_value_ = CSSMathFunctionValue::Create(
+ CSSMathExpressionNode::ParseCalc(ConsumeFunction(range_)),
+ value_range);
+ break;
+ case CSSValueID::kMin:
+ calc_value_ = CSSMathFunctionValue::Create(
+ CSSMathExpressionNode::ParseMin(ConsumeFunction(range_)),
+ value_range);
+ break;
+ case CSSValueID::kMax:
+ calc_value_ = CSSMathFunctionValue::Create(
+ CSSMathExpressionNode::ParseMax(ConsumeFunction(range_)),
+ value_range);
+ break;
+ case CSSValueID::kClamp:
+ calc_value_ = CSSMathFunctionValue::Create(
+ CSSMathExpressionNode::ParseClamp(ConsumeFunction(range_)),
+ value_range);
+ break;
+ default:
+ break;
+ }
+ if (calc_value_ && calc_value_->HasComparisons())
+ context.Count(WebFeature::kCSSComparisonFunctions);
+ }
+
+ explicit MathFunctionParser(CSSParserTokenRange& range,
+ const CSSParserContext& context)
+ : MathFunctionParser(range, context, kValueRangeAll) {}
+
+ const CSSMathFunctionValue* Value() const { return calc_value_; }
+ CSSMathFunctionValue* ConsumeValue() {
+ if (!calc_value_)
+ return nullptr;
+ source_range_ = range_;
+ CSSMathFunctionValue* result = calc_value_;
+ calc_value_ = nullptr;
+ return result;
+ }
+
+ CSSPrimitiveValue* ConsumeRoundedInt() {
+ if (!calc_value_)
+ return nullptr;
+ source_range_ = range_;
+ CSSPrimitiveValue::UnitType unit_type =
+ CSSPrimitiveValue::UnitType::kInteger;
+ double rounded_value = floor(calc_value_->GetDoubleValue() + 0.5);
+ return CSSNumericLiteralValue::Create(rounded_value, unit_type);
+ }
+
+ CSSPrimitiveValue* ConsumeNumber() {
+ if (!calc_value_)
+ return nullptr;
+ source_range_ = range_;
+ CSSPrimitiveValue::UnitType unit_type =
+ calc_value_->IsInt() ? CSSPrimitiveValue::UnitType::kInteger
+ : CSSPrimitiveValue::UnitType::kNumber;
+ return CSSNumericLiteralValue::Create(calc_value_->GetDoubleValue(),
+ unit_type);
+ }
+
+ bool ConsumeNumberRaw(double& result) {
+ if (!calc_value_ || calc_value_->Category() != kCalcNumber)
+ return false;
+ source_range_ = range_;
+ result = calc_value_->GetDoubleValue();
+ return true;
+ }
+
+ private:
+ CSSParserTokenRange& source_range_;
+ CSSParserTokenRange range_;
+ CSSMathFunctionValue* calc_value_ = nullptr;
+};
+
+CSSPrimitiveValue* ConsumeInteger(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ double minimum_value) {
+ const CSSParserToken& token = range.Peek();
+ if (token.GetType() == kNumberToken) {
+ if (token.GetNumericValueType() == kNumberValueType ||
+ token.NumericValue() < minimum_value)
+ return nullptr;
+ return CSSNumericLiteralValue::Create(
+ range.ConsumeIncludingWhitespace().NumericValue(),
+ CSSPrimitiveValue::UnitType::kInteger);
+ }
+ MathFunctionParser math_parser(range, context);
+ if (const CSSMathFunctionValue* math_value = math_parser.Value()) {
+ if (!RuntimeEnabledFeatures::CSSCalcAsIntEnabled() && !math_value->IsInt())
+ return nullptr;
+ if (math_value->Category() != kCalcNumber)
+ return nullptr;
+ double double_value = math_value->GetDoubleValue();
+ if (double_value < minimum_value)
+ return nullptr;
+ if (!RuntimeEnabledFeatures::CSSCalcAsIntEnabled())
+ return math_parser.ConsumeNumber();
+ if (math_value->IsInt())
+ return math_parser.ConsumeNumber();
+ return math_parser.ConsumeRoundedInt();
+ }
+ return nullptr;
+}
+
+// This implements the behavior defined in [1], where calc() expressions
+// are valid when <integer> is expected, even if the calc()-expression does
+// not result in an integral value.
+//
+// TODO(andruud): Eventually this behavior should just be part of
+// ConsumeInteger, and this function can be removed. For now, having a separate
+// function with this behavior allows us to implement [1] gradually.
+//
+// [1] https://drafts.csswg.org/css-values-4/#calc-type-checking
+CSSPrimitiveValue* ConsumeIntegerOrNumberCalc(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ CSSParserTokenRange int_range(range);
+ if (CSSPrimitiveValue* value = ConsumeInteger(int_range, context)) {
+ range = int_range;
+ return value;
+ }
+ MathFunctionParser math_parser(range, context);
+ if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
+ if (calculation->Category() != kCalcNumber)
+ return nullptr;
+ return math_parser.ConsumeValue();
+ }
+ return nullptr;
+}
+
+CSSPrimitiveValue* ConsumePositiveInteger(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ return ConsumeInteger(range, context, 1);
+}
+
+bool ConsumeNumberRaw(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ double& result) {
+ if (range.Peek().GetType() == kNumberToken) {
+ result = range.ConsumeIncludingWhitespace().NumericValue();
+ return true;
+ }
+ MathFunctionParser math_parser(range, context, kValueRangeAll);
+ return math_parser.ConsumeNumberRaw(result);
+}
+
+// TODO(timloh): Work out if this can just call consumeNumberRaw
+CSSPrimitiveValue* ConsumeNumber(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ ValueRange value_range) {
+ const CSSParserToken& token = range.Peek();
+ if (token.GetType() == kNumberToken) {
+ if (value_range == kValueRangeNonNegative && token.NumericValue() < 0)
+ return nullptr;
+ return CSSNumericLiteralValue::Create(
+ range.ConsumeIncludingWhitespace().NumericValue(), token.GetUnitType());
+ }
+ MathFunctionParser math_parser(range, context, kValueRangeAll);
+ if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
+ // TODO(rwlbuis) Calcs should not be subject to parse time range checks.
+ // spec: https://drafts.csswg.org/css-values-3/#calc-range
+ if (calculation->Category() != kCalcNumber ||
+ (value_range == kValueRangeNonNegative && calculation->IsNegative()))
+ return nullptr;
+ return math_parser.ConsumeNumber();
+ }
+ return nullptr;
+}
+
+inline bool ShouldAcceptUnitlessLength(double value,
+ CSSParserMode css_parser_mode,
+ UnitlessQuirk unitless) {
+ return value == 0 || css_parser_mode == kSVGAttributeMode ||
+ (css_parser_mode == kHTMLQuirksMode &&
+ unitless == UnitlessQuirk::kAllow);
+}
+
+CSSPrimitiveValue* ConsumeLength(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ ValueRange value_range,
+ UnitlessQuirk unitless) {
+ const CSSParserToken& token = range.Peek();
+ if (token.GetType() == kDimensionToken) {
+ switch (token.GetUnitType()) {
+ case CSSPrimitiveValue::UnitType::kQuirkyEms:
+ if (context.Mode() != kUASheetMode)
+ return nullptr;
+ FALLTHROUGH;
+ case CSSPrimitiveValue::UnitType::kEms:
+ case CSSPrimitiveValue::UnitType::kRems:
+ case CSSPrimitiveValue::UnitType::kChs:
+ case CSSPrimitiveValue::UnitType::kExs:
+ case CSSPrimitiveValue::UnitType::kPixels:
+ case CSSPrimitiveValue::UnitType::kCentimeters:
+ case CSSPrimitiveValue::UnitType::kMillimeters:
+ case CSSPrimitiveValue::UnitType::kQuarterMillimeters:
+ case CSSPrimitiveValue::UnitType::kInches:
+ case CSSPrimitiveValue::UnitType::kPoints:
+ case CSSPrimitiveValue::UnitType::kPicas:
+ case CSSPrimitiveValue::UnitType::kUserUnits:
+ case CSSPrimitiveValue::UnitType::kViewportWidth:
+ case CSSPrimitiveValue::UnitType::kViewportHeight:
+ case CSSPrimitiveValue::UnitType::kViewportMin:
+ case CSSPrimitiveValue::UnitType::kViewportMax:
+ break;
+ default:
+ return nullptr;
+ }
+ if (value_range == kValueRangeNonNegative && token.NumericValue() < 0)
+ return nullptr;
+ return CSSNumericLiteralValue::Create(
+ range.ConsumeIncludingWhitespace().NumericValue(), token.GetUnitType());
+ }
+ if (token.GetType() == kNumberToken) {
+ if (!ShouldAcceptUnitlessLength(token.NumericValue(), context.Mode(),
+ unitless) ||
+ (value_range == kValueRangeNonNegative && token.NumericValue() < 0))
+ return nullptr;
+ CSSPrimitiveValue::UnitType unit_type =
+ CSSPrimitiveValue::UnitType::kPixels;
+ if (context.Mode() == kSVGAttributeMode)
+ unit_type = CSSPrimitiveValue::UnitType::kUserUnits;
+ return CSSNumericLiteralValue::Create(
+ range.ConsumeIncludingWhitespace().NumericValue(), unit_type);
+ }
+ if (context.Mode() == kSVGAttributeMode)
+ return nullptr;
+ MathFunctionParser math_parser(range, context, value_range);
+ if (math_parser.Value() && math_parser.Value()->Category() == kCalcLength)
+ return math_parser.ConsumeValue();
+ return nullptr;
+}
+
+CSSPrimitiveValue* ConsumePercent(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ ValueRange value_range) {
+ const CSSParserToken& token = range.Peek();
+ if (token.GetType() == kPercentageToken) {
+ if (value_range == kValueRangeNonNegative && token.NumericValue() < 0)
+ return nullptr;
+ return CSSNumericLiteralValue::Create(
+ range.ConsumeIncludingWhitespace().NumericValue(),
+ CSSPrimitiveValue::UnitType::kPercentage);
+ }
+ MathFunctionParser math_parser(range, context, value_range);
+ if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
+ if (calculation->Category() == kCalcPercent)
+ return math_parser.ConsumeValue();
+ }
+ return nullptr;
+}
+
+CSSPrimitiveValue* ConsumeAlphaValue(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ if (CSSPrimitiveValue* value =
+ ConsumeNumber(range, context, kValueRangeAll)) {
+ return value;
+ }
+ if (CSSPrimitiveValue* value =
+ ConsumePercent(range, context, kValueRangeAll)) {
+ return CSSNumericLiteralValue::Create(value->GetDoubleValue() / 100.0,
+ CSSPrimitiveValue::UnitType::kNumber);
+ }
+ return nullptr;
+}
+
+bool CanConsumeCalcValue(CalculationCategory category,
+ CSSParserMode css_parser_mode) {
+ return category == kCalcLength || category == kCalcPercent ||
+ category == kCalcPercentLength ||
+ (css_parser_mode == kSVGAttributeMode && category == kCalcNumber);
+}
+
+CSSPrimitiveValue* ConsumeLengthOrPercent(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ ValueRange value_range,
+ UnitlessQuirk unitless) {
+ const CSSParserToken& token = range.Peek();
+ if (token.GetType() == kDimensionToken || token.GetType() == kNumberToken)
+ return ConsumeLength(range, context, value_range, unitless);
+ if (token.GetType() == kPercentageToken)
+ return ConsumePercent(range, context, value_range);
+ MathFunctionParser math_parser(range, context, value_range);
+ if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
+ if (CanConsumeCalcValue(calculation->Category(), context.Mode()))
+ return math_parser.ConsumeValue();
+ }
+ return nullptr;
+}
+
+namespace {
+
+bool IsNonZeroUserUnitsValue(const CSSPrimitiveValue* value) {
+ if (!value)
+ return false;
+ if (const auto* numeric_literal = DynamicTo<CSSNumericLiteralValue>(value)) {
+ return numeric_literal->GetType() ==
+ CSSPrimitiveValue::UnitType::kUserUnits &&
+ value->GetDoubleValue() != 0;
+ }
+ const auto& math_value = To<CSSMathFunctionValue>(*value);
+ return math_value.Category() == kCalcNumber && math_value.DoubleValue() != 0;
+}
+
+} // namespace
+
+CSSPrimitiveValue* ConsumeSVGGeometryPropertyLength(
+ CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ ValueRange value_range) {
+ CSSParserContext::ParserModeOverridingScope scope(context, kSVGAttributeMode);
+ CSSPrimitiveValue* value = ConsumeLengthOrPercent(range, context, value_range,
+ UnitlessQuirk::kForbid);
+ if (IsNonZeroUserUnitsValue(value))
+ context.Count(WebFeature::kSVGGeometryPropertyHasNonZeroUnitlessValue);
+ return value;
+}
+
+CSSPrimitiveValue* ConsumeGradientLengthOrPercent(
+ CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ ValueRange value_range,
+ UnitlessQuirk unitless) {
+ return ConsumeLengthOrPercent(range, context, value_range, unitless);
+}
+
+CSSPrimitiveValue* ConsumeAngle(
+ CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ base::Optional<WebFeature> unitless_zero_feature,
+ double minimum_value,
+ double maximum_value) {
+ const CSSParserToken& token = range.Peek();
+ if (token.GetType() == kDimensionToken) {
+ switch (token.GetUnitType()) {
+ case CSSPrimitiveValue::UnitType::kDegrees:
+ case CSSPrimitiveValue::UnitType::kRadians:
+ case CSSPrimitiveValue::UnitType::kGradians:
+ case CSSPrimitiveValue::UnitType::kTurns:
+ return CSSNumericLiteralValue::Create(
+ range.ConsumeIncludingWhitespace().NumericValue(),
+ token.GetUnitType());
+ default:
+ return nullptr;
+ }
+ }
+ if (token.GetType() == kNumberToken && token.NumericValue() == 0 &&
+ unitless_zero_feature) {
+ range.ConsumeIncludingWhitespace();
+ context.Count(*unitless_zero_feature);
+ return CSSNumericLiteralValue::Create(
+ 0, CSSPrimitiveValue::UnitType::kDegrees);
+ }
+ MathFunctionParser math_parser(range, context, kValueRangeAll);
+ if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
+ if (calculation->Category() != kCalcAngle)
+ return nullptr;
+ if (CSSMathFunctionValue* result = math_parser.ConsumeValue()) {
+ if (result->ComputeDegrees() < minimum_value) {
+ return CSSNumericLiteralValue::Create(
+ minimum_value, CSSPrimitiveValue::UnitType::kDegrees);
+ }
+ if (result->ComputeDegrees() > maximum_value) {
+ return CSSNumericLiteralValue::Create(
+ maximum_value, CSSPrimitiveValue::UnitType::kDegrees);
+ }
+ return result;
+ }
+ }
+ return nullptr;
+}
+
+CSSPrimitiveValue* ConsumeAngle(
+ CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ base::Optional<WebFeature> unitless_zero_feature) {
+ return ConsumeAngle(range, context, std::move(unitless_zero_feature),
+ std::numeric_limits<double>::lowest(),
+ std::numeric_limits<double>::max());
+}
+
+CSSPrimitiveValue* ConsumeTime(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ ValueRange value_range) {
+ const CSSParserToken& token = range.Peek();
+ if (token.GetType() == kDimensionToken) {
+ if (value_range == kValueRangeNonNegative && token.NumericValue() < 0)
+ return nullptr;
+ CSSPrimitiveValue::UnitType unit = token.GetUnitType();
+ if (unit == CSSPrimitiveValue::UnitType::kMilliseconds ||
+ unit == CSSPrimitiveValue::UnitType::kSeconds) {
+ return CSSNumericLiteralValue::Create(
+ range.ConsumeIncludingWhitespace().NumericValue(),
+ token.GetUnitType());
+ }
+ return nullptr;
+ }
+ MathFunctionParser math_parser(range, context, value_range);
+ if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
+ if (calculation->Category() == kCalcTime)
+ return math_parser.ConsumeValue();
+ }
+ return nullptr;
+}
+
+CSSPrimitiveValue* ConsumeResolution(CSSParserTokenRange& range) {
+ const CSSParserToken& token = range.Peek();
+ // Unlike the other types, calc() does not work with <resolution>.
+ if (token.GetType() != kDimensionToken)
+ return nullptr;
+ CSSPrimitiveValue::UnitType unit = token.GetUnitType();
+ if (unit == CSSPrimitiveValue::UnitType::kDotsPerPixel ||
+ unit == CSSPrimitiveValue::UnitType::kDotsPerInch ||
+ unit == CSSPrimitiveValue::UnitType::kDotsPerCentimeter) {
+ return CSSNumericLiteralValue::Create(
+ range.ConsumeIncludingWhitespace().NumericValue(), unit);
+ }
+ return nullptr;
+}
+
+CSSIdentifierValue* ConsumeIdent(CSSParserTokenRange& range) {
+ if (range.Peek().GetType() != kIdentToken)
+ return nullptr;
+ return CSSIdentifierValue::Create(range.ConsumeIncludingWhitespace().Id());
+}
+
+CSSIdentifierValue* ConsumeIdentRange(CSSParserTokenRange& range,
+ CSSValueID lower,
+ CSSValueID upper) {
+ if (range.Peek().Id() < lower || range.Peek().Id() > upper)
+ return nullptr;
+ return ConsumeIdent(range);
+}
+
+CSSCustomIdentValue* ConsumeCustomIdentWithToken(
+ const CSSParserToken& token,
+ const CSSParserContext& context) {
+ if (token.GetType() != kIdentToken || IsCSSWideKeyword(token.Value()))
+ return nullptr;
+
+ if (EqualIgnoringASCIICase(token.Value(), "default"))
+ context.Count(WebFeature::kDefaultInCustomIdent);
+
+ return MakeGarbageCollected<CSSCustomIdentValue>(
+ token.Value().ToAtomicString());
+}
+
+CSSCustomIdentValue* ConsumeCustomIdent(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ if (range.Peek().GetType() != kIdentToken ||
+ IsCSSWideKeyword(range.Peek().Value()))
+ return nullptr;
+
+ return ConsumeCustomIdentWithToken(range.ConsumeIncludingWhitespace(),
+ context);
+}
+
+CSSStringValue* ConsumeString(CSSParserTokenRange& range) {
+ if (range.Peek().GetType() != kStringToken)
+ return nullptr;
+ return MakeGarbageCollected<CSSStringValue>(
+ range.ConsumeIncludingWhitespace().Value().ToString());
+}
+
+StringView ConsumeUrlAsStringView(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ StringView url;
+ const CSSParserToken& token = range.Peek();
+ if (token.GetType() == kUrlToken) {
+ range.ConsumeIncludingWhitespace();
+ url = token.Value();
+ } else if (token.FunctionId() == CSSValueID::kUrl) {
+ CSSParserTokenRange url_range = range;
+ CSSParserTokenRange url_args = url_range.ConsumeBlock();
+ const CSSParserToken& next = url_args.ConsumeIncludingWhitespace();
+ if (next.GetType() == kBadStringToken || !url_args.AtEnd())
+ return StringView();
+ DCHECK_EQ(next.GetType(), kStringToken);
+ range = url_range;
+ range.ConsumeWhitespace();
+ url = next.Value();
+ }
+
+ // Invalidate the URL if only data URLs are allowed and the protocol is not
+ // data.
+ if (!url.IsNull() &&
+ context.ResourceFetchRestriction() ==
+ ResourceFetchRestriction::kOnlyDataUrls &&
+ !ProtocolIs(url.ToString(), "data")) {
+ // The StringView must be instantiated with an empty string otherwise the
+ // URL will incorrectly be identified as null. The resource should behave as
+ // if it failed to load.
+ url = StringView("");
+ }
+
+ return url;
+}
+
+cssvalue::CSSURIValue* ConsumeUrl(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ StringView url = ConsumeUrlAsStringView(range, context);
+ if (url.IsNull())
+ return nullptr;
+ AtomicString url_string(url.ToString());
+ return MakeGarbageCollected<cssvalue::CSSURIValue>(
+ url_string, context.CompleteURL(url_string));
+}
+
+CSSValue* ConsumeIdSelector(CSSParserTokenRange& range) {
+ if (!IsHashIdentifier(range.Peek()))
+ return nullptr;
+ auto token = range.ConsumeIncludingWhitespace();
+ return MakeGarbageCollected<cssvalue::CSSIdSelectorValue>(
+ token.Value().ToString());
+}
+
+static int ClampRGBComponent(const CSSPrimitiveValue& value) {
+ double result = value.GetDoubleValue();
+ if (value.IsPercentage()) {
+ // 2.55 cannot be precisely represented as a double
+ result = (result / 100.0) * 255.0;
+ }
+ return clampTo<int>(round(result), 0, 255);
+}
+
+static bool ParseRGBParameters(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ RGBA32& result) {
+ DCHECK(range.Peek().FunctionId() == CSSValueID::kRgb ||
+ range.Peek().FunctionId() == CSSValueID::kRgba);
+ CSSParserTokenRange args = ConsumeFunction(range);
+ CSSPrimitiveValue* color_parameter =
+ ConsumeNumber(args, context, kValueRangeAll);
+ if (!color_parameter)
+ color_parameter = ConsumePercent(args, context, kValueRangeAll);
+ if (!color_parameter)
+ return false;
+ const bool is_percent = color_parameter->IsPercentage();
+ int color_array[3];
+ color_array[0] = ClampRGBComponent(*color_parameter);
+ bool requires_commas = false;
+ for (int i = 1; i < 3; i++) {
+ if (ConsumeCommaIncludingWhitespace(args)) {
+ if (i != 1 && !requires_commas)
+ return false;
+ requires_commas = true;
+ } else if (requires_commas || args.AtEnd()) {
+ return false;
+ }
+ color_parameter = is_percent ? ConsumePercent(args, context, kValueRangeAll)
+ : ConsumeNumber(args, context, kValueRangeAll);
+ if (!color_parameter)
+ return false;
+ color_array[i] = ClampRGBComponent(*color_parameter);
+ }
+
+ bool comma_consumed = ConsumeCommaIncludingWhitespace(args);
+ bool slash_consumed = ConsumeSlashIncludingWhitespace(args);
+ if ((comma_consumed && !requires_commas) ||
+ (slash_consumed && requires_commas))
+ return false;
+ if (comma_consumed || slash_consumed) {
+ double alpha;
+ if (!ConsumeNumberRaw(args, context, alpha)) {
+ CSSPrimitiveValue* alpha_percent =
+ ConsumePercent(args, context, kValueRangeAll);
+ if (!alpha_percent)
+ return false;
+ else
+ alpha = alpha_percent->GetDoubleValue() / 100.0;
+ }
+ // W3 standard stipulates a 2.55 alpha value multiplication factor.
+ int alpha_component =
+ static_cast<int>(lround(clampTo<double>(alpha, 0.0, 1.0) * 255.0));
+ result = MakeRGBA(color_array[0], color_array[1], color_array[2],
+ alpha_component);
+ } else {
+ result = MakeRGB(color_array[0], color_array[1], color_array[2]);
+ }
+ return args.AtEnd();
+}
+
+static bool ParseHSLParameters(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ RGBA32& result) {
+ DCHECK(range.Peek().FunctionId() == CSSValueID::kHsl ||
+ range.Peek().FunctionId() == CSSValueID::kHsla);
+ CSSParserTokenRange args = ConsumeFunction(range);
+ CSSPrimitiveValue* hsl_value = ConsumeAngle(args, context, base::nullopt);
+ double angle_value;
+ if (!hsl_value) {
+ hsl_value = ConsumeNumber(args, context, kValueRangeAll);
+ if (!hsl_value)
+ return false;
+ angle_value = hsl_value->GetDoubleValue();
+ } else {
+ angle_value = hsl_value->ComputeDegrees();
+ }
+ double color_array[3];
+ color_array[0] = fmod(fmod(angle_value, 360.0) + 360.0, 360.0) / 60.0;
+ bool requires_commas = false;
+ for (int i = 1; i < 3; i++) {
+ if (ConsumeCommaIncludingWhitespace(args)) {
+ if (i != 1 && !requires_commas)
+ return false;
+ requires_commas = true;
+ } else if (requires_commas || args.AtEnd()) {
+ return false;
+ }
+ hsl_value = ConsumePercent(args, context, kValueRangeAll);
+ if (!hsl_value)
+ return false;
+ double double_value = hsl_value->GetDoubleValue();
+ color_array[i] = clampTo<double>(double_value, 0.0, 100.0) /
+ 100.0; // Needs to be value between 0 and 1.0.
+ }
+
+ double alpha = 1.0;
+ bool comma_consumed = ConsumeCommaIncludingWhitespace(args);
+ bool slash_consumed = ConsumeSlashIncludingWhitespace(args);
+ if ((comma_consumed && !requires_commas) ||
+ (slash_consumed && requires_commas))
+ return false;
+ if (comma_consumed || slash_consumed) {
+ if (!ConsumeNumberRaw(args, context, alpha)) {
+ CSSPrimitiveValue* alpha_percent =
+ ConsumePercent(args, context, kValueRangeAll);
+ if (!alpha_percent)
+ return false;
+ else
+ alpha = alpha_percent->GetDoubleValue() / 100.0;
+ }
+ alpha = clampTo<double>(alpha, 0.0, 1.0);
+ }
+ result =
+ MakeRGBAFromHSLA(color_array[0], color_array[1], color_array[2], alpha);
+ return args.AtEnd();
+}
+
+static bool ParseHexColor(CSSParserTokenRange& range,
+ RGBA32& result,
+ bool accept_quirky_colors) {
+ const CSSParserToken& token = range.Peek();
+ if (token.GetType() == kHashToken) {
+ if (!Color::ParseHexColor(token.Value(), result))
+ return false;
+ } else if (accept_quirky_colors) {
+ String color;
+ if (token.GetType() == kNumberToken || token.GetType() == kDimensionToken) {
+ if (token.GetNumericValueType() != kIntegerValueType ||
+ token.NumericValue() < 0. || token.NumericValue() >= 1000000.)
+ return false;
+ if (token.GetType() == kNumberToken) { // e.g. 112233
+ color = String::Format("%d", static_cast<int>(token.NumericValue()));
+ } else { // e.g. 0001FF
+ color = String::Number(static_cast<int>(token.NumericValue())) +
+ token.Value().ToString();
+ }
+ while (color.length() < 6)
+ color = "0" + color;
+ } else if (token.GetType() == kIdentToken) { // e.g. FF0000
+ color = token.Value().ToString();
+ }
+ unsigned length = color.length();
+ if (length != 3 && length != 6)
+ return false;
+ if (!Color::ParseHexColor(color, result))
+ return false;
+ } else {
+ return false;
+ }
+ range.ConsumeIncludingWhitespace();
+ return true;
+}
+
+static bool ParseColorFunction(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ RGBA32& result) {
+ CSSValueID function_id = range.Peek().FunctionId();
+ if (function_id < CSSValueID::kRgb || function_id > CSSValueID::kHsla)
+ return false;
+ CSSParserTokenRange color_range = range;
+ if ((function_id <= CSSValueID::kRgba &&
+ !ParseRGBParameters(color_range, context, result)) ||
+ (function_id >= CSSValueID::kHsl &&
+ !ParseHSLParameters(color_range, context, result)))
+ return false;
+ range = color_range;
+ return true;
+}
+
+CSSValue* ConsumeColor(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ bool accept_quirky_colors) {
+ CSSValueID id = range.Peek().Id();
+ if (StyleColor::IsColorKeyword(id)) {
+ if (!isValueAllowedInMode(id, context.Mode()))
+ return nullptr;
+ CSSIdentifierValue* color = ConsumeIdent(range);
+ return color;
+ }
+ RGBA32 color = Color::kTransparent;
+ if (!ParseHexColor(range, color, accept_quirky_colors) &&
+ !ParseColorFunction(range, context, color)) {
+ return ConsumeInternalLightDark(ConsumeColor, range, context,
+ accept_quirky_colors);
+ }
+ return cssvalue::CSSColorValue::Create(color);
+}
+
+CSSValue* ConsumeInternalForcedBackgroundColor(
+ CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ CSSValueID id = range.Peek().Id();
+ if (!StyleColor::IsColorKeyword(id))
+ return nullptr;
+ return ConsumeIdent(range);
+}
+
+CSSValue* ConsumeLineWidth(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ UnitlessQuirk unitless) {
+ CSSValueID id = range.Peek().Id();
+ if (id == CSSValueID::kThin || id == CSSValueID::kMedium ||
+ id == CSSValueID::kThick)
+ return ConsumeIdent(range);
+ return ConsumeLength(range, context, kValueRangeNonNegative, unitless);
+}
+
+static CSSValue* ConsumePositionComponent(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ UnitlessQuirk unitless,
+ bool& horizontal_edge,
+ bool& vertical_edge) {
+ if (range.Peek().GetType() != kIdentToken)
+ return ConsumeLengthOrPercent(range, context, kValueRangeAll, unitless);
+
+ CSSValueID id = range.Peek().Id();
+ if (id == CSSValueID::kLeft || id == CSSValueID::kRight) {
+ if (horizontal_edge)
+ return nullptr;
+ horizontal_edge = true;
+ } else if (id == CSSValueID::kTop || id == CSSValueID::kBottom) {
+ if (vertical_edge)
+ return nullptr;
+ vertical_edge = true;
+ } else if (id != CSSValueID::kCenter) {
+ return nullptr;
+ }
+ return ConsumeIdent(range);
+}
+
+static bool IsHorizontalPositionKeywordOnly(const CSSValue& value) {
+ auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
+ if (!identifier_value)
+ return false;
+ CSSValueID value_id = identifier_value->GetValueID();
+ return value_id == CSSValueID::kLeft || value_id == CSSValueID::kRight;
+}
+
+static bool IsVerticalPositionKeywordOnly(const CSSValue& value) {
+ auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
+ if (!identifier_value)
+ return false;
+ CSSValueID value_id = identifier_value->GetValueID();
+ return value_id == CSSValueID::kTop || value_id == CSSValueID::kBottom;
+}
+
+static void PositionFromOneValue(CSSValue* value,
+ CSSValue*& result_x,
+ CSSValue*& result_y) {
+ bool value_applies_to_y_axis_only = IsVerticalPositionKeywordOnly(*value);
+ result_x = value;
+ result_y = CSSIdentifierValue::Create(CSSValueID::kCenter);
+ if (value_applies_to_y_axis_only)
+ std::swap(result_x, result_y);
+}
+
+static void PositionFromTwoValues(CSSValue* value1,
+ CSSValue* value2,
+ CSSValue*& result_x,
+ CSSValue*& result_y) {
+ bool must_order_as_xy = IsHorizontalPositionKeywordOnly(*value1) ||
+ IsVerticalPositionKeywordOnly(*value2) ||
+ !value1->IsIdentifierValue() ||
+ !value2->IsIdentifierValue();
+ bool must_order_as_yx = IsVerticalPositionKeywordOnly(*value1) ||
+ IsHorizontalPositionKeywordOnly(*value2);
+ DCHECK(!must_order_as_xy || !must_order_as_yx);
+ result_x = value1;
+ result_y = value2;
+ if (must_order_as_yx)
+ std::swap(result_x, result_y);
+}
+
+static void PositionFromThreeOrFourValues(CSSValue** values,
+ CSSValue*& result_x,
+ CSSValue*& result_y) {
+ CSSIdentifierValue* center = nullptr;
+ for (int i = 0; values[i]; i++) {
+ auto* current_value = To<CSSIdentifierValue>(values[i]);
+ CSSValueID id = current_value->GetValueID();
+
+ if (id == CSSValueID::kCenter) {
+ DCHECK(!center);
+ center = current_value;
+ continue;
+ }
+
+ CSSValue* result = nullptr;
+ if (values[i + 1] && !values[i + 1]->IsIdentifierValue()) {
+ result = MakeGarbageCollected<CSSValuePair>(
+ current_value, values[++i], CSSValuePair::kKeepIdenticalValues);
+ } else {
+ result = current_value;
+ }
+
+ if (id == CSSValueID::kLeft || id == CSSValueID::kRight) {
+ DCHECK(!result_x);
+ result_x = result;
+ } else {
+ DCHECK(id == CSSValueID::kTop || id == CSSValueID::kBottom);
+ DCHECK(!result_y);
+ result_y = result;
+ }
+ }
+
+ if (center) {
+ DCHECK(!!result_x != !!result_y);
+ if (!result_x)
+ result_x = center;
+ else
+ result_y = center;
+ }
+
+ DCHECK(result_x && result_y);
+}
+
+bool ConsumePosition(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ UnitlessQuirk unitless,
+ base::Optional<WebFeature> three_value_position,
+ CSSValue*& result_x,
+ CSSValue*& result_y) {
+ bool horizontal_edge = false;
+ bool vertical_edge = false;
+ CSSValue* value1 = ConsumePositionComponent(range, context, unitless,
+ horizontal_edge, vertical_edge);
+ if (!value1)
+ return false;
+ if (!value1->IsIdentifierValue())
+ horizontal_edge = true;
+
+ CSSParserTokenRange range_after_first_consume = range;
+ CSSValue* value2 = ConsumePositionComponent(range, context, unitless,
+ horizontal_edge, vertical_edge);
+ if (!value2) {
+ PositionFromOneValue(value1, result_x, result_y);
+ return true;
+ }
+
+ CSSParserTokenRange range_after_second_consume = range;
+ CSSValue* value3 = nullptr;
+ auto* identifier_value1 = DynamicTo<CSSIdentifierValue>(value1);
+ auto* identifier_value2 = DynamicTo<CSSIdentifierValue>(value2);
+ // TODO(crbug.com/940442): Fix the strange comparison of a
+ // CSSIdentifierValue instance against a specific "range peek" type check.
+ if (identifier_value1 &&
+ !!identifier_value2 != (range.Peek().GetType() == kIdentToken) &&
+ (identifier_value2
+ ? identifier_value2->GetValueID()
+ : identifier_value1->GetValueID()) != CSSValueID::kCenter) {
+ value3 = ConsumePositionComponent(range, context, unitless, horizontal_edge,
+ vertical_edge);
+ }
+ if (!value3) {
+ if (vertical_edge && !value2->IsIdentifierValue()) {
+ range = range_after_first_consume;
+ PositionFromOneValue(value1, result_x, result_y);
+ return true;
+ }
+ PositionFromTwoValues(value1, value2, result_x, result_y);
+ return true;
+ }
+
+ CSSValue* value4 = nullptr;
+ auto* identifier_value3 = DynamicTo<CSSIdentifierValue>(value3);
+ if (identifier_value3 &&
+ identifier_value3->GetValueID() != CSSValueID::kCenter &&
+ range.Peek().GetType() != kIdentToken) {
+ value4 = ConsumePositionComponent(range, context, unitless, horizontal_edge,
+ vertical_edge);
+ }
+
+ if (!value4) {
+ if (!three_value_position) {
+ // [top | bottom] <length-percentage> is not permitted
+ if (vertical_edge && !value2->IsIdentifierValue()) {
+ range = range_after_first_consume;
+ PositionFromOneValue(value1, result_x, result_y);
+ return true;
+ }
+ range = range_after_second_consume;
+ PositionFromTwoValues(value1, value2, result_x, result_y);
+ return true;
+ }
+ DCHECK_EQ(*three_value_position,
+ WebFeature::kThreeValuedPositionBackground);
+ context.Count(*three_value_position);
+ }
+
+ CSSValue* values[5];
+ values[0] = value1;
+ values[1] = value2;
+ values[2] = value3;
+ values[3] = value4;
+ values[4] = nullptr;
+ PositionFromThreeOrFourValues(values, result_x, result_y);
+ return true;
+}
+
+CSSValuePair* ConsumePosition(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ UnitlessQuirk unitless,
+ base::Optional<WebFeature> three_value_position) {
+ CSSValue* result_x = nullptr;
+ CSSValue* result_y = nullptr;
+ if (ConsumePosition(range, context, unitless, three_value_position, result_x,
+ result_y)) {
+ return MakeGarbageCollected<CSSValuePair>(
+ result_x, result_y, CSSValuePair::kKeepIdenticalValues);
+ }
+ return nullptr;
+}
+
+bool ConsumeOneOrTwoValuedPosition(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ UnitlessQuirk unitless,
+ CSSValue*& result_x,
+ CSSValue*& result_y) {
+ bool horizontal_edge = false;
+ bool vertical_edge = false;
+ CSSValue* value1 = ConsumePositionComponent(range, context, unitless,
+ horizontal_edge, vertical_edge);
+ if (!value1)
+ return false;
+ if (!value1->IsIdentifierValue())
+ horizontal_edge = true;
+
+ if (vertical_edge &&
+ ConsumeLengthOrPercent(range, context, kValueRangeAll, unitless)) {
+ // <length-percentage> is not permitted after top | bottom.
+ return false;
+ }
+ CSSValue* value2 = ConsumePositionComponent(range, context, unitless,
+ horizontal_edge, vertical_edge);
+ if (!value2) {
+ PositionFromOneValue(value1, result_x, result_y);
+ return true;
+ }
+ PositionFromTwoValues(value1, value2, result_x, result_y);
+ return true;
+}
+
+bool ConsumeBorderShorthand(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ const CSSValue*& result_width,
+ const CSSValue*& result_style,
+ const CSSValue*& result_color) {
+ while (!result_width || !result_style || !result_color) {
+ if (!result_width) {
+ result_width = ConsumeLineWidth(range, context, UnitlessQuirk::kForbid);
+ if (result_width)
+ continue;
+ }
+ if (!result_style) {
+ result_style = ParseLonghand(CSSPropertyID::kBorderLeftStyle,
+ CSSPropertyID::kBorder, context, range);
+ if (result_style)
+ continue;
+ }
+ if (!result_color) {
+ result_color = ConsumeColor(range, context);
+ if (result_color)
+ continue;
+ }
+ break;
+ }
+
+ if (!result_width && !result_style && !result_color)
+ return false;
+
+ if (!result_width)
+ result_width = CSSInitialValue::Create();
+ if (!result_style)
+ result_style = CSSInitialValue::Create();
+ if (!result_color)
+ result_color = CSSInitialValue::Create();
+ return true;
+}
+
+// This should go away once we drop support for -webkit-gradient
+static CSSPrimitiveValue* ConsumeDeprecatedGradientPoint(
+ CSSParserTokenRange& args,
+ const CSSParserContext& context,
+ bool horizontal) {
+ if (args.Peek().GetType() == kIdentToken) {
+ if ((horizontal && ConsumeIdent<CSSValueID::kLeft>(args)) ||
+ (!horizontal && ConsumeIdent<CSSValueID::kTop>(args))) {
+ return CSSNumericLiteralValue::Create(
+ 0., CSSPrimitiveValue::UnitType::kPercentage);
+ }
+ if ((horizontal && ConsumeIdent<CSSValueID::kRight>(args)) ||
+ (!horizontal && ConsumeIdent<CSSValueID::kBottom>(args))) {
+ return CSSNumericLiteralValue::Create(
+ 100., CSSPrimitiveValue::UnitType::kPercentage);
+ }
+ if (ConsumeIdent<CSSValueID::kCenter>(args)) {
+ return CSSNumericLiteralValue::Create(
+ 50., CSSPrimitiveValue::UnitType::kPercentage);
+ }
+ return nullptr;
+ }
+ CSSPrimitiveValue* result = ConsumePercent(args, context, kValueRangeAll);
+ if (!result)
+ result = ConsumeNumber(args, context, kValueRangeAll);
+ return result;
+}
+
+// Used to parse colors for -webkit-gradient(...).
+static CSSValue* ConsumeDeprecatedGradientStopColor(
+ CSSParserTokenRange& args,
+ const CSSParserContext& context) {
+ if (args.Peek().Id() == CSSValueID::kCurrentcolor)
+ return nullptr;
+ return ConsumeColor(args, context);
+}
+
+static bool ConsumeDeprecatedGradientColorStop(
+ CSSParserTokenRange& range,
+ cssvalue::CSSGradientColorStop& stop,
+ const CSSParserContext& context) {
+ CSSValueID id = range.Peek().FunctionId();
+ if (id != CSSValueID::kFrom && id != CSSValueID::kTo &&
+ id != CSSValueID::kColorStop)
+ return false;
+
+ CSSParserTokenRange args = ConsumeFunction(range);
+ double position;
+ if (id == CSSValueID::kFrom || id == CSSValueID::kTo) {
+ position = (id == CSSValueID::kFrom) ? 0 : 1;
+ } else {
+ DCHECK(id == CSSValueID::kColorStop);
+ if (CSSPrimitiveValue* percent_value =
+ ConsumePercent(args, context, kValueRangeAll))
+ position = percent_value->GetDoubleValue() / 100.0;
+ else if (!ConsumeNumberRaw(args, context, position))
+ return false;
+
+ if (!ConsumeCommaIncludingWhitespace(args))
+ return false;
+ }
+
+ stop.offset_ = CSSNumericLiteralValue::Create(
+ position, CSSPrimitiveValue::UnitType::kNumber);
+ stop.color_ = ConsumeDeprecatedGradientStopColor(args, context);
+ return stop.color_ && args.AtEnd();
+}
+
+static CSSValue* ConsumeDeprecatedGradient(CSSParserTokenRange& args,
+ const CSSParserContext& context) {
+ CSSValueID id = args.ConsumeIncludingWhitespace().Id();
+ if (id != CSSValueID::kRadial && id != CSSValueID::kLinear)
+ return nullptr;
+
+ if (!ConsumeCommaIncludingWhitespace(args))
+ return nullptr;
+
+ const CSSPrimitiveValue* first_x =
+ ConsumeDeprecatedGradientPoint(args, context, true);
+ if (!first_x)
+ return nullptr;
+ const CSSPrimitiveValue* first_y =
+ ConsumeDeprecatedGradientPoint(args, context, false);
+ if (!first_y)
+ return nullptr;
+ if (!ConsumeCommaIncludingWhitespace(args))
+ return nullptr;
+
+ // For radial gradients only, we now expect a numeric radius.
+ const CSSPrimitiveValue* first_radius = nullptr;
+ if (id == CSSValueID::kRadial) {
+ first_radius = ConsumeNumber(args, context, kValueRangeNonNegative);
+ if (!first_radius || !ConsumeCommaIncludingWhitespace(args))
+ return nullptr;
+ }
+
+ const CSSPrimitiveValue* second_x =
+ ConsumeDeprecatedGradientPoint(args, context, true);
+ if (!second_x)
+ return nullptr;
+ const CSSPrimitiveValue* second_y =
+ ConsumeDeprecatedGradientPoint(args, context, false);
+ if (!second_y)
+ return nullptr;
+
+ // For radial gradients only, we now expect the second radius.
+ const CSSPrimitiveValue* second_radius = nullptr;
+ if (id == CSSValueID::kRadial) {
+ if (!ConsumeCommaIncludingWhitespace(args))
+ return nullptr;
+ second_radius = ConsumeNumber(args, context, kValueRangeNonNegative);
+ if (!second_radius)
+ return nullptr;
+ }
+
+ cssvalue::CSSGradientValue* result;
+ if (id == CSSValueID::kRadial) {
+ result = MakeGarbageCollected<cssvalue::CSSRadialGradientValue>(
+ first_x, first_y, first_radius, second_x, second_y, second_radius,
+ cssvalue::kNonRepeating, cssvalue::kCSSDeprecatedRadialGradient);
+ } else {
+ result = MakeGarbageCollected<cssvalue::CSSLinearGradientValue>(
+ first_x, first_y, second_x, second_y, nullptr, cssvalue::kNonRepeating,
+ cssvalue::kCSSDeprecatedLinearGradient);
+ }
+ cssvalue::CSSGradientColorStop stop;
+ while (ConsumeCommaIncludingWhitespace(args)) {
+ if (!ConsumeDeprecatedGradientColorStop(args, stop, context))
+ return nullptr;
+ result->AddStop(stop);
+ }
+
+ return result;
+}
+
+static CSSPrimitiveValue* ConsumeGradientAngleOrPercent(
+ CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ ValueRange value_range,
+ UnitlessQuirk) {
+ const CSSParserToken& token = range.Peek();
+ if (token.GetType() == kDimensionToken || token.GetType() == kNumberToken) {
+ return ConsumeAngle(range, context, WebFeature::kUnitlessZeroAngleGradient);
+ }
+ if (token.GetType() == kPercentageToken)
+ return ConsumePercent(range, context, value_range);
+ MathFunctionParser math_parser(range, context, value_range);
+ if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
+ CalculationCategory category = calculation->Category();
+ // TODO(fs): Add and support kCalcPercentAngle?
+ if (category == kCalcAngle || category == kCalcPercent)
+ return math_parser.ConsumeValue();
+ }
+ return nullptr;
+}
+
+using PositionFunctor = CSSPrimitiveValue* (*)(CSSParserTokenRange&,
+ const CSSParserContext&,
+ ValueRange,
+ UnitlessQuirk);
+
+static bool ConsumeGradientColorStops(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ cssvalue::CSSGradientValue* gradient,
+ PositionFunctor consume_position_func) {
+ bool supports_color_hints =
+ gradient->GradientType() == cssvalue::kCSSLinearGradient ||
+ gradient->GradientType() == cssvalue::kCSSRadialGradient ||
+ gradient->GradientType() == cssvalue::kCSSConicGradient;
+
+ // The first color stop cannot be a color hint.
+ bool previous_stop_was_color_hint = true;
+ do {
+ cssvalue::CSSGradientColorStop stop;
+ stop.color_ = ConsumeColor(range, context);
+ // Two hints in a row are not allowed.
+ if (!stop.color_ && (!supports_color_hints || previous_stop_was_color_hint))
+ return false;
+ previous_stop_was_color_hint = !stop.color_;
+ stop.offset_ = consume_position_func(range, context, kValueRangeAll,
+ UnitlessQuirk::kForbid);
+ if (!stop.color_ && !stop.offset_)
+ return false;
+ gradient->AddStop(stop);
+
+ if (!stop.color_ || !stop.offset_)
+ continue;
+
+ // Optional second position.
+ stop.offset_ = consume_position_func(range, context, kValueRangeAll,
+ UnitlessQuirk::kForbid);
+ if (stop.offset_)
+ gradient->AddStop(stop);
+ } while (ConsumeCommaIncludingWhitespace(range));
+
+ // The last color stop cannot be a color hint.
+ if (previous_stop_was_color_hint)
+ return false;
+
+ // Must have 2 or more stops to be valid.
+ return gradient->StopCount() >= 2;
+}
+
+static CSSValue* ConsumeDeprecatedRadialGradient(
+ CSSParserTokenRange& args,
+ const CSSParserContext& context,
+ cssvalue::CSSGradientRepeat repeating) {
+ CSSValue* center_x = nullptr;
+ CSSValue* center_y = nullptr;
+ ConsumeOneOrTwoValuedPosition(args, context, UnitlessQuirk::kForbid, center_x,
+ center_y);
+ if ((center_x || center_y) && !ConsumeCommaIncludingWhitespace(args))
+ return nullptr;
+
+ const CSSIdentifierValue* shape =
+ ConsumeIdent<CSSValueID::kCircle, CSSValueID::kEllipse>(args);
+ const CSSIdentifierValue* size_keyword =
+ ConsumeIdent<CSSValueID::kClosestSide, CSSValueID::kClosestCorner,
+ CSSValueID::kFarthestSide, CSSValueID::kFarthestCorner,
+ CSSValueID::kContain, CSSValueID::kCover>(args);
+ if (!shape)
+ shape = ConsumeIdent<CSSValueID::kCircle, CSSValueID::kEllipse>(args);
+
+ // Or, two lengths or percentages
+ const CSSPrimitiveValue* horizontal_size = nullptr;
+ const CSSPrimitiveValue* vertical_size = nullptr;
+ if (!shape && !size_keyword) {
+ horizontal_size =
+ ConsumeLengthOrPercent(args, context, kValueRangeNonNegative);
+ if (horizontal_size) {
+ vertical_size =
+ ConsumeLengthOrPercent(args, context, kValueRangeNonNegative);
+ if (!vertical_size)
+ return nullptr;
+ ConsumeCommaIncludingWhitespace(args);
+ }
+ } else {
+ ConsumeCommaIncludingWhitespace(args);
+ }
+
+ cssvalue::CSSGradientValue* result =
+ MakeGarbageCollected<cssvalue::CSSRadialGradientValue>(
+ center_x, center_y, shape, size_keyword, horizontal_size,
+ vertical_size, repeating, cssvalue::kCSSPrefixedRadialGradient);
+ return ConsumeGradientColorStops(args, context, result,
+ ConsumeGradientLengthOrPercent)
+ ? result
+ : nullptr;
+}
+
+static CSSValue* ConsumeRadialGradient(CSSParserTokenRange& args,
+ const CSSParserContext& context,
+ cssvalue::CSSGradientRepeat repeating) {
+ const CSSIdentifierValue* shape = nullptr;
+ const CSSIdentifierValue* size_keyword = nullptr;
+ const CSSPrimitiveValue* horizontal_size = nullptr;
+ const CSSPrimitiveValue* vertical_size = nullptr;
+
+ // First part of grammar, the size/shape clause:
+ // [ circle || <length> ] |
+ // [ ellipse || [ <length> | <percentage> ]{2} ] |
+ // [ [ circle | ellipse] || <size-keyword> ]
+ for (int i = 0; i < 3; ++i) {
+ if (args.Peek().GetType() == kIdentToken) {
+ CSSValueID id = args.Peek().Id();
+ if (id == CSSValueID::kCircle || id == CSSValueID::kEllipse) {
+ if (shape)
+ return nullptr;
+ shape = ConsumeIdent(args);
+ } else if (id == CSSValueID::kClosestSide ||
+ id == CSSValueID::kClosestCorner ||
+ id == CSSValueID::kFarthestSide ||
+ id == CSSValueID::kFarthestCorner) {
+ if (size_keyword)
+ return nullptr;
+ size_keyword = ConsumeIdent(args);
+ } else {
+ break;
+ }
+ } else {
+ CSSPrimitiveValue* center =
+ ConsumeLengthOrPercent(args, context, kValueRangeNonNegative);
+ if (!center)
+ break;
+ if (horizontal_size)
+ return nullptr;
+ horizontal_size = center;
+ center = ConsumeLengthOrPercent(args, context, kValueRangeNonNegative);
+ if (center) {
+ vertical_size = center;
+ ++i;
+ }
+ }
+ }
+
+ // You can specify size as a keyword or a length/percentage, not both.
+ if (size_keyword && horizontal_size)
+ return nullptr;
+ // Circles must have 0 or 1 lengths.
+ if (shape && shape->GetValueID() == CSSValueID::kCircle && vertical_size)
+ return nullptr;
+ // Ellipses must have 0 or 2 length/percentages.
+ if (shape && shape->GetValueID() == CSSValueID::kEllipse && horizontal_size &&
+ !vertical_size) {
+ return nullptr;
+ }
+ // If there's only one size, it must be a length.
+ if (!vertical_size && horizontal_size && horizontal_size->IsPercentage())
+ return nullptr;
+ if ((horizontal_size &&
+ horizontal_size->IsCalculatedPercentageWithLength()) ||
+ (vertical_size && vertical_size->IsCalculatedPercentageWithLength())) {
+ return nullptr;
+ }
+
+ CSSValue* center_x = nullptr;
+ CSSValue* center_y = nullptr;
+ if (args.Peek().Id() == CSSValueID::kAt) {
+ args.ConsumeIncludingWhitespace();
+ ConsumePosition(args, context, UnitlessQuirk::kForbid,
+ base::Optional<WebFeature>(), center_x, center_y);
+ if (!(center_x && center_y))
+ return nullptr;
+ // Right now, CSS radial gradients have the same start and end centers.
+ }
+
+ if ((shape || size_keyword || horizontal_size || center_x || center_y) &&
+ !ConsumeCommaIncludingWhitespace(args)) {
+ return nullptr;
+ }
+
+ cssvalue::CSSGradientValue* result =
+ MakeGarbageCollected<cssvalue::CSSRadialGradientValue>(
+ center_x, center_y, shape, size_keyword, horizontal_size,
+ vertical_size, repeating, cssvalue::kCSSRadialGradient);
+ return ConsumeGradientColorStops(args, context, result,
+ ConsumeGradientLengthOrPercent)
+ ? result
+ : nullptr;
+}
+
+static CSSValue* ConsumeLinearGradient(
+ CSSParserTokenRange& args,
+ const CSSParserContext& context,
+ cssvalue::CSSGradientRepeat repeating,
+ cssvalue::CSSGradientType gradient_type) {
+ bool expect_comma = true;
+ const CSSPrimitiveValue* angle =
+ ConsumeAngle(args, context, WebFeature::kUnitlessZeroAngleGradient);
+ const CSSIdentifierValue* end_x = nullptr;
+ const CSSIdentifierValue* end_y = nullptr;
+ if (!angle) {
+ if (gradient_type == cssvalue::kCSSPrefixedLinearGradient ||
+ ConsumeIdent<CSSValueID::kTo>(args)) {
+ end_x = ConsumeIdent<CSSValueID::kLeft, CSSValueID::kRight>(args);
+ end_y = ConsumeIdent<CSSValueID::kBottom, CSSValueID::kTop>(args);
+ if (!end_x && !end_y) {
+ if (gradient_type == cssvalue::kCSSLinearGradient)
+ return nullptr;
+ end_y = CSSIdentifierValue::Create(CSSValueID::kTop);
+ expect_comma = false;
+ } else if (!end_x) {
+ end_x = ConsumeIdent<CSSValueID::kLeft, CSSValueID::kRight>(args);
+ }
+ } else {
+ expect_comma = false;
+ }
+ }
+
+ if (expect_comma && !ConsumeCommaIncludingWhitespace(args))
+ return nullptr;
+
+ cssvalue::CSSGradientValue* result =
+ MakeGarbageCollected<cssvalue::CSSLinearGradientValue>(
+ end_x, end_y, nullptr, nullptr, angle, repeating, gradient_type);
+ return ConsumeGradientColorStops(args, context, result,
+ ConsumeGradientLengthOrPercent)
+ ? result
+ : nullptr;
+}
+
+static CSSValue* ConsumeConicGradient(CSSParserTokenRange& args,
+ const CSSParserContext& context,
+ cssvalue::CSSGradientRepeat repeating) {
+ const CSSPrimitiveValue* from_angle = nullptr;
+ if (ConsumeIdent<CSSValueID::kFrom>(args)) {
+ if (!(from_angle = ConsumeAngle(args, context,
+ WebFeature::kUnitlessZeroAngleGradient)))
+ return nullptr;
+ }
+
+ CSSValue* center_x = nullptr;
+ CSSValue* center_y = nullptr;
+ if (ConsumeIdent<CSSValueID::kAt>(args)) {
+ if (!ConsumePosition(args, context, UnitlessQuirk::kForbid,
+ base::Optional<WebFeature>(), center_x, center_y))
+ return nullptr;
+ }
+
+ // Comma separator required when fromAngle or position is present.
+ if ((from_angle || center_x || center_y) &&
+ !ConsumeCommaIncludingWhitespace(args)) {
+ return nullptr;
+ }
+
+ auto* result = MakeGarbageCollected<cssvalue::CSSConicGradientValue>(
+ center_x, center_y, from_angle, repeating);
+ return ConsumeGradientColorStops(args, context, result,
+ ConsumeGradientAngleOrPercent)
+ ? result
+ : nullptr;
+}
+
+CSSValue* ConsumeImageOrNone(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ if (range.Peek().Id() == CSSValueID::kNone)
+ return ConsumeIdent(range);
+ return ConsumeImage(range, context);
+}
+
+CSSValue* ConsumeAxis(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ CSSValueID axis_id = range.Peek().Id();
+ if (axis_id == CSSValueID::kX || axis_id == CSSValueID::kY ||
+ axis_id == CSSValueID::kZ) {
+ ConsumeIdent(range);
+ return MakeGarbageCollected<cssvalue::CSSAxisValue>(axis_id);
+ }
+
+ CSSValue* x_dimension = ConsumeNumber(range, context, kValueRangeAll);
+ CSSValue* y_dimension = ConsumeNumber(range, context, kValueRangeAll);
+ CSSValue* z_dimension = ConsumeNumber(range, context, kValueRangeAll);
+ if (!x_dimension || !y_dimension || !z_dimension)
+ return nullptr;
+ double x = To<CSSPrimitiveValue>(x_dimension)->GetDoubleValue();
+ double y = To<CSSPrimitiveValue>(y_dimension)->GetDoubleValue();
+ double z = To<CSSPrimitiveValue>(z_dimension)->GetDoubleValue();
+ return MakeGarbageCollected<cssvalue::CSSAxisValue>(x, y, z);
+}
+
+static CSSValue* ConsumeCrossFade(CSSParserTokenRange& args,
+ const CSSParserContext& context) {
+ CSSValue* from_image_value = ConsumeImageOrNone(args, context);
+ if (!from_image_value || !ConsumeCommaIncludingWhitespace(args))
+ return nullptr;
+ CSSValue* to_image_value = ConsumeImageOrNone(args, context);
+ if (!to_image_value || !ConsumeCommaIncludingWhitespace(args))
+ return nullptr;
+
+ CSSPrimitiveValue* percentage = nullptr;
+ if (CSSPrimitiveValue* percent_value =
+ ConsumePercent(args, context, kValueRangeAll)) {
+ percentage = CSSNumericLiteralValue::Create(
+ clampTo<double>(percent_value->GetDoubleValue() / 100.0, 0, 1),
+ CSSPrimitiveValue::UnitType::kNumber);
+ } else if (CSSPrimitiveValue* number_value =
+ ConsumeNumber(args, context, kValueRangeAll)) {
+ percentage = CSSNumericLiteralValue::Create(
+ clampTo<double>(number_value->GetDoubleValue(), 0, 1),
+ CSSPrimitiveValue::UnitType::kNumber);
+ }
+
+ if (!percentage)
+ return nullptr;
+ return MakeGarbageCollected<cssvalue::CSSCrossfadeValue>(
+ from_image_value, to_image_value, percentage);
+}
+
+static CSSValue* ConsumePaint(CSSParserTokenRange& args,
+ const CSSParserContext& context) {
+ const CSSParserToken& name_token = args.ConsumeIncludingWhitespace();
+ CSSCustomIdentValue* name = ConsumeCustomIdentWithToken(name_token, context);
+ if (!name)
+ return nullptr;
+
+ if (args.AtEnd())
+ return MakeGarbageCollected<CSSPaintValue>(name);
+
+ if (!RuntimeEnabledFeatures::CSSPaintAPIArgumentsEnabled()) {
+ // Arguments not enabled, but exists. Invalid.
+ return nullptr;
+ }
+
+ // Begin parse paint arguments.
+ if (!ConsumeCommaIncludingWhitespace(args))
+ return nullptr;
+
+ // Consume arguments.
+ // TODO(renjieliu): We may want to optimize the implementation by resolve
+ // variables early if paint function is registered.
+ Vector<CSSParserToken> argument_tokens;
+ Vector<scoped_refptr<CSSVariableData>> variable_data;
+ while (!args.AtEnd()) {
+ if (args.Peek().GetType() != kCommaToken) {
+ argument_tokens.AppendVector(ConsumeFunctionArgsOrNot(args));
+ } else {
+ if (!AddCSSPaintArgument(argument_tokens, &variable_data, context))
+ return nullptr;
+ argument_tokens.clear();
+ if (!ConsumeCommaIncludingWhitespace(args))
+ return nullptr;
+ }
+ }
+ if (!AddCSSPaintArgument(argument_tokens, &variable_data, context))
+ return nullptr;
+
+ return MakeGarbageCollected<CSSPaintValue>(name, variable_data);
+}
+
+static CSSValue* ConsumeGeneratedImage(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ CSSValueID id = range.Peek().FunctionId();
+ CSSParserTokenRange range_copy = range;
+ CSSParserTokenRange args = ConsumeFunction(range_copy);
+ CSSValue* result = nullptr;
+ if (id == CSSValueID::kRadialGradient) {
+ result = ConsumeRadialGradient(args, context, cssvalue::kNonRepeating);
+ } else if (id == CSSValueID::kRepeatingRadialGradient) {
+ result = ConsumeRadialGradient(args, context, cssvalue::kRepeating);
+ } else if (id == CSSValueID::kWebkitLinearGradient) {
+ context.Count(WebFeature::kDeprecatedWebKitLinearGradient);
+ result = ConsumeLinearGradient(args, context, cssvalue::kNonRepeating,
+ cssvalue::kCSSPrefixedLinearGradient);
+ } else if (id == CSSValueID::kWebkitRepeatingLinearGradient) {
+ context.Count(WebFeature::kDeprecatedWebKitRepeatingLinearGradient);
+ result = ConsumeLinearGradient(args, context, cssvalue::kRepeating,
+ cssvalue::kCSSPrefixedLinearGradient);
+ } else if (id == CSSValueID::kRepeatingLinearGradient) {
+ result = ConsumeLinearGradient(args, context, cssvalue::kRepeating,
+ cssvalue::kCSSLinearGradient);
+ } else if (id == CSSValueID::kLinearGradient) {
+ result = ConsumeLinearGradient(args, context, cssvalue::kNonRepeating,
+ cssvalue::kCSSLinearGradient);
+ } else if (id == CSSValueID::kWebkitGradient) {
+ context.Count(WebFeature::kDeprecatedWebKitGradient);
+ result = ConsumeDeprecatedGradient(args, context);
+ } else if (id == CSSValueID::kWebkitRadialGradient) {
+ context.Count(WebFeature::kDeprecatedWebKitRadialGradient);
+ result =
+ ConsumeDeprecatedRadialGradient(args, context, cssvalue::kNonRepeating);
+ } else if (id == CSSValueID::kWebkitRepeatingRadialGradient) {
+ context.Count(WebFeature::kDeprecatedWebKitRepeatingRadialGradient);
+ result =
+ ConsumeDeprecatedRadialGradient(args, context, cssvalue::kRepeating);
+ } else if (id == CSSValueID::kConicGradient) {
+ result = ConsumeConicGradient(args, context, cssvalue::kNonRepeating);
+ } else if (id == CSSValueID::kRepeatingConicGradient) {
+ result = ConsumeConicGradient(args, context, cssvalue::kRepeating);
+ } else if (id == CSSValueID::kWebkitCrossFade) {
+ result = ConsumeCrossFade(args, context);
+ } else if (id == CSSValueID::kPaint) {
+ result = context.IsSecureContext() ? ConsumePaint(args, context) : nullptr;
+ }
+ if (!result || !args.AtEnd())
+ return nullptr;
+
+ WebFeature feature;
+ if (id == CSSValueID::kWebkitCrossFade)
+ feature = WebFeature::kWebkitCrossFade;
+ else if (id == CSSValueID::kPaint)
+ feature = WebFeature::kCSSPaintFunction;
+ else
+ feature = WebFeature::kCSSGradient;
+ context.Count(feature);
+
+ range = range_copy;
+ return result;
+}
+
+static CSSValue* CreateCSSImageValueWithReferrer(
+ const AtomicString& raw_value,
+ const CSSParserContext& context) {
+ CSSValue* image_value = MakeGarbageCollected<CSSImageValue>(
+ raw_value, context.CompleteURL(raw_value), context.GetReferrer(),
+ context.IsOriginClean() ? OriginClean::kTrue : OriginClean::kFalse,
+ context.IsAdRelated());
+ return image_value;
+}
+
+static CSSValue* ConsumeImageSet(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ CSSParserTokenRange range_copy = range;
+ CSSParserTokenRange args = ConsumeFunction(range_copy);
+ auto* image_set = MakeGarbageCollected<CSSImageSetValue>(context.Mode());
+ do {
+ AtomicString url_value =
+ ConsumeUrlAsStringView(args, context).ToAtomicString();
+ if (url_value.IsNull())
+ return nullptr;
+
+ CSSValue* image = CreateCSSImageValueWithReferrer(url_value, context);
+ image_set->Append(*image);
+
+ const CSSParserToken& token = args.ConsumeIncludingWhitespace();
+ if (token.GetType() != kDimensionToken)
+ return nullptr;
+ if (token.Value() != "x")
+ return nullptr;
+ DCHECK(token.GetUnitType() == CSSPrimitiveValue::UnitType::kDotsPerPixel);
+ double image_scale_factor = token.NumericValue();
+ if (image_scale_factor <= 0)
+ return nullptr;
+ image_set->Append(*CSSNumericLiteralValue::Create(
+ image_scale_factor, CSSPrimitiveValue::UnitType::kNumber));
+ } while (ConsumeCommaIncludingWhitespace(args));
+ if (!args.AtEnd())
+ return nullptr;
+ range = range_copy;
+ return image_set;
+}
+
+static bool IsGeneratedImage(CSSValueID id) {
+ return id == CSSValueID::kLinearGradient ||
+ id == CSSValueID::kRadialGradient ||
+ id == CSSValueID::kConicGradient ||
+ id == CSSValueID::kRepeatingLinearGradient ||
+ id == CSSValueID::kRepeatingRadialGradient ||
+ id == CSSValueID::kRepeatingConicGradient ||
+ id == CSSValueID::kWebkitLinearGradient ||
+ id == CSSValueID::kWebkitRadialGradient ||
+ id == CSSValueID::kWebkitRepeatingLinearGradient ||
+ id == CSSValueID::kWebkitRepeatingRadialGradient ||
+ id == CSSValueID::kWebkitGradient ||
+ id == CSSValueID::kWebkitCrossFade || id == CSSValueID::kPaint;
+}
+
+CSSValue* ConsumeImage(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ ConsumeGeneratedImagePolicy generated_image) {
+ AtomicString uri = ConsumeUrlAsStringView(range, context).ToAtomicString();
+ if (!uri.IsNull())
+ return CreateCSSImageValueWithReferrer(uri, context);
+ if (range.Peek().GetType() == kFunctionToken) {
+ CSSValueID id = range.Peek().FunctionId();
+ if (id == CSSValueID::kWebkitImageSet)
+ return ConsumeImageSet(range, context);
+ if (generated_image == ConsumeGeneratedImagePolicy::kAllow &&
+ IsGeneratedImage(id)) {
+ return ConsumeGeneratedImage(range, context);
+ }
+ return ConsumeInternalLightDark(ConsumeImageOrNone, range, context);
+ }
+ return nullptr;
+}
+
+// https://drafts.csswg.org/css-shapes-1/#typedef-shape-box
+CSSIdentifierValue* ConsumeShapeBox(CSSParserTokenRange& range) {
+ return ConsumeIdent<CSSValueID::kContentBox, CSSValueID::kPaddingBox,
+ CSSValueID::kBorderBox, CSSValueID::kMarginBox>(range);
+}
+
+void AddProperty(CSSPropertyID resolved_property,
+ CSSPropertyID current_shorthand,
+ const CSSValue& value,
+ bool important,
+ IsImplicitProperty implicit,
+ HeapVector<CSSPropertyValue, 256>& properties) {
+ DCHECK(!isPropertyAlias(resolved_property));
+ DCHECK(implicit == IsImplicitProperty::kNotImplicit ||
+ implicit == IsImplicitProperty::kImplicit);
+
+ int shorthand_index = 0;
+ bool set_from_shorthand = false;
+
+ if (isValidCSSPropertyID(current_shorthand)) {
+ Vector<StylePropertyShorthand, 4> shorthands;
+ getMatchingShorthandsForLonghand(resolved_property, &shorthands);
+ set_from_shorthand = true;
+ if (shorthands.size() > 1) {
+ shorthand_index =
+ indexOfShorthandForLonghand(current_shorthand, shorthands);
+ }
+ }
+
+ properties.push_back(CSSPropertyValue(
+ CSSProperty::Get(resolved_property), value, important, set_from_shorthand,
+ shorthand_index, implicit == IsImplicitProperty::kImplicit));
+}
+
+CSSValue* ConsumeTransformValue(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ bool use_legacy_parsing = false;
+ return ConsumeTransformValue(range, context, use_legacy_parsing);
+}
+
+CSSValue* ConsumeTransformList(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ return ConsumeTransformList(range, context, CSSParserLocalContext());
+}
+
+CSSValue* ConsumeFilterFunctionList(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ if (range.Peek().Id() == CSSValueID::kNone)
+ return ConsumeIdent(range);
+
+ CSSValueList* list = CSSValueList::CreateSpaceSeparated();
+ do {
+ CSSValue* filter_value = ConsumeUrl(range, context);
+ if (!filter_value) {
+ filter_value = ConsumeFilterFunction(range, context);
+ if (!filter_value)
+ return nullptr;
+ }
+ list->Append(*filter_value);
+ } while (!range.AtEnd());
+ return list;
+}
+
+void CountKeywordOnlyPropertyUsage(CSSPropertyID property,
+ const CSSParserContext& context,
+ CSSValueID value_id) {
+ if (!context.IsUseCounterRecordingEnabled())
+ return;
+ switch (property) {
+ case CSSPropertyID::kAppearance:
+ if (value_id == CSSValueID::kInnerSpinButton ||
+ value_id == CSSValueID::kMediaSlider ||
+ value_id == CSSValueID::kMediaSliderthumb ||
+ value_id == CSSValueID::kMediaVolumeSlider ||
+ value_id == CSSValueID::kMediaVolumeSliderthumb ||
+ value_id == CSSValueID::kSliderVertical ||
+ value_id == CSSValueID::kSliderthumbHorizontal ||
+ value_id == CSSValueID::kSliderthumbVertical ||
+ value_id == CSSValueID::kSearchfieldCancelButton) {
+ if (const auto* document = context.GetDocument()) {
+ document->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kOther,
+ mojom::blink::ConsoleMessageLevel::kWarning,
+ String("The keyword '") + getValueName(value_id) +
+ "' specified to an 'appearance' property is not "
+ "standardized. It will be removed in the future."));
+ }
+ }
+ FALLTHROUGH;
+ // This function distinguishes 'appearance' and '-webkit-appearance'
+ // though other property aliases are handles as their aliased properties.
+ // See Appearance::ParseSingleValue().
+ case CSSPropertyID::kAliasWebkitAppearance: {
+ WebFeature feature;
+ if (value_id == CSSValueID::kNone) {
+ feature = WebFeature::kCSSValueAppearanceNone;
+ } else {
+ feature = WebFeature::kCSSValueAppearanceNotNone;
+ if (value_id == CSSValueID::kButton)
+ feature = WebFeature::kCSSValueAppearanceButton;
+ else if (value_id == CSSValueID::kCheckbox)
+ feature = WebFeature::kCSSValueAppearanceCheckbox;
+ else if (value_id == CSSValueID::kInnerSpinButton)
+ feature = WebFeature::kCSSValueAppearanceInnerSpinButton;
+ else if (value_id == CSSValueID::kMenulist)
+ feature = WebFeature::kCSSValueAppearanceMenulist;
+ else if (value_id == CSSValueID::kMenulistButton)
+ feature = WebFeature::kCSSValueAppearanceMenulistButton;
+ else if (value_id == CSSValueID::kMeter)
+ feature = WebFeature::kCSSValueAppearanceMeter;
+ else if (value_id == CSSValueID::kListbox)
+ feature = WebFeature::kCSSValueAppearanceListbox;
+ else if (value_id == CSSValueID::kProgressBar)
+ feature = WebFeature::kCSSValueAppearanceProgressBar;
+ else if (value_id == CSSValueID::kPushButton)
+ feature = WebFeature::kCSSValueAppearancePushButton;
+ else if (value_id == CSSValueID::kRadio)
+ feature = WebFeature::kCSSValueAppearanceRadio;
+ else if (value_id == CSSValueID::kSearchfieldCancelButton)
+ feature = WebFeature::kCSSValueAppearanceSearchCancel;
+ else if (value_id == CSSValueID::kSquareButton)
+ feature = WebFeature::kCSSValueAppearanceSquareButton;
+ else if (value_id == CSSValueID::kSearchfield)
+ feature = WebFeature::kCSSValueAppearanceSearchField;
+ else if (value_id == CSSValueID::kTextarea)
+ feature = WebFeature::kCSSValueAppearanceTextarea;
+ else if (value_id == CSSValueID::kTextfield)
+ feature = WebFeature::kCSSValueAppearanceTextField;
+ else
+ feature = WebFeature::kCSSValueAppearanceOthers;
+ }
+ context.Count(feature);
+ break;
+ }
+
+ case CSSPropertyID::kWebkitUserModify: {
+ switch (value_id) {
+ case CSSValueID::kReadOnly:
+ context.Count(WebFeature::kCSSValueUserModifyReadOnly);
+ break;
+ case CSSValueID::kReadWrite:
+ context.Count(WebFeature::kCSSValueUserModifyReadWrite);
+ break;
+ case CSSValueID::kReadWritePlaintextOnly:
+ context.Count(WebFeature::kCSSValueUserModifyReadWritePlaintextOnly);
+ break;
+ default:
+ NOTREACHED();
+ }
+ break;
+ }
+ case CSSPropertyID::kDisplay:
+ if (value_id == CSSValueID::kContents)
+ context.Count(WebFeature::kCSSValueDisplayContents);
+ break;
+ case CSSPropertyID::kOverflowX:
+ case CSSPropertyID::kOverflowY:
+ if (value_id == CSSValueID::kOverlay)
+ context.Count(WebFeature::kCSSValueOverflowOverlay);
+ break;
+ default:
+ break;
+ }
+}
+
+const CSSValue* ParseLonghand(CSSPropertyID unresolved_property,
+ CSSPropertyID current_shorthand,
+ const CSSParserContext& context,
+ CSSParserTokenRange& range) {
+ CSSPropertyID property_id = resolveCSSPropertyID(unresolved_property);
+ DCHECK(!CSSProperty::Get(property_id).IsShorthand());
+ if (CSSParserFastPaths::IsKeywordPropertyID(property_id)) {
+ if (CSSParserFastPaths::IsValidKeywordPropertyAndValue(
+ property_id, range.Peek().Id(), context.Mode())) {
+ CountKeywordOnlyPropertyUsage(property_id, context, range.Peek().Id());
+ return ConsumeIdent(range);
+ }
+
+ // Some properties need to fallback onto the regular parser.
+ if (!CSSParserFastPaths::IsPartialKeywordPropertyID(property_id))
+ return nullptr;
+ }
+
+ const auto local_context =
+ CSSParserLocalContext()
+ .WithAliasParsing(isPropertyAlias(unresolved_property))
+ .WithCurrentShorthand(current_shorthand);
+
+ const CSSValue* result = To<Longhand>(CSSProperty::Get(property_id))
+ .ParseSingleValue(range, context, local_context);
+ return result;
+}
+
+bool ConsumeShorthandVia2Longhands(
+ const StylePropertyShorthand& shorthand,
+ bool important,
+ const CSSParserContext& context,
+ CSSParserTokenRange& range,
+ HeapVector<CSSPropertyValue, 256>& properties) {
+ DCHECK_EQ(shorthand.length(), 2u);
+ const CSSProperty** longhands = shorthand.properties();
+
+ const CSSValue* start =
+ ParseLonghand(longhands[0]->PropertyID(), shorthand.id(), context, range);
+
+ if (!start)
+ return false;
+
+ const CSSValue* end =
+ ParseLonghand(longhands[1]->PropertyID(), shorthand.id(), context, range);
+
+ if (shorthand.id() == CSSPropertyID::kOverflow && start && end) {
+ context.Count(WebFeature::kTwoValuedOverflow);
+ }
+
+ if (!end)
+ end = start;
+ AddProperty(longhands[0]->PropertyID(), shorthand.id(), *start, important,
+ IsImplicitProperty::kNotImplicit, properties);
+ AddProperty(longhands[1]->PropertyID(), shorthand.id(), *end, important,
+ IsImplicitProperty::kNotImplicit, properties);
+
+ return range.AtEnd();
+}
+
+bool ConsumeShorthandVia4Longhands(
+ const StylePropertyShorthand& shorthand,
+ bool important,
+ const CSSParserContext& context,
+ CSSParserTokenRange& range,
+ HeapVector<CSSPropertyValue, 256>& properties) {
+ DCHECK_EQ(shorthand.length(), 4u);
+ const CSSProperty** longhands = shorthand.properties();
+ const CSSValue* top =
+ ParseLonghand(longhands[0]->PropertyID(), shorthand.id(), context, range);
+
+ if (!top)
+ return false;
+
+ const CSSValue* right =
+ ParseLonghand(longhands[1]->PropertyID(), shorthand.id(), context, range);
+
+ const CSSValue* bottom = nullptr;
+ const CSSValue* left = nullptr;
+ if (right) {
+ bottom = ParseLonghand(longhands[2]->PropertyID(), shorthand.id(), context,
+ range);
+ if (bottom) {
+ left = ParseLonghand(longhands[3]->PropertyID(), shorthand.id(), context,
+ range);
+ }
+ }
+
+ if (!right)
+ right = top;
+ if (!bottom)
+ bottom = top;
+ if (!left)
+ left = right;
+
+ AddProperty(longhands[0]->PropertyID(), shorthand.id(), *top, important,
+ IsImplicitProperty::kNotImplicit, properties);
+ AddProperty(longhands[1]->PropertyID(), shorthand.id(), *right, important,
+ IsImplicitProperty::kNotImplicit, properties);
+ AddProperty(longhands[2]->PropertyID(), shorthand.id(), *bottom, important,
+ IsImplicitProperty::kNotImplicit, properties);
+ AddProperty(longhands[3]->PropertyID(), shorthand.id(), *left, important,
+ IsImplicitProperty::kNotImplicit, properties);
+
+ return range.AtEnd();
+}
+
+bool ConsumeShorthandGreedilyViaLonghands(
+ const StylePropertyShorthand& shorthand,
+ bool important,
+ const CSSParserContext& context,
+ CSSParserTokenRange& range,
+ HeapVector<CSSPropertyValue, 256>& properties) {
+ // Existing shorthands have at most 6 longhands.
+ DCHECK_LE(shorthand.length(), 6u);
+ const CSSValue* longhands[6] = {nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr};
+ const CSSProperty** shorthand_properties = shorthand.properties();
+ do {
+ bool found_longhand = false;
+ for (size_t i = 0; !found_longhand && i < shorthand.length(); ++i) {
+ if (longhands[i])
+ continue;
+ longhands[i] = ParseLonghand(shorthand_properties[i]->PropertyID(),
+ shorthand.id(), context, range);
+
+ if (longhands[i])
+ found_longhand = true;
+ }
+ if (!found_longhand)
+ return false;
+ } while (!range.AtEnd());
+
+ for (size_t i = 0; i < shorthand.length(); ++i) {
+ if (longhands[i]) {
+ AddProperty(shorthand_properties[i]->PropertyID(), shorthand.id(),
+ *longhands[i], important, IsImplicitProperty::kNotImplicit,
+ properties);
+ } else {
+ AddProperty(shorthand_properties[i]->PropertyID(), shorthand.id(),
+ *CSSInitialValue::Create(), important,
+ IsImplicitProperty::kNotImplicit, properties);
+ }
+ }
+ return true;
+}
+
+void AddExpandedPropertyForValue(
+ CSSPropertyID property,
+ const CSSValue& value,
+ bool important,
+ HeapVector<CSSPropertyValue, 256>& properties) {
+ const StylePropertyShorthand& shorthand = shorthandForProperty(property);
+ unsigned shorthand_length = shorthand.length();
+ DCHECK(shorthand_length);
+ const CSSProperty** longhands = shorthand.properties();
+ for (unsigned i = 0; i < shorthand_length; ++i) {
+ AddProperty(longhands[i]->PropertyID(), property, value, important,
+ IsImplicitProperty::kNotImplicit, properties);
+ }
+}
+
bool IsBaselineKeyword(CSSValueID id) {
- return css_property_parser_helpers::IdentMatches<
- CSSValueID::kFirst, CSSValueID::kLast, CSSValueID::kBaseline>(id);
+ return IdentMatches<CSSValueID::kFirst, CSSValueID::kLast,
+ CSSValueID::kBaseline>(id);
}
bool IsSelfPositionKeyword(CSSValueID id) {
- return css_property_parser_helpers::IdentMatches<
- CSSValueID::kStart, CSSValueID::kEnd, CSSValueID::kCenter,
- CSSValueID::kSelfStart, CSSValueID::kSelfEnd, CSSValueID::kFlexStart,
- CSSValueID::kFlexEnd>(id);
+ return IdentMatches<CSSValueID::kStart, CSSValueID::kEnd, CSSValueID::kCenter,
+ CSSValueID::kSelfStart, CSSValueID::kSelfEnd,
+ CSSValueID::kFlexStart, CSSValueID::kFlexEnd>(id);
}
bool IsSelfPositionOrLeftOrRightKeyword(CSSValueID id) {
@@ -449,9 +2572,8 @@ bool IsSelfPositionOrLeftOrRightKeyword(CSSValueID id) {
}
bool IsContentPositionKeyword(CSSValueID id) {
- return css_property_parser_helpers::IdentMatches<
- CSSValueID::kStart, CSSValueID::kEnd, CSSValueID::kCenter,
- CSSValueID::kFlexStart, CSSValueID::kFlexEnd>(id);
+ return IdentMatches<CSSValueID::kStart, CSSValueID::kEnd, CSSValueID::kCenter,
+ CSSValueID::kFlexStart, CSSValueID::kFlexEnd>(id);
}
bool IsContentPositionOrLeftOrRightKeyword(CSSValueID id) {
@@ -465,15 +2587,46 @@ bool IsCSSWideKeyword(CSSValueID id) {
(id == CSSValueID::kRevert));
}
+// https://drafts.csswg.org/css-values-4/#css-wide-keywords
+bool IsCSSWideKeyword(StringView keyword) {
+ return EqualIgnoringASCIICase(keyword, "initial") ||
+ EqualIgnoringASCIICase(keyword, "inherit") ||
+ EqualIgnoringASCIICase(keyword, "unset") ||
+ (RuntimeEnabledFeatures::CSSRevertEnabled() &&
+ EqualIgnoringASCIICase(keyword, "revert"));
+}
+
+// https://drafts.csswg.org/css-cascade/#default
+bool IsRevertKeyword(StringView keyword) {
+ return EqualIgnoringASCIICase(keyword, "revert");
+}
+
+// https://drafts.csswg.org/css-values-4/#identifier-value
+bool IsDefaultKeyword(StringView keyword) {
+ return EqualIgnoringASCIICase(keyword, "default");
+}
+
+// https://drafts.csswg.org/css-syntax/#typedef-hash-token
+bool IsHashIdentifier(const CSSParserToken& token) {
+ return token.GetType() == kHashToken &&
+ token.GetHashTokenType() == kHashTokenId;
+}
+
+bool IsTimelineName(const CSSParserToken& token) {
+ if (token.GetType() == kStringToken)
+ return true;
+ return token.GetType() == kIdentToken &&
+ IsCustomIdent<CSSValueID::kNone>(token.Id());
+}
+
CSSValue* ConsumeScrollOffset(CSSParserTokenRange& range,
const CSSParserContext& context) {
range.ConsumeWhitespace();
- if (css_property_parser_helpers::IdentMatches<CSSValueID::kAuto>(
- range.Peek().Id()))
- return css_property_parser_helpers::ConsumeIdent(range);
+ if (IdentMatches<CSSValueID::kAuto>(range.Peek().Id()))
+ return ConsumeIdent(range);
CSSParserContext::ParserModeOverridingScope scope(context, kHTMLStandardMode);
- CSSValue* value = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative);
+ CSSValue* value =
+ ConsumeLengthOrPercent(range, context, kValueRangeNonNegative);
if (!range.AtEnd())
return nullptr;
return value;
@@ -485,7 +2638,7 @@ CSSValue* ConsumeSelfPositionOverflowPosition(
DCHECK(is_position_keyword);
CSSValueID id = range.Peek().Id();
if (IsAuto(id) || IsNormalOrStretch(id))
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
if (IsBaselineKeyword(id))
return ConsumeBaselineKeyword(range);
@@ -493,8 +2646,7 @@ CSSValue* ConsumeSelfPositionOverflowPosition(
CSSIdentifierValue* overflow_position = ConsumeOverflowPositionKeyword(range);
if (!is_position_keyword(range.Peek().Id()))
return nullptr;
- CSSIdentifierValue* self_position =
- css_property_parser_helpers::ConsumeIdent(range);
+ CSSIdentifierValue* self_position = ConsumeIdent(range);
if (overflow_position) {
return MakeGarbageCollected<CSSValuePair>(
overflow_position, self_position, CSSValuePair::kDropIdenticalValues);
@@ -507,7 +2659,7 @@ CSSValue* ConsumeContentDistributionOverflowPosition(
IsPositionKeyword is_position_keyword) {
DCHECK(is_position_keyword);
CSSValueID id = range.Peek().Id();
- if (css_property_parser_helpers::IdentMatches<CSSValueID::kNormal>(id)) {
+ if (IdentMatches<CSSValueID::kNormal>(id)) {
return MakeGarbageCollected<cssvalue::CSSContentDistributionValue>(
CSSValueID::kInvalid, range.ConsumeIncludingWhitespace().Id(),
CSSValueID::kInvalid);
@@ -543,16 +2695,15 @@ CSSValue* ConsumeContentDistributionOverflowPosition(
CSSValue* ConsumeAnimationIterationCount(CSSParserTokenRange& range,
const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kInfinite)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeNumber(range, context,
- kValueRangeNonNegative);
+ return ConsumeIdent(range);
+ return ConsumeNumber(range, context, kValueRangeNonNegative);
}
CSSValue* ConsumeAnimationName(CSSParserTokenRange& range,
const CSSParserContext& context,
bool allow_quoted_name) {
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
if (allow_quoted_name && range.Peek().GetType() == kStringToken) {
// Legacy support for strings in prefixed animations.
@@ -565,7 +2716,16 @@ CSSValue* ConsumeAnimationName(CSSParserTokenRange& range,
token.Value().ToAtomicString());
}
- return css_property_parser_helpers::ConsumeCustomIdent(range, context);
+ return ConsumeCustomIdent(range, context);
+}
+
+CSSValue* ConsumeAnimationTimeline(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ if (auto* value = ConsumeIdent<CSSValueID::kNone, CSSValueID::kAuto>(range))
+ return value;
+ if (auto* value = ConsumeCustomIdent(range, context))
+ return value;
+ return ConsumeString(range);
}
CSSValue* ConsumeAnimationTimingFunction(CSSParserTokenRange& range,
@@ -575,7 +2735,7 @@ CSSValue* ConsumeAnimationTimingFunction(CSSParserTokenRange& range,
id == CSSValueID::kEaseIn || id == CSSValueID::kEaseOut ||
id == CSSValueID::kEaseInOut || id == CSSValueID::kStepStart ||
id == CSSValueID::kStepEnd)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
CSSValueID function = range.Peek().FunctionId();
if (function == CSSValueID::kSteps)
@@ -628,7 +2788,7 @@ bool ConsumeAnimationShorthand(
}
parsed_longhand[i] = false;
}
- } while (css_property_parser_helpers::ConsumeCommaIncludingWhitespace(range));
+ } while (ConsumeCommaIncludingWhitespace(range));
return true;
}
@@ -648,33 +2808,25 @@ void AddBackgroundValue(CSSValue*& list, CSSValue* value) {
}
CSSValue* ConsumeBackgroundAttachment(CSSParserTokenRange& range) {
- return css_property_parser_helpers::ConsumeIdent<
- CSSValueID::kScroll, CSSValueID::kFixed, CSSValueID::kLocal>(range);
+ return ConsumeIdent<CSSValueID::kScroll, CSSValueID::kFixed,
+ CSSValueID::kLocal>(range);
}
CSSValue* ConsumeBackgroundBlendMode(CSSParserTokenRange& range) {
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kNormal || id == CSSValueID::kOverlay ||
(id >= CSSValueID::kMultiply && id <= CSSValueID::kLuminosity))
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
return nullptr;
}
CSSValue* ConsumeBackgroundBox(CSSParserTokenRange& range) {
- return css_property_parser_helpers::ConsumeIdent<
- CSSValueID::kBorderBox, CSSValueID::kPaddingBox, CSSValueID::kContentBox>(
- range);
+ return ConsumeIdent<CSSValueID::kBorderBox, CSSValueID::kPaddingBox,
+ CSSValueID::kContentBox>(range);
}
CSSValue* ConsumeBackgroundComposite(CSSParserTokenRange& range) {
- return css_property_parser_helpers::ConsumeIdentRange(
- range, CSSValueID::kClear, CSSValueID::kPlusLighter);
-}
-
-CSSValue* ConsumeMaskSourceType(CSSParserTokenRange& range) {
- DCHECK(RuntimeEnabledFeatures::CSSMaskSourceTypeEnabled());
- return css_property_parser_helpers::ConsumeIdent<
- CSSValueID::kAuto, CSSValueID::kAlpha, CSSValueID::kLuminance>(range);
+ return ConsumeIdentRange(range, CSSValueID::kClear, CSSValueID::kPlusLighter);
}
CSSPrimitiveValue* ConsumeLengthOrPercentCountNegative(
@@ -682,8 +2834,7 @@ CSSPrimitiveValue* ConsumeLengthOrPercentCountNegative(
const CSSParserContext& context,
base::Optional<WebFeature> negative_size) {
CSSPrimitiveValue* result = ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, kValueRangeNonNegative, UnitlessQuirk::kForbid);
if (!result && negative_size)
context.Count(*negative_size);
return result;
@@ -693,14 +2844,12 @@ CSSValue* ConsumeBackgroundSize(CSSParserTokenRange& range,
const CSSParserContext& context,
base::Optional<WebFeature> negative_size,
ParsingStyle parsing_style) {
- if (css_property_parser_helpers::IdentMatches<CSSValueID::kContain,
- CSSValueID::kCover>(
+ if (IdentMatches<CSSValueID::kContain, CSSValueID::kCover>(
range.Peek().Id())) {
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
}
- CSSValue* horizontal =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kAuto>(range);
+ CSSValue* horizontal = ConsumeIdent<CSSValueID::kAuto>(range);
if (!horizontal) {
horizontal =
ConsumeLengthOrPercentCountNegative(range, context, negative_size);
@@ -732,18 +2881,17 @@ static void SetAllowsNegativePercentageReference(CSSValue* value) {
math_value->SetAllowsNegativePercentageReference();
}
-bool ConsumeBackgroundPosition(
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- css_property_parser_helpers::UnitlessQuirk unitless,
- CSSValue*& result_x,
- CSSValue*& result_y) {
+bool ConsumeBackgroundPosition(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ UnitlessQuirk unitless,
+ CSSValue*& result_x,
+ CSSValue*& result_y) {
do {
CSSValue* position_x = nullptr;
CSSValue* position_y = nullptr;
- if (!css_property_parser_helpers::ConsumePosition(
- range, context, unitless,
- WebFeature::kThreeValuedPositionBackground, position_x, position_y))
+ if (!ConsumePosition(range, context, unitless,
+ WebFeature::kThreeValuedPositionBackground, position_x,
+ position_y))
return false;
// TODO(crbug.com/825895): So far, 'background-position' is the only
// property that allows resolving a percentage against a negative value. If
@@ -753,7 +2901,7 @@ bool ConsumeBackgroundPosition(
SetAllowsNegativePercentageReference(position_y);
AddBackgroundValue(result_x, position_x);
AddBackgroundValue(result_y, position_y);
- } while (css_property_parser_helpers::ConsumeCommaIncludingWhitespace(range));
+ } while (ConsumeCommaIncludingWhitespace(range));
return true;
}
@@ -761,12 +2909,12 @@ CSSValue* ConsumePrefixedBackgroundBox(CSSParserTokenRange& range,
AllowTextValue allow_text_value) {
// The values 'border', 'padding' and 'content' are deprecated and do not
// apply to the version of the property that has the -webkit- prefix removed.
- if (CSSValue* value = css_property_parser_helpers::ConsumeIdentRange(
- range, CSSValueID::kBorder, CSSValueID::kPaddingBox))
+ if (CSSValue* value = ConsumeIdentRange(range, CSSValueID::kBorder,
+ CSSValueID::kPaddingBox))
return value;
if (allow_text_value == AllowTextValue::kAllow &&
range.Peek().Id() == CSSValueID::kText)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
return nullptr;
}
@@ -775,18 +2923,17 @@ CSSValue* ParseBackgroundBox(CSSParserTokenRange& range,
AllowTextValue alias_allow_text_value) {
// This is legacy behavior that does not match spec, see crbug.com/604023
if (local_context.UseAliasParsing()) {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
- ConsumePrefixedBackgroundBox, range, alias_allow_text_value);
+ return ConsumeCommaSeparatedList(ConsumePrefixedBackgroundBox, range,
+ alias_allow_text_value);
}
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
- ConsumeBackgroundBox, range);
+ return ConsumeCommaSeparatedList(ConsumeBackgroundBox, range);
}
CSSValue* ParseBackgroundOrMaskSize(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext& local_context,
base::Optional<WebFeature> negative_size) {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
+ return ConsumeCommaSeparatedList(
ConsumeBackgroundSize, range, context, negative_size,
local_context.UseAliasParsing() ? ParsingStyle::kLegacy
: ParsingStyle::kNotLegacy);
@@ -806,7 +2953,7 @@ CSSValue* ConsumeBackgroundComponent(CSSPropertyID resolved_property,
return ConsumeBackgroundBox(range);
case CSSPropertyID::kBackgroundImage:
case CSSPropertyID::kWebkitMaskImage:
- return css_property_parser_helpers::ConsumeImageOrNone(range, context);
+ return ConsumeImageOrNone(range, context);
case CSSPropertyID::kBackgroundPositionX:
case CSSPropertyID::kWebkitMaskPositionX:
return ConsumePositionLonghand<CSSValueID::kLeft, CSSValueID::kRight>(
@@ -824,7 +2971,7 @@ CSSValue* ConsumeBackgroundComponent(CSSPropertyID resolved_property,
WebFeature::kNegativeMaskSize,
ParsingStyle::kNotLegacy);
case CSSPropertyID::kBackgroundColor:
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return ConsumeColor(range, context);
case CSSPropertyID::kWebkitMaskClip:
return ConsumePrefixedBackgroundBox(range, AllowTextValue::kAllow);
case CSSPropertyID::kWebkitMaskOrigin:
@@ -880,17 +3027,15 @@ bool ParseBackgroundOrMask(bool important,
ConsumeRepeatStyleComponent(range, value, value_y, implicit);
} else if (property.IDEquals(CSSPropertyID::kBackgroundPositionX) ||
property.IDEquals(CSSPropertyID::kWebkitMaskPositionX)) {
- if (!css_property_parser_helpers::ConsumePosition(
- range, context,
- css_property_parser_helpers::UnitlessQuirk::kForbid,
- WebFeature::kThreeValuedPositionBackground, value, value_y))
+ if (!ConsumePosition(range, context, UnitlessQuirk::kForbid,
+ WebFeature::kThreeValuedPositionBackground,
+ value, value_y))
continue;
if (value)
bg_position_parsed_in_current_layer = true;
} else if (property.IDEquals(CSSPropertyID::kBackgroundSize) ||
property.IDEquals(CSSPropertyID::kWebkitMaskSize)) {
- if (!css_property_parser_helpers::ConsumeSlashIncludingWhitespace(
- range))
+ if (!ConsumeSlashIncludingWhitespace(range))
continue;
value = ConsumeBackgroundSize(
range, context,
@@ -946,7 +3091,7 @@ bool ParseBackgroundOrMask(bool important,
AddBackgroundValue(longhands[i], CSSInitialValue::Create());
}
}
- } while (css_property_parser_helpers::ConsumeCommaIncludingWhitespace(range));
+ } while (ConsumeCommaIncludingWhitespace(range));
if (!range.AtEnd())
return false;
@@ -955,12 +3100,10 @@ bool ParseBackgroundOrMask(bool important,
if (property.IDEquals(CSSPropertyID::kBackgroundSize) && longhands[i] &&
context.UseLegacyBackgroundSizeShorthandBehavior())
continue;
- css_property_parser_helpers::AddProperty(
- property.PropertyID(), shorthand.id(), *longhands[i], important,
- implicit
- ? css_property_parser_helpers::IsImplicitProperty::kImplicit
- : css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ AddProperty(property.PropertyID(), shorthand.id(), *longhands[i], important,
+ implicit ? IsImplicitProperty::kImplicit
+ : IsImplicitProperty::kNotImplicit,
+ properties);
}
return true;
}
@@ -969,27 +3112,25 @@ bool ConsumeRepeatStyleComponent(CSSParserTokenRange& range,
CSSValue*& value1,
CSSValue*& value2,
bool& implicit) {
- if (css_property_parser_helpers::ConsumeIdent<CSSValueID::kRepeatX>(range)) {
+ if (ConsumeIdent<CSSValueID::kRepeatX>(range)) {
value1 = CSSIdentifierValue::Create(CSSValueID::kRepeat);
value2 = CSSIdentifierValue::Create(CSSValueID::kNoRepeat);
implicit = true;
return true;
}
- if (css_property_parser_helpers::ConsumeIdent<CSSValueID::kRepeatY>(range)) {
+ if (ConsumeIdent<CSSValueID::kRepeatY>(range)) {
value1 = CSSIdentifierValue::Create(CSSValueID::kNoRepeat);
value2 = CSSIdentifierValue::Create(CSSValueID::kRepeat);
implicit = true;
return true;
}
- value1 = css_property_parser_helpers::ConsumeIdent<
- CSSValueID::kRepeat, CSSValueID::kNoRepeat, CSSValueID::kRound,
- CSSValueID::kSpace>(range);
+ value1 = ConsumeIdent<CSSValueID::kRepeat, CSSValueID::kNoRepeat,
+ CSSValueID::kRound, CSSValueID::kSpace>(range);
if (!value1)
return false;
- value2 = css_property_parser_helpers::ConsumeIdent<
- CSSValueID::kRepeat, CSSValueID::kNoRepeat, CSSValueID::kRound,
- CSSValueID::kSpace>(range);
+ value2 = ConsumeIdent<CSSValueID::kRepeat, CSSValueID::kNoRepeat,
+ CSSValueID::kRound, CSSValueID::kSpace>(range);
if (!value2) {
value2 = value1;
implicit = true;
@@ -1008,7 +3149,7 @@ bool ConsumeRepeatStyle(CSSParserTokenRange& range,
return false;
AddBackgroundValue(result_x, repeat_x);
AddBackgroundValue(result_y, repeat_y);
- } while (css_property_parser_helpers::ConsumeCommaIncludingWhitespace(range));
+ } while (ConsumeCommaIncludingWhitespace(range));
return true;
}
@@ -1035,7 +3176,7 @@ bool ConsumeBorderImageComponents(CSSParserTokenRange& range,
DefaultFill default_fill) {
do {
if (!source) {
- source = css_property_parser_helpers::ConsumeImageOrNone(range, context);
+ source = ConsumeImageOrNone(range, context);
if (source)
continue;
}
@@ -1049,11 +3190,9 @@ bool ConsumeBorderImageComponents(CSSParserTokenRange& range,
if (slice) {
DCHECK(!width);
DCHECK(!outset);
- if (css_property_parser_helpers::ConsumeSlashIncludingWhitespace(
- range)) {
+ if (ConsumeSlashIncludingWhitespace(range)) {
width = ConsumeBorderImageWidth(range, context);
- if (css_property_parser_helpers::ConsumeSlashIncludingWhitespace(
- range)) {
+ if (ConsumeSlashIncludingWhitespace(range)) {
outset = ConsumeBorderImageOutset(range, context);
if (!outset)
return false;
@@ -1085,16 +3224,14 @@ CSSValue* ConsumeBorderImageRepeat(CSSParserTokenRange& range) {
CSSValue* ConsumeBorderImageSlice(CSSParserTokenRange& range,
const CSSParserContext& context,
DefaultFill default_fill) {
- bool fill =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kFill>(range);
+ bool fill = ConsumeIdent<CSSValueID::kFill>(range);
CSSValue* slices[4] = {nullptr};
for (size_t index = 0; index < 4; ++index) {
- CSSPrimitiveValue* value = css_property_parser_helpers::ConsumePercent(
- range, context, kValueRangeNonNegative);
+ CSSPrimitiveValue* value =
+ ConsumePercent(range, context, kValueRangeNonNegative);
if (!value) {
- value = css_property_parser_helpers::ConsumeNumber(
- range, context, kValueRangeNonNegative);
+ value = ConsumeNumber(range, context, kValueRangeNonNegative);
}
if (!value)
break;
@@ -1102,12 +3239,12 @@ CSSValue* ConsumeBorderImageSlice(CSSParserTokenRange& range,
}
if (!slices[0])
return nullptr;
- if (css_property_parser_helpers::ConsumeIdent<CSSValueID::kFill>(range)) {
+ if (ConsumeIdent<CSSValueID::kFill>(range)) {
if (fill)
return nullptr;
fill = true;
}
- css_property_parser_helpers::Complete4Sides(slices);
+ Complete4Sides(slices);
if (default_fill == DefaultFill::kFill)
fill = true;
return MakeGarbageCollected<cssvalue::CSSBorderImageSliceValue>(
@@ -1123,18 +3260,15 @@ CSSValue* ConsumeBorderImageWidth(CSSParserTokenRange& range,
CSSValue* value = nullptr;
for (size_t index = 0; index < 4; ++index) {
- value = css_property_parser_helpers::ConsumeNumber(range, context,
- kValueRangeNonNegative);
+ value = ConsumeNumber(range, context, kValueRangeNonNegative);
if (!value) {
CSSParserContext::ParserModeOverridingScope scope(context,
kHTMLStandardMode);
- value = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ value = ConsumeLengthOrPercent(range, context, kValueRangeNonNegative,
+ UnitlessQuirk::kForbid);
}
if (!value) {
- value =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kAuto>(range);
+ value = ConsumeIdent<CSSValueID::kAuto>(range);
}
if (!value)
break;
@@ -1142,7 +3276,7 @@ CSSValue* ConsumeBorderImageWidth(CSSParserTokenRange& range,
}
if (!widths[0])
return nullptr;
- css_property_parser_helpers::Complete4Sides(widths);
+ Complete4Sides(widths);
return MakeGarbageCollected<CSSQuadValue>(widths[0], widths[1], widths[2],
widths[3],
CSSQuadValue::kSerializeAsQuad);
@@ -1154,13 +3288,11 @@ CSSValue* ConsumeBorderImageOutset(CSSParserTokenRange& range,
CSSValue* value = nullptr;
for (size_t index = 0; index < 4; ++index) {
- value = css_property_parser_helpers::ConsumeNumber(range, context,
- kValueRangeNonNegative);
+ value = ConsumeNumber(range, context, kValueRangeNonNegative);
if (!value) {
CSSParserContext::ParserModeOverridingScope scope(context,
kHTMLStandardMode);
- value = css_property_parser_helpers::ConsumeLength(
- range, context, kValueRangeNonNegative);
+ value = ConsumeLength(range, context, kValueRangeNonNegative);
}
if (!value)
break;
@@ -1168,7 +3300,7 @@ CSSValue* ConsumeBorderImageOutset(CSSParserTokenRange& range,
}
if (!outsets[0])
return nullptr;
- css_property_parser_helpers::Complete4Sides(outsets);
+ Complete4Sides(outsets);
return MakeGarbageCollected<CSSQuadValue>(outsets[0], outsets[1], outsets[2],
outsets[3],
CSSQuadValue::kSerializeAsQuad);
@@ -1176,12 +3308,12 @@ CSSValue* ConsumeBorderImageOutset(CSSParserTokenRange& range,
CSSValue* ParseBorderRadiusCorner(CSSParserTokenRange& range,
const CSSParserContext& context) {
- CSSValue* parsed_value1 = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative);
+ CSSValue* parsed_value1 =
+ ConsumeLengthOrPercent(range, context, kValueRangeNonNegative);
if (!parsed_value1)
return nullptr;
- CSSValue* parsed_value2 = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative);
+ CSSValue* parsed_value2 =
+ ConsumeLengthOrPercent(range, context, kValueRangeNonNegative);
if (!parsed_value2)
parsed_value2 = parsed_value1;
return MakeGarbageCollected<CSSValuePair>(parsed_value1, parsed_value2,
@@ -1195,10 +3327,8 @@ CSSValue* ParseBorderWidthSide(CSSParserTokenRange& range,
bool allow_quirky_lengths = IsQuirksModeBehavior(context.Mode()) &&
(shorthand == CSSPropertyID::kInvalid ||
shorthand == CSSPropertyID::kBorderWidth);
- css_property_parser_helpers::UnitlessQuirk unitless =
- allow_quirky_lengths
- ? css_property_parser_helpers::UnitlessQuirk::kAllow
- : css_property_parser_helpers::UnitlessQuirk::kForbid;
+ UnitlessQuirk unitless =
+ allow_quirky_lengths ? UnitlessQuirk::kAllow : UnitlessQuirk::kForbid;
return ConsumeBorderWidth(range, context, unitless);
}
@@ -1206,9 +3336,9 @@ CSSValue* ConsumeShadow(CSSParserTokenRange& range,
const CSSParserContext& context,
AllowInsetAndSpread inset_and_spread) {
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
- ParseSingleShadow, range, context, inset_and_spread);
+ return ConsumeIdent(range);
+ return ConsumeCommaSeparatedList(ParseSingleShadow, range, context,
+ inset_and_spread);
}
CSSShadowValue* ParseSingleShadow(CSSParserTokenRange& range,
@@ -1220,46 +3350,43 @@ CSSShadowValue* ParseSingleShadow(CSSParserTokenRange& range,
if (range.AtEnd())
return nullptr;
- color = css_property_parser_helpers::ConsumeColor(range, context);
+ color = ConsumeColor(range, context);
if (range.Peek().Id() == CSSValueID::kInset) {
if (inset_and_spread != AllowInsetAndSpread::kAllow)
return nullptr;
- style = css_property_parser_helpers::ConsumeIdent(range);
+ style = ConsumeIdent(range);
if (!color)
- color = css_property_parser_helpers::ConsumeColor(range, context);
+ color = ConsumeColor(range, context);
}
CSSPrimitiveValue* horizontal_offset =
- css_property_parser_helpers::ConsumeLength(range, context,
- kValueRangeAll);
+ ConsumeLength(range, context, kValueRangeAll);
if (!horizontal_offset)
return nullptr;
CSSPrimitiveValue* vertical_offset =
- css_property_parser_helpers::ConsumeLength(range, context,
- kValueRangeAll);
+ ConsumeLength(range, context, kValueRangeAll);
if (!vertical_offset)
return nullptr;
- CSSPrimitiveValue* blur_radius = css_property_parser_helpers::ConsumeLength(
- range, context, kValueRangeNonNegative);
+ CSSPrimitiveValue* blur_radius =
+ ConsumeLength(range, context, kValueRangeNonNegative);
CSSPrimitiveValue* spread_distance = nullptr;
if (blur_radius) {
if (inset_and_spread == AllowInsetAndSpread::kAllow) {
- spread_distance = css_property_parser_helpers::ConsumeLength(
- range, context, kValueRangeAll);
+ spread_distance = ConsumeLength(range, context, kValueRangeAll);
}
}
if (!range.AtEnd()) {
if (!color)
- color = css_property_parser_helpers::ConsumeColor(range, context);
+ color = ConsumeColor(range, context);
if (range.Peek().Id() == CSSValueID::kInset) {
if (inset_and_spread != AllowInsetAndSpread::kAllow || style)
return nullptr;
- style = css_property_parser_helpers::ConsumeIdent(range);
+ style = ConsumeIdent(range);
if (!color) {
- color = css_property_parser_helpers::ConsumeColor(range, context);
+ color = ConsumeColor(range, context);
}
}
}
@@ -1271,19 +3398,19 @@ CSSShadowValue* ParseSingleShadow(CSSParserTokenRange& range,
CSSValue* ConsumeColumnCount(CSSParserTokenRange& range,
const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumePositiveInteger(range, context);
+ return ConsumeIdent(range);
+ return ConsumePositiveInteger(range, context);
}
CSSValue* ConsumeColumnWidth(CSSParserTokenRange& range,
const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
// Always parse lengths in strict mode here, since it would be ambiguous
// otherwise when used in the 'columns' shorthand property.
CSSParserContext::ParserModeOverridingScope scope(context, kHTMLStandardMode);
- CSSPrimitiveValue* column_width = css_property_parser_helpers::ConsumeLength(
- range, context, kValueRangeNonNegative);
+ CSSPrimitiveValue* column_width =
+ ConsumeLength(range, context, kValueRangeNonNegative);
if (!column_width)
return nullptr;
return column_width;
@@ -1294,7 +3421,7 @@ bool ConsumeColumnWidthOrCount(CSSParserTokenRange& range,
CSSValue*& column_width,
CSSValue*& column_count) {
if (range.Peek().Id() == CSSValueID::kAuto) {
- css_property_parser_helpers::ConsumeIdent(range);
+ ConsumeIdent(range);
return true;
}
if (!column_width) {
@@ -1310,26 +3437,23 @@ bool ConsumeColumnWidthOrCount(CSSParserTokenRange& range,
CSSValue* ConsumeGapLength(CSSParserTokenRange& range,
const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kNormal)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative);
+ return ConsumeIdent(range);
+ return ConsumeLengthOrPercent(range, context, kValueRangeNonNegative);
}
CSSValue* ConsumeCounter(CSSParserTokenRange& range,
const CSSParserContext& context,
int default_value) {
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
do {
- CSSCustomIdentValue* counter_name =
- css_property_parser_helpers::ConsumeCustomIdent(range, context);
+ CSSCustomIdentValue* counter_name = ConsumeCustomIdent(range, context);
if (!counter_name)
return nullptr;
int value = default_value;
- if (CSSPrimitiveValue* counter_value =
- css_property_parser_helpers::ConsumeInteger(range, context))
+ if (CSSPrimitiveValue* counter_value = ConsumeInteger(range, context))
value = clampTo<int>(counter_value->GetDoubleValue());
list->Append(*MakeGarbageCollected<CSSValuePair>(
counter_name,
@@ -1340,29 +3464,60 @@ CSSValue* ConsumeCounter(CSSParserTokenRange& range,
return list;
}
+CSSValue* ConsumeScriptLevel(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ CSSValueID function_id = range.Peek().FunctionId();
+ DCHECK(function_id == CSSValueID::kScriptlevel);
+ CSSParserTokenRange args = ConsumeFunction(range);
+ if (args.AtEnd())
+ return nullptr;
+ CSSValue* parsed_value = ConsumeIdent<CSSValueID::kAuto>(args);
+ if (!parsed_value)
+ parsed_value = ConsumeInteger(args, context);
+ if (!parsed_value) {
+ function_id = args.Peek().FunctionId();
+ if (function_id == CSSValueID::kAdd) {
+ auto* add_value = MakeGarbageCollected<CSSFunctionValue>(function_id);
+ CSSParserTokenRange add_args = ConsumeFunction(args);
+ if ((parsed_value = ConsumeInteger(add_args, context))) {
+ add_value->Append(*parsed_value);
+ parsed_value = add_value;
+ }
+ }
+ }
+ if (!parsed_value || !args.AtEnd())
+ return nullptr;
+ auto* script_level_value =
+ MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kScriptlevel);
+ script_level_value->Append(*parsed_value);
+ return script_level_value;
+}
+
CSSValue* ConsumeFontSize(CSSParserTokenRange& range,
const CSSParserContext& context,
- css_property_parser_helpers::UnitlessQuirk unitless) {
+ UnitlessQuirk unitless) {
if (range.Peek().Id() == CSSValueID::kWebkitXxxLarge)
context.Count(WebFeature::kFontSizeWebkitXxxLarge);
if (range.Peek().Id() >= CSSValueID::kXxSmall &&
range.Peek().Id() <= CSSValueID::kWebkitXxxLarge)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative, unitless);
+ return ConsumeIdent(range);
+ if (RuntimeEnabledFeatures::CSSMathStyleEnabled() &&
+ range.Peek().FunctionId() == CSSValueID::kScriptlevel)
+ return ConsumeScriptLevel(range, context);
+ return ConsumeLengthOrPercent(range, context, kValueRangeNonNegative,
+ unitless);
}
CSSValue* ConsumeLineHeight(CSSParserTokenRange& range,
const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kNormal)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
- CSSPrimitiveValue* line_height = css_property_parser_helpers::ConsumeNumber(
- range, context, kValueRangeNonNegative);
+ CSSPrimitiveValue* line_height =
+ ConsumeNumber(range, context, kValueRangeNonNegative);
if (line_height)
return line_height;
- return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative);
+ return ConsumeLengthOrPercent(range, context, kValueRangeNonNegative);
}
CSSValueList* ConsumeFontFamily(CSSParserTokenRange& range) {
@@ -1379,13 +3534,12 @@ CSSValueList* ConsumeFontFamily(CSSParserTokenRange& range) {
return nullptr;
}
}
- } while (css_property_parser_helpers::ConsumeCommaIncludingWhitespace(range));
+ } while (ConsumeCommaIncludingWhitespace(range));
return list;
}
CSSValue* ConsumeGenericFamily(CSSParserTokenRange& range) {
- return css_property_parser_helpers::ConsumeIdentRange(
- range, CSSValueID::kSerif, CSSValueID::kWebkitBody);
+ return ConsumeIdentRange(range, CSSValueID::kSerif, CSSValueID::kWebkitBody);
}
CSSValue* ConsumeFamilyName(CSSParserTokenRange& range) {
@@ -1413,7 +3567,7 @@ String ConcatenateFamilyName(CSSParserTokenRange& range) {
builder.Append(range.ConsumeIncludingWhitespace().Value());
}
if (!added_space &&
- (css_property_parser_helpers::IsCSSWideKeyword(first_token.Value()) ||
+ (IsCSSWideKeyword(first_token.Value()) ||
EqualIgnoringASCIICase(first_token.Value(), "default"))) {
return String();
}
@@ -1443,15 +3597,15 @@ CSSValue* ConsumeFontStyle(CSSParserTokenRange& range,
const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kNormal ||
range.Peek().Id() == CSSValueID::kItalic)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
if (range.Peek().Id() != CSSValueID::kOblique)
return nullptr;
CSSIdentifierValue* oblique_identifier =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kOblique>(range);
+ ConsumeIdent<CSSValueID::kOblique>(range);
- CSSPrimitiveValue* start_angle = css_property_parser_helpers::ConsumeAngle(
+ CSSPrimitiveValue* start_angle = ConsumeAngle(
range, context, base::nullopt, MinObliqueValue(), MaxObliqueValue());
if (!start_angle)
return oblique_identifier;
@@ -1465,7 +3619,7 @@ CSSValue* ConsumeFontStyle(CSSParserTokenRange& range,
*oblique_identifier, *value_list);
}
- CSSPrimitiveValue* end_angle = css_property_parser_helpers::ConsumeAngle(
+ CSSPrimitiveValue* end_angle = ConsumeAngle(
range, context, base::nullopt, MinObliqueValue(), MaxObliqueValue());
if (!end_angle || !IsAngleWithinLimits(end_angle))
return nullptr;
@@ -1482,7 +3636,7 @@ CSSIdentifierValue* ConsumeFontStretchKeywordOnly(CSSParserTokenRange& range) {
if (token.Id() == CSSValueID::kNormal ||
(token.Id() >= CSSValueID::kUltraCondensed &&
token.Id() <= CSSValueID::kUltraExpanded))
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
return nullptr;
}
@@ -1493,8 +3647,7 @@ CSSValue* ConsumeFontStretch(CSSParserTokenRange& range,
return parsed_keyword;
CSSPrimitiveValue* start_percent =
- css_property_parser_helpers::ConsumePercent(range, context,
- kValueRangeNonNegative);
+ ConsumePercent(range, context, kValueRangeNonNegative);
if (!start_percent)
return nullptr;
@@ -1502,8 +3655,8 @@ CSSValue* ConsumeFontStretch(CSSParserTokenRange& range,
if (context.Mode() != kCSSFontFaceRuleMode || range.AtEnd())
return start_percent;
- CSSPrimitiveValue* end_percent = css_property_parser_helpers::ConsumePercent(
- range, context, kValueRangeNonNegative);
+ CSSPrimitiveValue* end_percent =
+ ConsumePercent(range, context, kValueRangeNonNegative);
if (!end_percent)
return nullptr;
@@ -1514,7 +3667,7 @@ CSSValue* ConsumeFontWeight(CSSParserTokenRange& range,
const CSSParserContext& context) {
const CSSParserToken& token = range.Peek();
if (token.Id() >= CSSValueID::kNormal && token.Id() <= CSSValueID::kLighter)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
// Avoid consuming the first zero of font: 0/0; e.g. in the Acid3 test. In
// font:0/0; the first zero is the font size, the second is the line height.
@@ -1527,8 +3680,8 @@ CSSValue* ConsumeFontWeight(CSSParserTokenRange& range,
(token.NumericValue() < 1 || token.NumericValue() > 1000))
return nullptr;
- CSSPrimitiveValue* start_weight = css_property_parser_helpers::ConsumeNumber(
- range, context, kValueRangeNonNegative);
+ CSSPrimitiveValue* start_weight =
+ ConsumeNumber(range, context, kValueRangeNonNegative);
if (!start_weight || start_weight->GetFloatValue() < 1 ||
start_weight->GetFloatValue() > 1000)
return nullptr;
@@ -1539,8 +3692,8 @@ CSSValue* ConsumeFontWeight(CSSParserTokenRange& range,
if (context.Mode() != kCSSFontFaceRuleMode || range.AtEnd())
return start_weight;
- CSSPrimitiveValue* end_weight = css_property_parser_helpers::ConsumeNumber(
- range, context, kValueRangeNonNegative);
+ CSSPrimitiveValue* end_weight =
+ ConsumeNumber(range, context, kValueRangeNonNegative);
if (!end_weight || end_weight->GetFloatValue() < 1 ||
end_weight->GetFloatValue() > 1000)
return nullptr;
@@ -1551,7 +3704,7 @@ CSSValue* ConsumeFontWeight(CSSParserTokenRange& range,
CSSValue* ConsumeFontFeatureSettings(CSSParserTokenRange& range,
const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kNormal)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
CSSValueList* settings = CSSValueList::CreateCommaSeparated();
do {
CSSFontFeatureValue* font_feature_value =
@@ -1559,7 +3712,7 @@ CSSValue* ConsumeFontFeatureSettings(CSSParserTokenRange& range,
if (!font_feature_value)
return nullptr;
settings->Append(*font_feature_value);
- } while (css_property_parser_helpers::ConsumeCommaIncludingWhitespace(range));
+ } while (ConsumeCommaIncludingWhitespace(range));
return settings;
}
@@ -1585,8 +3738,7 @@ CSSFontFeatureValue* ConsumeFontFeatureTag(CSSParserTokenRange& range,
int tag_value = 1;
// Feature tag values could follow: <integer> | on | off
- if (CSSPrimitiveValue* value =
- css_property_parser_helpers::ConsumeInteger(range, context, 0)) {
+ if (CSSPrimitiveValue* value = ConsumeInteger(range, context, 0)) {
tag_value = clampTo<int>(value->GetDoubleValue());
} else if (range.Peek().Id() == CSSValueID::kOn ||
range.Peek().Id() == CSSValueID::kOff) {
@@ -1596,9 +3748,7 @@ CSSFontFeatureValue* ConsumeFontFeatureTag(CSSParserTokenRange& range,
}
CSSIdentifierValue* ConsumeFontVariantCSS21(CSSParserTokenRange& range) {
- return css_property_parser_helpers::ConsumeIdent<CSSValueID::kNormal,
- CSSValueID::kSmallCaps>(
- range);
+ return ConsumeIdent<CSSValueID::kNormal, CSSValueID::kSmallCaps>(range);
}
Vector<String> ParseGridTemplateAreasColumnNames(const String& grid_row_names) {
@@ -1645,10 +3795,9 @@ Vector<String> ParseGridTemplateAreasColumnNames(const String& grid_row_names) {
CSSValue* ConsumeGridBreadth(CSSParserTokenRange& range,
const CSSParserContext& context) {
const CSSParserToken& token = range.Peek();
- if (css_property_parser_helpers::IdentMatches<
- CSSValueID::kMinContent, CSSValueID::kMaxContent, CSSValueID::kAuto>(
- token.Id()))
- return css_property_parser_helpers::ConsumeIdent(range);
+ if (IdentMatches<CSSValueID::kMinContent, CSSValueID::kMaxContent,
+ CSSValueID::kAuto>(token.Id()))
+ return ConsumeIdent(range);
if (token.GetType() == kDimensionToken &&
token.GetUnitType() == CSSPrimitiveValue::UnitType::kFraction) {
if (range.Peek().NumericValue() < 0)
@@ -1657,20 +3806,16 @@ CSSValue* ConsumeGridBreadth(CSSParserTokenRange& range,
range.ConsumeIncludingWhitespace().NumericValue(),
CSSPrimitiveValue::UnitType::kFraction);
}
- return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ return ConsumeLengthOrPercent(range, context, kValueRangeNonNegative,
+ UnitlessQuirk::kForbid);
}
CSSValue* ConsumeFitContent(CSSParserTokenRange& range,
const CSSParserContext& context) {
CSSParserTokenRange range_copy = range;
- CSSParserTokenRange args =
- css_property_parser_helpers::ConsumeFunction(range_copy);
- CSSPrimitiveValue* length =
- css_property_parser_helpers::ConsumeLengthOrPercent(
- args, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ CSSParserTokenRange args = ConsumeFunction(range_copy);
+ CSSPrimitiveValue* length = ConsumeLengthOrPercent(
+ args, context, kValueRangeNonNegative, UnitlessQuirk::kAllow);
if (!length || !args.AtEnd())
return nullptr;
range = range_copy;
@@ -1712,20 +3857,19 @@ bool IsGridTrackFixedSized(const CSSValue& value) {
CSSValue* ConsumeGridTrackSize(CSSParserTokenRange& range,
const CSSParserContext& context) {
const CSSParserToken& token = range.Peek();
- if (css_property_parser_helpers::IdentMatches<CSSValueID::kAuto>(token.Id()))
- return css_property_parser_helpers::ConsumeIdent(range);
+ if (IdentMatches<CSSValueID::kAuto>(token.Id()))
+ return ConsumeIdent(range);
if (token.FunctionId() == CSSValueID::kMinmax) {
CSSParserTokenRange range_copy = range;
- CSSParserTokenRange args =
- css_property_parser_helpers::ConsumeFunction(range_copy);
+ CSSParserTokenRange args = ConsumeFunction(range_copy);
CSSValue* min_track_breadth = ConsumeGridBreadth(args, context);
auto* min_track_breadth_primitive_value =
DynamicTo<CSSPrimitiveValue>(min_track_breadth);
if (!min_track_breadth ||
(min_track_breadth_primitive_value &&
min_track_breadth_primitive_value->IsFlex()) ||
- !css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args))
+ !ConsumeCommaIncludingWhitespace(args))
return nullptr;
CSSValue* max_track_breadth = ConsumeGridBreadth(args, context);
if (!max_track_breadth || !args.AtEnd())
@@ -1750,7 +3894,7 @@ CSSCustomIdentValue* ConsumeCustomIdentForGridLine(
range.Peek().Id() == CSSValueID::kSpan ||
range.Peek().Id() == CSSValueID::kDefault)
return nullptr;
- return css_property_parser_helpers::ConsumeCustomIdent(range, context);
+ return ConsumeCustomIdent(range, context);
}
// Appends to the passed in CSSGridLineNamesValue if any, otherwise creates a
@@ -1780,28 +3924,26 @@ bool ConsumeGridTrackRepeatFunction(CSSParserTokenRange& range,
CSSValueList& list,
bool& is_auto_repeat,
bool& all_tracks_are_fixed_sized) {
- CSSParserTokenRange args =
- css_property_parser_helpers::ConsumeFunction(range);
+ CSSParserTokenRange args = ConsumeFunction(range);
// The number of repetitions for <auto-repeat> is not important at parsing
// level because it will be computed later, let's set it to 1.
size_t repetitions = 1;
- is_auto_repeat = css_property_parser_helpers::IdentMatches<
- CSSValueID::kAutoFill, CSSValueID::kAutoFit>(args.Peek().Id());
+ is_auto_repeat = IdentMatches<CSSValueID::kAutoFill, CSSValueID::kAutoFit>(
+ args.Peek().Id());
CSSValueList* repeated_values;
if (is_auto_repeat) {
repeated_values = MakeGarbageCollected<cssvalue::CSSGridAutoRepeatValue>(
args.ConsumeIncludingWhitespace().Id());
} else {
// TODO(rob.buis): a consumeIntegerRaw would be more efficient here.
- CSSPrimitiveValue* repetition =
- css_property_parser_helpers::ConsumePositiveInteger(args, context);
+ CSSPrimitiveValue* repetition = ConsumePositiveInteger(args, context);
if (!repetition)
return false;
repetitions =
clampTo<size_t>(repetition->GetDoubleValue(), 0, kGridMaxTracks);
repeated_values = CSSValueList::CreateSpaceSeparated();
}
- if (!css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args))
+ if (!ConsumeCommaIncludingWhitespace(args))
return false;
CSSGridLineNamesValue* line_names = ConsumeGridLineNames(args, context);
if (line_names)
@@ -1889,7 +4031,7 @@ bool ConsumeGridTemplateRowsAndAreasAndColumns(bool important,
range.Peek().Delimiter() == '/'));
if (!range.AtEnd()) {
- if (!css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range))
+ if (!ConsumeSlashIncludingWhitespace(range))
return false;
template_columns = ConsumeGridTrackList(
range, context, TrackListType::kGridTemplateNoRepeat);
@@ -1908,34 +4050,27 @@ bool ConsumeGridTemplateRowsAndAreasAndColumns(bool important,
CSSValue* ConsumeGridLine(CSSParserTokenRange& range,
const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
CSSIdentifierValue* span_value = nullptr;
CSSCustomIdentValue* grid_line_name = nullptr;
- CSSPrimitiveValue* numeric_value =
- css_property_parser_helpers::ConsumeInteger(range, context);
+ CSSPrimitiveValue* numeric_value = ConsumeInteger(range, context);
if (numeric_value) {
grid_line_name = ConsumeCustomIdentForGridLine(range, context);
- span_value =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kSpan>(range);
+ span_value = ConsumeIdent<CSSValueID::kSpan>(range);
} else {
- span_value =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kSpan>(range);
+ span_value = ConsumeIdent<CSSValueID::kSpan>(range);
if (span_value) {
- numeric_value =
- css_property_parser_helpers::ConsumeInteger(range, context);
+ numeric_value = ConsumeInteger(range, context);
grid_line_name = ConsumeCustomIdentForGridLine(range, context);
if (!numeric_value) {
- numeric_value =
- css_property_parser_helpers::ConsumeInteger(range, context);
+ numeric_value = ConsumeInteger(range, context);
}
} else {
grid_line_name = ConsumeCustomIdentForGridLine(range, context);
if (grid_line_name) {
- numeric_value =
- css_property_parser_helpers::ConsumeInteger(range, context);
- span_value =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kSpan>(range);
+ numeric_value = ConsumeInteger(range, context);
+ span_value = ConsumeIdent<CSSValueID::kSpan>(range);
if (!span_value && !numeric_value)
return grid_line_name;
} else {
@@ -2084,7 +4219,7 @@ bool ParseGridTemplateAreasRow(const String& grid_row_names,
CSSValue* ConsumeGridTemplatesRowsOrColumns(CSSParserTokenRange& range,
const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
return ConsumeGridTrackList(range, context, TrackListType::kGridTemplate);
}
@@ -2101,7 +4236,7 @@ bool ConsumeGridItemPositionShorthand(bool important,
if (!start_value)
return false;
- if (css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range)) {
+ if (ConsumeSlashIncludingWhitespace(range)) {
end_value = ConsumeGridLine(range, context);
if (!end_value)
return false;
@@ -2127,8 +4262,7 @@ bool ConsumeGridTemplateShorthand(bool important,
DCHECK_EQ(gridTemplateShorthand().length(), 3u);
CSSParserTokenRange range_copy = range;
- template_rows =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kNone>(range);
+ template_rows = ConsumeIdent<CSSValueID::kNone>(range);
// 1- 'none' case.
if (template_rows && range.AtEnd()) {
@@ -2145,7 +4279,7 @@ bool ConsumeGridTemplateShorthand(bool important,
}
if (template_rows) {
- if (!css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range))
+ if (!ConsumeSlashIncludingWhitespace(range))
return false;
template_columns = ConsumeGridTemplatesRowsOrColumns(range, context);
if (!template_columns || !range.AtEnd())
@@ -2231,8 +4365,7 @@ CSSValue* ConsumePath(CSSParserTokenRange& range) {
return nullptr;
CSSParserTokenRange function_range = range;
- CSSParserTokenRange function_args =
- css_property_parser_helpers::ConsumeFunction(function_range);
+ CSSParserTokenRange function_args = ConsumeFunction(function_range);
if (function_args.Peek().GetType() != kStringToken)
return nullptr;
@@ -2255,30 +4388,28 @@ CSSValue* ConsumeRay(CSSParserTokenRange& range,
const CSSParserContext& context) {
DCHECK_EQ(range.Peek().FunctionId(), CSSValueID::kRay);
CSSParserTokenRange function_range = range;
- CSSParserTokenRange function_args =
- css_property_parser_helpers::ConsumeFunction(function_range);
+ CSSParserTokenRange function_args = ConsumeFunction(function_range);
CSSPrimitiveValue* angle = nullptr;
CSSIdentifierValue* size = nullptr;
CSSIdentifierValue* contain = nullptr;
while (!function_args.AtEnd()) {
if (!angle) {
- angle = css_property_parser_helpers::ConsumeAngle(
- function_args, context, base::Optional<WebFeature>());
+ angle =
+ ConsumeAngle(function_args, context, base::Optional<WebFeature>());
if (angle)
continue;
}
if (!size) {
- size = css_property_parser_helpers::ConsumeIdent<
- CSSValueID::kClosestSide, CSSValueID::kClosestCorner,
- CSSValueID::kFarthestSide, CSSValueID::kFarthestCorner,
- CSSValueID::kSides>(function_args);
+ size =
+ ConsumeIdent<CSSValueID::kClosestSide, CSSValueID::kClosestCorner,
+ CSSValueID::kFarthestSide, CSSValueID::kFarthestCorner,
+ CSSValueID::kSides>(function_args);
if (size)
continue;
}
if (RuntimeEnabledFeatures::CSSOffsetPathRayContainEnabled() && !contain) {
- contain = css_property_parser_helpers::ConsumeIdent<CSSValueID::kContain>(
- function_args);
+ contain = ConsumeIdent<CSSValueID::kContain>(function_args);
if (contain)
continue;
}
@@ -2290,46 +4421,41 @@ CSSValue* ConsumeRay(CSSParserTokenRange& range,
return MakeGarbageCollected<cssvalue::CSSRayValue>(*angle, *size, contain);
}
-CSSValue* ConsumeMaxWidthOrHeight(
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- css_property_parser_helpers::UnitlessQuirk unitless) {
+CSSValue* ConsumeMaxWidthOrHeight(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ UnitlessQuirk unitless) {
if (range.Peek().Id() == CSSValueID::kNone ||
ValidWidthOrHeightKeyword(range.Peek().Id(), context))
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative, unitless);
+ return ConsumeIdent(range);
+ return ConsumeLengthOrPercent(range, context, kValueRangeNonNegative,
+ unitless);
}
-CSSValue* ConsumeWidthOrHeight(
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- css_property_parser_helpers::UnitlessQuirk unitless) {
+CSSValue* ConsumeWidthOrHeight(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ UnitlessQuirk unitless) {
if (range.Peek().Id() == CSSValueID::kAuto ||
ValidWidthOrHeightKeyword(range.Peek().Id(), context))
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative, unitless);
+ return ConsumeIdent(range);
+ return ConsumeLengthOrPercent(range, context, kValueRangeNonNegative,
+ unitless);
}
-CSSValue* ConsumeMarginOrOffset(
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- css_property_parser_helpers::UnitlessQuirk unitless) {
+CSSValue* ConsumeMarginOrOffset(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ UnitlessQuirk unitless) {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeAll, unitless);
+ return ConsumeIdent(range);
+ return ConsumeLengthOrPercent(range, context, kValueRangeAll, unitless);
}
CSSValue* ConsumeScrollPadding(CSSParserTokenRange& range,
const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
CSSParserContext::ParserModeOverridingScope scope(context, kHTMLStandardMode);
- return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ return ConsumeLengthOrPercent(range, context, kValueRangeNonNegative,
+ UnitlessQuirk::kForbid);
}
CSSValue* ConsumeOffsetPath(CSSParserTokenRange& range,
@@ -2350,24 +4476,21 @@ CSSValue* ConsumeOffsetPath(CSSParserTokenRange& range,
CSSValue* ConsumePathOrNone(CSSParserTokenRange& range) {
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
return ConsumePath(range);
}
CSSValue* ConsumeOffsetRotate(CSSParserTokenRange& range,
const CSSParserContext& context) {
- CSSValue* angle = css_property_parser_helpers::ConsumeAngle(
- range, context, base::Optional<WebFeature>());
+ CSSValue* angle = ConsumeAngle(range, context, base::Optional<WebFeature>());
CSSValue* keyword =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kAuto,
- CSSValueID::kReverse>(range);
+ ConsumeIdent<CSSValueID::kAuto, CSSValueID::kReverse>(range);
if (!angle && !keyword)
return nullptr;
if (!angle) {
- angle = css_property_parser_helpers::ConsumeAngle(
- range, context, base::Optional<WebFeature>());
+ angle = ConsumeAngle(range, context, base::Optional<WebFeature>());
}
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
@@ -2388,8 +4511,7 @@ bool ConsumeRadii(CSSValue* horizontal_radii[4],
range.Peek().GetType() != kDelimiterToken;
++horizontal_value_count) {
horizontal_radii[horizontal_value_count] =
- css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative);
+ ConsumeLengthOrPercent(range, context, kValueRangeNonNegative);
if (!horizontal_radii[horizontal_value_count])
return false;
}
@@ -2402,25 +4524,25 @@ bool ConsumeRadii(CSSValue* horizontal_radii[4],
vertical_radii[0] = horizontal_radii[1];
horizontal_radii[1] = nullptr;
} else {
- css_property_parser_helpers::Complete4Sides(horizontal_radii);
+ Complete4Sides(horizontal_radii);
for (unsigned i = 0; i < 4; ++i)
vertical_radii[i] = horizontal_radii[i];
return true;
}
} else {
- if (!css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range))
+ if (!ConsumeSlashIncludingWhitespace(range))
return false;
for (unsigned i = 0; i < 4 && !range.AtEnd(); ++i) {
- vertical_radii[i] = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative);
+ vertical_radii[i] =
+ ConsumeLengthOrPercent(range, context, kValueRangeNonNegative);
if (!vertical_radii[i])
return false;
}
if (!vertical_radii[0] || !range.AtEnd())
return false;
}
- css_property_parser_helpers::Complete4Sides(horizontal_radii);
- css_property_parser_helpers::Complete4Sides(vertical_radii);
+ Complete4Sides(horizontal_radii);
+ Complete4Sides(vertical_radii);
return true;
}
@@ -2431,8 +4553,7 @@ CSSValue* ConsumeBasicShape(CSSParserTokenRange& range,
return nullptr;
CSSValueID id = range.Peek().FunctionId();
CSSParserTokenRange range_copy = range;
- CSSParserTokenRange args =
- css_property_parser_helpers::ConsumeFunction(range_copy);
+ CSSParserTokenRange args = ConsumeFunction(range_copy);
if (id == CSSValueID::kCircle)
shape = ConsumeBasicShapeCircle(args, context);
else if (id == CSSValueID::kEllipse)
@@ -2453,7 +4574,7 @@ CSSValue* ConsumeBasicShape(CSSParserTokenRange& range,
CSSValue* ConsumeTextDecorationLine(CSSParserTokenRange& range) {
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
CSSIdentifierValue* underline = nullptr;
CSSIdentifierValue* overline = nullptr;
@@ -2463,13 +4584,13 @@ CSSValue* ConsumeTextDecorationLine(CSSParserTokenRange& range) {
while (true) {
id = range.Peek().Id();
if (id == CSSValueID::kUnderline && !underline)
- underline = css_property_parser_helpers::ConsumeIdent(range);
+ underline = ConsumeIdent(range);
else if (id == CSSValueID::kOverline && !overline)
- overline = css_property_parser_helpers::ConsumeIdent(range);
+ overline = ConsumeIdent(range);
else if (id == CSSValueID::kLineThrough && !line_through)
- line_through = css_property_parser_helpers::ConsumeIdent(range);
+ line_through = ConsumeIdent(range);
else if (id == CSSValueID::kBlink && !blink)
- blink = css_property_parser_helpers::ConsumeIdent(range);
+ blink = ConsumeIdent(range);
else
break;
}
@@ -2495,8 +4616,7 @@ CSSValue* ConsumeTransformValue(CSSParserTokenRange& range,
CSSValueID function_id = range.Peek().FunctionId();
if (!IsValidCSSValueID(function_id))
return nullptr;
- CSSParserTokenRange args =
- css_property_parser_helpers::ConsumeFunction(range);
+ CSSParserTokenRange args = ConsumeFunction(range);
if (args.AtEnd())
return nullptr;
auto* transform_value = MakeGarbageCollected<CSSFunctionValue>(function_id);
@@ -2509,15 +4629,15 @@ CSSValue* ConsumeTransformValue(CSSParserTokenRange& range,
case CSSValueID::kSkewX:
case CSSValueID::kSkewY:
case CSSValueID::kSkew:
- parsed_value = css_property_parser_helpers::ConsumeAngle(
- args, context, WebFeature::kUnitlessZeroAngleTransform);
+ parsed_value =
+ ConsumeAngle(args, context, WebFeature::kUnitlessZeroAngleTransform);
if (!parsed_value)
return nullptr;
if (function_id == CSSValueID::kSkew &&
- css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args)) {
+ ConsumeCommaIncludingWhitespace(args)) {
transform_value->Append(*parsed_value);
- parsed_value = css_property_parser_helpers::ConsumeAngle(
- args, context, WebFeature::kUnitlessZeroAngleTransform);
+ parsed_value = ConsumeAngle(args, context,
+ WebFeature::kUnitlessZeroAngleTransform);
if (!parsed_value)
return nullptr;
}
@@ -2526,15 +4646,13 @@ CSSValue* ConsumeTransformValue(CSSParserTokenRange& range,
case CSSValueID::kScaleY:
case CSSValueID::kScaleZ:
case CSSValueID::kScale:
- parsed_value = css_property_parser_helpers::ConsumeNumber(args, context,
- kValueRangeAll);
+ parsed_value = ConsumeNumber(args, context, kValueRangeAll);
if (!parsed_value)
return nullptr;
if (function_id == CSSValueID::kScale &&
- css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args)) {
+ ConsumeCommaIncludingWhitespace(args)) {
transform_value->Append(*parsed_value);
- parsed_value = css_property_parser_helpers::ConsumeNumber(
- args, context, kValueRangeAll);
+ parsed_value = ConsumeNumber(args, context, kValueRangeAll);
if (!parsed_value)
return nullptr;
}
@@ -2548,22 +4666,19 @@ CSSValue* ConsumeTransformValue(CSSParserTokenRange& range,
case CSSValueID::kTranslateX:
case CSSValueID::kTranslateY:
case CSSValueID::kTranslate:
- parsed_value = css_property_parser_helpers::ConsumeLengthOrPercent(
- args, context, kValueRangeAll);
+ parsed_value = ConsumeLengthOrPercent(args, context, kValueRangeAll);
if (!parsed_value)
return nullptr;
if (function_id == CSSValueID::kTranslate &&
- css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args)) {
+ ConsumeCommaIncludingWhitespace(args)) {
transform_value->Append(*parsed_value);
- parsed_value = css_property_parser_helpers::ConsumeLengthOrPercent(
- args, context, kValueRangeAll);
+ parsed_value = ConsumeLengthOrPercent(args, context, kValueRangeAll);
if (!parsed_value)
return nullptr;
}
break;
case CSSValueID::kTranslateZ:
- parsed_value = css_property_parser_helpers::ConsumeLength(args, context,
- kValueRangeAll);
+ parsed_value = ConsumeLength(args, context, kValueRangeAll);
break;
case CSSValueID::kMatrix:
case CSSValueID::kMatrix3d:
@@ -2578,11 +4693,11 @@ CSSValue* ConsumeTransformValue(CSSParserTokenRange& range,
break;
case CSSValueID::kRotate3d:
if (!ConsumeNumbers(args, context, transform_value, 3) ||
- !css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args)) {
+ !ConsumeCommaIncludingWhitespace(args)) {
return nullptr;
}
- parsed_value = css_property_parser_helpers::ConsumeAngle(
- args, context, WebFeature::kUnitlessZeroAngleTransform);
+ parsed_value =
+ ConsumeAngle(args, context, WebFeature::kUnitlessZeroAngleTransform);
if (!parsed_value)
return nullptr;
break;
@@ -2604,7 +4719,7 @@ CSSValue* ConsumeTransformList(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext& local_context) {
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
do {
@@ -2624,7 +4739,7 @@ CSSValue* ConsumeTransitionProperty(CSSParserTokenRange& range,
if (token.GetType() != kIdentToken)
return nullptr;
if (token.Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
const auto* execution_context = context.GetExecutionContext();
CSSPropertyID unresolved_property =
token.ParseAsUnresolvedCSSPropertyID(execution_context);
@@ -2637,7 +4752,7 @@ CSSValue* ConsumeTransitionProperty(CSSParserTokenRange& range,
range.ConsumeIncludingWhitespace();
return MakeGarbageCollected<CSSCustomIdentValue>(unresolved_property);
}
- return css_property_parser_helpers::ConsumeCustomIdent(range, context);
+ return ConsumeCustomIdent(range, context);
}
bool IsValidPropertyList(const CSSValueList& value_list) {
@@ -2658,40 +4773,34 @@ CSSValue* ConsumeBorderColorSide(CSSParserTokenRange& range,
bool allow_quirky_colors = IsQuirksModeBehavior(context.Mode()) &&
(shorthand == CSSPropertyID::kInvalid ||
shorthand == CSSPropertyID::kBorderColor);
- return css_property_parser_helpers::ConsumeColor(range, context,
- allow_quirky_colors);
+ return ConsumeColor(range, context, allow_quirky_colors);
}
-CSSValue* ConsumeBorderWidth(
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- css_property_parser_helpers::UnitlessQuirk unitless) {
- return css_property_parser_helpers::ConsumeLineWidth(range, context,
- unitless);
+CSSValue* ConsumeBorderWidth(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ UnitlessQuirk unitless) {
+ return ConsumeLineWidth(range, context, unitless);
}
CSSValue* ParseSpacing(CSSParserTokenRange& range,
const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kNormal)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return ConsumeIdent(range);
// TODO(timloh): allow <percentage>s in word-spacing.
- return css_property_parser_helpers::ConsumeLength(
- range, context, kValueRangeAll,
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ return ConsumeLength(range, context, kValueRangeAll, UnitlessQuirk::kAllow);
}
CSSValue* ParsePaintStroke(CSSParserTokenRange& range,
const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
- cssvalue::CSSURIValue* url =
- css_property_parser_helpers::ConsumeUrl(range, context);
+ return ConsumeIdent(range);
+ cssvalue::CSSURIValue* url = ConsumeUrl(range, context);
if (url) {
CSSValue* parsed_value = nullptr;
if (range.Peek().Id() == CSSValueID::kNone) {
- parsed_value = css_property_parser_helpers::ConsumeIdent(range);
+ parsed_value = ConsumeIdent(range);
} else {
- parsed_value = css_property_parser_helpers::ConsumeColor(range, context);
+ parsed_value = ConsumeColor(range, context);
}
if (parsed_value) {
CSSValueList* values = CSSValueList::CreateSpaceSeparated();
@@ -2701,14 +4810,14 @@ CSSValue* ParsePaintStroke(CSSParserTokenRange& range,
}
return url;
}
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return ConsumeColor(range, context);
}
-css_property_parser_helpers::UnitlessQuirk UnitlessUnlessShorthand(
+UnitlessQuirk UnitlessUnlessShorthand(
const CSSParserLocalContext& local_context) {
return local_context.CurrentShorthand() == CSSPropertyID::kInvalid
- ? css_property_parser_helpers::UnitlessQuirk::kAllow
- : css_property_parser_helpers::UnitlessQuirk::kForbid;
+ ? UnitlessQuirk::kAllow
+ : UnitlessQuirk::kForbid;
}
} // namespace css_parsing_utils
diff --git a/chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils.h b/chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
index 6cf2745204c..5a96ee00469 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
+++ b/chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
@@ -5,27 +5,42 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PROPERTIES_CSS_PARSING_UTILS_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PROPERTIES_CSS_PARSING_UTILS_H_
+#include "base/optional.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/css/css_custom_ident_value.h"
+#include "third_party/blink/renderer/core/css/css_function_value.h"
+#include "third_party/blink/renderer/core/css/css_identifier_value.h"
#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
+#include "third_party/blink/renderer/core/css/css_primitive_value.h"
+#include "third_party/blink/renderer/core/css/css_value_list.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_mode.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h"
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
+#include "third_party/blink/renderer/core/frame/web_feature_forward.h"
#include "third_party/blink/renderer/core/style/grid_area.h"
+#include "third_party/blink/renderer/platform/geometry/length.h" // For ValueRange
+#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
namespace cssvalue {
class CSSFontFeatureValue;
+class CSSURIValue;
} // namespace cssvalue
class CSSIdentifierValue;
class CSSParserContext;
class CSSParserLocalContext;
+class CSSPropertyValue;
class CSSShadowValue;
+class CSSStringValue;
class CSSValue;
class CSSValueList;
+class CSSValuePair;
class StylePropertyShorthand;
+// "Consume" functions, when successful, should consume all the relevant tokens
+// as well as any trailing whitespace. When the start of the range doesn't
+// match the type we're looking for, the range should not be modified.
namespace css_parsing_utils {
enum class AllowInsetAndSpread { kAllow, kForbid };
@@ -33,6 +48,7 @@ enum class AllowTextValue { kAllow, kForbid };
enum class DefaultFill { kFill, kNoFill };
enum class ParsingStyle { kLegacy, kNotLegacy };
enum class TrackListType { kGridTemplate, kGridTemplateNoRepeat, kGridAuto };
+enum class UnitlessQuirk { kAllow, kForbid };
using ConsumeAnimationItemValue = CSSValue* (*)(CSSPropertyID,
CSSParserTokenRange&,
@@ -42,12 +58,192 @@ using IsPositionKeyword = bool (*)(CSSValueID);
constexpr size_t kMaxNumAnimationLonghands = 8;
+void Complete4Sides(CSSValue* side[4]);
+
+// TODO(timloh): These should probably just be consumeComma and consumeSlash.
+bool ConsumeCommaIncludingWhitespace(CSSParserTokenRange&);
+bool ConsumeSlashIncludingWhitespace(CSSParserTokenRange&);
+// consumeFunction expects the range starts with a FunctionToken.
+CSSParserTokenRange ConsumeFunction(CSSParserTokenRange&);
+
+CSSPrimitiveValue* ConsumeInteger(
+ CSSParserTokenRange&,
+ const CSSParserContext&,
+ double minimum_value = -std::numeric_limits<double>::max());
+CSSPrimitiveValue* ConsumeIntegerOrNumberCalc(CSSParserTokenRange&,
+ const CSSParserContext&);
+CSSPrimitiveValue* ConsumePositiveInteger(CSSParserTokenRange&,
+ const CSSParserContext&);
+bool ConsumeNumberRaw(CSSParserTokenRange&,
+ const CSSParserContext& context,
+ double& result);
+CSSPrimitiveValue* ConsumeNumber(CSSParserTokenRange&,
+ const CSSParserContext&,
+ ValueRange);
+CSSPrimitiveValue* ConsumeLength(CSSParserTokenRange&,
+ const CSSParserContext&,
+ ValueRange,
+ UnitlessQuirk = UnitlessQuirk::kForbid);
+CSSPrimitiveValue* ConsumePercent(CSSParserTokenRange&,
+ const CSSParserContext&,
+ ValueRange);
+CSSPrimitiveValue* ConsumeAlphaValue(CSSParserTokenRange&,
+ const CSSParserContext&);
+CSSPrimitiveValue* ConsumeLengthOrPercent(
+ CSSParserTokenRange&,
+ const CSSParserContext&,
+ ValueRange,
+ UnitlessQuirk = UnitlessQuirk::kForbid);
+CSSPrimitiveValue* ConsumeSVGGeometryPropertyLength(CSSParserTokenRange&,
+ const CSSParserContext&,
+ ValueRange);
+
+CSSPrimitiveValue* ConsumeAngle(
+ CSSParserTokenRange&,
+ const CSSParserContext&,
+ base::Optional<WebFeature> unitless_zero_feature);
+CSSPrimitiveValue* ConsumeAngle(
+ CSSParserTokenRange&,
+ const CSSParserContext&,
+ base::Optional<WebFeature> unitless_zero_feature,
+ double minimum_value,
+ double maximum_value);
+CSSPrimitiveValue* ConsumeTime(CSSParserTokenRange&,
+ const CSSParserContext&,
+ ValueRange);
+CSSPrimitiveValue* ConsumeResolution(CSSParserTokenRange&);
+
+CSSIdentifierValue* ConsumeIdent(CSSParserTokenRange&);
+CSSIdentifierValue* ConsumeIdentRange(CSSParserTokenRange&,
+ CSSValueID lower,
+ CSSValueID upper);
+template <CSSValueID, CSSValueID...>
+inline bool IdentMatches(CSSValueID id);
+template <CSSValueID... allowedIdents>
+CSSIdentifierValue* ConsumeIdent(CSSParserTokenRange&);
+
+CSSCustomIdentValue* ConsumeCustomIdent(CSSParserTokenRange&,
+ const CSSParserContext&);
+CSSStringValue* ConsumeString(CSSParserTokenRange&);
+StringView ConsumeUrlAsStringView(CSSParserTokenRange&,
+ const CSSParserContext&);
+cssvalue::CSSURIValue* ConsumeUrl(CSSParserTokenRange&,
+ const CSSParserContext&);
+CORE_EXPORT CSSValue* ConsumeIdSelector(CSSParserTokenRange&);
+
+CSSValue* ConsumeColor(CSSParserTokenRange&,
+ const CSSParserContext&,
+ bool accept_quirky_colors = false);
+
+CSSValue* ConsumeInternalForcedBackgroundColor(CSSParserTokenRange&,
+ const CSSParserContext&);
+
+CSSValue* ConsumeLineWidth(CSSParserTokenRange&,
+ const CSSParserContext&,
+ UnitlessQuirk);
+
+CSSValuePair* ConsumePosition(CSSParserTokenRange&,
+ const CSSParserContext&,
+ UnitlessQuirk,
+ base::Optional<WebFeature> three_value_position);
+bool ConsumePosition(CSSParserTokenRange&,
+ const CSSParserContext&,
+ UnitlessQuirk,
+ base::Optional<WebFeature> three_value_position,
+ CSSValue*& result_x,
+ CSSValue*& result_y);
+bool ConsumeOneOrTwoValuedPosition(CSSParserTokenRange&,
+ const CSSParserContext&,
+ UnitlessQuirk,
+ CSSValue*& result_x,
+ CSSValue*& result_y);
+bool ConsumeBorderShorthand(CSSParserTokenRange&,
+ const CSSParserContext&,
+ const CSSValue*& result_width,
+ const CSSValue*& result_style,
+ const CSSValue*& result_color);
+
+enum class ConsumeGeneratedImagePolicy { kAllow, kForbid };
+
+CSSValue* ConsumeImage(
+ CSSParserTokenRange&,
+ const CSSParserContext&,
+ ConsumeGeneratedImagePolicy = ConsumeGeneratedImagePolicy::kAllow);
+CSSValue* ConsumeImageOrNone(CSSParserTokenRange&, const CSSParserContext&);
+
+CSSValue* ConsumeAxis(CSSParserTokenRange&, const CSSParserContext& context);
+
+CSSIdentifierValue* ConsumeShapeBox(CSSParserTokenRange&);
+
+enum class IsImplicitProperty { kNotImplicit, kImplicit };
+
+void AddProperty(CSSPropertyID resolved_property,
+ CSSPropertyID current_shorthand,
+ const CSSValue&,
+ bool important,
+ IsImplicitProperty,
+ HeapVector<CSSPropertyValue, 256>& properties);
+
+void CountKeywordOnlyPropertyUsage(CSSPropertyID,
+ const CSSParserContext&,
+ CSSValueID);
+
+const CSSValue* ParseLonghand(CSSPropertyID unresolved_property,
+ CSSPropertyID current_shorthand,
+ const CSSParserContext&,
+ CSSParserTokenRange&);
+
+bool ConsumeShorthandVia2Longhands(
+ const StylePropertyShorthand&,
+ bool important,
+ const CSSParserContext&,
+ CSSParserTokenRange&,
+ HeapVector<CSSPropertyValue, 256>& properties);
+
+bool ConsumeShorthandVia4Longhands(
+ const StylePropertyShorthand&,
+ bool important,
+ const CSSParserContext&,
+ CSSParserTokenRange&,
+ HeapVector<CSSPropertyValue, 256>& properties);
+
+bool ConsumeShorthandGreedilyViaLonghands(
+ const StylePropertyShorthand&,
+ bool important,
+ const CSSParserContext&,
+ CSSParserTokenRange&,
+ HeapVector<CSSPropertyValue, 256>& properties);
+
+void AddExpandedPropertyForValue(CSSPropertyID prop_id,
+ const CSSValue&,
+ bool,
+ HeapVector<CSSPropertyValue, 256>& properties);
+
+CSSValue* ConsumeTransformValue(CSSParserTokenRange&, const CSSParserContext&);
+CSSValue* ConsumeTransformList(CSSParserTokenRange&, const CSSParserContext&);
+CSSValue* ConsumeFilterFunctionList(CSSParserTokenRange&,
+ const CSSParserContext&);
+
bool IsBaselineKeyword(CSSValueID id);
bool IsSelfPositionKeyword(CSSValueID);
bool IsSelfPositionOrLeftOrRightKeyword(CSSValueID);
bool IsContentPositionKeyword(CSSValueID);
bool IsContentPositionOrLeftOrRightKeyword(CSSValueID);
CORE_EXPORT bool IsCSSWideKeyword(CSSValueID);
+CORE_EXPORT bool IsCSSWideKeyword(StringView);
+bool IsRevertKeyword(StringView);
+bool IsDefaultKeyword(StringView);
+bool IsHashIdentifier(const CSSParserToken&);
+
+// This function returns false for CSS-wide keywords, 'default', and any
+// template parameters provided.
+//
+// https://drafts.csswg.org/css-values-4/#identifier-value
+template <CSSValueID, CSSValueID...>
+bool IsCustomIdent(CSSValueID);
+
+// https://drafts.csswg.org/scroll-animations-1/#typedef-timeline-name
+bool IsTimelineName(const CSSParserToken&);
CSSValue* ConsumeScrollOffset(CSSParserTokenRange&, const CSSParserContext&);
CSSValue* ConsumeSelfPositionOverflowPosition(CSSParserTokenRange&,
@@ -66,6 +262,8 @@ CSSValue* ConsumeAnimationIterationCount(CSSParserTokenRange&,
CSSValue* ConsumeAnimationName(CSSParserTokenRange&,
const CSSParserContext&,
bool allow_quoted_name);
+CSSValue* ConsumeAnimationTimeline(CSSParserTokenRange&,
+ const CSSParserContext&);
CSSValue* ConsumeAnimationTimingFunction(CSSParserTokenRange&,
const CSSParserContext&);
bool ConsumeAnimationShorthand(
@@ -81,10 +279,9 @@ CSSValue* ConsumeBackgroundAttachment(CSSParserTokenRange&);
CSSValue* ConsumeBackgroundBlendMode(CSSParserTokenRange&);
CSSValue* ConsumeBackgroundBox(CSSParserTokenRange&);
CSSValue* ConsumeBackgroundComposite(CSSParserTokenRange&);
-CSSValue* ConsumeMaskSourceType(CSSParserTokenRange&);
bool ConsumeBackgroundPosition(CSSParserTokenRange&,
const CSSParserContext&,
- css_property_parser_helpers::UnitlessQuirk,
+ UnitlessQuirk,
CSSValue*& result_x,
CSSValue*& result_y);
CSSValue* ConsumePrefixedBackgroundBox(CSSParserTokenRange&, AllowTextValue);
@@ -152,11 +349,9 @@ CSSValue* ConsumeGapLength(CSSParserTokenRange&, const CSSParserContext&);
CSSValue* ConsumeCounter(CSSParserTokenRange&, const CSSParserContext&, int);
-CSSValue* ConsumeFontSize(
- CSSParserTokenRange&,
- const CSSParserContext&,
- css_property_parser_helpers::UnitlessQuirk =
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+CSSValue* ConsumeFontSize(CSSParserTokenRange&,
+ const CSSParserContext&,
+ UnitlessQuirk = UnitlessQuirk::kForbid);
CSSValue* ConsumeLineHeight(CSSParserTokenRange&, const CSSParserContext&);
@@ -204,20 +399,16 @@ bool ConsumeFromPageBreakBetween(CSSParserTokenRange&, CSSValueID&);
bool ConsumeFromColumnBreakBetween(CSSParserTokenRange&, CSSValueID&);
bool ConsumeFromColumnOrPageBreakInside(CSSParserTokenRange&, CSSValueID&);
-CSSValue* ConsumeMaxWidthOrHeight(
- CSSParserTokenRange&,
- const CSSParserContext&,
- css_property_parser_helpers::UnitlessQuirk =
- css_property_parser_helpers::UnitlessQuirk::kForbid);
-CSSValue* ConsumeWidthOrHeight(
- CSSParserTokenRange&,
- const CSSParserContext&,
- css_property_parser_helpers::UnitlessQuirk =
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+CSSValue* ConsumeMaxWidthOrHeight(CSSParserTokenRange&,
+ const CSSParserContext&,
+ UnitlessQuirk = UnitlessQuirk::kForbid);
+CSSValue* ConsumeWidthOrHeight(CSSParserTokenRange&,
+ const CSSParserContext&,
+ UnitlessQuirk = UnitlessQuirk::kForbid);
CSSValue* ConsumeMarginOrOffset(CSSParserTokenRange&,
const CSSParserContext&,
- css_property_parser_helpers::UnitlessQuirk);
+ UnitlessQuirk);
CSSValue* ConsumeScrollPadding(CSSParserTokenRange&, const CSSParserContext&);
CSSValue* ConsumeOffsetPath(CSSParserTokenRange&, const CSSParserContext&);
CSSValue* ConsumePathOrNone(CSSParserTokenRange&);
@@ -247,12 +438,58 @@ CSSValue* ConsumeBorderColorSide(CSSParserTokenRange&,
const CSSParserLocalContext&);
CSSValue* ConsumeBorderWidth(CSSParserTokenRange&,
const CSSParserContext&,
- css_property_parser_helpers::UnitlessQuirk);
+ UnitlessQuirk);
CSSValue* ParsePaintStroke(CSSParserTokenRange&, const CSSParserContext&);
CSSValue* ParseSpacing(CSSParserTokenRange&, const CSSParserContext&);
-css_property_parser_helpers::UnitlessQuirk UnitlessUnlessShorthand(
- const CSSParserLocalContext&);
+UnitlessQuirk UnitlessUnlessShorthand(const CSSParserLocalContext&);
+
+// Template implementations are at the bottom of the file for readability.
+
+template <typename... emptyBaseCase>
+inline bool IdentMatches(CSSValueID id) {
+ return false;
+}
+template <CSSValueID head, CSSValueID... tail>
+inline bool IdentMatches(CSSValueID id) {
+ return id == head || IdentMatches<tail...>(id);
+}
+
+template <typename...>
+bool IsCustomIdent(CSSValueID id) {
+ return !IsCSSWideKeyword(id) && id != CSSValueID::kDefault;
+}
+
+template <CSSValueID head, CSSValueID... tail>
+bool IsCustomIdent(CSSValueID id) {
+ return id != head && IsCustomIdent<tail...>(id);
+}
+
+template <CSSValueID... names>
+CSSIdentifierValue* ConsumeIdent(CSSParserTokenRange& range) {
+ if (range.Peek().GetType() != kIdentToken ||
+ !IdentMatches<names...>(range.Peek().Id()))
+ return nullptr;
+ return CSSIdentifierValue::Create(range.ConsumeIncludingWhitespace().Id());
+}
+
+// ConsumeCommaSeparatedList takes a callback function to call on each item in
+// the list, followed by the arguments to pass to this callback.
+// The first argument to the callback must be the CSSParserTokenRange
+template <typename Func, typename... Args>
+CSSValueList* ConsumeCommaSeparatedList(Func callback,
+ CSSParserTokenRange& range,
+ Args&&... args) {
+ CSSValueList* list = CSSValueList::CreateCommaSeparated();
+ do {
+ CSSValue* value = callback(range, std::forward<Args>(args)...);
+ if (!value)
+ return nullptr;
+ list->Append(*value);
+ } while (ConsumeCommaIncludingWhitespace(range));
+ DCHECK(list->length());
+ return list;
+}
template <CSSValueID start, CSSValueID end>
CSSValue* ConsumePositionLonghand(CSSParserTokenRange& range,
@@ -272,8 +509,7 @@ CSSValue* ConsumePositionLonghand(CSSParserTokenRange& range,
return CSSNumericLiteralValue::Create(
percent, CSSPrimitiveValue::UnitType::kPercentage);
}
- return css_property_parser_helpers::ConsumeLengthOrPercent(range, context,
- kValueRangeAll);
+ return ConsumeLengthOrPercent(range, context, kValueRangeAll);
}
} // namespace css_parsing_utils
diff --git a/chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils_test.cc b/chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils_test.cc
index 3e768f51ca7..d0888d91aff 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils_test.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
#include "third_party/blink/renderer/core/html/html_html_element.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
@@ -11,6 +12,8 @@
namespace blink {
+using css_parsing_utils::ConsumeIdSelector;
+
TEST(CSSParsingUtilsTest, BasicShapeUseCount) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
@@ -26,11 +29,72 @@ TEST(CSSParsingUtilsTest, Revert) {
{
ScopedCSSRevertForTest scoped_revert(true);
EXPECT_TRUE(css_parsing_utils::IsCSSWideKeyword(CSSValueID::kRevert));
+ EXPECT_TRUE(css_parsing_utils::IsCSSWideKeyword("revert"));
}
{
ScopedCSSRevertForTest scoped_revert(false);
EXPECT_FALSE(css_parsing_utils::IsCSSWideKeyword(CSSValueID::kRevert));
+ EXPECT_FALSE(css_parsing_utils::IsCSSWideKeyword("revert"));
+ }
+}
+
+TEST(CSSParsingUtilsTest, ConsumeIdSelector) {
+ {
+ String text = "#foo";
+ auto tokens = CSSTokenizer(text).TokenizeToEOF();
+ CSSParserTokenRange range(tokens);
+ EXPECT_EQ("#foo", ConsumeIdSelector(range)->CssText());
+ }
+ {
+ String text = "#bar ";
+ auto tokens = CSSTokenizer(text).TokenizeToEOF();
+ CSSParserTokenRange range(tokens);
+ EXPECT_EQ("#bar", ConsumeIdSelector(range)->CssText());
+ EXPECT_TRUE(range.AtEnd())
+ << "ConsumeIdSelector cleans up trailing whitespace";
+ }
+
+ {
+ String text = "#123";
+ auto tokens = CSSTokenizer(text).TokenizeToEOF();
+ CSSParserTokenRange range(tokens);
+ ASSERT_TRUE(range.Peek().GetType() == kHashToken &&
+ range.Peek().GetHashTokenType() == kHashTokenUnrestricted);
+ EXPECT_FALSE(ConsumeIdSelector(range))
+ << "kHashTokenUnrestricted is not a valid <id-selector>";
+ }
+ {
+ String text = "#";
+ auto tokens = CSSTokenizer(text).TokenizeToEOF();
+ CSSParserTokenRange range(tokens);
+ EXPECT_FALSE(ConsumeIdSelector(range));
+ }
+ {
+ String text = " #foo";
+ auto tokens = CSSTokenizer(text).TokenizeToEOF();
+ CSSParserTokenRange range(tokens);
+ EXPECT_FALSE(ConsumeIdSelector(range))
+ << "ConsumeIdSelector does not accept preceding whitespace";
+ EXPECT_EQ(kWhitespaceToken, range.Peek().GetType());
+ }
+ {
+ String text = "foo";
+ auto tokens = CSSTokenizer(text).TokenizeToEOF();
+ CSSParserTokenRange range(tokens);
+ EXPECT_FALSE(ConsumeIdSelector(range));
+ }
+ {
+ String text = "##";
+ auto tokens = CSSTokenizer(text).TokenizeToEOF();
+ CSSParserTokenRange range(tokens);
+ EXPECT_FALSE(ConsumeIdSelector(range));
+ }
+ {
+ String text = "10px";
+ auto tokens = CSSTokenizer(text).TokenizeToEOF();
+ CSSParserTokenRange range(tokens);
+ EXPECT_FALSE(ConsumeIdSelector(range));
}
}
diff --git a/chromium/third_party/blink/renderer/core/css/properties/css_property_ref.h b/chromium/third_party/blink/renderer/core/css/properties/css_property_ref.h
index f3e986218fb..c956e974602 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/css_property_ref.h
+++ b/chromium/third_party/blink/renderer/core/css/properties/css_property_ref.h
@@ -66,7 +66,7 @@ class CORE_EXPORT CSSPropertyRef {
return GetProperty();
}
- void Trace(Visitor* visitor) { visitor->Trace(custom_property_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(custom_property_); }
private:
CSSPropertyID property_id_;
diff --git a/chromium/third_party/blink/renderer/core/css/properties/css_property_test.cc b/chromium/third_party/blink/renderer/core/css/properties/css_property_test.cc
index 7dca63e71c3..2614c2700b4 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/css_property_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/css_property_test.cc
@@ -32,6 +32,16 @@ class CSSPropertyTest : public PageTestBase {
const CSSValue& value) {
StyleResolverState state(GetDocument(), *GetDocument().body());
state.SetStyle(ComputedStyle::Create());
+
+ // The border-style needs to be non-hidden and non-none, otherwise
+ // the computed values of border-width properties are always zero.
+ //
+ // https://drafts.csswg.org/css-backgrounds-3/#the-border-width
+ state.Style()->SetBorderBottomStyle(EBorderStyle::kSolid);
+ state.Style()->SetBorderLeftStyle(EBorderStyle::kSolid);
+ state.Style()->SetBorderRightStyle(EBorderStyle::kSolid);
+ state.Style()->SetBorderTopStyle(EBorderStyle::kSolid);
+
StyleBuilder::ApplyProperty(property, state, value);
return state.TakeStyle();
}
@@ -138,9 +148,28 @@ namespace {
// Examples must produce unique computed values. For example, it's not
// allowed to list both 2px and calc(1px + 1px).
+const char* align_content_examples[] = {"normal", "first baseline", "stretch",
+ "safe end", nullptr};
+const char* border_style_examples[] = {"none", "solid", "dashed", nullptr};
const char* color_examples[] = {"red", "green", "#fef", "#faf", nullptr};
const char* direction_examples[] = {"ltr", "rtl", nullptr};
+const char* flex_direction_examples[] = {"row", "column", nullptr};
+const char* flex_wrap_examples[] = {"nowrap", "wrap", nullptr};
+const char* float_examples[] = {"1", "2.5", nullptr};
+const char* justify_content_examples[] = {"normal", "stretch", "safe end",
+ "left", nullptr};
const char* length_or_auto_examples[] = {"auto", "1px", "2px", "5%", nullptr};
+const char* length_or_none_examples[] = {"none", "1px", "2px", "5%", nullptr};
+const char* length_percentage_examples[] = {"1px", "2%", "calc(1% + 2px)",
+ nullptr};
+const char* length_size_examples[] = {"4px", "1px 2px", "3%", "calc(1% + 1px)",
+ nullptr};
+const char* line_width_examples[] = {"medium", "thin", "100px", nullptr};
+const char* none_auto_examples[] = {"none", "auto", nullptr};
+const char* self_align_examples[] = {"flex-start", "flex-end", "first baseline",
+ "safe end", nullptr};
+const char* text_decoration_line_examples[] = {"none", "underline", nullptr};
+const char* text_decoration_style_examples[] = {"solid", "dashed", nullptr};
const char* vertical_align_examples[] = {"sub", "super", "1px", "3%", nullptr};
const char* writing_mode_examples[] = {"horizontal-tb", "vertical-rl", nullptr};
@@ -149,16 +178,58 @@ struct ComputedValuesEqualData {
const char** examples;
} computed_values_equal_data[] = {
{"-webkit-writing-mode", writing_mode_examples},
+ {"align-content", align_content_examples},
+ {"align-items", self_align_examples},
+ {"align-self", self_align_examples},
{"border-bottom-color", color_examples},
+ {"border-bottom-left-radius", length_size_examples},
+ {"border-bottom-right-radius", length_size_examples},
+ {"border-bottom-style", border_style_examples},
+ {"border-bottom-width", line_width_examples},
{"border-left-color", color_examples},
+ {"border-left-style", border_style_examples},
+ {"border-left-width", line_width_examples},
{"border-right-color", color_examples},
+ {"border-right-style", border_style_examples},
+ {"border-right-width", line_width_examples},
{"border-top-color", color_examples},
+ {"border-top-left-radius", length_size_examples},
+ {"border-top-right-radius", length_size_examples},
+ {"border-top-style", border_style_examples},
+ {"border-top-width", line_width_examples},
{"bottom", length_or_auto_examples},
{"direction", direction_examples},
+ {"flex-basis", length_or_auto_examples},
+ {"flex-direction", flex_direction_examples},
+ {"flex-grow", float_examples},
+ {"flex-shrink", float_examples},
+ {"flex-wrap", flex_wrap_examples},
+ {"height", length_or_auto_examples},
+ {"justify-content", justify_content_examples},
+ {"justify-items", self_align_examples},
+ {"justify-self", self_align_examples},
{"left", length_or_auto_examples},
+ {"margin-bottom", length_or_auto_examples},
+ {"margin-left", length_or_auto_examples},
+ {"margin-right", length_or_auto_examples},
+ {"margin-top", length_or_auto_examples},
+ {"max-height", length_or_none_examples},
+ {"max-width", length_or_none_examples},
+ {"min-height", length_or_auto_examples},
+ {"min-width", length_or_auto_examples},
+ {"padding-bottom", length_percentage_examples},
+ {"padding-left", length_percentage_examples},
+ {"padding-right", length_percentage_examples},
+ {"padding-top", length_percentage_examples},
{"right", length_or_auto_examples},
+ {"text-decoration-color", color_examples},
+ {"text-decoration-line", text_decoration_line_examples},
+ {"text-decoration-skip-ink", none_auto_examples},
+ {"text-decoration-style", text_decoration_style_examples},
+ {"text-decoration-thickness", length_or_auto_examples},
{"top", length_or_auto_examples},
{"vertical-align", vertical_align_examples},
+ {"width", length_or_auto_examples},
{"writing-mode", writing_mode_examples},
};
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/custom_property.h b/chromium/third_party/blink/renderer/core/css/properties/longhands/custom_property.h
index 28b2991c75f..6940f08cadd 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/custom_property.h
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/custom_property.h
@@ -52,7 +52,7 @@ class CORE_EXPORT CustomProperty : public Variable {
bool IsRegistered() const { return registration_; }
- void Trace(Visitor* visitor) { visitor->Trace(registration_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(registration_); }
private:
CustomProperty(const AtomicString& name,
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
index a5e40f0e436..d5811a3ef19 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/core/css/css_function_value.h"
#include "third_party/blink/renderer/core/css/css_grid_template_areas_value.h"
#include "third_party/blink/renderer/core/css/css_identifier_value.h"
+#include "third_party/blink/renderer/core/css/css_initial_color_value.h"
#include "third_party/blink/renderer/core/css/css_layout_function_value.h"
#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
#include "third_party/blink/renderer/core/css/css_primitive_value.h"
@@ -31,7 +32,6 @@
#include "third_party/blink/renderer/core/css/parser/css_parser_token.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser.h"
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
#include "third_party/blink/renderer/core/css/parser/font_variant_east_asian_parser.h"
#include "third_party/blink/renderer/core/css/parser/font_variant_ligatures_parser.h"
#include "third_party/blink/renderer/core/css/parser/font_variant_numeric_parser.h"
@@ -45,6 +45,7 @@
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
+#include "third_party/blink/renderer/core/layout/counter_node.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
@@ -85,8 +86,7 @@ const CSSValue* AlignItems::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
// align-items property does not allow the 'auto' value.
- if (css_property_parser_helpers::IdentMatches<CSSValueID::kAuto>(
- range.Peek().Id()))
+ if (css_parsing_utils::IdentMatches<CSSValueID::kAuto>(range.Peek().Id()))
return nullptr;
return css_parsing_utils::ConsumeSelfPositionOverflowPosition(
range, css_parsing_utils::IsSelfPositionKeyword);
@@ -129,8 +129,8 @@ const CSSValue* AnimationDelay::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_property_parser_helpers::ConsumeTime, range, context, kValueRangeAll);
+ return css_parsing_utils::ConsumeCommaSeparatedList(
+ css_parsing_utils::ConsumeTime, range, context, kValueRangeAll);
}
const CSSValue* AnimationDelay::CSSValueFromComputedStyleInternal(
@@ -153,8 +153,8 @@ const CSSValue* AnimationDirection::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext&,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_property_parser_helpers::ConsumeIdent<
+ return css_parsing_utils::ConsumeCommaSeparatedList(
+ css_parsing_utils::ConsumeIdent<
CSSValueID::kNormal, CSSValueID::kAlternate, CSSValueID::kReverse,
CSSValueID::kAlternateReverse>,
range);
@@ -188,9 +188,8 @@ const CSSValue* AnimationDuration::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_property_parser_helpers::ConsumeTime, range, context,
- kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeCommaSeparatedList(
+ css_parsing_utils::ConsumeTime, range, context, kValueRangeNonNegative);
}
const CSSValue* AnimationDuration::CSSValueFromComputedStyleInternal(
@@ -213,10 +212,10 @@ const CSSValue* AnimationFillMode::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext&,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_property_parser_helpers::ConsumeIdent<
- CSSValueID::kNone, CSSValueID::kForwards, CSSValueID::kBackwards,
- CSSValueID::kBoth>,
+ return css_parsing_utils::ConsumeCommaSeparatedList(
+ css_parsing_utils::ConsumeIdent<CSSValueID::kNone, CSSValueID::kForwards,
+ CSSValueID::kBackwards,
+ CSSValueID::kBoth>,
range);
}
@@ -248,7 +247,7 @@ const CSSValue* AnimationIterationCount::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
+ return css_parsing_utils::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumeAnimationIterationCount, range, context);
}
@@ -284,7 +283,7 @@ const CSSValue* AnimationName::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
// Allow quoted name if this is an alias property.
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
+ return css_parsing_utils::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumeAnimationName, range, context,
local_context.UseAliasParsing());
}
@@ -317,9 +316,9 @@ const CSSValue* AnimationPlayState::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext&,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kRunning,
- CSSValueID::kPaused>,
+ return css_parsing_utils::ConsumeCommaSeparatedList(
+ css_parsing_utils::ConsumeIdent<CSSValueID::kRunning,
+ CSSValueID::kPaused>,
range);
}
@@ -347,11 +346,39 @@ const CSSValue* AnimationPlayState::InitialValue() const {
return value;
}
+const CSSValue* AnimationTimeline::ParseSingleValue(
+ CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ const CSSParserLocalContext& local_context) const {
+ return css_parsing_utils::ConsumeCommaSeparatedList(
+ css_parsing_utils::ConsumeAnimationTimeline, range, context);
+}
+
+const CSSValue* AnimationTimeline::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject*,
+ bool allow_visited_style) const {
+ CSSValueList* list = CSSValueList::CreateCommaSeparated();
+ const CSSAnimationData* animation_data = style.Animations();
+ if (animation_data) {
+ for (const auto& timeline : animation_data->TimelineList())
+ list->Append(*ComputedStyleUtils::ValueForStyleNameOrKeyword(timeline));
+ } else {
+ list->Append(*InitialValue());
+ }
+ return list;
+}
+
+const CSSValue* AnimationTimeline::InitialValue() const {
+ return CSSIdentifierValue::Create(CSSValueID::kAuto);
+}
+
const CSSValue* AnimationTimingFunction::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
+ return css_parsing_utils::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumeAnimationTimingFunction, range, context);
}
@@ -375,15 +402,13 @@ const CSSValue* AspectRatio::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- CSSValue* width =
- css_property_parser_helpers::ConsumePositiveInteger(range, context);
+ return css_parsing_utils::ConsumeIdent(range);
+ CSSValue* width = css_parsing_utils::ConsumePositiveInteger(range, context);
if (!width)
return nullptr;
- if (!css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range))
+ if (!css_parsing_utils::ConsumeSlashIncludingWhitespace(range))
return nullptr;
- CSSValue* height =
- css_property_parser_helpers::ConsumePositiveInteger(range, context);
+ CSSValue* height = css_parsing_utils::ConsumePositiveInteger(range, context);
if (!height)
return nullptr;
CSSValueList* list = CSSValueList::CreateSlashSeparated();
@@ -413,7 +438,7 @@ const CSSValue* BackdropFilter::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeFilterFunctionList(range, context);
+ return css_parsing_utils::ConsumeFilterFunctionList(range, context);
}
const CSSValue* BackdropFilter::CSSValueFromComputedStyleInternal(
@@ -438,7 +463,7 @@ const CSSValue* BackgroundAttachment::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext&,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
+ return css_parsing_utils::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumeBackgroundAttachment, range);
}
@@ -458,7 +483,7 @@ const CSSValue* BackgroundBlendMode::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext&,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
+ return css_parsing_utils::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumeBackgroundBlendMode, range);
}
@@ -500,8 +525,8 @@ const CSSValue* BackgroundColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(
- range, context, IsQuirksModeBehavior(context.Mode()));
+ return css_parsing_utils::ConsumeColor(range, context,
+ IsQuirksModeBehavior(context.Mode()));
}
const blink::Color BackgroundColor::ColorIncludingFallback(
@@ -529,8 +554,8 @@ const CSSValue* BackgroundImage::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_property_parser_helpers::ConsumeImageOrNone, range, context);
+ return css_parsing_utils::ConsumeCommaSeparatedList(
+ css_parsing_utils::ConsumeImageOrNone, range, context);
}
const CSSValue* BackgroundImage::CSSValueFromComputedStyleInternal(
@@ -569,7 +594,7 @@ const CSSValue* BackgroundPositionX::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
+ return css_parsing_utils::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumePositionLonghand<CSSValueID::kLeft,
CSSValueID::kRight>,
range, context);
@@ -589,7 +614,7 @@ const CSSValue* BackgroundPositionY::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
+ return css_parsing_utils::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumePositionLonghand<CSSValueID::kTop,
CSSValueID::kBottom>,
range, context);
@@ -629,10 +654,10 @@ const CSSValue* BaselineShift::ParseSingleValue(
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kBaseline || id == CSSValueID::kSub ||
id == CSSValueID::kSuper)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
CSSParserContext::ParserModeOverridingScope scope(context, kSVGAttributeMode);
- return css_property_parser_helpers::ConsumeLengthOrPercent(range, context,
- kValueRangeAll);
+ return css_parsing_utils::ConsumeLengthOrPercent(range, context,
+ kValueRangeAll);
}
const CSSValue* BaselineShift::CSSValueFromComputedStyleInternal(
@@ -704,7 +729,7 @@ const CSSValue* BorderBlockEndColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const CSSValue* BorderBlockEndWidth::ParseSingleValue(
@@ -712,14 +737,14 @@ const CSSValue* BorderBlockEndWidth::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeBorderWidth(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* BorderBlockStartColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const CSSValue* BorderBlockStartWidth::ParseSingleValue(
@@ -727,7 +752,7 @@ const CSSValue* BorderBlockStartWidth::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeBorderWidth(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* BorderBottomColor::ParseSingleValue(
@@ -900,7 +925,7 @@ const CSSValue* BorderImageSource::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeImageOrNone(range, context);
+ return css_parsing_utils::ConsumeImageOrNone(range, context);
}
const CSSValue* BorderImageSource::CSSValueFromComputedStyleInternal(
@@ -956,7 +981,7 @@ const CSSValue* BorderInlineEndColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const CSSValue* BorderInlineEndWidth::ParseSingleValue(
@@ -964,14 +989,14 @@ const CSSValue* BorderInlineEndWidth::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeBorderWidth(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* BorderInlineStartColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const CSSValue* BorderInlineStartWidth::ParseSingleValue(
@@ -979,7 +1004,7 @@ const CSSValue* BorderInlineStartWidth::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeBorderWidth(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* BorderLeftColor::ParseSingleValue(
@@ -1259,8 +1284,8 @@ const CSSValue* CaretColor::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const blink::Color CaretColor::ColorIncludingFallback(
@@ -1317,10 +1342,9 @@ namespace {
CSSValue* ConsumeClipComponent(CSSParserTokenRange& range,
const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeLength(
- range, context, kValueRangeAll,
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeLength(
+ range, context, kValueRangeAll, css_parsing_utils::UnitlessQuirk::kAllow);
}
} // namespace
@@ -1329,28 +1353,24 @@ const CSSValue* Clip::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
if (range.Peek().FunctionId() != CSSValueID::kRect)
return nullptr;
- CSSParserTokenRange args =
- css_property_parser_helpers::ConsumeFunction(range);
+ CSSParserTokenRange args = css_parsing_utils::ConsumeFunction(range);
// rect(t, r, b, l) || rect(t r b l)
CSSValue* top = ConsumeClipComponent(args, context);
if (!top)
return nullptr;
- bool needs_comma =
- css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args);
+ bool needs_comma = css_parsing_utils::ConsumeCommaIncludingWhitespace(args);
CSSValue* right = ConsumeClipComponent(args, context);
- if (!right ||
- (needs_comma &&
- !css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args)))
+ if (!right || (needs_comma &&
+ !css_parsing_utils::ConsumeCommaIncludingWhitespace(args)))
return nullptr;
CSSValue* bottom = ConsumeClipComponent(args, context);
- if (!bottom ||
- (needs_comma &&
- !css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args)))
+ if (!bottom || (needs_comma &&
+ !css_parsing_utils::ConsumeCommaIncludingWhitespace(args)))
return nullptr;
CSSValue* left = ConsumeClipComponent(args, context);
if (!left || !args.AtEnd())
@@ -1382,9 +1402,9 @@ const CSSValue* ClipPath::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
if (cssvalue::CSSURIValue* url =
- css_property_parser_helpers::ConsumeUrl(range, context))
+ css_parsing_utils::ConsumeUrl(range, context))
return url;
return css_parsing_utils::ConsumeBasicShape(range, context);
}
@@ -1418,8 +1438,8 @@ const CSSValue* ClipRule::CSSValueFromComputedStyleInternal(
const CSSValue* Color::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(
- range, context, IsQuirksModeBehavior(context.Mode()));
+ return css_parsing_utils::ConsumeColor(range, context,
+ IsQuirksModeBehavior(context.Mode()));
}
const blink::Color Color::ColorIncludingFallback(
@@ -1469,6 +1489,12 @@ void Color::ApplyValue(StyleResolverState& state, const CSSValue& value) const {
ApplyInherit(state);
return;
}
+ if (auto* initial_color_value = DynamicTo<CSSInitialColorValue>(value)) {
+ DCHECK(RuntimeEnabledFeatures::CSSCascadeEnabled());
+ DCHECK_EQ(state.GetElement(), state.GetDocument().documentElement());
+ state.Style()->SetColor(state.Style()->InitialColorForColorScheme());
+ return;
+ }
state.Style()->SetColor(StyleBuilderConverter::ConvertColor(state, value));
}
@@ -1501,16 +1527,7 @@ const CSSValue* ColorScheme::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kNormal)
- return css_property_parser_helpers::ConsumeIdent(range);
- if (range.Peek().Id() == CSSValueID::kOnly) {
- // Handle 'only light'
- CSSValueList* values = CSSValueList::CreateSpaceSeparated();
- values->Append(*css_property_parser_helpers::ConsumeIdent(range));
- if (range.Peek().Id() != CSSValueID::kLight)
- return nullptr;
- values->Append(*css_property_parser_helpers::ConsumeIdent(range));
- return values;
- }
+ return css_parsing_utils::ConsumeIdent(range);
CSSValueList* values = CSSValueList::CreateSpaceSeparated();
do {
@@ -1522,21 +1539,11 @@ const CSSValue* ColorScheme::ParseSingleValue(
id == CSSValueID::kDefault) {
return nullptr;
}
- if (id == CSSValueID::kOnly) {
- values->Append(*css_property_parser_helpers::ConsumeIdent(range));
- // Has to be 'light only'
- if (range.AtEnd() && values->length() == 2 &&
- To<CSSIdentifierValue>(values->Item(0)).GetValueID() ==
- CSSValueID::kLight) {
- return values;
- }
- return nullptr;
- }
CSSValue* value =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kDark,
- CSSValueID::kLight>(range);
+ css_parsing_utils::ConsumeIdent<CSSValueID::kDark, CSSValueID::kLight>(
+ range);
if (!value)
- value = css_property_parser_helpers::ConsumeCustomIdent(range, context);
+ value = css_parsing_utils::ConsumeCustomIdent(range, context);
if (!value)
return nullptr;
values->Append(*value);
@@ -1582,21 +1589,24 @@ void ColorScheme::ApplyValue(StyleResolverState& state,
bool prefers_dark =
state.GetDocument().GetStyleEngine().GetPreferredColorScheme() ==
PreferredColorScheme::kDark;
- bool use_dark = false;
+ bool has_dark = false;
+ bool has_light = false;
Vector<AtomicString> color_schemes;
for (auto& item : *scheme_list) {
if (const auto* custom_ident = DynamicTo<CSSCustomIdentValue>(*item)) {
color_schemes.push_back(custom_ident->Value());
} else if (const auto* ident = DynamicTo<CSSIdentifierValue>(*item)) {
color_schemes.push_back(ident->CssText());
- if (prefers_dark && ident->GetValueID() == CSSValueID::kDark)
- use_dark = true;
+ if (ident->GetValueID() == CSSValueID::kDark)
+ has_dark = true;
+ else if (ident->GetValueID() == CSSValueID::kLight)
+ has_light = true;
} else {
NOTREACHED();
}
}
state.Style()->SetColorScheme(color_schemes);
- state.Style()->SetDarkColorScheme(use_dark);
+ state.Style()->SetDarkColorScheme(has_dark && (!has_light || prefers_dark));
} else {
NOTREACHED();
}
@@ -1647,7 +1657,7 @@ const CSSValue* ColumnRuleColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const blink::Color ColumnRuleColor::ColorIncludingFallback(
@@ -1680,8 +1690,8 @@ const CSSValue* ColumnRuleWidth::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLineWidth(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
+ return css_parsing_utils::ConsumeLineWidth(
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* ColumnRuleWidth::CSSValueFromComputedStyleInternal(
@@ -1696,8 +1706,8 @@ const CSSValue* ColumnSpan::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeIdent<CSSValueID::kAll,
- CSSValueID::kNone>(range);
+ return css_parsing_utils::ConsumeIdent<CSSValueID::kAll, CSSValueID::kNone>(
+ range);
}
const CSSValue* ColumnSpan::CSSValueFromComputedStyleInternal(
@@ -1733,11 +1743,11 @@ const CSSValue* Contain::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserLocalContext&) const {
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
if (id == CSSValueID::kStrict || id == CSSValueID::kContent) {
- list->Append(*css_property_parser_helpers::ConsumeIdent(range));
+ list->Append(*css_parsing_utils::ConsumeIdent(range));
return list;
}
@@ -1748,13 +1758,13 @@ const CSSValue* Contain::ParseSingleValue(CSSParserTokenRange& range,
while (true) {
id = range.Peek().Id();
if (id == CSSValueID::kSize && !size)
- size = css_property_parser_helpers::ConsumeIdent(range);
+ size = css_parsing_utils::ConsumeIdent(range);
else if (id == CSSValueID::kLayout && !layout)
- layout = css_property_parser_helpers::ConsumeIdent(range);
+ layout = css_parsing_utils::ConsumeIdent(range);
else if (id == CSSValueID::kStyle && !style)
- style = css_property_parser_helpers::ConsumeIdent(range);
+ style = css_parsing_utils::ConsumeIdent(range);
else if (id == CSSValueID::kPaint && !paint)
- paint = css_property_parser_helpers::ConsumeIdent(range);
+ paint = css_parsing_utils::ConsumeIdent(range);
else
break;
}
@@ -1803,13 +1813,13 @@ const CSSValue* ContainIntrinsicSize::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- CSSValue* width = css_property_parser_helpers::ConsumeLength(
- range, context, kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeIdent(range);
+ CSSValue* width =
+ css_parsing_utils::ConsumeLength(range, context, kValueRangeNonNegative);
if (!width)
return nullptr;
- CSSValue* height = css_property_parser_helpers::ConsumeLength(
- range, context, kValueRangeNonNegative);
+ CSSValue* height =
+ css_parsing_utils::ConsumeLength(range, context, kValueRangeNonNegative);
if (!height)
height = width;
return MakeGarbageCollected<CSSValuePair>(width, height,
@@ -1859,7 +1869,7 @@ CSSValue* ConsumeCounterContent(CSSParserTokenRange args,
const CSSParserContext& context,
bool counters) {
CSSCustomIdentValue* identifier =
- css_property_parser_helpers::ConsumeCustomIdent(args, context);
+ css_parsing_utils::ConsumeCustomIdent(args, context);
if (!identifier)
return nullptr;
@@ -1867,7 +1877,7 @@ CSSValue* ConsumeCounterContent(CSSParserTokenRange args,
if (!counters) {
separator = MakeGarbageCollected<CSSStringValue>(String());
} else {
- if (!css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args) ||
+ if (!css_parsing_utils::ConsumeCommaIncludingWhitespace(args) ||
args.Peek().GetType() != kStringToken)
return nullptr;
separator = MakeGarbageCollected<CSSStringValue>(
@@ -1875,12 +1885,12 @@ CSSValue* ConsumeCounterContent(CSSParserTokenRange args,
}
CSSIdentifierValue* list_style = nullptr;
- if (css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args)) {
+ if (css_parsing_utils::ConsumeCommaIncludingWhitespace(args)) {
CSSValueID id = args.Peek().Id();
if ((id != CSSValueID::kNone &&
(id < CSSValueID::kDisc || id > CSSValueID::kKatakanaIroha)))
return nullptr;
- list_style = css_property_parser_helpers::ConsumeIdent(args);
+ list_style = css_parsing_utils::ConsumeIdent(args);
} else {
list_style = CSSIdentifierValue::Create(CSSValueID::kDecimal);
}
@@ -1896,39 +1906,36 @@ CSSValue* ConsumeCounterContent(CSSParserTokenRange args,
const CSSValue* Content::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- if (css_property_parser_helpers::IdentMatches<CSSValueID::kNone,
- CSSValueID::kNormal>(
+ if (css_parsing_utils::IdentMatches<CSSValueID::kNone, CSSValueID::kNormal>(
range.Peek().Id()))
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
CSSValueList* values = CSSValueList::CreateSpaceSeparated();
CSSValueList* outer_list = CSSValueList::CreateSlashSeparated();
bool alt_text_present = false;
do {
- CSSValue* parsed_value =
- css_property_parser_helpers::ConsumeImage(range, context);
+ CSSValue* parsed_value = css_parsing_utils::ConsumeImage(range, context);
if (!parsed_value) {
- parsed_value = css_property_parser_helpers::ConsumeIdent<
+ parsed_value = css_parsing_utils::ConsumeIdent<
CSSValueID::kOpenQuote, CSSValueID::kCloseQuote,
CSSValueID::kNoOpenQuote, CSSValueID::kNoCloseQuote>(range);
}
if (!parsed_value)
- parsed_value = css_property_parser_helpers::ConsumeString(range);
+ parsed_value = css_parsing_utils::ConsumeString(range);
if (!parsed_value) {
if (range.Peek().FunctionId() == CSSValueID::kAttr) {
- parsed_value = ConsumeAttr(
- css_property_parser_helpers::ConsumeFunction(range), context);
+ parsed_value =
+ ConsumeAttr(css_parsing_utils::ConsumeFunction(range), context);
} else if (range.Peek().FunctionId() == CSSValueID::kCounter) {
parsed_value = ConsumeCounterContent(
- css_property_parser_helpers::ConsumeFunction(range), context,
- false);
+ css_parsing_utils::ConsumeFunction(range), context, false);
} else if (range.Peek().FunctionId() == CSSValueID::kCounters) {
parsed_value = ConsumeCounterContent(
- css_property_parser_helpers::ConsumeFunction(range), context, true);
+ css_parsing_utils::ConsumeFunction(range), context, true);
}
}
if (!parsed_value) {
- if (css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range)) {
+ if (css_parsing_utils::ConsumeSlashIncludingWhitespace(range)) {
// No values were parsed before the slash, so nothing to apply the
// alternative text to.
if (!values->length())
@@ -1943,8 +1950,7 @@ const CSSValue* Content::ParseSingleValue(CSSParserTokenRange& range,
} while (!range.AtEnd() && !alt_text_present);
outer_list->Append(*values);
if (alt_text_present) {
- CSSStringValue* alt_text =
- css_property_parser_helpers::ConsumeString(range);
+ CSSStringValue* alt_text = css_parsing_utils::ConsumeString(range);
if (!alt_text)
return nullptr;
outer_list->Append(*alt_text);
@@ -2077,7 +2083,8 @@ const CSSValue* CounterIncrement::CSSValueFromComputedStyleInternal(
const SVGComputedStyle&,
const LayoutObject*,
bool allow_visited_style) const {
- return ComputedStyleUtils::ValueForCounterDirectives(style, true);
+ return ComputedStyleUtils::ValueForCounterDirectives(
+ style, CounterNode::kIncrementType);
}
const int kCounterResetDefaultValue = 0;
@@ -2095,7 +2102,27 @@ const CSSValue* CounterReset::CSSValueFromComputedStyleInternal(
const SVGComputedStyle&,
const LayoutObject*,
bool allow_visited_style) const {
- return ComputedStyleUtils::ValueForCounterDirectives(style, false);
+ return ComputedStyleUtils::ValueForCounterDirectives(style,
+ CounterNode::kResetType);
+}
+
+const int kCounterSetDefaultValue = 0;
+
+const CSSValue* CounterSet::ParseSingleValue(
+ CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ const CSSParserLocalContext&) const {
+ return css_parsing_utils::ConsumeCounter(range, context,
+ kCounterSetDefaultValue);
+}
+
+const CSSValue* CounterSet::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject*,
+ bool allow_visited_style) const {
+ return ComputedStyleUtils::ValueForCounterDirectives(style,
+ CounterNode::kSetType);
}
const CSSValue* Cursor::ParseSingleValue(CSSParserTokenRange& range,
@@ -2103,16 +2130,15 @@ const CSSValue* Cursor::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserLocalContext&) const {
bool in_quirks_mode = IsQuirksModeBehavior(context.Mode());
CSSValueList* list = nullptr;
- while (
- CSSValue* image = css_property_parser_helpers::ConsumeImage(
- range, context,
- css_property_parser_helpers::ConsumeGeneratedImagePolicy::kForbid)) {
+ while (CSSValue* image = css_parsing_utils::ConsumeImage(
+ range, context,
+ css_parsing_utils::ConsumeGeneratedImagePolicy::kForbid)) {
double num;
IntPoint hot_spot(-1, -1);
bool hot_spot_specified = false;
- if (css_property_parser_helpers::ConsumeNumberRaw(range, context, num)) {
+ if (css_parsing_utils::ConsumeNumberRaw(range, context, num)) {
hot_spot.SetX(clampTo<int>(num));
- if (!css_property_parser_helpers::ConsumeNumberRaw(range, context, num))
+ if (!css_parsing_utils::ConsumeNumberRaw(range, context, num))
return nullptr;
hot_spot.SetY(clampTo<int>(num));
hot_spot_specified = true;
@@ -2123,7 +2149,7 @@ const CSSValue* Cursor::ParseSingleValue(CSSParserTokenRange& range,
list->Append(*MakeGarbageCollected<cssvalue::CSSCursorImageValue>(
*image, hot_spot_specified, hot_spot));
- if (!css_property_parser_helpers::ConsumeCommaIncludingWhitespace(range))
+ if (!css_parsing_utils::ConsumeCommaIncludingWhitespace(range))
return nullptr;
}
@@ -2146,7 +2172,7 @@ const CSSValue* Cursor::ParseSingleValue(CSSParserTokenRange& range,
range.ConsumeIncludingWhitespace();
} else if ((id >= CSSValueID::kAuto && id <= CSSValueID::kWebkitZoomOut) ||
id == CSSValueID::kCopy || id == CSSValueID::kNone) {
- cursor_type = css_property_parser_helpers::ConsumeIdent(range);
+ cursor_type = css_parsing_utils::ConsumeIdent(range);
} else {
return nullptr;
}
@@ -2218,8 +2244,8 @@ void Cursor::ApplyValue(StyleResolverState& state,
const CSSValue* Cx::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeSVGGeometryPropertyLength(
- range, context, kValueRangeAll);
+ return css_parsing_utils::ConsumeSVGGeometryPropertyLength(range, context,
+ kValueRangeAll);
}
const CSSValue* Cx::CSSValueFromComputedStyleInternal(
@@ -2234,8 +2260,8 @@ const CSSValue* Cx::CSSValueFromComputedStyleInternal(
const CSSValue* Cy::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeSVGGeometryPropertyLength(
- range, context, kValueRangeAll);
+ return css_parsing_utils::ConsumeSVGGeometryPropertyLength(range, context,
+ kValueRangeAll);
}
const CSSValue* Cy::CSSValueFromComputedStyleInternal(
@@ -2293,10 +2319,9 @@ const CSSValue* Display::ParseSingleValue(CSSParserTokenRange& range,
return nullptr;
CSSParserTokenRange range_copy = range;
- CSSParserTokenRange args =
- css_property_parser_helpers::ConsumeFunction(range_copy);
+ CSSParserTokenRange args = css_parsing_utils::ConsumeFunction(range_copy);
CSSCustomIdentValue* name =
- css_property_parser_helpers::ConsumeCustomIdent(args, context);
+ css_parsing_utils::ConsumeCustomIdent(args, context);
// If we didn't get a custom-ident or didn't exhaust the function arguments
// return nothing.
@@ -2389,7 +2414,7 @@ const CSSValue* FillOpacity::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeAlphaValue(range, context);
+ return css_parsing_utils::ConsumeAlphaValue(range, context);
}
const CSSValue* FillOpacity::CSSValueFromComputedStyleInternal(
@@ -2412,7 +2437,7 @@ const CSSValue* FillRule::CSSValueFromComputedStyleInternal(
const CSSValue* Filter::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeFilterFunctionList(range, context);
+ return css_parsing_utils::ConsumeFilterFunctionList(range, context);
}
const CSSValue* Filter::CSSValueFromComputedStyleInternal(
@@ -2429,9 +2454,9 @@ const CSSValue* FlexBasis::ParseSingleValue(
const CSSParserLocalContext&) const {
// FIXME: Support intrinsic dimensions too.
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeLengthOrPercent(range, context,
+ kValueRangeNonNegative);
}
const CSSValue* FlexBasis::CSSValueFromComputedStyleInternal(
@@ -2454,8 +2479,8 @@ const CSSValue* FlexDirection::CSSValueFromComputedStyleInternal(
const CSSValue* FlexGrow::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeNumber(range, context,
- kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeNumber(range, context,
+ kValueRangeNonNegative);
}
const CSSValue* FlexGrow::CSSValueFromComputedStyleInternal(
@@ -2471,8 +2496,8 @@ const CSSValue* FlexShrink::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeNumber(range, context,
- kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeNumber(range, context,
+ kValueRangeNonNegative);
}
const CSSValue* FlexShrink::CSSValueFromComputedStyleInternal(
@@ -2506,7 +2531,7 @@ const CSSValue* FloodColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const blink::Color FloodColor::ColorIncludingFallback(
@@ -2531,7 +2556,7 @@ const CSSValue* FloodOpacity::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeAlphaValue(range, context);
+ return css_parsing_utils::ConsumeAlphaValue(range, context);
}
const CSSValue* FloodOpacity::CSSValueFromComputedStyleInternal(
@@ -2607,9 +2632,9 @@ const CSSValue* FontSizeAdjust::ParseSingleValue(
const CSSParserLocalContext&) const {
DCHECK(RuntimeEnabledFeatures::CSSFontSizeAdjustEnabled());
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeNumber(range, context,
- kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeNumber(range, context,
+ kValueRangeNonNegative);
}
const CSSValue* FontSizeAdjust::CSSValueFromComputedStyleInternal(
@@ -2628,7 +2653,7 @@ const CSSValue* FontSize::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeFontSize(
- range, context, css_property_parser_helpers::UnitlessQuirk::kAllow);
+ range, context, css_parsing_utils::UnitlessQuirk::kAllow);
}
const CSSValue* FontSize::CSSValueFromComputedStyleInternal(
@@ -2673,7 +2698,7 @@ const CSSValue* FontVariantCaps::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeIdent<
+ return css_parsing_utils::ConsumeIdent<
CSSValueID::kNormal, CSSValueID::kSmallCaps, CSSValueID::kAllSmallCaps,
CSSValueID::kPetiteCaps, CSSValueID::kAllPetiteCaps, CSSValueID::kUnicase,
CSSValueID::kTitlingCaps>(range);
@@ -2692,7 +2717,7 @@ const CSSValue* FontVariantEastAsian::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kNormal)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
FontVariantEastAsianParser east_asian_parser;
do {
@@ -2718,7 +2743,7 @@ const CSSValue* FontVariantLigatures::ParseSingleValue(
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kNormal ||
range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
FontVariantLigaturesParser ligatures_parser;
do {
@@ -2743,7 +2768,7 @@ const CSSValue* FontVariantNumeric::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kNormal)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
FontVariantNumericParser numeric_parser;
do {
@@ -2787,7 +2812,7 @@ cssvalue::CSSFontVariationValue* ConsumeFontVariationTag(
}
double tag_value = 0;
- if (!css_property_parser_helpers::ConsumeNumberRaw(range, context, tag_value))
+ if (!css_parsing_utils::ConsumeNumberRaw(range, context, tag_value))
return nullptr;
return MakeGarbageCollected<cssvalue::CSSFontVariationValue>(
tag, clampTo<float>(tag_value));
@@ -2800,7 +2825,7 @@ const CSSValue* FontVariationSettings::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kNormal)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
CSSValueList* variation_settings = CSSValueList::CreateCommaSeparated();
do {
cssvalue::CSSFontVariationValue* font_variation_value =
@@ -2808,7 +2833,7 @@ const CSSValue* FontVariationSettings::ParseSingleValue(
if (!font_variation_value)
return nullptr;
variation_settings->Append(*font_variation_value);
- } while (css_property_parser_helpers::ConsumeCommaIncludingWhitespace(range));
+ } while (css_parsing_utils::ConsumeCommaIncludingWhitespace(range));
return variation_settings;
}
@@ -2887,6 +2912,13 @@ void InternalVisitedColor::ApplyValue(StyleResolverState& state,
ApplyInherit(state);
return;
}
+ if (auto* initial_color_value = DynamicTo<CSSInitialColorValue>(value)) {
+ DCHECK(RuntimeEnabledFeatures::CSSCascadeEnabled());
+ DCHECK_EQ(state.GetElement(), state.GetDocument().documentElement());
+ state.Style()->SetInternalVisitedColor(
+ state.Style()->InitialColorForColorScheme());
+ return;
+ }
state.Style()->SetInternalVisitedColor(
StyleBuilderConverter::ConvertColor(state, value, true));
}
@@ -2902,8 +2934,8 @@ const CSSValue* InternalVisitedColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
- return css_property_parser_helpers::ConsumeColor(
- range, context, IsQuirksModeBehavior(context.Mode()));
+ return css_parsing_utils::ConsumeColor(range, context,
+ IsQuirksModeBehavior(context.Mode()));
}
const CSSValue* GridAutoColumns::ParseSingleValue(
@@ -2934,14 +2966,14 @@ const CSSValue* GridAutoFlow::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
CSSIdentifierValue* row_or_column_value =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kRow,
- CSSValueID::kColumn>(range);
+ css_parsing_utils::ConsumeIdent<CSSValueID::kRow, CSSValueID::kColumn>(
+ range);
CSSIdentifierValue* dense_algorithm =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kDense>(range);
+ css_parsing_utils::ConsumeIdent<CSSValueID::kDense>(range);
if (!row_or_column_value) {
row_or_column_value =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kRow,
- CSSValueID::kColumn>(range);
+ css_parsing_utils::ConsumeIdent<CSSValueID::kRow, CSSValueID::kColumn>(
+ range);
if (!row_or_column_value && !dense_algorithm)
return nullptr;
}
@@ -3066,7 +3098,7 @@ const CSSValue* GridTemplateAreas::ParseSingleValue(
const CSSParserContext&,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
NamedGridAreaMap grid_area_map;
size_t row_count = 0;
@@ -3103,6 +3135,11 @@ const CSSValue* GridTemplateAreas::CSSValueFromComputedStyleInternal(
}
void GridTemplateAreas::ApplyInitial(StyleResolverState& state) const {
+ state.Style()->SetImplicitNamedGridColumnLines(
+ ComputedStyleInitialValues::InitialImplicitNamedGridColumnLines());
+ state.Style()->SetImplicitNamedGridRowLines(
+ ComputedStyleInitialValues::InitialImplicitNamedGridRowLines());
+
state.Style()->SetNamedGridArea(
ComputedStyleInitialValues::InitialNamedGridArea());
state.Style()->SetNamedGridAreaRowCount(
@@ -3112,6 +3149,11 @@ void GridTemplateAreas::ApplyInitial(StyleResolverState& state) const {
}
void GridTemplateAreas::ApplyInherit(StyleResolverState& state) const {
+ state.Style()->SetImplicitNamedGridColumnLines(
+ state.ParentStyle()->ImplicitNamedGridColumnLines());
+ state.Style()->SetImplicitNamedGridRowLines(
+ state.ParentStyle()->ImplicitNamedGridRowLines());
+
state.Style()->SetNamedGridArea(state.ParentStyle()->NamedGridArea());
state.Style()->SetNamedGridAreaRowCount(
state.ParentStyle()->NamedGridAreaRowCount());
@@ -3122,8 +3164,8 @@ void GridTemplateAreas::ApplyInherit(StyleResolverState& state) const {
void GridTemplateAreas::ApplyValue(StyleResolverState& state,
const CSSValue& value) const {
if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) {
- // FIXME: Shouldn't we clear the grid-area values
DCHECK_EQ(identifier_value->GetValueID(), CSSValueID::kNone);
+ ApplyInitial(state);
return;
}
@@ -3194,7 +3236,7 @@ const CSSValue* Height::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeWidthOrHeight(
- range, context, css_property_parser_helpers::UnitlessQuirk::kAllow);
+ range, context, css_parsing_utils::UnitlessQuirk::kAllow);
}
bool Height::IsLayoutDependent(const ComputedStyle* style,
@@ -3229,9 +3271,9 @@ const CSSValue* ImageOrientation::ParseSingleValue(
const CSSParserLocalContext&) const {
DCHECK(RuntimeEnabledFeatures::ImageOrientationEnabled());
if (range.Peek().Id() == CSSValueID::kFromImage)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
if (range.Peek().Id() == CSSValueID::kNone) {
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
}
return nullptr;
}
@@ -3271,7 +3313,7 @@ const CSSValue* InsetBlockEnd::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* InsetBlockStart::ParseSingleValue(
@@ -3279,7 +3321,7 @@ const CSSValue* InsetBlockStart::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* InsetInlineEnd::ParseSingleValue(
@@ -3287,7 +3329,7 @@ const CSSValue* InsetInlineEnd::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* InsetInlineStart::ParseSingleValue(
@@ -3295,7 +3337,24 @@ const CSSValue* InsetInlineStart::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid);
+}
+
+const CSSValue*
+InternalForcedBackgroundColorRgb::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject*,
+ bool allow_visited_style) const {
+ return CSSIdentifierValue::Create(style.InternalForcedBackgroundColorRgb());
+}
+
+const CSSValue* InternalForcedBackgroundColorRgb::ParseSingleValue(
+ CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ const CSSParserLocalContext& local_context) const {
+ return css_parsing_utils::ConsumeInternalForcedBackgroundColor(range,
+ context);
}
const blink::Color InternalVisitedBackgroundColor::ColorIncludingFallback(
@@ -3323,8 +3382,8 @@ const CSSValue* InternalVisitedBackgroundColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
- return css_property_parser_helpers::ConsumeColor(
- range, context, IsQuirksModeBehavior(context.Mode()));
+ return css_parsing_utils::ConsumeColor(range, context,
+ IsQuirksModeBehavior(context.Mode()));
}
const blink::Color InternalVisitedBorderLeftColor::ColorIncludingFallback(
@@ -3460,7 +3519,7 @@ const CSSValue* InternalVisitedColumnRuleColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const blink::Color InternalVisitedOutlineColor::ColorIncludingFallback(
@@ -3498,7 +3557,7 @@ const CSSValue* InternalVisitedTextDecorationColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const blink::Color InternalVisitedTextEmphasisColor::ColorIncludingFallback(
@@ -3513,7 +3572,7 @@ const CSSValue* InternalVisitedTextEmphasisColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const blink::Color InternalVisitedTextFillColor::ColorIncludingFallback(
@@ -3528,7 +3587,7 @@ const CSSValue* InternalVisitedTextFillColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const blink::Color InternalVisitedTextStrokeColor::ColorIncludingFallback(
@@ -3543,7 +3602,7 @@ const CSSValue* InternalVisitedTextStrokeColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const CSSValue* Isolation::CSSValueFromComputedStyleInternal(
@@ -3559,9 +3618,8 @@ const CSSValue* JustifyContent::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
// justify-content property does not allow the <baseline-position> values.
- if (css_property_parser_helpers::IdentMatches<
- CSSValueID::kFirst, CSSValueID::kLast, CSSValueID::kBaseline>(
- range.Peek().Id()))
+ if (css_parsing_utils::IdentMatches<CSSValueID::kFirst, CSSValueID::kLast,
+ CSSValueID::kBaseline>(range.Peek().Id()))
return nullptr;
return css_parsing_utils::ConsumeContentDistributionOverflowPosition(
range, css_parsing_utils::IsContentPositionOrLeftOrRightKeyword);
@@ -3583,19 +3641,15 @@ const CSSValue* JustifyItems::ParseSingleValue(
const CSSParserLocalContext&) const {
CSSParserTokenRange range_copy = range;
// justify-items property does not allow the 'auto' value.
- if (css_property_parser_helpers::IdentMatches<CSSValueID::kAuto>(
- range.Peek().Id()))
+ if (css_parsing_utils::IdentMatches<CSSValueID::kAuto>(range.Peek().Id()))
return nullptr;
CSSIdentifierValue* legacy =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kLegacy>(
- range_copy);
+ css_parsing_utils::ConsumeIdent<CSSValueID::kLegacy>(range_copy);
CSSIdentifierValue* position_keyword =
- css_property_parser_helpers::ConsumeIdent<
- CSSValueID::kCenter, CSSValueID::kLeft, CSSValueID::kRight>(
- range_copy);
+ css_parsing_utils::ConsumeIdent<CSSValueID::kCenter, CSSValueID::kLeft,
+ CSSValueID::kRight>(range_copy);
if (!legacy) {
- legacy = css_property_parser_helpers::ConsumeIdent<CSSValueID::kLegacy>(
- range_copy);
+ legacy = css_parsing_utils::ConsumeIdent<CSSValueID::kLegacy>(range_copy);
}
if (legacy) {
range = range_copy;
@@ -3683,7 +3737,7 @@ const CSSValue* LightingColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const blink::Color LightingColor::ColorIncludingFallback(
@@ -3731,8 +3785,8 @@ const CSSValue* LineHeightStep::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLength(range, context,
- kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeLength(range, context,
+ kValueRangeNonNegative);
}
const CSSValue* LineHeightStep::CSSValueFromComputedStyleInternal(
@@ -3747,7 +3801,7 @@ const CSSValue* ListStyleImage::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeImageOrNone(range, context);
+ return css_parsing_utils::ConsumeImageOrNone(range, context);
}
const CSSValue* ListStyleImage::CSSValueFromComputedStyleInternal(
@@ -3780,7 +3834,7 @@ const CSSValue* ListStyleType::ParseSingleValue(
const CSSParserLocalContext&) const {
// NOTE: All the keyword values for the list-style-type property are handled
// by the CSSParserFastPaths.
- return css_property_parser_helpers::ConsumeString(range);
+ return css_parsing_utils::ConsumeString(range);
}
const CSSValue* ListStyleType::CSSValueFromComputedStyleInternal(
@@ -3831,7 +3885,7 @@ const CSSValue* MarginBlockEnd::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid);
}
bool MarginBlockStart::IsLayoutDependent(const ComputedStyle* style,
@@ -3844,7 +3898,7 @@ const CSSValue* MarginBlockStart::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* MarginBottom::ParseSingleValue(
@@ -3852,7 +3906,7 @@ const CSSValue* MarginBottom::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context, css_property_parser_helpers::UnitlessQuirk::kAllow);
+ range, context, css_parsing_utils::UnitlessQuirk::kAllow);
}
bool MarginBottom::IsLayoutDependent(const ComputedStyle* style,
@@ -3885,7 +3939,7 @@ const CSSValue* MarginInlineEnd::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid);
}
bool MarginInlineStart::IsLayoutDependent(const ComputedStyle* style,
@@ -3898,7 +3952,7 @@ const CSSValue* MarginInlineStart::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* MarginLeft::ParseSingleValue(
@@ -3906,7 +3960,7 @@ const CSSValue* MarginLeft::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context, css_property_parser_helpers::UnitlessQuirk::kAllow);
+ range, context, css_parsing_utils::UnitlessQuirk::kAllow);
}
bool MarginLeft::IsLayoutDependent(const ComputedStyle* style,
@@ -3934,7 +3988,7 @@ const CSSValue* MarginRight::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context, css_property_parser_helpers::UnitlessQuirk::kAllow);
+ range, context, css_parsing_utils::UnitlessQuirk::kAllow);
}
bool MarginRight::IsLayoutDependent(const ComputedStyle* style,
@@ -3976,7 +4030,7 @@ const CSSValue* MarginTop::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context, css_property_parser_helpers::UnitlessQuirk::kAllow);
+ range, context, css_parsing_utils::UnitlessQuirk::kAllow);
}
bool MarginTop::IsLayoutDependent(const ComputedStyle* style,
@@ -4003,8 +4057,8 @@ const CSSValue* MarkerEnd::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeUrl(range, context);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeUrl(range, context);
}
const CSSValue* MarkerEnd::CSSValueFromComputedStyleInternal(
@@ -4020,8 +4074,8 @@ const CSSValue* MarkerMid::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeUrl(range, context);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeUrl(range, context);
}
const CSSValue* MarkerMid::CSSValueFromComputedStyleInternal(
@@ -4037,8 +4091,8 @@ const CSSValue* MarkerStart::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeUrl(range, context);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeUrl(range, context);
}
const CSSValue* MarkerStart::CSSValueFromComputedStyleInternal(
@@ -4054,8 +4108,8 @@ const CSSValue* Mask::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeUrl(range, context);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeUrl(range, context);
}
const CSSValue* Mask::CSSValueFromComputedStyleInternal(
@@ -4066,37 +4120,6 @@ const CSSValue* Mask::CSSValueFromComputedStyleInternal(
return ComputedStyleUtils::ValueForSVGResource(svg_style.MaskerResource());
}
-const CSSValue* MaskSourceType::ParseSingleValue(
- CSSParserTokenRange& range,
- const CSSParserContext&,
- const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_parsing_utils::ConsumeMaskSourceType, range);
-}
-
-static CSSValue* ValueForFillSourceType(EMaskSourceType type) {
- switch (type) {
- case EMaskSourceType::kAlpha:
- return CSSIdentifierValue::Create(CSSValueID::kAlpha);
- case EMaskSourceType::kLuminance:
- return CSSIdentifierValue::Create(CSSValueID::kLuminance);
- }
- NOTREACHED();
- return nullptr;
-}
-
-const CSSValue* MaskSourceType::CSSValueFromComputedStyleInternal(
- const ComputedStyle& style,
- const SVGComputedStyle&,
- const LayoutObject*,
- bool allow_visited_style) const {
- CSSValueList* list = CSSValueList::CreateCommaSeparated();
- for (const FillLayer* curr_layer = &style.MaskLayers(); curr_layer;
- curr_layer = curr_layer->Next())
- list->Append(*ValueForFillSourceType(curr_layer->MaskSourceType()));
- return list;
-}
-
const CSSValue* MaskType::CSSValueFromComputedStyleInternal(
const ComputedStyle& style,
const SVGComputedStyle& svg_style,
@@ -4133,7 +4156,7 @@ const CSSValue* MaxHeight::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMaxWidthOrHeight(
- range, context, css_property_parser_helpers::UnitlessQuirk::kAllow);
+ range, context, css_parsing_utils::UnitlessQuirk::kAllow);
}
const CSSValue* MaxHeight::CSSValueFromComputedStyleInternal(
@@ -4158,7 +4181,7 @@ const CSSValue* MaxWidth::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMaxWidthOrHeight(
- range, context, css_property_parser_helpers::UnitlessQuirk::kAllow);
+ range, context, css_parsing_utils::UnitlessQuirk::kAllow);
}
const CSSValue* MaxWidth::CSSValueFromComputedStyleInternal(
@@ -4184,7 +4207,7 @@ const CSSValue* MinHeight::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeWidthOrHeight(
- range, context, css_property_parser_helpers::UnitlessQuirk::kAllow);
+ range, context, css_parsing_utils::UnitlessQuirk::kAllow);
}
const CSSValue* MinHeight::CSSValueFromComputedStyleInternal(
@@ -4209,7 +4232,7 @@ const CSSValue* MinWidth::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeWidthOrHeight(
- range, context, css_property_parser_helpers::UnitlessQuirk::kAllow);
+ range, context, css_parsing_utils::UnitlessQuirk::kAllow);
}
const CSSValue* MinWidth::CSSValueFromComputedStyleInternal(
@@ -4244,7 +4267,7 @@ const CSSValue* ObjectPosition::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumePosition(range, context,
- css_property_parser_helpers::UnitlessQuirk::kForbid,
+ css_parsing_utils::UnitlessQuirk::kForbid,
base::Optional<WebFeature>());
}
@@ -4267,9 +4290,9 @@ const CSSValue* OffsetAnchor::ParseSingleValue(
const CSSParserLocalContext&) const {
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumePosition(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid,
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumePosition(
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid,
base::Optional<WebFeature>());
}
@@ -4285,8 +4308,8 @@ const CSSValue* OffsetDistance::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLengthOrPercent(range, context,
- kValueRangeAll);
+ return css_parsing_utils::ConsumeLengthOrPercent(range, context,
+ kValueRangeAll);
}
const CSSValue* OffsetDistance::CSSValueFromComputedStyleInternal(
@@ -4321,9 +4344,9 @@ const CSSValue* OffsetPosition::ParseSingleValue(
const CSSParserLocalContext&) const {
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- CSSValue* value = css_property_parser_helpers::ConsumePosition(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid,
+ return css_parsing_utils::ConsumeIdent(range);
+ CSSValue* value = css_parsing_utils::ConsumePosition(
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid,
base::Optional<WebFeature>());
// Count when we receive a valid position other than 'auto'.
@@ -4362,7 +4385,7 @@ const CSSValue* OffsetRotate::CSSValueFromComputedStyleInternal(
const CSSValue* Opacity::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeAlphaValue(range, context);
+ return css_parsing_utils::ConsumeAlphaValue(range, context);
}
const CSSValue* Opacity::CSSValueFromComputedStyleInternal(
@@ -4377,7 +4400,7 @@ const CSSValue* Opacity::CSSValueFromComputedStyleInternal(
const CSSValue* Order::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeInteger(range, context);
+ return css_parsing_utils::ConsumeInteger(range, context);
}
const CSSValue* Order::CSSValueFromComputedStyleInternal(
@@ -4401,7 +4424,7 @@ const CSSValue* OriginTrialTestProperty::CSSValueFromComputedStyleInternal(
const CSSValue* Orphans::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumePositiveInteger(range, context);
+ return css_parsing_utils::ConsumePositiveInteger(range, context);
}
const CSSValue* Orphans::CSSValueFromComputedStyleInternal(
@@ -4419,8 +4442,8 @@ const CSSValue* OutlineColor::ParseSingleValue(
const CSSParserLocalContext&) const {
// Allow the special focus color even in HTML Standard parsing mode.
if (range.Peek().Id() == CSSValueID::kWebkitFocusRingColor)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const blink::Color OutlineColor::ColorIncludingFallback(
@@ -4445,8 +4468,7 @@ const CSSValue* OutlineOffset::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLength(range, context,
- kValueRangeAll);
+ return css_parsing_utils::ConsumeLength(range, context, kValueRangeAll);
}
const CSSValue* OutlineOffset::CSSValueFromComputedStyleInternal(
@@ -4491,8 +4513,8 @@ const CSSValue* OutlineWidth::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLineWidth(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
+ return css_parsing_utils::ConsumeLineWidth(
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* OutlineWidth::CSSValueFromComputedStyleInternal(
@@ -4560,9 +4582,8 @@ const CSSValue* PaddingBlockEnd::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ return ConsumeLengthOrPercent(range, context, kValueRangeNonNegative,
+ css_parsing_utils::UnitlessQuirk::kForbid);
}
bool PaddingBlockStart::IsLayoutDependent(const ComputedStyle* style,
@@ -4574,18 +4595,16 @@ const CSSValue* PaddingBlockStart::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ return ConsumeLengthOrPercent(range, context, kValueRangeNonNegative,
+ css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* PaddingBottom::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ return ConsumeLengthOrPercent(range, context, kValueRangeNonNegative,
+ css_parsing_utils::UnitlessQuirk::kAllow);
}
bool PaddingBottom::IsLayoutDependent(const ComputedStyle* style,
@@ -4617,9 +4636,8 @@ const CSSValue* PaddingInlineEnd::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ return ConsumeLengthOrPercent(range, context, kValueRangeNonNegative,
+ css_parsing_utils::UnitlessQuirk::kForbid);
}
bool PaddingInlineStart::IsLayoutDependent(const ComputedStyle* style,
@@ -4631,18 +4649,16 @@ const CSSValue* PaddingInlineStart::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ return ConsumeLengthOrPercent(range, context, kValueRangeNonNegative,
+ css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* PaddingLeft::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ return ConsumeLengthOrPercent(range, context, kValueRangeNonNegative,
+ css_parsing_utils::UnitlessQuirk::kAllow);
}
bool PaddingLeft::IsLayoutDependent(const ComputedStyle* style,
@@ -4669,9 +4685,8 @@ const CSSValue* PaddingRight::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ return ConsumeLengthOrPercent(range, context, kValueRangeNonNegative,
+ css_parsing_utils::UnitlessQuirk::kAllow);
}
bool PaddingRight::IsLayoutDependent(const ComputedStyle* style,
@@ -4698,9 +4713,8 @@ const CSSValue* PaddingTop::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ return ConsumeLengthOrPercent(range, context, kValueRangeNonNegative,
+ css_parsing_utils::UnitlessQuirk::kAllow);
}
bool PaddingTop::IsLayoutDependent(const ComputedStyle* style,
@@ -4727,8 +4741,8 @@ const CSSValue* Page::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeCustomIdent(range, context);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeCustomIdent(range, context);
}
const CSSValue* Page::CSSValueFromComputedStyleInternal(
@@ -4746,7 +4760,7 @@ const CSSValue* PaintOrder::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kNormal)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
Vector<CSSValueID, 3> paint_type_list;
CSSIdentifierValue* fill = nullptr;
@@ -4755,11 +4769,11 @@ const CSSValue* PaintOrder::ParseSingleValue(
do {
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kFill && !fill)
- fill = css_property_parser_helpers::ConsumeIdent(range);
+ fill = css_parsing_utils::ConsumeIdent(range);
else if (id == CSSValueID::kStroke && !stroke)
- stroke = css_property_parser_helpers::ConsumeIdent(range);
+ stroke = css_parsing_utils::ConsumeIdent(range);
else if (id == CSSValueID::kMarkers && !markers)
- markers = css_property_parser_helpers::ConsumeIdent(range);
+ markers = css_parsing_utils::ConsumeIdent(range);
else
return nullptr;
paint_type_list.push_back(id);
@@ -4836,14 +4850,13 @@ const CSSValue* Perspective::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext& localContext) const {
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
- CSSPrimitiveValue* parsed_value = css_property_parser_helpers::ConsumeLength(
- range, context, kValueRangeAll);
+ return css_parsing_utils::ConsumeIdent(range);
+ CSSPrimitiveValue* parsed_value =
+ css_parsing_utils::ConsumeLength(range, context, kValueRangeAll);
bool use_legacy_parsing = localContext.UseAliasParsing();
if (!parsed_value && use_legacy_parsing) {
double perspective;
- if (!css_property_parser_helpers::ConsumeNumberRaw(range, context,
- perspective))
+ if (!css_parsing_utils::ConsumeNumberRaw(range, context, perspective))
return nullptr;
context.Count(WebFeature::kUnitlessPerspectiveInPerspectiveProperty);
parsed_value = CSSNumericLiteralValue::Create(
@@ -4870,7 +4883,7 @@ const CSSValue* PerspectiveOrigin::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumePosition(range, context,
- css_property_parser_helpers::UnitlessQuirk::kForbid,
+ css_parsing_utils::UnitlessQuirk::kForbid,
base::Optional<WebFeature>());
}
@@ -4932,11 +4945,10 @@ const CSSValue* Quotes::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
CSSValueList* values = CSSValueList::CreateSpaceSeparated();
while (!range.AtEnd()) {
- CSSStringValue* parsed_value =
- css_property_parser_helpers::ConsumeString(range);
+ CSSStringValue* parsed_value = css_parsing_utils::ConsumeString(range);
if (!parsed_value)
return nullptr;
values->Append(*parsed_value);
@@ -4972,7 +4984,7 @@ const CSSValue* Quotes::CSSValueFromComputedStyleInternal(
const CSSValue* R::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeSVGGeometryPropertyLength(
+ return css_parsing_utils::ConsumeSVGGeometryPropertyLength(
range, context, kValueRangeNonNegative);
}
@@ -5040,22 +5052,22 @@ const CSSValue* Rotate::ParseSingleValue(CSSParserTokenRange& range,
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
- CSSValue* rotation = css_property_parser_helpers::ConsumeAngle(
+ CSSValue* rotation = css_parsing_utils::ConsumeAngle(
range, context, base::Optional<WebFeature>());
- CSSValue* axis = css_property_parser_helpers::ConsumeAxis(range, context);
+ CSSValue* axis = css_parsing_utils::ConsumeAxis(range, context);
if (axis)
list->Append(*axis);
else if (!rotation)
return nullptr;
if (!rotation) {
- rotation = css_property_parser_helpers::ConsumeAngle(
- range, context, base::Optional<WebFeature>());
+ rotation = css_parsing_utils::ConsumeAngle(range, context,
+ base::Optional<WebFeature>());
if (!rotation)
return nullptr;
}
@@ -5103,8 +5115,8 @@ const CSSValue* Rx::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeSVGGeometryPropertyLength(
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeSVGGeometryPropertyLength(
range, context, kValueRangeNonNegative);
}
@@ -5121,8 +5133,8 @@ const CSSValue* Ry::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeSVGGeometryPropertyLength(
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeSVGGeometryPropertyLength(
range, context, kValueRangeNonNegative);
}
@@ -5142,21 +5154,21 @@ const CSSValue* Scale::ParseSingleValue(CSSParserTokenRange& range,
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
- CSSValue* x_scale = css_property_parser_helpers::ConsumeNumber(
- range, context, kValueRangeAll);
+ CSSValue* x_scale =
+ css_parsing_utils::ConsumeNumber(range, context, kValueRangeAll);
if (!x_scale)
return nullptr;
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
list->Append(*x_scale);
- CSSValue* y_scale = css_property_parser_helpers::ConsumeNumber(
- range, context, kValueRangeAll);
+ CSSValue* y_scale =
+ css_parsing_utils::ConsumeNumber(range, context, kValueRangeAll);
if (y_scale) {
- CSSValue* z_scale = css_property_parser_helpers::ConsumeNumber(
- range, context, kValueRangeAll);
+ CSSValue* z_scale =
+ css_parsing_utils::ConsumeNumber(range, context, kValueRangeAll);
if (z_scale) {
list->Append(*y_scale);
list->Append(*z_scale);
@@ -5196,6 +5208,80 @@ const CSSValue* Scale::CSSValueFromComputedStyleInternal(
return list;
}
+// https://www.w3.org/TR/css-overflow-4
+// auto | [ stable | always ] && both? && force?
+const CSSValue* ScrollbarGutter::ParseSingleValue(
+ CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ const CSSParserLocalContext&) const {
+ if (!RuntimeEnabledFeatures::ScrollbarGutterEnabled())
+ return nullptr;
+
+ if (auto* value = css_parsing_utils::ConsumeIdent<CSSValueID::kAuto>(range))
+ return value;
+
+ CSSIdentifierValue* stable_or_always = nullptr;
+ CSSIdentifierValue* both = nullptr;
+ CSSIdentifierValue* force = nullptr;
+
+ while (!range.AtEnd()) {
+ if (!stable_or_always) {
+ if ((stable_or_always =
+ css_parsing_utils::ConsumeIdent<CSSValueID::kStable,
+ CSSValueID::kAlways>(range)))
+ continue;
+ }
+ CSSValueID id = range.Peek().Id();
+ if (id == CSSValueID::kBoth && !both)
+ both = css_parsing_utils::ConsumeIdent(range);
+ else if (id == CSSValueID::kForce && !force)
+ force = css_parsing_utils::ConsumeIdent(range);
+ else
+ return nullptr;
+ }
+ if (!stable_or_always)
+ return nullptr;
+ if (both || force) {
+ CSSValueList* list = CSSValueList::CreateSpaceSeparated();
+ list->Append(*stable_or_always);
+ if (both)
+ list->Append(*both);
+ if (force)
+ list->Append(*force);
+ return list;
+ }
+ return stable_or_always;
+}
+
+const CSSValue* ScrollbarGutter::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject*,
+ bool allow_visited_style) const {
+ auto scrollbar_gutter = style.ScrollbarGutter();
+ if (scrollbar_gutter == kScrollbarGutterAuto)
+ return CSSIdentifierValue::Create(CSSValueID::kAuto);
+
+ DCHECK(scrollbar_gutter & (kScrollbarGutterStable | kScrollbarGutterAlways));
+
+ CSSValue* main_value = nullptr;
+ if (scrollbar_gutter & kScrollbarGutterStable)
+ main_value = CSSIdentifierValue::Create(CSSValueID::kStable);
+ else
+ main_value = CSSIdentifierValue::Create(CSSValueID::kAlways);
+
+ if (!(scrollbar_gutter & (kScrollbarGutterBoth | kScrollbarGutterForce)))
+ return main_value;
+
+ CSSValueList* list = CSSValueList::CreateSpaceSeparated();
+ list->Append(*main_value);
+ if (scrollbar_gutter & kScrollbarGutterBoth)
+ list->Append(*CSSIdentifierValue::Create(kScrollbarGutterBoth));
+ if (scrollbar_gutter & kScrollbarGutterForce)
+ list->Append(*CSSIdentifierValue::Create(kScrollbarGutterForce));
+ return list;
+}
+
const CSSValue* ScrollBehavior::CSSValueFromComputedStyleInternal(
const ComputedStyle& style,
const SVGComputedStyle&,
@@ -5213,11 +5299,11 @@ static bool ConsumePan(CSSParserTokenRange& range,
if ((id == CSSValueID::kPanX || id == CSSValueID::kPanRight ||
id == CSSValueID::kPanLeft) &&
!*pan_x) {
- *pan_x = css_property_parser_helpers::ConsumeIdent(range);
+ *pan_x = css_parsing_utils::ConsumeIdent(range);
} else if ((id == CSSValueID::kPanY || id == CSSValueID::kPanDown ||
id == CSSValueID::kPanUp) &&
!*pan_y) {
- *pan_y = css_property_parser_helpers::ConsumeIdent(range);
+ *pan_y = css_parsing_utils::ConsumeIdent(range);
} else {
return false;
}
@@ -5233,7 +5319,7 @@ const CSSValue* ScrollCustomization::ParseSingleValue(
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kAuto || id == CSSValueID::kNone) {
- list->Append(*css_property_parser_helpers::ConsumeIdent(range));
+ list->Append(*css_parsing_utils::ConsumeIdent(range));
return list;
}
@@ -5265,7 +5351,7 @@ const CSSValue* ScrollMarginBlockEnd::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context, kValueRangeAll,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollMarginBlockStart::ParseSingleValue(
@@ -5273,7 +5359,7 @@ const CSSValue* ScrollMarginBlockStart::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context, kValueRangeAll,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollMarginBottom::ParseSingleValue(
@@ -5281,7 +5367,7 @@ const CSSValue* ScrollMarginBottom::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context, kValueRangeAll,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollMarginBottom::CSSValueFromComputedStyleInternal(
@@ -5297,7 +5383,7 @@ const CSSValue* ScrollMarginInlineEnd::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context, kValueRangeAll,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollMarginInlineStart::ParseSingleValue(
@@ -5305,7 +5391,7 @@ const CSSValue* ScrollMarginInlineStart::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context, kValueRangeAll,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollMarginLeft::ParseSingleValue(
@@ -5313,7 +5399,7 @@ const CSSValue* ScrollMarginLeft::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context, kValueRangeAll,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollMarginLeft::CSSValueFromComputedStyleInternal(
@@ -5329,7 +5415,7 @@ const CSSValue* ScrollMarginRight::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context, kValueRangeAll,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollMarginRight::CSSValueFromComputedStyleInternal(
@@ -5345,7 +5431,7 @@ const CSSValue* ScrollMarginTop::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context, kValueRangeAll,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollMarginTop::CSSValueFromComputedStyleInternal(
@@ -5452,17 +5538,19 @@ const CSSValue* ScrollSnapAlign::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- CSSValue* block_value = css_property_parser_helpers::ConsumeIdent<
- CSSValueID::kNone, CSSValueID::kStart, CSSValueID::kEnd,
- CSSValueID::kCenter>(range);
+ CSSValue* block_value =
+ css_parsing_utils::ConsumeIdent<CSSValueID::kNone, CSSValueID::kStart,
+ CSSValueID::kEnd, CSSValueID::kCenter>(
+ range);
if (!block_value)
return nullptr;
if (range.AtEnd())
return block_value;
- CSSValue* inline_value = css_property_parser_helpers::ConsumeIdent<
- CSSValueID::kNone, CSSValueID::kStart, CSSValueID::kEnd,
- CSSValueID::kCenter>(range);
+ CSSValue* inline_value =
+ css_parsing_utils::ConsumeIdent<CSSValueID::kNone, CSSValueID::kStart,
+ CSSValueID::kEnd, CSSValueID::kCenter>(
+ range);
if (!inline_value)
return block_value;
auto* pair = MakeGarbageCollected<CSSValuePair>(
@@ -5496,7 +5584,7 @@ const CSSValue* ScrollSnapType::ParseSingleValue(
axis_id != CSSValueID::kY && axis_id != CSSValueID::kBlock &&
axis_id != CSSValueID::kInline && axis_id != CSSValueID::kBoth)
return nullptr;
- CSSValue* axis_value = css_property_parser_helpers::ConsumeIdent(range);
+ CSSValue* axis_value = css_parsing_utils::ConsumeIdent(range);
if (range.AtEnd() || axis_id == CSSValueID::kNone)
return axis_value;
@@ -5504,7 +5592,7 @@ const CSSValue* ScrollSnapType::ParseSingleValue(
if (strictness_id != CSSValueID::kProximity &&
strictness_id != CSSValueID::kMandatory)
return axis_value;
- CSSValue* strictness_value = css_property_parser_helpers::ConsumeIdent(range);
+ CSSValue* strictness_value = css_parsing_utils::ConsumeIdent(range);
if (strictness_id == CSSValueID::kProximity)
return axis_value; // Shortest serialization.
auto* pair = MakeGarbageCollected<CSSValuePair>(
@@ -5525,7 +5613,7 @@ const CSSValue* ShapeImageThreshold::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeAlphaValue(range, context);
+ return css_parsing_utils::ConsumeAlphaValue(range, context);
}
const CSSValue* ShapeImageThreshold::CSSValueFromComputedStyleInternal(
@@ -5541,8 +5629,8 @@ const CSSValue* ShapeMargin::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeLengthOrPercent(range, context,
+ kValueRangeNonNegative);
}
const CSSValue* ShapeMargin::CSSValueFromComputedStyleInternal(
@@ -5558,15 +5646,15 @@ const CSSValue* ShapeOutside::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (CSSValue* image_value =
- css_property_parser_helpers::ConsumeImageOrNone(range, context))
+ css_parsing_utils::ConsumeImageOrNone(range, context))
return image_value;
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
- CSSValue* box_value = css_property_parser_helpers::ConsumeShapeBox(range);
+ CSSValue* box_value = css_parsing_utils::ConsumeShapeBox(range);
if (CSSValue* shape_value =
css_parsing_utils::ConsumeBasicShape(range, context)) {
list->Append(*shape_value);
if (!box_value) {
- box_value = css_property_parser_helpers::ConsumeShapeBox(range);
+ box_value = css_parsing_utils::ConsumeShapeBox(range);
}
}
if (box_value)
@@ -5594,7 +5682,7 @@ const CSSValue* ShapeRendering::CSSValueFromComputedStyleInternal(
}
static CSSValue* ConsumePageSize(CSSParserTokenRange& range) {
- return css_property_parser_helpers::ConsumeIdent<
+ return css_parsing_utils::ConsumeIdent<
CSSValueID::kA3, CSSValueID::kA4, CSSValueID::kA5, CSSValueID::kB4,
CSSValueID::kB5, CSSValueID::kJisB5, CSSValueID::kJisB4,
CSSValueID::kLedger, CSSValueID::kLegal, CSSValueID::kLetter>(range);
@@ -5640,14 +5728,14 @@ const CSSValue* Size::ParseSingleValue(CSSParserTokenRange& range,
CSSValueList* result = CSSValueList::CreateSpaceSeparated();
if (range.Peek().Id() == CSSValueID::kAuto) {
- result->Append(*css_property_parser_helpers::ConsumeIdent(range));
+ result->Append(*css_parsing_utils::ConsumeIdent(range));
return result;
}
- if (CSSValue* width = css_property_parser_helpers::ConsumeLength(
+ if (CSSValue* width = css_parsing_utils::ConsumeLength(
range, context, kValueRangeNonNegative)) {
- CSSValue* height = css_property_parser_helpers::ConsumeLength(
- range, context, kValueRangeNonNegative);
+ CSSValue* height = css_parsing_utils::ConsumeLength(range, context,
+ kValueRangeNonNegative);
result->Append(*width);
if (height)
result->Append(*height);
@@ -5656,8 +5744,8 @@ const CSSValue* Size::ParseSingleValue(CSSParserTokenRange& range,
CSSValue* page_size = ConsumePageSize(range);
CSSValue* orientation =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kPortrait,
- CSSValueID::kLandscape>(range);
+ css_parsing_utils::ConsumeIdent<CSSValueID::kPortrait,
+ CSSValueID::kLandscape>(range);
if (!page_size)
page_size = ConsumePageSize(range);
@@ -5749,7 +5837,7 @@ const CSSValue* StopColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const blink::Color StopColor::ColorIncludingFallback(
@@ -5773,7 +5861,7 @@ const CSSValue* StopOpacity::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeAlphaValue(range, context);
+ return css_parsing_utils::ConsumeAlphaValue(range, context);
}
const CSSValue* StopOpacity::CSSValueFromComputedStyleInternal(
@@ -5806,17 +5894,15 @@ const CSSValue* StrokeDasharray::ParseSingleValue(
const CSSParserLocalContext&) const {
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
CSSParserContext::ParserModeOverridingScope scope(context, kSVGAttributeMode);
CSSValueList* dashes = CSSValueList::CreateCommaSeparated();
do {
- CSSPrimitiveValue* dash =
- css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeNonNegative);
- if (!dash ||
- (css_property_parser_helpers::ConsumeCommaIncludingWhitespace(range) &&
- range.AtEnd()))
+ CSSPrimitiveValue* dash = css_parsing_utils::ConsumeLengthOrPercent(
+ range, context, kValueRangeNonNegative);
+ if (!dash || (css_parsing_utils::ConsumeCommaIncludingWhitespace(range) &&
+ range.AtEnd()))
return nullptr;
dashes->Append(*dash);
} while (!range.AtEnd());
@@ -5837,9 +5923,9 @@ const CSSValue* StrokeDashoffset::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
CSSParserContext::ParserModeOverridingScope scope(context, kSVGAttributeMode);
- return css_property_parser_helpers::ConsumeLengthOrPercent(
+ return css_parsing_utils::ConsumeLengthOrPercent(
range, context, kValueRangeAll,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* StrokeDashoffset::CSSValueFromComputedStyleInternal(
@@ -5871,8 +5957,8 @@ const CSSValue* StrokeMiterlimit::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeNumber(range, context,
- kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeNumber(range, context,
+ kValueRangeNonNegative);
}
const CSSValue* StrokeMiterlimit::CSSValueFromComputedStyleInternal(
@@ -5888,7 +5974,7 @@ const CSSValue* StrokeOpacity::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeAlphaValue(range, context);
+ return css_parsing_utils::ConsumeAlphaValue(range, context);
}
const CSSValue* StrokeOpacity::CSSValueFromComputedStyleInternal(
@@ -5905,9 +5991,9 @@ const CSSValue* StrokeWidth::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
CSSParserContext::ParserModeOverridingScope scope(context, kSVGAttributeMode);
- return css_property_parser_helpers::ConsumeLengthOrPercent(
+ return css_parsing_utils::ConsumeLengthOrPercent(
range, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* StrokeWidth::CSSValueFromComputedStyleInternal(
@@ -5937,23 +6023,23 @@ const CSSValue* ContentVisibility::ParseSingleValue(
!RuntimeEnabledFeatures::CSSContentVisibilityHiddenMatchableEnabled()) {
return nullptr;
}
- if (!css_property_parser_helpers::IdentMatches<
- CSSValueID::kVisible, CSSValueID::kAuto, CSSValueID::kHidden,
- CSSValueID::kHiddenMatchable>(id)) {
+ if (!css_parsing_utils::IdentMatches<CSSValueID::kVisible, CSSValueID::kAuto,
+ CSSValueID::kHidden,
+ CSSValueID::kHiddenMatchable>(id)) {
return nullptr;
}
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
}
const CSSValue* TabSize::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- CSSPrimitiveValue* parsed_value = css_property_parser_helpers::ConsumeNumber(
- range, context, kValueRangeNonNegative);
+ CSSPrimitiveValue* parsed_value =
+ css_parsing_utils::ConsumeNumber(range, context, kValueRangeNonNegative);
if (parsed_value)
return parsed_value;
- return css_property_parser_helpers::ConsumeLength(range, context,
- kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeLength(range, context,
+ kValueRangeNonNegative);
}
const CSSValue* TabSize::CSSValueFromComputedStyleInternal(
@@ -6038,7 +6124,7 @@ const CSSValue* TextDecorationColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const blink::Color TextDecorationColor::ColorIncludingFallback(
@@ -6097,13 +6183,12 @@ const CSSValue* TextDecorationThickness::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
DCHECK(RuntimeEnabledFeatures::UnderlineOffsetThicknessEnabled());
- if (auto* ident =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kFromFont,
+ if (auto* ident = css_parsing_utils::ConsumeIdent<CSSValueID::kFromFont,
CSSValueID::kAuto>(range)) {
return ident;
}
- return css_property_parser_helpers::ConsumeLengthOrPercent(range, context,
- kValueRangeAll);
+ return css_parsing_utils::ConsumeLengthOrPercent(range, context,
+ kValueRangeAll);
}
const CSSValue* TextDecorationThickness::CSSValueFromComputedStyleInternal(
@@ -6111,9 +6196,14 @@ const CSSValue* TextDecorationThickness::CSSValueFromComputedStyleInternal(
const SVGComputedStyle&,
const LayoutObject*,
bool allow_visited_style) const {
+ DCHECK(RuntimeEnabledFeatures::UnderlineOffsetThicknessEnabled());
+
if (style.GetTextDecorationThickness().IsFromFont())
return CSSIdentifierValue::Create(CSSValueID::kFromFont);
+ if (style.GetTextDecorationThickness().IsAuto())
+ return CSSIdentifierValue::Create(CSSValueID::kAuto);
+
return ComputedStyleUtils::ZoomAdjustedPixelValueForLength(
style.GetTextDecorationThickness().Thickness(), style);
}
@@ -6129,9 +6219,9 @@ const CSSValue* TextIndent::ParseSingleValue(
CSSValue* each_line = nullptr;
do {
if (!length_percentage) {
- length_percentage = css_property_parser_helpers::ConsumeLengthOrPercent(
+ length_percentage = css_parsing_utils::ConsumeLengthOrPercent(
range, context, kValueRangeAll,
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ css_parsing_utils::UnitlessQuirk::kAllow);
if (length_percentage) {
continue;
}
@@ -6140,11 +6230,11 @@ const CSSValue* TextIndent::ParseSingleValue(
if (RuntimeEnabledFeatures::CSS3TextEnabled()) {
CSSValueID id = range.Peek().Id();
if (!hanging && id == CSSValueID::kHanging) {
- hanging = css_property_parser_helpers::ConsumeIdent(range);
+ hanging = css_parsing_utils::ConsumeIdent(range);
continue;
}
if (!each_line && id == CSSValueID::kEachLine) {
- each_line = css_property_parser_helpers::ConsumeIdent(range);
+ each_line = css_parsing_utils::ConsumeIdent(range);
continue;
}
}
@@ -6296,11 +6386,11 @@ const CSSValue* TextSizeAdjust::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumePercent(range, context,
- kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumePercent(range, context,
+ kValueRangeNonNegative);
}
const CSSValue* TextSizeAdjust::CSSValueFromComputedStyleInternal(
@@ -6330,25 +6420,22 @@ const CSSValue* TextUnderlinePosition::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
CSSIdentifierValue* from_font_or_under_value =
RuntimeEnabledFeatures::UnderlineOffsetThicknessEnabled()
- ? css_property_parser_helpers::ConsumeIdent<CSSValueID::kFromFont,
- CSSValueID::kUnder>(range)
- : css_property_parser_helpers::ConsumeIdent<CSSValueID::kUnder>(
- range);
+ ? css_parsing_utils::ConsumeIdent<CSSValueID::kFromFont,
+ CSSValueID::kUnder>(range)
+ : css_parsing_utils::ConsumeIdent<CSSValueID::kUnder>(range);
CSSIdentifierValue* left_or_right_value =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kLeft,
- CSSValueID::kRight>(range);
+ css_parsing_utils::ConsumeIdent<CSSValueID::kLeft, CSSValueID::kRight>(
+ range);
if (left_or_right_value && !from_font_or_under_value) {
from_font_or_under_value =
RuntimeEnabledFeatures::UnderlineOffsetThicknessEnabled()
- ? css_property_parser_helpers::ConsumeIdent<CSSValueID::kFromFont,
- CSSValueID::kUnder>(
- range)
- : css_property_parser_helpers::ConsumeIdent<CSSValueID::kUnder>(
- range);
+ ? css_parsing_utils::ConsumeIdent<CSSValueID::kFromFont,
+ CSSValueID::kUnder>(range)
+ : css_parsing_utils::ConsumeIdent<CSSValueID::kUnder>(range);
}
if (!from_font_or_under_value && !left_or_right_value)
return nullptr;
@@ -6398,9 +6485,9 @@ const CSSValue* TextUnderlineOffset::ParseSingleValue(
const CSSParserLocalContext&) const {
DCHECK(RuntimeEnabledFeatures::UnderlineOffsetThicknessEnabled());
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeLengthOrPercent(range, context,
- kValueRangeAll);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeLengthOrPercent(range, context,
+ kValueRangeAll);
}
const CSSValue* TextUnderlineOffset::CSSValueFromComputedStyleInternal(
@@ -6445,13 +6532,13 @@ static bool ConsumePan(CSSParserTokenRange& range,
if ((id == CSSValueID::kPanX || id == CSSValueID::kPanRight ||
id == CSSValueID::kPanLeft) &&
!pan_x) {
- pan_x = css_property_parser_helpers::ConsumeIdent(range);
+ pan_x = css_parsing_utils::ConsumeIdent(range);
} else if ((id == CSSValueID::kPanY || id == CSSValueID::kPanDown ||
id == CSSValueID::kPanUp) &&
!pan_y) {
- pan_y = css_property_parser_helpers::ConsumeIdent(range);
+ pan_y = css_parsing_utils::ConsumeIdent(range);
} else if (id == CSSValueID::kPinchZoom && !pinch_zoom) {
- pinch_zoom = css_property_parser_helpers::ConsumeIdent(range);
+ pinch_zoom = css_parsing_utils::ConsumeIdent(range);
} else {
return false;
}
@@ -6468,7 +6555,7 @@ const CSSValue* TouchAction::ParseSingleValue(
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kAuto || id == CSSValueID::kNone ||
id == CSSValueID::kManipulation) {
- list->Append(*css_property_parser_helpers::ConsumeIdent(range));
+ list->Append(*css_parsing_utils::ConsumeIdent(range));
return list;
}
@@ -6534,14 +6621,14 @@ const CSSValue* TransformOrigin::ParseSingleValue(
const CSSParserLocalContext&) const {
CSSValue* result_x = nullptr;
CSSValue* result_y = nullptr;
- if (css_property_parser_helpers::ConsumeOneOrTwoValuedPosition(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid,
- result_x, result_y)) {
+ if (css_parsing_utils::ConsumeOneOrTwoValuedPosition(
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid, result_x,
+ result_y)) {
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
list->Append(*result_x);
list->Append(*result_y);
- CSSValue* result_z = css_property_parser_helpers::ConsumeLength(
- range, context, kValueRangeAll);
+ CSSValue* result_z =
+ css_parsing_utils::ConsumeLength(range, context, kValueRangeAll);
if (result_z)
list->Append(*result_z);
return list;
@@ -6595,8 +6682,8 @@ const CSSValue* TransitionDelay::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_property_parser_helpers::ConsumeTime, range, context, kValueRangeAll);
+ return css_parsing_utils::ConsumeCommaSeparatedList(
+ css_parsing_utils::ConsumeTime, range, context, kValueRangeAll);
}
const CSSValue* TransitionDelay::CSSValueFromComputedStyleInternal(
@@ -6619,9 +6706,8 @@ const CSSValue* TransitionDuration::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_property_parser_helpers::ConsumeTime, range, context,
- kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeCommaSeparatedList(
+ css_parsing_utils::ConsumeTime, range, context, kValueRangeNonNegative);
}
const CSSValue* TransitionDuration::CSSValueFromComputedStyleInternal(
@@ -6644,7 +6730,7 @@ const CSSValue* TransitionProperty::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- CSSValueList* list = css_property_parser_helpers::ConsumeCommaSeparatedList(
+ CSSValueList* list = css_parsing_utils::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumeTransitionProperty, range, context);
if (!list || !css_parsing_utils::IsValidPropertyList(*list))
return nullptr;
@@ -6669,7 +6755,7 @@ const CSSValue* TransitionTimingFunction::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
+ return css_parsing_utils::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumeAnimationTimingFunction, range, context);
}
@@ -6695,20 +6781,19 @@ const CSSValue* Translate::ParseSingleValue(
DCHECK(RuntimeEnabledFeatures::CSSIndependentTransformPropertiesEnabled());
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
- CSSValue* translate_x = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeAll);
+ CSSValue* translate_x =
+ css_parsing_utils::ConsumeLengthOrPercent(range, context, kValueRangeAll);
if (!translate_x)
return nullptr;
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
list->Append(*translate_x);
CSSPrimitiveValue* translate_y =
- css_property_parser_helpers::ConsumeLengthOrPercent(range, context,
- kValueRangeAll);
+ css_parsing_utils::ConsumeLengthOrPercent(range, context, kValueRangeAll);
if (translate_y) {
- CSSValue* translate_z = css_property_parser_helpers::ConsumeLength(
- range, context, kValueRangeAll);
+ CSSValue* translate_z =
+ css_parsing_utils::ConsumeLength(range, context, kValueRangeAll);
if (translate_y->IsZero() && !translate_z)
return list;
@@ -6777,12 +6862,12 @@ const CSSValue* VerticalAlign::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- CSSValue* parsed_value = css_property_parser_helpers::ConsumeIdentRange(
+ CSSValue* parsed_value = css_parsing_utils::ConsumeIdentRange(
range, CSSValueID::kBaseline, CSSValueID::kWebkitBaselineMiddle);
if (!parsed_value) {
- parsed_value = css_property_parser_helpers::ConsumeLengthOrPercent(
+ parsed_value = css_parsing_utils::ConsumeLengthOrPercent(
range, context, kValueRangeAll,
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ css_parsing_utils::UnitlessQuirk::kAllow);
}
return parsed_value;
}
@@ -6885,9 +6970,8 @@ const CSSValue* Appearance::ParseSingleValue(
context.Mode())) {
if (local_context.UseAliasParsing())
property = CSSPropertyID::kAliasWebkitAppearance;
- css_property_parser_helpers::CountKeywordOnlyPropertyUsage(property,
- context, id);
- return css_property_parser_helpers::ConsumeIdent(range);
+ css_parsing_utils::CountKeywordOnlyPropertyUsage(property, context, id);
+ return css_parsing_utils::ConsumeIdent(range);
}
return nullptr;
}
@@ -6904,8 +6988,8 @@ const CSSValue* WebkitBorderHorizontalSpacing::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLength(range, context,
- kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeLength(range, context,
+ kValueRangeNonNegative);
}
const CSSValue*
@@ -6945,8 +7029,8 @@ const CSSValue* WebkitBorderVerticalSpacing::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLength(range, context,
- kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeLength(range, context,
+ kValueRangeNonNegative);
}
const CSSValue* WebkitBorderVerticalSpacing::CSSValueFromComputedStyleInternal(
@@ -6987,8 +7071,7 @@ const CSSValue* WebkitBoxFlex::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeNumber(range, context,
- kValueRangeAll);
+ return css_parsing_utils::ConsumeNumber(range, context, kValueRangeAll);
}
const CSSValue* WebkitBoxFlex::CSSValueFromComputedStyleInternal(
@@ -7004,7 +7087,7 @@ const CSSValue* WebkitBoxOrdinalGroup::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumePositiveInteger(range, context);
+ return css_parsing_utils::ConsumePositiveInteger(range, context);
}
const CSSValue* WebkitBoxOrdinalGroup::CSSValueFromComputedStyleInternal(
@@ -7036,9 +7119,10 @@ namespace {
CSSValue* ConsumeReflect(CSSParserTokenRange& range,
const CSSParserContext& context) {
- CSSIdentifierValue* direction = css_property_parser_helpers::ConsumeIdent<
- CSSValueID::kAbove, CSSValueID::kBelow, CSSValueID::kLeft,
- CSSValueID::kRight>(range);
+ CSSIdentifierValue* direction =
+ css_parsing_utils::ConsumeIdent<CSSValueID::kAbove, CSSValueID::kBelow,
+ CSSValueID::kLeft, CSSValueID::kRight>(
+ range);
if (!direction)
return nullptr;
@@ -7047,9 +7131,8 @@ CSSValue* ConsumeReflect(CSSParserTokenRange& range,
offset =
CSSNumericLiteralValue::Create(0, CSSPrimitiveValue::UnitType::kPixels);
} else {
- offset = ConsumeLengthOrPercent(
- range, context, kValueRangeAll,
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ offset = ConsumeLengthOrPercent(range, context, kValueRangeAll,
+ css_parsing_utils::UnitlessQuirk::kForbid);
if (!offset)
return nullptr;
}
@@ -7086,9 +7169,8 @@ const CSSValue* WebkitFontSizeDelta::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLength(
- range, context, kValueRangeAll,
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ return css_parsing_utils::ConsumeLength(
+ range, context, kValueRangeAll, css_parsing_utils::UnitlessQuirk::kAllow);
}
const CSSValue* WebkitFontSmoothing::CSSValueFromComputedStyleInternal(
@@ -7104,8 +7186,8 @@ const CSSValue* WebkitHighlight::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeString(range);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeString(range);
}
const CSSValue* WebkitHighlight::CSSValueFromComputedStyleInternal(
@@ -7123,8 +7205,8 @@ const CSSValue* WebkitHyphenateCharacter::ParseSingleValue(
const CSSParserContext&,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeString(range);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeString(range);
}
const CSSValue* WebkitHyphenateCharacter::CSSValueFromComputedStyleInternal(
@@ -7150,7 +7232,7 @@ const CSSValue* WebkitLineClamp::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
// When specifying number of lines, don't allow 0 as a valid value.
- return css_property_parser_helpers::ConsumePositiveInteger(range, context);
+ return css_parsing_utils::ConsumePositiveInteger(range, context);
}
const CSSValue* WebkitLineClamp::CSSValueFromComputedStyleInternal(
@@ -7169,8 +7251,8 @@ const CSSValue* WebkitLocale::ParseSingleValue(
const CSSParserContext&,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeString(range);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeString(range);
}
const CSSValue* WebkitLocale::CSSValueFromComputedStyleInternal(
@@ -7245,7 +7327,7 @@ const CSSValue* WebkitMaskBoxImageSource::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeImageOrNone(range, context);
+ return css_parsing_utils::ConsumeImageOrNone(range, context);
}
const CSSValue* WebkitMaskBoxImageSource::CSSValueFromComputedStyleInternal(
@@ -7286,7 +7368,7 @@ const CSSValue* WebkitMaskClip::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext&,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
+ return css_parsing_utils::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumePrefixedBackgroundBox, range,
css_parsing_utils::AllowTextValue::kAllow);
}
@@ -7309,7 +7391,7 @@ const CSSValue* WebkitMaskComposite::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext&,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
+ return css_parsing_utils::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumeBackgroundComposite, range);
}
@@ -7329,8 +7411,8 @@ const CSSValue* WebkitMaskImage::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_property_parser_helpers::ConsumeImageOrNone, range, context);
+ return css_parsing_utils::ConsumeCommaSeparatedList(
+ css_parsing_utils::ConsumeImageOrNone, range, context);
}
const CSSValue* WebkitMaskImage::CSSValueFromComputedStyleInternal(
@@ -7347,7 +7429,7 @@ const CSSValue* WebkitMaskOrigin::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext&,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
+ return css_parsing_utils::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumePrefixedBackgroundBox, range,
css_parsing_utils::AllowTextValue::kForbid);
}
@@ -7370,7 +7452,7 @@ const CSSValue* WebkitMaskPositionX::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
+ return css_parsing_utils::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumePositionLonghand<CSSValueID::kLeft,
CSSValueID::kRight>,
range, context);
@@ -7390,7 +7472,7 @@ const CSSValue* WebkitMaskPositionY::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeCommaSeparatedList(
+ return css_parsing_utils::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumePositionLonghand<CSSValueID::kTop,
CSSValueID::kBottom>,
range, context);
@@ -7486,7 +7568,7 @@ const CSSValue* WebkitTapHighlightColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const blink::Color WebkitTapHighlightColor::ColorIncludingFallback(
@@ -7538,7 +7620,7 @@ const CSSValue* WebkitTextEmphasisColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const blink::Color WebkitTextEmphasisColor::ColorIncludingFallback(
@@ -7564,15 +7646,16 @@ const CSSValue* WebkitTextEmphasisPosition::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
CSSIdentifierValue* values[2] = {
- css_property_parser_helpers::ConsumeIdent<
- CSSValueID::kOver, CSSValueID::kUnder, CSSValueID::kRight,
- CSSValueID::kLeft>(range),
+ css_parsing_utils::ConsumeIdent<CSSValueID::kOver, CSSValueID::kUnder,
+ CSSValueID::kRight, CSSValueID::kLeft>(
+ range),
nullptr};
if (!values[0])
return nullptr;
- values[1] = css_property_parser_helpers::ConsumeIdent<
- CSSValueID::kOver, CSSValueID::kUnder, CSSValueID::kRight,
- CSSValueID::kLeft>(range);
+ values[1] =
+ css_parsing_utils::ConsumeIdent<CSSValueID::kOver, CSSValueID::kUnder,
+ CSSValueID::kRight, CSSValueID::kLeft>(
+ range);
CSSIdentifierValue* over_under = nullptr;
CSSIdentifierValue* left_right = nullptr;
@@ -7640,21 +7723,21 @@ const CSSValue* WebkitTextEmphasisStyle::ParseSingleValue(
const CSSParserLocalContext&) const {
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
- if (CSSValue* text_emphasis_style =
- css_property_parser_helpers::ConsumeString(range))
+ if (CSSValue* text_emphasis_style = css_parsing_utils::ConsumeString(range))
return text_emphasis_style;
CSSIdentifierValue* fill =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kFilled,
- CSSValueID::kOpen>(range);
- CSSIdentifierValue* shape = css_property_parser_helpers::ConsumeIdent<
+ css_parsing_utils::ConsumeIdent<CSSValueID::kFilled, CSSValueID::kOpen>(
+ range);
+ CSSIdentifierValue* shape = css_parsing_utils::ConsumeIdent<
CSSValueID::kDot, CSSValueID::kCircle, CSSValueID::kDoubleCircle,
CSSValueID::kTriangle, CSSValueID::kSesame>(range);
if (!fill) {
- fill = css_property_parser_helpers::ConsumeIdent<CSSValueID::kFilled,
- CSSValueID::kOpen>(range);
+ fill =
+ css_parsing_utils::ConsumeIdent<CSSValueID::kFilled, CSSValueID::kOpen>(
+ range);
}
if (fill && shape) {
CSSValueList* parsed_values = CSSValueList::CreateSpaceSeparated();
@@ -7763,7 +7846,7 @@ const CSSValue* WebkitTextFillColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const blink::Color WebkitTextFillColor::ColorIncludingFallback(
@@ -7792,6 +7875,15 @@ const CSSValue* WebkitTextOrientation::CSSValueFromComputedStyleInternal(
return CSSIdentifierValue::Create(style.GetTextOrientation());
}
+void WebkitTextOrientation::ApplyInitial(StyleResolverState& state) const {
+ state.SetTextOrientation(
+ ComputedStyleInitialValues::InitialTextOrientation());
+}
+
+void WebkitTextOrientation::ApplyInherit(StyleResolverState& state) const {
+ state.SetTextOrientation(state.ParentStyle()->GetTextOrientation());
+}
+
void WebkitTextOrientation::ApplyValue(StyleResolverState& state,
const CSSValue& value) const {
state.SetTextOrientation(
@@ -7810,7 +7902,7 @@ const CSSValue* WebkitTextStrokeColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context);
+ return css_parsing_utils::ConsumeColor(range, context);
}
const blink::Color WebkitTextStrokeColor::ColorIncludingFallback(
@@ -7833,8 +7925,8 @@ const CSSValue* WebkitTextStrokeWidth::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLineWidth(
- range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
+ return css_parsing_utils::ConsumeLineWidth(
+ range, context, css_parsing_utils::UnitlessQuirk::kForbid);
}
const CSSValue* WebkitTextStrokeWidth::CSSValueFromComputedStyleInternal(
@@ -7867,8 +7959,7 @@ const CSSValue* WebkitTransformOriginZ::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLength(range, context,
- kValueRangeAll);
+ return css_parsing_utils::ConsumeLength(range, context, kValueRangeAll);
}
const CSSValue* WebkitUserDrag::CSSValueFromComputedStyleInternal(
@@ -7919,7 +8010,7 @@ const CSSValue* WhiteSpace::CSSValueFromComputedStyleInternal(
const CSSValue* Widows::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumePositiveInteger(range, context);
+ return css_parsing_utils::ConsumePositiveInteger(range, context);
}
const CSSValue* Widows::CSSValueFromComputedStyleInternal(
@@ -7935,7 +8026,7 @@ const CSSValue* Width::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeWidthOrHeight(
- range, context, css_property_parser_helpers::UnitlessQuirk::kAllow);
+ range, context, css_parsing_utils::UnitlessQuirk::kAllow);
}
bool Width::IsLayoutDependent(const ComputedStyle* style,
@@ -7961,7 +8052,7 @@ const CSSValue* WillChange::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeIdent(range);
CSSValueList* values = CSSValueList::CreateCommaSeparated();
// Every comma-separated list of identifiers is a valid will-change value,
@@ -7997,7 +8088,7 @@ const CSSValue* WillChange::ParseSingleValue(
return nullptr;
case CSSValueID::kContents:
case CSSValueID::kScrollPosition:
- values->Append(*css_property_parser_helpers::ConsumeIdent(range));
+ values->Append(*css_parsing_utils::ConsumeIdent(range));
break;
default:
range.ConsumeIncludingWhitespace();
@@ -8007,7 +8098,7 @@ const CSSValue* WillChange::ParseSingleValue(
if (range.AtEnd())
break;
- if (!css_property_parser_helpers::ConsumeCommaIncludingWhitespace(range))
+ if (!css_parsing_utils::ConsumeCommaIncludingWhitespace(range))
return nullptr;
}
@@ -8122,8 +8213,8 @@ void WritingMode::ApplyValue(StyleResolverState& state,
const CSSValue* X::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeSVGGeometryPropertyLength(
- range, context, kValueRangeAll);
+ return css_parsing_utils::ConsumeSVGGeometryPropertyLength(range, context,
+ kValueRangeAll);
}
const CSSValue* X::CSSValueFromComputedStyleInternal(
@@ -8138,8 +8229,8 @@ const CSSValue* X::CSSValueFromComputedStyleInternal(
const CSSValue* Y::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeSVGGeometryPropertyLength(
- range, context, kValueRangeAll);
+ return css_parsing_utils::ConsumeSVGGeometryPropertyLength(range, context,
+ kValueRangeAll);
}
const CSSValue* Y::CSSValueFromComputedStyleInternal(
@@ -8155,8 +8246,8 @@ const CSSValue* ZIndex::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kAuto)
- return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeInteger(range, context);
+ return css_parsing_utils::ConsumeIdent(range);
+ return css_parsing_utils::ConsumeInteger(range, context);
}
const CSSValue* ZIndex::CSSValueFromComputedStyleInternal(
@@ -8164,7 +8255,7 @@ const CSSValue* ZIndex::CSSValueFromComputedStyleInternal(
const SVGComputedStyle&,
const LayoutObject*,
bool allow_visited_style) const {
- if (style.HasAutoZIndex() || !style.IsStackingContext())
+ if (style.HasAutoZIndex())
return CSSIdentifierValue::Create(CSSValueID::kAuto);
return CSSNumericLiteralValue::Create(style.ZIndex(),
CSSPrimitiveValue::UnitType::kInteger);
@@ -8176,16 +8267,16 @@ const CSSValue* Zoom::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserToken& token = range.Peek();
CSSValue* zoom = nullptr;
if (token.GetType() == kIdentToken) {
- CSSIdentifierValue* ident = css_property_parser_helpers::ConsumeIdent<
+ CSSIdentifierValue* ident = css_parsing_utils::ConsumeIdent<
CSSValueID::kNormal, CSSValueID::kInternalResetEffective>(range);
if (ident && isValueAllowedInMode(ident->GetValueID(), context.Mode()))
zoom = ident;
} else {
- zoom = css_property_parser_helpers::ConsumePercent(range, context,
- kValueRangeNonNegative);
+ zoom = css_parsing_utils::ConsumePercent(range, context,
+ kValueRangeNonNegative);
if (!zoom) {
- zoom = css_property_parser_helpers::ConsumeNumber(range, context,
- kValueRangeNonNegative);
+ zoom = css_parsing_utils::ConsumeNumber(range, context,
+ kValueRangeNonNegative);
}
}
if (zoom) {
@@ -8232,8 +8323,8 @@ const CSSValue* InternalEmptyLineHeight::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext&,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeIdent<CSSValueID::kFabricated,
- CSSValueID::kNone>(range);
+ return css_parsing_utils::ConsumeIdent<CSSValueID::kFabricated,
+ CSSValueID::kNone>(range);
}
} // namespace css_longhand
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc
index 657fd78d604..f0655149f29 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc
@@ -14,7 +14,6 @@
#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_fast_paths.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_local_context.h"
-#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
#include "third_party/blink/renderer/core/css/parser/font_variant_east_asian_parser.h"
#include "third_party/blink/renderer/core/css/parser/font_variant_ligatures_parser.h"
#include "third_party/blink/renderer/core/css/parser/font_variant_numeric_parser.h"
@@ -43,17 +42,16 @@ CSSValue* ConsumeAnimationValue(CSSPropertyID property,
bool use_legacy_parsing) {
switch (property) {
case CSSPropertyID::kAnimationDelay:
- return css_property_parser_helpers::ConsumeTime(range, context,
- kValueRangeAll);
+ return css_parsing_utils::ConsumeTime(range, context, kValueRangeAll);
case CSSPropertyID::kAnimationDirection:
- return css_property_parser_helpers::ConsumeIdent<
+ return css_parsing_utils::ConsumeIdent<
CSSValueID::kNormal, CSSValueID::kAlternate, CSSValueID::kReverse,
CSSValueID::kAlternateReverse>(range);
case CSSPropertyID::kAnimationDuration:
- return css_property_parser_helpers::ConsumeTime(range, context,
- kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeTime(range, context,
+ kValueRangeNonNegative);
case CSSPropertyID::kAnimationFillMode:
- return css_property_parser_helpers::ConsumeIdent<
+ return css_parsing_utils::ConsumeIdent<
CSSValueID::kNone, CSSValueID::kForwards, CSSValueID::kBackwards,
CSSValueID::kBoth>(range);
case CSSPropertyID::kAnimationIterationCount:
@@ -62,9 +60,8 @@ CSSValue* ConsumeAnimationValue(CSSPropertyID property,
return css_parsing_utils::ConsumeAnimationName(range, context,
use_legacy_parsing);
case CSSPropertyID::kAnimationPlayState:
- return css_property_parser_helpers::ConsumeIdent<CSSValueID::kRunning,
- CSSValueID::kPaused>(
- range);
+ return css_parsing_utils::ConsumeIdent<CSSValueID::kRunning,
+ CSSValueID::kPaused>(range);
case CSSPropertyID::kAnimationTimingFunction:
return css_parsing_utils::ConsumeAnimationTimingFunction(range, context);
default:
@@ -81,7 +78,7 @@ bool Animation::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext& local_context,
HeapVector<CSSPropertyValue, 256>& properties) const {
- const StylePropertyShorthand shorthand = animationShorthandForParsing();
+ const StylePropertyShorthand shorthand = animationShorthand();
const unsigned longhand_count = shorthand.length();
HeapVector<Member<CSSValueList>, css_parsing_utils::kMaxNumAnimationLonghands>
@@ -93,10 +90,9 @@ bool Animation::ParseShorthand(
}
for (unsigned i = 0; i < longhand_count; ++i) {
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
shorthand.properties()[i]->PropertyID(), shorthand.id(), *longhands[i],
- important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
}
return range.AtEnd();
@@ -187,21 +183,19 @@ bool BackgroundPosition::ParseShorthand(
CSSValue* result_y = nullptr;
if (!css_parsing_utils::ConsumeBackgroundPosition(
- range, context, css_property_parser_helpers::UnitlessQuirk::kAllow,
- result_x, result_y) ||
+ range, context, css_parsing_utils::UnitlessQuirk::kAllow, result_x,
+ result_y) ||
!range.AtEnd())
return false;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBackgroundPositionX, CSSPropertyID::kBackgroundPosition,
- *result_x, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ *result_x, important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBackgroundPositionY, CSSPropertyID::kBackgroundPosition,
- *result_y, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ *result_y, important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
return true;
}
@@ -229,17 +223,17 @@ bool BackgroundRepeat::ParseShorthand(
!range.AtEnd())
return false;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBackgroundRepeatX, CSSPropertyID::kBackgroundRepeat,
*result_x, important,
- implicit ? css_property_parser_helpers::IsImplicitProperty::kImplicit
- : css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ implicit ? css_parsing_utils::IsImplicitProperty::kImplicit
+ : css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBackgroundRepeatY, CSSPropertyID::kBackgroundRepeat,
*result_y, important,
- implicit ? css_property_parser_helpers::IsImplicitProperty::kImplicit
- : css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ implicit ? css_parsing_utils::IsImplicitProperty::kImplicit
+ : css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
return true;
@@ -260,7 +254,7 @@ bool BorderBlockColor::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
borderBlockColorShorthand(), important, context, range, properties);
}
@@ -283,16 +277,16 @@ bool BorderBlock::ParseShorthand(
const CSSValue* style = nullptr;
const CSSValue* color = nullptr;
- if (!css_property_parser_helpers::ConsumeBorderShorthand(
- range, context, width, style, color)) {
+ if (!css_parsing_utils::ConsumeBorderShorthand(range, context, width, style,
+ color)) {
return false;
};
- css_property_parser_helpers::AddExpandedPropertyForValue(
+ css_parsing_utils::AddExpandedPropertyForValue(
CSSPropertyID::kBorderBlockWidth, *width, important, properties);
- css_property_parser_helpers::AddExpandedPropertyForValue(
+ css_parsing_utils::AddExpandedPropertyForValue(
CSSPropertyID::kBorderBlockStyle, *style, important, properties);
- css_property_parser_helpers::AddExpandedPropertyForValue(
+ css_parsing_utils::AddExpandedPropertyForValue(
CSSPropertyID::kBorderBlockColor, *color, important, properties);
return range.AtEnd();
@@ -321,7 +315,7 @@ bool BorderBlockEnd::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandGreedilyViaLonghands(
+ return css_parsing_utils::ConsumeShorthandGreedilyViaLonghands(
borderBlockEndShorthand(), important, context, range, properties);
}
@@ -331,7 +325,7 @@ bool BorderBlockStart::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandGreedilyViaLonghands(
+ return css_parsing_utils::ConsumeShorthandGreedilyViaLonghands(
borderBlockStartShorthand(), important, context, range, properties);
}
@@ -341,7 +335,7 @@ bool BorderBlockStyle::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
borderBlockStyleShorthand(), important, context, range, properties);
}
@@ -360,7 +354,7 @@ bool BorderBlockWidth::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
borderBlockWidthShorthand(), important, context, range, properties);
}
@@ -379,7 +373,7 @@ bool BorderBottom::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandGreedilyViaLonghands(
+ return css_parsing_utils::ConsumeShorthandGreedilyViaLonghands(
borderBottomShorthand(), important, context, range, properties);
}
@@ -398,7 +392,7 @@ bool BorderColor::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia4Longhands(
+ return css_parsing_utils::ConsumeShorthandVia4Longhands(
borderColorShorthand(), important, context, range, properties);
}
@@ -421,20 +415,20 @@ bool Border::ParseShorthand(
const CSSValue* style = nullptr;
const CSSValue* color = nullptr;
- if (!css_property_parser_helpers::ConsumeBorderShorthand(
- range, context, width, style, color)) {
+ if (!css_parsing_utils::ConsumeBorderShorthand(range, context, width, style,
+ color)) {
return false;
};
- css_property_parser_helpers::AddExpandedPropertyForValue(
- CSSPropertyID::kBorderWidth, *width, important, properties);
- css_property_parser_helpers::AddExpandedPropertyForValue(
- CSSPropertyID::kBorderStyle, *style, important, properties);
- css_property_parser_helpers::AddExpandedPropertyForValue(
- CSSPropertyID::kBorderColor, *color, important, properties);
- css_property_parser_helpers::AddExpandedPropertyForValue(
- CSSPropertyID::kBorderImage, *CSSInitialValue::Create(), important,
- properties);
+ css_parsing_utils::AddExpandedPropertyForValue(CSSPropertyID::kBorderWidth,
+ *width, important, properties);
+ css_parsing_utils::AddExpandedPropertyForValue(CSSPropertyID::kBorderStyle,
+ *style, important, properties);
+ css_parsing_utils::AddExpandedPropertyForValue(CSSPropertyID::kBorderColor,
+ *color, important, properties);
+ css_parsing_utils::AddExpandedPropertyForValue(CSSPropertyID::kBorderImage,
+ *CSSInitialValue::Create(),
+ important, properties);
return range.AtEnd();
}
@@ -477,38 +471,38 @@ bool BorderImage::ParseShorthand(
return false;
}
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBorderImageSource, CSSPropertyID::kBorderImage,
source
? *source
: *To<Longhand>(&GetCSSPropertyBorderImageSource())->InitialValue(),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBorderImageSlice, CSSPropertyID::kBorderImage,
slice ? *slice
: *To<Longhand>(&GetCSSPropertyBorderImageSlice())->InitialValue(),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBorderImageWidth, CSSPropertyID::kBorderImage,
width ? *width
: *To<Longhand>(&GetCSSPropertyBorderImageWidth())->InitialValue(),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBorderImageOutset, CSSPropertyID::kBorderImage,
outset
? *outset
: *To<Longhand>(&GetCSSPropertyBorderImageOutset())->InitialValue(),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBorderImageRepeat, CSSPropertyID::kBorderImage,
repeat
? *repeat
: *To<Longhand>(&GetCSSPropertyBorderImageRepeat())->InitialValue(),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
return true;
@@ -529,7 +523,7 @@ bool BorderInlineColor::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
borderInlineColorShorthand(), important, context, range, properties);
}
@@ -552,16 +546,16 @@ bool BorderInline::ParseShorthand(
const CSSValue* style = nullptr;
const CSSValue* color = nullptr;
- if (!css_property_parser_helpers::ConsumeBorderShorthand(
- range, context, width, style, color)) {
+ if (!css_parsing_utils::ConsumeBorderShorthand(range, context, width, style,
+ color)) {
return false;
};
- css_property_parser_helpers::AddExpandedPropertyForValue(
+ css_parsing_utils::AddExpandedPropertyForValue(
CSSPropertyID::kBorderInlineWidth, *width, important, properties);
- css_property_parser_helpers::AddExpandedPropertyForValue(
+ css_parsing_utils::AddExpandedPropertyForValue(
CSSPropertyID::kBorderInlineStyle, *style, important, properties);
- css_property_parser_helpers::AddExpandedPropertyForValue(
+ css_parsing_utils::AddExpandedPropertyForValue(
CSSPropertyID::kBorderInlineColor, *color, important, properties);
return range.AtEnd();
@@ -590,7 +584,7 @@ bool BorderInlineEnd::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandGreedilyViaLonghands(
+ return css_parsing_utils::ConsumeShorthandGreedilyViaLonghands(
borderInlineEndShorthand(), important, context, range, properties);
}
@@ -600,7 +594,7 @@ bool BorderInlineStart::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandGreedilyViaLonghands(
+ return css_parsing_utils::ConsumeShorthandGreedilyViaLonghands(
borderInlineStartShorthand(), important, context, range, properties);
}
@@ -610,7 +604,7 @@ bool BorderInlineStyle::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
borderInlineStyleShorthand(), important, context, range, properties);
}
@@ -629,7 +623,7 @@ bool BorderInlineWidth::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
borderInlineWidthShorthand(), important, context, range, properties);
}
@@ -648,7 +642,7 @@ bool BorderLeft::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandGreedilyViaLonghands(
+ return css_parsing_utils::ConsumeShorthandGreedilyViaLonghands(
borderLeftShorthand(), important, context, range, properties);
}
@@ -675,33 +669,33 @@ bool BorderRadius::ParseShorthand(
local_context.UseAliasParsing()))
return false;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBorderTopLeftRadius, CSSPropertyID::kBorderRadius,
*MakeGarbageCollected<CSSValuePair>(horizontal_radii[0],
vertical_radii[0],
CSSValuePair::kDropIdenticalValues),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBorderTopRightRadius, CSSPropertyID::kBorderRadius,
*MakeGarbageCollected<CSSValuePair>(horizontal_radii[1],
vertical_radii[1],
CSSValuePair::kDropIdenticalValues),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBorderBottomRightRadius, CSSPropertyID::kBorderRadius,
*MakeGarbageCollected<CSSValuePair>(horizontal_radii[2],
vertical_radii[2],
CSSValuePair::kDropIdenticalValues),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBorderBottomLeftRadius, CSSPropertyID::kBorderRadius,
*MakeGarbageCollected<CSSValuePair>(horizontal_radii[3],
vertical_radii[3],
CSSValuePair::kDropIdenticalValues),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
return true;
}
@@ -720,7 +714,7 @@ bool BorderRight::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandGreedilyViaLonghands(
+ return css_parsing_utils::ConsumeShorthandGreedilyViaLonghands(
borderRightShorthand(), important, context, range, properties);
}
@@ -741,27 +735,24 @@ bool BorderSpacing::ParseShorthand(
HeapVector<CSSPropertyValue, 256>& properties) const {
CSSValue* horizontal_spacing =
ConsumeLength(range, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ css_parsing_utils::UnitlessQuirk::kAllow);
if (!horizontal_spacing)
return false;
CSSValue* vertical_spacing = horizontal_spacing;
if (!range.AtEnd()) {
- vertical_spacing =
- ConsumeLength(range, context, kValueRangeNonNegative,
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ vertical_spacing = ConsumeLength(range, context, kValueRangeNonNegative,
+ css_parsing_utils::UnitlessQuirk::kAllow);
}
if (!vertical_spacing || !range.AtEnd())
return false;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kWebkitBorderHorizontalSpacing,
CSSPropertyID::kBorderSpacing, *horizontal_spacing, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kWebkitBorderVerticalSpacing,
CSSPropertyID::kBorderSpacing, *vertical_spacing, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -782,7 +773,7 @@ bool BorderStyle::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia4Longhands(
+ return css_parsing_utils::ConsumeShorthandVia4Longhands(
borderStyleShorthand(), important, context, range, properties);
}
@@ -801,7 +792,7 @@ bool BorderTop::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandGreedilyViaLonghands(
+ return css_parsing_utils::ConsumeShorthandGreedilyViaLonghands(
borderTopShorthand(), important, context, range, properties);
}
@@ -820,7 +811,7 @@ bool BorderWidth::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia4Longhands(
+ return css_parsing_utils::ConsumeShorthandVia4Longhands(
borderWidthShorthand(), important, context, range, properties);
}
@@ -839,7 +830,7 @@ bool ColumnRule::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandGreedilyViaLonghands(
+ return css_parsing_utils::ConsumeShorthandGreedilyViaLonghands(
columnRuleShorthand(), important, context, range, properties);
}
@@ -871,13 +862,13 @@ bool Columns::ParseShorthand(
column_width = CSSIdentifierValue::Create(CSSValueID::kAuto);
if (!column_count)
column_count = CSSIdentifierValue::Create(CSSValueID::kAuto);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kColumnWidth, CSSPropertyID::kInvalid, *column_width,
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kColumnCount, CSSPropertyID::kInvalid, *column_count,
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
return true;
}
@@ -910,7 +901,7 @@ bool Flex::ParseShorthand(bool important,
unsigned index = 0;
while (!range.AtEnd() && index++ < 3) {
double num;
- if (css_property_parser_helpers::ConsumeNumberRaw(range, context, num)) {
+ if (css_parsing_utils::ConsumeNumberRaw(range, context, num)) {
if (num < 0)
return false;
if (flex_grow == kUnsetValue) {
@@ -928,9 +919,9 @@ bool Flex::ParseShorthand(bool important,
}
} else if (!flex_basis) {
if (range.Peek().Id() == CSSValueID::kAuto)
- flex_basis = css_property_parser_helpers::ConsumeIdent(range);
+ flex_basis = css_parsing_utils::ConsumeIdent(range);
if (!flex_basis) {
- flex_basis = css_property_parser_helpers::ConsumeLengthOrPercent(
+ flex_basis = css_parsing_utils::ConsumeLengthOrPercent(
range, context, kValueRangeNonNegative);
}
if (index == 2 && !range.AtEnd())
@@ -951,23 +942,22 @@ bool Flex::ParseShorthand(bool important,
if (!range.AtEnd())
return false;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFlexGrow, CSSPropertyID::kFlex,
*CSSNumericLiteralValue::Create(clampTo<float>(flex_grow),
CSSPrimitiveValue::UnitType::kNumber),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFlexShrink, CSSPropertyID::kFlex,
*CSSNumericLiteralValue::Create(clampTo<float>(flex_shrink),
CSSPrimitiveValue::UnitType::kNumber),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFlexBasis, CSSPropertyID::kFlex, *flex_basis, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -987,7 +977,7 @@ bool FlexFlow::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandGreedilyViaLonghands(
+ return css_parsing_utils::ConsumeShorthandGreedilyViaLonghands(
flexFlowShorthand(), important, context, range, properties);
}
@@ -1017,63 +1007,57 @@ bool ConsumeSystemFont(bool important,
LayoutTheme::GetTheme().SystemFont(system_font_id, font_style, font_weight,
font_size, font_family);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontStyle, CSSPropertyID::kFont,
*CSSIdentifierValue::Create(font_style == ItalicSlopeValue()
? CSSValueID::kItalic
: CSSValueID::kNormal),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontWeight, CSSPropertyID::kFont,
*CSSNumericLiteralValue::Create(font_weight,
CSSPrimitiveValue::UnitType::kNumber),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontSize, CSSPropertyID::kFont,
*CSSNumericLiteralValue::Create(font_size,
CSSPrimitiveValue::UnitType::kPixels),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
CSSValueList* font_family_list = CSSValueList::CreateCommaSeparated();
font_family_list->Append(*CSSFontFamilyValue::Create(font_family));
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontFamily, CSSPropertyID::kFont, *font_family_list,
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontStretch, CSSPropertyID::kFont,
*CSSIdentifierValue::Create(CSSValueID::kNormal), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantCaps, CSSPropertyID::kFont,
*CSSIdentifierValue::Create(CSSValueID::kNormal), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantLigatures, CSSPropertyID::kFont,
*CSSIdentifierValue::Create(CSSValueID::kNormal), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantNumeric, CSSPropertyID::kFont,
*CSSIdentifierValue::Create(CSSValueID::kNormal), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantEastAsian, CSSPropertyID::kFont,
*CSSIdentifierValue::Create(CSSValueID::kNormal), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kLineHeight, CSSPropertyID::kFont,
*CSSIdentifierValue::Create(CSSValueID::kNormal), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -1091,7 +1075,7 @@ bool ConsumeFont(bool important,
for (int i = 0; i < kNumReorderableFontProperties && !range.AtEnd(); ++i) {
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kNormal) {
- css_property_parser_helpers::ConsumeIdent(range);
+ css_parsing_utils::ConsumeIdent(range);
continue;
}
if (!font_style &&
@@ -1130,45 +1114,42 @@ bool ConsumeFont(bool important,
if (range.AtEnd())
return false;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontStyle, CSSPropertyID::kFont,
font_style ? *font_style
: *CSSIdentifierValue::Create(CSSValueID::kNormal),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantCaps, CSSPropertyID::kFont,
font_variant_caps ? *font_variant_caps
: *CSSIdentifierValue::Create(CSSValueID::kNormal),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantLigatures, CSSPropertyID::kFont,
*CSSIdentifierValue::Create(CSSValueID::kNormal), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantNumeric, CSSPropertyID::kFont,
*CSSIdentifierValue::Create(CSSValueID::kNormal), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantEastAsian, CSSPropertyID::kFont,
*CSSIdentifierValue::Create(CSSValueID::kNormal), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontWeight, CSSPropertyID::kFont,
font_weight ? *font_weight
: *CSSIdentifierValue::Create(CSSValueID::kNormal),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontStretch, CSSPropertyID::kFont,
font_stretch ? *font_stretch
: *CSSIdentifierValue::Create(CSSValueID::kNormal),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
// Now a font size _must_ come.
@@ -1176,27 +1157,24 @@ bool ConsumeFont(bool important,
if (!font_size || range.AtEnd())
return false;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontSize, CSSPropertyID::kFont, *font_size, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
- if (css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range)) {
+ if (css_parsing_utils::ConsumeSlashIncludingWhitespace(range)) {
CSSValue* line_height =
css_parsing_utils::ConsumeLineHeight(range, context);
if (!line_height)
return false;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kLineHeight, CSSPropertyID::kFont, *line_height,
- important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
} else {
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kLineHeight, CSSPropertyID::kFont,
*CSSIdentifierValue::Create(CSSValueID::kNormal), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
}
// Font family must come now.
@@ -1204,9 +1182,9 @@ bool ConsumeFont(bool important,
if (!parsed_family_value)
return false;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontFamily, CSSPropertyID::kFont, *parsed_family_value,
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
// FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20110324/#font-prop requires
@@ -1244,29 +1222,24 @@ bool FontVariant::ParseShorthand(
const CSSParserContext&,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- if (css_property_parser_helpers::IdentMatches<CSSValueID::kNormal,
- CSSValueID::kNone>(
+ if (css_parsing_utils::IdentMatches<CSSValueID::kNormal, CSSValueID::kNone>(
range.Peek().Id())) {
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantLigatures, CSSPropertyID::kFontVariant,
- *css_property_parser_helpers::ConsumeIdent(range), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ *css_parsing_utils::ConsumeIdent(range), important,
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantCaps, CSSPropertyID::kFontVariant,
*CSSIdentifierValue::Create(CSSValueID::kNormal), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantNumeric, CSSPropertyID::kFontVariant,
*CSSIdentifierValue::Create(CSSValueID::kNormal), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantEastAsian, CSSPropertyID::kFontVariant,
*CSSIdentifierValue::Create(CSSValueID::kNormal), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return range.AtEnd();
}
@@ -1308,33 +1281,30 @@ bool FontVariant::ParseShorthand(
// Only one caps value permitted in font-variant grammar.
if (caps_value)
return false;
- caps_value = css_property_parser_helpers::ConsumeIdent(range);
+ caps_value = css_parsing_utils::ConsumeIdent(range);
break;
default:
return false;
}
} while (!range.AtEnd());
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantLigatures, CSSPropertyID::kFontVariant,
*ligatures_parser.FinalizeValue(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantNumeric, CSSPropertyID::kFontVariant,
*numeric_parser.FinalizeValue(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantEastAsian, CSSPropertyID::kFontVariant,
*east_asian_parser.FinalizeValue(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kFontVariantCaps, CSSPropertyID::kFontVariant,
caps_value ? *caps_value
: *CSSIdentifierValue::Create(CSSValueID::kNormal),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
return true;
}
@@ -1360,14 +1330,12 @@ bool Gap::ParseShorthand(bool important,
return false;
if (!column_gap)
column_gap = row_gap;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kRowGap, CSSPropertyID::kGap, *row_gap, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kColumnGap, CSSPropertyID::kGap, *column_gap, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -1395,15 +1363,15 @@ bool GridArea::ParseShorthand(
CSSValue* column_start_value = nullptr;
CSSValue* row_end_value = nullptr;
CSSValue* column_end_value = nullptr;
- if (css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range)) {
+ if (css_parsing_utils::ConsumeSlashIncludingWhitespace(range)) {
column_start_value = css_parsing_utils::ConsumeGridLine(range, context);
if (!column_start_value)
return false;
- if (css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range)) {
+ if (css_parsing_utils::ConsumeSlashIncludingWhitespace(range)) {
row_end_value = css_parsing_utils::ConsumeGridLine(range, context);
if (!row_end_value)
return false;
- if (css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range)) {
+ if (css_parsing_utils::ConsumeSlashIncludingWhitespace(range)) {
column_end_value = css_parsing_utils::ConsumeGridLine(range, context);
if (!column_end_value)
return false;
@@ -1428,24 +1396,22 @@ bool GridArea::ParseShorthand(
: CSSIdentifierValue::Create(CSSValueID::kAuto);
}
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridRowStart, CSSPropertyID::kGridArea, *row_start_value,
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridColumnStart, CSSPropertyID::kGridArea,
*column_start_value, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridRowEnd, CSSPropertyID::kGridArea, *row_end_value,
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridColumnEnd, CSSPropertyID::kGridArea,
*column_end_value, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -1475,16 +1441,14 @@ bool GridColumn::ParseShorthand(
return false;
}
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
shorthand.properties()[0]->PropertyID(), CSSPropertyID::kGridColumn,
*start_value, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
shorthand.properties()[1]->PropertyID(), CSSPropertyID::kGridColumn,
*end_value, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -1508,9 +1472,9 @@ bool GridColumnGap::ParseShorthand(
if (!gap_length || !range.AtEnd())
return false;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kColumnGap, CSSPropertyID::kGridColumnGap, *gap_length,
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
return true;
}
@@ -1530,17 +1494,15 @@ CSSValueList* ConsumeImplicitAutoFlow(CSSParserTokenRange& range,
const CSSValue& flow_direction) {
// [ auto-flow && dense? ]
CSSValue* dense_algorithm = nullptr;
- if ((css_property_parser_helpers::ConsumeIdent<CSSValueID::kAutoFlow>(
- range))) {
+ if ((css_parsing_utils::ConsumeIdent<CSSValueID::kAutoFlow>(range))) {
dense_algorithm =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kDense>(range);
+ css_parsing_utils::ConsumeIdent<CSSValueID::kDense>(range);
} else {
dense_algorithm =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kDense>(range);
+ css_parsing_utils::ConsumeIdent<CSSValueID::kDense>(range);
if (!dense_algorithm)
return nullptr;
- if (!css_property_parser_helpers::ConsumeIdent<CSSValueID::kAutoFlow>(
- range))
+ if (!css_parsing_utils::ConsumeIdent<CSSValueID::kAutoFlow>(range))
return nullptr;
}
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
@@ -1572,40 +1534,34 @@ bool Grid::ParseShorthand(bool important,
DCHECK(template_columns);
DCHECK(template_areas);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridTemplateRows, CSSPropertyID::kGrid, *template_rows,
- important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridTemplateColumns, CSSPropertyID::kGrid,
*template_columns, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridTemplateAreas, CSSPropertyID::kGrid,
*template_areas, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
// It can only be specified the explicit or the implicit grid properties in
// a single grid declaration. The sub-properties not specified are set to
// their initial value, as normal for shorthands.
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridAutoFlow, CSSPropertyID::kGrid,
*CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridAutoColumns, CSSPropertyID::kGrid,
*CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridAutoRows, CSSPropertyID::kGrid,
*CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -1617,22 +1573,22 @@ bool Grid::ParseShorthand(bool important,
template_rows = nullptr;
template_columns = nullptr;
- if (css_property_parser_helpers::IdentMatches<CSSValueID::kDense,
- CSSValueID::kAutoFlow>(
+ if (css_parsing_utils::IdentMatches<CSSValueID::kDense,
+ CSSValueID::kAutoFlow>(
range.Peek().Id())) {
// 2- [ auto-flow && dense? ] <grid-auto-rows>? / <grid-template-columns>
grid_auto_flow = ConsumeImplicitAutoFlow(
range, *CSSIdentifierValue::Create(CSSValueID::kRow));
if (!grid_auto_flow)
return false;
- if (css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range)) {
+ if (css_parsing_utils::ConsumeSlashIncludingWhitespace(range)) {
auto_rows_value = CSSInitialValue::Create();
} else {
auto_rows_value = css_parsing_utils::ConsumeGridTrackList(
range, context, css_parsing_utils::TrackListType::kGridAuto);
if (!auto_rows_value)
return false;
- if (!css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range))
+ if (!css_parsing_utils::ConsumeSlashIncludingWhitespace(range))
return false;
}
if (!(template_columns =
@@ -1647,7 +1603,7 @@ bool Grid::ParseShorthand(bool important,
css_parsing_utils::ConsumeGridTemplatesRowsOrColumns(range, context);
if (!template_rows)
return false;
- if (!css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range))
+ if (!css_parsing_utils::ConsumeSlashIncludingWhitespace(range))
return false;
grid_auto_flow = ConsumeImplicitAutoFlow(
range, *CSSIdentifierValue::Create(CSSValueID::kColumn));
@@ -1671,32 +1627,29 @@ bool Grid::ParseShorthand(bool important,
// It can only be specified the explicit or the implicit grid properties in a
// single grid declaration. The sub-properties not specified are set to their
// initial value, as normal for shorthands.
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridTemplateColumns, CSSPropertyID::kGrid,
*template_columns, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridTemplateRows, CSSPropertyID::kGrid, *template_rows,
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridTemplateAreas, CSSPropertyID::kGrid,
*CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridAutoFlow, CSSPropertyID::kGrid, *grid_auto_flow,
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridAutoColumns, CSSPropertyID::kGrid,
*auto_columns_value, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridAutoRows, CSSPropertyID::kGrid, *auto_rows_value,
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
return true;
}
@@ -1728,14 +1681,12 @@ bool GridGap::ParseShorthand(
return false;
if (!column_gap)
column_gap = row_gap;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kRowGap, CSSPropertyID::kGap, *row_gap, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kColumnGap, CSSPropertyID::kGap, *column_gap, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -1765,16 +1716,14 @@ bool GridRow::ParseShorthand(
return false;
}
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
shorthand.properties()[0]->PropertyID(), CSSPropertyID::kGridRow,
*start_value, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
shorthand.properties()[1]->PropertyID(), CSSPropertyID::kGridRow,
*end_value, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -1798,9 +1747,9 @@ bool GridRowGap::ParseShorthand(
if (!gap_length || !range.AtEnd())
return false;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kRowGap, CSSPropertyID::kGridRowGap, *gap_length,
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
return true;
}
@@ -1832,21 +1781,18 @@ bool GridTemplate::ParseShorthand(
DCHECK(template_columns);
DCHECK(template_areas);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridTemplateRows, CSSPropertyID::kGridTemplate,
*template_rows, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridTemplateColumns, CSSPropertyID::kGridTemplate,
*template_columns, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kGridTemplateAreas, CSSPropertyID::kGridTemplate,
*template_areas, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -1871,7 +1817,7 @@ bool InsetBlock::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
insetBlockShorthand(), important, context, range, properties);
}
@@ -1890,7 +1836,7 @@ bool Inset::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia4Longhands(
+ return css_parsing_utils::ConsumeShorthandVia4Longhands(
insetShorthand(), important, context, range, properties);
}
@@ -1909,7 +1855,7 @@ bool InsetInline::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
insetInlineShorthand(), important, context, range, properties);
}
@@ -1934,27 +1880,26 @@ bool ListStyle::ParseShorthand(
const CSSValue* list_style_type = nullptr;
do {
if (!none) {
- none =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kNone>(range);
+ none = css_parsing_utils::ConsumeIdent<CSSValueID::kNone>(range);
if (none)
continue;
}
if (!list_style_position) {
- list_style_position = css_property_parser_helpers::ParseLonghand(
+ list_style_position = css_parsing_utils::ParseLonghand(
CSSPropertyID::kListStylePosition, CSSPropertyID::kListStyle, context,
range);
if (list_style_position)
continue;
}
if (!list_style_image) {
- list_style_image = css_property_parser_helpers::ParseLonghand(
+ list_style_image = css_parsing_utils::ParseLonghand(
CSSPropertyID::kListStyleImage, CSSPropertyID::kListStyle, context,
range);
if (list_style_image)
continue;
}
if (!list_style_type) {
- list_style_type = css_property_parser_helpers::ParseLonghand(
+ list_style_type = css_parsing_utils::ParseLonghand(
CSSPropertyID::kListStyleType, CSSPropertyID::kListStyle, context,
range);
if (list_style_type)
@@ -1974,36 +1919,36 @@ bool ListStyle::ParseShorthand(
if (list_style_position) {
AddProperty(CSSPropertyID::kListStylePosition, CSSPropertyID::kListStyle,
*list_style_position, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
} else {
AddProperty(CSSPropertyID::kListStylePosition, CSSPropertyID::kListStyle,
*CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
}
if (list_style_image) {
AddProperty(CSSPropertyID::kListStyleImage, CSSPropertyID::kListStyle,
*list_style_image, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
} else {
AddProperty(CSSPropertyID::kListStyleImage, CSSPropertyID::kListStyle,
*CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
}
if (list_style_type) {
AddProperty(CSSPropertyID::kListStyleType, CSSPropertyID::kListStyle,
*list_style_type, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
} else {
AddProperty(CSSPropertyID::kListStyleType, CSSPropertyID::kListStyle,
*CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
}
@@ -2025,7 +1970,7 @@ bool MarginBlock::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
marginBlockShorthand(), important, context, range, properties);
}
@@ -2044,7 +1989,7 @@ bool Margin::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia4Longhands(
+ return css_parsing_utils::ConsumeShorthandVia4Longhands(
marginShorthand(), important, context, range, properties);
}
@@ -2071,7 +2016,7 @@ bool MarginInline::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
marginInlineShorthand(), important, context, range, properties);
}
@@ -2090,23 +2035,20 @@ bool Marker::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- const CSSValue* marker = css_property_parser_helpers::ParseLonghand(
+ const CSSValue* marker = css_parsing_utils::ParseLonghand(
CSSPropertyID::kMarkerStart, CSSPropertyID::kMarker, context, range);
if (!marker || !range.AtEnd())
return false;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kMarkerStart, CSSPropertyID::kMarker, *marker, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kMarkerMid, CSSPropertyID::kMarker, *marker, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kMarkerEnd, CSSPropertyID::kMarker, *marker, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -2144,16 +2086,16 @@ bool Offset::ParseShorthand(
const CSSValue* offset_distance = nullptr;
const CSSValue* offset_rotate = nullptr;
if (offset_path) {
- offset_distance = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context, kValueRangeAll);
+ offset_distance = css_parsing_utils::ConsumeLengthOrPercent(range, context,
+ kValueRangeAll);
offset_rotate = css_parsing_utils::ConsumeOffsetRotate(range, context);
if (offset_rotate && !offset_distance) {
- offset_distance = css_property_parser_helpers::ConsumeLengthOrPercent(
+ offset_distance = css_parsing_utils::ConsumeLengthOrPercent(
range, context, kValueRangeAll);
}
}
const CSSValue* offset_anchor = nullptr;
- if (css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range)) {
+ if (css_parsing_utils::ConsumeSlashIncludingWhitespace(range)) {
offset_anchor =
To<Longhand>(GetCSSPropertyOffsetAnchor())
.ParseSingleValue(range, context, CSSParserLocalContext());
@@ -2168,73 +2110,63 @@ bool Offset::ParseShorthand(
return false;
if (offset_position) {
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kOffsetPosition, CSSPropertyID::kOffset,
*offset_position, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
} else if (RuntimeEnabledFeatures::CSSOffsetPositionAnchorEnabled()) {
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kOffsetPosition, CSSPropertyID::kOffset,
*CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
}
if (offset_path) {
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kOffsetPath, CSSPropertyID::kOffset, *offset_path,
- important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
} else {
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kOffsetPath, CSSPropertyID::kOffset,
*CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
}
if (offset_distance) {
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kOffsetDistance, CSSPropertyID::kOffset,
*offset_distance, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
} else {
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kOffsetDistance, CSSPropertyID::kOffset,
*CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
}
if (offset_rotate) {
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kOffsetRotate, CSSPropertyID::kOffset, *offset_rotate,
- important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
} else {
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kOffsetRotate, CSSPropertyID::kOffset,
*CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
}
if (offset_anchor) {
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kOffsetAnchor, CSSPropertyID::kOffset, *offset_anchor,
- important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
} else if (RuntimeEnabledFeatures::CSSOffsetPositionAnchorEnabled()) {
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kOffsetAnchor, CSSPropertyID::kOffset,
*CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
}
return true;
@@ -2255,7 +2187,7 @@ bool Outline::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandGreedilyViaLonghands(
+ return css_parsing_utils::ConsumeShorthandGreedilyViaLonghands(
outlineShorthand(), important, context, range, properties);
}
@@ -2274,7 +2206,7 @@ bool Overflow::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
overflowShorthand(), important, context, range, properties);
}
@@ -2297,7 +2229,7 @@ bool OverscrollBehavior::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
overscrollBehaviorShorthand(), important, context, range, properties);
}
@@ -2320,7 +2252,7 @@ bool PaddingBlock::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
paddingBlockShorthand(), important, context, range, properties);
}
@@ -2339,7 +2271,7 @@ bool Padding::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia4Longhands(
+ return css_parsing_utils::ConsumeShorthandVia4Longhands(
paddingShorthand(), important, context, range, properties);
}
@@ -2366,7 +2298,7 @@ bool PaddingInline::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
paddingInlineShorthand(), important, context, range, properties);
}
@@ -2391,11 +2323,10 @@ bool PageBreakAfter::ParseShorthand(
}
DCHECK(IsValidCSSValueID(value));
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBreakAfter, CSSPropertyID::kPageBreakAfter,
*CSSIdentifierValue::Create(value), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -2419,11 +2350,10 @@ bool PageBreakBefore::ParseShorthand(
}
DCHECK(IsValidCSSValueID(value));
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBreakBefore, CSSPropertyID::kPageBreakBefore,
*CSSIdentifierValue::Create(value), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -2446,11 +2376,10 @@ bool PageBreakInside::ParseShorthand(
return false;
}
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBreakInside, CSSPropertyID::kPageBreakInside,
*CSSIdentifierValue::Create(value), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -2500,16 +2429,14 @@ bool PlaceContent::ParseShorthand(
DCHECK(align_content_value);
DCHECK(justify_content_value);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kAlignContent, CSSPropertyID::kPlaceContent,
*align_content_value, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kJustifyContent, CSSPropertyID::kPlaceContent,
*justify_content_value, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -2550,16 +2477,14 @@ bool PlaceItems::ParseShorthand(
DCHECK(align_items_value);
DCHECK(justify_items_value);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kAlignItems, CSSPropertyID::kPlaceItems,
*align_items_value, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kJustifyItems, CSSPropertyID::kPlaceItems,
*justify_items_value, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -2600,15 +2525,14 @@ bool PlaceSelf::ParseShorthand(
DCHECK(align_self_value);
DCHECK(justify_self_value);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kAlignSelf, CSSPropertyID::kPlaceSelf, *align_self_value,
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kJustifySelf, CSSPropertyID::kPlaceSelf,
*justify_self_value, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -2628,7 +2552,7 @@ bool ScrollMarginBlock::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
scrollMarginBlockShorthand(), important, context, range, properties);
}
@@ -2647,7 +2571,7 @@ bool ScrollMargin::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia4Longhands(
+ return css_parsing_utils::ConsumeShorthandVia4Longhands(
scrollMarginShorthand(), important, context, range, properties);
}
@@ -2666,7 +2590,7 @@ bool ScrollMarginInline::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
scrollMarginInlineShorthand(), important, context, range, properties);
}
@@ -2685,7 +2609,7 @@ bool ScrollPaddingBlock::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
scrollPaddingBlockShorthand(), important, context, range, properties);
}
@@ -2704,7 +2628,7 @@ bool ScrollPadding::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia4Longhands(
+ return css_parsing_utils::ConsumeShorthandVia4Longhands(
scrollPaddingShorthand(), important, context, range, properties);
}
@@ -2723,7 +2647,7 @@ bool ScrollPaddingInline::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
+ return css_parsing_utils::ConsumeShorthandVia2Longhands(
scrollPaddingInlineShorthand(), important, context, range, properties);
}
@@ -2743,8 +2667,11 @@ bool TextDecoration::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandGreedilyViaLonghands(
- textDecorationShorthand(), important, context, range, properties);
+ // Use RuntimeEnabledFeature-aware shorthandForProperty() method until
+ // text-decoration-thickness ships, see style_property_shorthand.cc.tmpl.
+ return css_parsing_utils::ConsumeShorthandGreedilyViaLonghands(
+ shorthandForProperty(CSSPropertyID::kTextDecoration), important, context,
+ range, properties);
}
const CSSValue* TextDecoration::CSSValueFromComputedStyleInternal(
@@ -2752,8 +2679,31 @@ const CSSValue* TextDecoration::CSSValueFromComputedStyleInternal(
const SVGComputedStyle&,
const LayoutObject* layout_object,
bool allow_visited_style) const {
- return ComputedStyleUtils::ValuesForShorthandProperty(
- textDecorationShorthand(), style, layout_object, allow_visited_style);
+ // Use RuntimeEnabledFeature-aware shorthandForProperty() method until
+ // text-decoration-thickness ships, see style_property_shorthand.cc.tmpl.
+ const StylePropertyShorthand& shorthand =
+ shorthandForProperty(CSSPropertyID::kTextDecoration);
+
+ CSSValueList* list = CSSValueList::CreateSpaceSeparated();
+ for (unsigned i = 0; i < shorthand.length(); ++i) {
+ const CSSValue* value =
+ shorthand.properties()[i]->CSSValueFromComputedStyle(
+ style, layout_object, allow_visited_style);
+ // Do not include initial value 'auto' for thickness.
+ // TODO(https://crbug.com/1093826): general shorthand serialization issues
+ // remain, in particular for text-decoration.
+ if (shorthand.properties()[i]->PropertyID() ==
+ CSSPropertyID::kTextDecorationThickness) {
+ if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) {
+ CSSValueID value_id = identifier_value->GetValueID();
+ if (value_id == CSSValueID::kAuto)
+ continue;
+ }
+ }
+ DCHECK(value);
+ list->Append(*value);
+ }
+ return list;
}
namespace {
@@ -2764,11 +2714,10 @@ CSSValue* ConsumeTransitionValue(CSSPropertyID property,
bool use_legacy_parsing) {
switch (property) {
case CSSPropertyID::kTransitionDelay:
- return css_property_parser_helpers::ConsumeTime(range, context,
- kValueRangeAll);
+ return css_parsing_utils::ConsumeTime(range, context, kValueRangeAll);
case CSSPropertyID::kTransitionDuration:
- return css_property_parser_helpers::ConsumeTime(range, context,
- kValueRangeNonNegative);
+ return css_parsing_utils::ConsumeTime(range, context,
+ kValueRangeNonNegative);
case CSSPropertyID::kTransitionProperty:
return css_parsing_utils::ConsumeTransitionProperty(range, context);
case CSSPropertyID::kTransitionTimingFunction:
@@ -2806,10 +2755,9 @@ bool Transition::ParseShorthand(
}
for (unsigned i = 0; i < longhand_count; ++i) {
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
shorthand.properties()[i]->PropertyID(), shorthand.id(), *longhands[i],
- important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
}
@@ -2867,11 +2815,10 @@ bool WebkitColumnBreakAfter::ParseShorthand(
return false;
}
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBreakAfter, CSSPropertyID::kWebkitColumnBreakAfter,
*CSSIdentifierValue::Create(value), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -2895,11 +2842,10 @@ bool WebkitColumnBreakBefore::ParseShorthand(
return false;
}
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBreakBefore, CSSPropertyID::kWebkitColumnBreakBefore,
*CSSIdentifierValue::Create(value), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -2923,11 +2869,10 @@ bool WebkitColumnBreakInside::ParseShorthand(
return false;
}
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kBreakInside, CSSPropertyID::kWebkitColumnBreakInside,
*CSSIdentifierValue::Create(value), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -2958,36 +2903,31 @@ bool WebkitMaskBoxImage::ParseShorthand(
return false;
}
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kWebkitMaskBoxImageSource,
CSSPropertyID::kWebkitMaskBoxImage,
source ? *source : *CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kWebkitMaskBoxImageSlice,
CSSPropertyID::kWebkitMaskBoxImage,
slice ? *slice : *CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kWebkitMaskBoxImageWidth,
CSSPropertyID::kWebkitMaskBoxImage,
width ? *width : *CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kWebkitMaskBoxImageOutset,
CSSPropertyID::kWebkitMaskBoxImage,
outset ? *outset : *CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
+ css_parsing_utils::AddProperty(
CSSPropertyID::kWebkitMaskBoxImageRepeat,
CSSPropertyID::kWebkitMaskBoxImage,
repeat ? *repeat : *CSSInitialValue::Create(), important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
+ css_parsing_utils::IsImplicitProperty::kNotImplicit, properties);
return true;
}
@@ -3021,21 +2961,19 @@ bool WebkitMaskPosition::ParseShorthand(
CSSValue* result_y = nullptr;
if (!css_parsing_utils::ConsumeBackgroundPosition(
- range, context, css_property_parser_helpers::UnitlessQuirk::kAllow,
- result_x, result_y) ||
+ range, context, css_parsing_utils::UnitlessQuirk::kAllow, result_x,
+ result_y) ||
!range.AtEnd())
return false;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kWebkitMaskPositionX, CSSPropertyID::kWebkitMaskPosition,
- *result_x, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ *result_x, important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kWebkitMaskPositionY, CSSPropertyID::kWebkitMaskPosition,
- *result_y, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ *result_y, important, css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
return true;
}
@@ -3063,17 +3001,17 @@ bool WebkitMaskRepeat::ParseShorthand(
!range.AtEnd())
return false;
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kWebkitMaskRepeatX, CSSPropertyID::kWebkitMaskRepeat,
*result_x, important,
- implicit ? css_property_parser_helpers::IsImplicitProperty::kImplicit
- : css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ implicit ? css_parsing_utils::IsImplicitProperty::kImplicit
+ : css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
- css_property_parser_helpers::AddProperty(
+ css_parsing_utils::AddProperty(
CSSPropertyID::kWebkitMaskRepeatY, CSSPropertyID::kWebkitMaskRepeat,
*result_y, important,
- implicit ? css_property_parser_helpers::IsImplicitProperty::kImplicit
- : css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
+ implicit ? css_parsing_utils::IsImplicitProperty::kImplicit
+ : css_parsing_utils::IsImplicitProperty::kNotImplicit,
properties);
return true;
@@ -3094,7 +3032,7 @@ bool WebkitTextEmphasis::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandGreedilyViaLonghands(
+ return css_parsing_utils::ConsumeShorthandGreedilyViaLonghands(
webkitTextEmphasisShorthand(), important, context, range, properties);
}
@@ -3104,7 +3042,7 @@ bool WebkitTextStroke::ParseShorthand(
const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandGreedilyViaLonghands(
+ return css_parsing_utils::ConsumeShorthandGreedilyViaLonghands(
webkitTextStrokeShorthand(), important, context, range, properties);
}
diff --git a/chromium/third_party/blink/renderer/core/css/property_registration.cc b/chromium/third_party/blink/renderer/core/css/property_registration.cc
index c27045c2d20..1300d30b9c2 100644
--- a/chromium/third_party/blink/renderer/core/css/property_registration.cc
+++ b/chromium/third_party/blink/renderer/core/css/property_registration.cc
@@ -233,8 +233,17 @@ void PropertyRegistration::registerProperty(
}
void PropertyRegistration::RemoveDeclaredProperties(Document& document) {
- document.EnsurePropertyRegistry().RemoveDeclaredProperties();
- document.GetStyleEngine().PropertyRegistryChanged();
+ if (!document.GetPropertyRegistry())
+ return;
+
+ PropertyRegistry& registry = document.EnsurePropertyRegistry();
+
+ size_t version_before = registry.Version();
+ registry.RemoveDeclaredProperties();
+ size_t version_after = registry.Version();
+
+ if (version_before != version_after)
+ document.GetStyleEngine().PropertyRegistryChanged();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/property_registration.h b/chromium/third_party/blink/renderer/core/css/property_registration.h
index d9e33ea0ec8..1fa15b09b6c 100644
--- a/chromium/third_party/blink/renderer/core/css/property_registration.h
+++ b/chromium/third_party/blink/renderer/core/css/property_registration.h
@@ -55,7 +55,7 @@ class CORE_EXPORT PropertyRegistration final
return interpolation_types_;
}
- void Trace(Visitor* visitor) { visitor->Trace(initial_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(initial_); }
private:
friend class ::blink::PropertyRegistry;
diff --git a/chromium/third_party/blink/renderer/core/css/property_registry.cc b/chromium/third_party/blink/renderer/core/css/property_registry.cc
index d075c732751..397f895cf1c 100644
--- a/chromium/third_party/blink/renderer/core/css/property_registry.cc
+++ b/chromium/third_party/blink/renderer/core/css/property_registry.cc
@@ -21,6 +21,8 @@ void PropertyRegistry::DeclareProperty(const AtomicString& name,
}
void PropertyRegistry::RemoveDeclaredProperties() {
+ if (declared_properties_.IsEmpty())
+ return;
declared_properties_.clear();
version_++;
}
diff --git a/chromium/third_party/blink/renderer/core/css/property_registry.h b/chromium/third_party/blink/renderer/core/css/property_registry.h
index 075df780f8f..9c94f78c573 100644
--- a/chromium/third_party/blink/renderer/core/css/property_registry.h
+++ b/chromium/third_party/blink/renderer/core/css/property_registry.h
@@ -80,7 +80,7 @@ class CORE_EXPORT PropertyRegistry : public GarbageCollected<PropertyRegistry> {
Iterator begin() const;
Iterator end() const;
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(registered_properties_);
visitor->Trace(declared_properties_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/property_registry_test.cc b/chromium/third_party/blink/renderer/core/css/property_registry_test.cc
index d70fa3b4d12..8b4be0b8b0d 100644
--- a/chromium/third_party/blink/renderer/core/css/property_registry_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/property_registry_test.cc
@@ -230,6 +230,9 @@ TEST_F(PropertyRegistryTest, Version) {
Registry().RemoveDeclaredProperties();
EXPECT_EQ(6u, Registry().Version());
+
+ Registry().RemoveDeclaredProperties();
+ EXPECT_EQ(6u, Registry().Version());
}
TEST_F(PropertyRegistryTest, RemoveDeclaredProperties) {
diff --git a/chromium/third_party/blink/renderer/core/css/property_set_css_style_declaration.cc b/chromium/third_party/blink/renderer/core/css/property_set_css_style_declaration.cc
index 33ab62e21d1..d6c63e3c260 100644
--- a/chromium/third_party/blink/renderer/core/css/property_set_css_style_declaration.cc
+++ b/chromium/third_party/blink/renderer/core/css/property_set_css_style_declaration.cc
@@ -27,7 +27,7 @@
namespace blink {
-void PropertySetCSSStyleDeclaration::Trace(Visitor* visitor) {
+void PropertySetCSSStyleDeclaration::Trace(Visitor* visitor) const {
visitor->Trace(property_set_);
AbstractPropertySetCSSStyleDeclaration::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/property_set_css_style_declaration.h b/chromium/third_party/blink/renderer/core/css/property_set_css_style_declaration.h
index 2d7ec1b1076..c7ada340d80 100644
--- a/chromium/third_party/blink/renderer/core/css/property_set_css_style_declaration.h
+++ b/chromium/third_party/blink/renderer/core/css/property_set_css_style_declaration.h
@@ -41,7 +41,7 @@ class PropertySetCSSStyleDeclaration
: AbstractPropertySetCSSStyleDeclaration(execution_context),
property_set_(&property_set) {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
MutableCSSPropertyValueSet& PropertySet() const final {
diff --git a/chromium/third_party/blink/renderer/core/css/pseudo_style_request.h b/chromium/third_party/blink/renderer/core/css/pseudo_style_request.h
index 857accbd03e..908eec6a303 100644
--- a/chromium/third_party/blink/renderer/core/css/pseudo_style_request.h
+++ b/chromium/third_party/blink/renderer/core/css/pseudo_style_request.h
@@ -51,7 +51,7 @@ class PseudoElementStyleRequest {
scrollbar_part(kNoPart),
scrollbar(nullptr) {}
- void Trace(Visitor* visitor) { visitor->Trace(scrollbar); }
+ void Trace(Visitor* visitor) const { visitor->Trace(scrollbar); }
// The spec disallows inheritance for ::backdrop.
bool AllowsInheritance(const ComputedStyle* parent_style) const {
diff --git a/chromium/third_party/blink/renderer/core/css/remote_font_face_source.cc b/chromium/third_party/blink/renderer/core/css/remote_font_face_source.cc
index 7a86d44d611..6b0ce7c4128 100644
--- a/chromium/third_party/blink/renderer/core/css/remote_font_face_source.cc
+++ b/chromium/third_party/blink/renderer/core/css/remote_font_face_source.cc
@@ -56,9 +56,11 @@ RemoteFontFaceSource::ComputeFontDisplayAutoPeriod() const {
using Mode = features::AlignFontDisplayAutoTimeoutWithLCPGoalMode;
Mode mode =
features::kAlignFontDisplayAutoTimeoutWithLCPGoalModeParam.Get();
- if (mode == Mode::kToFailurePeriod)
+ if (mode == Mode::kToSwapPeriod)
+ return kSwapPeriod;
+ DCHECK_EQ(Mode::kToFailurePeriod, mode);
+ if (custom_font_data_ && !custom_font_data_->MayBeIconFont())
return kFailurePeriod;
- DCHECK_EQ(Mode::kToSwapPeriod, mode);
return kSwapPeriod;
}
@@ -359,7 +361,7 @@ RemoteFontFaceSource::CreateLoadingFallbackFontData(
}
void RemoteFontFaceSource::BeginLoadIfNeeded() {
- if (IsLoaded())
+ if (IsLoaded() || !font_selector_->GetExecutionContext())
return;
DCHECK(GetResource());
@@ -396,7 +398,7 @@ void RemoteFontFaceSource::BeginLoadIfNeeded() {
face_->DidBeginLoad();
}
-void RemoteFontFaceSource::Trace(Visitor* visitor) {
+void RemoteFontFaceSource::Trace(Visitor* visitor) const {
visitor->Trace(face_);
visitor->Trace(font_selector_);
CSSFontFaceSource::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/remote_font_face_source.h b/chromium/third_party/blink/renderer/core/css/remote_font_face_source.h
index eae4e343063..545ce57ac99 100644
--- a/chromium/third_party/blink/renderer/core/css/remote_font_face_source.h
+++ b/chromium/third_party/blink/renderer/core/css/remote_font_face_source.h
@@ -48,7 +48,7 @@ class RemoteFontFaceSource final : public CSSFontFaceSource,
bool HadBlankText() override { return histograms_.HadBlankText(); }
void PaintRequested() override { histograms_.FallbackFontPainted(period_); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
scoped_refptr<SimpleFontData> CreateFontData(
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_priority.h b/chromium/third_party/blink/renderer/core/css/resolver/cascade_priority.h
index 9a49e2c72d2..afc3253510b 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/cascade_priority.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_priority.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_PRIORITY_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_PRIORITY_H_
-#include "base/logging.h"
+#include "base/check_op.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/resolver/cascade_origin.h"
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_resolver.cc b/chromium/third_party/blink/renderer/core/css/resolver/cascade_resolver.cc
index 55865460fa8..49332075b1b 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/cascade_resolver.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_resolver.cc
@@ -7,25 +7,21 @@
#include "third_party/blink/renderer/core/animation/css/css_animations.h"
#include "third_party/blink/renderer/core/css/css_variable_data.h"
#include "third_party/blink/renderer/core/css/properties/css_property.h"
+#include "third_party/blink/renderer/core/css/properties/longhands/custom_property.h"
#include "third_party/blink/renderer/core/css/resolver/cascade_priority.h"
namespace blink {
bool CascadeResolver::IsLocked(const CSSProperty& property) const {
- return IsLocked(property.GetCSSPropertyName());
-}
-
-bool CascadeResolver::IsLocked(const CSSPropertyName& name) const {
- return stack_.Contains(name);
+ return Find(property) != kNotFound;
}
bool CascadeResolver::AllowSubstitution(CSSVariableData* data) const {
if (data && data->IsAnimationTainted() && stack_.size()) {
- const CSSPropertyName& name = stack_.back();
- if (name.IsCustomProperty())
+ const CSSProperty* property = CurrentProperty();
+ if (IsA<CustomProperty>(*property))
return true;
- const CSSProperty& property = CSSProperty::Get(name.Id());
- return !CSSAnimations::IsAnimationAffectingProperty(property);
+ return !CSSAnimations::IsAnimationAffectingProperty(*property);
}
return true;
}
@@ -41,7 +37,7 @@ void CascadeResolver::MarkApplied(CascadePriority* priority) const {
}
bool CascadeResolver::DetectCycle(const CSSProperty& property) {
- wtf_size_t index = stack_.Find(property.GetCSSPropertyName());
+ wtf_size_t index = Find(property);
if (index == kNotFound)
return false;
cycle_depth_ = std::min(cycle_depth_, index);
@@ -52,15 +48,21 @@ bool CascadeResolver::InCycle() const {
return cycle_depth_ != kNotFound;
}
-CascadeResolver::AutoLock::AutoLock(const CSSProperty& property,
- CascadeResolver& resolver)
- : AutoLock(property.GetCSSPropertyName(), resolver) {}
+wtf_size_t CascadeResolver::Find(const CSSProperty& property) const {
+ wtf_size_t index = 0;
+ for (const CSSProperty* p : stack_) {
+ if (p->GetCSSPropertyName() == property.GetCSSPropertyName())
+ return index;
+ ++index;
+ }
+ return kNotFound;
+}
-CascadeResolver::AutoLock::AutoLock(const CSSPropertyName& name,
+CascadeResolver::AutoLock::AutoLock(const CSSProperty& property,
CascadeResolver& resolver)
: resolver_(resolver) {
- DCHECK(!resolver.IsLocked(name));
- resolver_.stack_.push_back(name);
+ DCHECK(!resolver.IsLocked(property));
+ resolver_.stack_.push_back(&property);
}
CascadeResolver::AutoLock::~AutoLock() {
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_resolver.h b/chromium/third_party/blink/renderer/core/css/resolver/cascade_resolver.h
index d60be0d8662..7c3f8808bba 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/cascade_resolver.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_resolver.h
@@ -34,13 +34,17 @@ class CORE_EXPORT CascadeResolver {
public:
// TODO(crbug.com/985047): Probably use a HashMap for this.
- using NameStack = Vector<CSSPropertyName, 8>;
+ using PropertyStack = Vector<const CSSProperty*, 8>;
// A 'locked' property is a property we are in the process of applying.
// In other words, once a property is locked, locking it again would form
// a cycle, and is therefore an error.
bool IsLocked(const CSSProperty&) const;
- bool IsLocked(const CSSPropertyName&) const;
+
+ // Returns the property we're currently applying.
+ const CSSProperty* CurrentProperty() const {
+ return stack_.size() ? stack_.back() : nullptr;
+ }
// We do not allow substitution of animation-tainted values into
// an animation-affecting property.
@@ -73,7 +77,6 @@ class CORE_EXPORT CascadeResolver {
public:
AutoLock(const CSSProperty&, CascadeResolver&);
- AutoLock(const CSSPropertyName&, CascadeResolver&);
~AutoLock();
private:
@@ -102,8 +105,12 @@ class CORE_EXPORT CascadeResolver {
// Returns true whenever the CascadeResolver is in a cycle state.
// This DOES NOT detect cycles; the caller must call DetectCycle first.
bool InCycle() const;
+ // Returns the index of the given property (compared using the property's
+ // CSSPropertyName), or kNotFound if the property (name) is not present in
+ // stack_.
+ wtf_size_t Find(const CSSProperty&) const;
- NameStack stack_;
+ PropertyStack stack_;
wtf_size_t cycle_depth_ = kNotFound;
CascadeFilter filter_;
const uint8_t generation_ = 0;
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/css_property_priority.h b/chromium/third_party/blink/renderer/core/css/resolver/css_property_priority.h
index 1e965ec2f22..04f8f7ac5cc 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/css_property_priority.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/css_property_priority.h
@@ -64,7 +64,7 @@ constexpr CSSPropertyID
CSSPropertyPriorityData<kAnimationPropertyPriority>::Last() {
static_assert(
static_cast<int>(CSSPropertyID::kTransitionTimingFunction) ==
- static_cast<int>(CSSPropertyID::kAnimationDelay) + 11,
+ static_cast<int>(CSSPropertyID::kAnimationDelay) + 12,
"CSSPropertyID::kTransitionTimingFunction should be the end of the high "
"priority property range");
static_assert(
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc b/chromium/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc
index 46c9f87039f..a8af005e0ef 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc
@@ -32,6 +32,7 @@
#include "third_party/blink/renderer/core/animation/css/css_animation_data.h"
#include "third_party/blink/renderer/core/css/css_border_image_slice_value.h"
#include "third_party/blink/renderer/core/css/css_custom_ident_value.h"
+#include "third_party/blink/renderer/core/css/css_identifier_value.h"
#include "third_party/blink/renderer/core/css/css_primitive_value.h"
#include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h"
#include "third_party/blink/renderer/core/css/css_quad_value.h"
@@ -287,35 +288,6 @@ void CSSToStyleMap::MapFillPositionY(StyleResolverState& state,
}
}
-void CSSToStyleMap::MapFillMaskSourceType(StyleResolverState&,
- FillLayer* layer,
- const CSSValue& value) {
- EMaskSourceType type = FillLayer::InitialFillMaskSourceType(layer->GetType());
- if (value.IsInitialValue()) {
- layer->SetMaskSourceType(type);
- return;
- }
-
- const auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
- if (!identifier_value)
- return;
-
- switch (identifier_value->GetValueID()) {
- case CSSValueID::kAlpha:
- type = EMaskSourceType::kAlpha;
- break;
- case CSSValueID::kLuminance:
- type = EMaskSourceType::kLuminance;
- break;
- case CSSValueID::kAuto:
- break;
- default:
- NOTREACHED();
- }
-
- layer->SetMaskSourceType(type);
-}
-
double CSSToStyleMap::MapAnimationDelay(const CSSValue& value) {
if (value.IsInitialValue())
return CSSTimingData::InitialDelay();
@@ -386,6 +358,23 @@ AtomicString CSSToStyleMap::MapAnimationName(const CSSValue& value) {
return CSSAnimationData::InitialName();
}
+StyleNameOrKeyword CSSToStyleMap::MapAnimationTimeline(const CSSValue& value) {
+ if (value.IsInitialValue())
+ return CSSAnimationData::InitialTimeline();
+ if (auto* ident = DynamicTo<CSSIdentifierValue>(value)) {
+ DCHECK(ident->GetValueID() == CSSValueID::kAuto ||
+ ident->GetValueID() == CSSValueID::kNone);
+ return StyleNameOrKeyword(ident->GetValueID());
+ }
+ if (auto* custom_ident = DynamicTo<CSSCustomIdentValue>(value)) {
+ return StyleNameOrKeyword(
+ StyleName(custom_ident->Value(), StyleName::Type::kCustomIdent));
+ }
+ return StyleNameOrKeyword(
+ StyleName(AtomicString(To<CSSStringValue>(value).Value()),
+ StyleName::Type::kString));
+}
+
EAnimPlayState CSSToStyleMap::MapAnimationPlayState(const CSSValue& value) {
if (value.IsInitialValue())
return CSSAnimationData::InitialPlayState();
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/css_to_style_map.h b/chromium/third_party/blink/renderer/core/css/resolver/css_to_style_map.h
index 9781979c133..ca0fd735647 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/css_to_style_map.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/css_to_style_map.h
@@ -23,10 +23,12 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CSS_TO_STYLE_MAP_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CSS_TO_STYLE_MAP_H_
+#include "third_party/blink/renderer/core/animation/css/css_animation_data.h"
#include "third_party/blink/renderer/core/animation/css/css_transition_data.h"
#include "third_party/blink/renderer/core/animation/timing.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
+#include "third_party/blink/renderer/core/style/style_name_or_keyword.h"
#include "third_party/blink/renderer/platform/animation/timing_function.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -63,9 +65,6 @@ class CSSToStyleMap {
static void MapFillPositionY(StyleResolverState&,
FillLayer*,
const CSSValue&);
- static void MapFillMaskSourceType(StyleResolverState&,
- FillLayer*,
- const CSSValue&);
static double MapAnimationDelay(const CSSValue&);
static Timing::PlaybackDirection MapAnimationDirection(const CSSValue&);
@@ -73,6 +72,7 @@ class CSSToStyleMap {
static Timing::FillMode MapAnimationFillMode(const CSSValue&);
static double MapAnimationIterationCount(const CSSValue&);
static AtomicString MapAnimationName(const CSSValue&);
+ static StyleNameOrKeyword MapAnimationTimeline(const CSSValue&);
static EAnimPlayState MapAnimationPlayState(const CSSValue&);
static CSSTransitionData::TransitionProperty MapAnimationProperty(
const CSSValue&);
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/match_result.cc b/chromium/third_party/blink/renderer/core/css/resolver/match_result.cc
index ae05e3e6776..9425376e13a 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/match_result.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/match_result.cc
@@ -43,7 +43,7 @@ MatchedProperties::MatchedProperties() {
memset(&types_, 0, sizeof(types_));
}
-void MatchedProperties::Trace(Visitor* visitor) {
+void MatchedProperties::Trace(Visitor* visitor) const {
visitor->Trace(properties);
}
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/match_result.h b/chromium/third_party/blink/renderer/core/css/resolver/match_result.h
index 476088ef23e..f9bbbfa48ef 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/match_result.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/match_result.h
@@ -45,7 +45,7 @@ struct CORE_EXPORT MatchedProperties {
public:
MatchedProperties();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
Member<CSSPropertyValueSet> properties;
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc b/chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
index 5f37a6cce7a..3a66124c8ad 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/core/css/properties/css_property_ref.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hasher.h"
namespace blink {
@@ -60,24 +61,52 @@ void CachedMatchedProperties::Set(
this->computed_style = ComputedStyle::Clone(style);
this->parent_computed_style = ComputedStyle::Clone(parent_style);
- for (const CSSPropertyName& name : dependencies)
- this->dependencies.push_back(name);
+ DCHECK(
+ RuntimeEnabledFeatures::CSSMatchedPropertiesCacheDependenciesEnabled() ||
+ dependencies.IsEmpty());
+ if (dependencies.size()) {
+ DCHECK(dependencies.size() <= StyleResolverState::kMaxDependencies);
+ // Plus one for g_null_atom.
+ this->dependencies =
+ std::make_unique<AtomicString[]>(dependencies.size() + 1);
+
+ size_t index = 0;
+ for (const CSSPropertyName& name : dependencies) {
+ DCHECK_LT(index, dependencies.size());
+ this->dependencies[index++] = name.ToAtomicString();
+ }
+ DCHECK_EQ(index, dependencies.size());
+ this->dependencies[index] = g_null_atom;
+ }
}
void CachedMatchedProperties::Clear() {
matched_properties.clear();
+ matched_properties_types.clear();
computed_style = nullptr;
parent_computed_style = nullptr;
- dependencies.clear();
+ dependencies.reset();
}
bool CachedMatchedProperties::DependenciesEqual(
const StyleResolverState& state) {
if (!state.ParentStyle())
return false;
+ if ((parent_computed_style->IsEnsuredInDisplayNone() ||
+ computed_style->IsEnsuredOutsideFlatTree()) &&
+ !state.ParentStyle()->IsEnsuredInDisplayNone() &&
+ !state.Style()->IsEnsuredOutsideFlatTree()) {
+ // If we cached a ComputedStyle in a display:none subtree, or outside the
+ // flat tree, we would not have triggered fetches for external resources
+ // and have StylePendingImages in the ComputedStyle. Instead of having to
+ // inspect the cached ComputedStyle for such resources, don't use a cached
+ // ComputedStyle when it was cached in display:none but is now rendered.
+ return false;
+ }
- for (const CSSPropertyName& name : dependencies) {
- CSSPropertyRef ref(name, state.GetDocument());
+ for (const AtomicString* name = dependencies.get(); name && !name->IsNull();
+ name++) {
+ CSSPropertyRef ref(*name, state.GetDocument());
DCHECK(ref.IsValid());
if (!ref.GetProperty().ComputedValuesEqual(*parent_computed_style,
*state.ParentStyle())) {
@@ -92,7 +121,8 @@ MatchedPropertiesCache::MatchedPropertiesCache() = default;
MatchedPropertiesCache::Key::Key(const MatchResult& result)
: Key(result,
- result.IsCacheable() ? ComputeMatchedPropertiesHash(result) : 0) {}
+ result.IsCacheable() ? ComputeMatchedPropertiesHash(result)
+ : HashTraits<unsigned>::EmptyValue()) {}
MatchedPropertiesCache::Key::Key(const MatchResult& result, unsigned hash)
: result_(result), hash_(hash) {}
@@ -101,7 +131,6 @@ const CachedMatchedProperties* MatchedPropertiesCache::Find(
const Key& key,
const StyleResolverState& style_resolver_state) {
DCHECK(key.IsValid());
- DCHECK(key.hash_);
Cache::iterator it = cache_.find(key.hash_);
if (it == cache_.end())
return nullptr;
@@ -148,7 +177,6 @@ void MatchedPropertiesCache::Add(const Key& key,
const ComputedStyle& parent_style,
const HashSet<CSSPropertyName>& dependencies) {
DCHECK(key.IsValid());
- DCHECK(key.hash_);
Cache::AddResult add_result = cache_.insert(key.hash_, nullptr);
if (add_result.is_new_entry || !add_result.stored_value->value) {
add_result.stored_value->value =
@@ -194,14 +222,18 @@ bool MatchedPropertiesCache::IsStyleCacheable(const ComputedStyle& style) {
return false;
if (style.TextAutosizingMultiplier() != 1)
return false;
- if (style.GetWritingMode() !=
- ComputedStyleInitialValues::InitialWritingMode() ||
- style.Direction() != ComputedStyleInitialValues::InitialDirection())
- return false;
- // styles with non inherited properties that reference variables are not
- // cacheable.
- if (style.HasVariableReferenceFromNonInheritedProperty())
- return false;
+ if (!RuntimeEnabledFeatures::CSSMatchedPropertiesCacheDependenciesEnabled()) {
+ if (style.GetWritingMode() !=
+ ComputedStyleInitialValues::InitialWritingMode() ||
+ style.Direction() != ComputedStyleInitialValues::InitialDirection()) {
+ return false;
+ }
+
+ // styles with non inherited properties that reference variables are not
+ // cacheable.
+ if (style.HasVariableReferenceFromNonInheritedProperty())
+ return false;
+ }
// -internal-light-dark() values in UA sheets have different computed values
// based on the used value of color-scheme.
if (style.HasNonInheritedLightDarkValue())
@@ -215,15 +247,20 @@ bool MatchedPropertiesCache::IsCacheable(const StyleResolverState& state) {
if (!IsStyleCacheable(style))
return false;
- // The cache assumes static knowledge about which properties are inherited.
- // Without a flat tree parent, StyleBuilder::ApplyProperty will not
- // SetHasExplicitlyInheritedProperties on the parent style.
- if (!state.ParentNode() || parent_style.HasExplicitlyInheritedProperties())
- return false;
- return true;
+
+ if (!RuntimeEnabledFeatures::CSSMatchedPropertiesCacheDependenciesEnabled()) {
+ // The cache assumes static knowledge about which properties are inherited.
+ // Without a flat tree parent, StyleBuilder::ApplyProperty will not
+ // SetChildHasExplicitInheritance on the parent style.
+ if (!state.ParentNode() || parent_style.ChildHasExplicitInheritance())
+ return false;
+ return true;
+ }
+
+ return state.HasValidDependencies() && !state.HasIncomparableDependency();
}
-void MatchedPropertiesCache::Trace(Visitor* visitor) {
+void MatchedPropertiesCache::Trace(Visitor* visitor) const {
visitor->Trace(cache_);
visitor->RegisterWeakCallbackMethod<
MatchedPropertiesCache,
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h b/chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h
index 40a5909f127..2f5134eea32 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h
@@ -36,7 +36,7 @@ namespace blink {
class ComputedStyle;
class StyleResolverState;
-class CachedMatchedProperties final
+class CORE_EXPORT CachedMatchedProperties final
: public GarbageCollected<CachedMatchedProperties> {
public:
// Caches data of MatchedProperties. See |MatchedPropertiesCache::Cache| for
@@ -49,7 +49,12 @@ class CachedMatchedProperties final
scoped_refptr<ComputedStyle> computed_style;
scoped_refptr<ComputedStyle> parent_computed_style;
- Vector<CSSPropertyName> dependencies;
+ // g_null_atom-terminated array of property names.
+ //
+ // Note that this stores AtomicString for both standard and custom
+ // properties, for memory saving purposes. (CSSPropertyName is twice as
+ // big).
+ std::unique_ptr<AtomicString[]> dependencies;
void Set(const ComputedStyle&,
const ComputedStyle& parent_style,
@@ -61,7 +66,7 @@ class CachedMatchedProperties final
// cached parent style vs. the incoming parent style.
bool DependenciesEqual(const StyleResolverState&);
- void Trace(Visitor*) {}
+ void Trace(Visitor*) const {}
bool operator==(const MatchedPropertiesVector& properties);
bool operator!=(const MatchedPropertiesVector& properties);
@@ -79,7 +84,13 @@ class CORE_EXPORT MatchedPropertiesCache {
public:
explicit Key(const MatchResult&);
- bool IsValid() const { return hash_ != 0; }
+
+ bool IsValid() const {
+ // If hash_ happens to compute to the empty value or the deleted value,
+ // the corresponding MatchResult can't be cached.
+ return hash_ != HashTraits<unsigned>::EmptyValue() &&
+ !HashTraits<unsigned>::IsDeletedValue(hash_);
+ }
private:
friend class MatchedPropertiesCache;
@@ -103,7 +114,7 @@ class CORE_EXPORT MatchedPropertiesCache {
static bool IsCacheable(const StyleResolverState&);
static bool IsStyleCacheable(const ComputedStyle&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// The cache is mapping a hash to a cached entry where the entry is kept as
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc
index 496fa2b2c0d..6b4912d6e3c 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
namespace blink {
@@ -21,7 +22,6 @@ class MatchedPropertiesCacheTestKey {
public:
explicit MatchedPropertiesCacheTestKey(String block_text, unsigned hash)
: key_(ParseBlock(block_text), hash) {
- DCHECK(key_.IsValid());
}
const MatchedPropertiesCache::Key& InnerKey() const { return key_; }
@@ -82,13 +82,116 @@ class MatchedPropertiesCacheTestCache {
using TestCache = MatchedPropertiesCacheTestCache;
-class MatchedPropertiesCacheTest : public PageTestBase {
+class MatchedPropertiesCacheTest
+ : public PageTestBase,
+ private ScopedCSSMatchedPropertiesCacheDependenciesForTest {
public:
+ MatchedPropertiesCacheTest()
+ : ScopedCSSMatchedPropertiesCacheDependenciesForTest(true) {}
+
scoped_refptr<ComputedStyle> CreateStyle() {
return StyleResolver::InitialStyleForElement(GetDocument());
}
};
+TEST_F(MatchedPropertiesCacheTest, ClearEntry) {
+ MatchResult result;
+ result.AddMatchedProperties(
+ css_test_helpers::ParseDeclarationBlock("top:inherit"));
+
+ auto style = CreateStyle();
+ auto parent = CreateStyle();
+
+ HashSet<CSSPropertyName> dependencies;
+ dependencies.insert(CSSPropertyName(CSSPropertyID::kTop));
+
+ auto* entry = MakeGarbageCollected<CachedMatchedProperties>();
+ entry->Set(*style, *parent, result.GetMatchedProperties(), dependencies);
+
+ EXPECT_TRUE(entry->computed_style);
+ EXPECT_TRUE(entry->parent_computed_style);
+ EXPECT_FALSE(entry->matched_properties.IsEmpty());
+ EXPECT_FALSE(entry->matched_properties_types.IsEmpty());
+ EXPECT_TRUE(entry->dependencies);
+
+ entry->Clear();
+
+ EXPECT_FALSE(entry->computed_style);
+ EXPECT_FALSE(entry->parent_computed_style);
+ EXPECT_TRUE(entry->matched_properties.IsEmpty());
+ EXPECT_TRUE(entry->matched_properties_types.IsEmpty());
+ EXPECT_FALSE(entry->dependencies);
+}
+
+TEST_F(MatchedPropertiesCacheTest, NoDependencies) {
+ MatchResult result;
+ auto style = CreateStyle();
+ auto parent = CreateStyle();
+
+ HashSet<CSSPropertyName> dependencies;
+
+ auto* entry = MakeGarbageCollected<CachedMatchedProperties>();
+ entry->Set(*style, *parent, result.GetMatchedProperties(), dependencies);
+
+ EXPECT_FALSE(entry->dependencies);
+}
+
+TEST_F(MatchedPropertiesCacheTest, OneDependency) {
+ MatchResult result;
+ auto style = CreateStyle();
+ auto parent = CreateStyle();
+
+ HashSet<CSSPropertyName> dependencies;
+ dependencies.insert(CSSPropertyName(CSSPropertyID::kTop));
+
+ auto* entry = MakeGarbageCollected<CachedMatchedProperties>();
+ entry->Set(*style, *parent, result.GetMatchedProperties(), dependencies);
+
+ ASSERT_TRUE(entry->dependencies);
+ EXPECT_EQ("top", entry->dependencies[0]);
+ EXPECT_EQ(g_null_atom, entry->dependencies[1]);
+}
+
+TEST_F(MatchedPropertiesCacheTest, TwoDependencies) {
+ MatchResult result;
+ auto style = CreateStyle();
+ auto parent = CreateStyle();
+
+ HashSet<CSSPropertyName> dependencies;
+ dependencies.insert(CSSPropertyName(CSSPropertyID::kTop));
+ dependencies.insert(CSSPropertyName(CSSPropertyID::kLeft));
+
+ auto* entry = MakeGarbageCollected<CachedMatchedProperties>();
+ entry->Set(*style, *parent, result.GetMatchedProperties(), dependencies);
+
+ ASSERT_TRUE(entry->dependencies);
+ EXPECT_TRUE(entry->dependencies[0] == "top" ||
+ entry->dependencies[0] == "left");
+ EXPECT_TRUE(entry->dependencies[1] == "top" ||
+ entry->dependencies[1] == "left");
+ EXPECT_NE(entry->dependencies[0], entry->dependencies[1]);
+ EXPECT_TRUE(entry->dependencies[2] == g_null_atom);
+}
+
+TEST_F(MatchedPropertiesCacheTest, AllowedKeyValues) {
+ unsigned empty = HashTraits<unsigned>::EmptyValue();
+ unsigned deleted = std::numeric_limits<unsigned>::max();
+
+ ASSERT_EQ(0u, HashTraits<unsigned>::EmptyValue());
+ ASSERT_TRUE(HashTraits<unsigned>::IsDeletedValue(deleted));
+
+ EXPECT_FALSE(TestKey("left:0", empty).InnerKey().IsValid());
+ EXPECT_TRUE(TestKey("left:0", empty + 1).InnerKey().IsValid());
+ EXPECT_TRUE(TestKey("left:0", deleted - 1).InnerKey().IsValid());
+ EXPECT_FALSE(TestKey("left:0", deleted).InnerKey().IsValid());
+}
+
+TEST_F(MatchedPropertiesCacheTest, InvalidKeyForUncacheableMatchResult) {
+ MatchResult result;
+ result.SetIsCacheable(false);
+ EXPECT_FALSE(MatchedPropertiesCache::Key(result).IsValid());
+}
+
TEST_F(MatchedPropertiesCacheTest, Miss) {
TestCache cache(GetDocument());
TestKey key("color:red", 1);
@@ -244,4 +347,242 @@ TEST_F(MatchedPropertiesCacheTest, HitWithMixedDependencies) {
EXPECT_TRUE(cache.Find(key, *style, *parent2));
}
+TEST_F(MatchedPropertiesCacheTest, ExplicitlyInheritedCacheable) {
+ ASSERT_TRUE(GetCSSPropertyVerticalAlign().IsComputedValueComparable());
+
+ TestCache cache(GetDocument());
+
+ auto style = CreateStyle();
+ auto parent = CreateStyle();
+ parent->SetChildHasExplicitInheritance();
+
+ StyleResolverState state(GetDocument(), *GetDocument().body(), parent.get(),
+ parent.get());
+ state.SetStyle(style);
+ // Simulate explicit inheritance on vertical-align.
+ state.MarkDependency(GetCSSPropertyVerticalAlign());
+
+ EXPECT_TRUE(MatchedPropertiesCache::IsCacheable(state));
+}
+
+TEST_F(MatchedPropertiesCacheTest, NotCacheableWithIncomparableDependency) {
+ const CSSProperty& incomparable = GetCSSPropertyInternalEmptyLineHeight();
+ ASSERT_FALSE(incomparable.IsComputedValueComparable());
+
+ TestCache cache(GetDocument());
+
+ auto style = CreateStyle();
+ auto parent = CreateStyle();
+ parent->SetChildHasExplicitInheritance();
+
+ StyleResolverState state(GetDocument(), *GetDocument().body(), parent.get(),
+ parent.get());
+ state.SetStyle(style);
+ // Simulate explicit inheritance on the incomparable property.
+ state.MarkDependency(incomparable);
+
+ EXPECT_FALSE(MatchedPropertiesCache::IsCacheable(state));
+}
+
+TEST_F(MatchedPropertiesCacheTest, WritingModeCacheable) {
+ ASSERT_NE(WritingMode::kVerticalRl,
+ ComputedStyleInitialValues::InitialWritingMode());
+
+ TestCache cache(GetDocument());
+
+ auto style = CreateStyle();
+ auto parent = CreateStyle();
+ style->SetWritingMode(WritingMode::kVerticalRl);
+
+ StyleResolverState state(GetDocument(), *GetDocument().body(), parent.get(),
+ parent.get());
+ state.SetStyle(style);
+
+ EXPECT_TRUE(MatchedPropertiesCache::IsCacheable(state));
+}
+
+TEST_F(MatchedPropertiesCacheTest, DirectionCacheable) {
+ ASSERT_NE(TextDirection::kRtl,
+ ComputedStyleInitialValues::InitialDirection());
+
+ TestCache cache(GetDocument());
+
+ auto style = CreateStyle();
+ auto parent = CreateStyle();
+ style->SetDirection(TextDirection::kRtl);
+
+ StyleResolverState state(GetDocument(), *GetDocument().body(), parent.get(),
+ parent.get());
+ state.SetStyle(style);
+
+ EXPECT_TRUE(MatchedPropertiesCache::IsCacheable(state));
+}
+
+TEST_F(MatchedPropertiesCacheTest, VarInNonInheritedPropertyCachable) {
+ TestCache cache(GetDocument());
+
+ auto style = CreateStyle();
+ // Simulate non-inherited-property: var(--my-prop)
+ style->SetHasVariableReferenceFromNonInheritedProperty();
+
+ auto parent = CreateStyle();
+
+ StyleResolverState state(GetDocument(), *GetDocument().body(), parent.get(),
+ parent.get());
+ state.SetStyle(style);
+
+ EXPECT_TRUE(MatchedPropertiesCache::IsCacheable(state));
+}
+
+TEST_F(MatchedPropertiesCacheTest, MaxDependencies) {
+ TestCache cache(GetDocument());
+
+ auto style = CreateStyle();
+ auto parent = CreateStyle();
+
+ StyleResolverState state(GetDocument(), *GetDocument().body(), parent.get(),
+ parent.get());
+ state.SetStyle(style);
+ for (size_t i = 0; i < StyleResolverState::kMaxDependencies; i++) {
+ CustomProperty property(AtomicString(String::Format("--x%zu", i)),
+ GetDocument());
+ state.MarkDependency(property);
+ EXPECT_TRUE(MatchedPropertiesCache::IsCacheable(state));
+ }
+ CustomProperty property("--y", GetDocument());
+ state.MarkDependency(property);
+ // Limit exceeded.
+ EXPECT_FALSE(MatchedPropertiesCache::IsCacheable(state));
+}
+
+TEST_F(MatchedPropertiesCacheTest,
+ ExplicitlyInheritedNotCacheableWithoutFeature) {
+ ScopedCSSMatchedPropertiesCacheDependenciesForTest scoped_feature(false);
+
+ TestCache cache(GetDocument());
+
+ auto style = CreateStyle();
+ auto parent = CreateStyle();
+ parent->SetChildHasExplicitInheritance();
+
+ StyleResolverState state(GetDocument(), *GetDocument().body(), parent.get(),
+ parent.get());
+ state.SetStyle(style);
+
+ EXPECT_FALSE(MatchedPropertiesCache::IsCacheable(state));
+}
+
+TEST_F(MatchedPropertiesCacheTest,
+ VarInNonInheritedPropertyNotCachableWithoutFeature) {
+ ScopedCSSMatchedPropertiesCacheDependenciesForTest scoped_feature(false);
+
+ TestCache cache(GetDocument());
+
+ auto style = CreateStyle();
+ auto parent = CreateStyle();
+ // Simulate non-inherited-property: var(--my-prop)
+ style->SetHasVariableReferenceFromNonInheritedProperty();
+
+ StyleResolverState state(GetDocument(), *GetDocument().body(), parent.get(),
+ parent.get());
+ state.SetStyle(style);
+
+ EXPECT_FALSE(MatchedPropertiesCache::IsCacheable(state));
+}
+
+TEST_F(MatchedPropertiesCacheTest, WritingModeNotCacheableWithoutFeature) {
+ ScopedCSSMatchedPropertiesCacheDependenciesForTest scoped_feature(false);
+
+ ASSERT_NE(WritingMode::kVerticalRl,
+ ComputedStyleInitialValues::InitialWritingMode());
+
+ TestCache cache(GetDocument());
+
+ auto style = CreateStyle();
+ auto parent = CreateStyle();
+ style->SetWritingMode(WritingMode::kVerticalRl);
+
+ StyleResolverState state(GetDocument(), *GetDocument().body(), parent.get(),
+ parent.get());
+ state.SetStyle(style);
+
+ EXPECT_FALSE(MatchedPropertiesCache::IsCacheable(state));
+}
+
+TEST_F(MatchedPropertiesCacheTest, DirectionNotCacheableWithoutFeature) {
+ ScopedCSSMatchedPropertiesCacheDependenciesForTest scoped_feature(false);
+
+ ASSERT_NE(TextDirection::kRtl,
+ ComputedStyleInitialValues::InitialDirection());
+
+ TestCache cache(GetDocument());
+
+ auto style = CreateStyle();
+ auto parent = CreateStyle();
+ style->SetDirection(TextDirection::kRtl);
+
+ StyleResolverState state(GetDocument(), *GetDocument().body(), parent.get(),
+ parent.get());
+ state.SetStyle(style);
+
+ EXPECT_FALSE(MatchedPropertiesCache::IsCacheable(state));
+}
+
+TEST_F(MatchedPropertiesCacheTest, EnsuredInDisplayNone) {
+ TestCache cache(GetDocument());
+
+ auto style = CreateStyle();
+ auto parent = CreateStyle();
+ auto ensured_parent = CreateStyle();
+ ensured_parent->SetIsEnsuredInDisplayNone();
+
+ TestKey key1("display:block", 1);
+
+ cache.Add(key1, *style, *parent);
+ EXPECT_TRUE(cache.Find(key1, *style, *parent));
+ EXPECT_TRUE(cache.Find(key1, *style, *ensured_parent));
+
+ cache.Add(key1, *style, *ensured_parent);
+ EXPECT_FALSE(cache.Find(key1, *style, *parent));
+ EXPECT_TRUE(cache.Find(key1, *style, *ensured_parent));
+}
+
+TEST_F(MatchedPropertiesCacheTest, EnsuredOutsideFlatTree) {
+ TestCache cache(GetDocument());
+
+ auto style = CreateStyle();
+ auto parent = CreateStyle();
+ auto ensured_style = CreateStyle();
+ ensured_style->SetIsEnsuredOutsideFlatTree();
+
+ TestKey key1("display:block", 1);
+
+ cache.Add(key1, *style, *parent);
+ EXPECT_TRUE(cache.Find(key1, *style, *parent));
+ EXPECT_TRUE(cache.Find(key1, *ensured_style, *parent));
+
+ cache.Add(key1, *ensured_style, *parent);
+ EXPECT_FALSE(cache.Find(key1, *style, *parent));
+ EXPECT_TRUE(cache.Find(key1, *ensured_style, *parent));
+}
+
+TEST_F(MatchedPropertiesCacheTest, EnsuredOutsideFlatTreeAndDisplayNone) {
+ TestCache cache(GetDocument());
+
+ auto parent = CreateStyle();
+ auto parent_none = CreateStyle();
+ auto style = CreateStyle();
+ auto style_flat = CreateStyle();
+ parent_none->SetIsEnsuredInDisplayNone();
+ style_flat->SetIsEnsuredOutsideFlatTree();
+
+ TestKey key1("display:block", 1);
+
+ cache.Add(key1, *style, *parent_none);
+ EXPECT_TRUE(cache.Find(key1, *style_flat, *parent));
+
+ cache.Add(key1, *style_flat, *parent);
+ EXPECT_TRUE(cache.Find(key1, *style, *parent_none));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.cc b/chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.cc
index 0b75dc38e7c..e362fd04383 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.cc
@@ -288,7 +288,7 @@ void ScopedStyleResolver::MatchPageRules(PageRuleCollector& collector) {
collector.MatchPageRules(&sheet->Contents()->GetRuleSet());
}
-void ScopedStyleResolver::Trace(Visitor* visitor) {
+void ScopedStyleResolver::Trace(Visitor* visitor) const {
visitor->Trace(scope_);
visitor->Trace(author_style_sheets_);
visitor->Trace(keyframes_rule_map_);
@@ -386,7 +386,7 @@ void ScopedStyleResolver::AddSlottedRules(const RuleSet& author_rules,
parent_style_sheet, sheet_index, slotted_rule_set));
}
-void ScopedStyleResolver::RuleSubSet::Trace(Visitor* visitor) {
+void ScopedStyleResolver::RuleSubSet::Trace(Visitor* visitor) const {
visitor->Trace(parent_style_sheet_);
visitor->Trace(rule_set_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.h b/chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.h
index ae51e9644af..c6932e4b9b0 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.h
@@ -88,7 +88,7 @@ class CORE_EXPORT ScopedStyleResolver final
static Element& InvalidationRootForTreeScope(const TreeScope&);
void V0ShadowAddedOnV1Document();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void AddTreeBoundaryCrossingRules(const RuleSet&,
@@ -118,7 +118,7 @@ class CORE_EXPORT ScopedStyleResolver final
unsigned parent_index_;
Member<RuleSet> rule_set_;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
};
using CSSStyleSheetRuleSubSet = HeapVector<Member<RuleSubSet>>;
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/chromium/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
index fa15f6680c3..c27e37c36f7 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -50,10 +50,10 @@
#include "third_party/blink/renderer/core/html/html_table_cell_element.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/html_names.h"
-#include "third_party/blink/renderer/core/layout/layout_list_marker.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_replaced.h"
#include "third_party/blink/renderer/core/layout/layout_theme.h"
+#include "third_party/blink/renderer/core/layout/list_marker.h"
#include "third_party/blink/renderer/core/mathml/mathml_fraction_element.h"
#include "third_party/blink/renderer/core/mathml/mathml_space_element.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
@@ -87,6 +87,23 @@ TouchAction AdjustTouchActionForElement(TouchAction touch_action,
return touch_action;
}
+void AdjustBackgroundForForcedColorsMode(StyleResolverState& state,
+ ComputedStyle& style,
+ Element* element) {
+ if (!element || !element->GetDocument().InForcedColorsMode() ||
+ style.ForcedColorAdjust() == EForcedColorAdjust::kNone)
+ return;
+
+ int bg_color_alpha =
+ LayoutObject::ResolveColor(style, GetCSSPropertyBackgroundColor())
+ .Alpha();
+ Color bg_color_rbg = StyleColor::ColorFromKeyword(
+ style.InternalForcedBackgroundColorRgb(), WebColorScheme::kLight);
+ Color bg_color = Color(bg_color_rbg.Red(), bg_color_rbg.Green(),
+ bg_color_rbg.Blue(), bg_color_alpha);
+ style.SetBackgroundColor(bg_color);
+}
+
} // namespace
static EDisplay EquivalentBlockDisplay(EDisplay display) {
@@ -222,7 +239,7 @@ static void AdjustStyleForMarker(ComputedStyle& style,
!parent_style.IsInsideListElement());
if (is_inside) {
- auto margins = LayoutListMarker::InlineMarginsForInside(
+ auto margins = ListMarker::InlineMarginsForInside(
style, parent_style.GeneratesMarkerImage());
style.SetMarginStart(Length::Fixed(margins.first));
style.SetMarginEnd(Length::Fixed(margins.second));
@@ -509,10 +526,10 @@ static void AdjustEffectiveTouchAction(ComputedStyle& style,
bool is_svg_root) {
TouchAction inherited_action = parent_style.GetEffectiveTouchAction();
- bool is_replaced_canvas =
- element && IsA<HTMLCanvasElement>(element) &&
- element->GetDocument().GetFrame() &&
- element->GetDocument().CanExecuteScripts(kNotAboutToExecuteScript);
+ bool is_replaced_canvas = element && IsA<HTMLCanvasElement>(element) &&
+ element->GetExecutionContext() &&
+ element->GetExecutionContext()->CanExecuteScripts(
+ kNotAboutToExecuteScript);
bool is_non_replaced_inline_elements =
style.IsDisplayInlineType() &&
!(style.IsDisplayReplacedType() || is_svg_root ||
@@ -655,12 +672,11 @@ void StyleAdjuster::AdjustComputedStyle(StyleResolverState& state,
if (style.GetPosition() == EPosition::kStatic &&
!LayoutParentStyleForcesZIndexToCreateStackingContext(
layout_parent_style)) {
- style.SetIsStackingContext(false);
- // TODO(alancutter): Avoid altering z-index here.
+ style.SetIsStackingContextWithoutContainment(false);
if (!style.HasAutoZIndex())
- style.SetZIndex(0);
+ style.SetEffectiveZIndexZero(true);
} else if (!style.HasAutoZIndex()) {
- style.SetIsStackingContext(true);
+ style.SetIsStackingContextWithoutContainment(true);
}
if (style.OverflowX() != EOverflow::kVisible ||
@@ -794,5 +810,7 @@ void StyleAdjuster::AdjustComputedStyle(StyleResolverState& state,
(element && element->GetDocument().Printing()))
style.SetInsideNGFragmentationContext(true);
}
+
+ AdjustBackgroundForForcedColorsMode(state, style, element);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_builder.cc b/chromium/third_party/blink/renderer/core/css/resolver/style_builder.cc
index 744995d74cd..b39f767b8f7 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_builder.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_builder.cc
@@ -98,9 +98,10 @@ void StyleBuilder::ApplyProperty(const CSSProperty& property,
// isInherit => (state.parentNode() && state.parentStyle())
DCHECK(!is_inherit || (state.ParentNode() && state.ParentStyle()));
- if (is_inherit && !state.ParentStyle()->HasExplicitlyInheritedProperties() &&
- !is_inherited) {
- state.ParentStyle()->SetHasExplicitlyInheritedProperties();
+ if (is_inherit && !is_inherited) {
+ state.MarkDependency(property);
+ state.Style()->SetHasExplicitInheritance();
+ state.ParentStyle()->SetChildHasExplicitInheritance();
} else if (value.IsUnsetValue()) {
DCHECK(!is_inherit && !is_initial);
if (is_inherited)
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/chromium/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
index 8a34c4c5594..fc9d98b1e1e 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -59,6 +59,7 @@
#include "third_party/blink/renderer/core/style/reference_clip_path_operation.h"
#include "third_party/blink/renderer/core/style/shape_clip_path_operation.h"
#include "third_party/blink/renderer/core/style/style_svg_resource.h"
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
@@ -293,6 +294,58 @@ StyleBuilderConverter::ConvertFontVariationSettings(StyleResolverState& state,
return settings;
}
+float MathScriptScaleFactor(StyleResolverState& state) {
+ int a = state.ParentStyle()->MathScriptLevel();
+ int b = state.Style()->MathScriptLevel();
+ if (b == a)
+ return 1.0;
+ bool invertScaleFactor = false;
+ if (b < a) {
+ std::swap(a, b);
+ invertScaleFactor = true;
+ }
+
+ // Determine the scale factors from the inherited font.
+ float defaultScaleDown = 0.71;
+ int exponent = b - a;
+ float scaleFactor = 1.0;
+ HarfBuzzFace* parent_harfbuzz_face = state.ParentStyle()
+ ->GetFont()
+ .PrimaryFont()
+ ->PlatformData()
+ .GetHarfBuzzFace();
+ if (OpenTypeMathSupport::HasMathData(parent_harfbuzz_face)) {
+ float scriptPercentScaleDown =
+ OpenTypeMathSupport::MathConstant(
+ parent_harfbuzz_face,
+ OpenTypeMathSupport::MathConstants::kScriptPercentScaleDown)
+ .value_or(0);
+ // Note: zero can mean both zero for the math constant and the fallback.
+ if (!scriptPercentScaleDown)
+ scriptPercentScaleDown = defaultScaleDown;
+ float scriptScriptPercentScaleDown =
+ OpenTypeMathSupport::MathConstant(
+ parent_harfbuzz_face,
+ OpenTypeMathSupport::MathConstants::kScriptScriptPercentScaleDown)
+ .value_or(0);
+ // Note: zero can mean both zero for the math constant and the fallback.
+ if (!scriptScriptPercentScaleDown)
+ scriptScriptPercentScaleDown = defaultScaleDown * defaultScaleDown;
+ if (a <= 0 && b >= 2) {
+ scaleFactor *= scriptScriptPercentScaleDown;
+ exponent -= 2;
+ } else if (a == 1) {
+ scaleFactor *= scriptScriptPercentScaleDown / scriptPercentScaleDown;
+ exponent--;
+ } else if (b == 1) {
+ scaleFactor *= scriptPercentScaleDown;
+ exponent--;
+ }
+ }
+ scaleFactor *= pow(defaultScaleDown, exponent);
+ return invertScaleFactor ? 1 / scaleFactor : scaleFactor;
+}
+
static float ComputeFontSize(const CSSToLengthConversionData& conversion_data,
const CSSPrimitiveValue& primitive_value,
const FontDescription::Size& parent_size) {
@@ -356,14 +409,48 @@ FontDescription::Size StyleBuilderConverterBase::ConvertFontSize(
is_absolute);
}
+static FontDescription::Size ConvertScriptLevelFontSize(
+ StyleResolverState& state,
+ const FontDescription::Size& parent_size,
+ const CSSFunctionValue& function_value) {
+ SECURITY_DCHECK(function_value.length() == 1);
+ const auto& css_value = function_value.Item(0);
+ if (const auto* list = DynamicTo<CSSValueList>(css_value)) {
+ DCHECK_EQ(list->length(), 1U);
+ const auto& relative_value = To<CSSPrimitiveValue>(list->Item(0));
+ state.Style()->SetMathScriptLevel(state.ParentStyle()->MathScriptLevel() +
+ relative_value.GetIntValue());
+ } else if (auto* identifier_value =
+ DynamicTo<CSSIdentifierValue>(css_value)) {
+ DCHECK(identifier_value->GetValueID() == CSSValueID::kAuto);
+ unsigned level = 0;
+ if (state.ParentStyle()->MathStyle() == EMathStyle::kInline)
+ level += 1;
+ state.Style()->SetMathScriptLevel(state.ParentStyle()->MathScriptLevel() +
+ level);
+ } else if (DynamicTo<CSSPrimitiveValue>(css_value)) {
+ state.Style()->SetMathScriptLevel(
+ To<CSSPrimitiveValue>(css_value).GetIntValue());
+ }
+ auto scale_factor = MathScriptScaleFactor(state);
+ state.Style()->SetHasGlyphRelativeUnits();
+ return FontDescription::Size(0, (scale_factor * parent_size.value),
+ parent_size.is_absolute);
+}
+
FontDescription::Size StyleBuilderConverter::ConvertFontSize(
StyleResolverState& state,
const CSSValue& value) {
+ // FIXME: Find out when parentStyle could be 0?
+ auto parent_size = state.ParentStyle()
+ ? state.ParentFontDescription().GetSize()
+ : FontDescription::Size(0, 0.0f, false);
+
+ if (const auto* function_value = DynamicTo<CSSFunctionValue>(value))
+ return ConvertScriptLevelFontSize(state, parent_size, *function_value);
+
return StyleBuilderConverterBase::ConvertFontSize(
- value, state.FontSizeConversionData(),
- // FIXME: Find out when parentStyle could be 0?
- state.ParentStyle() ? state.ParentFontDescription().GetSize()
- : FontDescription::Size(0, 0.0f, false));
+ value, state.FontSizeConversionData(), parent_size);
}
float StyleBuilderConverter::ConvertFontSizeAdjust(StyleResolverState& state,
@@ -997,13 +1084,14 @@ LayoutUnit StyleBuilderConverter::ConvertLayoutUnit(StyleResolverState& state,
return LayoutUnit::Clamp(ConvertComputedLength<float>(state, value));
}
-GapLength StyleBuilderConverter::ConvertGapLength(StyleResolverState& state,
- const CSSValue& value) {
+base::Optional<Length> StyleBuilderConverter::ConvertGapLength(
+ const StyleResolverState& state,
+ const CSSValue& value) {
auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
if (identifier_value && identifier_value->GetValueID() == CSSValueID::kNormal)
- return GapLength();
+ return base::nullopt;
- return GapLength(ConvertLength(state, value));
+ return ConvertLength(state, value);
}
Length StyleBuilderConverter::ConvertLength(const StyleResolverState& state,
@@ -1410,6 +1498,13 @@ StyleColor StyleBuilderConverter::ConvertStyleColor(StyleResolverState& state,
value, Color(), state.Style()->UsedColorScheme(), for_visited_link);
}
+CSSValueID StyleBuilderConverter::ConvertCSSValueID(StyleResolverState& state,
+ const CSSValue& value) {
+ auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
+ DCHECK(identifier_value);
+ return identifier_value->GetValueID();
+}
+
StyleAutoColor StyleBuilderConverter::ConvertStyleAutoColor(
StyleResolverState& state,
const CSSValue& value,
@@ -1923,4 +2018,22 @@ RubyPosition StyleBuilderConverter::ConvertRubyPosition(
return RubyPosition::kBefore;
}
+ScrollbarGutter StyleBuilderConverter::ConvertScrollbarGutter(
+ StyleResolverState& state,
+ const CSSValue& value) {
+ ScrollbarGutter flags = kScrollbarGutterAuto;
+
+ auto process = [&flags](const CSSValue& identifier) {
+ flags |= To<CSSIdentifierValue>(identifier).ConvertTo<ScrollbarGutter>();
+ };
+
+ if (auto* value_list = DynamicTo<CSSValueList>(value)) {
+ for (auto& entry : *value_list)
+ process(*entry);
+ } else {
+ process(value);
+ }
+ return flags;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_builder_converter.h b/chromium/third_party/blink/renderer/core/css/resolver/style_builder_converter.h
index f0e732e8997..46df18e4d2e 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_builder_converter.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_builder_converter.h
@@ -152,7 +152,6 @@ class StyleBuilderConverter {
static StyleContentAlignmentData ConvertContentAlignmentData(
StyleResolverState&,
const CSSValue&);
- static GapLength ConvertGapLength(StyleResolverState&, const CSSValue&);
static GridAutoFlow ConvertGridAutoFlow(StyleResolverState&, const CSSValue&);
static GridPosition ConvertGridPosition(StyleResolverState&, const CSSValue&);
static GridTrackSize ConvertGridTrackSize(StyleResolverState&,
@@ -163,7 +162,8 @@ class StyleBuilderConverter {
static T ConvertLineWidth(StyleResolverState&, const CSSValue&);
static float ConvertBorderWidth(StyleResolverState&, const CSSValue&);
static LayoutUnit ConvertLayoutUnit(StyleResolverState&, const CSSValue&);
- static GapLength ConvertGapLength(const StyleResolverState&, const CSSValue&);
+ static base::Optional<Length> ConvertGapLength(const StyleResolverState&,
+ const CSSValue&);
static Length ConvertLength(const StyleResolverState&, const CSSValue&);
static UnzoomedLength ConvertUnzoomedLength(const StyleResolverState&,
const CSSValue&);
@@ -201,6 +201,7 @@ class StyleBuilderConverter {
static StyleColor ConvertStyleColor(StyleResolverState&,
const CSSValue&,
bool for_visited_link = false);
+ static CSSValueID ConvertCSSValueID(StyleResolverState&, const CSSValue&);
static StyleAutoColor ConvertStyleAutoColor(StyleResolverState&,
const CSSValue&,
bool for_visited_link = false);
@@ -289,6 +290,9 @@ class StyleBuilderConverter {
static RubyPosition ConvertRubyPosition(StyleResolverState& state,
const CSSValue& value);
+
+ static ScrollbarGutter ConvertScrollbarGutter(StyleResolverState& state,
+ const CSSValue& value);
};
template <typename T>
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_builder_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/style_builder_test.cc
index c2d3085f5b7..495229341d3 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_builder_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_builder_test.cc
@@ -48,27 +48,52 @@ TEST_F(StyleBuilderTest, WritingModeChangeDirtiesFont) {
}
TEST_F(StyleBuilderTest, TextOrientationChangeDirtiesFont) {
+ const CSSProperty* properties[] = {
+ &GetCSSPropertyTextOrientation(),
+ &GetCSSPropertyWebkitTextOrientation(),
+ };
+
HeapVector<Member<const CSSValue>> values = {
CSSInitialValue::Create(),
CSSInheritedValue::Create(),
CSSIdentifierValue::Create(CSSValueID::kMixed),
};
- for (const CSSValue* value : values) {
- auto parent_style = ComputedStyle::Create();
- auto style = ComputedStyle::Create();
- // This test assumes that initial 'text-orientation' is not 'upright'.
- ASSERT_NE(ETextOrientation::kUpright, style->GetTextOrientation());
- style->SetTextOrientation(ETextOrientation::kUpright);
+ for (const CSSProperty* property : properties) {
+ for (const CSSValue* value : values) {
+ auto parent_style = ComputedStyle::Create();
+ auto style = ComputedStyle::Create();
+ // This test assumes that initial 'text-orientation' is not 'upright'.
+ ASSERT_NE(ETextOrientation::kUpright, style->GetTextOrientation());
+ style->SetTextOrientation(ETextOrientation::kUpright);
- StyleResolverState state(GetDocument(), *GetDocument().body(),
- parent_style.get(), parent_style.get());
- state.SetStyle(style);
+ StyleResolverState state(GetDocument(), *GetDocument().body(),
+ parent_style.get(), parent_style.get());
+ state.SetStyle(style);
- ASSERT_FALSE(state.GetFontBuilder().FontDirty());
- StyleBuilder::ApplyProperty(GetCSSPropertyTextOrientation(), state, *value);
- EXPECT_TRUE(state.GetFontBuilder().FontDirty());
+ ASSERT_FALSE(state.GetFontBuilder().FontDirty());
+ StyleBuilder::ApplyProperty(*property, state, *value);
+ EXPECT_TRUE(state.GetFontBuilder().FontDirty());
+ }
}
}
+TEST_F(StyleBuilderTest, HasExplicitInheritance) {
+ auto parent_style = ComputedStyle::Create();
+ auto style = ComputedStyle::Create();
+ StyleResolverState state(GetDocument(), *GetDocument().body(),
+ parent_style.get(), parent_style.get());
+ state.SetStyle(style);
+ EXPECT_FALSE(style->HasExplicitInheritance());
+
+ // Flag should not be set for properties which are inherited.
+ StyleBuilder::ApplyProperty(GetCSSPropertyColor(), state,
+ *CSSInheritedValue::Create());
+ EXPECT_FALSE(style->HasExplicitInheritance());
+
+ StyleBuilder::ApplyProperty(GetCSSPropertyBackgroundColor(), state,
+ *CSSInheritedValue::Create());
+ EXPECT_TRUE(style->HasExplicitInheritance());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_cascade.cc b/chromium/third_party/blink/renderer/core/css/resolver/style_cascade.cc
index 5254cf5a5d1..91ac5f018a1 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_cascade.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_cascade.cc
@@ -154,12 +154,11 @@ void StyleCascade::Apply(CascadeFilter filter) {
ApplyMatchResult(resolver);
ApplyInterpolations(resolver);
- if (map_.Find(CSSPropertyName(CSSPropertyID::kAppearance)) &&
- !resolver.filter_.Rejects(GetCSSPropertyAppearance()) &&
- state_.Style()->HasAppearance()) {
- CSSProperty::Flags flags = resolver.AuthorFlags();
- state_.Style()->SetHasAuthorBackground(flags & CSSProperty::kBackground);
- state_.Style()->SetHasAuthorBorder(flags & CSSProperty::kBorder);
+ if (state_.Style()->HasAppearance()) {
+ if (resolver.AuthorFlags() & CSSProperty::kBackground)
+ state_.Style()->SetHasAuthorBackground(true);
+ if (resolver.AuthorFlags() & CSSProperty::kBorder)
+ state_.Style()->SetHasAuthorBorder(true);
}
}
@@ -268,11 +267,18 @@ void StyleCascade::ApplyCascadeAffecting(CascadeResolver& resolver) {
LookupAndApply(GetCSSPropertyDirection(), resolver);
LookupAndApply(GetCSSPropertyWritingMode(), resolver);
-
- if (depends_on_cascade_affecting_property_ &&
- (direction != state_.Style()->Direction() ||
- writing_mode != state_.Style()->GetWritingMode())) {
- Reanalyze();
+ LookupAndApply(GetCSSPropertyForcedColorAdjust(), resolver);
+
+ if (depends_on_cascade_affecting_property_) {
+ // We could avoid marking these if this cascade provided a value, but
+ // marking them unconditionally keeps it simple. See also note about
+ // over-marking in StyleResolverState::Dependencies.
+ MarkDependency(GetCSSPropertyDirection());
+ MarkDependency(GetCSSPropertyWritingMode());
+ if (direction != state_.Style()->Direction() ||
+ writing_mode != state_.Style()->GetWritingMode()) {
+ Reanalyze();
+ }
}
}
@@ -293,17 +299,6 @@ void StyleCascade::ApplyHighPriority(CascadeResolver& resolver) {
state_.SetConversionFontSizes(CSSToLengthConversionData::FontSizes(
state_.Style(), state_.RootElementStyle()));
state_.SetConversionZoom(state_.Style()->EffectiveZoom());
-
- // Force color-scheme sensitive initial color for the document element,
- // if no value is present in the cascade.
- //
- // TODO(crbug.com/1046753): This should be unnecessary when canvastext is
- // supported.
- uint64_t color_bit = 1ull << static_cast<uint64_t>(CSSPropertyID::kColor);
- if (~bits & color_bit) {
- if (state_.GetElement() == GetDocument().documentElement())
- state_.Style()->SetColor(state_.Style()->InitialColorForColorScheme());
- }
}
void StyleCascade::ApplyWebkitBorderImage(CascadeResolver& resolver) {
@@ -375,8 +370,6 @@ void StyleCascade::ApplyInterpolationMap(const ActiveInterpolationsMap& map,
CascadePriority* p = map_.Find(property.GetCSSPropertyName());
if (!p || *p >= priority) {
- if (p->IsImportant())
- state_.SetHasImportantOverrides();
continue;
}
*p = priority;
@@ -414,7 +407,6 @@ void StyleCascade::ApplyInterpolation(
map_.Find(visited->GetCSSPropertyName());
if (visited_priority && priority < *visited_priority) {
DCHECK(visited_priority->IsImportant());
- state_.SetHasImportantOverrides();
// Resetting generation to zero makes it possible to apply the
// visited property again.
*visited_priority = CascadePriority(*visited_priority, 0);
@@ -435,7 +427,7 @@ void StyleCascade::LookupAndApply(const CSSProperty& property,
DCHECK(!property.IsSurrogate());
CSSPropertyName name = property.GetCSSPropertyName();
- DCHECK(!resolver.IsLocked(name));
+ DCHECK(!resolver.IsLocked(property));
CascadePriority* p = map_.Find(name);
if (!p)
@@ -537,12 +529,24 @@ StyleCascade::TokenSequence::BuildVariableData() {
has_font_units_, has_root_font_units_, absolutized, base_url_, charset_);
}
+bool StyleCascade::ShouldRevert(const CSSProperty& property,
+ const CSSValue& value,
+ CascadeOrigin origin) {
+ return value.IsRevertValue() ||
+ (state_.GetDocument().InForcedColorsMode() &&
+ state_.Style()->ForcedColorAdjust() != EForcedColorAdjust::kNone &&
+ property.IsAffectedByForcedColors() &&
+ !(property.PropertyID() == CSSPropertyID::kBackgroundImage &&
+ value.MayContainUrl()) &&
+ origin >= CascadeOrigin::kAuthor);
+}
+
const CSSValue* StyleCascade::Resolve(const CSSProperty& property,
const CSSValue& value,
CascadeOrigin origin,
CascadeResolver& resolver) {
DCHECK(!property.IsSurrogate());
- if (value.IsRevertValue())
+ if (ShouldRevert(property, value, origin))
return ResolveRevert(property, origin, resolver);
resolver.CollectAuthorFlags(property, origin);
if (const auto* v = DynamicTo<CSSCustomPropertyDeclaration>(value))
@@ -752,7 +756,8 @@ bool StyleCascade::ResolveVarInto(CSSParserTokenRange range,
// Any custom property referenced (by anything, even just once) in the
// document can currently not be animated on the compositor. Hence we mark
// properties that have been referenced.
- MarkIsReferenced(property);
+ DCHECK(resolver.CurrentProperty());
+ MarkIsReferenced(*resolver.CurrentProperty(), property);
if (!resolver.DetectCycle(property)) {
// We are about to substitute var(property). In order to do that, we must
@@ -873,10 +878,16 @@ bool StyleCascade::ValidateFallback(const CustomProperty& property,
return property.ParseSingleValue(range, *context, local_context);
}
-void StyleCascade::MarkIsReferenced(const CustomProperty& property) {
- if (!property.IsRegistered())
+void StyleCascade::MarkIsReferenced(const CSSProperty& referencer,
+ const CustomProperty& referenced) {
+ // For simplicity, we mark all inherited custom property references as
+ // dependencies, even though it might not be a dependency if this cascade
+ // defines a value for that property.
+ if (!referencer.IsInherited() && referenced.IsInherited())
+ MarkDependency(referenced);
+ if (!referenced.IsRegistered())
return;
- const AtomicString& name = property.GetPropertyNameAtomicString();
+ const AtomicString& name = referenced.GetPropertyNameAtomicString();
state_.GetDocument().EnsurePropertyRegistry().MarkReferenced(name);
}
@@ -886,6 +897,10 @@ void StyleCascade::MarkHasVariableReference(const CSSProperty& property) {
state_.Style()->SetHasVariableReference();
}
+void StyleCascade::MarkDependency(const CSSProperty& property) {
+ state_.MarkDependency(property);
+}
+
const Document& StyleCascade::GetDocument() const {
return state_.GetDocument();
}
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_cascade.h b/chromium/third_party/blink/renderer/core/css/resolver/style_cascade.h
index 66636e27dad..6fa26a4247e 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_cascade.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_cascade.h
@@ -305,14 +305,24 @@ class CORE_EXPORT StyleCascade {
bool ValidateFallback(const CustomProperty&, CSSParserTokenRange) const;
// Marks the CustomProperty as referenced by something. Needed to avoid
// animating these custom properties on the compositor.
- void MarkIsReferenced(const CustomProperty&);
+ void MarkIsReferenced(const CSSProperty& referencer,
+ const CustomProperty& referenced);
// Marks a CSSProperty as having a reference to a custom property. Needed to
// disable the matched property cache in some cases.
void MarkHasVariableReference(const CSSProperty&);
+ // The resulting ComputedStyle may depend on values from the parent style,
+ // for example, explicit inheritance or var() references means we hold a
+ // dependency on the relevant property. We maintain a set of these
+ // dependencies on StyleResolverState, which is later used by the
+ // MatchedPropertiesCache to figure out if a given cache lookup is a hit or a
+ // miss.
+ void MarkDependency(const CSSProperty&);
const Document& GetDocument() const;
const CSSProperty& ResolveSurrogate(const CSSProperty& surrogate);
+ bool ShouldRevert(const CSSProperty&, const CSSValue&, CascadeOrigin);
+
StyleResolverState& state_;
MatchResult match_result_;
CascadeInterpolations interpolations_;
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
index 9d8bbcdf9bd..9e6d48dfb68 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/animation/css/css_animations.h"
#include "third_party/blink/renderer/core/css/active_style_sheets.h"
#include "third_party/blink/renderer/core/css/css_custom_property_declaration.h"
+#include "third_party/blink/renderer/core/css/css_initial_color_value.h"
#include "third_party/blink/renderer/core/css/css_pending_substitution_value.h"
#include "third_party/blink/renderer/core/css/css_primitive_value.h"
#include "third_party/blink/renderer/core/css/css_test_helpers.h"
@@ -38,6 +39,7 @@
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
+#include "third_party/blink/renderer/core/testing/color_scheme_helper.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -54,13 +56,10 @@ class TestCascadeResolver {
STACK_ALLOCATED();
public:
- explicit TestCascadeResolver(Document& document, uint8_t generation = 0)
- : document_(document), resolver_(CascadeFilter(), generation) {}
+ explicit TestCascadeResolver(uint8_t generation = 0)
+ : resolver_(CascadeFilter(), generation) {}
bool InCycle() const { return resolver_.InCycle(); }
- bool DetectCycle(String name) {
- CSSPropertyRef ref(name, document_);
- DCHECK(ref.IsValid());
- const CSSProperty& property = ref.GetProperty();
+ bool DetectCycle(const CSSProperty& property) {
return resolver_.DetectCycle(property);
}
wtf_size_t CycleDepth() const { return resolver_.cycle_depth_; }
@@ -72,11 +71,13 @@ class TestCascadeResolver {
}
uint8_t GetGeneration() { return resolver_.generation_; }
CascadeResolver& InnerResolver() { return resolver_; }
+ const CSSProperty* CurrentProperty() const {
+ return resolver_.CurrentProperty();
+ }
private:
friend class TestCascadeAutoLock;
- Document& document_;
CascadeResolver resolver_;
};
@@ -130,7 +131,7 @@ class TestCascade {
void ApplySingle(const CSSProperty& property) {
EnsureAtLeast(CascadeOrigin::kAuthor);
cascade_.AnalyzeIfNeeded();
- TestCascadeResolver resolver(GetDocument(), ++cascade_.generation_);
+ TestCascadeResolver resolver(++cascade_.generation_);
cascade_.LookupAndApply(property, resolver.InnerResolver());
}
@@ -259,20 +260,24 @@ class TestCascadeAutoLock {
STACK_ALLOCATED();
public:
- TestCascadeAutoLock(const CSSPropertyName& name,
+ TestCascadeAutoLock(const CSSProperty& property,
TestCascadeResolver& resolver)
- : lock_(name, resolver.resolver_) {}
+ : lock_(property, resolver.resolver_) {}
private:
CascadeResolver::AutoLock lock_;
};
-class StyleCascadeTest : public PageTestBase,
- private ScopedCSSCascadeForTest,
- private ScopedCSSRevertForTest {
+class StyleCascadeTest
+ : public PageTestBase,
+ private ScopedCSSCascadeForTest,
+ private ScopedCSSRevertForTest,
+ private ScopedCSSMatchedPropertiesCacheDependenciesForTest {
public:
StyleCascadeTest()
- : ScopedCSSCascadeForTest(true), ScopedCSSRevertForTest(true) {}
+ : ScopedCSSCascadeForTest(true),
+ ScopedCSSRevertForTest(true),
+ ScopedCSSMatchedPropertiesCacheDependenciesForTest(true) {}
CSSStyleSheet* CreateSheet(const String& css_text) {
auto* init = MakeGarbageCollected<CSSStyleSheetInit>();
@@ -280,8 +285,8 @@ class StyleCascadeTest : public PageTestBase,
CSSStyleSheet* sheet =
CSSStyleSheet::Create(GetDocument(), init, exception_state);
sheet->replaceSync(css_text, exception_state);
- sheet->Contents()->EnsureRuleSet(MediaQueryEvaluator(),
- kRuleHasNoSpecialState);
+ sheet->Contents()->EnsureRuleSet(
+ MediaQueryEvaluator(GetDocument().GetFrame()), kRuleHasNoSpecialState);
return sheet;
}
@@ -338,6 +343,10 @@ class StyleCascadeTest : public PageTestBase,
Document* document_;
AtomicString name_;
};
+
+ CSSPropertyName PropertyName(String name) {
+ return *CSSPropertyName::From(GetDocument().GetExecutionContext(), name);
+ }
};
TEST_F(StyleCascadeTest, ApplySingle) {
@@ -617,21 +626,45 @@ TEST_F(StyleCascadeTest, PendingSubstitutionInLogicalShorthand) {
EXPECT_EQ("10px", cascade.ComputedValue("margin-right"));
}
+TEST_F(StyleCascadeTest, DetectCycleByName) {
+ TestCascade cascade(GetDocument());
+ TestCascadeResolver resolver;
+
+ // Two different CustomProperty instances with the same name:
+ CustomProperty a1("--a", GetDocument());
+ CustomProperty a2("--a", GetDocument());
+
+ {
+ TestCascadeAutoLock lock(a1, resolver);
+ EXPECT_FALSE(resolver.InCycle());
+
+ // This should still be detected as a cycle, even though it's not the same
+ // CustomProperty instance.
+ EXPECT_TRUE(resolver.DetectCycle(a2));
+ EXPECT_TRUE(resolver.InCycle());
+ }
+ EXPECT_FALSE(resolver.InCycle());
+}
+
TEST_F(StyleCascadeTest, ResolverDetectCycle) {
TestCascade cascade(GetDocument());
- TestCascadeResolver resolver(GetDocument());
+ TestCascadeResolver resolver;
+
+ CustomProperty a("--a", GetDocument());
+ CustomProperty b("--b", GetDocument());
+ CustomProperty c("--c", GetDocument());
{
- TestCascadeAutoLock lock(CSSPropertyName("--a"), resolver);
+ TestCascadeAutoLock lock(a, resolver);
EXPECT_FALSE(resolver.InCycle());
{
- TestCascadeAutoLock lock(CSSPropertyName("--b"), resolver);
+ TestCascadeAutoLock lock(b, resolver);
EXPECT_FALSE(resolver.InCycle());
{
- TestCascadeAutoLock lock(CSSPropertyName("--c"), resolver);
+ TestCascadeAutoLock lock(c, resolver);
EXPECT_FALSE(resolver.InCycle());
- EXPECT_TRUE(resolver.DetectCycle("--a"));
+ EXPECT_TRUE(resolver.DetectCycle(a));
EXPECT_TRUE(resolver.InCycle());
}
EXPECT_TRUE(resolver.InCycle());
@@ -643,19 +676,24 @@ TEST_F(StyleCascadeTest, ResolverDetectCycle) {
TEST_F(StyleCascadeTest, ResolverDetectNoCycle) {
TestCascade cascade(GetDocument());
- TestCascadeResolver resolver(GetDocument());
+ TestCascadeResolver resolver;
+
+ CustomProperty a("--a", GetDocument());
+ CustomProperty b("--b", GetDocument());
+ CustomProperty c("--c", GetDocument());
+ CustomProperty x("--x", GetDocument());
{
- TestCascadeAutoLock lock(CSSPropertyName("--a"), resolver);
+ TestCascadeAutoLock lock(a, resolver);
EXPECT_FALSE(resolver.InCycle());
{
- TestCascadeAutoLock lock(CSSPropertyName("--b"), resolver);
+ TestCascadeAutoLock lock(b, resolver);
EXPECT_FALSE(resolver.InCycle());
{
- TestCascadeAutoLock lock(CSSPropertyName("--c"), resolver);
+ TestCascadeAutoLock lock(c, resolver);
EXPECT_FALSE(resolver.InCycle());
- EXPECT_FALSE(resolver.DetectCycle("--x"));
+ EXPECT_FALSE(resolver.DetectCycle(x));
EXPECT_FALSE(resolver.InCycle());
}
EXPECT_FALSE(resolver.InCycle());
@@ -667,13 +705,15 @@ TEST_F(StyleCascadeTest, ResolverDetectNoCycle) {
TEST_F(StyleCascadeTest, ResolverDetectCycleSelf) {
TestCascade cascade(GetDocument());
- TestCascadeResolver resolver(GetDocument());
+ TestCascadeResolver resolver;
+
+ CustomProperty a("--a", GetDocument());
{
- TestCascadeAutoLock lock(CSSPropertyName("--a"), resolver);
+ TestCascadeAutoLock lock(a, resolver);
EXPECT_FALSE(resolver.InCycle());
- EXPECT_TRUE(resolver.DetectCycle("--a"));
+ EXPECT_TRUE(resolver.DetectCycle(a));
EXPECT_TRUE(resolver.InCycle());
}
EXPECT_FALSE(resolver.InCycle());
@@ -683,28 +723,33 @@ TEST_F(StyleCascadeTest, ResolverDetectMultiCycle) {
using AutoLock = TestCascadeAutoLock;
TestCascade cascade(GetDocument());
- TestCascadeResolver resolver(GetDocument());
+ TestCascadeResolver resolver;
+
+ CustomProperty a("--a", GetDocument());
+ CustomProperty b("--b", GetDocument());
+ CustomProperty c("--c", GetDocument());
+ CustomProperty d("--d", GetDocument());
{
- AutoLock lock(CSSPropertyName("--a"), resolver);
+ AutoLock lock(a, resolver);
EXPECT_FALSE(resolver.InCycle());
{
- AutoLock lock(CSSPropertyName("--b"), resolver);
+ AutoLock lock(b, resolver);
EXPECT_FALSE(resolver.InCycle());
{
- AutoLock lock(CSSPropertyName("--c"), resolver);
+ AutoLock lock(c, resolver);
EXPECT_FALSE(resolver.InCycle());
{
- AutoLock lock(CSSPropertyName("--d"), resolver);
+ AutoLock lock(d, resolver);
EXPECT_FALSE(resolver.InCycle());
// Cycle 1 (big cycle):
- EXPECT_TRUE(resolver.DetectCycle("--b"));
+ EXPECT_TRUE(resolver.DetectCycle(b));
EXPECT_TRUE(resolver.InCycle());
EXPECT_EQ(1u, resolver.CycleDepth());
// Cycle 2 (small cycle):
- EXPECT_TRUE(resolver.DetectCycle("--c"));
+ EXPECT_TRUE(resolver.DetectCycle(c));
EXPECT_TRUE(resolver.InCycle());
EXPECT_EQ(1u, resolver.CycleDepth());
}
@@ -720,28 +765,33 @@ TEST_F(StyleCascadeTest, ResolverDetectMultiCycleReverse) {
using AutoLock = TestCascadeAutoLock;
TestCascade cascade(GetDocument());
- TestCascadeResolver resolver(GetDocument());
+ TestCascadeResolver resolver;
+
+ CustomProperty a("--a", GetDocument());
+ CustomProperty b("--b", GetDocument());
+ CustomProperty c("--c", GetDocument());
+ CustomProperty d("--d", GetDocument());
{
- AutoLock lock(CSSPropertyName("--a"), resolver);
+ AutoLock lock(a, resolver);
EXPECT_FALSE(resolver.InCycle());
{
- AutoLock lock(CSSPropertyName("--b"), resolver);
+ AutoLock lock(b, resolver);
EXPECT_FALSE(resolver.InCycle());
{
- AutoLock lock(CSSPropertyName("--c"), resolver);
+ AutoLock lock(c, resolver);
EXPECT_FALSE(resolver.InCycle());
{
- AutoLock lock(CSSPropertyName("--d"), resolver);
+ AutoLock lock(d, resolver);
EXPECT_FALSE(resolver.InCycle());
// Cycle 1 (small cycle):
- EXPECT_TRUE(resolver.DetectCycle("--c"));
+ EXPECT_TRUE(resolver.DetectCycle(c));
EXPECT_TRUE(resolver.InCycle());
EXPECT_EQ(2u, resolver.CycleDepth());
// Cycle 2 (big cycle):
- EXPECT_TRUE(resolver.DetectCycle("--b"));
+ EXPECT_TRUE(resolver.DetectCycle(b));
EXPECT_TRUE(resolver.InCycle());
EXPECT_EQ(1u, resolver.CycleDepth());
}
@@ -754,7 +804,7 @@ TEST_F(StyleCascadeTest, ResolverDetectMultiCycleReverse) {
}
TEST_F(StyleCascadeTest, ResolverMarkApplied) {
- TestCascadeResolver resolver(GetDocument(), 2);
+ TestCascadeResolver resolver(2);
CascadePriority priority(CascadeOrigin::kAuthor);
EXPECT_EQ(0, priority.GetGeneration());
@@ -767,8 +817,36 @@ TEST_F(StyleCascadeTest, ResolverMarkApplied) {
EXPECT_EQ(2, priority.GetGeneration());
}
+TEST_F(StyleCascadeTest, CurrentProperty) {
+ using AutoLock = TestCascadeAutoLock;
+
+ TestCascade cascade(GetDocument());
+ TestCascadeResolver resolver;
+
+ CustomProperty a("--a", GetDocument());
+ CustomProperty b("--b", GetDocument());
+ CustomProperty c("--c", GetDocument());
+
+ EXPECT_FALSE(resolver.CurrentProperty());
+ {
+ AutoLock lock(a, resolver);
+ EXPECT_EQ(&a, resolver.CurrentProperty());
+ {
+ AutoLock lock(b, resolver);
+ EXPECT_EQ(&b, resolver.CurrentProperty());
+ {
+ AutoLock lock(c, resolver);
+ EXPECT_EQ(&c, resolver.CurrentProperty());
+ }
+ EXPECT_EQ(&b, resolver.CurrentProperty());
+ }
+ EXPECT_EQ(&a, resolver.CurrentProperty());
+ }
+ EXPECT_FALSE(resolver.CurrentProperty());
+}
+
TEST_F(StyleCascadeTest, ResolverMarkUnapplied) {
- TestCascadeResolver resolver(GetDocument(), 7);
+ TestCascadeResolver resolver(7);
CascadePriority priority(CascadeOrigin::kAuthor);
EXPECT_EQ(0, priority.GetGeneration());
@@ -2603,6 +2681,37 @@ TEST_F(StyleCascadeTest, RubyPositionSurrogateCanCascadeAsOriginal) {
}
}
+TEST_F(StyleCascadeTest, TextOrientationPriority) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("text-orientation:upright !important");
+ cascade.Add("-webkit-text-orientation:sideways");
+ cascade.Apply();
+
+ EXPECT_EQ("upright", cascade.ComputedValue("text-orientation"));
+ EXPECT_EQ("upright", cascade.ComputedValue("-webkit-text-orientation"));
+}
+
+TEST_F(StyleCascadeTest, TextOrientationRevert) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("text-orientation:upright", CascadeOrigin::kUserAgent);
+ cascade.Add("-webkit-text-orientation:mixed");
+ cascade.Add("-webkit-text-orientation:revert");
+ cascade.Apply();
+
+ EXPECT_EQ("upright", cascade.ComputedValue("text-orientation"));
+ EXPECT_EQ("upright", cascade.ComputedValue("-webkit-text-orientation"));
+}
+
+TEST_F(StyleCascadeTest, TextOrientationLegacyKeyword) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("-webkit-text-orientation:vertical-right");
+ cascade.Apply();
+
+ EXPECT_EQ("mixed", cascade.ComputedValue("text-orientation"));
+ EXPECT_EQ("vertical-right",
+ cascade.ComputedValue("-webkit-text-orientation"));
+}
+
TEST_F(StyleCascadeTest, WebkitBorderImageCascadeOrder) {
String gradient1("linear-gradient(rgb(0, 0, 0), rgb(0, 128, 0))");
String gradient2("linear-gradient(rgb(0, 0, 0), rgb(0, 200, 0))");
@@ -3114,4 +3223,120 @@ TEST_F(StyleCascadeTest, GetImportantSetMany) {
*cascade.GetImportantSet());
}
+TEST_F(StyleCascadeTest, NoDependenciesPresent) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("left:2px");
+ cascade.Add("top:initial");
+ cascade.Add("border:1px solid black");
+ cascade.Add("--x:bar");
+ cascade.Add("direction:rtl");
+ cascade.Apply();
+ const auto& state = cascade.State();
+ EXPECT_TRUE(state.Dependencies().IsEmpty());
+ EXPECT_FALSE(state.HasIncomparableDependency());
+}
+
+TEST_F(StyleCascadeTest, ExplicitInheritanceDependencyIsDetected) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("left:inherit");
+ cascade.Add("right:inherit");
+ cascade.Apply();
+ const auto& state = cascade.State();
+ EXPECT_EQ(2u, state.Dependencies().size());
+ EXPECT_TRUE(state.Dependencies().Contains(PropertyName("left")));
+ EXPECT_TRUE(state.Dependencies().Contains(PropertyName("right")));
+ EXPECT_FALSE(state.HasIncomparableDependency());
+}
+
+TEST_F(StyleCascadeTest, IncomparableDependencyDetected) {
+ ASSERT_FALSE(
+ GetCSSPropertyInternalEmptyLineHeight().IsComputedValueComparable());
+
+ TestCascade cascade(GetDocument());
+ cascade.Add("-internal-empty-line-height:inherit", CascadeOrigin::kUserAgent);
+ cascade.Apply();
+ const auto& state = cascade.State();
+ EXPECT_EQ(1u, state.Dependencies().size());
+ EXPECT_TRUE(state.Dependencies().Contains(
+ CSSPropertyName(CSSPropertyID::kInternalEmptyLineHeight)));
+ EXPECT_TRUE(state.HasIncomparableDependency());
+}
+
+TEST_F(StyleCascadeTest, CustomPropertyDependencyIsDetected) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("left:var(--x,1px)");
+ cascade.Add("right:var(--x,2px)");
+ cascade.Apply();
+ const auto& state = cascade.State();
+ EXPECT_EQ(1u, state.Dependencies().size());
+ EXPECT_TRUE(state.Dependencies().Contains(PropertyName("--x")));
+ EXPECT_FALSE(state.HasIncomparableDependency());
+}
+
+TEST_F(StyleCascadeTest, NonInheritedCustomPropertyIsNoDependency) {
+ RegisterProperty(GetDocument(), "--x", "<length>", "0px", false);
+ TestCascade cascade(GetDocument());
+ cascade.Add("left:var(--x,1px)");
+ cascade.Add("right:var(--x,2px)");
+ cascade.Apply();
+ const auto& state = cascade.State();
+ EXPECT_EQ(0u, state.Dependencies().size());
+}
+
+TEST_F(StyleCascadeTest, DirectionAndWritingModeDependenciesAreDetected) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("margin-inline-start: 2px");
+ cascade.Apply();
+ const auto& state = cascade.State();
+ EXPECT_EQ(2u, state.Dependencies().size());
+ EXPECT_TRUE(state.Dependencies().Contains(PropertyName("direction")));
+ EXPECT_TRUE(state.Dependencies().Contains(PropertyName("writing-mode")));
+ EXPECT_FALSE(state.HasIncomparableDependency());
+}
+
+TEST_F(StyleCascadeTest, RootColorNotModifiedByEmptyCascade) {
+ TestCascade cascade(GetDocument(), GetDocument().documentElement());
+ cascade.Add("color:red");
+ cascade.Apply();
+
+ cascade.Reset();
+ cascade.Add("display:block");
+ cascade.Apply(); // Should not affect 'color'.
+
+ auto style = cascade.TakeStyle();
+
+ style->SetInsideLink(EInsideLink::kInsideVisitedLink);
+ EXPECT_EQ(Color(255, 0, 0),
+ style->VisitedDependentColor(GetCSSPropertyColor()));
+
+ style->SetInsideLink(EInsideLink::kNotInsideLink);
+ EXPECT_EQ(Color(255, 0, 0),
+ style->VisitedDependentColor(GetCSSPropertyColor()));
+}
+
+TEST_F(StyleCascadeTest, InitialColor) {
+ ColorSchemeHelper color_scheme_helper(GetDocument());
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
+
+ TestCascade cascade(GetDocument(), GetDocument().documentElement());
+ cascade.Add("color-scheme:dark");
+
+ // CSSInitialColorValue is not reachable via a string, hence we must
+ // create the CSSPropertyValueSet that contains it manually.
+ auto* set =
+ MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLStandardMode);
+ set->SetProperty(CSSPropertyID::kColor, *CSSInitialColorValue::Create());
+ cascade.Add(set);
+
+ cascade.Apply();
+
+ auto style = cascade.TakeStyle();
+
+ style->SetInsideLink(EInsideLink::kInsideVisitedLink);
+ EXPECT_EQ(Color::kWhite, style->VisitedDependentColor(GetCSSPropertyColor()));
+
+ style->SetInsideLink(EInsideLink::kNotInsideLink);
+ EXPECT_EQ(Color::kWhite, style->VisitedDependentColor(GetCSSPropertyColor()));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/chromium/third_party/blink/renderer/core/css/resolver/style_resolver.cc
index 29f5ff72d0c..f943580c515 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_resolver.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -43,6 +43,7 @@
#include "third_party/blink/renderer/core/css/css_default_style_sheets.h"
#include "third_party/blink/renderer/core/css/css_font_selector.h"
#include "third_party/blink/renderer/core/css/css_identifier_value.h"
+#include "third_party/blink/renderer/core/css/css_initial_color_value.h"
#include "third_party/blink/renderer/core/css/css_keyframe_rule.h"
#include "third_party/blink/renderer/core/css/css_keyframes_rule.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
@@ -205,24 +206,15 @@ static CSSPropertyValueSet* RightToLeftDeclaration() {
return right_to_left_decl;
}
-static CSSPropertyValueSet* MarkerUserAgentDeclarations() {
+static CSSPropertyValueSet* DocumentElementUserAgentDeclarations() {
DEFINE_STATIC_LOCAL(
- Persistent<MutableCSSPropertyValueSet>, marker_ua_decl,
- (MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode)));
- if (marker_ua_decl->IsEmpty()) {
- // Set 'unicode-bidi: isolate'
- marker_ua_decl->SetProperty(
- CSSPropertyID::kUnicodeBidi,
- *CSSIdentifierValue::Create(CSSValueID::kIsolate));
-
- // Set 'font-variant-numeric: tabular-nums'
- CSSValueList* variant_numeric = CSSValueList::CreateSpaceSeparated();
- variant_numeric->Append(
- *CSSIdentifierValue::Create(CSSValueID::kTabularNums));
- marker_ua_decl->SetProperty(CSSPropertyID::kFontVariantNumeric,
- *variant_numeric);
+ Persistent<MutableCSSPropertyValueSet>, document_element_ua_decl,
+ (MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLStandardMode)));
+ if (document_element_ua_decl->IsEmpty()) {
+ document_element_ua_decl->SetProperty(CSSPropertyID::kColor,
+ *CSSInitialColorValue::Create());
}
- return marker_ua_decl;
+ return document_element_ua_decl;
}
static void CollectScopedResolversForHostedShadowTrees(
@@ -658,6 +650,12 @@ void StyleResolver::MatchUARules(const Element& element,
if (IsForcedColorsModeEnabled())
MatchRuleSet(collector, default_style_sheets.DefaultForcedColorStyle());
+ if (collector.IsCollectingForPseudoElement()) {
+ if (RuleSet* default_pseudo_style =
+ default_style_sheets.DefaultPseudoElementStyleOrNull())
+ MatchRuleSet(collector, default_pseudo_style);
+ }
+
collector.FinishAddingUARules();
collector.SetMatchingUARules(false);
}
@@ -769,7 +767,7 @@ scoped_refptr<ComputedStyle> StyleResolver::StyleForViewport(
InitialStyleForElement(document);
viewport_style->SetZIndex(0);
- viewport_style->SetIsStackingContext(true);
+ viewport_style->SetIsStackingContextWithoutContainment(true);
viewport_style->SetDisplay(EDisplay::kBlock);
viewport_style->SetPosition(EPosition::kAbsolute);
@@ -784,12 +782,8 @@ scoped_refptr<ComputedStyle> StyleResolver::StyleForViewport(
return viewport_style;
}
-// Start loading resources referenced by this style.
-void StyleResolver::LoadPendingResources(StyleResolverState& state) {
- state.GetElementStyleResources().LoadPendingResources(state.Style());
-}
-
-static ElementAnimations* GetElementAnimations(StyleResolverState& state) {
+static ElementAnimations* GetElementAnimations(
+ const StyleResolverState& state) {
if (!state.GetAnimatingElement())
return nullptr;
return state.GetAnimatingElement()->GetElementAnimations();
@@ -797,70 +791,35 @@ static ElementAnimations* GetElementAnimations(StyleResolverState& state) {
static const ComputedStyle* CachedAnimationBaseComputedStyle(
StyleResolverState& state) {
- ElementAnimations* element_animations = GetElementAnimations(state);
- if (!element_animations)
- return nullptr;
-
- if (CSSAnimations::IsAnimatingCustomProperties(element_animations)) {
- state.SetIsAnimatingCustomProperties(true);
- // TODO(alancutter): Use the base computed style optimisation in the
- // presence of custom property animations that don't affect pre-animated
- // computed values.
- return nullptr;
- }
-
- if (CSSAnimations::IsAnimatingRevert(element_animations)) {
- state.SetIsAnimatingRevert(true);
+ if (!RuntimeEnabledFeatures::CSSCascadeEnabled())
return nullptr;
- }
-
- if (CSSAnimations::IsAnimatingFontAffectingProperties(element_animations)) {
- state.SetHasFontAffectingAnimation();
- if (element_animations->BaseComputedStyle() &&
- element_animations->BaseComputedStyle()->HasFontRelativeUnits()) {
- return nullptr;
- }
- }
-
- if (CSSAnimations::IsAnimatingStandardProperties(
- element_animations, element_animations->BaseImportantSet(),
- KeyframeEffect::kDefaultPriority)) {
- state.SetHasImportantOverrides();
- return nullptr;
- }
-
- return element_animations->BaseComputedStyle();
+ ElementAnimations* element_animations = GetElementAnimations(state);
+ return element_animations ? element_animations->BaseComputedStyle() : nullptr;
}
static void UpdateAnimationBaseComputedStyle(StyleResolverState& state,
- StyleCascade* cascade) {
+ StyleCascade* cascade,
+ bool forced_update) {
if (!state.GetAnimatingElement())
return;
+ if (forced_update)
+ state.GetAnimatingElement()->EnsureElementAnimations();
+
ElementAnimations* element_animations =
state.GetAnimatingElement()->GetElementAnimations();
- if (element_animations) {
- std::unique_ptr<CSSBitset> important_set;
- if (!element_animations->BaseComputedStyle()) {
- important_set = (cascade ? cascade->GetImportantSet() : nullptr);
- if (CSSAnimations::IsAnimatingStandardProperties(
- element_animations, important_set.get(),
- KeyframeEffect::kDefaultPriority)) {
- state.SetHasImportantOverrides();
- }
- }
+ if (!element_animations)
+ return;
- if (!element_animations->IsAnimationStyleChange() ||
- state.IsAnimatingCustomProperties() || state.IsAnimatingRevert() ||
- state.HasImportantOverrides() ||
- (state.HasFontAffectingAnimation() &&
- state.Style()->HasFontRelativeUnits())) {
- element_animations->ClearBaseComputedStyle();
- } else {
- element_animations->UpdateBaseComputedStyle(state.Style(),
- std::move(important_set));
- }
+ if (element_animations->IsAnimationStyleChange() &&
+ element_animations->BaseComputedStyle()) {
+ return;
}
+
+ std::unique_ptr<CSSBitset> important_set =
+ (cascade ? cascade->GetImportantSet() : nullptr);
+ element_animations->UpdateBaseComputedStyle(state.Style(),
+ std::move(important_set));
}
scoped_refptr<ComputedStyle> StyleResolver::StyleForElement(
@@ -915,6 +874,8 @@ scoped_refptr<ComputedStyle> StyleResolver::StyleForElement(
if (state.Style()->HasGlyphRelativeUnits())
UseCounter::Count(GetDocument(), WebFeature::kHasGlyphRelativeUnits);
+ state.LoadPendingResources();
+
// Now return the style.
return state.TakeStyle();
}
@@ -974,16 +935,27 @@ void StyleResolver::ApplyBaseComputedStyle(
MatchResult& match_result,
RuleMatchingBehavior matching_behavior,
bool can_cache_animation_base_computed_style) {
+ bool base_is_usable = can_cache_animation_base_computed_style &&
+ CanReuseBaseComputedStyle(state);
const ComputedStyle* animation_base_computed_style =
- can_cache_animation_base_computed_style
- ? CachedAnimationBaseComputedStyle(state)
- : nullptr;
-
+ base_is_usable ? CachedAnimationBaseComputedStyle(state) : nullptr;
if (ShouldComputeBaseComputedStyle(animation_base_computed_style)) {
InitStyleAndApplyInheritance(*element, state);
GetDocument().GetStyleEngine().EnsureUAStyleForElement(*element);
+ // This adds a CSSInitialColorValue to the cascade for the document
+ // element. The CSSInitialColorValue will resolve to a color-scheme
+ // sensitive color in Color::ApplyValue. It is added at the start of the
+ // MatchResult such that subsequent declarations (even from the UA sheet)
+ // get a higher priority.
+ //
+ // TODO(crbug.com/1046753): Remove this when canvastext is supported.
+ if (element == state.GetDocument().documentElement() && cascade) {
+ cascade->MutableMatchResult().AddMatchedProperties(
+ DocumentElementUserAgentDeclarations());
+ }
+
ElementRuleCollector collector(state.ElementContext(), selector_filter_,
match_result, state.Style(),
state.Style()->InsideLink());
@@ -1038,15 +1010,12 @@ void StyleResolver::ApplyBaseComputedStyle(
StyleAdjuster::AdjustComputedStyle(state, element);
- if (can_cache_animation_base_computed_style) {
- DCHECK(ValidateBaseComputedStyle(animation_base_computed_style,
- *state.Style()));
- if (!animation_base_computed_style)
- UpdateAnimationBaseComputedStyle(state, cascade);
- }
+ DCHECK(ValidateBaseComputedStyle(animation_base_computed_style,
+ *state.Style()));
}
- if (animation_base_computed_style) {
+ if (base_is_usable) {
+ DCHECK(animation_base_computed_style);
state.SetStyle(ComputedStyle::Clone(*animation_base_computed_style));
if (!state.ParentStyle()) {
state.SetParentStyle(InitialStyleForElement(GetDocument()));
@@ -1099,8 +1068,9 @@ bool StyleResolver::PseudoStyleForElementInternal(
SelectorFilterParentScope::EnsureParentStackIsPushed();
+ bool base_is_usable = CanReuseBaseComputedStyle(state);
const ComputedStyle* animation_base_computed_style =
- CachedAnimationBaseComputedStyle(state);
+ base_is_usable ? CachedAnimationBaseComputedStyle(state) : nullptr;
// Since we don't use pseudo-elements in any of our quirk/print
// user agent rules, don't waste time walking those rules.
@@ -1130,17 +1100,12 @@ bool StyleResolver::PseudoStyleForElementInternal(
state.Style()->InsideLink());
collector.SetPseudoElementStyleRequest(pseudo_style_request);
- // The UA sheet is supposed to set some styles to ::marker pseudo-elements,
- // but that would use a slow universal element selector. So instead we apply
- // the styles here as an optimization.
- if (pseudo_style_request.pseudo_id == kPseudoIdMarker) {
- cascade.MutableMatchResult().AddMatchedProperties(
- MarkerUserAgentDeclarations());
- }
+ GetDocument().GetStyleEngine().EnsureUAStyleForPseudoElement(
+ pseudo_style_request.pseudo_id);
+ MatchUARules(state.GetElement(), collector);
// TODO(obrufau): support styling nested pseudo-elements
if (!element.IsPseudoElement()) {
- MatchUARules(state.GetElement(), collector);
MatchUserRules(collector);
MatchAuthorRules(state.GetElement(), collector);
}
@@ -1170,9 +1135,6 @@ bool StyleResolver::PseudoStyleForElementInternal(
DCHECK(ValidateBaseComputedStyle(animation_base_computed_style,
*state.Style()));
-
- if (!animation_base_computed_style)
- UpdateAnimationBaseComputedStyle(state, &cascade);
}
if (animation_base_computed_style) {
@@ -1206,9 +1168,9 @@ scoped_refptr<ComputedStyle> StyleResolver::PseudoStyleForElement(
if (!element)
return nullptr;
- StyleResolverState state(GetDocument(), *element,
- pseudo_style_request.pseudo_id, parent_style,
- parent_layout_object_style);
+ StyleResolverState state(
+ GetDocument(), *element, pseudo_style_request.pseudo_id,
+ pseudo_style_request.type, parent_style, parent_layout_object_style);
if (!PseudoStyleForElementInternal(*element, pseudo_style_request, state)) {
if (pseudo_style_request.type == PseudoElementStyleRequest::kForRenderer)
return nullptr;
@@ -1216,14 +1178,18 @@ scoped_refptr<ComputedStyle> StyleResolver::PseudoStyleForElement(
}
if (PseudoElement* pseudo_element =
- element->GetPseudoElement(pseudo_style_request.pseudo_id))
+ element->GetPseudoElement(pseudo_style_request.pseudo_id)) {
SetAnimationUpdateIfNeeded(state, *pseudo_element);
+ state.LoadPendingResources();
+ }
// Now return the style.
return state.TakeStyle();
}
-scoped_refptr<const ComputedStyle> StyleResolver::StyleForPage(int page_index) {
+scoped_refptr<const ComputedStyle> StyleResolver::StyleForPage(
+ int page_index,
+ const AtomicString& page_name) {
scoped_refptr<const ComputedStyle> initial_style =
InitialStyleForElement(GetDocument());
if (!GetDocument().documentElement())
@@ -1242,7 +1208,7 @@ scoped_refptr<const ComputedStyle> StyleResolver::StyleForPage(int page_index) {
STACK_UNINITIALIZED StyleCascade cascade(state);
- PageRuleCollector collector(root_element_style, page_index,
+ PageRuleCollector collector(root_element_style, page_index, page_name,
cascade.MutableMatchResult());
collector.MatchPageRules(
@@ -1272,8 +1238,6 @@ scoped_refptr<const ComputedStyle> StyleResolver::StyleForPage(int page_index) {
state, result.AllRules(), false, inherited_only, needs_apply_pass);
}
- LoadPendingResources(state);
-
// Now return the style.
return state.TakeStyle();
}
@@ -1380,10 +1344,11 @@ void StyleResolver::CollectPseudoRulesForElement(
unsigned rules_to_include) {
collector.SetPseudoElementStyleRequest(PseudoElementStyleRequest(pseudo_id));
- if (rules_to_include & kUAAndUserCSSRules) {
+ if (rules_to_include & kUACSSRules)
MatchUARules(element, collector);
+
+ if (rules_to_include & kUserCSSRules)
MatchUserRules(collector);
- }
if (rules_to_include & kAuthorCSSRules) {
collector.SetSameOriginOnly(!(rules_to_include & kCrossOriginCSSRules));
@@ -1405,8 +1370,10 @@ bool StyleResolver::ApplyAnimatedStandardProperties(
DCHECK(animating_element == &element || !animating_element ||
animating_element->ParentOrShadowHostElement() == element);
- if (!HasAnimationsOrTransitions(state))
+ if (!HasAnimationsOrTransitions(state)) {
+ UpdateAnimationBaseComputedStyle(state, cascade, false);
return false;
+ }
if (!state.IsAnimationInterpolationMapReady() ||
RuntimeEnabledFeatures::CSSCascadeEnabled()) {
@@ -1423,7 +1390,10 @@ bool StyleResolver::ApplyAnimatedStandardProperties(
CSSAnimations::SnapshotCompositorKeyframes(
element, state.AnimationUpdate(), *state.Style(), state.ParentStyle());
- if (state.AnimationUpdate().IsEmpty())
+ bool has_update = !state.AnimationUpdate().IsEmpty();
+ UpdateAnimationBaseComputedStyle(state, cascade, has_update);
+
+ if (!has_update)
return false;
const ActiveInterpolationsMap& standard_animations =
@@ -1466,7 +1436,7 @@ bool StyleResolver::ApplyAnimatedStandardProperties(
}
// Start loading resources used by animations.
- LoadPendingResources(state);
+ state.LoadPendingResources();
DCHECK(!state.GetFontBuilder().FontDirty());
@@ -1835,9 +1805,18 @@ bool StyleResolver::CacheSuccess::FontChanged(
style.GetFontDescription();
}
-bool StyleResolver::CacheSuccess::EffectiveZoomOrFontChanged(
+bool StyleResolver::CacheSuccess::InheritedVariablesChanged(
const ComputedStyle& style) const {
- return EffectiveZoomChanged(style) || FontChanged(style);
+ if (!cached_matched_properties)
+ return false;
+ return cached_matched_properties->computed_style->InheritedVariables() !=
+ style.InheritedVariables();
+}
+
+bool StyleResolver::CacheSuccess::IsUsableAfterApplyInheritedOnly(
+ const ComputedStyle& style) const {
+ return !EffectiveZoomChanged(style) && !FontChanged(style) &&
+ !InheritedVariablesChanged(style);
}
StyleResolver::CacheSuccess StyleResolver::ApplyMatchedCache(
@@ -1883,6 +1862,10 @@ StyleResolver::CacheSuccess StyleResolver::ApplyMatchedCache(
if (!IsForcedColorsModeEnabled() || is_inherited_cache_hit) {
state.Style()->CopyNonInheritedFromCached(
*cached_matched_properties->computed_style);
+ // If the child style is a cache hit, we'll never reach StyleBuilder::
+ // ApplyProperty, hence we'll never set the flag on the parent.
+ if (state.Style()->HasExplicitInheritance())
+ state.ParentStyle()->SetChildHasExplicitInheritance();
is_non_inherited_cache_hit = true;
}
UpdateFont(state);
@@ -1896,15 +1879,14 @@ void StyleResolver::MaybeAddToMatchedPropertiesCache(
StyleResolverState& state,
const CacheSuccess& cache_success,
const MatchResult& match_result) {
+ state.LoadPendingResources();
if (!state.IsAnimatingCustomProperties() &&
!cache_success.cached_matched_properties && cache_success.key.IsValid() &&
MatchedPropertiesCache::IsCacheable(state)) {
INCREMENT_STYLE_STATS_COUNTER(GetDocument().GetStyleEngine(),
matched_property_cache_added, 1);
- // TODO(crbug.com/1057072): Pass dependencies to MatchedPropertiesCache.
- HashSet<CSSPropertyName> unused_dependencies;
matched_properties_cache_.Add(cache_success.key, *state.Style(),
- *state.ParentStyle(), unused_dependencies);
+ *state.ParentStyle(), state.Dependencies());
}
}
@@ -2080,7 +2062,6 @@ void StyleResolver::ApplyMatchedLowPriorityProperties(
state, match_result, apply_inherited_only, needs_apply_pass);
}
- LoadPendingResources(state);
MaybeAddToMatchedPropertiesCache(state, cache_success, match_result);
DCHECK(!state.GetFontBuilder().FontDirty());
@@ -2138,6 +2119,50 @@ void StyleResolver::ApplyMatchedProperties(StyleResolverState& state,
apply_inherited_only, needs_apply_pass);
}
+bool StyleResolver::CanReuseBaseComputedStyle(const StyleResolverState& state) {
+ ElementAnimations* element_animations = GetElementAnimations(state);
+ if (!element_animations || !element_animations->BaseComputedStyle())
+ return false;
+
+ if (!element_animations->IsAnimationStyleChange())
+ return false;
+
+ // Animating a custom property can have side effects on other properties
+ // via variable references. Disallow base computed style optimization in such
+ // cases.
+ if (CSSAnimations::IsAnimatingCustomProperties(element_animations))
+ return false;
+
+ // We need to build the cascade to know what to revert to.
+ if (CSSAnimations::IsAnimatingRevert(element_animations))
+ return false;
+
+ // When applying an animation or transition for a font affecting property,
+ // font-relative units (e.g. em, ex) in the base style must respond to the
+ // animation. We cannot use the base computed style optimization in such
+ // cases.
+ if (CSSAnimations::IsAnimatingFontAffectingProperties(element_animations)) {
+ if (element_animations->BaseComputedStyle() &&
+ element_animations->BaseComputedStyle()->HasFontRelativeUnits()) {
+ return false;
+ }
+ }
+
+ // Normally, we apply all active animation effects on top of the style created
+ // by regular CSS declarations. However, !important declarations have a
+ // higher priority than animation effects [1]. If we're currently animating
+ // (not transitioning) a property which was declared !important in the base
+ // style, we disable the base computed style optimization.
+ // [1] https://drafts.csswg.org/css-cascade-4/#cascade-origin
+ if (CSSAnimations::IsAnimatingStandardProperties(
+ element_animations, element_animations->BaseImportantSet(),
+ KeyframeEffect::kDefaultPriority)) {
+ return false;
+ }
+
+ return true;
+}
+
scoped_refptr<ComputedStyle> StyleResolver::StyleForInterpolations(
Element& element,
ActiveInterpolationsMap& interpolations) {
@@ -2174,70 +2199,17 @@ void StyleResolver::CascadeAndApplyMatchedProperties(StyleResolverState& state,
if (cache_success.ShouldApplyInheritedOnly()) {
cascade.Apply(CascadeFilter(CSSProperty::kInherited, false));
- if (cache_success.EffectiveZoomOrFontChanged(state.StyleRef()))
+ if (!cache_success.IsUsableAfterApplyInheritedOnly(state.StyleRef()))
cascade.Apply(CascadeFilter(CSSProperty::kInherited, true));
} else {
cascade.Apply();
}
- CascadeAndApplyForcedColors(state, result);
-
- LoadPendingResources(state);
MaybeAddToMatchedPropertiesCache(state, cache_success, result);
DCHECK(!state.GetFontBuilder().FontDirty());
}
-void StyleResolver::CascadeAndApplyForcedColors(StyleResolverState& state,
- const MatchResult& result) {
- if (!IsForcedColorsModeEnabled())
- return;
- if (state.Style()->ForcedColorAdjust() == EForcedColorAdjust::kNone)
- return;
-
- Color prev_bg_color = state.Style()->BackgroundColor().GetColor();
-
- STACK_UNINITIALIZED StyleCascade cascade(state);
-
- const CSSValue* unset = cssvalue::CSSUnsetValue::Create();
- const CSSValue* canvas = CSSIdentifierValue::Create(CSSValueID::kCanvas);
- auto* set =
- MakeGarbageCollected<MutableCSSPropertyValueSet>(state.GetParserMode());
- set->SetProperty(CSSPropertyID::kBackgroundColor, *canvas);
- set->SetProperty(CSSPropertyID::kBorderBottomColor, *unset);
- set->SetProperty(CSSPropertyID::kBorderLeftColor, *unset);
- set->SetProperty(CSSPropertyID::kBorderRightColor, *unset);
- set->SetProperty(CSSPropertyID::kBorderTopColor, *unset);
- set->SetProperty(CSSPropertyID::kBoxShadow, *unset);
- set->SetProperty(CSSPropertyID::kColor, *unset);
- set->SetProperty(CSSPropertyID::kColumnRuleColor, *unset);
- set->SetProperty(CSSPropertyID::kFill, *unset);
- set->SetProperty(CSSPropertyID::kOutlineColor, *unset);
- set->SetProperty(CSSPropertyID::kStroke, *unset);
- set->SetProperty(CSSPropertyID::kTextDecorationColor, *unset);
- set->SetProperty(CSSPropertyID::kTextShadow, *unset);
- set->SetProperty(CSSPropertyID::kWebkitTapHighlightColor, *unset);
- set->SetProperty(CSSPropertyID::kWebkitTextEmphasisColor, *unset);
-
- cascade.MutableMatchResult().AddMatchedProperties(set);
-
- for (const auto& matched_properties : result.UaRules()) {
- cascade.MutableMatchResult().AddMatchedProperties(
- matched_properties.properties,
- matched_properties.types_.link_match_type,
- static_cast<ValidPropertyFilter>(
- matched_properties.types_.valid_property_filter));
- }
-
- CascadeFilter filter(CSSProperty::kIsAffectedByForcedColors, false);
- cascade.Apply(filter);
-
- Color current_bg_color = state.Style()->BackgroundColor().GetColor();
- Color bg_color(current_bg_color.Red(), current_bg_color.Green(),
- current_bg_color.Blue(), prev_bg_color.Alpha());
- state.Style()->SetBackgroundColor(bg_color);
-}
-
bool StyleResolver::HasAuthorBackground(const StyleResolverState& state) {
const CachedUAStyle* cached_ua_style = state.GetCachedUAStyle();
if (!cached_ua_style)
@@ -2328,7 +2300,7 @@ void StyleResolver::UpdateMediaType() {
}
}
-void StyleResolver::Trace(Visitor* visitor) {
+void StyleResolver::Trace(Visitor* visitor) const {
visitor->Trace(matched_properties_cache_);
visitor->Trace(selector_filter_);
visitor->Trace(document_);
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_resolver.h b/chromium/third_party/blink/renderer/core/css/resolver/style_resolver.h
index 383a12c65ce..c4e5799aeb6 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_resolver.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_resolver.h
@@ -87,7 +87,9 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> {
const ComputedStyle* parent_style,
const ComputedStyle* layout_parent_style);
- scoped_refptr<const ComputedStyle> StyleForPage(int page_index);
+ scoped_refptr<const ComputedStyle> StyleForPage(
+ int page_index,
+ const AtomicString& page_name);
scoped_refptr<const ComputedStyle> StyleForText(Text*);
static scoped_refptr<ComputedStyle> StyleForViewport(Document&);
@@ -102,12 +104,16 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> {
// These methods will give back the set of rules that matched for a given
// element (or a pseudo-element).
enum CSSRuleFilter {
- kUAAndUserCSSRules = 1 << 1,
- kAuthorCSSRules = 1 << 2,
- kEmptyCSSRules = 1 << 3,
- kCrossOriginCSSRules = 1 << 4,
+ kUACSSRules = 1 << 1,
+ kUserCSSRules = 1 << 2,
+ kAuthorCSSRules = 1 << 3,
+ kEmptyCSSRules = 1 << 4,
+ kCrossOriginCSSRules = 1 << 5,
+ kUAAndUserCSSRules = kUACSSRules | kUserCSSRules,
kAllButEmptyCSSRules =
kUAAndUserCSSRules | kAuthorCSSRules | kCrossOriginCSSRules,
+ kAllButUACSSRules =
+ kUserCSSRules | kAuthorCSSRules | kEmptyCSSRules | kCrossOriginCSSRules,
kAllCSSRules = kAllButEmptyCSSRules | kEmptyCSSRules,
};
RuleIndexList* CssRulesForElement(
@@ -132,11 +138,13 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> {
static bool HasAuthorBackground(const StyleResolverState&);
+ static bool CanReuseBaseComputedStyle(const StyleResolverState& state);
+
scoped_refptr<ComputedStyle> StyleForInterpolations(
Element& target,
ActiveInterpolationsMap& animations);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void InitStyleAndApplyInheritance(Element& element,
@@ -153,14 +161,13 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> {
void AddMatchedRulesToTracker(const ElementRuleCollector&);
- void LoadPendingResources(StyleResolverState&);
-
void CollectPseudoRulesForElement(const Element&,
ElementRuleCollector&,
PseudoId,
unsigned rules_to_include);
void MatchRuleSet(ElementRuleCollector&, RuleSet*);
void MatchUARules(const Element&, ElementRuleCollector&);
+ void MatchUAPseudoElementRules(ElementRuleCollector&);
void MatchUserRules(ElementRuleCollector&);
// This matches `::part` selectors. It looks in ancestor scopes as far as
// part mapping requires.
@@ -207,7 +214,8 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> {
}
bool EffectiveZoomChanged(const ComputedStyle&) const;
bool FontChanged(const ComputedStyle&) const;
- bool EffectiveZoomOrFontChanged(const ComputedStyle&) const;
+ bool InheritedVariablesChanged(const ComputedStyle&) const;
+ bool IsUsableAfterApplyInheritedOnly(const ComputedStyle&) const;
};
// These flags indicate whether an apply pass for a given CSSPropertyPriority
@@ -270,7 +278,6 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> {
const MatchResult& match_result,
bool apply_inherited_only,
NeedsApplyPass& needs_apply_pass);
- void CascadeAndApplyForcedColors(StyleResolverState&, const MatchResult&);
void CascadeAndApplyMatchedProperties(StyleResolverState&,
StyleCascade& cascade);
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc b/chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
index 46d980e079f..cb059925310 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/pseudo_element.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
@@ -36,19 +37,15 @@ StyleResolverState::StyleResolverState(
Document& document,
Element& element,
PseudoElement* pseudo_element,
+ PseudoElementStyleRequest::RequestType pseudo_request_type,
AnimatingElementType animating_element_type,
const ComputedStyle* parent_style,
const ComputedStyle* layout_parent_style)
: element_context_(element),
document_(&document),
- style_(nullptr),
parent_style_(parent_style),
layout_parent_style_(layout_parent_style),
- is_animation_interpolation_map_ready_(false),
- is_animating_custom_properties_(false),
- has_dir_auto_attribute_(false),
- cascaded_color_value_(nullptr),
- cascaded_visited_color_value_(nullptr),
+ pseudo_request_type_(pseudo_request_type),
font_builder_(&document),
element_style_resources_(GetElement(),
document.DevicePixelRatio(),
@@ -77,18 +74,22 @@ StyleResolverState::StyleResolverState(Document& document,
: StyleResolverState(document,
element,
nullptr /* pseudo_element */,
+ PseudoElementStyleRequest::kForRenderer,
AnimatingElementType::kElement,
parent_style,
layout_parent_style) {}
-StyleResolverState::StyleResolverState(Document& document,
- Element& element,
- PseudoId pseudo_id,
- const ComputedStyle* parent_style,
- const ComputedStyle* layout_parent_style)
+StyleResolverState::StyleResolverState(
+ Document& document,
+ Element& element,
+ PseudoId pseudo_id,
+ PseudoElementStyleRequest::RequestType pseudo_request_type,
+ const ComputedStyle* parent_style,
+ const ComputedStyle* layout_parent_style)
: StyleResolverState(document,
element,
element.GetPseudoElement(pseudo_id),
+ pseudo_request_type,
AnimatingElementType::kPseudoElement,
parent_style,
layout_parent_style) {}
@@ -156,6 +157,13 @@ void StyleResolverState::CacheUserAgentBorderAndBackground() {
}
void StyleResolverState::LoadPendingResources() {
+ if (pseudo_request_type_ == PseudoElementStyleRequest::kForComputedStyle ||
+ (ParentStyle() && ParentStyle()->IsEnsuredInDisplayNone()) ||
+ StyleRef().Display() == EDisplay::kNone ||
+ StyleRef().Display() == EDisplay::kContents ||
+ StyleRef().IsEnsuredOutsideFlatTree())
+ return;
+
element_style_resources_.LoadPendingResources(Style());
}
@@ -211,7 +219,7 @@ CSSParserMode StyleResolverState::GetParserMode() const {
return GetDocument().InQuirksMode() ? kHTMLQuirksMode : kHTMLStandardMode;
}
-const Element* StyleResolverState::GetAnimatingElement() const {
+Element* StyleResolverState::GetAnimatingElement() const {
if (animating_element_type_ == AnimatingElementType::kElement)
return &GetElement();
DCHECK_EQ(AnimatingElementType::kPseudoElement, animating_element_type_);
@@ -231,4 +239,14 @@ const CSSValue& StyleResolverState::ResolveLightDarkPair(
return value;
}
+void StyleResolverState::MarkDependency(const CSSProperty& property) {
+ if (!RuntimeEnabledFeatures::CSSMatchedPropertiesCacheDependenciesEnabled())
+ return;
+ if (!HasValidDependencies())
+ return;
+
+ has_incomparable_dependency_ |= !property.IsComputedValueComparable();
+ dependencies_.insert(property.GetCSSPropertyName());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state.h b/chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state.h
index af7d94ed519..d73f6b7d471 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state.h
@@ -28,9 +28,11 @@
#include "third_party/blink/renderer/core/animation/css/css_animation_update.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/css_pending_substitution_value.h"
+#include "third_party/blink/renderer/core/css/css_property_name.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_mode.h"
+#include "third_party/blink/renderer/core/css/pseudo_style_request.h"
#include "third_party/blink/renderer/core/css/resolver/css_to_style_map.h"
#include "third_party/blink/renderer/core/css/resolver/element_resolve_context.h"
#include "third_party/blink/renderer/core/css/resolver/element_style_resources.h"
@@ -59,6 +61,7 @@ class CORE_EXPORT StyleResolverState {
StyleResolverState(Document&,
Element&,
PseudoId,
+ PseudoElementStyleRequest::RequestType,
const ComputedStyle* parent_style,
const ComputedStyle* layout_parent_style);
~StyleResolverState();
@@ -128,30 +131,8 @@ class CORE_EXPORT StyleResolverState {
void SetIsAnimatingCustomProperties(bool value) {
is_animating_custom_properties_ = value;
}
- bool IsAnimatingRevert() const { return is_animating_revert_; }
- void SetIsAnimatingRevert(bool value) { is_animating_revert_ = value; }
-
- // Normally, we apply all active animation effects on top of the style created
- // by regular CSS declarations. However, !important declarations have a
- // higher priority than animation effects [1]. If we're currently animating
- // (not transitioning) a property which was declared !important in the base
- // style, this flag is set such that we can disable the base computed style
- // optimization.
- //
- // [1] https://drafts.csswg.org/css-cascade-4/#cascade-origin
- bool HasImportantOverrides() const { return has_important_overrides_; }
- void SetHasImportantOverrides() { has_important_overrides_ = true; }
-
- // This flag is set when applying an animation (or transition) for a font
- // affecting property. When such properties are animated, font-relative
- // units (e.g. em, ex) in the base style must respond to the animation.
- // Therefore we can't use the base computed style optimization in such cases.
- bool HasFontAffectingAnimation() const {
- return has_font_affecting_animation_;
- }
- void SetHasFontAffectingAnimation() { has_font_affecting_animation_ = true; }
- const Element* GetAnimatingElement() const;
+ Element* GetAnimatingElement() const;
void SetParentStyle(scoped_refptr<const ComputedStyle>);
const ComputedStyle* ParentStyle() const { return parent_style_.get(); }
@@ -224,12 +205,61 @@ class CORE_EXPORT StyleResolverState {
// stored in the MatchedPropertiesCache.
const CSSValue& ResolveLightDarkPair(const CSSProperty&, const CSSValue&);
+ // The dependencies we track here end up in an entry in the
+ // MatchedPropertiesCache. Declarations such as "all:inherit" incurs several
+ // hundred dependencies, which is too big to cache, hence the number of
+ // dependencies we can track is limited.
+ static const size_t kMaxDependencies = 8;
+
+ // Mark the ComputedStyle as possibly dependent on the specified property.
+ //
+ // A "dependency" in this context means that one or more of the computed
+ // values held by the ComputedStyle depends on the computed value of the
+ // parent ComputedStyle.
+ //
+ // For example, a declaration such as background-color:var(--x) would incur
+ // a dependency on --x.
+ void MarkDependency(const CSSProperty&);
+
+ // Returns the set of all properties seen by MarkDependency.
+ //
+ // The caller must check if the dependencies are valid via
+ // HasValidDependencies() before calling this function.
+ //
+ // Note that this set might be larger than the actual set of dependencies,
+ // as we do some degree of over-marking to keep the implementation simple.
+ //
+ // For example, we mark all custom properties referenced as dependencies, even
+ // though the ComputedStyle itself may define a value for some or all of those
+ // custom properties. In the following example, both --x and --y will be
+ // added to this set, even though only --y is a true dependency:
+ //
+ // div {
+ // --x: 10px;
+ // margin: var(--x) (--y);
+ // }
+ //
+ const HashSet<CSSPropertyName>& Dependencies() const {
+ DCHECK(HasValidDependencies());
+ return dependencies_;
+ }
+
+ // True if there's a dependency without the kComputedValueComparable flag.
+ bool HasIncomparableDependency() const {
+ return has_incomparable_dependency_;
+ }
+
+ bool HasValidDependencies() const {
+ return dependencies_.size() <= kMaxDependencies;
+ }
+
private:
enum class AnimatingElementType { kElement, kPseudoElement };
StyleResolverState(Document&,
Element&,
PseudoElement*,
+ PseudoElementStyleRequest::RequestType,
AnimatingElementType,
const ComputedStyle* parent_style,
const ComputedStyle* layout_parent_style);
@@ -254,19 +284,13 @@ class CORE_EXPORT StyleResolverState {
scoped_refptr<const ComputedStyle> layout_parent_style_;
CSSAnimationUpdate animation_update_;
- bool is_animation_interpolation_map_ready_;
- bool is_animating_custom_properties_;
- // We can't use the base computed style optimization when 'revert' appears
- // in a keyframe. (We need to build the cascade to know what to revert to).
- // TODO(crbug.com/1068515): Refactor caching to remove these flags.
- bool is_animating_revert_ = false;
- bool has_important_overrides_ = false;
- bool has_font_affecting_animation_ = false;
+ bool is_animation_interpolation_map_ready_ = false;
+ bool is_animating_custom_properties_ = false;
+ bool has_dir_auto_attribute_ = false;
+ PseudoElementStyleRequest::RequestType pseudo_request_type_;
- bool has_dir_auto_attribute_;
-
- const CSSValue* cascaded_color_value_;
- const CSSValue* cascaded_visited_color_value_;
+ const CSSValue* cascaded_color_value_ = nullptr;
+ const CSSValue* cascaded_visited_color_value_ = nullptr;
FontBuilder font_builder_;
@@ -276,6 +300,13 @@ class CORE_EXPORT StyleResolverState {
Element* pseudo_element_;
AnimatingElementType animating_element_type_;
+ // Properties depended on by the ComputedStyle. This is known after the
+ // cascade is applied.
+ HashSet<CSSPropertyName> dependencies_;
+ // True if there's an entry in 'dependencies_' which does not have the
+ // CSSProperty::kComputedValueComparable flag set.
+ bool has_incomparable_dependency_ = false;
+
mutable HeapHashMap<
Member<const cssvalue::CSSPendingSubstitutionValue>,
Member<HeapHashMap<CSSPropertyID, Member<const CSSValue>>>>
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state_test.cc
new file mode 100644
index 00000000000..f78d52131d6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state_test.cc
@@ -0,0 +1,66 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
+#include "third_party/blink/renderer/core/css/properties/longhands/custom_property.h"
+#include "third_party/blink/renderer/core/html/html_element.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
+
+namespace blink {
+
+class StyleResolverStateTest
+ : public PageTestBase,
+ private ScopedCSSMatchedPropertiesCacheDependenciesForTest {
+ public:
+ StyleResolverStateTest()
+ : ScopedCSSMatchedPropertiesCacheDependenciesForTest(true) {}
+};
+
+TEST_F(StyleResolverStateTest, Dependencies) {
+ StyleResolverState state(GetDocument(), *GetDocument().body(), nullptr,
+ nullptr);
+
+ EXPECT_TRUE(state.Dependencies().IsEmpty());
+
+ const auto& left = GetCSSPropertyLeft();
+ const auto& right = GetCSSPropertyRight();
+ const auto& incomparable = GetCSSPropertyInternalEmptyLineHeight();
+
+ state.MarkDependency(left);
+ EXPECT_EQ(1u, state.Dependencies().size());
+ EXPECT_TRUE(state.Dependencies().Contains(left.GetCSSPropertyName()));
+ EXPECT_FALSE(state.HasIncomparableDependency());
+
+ state.MarkDependency(right);
+ EXPECT_EQ(2u, state.Dependencies().size());
+ EXPECT_TRUE(state.Dependencies().Contains(left.GetCSSPropertyName()));
+ EXPECT_TRUE(state.Dependencies().Contains(right.GetCSSPropertyName()));
+ EXPECT_FALSE(state.HasIncomparableDependency());
+
+ state.MarkDependency(incomparable);
+ EXPECT_EQ(3u, state.Dependencies().size());
+ EXPECT_TRUE(state.Dependencies().Contains(left.GetCSSPropertyName()));
+ EXPECT_TRUE(state.Dependencies().Contains(right.GetCSSPropertyName()));
+ EXPECT_TRUE(state.Dependencies().Contains(incomparable.GetCSSPropertyName()));
+ EXPECT_TRUE(state.HasIncomparableDependency());
+}
+
+TEST_F(StyleResolverStateTest, MaxDependencies) {
+ StyleResolverState state(GetDocument(), *GetDocument().body(), nullptr,
+ nullptr);
+
+ EXPECT_TRUE(state.HasValidDependencies());
+
+ for (size_t i = 0; i < StyleResolverState::kMaxDependencies; ++i) {
+ auto name = AtomicString(String::Format("--v%zu", i));
+ state.MarkDependency(CustomProperty(name, GetDocument()));
+ EXPECT_TRUE(state.HasValidDependencies());
+ }
+
+ state.MarkDependency(CustomProperty("--exceeds-limit", GetDocument()));
+ EXPECT_FALSE(state.HasValidDependencies());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc
index 46d01c3a140..4042cb895fe 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc
@@ -8,12 +8,19 @@
#include "third_party/blink/renderer/core/animation/animation_test_helper.h"
#include "third_party/blink/renderer/core/animation/document_timeline.h"
#include "third_party/blink/renderer/core/animation/element_animations.h"
+#include "third_party/blink/renderer/core/css/css_image_value.h"
+#include "third_party/blink/renderer/core/css/css_value_list.h"
+#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
#include "third_party/blink/renderer/core/css/properties/css_property_ref.h"
+#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
+#include "third_party/blink/renderer/core/css/style_sheet_contents.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
+#include "third_party/blink/renderer/core/dom/pseudo_element.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/dom/text.h"
+#include "third_party/blink/renderer/core/html/html_style_element.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
@@ -62,6 +69,8 @@ TEST_F(StyleResolverTest, AnimationBaseComputedStyle) {
<style>
html { font-size: 10px; }
body { font-size: 20px; }
+ @keyframes fade { to { opacity: 0; }}
+ #div { animation: fade 1s; }
</style>
<div id="div">Test</div>
)HTML");
@@ -120,7 +129,7 @@ TEST_F(StyleResolverTest, HasEmUnits) {
EXPECT_TRUE(StyleForId("div")->HasEmUnits());
}
-TEST_F(StyleResolverTest, BasePresentIfFontRelativeUnitsAbsent) {
+TEST_F(StyleResolverTest, BaseReusableIfFontRelativeUnitsAbsent) {
GetDocument().documentElement()->setInnerHTML("<div id=div>Test</div>");
UpdateAllLifecyclePhasesForTest();
Element* div = GetDocument().getElementById("div");
@@ -137,6 +146,9 @@ TEST_F(StyleResolverTest, BasePresentIfFontRelativeUnitsAbsent) {
ASSERT_TRUE(div->GetElementAnimations());
EXPECT_TRUE(div->GetElementAnimations()->BaseComputedStyle());
+
+ StyleResolverState state(GetDocument(), *div);
+ EXPECT_TRUE(StyleResolver::CanReuseBaseComputedStyle(state));
}
TEST_F(StyleResolverTest, NoCrashWhenAnimatingWithoutCascade) {
@@ -251,15 +263,47 @@ TEST_F(StyleResolverTest, AnimationMaskedByImportant) {
StyleForId("div");
ASSERT_TRUE(div->GetElementAnimations());
- EXPECT_FALSE(div->GetElementAnimations()->BaseComputedStyle());
- EXPECT_FALSE(div->GetElementAnimations()->BaseImportantSet());
+ EXPECT_TRUE(div->GetElementAnimations()->BaseComputedStyle());
+ EXPECT_TRUE(div->GetElementAnimations()->BaseImportantSet());
+
+ StyleResolverState state(GetDocument(), *div);
+ EXPECT_FALSE(StyleResolver::CanReuseBaseComputedStyle(state));
+}
+
+TEST_F(StyleResolverTest, CachedExplicitInheritanceFlags) {
+ ScopedCSSMatchedPropertiesCacheDependenciesForTest scoped_feature(true);
+
+ GetDocument().documentElement()->setInnerHTML(R"HTML(
+ <style>
+ #outer { height: 10px; }
+ #inner { height: inherit; }
+ </style>
+ <div id=outer>
+ <div id=inner></div>
+ </div>
+ )HTML");
+ UpdateAllLifecyclePhasesForTest();
+
+ Element* outer = GetDocument().getElementById("outer");
+ ASSERT_TRUE(outer);
+ EXPECT_TRUE(outer->ComputedStyleRef().ChildHasExplicitInheritance());
+
+ auto recalc_reason = StyleChangeReasonForTracing::Create("test");
+
+ // This will hit the MatchedPropertiesCache for both #outer/#inner,
+ // which means special care must be taken for the ChildHasExplicit-
+ // Inheritance flag to persist.
+ GetStyleEngine().MarkAllElementsForStyleRecalc(recalc_reason);
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_TRUE(outer->ComputedStyleRef().ChildHasExplicitInheritance());
}
class StyleResolverFontRelativeUnitTest
: public testing::WithParamInterface<const char*>,
public StyleResolverTest {};
-TEST_P(StyleResolverFontRelativeUnitTest, NoBaseIfFontRelativeUnitPresent) {
+TEST_P(StyleResolverFontRelativeUnitTest,
+ BaseNotReusableIfFontRelativeUnitPresent) {
GetDocument().documentElement()->setInnerHTML(
String::Format("<div id=div style='width:1%s'>Test</div>", GetParam()));
UpdateAllLifecyclePhasesForTest();
@@ -276,11 +320,14 @@ TEST_P(StyleResolverFontRelativeUnitTest, NoBaseIfFontRelativeUnitPresent) {
EXPECT_TRUE(computed_style->HasFontRelativeUnits());
ASSERT_TRUE(div->GetElementAnimations());
- EXPECT_FALSE(div->GetElementAnimations()->BaseComputedStyle());
+ EXPECT_TRUE(div->GetElementAnimations()->BaseComputedStyle());
+
+ StyleResolverState state(GetDocument(), *div);
+ EXPECT_FALSE(StyleResolver::CanReuseBaseComputedStyle(state));
}
TEST_P(StyleResolverFontRelativeUnitTest,
- BasePresentIfNoFontAffectingAnimation) {
+ BaseReusableIfNoFontAffectingAnimation) {
GetDocument().documentElement()->setInnerHTML(
String::Format("<div id=div style='width:1%s'>Test</div>", GetParam()));
UpdateAllLifecyclePhasesForTest();
@@ -298,10 +345,261 @@ TEST_P(StyleResolverFontRelativeUnitTest,
EXPECT_TRUE(computed_style->HasFontRelativeUnits());
ASSERT_TRUE(div->GetElementAnimations());
EXPECT_TRUE(div->GetElementAnimations()->BaseComputedStyle());
+
+ StyleResolverState state(GetDocument(), *div);
+ EXPECT_TRUE(StyleResolver::CanReuseBaseComputedStyle(state));
}
INSTANTIATE_TEST_SUITE_P(All,
StyleResolverFontRelativeUnitTest,
testing::Values("em", "rem", "ex", "ch"));
+namespace {
+
+const CSSImageValue& GetBackgroundImageValue(const ComputedStyle& style) {
+ const CSSValue* computed_value = ComputedStyleUtils::ComputedPropertyValue(
+ GetCSSPropertyBackgroundImage(), style);
+
+ const CSSValueList* bg_img_list = To<CSSValueList>(computed_value);
+ return To<CSSImageValue>(bg_img_list->Item(0));
+}
+
+const CSSImageValue& GetBackgroundImageValue(const Element* element) {
+ DCHECK(element);
+ return GetBackgroundImageValue(element->ComputedStyleRef());
+}
+
+} // namespace
+
+TEST_F(StyleResolverTest, BackgroundImageFetch) {
+ GetDocument().documentElement()->setInnerHTML(R"HTML(
+ <style>
+ #none {
+ display: none;
+ background-image: url(img-none.png);
+ }
+ #inside-none {
+ background-image: url(img-inside-none.png);
+ }
+ #hidden {
+ visibility: hidden;
+ background-image: url(img-hidden.png);
+ }
+ #inside-hidden {
+ background-image: url(img-inside-hidden.png);
+ }
+ #contents {
+ display: contents;
+ background-image: url(img-contents.png);
+ }
+ #non-slotted {
+ background-image: url(img-non-slotted.png);
+ }
+ #no-pseudo::before {
+ background-image: url(img-no-pseudo.png);
+ }
+ #first-line::first-line {
+ background-image: url(first-line.png);
+ }
+ #first-line-span::first-line {
+ background-image: url(first-line-span.png);
+ }
+ #first-line-none { display: none; }
+ #first-line-none::first-line {
+ background-image: url(first-line-none.png);
+ }
+ </style>
+ <div id="none">
+ <div id="inside-none"></div>
+ </div>
+ <div id="hidden">
+ <div id="inside-hidden"></div>
+ </div>
+ <div id="contents"></div>
+ <div id="host">
+ <div id="non-slotted"></div>
+ </div>
+ <div id="no-pseudo"></div>
+ <div id="first-line">XXX</div>
+ <span id="first-line-span">XXX</span>
+ <div id="first-line-none">XXX</div>
+ )HTML");
+
+ GetDocument().getElementById("host")->AttachShadowRootInternal(
+ ShadowRootType::kOpen);
+ UpdateAllLifecyclePhasesForTest();
+
+ auto* none = GetDocument().getElementById("none");
+ auto* inside_none = GetDocument().getElementById("inside-none");
+ auto* hidden = GetDocument().getElementById("hidden");
+ auto* inside_hidden = GetDocument().getElementById("inside-hidden");
+ auto* contents = GetDocument().getElementById("contents");
+ auto* non_slotted = GetDocument().getElementById("non-slotted");
+ auto* no_pseudo = GetDocument().getElementById("no-pseudo");
+ auto* first_line = GetDocument().getElementById("first-line");
+ auto* first_line_span = GetDocument().getElementById("first-line-span");
+ auto* first_line_none = GetDocument().getElementById("first-line-none");
+
+ inside_none->EnsureComputedStyle();
+ non_slotted->EnsureComputedStyle();
+ auto* before_style = no_pseudo->EnsureComputedStyle(kPseudoIdBefore);
+ auto* first_line_style = first_line->EnsureComputedStyle(kPseudoIdFirstLine);
+ auto* first_line_span_style =
+ first_line_span->EnsureComputedStyle(kPseudoIdFirstLine);
+ auto* first_line_none_style =
+ first_line_none->EnsureComputedStyle(kPseudoIdFirstLine);
+
+ ASSERT_TRUE(before_style);
+ EXPECT_TRUE(GetBackgroundImageValue(*before_style).IsCachePending())
+ << "No fetch for non-generated ::before";
+ ASSERT_TRUE(first_line_style);
+ EXPECT_FALSE(GetBackgroundImageValue(*first_line_style).IsCachePending())
+ << "Fetched by layout of ::first-line";
+ ASSERT_TRUE(first_line_span_style);
+ EXPECT_TRUE(GetBackgroundImageValue(*first_line_span_style).IsCachePending())
+ << "No fetch for inline with ::first-line";
+ ASSERT_TRUE(first_line_none_style);
+ EXPECT_TRUE(GetBackgroundImageValue(*first_line_none_style).IsCachePending())
+ << "No fetch for display:none with ::first-line";
+ EXPECT_TRUE(GetBackgroundImageValue(none).IsCachePending())
+ << "No fetch for display:none";
+ EXPECT_TRUE(GetBackgroundImageValue(inside_none).IsCachePending())
+ << "No fetch inside display:none";
+ EXPECT_FALSE(GetBackgroundImageValue(hidden).IsCachePending())
+ << "Fetch for visibility:hidden";
+ EXPECT_FALSE(GetBackgroundImageValue(inside_hidden).IsCachePending())
+ << "Fetch for inherited visibility:hidden";
+ EXPECT_TRUE(GetBackgroundImageValue(contents).IsCachePending())
+ << "No fetch for display:contents";
+ EXPECT_TRUE(GetBackgroundImageValue(non_slotted).IsCachePending())
+ << "No fetch for element outside the flat tree";
+}
+
+TEST_F(StyleResolverTest, NoFetchForAtPage) {
+ // Strictly, we should drop descriptors from @page rules which are not valid
+ // descriptors, but as long as we apply them to ComputedStyle we should at
+ // least not trigger fetches. The display:contents is here to make sure we
+ // don't hit a DCHECK in StylePendingImage::ComputedCSSValue().
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <style>
+ @page {
+ display: contents;
+ background-image: url(bg-img.png);
+ }
+ </style>
+ )HTML");
+
+ scoped_refptr<const ComputedStyle> page_style =
+ GetDocument().EnsureStyleResolver().StyleForPage(0, "");
+ ASSERT_TRUE(page_style);
+ const CSSValue* computed_value = ComputedStyleUtils::ComputedPropertyValue(
+ GetCSSPropertyBackgroundImage(), *page_style);
+
+ const CSSValueList* bg_img_list = To<CSSValueList>(computed_value);
+ EXPECT_TRUE(To<CSSImageValue>(bg_img_list->Item(0)).IsCachePending());
+}
+
+TEST_F(StyleResolverTest, CSSMarkerPseudoElement) {
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <style>
+ b::before {
+ content: "[before]";
+ display: list-item;
+ }
+ #marker ::marker {
+ color: blue;
+ }
+ </style>
+ <ul>
+ <li style="list-style: decimal outside"><b></b></li>
+ <li style="list-style: decimal inside"><b></b></li>
+ <li style="list-style: disc outside"><b></b></li>
+ <li style="list-style: disc inside"><b></b></li>
+ <li style="list-style: '- ' outside"><b></b></li>
+ <li style="list-style: '- ' inside"><b></b></li>
+ <li style="list-style: linear-gradient(blue, cyan) outside"><b></b></li>
+ <li style="list-style: linear-gradient(blue, cyan) inside"><b></b></li>
+ <li style="list-style: none outside"><b></b></li>
+ <li style="list-style: none inside"><b></b></li>
+ </ul>
+ )HTML");
+ StaticElementList* lis = GetDocument().QuerySelectorAll("li");
+ EXPECT_EQ(lis->length(), 10U);
+
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
+ for (unsigned i = 0; i < lis->length(); ++i) {
+ Element* li = lis->item(i);
+ PseudoElement* marker = li->GetPseudoElement(kPseudoIdMarker);
+ PseudoElement* before =
+ li->QuerySelector("b")->GetPseudoElement(kPseudoIdBefore);
+ PseudoElement* nested_marker = before->GetPseudoElement(kPseudoIdMarker);
+
+ // Check that UA styles for list markers don't set HasPseudoElementStyle
+ const ComputedStyle* li_style = li->GetComputedStyle();
+ EXPECT_FALSE(li_style->HasPseudoElementStyle(kPseudoIdMarker));
+ EXPECT_FALSE(li_style->HasAnyPseudoElementStyles());
+ const ComputedStyle* before_style = before->GetComputedStyle();
+ EXPECT_FALSE(before_style->HasPseudoElementStyle(kPseudoIdMarker));
+ EXPECT_FALSE(before_style->HasAnyPseudoElementStyles());
+
+ if (i >= 8) {
+ EXPECT_FALSE(marker);
+ EXPECT_FALSE(nested_marker);
+ continue;
+ }
+
+ // Check that list markers have UA styles
+ EXPECT_TRUE(marker);
+ EXPECT_TRUE(nested_marker);
+ EXPECT_EQ(marker->GetComputedStyle()->GetUnicodeBidi(),
+ UnicodeBidi::kIsolate);
+ EXPECT_EQ(nested_marker->GetComputedStyle()->GetUnicodeBidi(),
+ UnicodeBidi::kIsolate);
+ }
+
+ GetDocument().body()->SetIdAttribute("marker");
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
+ for (unsigned i = 0; i < lis->length(); ++i) {
+ Element* li = lis->item(i);
+ PseudoElement* before =
+ li->QuerySelector("b")->GetPseudoElement(kPseudoIdBefore);
+
+ // Check that author styles for list markers do set HasPseudoElementStyle
+ const ComputedStyle* li_style = li->GetComputedStyle();
+ EXPECT_TRUE(li_style->HasPseudoElementStyle(kPseudoIdMarker));
+ EXPECT_TRUE(li_style->HasAnyPseudoElementStyles());
+
+ // But ::marker styles don't match a ::before::marker
+ const ComputedStyle* before_style = before->GetComputedStyle();
+ EXPECT_FALSE(before_style->HasPseudoElementStyle(kPseudoIdMarker));
+ EXPECT_FALSE(before_style->HasAnyPseudoElementStyles());
+ }
+}
+
+TEST_F(StyleResolverTest, ApplyInheritedOnlyCustomPropertyChange) {
+ ScopedCSSMatchedPropertiesCacheDependenciesForTest scoped_feature(true);
+
+ // This test verifies that when we get a "apply inherited only"-type
+ // hit in the MatchesPropertiesCache, we're able to detect that custom
+ // properties changed, and that we therefore need to apply the non-inherited
+ // properties as well.
+
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <style>
+ #parent1 { --a: 10px; }
+ #parent2 { --a: 20px; }
+ #child1, #child2 {
+ --b: var(--a);
+ width: var(--b);
+ }
+ </style>
+ <div id=parent1><div id=child1></div></div>
+ <div id=parent2><div id=child2></div></div>
+ )HTML");
+ UpdateAllLifecyclePhasesForTest();
+
+ EXPECT_EQ("10px", ComputedValue("width", *StyleForId("child1")));
+ EXPECT_EQ("20px", ComputedValue("width", *StyleForId("child2")));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.cc b/chromium/third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.cc
index acdb913c628..c854c5e73c5 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.cc
@@ -42,7 +42,7 @@ void StyleRuleUsageTracker::Track(const CSSStyleSheet* parent_sheet,
}
}
-void StyleRuleUsageTracker::Trace(Visitor* visitor) {
+void StyleRuleUsageTracker::Trace(Visitor* visitor) const {
visitor->Trace(used_rules_);
visitor->Trace(used_rules_delta_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.h b/chromium/third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.h
index d28f7d43763..54132c60265 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.h
@@ -19,7 +19,7 @@ class StyleRuleUsageTracker : public GarbageCollected<StyleRuleUsageTracker> {
void Track(const CSSStyleSheet*, const StyleRule*);
RuleListByStyleSheet TakeDelta();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
bool InsertToUsedRulesMap(const CSSStyleSheet*, const StyleRule*);
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc b/chromium/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc
index 4118e5261cd..914ddaed286 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc
@@ -390,7 +390,7 @@ void ViewportStyleResolver::UpdateViewport(
needs_update_ = kNoUpdate;
}
-void ViewportStyleResolver::Trace(Visitor* visitor) {
+void ViewportStyleResolver::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(property_set_);
visitor->Trace(initial_viewport_medium_);
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h b/chromium/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h
index aec4e463abc..4ce4c71f7ed 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h
@@ -57,7 +57,7 @@ class CORE_EXPORT ViewportStyleResolver final
void CollectViewportRulesFromAuthorSheet(const CSSStyleSheet&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void Reset();
diff --git a/chromium/third_party/blink/renderer/core/css/rule_feature_set_test.cc b/chromium/third_party/blink/renderer/core/css/rule_feature_set_test.cc
index 02ce7c9fdbe..39fb0857533 100644
--- a/chromium/third_party/blink/renderer/core/css/rule_feature_set_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/rule_feature_set_test.cc
@@ -26,7 +26,7 @@ class RuleFeatureSetTest : public testing::Test {
RuleFeatureSetTest() = default;
void SetUp() override {
- document_ = MakeGarbageCollected<HTMLDocument>();
+ document_ = HTMLDocument::CreateForTest();
auto* html = MakeGarbageCollected<HTMLHtmlElement>(*document_);
html->AppendChild(MakeGarbageCollected<HTMLBodyElement>(*document_));
document_->AppendChild(html);
diff --git a/chromium/third_party/blink/renderer/core/css/rule_set.cc b/chromium/third_party/blink/renderer/core/css/rule_set.cc
index b5b09b832f1..e196fed675c 100644
--- a/chromium/third_party/blink/renderer/core/css/rule_set.cc
+++ b/chromium/third_party/blink/renderer/core/css/rule_set.cc
@@ -429,22 +429,22 @@ bool RuleSet::DidMediaQueryResultsChange(
return false;
}
-void MinimalRuleData::Trace(Visitor* visitor) {
+void MinimalRuleData::Trace(Visitor* visitor) const {
visitor->Trace(rule_);
}
-void RuleData::Trace(Visitor* visitor) {
+void RuleData::Trace(Visitor* visitor) const {
visitor->Trace(rule_);
}
-void RuleSet::PendingRuleMaps::Trace(Visitor* visitor) {
+void RuleSet::PendingRuleMaps::Trace(Visitor* visitor) const {
visitor->Trace(id_rules);
visitor->Trace(class_rules);
visitor->Trace(tag_rules);
visitor->Trace(shadow_pseudo_element_rules);
}
-void RuleSet::Trace(Visitor* visitor) {
+void RuleSet::Trace(Visitor* visitor) const {
visitor->Trace(id_rules_);
visitor->Trace(class_rules_);
visitor->Trace(tag_rules_);
diff --git a/chromium/third_party/blink/renderer/core/css/rule_set.h b/chromium/third_party/blink/renderer/core/css/rule_set.h
index 26a1b5f107d..a4312869606 100644
--- a/chromium/third_party/blink/renderer/core/css/rule_set.h
+++ b/chromium/third_party/blink/renderer/core/css/rule_set.h
@@ -68,7 +68,7 @@ class MinimalRuleData {
MinimalRuleData(StyleRule* rule, unsigned selector_index, AddRuleFlags flags)
: rule_(rule), selector_index_(selector_index), flags_(flags) {}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
Member<StyleRule> rule_;
unsigned selector_index_;
@@ -127,7 +127,7 @@ class CORE_EXPORT RuleData : public GarbageCollected<RuleData> {
return descendant_selector_identifier_hashes_;
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// This number is picked fairly arbitrary. If lowered, be aware that there
// might be sites and extensions using style rules with selector lists
@@ -290,7 +290,7 @@ class CORE_EXPORT RuleSet final : public GarbageCollected<RuleSet> {
void Show() const;
#endif
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
using PendingRuleMap =
@@ -325,7 +325,7 @@ class CORE_EXPORT RuleSet final : public GarbageCollected<RuleSet> {
PendingRuleMap tag_rules;
PendingRuleMap shadow_pseudo_element_rules;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
};
PendingRuleMaps* EnsurePendingRules() {
diff --git a/chromium/third_party/blink/renderer/core/css/selector_checker.cc b/chromium/third_party/blink/renderer/core/css/selector_checker.cc
index 8f748ae1507..61e1a293c96 100644
--- a/chromium/third_party/blink/renderer/core/css/selector_checker.cc
+++ b/chromium/third_party/blink/renderer/core/css/selector_checker.cc
@@ -58,6 +58,7 @@
#include "third_party/blink/renderer/core/html/html_slot_element.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
+#include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h"
#include "third_party/blink/renderer/core/html/track/vtt/vtt_element.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/page/focus_controller.h"
@@ -436,7 +437,7 @@ SelectorChecker::MatchStatus SelectorChecker::MatchForRelation(
switch (relation) {
case CSSSelector::kShadowDeepAsDescendant:
- Deprecation::CountDeprecation(context.element->GetDocument(),
+ Deprecation::CountDeprecation(context.element->GetExecutionContext(),
WebFeature::kCSSDeepCombinator);
FALLTHROUGH;
case CSSSelector::kDescendant:
@@ -1407,9 +1408,18 @@ bool SelectorChecker::CheckPseudoElement(const SelectorCheckingContext& context,
}
return false;
case CSSSelector::kPseudoWebKitCustomElement: {
- if (ShadowRoot* root = element.ContainingShadowRoot())
- return root->IsUserAgent() &&
- element.ShadowPseudoId() == selector.Value();
+ if (ShadowRoot* root = element.ContainingShadowRoot()) {
+ if (!root->IsUserAgent())
+ return false;
+ if (element.ShadowPseudoId() != selector.Value())
+ return false;
+ if (!is_ua_rule_ &&
+ selector.Value() == shadow_element_names::WebKitDetailsMarker()) {
+ UseCounter::Count(element.GetDocument(),
+ WebFeature::kCSSSelectorPseudoWebKitDetailsMarker);
+ }
+ return true;
+ }
return false;
}
case CSSSelector::kPseudoBlinkInternalElement:
diff --git a/chromium/third_party/blink/renderer/core/css/selector_filter.cc b/chromium/third_party/blink/renderer/core/css/selector_filter.cc
index 64d86ed4bb5..16e336cd1dd 100644
--- a/chromium/third_party/blink/renderer/core/css/selector_filter.cc
+++ b/chromium/third_party/blink/renderer/core/css/selector_filter.cc
@@ -198,11 +198,11 @@ void SelectorFilter::CollectIdentifierHashes(
*hash = 0;
}
-void SelectorFilter::ParentStackFrame::Trace(Visitor* visitor) {
+void SelectorFilter::ParentStackFrame::Trace(Visitor* visitor) const {
visitor->Trace(element);
}
-void SelectorFilter::Trace(Visitor* visitor) {
+void SelectorFilter::Trace(Visitor* visitor) const {
visitor->Trace(parent_stack_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/selector_filter.h b/chromium/third_party/blink/renderer/core/css/selector_filter.h
index d911116c19d..bc8489ec1a5 100644
--- a/chromium/third_party/blink/renderer/core/css/selector_filter.h
+++ b/chromium/third_party/blink/renderer/core/css/selector_filter.h
@@ -53,7 +53,7 @@ class CORE_EXPORT SelectorFilter {
ParentStackFrame() : element(nullptr) {}
explicit ParentStackFrame(Element& element) : element(&element) {}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
Member<Element> element;
Vector<unsigned, 4> identifier_hashes;
@@ -75,7 +75,7 @@ class CORE_EXPORT SelectorFilter {
unsigned* identifier_hashes,
unsigned maximum_identifier_count);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void PushParentStackFrame(Element& parent);
diff --git a/chromium/third_party/blink/renderer/core/css/selector_query_test.cc b/chromium/third_party/blink/renderer/core/css/selector_query_test.cc
index 84cffc1e660..8d701d91372 100644
--- a/chromium/third_party/blink/renderer/core/css/selector_query_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/selector_query_test.cc
@@ -64,7 +64,7 @@ void RunTests(ContainerNode& scope, const QueryTest (&test_cases)[length]) {
} // namespace
TEST(SelectorQueryTest, NotMatchingPseudoElement) {
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* html = MakeGarbageCollected<HTMLHtmlElement>(*document);
document->AppendChild(html);
document->documentElement()->setInnerHTML(
@@ -93,7 +93,7 @@ TEST(SelectorQueryTest, NotMatchingPseudoElement) {
}
TEST(SelectorQueryTest, LastOfTypeNotFinishedParsing) {
- auto* document = MakeGarbageCollected<HTMLDocument>();
+ auto* document = HTMLDocument::CreateForTest();
auto* html = MakeGarbageCollected<HTMLHtmlElement>(*document);
document->AppendChild(html);
document->documentElement()->setInnerHTML(
@@ -115,7 +115,7 @@ TEST(SelectorQueryTest, LastOfTypeNotFinishedParsing) {
}
TEST(SelectorQueryTest, StandardsModeFastPaths) {
- auto* document = MakeGarbageCollected<HTMLDocument>();
+ auto* document = HTMLDocument::CreateForTest();
document->write(R"HTML(
<!DOCTYPE html>
<html>
@@ -227,7 +227,7 @@ TEST(SelectorQueryTest, StandardsModeFastPaths) {
}
TEST(SelectorQueryTest, FastPathScoped) {
- auto* document = MakeGarbageCollected<HTMLDocument>();
+ auto* document = HTMLDocument::CreateForTest();
document->write(R"HTML(
<!DOCTYPE html>
<html id=root-id class=root-class>
@@ -293,7 +293,7 @@ TEST(SelectorQueryTest, FastPathScoped) {
}
TEST(SelectorQueryTest, QuirksModeSlowPath) {
- auto* document = MakeGarbageCollected<HTMLDocument>();
+ auto* document = HTMLDocument::CreateForTest();
document->write(R"HTML(
<html>
<head></head>
@@ -329,7 +329,7 @@ TEST(SelectorQueryTest, QuirksModeSlowPath) {
}
TEST(SelectorQueryTest, DisconnectedSubtree) {
- auto* document = MakeGarbageCollected<HTMLDocument>();
+ auto* document = HTMLDocument::CreateForTest();
Element* scope = document->CreateRawElement(html_names::kDivTag);
scope->setInnerHTML(R"HTML(
<section>
@@ -356,7 +356,7 @@ TEST(SelectorQueryTest, DisconnectedSubtree) {
}
TEST(SelectorQueryTest, DisconnectedTreeScope) {
- auto* document = MakeGarbageCollected<HTMLDocument>();
+ auto* document = HTMLDocument::CreateForTest();
Element* host = document->CreateRawElement(html_names::kDivTag);
ShadowRoot& shadowRoot =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
diff --git a/chromium/third_party/blink/renderer/core/css/shadow_tree_style_sheet_collection.cc b/chromium/third_party/blink/renderer/core/css/shadow_tree_style_sheet_collection.cc
index f4c0d29f459..d379c61a0e3 100644
--- a/chromium/third_party/blink/renderer/core/css/shadow_tree_style_sheet_collection.cc
+++ b/chromium/third_party/blink/renderer/core/css/shadow_tree_style_sheet_collection.cc
@@ -45,7 +45,7 @@ ShadowTreeStyleSheetCollection::ShadowTreeStyleSheetCollection(
: TreeScopeStyleSheetCollection(shadow_root) {}
void ShadowTreeStyleSheetCollection::CollectStyleSheets(
- StyleEngine& master_engine,
+ StyleEngine& engine,
StyleSheetCollection& collection) {
for (Node* n : style_sheet_candidate_nodes_) {
StyleSheetCandidate candidate(*n);
@@ -59,7 +59,7 @@ void ShadowTreeStyleSheetCollection::CollectStyleSheets(
if (candidate.CanBeActivated(g_null_atom)) {
CSSStyleSheet* css_sheet = To<CSSStyleSheet>(sheet);
collection.AppendActiveStyleSheet(
- std::make_pair(css_sheet, master_engine.RuleSetForSheet(*css_sheet)));
+ std::make_pair(css_sheet, engine.RuleSetForSheet(*css_sheet)));
}
}
if (!GetTreeScope().HasAdoptedStyleSheets())
@@ -70,15 +70,15 @@ void ShadowTreeStyleSheetCollection::CollectStyleSheets(
continue;
DCHECK_EQ(GetTreeScope().GetDocument(), sheet->AssociatedDocument());
collection.AppendActiveStyleSheet(
- std::make_pair(sheet, master_engine.RuleSetForSheet(*sheet)));
+ std::make_pair(sheet, engine.RuleSetForSheet(*sheet)));
}
}
void ShadowTreeStyleSheetCollection::UpdateActiveStyleSheets(
- StyleEngine& master_engine) {
+ StyleEngine& engine) {
// StyleSheetCollection is GarbageCollected<>, allocate it on the heap.
auto* collection = MakeGarbageCollected<StyleSheetCollection>();
- CollectStyleSheets(master_engine, *collection);
+ CollectStyleSheets(engine, *collection);
ApplyActiveStyleSheetChanges(*collection);
}
diff --git a/chromium/third_party/blink/renderer/core/css/shadow_tree_style_sheet_collection.h b/chromium/third_party/blink/renderer/core/css/shadow_tree_style_sheet_collection.h
index 5a9cd376b13..d77f36702fa 100644
--- a/chromium/third_party/blink/renderer/core/css/shadow_tree_style_sheet_collection.h
+++ b/chromium/third_party/blink/renderer/core/css/shadow_tree_style_sheet_collection.h
@@ -44,15 +44,15 @@ class ShadowTreeStyleSheetCollection final
: public TreeScopeStyleSheetCollection {
public:
explicit ShadowTreeStyleSheetCollection(ShadowRoot&);
- void UpdateActiveStyleSheets(StyleEngine& master_engine);
+ void UpdateActiveStyleSheets(StyleEngine&);
bool IsShadowTreeStyleSheetCollection() const final { return true; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
TreeScopeStyleSheetCollection::Trace(visitor);
}
private:
- void CollectStyleSheets(StyleEngine& master_engine, StyleSheetCollection&);
+ void CollectStyleSheets(StyleEngine&, StyleSheetCollection&);
DISALLOW_COPY_AND_ASSIGN(ShadowTreeStyleSheetCollection);
};
diff --git a/chromium/third_party/blink/renderer/core/css/style-calculation.md b/chromium/third_party/blink/renderer/core/css/style-calculation.md
index f4d9f682c23..60553d48ecf 100644
--- a/chromium/third_party/blink/renderer/core/css/style-calculation.md
+++ b/chromium/third_party/blink/renderer/core/css/style-calculation.md
@@ -1,6 +1,6 @@
# CSS Style Calculation in Blink
-[Rendered](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/core/css/style-calculation.md)
+[Rendered](https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/renderer/core/css/style-calculation.md)
# About this document
@@ -36,13 +36,13 @@ The following are long-lived objects that remain static during the calculation
of each element's style.
* [`Element`](https://cs.chromium.org/?q=symbol:%5Eblink::Element$) See also
-[dom/README.md](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/core/dom/README.md)
+[dom/README.md](https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/renderer/core/dom/README.md)
* [`TreeScope`](https://cs.chromium.org/?q=symbol:%5Eblink::TreeScope$)
Represents a tree of elements for a document or shadow root. Gives fast access
to various things inside the tree of elements. Holds a
[`ScopedStyleResolver`](https://cs.chromium.org/?q=symbol:%5Eblink::ScopedStyleResolver$)
for this scope. See
-[dom/README.md](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/core/dom/README.md#treescope)
+[dom/README.md](https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/renderer/core/dom/README.md#treescope)
* [`StyleEngine`](https://cs.chromium.org/?q=symbol:%5Eblink::StyleEngine$)
* [`StyleResolver`](https://cs.chromium.org/?q=symbol:%5Eblink::StyleResolver$)
* [`ScopedStyleResolver`](https://cs.chromium.org/?q=symbol:%5Eblink::ScopedStyleResolver$)
diff --git a/chromium/third_party/blink/renderer/core/css/style-invalidation.md b/chromium/third_party/blink/renderer/core/css/style-invalidation.md
index 5e647a38625..f7b12201f3c 100644
--- a/chromium/third_party/blink/renderer/core/css/style-invalidation.md
+++ b/chromium/third_party/blink/renderer/core/css/style-invalidation.md
@@ -1,6 +1,6 @@
# CSS Style Invalidation in Blink
-[Rendered](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/core/css/style-invalidation.md)
+[Rendered](https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/renderer/core/css/style-invalidation.md)
# About this document
diff --git a/chromium/third_party/blink/renderer/core/css/style_color.h b/chromium/third_party/blink/renderer/core/css/style_color.h
index 0632d454a83..9ecb0972893 100644
--- a/chromium/third_party/blink/renderer/core/css/style_color.h
+++ b/chromium/third_party/blink/renderer/core/css/style_color.h
@@ -45,6 +45,8 @@ class StyleColor {
StyleColor() : color_keyword_(CSSValueID::kCurrentcolor) {}
StyleColor(Color color)
: color_(color), color_keyword_(CSSValueID::kInvalid) {}
+ explicit StyleColor(RGBA32 color)
+ : color_(color), color_keyword_(CSSValueID::kInvalid) {}
static StyleColor CurrentColor() { return StyleColor(); }
bool IsCurrentColor() const {
diff --git a/chromium/third_party/blink/renderer/core/css/style_element.cc b/chromium/third_party/blink/renderer/core/css/style_element.cc
index 52c653e7cff..39b26e7d509 100644
--- a/chromium/third_party/blink/renderer/core/css/style_element.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_element.cc
@@ -132,14 +132,16 @@ StyleElement::ProcessingResult StyleElement::CreateSheet(Element& element,
Document& document = element.GetDocument();
const ContentSecurityPolicy* csp =
- document.GetContentSecurityPolicyForWorld();
+ element.GetExecutionContext()
+ ? element.GetExecutionContext()->GetContentSecurityPolicyForWorld()
+ : nullptr;
// CSP is bypassed for style elements in user agent shadow DOM.
bool passes_content_security_policy_checks =
IsInUserAgentShadowDOM(element) ||
- csp->AllowInline(ContentSecurityPolicy::InlineType::kStyle, &element,
- text, element.nonce(), document.Url(),
- start_position_.line_);
+ (csp && csp->AllowInline(ContentSecurityPolicy::InlineType::kStyle,
+ &element, text, element.nonce(), document.Url(),
+ start_position_.line_));
// Clearing the current sheet may remove the cache entry so create the new
// sheet first
@@ -195,7 +197,7 @@ void StyleElement::StartLoadingDynamicSheet(Document& document) {
document.GetStyleEngine().AddPendingSheet(style_engine_context_);
}
-void StyleElement::Trace(Visitor* visitor) {
+void StyleElement::Trace(Visitor* visitor) const {
visitor->Trace(sheet_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/style_element.h b/chromium/third_party/blink/renderer/core/css/style_element.h
index bb39739da6b..9e20225458f 100644
--- a/chromium/third_party/blink/renderer/core/css/style_element.h
+++ b/chromium/third_party/blink/renderer/core/css/style_element.h
@@ -35,7 +35,7 @@ class CORE_EXPORT StyleElement : public GarbageCollectedMixin {
public:
StyleElement(Document*, bool created_by_parser);
virtual ~StyleElement();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
enum ProcessingResult { kProcessingSuccessful, kProcessingFatalError };
diff --git a/chromium/third_party/blink/renderer/core/css/style_engine.cc b/chromium/third_party/blink/renderer/core/css/style_engine.cc
index 3e91e19e1d9..0bbd60641ac 100644
--- a/chromium/third_party/blink/renderer/core/css/style_engine.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_engine.cc
@@ -75,6 +75,7 @@
#include "third_party/blink/renderer/core/html/imports/html_imports_controller.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
+#include "third_party/blink/renderer/core/layout/layout_theme.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/page_popup_controller.h"
@@ -108,7 +109,7 @@ CSSFontSelector* CreateCSSFontSelectorFor(Document& document) {
StyleEngine::StyleEngine(Document& document)
: document_(&document),
- is_master_(!document.IsHTMLImport()),
+ is_html_import_(document.IsHTMLImport()),
document_style_sheet_collection_(
MakeGarbageCollected<DocumentStyleSheetCollection>(document)) {
if (document.GetFrame()) {
@@ -119,7 +120,7 @@ StyleEngine::StyleEngine(Document& document)
}
if (document.IsInMainFrame())
viewport_resolver_ = MakeGarbageCollected<ViewportStyleResolver>(document);
- if (IsMaster())
+ if (!IsHTMLImport())
global_rule_set_ = MakeGarbageCollected<CSSGlobalRuleSet>();
if (auto* settings = GetDocument().GetSettings()) {
if (!settings->GetForceDarkModeEnabled())
@@ -127,19 +128,20 @@ StyleEngine::StyleEngine(Document& document)
}
if (Platform::Current() && Platform::Current()->ThemeEngine())
forced_colors_ = Platform::Current()->ThemeEngine()->GetForcedColors();
+ UpdateForcedBackgroundColor();
}
StyleEngine::~StyleEngine() = default;
-inline Document* StyleEngine::Master() {
- if (IsMaster())
+inline Document* StyleEngine::HTMLImportRootDocument() {
+ if (!IsHTMLImport())
return document_;
HTMLImportsController* import = GetDocument().ImportsController();
// Document::ImportsController() can return null while executing its
// destructor.
if (!import)
return nullptr;
- return import->Master();
+ return import->TreeRoot();
}
TreeScopeStyleSheetCollection& StyleEngine::EnsureStyleSheetCollectionFor(
@@ -171,21 +173,11 @@ TreeScopeStyleSheetCollection* StyleEngine::StyleSheetCollectionFor(
const HeapVector<Member<StyleSheet>>& StyleEngine::StyleSheetsForStyleSheetList(
TreeScope& tree_scope) {
- DCHECK(Master());
+ DCHECK(HTMLImportRootDocument());
TreeScopeStyleSheetCollection& collection =
EnsureStyleSheetCollectionFor(tree_scope);
- if (Master()->IsActive()) {
- if (all_tree_scopes_dirty_) {
- // If all tree scopes are dirty, update all of active style. Otherwise, we
- // would have to mark all tree scopes explicitly dirty for stylesheet list
- // or repeatedly update the stylesheet list on styleSheets access. Note
- // that this can only happen once if we kDidLayoutWithPendingSheets in
- // Document::UpdateStyleAndLayoutTreeIgnoringPendingStyleSheets.
- UpdateActiveStyle();
- } else {
- collection.UpdateStyleSheetList();
- }
- }
+ if (HTMLImportRootDocument()->IsActive())
+ collection.UpdateStyleSheetList();
return collection.StyleSheetsForStyleSheetList();
}
@@ -285,7 +277,7 @@ void StyleEngine::RemovePendingSheet(Node& style_sheet_candidate_node,
void StyleEngine::SetNeedsActiveStyleUpdate(TreeScope& tree_scope) {
DCHECK(tree_scope.RootNode().isConnected());
- if (GetDocument().IsActive() || !IsMaster())
+ if (GetDocument().IsActive() || IsHTMLImport())
MarkTreeScopeDirty(tree_scope);
}
@@ -440,7 +432,7 @@ void StyleEngine::MediaQueriesChangedInScope(TreeScope& tree_scope) {
}
void StyleEngine::WatchedSelectorsChanged() {
- DCHECK(IsMaster());
+ DCHECK(!IsHTMLImport());
DCHECK(global_rule_set_);
global_rule_set_->InitWatchedSelectorsRuleSet(GetDocument());
// TODO(futhark@chromium.org): Should be able to use RuleSetInvalidation here.
@@ -449,11 +441,11 @@ void StyleEngine::WatchedSelectorsChanged() {
}
bool StyleEngine::ShouldUpdateDocumentStyleSheetCollection() const {
- return all_tree_scopes_dirty_ || document_scope_dirty_;
+ return document_scope_dirty_;
}
bool StyleEngine::ShouldUpdateShadowTreeStyleSheetCollection() const {
- return all_tree_scopes_dirty_ || !dirty_tree_scopes_.IsEmpty();
+ return !dirty_tree_scopes_.IsEmpty();
}
void StyleEngine::MediaQueryAffectingValueChanged(
@@ -512,20 +504,18 @@ void StyleEngine::MediaQueryAffectingValueChanged(MediaValueChange change) {
}
void StyleEngine::UpdateActiveStyleSheetsInImport(
- StyleEngine& master_engine,
+ StyleEngine& root_engine,
DocumentStyleSheetCollector& parent_collector) {
- DCHECK(RuntimeEnabledFeatures::HTMLImportsEnabled(&GetDocument()));
- DCHECK(!IsMaster());
+ DCHECK(RuntimeEnabledFeatures::HTMLImportsEnabled(
+ GetDocument().GetExecutionContext()));
+ DCHECK(IsHTMLImport());
HeapVector<Member<StyleSheet>> sheets_for_list;
ImportedDocumentStyleSheetCollector subcollector(parent_collector,
sheets_for_list);
- GetDocumentStyleSheetCollection().CollectStyleSheets(master_engine,
+ GetDocumentStyleSheetCollection().CollectStyleSheets(root_engine,
subcollector);
GetDocumentStyleSheetCollection().SwapSheetsForSheetList(sheets_for_list);
- // all_tree_scopes_dirty_ should only be set on main documents, never html
- // imports.
- DCHECK(!all_tree_scopes_dirty_);
// Mark false for consistency. It is never checked for import documents.
document_scope_dirty_ = false;
}
@@ -564,7 +554,7 @@ void StyleEngine::UpdateActiveStyleSheets() {
if (!NeedsActiveStyleSheetUpdate())
return;
- DCHECK(IsMaster());
+ DCHECK(!IsHTMLImport());
DCHECK(!GetDocument().InStyleRecalc());
DCHECK(GetDocument().IsActive());
@@ -578,14 +568,8 @@ void StyleEngine::UpdateActiveStyleSheets() {
if (ShouldUpdateShadowTreeStyleSheetCollection()) {
UnorderedTreeScopeSet tree_scopes_removed;
-
- if (all_tree_scopes_dirty_) {
- for (TreeScope* tree_scope : active_tree_scopes_)
- UpdateActiveStyleSheetsInShadow(tree_scope, tree_scopes_removed);
- } else {
- for (TreeScope* tree_scope : dirty_tree_scopes_)
- UpdateActiveStyleSheetsInShadow(tree_scope, tree_scopes_removed);
- }
+ for (TreeScope* tree_scope : dirty_tree_scopes_)
+ UpdateActiveStyleSheetsInShadow(tree_scope, tree_scopes_removed);
for (TreeScope* tree_scope : tree_scopes_removed)
active_tree_scopes_.erase(tree_scope);
}
@@ -594,7 +578,6 @@ void StyleEngine::UpdateActiveStyleSheets() {
dirty_tree_scopes_.clear();
document_scope_dirty_ = false;
- all_tree_scopes_dirty_ = false;
tree_scopes_removed_ = false;
user_style_dirty_ = false;
}
@@ -703,7 +686,7 @@ void StyleEngine::CreateResolver() {
void StyleEngine::ClearResolvers() {
DCHECK(!GetDocument().InStyleRecalc());
- DCHECK(IsMaster() || !resolver_);
+ DCHECK(!IsHTMLImport() || !resolver_);
GetDocument().ClearScopedStyleResolver();
for (TreeScope* tree_scope : active_tree_scopes_)
@@ -801,7 +784,7 @@ void StyleEngine::MarkDocumentDirty() {
document_scope_dirty_ = true;
document_style_sheet_collection_->MarkSheetListDirty();
if (GetDocument().ImportLoader())
- GetDocument().MasterDocument().GetStyleEngine().MarkDocumentDirty();
+ GetDocument().TreeRootDocument().GetStyleEngine().MarkDocumentDirty();
else
GetDocument().ScheduleLayoutTreeUpdateIfNeeded();
}
@@ -902,18 +885,15 @@ void StyleEngine::InvalidateStyleAndLayoutForFontUpdates() {
TRACE_EVENT0("blink", "StyleEngine::InvalidateStyleAndLayoutForFontUpdates");
fonts_need_update_ = false;
- Element* root = GetDocument().documentElement();
- if (!root)
- return;
- {
+ if (Element* root = GetDocument().documentElement()) {
TRACE_EVENT0("blink", "Node::MarkSubtreeNeedsStyleRecalcForFontUpdates");
root->MarkSubtreeNeedsStyleRecalcForFontUpdates();
}
- if (LayoutObject* root_object = root->GetLayoutObject()) {
+ if (LayoutView* layout_view = GetDocument().GetLayoutView()) {
TRACE_EVENT0("blink", "LayoutObject::InvalidateSubtreeForFontUpdates");
- root_object->InvalidateSubtreeLayoutForFontUpdates();
+ layout_view->InvalidateSubtreeLayoutForFontUpdates();
}
}
@@ -942,6 +922,7 @@ void StyleEngine::FontsNeedUpdate(FontSelector*, FontInvalidationReason) {
}
void StyleEngine::PlatformColorsChanged() {
+ UpdateForcedBackgroundColor();
if (resolver_)
resolver_->InvalidateMatchedPropertiesCache();
MarkAllElementsForStyleRecalc(StyleChangeReasonForTracing::Create(
@@ -1400,7 +1381,7 @@ void StyleEngine::SetHttpDefaultStyle(const String& content) {
}
void StyleEngine::EnsureUAStyleForXrOverlay() {
- DCHECK(IsMaster());
+ DCHECK(!IsHTMLImport());
DCHECK(global_rule_set_);
if (CSSDefaultStyleSheets::Instance().EnsureDefaultStyleSheetForXrOverlay()) {
global_rule_set_->MarkDirty();
@@ -1409,7 +1390,7 @@ void StyleEngine::EnsureUAStyleForXrOverlay() {
}
void StyleEngine::EnsureUAStyleForFullscreen() {
- DCHECK(IsMaster());
+ DCHECK(!IsHTMLImport());
DCHECK(global_rule_set_);
if (global_rule_set_->HasFullscreenUAStyle())
return;
@@ -1419,7 +1400,7 @@ void StyleEngine::EnsureUAStyleForFullscreen() {
}
void StyleEngine::EnsureUAStyleForElement(const Element& element) {
- DCHECK(IsMaster());
+ DCHECK(!IsHTMLImport());
DCHECK(global_rule_set_);
if (CSSDefaultStyleSheets::Instance().EnsureDefaultStyleSheetsForElement(
element)) {
@@ -1428,8 +1409,18 @@ void StyleEngine::EnsureUAStyleForElement(const Element& element) {
}
}
+void StyleEngine::EnsureUAStyleForPseudoElement(PseudoId pseudo_id) {
+ DCHECK(!IsHTMLImport());
+ DCHECK(global_rule_set_);
+ if (CSSDefaultStyleSheets::Instance()
+ .EnsureDefaultStyleSheetsForPseudoElement(pseudo_id)) {
+ global_rule_set_->MarkDirty();
+ UpdateActiveStyle();
+ }
+}
+
bool StyleEngine::HasRulesForId(const AtomicString& id) const {
- DCHECK(IsMaster());
+ DCHECK(!IsHTMLImport());
DCHECK(global_rule_set_);
return global_rule_set_->GetRuleFeatureSet().HasSelectorForId(id);
}
@@ -1458,7 +1449,10 @@ void StyleEngine::ViewportRulesChanged() {
void StyleEngine::HtmlImportAddedOrRemoved() {
if (GetDocument().ImportLoader()) {
- GetDocument().MasterDocument().GetStyleEngine().HtmlImportAddedOrRemoved();
+ GetDocument()
+ .TreeRootDocument()
+ .GetStyleEngine()
+ .HtmlImportAddedOrRemoved();
return;
}
@@ -1555,7 +1549,7 @@ void StyleEngine::InvalidateInitialData() {
void StyleEngine::ApplyUserRuleSetChanges(
const ActiveStyleSheetVector& old_style_sheets,
const ActiveStyleSheetVector& new_style_sheets) {
- DCHECK(IsMaster());
+ DCHECK(!IsHTMLImport());
DCHECK(global_rule_set_);
HeapHashSet<Member<RuleSet>> changed_rule_sets;
@@ -1596,6 +1590,19 @@ void StyleEngine::ApplyUserRuleSetChanges(
ScopedStyleResolver::KeyframesRulesAdded(GetDocument());
}
+ if (changed_rule_flags & kPropertyRules) {
+ ClearPropertyRules();
+ AddPropertyRulesFromSheets(new_style_sheets);
+
+ // We just cleared all the rules, which includes any author rules. They
+ // must be forcibly re-added.
+ if (ScopedStyleResolver* scoped_resolver =
+ GetDocument().GetScopedStyleResolver()) {
+ scoped_resolver->SetNeedsAppendAllSheets();
+ MarkDocumentDirty();
+ }
+ }
+
if ((changed_rule_flags & kFontFaceRules) || has_rebuilt_font_face_cache) {
GetFontSelector()->FontFaceInvalidated(
FontInvalidationReason::kGeneralInvalidation);
@@ -1609,7 +1616,7 @@ void StyleEngine::ApplyRuleSetChanges(
TreeScope& tree_scope,
const ActiveStyleSheetVector& old_style_sheets,
const ActiveStyleSheetVector& new_style_sheets) {
- DCHECK(IsMaster());
+ DCHECK(!IsHTMLImport());
DCHECK(global_rule_set_);
HeapHashSet<Member<RuleSet>> changed_rule_sets;
@@ -1621,9 +1628,11 @@ void StyleEngine::ApplyRuleSetChanges(
bool rebuild_font_face_cache = change == kActiveSheetsChanged &&
(changed_rule_flags & kFontFaceRules) &&
tree_scope.RootNode().IsDocumentNode();
+ bool rebuild_at_property_registry = false;
ScopedStyleResolver* scoped_resolver = tree_scope.GetScopedStyleResolver();
if (scoped_resolver && scoped_resolver->NeedsAppendAllSheets()) {
rebuild_font_face_cache = true;
+ rebuild_at_property_registry = true;
change = kActiveSheetsChanged;
}
@@ -1636,17 +1645,13 @@ void StyleEngine::ApplyRuleSetChanges(
if (changed_rule_flags & kKeyframesRules)
ScopedStyleResolver::KeyframesRulesAdded(tree_scope);
- if (changed_rule_flags & kPropertyRules) {
+ if ((changed_rule_flags & kPropertyRules) || rebuild_at_property_registry) {
// @property rules are (for now) ignored in shadow trees, per spec.
// https://drafts.css-houdini.org/css-properties-values-api-1/#at-property-rule
if (tree_scope.RootNode().IsDocumentNode()) {
- PropertyRegistration::RemoveDeclaredProperties(GetDocument());
-
- for (auto* it = new_style_sheets.begin(); it != new_style_sheets.end();
- it++) {
- DCHECK(it->second);
- AddPropertyRules(*it->second);
- }
+ ClearPropertyRules();
+ AddPropertyRulesFromSheets(active_user_style_sheets_);
+ AddPropertyRulesFromSheets(new_style_sheets);
}
}
@@ -1734,7 +1739,7 @@ const MediaQueryEvaluator& StyleEngine::EnsureMediaQueryEvaluator() {
}
bool StyleEngine::MediaQueryAffectedByViewportChange() {
- DCHECK(IsMaster());
+ DCHECK(!IsHTMLImport());
DCHECK(global_rule_set_);
return EnsureMediaQueryEvaluator().DidResultsChange(
global_rule_set_->GetRuleFeatureSet()
@@ -1742,7 +1747,7 @@ bool StyleEngine::MediaQueryAffectedByViewportChange() {
}
bool StyleEngine::MediaQueryAffectedByDeviceChange() {
- DCHECK(IsMaster());
+ DCHECK(!IsHTMLImport());
DCHECK(global_rule_set_);
return EnsureMediaQueryEvaluator().DidResultsChange(
global_rule_set_->GetRuleFeatureSet().DeviceDependentMediaQueryResults());
@@ -1857,6 +1862,18 @@ void StyleEngine::CollectMatchingUserRules(
}
}
+void StyleEngine::ClearPropertyRules() {
+ PropertyRegistration::RemoveDeclaredProperties(GetDocument());
+}
+
+void StyleEngine::AddPropertyRulesFromSheets(
+ const ActiveStyleSheetVector& sheets) {
+ for (const ActiveStyleSheet& active_sheet : sheets) {
+ if (RuleSet* rule_set = active_sheet.second)
+ AddPropertyRules(*rule_set);
+ }
+}
+
bool StyleEngine::AddUserFontFaceRules(const RuleSet& rule_set) {
if (!font_selector_)
return false;
@@ -2035,21 +2052,12 @@ void StyleEngine::ViewportDefiningElementDidChange() {
// ViewportDefiningElement changes in order to trigger an update of
// HasOverflowClip() and the PaintLayer in StyleDidChange().
layout_object->SetStyle(ComputedStyle::Clone(*layout_object->Style()));
- // CompositingReason::kClipsCompositingDescendants depends on the root
- // element having a clip-related style. Since style update due to changes of
- // viewport-defining element don't end up as a StyleDifference, we need a
- // special dirty bit for this situation.
- if (layout_object->HasLayer()) {
- ToLayoutBoxModelObject(layout_object)
- ->Layer()
- ->SetNeedsCompositingReasonsUpdate();
- }
}
}
void StyleEngine::UpdateStyleInvalidationRoot(ContainerNode* ancestor,
Node* dirty_node) {
- DCHECK(IsMaster());
+ DCHECK(!IsHTMLImport());
if (GetDocument().IsActive()) {
if (in_dom_removal_) {
ancestor = nullptr;
@@ -2081,15 +2089,20 @@ void StyleEngine::UpdateLayoutTreeRebuildRoot(ContainerNode* ancestor,
bool StyleEngine::SupportsDarkColorScheme() {
if (!meta_color_scheme_)
return false;
+ bool has_light = false;
+ bool has_dark = false;
if (const auto* scheme_list = DynamicTo<CSSValueList>(*meta_color_scheme_)) {
for (auto& item : *scheme_list) {
if (const auto* ident = DynamicTo<CSSIdentifierValue>(*item)) {
if (ident->GetValueID() == CSSValueID::kDark)
- return true;
+ has_dark = true;
+ else if (ident->GetValueID() == CSSValueID::kLight)
+ has_light = true;
}
}
}
- return false;
+ return has_dark &&
+ (!has_light || preferred_color_scheme_ == PreferredColorScheme::kDark);
}
void StyleEngine::UpdateColorScheme() {
@@ -2110,19 +2123,21 @@ void StyleEngine::UpdateColorScheme() {
if (value.IsValid())
preferred_color_scheme_ = CSSValueIDToPreferredColorScheme(value.id);
}
- bool use_dark_scheme =
- preferred_color_scheme_ == PreferredColorScheme::kDark &&
- SupportsDarkColorScheme();
- if (!use_dark_scheme && settings->GetForceDarkModeEnabled()) {
+ if (!SupportsDarkColorScheme() && settings->GetForceDarkModeEnabled()) {
// Make sure we don't match (prefers-color-scheme: dark) when forced
// darkening is enabled.
- preferred_color_scheme_ = PreferredColorScheme::kNoPreference;
+ preferred_color_scheme_ = PreferredColorScheme::kLight;
}
+ if (GetDocument().Printing())
+ preferred_color_scheme_ = PreferredColorScheme::kLight;
+ bool color_scheme_changed = false;
if (forced_colors_ != old_forced_colors ||
- preferred_color_scheme_ != old_preferred_color_scheme)
+ preferred_color_scheme_ != old_preferred_color_scheme) {
PlatformColorsChanged();
- UpdateColorSchemeBackground();
+ color_scheme_changed = true;
+ }
+ UpdateColorSchemeBackground(color_scheme_changed);
}
void StyleEngine::ColorSchemeChanged() {
@@ -2138,27 +2153,44 @@ void StyleEngine::SetColorSchemeFromMeta(const CSSValue* color_scheme) {
UpdateColorScheme();
}
-void StyleEngine::UpdateColorSchemeBackground() {
+void StyleEngine::UpdateColorSchemeBackground(bool color_scheme_changed) {
LocalFrameView* view = GetDocument().View();
if (!view)
return;
- bool use_dark_background = false;
+ bool use_color_adjust_background = false;
+ use_dark_background_ = false;
- if (preferred_color_scheme_ == PreferredColorScheme::kDark &&
- forced_colors_ != ForcedColors::kActive) {
+ if (forced_colors_ != ForcedColors::kNone) {
+ use_color_adjust_background = true;
+ } else {
const ComputedStyle* style = nullptr;
if (auto* root_element = GetDocument().documentElement())
style = root_element->GetComputedStyle();
if (style) {
if (style->UsedColorSchemeForInitialColors() == WebColorScheme::kDark)
- use_dark_background = true;
+ use_dark_background_ = true;
} else if (SupportsDarkColorScheme()) {
- use_dark_background = true;
+ use_dark_background_ = true;
}
}
- view->SetUseDarkSchemeBackground(use_dark_background);
+ use_color_adjust_background |= use_dark_background_;
+ view->SetUseColorAdjustBackground(use_color_adjust_background,
+ color_scheme_changed);
+}
+
+void StyleEngine::UpdateForcedBackgroundColor() {
+ forced_background_color_ = LayoutTheme::GetTheme().SystemColor(
+ CSSValueID::kCanvas, WebColorScheme::kLight);
+}
+
+Color StyleEngine::ColorAdjustBackgroundColor() const {
+ if (use_dark_background_ && forced_colors_ == ForcedColors::kNone)
+ return Color::kBlack;
+
+ DCHECK(forced_colors_ != ForcedColors::kNone);
+ return ForcedBackgroundColor();
}
void StyleEngine::MarkAllElementsForStyleRecalc(
@@ -2199,7 +2231,7 @@ void StyleEngine::PropagateWritingModeAndDirectionToHTMLRoot() {
root_element->PropagateWritingModeAndDirectionFromBody();
}
-void StyleEngine::Trace(Visitor* visitor) {
+void StyleEngine::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(injected_user_style_sheets_);
visitor->Trace(injected_author_style_sheets_);
diff --git a/chromium/third_party/blink/renderer/core/css/style_engine.h b/chromium/third_party/blink/renderer/core/css/style_engine.h
index 4fb115318de..4b2e42ffcc4 100644
--- a/chromium/third_party/blink/renderer/core/css/style_engine.h
+++ b/chromium/third_party/blink/renderer/core/css/style_engine.h
@@ -147,7 +147,7 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
WebDocument::kAuthorOrigin);
CSSStyleSheet& EnsureInspectorStyleSheet();
RuleSet* WatchedSelectorsRuleSet() {
- DCHECK(IsMaster());
+ DCHECK(!IsHTMLImport());
DCHECK(global_rule_set_);
return global_rule_set_->WatchedSelectorsRuleSet();
}
@@ -158,10 +158,9 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
RuleSet* RuleSetForSheet(CSSStyleSheet&);
void MediaQueryAffectingValueChanged(MediaValueChange change);
void UpdateActiveStyleSheetsInImport(
- StyleEngine& master_engine,
+ StyleEngine& root_engine,
DocumentStyleSheetCollector& parent_collector);
void UpdateActiveStyle();
- void MarkAllTreeScopesDirty() { all_tree_scopes_dirty_ = true; }
String PreferredStylesheetSetName() const {
return preferred_stylesheet_set_name_;
@@ -232,7 +231,7 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
bool MediaQueryAffectedByViewportChange();
bool MediaQueryAffectedByDeviceChange();
bool HasViewportDependentMediaQueries() {
- DCHECK(IsMaster());
+ DCHECK(!IsHTMLImport());
DCHECK(global_rule_set_);
UpdateActiveStyle();
return !global_rule_set_->GetRuleFeatureSet()
@@ -271,6 +270,7 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
void EnsureUAStyleForFullscreen();
void EnsureUAStyleForXrOverlay();
void EnsureUAStyleForElement(const Element&);
+ void EnsureUAStyleForPseudoElement(PseudoId);
void PlatformColorsChanged();
@@ -382,9 +382,11 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
return preferred_color_scheme_;
}
ForcedColors GetForcedColors() const { return forced_colors_; }
- void UpdateColorSchemeBackground();
+ void UpdateColorSchemeBackground(bool color_scheme_changed = false);
+ Color ForcedBackgroundColor() const { return forced_background_color_; }
+ Color ColorAdjustBackgroundColor() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override { return "StyleEngine"; }
private:
@@ -395,9 +397,8 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
private:
bool NeedsActiveStyleSheetUpdate() const {
- return all_tree_scopes_dirty_ || tree_scopes_removed_ ||
- document_scope_dirty_ || dirty_tree_scopes_.size() ||
- user_style_dirty_;
+ return tree_scopes_removed_ || document_scope_dirty_ ||
+ dirty_tree_scopes_.size() || user_style_dirty_;
}
TreeScopeStyleSheetCollection& EnsureStyleSheetCollectionFor(TreeScope&);
@@ -409,8 +410,8 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
void MarkTreeScopeDirty(TreeScope&);
void MarkUserStyleDirty();
- bool IsMaster() const { return is_master_; }
- Document* Master();
+ bool IsHTMLImport() const { return is_html_import_; }
+ Document* HTMLImportRootDocument();
Document& GetDocument() const { return *document_; }
typedef HeapHashSet<Member<TreeScope>> UnorderedTreeScopeSet;
@@ -424,7 +425,7 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
MediaValueChange);
const RuleFeatureSet& GetRuleFeatureSet() const {
- DCHECK(IsMaster());
+ DCHECK(!IsHTMLImport());
DCHECK(global_rule_set_);
return global_rule_set_->GetRuleFeatureSet();
}
@@ -484,6 +485,8 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
void ClearKeyframeRules() { keyframes_rule_map_.clear(); }
void ClearPropertyRules();
+ void AddPropertyRulesFromSheets(const ActiveStyleSheetVector&);
+
// Returns true if any @font-face rules are added.
bool AddUserFontFaceRules(const RuleSet&);
void AddUserKeyframeRules(const RuleSet&);
@@ -492,12 +495,15 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
void UpdateColorScheme();
bool SupportsDarkColorScheme();
+ void UpdateForcedBackgroundColor();
void ViewportDefiningElementDidChange();
void PropagateWritingModeAndDirectionToHTMLRoot();
Member<Document> document_;
- bool is_master_;
+
+ // True if this StyleEngine is for an HTML Import document.
+ bool is_html_import_ = false;
// Tracks the number of currently loading top-level stylesheets. Sheets loaded
// using the @import directive are not included in this count. We use this
@@ -535,7 +541,6 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
StyleSheetCollectionMap style_sheet_collection_map_;
bool document_scope_dirty_ = true;
- bool all_tree_scopes_dirty_ = false;
bool tree_scopes_removed_ = false;
bool user_style_dirty_ = false;
UnorderedTreeScopeSet dirty_tree_scopes_;
@@ -603,12 +608,13 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
// The preferred color scheme is set in settings, but may be overridden by the
// ForceDarkMode setting where the preferred_color_scheme_ will be set to
- // kNoPreference to avoid dark styling to be applied before auto darkening.
- PreferredColorScheme preferred_color_scheme_ =
- PreferredColorScheme::kNoPreference;
+ // kLight to avoid dark styling to be applied before auto darkening.
+ PreferredColorScheme preferred_color_scheme_ = PreferredColorScheme::kLight;
+ bool use_dark_background_ = false;
// Forced colors is set in WebThemeEngine.
ForcedColors forced_colors_ = ForcedColors::kNone;
+ Color forced_background_color_;
friend class NodeTest;
friend class StyleEngineTest;
diff --git a/chromium/third_party/blink/renderer/core/css/style_engine_test.cc b/chromium/third_party/blink/renderer/core/css/style_engine_test.cc
index d8b6e717efa..856333ec309 100644
--- a/chromium/third_party/blink/renderer/core/css/style_engine_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -21,6 +21,7 @@
#include "third_party/blink/renderer/core/css/css_style_sheet.h"
#include "third_party/blink/renderer/core/css/css_test_helpers.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
+#include "third_party/blink/renderer/core/css/properties/css_property_ref.h"
#include "third_party/blink/renderer/core/css/style_sheet_contents.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/first_letter_pseudo_element.h"
@@ -36,12 +37,14 @@
#include "third_party/blink/renderer/core/html/html_span_element.h"
#include "third_party/blink/renderer/core/html/html_style_element.h"
#include "third_party/blink/renderer/core/layout/layout_text_fragment.h"
+#include "third_party/blink/renderer/core/layout/layout_theme.h"
#include "third_party/blink/renderer/core/page/viewport_description.h"
#include "third_party/blink/renderer/core/testing/color_scheme_helper.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
+#include "third_party/blink/renderer/platform/network/network_state_notifier.h"
namespace blink {
@@ -72,6 +75,22 @@ class StyleEngineTest : public testing::Test {
return GetStyleEngine().style_recalc_root_.GetRootNode();
}
+ const CSSValue* ComputedValue(Element* element, String property_name) {
+ CSSPropertyRef ref(property_name, GetDocument());
+ DCHECK(ref.IsValid());
+ return ref.GetProperty().CSSValueFromComputedStyle(
+ element->ComputedStyleRef(),
+ /* layout_object */ nullptr,
+ /* allow_visited_style */ false);
+ }
+
+ void InjectSheet(String key, WebDocument::CSSOrigin origin, String text) {
+ auto* context = MakeGarbageCollected<CSSParserContext>(GetDocument());
+ auto* sheet = MakeGarbageCollected<StyleSheetContents>(context);
+ sheet->ParseString(text);
+ GetStyleEngine().InjectSheet(StyleSheetKey(key), sheet, origin);
+ }
+
private:
std::unique_ptr<DummyPageHolder> dummy_page_holder_;
};
@@ -88,8 +107,9 @@ StyleEngineTest::ScheduleInvalidationsForRules(TreeScope& tree_scope,
kHTMLStandardMode, SecureContextMode::kInsecureContext));
sheet->ParseString(css_text);
HeapHashSet<Member<RuleSet>> rule_sets;
- RuleSet& rule_set = sheet->EnsureRuleSet(MediaQueryEvaluator(),
- kRuleHasDocumentSecurityOrigin);
+ RuleSet& rule_set =
+ sheet->EnsureRuleSet(MediaQueryEvaluator(GetDocument().GetFrame()),
+ kRuleHasDocumentSecurityOrigin);
rule_set.CompactRulesIfNeeded();
if (rule_set.NeedsFullRecalcForRuleSetInvalidation())
return kRuleSetInvalidationFullRecalc;
@@ -1020,7 +1040,7 @@ TEST_F(StyleEngineTest, VisitedExplicitInheritanceMatchedPropertiesCache) {
Element* span = GetDocument().getElementById("span");
const ComputedStyle* style = span->GetComputedStyle();
- EXPECT_FALSE(style->HasExplicitlyInheritedProperties());
+ EXPECT_FALSE(style->ChildHasExplicitInheritance());
style = span->firstChild()->GetComputedStyle();
EXPECT_TRUE(MatchedPropertiesCache::IsStyleCacheable(*style));
@@ -1162,10 +1182,6 @@ TEST_F(StyleEngineTest, StyleSheetsForStyleSheetList_Document) {
GetStyleEngine().StyleSheetsForStyleSheetList(GetDocument());
EXPECT_EQ(2u, second_sheet_list.size());
EXPECT_TRUE(GetStyleEngine().NeedsActiveStyleUpdate());
-
- GetStyleEngine().MarkAllTreeScopesDirty();
- GetStyleEngine().StyleSheetsForStyleSheetList(GetDocument());
- EXPECT_FALSE(GetStyleEngine().NeedsActiveStyleUpdate());
}
TEST_F(StyleEngineTest, StyleSheetsForStyleSheetList_ShadowRoot) {
@@ -1193,10 +1209,6 @@ TEST_F(StyleEngineTest, StyleSheetsForStyleSheetList_ShadowRoot) {
GetStyleEngine().StyleSheetsForStyleSheetList(shadow_root);
EXPECT_EQ(2u, second_sheet_list.size());
EXPECT_TRUE(GetStyleEngine().NeedsActiveStyleUpdate());
-
- GetStyleEngine().MarkAllTreeScopesDirty();
- GetStyleEngine().StyleSheetsForStyleSheetList(shadow_root);
- EXPECT_FALSE(GetStyleEngine().NeedsActiveStyleUpdate());
}
class StyleEngineClient : public frame_test_helpers::TestWebWidgetClient {
@@ -1517,7 +1529,7 @@ TEST_F(StyleEngineTest, MediaQueriesChangeColorSchemeForcedDarkMode) {
GetDocument().body()->setInnerHTML(R"HTML(
<style>
- @media (prefers-color-scheme: no-preference) {
+ @media (prefers-color-scheme: light) {
body { color: green }
}
@media (prefers-color-scheme: dark) {
@@ -1556,6 +1568,48 @@ TEST_F(StyleEngineTest, MediaQueriesChangePrefersReducedMotion) {
GetCSSPropertyColor()));
}
+TEST_F(StyleEngineTest, MediaQueriesChangePrefersReducedDataOn) {
+ GetNetworkStateNotifier().SetSaveDataEnabled(true);
+
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <style>
+ body { color: red }
+ @media (prefers-reduced-data: reduce) {
+ body { color: green }
+ }
+ </style>
+ <body></body>
+ )HTML");
+
+ UpdateAllLifecyclePhases();
+
+ EXPECT_TRUE(GetNetworkStateNotifier().SaveDataEnabled());
+ EXPECT_EQ(MakeRGB(0, 128, 0),
+ GetDocument().body()->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+}
+
+TEST_F(StyleEngineTest, MediaQueriesChangePrefersReducedDataOff) {
+ GetNetworkStateNotifier().SetSaveDataEnabled(false);
+
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <style>
+ body { color: red }
+ @media (prefers-reduced-data: reduce) {
+ body { color: green }
+ }
+ </style>
+ <body></body>
+ )HTML");
+
+ UpdateAllLifecyclePhases();
+
+ EXPECT_FALSE(GetNetworkStateNotifier().SaveDataEnabled());
+ EXPECT_EQ(MakeRGB(255, 0, 0),
+ GetDocument().body()->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+}
+
TEST_F(StyleEngineTest, MediaQueriesChangeForcedColors) {
ScopedForcedColorsForTest scoped_feature(true);
GetDocument().body()->setInnerHTML(R"HTML(
@@ -1599,9 +1653,6 @@ TEST_F(StyleEngineTest, MediaQueriesChangeForcedColorsAndPreferredColorScheme) {
@media (forced-colors: none) and (prefers-color-scheme: dark) {
body { color: green }
}
- @media (forced-colors: active) and (prefers-color-scheme: no-preference) {
- body { color: yellow }
- }
@media (forced-colors: active) and (prefers-color-scheme: dark) {
body { color: orange }
}
@@ -1635,14 +1686,6 @@ TEST_F(StyleEngineTest, MediaQueriesChangeForcedColorsAndPreferredColorScheme) {
GetDocument().body()->GetComputedStyle()->VisitedDependentColor(
GetCSSPropertyColor()));
- // ForcedColors = kActive, PreferredColorScheme = kNoPreference
- color_scheme_helper.SetPreferredColorScheme(
- PreferredColorScheme::kNoPreference);
- UpdateAllLifecyclePhases();
- EXPECT_EQ(MakeRGB(255, 255, 0),
- GetDocument().body()->GetComputedStyle()->VisitedDependentColor(
- GetCSSPropertyColor()));
-
// ForcedColors = kActive, PreferredColorScheme = kLight
color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kLight);
UpdateAllLifecyclePhases();
@@ -2125,6 +2168,14 @@ TEST_F(StyleEngineTest, ColorSchemeBaseBackgroundChange) {
UpdateAllLifecyclePhases();
EXPECT_EQ(Color::kBlack, GetDocument().View()->BaseBackgroundColor());
+
+ color_scheme_helper.SetForcedColors(GetDocument(), ForcedColors::kActive);
+ UpdateAllLifecyclePhases();
+ Color system_background_color = LayoutTheme::GetTheme().SystemColor(
+ CSSValueID::kCanvas, WebColorScheme::kLight);
+
+ EXPECT_EQ(system_background_color,
+ GetDocument().View()->BaseBackgroundColor());
}
TEST_F(StyleEngineTest, ColorSchemeOverride) {
@@ -2660,6 +2711,145 @@ TEST_F(StyleEngineTest, RevertUseCount) {
EXPECT_TRUE(GetDocument().IsUseCounted(WebFeature::kCSSKeywordRevert));
}
+TEST_F(StyleEngineTest, PrintNoDarkColorScheme) {
+ ColorSchemeHelper color_scheme_helper(GetDocument());
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
+
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <style>
+ :root { color-scheme: light dark }
+ @media (prefers-color-scheme: light) {
+ body { color: green; }
+ }
+ @media (prefers-color-scheme: dark) {
+ body { color: red; }
+ }
+ </style>
+ )HTML");
+ UpdateAllLifecyclePhases();
+ Element* body = GetDocument().body();
+ Element* root = GetDocument().documentElement();
+
+ EXPECT_EQ(Color::kWhite, root->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+ EXPECT_EQ(WebColorScheme::kDark,
+ root->GetComputedStyle()->UsedColorSchemeForInitialColors());
+ EXPECT_EQ(MakeRGB(255, 0, 0), body->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+
+ FloatSize page_size(400, 400);
+ GetDocument().GetFrame()->StartPrinting(page_size, page_size, 1);
+ EXPECT_EQ(Color::kBlack, root->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+ EXPECT_EQ(WebColorScheme::kLight,
+ root->GetComputedStyle()->UsedColorSchemeForInitialColors());
+ EXPECT_EQ(MakeRGB(0, 128, 0), body->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+
+ GetDocument().GetFrame()->EndPrinting();
+ EXPECT_EQ(Color::kWhite, root->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+ EXPECT_EQ(WebColorScheme::kDark,
+ root->GetComputedStyle()->UsedColorSchemeForInitialColors());
+ EXPECT_EQ(MakeRGB(255, 0, 0), body->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+}
+
+TEST_F(StyleEngineTest, AtPropertyUseCount) {
+ ScopedCSSVariables2AtPropertyForTest scoped_feature(true);
+
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <style>
+ body { --x: No @property rule here; }
+ </style>
+ )HTML");
+ UpdateAllLifecyclePhases();
+ EXPECT_FALSE(GetDocument().IsUseCounted(WebFeature::kCSSAtRuleProperty));
+
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <style>
+ @property --x {
+ syntax: "<length>";
+ inherits: false;
+ initial-value: 0px;
+ }
+ </style>
+ )HTML");
+ UpdateAllLifecyclePhases();
+ EXPECT_TRUE(GetDocument().IsUseCounted(WebFeature::kCSSAtRuleProperty));
+}
+
+TEST_F(StyleEngineTest, AtScrollTimelineUseCount) {
+ ScopedCSSScrollTimelineForTest scoped_feature(true);
+
+ GetDocument().body()->setInnerHTML("<div>No @scroll-timline</div>");
+ UpdateAllLifecyclePhases();
+ EXPECT_FALSE(
+ GetDocument().IsUseCounted(WebFeature::kCSSAtRuleScrollTimeline));
+
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <style>
+ @scroll-timeline foo { }
+ </style>
+ )HTML");
+ UpdateAllLifecyclePhases();
+ EXPECT_TRUE(GetDocument().IsUseCounted(WebFeature::kCSSAtRuleScrollTimeline));
+}
+
+TEST_F(StyleEngineTest, MediaQueryAffectedByViewportSanityCheck) {
+ GetDocument().body()->setInnerHTML("<audio controls>");
+ UpdateAllLifecyclePhases();
+ EXPECT_FALSE(GetStyleEngine().MediaQueryAffectedByViewportChange());
+}
+
+TEST_F(StyleEngineTest, RemoveDeclaredPropertiesEmptyRegistry) {
+ ScopedCSSVariables2AtPropertyForTest scoped_feature(true);
+
+ EXPECT_FALSE(GetDocument().GetPropertyRegistry());
+ PropertyRegistration::RemoveDeclaredProperties(GetDocument());
+ EXPECT_FALSE(GetDocument().GetPropertyRegistry());
+}
+
+TEST_F(StyleEngineTest, AtPropertyInUserOrigin) {
+ // @property in the user origin:
+ InjectSheet("user1", WebDocument::kUserOrigin, R"CSS(
+ @property --x {
+ syntax: "<length>";
+ inherits: false;
+ initial-value: 10px;
+ }
+ )CSS");
+ UpdateAllLifecyclePhases();
+ ASSERT_TRUE(ComputedValue(GetDocument().body(), "--x"));
+ EXPECT_EQ("10px", ComputedValue(GetDocument().body(), "--x")->CssText());
+
+ // @property in the author origin (should win over user origin)
+ InjectSheet("author", WebDocument::kAuthorOrigin, R"CSS(
+ @property --x {
+ syntax: "<length>";
+ inherits: false;
+ initial-value: 20px;
+ }
+ )CSS");
+ UpdateAllLifecyclePhases();
+ ASSERT_TRUE(ComputedValue(GetDocument().body(), "--x"));
+ EXPECT_EQ("20px", ComputedValue(GetDocument().body(), "--x")->CssText());
+
+ // An additional @property in the user origin:
+ InjectSheet("user2", WebDocument::kUserOrigin, R"CSS(
+ @property --y {
+ syntax: "<length>";
+ inherits: false;
+ initial-value: 30px;
+ }
+ )CSS");
+ UpdateAllLifecyclePhases();
+ ASSERT_TRUE(ComputedValue(GetDocument().body(), "--x"));
+ ASSERT_TRUE(ComputedValue(GetDocument().body(), "--y"));
+ EXPECT_EQ("20px", ComputedValue(GetDocument().body(), "--x")->CssText());
+ EXPECT_EQ("30px", ComputedValue(GetDocument().body(), "--y")->CssText());
+}
+
class ParameterizedStyleEngineTest
: public testing::WithParamInterface<bool>,
private ScopedCSSReducedFontLoadingInvalidationsForTest,
diff --git a/chromium/third_party/blink/renderer/core/css/style_environment_variables.cc b/chromium/third_party/blink/renderer/core/css/style_environment_variables.cc
index f7b97c8209a..39cb56934c7 100644
--- a/chromium/third_party/blink/renderer/core/css/style_environment_variables.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_environment_variables.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/css/style_environment_variables.h"
#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
@@ -12,6 +13,8 @@ namespace {
// This is the default value for all safe-area-inset-* variables.
static const char kSafeAreaInsetDefault[] = "0px";
+// This is the default value for all keyboard-inset-* variables.
+static const char kKeyboardInsetDefault[] = "0px";
// Use this to set default values for environment variables when the root
// instance is created.
@@ -24,6 +27,16 @@ void SetDefaultEnvironmentVariables(StyleEnvironmentVariables* instance) {
kSafeAreaInsetDefault);
instance->SetVariable(UADefinedVariable::kSafeAreaInsetRight,
kSafeAreaInsetDefault);
+ if (RuntimeEnabledFeatures::VirtualKeyboardEnabled()) {
+ instance->SetVariable(UADefinedVariable::kKeyboardInsetTop,
+ kKeyboardInsetDefault);
+ instance->SetVariable(UADefinedVariable::kKeyboardInsetLeft,
+ kKeyboardInsetDefault);
+ instance->SetVariable(UADefinedVariable::kKeyboardInsetBottom,
+ kKeyboardInsetDefault);
+ instance->SetVariable(UADefinedVariable::kKeyboardInsetRight,
+ kKeyboardInsetDefault);
+ }
}
} // namespace.
@@ -62,6 +75,18 @@ const AtomicString StyleEnvironmentVariables::GetVariableName(
return "safe-area-inset-bottom";
case UADefinedVariable::kSafeAreaInsetRight:
return "safe-area-inset-right";
+ case UADefinedVariable::kKeyboardInsetTop:
+ DCHECK(RuntimeEnabledFeatures::VirtualKeyboardEnabled());
+ return "keyboard-inset-top";
+ case UADefinedVariable::kKeyboardInsetLeft:
+ DCHECK(RuntimeEnabledFeatures::VirtualKeyboardEnabled());
+ return "keyboard-inset-left";
+ case UADefinedVariable::kKeyboardInsetBottom:
+ DCHECK(RuntimeEnabledFeatures::VirtualKeyboardEnabled());
+ return "keyboard-inset-bottom";
+ case UADefinedVariable::kKeyboardInsetRight:
+ DCHECK(RuntimeEnabledFeatures::VirtualKeyboardEnabled());
+ return "keyboard-inset-right";
default:
break;
}
diff --git a/chromium/third_party/blink/renderer/core/css/style_environment_variables.h b/chromium/third_party/blink/renderer/core/css/style_environment_variables.h
index c5452476f6f..4a3e2b92b3b 100644
--- a/chromium/third_party/blink/renderer/core/css/style_environment_variables.h
+++ b/chromium/third_party/blink/renderer/core/css/style_environment_variables.h
@@ -25,6 +25,16 @@ enum class UADefinedVariable {
kSafeAreaInsetLeft,
kSafeAreaInsetBottom,
kSafeAreaInsetRight,
+
+ // The keyboard area insets are four environment variables that define a
+ // virtual keyboard rectangle by its top, right, bottom, and left insets
+ // from the edge of the viewport.
+ // Explainers:
+ // https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/VirtualKeyboardAPI/explainer.md
+ kKeyboardInsetTop,
+ kKeyboardInsetLeft,
+ kKeyboardInsetBottom,
+ kKeyboardInsetRight,
};
// StyleEnvironmentVariables stores user agent and user defined CSS environment
diff --git a/chromium/third_party/blink/renderer/core/css/style_media.cc b/chromium/third_party/blink/renderer/core/css/style_media.cc
index 6725fe11f60..2faa9e7090d 100644
--- a/chromium/third_party/blink/renderer/core/css/style_media.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_media.cc
@@ -62,7 +62,7 @@ bool StyleMedia::matchMedium(const String& query) const {
return screen_eval.Eval(*media);
}
-void StyleMedia::Trace(Visitor* visitor) {
+void StyleMedia::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/style_media.h b/chromium/third_party/blink/renderer/core/css/style_media.h
index 7a16067f560..9cc50bd83a2 100644
--- a/chromium/third_party/blink/renderer/core/css/style_media.h
+++ b/chromium/third_party/blink/renderer/core/css/style_media.h
@@ -46,7 +46,7 @@ class StyleMedia final : public ScriptWrappable, public ExecutionContextClient {
AtomicString type() const;
bool matchMedium(const String&) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/style_property_serializer.cc b/chromium/third_party/blink/renderer/core/css/style_property_serializer.cc
index 52a5a7cf847..905137245f6 100644
--- a/chromium/third_party/blink/renderer/core/css/style_property_serializer.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_property_serializer.cc
@@ -71,7 +71,7 @@ StylePropertySerializer::CSSPropertyValueSetForSerializer::
}
void StylePropertySerializer::CSSPropertyValueSetForSerializer::Trace(
- blink::Visitor* visitor) {
+ blink::Visitor* visitor) const {
visitor->Trace(property_set_);
}
@@ -533,7 +533,7 @@ String StylePropertySerializer::SerializeShorthand(
case CSSPropertyID::kPaddingInline:
return Get2Values(paddingInlineShorthand());
case CSSPropertyID::kTextDecoration:
- return GetShorthandValue(textDecorationShorthand());
+ return TextDecorationValue();
case CSSPropertyID::kTransition:
return GetLayeredShorthandValue(transitionShorthand());
case CSSPropertyID::kListStyle:
@@ -819,6 +819,37 @@ String StylePropertySerializer::OffsetValue() const {
return result.ToString();
}
+String StylePropertySerializer::TextDecorationValue() const {
+ StringBuilder result;
+ const auto& shorthand = shorthandForProperty(CSSPropertyID::kTextDecoration);
+ for (unsigned i = 0; i < shorthand.length(); ++i) {
+ const CSSValue* value =
+ property_set_.GetPropertyCSSValue(*shorthand.properties()[i]);
+ String value_text = value->CssText();
+ if (value->IsInitialValue())
+ continue;
+ if (shorthand.properties()[i]->PropertyID() ==
+ CSSPropertyID::kTextDecorationThickness) {
+ if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) {
+ // Do not include initial value 'auto' for thickness.
+ // TODO(https://crbug.com/1093826): general shorthand serialization
+ // issues remain, in particular for text-decoration.
+ CSSValueID value_id = identifier_value->GetValueID();
+ if (value_id == CSSValueID::kAuto)
+ continue;
+ }
+ }
+ if (!result.IsEmpty())
+ result.Append(" ");
+ result.Append(value_text);
+ }
+
+ if (result.IsEmpty()) {
+ return "none";
+ }
+ return result.ToString();
+}
+
String StylePropertySerializer::Get2Values(
const StylePropertyShorthand& shorthand) const {
// Assume the properties are in the usual order start, end.
diff --git a/chromium/third_party/blink/renderer/core/css/style_property_serializer.h b/chromium/third_party/blink/renderer/core/css/style_property_serializer.h
index 4d214d695a5..70729bae821 100644
--- a/chromium/third_party/blink/renderer/core/css/style_property_serializer.h
+++ b/chromium/third_party/blink/renderer/core/css/style_property_serializer.h
@@ -60,6 +60,7 @@ class StylePropertySerializer {
bool AppendFontLonghandValueIfNotNormal(const CSSProperty&,
StringBuilder& result) const;
String OffsetValue() const;
+ String TextDecorationValue() const;
String BackgroundRepeatPropertyValue() const;
String GetPropertyText(const CSSProperty&,
const String& value,
@@ -129,7 +130,7 @@ class StylePropertySerializer {
const CSSValue* GetPropertyCSSValue(const CSSProperty&) const;
bool IsDescriptorContext() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
bool HasExpandedAllProperty() const {
diff --git a/chromium/third_party/blink/renderer/core/css/style_property_shorthand_custom.cc b/chromium/third_party/blink/renderer/core/css/style_property_shorthand_custom.cc
index a3b9cdd729e..8fb1a5d927f 100644
--- a/chromium/third_party/blink/renderer/core/css/style_property_shorthand_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_property_shorthand_custom.cc
@@ -25,34 +25,10 @@
namespace blink {
-const StylePropertyShorthand& animationShorthandForParsing() {
- // When we parse the animation shorthand we need to look for animation-name
- // last because otherwise it might match against the keywords for fill mode,
- // timing functions and infinite iteration. This means that animation names
- // that are the same as keywords (e.g. 'forwards') won't always match in the
- // shorthand. In that case the authors should be using longhands (or
- // reconsidering their approach). This is covered by the animations spec
- // bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=14790
- // And in the spec (editor's draft) at:
- // https://drafts.csswg.org/css-animations/#animation-shorthand-property
- static const CSSProperty* kAnimationPropertiesForParsing[] = {
- &GetCSSPropertyAnimationDuration(),
- &GetCSSPropertyAnimationTimingFunction(),
- &GetCSSPropertyAnimationDelay(),
- &GetCSSPropertyAnimationIterationCount(),
- &GetCSSPropertyAnimationDirection(),
- &GetCSSPropertyAnimationFillMode(),
- &GetCSSPropertyAnimationPlayState(),
- &GetCSSPropertyAnimationName()};
- static constexpr StylePropertyShorthand
- webkit_animation_longhands_for_parsing(
- CSSPropertyID::kAnimation, kAnimationPropertiesForParsing,
- base::size(kAnimationPropertiesForParsing));
- return webkit_animation_longhands_for_parsing;
-}
-
-// Similar to animations, we have property after timing-function and delay after
-// duration
+// The transition-property longhand appears last during parsing to prevent it
+// from matching against transition-timing-function keywords. Ideally we would
+// change the spec to use this order, see:
+// https://github.com/w3c/csswg-drafts/issues/4223
const StylePropertyShorthand& transitionShorthandForParsing() {
static const CSSProperty* kTransitionProperties[] = {
&GetCSSPropertyTransitionDuration(),
diff --git a/chromium/third_party/blink/renderer/core/css/style_rule.cc b/chromium/third_party/blink/renderer/core/css/style_rule.cc
index abc3fc6c294..916dc8b842e 100644
--- a/chromium/third_party/blink/renderer/core/css/style_rule.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_rule.cc
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/css/css_namespace_rule.h"
#include "third_party/blink/renderer/core/css/css_page_rule.h"
#include "third_party/blink/renderer/core/css/css_property_rule.h"
+#include "third_party/blink/renderer/core/css/css_scroll_timeline_rule.h"
#include "third_party/blink/renderer/core/css/css_style_rule.h"
#include "third_party/blink/renderer/core/css/css_supports_rule.h"
#include "third_party/blink/renderer/core/css/css_value_list.h"
@@ -54,7 +55,7 @@ CSSRule* StyleRuleBase::CreateCSSOMWrapper(CSSRule* parent_rule) const {
return CreateCSSOMWrapper(nullptr, parent_rule);
}
-void StyleRuleBase::Trace(Visitor* visitor) {
+void StyleRuleBase::Trace(Visitor* visitor) const {
switch (GetType()) {
case kCharset:
To<StyleRuleCharset>(this)->TraceAfterDispatch(visitor);
@@ -74,6 +75,9 @@ void StyleRuleBase::Trace(Visitor* visitor) {
case kMedia:
To<StyleRuleMedia>(this)->TraceAfterDispatch(visitor);
return;
+ case kScrollTimeline:
+ To<StyleRuleScrollTimeline>(this)->TraceAfterDispatch(visitor);
+ return;
case kSupports:
To<StyleRuleSupports>(this)->TraceAfterDispatch(visitor);
return;
@@ -116,6 +120,9 @@ void StyleRuleBase::FinalizeGarbageCollectedObject() {
case kMedia:
To<StyleRuleMedia>(this)->~StyleRuleMedia();
return;
+ case kScrollTimeline:
+ To<StyleRuleScrollTimeline>(this)->~StyleRuleScrollTimeline();
+ return;
case kSupports:
To<StyleRuleSupports>(this)->~StyleRuleSupports();
return;
@@ -150,6 +157,8 @@ StyleRuleBase* StyleRuleBase::Copy() const {
return To<StyleRuleFontFace>(this)->Copy();
case kMedia:
return To<StyleRuleMedia>(this)->Copy();
+ case kScrollTimeline:
+ return To<StyleRuleScrollTimeline>(this)->Copy();
case kSupports:
return To<StyleRuleSupports>(this)->Copy();
case kImport:
@@ -196,6 +205,10 @@ CSSRule* StyleRuleBase::CreateCSSOMWrapper(CSSStyleSheet* parent_sheet,
rule = MakeGarbageCollected<CSSMediaRule>(To<StyleRuleMedia>(self),
parent_sheet);
break;
+ case kScrollTimeline:
+ rule = MakeGarbageCollected<CSSScrollTimelineRule>(
+ To<StyleRuleScrollTimeline>(self), parent_sheet);
+ break;
case kSupports:
rule = MakeGarbageCollected<CSSSupportsRule>(To<StyleRuleSupports>(self),
parent_sheet);
@@ -364,6 +377,44 @@ void StyleRuleFontFace::TraceAfterDispatch(blink::Visitor* visitor) const {
StyleRuleBase::TraceAfterDispatch(visitor);
}
+StyleRuleScrollTimeline::StyleRuleScrollTimeline(
+ const String& name,
+ const CSSPropertyValueSet* properties)
+ : StyleRuleBase(kScrollTimeline), name_(name), properties_(properties) {}
+
+StyleRuleScrollTimeline::StyleRuleScrollTimeline(
+ const StyleRuleScrollTimeline& scroll_timeline_rule)
+ : StyleRuleBase(scroll_timeline_rule),
+ properties_(scroll_timeline_rule.properties_->MutableCopy()) {}
+
+StyleRuleScrollTimeline::~StyleRuleScrollTimeline() = default;
+
+const CSSValue* StyleRuleScrollTimeline::GetSource() const {
+ return properties_->GetPropertyCSSValue(CSSPropertyID::kSource);
+}
+
+const CSSValue* StyleRuleScrollTimeline::GetOrientation() const {
+ return properties_->GetPropertyCSSValue(CSSPropertyID::kOrientation);
+}
+
+const CSSValue* StyleRuleScrollTimeline::GetStart() const {
+ return properties_->GetPropertyCSSValue(CSSPropertyID::kStart);
+}
+
+const CSSValue* StyleRuleScrollTimeline::GetEnd() const {
+ return properties_->GetPropertyCSSValue(CSSPropertyID::kEnd);
+}
+
+const CSSValue* StyleRuleScrollTimeline::GetTimeRange() const {
+ return properties_->GetPropertyCSSValue(CSSPropertyID::kTimeRange);
+}
+
+void StyleRuleScrollTimeline::TraceAfterDispatch(
+ blink::Visitor* visitor) const {
+ visitor->Trace(properties_);
+ StyleRuleBase::TraceAfterDispatch(visitor);
+}
+
StyleRuleGroup::StyleRuleGroup(RuleType type,
HeapVector<Member<StyleRuleBase>>& adopt_rule)
: StyleRuleBase(type) {
diff --git a/chromium/third_party/blink/renderer/core/css/style_rule.h b/chromium/third_party/blink/renderer/core/css/style_rule.h
index 05bd60b1866..34dea7ebfa4 100644
--- a/chromium/third_party/blink/renderer/core/css/style_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/style_rule.h
@@ -48,6 +48,7 @@ class CORE_EXPORT StyleRuleBase : public GarbageCollected<StyleRuleBase> {
kKeyframes,
kKeyframe,
kNamespace,
+ kScrollTimeline,
kSupports,
kViewport,
};
@@ -63,6 +64,7 @@ class CORE_EXPORT StyleRuleBase : public GarbageCollected<StyleRuleBase> {
bool IsPageRule() const { return GetType() == kPage; }
bool IsPropertyRule() const { return GetType() == kProperty; }
bool IsStyleRule() const { return GetType() == kStyle; }
+ bool IsScrollTimelineRule() const { return GetType() == kScrollTimeline; }
bool IsSupportsRule() const { return GetType() == kSupports; }
bool IsViewportRule() const { return GetType() == kViewport; }
bool IsImportRule() const { return GetType() == kImport; }
@@ -73,7 +75,7 @@ class CORE_EXPORT StyleRuleBase : public GarbageCollected<StyleRuleBase> {
CSSRule* CreateCSSOMWrapper(CSSStyleSheet* parent_sheet = nullptr) const;
CSSRule* CreateCSSOMWrapper(CSSRule* parent_rule) const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void TraceAfterDispatch(blink::Visitor* visitor) const {}
void FinalizeGarbageCollectedObject();
@@ -210,6 +212,30 @@ class StyleRuleProperty : public StyleRuleBase {
Member<CSSPropertyValueSet> properties_;
};
+class StyleRuleScrollTimeline : public StyleRuleBase {
+ public:
+ StyleRuleScrollTimeline(const String& name, const CSSPropertyValueSet*);
+ StyleRuleScrollTimeline(const StyleRuleScrollTimeline&);
+ ~StyleRuleScrollTimeline();
+
+ StyleRuleScrollTimeline* Copy() const {
+ return MakeGarbageCollected<StyleRuleScrollTimeline>(*this);
+ }
+
+ void TraceAfterDispatch(blink::Visitor*) const;
+
+ const String& GetName() const { return name_; }
+ const CSSValue* GetSource() const;
+ const CSSValue* GetOrientation() const;
+ const CSSValue* GetStart() const;
+ const CSSValue* GetEnd() const;
+ const CSSValue* GetTimeRange() const;
+
+ private:
+ String name_;
+ Member<const CSSPropertyValueSet> properties_;
+};
+
class CORE_EXPORT StyleRuleGroup : public StyleRuleBase {
public:
const HeapVector<Member<StyleRuleBase>>& ChildRules() const {
@@ -341,6 +367,13 @@ struct DowncastTraits<StyleRuleProperty> {
};
template <>
+struct DowncastTraits<StyleRuleScrollTimeline> {
+ static bool AllowFrom(const StyleRuleBase& rule) {
+ return rule.IsScrollTimelineRule();
+ }
+};
+
+template <>
struct DowncastTraits<StyleRuleMedia> {
static bool AllowFrom(const StyleRuleBase& rule) {
return rule.IsMediaRule();
diff --git a/chromium/third_party/blink/renderer/core/css/style_rule_css_style_declaration.cc b/chromium/third_party/blink/renderer/core/css/style_rule_css_style_declaration.cc
index 95e62d4c6ad..9ae593b1e7c 100644
--- a/chromium/third_party/blink/renderer/core/css/style_rule_css_style_declaration.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_rule_css_style_declaration.cc
@@ -64,7 +64,7 @@ void StyleRuleCSSStyleDeclaration::Reattach(
property_set_ = &property_set;
}
-void StyleRuleCSSStyleDeclaration::Trace(Visitor* visitor) {
+void StyleRuleCSSStyleDeclaration::Trace(Visitor* visitor) const {
visitor->Trace(parent_rule_);
PropertySetCSSStyleDeclaration::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/style_rule_css_style_declaration.h b/chromium/third_party/blink/renderer/core/css/style_rule_css_style_declaration.h
index cbf19455579..cf5858c86d3 100644
--- a/chromium/third_party/blink/renderer/core/css/style_rule_css_style_declaration.h
+++ b/chromium/third_party/blink/renderer/core/css/style_rule_css_style_declaration.h
@@ -40,7 +40,7 @@ class StyleRuleCSSStyleDeclaration : public PropertySetCSSStyleDeclaration {
void Reattach(MutableCSSPropertyValueSet&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
CSSStyleSheet* ParentStyleSheet() const override;
diff --git a/chromium/third_party/blink/renderer/core/css/style_rule_import.cc b/chromium/third_party/blink/renderer/core/css/style_rule_import.cc
index b407494abdd..447d130a9c2 100644
--- a/chromium/third_party/blink/renderer/core/css/style_rule_import.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_rule_import.cc
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/core/css/style_sheet_contents.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
@@ -118,12 +119,10 @@ void StyleRuleImport::RequestStyleSheet() {
// context document for getting origin and ResourceFetcher to use the main
// Document's origin, while using the element document for CompleteURL() to
// use imported Documents' base URLs.
- document_for_origin = document->ContextDocument();
+ document_for_origin =
+ To<LocalDOMWindow>(document->GetExecutionContext())->document();
}
- if (!document_for_origin)
- return;
-
ResourceFetcher* fetcher = document_for_origin->Fetcher();
if (!fetcher)
return;
diff --git a/chromium/third_party/blink/renderer/core/css/style_rule_import.h b/chromium/third_party/blink/renderer/core/css/style_rule_import.h
index db062f0825a..1fce47d96ed 100644
--- a/chromium/third_party/blink/renderer/core/css/style_rule_import.h
+++ b/chromium/third_party/blink/renderer/core/css/style_rule_import.h
@@ -80,7 +80,7 @@ class StyleRuleImport : public StyleRuleBase {
String DebugName() const override { return "ImportedStyleSheetClient"; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(owner_rule_);
ResourceClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/style_sheet_collection.cc b/chromium/third_party/blink/renderer/core/css/style_sheet_collection.cc
index 92c1fec1051..a06c56b4cda 100644
--- a/chromium/third_party/blink/renderer/core/css/style_sheet_collection.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_sheet_collection.cc
@@ -62,7 +62,7 @@ void StyleSheetCollection::AppendSheetForList(StyleSheet* sheet) {
style_sheets_for_style_sheet_list_.push_back(sheet);
}
-void StyleSheetCollection::Trace(Visitor* visitor) {
+void StyleSheetCollection::Trace(Visitor* visitor) const {
visitor->Trace(active_author_style_sheets_);
visitor->Trace(style_sheets_for_style_sheet_list_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/style_sheet_collection.h b/chromium/third_party/blink/renderer/core/css/style_sheet_collection.h
index a1f8d3d677d..309c9c9f486 100644
--- a/chromium/third_party/blink/renderer/core/css/style_sheet_collection.h
+++ b/chromium/third_party/blink/renderer/core/css/style_sheet_collection.h
@@ -65,7 +65,7 @@ class CORE_EXPORT StyleSheetCollection
void AppendSheetForList(StyleSheet*);
void MarkSheetListDirty() { sheet_list_dirty_ = true; }
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override {
return "StyleSheetCollection";
}
diff --git a/chromium/third_party/blink/renderer/core/css/style_sheet_contents.cc b/chromium/third_party/blink/renderer/core/css/style_sheet_contents.cc
index 85d3a8e9d08..88f33aaf230 100644
--- a/chromium/third_party/blink/renderer/core/css/style_sheet_contents.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_sheet_contents.cc
@@ -513,6 +513,7 @@ static bool ChildRulesHaveFailedOrCanceledSubresources(
case StyleRuleBase::kProperty:
case StyleRuleBase::kKeyframes:
case StyleRuleBase::kKeyframe:
+ case StyleRuleBase::kScrollTimeline:
case StyleRuleBase::kSupports:
case StyleRuleBase::kViewport:
break;
@@ -676,7 +677,7 @@ void StyleSheetContents::FindFontFaceRules(
FindFontFaceRulesFromRules(ChildRules(), font_face_rules);
}
-void StyleSheetContents::Trace(Visitor* visitor) {
+void StyleSheetContents::Trace(Visitor* visitor) const {
visitor->Trace(owner_rule_);
visitor->Trace(import_rules_);
visitor->Trace(namespace_rules_);
diff --git a/chromium/third_party/blink/renderer/core/css/style_sheet_contents.h b/chromium/third_party/blink/renderer/core/css/style_sheet_contents.h
index 746d80b89b7..ea6859adbc5 100644
--- a/chromium/third_party/blink/renderer/core/css/style_sheet_contents.h
+++ b/chromium/third_party/blink/renderer/core/css/style_sheet_contents.h
@@ -191,7 +191,7 @@ class CORE_EXPORT StyleSheetContents final
String SourceMapURL() const { return source_map_url_; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
StyleSheetContents& operator=(const StyleSheetContents&) = delete;
diff --git a/chromium/third_party/blink/renderer/core/css/style_sheet_list.cc b/chromium/third_party/blink/renderer/core/css/style_sheet_list.cc
index eb9e126c479..5d2eebbf12c 100644
--- a/chromium/third_party/blink/renderer/core/css/style_sheet_list.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_sheet_list.cc
@@ -86,7 +86,7 @@ CSSStyleSheet* StyleSheetList::AnonymousNamedGetter(const AtomicString& name) {
return sheet;
}
-void StyleSheetList::Trace(Visitor* visitor) {
+void StyleSheetList::Trace(Visitor* visitor) const {
visitor->Trace(tree_scope_);
visitor->Trace(style_sheet_vector_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/style_sheet_list.h b/chromium/third_party/blink/renderer/core/css/style_sheet_list.h
index 88905c866de..cf1e7cc6626 100644
--- a/chromium/third_party/blink/renderer/core/css/style_sheet_list.h
+++ b/chromium/third_party/blink/renderer/core/css/style_sheet_list.h
@@ -50,7 +50,7 @@ class CORE_EXPORT StyleSheetList final : public ScriptWrappable {
CSSStyleSheet* AnonymousNamedGetter(const AtomicString&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const HeapVector<Member<StyleSheet>>& StyleSheets() const;
diff --git a/chromium/third_party/blink/renderer/core/css/style_traversal_root.h b/chromium/third_party/blink/renderer/core/css/style_traversal_root.h
index 83d3a95dbf0..aab33381285 100644
--- a/chromium/third_party/blink/renderer/core/css/style_traversal_root.h
+++ b/chromium/third_party/blink/renderer/core/css/style_traversal_root.h
@@ -46,7 +46,7 @@ class CORE_EXPORT StyleTraversalRoot {
root_type_ = RootType::kSingleRoot;
}
- void Trace(Visitor* visitor) { visitor->Trace(root_node_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(root_node_); }
protected:
virtual ~StyleTraversalRoot() = default;
diff --git a/chromium/third_party/blink/renderer/core/css/style_traversal_root_test.cc b/chromium/third_party/blink/renderer/core/css/style_traversal_root_test.cc
index a806ca05a54..04bdb857ae4 100644
--- a/chromium/third_party/blink/renderer/core/css/style_traversal_root_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_traversal_root_test.cc
@@ -45,7 +45,7 @@ class StyleTraversalRootTest : public testing::Test {
protected:
enum ElementIndex { kA, kB, kC, kD, kE, kF, kG, kElementCount };
void SetUp() final {
- document_ = MakeGarbageCollected<Document>();
+ document_ = Document::CreateForTest();
elements_ = MakeGarbageCollected<HeapVector<Member<Element>, 7>>();
for (size_t i = 0; i < kElementCount; i++) {
elements_->push_back(GetDocument().CreateRawElement(html_names::kDivTag));
diff --git a/chromium/third_party/blink/renderer/core/css/svg.css b/chromium/third_party/blink/renderer/core/css/svg.css
index a4783c4cb69..4de942881ef 100644
--- a/chromium/third_party/blink/renderer/core/css/svg.css
+++ b/chromium/third_party/blink/renderer/core/css/svg.css
@@ -94,7 +94,7 @@ foreignObject {
This is added as to not break SVG content in forced colors mode:
https://drafts.csswg.org/css-color-adjust-1/#forced-colors-properties
*/
-@media forced-colors {
+@media ua-forced-colors {
svg:root {
color: CanvasText;
}
diff --git a/chromium/third_party/blink/renderer/core/css/tree_scope_style_sheet_collection.cc b/chromium/third_party/blink/renderer/core/css/tree_scope_style_sheet_collection.cc
index 738ab2f9d56..f39744ac3e9 100644
--- a/chromium/third_party/blink/renderer/core/css/tree_scope_style_sheet_collection.cc
+++ b/chromium/third_party/blink/renderer/core/css/tree_scope_style_sheet_collection.cc
@@ -85,7 +85,7 @@ void TreeScopeStyleSheetCollection::UpdateStyleSheetList() {
SwapSheetsForSheetList(new_list);
}
-void TreeScopeStyleSheetCollection::Trace(Visitor* visitor) {
+void TreeScopeStyleSheetCollection::Trace(Visitor* visitor) const {
visitor->Trace(tree_scope_);
visitor->Trace(style_sheet_candidate_nodes_);
StyleSheetCollection::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/tree_scope_style_sheet_collection.h b/chromium/third_party/blink/renderer/core/css/tree_scope_style_sheet_collection.h
index e7e28c21fe0..c062d3d1930 100644
--- a/chromium/third_party/blink/renderer/core/css/tree_scope_style_sheet_collection.h
+++ b/chromium/third_party/blink/renderer/core/css/tree_scope_style_sheet_collection.h
@@ -54,7 +54,7 @@ class CORE_EXPORT TreeScopeStyleSheetCollection : public StyleSheetCollection {
virtual bool IsShadowTreeStyleSheetCollection() const { return false; }
void UpdateStyleSheetList();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit TreeScopeStyleSheetCollection(TreeScope&);
diff --git a/chromium/third_party/blink/renderer/core/css/vision_deficiency.cc b/chromium/third_party/blink/renderer/core/css/vision_deficiency.cc
index 5d29202ce64..370529d2927 100644
--- a/chromium/third_party/blink/renderer/core/css/vision_deficiency.cc
+++ b/chromium/third_party/blink/renderer/core/css/vision_deficiency.cc
@@ -3,6 +3,8 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/core/css/vision_deficiency.h"
+
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/text/string_view.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/chromium/third_party/blink/renderer/core/display_lock/BUILD.gn b/chromium/third_party/blink/renderer/core/display_lock/BUILD.gn
index e02ed4cb974..5672806269e 100644
--- a/chromium/third_party/blink/renderer/core/display_lock/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/display_lock/BUILD.gn
@@ -12,8 +12,6 @@ blink_core_sources("display_lock") {
"display_lock_document_state.h",
"display_lock_utilities.cc",
"display_lock_utilities.h",
- "render_subtree_activation_event.cc",
- "render_subtree_activation_event.h",
]
public_deps = [
diff --git a/chromium/third_party/blink/renderer/core/display_lock/display_lock_context.cc b/chromium/third_party/blink/renderer/core/display_lock/display_lock_context.cc
index d389bf68298..b4f83680690 100644
--- a/chromium/third_party/blink/renderer/core/display_lock/display_lock_context.cc
+++ b/chromium/third_party/blink/renderer/core/display_lock/display_lock_context.cc
@@ -13,7 +13,6 @@
#include "third_party/blink/renderer/core/css/style_recalc.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_document_state.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
-#include "third_party/blink/renderer/core/display_lock/render_subtree_activation_event.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/element.h"
@@ -30,6 +29,8 @@
#include "third_party/blink/renderer/core/paint/pre_paint_tree_walk.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
@@ -106,12 +107,16 @@ void DisplayLockContext::SetRequestedState(EContentVisibility state) {
RequestUnlock();
break;
case EContentVisibility::kAuto:
+ UseCounter::Count(document_, WebFeature::kContentVisibilityAuto);
RequestLock(static_cast<uint16_t>(DisplayLockActivationReason::kAny));
break;
case EContentVisibility::kHidden:
+ UseCounter::Count(document_, WebFeature::kContentVisibilityHidden);
RequestLock(0u);
break;
case EContentVisibility::kHiddenMatchable:
+ UseCounter::Count(document_,
+ WebFeature::kContentVisibilityHiddenMatchable);
RequestLock(
static_cast<uint16_t>(DisplayLockActivationReason::kAny) &
~static_cast<uint16_t>(DisplayLockActivationReason::kViewport));
@@ -235,7 +240,9 @@ void DisplayLockContext::UpdateActivationObservationIfNeeded() {
}
bool DisplayLockContext::NeedsLifecycleNotifications() const {
- return needs_deferred_not_intersecting_signal_;
+ return needs_deferred_not_intersecting_signal_ ||
+ render_affecting_state_[static_cast<int>(
+ RenderAffectingState::kAutoStateUnlockedUntilLifecycle)];
}
void DisplayLockContext::UpdateLifecycleNotificationRegistration() {
@@ -278,6 +285,24 @@ void DisplayLockContext::Lock() {
element_->SetNeedsStyleRecalc(
kLocalStyleChange,
StyleChangeReasonForTracing::Create(style_change_reason::kDisplayLock));
+
+ // TODO(vmpstr): Note when an 'auto' context gets locked, we should clear
+ // the ancestor scroll anchors. This is a workaround for a behavior that
+ // happens when the user quickly scrolls (e.g. scrollbar scrolls) into an
+ // area that only has locked content. We can get into a loop that will
+ // keep unlocking an element, which may shrink it to be out of the viewport,
+ // and thus relocking it again. It is is also possible that we selected the
+ // scroller itself or one of the locked elements as the anchor, so we don't
+ // actually shift the scroll and the loop continues indefinitely. The user
+ // can easily get out of the loop by scrolling since that triggers a new
+ // scroll anchor selection. The work-around for us is also to pick a new
+ // scroll anchor for the scroller that has a newly-locked context. The
+ // reason it works is that it causes us to pick an anchor while the element
+ // is still unlocked, so when it gets relocked we shift the scroll to
+ // whatever visible content we had. The TODO here is to figure out if there
+ // is a better way to solve this. In either case, we have to select a new
+ // scroll anchor to get out of this behavior.
+ element_->NotifyPriorityScrollAnchorStatusChanged();
}
// In either case, we schedule an animation. If we're already inside a
@@ -378,12 +403,6 @@ bool DisplayLockContext::IsActivatable(
return activatable_mask_ & static_cast<uint16_t>(reason);
}
-void DisplayLockContext::FireActivationEvent(Element* activated_element) {
- DCHECK(RuntimeEnabledFeatures::CSSContentVisibilityActivationEventEnabled());
- element_->DispatchEvent(
- *MakeGarbageCollected<RenderSubtreeActivationEvent>(*activated_element));
-}
-
void DisplayLockContext::CommitForActivationWithSignal(
Element* activated_element,
DisplayLockActivationReason reason) {
@@ -393,16 +412,31 @@ void DisplayLockContext::CommitForActivationWithSignal(
DCHECK(IsLocked());
DCHECK(ShouldCommitForActivation(DisplayLockActivationReason::kAny));
- // TODO(vmpstr): Remove this when we have a beforematch event.
- if (RuntimeEnabledFeatures::CSSContentVisibilityActivationEventEnabled()) {
- document_->EnqueueDisplayLockActivationTask(
- WTF::Bind(&DisplayLockContext::FireActivationEvent,
- WrapWeakPersistent(this), WrapPersistent(activated_element)));
+ // Find in page scrolls content into view. However, if the position of the
+ // target is outside of the bounds that would cause the auto-context to
+ // unlock, then we can scroll into wrong content while the context remains
+ // lock. To avoid this, unlock it until the next lifecycle. If the scroll is
+ // successful, then we will gain visibility anyway so the context will be
+ // unlocked for other reasons.
+ // TODO(vmpstr): See if scrollIntoView() needs this as well.
+ if (reason == DisplayLockActivationReason::kFindInPage) {
+ // Note that because the visibility is only determined at the _end_ of the
+ // next frame, we need to ensure that we stay unlocked for two frames.
+ SetKeepUnlockedUntilLifecycleCount(2);
}
RecordActivationReason(document_, reason);
}
+void DisplayLockContext::SetKeepUnlockedUntilLifecycleCount(int count) {
+ DCHECK_GT(count, 0);
+ keep_unlocked_count_ = std::max(keep_unlocked_count_, count);
+ SetRenderAffectingState(
+ RenderAffectingState::kAutoStateUnlockedUntilLifecycle, true);
+ UpdateLifecycleNotificationRegistration();
+ ScheduleAnimation();
+}
+
void DisplayLockContext::NotifyIsIntersectingViewport() {
// If we are now intersecting, then we are definitely not nested in a locked
// subtree and we don't need to lock as a result.
@@ -702,6 +736,10 @@ bool DisplayLockContext::MarkForCompositingUpdatesIfNeeded() {
layout_box->Layer()->SetNeedsCompositingInputsUpdate();
needs_compositing_dependent_flag_update_ = false;
+ if (needs_graphics_layer_rebuild_)
+ layout_box->Layer()->SetNeedsGraphicsLayerRebuild();
+ needs_graphics_layer_rebuild_ = false;
+
return true;
}
return false;
@@ -795,6 +833,20 @@ void DisplayLockContext::WillStartLifecycleUpdate(const LocalFrameView& view) {
// visible.
if (needs_deferred_not_intersecting_signal_)
NotifyIsNotIntersectingViewport();
+
+ // If we're keeping this context unlocked, update the values.
+ if (keep_unlocked_count_) {
+ if (--keep_unlocked_count_) {
+ ScheduleAnimation();
+ } else {
+ SetRenderAffectingState(
+ RenderAffectingState::kAutoStateUnlockedUntilLifecycle, false);
+ UpdateLifecycleNotificationRegistration();
+ }
+ } else {
+ DCHECK(!render_affecting_state_[static_cast<int>(
+ RenderAffectingState::kAutoStateUnlockedUntilLifecycle)]);
+ }
}
void DisplayLockContext::NotifyWillDisconnect() {
@@ -965,6 +1017,17 @@ void DisplayLockContext::DetermineIfSubtreeHasSelection() {
void DisplayLockContext::SetRenderAffectingState(RenderAffectingState state,
bool new_flag) {
+ // If we have forced activatable locks, it is possible that we're within
+ // find-in-page. We cannot lock an object while doing this, since it may
+ // invalidate layout and in turn prevent find-in-page from properly finding
+ // text (and DCHECK). Since layout is clean for this lock (we're unlocked),
+ // keep the context unlocked until the next lifecycle starts.
+ if (state == RenderAffectingState::kSubtreeHasSelection && !new_flag &&
+ document_->GetDisplayLockDocumentState()
+ .ActivatableDisplayLocksForced()) {
+ SetKeepUnlockedUntilLifecycleCount(1);
+ }
+
render_affecting_state_[static_cast<int>(state)] = new_flag;
NotifyRenderAffectingStateChanged();
}
@@ -992,7 +1055,8 @@ void DisplayLockContext::NotifyRenderAffectingStateChanged() {
(state_ != EContentVisibility::kAuto ||
(!state(RenderAffectingState::kIntersectsViewport) &&
!state(RenderAffectingState::kSubtreeHasFocus) &&
- !state(RenderAffectingState::kSubtreeHasSelection)));
+ !state(RenderAffectingState::kSubtreeHasSelection) &&
+ !state(RenderAffectingState::kAutoStateUnlockedUntilLifecycle)));
if (should_be_locked && !IsLocked())
Lock();
@@ -1000,10 +1064,41 @@ void DisplayLockContext::NotifyRenderAffectingStateChanged() {
Unlock();
}
-void DisplayLockContext::Trace(Visitor* visitor) {
+void DisplayLockContext::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(document_);
visitor->Trace(whitespace_reattach_set_);
}
+const char* DisplayLockContext::RenderAffectingStateName(int state) const {
+ switch (static_cast<RenderAffectingState>(state)) {
+ case RenderAffectingState::kLockRequested:
+ return "LockRequested";
+ case RenderAffectingState::kIntersectsViewport:
+ return "IntersectsViewport";
+ case RenderAffectingState::kSubtreeHasFocus:
+ return "SubtreeHasFocus";
+ case RenderAffectingState::kSubtreeHasSelection:
+ return "SubtreeHasSelection";
+ case RenderAffectingState::kAutoStateUnlockedUntilLifecycle:
+ return "AutoStateUnlockedUntilLifecycle";
+ case RenderAffectingState::kNumRenderAffectingStates:
+ break;
+ }
+ return "<Invalid State>";
+}
+
+String DisplayLockContext::RenderAffectingStateToString() const {
+ StringBuilder builder;
+ for (int i = 0;
+ i < static_cast<int>(RenderAffectingState::kNumRenderAffectingStates);
+ ++i) {
+ builder.Append(RenderAffectingStateName(i));
+ builder.Append(": ");
+ builder.Append(render_affecting_state_[i] ? "true" : "false");
+ builder.Append("\n");
+ }
+ return builder.ToString();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/display_lock/display_lock_context.h b/chromium/third_party/blink/renderer/core/display_lock/display_lock_context.h
index 57f785686f4..50820bebd50 100644
--- a/chromium/third_party/blink/renderer/core/display_lock/display_lock_context.h
+++ b/chromium/third_party/blink/renderer/core/display_lock/display_lock_context.h
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -161,6 +162,11 @@ class CORE_EXPORT DisplayLockContext final
needs_compositing_dependent_flag_update_ = true;
}
+ void NotifyGraphicsLayerRebuildBlocked() {
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+ needs_graphics_layer_rebuild_ = true;
+ }
+
// Notify this element will be disconnected.
void NotifyWillDisconnect();
@@ -195,7 +201,10 @@ class CORE_EXPORT DisplayLockContext final
}
// GC functions.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
+
+ // Debugging functions.
+ String RenderAffectingStateToString() const;
private:
// Give access to |NotifyForcedUpdateScopeStarted()| and
@@ -276,10 +285,6 @@ class CORE_EXPORT DisplayLockContext final
// register/unregister is required.
void UpdateActivationObservationIfNeeded();
- // This function is called from within a task to fire the activation event.
- // Scheduled by CommitForActivationWithSignal.
- void FireActivationEvent(Element* activated_element);
-
// Determines whether or not we need lifecycle notifications.
bool NeedsLifecycleNotifications() const;
// Updates the lifecycle notification registration based on whether we need
@@ -299,6 +304,12 @@ class CORE_EXPORT DisplayLockContext final
// selected notes up to its root looking for `element_`.
void DetermineIfSubtreeHasSelection();
+ // Keep this context unlocked until the beginning of lifecycle. Effectively
+ // keeps this context unlocked for the next `count` frames. It also schedules
+ // a frame to ensure the lifecycle happens. Only affects locks with 'auto'
+ // setting.
+ void SetKeepUnlockedUntilLifecycleCount(int count);
+
WeakMember<Element> element_;
WeakMember<Document> document_;
EContentVisibility state_ = EContentVisibility::kVisible;
@@ -352,18 +363,28 @@ class CORE_EXPORT DisplayLockContext final
// Lock has been requested.
bool is_locked_ = false;
+ // If true, this lock is kept unlocked at least until the beginning of the
+ // lifecycle. If nothing else is keeping it unlocked, then it will be locked
+ // again at the start of the lifecycle.
+ bool keep_unlocked_until_lifecycle_ = false;
+
+ bool needs_graphics_layer_rebuild_ = false;
+
enum class RenderAffectingState : int {
kLockRequested,
kIntersectsViewport,
kSubtreeHasFocus,
kSubtreeHasSelection,
+ kAutoStateUnlockedUntilLifecycle,
kNumRenderAffectingStates
};
void SetRenderAffectingState(RenderAffectingState state, bool flag);
void NotifyRenderAffectingStateChanged();
+ const char* RenderAffectingStateName(int state) const;
bool render_affecting_state_[static_cast<int>(
RenderAffectingState::kNumRenderAffectingStates)] = {false};
+ int keep_unlocked_count_ = 0;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc b/chromium/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
index 4a9864200b7..7ec4f79453b 100644
--- a/chromium/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
+++ b/chromium/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
@@ -150,19 +150,19 @@ class DisplayLockContextTest
return context->needs_graphics_layer_collection_;
}
- mojom::blink::FindOptionsPtr FindOptions(bool find_next = false) {
+ mojom::blink::FindOptionsPtr FindOptions(bool new_session = true) {
auto find_options = mojom::blink::FindOptions::New();
find_options->run_synchronously_for_testing = true;
- find_options->find_next = find_next;
+ find_options->new_session = new_session;
find_options->forward = true;
return find_options;
}
void Find(String search_text,
DisplayLockTestFindInPageClient& client,
- bool find_next = false) {
+ bool new_session = true) {
client.Reset();
- GetFindInPage()->Find(FAKE_FIND_ID, search_text, FindOptions(find_next));
+ GetFindInPage()->Find(FAKE_FIND_ID, search_text, FindOptions(new_session));
test::RunPendingTasks();
}
@@ -335,6 +335,85 @@ TEST_F(DisplayLockContextTest,
EXPECT_GT(GetDocument().scrollingElement()->scrollTop(), 1000);
}
+TEST_F(DisplayLockContextTest, FindInPageContinuesAfterRelock) {
+ ResizeAndFocus();
+ SetHtmlInnerHTML(R"HTML(
+ <style>
+ .spacer {
+ height: 10000px;
+ }
+ #container {
+ width: 100px;
+ height: 100px;
+ }
+ .auto { content-visibility: auto }
+ </style>
+ <body><div class=spacer></div><div id="container" class=auto>testing</div></body>
+ )HTML");
+
+ const String search_text = "testing";
+ DisplayLockTestFindInPageClient client;
+ client.SetFrame(LocalMainFrame());
+
+ // Finds on a normal element.
+ Find(search_text, client);
+ EXPECT_EQ(1, client.Count());
+
+ auto* container = GetDocument().getElementById("container");
+ GetDocument().scrollingElement()->setScrollTop(0);
+
+ UpdateAllLifecyclePhasesForTest();
+ UpdateAllLifecyclePhasesForTest();
+
+ EXPECT_TRUE(container->GetDisplayLockContext()->IsLocked());
+
+ // Clears selections since we're going to use the same query next time.
+ GetFindInPage()->StopFinding(
+ mojom::StopFindAction::kStopFindActionKeepSelection);
+
+ UpdateAllLifecyclePhasesForTest();
+
+ // This should not crash.
+ Find(search_text, client, false);
+
+ EXPECT_EQ(1, client.Count());
+}
+
+TEST_F(DisplayLockContextTest, FindInPageTargetBelowLockedSize) {
+ ResizeAndFocus();
+ SetHtmlInnerHTML(R"HTML(
+ <style>
+ .spacer { height: 1000px; }
+ #container { contain-intrinsic-size: 1px; }
+ .auto { content-visibility: auto }
+ </style>
+ <body>
+ <div class=spacer></div>
+ <div id=container class=auto>
+ <div class=spacer></div>
+ <div id=target>testing</div>
+ </div>
+ <div class=spacer></div>
+ <div class=spacer></div>
+ </body>
+ )HTML");
+
+ const String search_text = "testing";
+ DisplayLockTestFindInPageClient client;
+ client.SetFrame(LocalMainFrame());
+
+ Find(search_text, client);
+ EXPECT_EQ(1, client.Count());
+
+ auto* container = GetDocument().getElementById("container");
+ // The container should be unlocked.
+ EXPECT_FALSE(container->GetDisplayLockContext()->IsLocked());
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_FALSE(container->GetDisplayLockContext()->IsLocked());
+
+ EXPECT_FLOAT_EQ(GetDocument().scrollingElement()->scrollTop(), 1768.5);
+}
+
TEST_F(DisplayLockContextTest,
ActivatableLockedElementTickmarksAreAtLockedRoots) {
ResizeAndFocus();
@@ -637,7 +716,7 @@ TEST_F(DisplayLockContextTest,
CommitElement(*div_one);
// Going forward from #one would go to #three.
- Find(search_text, client, true /* find_next */);
+ Find(search_text, client, false /* new_session */);
EXPECT_EQ(2, client.Count());
EXPECT_EQ(2, client.ActiveIndex());
EXPECT_EQ(text_rect(div_three), client.ActiveMatchRect());
@@ -1849,6 +1928,52 @@ TEST_F(DisplayLockContextRenderingTest,
EXPECT_FALSE(child_layer->NeedsVisualOverflowRecalc());
}
+TEST_F(DisplayLockContextRenderingTest, FloatChildLocked) {
+ SetHtmlInnerHTML(R"HTML(
+ <style>
+ .hidden { content-visibility: hidden }
+ #floating { float: left; width: 100px; height: 100px }
+ </style>
+ <div id=lockable style="width: 200px; height: 50px; position: absolute">
+ <div id=floating></div>
+ </div>
+ )HTML");
+
+ auto* lockable = GetDocument().getElementById("lockable");
+ auto* lockable_box = lockable->GetLayoutBox();
+ auto* floating = GetDocument().getElementById("floating");
+ EXPECT_EQ(LayoutRect(0, 0, 200, 100), lockable_box->VisualOverflowRect());
+ EXPECT_EQ(LayoutRect(0, 0, 200, 100), lockable_box->LayoutOverflowRect());
+
+ lockable->classList().Add("hidden");
+ UpdateAllLifecyclePhasesForTest();
+
+ // Verify that the display lock knows that the descendant dependent flags
+ // update was blocked.
+ ASSERT_TRUE(lockable->GetDisplayLockContext());
+ EXPECT_TRUE(DescendantDependentFlagUpdateWasBlocked(
+ lockable->GetDisplayLockContext()));
+ EXPECT_EQ(LayoutRect(0, 0, 200, 50), lockable_box->VisualOverflowRect());
+ EXPECT_EQ(LayoutRect(0, 0, 200, 50), lockable_box->LayoutOverflowRect());
+
+ floating->setAttribute(html_names::kStyleAttr, "height: 200px");
+ // The following should not crash/DCHECK.
+ UpdateAllLifecyclePhasesForTest();
+
+ ASSERT_TRUE(lockable->GetDisplayLockContext());
+ EXPECT_TRUE(DescendantDependentFlagUpdateWasBlocked(
+ lockable->GetDisplayLockContext()));
+ EXPECT_EQ(LayoutRect(0, 0, 200, 50), lockable_box->VisualOverflowRect());
+ EXPECT_EQ(LayoutRect(0, 0, 200, 50), lockable_box->LayoutOverflowRect());
+
+ // After unlocking, we should process the pending visual overflow recalc.
+ lockable->classList().Remove("hidden");
+ UpdateAllLifecyclePhasesForTest();
+
+ EXPECT_EQ(LayoutRect(0, 0, 200, 200), lockable_box->VisualOverflowRect());
+ EXPECT_EQ(LayoutRect(0, 0, 200, 200), lockable_box->LayoutOverflowRect());
+}
+
TEST_F(DisplayLockContextRenderingTest,
VisualOverflowCalculateOnChildPaintLayerInForcedLock) {
SetHtmlInnerHTML(R"HTML(
@@ -2025,15 +2150,7 @@ TEST_F(DisplayLockContextRenderingTest,
auto* unrelated_element = GetDocument().getElementById("unrelated");
auto* outer_element = GetDocument().getElementById("outer");
- // Since visibility switch happens at the start of the next lifecycle, we
- // should have clean layout for now.
- EXPECT_FALSE(outer_element->GetLayoutObject()->NeedsLayout());
- EXPECT_FALSE(outer_element->GetLayoutObject()->SelfNeedsLayout());
- EXPECT_FALSE(unrelated_element->GetLayoutObject()->NeedsLayout());
- EXPECT_FALSE(unrelated_element->GetLayoutObject()->SelfNeedsLayout());
- EXPECT_FALSE(inner_element->GetLayoutObject()->NeedsLayout());
- EXPECT_FALSE(inner_element->GetLayoutObject()->SelfNeedsLayout());
-
+ // Ensure that the visibility switch happens.
RunStartOfLifecycleTasks();
// Now that the intersection observer notifications switch the visibility of
@@ -2164,15 +2281,7 @@ TEST_F(DisplayLockContextRenderingTest, NestedLockDoesHideWhenItIsOffscreen) {
auto* unrelated_element = GetDocument().getElementById("unrelated");
auto* outer_element = GetDocument().getElementById("outer");
- // Since visibility switch happens at the start of the next lifecycle, we
- // should have clean layout for now.
- EXPECT_FALSE(outer_element->GetLayoutObject()->NeedsLayout());
- EXPECT_FALSE(outer_element->GetLayoutObject()->SelfNeedsLayout());
- EXPECT_FALSE(unrelated_element->GetLayoutObject()->NeedsLayout());
- EXPECT_FALSE(unrelated_element->GetLayoutObject()->SelfNeedsLayout());
- EXPECT_FALSE(inner_element->GetLayoutObject()->NeedsLayout());
- EXPECT_FALSE(inner_element->GetLayoutObject()->SelfNeedsLayout());
-
+ // Ensure that the visibility switch happens.
RunStartOfLifecycleTasks();
// Now that the intersection observer notifications switch the visibility of
@@ -2463,6 +2572,50 @@ TEST_F(DisplayLockContextRenderingTest, ContainStrictChild) {
UpdateAllLifecyclePhasesForTest();
}
+TEST_F(DisplayLockContextRenderingTest, UseCounter) {
+ SetHtmlInnerHTML(R"HTML(
+ <style>
+ .auto { content-visibility: auto; }
+ .hidden { content-visibility: hidden; }
+ .matchable { content-visibility: hidden-matchable; }
+ </style>
+ <div id=e1></div>
+ <div id=e2></div>
+ <div id=e3></div>
+ )HTML");
+
+ EXPECT_FALSE(GetDocument().IsUseCounted(WebFeature::kContentVisibilityAuto));
+ EXPECT_FALSE(
+ GetDocument().IsUseCounted(WebFeature::kContentVisibilityHidden));
+ EXPECT_FALSE(GetDocument().IsUseCounted(
+ WebFeature::kContentVisibilityHiddenMatchable));
+
+ GetDocument().getElementById("e1")->classList().Add("auto");
+ UpdateAllLifecyclePhasesForTest();
+
+ EXPECT_TRUE(GetDocument().IsUseCounted(WebFeature::kContentVisibilityAuto));
+ EXPECT_FALSE(
+ GetDocument().IsUseCounted(WebFeature::kContentVisibilityHidden));
+ EXPECT_FALSE(GetDocument().IsUseCounted(
+ WebFeature::kContentVisibilityHiddenMatchable));
+
+ GetDocument().getElementById("e2")->classList().Add("hidden");
+ UpdateAllLifecyclePhasesForTest();
+
+ EXPECT_TRUE(GetDocument().IsUseCounted(WebFeature::kContentVisibilityAuto));
+ EXPECT_TRUE(GetDocument().IsUseCounted(WebFeature::kContentVisibilityHidden));
+ EXPECT_FALSE(GetDocument().IsUseCounted(
+ WebFeature::kContentVisibilityHiddenMatchable));
+
+ GetDocument().getElementById("e3")->classList().Add("matchable");
+ UpdateAllLifecyclePhasesForTest();
+
+ EXPECT_TRUE(GetDocument().IsUseCounted(WebFeature::kContentVisibilityAuto));
+ EXPECT_TRUE(GetDocument().IsUseCounted(WebFeature::kContentVisibilityHidden));
+ EXPECT_TRUE(GetDocument().IsUseCounted(
+ WebFeature::kContentVisibilityHiddenMatchable));
+}
+
TEST_F(DisplayLockContextRenderingTest, CompositingRootIsSkippedIfLocked) {
SetHtmlInnerHTML(R"HTML(
<style>
@@ -2608,6 +2761,102 @@ TEST_F(DisplayLockContextRenderingTest,
EXPECT_TRUE(GetDocument().NeedsLayoutTreeUpdateForNode(*target));
}
+TEST_F(DisplayLockContextRenderingTest, InnerScrollerAutoVisibilityMargin) {
+ SetHtmlInnerHTML(R"HTML(
+ <style>
+ .auto { content-visibility: auto; }
+ #scroller { height: 300px; overflow: scroll }
+ #target { height: 10px; width: 10px; }
+ .spacer { height: 3000px }
+ </style>
+ <div id=scroller>
+ <div class=spacer></div>
+ <div id=target class=auto></div>
+ </div>
+ )HTML");
+
+ UpdateAllLifecyclePhasesForTest();
+ auto* target = GetDocument().getElementById("target");
+ ASSERT_TRUE(target->GetDisplayLockContext());
+ EXPECT_TRUE(target->GetDisplayLockContext()->IsLocked());
+
+ auto* scroller = GetDocument().getElementById("scroller");
+ // 2600 is spacer (3000) minus scroller height (300) minus 100 for some extra
+ // padding.
+ scroller->setScrollTop(2600);
+ UpdateAllLifecyclePhasesForTest();
+
+ // Since the intersection observation is delivered on the next frame, run
+ // another lifecycle.
+ UpdateAllLifecyclePhasesForTest();
+
+ EXPECT_FALSE(target->GetDisplayLockContext()->IsLocked());
+}
+
+TEST_F(DisplayLockContextRenderingTest,
+ AutoReachesStableStateOnContentSmallerThanLockedSize) {
+ SetHtmlInnerHTML(R"HTML(
+ <style>
+ .spacer { height: 10000px; }
+ .auto {
+ content-visibility: auto;
+ contain-intrinsic-size: 1px 10000px;
+ }
+ .auto > div {
+ height: 3000px;
+ }
+ </style>
+
+ <div class=spacer></div>
+ <div id=e1 class=auto><div>content</div></div>
+ <div id=e2 class=auto><div>content</div></div>
+ <div class=spacer></div>
+ )HTML");
+
+ UpdateAllLifecyclePhasesForTest();
+
+ GetDocument().scrollingElement()->setScrollTop(19000);
+
+ Element* element = GetDocument().getElementById("e1");
+
+ // Note that this test also unlock/relocks #e2 but we only care about #e1
+ // settling into a steady state.
+
+ // Initially we start with locked in the viewport.
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_TRUE(element->GetDisplayLockContext()->IsLocked());
+ EXPECT_EQ(GetDocument().scrollingElement()->scrollTop(), 19000.);
+
+ // It gets unlocked because it's in the viewport.
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_FALSE(element->GetDisplayLockContext()->IsLocked());
+ EXPECT_EQ(GetDocument().scrollingElement()->scrollTop(), 19000.);
+
+ // By unlocking it, it shrinks so next time it gets relocked.
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_TRUE(element->GetDisplayLockContext()->IsLocked());
+ EXPECT_EQ(GetDocument().scrollingElement()->scrollTop(), 19000.);
+
+ // It again gets unlocked and shrink.
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_FALSE(element->GetDisplayLockContext()->IsLocked());
+ EXPECT_EQ(GetDocument().scrollingElement()->scrollTop(), 19000.);
+
+ // On the next relock we select the following element as an anchor and thus
+ // the scroll top changes to be higher.
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_TRUE(element->GetDisplayLockContext()->IsLocked());
+ EXPECT_GT(GetDocument().scrollingElement()->scrollTop(), 19000.);
+
+ // Subsequent updates no longer unlock the element because even if its locked
+ // state it is far enough off-screen.
+ for (int i = 0; i < 5; ++i) {
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_TRUE(element->GetDisplayLockContext()->IsLocked());
+ EXPECT_GT(GetDocument().scrollingElement()->scrollTop(), 19000.);
+ }
+}
+
class DisplayLockContextLegacyRenderingTest
: public RenderingTest,
private ScopedCSSContentVisibilityHiddenMatchableForTest,
diff --git a/chromium/third_party/blink/renderer/core/display_lock/display_lock_document_state.cc b/chromium/third_party/blink/renderer/core/display_lock/display_lock_document_state.cc
index 2551d422d18..9e142c8ad7f 100644
--- a/chromium/third_party/blink/renderer/core/display_lock/display_lock_document_state.cc
+++ b/chromium/third_party/blink/renderer/core/display_lock/display_lock_document_state.cc
@@ -16,7 +16,7 @@ namespace blink {
DisplayLockDocumentState::DisplayLockDocumentState(Document* document)
: document_(document) {}
-void DisplayLockDocumentState::Trace(Visitor* visitor) {
+void DisplayLockDocumentState::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(intersection_observer_);
visitor->Trace(display_lock_contexts_);
@@ -93,7 +93,10 @@ IntersectionObserver& DisplayLockDocumentState::EnsureIntersectionObserver() {
WTF::BindRepeating(
&DisplayLockDocumentState::ProcessDisplayLockActivationObservation,
WrapWeakPersistent(this)),
- IntersectionObserver::kDeliverDuringPostLifecycleSteps);
+ IntersectionObserver::kDeliverDuringPostLifecycleSteps,
+ IntersectionObserver::kFractionOfTarget, 0 /* delay */,
+ false /* track_visibility */, false /* always report_root_bounds */,
+ IntersectionObserver::kApplyMarginToTarget);
}
return *intersection_observer_;
}
diff --git a/chromium/third_party/blink/renderer/core/display_lock/display_lock_document_state.h b/chromium/third_party/blink/renderer/core/display_lock/display_lock_document_state.h
index 371261b979a..f452817dbea 100644
--- a/chromium/third_party/blink/renderer/core/display_lock/display_lock_document_state.h
+++ b/chromium/third_party/blink/renderer/core/display_lock/display_lock_document_state.h
@@ -27,7 +27,7 @@ class CORE_EXPORT DisplayLockDocumentState final
explicit DisplayLockDocumentState(Document* document);
// GC.
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// Registers a display lock context with the state. This is used to force all
// activatable locks.
@@ -116,7 +116,7 @@ class CORE_EXPORT DisplayLockDocumentState final
DisplayLockUtilities::ScopedForcedUpdate::Impl* chain)
: node(node), self_forced(self_forced), chain(chain) {}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(node);
visitor->Trace(chain);
}
diff --git a/chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities.h b/chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities.h
index f9b43ec5004..ddb56de9578 100644
--- a/chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities.h
+++ b/chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities.h
@@ -72,7 +72,7 @@ class CORE_EXPORT DisplayLockUtilities {
void Destroy();
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(node_);
visitor->Trace(forced_context_set_);
visitor->Trace(parent_frame_impl_);
diff --git a/chromium/third_party/blink/renderer/core/display_lock/render_subtree_activation_event.cc b/chromium/third_party/blink/renderer/core/display_lock/render_subtree_activation_event.cc
deleted file mode 100644
index 41a573acb7e..00000000000
--- a/chromium/third_party/blink/renderer/core/display_lock/render_subtree_activation_event.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/display_lock/render_subtree_activation_event.h"
-
-#include "third_party/blink/renderer/core/dom/element.h"
-#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
-#include "third_party/blink/renderer/core/event_interface_names.h"
-
-namespace blink {
-
-const AtomicString& RenderSubtreeActivationEvent::InterfaceName() const {
- return event_interface_names::kRenderSubtreeActivationEvent;
-}
-
-RenderSubtreeActivationEvent::RenderSubtreeActivationEvent(
- Element& activated_element)
- : Event(event_type_names::kRendersubtreeactivation,
- Bubbles::kYes,
- Cancelable::kYes,
- ComposedMode::kScoped),
- activated_element_(activated_element) {}
-
-void RenderSubtreeActivationEvent::Trace(Visitor* visitor) {
- visitor->Trace(activated_element_);
- Event::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/display_lock/render_subtree_activation_event.h b/chromium/third_party/blink/renderer/core/display_lock/render_subtree_activation_event.h
deleted file mode 100644
index 386007f4e3d..00000000000
--- a/chromium/third_party/blink/renderer/core/display_lock/render_subtree_activation_event.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DISPLAY_LOCK_RENDER_SUBTREE_ACTIVATION_EVENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_DISPLAY_LOCK_RENDER_SUBTREE_ACTIVATION_EVENT_H_
-
-#include "third_party/blink/renderer/core/dom/events/event.h"
-
-namespace blink {
-
-class Element;
-
-class RenderSubtreeActivationEvent : public Event {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- explicit RenderSubtreeActivationEvent(Element& activated_element);
-
- Element& activatedElement() const { return *activated_element_.Get(); }
-
- const AtomicString& InterfaceName() const override;
-
- void Trace(Visitor*) override;
-
- private:
- Member<Element> activated_element_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DISPLAY_LOCK_RENDER_SUBTREE_ACTIVATION_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/core/display_lock/render_subtree_activation_event.idl b/chromium/third_party/blink/renderer/core/display_lock/render_subtree_activation_event.idl
deleted file mode 100644
index b304b20d346..00000000000
--- a/chromium/third_party/blink/renderer/core/display_lock/render_subtree_activation_event.idl
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-[
- Exposed=Window,
- RuntimeEnabled=CSSContentVisibilityActivationEvent
-] interface RenderSubtreeActivationEvent : Event {
- readonly attribute Element activatedElement;
-};
diff --git a/chromium/third_party/blink/renderer/core/dom/abort_controller.cc b/chromium/third_party/blink/renderer/core/dom/abort_controller.cc
index 5bfa9f482af..8f5ca85fa31 100644
--- a/chromium/third_party/blink/renderer/core/dom/abort_controller.cc
+++ b/chromium/third_party/blink/renderer/core/dom/abort_controller.cc
@@ -22,7 +22,7 @@ void AbortController::abort() {
signal_->SignalAbort();
}
-void AbortController::Trace(Visitor* visitor) {
+void AbortController::Trace(Visitor* visitor) const {
visitor->Trace(signal_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/abort_controller.h b/chromium/third_party/blink/renderer/core/dom/abort_controller.h
index 133f6276d52..9feb38855cf 100644
--- a/chromium/third_party/blink/renderer/core/dom/abort_controller.h
+++ b/chromium/third_party/blink/renderer/core/dom/abort_controller.h
@@ -34,7 +34,7 @@ class CORE_EXPORT AbortController : public ScriptWrappable {
// https://dom.spec.whatwg.org/#dom-abortcontroller-abort
void abort();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<AbortSignal> signal_;
diff --git a/chromium/third_party/blink/renderer/core/dom/abort_signal.cc b/chromium/third_party/blink/renderer/core/dom/abort_signal.cc
index 64cafa08bdb..97968689a8b 100644
--- a/chromium/third_party/blink/renderer/core/dom/abort_signal.cc
+++ b/chromium/third_party/blink/renderer/core/dom/abort_signal.cc
@@ -75,7 +75,7 @@ void AbortSignal::Follow(AbortSignal* parentSignal) {
parentSignal->AddSignalAbortAlgorithm(this);
}
-void AbortSignal::Trace(Visitor* visitor) {
+void AbortSignal::Trace(Visitor* visitor) const {
visitor->Trace(execution_context_);
visitor->Trace(dependent_signals_);
EventTargetWithInlineData::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/dom/abort_signal.h b/chromium/third_party/blink/renderer/core/dom/abort_signal.h
index 1915edd025e..22efc1ede00 100644
--- a/chromium/third_party/blink/renderer/core/dom/abort_signal.h
+++ b/chromium/third_party/blink/renderer/core/dom/abort_signal.h
@@ -61,7 +61,7 @@ class CORE_EXPORT AbortSignal : public EventTargetWithInlineData {
virtual bool IsTaskSignal() const { return false; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void AddSignalAbortAlgorithm(AbortSignal*);
diff --git a/chromium/third_party/blink/renderer/core/dom/attr.cc b/chromium/third_party/blink/renderer/core/dom/attr.cc
index 6551d03fc73..e3c1d26e2b0 100644
--- a/chromium/third_party/blink/renderer/core/dom/attr.cc
+++ b/chromium/third_party/blink/renderer/core/dom/attr.cc
@@ -105,7 +105,7 @@ void Attr::AttachToElement(Element* element,
standalone_value_or_attached_local_name_ = attached_local_name;
}
-void Attr::Trace(Visitor* visitor) {
+void Attr::Trace(Visitor* visitor) const {
visitor->Trace(element_);
Node::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/attr.h b/chromium/third_party/blink/renderer/core/dom/attr.h
index 724c411d96a..e7a85e1632a 100644
--- a/chromium/third_party/blink/renderer/core/dom/attr.h
+++ b/chromium/third_party/blink/renderer/core/dom/attr.h
@@ -57,7 +57,7 @@ class CORE_EXPORT Attr final : public Node {
const AtomicString& namespaceURI() const { return name_.NamespaceURI(); }
const AtomicString& prefix() const { return name_.Prefix(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool IsElementNode() const =
diff --git a/chromium/third_party/blink/renderer/core/dom/attr_test.cc b/chromium/third_party/blink/renderer/core/dom/attr_test.cc
index d3245defda3..efa8ecbb984 100644
--- a/chromium/third_party/blink/renderer/core/dom/attr_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/attr_test.cc
@@ -24,7 +24,7 @@ class AttrTest : public testing::Test {
};
void AttrTest::SetUp() {
- document_ = MakeGarbageCollected<Document>();
+ document_ = Document::CreateForTest();
value_ = "value";
}
diff --git a/chromium/third_party/blink/renderer/core/dom/attribute_collection.h b/chromium/third_party/blink/renderer/core/dom/attribute_collection.h
index c315c86c131..c403f85ba4b 100644
--- a/chromium/third_party/blink/renderer/core/dom/attribute_collection.h
+++ b/chromium/third_party/blink/renderer/core/dom/attribute_collection.h
@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/core/dom/attribute.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string_table.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -67,8 +68,56 @@ class AttributeCollectionGeneric {
wtf_size_t FindIndex(const QualifiedName&) const;
wtf_size_t FindIndex(const AtomicString& name) const;
+ // FindHinted() and FindIndexHinted() have subtle semantics.
+ //
+ // The |hint| is a WeakResult that represents whether or not an AtomicString
+ // exists for the AttributeCollectionGeneric version of |name| which has two
+ // odd quirks:
+ //
+ // 1) In an HTML context, the hint will be from a lookup of the ASCII
+ // lowercased version of the attribute |name| as is required by spec.
+ // 2) The |hint| is a snapshot of a membership query of the
+ // AtomicStringTable from a specific point in time.
+ //
+ // For (1), the HTML spec says that attribute names without prefixes should
+ // be lowercased before comparison. However, if an attribute is added with
+ // a namespace using the *NS() attribute APIs then lookup becomes case
+ // sensitive. Therefore the API require both non-lowercased |name| and a
+ // lowercased |hint|.
+ //
+ // For (2), the caller must ensure that its logic is robust to changes in
+ // the AtomicStringTable between the creation of the |hint| and its use with
+ // this API. In particular, one should not modify |collection| between
+ // creation of |hint| and execution of any hinted function.
+ //
+ // A concrete example of a valid usage pattern is:
+ //
+ // WTF::AtomicStringTable::WeakResult hint =
+ // WTF::AtomicStringTable::WeakFindLowercased(name);
+ // .... Mutate |WTF::AtomicStringTable| but not |collection| ....
+ // collection.FindHinted(name, hint);
+ //
+ // Because FindHinted() is an existence check, as long as collection is not
+ // mutated between the hint creation and the lookup, we know that
+ //
+ // (a) If hint.IsNull(), it cannot ever be in |collection| since
+ // then the corresponding AtomicString would be found in
+ // the AtomicStringTable.
+ // (b) If !hint.IsNull() and hint is in |collection| then the table
+ // has a reference to the corresponding AtomicString meaning
+ // it will not be removed from the AtomicString.
+ // (c) If the !hint.IsNull() and it is not in |collection|, then it is
+ // possible that the underlying memory buffer for the AtomicString
+ // corresponding to the him can be reallocated to a different string
+ // making the |hint| semantically invalid. However, because the
+ // |collection| is not mutated, |hint| will not match anything.
+ iterator FindHinted(const StringView& name,
+ WTF::AtomicStringTable::WeakResult hint) const;
+ wtf_size_t FindIndexHinted(const StringView& name,
+ WTF::AtomicStringTable::WeakResult hint) const;
+
protected:
- wtf_size_t FindSlowCase(const AtomicString& name) const;
+ wtf_size_t FindWithPrefix(const StringView& name) const;
ContainerMemberType attributes_;
};
@@ -134,6 +183,16 @@ AttributeCollectionGeneric<Container, ContainerMemberType>::Find(
}
template <typename Container, typename ContainerMemberType>
+inline typename AttributeCollectionGeneric<Container,
+ ContainerMemberType>::iterator
+AttributeCollectionGeneric<Container, ContainerMemberType>::FindHinted(
+ const StringView& name,
+ WTF::AtomicStringTable::WeakResult hint) const {
+ wtf_size_t index = FindIndexHinted(name, hint);
+ return index != kNotFound ? &at(index) : nullptr;
+}
+
+template <typename Container, typename ContainerMemberType>
inline wtf_size_t
AttributeCollectionGeneric<Container, ContainerMemberType>::FindIndex(
const QualifiedName& name) const {
@@ -150,7 +209,17 @@ template <typename Container, typename ContainerMemberType>
inline wtf_size_t
AttributeCollectionGeneric<Container, ContainerMemberType>::FindIndex(
const AtomicString& name) const {
- bool do_slow_check = false;
+ return FindIndexHinted(name, WTF::AtomicStringTable::WeakResult(name.Impl()));
+}
+
+template <typename Container, typename ContainerMemberType>
+inline wtf_size_t
+AttributeCollectionGeneric<Container, ContainerMemberType>::FindIndexHinted(
+ const StringView& name,
+ WTF::AtomicStringTable::WeakResult hint) const {
+ // A slow check is required if there are any attributes with prefixes
+ // and no unprefixed name matches.
+ bool has_attributes_with_prefixes = false;
// Optimize for the case where the attribute exists and its name exactly
// matches.
@@ -160,15 +229,17 @@ AttributeCollectionGeneric<Container, ContainerMemberType>::FindIndex(
// FIXME: Why check the prefix? Namespaces should be all that matter.
// Most attributes (all of HTML and CSS) have no namespace.
if (!it->GetName().HasPrefix()) {
- if (name == it->LocalName())
+ if (hint == it->LocalName())
return index;
} else {
- do_slow_check = true;
+ has_attributes_with_prefixes = true;
}
}
- if (do_slow_check)
- return FindSlowCase(name);
+ // Note that if the attribute has a prefix, the match has to be case
+ // sensitive therefore |name| must be used.
+ if (has_attributes_with_prefixes)
+ return FindWithPrefix(name);
return kNotFound;
}
@@ -187,17 +258,18 @@ AttributeCollectionGeneric<Container, ContainerMemberType>::Find(
template <typename Container, typename ContainerMemberType>
wtf_size_t
-AttributeCollectionGeneric<Container, ContainerMemberType>::FindSlowCase(
- const AtomicString& name) const {
- // Continue to checking case-insensitively and/or full namespaced names if
- // necessary:
+AttributeCollectionGeneric<Container, ContainerMemberType>::FindWithPrefix(
+ const StringView& name) const {
+ // Check all attributes with prefixes. This is a case sensitive check.
+ // Attributes with empty prefixes are expected to be handled outside this
+ // function.
iterator end = this->end();
wtf_size_t index = 0;
for (iterator it = begin(); it != end; ++it, ++index) {
if (!it->GetName().HasPrefix()) {
// Skip attributes with no prefixes because they must be checked in
// FindIndex(const AtomicString&).
- DCHECK_NE(name, it->LocalName());
+ DCHECK(!(name == it->LocalName()));
} else {
// FIXME: Would be faster to do this comparison without calling ToString,
// which generates a temporary string by concatenation. But this branch is
diff --git a/chromium/third_party/blink/renderer/core/dom/beforeunload_event_listener.cc b/chromium/third_party/blink/renderer/core/dom/beforeunload_event_listener.cc
index a66ac3a2b91..38a80e26eb8 100644
--- a/chromium/third_party/blink/renderer/core/dom/beforeunload_event_listener.cc
+++ b/chromium/third_party/blink/renderer/core/dom/beforeunload_event_listener.cc
@@ -21,7 +21,7 @@ void BeforeUnloadEventListener::Invoke(ExecutionContext* execution_context,
To<BeforeUnloadEvent>(event)->setReturnValue(g_empty_string);
}
-void BeforeUnloadEventListener::Trace(Visitor* visitor) {
+void BeforeUnloadEventListener::Trace(Visitor* visitor) const {
visitor->Trace(doc_);
NativeEventListener::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/beforeunload_event_listener.h b/chromium/third_party/blink/renderer/core/dom/beforeunload_event_listener.h
index 9f5f71386dd..75586b00c18 100644
--- a/chromium/third_party/blink/renderer/core/dom/beforeunload_event_listener.h
+++ b/chromium/third_party/blink/renderer/core/dom/beforeunload_event_listener.h
@@ -26,7 +26,7 @@ class BeforeUnloadEventListener : public NativeEventListener {
show_dialog_ = show_dialog;
}
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
void Invoke(ExecutionContext*, Event* event) override;
diff --git a/chromium/third_party/blink/renderer/core/dom/child_list_mutation_scope.cc b/chromium/third_party/blink/renderer/core/dom/child_list_mutation_scope.cc
index 094924a7381..4e7afce6f78 100644
--- a/chromium/third_party/blink/renderer/core/dom/child_list_mutation_scope.cc
+++ b/chromium/third_party/blink/renderer/core/dom/child_list_mutation_scope.cc
@@ -151,7 +151,7 @@ bool ChildListMutationAccumulator::IsEmpty() {
return result;
}
-void ChildListMutationAccumulator::Trace(Visitor* visitor) {
+void ChildListMutationAccumulator::Trace(Visitor* visitor) const {
visitor->Trace(target_);
visitor->Trace(removed_nodes_);
visitor->Trace(added_nodes_);
diff --git a/chromium/third_party/blink/renderer/core/dom/child_list_mutation_scope.h b/chromium/third_party/blink/renderer/core/dom/child_list_mutation_scope.h
index e8290df1d71..0f6bd80b2e1 100644
--- a/chromium/third_party/blink/renderer/core/dom/child_list_mutation_scope.h
+++ b/chromium/third_party/blink/renderer/core/dom/child_list_mutation_scope.h
@@ -66,7 +66,7 @@ class ChildListMutationAccumulator final
void EnterMutationScope() { mutation_scopes_++; }
void LeaveMutationScope();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void EnqueueMutationRecord();
diff --git a/chromium/third_party/blink/renderer/core/dom/child_node_list.cc b/chromium/third_party/blink/renderer/core/dom/child_node_list.cc
index fbd31f32306..c6599f17f3c 100644
--- a/chromium/third_party/blink/renderer/core/dom/child_node_list.cc
+++ b/chromium/third_party/blink/renderer/core/dom/child_node_list.cc
@@ -79,7 +79,7 @@ Node* ChildNodeList::TraverseBackwardToOffset(unsigned offset,
return nullptr;
}
-void ChildNodeList::Trace(Visitor* visitor) {
+void ChildNodeList::Trace(Visitor* visitor) const {
visitor->Trace(parent_);
visitor->Trace(collection_index_cache_);
NodeList::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/dom/child_node_list.h b/chromium/third_party/blink/renderer/core/dom/child_node_list.h
index 80d86082530..1ba5bf92488 100644
--- a/chromium/third_party/blink/renderer/core/dom/child_node_list.h
+++ b/chromium/third_party/blink/renderer/core/dom/child_node_list.h
@@ -60,7 +60,7 @@ class ChildNodeList final : public NodeList {
Node& current_node,
unsigned& current_offset) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool IsChildNodeList() const override { return true; }
diff --git a/chromium/third_party/blink/renderer/core/dom/collection_index_cache.h b/chromium/third_party/blink/renderer/core/dom/collection_index_cache.h
index caf4bf7b3c1..1907d41209a 100644
--- a/chromium/third_party/blink/renderer/core/dom/collection_index_cache.h
+++ b/chromium/third_party/blink/renderer/core/dom/collection_index_cache.h
@@ -66,7 +66,7 @@ class CollectionIndexCache {
void NodeInserted();
void NodeRemoved();
- virtual void Trace(Visitor* visitor) { visitor->Trace(current_node_); }
+ virtual void Trace(Visitor* visitor) const { visitor->Trace(current_node_); }
protected:
ALWAYS_INLINE NodeType* CachedNode() const { return current_node_; }
diff --git a/chromium/third_party/blink/renderer/core/dom/container_node.cc b/chromium/third_party/blink/renderer/core/dom/container_node.cc
index 7eacc4f0932..21ab2589958 100644
--- a/chromium/third_party/blink/renderer/core/dom/container_node.cc
+++ b/chromium/third_party/blink/renderer/core/dom/container_node.cc
@@ -658,7 +658,7 @@ void ContainerNode::WillRemoveChildren() {
ChildFrameDisconnector::kDescendantsOnly);
}
-void ContainerNode::Trace(Visitor* visitor) {
+void ContainerNode::Trace(Visitor* visitor) const {
visitor->Trace(first_child_);
visitor->Trace(last_child_);
Node::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/dom/container_node.h b/chromium/third_party/blink/renderer/core/dom/container_node.h
index 209f085f8e5..a698ddcdceb 100644
--- a/chromium/third_party/blink/renderer/core/dom/container_node.h
+++ b/chromium/third_party/blink/renderer/core/dom/container_node.h
@@ -385,7 +385,7 @@ class CORE_EXPORT ContainerNode : public Node {
virtual bool ChildrenCanHaveStyle() const { return true; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
ContainerNode(TreeScope*, ConstructionType = kCreateContainer);
diff --git a/chromium/third_party/blink/renderer/core/dom/context_features_client_impl.cc b/chromium/third_party/blink/renderer/core/dom/context_features_client_impl.cc
index 390c594ff0c..084ea9cf33a 100644
--- a/chromium/third_party/blink/renderer/core/dom/context_features_client_impl.cc
+++ b/chromium/third_party/blink/renderer/core/dom/context_features_client_impl.cc
@@ -87,7 +87,7 @@ class ContextFeaturesCache final
void ValidateAgainst(Document*);
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
Supplement<Document>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/create_element_flags.h b/chromium/third_party/blink/renderer/core/dom/create_element_flags.h
index 37accd81586..dcabf7adf44 100644
--- a/chromium/third_party/blink/renderer/core/dom/create_element_flags.h
+++ b/chromium/third_party/blink/renderer/core/dom/create_element_flags.h
@@ -7,19 +7,24 @@
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+namespace blink {
+
+class Document;
+
class CreateElementFlags {
STACK_ALLOCATED();
public:
bool IsCreatedByParser() const { return created_by_parser_; }
+ Document* ParserDocument() const { return parser_document_; }
bool IsAsyncCustomElements() const { return async_custom_elements_; }
bool IsCustomElementsV1() const { return custom_elements_v1_; }
bool IsCustomElementsV0() const { return custom_elements_v0_; }
bool WasAlreadyStarted() const { return already_started_; }
// https://html.spec.whatwg.org/C/#create-an-element-for-the-token
- static CreateElementFlags ByParser() {
- return CreateElementFlags().SetCreatedByParser(true);
+ static CreateElementFlags ByParser(Document* document) {
+ return CreateElementFlags().SetCreatedByParser(true, document);
}
// https://dom.spec.whatwg.org/#concept-node-clone
@@ -37,9 +42,9 @@ class CreateElementFlags {
}
// https://html.spec.whatwg.org/C/#create-an-element-for-the-token
- static CreateElementFlags ByFragmentParser() {
+ static CreateElementFlags ByFragmentParser(Document* document) {
return CreateElementFlags()
- .SetCreatedByParser(true)
+ .SetCreatedByParser(true, document)
.SetAsyncCustomElements();
}
@@ -51,8 +56,10 @@ class CreateElementFlags {
custom_elements_v0_(true),
already_started_(false) {}
- CreateElementFlags& SetCreatedByParser(bool flag) {
+ CreateElementFlags& SetCreatedByParser(bool flag, Document* document) {
+ DCHECK(flag || !document);
created_by_parser_ = flag;
+ parser_document_ = document;
return *this;
}
@@ -81,6 +88,18 @@ class CreateElementFlags {
}
bool created_by_parser_ : 1;
+ // This implements the HTML Standard concept of a "parser document" [1].
+ // Contrary to the spec, this member can be null even when
+ // |created_by_parser_| is true. This can happen in rare cases where the
+ // parser creates an element after it detaches from its document. The element
+ // will be constructed with |created_by_parser_| = true, but the parser's
+ // document used for |parser_document_| is null. If the parser is ever changed
+ // such that elements created after detachment are constructed with
+ // |created_by_parser_| = false, we can get rid of that flag and simply query
+ // |parser_document_| for this information. See crbug.com/1086507.
+ // [1]: https://html.spec.whatwg.org/C/#parser-document
+ Document* parser_document_;
+
bool async_custom_elements_ : 1;
bool custom_elements_v1_ : 1;
bool custom_elements_v0_ : 1;
@@ -88,4 +107,6 @@ class CreateElementFlags {
bool already_started_ : 1;
};
+} // namespace blink
+
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_CREATE_ELEMENT_FLAGS_H_
diff --git a/chromium/third_party/blink/renderer/core/dom/dataset_dom_string_map.cc b/chromium/third_party/blink/renderer/core/dom/dataset_dom_string_map.cc
index 77a2ed4f2b7..ae60b21220f 100644
--- a/chromium/third_party/blink/renderer/core/dom/dataset_dom_string_map.cc
+++ b/chromium/third_party/blink/renderer/core/dom/dataset_dom_string_map.cc
@@ -200,7 +200,7 @@ bool DatasetDOMStringMap::DeleteItem(const String& name) {
return false;
}
-void DatasetDOMStringMap::Trace(Visitor* visitor) {
+void DatasetDOMStringMap::Trace(Visitor* visitor) const {
visitor->Trace(element_);
DOMStringMap::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/dataset_dom_string_map.h b/chromium/third_party/blink/renderer/core/dom/dataset_dom_string_map.h
index 71379d4dca5..53734f3618e 100644
--- a/chromium/third_party/blink/renderer/core/dom/dataset_dom_string_map.h
+++ b/chromium/third_party/blink/renderer/core/dom/dataset_dom_string_map.h
@@ -45,7 +45,7 @@ class DatasetDOMStringMap final : public DOMStringMap {
ExceptionState&) override;
bool DeleteItem(const String& name) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Element> element_;
diff --git a/chromium/third_party/blink/renderer/core/dom/distributed_nodes.cc b/chromium/third_party/blink/renderer/core/dom/distributed_nodes.cc
index 8b7f4478414..0119b90fef4 100644
--- a/chromium/third_party/blink/renderer/core/dom/distributed_nodes.cc
+++ b/chromium/third_party/blink/renderer/core/dom/distributed_nodes.cc
@@ -66,7 +66,7 @@ Node* DistributedNodes::PreviousTo(const Node* node) const {
return at(index - 1);
}
-void DistributedNodes::Trace(Visitor* visitor) {
+void DistributedNodes::Trace(Visitor* visitor) const {
visitor->Trace(nodes_);
visitor->Trace(indices_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/distributed_nodes.h b/chromium/third_party/blink/renderer/core/dom/distributed_nodes.h
index 265dd6e67b3..b649acccf2e 100644
--- a/chromium/third_party/blink/renderer/core/dom/distributed_nodes.h
+++ b/chromium/third_party/blink/renderer/core/dom/distributed_nodes.h
@@ -64,7 +64,7 @@ class DistributedNodes final {
void Swap(DistributedNodes& other);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
HeapVector<Member<Node>> nodes_;
diff --git a/chromium/third_party/blink/renderer/core/dom/document.cc b/chromium/third_party/blink/renderer/core/dom/document.cc
index fb101440a37..2fea6ad5cb1 100644
--- a/chromium/third_party/blink/renderer/core/dom/document.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document.cc
@@ -42,6 +42,7 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/mojom/base/text_direction.mojom-blink.h"
+#include "services/metrics/public/cpp/metrics_utils.h"
#include "services/metrics/public/cpp/mojo_ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
@@ -51,6 +52,7 @@
#include "services/network/public/mojom/web_sandbox_flags.mojom-blink.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/public/common/css/preferred_color_scheme.h"
#include "third_party/blink/public/common/feature_policy/document_policy_features.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
@@ -155,10 +157,8 @@
#include "third_party/blink/renderer/core/events/page_transition_event.h"
#include "third_party/blink/renderer/core/events/visual_viewport_resize_event.h"
#include "third_party/blink/renderer/core/events/visual_viewport_scroll_event.h"
-#include "third_party/blink/renderer/core/execution_context/agent_metrics_collector.h"
#include "third_party/blink/renderer/core/execution_context/security_context_init.h"
#include "third_party/blink/renderer/core/execution_context/window_agent.h"
-#include "third_party/blink/renderer/core/execution_context/window_agent_factory.h"
#include "third_party/blink/renderer/core/feature_policy/dom_document_policy.h"
#include "third_party/blink/renderer/core/feature_policy/feature_policy_parser.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
@@ -216,6 +216,7 @@
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/html/parser/nesting_level_incrementer.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
+#include "third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.h"
#include "third_party/blink/renderer/core/html/plugin_document.h"
#include "third_party/blink/renderer/core/html/portal/document_portals.h"
#include "third_party/blink/renderer/core/html/portal/portal_contents.h"
@@ -246,7 +247,6 @@
#include "third_party/blink/renderer/core/loader/interactive_detector.h"
#include "third_party/blink/renderer/core/loader/prerenderer_client.h"
#include "third_party/blink/renderer/core/loader/progress_tracker.h"
-#include "third_party/blink/renderer/core/loader/text_resource_decoder_builder.h"
#include "third_party/blink/renderer/core/mathml/mathml_element.h"
#include "third_party/blink/renderer/core/mathml/mathml_row_element.h"
#include "third_party/blink/renderer/core/mathml_element_factory.h"
@@ -256,6 +256,7 @@
#include "third_party/blink/renderer/core/page/event_with_hit_test_results.h"
#include "third_party/blink/renderer/core/page/focus_controller.h"
#include "third_party/blink/renderer/core/page/frame_tree.h"
+#include "third_party/blink/renderer/core/page/named_pages_mapper.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/plugin_script_forbidden_scope.h"
#include "third_party/blink/renderer/core/page/pointer_lock_controller.h"
@@ -313,12 +314,12 @@
#include "third_party/blink/renderer/platform/scheduler/public/event_loop.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
-#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
#include "third_party/blink/renderer/platform/web_test_support.h"
#include "third_party/blink/renderer/platform/weborigin/origin_access_entry.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+#include "third_party/blink/renderer/platform/widget/frame_widget.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/hash_functions.h"
@@ -336,6 +337,25 @@ namespace blink {
namespace {
+// This enum must match the numbering for RequestStorageResult in
+// histograms/enums.xml. Do not reorder or remove items, only add new items
+// at the end.
+enum class RequestStorageResult {
+ APPROVED_EXISTING_ACCESS = 0,
+ APPROVED_NEW_GRANT = 1,
+ REJECTED_NO_USER_GESTURE = 2,
+ REJECTED_NO_ORIGIN = 3,
+ REJECTED_OPAQUE_ORIGIN = 4,
+ REJECTED_EXISTING_DENIAL = 5,
+ REJECTED_SANDBOXED = 6,
+ REJECTED_GRANT_DENIED = 7,
+ kMaxValue = REJECTED_GRANT_DENIED,
+};
+void FireRequestStorageAccessHistogram(RequestStorageResult result) {
+ base::UmaHistogramEnumeration("API.StorageAccess.RequestStorageAccess",
+ result);
+}
+
// Returns true if any of <object> ancestors don't start loading or are loading
// plugins/frames/images. If there are no <object> ancestors, this function
// returns false.
@@ -616,7 +636,7 @@ class Document::NetworkStateObserver final
online_observer_handle_ = nullptr;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
ExecutionContextLifecycleObserver::Trace(visitor);
}
@@ -639,16 +659,18 @@ ExplicitlySetAttrElementsMap* Document::GetExplicitlySetAttrElementsMap(
}
Document* Document::Create(Document& document) {
- Document* new_document =
- MakeGarbageCollected<Document>(DocumentInit::Create()
- .WithContextDocument(&document)
- .WithURL(BlankURL())
- .WithOwnerDocument(&document));
+ Document* new_document = MakeGarbageCollected<Document>(
+ DocumentInit::Create()
+ .WithExecutionContext(document.GetExecutionContext())
+ .WithURL(BlankURL())
+ .WithOwnerDocument(&document));
new_document->SetContextFeatures(document.GetContextFeatures());
return new_document;
}
-Document::Document() : Document(DocumentInit::Create()) {}
+Document* Document::CreateForTest() {
+ return MakeGarbageCollected<Document>(DocumentInit::Create().ForTest());
+}
Document::Document(const DocumentInit& initializer,
DocumentClassFlags document_classes)
@@ -663,15 +685,12 @@ Document::Document(const DocumentInit& initializer,
TreeScope(*this),
evaluate_media_queries_on_style_recalc_(false),
pending_sheet_layout_(kNoLayoutWithPendingSheets),
- window_agent_factory_(initializer.GetWindowAgentFactory()),
- frame_(initializer.GetFrame()),
- // TODO(dcheng): Why does this need both a LocalFrame and LocalDOMWindow
- // pointer?
- dom_window_(frame_ ? frame_->DomWindow() : nullptr),
+ dom_window_(initializer.GetFrame() ? initializer.GetFrame()->DomWindow()
+ : nullptr),
imports_controller_(initializer.ImportsController()),
security_context_(security_initializer, SecurityContext::kWindow),
use_counter_during_construction_(initializer.GetUseCounter()),
- context_document_(initializer.ContextDocument()),
+ execution_context_(initializer.GetExecutionContext()),
context_features_(ContextFeatures::DefaultSwitch()),
http_refresh_scheduler_(MakeGarbageCollected<HttpRefreshScheduler>(this)),
well_formed_(false),
@@ -697,11 +716,11 @@ Document::Document(const DocumentInit& initializer,
// associated parser here (we create the parser in ImplicitOpen). But
// waiting to set the ready state to 'loading' in ImplicitOpen fires a
// readystatechange event, which can be observed in the case where we
- // reuse a window. If there's a window being reused, then there must be
- // a frame, and if there's a frame, there must be an associated parser, so
- // setting based on frame_ here is sufficient to ensure that the quirk of
- // when we set the ready state is not web-observable.
- ready_state_(frame_ ? kLoading : kComplete),
+ // reuse a window. If there's a window being reused, there must be an
+ // associated parser, so setting based on dom_window_ here is sufficient
+ // to ensure that the quirk of when we set the ready state is not
+ // web-observable.
+ ready_state_(dom_window_ ? kLoading : kComplete),
parsing_state_(kFinishedParsing),
contains_plugins_(false),
ignore_destructive_write_count_(0),
@@ -742,7 +761,6 @@ Document::Document(const DocumentInit& initializer,
write_recursion_depth_(0),
scripted_animation_controller_(
MakeGarbageCollected<ScriptedAnimationController>(domWindow())),
- current_frame_is_throttled_(false),
registration_context_(initializer.RegistrationContext(this)),
element_data_cache_clear_timer_(
GetTaskRunner(TaskType::kInternalUserInteraction),
@@ -759,38 +777,34 @@ Document::Document(const DocumentInit& initializer,
this,
&Document::DidAssociateFormControlsTimerFired),
has_viewport_units_(false),
- parser_sync_policy_(kAllowAsynchronousParsing),
+ parser_sync_policy_(
+ RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()
+ ? kAllowDeferredParsing
+ : kAllowAsynchronousParsing),
node_count_(0),
logged_field_edit_(false),
ukm_source_id_(ukm::UkmRecorder::GetNewSourceID()),
needs_to_record_ukm_outlive_time_(false),
viewport_data_(MakeGarbageCollected<ViewportData>(*this)),
is_for_external_handler_(initializer.IsForExternalHandler()),
- isolated_world_csp_map_(
- MakeGarbageCollected<
- HeapHashMap<int, Member<ContentSecurityPolicy>>>()),
display_lock_document_state_(
MakeGarbageCollected<DisplayLockDocumentState>(this)),
permission_service_(GetExecutionContext()),
has_trust_tokens_answerer_(GetExecutionContext()),
font_preload_manager_(*this) {
- security_initializer.ApplyPendingDataToDocument(*this);
GetOriginTrialContext()->BindExecutionContext(GetExecutionContext());
- if (frame_) {
+ if (dom_window_) {
pending_fp_headers_ = security_initializer.FeaturePolicyHeader();
pending_dp_headers_ = initializer.GetDocumentPolicy().feature_state;
}
- if (frame_) {
- DCHECK(frame_->GetPage());
- ProvideContextFeaturesToDocumentFrom(*this, *frame_->GetPage());
+ if (GetFrame()) {
+ DCHECK(GetFrame()->GetPage());
+ ProvideContextFeaturesToDocumentFrom(*this, *GetFrame()->GetPage());
fetcher_ = FrameFetchContext::CreateFetcherForCommittedDocument(
- *frame_->Loader().GetDocumentLoader(), *this);
- // TODO(dcheng): Why does this need to check that DOMWindow is non-null?
- CustomElementRegistry* registry =
- frame_->DomWindow() ? frame_->DomWindow()->MaybeCustomElements()
- : nullptr;
+ *GetFrame()->Loader().GetDocumentLoader(), *this);
+ CustomElementRegistry* registry = dom_window_->MaybeCustomElements();
if (registry && registration_context_)
registry->Entangle(registration_context_);
cookie_jar_ = MakeGarbageCollected<CookieJar>(this);
@@ -853,15 +867,13 @@ Document::Document(const DocumentInit& initializer,
// objects, else this new Document would have a new ExecutionContext which
// suspended state would not match the one from the parent, and could start
// loading resources ignoring the defersLoading flag.
- DCHECK(!ParentDocument() || !ParentDocument()->IsContextPaused());
+ DCHECK(!ParentDocument() ||
+ !ParentDocument()->domWindow()->IsContextPaused());
#ifndef NDEBUG
liveDocumentSet().insert(this);
#endif
- if (frame_ && frame_->GetPage()->GetAgentMetricsCollector())
- frame_->GetPage()->GetAgentMetricsCollector()->DidAttachDocument(*this);
-
// We will use Loader() as UseCounter after initialization.
use_counter_during_construction_ = nullptr;
}
@@ -957,58 +969,6 @@ Location* Document::location() const {
return domWindow()->location();
}
-ContentSecurityPolicy* Document::GetContentSecurityPolicyForWorld() {
- v8::Isolate* isolate = GetIsolate();
- if (!isolate)
- return GetContentSecurityPolicy();
- v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Context> v8_context = isolate->GetCurrentContext();
-
- // This can be called before we enter v8, hence the context might be empty,
- // which implies we are not in an isolated world.
- if (v8_context.IsEmpty())
- return GetContentSecurityPolicy();
-
- DOMWrapperWorld& world = DOMWrapperWorld::Current(isolate);
- if (!world.IsIsolatedWorld())
- return GetContentSecurityPolicy();
-
- int32_t world_id = world.GetWorldId();
- auto it = isolated_world_csp_map_->find(world_id);
- if (it != isolated_world_csp_map_->end())
- return it->value;
-
- ContentSecurityPolicy* policy =
- IsolatedWorldCSP::Get().CreateIsolatedWorldCSP(*this, world_id);
- if (!policy)
- return GetContentSecurityPolicy();
-
- isolated_world_csp_map_->insert(world_id, policy);
- return policy;
-}
-
-bool Document::FeatureEnabled(OriginTrialFeature feature) const {
- return GetOriginTrialContext()->IsFeatureEnabled(feature);
-}
-
-void Document::CountFeaturePolicyUsage(mojom::WebFeature feature) {
- UseCounter::Count(*this, feature);
-}
-
-bool Document::FeaturePolicyFeatureObserved(
- mojom::blink::FeaturePolicyFeature feature) {
- wtf_size_t feature_index = static_cast<wtf_size_t>(feature);
- if (parsed_feature_policies_.size() == 0) {
- parsed_feature_policies_.resize(
- static_cast<wtf_size_t>(mojom::blink::FeaturePolicyFeature::kMaxValue) +
- 1);
- } else if (parsed_feature_policies_[feature_index]) {
- return true;
- }
- parsed_feature_policies_[feature_index] = true;
- return false;
-}
-
bool Document::DocumentPolicyFeatureObserved(
mojom::blink::DocumentPolicyFeature feature) {
wtf_size_t feature_index = static_cast<wtf_size_t>(feature);
@@ -1044,85 +1004,23 @@ bool Document::IsSandboxed(network::mojom::blink::WebSandboxFlags mask) const {
return GetSecurityContext().IsSandboxed(mask);
}
-PublicURLManager& Document::GetPublicURLManager() {
- DCHECK(GetExecutionContext());
- return GetExecutionContext()->GetPublicURLManager();
-}
-
-bool Document::IsContextPaused() const {
- return GetExecutionContext() ? GetExecutionContext()->IsContextPaused()
- : false;
-}
-
-bool Document::IsContextDestroyed() const {
- return GetExecutionContext() ? GetExecutionContext()->IsContextDestroyed()
- : true;
-}
-
-ContentSecurityPolicyDelegate& Document::GetContentSecurityPolicyDelegate() {
- return GetExecutionContext()->GetContentSecurityPolicyDelegate();
-}
-
SecureContextMode Document::GetSecureContextMode() const {
return GetSecurityContext().GetSecureContextMode();
}
-bool Document::IsSecureContext() const {
- return GetExecutionContext()->IsSecureContext();
-}
-
-bool Document::IsSecureContext(String& error_message) const {
- return GetExecutionContext()->IsSecureContext(error_message);
-}
-
-void Document::SetReferrerPolicy(network::mojom::ReferrerPolicy policy) {
- GetExecutionContext()->SetReferrerPolicy(policy);
-}
-
-v8::Isolate* Document::GetIsolate() const {
- return GetExecutionContext() ? GetExecutionContext()->GetIsolate() : nullptr;
-}
-
-Agent* Document::GetAgent() const {
- return GetSecurityContext().GetAgent();
-}
-
OriginTrialContext* Document::GetOriginTrialContext() const {
- return MasterDocument().GetSecurityContext().GetOriginTrialContext();
+ return TreeRootDocument().GetSecurityContext().GetOriginTrialContext();
}
void Document::SetSecureContextModeForTesting(SecureContextMode mode) {
GetSecurityContext().SetSecureContextModeForTesting(mode);
}
-bool Document::IsFeatureEnabled(mojom::blink::FeaturePolicyFeature feature,
- ReportOptions report_on_failure,
- const String& message) const {
- return GetExecutionContext() && GetExecutionContext()->IsFeatureEnabled(
- feature, report_on_failure, message);
-}
-
-bool Document::IsFeatureEnabled(mojom::blink::DocumentPolicyFeature feature,
- ReportOptions report_option,
- const String& message,
- const String& source_file) const {
- return GetExecutionContext() &&
- GetExecutionContext()->IsFeatureEnabled(feature, report_option,
- message, source_file);
-}
-
-bool Document::IsFeatureEnabled(mojom::blink::DocumentPolicyFeature feature,
- PolicyValue threshold_value,
- ReportOptions report_option,
- const String& message,
- const String& source_file) const {
- return GetExecutionContext() &&
- GetExecutionContext()->IsFeatureEnabled(
- feature, threshold_value, report_option, message, source_file);
-}
-
-String Document::addressSpaceForBindings() const {
- return GetExecutionContext()->addressSpaceForBindings();
+String Document::addressSpaceForBindings(ScriptState* script_state) const {
+ // "public" is the lowest-privilege value.
+ if (!script_state->ContextIsValid())
+ return "public";
+ return ExecutionContext::From(script_state)->addressSpaceForBindings();
}
void Document::ChildrenChanged(const ChildrenChange& change) {
@@ -1138,14 +1036,6 @@ void Document::ChildrenChanged(const ChildrenChange& change) {
BeginLifecycleUpdatesIfRenderingReady();
}
-void Document::setRootScroller(Element* new_scroller, ExceptionState&) {
- root_scroller_controller_->Set(new_scroller);
-}
-
-Element* Document::rootScroller() const {
- return root_scroller_controller_->Get();
-}
-
bool Document::IsInMainFrame() const {
return GetFrame() && GetFrame()->IsMainFrame();
}
@@ -1283,7 +1173,8 @@ Element* Document::CreateElementForBinding(
bool is_v1 =
string_or_options.IsElementCreationOptions() || !RegistrationContext();
// V0 is only allowed with the flag.
- DCHECK(is_v1 || RuntimeEnabledFeatures::CustomElementsV0Enabled(this));
+ DCHECK(is_v1 || RuntimeEnabledFeatures::CustomElementsV0Enabled(
+ GetExecutionContext()));
bool create_v1_builtin = string_or_options.IsElementCreationOptions();
bool should_create_builtin =
create_v1_builtin || string_or_options.IsString();
@@ -1361,7 +1252,8 @@ Element* Document::createElementNS(
bool is_v1 =
string_or_options.IsElementCreationOptions() || !RegistrationContext();
// V0 is only allowed with the flag.
- DCHECK(is_v1 || RuntimeEnabledFeatures::CustomElementsV0Enabled(this));
+ DCHECK(is_v1 || RuntimeEnabledFeatures::CustomElementsV0Enabled(
+ GetExecutionContext()));
bool create_v1_builtin = string_or_options.IsElementCreationOptions();
bool should_create_builtin =
create_v1_builtin || string_or_options.IsString();
@@ -1439,7 +1331,7 @@ ScriptValue Document::registerElement(ScriptState* script_state,
}
V0CustomElementRegistrationContext* Document::RegistrationContext() const {
- if (RuntimeEnabledFeatures::CustomElementsV0Enabled(this))
+ if (RuntimeEnabledFeatures::CustomElementsV0Enabled(GetExecutionContext()))
return registration_context_.Get();
return nullptr;
}
@@ -1459,7 +1351,7 @@ void Document::ClearImportsController() {
HTMLImportsController* Document::EnsureImportsController() {
if (!imports_controller_) {
- DCHECK(frame_);
+ DCHECK(dom_window_);
imports_controller_ = MakeGarbageCollected<HTMLImportsController>(*this);
}
@@ -1473,16 +1365,16 @@ HTMLImportLoader* Document::ImportLoader() const {
}
bool Document::IsHTMLImport() const {
- return imports_controller_ && imports_controller_->Master() != this;
+ return imports_controller_ && imports_controller_->TreeRoot() != this;
}
-Document& Document::MasterDocument() const {
+Document& Document::TreeRootDocument() const {
if (!imports_controller_)
return *const_cast<Document*>(this);
- Document* master = imports_controller_->Master();
- DCHECK(master);
- return *master;
+ Document* tree_root = imports_controller_->TreeRoot();
+ DCHECK(tree_root);
+ return *tree_root;
}
bool Document::HaveImportsLoaded() const {
@@ -1495,17 +1387,10 @@ LocalDOMWindow* Document::ExecutingWindow() const {
if (LocalDOMWindow* owning_window = domWindow())
return owning_window;
if (HTMLImportsController* import = ImportsController())
- return import->Master()->domWindow();
+ return import->TreeRoot()->domWindow();
return nullptr;
}
-LocalFrame* Document::ExecutingFrame() {
- LocalDOMWindow* window = ExecutingWindow();
- if (!window)
- return nullptr;
- return window->GetFrame();
-}
-
DocumentFragment* Document::createDocumentFragment() {
return DocumentFragment::Create(*this);
}
@@ -1910,7 +1795,7 @@ void Document::UpdateTitle(const String& title) {
else
title_ = CanonicalizedTitle<UChar>(this, raw_title_);
- if (!frame_ || old_title == title_)
+ if (!dom_window_ || old_title == title_)
return;
DispatchDidReceiveTitle();
@@ -1919,12 +1804,13 @@ void Document::UpdateTitle(const String& title) {
}
void Document::DispatchDidReceiveTitle() {
- if (GetFrame() && !GetFrame()->Tree().Parent()) {
+ if (IsInMainFrame()) {
String shortened_title = title_.Substring(0, mojom::blink::kMaxTitleChars);
GetFrame()->GetLocalFrameHostRemote().UpdateTitle(
- shortened_title, mojo_base::mojom::blink::TextDirection::LEFT_TO_RIGHT);
+ shortened_title, base::i18n::TextDirection::LEFT_TO_RIGHT);
+ GetFrame()->GetPage()->GetPageScheduler()->OnTitleOrFaviconUpdated();
}
- frame_->Client()->DispatchDidReceiveTitle(title_);
+ GetFrame()->Client()->DispatchDidReceiveTitle(title_);
}
void Document::setTitle(const String& title) {
@@ -2014,22 +1900,22 @@ bool Document::IsPageVisible() const {
// page. If there is no page associated with the document, we will assume
// that the page is hidden, as specified by the spec:
// https://w3c.github.io/page-visibility/#hidden-attribute
- if (!frame_ || !frame_->GetPage())
+ if (!GetFrame() || !GetFrame()->GetPage())
return false;
// While visibilitychange is being dispatched during unloading it is
// expected that the visibility is hidden regardless of the page's
// visibility.
if (load_event_progress_ >= kUnloadVisibilityChangeInProgress)
return false;
- return frame_->GetPage()->IsPageVisible();
+ return GetFrame()->GetPage()->IsPageVisible();
}
bool Document::IsPrefetchOnly() const {
- if (!frame_ || !frame_->GetPage())
+ if (!GetFrame() || !GetFrame()->GetPage())
return false;
PrerendererClient* prerenderer_client =
- PrerendererClient::From(frame_->GetPage());
+ PrerendererClient::From(GetFrame()->GetPage());
return prerenderer_client && prerenderer_client->IsPrefetchOnly();
}
@@ -2098,23 +1984,27 @@ void Document::SetStateForNewControls(const Vector<String>& state_vector) {
}
LocalFrameView* Document::View() const {
- return frame_ ? frame_->View() : nullptr;
+ return GetFrame() ? GetFrame()->View() : nullptr;
+}
+
+LocalFrame* Document::GetFrame() const {
+ return dom_window_ ? dom_window_->GetFrame() : nullptr;
}
Page* Document::GetPage() const {
- return frame_ ? frame_->GetPage() : nullptr;
+ return GetFrame() ? GetFrame()->GetPage() : nullptr;
}
-LocalFrame* Document::GetFrameOfMasterDocument() const {
- if (frame_)
- return frame_;
+LocalFrame* Document::GetFrameOfTreeRootDocument() const {
+ if (GetFrame())
+ return GetFrame();
if (imports_controller_)
- return imports_controller_->Master()->GetFrame();
+ return imports_controller_->TreeRoot()->GetFrame();
return nullptr;
}
Settings* Document::GetSettings() const {
- return frame_ ? frame_->GetSettings() : nullptr;
+ return GetFrame() ? GetFrame()->GetSettings() : nullptr;
}
Range* Document::createRange() {
@@ -2809,7 +2699,7 @@ void Document::ApplyScrollRestorationLogic() {
auto* document_loader = frame_loader.GetDocumentLoader();
if (!document_loader)
return;
- if (frame_->IsLoading() &&
+ if (GetFrame()->IsLoading() &&
!FrameLoader::NeedsHistoryItemRestore(document_loader->LoadType()))
return;
@@ -2841,7 +2731,7 @@ void Document::ApplyScrollRestorationLogic() {
bool can_restore_without_annoying_user =
!document_loader->GetInitialScrollState().was_scrolled_by_user &&
- (can_restore_without_clamping || !frame_->IsLoading() ||
+ (can_restore_without_clamping || !GetFrame()->IsLoading() ||
!should_restore_scroll);
if (!can_restore_without_annoying_user)
return;
@@ -3004,7 +2894,14 @@ void Document::ClearFocusedElementTimerFired(TimerBase*) {
scoped_refptr<const ComputedStyle> Document::StyleForPage(int page_index) {
UpdateDistributionForUnknownReasons();
- return EnsureStyleResolver().StyleForPage(page_index);
+
+ AtomicString page_name;
+ if (const LayoutView* layout_view = GetLayoutView()) {
+ if (const NamedPagesMapper* mapper = layout_view->GetNamedPagesMapper())
+ page_name = mapper->NamedPageAtIndex(page_index);
+ }
+
+ return EnsureStyleResolver().StyleForPage(page_index, page_name);
}
void Document::EnsurePaintLocationDataValidForNode(
@@ -3085,6 +2982,8 @@ void Document::GetPageDescription(int page_index,
}
if (!style->MarginLeft().IsAuto())
description->margin_left = IntValueForLength(style->MarginLeft(), width);
+
+ description->orientation = style->GetPageOrientation();
}
void Document::SetIsViewSource(bool is_view_source) {
@@ -3179,7 +3078,7 @@ void Document::Initialize() {
if (TextAutosizer* autosizer = GetTextAutosizer())
autosizer->UpdatePageInfo();
- frame_->DidAttachDocument();
+ GetFrame()->DidAttachDocument();
lifecycle_.AdvanceTo(DocumentLifecycle::kStyleClean);
if (View())
@@ -3190,27 +3089,23 @@ void Document::Initialize() {
// ExecutionContextLifecycleObserver::contextDestroyed wouldn't be fired.
network_state_observer_ =
MakeGarbageCollected<NetworkStateObserver>(GetExecutionContext());
-
- // Check for frame_ so we only attach documents with its own scheduler.
- if (frame_)
- GetAgent()->AttachDocument(this);
}
void Document::Shutdown() {
TRACE_EVENT0("blink", "Document::shutdown");
- CHECK(!frame_ || frame_->Tree().ChildCount() == 0);
+ CHECK(!GetFrame() || GetFrame()->Tree().ChildCount() == 0);
if (!IsActive())
return;
- // An active Document must have an associated frame.
- CHECK(frame_);
+ // An active Document must have an associated window.
+ CHECK(dom_window_);
// Frame navigation can cause a new Document to be attached. Don't allow that,
// since that will cause a situation where LocalFrame still has a Document
// attached after this finishes! Normally, it shouldn't actually be possible
// to trigger navigation here. However, plugins (see below) can cause lots of
// crazy things to happen, since plugin detach involves nested run loops.
- FrameNavigationDisabler navigation_disabler(*frame_);
+ FrameNavigationDisabler navigation_disabler(*GetFrame());
// Defer plugin dispose to avoid plugins trying to run script inside
// ScriptForbiddenScope, which will crash the renderer after
// https://crrev.com/200984
@@ -3224,10 +3119,10 @@ void Document::Shutdown() {
lifecycle_.AdvanceTo(DocumentLifecycle::kStopping);
// Do not add code before this without a documented reason. A postcondition of
- // Shutdown() is that |frame_| must not have an attached Document. Allowing
- // script execution when the Document is shutting down can make it easy to
- // accidentally violate this condition, and the ordering of the scopers above
- // is subtle due to legacy interactions with plugins.
+ // Shutdown() is that |dom_window_| must not have an attached Document.
+ // Allowing script execution when the Document is shutting down can make it
+ // easy to accidentally violate this condition, and the ordering of the
+ // scopers above is subtle due to legacy interactions with plugins.
if (num_canvases_ > 0)
UMA_HISTOGRAM_COUNTS_100("Blink.Canvas.NumCanvasesPerPage", num_canvases_);
@@ -3245,13 +3140,13 @@ void Document::Shutdown() {
// EmbeddedContentView. If we don't clear it here, it may be clobbered later
// in LocalFrame::CreateView(). See also https://crbug.com/673170 and the
// comment in LocalFrameView::Dispose().
- HTMLFrameOwnerElement* owner_element = frame_->DeprecatedLocalOwner();
+ HTMLFrameOwnerElement* owner_element = GetFrame()->DeprecatedLocalOwner();
// In the case of a provisional frame, skip clearing the EmbeddedContentView.
// A provisional frame is not fully attached to the DOM yet and clearing the
// EmbeddedContentView here could clear a not-yet-swapped-out frame
// (https://crbug.com/807772).
- if (owner_element && !frame_->IsProvisional())
+ if (owner_element && !GetFrame()->IsProvisional())
owner_element->SetEmbeddedContentView(nullptr);
markers_->PrepareForDestruction();
@@ -3270,8 +3165,8 @@ void Document::Shutdown() {
DetachCompositorTimeline(Timeline().CompositorTimeline());
- if (frame_->IsLocalRoot())
- GetPage()->GetChromeClient().AttachRootLayer(nullptr, frame_.Get());
+ if (GetFrame()->IsLocalRoot())
+ GetPage()->GetChromeClient().AttachRootLayer(nullptr, GetFrame());
if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
layout_view_->CleanUpCompositor();
@@ -3316,7 +3211,7 @@ void Document::Shutdown() {
GetStyleEngine().DidDetach();
- frame_->GetEventHandlerRegistry().DocumentDetached(*this);
+ GetFrame()->GetEventHandlerRegistry().DocumentDetached(*this);
// Signal destruction to mutation observers.
synchronous_mutation_observer_list_.ForEachObserver(
@@ -3328,7 +3223,7 @@ void Document::Shutdown() {
cookie_jar_ = nullptr; // Not accessible after navigated away.
fetcher_->ClearContext();
- // If this document is the master for an HTMLImportsController, sever that
+ // If this document is the tree_root for an HTMLImportsController, sever that
// relationship. This ensures that we don't leave import loads in flight,
// thinking they should have access to a valid frame when they don't.
if (imports_controller_) {
@@ -3343,15 +3238,6 @@ void Document::Shutdown() {
// TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes.
CHECK(!View()->IsAttached());
- // Check for frame_ so we only detach documents with its own scheduler.
- // TODO(bokan): Can this happen? |frame_| is dereferenced above and CHECKed
- // at top.
- if (frame_)
- GetAgent()->DetachDocument(this);
-
- // TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes.
- CHECK(!View()->IsAttached());
-
needs_to_record_ukm_outlive_time_ = IsInMainFrame();
if (needs_to_record_ukm_outlive_time_) {
// Ensure |ukm_recorder_| and |ukm_source_id_|.
@@ -3367,7 +3253,8 @@ void Document::Shutdown() {
// it's never possible to re-attach. Eventually Document::detachLayoutTree()
// should be renamed, or this setting of the frame to 0 could be made
// explicit in each of the callers of Document::detachLayoutTree().
- frame_ = nullptr;
+ dom_window_ = nullptr;
+ execution_context_ = nullptr;
document_outlive_time_reporter_ =
std::make_unique<DocumentOutliveTimeReporter>(this);
@@ -3448,7 +3335,6 @@ AXObjectCache* Document::ExistingAXObjectCache() const {
auto& cache_owner = AXObjectCacheOwner();
// If the LayoutView is gone then we are in the process of destruction.
- // This method will be called before frame_ = nullptr.
if (!cache_owner.GetLayoutView())
return nullptr;
@@ -3498,14 +3384,24 @@ void Document::SetPrinting(PrintingState state) {
printing_ = state;
bool is_printing = Printing();
- if ((was_printing != is_printing) && documentElement() && GetFrame() &&
- !GetFrame()->IsMainFrame() && GetFrame()->Owner() &&
- GetFrame()->Owner()->IsDisplayNone()) {
- // In non-printing mode we do not generate style or layout objects for
- // display:none iframes, yet we do when printing (see
- // LayoutView::CanHaveChildren). Trigger a style recalc on the root element
- // to create a layout tree for printing.
- DisplayNoneChangedForFrame();
+ if (was_printing != is_printing) {
+ // We force the color-scheme to light for printing.
+ ColorSchemeChanged();
+ // StyleResolver::InitialStyleForElement uses different zoom for printing.
+ GetStyleEngine().MarkViewportStyleDirty();
+ // Separate UA sheet for printing.
+ GetStyleEngine().MarkAllElementsForStyleRecalc(
+ StyleChangeReasonForTracing::Create(
+ style_change_reason::kStyleSheetChange));
+
+ if (documentElement() && GetFrame() && !GetFrame()->IsMainFrame() &&
+ GetFrame()->Owner() && GetFrame()->Owner()->IsDisplayNone()) {
+ // In non-printing mode we do not generate style or layout objects for
+ // display:none iframes, yet we do when printing (see
+ // LayoutView::CanHaveChildren). Trigger a style recalc on the root
+ // element to create a layout tree for printing.
+ DisplayNoneChangedForFrame();
+ }
}
}
@@ -3553,6 +3449,9 @@ void Document::open(Document* entered_document,
return;
}
+ if (entered_document && !entered_document->GetExecutionContext())
+ return;
+
// If |document| has an active parser whose script nesting level is greater
// than 0, then return |document|.
if (ScriptableDocumentParser* parser = GetScriptableDocumentParser()) {
@@ -3569,9 +3468,9 @@ void Document::open(Document* entered_document,
if (ignore_opens_and_writes_for_abort_)
return;
- // Change |document|'s URL to the URL of the responsible document specified
- // by the entry settings object.
- if (entered_document && this != entered_document) {
+ // If this document is fully active, change |document|'s URL to the URL of the
+ // responsible document specified by the entry settings object.
+ if (dom_window_ && entered_document && this != entered_document) {
auto* csp = MakeGarbageCollected<ContentSecurityPolicy>();
csp->CopyStateFrom(entered_document->GetContentSecurityPolicy());
// We inherit the sandbox flags of the entered document, so mask on
@@ -3588,7 +3487,8 @@ void Document::open(Document* entered_document,
GetSecurityContext().SetSecurityOrigin(
entered_document->GetMutableSecurityOrigin());
- SetReferrerPolicy(entered_document->GetReferrerPolicy());
+ GetExecutionContext()->SetReferrerPolicy(
+ entered_document->GetExecutionContext()->GetReferrerPolicy());
SetCookieURL(entered_document->CookieURL());
}
@@ -3616,12 +3516,9 @@ void Document::open() {
// This also prevents window.open(url) -- eg window.open("about:blank") --
// from blowing away results from a subsequent window.document.open /
// window.document.write call.
- if (frame_ && (frame_->Loader().HasProvisionalNavigation() ||
- IsHttpRefreshScheduledWithin(base::TimeDelta()))) {
- frame_->Loader().StopAllLoaders();
- // Navigations handled by the client should also be cancelled.
- if (frame_ && frame_->Client())
- frame_->Client()->AbortClientNavigation();
+ if (GetFrame() && (GetFrame()->Loader().HasProvisionalNavigation() ||
+ IsHttpRefreshScheduledWithin(base::TimeDelta()))) {
+ GetFrame()->Loader().StopAllLoaders(/*abort_client=*/true);
}
CancelPendingJavaScriptUrls();
@@ -3642,8 +3539,8 @@ void Document::open() {
RemoveAllEventListenersRecursively();
ResetTreeScope();
- if (frame_)
- frame_->Selection().Clear();
+ if (GetFrame())
+ GetFrame()->Selection().Clear();
// Create a new HTML parser and associate it with |document|.
//
@@ -3654,8 +3551,8 @@ void Document::open() {
if (ScriptableDocumentParser* parser = GetScriptableDocumentParser())
parser->SetWasCreatedByScript(true);
- if (frame_)
- frame_->Loader().DidExplicitOpen();
+ if (GetFrame())
+ GetFrame()->Loader().DidExplicitOpen();
}
void Document::DetachParser() {
@@ -3703,7 +3600,7 @@ DocumentParser* Document::ImplicitOpen(
if (!ThreadedParsingEnabledForTesting()) {
parser_sync_policy = kForceSynchronousParsing;
- } else if (parser_sync_policy == kAllowAsynchronousParsing &&
+ } else if (parser_sync_policy != kForceSynchronousParsing &&
IsPrefetchOnly()) {
// Prefetch must be synchronous.
parser_sync_policy = kForceSynchronousParsing;
@@ -3947,6 +3844,8 @@ void Document::ImplicitClose() {
return;
}
+ fetcher_->ScheduleWarnUnusedPreloads();
+
// We used to force a synchronous display and flush here. This really isn't
// necessary and can in fact be actively harmful if pages are loading at a
// rate of > 60fps
@@ -4008,7 +3907,7 @@ void Document::Abort() {
void Document::CheckCompleted() {
if (CheckCompletedInternal()) {
- frame_->Loader().DidFinishNavigation(
+ GetFrame()->Loader().DidFinishNavigation(
FrameLoader::NavigationFinishState::kSuccess);
}
}
@@ -4017,11 +3916,11 @@ bool Document::CheckCompletedInternal() {
if (!ShouldComplete())
return false;
- if (frame_ && !UnloadStarted()) {
- frame_->Client()->RunScriptsAtDocumentIdle();
+ if (GetFrame() && !UnloadStarted()) {
+ GetFrame()->Client()->RunScriptsAtDocumentIdle();
// Injected scripts may have disconnected this frame.
- if (!frame_)
+ if (!GetFrame())
return false;
// Check again, because runScriptsAtDocumentIdle() may have delayed the load
@@ -4036,7 +3935,7 @@ bool Document::CheckCompletedInternal() {
ImplicitClose();
// The readystatechanged or load event may have disconnected this frame.
- if (!frame_ || !frame_->IsAttached())
+ if (!GetFrame() || !GetFrame()->IsAttached())
return false;
http_refresh_scheduler_->MaybeStartTimer();
View()->HandleLoadCompleted();
@@ -4047,26 +3946,31 @@ bool Document::CheckCompletedInternal() {
// No need to repeat if we've already notified this load as finished.
if (!Loader()->SentDidFinishLoad()) {
- if (frame_->IsMainFrame())
- GetViewportData().GetViewportDescription().ReportMobilePageStats(frame_);
+ if (GetFrame()->IsMainFrame()) {
+ GetViewportData().GetViewportDescription().ReportMobilePageStats(
+ GetFrame());
+ }
Loader()->SetSentDidFinishLoad();
- frame_->Client()->DispatchDidFinishLoad();
- frame_->GetLocalFrameHostRemote().DidFinishLoad(Loader()->Url());
- if (!frame_)
+ GetFrame()->Client()->DispatchDidFinishLoad();
+ GetFrame()->GetLocalFrameHostRemote().DidFinishLoad(Loader()->Url());
+ if (!GetFrame())
return false;
// Send the source ID of the document to the browser.
- if (frame_->Client()->GetRemoteNavigationAssociatedInterfaces()) {
+ if (GetFrame()->Client()->GetRemoteNavigationAssociatedInterfaces()) {
mojo::AssociatedRemote<mojom::blink::UkmSourceIdFrameHost> ukm_binding;
- frame_->Client()->GetRemoteNavigationAssociatedInterfaces()->GetInterface(
- &ukm_binding);
+ GetFrame()
+ ->Client()
+ ->GetRemoteNavigationAssociatedInterfaces()
+ ->GetInterface(&ukm_binding);
DCHECK(ukm_binding.is_bound());
ukm_binding->SetDocumentSourceId(ukm_source_id_);
}
- frame_->GetFrameScheduler()->RegisterStickyFeature(
+ GetFrame()->GetFrameScheduler()->RegisterStickyFeature(
SchedulingPolicy::Feature::kDocumentLoaded,
{SchedulingPolicy::RecordMetricsForBackForwardCache()});
+ GetFrame()->GetFrameScheduler()->OnLoad();
AnchorElementMetrics::NotifyOnLoad(*this);
@@ -4108,11 +4012,21 @@ bool Document::DispatchBeforeUnloadEvent(ChromeClient* chrome_client,
MainThreadDisallowSynchronousXHRScope disallow_synchronous_xhr;
auto& before_unload_event = *MakeGarbageCollected<BeforeUnloadEvent>();
before_unload_event.initEvent(event_type_names::kBeforeunload, false, true);
- load_event_progress_ = kBeforeUnloadEventInProgress;
const base::TimeTicks beforeunload_event_start = base::TimeTicks::Now();
- dom_window_->DispatchEvent(before_unload_event, this);
+
+ {
+ // We want to avoid progressing to kBeforeUnloadEventHandled if the page
+ // cancels the unload. Because a subframe may cancel unload on our behalf,
+ // only the caller, which makes this call over the frame subtree, can know
+ // whether or not we'll unload so the caller is responsible for advancing
+ // to kBeforeUnloadEventHandled. Here, we'll reset back to our prior value
+ // once the handler has run.
+ base::AutoReset<LoadEventProgress> set_in_progress(
+ &load_event_progress_, kBeforeUnloadEventInProgress);
+ dom_window_->DispatchEvent(before_unload_event, this);
+ }
+
const base::TimeTicks beforeunload_event_end = base::TimeTicks::Now();
- load_event_progress_ = kBeforeUnloadEventCompleted;
DEFINE_STATIC_LOCAL(
CustomCountHistogram, beforeunload_histogram,
("DocumentEventTiming.BeforeUnloadDuration", 0, 10000000, 50));
@@ -4143,7 +4057,7 @@ bool Document::DispatchBeforeUnloadEvent(ChromeClient* chrome_client,
"Blocked attempt to show a 'beforeunload' confirmation panel for a "
"frame that never had a user gesture since its load. "
"https://www.chromestatus.com/feature/5082396709879808";
- Intervention::GenerateReport(frame_, "BeforeUnloadNoGesture", message);
+ Intervention::GenerateReport(GetFrame(), "BeforeUnloadNoGesture", message);
return true;
}
@@ -4153,7 +4067,7 @@ bool Document::DispatchBeforeUnloadEvent(ChromeClient* chrome_client,
String message =
"Blocked attempt to show multiple 'beforeunload' confirmation panels "
"for a single navigation.";
- Intervention::GenerateReport(frame_, "BeforeUnloadMultiple", message);
+ Intervention::GenerateReport(GetFrame(), "BeforeUnloadMultiple", message);
return true;
}
@@ -4171,7 +4085,7 @@ bool Document::DispatchBeforeUnloadEvent(ChromeClient* chrome_client,
const base::TimeTicks beforeunload_confirmpanel_start =
base::TimeTicks::Now();
did_allow_navigation =
- chrome_client->OpenBeforeUnloadConfirmPanel(text, frame_, is_reload);
+ chrome_client->OpenBeforeUnloadConfirmPanel(text, GetFrame(), is_reload);
const base::TimeTicks beforeunload_confirmpanel_end = base::TimeTicks::Now();
if (did_allow_navigation) {
// Only record when a navigation occurs, since we want to understand
@@ -4214,7 +4128,7 @@ void Document::DispatchUnloadEvents(
pagehide_histogram.CountMicroseconds(pagehide_event_end -
pagehide_event_start);
}
- if (!frame_)
+ if (!dom_window_)
return;
// This must be queried before |load_event_progress_| is changed to
@@ -4239,15 +4153,15 @@ void Document::DispatchUnloadEvents(
DispatchEvent(
*Event::CreateBubble(event_type_names::kWebkitvisibilitychange));
}
- if (!frame_)
+ if (!dom_window_)
return;
- frame_->Loader().SaveScrollAnchor();
+ GetFrame()->Loader().SaveScrollAnchor();
load_event_progress_ = kUnloadEventInProgress;
Event& unload_event = *Event::Create(event_type_names::kUnload);
const base::TimeTicks unload_event_start = base::TimeTicks::Now();
- frame_->DomWindow()->DispatchEvent(unload_event, this);
+ dom_window_->DispatchEvent(unload_event, this);
const base::TimeTicks unload_event_end = base::TimeTicks::Now();
if (unload_timing) {
@@ -4298,7 +4212,7 @@ Document::PageDismissalType Document::PageDismissalEventBeingDispatched()
case kLoadEventNotRun:
case kLoadEventInProgress:
case kLoadEventCompleted:
- case kBeforeUnloadEventCompleted:
+ case kBeforeUnloadEventHandled:
case kUnloadEventHandled:
return kNoDismissal;
}
@@ -4367,6 +4281,9 @@ void Document::write(const String& text,
return;
}
+ if (entered_document && !entered_document->GetExecutionContext())
+ return;
+
if (ignore_opens_and_writes_for_abort_)
return;
@@ -4455,14 +4372,10 @@ void Document::writeln(v8::Isolate* isolate,
writeln(string, EnteredDOMWindow(isolate)->document(), exception_state);
}
-bool Document::IsTrustedTypesEnabledForDoc() const {
- return GetExecutionContext()->RequireTrustedTypes();
-}
-
void Document::write(v8::Isolate* isolate,
TrustedHTML* text,
ExceptionState& exception_state) {
- DCHECK(RuntimeEnabledFeatures::TrustedDOMTypesEnabled(this));
+ DCHECK(RuntimeEnabledFeatures::TrustedDOMTypesEnabled(GetExecutionContext()));
write(text->toString(), EnteredDOMWindow(isolate)->document(),
exception_state);
}
@@ -4470,7 +4383,7 @@ void Document::write(v8::Isolate* isolate,
void Document::writeln(v8::Isolate* isolate,
TrustedHTML* text,
ExceptionState& exception_state) {
- DCHECK(RuntimeEnabledFeatures::TrustedDOMTypesEnabled(this));
+ DCHECK(RuntimeEnabledFeatures::TrustedDOMTypesEnabled(GetExecutionContext()));
writeln(text->toString(), EnteredDOMWindow(isolate)->document(),
exception_state);
}
@@ -4505,21 +4418,18 @@ void Document::SetURL(const KURL& url) {
}
}
- // If text fragment identifiers are enabled, we strip the fragment directive
- // from the URL fragment.
- // E.g. "#id:~:text=a" --> "#id"
- if (RuntimeEnabledFeatures::TextFragmentIdentifiersEnabled(this)) {
- String fragment = new_url.FragmentIdentifier();
- wtf_size_t start_pos = fragment.Find(kFragmentDirectivePrefix);
- if (start_pos != kNotFound) {
- fragment_directive_ =
- fragment.Substring(start_pos + kFragmentDirectivePrefixStringLength);
+ // Strip the fragment directive from the URL fragment. E.g. "#id:~:text=a"
+ // --> "#id". See https://github.com/WICG/scroll-to-text-fragment.
+ String fragment = new_url.FragmentIdentifier();
+ wtf_size_t start_pos = fragment.Find(kFragmentDirectivePrefix);
+ if (start_pos != kNotFound) {
+ fragment_directive_ =
+ fragment.Substring(start_pos + kFragmentDirectivePrefixStringLength);
- if (start_pos == 0)
- new_url.RemoveFragmentIdentifier();
- else
- new_url.SetFragmentIdentifier(fragment.Substring(0, start_pos));
- }
+ if (start_pos == 0)
+ new_url.RemoveFragmentIdentifier();
+ else
+ new_url.SetFragmentIdentifier(fragment.Substring(0, start_pos));
}
url_ = new_url;
@@ -4532,8 +4442,8 @@ void Document::SetURL(const KURL& url) {
if (ukm_recorder_ && IsInMainFrame())
ukm_recorder_->UpdateSourceURL(ukm_source_id_, url_);
- if (frame_) {
- if (FrameScheduler* frame_scheduler = frame_->GetFrameScheduler())
+ if (GetFrame()) {
+ if (FrameScheduler* frame_scheduler = GetFrame()->GetFrameScheduler())
frame_scheduler->TraceUrlChange(url_.GetString());
}
}
@@ -4587,8 +4497,8 @@ KURL Document::FallbackBaseURL() const {
if (Document* parent = ParentDocument())
return parent->BaseURL();
} else if (urlForBinding().IsAboutBlankURL()) {
- if (context_document_)
- return context_document_->BaseURL();
+ if (!dom_window_ && execution_context_)
+ return execution_context_->BaseURL();
// TODO(tkent): Referring to ParentDocument() is not correct. See
// crbug.com/751329.
if (Document* parent = ParentDocument())
@@ -4689,7 +4599,7 @@ void Document::DidAddPendingParserBlockingStylesheet() {
}
void Document::DidRemoveAllPendingStylesheets() {
- // Only imports on master documents can trigger rendering.
+ // Only imports on tree_root documents can trigger rendering.
if (HTMLImportLoader* import = ImportLoader())
import->DidRemoveAllPendingStylesheets();
if (!HaveImportsLoaded())
@@ -4735,7 +4645,7 @@ CSSStyleSheet& Document::ElementSheet() {
void Document::MaybeHandleHttpRefresh(const String& content,
HttpRefreshType http_refresh_type) {
- if (is_view_source_ || !frame_)
+ if (is_view_source_ || !dom_window_)
return;
base::TimeDelta delay;
@@ -4779,35 +4689,6 @@ bool Document::IsHttpRefreshScheduledWithin(base::TimeDelta interval) {
return http_refresh_scheduler_->IsScheduledWithin(interval);
}
-// https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
-String Document::OutgoingReferrer() const {
- // Step 3.1: "If environment's global object is a Window object, then"
-
- // Step 3.1.1: "Let document be the associated Document of environment's
- // global object."
- const Document* referrer_document = this;
-
- // Step 3.1.2: "If document's origin is an opaque origin, return no referrer."
- if (GetSecurityOrigin()->IsOpaque())
- return String();
-
- // Step 3.1.3: "While document is an iframe srcdoc document, let document be
- // document's browsing context's browsing context container's node document."
- if (LocalFrame* frame = frame_) {
- while (frame->GetDocument()->IsSrcdocDocument()) {
- // Srcdoc documents must be local within the containing frame.
- frame = To<LocalFrame>(frame->Tree().Parent());
- // Srcdoc documents cannot be top-level documents, by definition,
- // because they need to be contained in iframes with the srcdoc.
- DCHECK(frame);
- }
- referrer_document = frame->GetDocument();
- }
-
- // Step: 3.1.4: "Let referrerSource be document's URL."
- return referrer_document->url_.StrippedForUseAsReferrer();
-}
-
network::mojom::ReferrerPolicy Document::GetReferrerPolicy() const {
return GetExecutionContext() ? GetExecutionContext()->GetReferrerPolicy()
: network::mojom::ReferrerPolicy::kDefault;
@@ -5027,6 +4908,9 @@ bool Document::CanAcceptChild(const Node& new_child,
Node* Document::Clone(Document& factory, CloneChildrenFlag flag) const {
DCHECK_EQ(this, &factory)
<< "Document::Clone() doesn't support importNode mode.";
+
+ if (!execution_context_)
+ return nullptr;
Document* clone = CloneDocumentWithoutChildren();
clone->CloneDataFromDocument(*this);
if (flag != CloneChildrenFlag::kSkip)
@@ -5036,7 +4920,7 @@ Node* Document::Clone(Document& factory, CloneChildrenFlag flag) const {
Document* Document::CloneDocumentWithoutChildren() const {
DocumentInit init = DocumentInit::Create()
- .WithContextDocument(ContextDocument())
+ .WithExecutionContext(execution_context_.Get())
.WithOwnerDocument(const_cast<Document*>(this))
.WithURL(Url());
if (IsA<XMLDocument>(this)) {
@@ -5356,8 +5240,12 @@ void Document::NotifyFocusedElementChanged(Element* old_focused_element,
bool is_editable = false;
gfx::Rect element_bounds;
if (new_focused_element) {
- IntRect rect = new_focused_element->BoundsInViewport();
- View()->FrameToScreen(rect);
+ // Convert to window coordinate system (this will be in DIPs).
+ WebRect rect = WebRect(new_focused_element->BoundsInViewport());
+ if (GetFrame()->GetWidgetForLocalRoot()) {
+ GetFrame()->GetWidgetForLocalRoot()->Client()->ConvertViewportToWindow(
+ &rect);
+ }
is_editable = IsEditableElement(*new_focused_element);
element_bounds = gfx::Rect(rect);
}
@@ -5370,6 +5258,10 @@ void Document::NotifyFocusedElementChanged(Element* old_focused_element,
if (old_document && old_document != this && old_document->GetFrame())
old_document->GetFrame()->Client()->FocusedElementChanged(nullptr);
+ // Ensures that further text input state can be sent even when previously
+ // focused input and the newly focused input share the exact same state.
+ if (GetFrame()->GetWidgetForLocalRoot())
+ GetFrame()->GetWidgetForLocalRoot()->ClearTextInputState();
GetFrame()->Client()->FocusedElementChanged(new_focused_element);
GetPage()->GetChromeClient().SetKeyboardFocusURL(new_focused_element);
@@ -5383,7 +5275,7 @@ void Document::NotifyFocusedElementChanged(Element* old_focused_element,
}
void Document::SetSequentialFocusNavigationStartingPoint(Node* node) {
- if (!frame_)
+ if (!dom_window_)
return;
if (!node) {
sequential_focus_navigation_starting_point_ = nullptr;
@@ -5952,18 +5844,18 @@ void Document::setDomain(const String& raw_domain,
ExceptionState& exception_state) {
UseCounter::Count(*this, WebFeature::kDocumentSetDomain);
- const String feature_policy_error =
- "Setting `document.domain` is disabled by Feature Policy.";
- if (!IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kDocumentDomain,
- ReportOptions::kReportOnFailure,
- feature_policy_error)) {
- exception_state.ThrowSecurityError(feature_policy_error);
+ if (!dom_window_) {
+ exception_state.ThrowSecurityError(
+ "A browsing context is required to set a domain.");
return;
}
- if (!frame_) {
- exception_state.ThrowSecurityError(
- "A browsing context is required to set a domain.");
+ const String feature_policy_error =
+ "Setting `document.domain` is disabled by Feature Policy.";
+ if (!GetExecutionContext()->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kDocumentDomain,
+ ReportOptions::kReportOnFailure, feature_policy_error)) {
+ exception_state.ThrowSecurityError(feature_policy_error);
return;
}
@@ -6015,29 +5907,30 @@ void Document::setDomain(const String& raw_domain,
return;
}
- if (frame_) {
+ if (GetFrame()) {
UseCounter::Count(*this,
GetSecurityOrigin()->Port() == 0
? WebFeature::kDocumentDomainSetWithDefaultPort
: WebFeature::kDocumentDomainSetWithNonDefaultPort);
- bool was_cross_origin_to_main_frame = frame_->IsCrossOriginToMainFrame();
+ bool was_cross_origin_to_main_frame =
+ GetFrame()->IsCrossOriginToMainFrame();
bool was_cross_origin_to_parent_frame =
- frame_->IsCrossOriginToParentFrame();
+ GetFrame()->IsCrossOriginToParentFrame();
GetMutableSecurityOrigin()->SetDomainFromDOM(new_domain);
- bool is_cross_origin_to_main_frame = frame_->IsCrossOriginToMainFrame();
- if (FrameScheduler* frame_scheduler = frame_->GetFrameScheduler())
+ bool is_cross_origin_to_main_frame = GetFrame()->IsCrossOriginToMainFrame();
+ if (FrameScheduler* frame_scheduler = GetFrame()->GetFrameScheduler())
frame_scheduler->SetCrossOriginToMainFrame(is_cross_origin_to_main_frame);
if (View() &&
(was_cross_origin_to_main_frame != is_cross_origin_to_main_frame)) {
View()->CrossOriginToMainFrameChanged();
}
- if (frame_->IsMainFrame()) {
+ if (GetFrame()->IsMainFrame()) {
// Notify descendants if their cross-origin-to-main-frame status changed.
// TODO(pdr): This will notify even if |Frame::IsCrossOriginToMainFrame|
// is the same. Track whether each child was cross-origin to main before
// and after changing the domain, and only notify the changed ones.
- for (Frame* child = frame_->Tree().FirstChild(); child;
- child = child->Tree().TraverseNext(frame_)) {
+ for (Frame* child = GetFrame()->Tree().FirstChild(); child;
+ child = child->Tree().TraverseNext(GetFrame())) {
auto* child_local_frame = DynamicTo<LocalFrame>(child);
if (child_local_frame && child_local_frame->View())
child_local_frame->View()->CrossOriginToMainFrameChanged();
@@ -6045,21 +5938,21 @@ void Document::setDomain(const String& raw_domain,
}
if (View() && was_cross_origin_to_parent_frame !=
- frame_->IsCrossOriginToParentFrame()) {
+ GetFrame()->IsCrossOriginToParentFrame()) {
View()->CrossOriginToParentFrameChanged();
}
// Notify all child frames if their cross-origin-to-parent status changed.
// TODO(pdr): This will notify even if |Frame::IsCrossOriginToParentFrame|
// is the same. Track whether each child was cross-origin-to-parent before
// and after changing the domain, and only notify the changed ones.
- for (Frame* child = frame_->Tree().FirstChild(); child;
+ for (Frame* child = GetFrame()->Tree().FirstChild(); child;
child = child->Tree().NextSibling()) {
auto* child_local_frame = DynamicTo<LocalFrame>(child);
if (child_local_frame && child_local_frame->View())
child_local_frame->View()->CrossOriginToParentFrameChanged();
}
- frame_->GetScriptController().UpdateSecurityOrigin(GetSecurityOrigin());
+ GetFrame()->GetScriptController().UpdateSecurityOrigin(GetSecurityOrigin());
}
}
@@ -6068,7 +5961,7 @@ String Document::lastModified() const {
base::Time::Exploded exploded;
bool found_date = false;
AtomicString http_last_modified = override_last_modified_;
- if (http_last_modified.IsEmpty() && frame_) {
+ if (http_last_modified.IsEmpty()) {
if (DocumentLoader* document_loader = Loader()) {
http_last_modified = document_loader->GetResponse().HttpHeaderField(
http_names::kLastModified);
@@ -6102,9 +5995,9 @@ scoped_refptr<const SecurityOrigin> Document::TopFrameOrigin() const {
net::SiteForCookies Document::SiteForCookies() const {
// TODO(mkwst): This doesn't properly handle HTML Import documents.
- // If this is an imported document, grab its master document's first-party:
+ // If this is an imported document, grab its tree_root document's first-party:
if (IsHTMLImport())
- return ImportsController()->Master()->SiteForCookies();
+ return ImportsController()->TreeRoot()->SiteForCookies();
if (!GetFrame())
return net::SiteForCookies();
@@ -6154,53 +6047,128 @@ void Document::PermissionServiceConnectionError() {
permission_service_.reset();
}
-ScriptPromise Document::hasStorageAccess(ScriptState* script_state) const {
+ScriptPromise Document::hasStorageAccess(ScriptState* script_state) {
const bool has_access =
- TopFrameOrigin() &&
- GetSecurityOrigin()->IsSameOriginWith(TopFrameOrigin().get());
+ TopFrameOrigin() && !GetSecurityOrigin()->IsOpaque() && CookiesEnabled();
ScriptPromiseResolver* resolver =
MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- // TODO (http://crbug.com/989663)
- // Hookup actual logic to Resolve/Reject this request properly.
ScriptPromise promise = resolver->Promise();
resolver->Resolve(has_access);
return promise;
}
ScriptPromise Document::requestStorageAccess(ScriptState* script_state) {
- DCHECK(frame_);
+ DCHECK(GetFrame());
ScriptPromiseResolver* resolver =
MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- // TODO (http://crbug.com/989663)
- // Hookup actual logic to Resolve/Reject this request properly.
-
// Access the promise first to ensure it is created so that the proper state
// can be changed when it is resolved or rejected.
ScriptPromise promise = resolver->Promise();
- const bool has_user_gesture = LocalFrame::HasTransientUserActivation(frame_);
- if (has_user_gesture) {
- auto descriptor = mojom::blink::PermissionDescriptor::New();
- descriptor->name = mojom::blink::PermissionName::STORAGE_ACCESS;
- GetPermissionService(ExecutionContext::From(script_state))
- ->RequestPermission(
- std::move(descriptor), has_user_gesture,
- WTF::Bind(
- [](ScriptPromiseResolver* resolver,
- mojom::blink::PermissionStatus status) {
- DCHECK(resolver);
- (status == mojom::blink::PermissionStatus::GRANTED)
- ? resolver->Resolve()
- : resolver->Reject();
- },
- WrapPersistent(resolver)));
- } else {
- // Without a user gesture any request for storage access is immediately
- // denied.
+ const bool has_user_gesture =
+ LocalFrame::HasTransientUserActivation(GetFrame());
+ if (!has_user_gesture) {
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kSecurity,
+ mojom::blink::ConsoleMessageLevel::kError,
+ "requestStorageAccess: Must be handling a user gesture to use."));
+ FireRequestStorageAccessHistogram(
+ RequestStorageResult::REJECTED_NO_USER_GESTURE);
+
+ resolver->Reject();
+ return promise;
+ }
+
+ if (!TopFrameOrigin()) {
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kSecurity,
+ mojom::blink::ConsoleMessageLevel::kError,
+ "requestStorageAccess: Cannot execute in documents lacking top-frame "
+ "origins."));
+ FireRequestStorageAccessHistogram(RequestStorageResult::REJECTED_NO_ORIGIN);
+
+ resolver->Reject();
+ return promise;
+ }
+
+ if (GetSecurityOrigin()->IsOpaque()) {
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kSecurity,
+ mojom::blink::ConsoleMessageLevel::kError,
+ "requestStorageAccess: Cannot be used by opaque origins."));
+ FireRequestStorageAccessHistogram(
+ RequestStorageResult::REJECTED_OPAQUE_ORIGIN);
+
resolver->Reject();
+ return promise;
}
+
+ if (IsSandboxed(network::mojom::blink::WebSandboxFlags::
+ kStorageAccessByUserActivation)) {
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kSecurity,
+ mojom::blink::ConsoleMessageLevel::kError,
+ "requestStorageAccess: Refused to execute request. The document is "
+ "sandboxed, and the 'allow-storage-access-by-user-activation' keyword "
+ "is not set."));
+ FireRequestStorageAccessHistogram(RequestStorageResult::REJECTED_SANDBOXED);
+
+ resolver->Reject();
+ return promise;
+ }
+
+ if (CookiesEnabled()) {
+ FireRequestStorageAccessHistogram(
+ RequestStorageResult::APPROVED_EXISTING_ACCESS);
+
+ // If there is current access to storage we no longer need to make a request
+ // and can resolve the promise.
+ resolver->Resolve();
+ return promise;
+ }
+
+ if (expressly_denied_storage_access_) {
+ FireRequestStorageAccessHistogram(
+ RequestStorageResult::REJECTED_EXISTING_DENIAL);
+
+ // If a previous rejection has been received the promise can be immediately
+ // rejected without further action.
+ resolver->Reject();
+ return promise;
+ }
+
+ auto descriptor = mojom::blink::PermissionDescriptor::New();
+ descriptor->name = mojom::blink::PermissionName::STORAGE_ACCESS;
+ GetPermissionService(ExecutionContext::From(script_state))
+ ->RequestPermission(
+ std::move(descriptor), has_user_gesture,
+ WTF::Bind(
+ [](ScriptPromiseResolver* resolver, Document* document,
+ mojom::blink::PermissionStatus status) {
+ DCHECK(resolver);
+ DCHECK(document);
+
+ switch (status) {
+ case mojom::blink::PermissionStatus::GRANTED:
+ document->expressly_denied_storage_access_ = false;
+ FireRequestStorageAccessHistogram(
+ RequestStorageResult::APPROVED_NEW_GRANT);
+ resolver->Resolve();
+ break;
+ case mojom::blink::PermissionStatus::DENIED:
+ document->expressly_denied_storage_access_ = true;
+ FALLTHROUGH;
+ case mojom::blink::PermissionStatus::ASK:
+ default:
+ FireRequestStorageAccessHistogram(
+ RequestStorageResult::REJECTED_GRANT_DENIED);
+ resolver->Reject();
+ }
+ },
+ WrapPersistent(resolver), WrapPersistent(this)));
+
return promise;
}
@@ -6253,7 +6221,7 @@ ScriptPromise Document::hasTrustToken(ScriptState* script_state,
}
if (!has_trust_tokens_answerer_.is_bound()) {
- GetBrowserInterfaceBroker().GetInterface(
+ GetFrame()->GetBrowserInterfaceBroker().GetInterface(
has_trust_tokens_answerer_.BindNewPipeAndPassReceiver(
GetExecutionContext()->GetTaskRunner(TaskType::kInternalDefault)));
has_trust_tokens_answerer_.set_disconnect_handler(
@@ -6585,7 +6553,7 @@ KURL Document::OpenSearchDescriptionURL() {
WebFeature osd_disposition;
scoped_refptr<const SecurityOrigin> target =
SecurityOrigin::Create(link_element->Href());
- if (IsSecureContext()) {
+ if (execution_context_->IsSecureContext()) {
osd_disposition = target->IsPotentiallyTrustworthy()
? WebFeature::kOpenSearchSecureOriginSecureTarget
: WebFeature::kOpenSearchSecureOriginInsecureTarget;
@@ -6646,9 +6614,9 @@ void Document::setDesignMode(const String& value) {
}
Document* Document::ParentDocument() const {
- if (!frame_)
+ if (!GetFrame())
return nullptr;
- auto* parent_local_frame = DynamicTo<LocalFrame>(frame_->Tree().Parent());
+ auto* parent_local_frame = DynamicTo<LocalFrame>(GetFrame()->Tree().Parent());
if (!parent_local_frame)
return nullptr;
return parent_local_frame->GetDocument();
@@ -6666,9 +6634,8 @@ Document& Document::TopDocument() const {
return *doc;
}
-Document* Document::ContextDocument() const {
- return context_document_ ? context_document_.Get()
- : const_cast<Document*>(this);
+ExecutionContext* Document::GetExecutionContext() const {
+ return execution_context_.Get();
}
Attr* Document::createAttribute(const AtomicString& name,
@@ -6766,10 +6733,7 @@ HTMLCollection* Document::DocumentAllNamedItems(const AtomicString& name) {
}
DOMWindow* Document::defaultView() const {
- // The HTML spec requires to return null if the document is detached from the
- // DOM. However, |dom_window_| is not cleared on the detachment. So, we need
- // to check |frame_| to tell whether the document is attached or not.
- return frame_ ? dom_window_ : nullptr;
+ return dom_window_;
}
namespace {
@@ -6794,12 +6758,60 @@ void SetOriginTrialFreezePolicy(
} // namespace
+void Document::RecordAsyncScriptCount() {
+ UMA_HISTOGRAM_COUNTS_100("Blink.Script.AsyncScriptCount",
+ async_script_count_);
+
+ // Only record async script count for mainframe documents, as per UKM policy.
+ if (!IsInMainFrame())
+ return;
+
+ auto* recorder = UkmRecorder();
+ DCHECK(recorder);
+ DCHECK(UkmSourceID() != ukm::kInvalidSourceId);
+ ukm::builders::Blink_Script_AsyncScripts(UkmSourceID())
+ .SetAsyncScriptCount(
+ ukm::GetExponentialBucketMin(async_script_count_, 1.3))
+ .Record(recorder);
+}
+
+void Document::MaybeExecuteDelayedAsyncScripts() {
+ // Notify the ScriptRunner if the first paint has been recorded and we're
+ // delaying async scripts until first paint.
+ if (first_paint_recorded_ &&
+ ((base::FeatureList::IsEnabled(features::kDelayAsyncScriptExecution) &&
+ features::kDelayAsyncScriptExecutionDelayParam.Get() ==
+ features::DelayAsyncScriptDelayType::
+ kFirstPaintOrFinishedParsing) ||
+ RuntimeEnabledFeatures::
+ DelayAsyncScriptExecutionUntilFirstPaintOrFinishedParsingEnabled())) {
+ script_runner_->NotifyDelayedAsyncScriptsMilestoneReached();
+ }
+
+ if (!Parsing() &&
+ (base::FeatureList::IsEnabled(features::kDelayAsyncScriptExecution) ||
+ RuntimeEnabledFeatures::
+ DelayAsyncScriptExecutionUntilFinishedParsingEnabled() ||
+ RuntimeEnabledFeatures::
+ DelayAsyncScriptExecutionUntilFirstPaintOrFinishedParsingEnabled())) {
+ script_runner_->NotifyDelayedAsyncScriptsMilestoneReached();
+ }
+}
+
+void Document::MarkFirstPaint() {
+ first_paint_recorded_ = true;
+ MaybeExecuteDelayedAsyncScripts();
+}
+
void Document::FinishedParsing() {
DCHECK(!GetScriptableDocumentParser() || !parser_->IsParsing());
DCHECK(!GetScriptableDocumentParser() || ready_state_ != kLoading);
+ RecordAsyncScriptCount();
SetParsingState(kInDOMContentLoaded);
DocumentParserTiming::From(*this).MarkParserStop();
+ MaybeExecuteDelayedAsyncScripts();
+
// FIXME: DOMContentLoaded is dispatched synchronously, but this should be
// dispatched in a queued task, see https://crbug.com/425790
if (document_timing_.DomContentLoadedEventStart().is_null())
@@ -7026,11 +7038,11 @@ void Document::PoliciesInitialized(const DocumentInit& document_initializer) {
UseCounter::Count(*this, WebFeature::kFeaturePolicyHeader);
// At this point, the document will not have been installed in the frame's
- // LocalDOMWindow, so we cannot call frame_->IsFeatureEnabled. This calls
+ // LocalDOMWindow, so we cannot call GetFrame()->IsFeatureEnabled. This calls
// SecurityContext::IsFeatureEnabled instead, which cannot report, but we
// don't need reporting here in any case.
is_vertical_scroll_enforced_ =
- frame_ && !frame_->IsMainFrame() &&
+ GetFrame() && !GetFrame()->IsMainFrame() &&
RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() &&
!GetSecurityContext().GetFeaturePolicy()->IsFeatureEnabled(
mojom::blink::FeaturePolicyFeature::kVerticalScroll);
@@ -7039,22 +7051,27 @@ void Document::PoliciesInitialized(const DocumentInit& document_initializer) {
const ParsedFeaturePolicy Document::GetOwnerContainerPolicy() const {
// If this frame is not the main frame, then get the container policy from its
// owner.
- if (frame_ && frame_->Owner())
- return frame_->Owner()->GetFramePolicy().container_policy;
+ if (GetFrame() && GetFrame()->Owner())
+ return GetFrame()->Owner()->GetFramePolicy().container_policy;
return ParsedFeaturePolicy();
}
const FeaturePolicy* Document::GetParentFeaturePolicy() const {
// If this frame is not the main frame, then get the feature policy from its
// parent.
- if (frame_ && !frame_->IsMainFrame())
- return frame_->Tree().Parent()->GetSecurityContext()->GetFeaturePolicy();
+ if (GetFrame() && !GetFrame()->IsMainFrame()) {
+ return GetFrame()
+ ->Tree()
+ .Parent()
+ ->GetSecurityContext()
+ ->GetFeaturePolicy();
+ }
return nullptr;
}
void Document::ApplyPendingFramePolicyHeaders() {
- if (frame_) {
- frame_->Client()->DidSetFramePolicyHeaders(
+ if (GetFrame()) {
+ GetFrame()->Client()->DidSetFramePolicyHeaders(
GetSandboxFlags(), pending_fp_headers_, pending_dp_headers_);
}
pending_fp_headers_.clear();
@@ -7067,9 +7084,9 @@ bool Document::AllowedToUseDynamicMarkUpInsertion(
if (!RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled()) {
return true;
}
- if (!frame_ ||
- IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kDocumentWrite,
- ReportOptions::kReportOnFailure)) {
+ if (!GetFrame() || GetExecutionContext()->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kDocumentWrite,
+ ReportOptions::kReportOnFailure)) {
return true;
}
@@ -7118,14 +7135,14 @@ FontMatchingMetrics* Document::GetFontMatchingMetrics() {
void Document::InitContentSecurityPolicy(ContentSecurityPolicy* csp) {
GetSecurityContext().SetContentSecurityPolicy(csp);
GetContentSecurityPolicy()->BindToDelegate(
- GetContentSecurityPolicyDelegate());
+ GetExecutionContext()->GetContentSecurityPolicyDelegate());
}
void Document::InitSecurityContext(const DocumentInit& initializer) {
DCHECK(GetSecurityOrigin());
// If the CSP was provided by the DocumentLoader or is from ImportsController
// it doesn't need to be bound right now. ImportsController takes a reference
- // to a master document's CSP which is already bound. Document construction
+ // to a tree_root document's CSP which is already bound. Document construction
// occurs in the DocumentLoader occurs before the frame reference is bound so
// callbacks from binding the CSP delegate immediately would not get called
// if it was bound immediately. eg. Callbacks back to browser or console
@@ -7157,46 +7174,7 @@ void Document::InitSecurityContext(const DocumentInit& initializer) {
void Document::BindContentSecurityPolicy() {
DCHECK(!GetContentSecurityPolicy()->IsBound());
GetContentSecurityPolicy()->BindToDelegate(
- GetContentSecurityPolicyDelegate());
-}
-
-bool Document::CanExecuteScripts(ReasonForCallingCanExecuteScripts reason) {
- DCHECK(GetFrame())
- << "you are querying canExecuteScripts on a non contextDocument.";
-
- // Normally, scripts are not allowed in sandboxed contexts that disallow them.
- // However, there is an exception for cases when the script should bypass the
- // main world's CSP (such as for privileged isolated worlds). See
- // https://crbug.com/811528.
- if (IsSandboxed(network::mojom::blink::WebSandboxFlags::kScripts) &&
- !ContentSecurityPolicy::ShouldBypassMainWorld(domWindow())) {
- // FIXME: This message should be moved off the console once a solution to
- // https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
- if (reason == kAboutToExecuteScript) {
- AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
- mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError,
- "Blocked script execution in '" + Url().ElidedString() +
- "' because the document's frame is sandboxed and the "
- "'allow-scripts' permission is not set."));
- }
- return false;
- }
-
- // No scripting on a detached frame.
- if (!GetFrame()->Client())
- return false;
-
- WebContentSettingsClient* settings_client =
- GetFrame()->GetContentSettingsClient();
-
- Settings* settings = GetFrame()->GetSettings();
- bool script_enabled = settings && settings->GetScriptEnabled();
- if (settings_client)
- script_enabled = settings_client->AllowScript(script_enabled);
- if (!script_enabled && reason == kAboutToExecuteScript && settings_client)
- settings_client->DidNotAllowScript();
- return script_enabled;
+ GetExecutionContext()->GetContentSecurityPolicyDelegate());
}
bool Document::AllowInlineEventHandler(Node* node,
@@ -7204,27 +7182,27 @@ bool Document::AllowInlineEventHandler(Node* node,
const String& context_url,
const WTF::OrdinalNumber& context_line) {
auto* element = DynamicTo<Element>(node);
+ // HTML says that inline script needs browsing context to create its execution
+ // environment.
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#event-handler-attributes
+ // Also, if the listening node came from other document, which happens on
+ // context-less event dispatching, we also need to ask the owner document of
+ // the node.
+ LocalDOMWindow* window = ExecutingWindow();
+ if (!window)
+ return false;
// https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-content-attributes
// Step 5.1. If the Should element's inline behavior be blocked by Content
// Security Policy? algorithm returns "Blocked" when executed upon element,
// "script attribute", and value, then return. [CSP] [spec text]
- if (!GetContentSecurityPolicyForWorld()->AllowInline(
+ if (!window->GetContentSecurityPolicyForWorld()->AllowInline(
ContentSecurityPolicy::InlineType::kScriptAttribute, element,
listener->ScriptBody(), String() /* nonce */, context_url,
context_line))
return false;
- // HTML says that inline script needs browsing context to create its execution
- // environment.
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#event-handler-attributes
- // Also, if the listening node came from other document, which happens on
- // context-less event dispatching, we also need to ask the owner document of
- // the node.
- LocalFrame* frame = ExecutingFrame();
- if (!frame)
- return false;
- if (!ContextDocument()->CanExecuteScripts(kNotAboutToExecuteScript))
+ if (!window->CanExecuteScripts(kNotAboutToExecuteScript))
return false;
if (node && node->GetDocument() != this &&
!node->GetDocument().AllowInlineEventHandler(node, listener, context_url,
@@ -7454,23 +7432,6 @@ void Document::ServiceScriptedAnimations(
}
}
-int Document::RequestPostAnimationFrame(
- FrameRequestCallbackCollection::FrameCallback* cb) {
- return scripted_animation_controller_->RegisterPostFrameCallback(cb);
-}
-
-void Document::CancelPostAnimationFrame(int id) {
- scripted_animation_controller_->CancelPostFrameCallback(id);
-}
-
-void Document::RunPostAnimationFrameCallbacks() {
- bool was_throttled = current_frame_is_throttled_;
- current_frame_is_throttled_ = false;
- if (was_throttled)
- return;
- scripted_animation_controller_->RunPostFrameCallbacks();
-}
-
ScriptedIdleTaskController& Document::EnsureScriptedIdleTaskController() {
if (!scripted_idle_task_controller_) {
scripted_idle_task_controller_ =
@@ -7498,15 +7459,7 @@ void Document::CancelIdleCallback(int id) {
}
DocumentLoader* Document::Loader() const {
- if (!frame_)
- return nullptr;
-
- // TODO(dcheng): remove this check. frame_ is guaranteed to be non-null only
- // if frame_->GetDocument() == this.
- if (frame_->GetDocument() != this)
- return nullptr;
-
- return frame_->Loader().GetDocumentLoader();
+ return GetFrame() ? GetFrame()->Loader().GetDocumentLoader() : nullptr;
}
Node* EventTargetNodeForDocument(Document* doc) {
@@ -7575,8 +7528,8 @@ void Document::SetContextFeatures(ContextFeatures& features) {
void Document::UpdateHoverActiveState(bool is_active,
bool update_active_chain,
Element* inner_element) {
- if (is_active && frame_)
- frame_->GetEventHandler().NotifyElementActivated();
+ if (is_active && GetFrame())
+ GetFrame()->GetEventHandler().NotifyElementActivated();
Element* inner_element_in_document = inner_element;
@@ -7742,13 +7695,13 @@ Document& Document::EnsureTemplateDocument() {
if (IsA<HTMLDocument>(this)) {
template_document_ = MakeGarbageCollected<HTMLDocument>(
DocumentInit::Create()
- .WithContextDocument(ContextDocument())
+ .WithExecutionContext(execution_context_.Get())
.WithURL(BlankURL())
.WithNewRegistrationContext());
} else {
template_document_ = MakeGarbageCollected<Document>(
DocumentInit::Create()
- .WithContextDocument(ContextDocument())
+ .WithExecutionContext(execution_context_.Get())
.WithURL(BlankURL()));
}
@@ -7778,7 +7731,7 @@ void Document::DidAssociateFormControlsTimerFired(TimerBase* timer) {
}
float Document::DevicePixelRatio() const {
- return frame_ ? frame_->DevicePixelRatio() : 1.0;
+ return GetFrame() ? GetFrame()->DevicePixelRatio() : 1.0;
}
TextAutosizer* Document::GetTextAutosizer() {
@@ -8124,7 +8077,7 @@ PropertyRegistry& Document::EnsurePropertyRegistry() {
void Document::MaybeQueueSendDidEditFieldInInsecureContext() {
if (logged_field_edit_ || sensitive_input_edited_task_.IsActive() ||
- IsSecureContext()) {
+ execution_context_->IsSecureContext()) {
// Send a message on the first edit; the browser process doesn't care
// about the presence of additional edits.
//
@@ -8141,31 +8094,21 @@ void Document::MaybeQueueSendDidEditFieldInInsecureContext() {
WrapWeakPersistent(this)));
}
-BrowserInterfaceBrokerProxy& Document::GetBrowserInterfaceBroker() {
- if (!GetFrame())
- return GetEmptyBrowserInterfaceBroker();
-
- return GetFrame()->GetBrowserInterfaceBroker();
-}
-
DocumentResourceCoordinator* Document::GetResourceCoordinator() {
if (!resource_coordinator_ && GetFrame()) {
- resource_coordinator_ =
- DocumentResourceCoordinator::MaybeCreate(GetBrowserInterfaceBroker());
+ resource_coordinator_ = DocumentResourceCoordinator::MaybeCreate(
+ GetFrame()->GetBrowserInterfaceBroker());
}
return resource_coordinator_.get();
}
-FrameOrWorkerScheduler* Document::GetScheduler() {
- DCHECK(IsMainThread());
- return GetExecutionContext()->GetScheduler();
-}
-
scoped_refptr<base::SingleThreadTaskRunner> Document::GetTaskRunner(
TaskType type) {
DCHECK(IsMainThread());
if (GetExecutionContext())
return GetExecutionContext()->GetTaskRunner(type);
+ // GetExecutionContext() can be nullptr in unit tests and after Shutdown().
+ // Fallback to the default task runner for this thread if all else fails.
return Thread::Current()->GetTaskRunner();
}
@@ -8178,7 +8121,7 @@ DOMFeaturePolicy* Document::featurePolicy() {
const AtomicString& Document::RequiredCSP() {
if (!Loader())
return g_null_atom;
- return frame_->Loader().RequiredCSP();
+ return GetFrame()->Loader().RequiredCSP();
}
StylePropertyMapReadOnly* Document::ComputedStyleMap(Element* element) {
@@ -8202,7 +8145,7 @@ StylePropertyMapReadOnly* Document::RemoveComputedStyleMapItem(
return element_computed_style_map_.Take(element);
}
-void Document::Trace(Visitor* visitor) {
+void Document::Trace(Visitor* visitor) const {
visitor->Trace(security_context_);
visitor->Trace(imports_controller_);
visitor->Trace(use_counter_during_construction_);
@@ -8232,8 +8175,6 @@ void Document::Trace(Visitor* visitor) {
visitor->Trace(form_controller_);
visitor->Trace(visited_link_state_);
visitor->Trace(element_computed_style_map_);
- visitor->Trace(window_agent_factory_);
- visitor->Trace(frame_);
visitor->Trace(dom_window_);
visitor->Trace(fetcher_);
visitor->Trace(parser_);
@@ -8257,7 +8198,7 @@ void Document::Trace(Visitor* visitor) {
visitor->Trace(timeline_);
visitor->Trace(pending_animations_);
visitor->Trace(worklet_animation_controller_);
- visitor->Trace(context_document_);
+ visitor->Trace(execution_context_);
visitor->Trace(canvas_font_cache_);
visitor->Trace(intersection_observer_controller_);
visitor->Trace(snap_coordinator_);
@@ -8268,7 +8209,6 @@ void Document::Trace(Visitor* visitor) {
visitor->Trace(viewport_data_);
visitor->Trace(navigation_initiator_);
visitor->Trace(lazy_load_image_observer_);
- visitor->Trace(isolated_world_csp_map_);
visitor->Trace(computed_node_mapping_);
visitor->Trace(mime_handler_view_before_unload_event_listener_);
visitor->Trace(cookie_jar_);
@@ -8307,9 +8247,9 @@ bool Document::NextFrameHasPendingRAF() const {
void Document::NavigateLocalAdsFrames() {
// This navigates all the frames detected as an advertisement to about:blank.
- DCHECK(frame_);
- for (Frame* child = frame_->Tree().FirstChild(); child;
- child = child->Tree().TraverseNext(frame_)) {
+ DCHECK(GetFrame());
+ for (Frame* child = GetFrame()->Tree().FirstChild(); child;
+ child = child->Tree().TraverseNext(GetFrame())) {
if (auto* child_local_frame = DynamicTo<LocalFrame>(child)) {
if (child_local_frame->IsAdSubframe()) {
FrameLoadRequest request(this, ResourceRequest(BlankURL()));
@@ -8337,18 +8277,12 @@ bool Document::IsSlotAssignmentOrLegacyDistributionDirty() const {
return false;
}
-bool Document::IsLazyLoadPolicyEnforced() const {
- return RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() &&
- !GetSecurityContext().GetFeaturePolicy()->IsFeatureEnabled(
- mojom::blink::FeaturePolicyFeature::kLazyLoad);
-}
-
bool Document::IsFocusAllowed() const {
- if (frame_ && frame_->GetPage()->InsidePortal())
+ if (GetFrame() && GetFrame()->GetPage()->InsidePortal())
return false;
- if (!frame_ || frame_->IsMainFrame() ||
- LocalFrame::HasTransientUserActivation(frame_)) {
+ if (!GetFrame() || GetFrame()->IsMainFrame() ||
+ LocalFrame::HasTransientUserActivation(GetFrame())) {
// 'autofocus' runs Element::focus asynchronously at which point the
// document might not have a frame (see https://crbug.com/960224).
return true;
@@ -8357,7 +8291,7 @@ bool Document::IsFocusAllowed() const {
WebFeature uma_type;
bool sandboxed =
IsSandboxed(network::mojom::blink::WebSandboxFlags::kNavigation);
- bool ad = frame_->IsAdSubframe();
+ bool ad = GetFrame()->IsAdSubframe();
if (sandboxed) {
uma_type = ad ? WebFeature::kFocusWithoutUserActivationSandboxedAdFrame
: WebFeature::kFocusWithoutUserActivationSandboxedNotAdFrame;
@@ -8369,7 +8303,7 @@ bool Document::IsFocusAllowed() const {
CountUse(uma_type);
if (!RuntimeEnabledFeatures::BlockingFocusWithoutUserActivationEnabled())
return true;
- return IsFeatureEnabled(
+ return GetExecutionContext()->IsFeatureEnabled(
mojom::blink::FeaturePolicyFeature::kFocusWithoutUserActivation);
}
@@ -8389,23 +8323,19 @@ LazyLoadImageObserver& Document::EnsureLazyLoadImageObserver() {
return *lazy_load_image_observer_;
}
-WindowAgent& Document::GetWindowAgent() {
- return *static_cast<WindowAgent*>(GetAgent());
-}
-
void Document::IncrementNumberOfCanvases() {
num_canvases_++;
}
void Document::ExecuteJavaScriptUrls() {
- DCHECK(frame_);
+ DCHECK(GetFrame());
Vector<PendingJavascriptUrl> urls_to_execute;
urls_to_execute.swap(pending_javascript_urls_);
for (auto& url_to_execute : urls_to_execute) {
- frame_->GetScriptController().ExecuteJavaScriptURL(
+ GetFrame()->GetScriptController().ExecuteJavaScriptURL(
url_to_execute.url, url_to_execute.disposition);
- if (!frame_)
+ if (!GetFrame())
break;
}
CheckCompleted();
@@ -8415,9 +8345,9 @@ void Document::ProcessJavaScriptUrl(
const KURL& url,
network::mojom::CSPDisposition disposition) {
DCHECK(url.ProtocolIsJavaScript());
- if (frame_->Loader().StateMachine()->IsDisplayingInitialEmptyDocument())
+ if (GetFrame()->Loader().StateMachine()->IsDisplayingInitialEmptyDocument())
load_event_progress_ = kLoadEventNotRun;
- frame_->Loader().Progress().ProgressStarted();
+ GetFrame()->Loader().Progress().ProgressStarted();
pending_javascript_urls_.push_back(PendingJavascriptUrl(url, disposition));
if (!javascript_url_task_handle_.IsActive()) {
javascript_url_task_handle_ = PostCancellableTask(
@@ -8448,10 +8378,6 @@ bool Document::IsInWebAppScope() const {
return Url().GetString().StartsWith(web_app_scope);
}
-void Document::ClearIsolatedWorldCSPForTesting(int32_t world_id) {
- isolated_world_csp_map_->erase(world_id);
-}
-
bool Document::ChildrenCanHaveStyle() const {
if (LayoutObject* view = GetLayoutView())
return view->CanHaveChildren();
@@ -8509,6 +8435,12 @@ bool Document::InForcedColorsMode() const {
return in_forced_colors_mode_ && !Printing();
}
+bool Document::InDarkMode() {
+ return !InForcedColorsMode() && !Printing() &&
+ GetStyleEngine().GetPreferredColorScheme() ==
+ PreferredColorScheme::kDark;
+}
+
void Document::CountUse(mojom::WebFeature feature) const {
if (use_counter_during_construction_)
use_counter_during_construction_->CountUse(feature);
@@ -8524,35 +8456,8 @@ void Document::CountUse(mojom::WebFeature feature) {
}
void Document::CountDeprecation(mojom::WebFeature feature) {
- // TODO(yoichio): We should remove these counters when v0 APIs are removed.
- // crbug.com/946875.
- if (const OriginTrialContext* origin_trial_context =
- GetOriginTrialContext()) {
- if (feature == WebFeature::kHTMLImports &&
- origin_trial_context->IsFeatureEnabled(
- OriginTrialFeature::kHTMLImports)) {
- CountUse(WebFeature::kHTMLImportsOnReverseOriginTrials);
- } else if (feature == WebFeature::kElementCreateShadowRoot &&
- origin_trial_context->IsFeatureEnabled(
- OriginTrialFeature::kShadowDOMV0)) {
- CountUse(WebFeature::kElementCreateShadowRootOnReverseOriginTrials);
- } else if (feature == WebFeature::kDocumentRegisterElement &&
- origin_trial_context->IsFeatureEnabled(
- OriginTrialFeature::kCustomElementsV0)) {
- CountUse(WebFeature::kDocumentRegisterElementOnReverseOriginTrials);
- }
- }
-
- // Don't count usage of WebComponentsV0 for chrome:// URLs, but still report
- // the deprecation messages.
- if (Url().ProtocolIs("chrome") &&
- (feature == WebFeature::kHTMLImports ||
- feature == WebFeature::kElementCreateShadowRoot ||
- feature == WebFeature::kDocumentRegisterElement)) {
- Deprecation::DeprecationWarningOnly(Loader(), feature);
- } else {
- Deprecation::CountDeprecation(Loader(), feature);
- }
+ if (GetExecutionContext())
+ GetExecutionContext()->CountDeprecation(feature);
}
void Document::CountProperty(CSSPropertyID property) const {
@@ -8569,13 +8474,6 @@ void Document::CountAnimatedProperty(CSSPropertyID property) const {
}
}
-void Document::CountUseOnlyInCrossOriginIframe(
- mojom::WebFeature feature) const {
- LocalFrame* frame = GetFrame();
- if (frame && frame->IsCrossOriginToMainFrame())
- CountUse(feature);
-}
-
bool Document::IsUseCounted(mojom::WebFeature feature) const {
if (DocumentLoader* loader = Loader()) {
return loader->GetUseCounterHelper().HasRecordedMeasurement(feature);
diff --git a/chromium/third_party/blink/renderer/core/dom/document.h b/chromium/third_party/blink/renderer/core/dom/document.h
index 41f485b9aa1..b197ad6e06c 100644
--- a/chromium/third_party/blink/renderer/core/dom/document.h
+++ b/chromium/third_party/blink/renderer/core/dom/document.h
@@ -106,8 +106,6 @@ class CompositorAnimationTimeline;
class ComputedAccessibleNode;
class DisplayLockDocumentState;
class ElementIntersectionObserverData;
-class WindowAgent;
-class WindowAgentFactory;
class ComputedStyle;
class ConsoleMessage;
class ContextFeatures;
@@ -267,12 +265,27 @@ using ExplicitlySetAttrElementsMap =
// A document (https://dom.spec.whatwg.org/#concept-document) is the root node
// of a tree of DOM nodes, generally resulting from the parsing of an markup
-// (typically, HTML) resource. It provides both the content to be displayed to
-// the user in a frame and an execution context for JavaScript code.
+// (typically, HTML) resource.
+//
+// A document may or may not have a browsing context
+// (https://html.spec.whatwg.org/#browsing-context). A document with a browsing
+// context is created by navigation, and has a non-null domWindow(), GetFrame(),
+// Loader(), etc., and is visible to the user. It will have a valid
+// GetExecutionContext(), which will be equal to domWindow(). If the Document
+// constructor receives a DocumentInit created WithDocumentLoader(), it will
+// have a browsing context.
+// Documents created by all other APIs do not have a browsing context. These
+// Documents still have a valid GetExecutionContext() (i.e., the domWindow() of
+// the Document in which they were created), so they can still access
+// script, but return null for domWindow(), GetFrame() and Loader(). Generally,
+// they should not downcast the ExecutionContext to a LocalDOMWindow and access
+// the properties of the window directly.
+// Finally, unit tests are allowed to create a Document that does not even
+// have a valid GetExecutionContext(). This is a lightweight way to test
+// properties of the Document and the DOM that do not require script.
class CORE_EXPORT Document : public ContainerNode,
public TreeScope,
public UseCounter,
- public FeaturePolicyParserDelegate,
public Supplementable<Document> {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(Document);
@@ -284,13 +297,13 @@ class CORE_EXPORT Document : public ContainerNode,
// https://dom.spec.whatwg.org/#dom-document-document
static Document* Create(Document&);
- // Construct a Document instance with the default DocumentInit and
- // kDefaultDocumentClass.
- Document();
explicit Document(const DocumentInit& init,
DocumentClassFlags flags = kDefaultDocumentClass);
~Document() override;
+ // Constructs a Document instance without a subclass for testing.
+ static Document* CreateForTest();
+
static Range* CreateRangeAdjustedToTreeScope(const TreeScope&,
const Position&);
@@ -303,23 +316,11 @@ class CORE_EXPORT Document : public ContainerNode,
using TreeScope::getElementById;
- // TODO(crbug.com/1029822) Former ExecutionContext overrides. Most of these
- // should move to LocalDOMWindow.
- ContentSecurityPolicy* GetContentSecurityPolicyForWorld();
+ // Gets the associated LocalDOMWindow even if this Document is associated with
+ // an HTMLImportsController.
LocalDOMWindow* ExecutingWindow() const;
- bool CanExecuteScripts(ReasonForCallingCanExecuteScripts);
- String OutgoingReferrer() const;
- network::mojom::ReferrerPolicy GetReferrerPolicy() const;
- BrowserInterfaceBrokerProxy& GetBrowserInterfaceBroker();
- FrameOrWorkerScheduler* GetScheduler();
- // FeaturePolicyParserDelegate override
- // TODO(crbug.com/1029822) FeaturePolicyParserDelegate overrides, these
- // should migrate to LocalDOMWindow.
- bool FeatureEnabled(OriginTrialFeature) const override;
- void CountFeaturePolicyUsage(mojom::WebFeature feature) override;
- bool FeaturePolicyFeatureObserved(
- mojom::blink::FeaturePolicyFeature feature) override;
+ network::mojom::ReferrerPolicy GetReferrerPolicy() const;
bool DocumentPolicyFeatureObserved(
mojom::blink::DocumentPolicyFeature feature);
@@ -329,43 +330,17 @@ class CORE_EXPORT Document : public ContainerNode,
return security_context_;
}
- // TODO(crbug.com/1029822): Temporary helpers to access ExecutionContext
- // methods. These will need to be audited. Some might be useful permanent
- // helpers.
+ // Helpers for getting state off of SecurityContext.
const SecurityOrigin* GetSecurityOrigin() const;
SecurityOrigin* GetMutableSecurityOrigin();
ContentSecurityPolicy* GetContentSecurityPolicy() const;
network::mojom::blink::WebSandboxFlags GetSandboxFlags() const;
bool IsSandboxed(network::mojom::blink::WebSandboxFlags mask) const;
- PublicURLManager& GetPublicURLManager();
- bool IsContextPaused() const;
- bool IsContextDestroyed() const;
- ContentSecurityPolicyDelegate& GetContentSecurityPolicyDelegate();
SecureContextMode GetSecureContextMode() const;
- bool IsSecureContext() const;
- bool IsSecureContext(String& error_message) const;
void SetSecureContextModeForTesting(SecureContextMode);
- void SetReferrerPolicy(network::mojom::ReferrerPolicy);
- v8::Isolate* GetIsolate() const;
- Agent* GetAgent() const;
OriginTrialContext* GetOriginTrialContext() const;
- bool IsFeatureEnabled(
- mojom::blink::FeaturePolicyFeature,
- ReportOptions report_on_failure = ReportOptions::kDoNotReport,
- const String& message = g_empty_string) const;
- bool IsFeatureEnabled(
- mojom::blink::DocumentPolicyFeature,
- ReportOptions report_option = ReportOptions::kDoNotReport,
- const String& message = g_empty_string,
- const String& source_file = g_empty_string) const;
- bool IsFeatureEnabled(
- mojom::blink::DocumentPolicyFeature,
- PolicyValue threshold_value,
- ReportOptions report_option = ReportOptions::kDoNotReport,
- const String& message = g_empty_string,
- const String& source_file = g_empty_string) const;
-
- String addressSpaceForBindings() const;
+
+ String addressSpaceForBindings(ScriptState*) const;
bool CanContainRangeEndPoint() const override { return true; }
@@ -573,12 +548,12 @@ class CORE_EXPORT Document : public ContainerNode,
DocumentState* GetDocumentState() const;
void SetStateForNewControls(const Vector<String>&);
- LocalFrameView* View() const; // can be null
- LocalFrame* GetFrame() const { return frame_; } // can be null
- // Returns frame_ for current document, or if this is an HTML import, master
- // document's frame_, if any. Can be null.
+ LocalFrameView* View() const; // can be null
+ LocalFrame* GetFrame() const; // can be null
+ // Returns frame_ for current document, or if this is an HTML import,
+ // tree_root document's frame_, if any. Can be null.
// TODO(kochi): Audit usage of this interface (crbug.com/746150).
- LocalFrame* GetFrameOfMasterDocument() const;
+ LocalFrame* GetFrameOfTreeRootDocument() const;
Page* GetPage() const; // can be null
Settings* GetSettings() const; // can be null
@@ -765,7 +740,6 @@ class CORE_EXPORT Document : public ContainerNode,
// TODO(mkwst): Write a spec for this.
void write(v8::Isolate*, TrustedHTML*, ExceptionState&);
void writeln(v8::Isolate*, TrustedHTML*, ExceptionState&);
- bool IsTrustedTypesEnabledForDoc() const;
bool WellFormed() const { return well_formed_; }
@@ -961,7 +935,6 @@ class CORE_EXPORT Document : public ContainerNode,
unsigned old_length);
void DidSplitTextNode(const Text& old_node);
- void ClearDOMWindow() { dom_window_ = nullptr; }
LocalDOMWindow* domWindow() const { return dom_window_; }
// Helper functions for forwarding LocalDOMWindow event related tasks to the
@@ -1081,7 +1054,7 @@ class CORE_EXPORT Document : public ContainerNode,
// Storage Access API methods to check for or request access to storage that
// may otherwise be blocked.
- ScriptPromise hasStorageAccess(ScriptState* script_state) const;
+ ScriptPromise hasStorageAccess(ScriptState* script_state);
ScriptPromise requestStorageAccess(ScriptState* script_state);
// Sends a query via Mojo to ask whether the user has any trust tokens. This
@@ -1153,7 +1126,9 @@ class CORE_EXPORT Document : public ContainerNode,
// The document of the parent frame.
Document* ParentDocument() const;
Document& TopDocument() const;
- Document* ContextDocument() const;
+
+ // Will only return nullptr in unit tests.
+ ExecutionContext* GetExecutionContext() const final;
ScriptRunner* GetScriptRunner() { return script_runner_.Get(); }
@@ -1237,7 +1212,11 @@ class CORE_EXPORT Document : public ContainerNode,
kLoadEventInProgress,
kLoadEventCompleted,
kBeforeUnloadEventInProgress,
- kBeforeUnloadEventCompleted,
+ // Advanced to only if the beforeunload event in this document and
+ // subdocuments isn't canceled and will cause an unload. If beforeunload is
+ // canceled |load_event_progress_| will revert to its value prior to the
+ // beforeunload being dispatched.
+ kBeforeUnloadEventHandled,
kPageHideInProgress,
kUnloadVisibilityChangeInProgress,
kUnloadEventInProgress,
@@ -1249,12 +1228,19 @@ class CORE_EXPORT Document : public ContainerNode,
bool LoadEventFinished() const {
return load_event_progress_ >= kLoadEventCompleted;
}
- bool UnloadStarted() const {
- return load_event_progress_ >= kPageHideInProgress;
+ bool BeforeUnloadStarted() const {
+ return load_event_progress_ >= kBeforeUnloadEventInProgress;
}
bool ProcessingBeforeUnload() const {
return load_event_progress_ == kBeforeUnloadEventInProgress;
}
+ bool UnloadStarted() const {
+ return load_event_progress_ >= kPageHideInProgress;
+ }
+
+ void BeforeUnloadDoneWillUnload() {
+ load_event_progress_ = kBeforeUnloadEventHandled;
+ }
void SetContainsPlugins() { contains_plugins_ = true; }
bool ContainsPlugins() const { return contains_plugins_; }
@@ -1297,13 +1283,6 @@ class CORE_EXPORT Document : public ContainerNode,
void CancelAnimationFrame(int id);
void ServiceScriptedAnimations(
base::TimeTicks monotonic_animation_start_time);
- void SetCurrentFrameIsThrottled(bool throttled) {
- current_frame_is_throttled_ = true;
- }
-
- int RequestPostAnimationFrame(FrameRequestCallbackCollection::FrameCallback*);
- void CancelPostAnimationFrame(int id);
- void RunPostAnimationFrameCallbacks();
int RequestIdleCallback(ScriptedIdleTaskController::IdleTask*,
const IdleRequestOptions*);
@@ -1332,8 +1311,7 @@ class CORE_EXPORT Document : public ContainerNode,
HTMLImportLoader* ImportLoader() const;
bool IsHTMLImport() const;
- // TODO(kochi): Audit usage of this interface (crbug.com/746150).
- Document& MasterDocument() const;
+ Document& TreeRootDocument() const;
void DidLoadAllImports();
@@ -1393,8 +1371,6 @@ class CORE_EXPORT Document : public ContainerNode,
void AddConsoleMessage(ConsoleMessage* message,
bool discard_duplicates = false) const;
- LocalFrame* ExecutingFrame();
-
DocumentLifecycle& Lifecycle() { return lifecycle_; }
const DocumentLifecycle& Lifecycle() const { return lifecycle_; }
bool IsActive() const { return lifecycle_.IsActive(); }
@@ -1417,7 +1393,7 @@ class CORE_EXPORT Document : public ContainerNode,
void UpdateActiveStyle();
void InvalidateStyleAndLayoutForFontUpdates();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
AtomicString ConvertLocalName(const AtomicString&);
@@ -1456,8 +1432,6 @@ class CORE_EXPORT Document : public ContainerNode,
return shadow_cascade_order_ == ShadowCascadeOrder::kShadowCascadeV1;
}
- Element* rootScroller() const;
- void setRootScroller(Element*, ExceptionState& = ASSERT_NO_EXCEPTION);
RootScrollerController& GetRootScrollerController() const {
DCHECK(root_scroller_controller_);
return *root_scroller_controller_;
@@ -1550,18 +1524,12 @@ class CORE_EXPORT Document : public ContainerNode,
}
bool IsVerticalScrollEnforced() const { return is_vertical_scroll_enforced_; }
- bool IsLazyLoadPolicyEnforced() const;
bool IsFocusAllowed() const;
NavigationInitiatorImpl& NavigationInitiator();
LazyLoadImageObserver& EnsureLazyLoadImageObserver();
- WindowAgent& GetWindowAgent();
- WindowAgentFactory* GetWindowAgentFactory() const {
- return window_agent_factory_;
- }
-
void IncrementNumberOfCanvases();
void ProcessJavaScriptUrl(const KURL&, network::mojom::CSPDisposition);
@@ -1598,8 +1566,6 @@ class CORE_EXPORT Document : public ContainerNode,
// A new vision deficiency is being emulated through DevTools.
void VisionDeficiencyChanged();
- void ClearIsolatedWorldCSPForTesting(int32_t world_id);
-
// A META element with name=color-scheme was added, removed, or modified.
// Update the presentation level color-scheme property for the root element.
void ColorSchemeMetaChanged();
@@ -1610,9 +1576,6 @@ class CORE_EXPORT Document : public ContainerNode,
void CountUse(mojom::WebFeature feature) const;
void CountProperty(CSSPropertyID property_id) const;
void CountAnimatedProperty(CSSPropertyID property_id) const;
- // Count |feature| only when this document is associated with a cross-origin
- // iframe.
- void CountUseOnlyInCrossOriginIframe(mojom::WebFeature feature) const;
// Return whether the Feature was previously counted for this document.
// NOTE: only for use in testing.
bool IsUseCounted(mojom::WebFeature) const;
@@ -1632,6 +1595,7 @@ class CORE_EXPORT Document : public ContainerNode,
void UpdateForcedColors();
bool InForcedColorsMode() const;
+ bool InDarkMode();
// Capture the toggle event during parsing either by HTML parser or XML
// parser.
@@ -1686,6 +1650,12 @@ class CORE_EXPORT Document : public ContainerNode,
FontPreloadManager& GetFontPreloadManager() { return font_preload_manager_; }
void FontPreloadingFinishedOrTimedOut();
+ void IncrementAsyncScriptCount() { async_script_count_++; }
+ void RecordAsyncScriptCount();
+
+ void MarkFirstPaint();
+ void MaybeExecuteDelayedAsyncScripts();
+
void SetFindInPageActiveMatchNode(Node*);
const Node* GetFindInPageActiveMatchNode() const;
@@ -1849,8 +1819,6 @@ class CORE_EXPORT Document : public ContainerNode,
// stylesheets do eventually load.
PendingSheetLayout pending_sheet_layout_;
- Member<WindowAgentFactory> window_agent_factory_;
- Member<LocalFrame> frame_;
Member<LocalDOMWindow> dom_window_;
Member<HTMLImportsController> imports_controller_;
@@ -1862,9 +1830,14 @@ class CORE_EXPORT Document : public ContainerNode,
// TODO(dgozman): we should probably explicitly set and clear loader instead.
Member<UseCounter> use_counter_during_construction_;
- // The document of creator browsing context for frame-less documents such as
- // documents created by DOMParser and DOMImplementation.
- WeakMember<Document> context_document_;
+ // For Documents given a dom_window_ at creation that are not Shutdown(),
+ // execution_context_ and dom_window_ will be equal.
+ // For Documents given a dom_window_ at creation that are Shutdown(),
+ // execution_context_ will be nullptr.
+ // For Documents not given a dom_window_ at creation, execution_context_
+ // will be the LocalDOMWindow where script will execute (which may be nullptr
+ // in unit tests).
+ Member<ExecutionContext> execution_context_;
Member<ResourceFetcher> fetcher_;
Member<DocumentParser> parser_;
@@ -2060,7 +2033,6 @@ class CORE_EXPORT Document : public ContainerNode,
unsigned write_recursion_depth_;
Member<ScriptedAnimationController> scripted_animation_controller_;
- bool current_frame_is_throttled_;
Member<ScriptedIdleTaskController> scripted_idle_task_controller_;
Member<TextAutosizer> text_autosizer_;
@@ -2115,7 +2087,7 @@ class CORE_EXPORT Document : public ContainerNode,
// |ukm_recorder_| and |source_id_| will allow objects that are part of
// the document to record UKM.
std::unique_ptr<ukm::UkmRecorder> ukm_recorder_;
- int64_t ukm_source_id_;
+ const int64_t ukm_source_id_;
bool needs_to_record_ukm_outlive_time_;
// Tracks and reports UKM metrics of the number of attempted font family match
@@ -2192,10 +2164,6 @@ class CORE_EXPORT Document : public ContainerNode,
AtomicString override_last_modified_;
- // Map from isolated world IDs to their ContentSecurityPolicy instances.
- Member<HeapHashMap<int, Member<ContentSecurityPolicy>>>
- isolated_world_csp_map_;
-
// Used to keep track of which ComputedAccessibleNodes have already been
// instantiated in this document to avoid constructing duplicates.
HeapHashMap<AXID, Member<ComputedAccessibleNode>> computed_node_mapping_;
@@ -2237,6 +2205,11 @@ class CORE_EXPORT Document : public ContainerNode,
bool had_find_in_page_request_ = false;
bool had_find_in_page_render_subtree_active_match_ = false;
+ // To reduce the API noisiness an explicit deny decision will set a
+ // flag that auto rejects the promise without the need for an IPC
+ // call or potential user prompt.
+ bool expressly_denied_storage_access_ = false;
+
// Mojo remote used to determine if the document has permission to access
// storage or not.
HeapMojoRemote<mojom::blink::PermissionService> permission_service_;
@@ -2259,6 +2232,9 @@ class CORE_EXPORT Document : public ContainerNode,
FontPreloadManager font_preload_manager_;
+ int async_script_count_ = 0;
+ bool first_paint_recorded_ = false;
+
WeakMember<Node> find_in_page_active_match_node_;
};
diff --git a/chromium/third_party/blink/renderer/core/dom/document.idl b/chromium/third_party/blink/renderer/core/dom/document.idl
index efce87b4f66..79b5644bae0 100644
--- a/chromium/third_party/blink/renderer/core/dom/document.idl
+++ b/chromium/third_party/blink/renderer/core/dom/document.idl
@@ -76,9 +76,6 @@ typedef (HTMLScriptElement or SVGScriptElement) HTMLOrSVGScriptElement;
[NewObject] NodeIterator createNodeIterator(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null);
[NewObject] TreeWalker createTreeWalker(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null);
- // NonDocumentRootScroller (https://github.com/bokand/NonDocumentRootScroller)
- [RaisesException=Setter, RuntimeEnabled=SetRootScroller, Measure] attribute Element? rootScroller;
-
// FIXME: xmlEncoding/xmlVersion/xmlStandalone have been removed from the spec.
[MeasureAs=DocumentXMLEncoding] readonly attribute DOMString? xmlEncoding;
[RaisesException=Setter, MeasureAs=DocumentXMLVersion] attribute DOMString? xmlVersion;
@@ -182,17 +179,17 @@ typedef (HTMLScriptElement or SVGScriptElement) HTMLOrSVGScriptElement;
// CORS and RFC1918
// https://wicg.github.io/cors-rfc1918/#feature-detect
- [RuntimeEnabled=AddressSpace, ImplementedAs=addressSpaceForBindings] readonly attribute AddressSpace addressSpace;
+ [CallWith=ScriptState, RuntimeEnabled=AddressSpace, ImplementedAs=addressSpaceForBindings] readonly attribute AddressSpace addressSpace;
// Non-standard APIs
[MeasureAs=DocumentCaretRangeFromPoint] Range caretRangeFromPoint(optional long x = 0, optional long y = 0);
// Storage Access API
- [CallWith=ScriptState, NewObject, RuntimeEnabled=StorageAccessAPI] Promise<boolean> hasStorageAccess();
- [CallWith=ScriptState, NewObject, RuntimeEnabled=StorageAccessAPI] Promise<void> requestStorageAccess();
+ [CallWith=ScriptState, NewObject, RuntimeEnabled=StorageAccessAPI, MeasureAs=StorageAccessAPI_HasStorageAccess_Method] Promise<boolean> hasStorageAccess();
+ [CallWith=ScriptState, NewObject, RuntimeEnabled=StorageAccessAPI, MeasureAs=StorageAccessAPI_requestStorageAccess_Method] Promise<void> requestStorageAccess();
// https://w3c.github.io/webappsec-feature-policy/#the-policy-object
- [RuntimeEnabled=FeaturePolicyJavaScriptInterface] readonly attribute FeaturePolicy featurePolicy;
+ readonly attribute FeaturePolicy featurePolicy;
// Deprecated prefixed page visibility API.
// TODO(davidben): This is a property so attaching a deprecation warning results in false positives when outputting
diff --git a/chromium/third_party/blink/renderer/core/dom/document_init.cc b/chromium/third_party/blink/renderer/core/dom/document_init.cc
index 8d1802954e2..bab98605009 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_init.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document_init.cc
@@ -34,13 +34,22 @@
#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_implementation.h"
+#include "third_party/blink/renderer/core/dom/sink_document.h"
+#include "third_party/blink/renderer/core/dom/xml_document.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h"
#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
+#include "third_party/blink/renderer/core/html/html_view_source_document.h"
+#include "third_party/blink/renderer/core/html/image_document.h"
#include "third_party/blink/renderer/core/html/imports/html_imports_controller.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
+#include "third_party/blink/renderer/core/html/media/media_document.h"
+#include "third_party/blink/renderer/core/html/plugin_document.h"
+#include "third_party/blink/renderer/core/html/text_document.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
@@ -63,6 +72,11 @@ static Document* ParentDocument(DocumentLoader* loader) {
return &owner_element->GetDocument();
}
+bool IsPagePopupRunningInWebTest(LocalFrame* frame) {
+ return frame && frame->GetPage()->GetChromeClient().IsPopup() &&
+ WebTestSupport::IsRunningWebTest();
+}
+
// static
DocumentInit DocumentInit::Create() {
return DocumentInit();
@@ -72,6 +86,17 @@ DocumentInit::DocumentInit(const DocumentInit&) = default;
DocumentInit::~DocumentInit() = default;
+DocumentInit& DocumentInit::ForTest() {
+ DCHECK(!execution_context_);
+ DCHECK(!document_loader_);
+#if DCHECK_IS_ON()
+ DCHECK(!for_test_);
+ for_test_ = true;
+#endif
+ content_security_policy_ = MakeGarbageCollected<ContentSecurityPolicy>();
+ return *this;
+}
+
DocumentInit& DocumentInit::WithImportsController(
HTMLImportsController* controller) {
imports_controller_ = controller;
@@ -79,7 +104,7 @@ DocumentInit& DocumentInit::WithImportsController(
}
bool DocumentInit::ShouldSetURL() const {
- DocumentLoader* loader = MasterDocumentLoader();
+ DocumentLoader* loader = TreeRootDocumentLoader();
return (loader && loader->GetFrame()->Tree().Parent()) || !url_.IsEmpty();
}
@@ -88,11 +113,11 @@ bool DocumentInit::IsSrcdocDocument() const {
return parent_document_ && is_srcdoc_document_;
}
-DocumentLoader* DocumentInit::MasterDocumentLoader() const {
+DocumentLoader* DocumentInit::TreeRootDocumentLoader() const {
if (document_loader_)
return document_loader_;
if (imports_controller_) {
- return imports_controller_->Master()
+ return imports_controller_->TreeRoot()
->GetFrame()
->Loader()
.GetDocumentLoader();
@@ -101,22 +126,18 @@ DocumentLoader* DocumentInit::MasterDocumentLoader() const {
}
network::mojom::blink::WebSandboxFlags DocumentInit::GetSandboxFlags() const {
- network::mojom::blink::WebSandboxFlags flags = sandbox_flags_;
- if (DocumentLoader* loader = MasterDocumentLoader())
+ DCHECK(content_security_policy_);
+ network::mojom::blink::WebSandboxFlags flags =
+ sandbox_flags_ | content_security_policy_->GetSandboxMask();
+ if (DocumentLoader* loader = TreeRootDocumentLoader())
flags |= loader->GetFrame()->Loader().EffectiveSandboxFlags();
- // If the load was blocked by CSP, force the Document's origin to be unique,
- // so that the blocked document appears to be a normal cross-origin
- // document's load per CSP spec:
- // https://www.w3.org/TR/CSP3/#directive-frame-ancestors.
- if (blocked_by_csp_)
- flags |= network::mojom::blink::WebSandboxFlags::kOrigin;
return flags;
}
mojom::blink::InsecureRequestPolicy DocumentInit::GetInsecureRequestPolicy()
const {
- DCHECK(MasterDocumentLoader());
- Frame* parent_frame = MasterDocumentLoader()->GetFrame()->Tree().Parent();
+ DCHECK(TreeRootDocumentLoader());
+ Frame* parent_frame = TreeRootDocumentLoader()->GetFrame()->Tree().Parent();
if (!parent_frame)
return mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone;
return parent_frame->GetSecurityContext()->GetInsecureRequestPolicy();
@@ -124,8 +145,8 @@ mojom::blink::InsecureRequestPolicy DocumentInit::GetInsecureRequestPolicy()
const SecurityContext::InsecureNavigationsSet*
DocumentInit::InsecureNavigationsToUpgrade() const {
- DCHECK(MasterDocumentLoader());
- Frame* parent_frame = MasterDocumentLoader()->GetFrame()->Tree().Parent();
+ DCHECK(TreeRootDocumentLoader());
+ Frame* parent_frame = TreeRootDocumentLoader()->GetFrame()->Tree().Parent();
if (!parent_frame)
return nullptr;
return &parent_frame->GetSecurityContext()->InsecureNavigationsToUpgrade();
@@ -135,17 +156,20 @@ network::mojom::IPAddressSpace DocumentInit::GetIPAddressSpace() const {
return ip_address_space_;
}
-Settings* DocumentInit::GetSettings() const {
- DCHECK(MasterDocumentLoader());
- return MasterDocumentLoader()->GetFrame()->GetSettings();
-}
-
-DocumentInit& DocumentInit::WithDocumentLoader(DocumentLoader* loader) {
+DocumentInit& DocumentInit::WithDocumentLoader(DocumentLoader* loader,
+ ContentSecurityPolicy* policy) {
DCHECK(!document_loader_);
+ DCHECK(!execution_context_);
DCHECK(!imports_controller_);
+#if DCHECK_IS_ON()
+ DCHECK(!for_test_);
+#endif
+ DCHECK(!content_security_policy_);
+ DCHECK(loader);
+ DCHECK(policy);
document_loader_ = loader;
- if (document_loader_)
- parent_document_ = ParentDocument(document_loader_);
+ parent_document_ = ParentDocument(document_loader_);
+ content_security_policy_ = policy;
return *this;
}
@@ -207,13 +231,16 @@ DocumentInit::Type DocumentInit::ComputeDocumentType(
}
}
- if (DOMImplementation::IsTextMIMEType(mime_type))
+ if (MIMETypeRegistry::IsSupportedJavaScriptMIMEType(mime_type) ||
+ MIMETypeRegistry::IsJSONMimeType(mime_type) ||
+ MIMETypeRegistry::IsPlainTextMIMEType(mime_type)) {
return Type::kText;
+ }
if (mime_type == "image/svg+xml")
return Type::kSVG;
- if (DOMImplementation::IsXMLMIMEType(mime_type))
+ if (MIMETypeRegistry::IsXMLMIMEType(mime_type))
return Type::kXML;
return Type::kHTML;
@@ -244,9 +271,17 @@ DocumentInit& DocumentInit::WithTypeFrom(const String& mime_type) {
return *this;
}
-DocumentInit& DocumentInit::WithContextDocument(Document* context_document) {
- DCHECK(!context_document_);
- context_document_ = context_document;
+DocumentInit& DocumentInit::WithExecutionContext(
+ ExecutionContext* execution_context) {
+ DCHECK(!execution_context_);
+ DCHECK(!document_loader_);
+#if DCHECK_IS_ON()
+ DCHECK(!for_test_);
+#endif
+ execution_context_ = execution_context;
+ content_security_policy_ = MakeGarbageCollected<ContentSecurityPolicy>();
+ content_security_policy_->CopyStateFrom(
+ execution_context_->GetContentSecurityPolicy());
return *this;
}
@@ -256,23 +291,93 @@ DocumentInit& DocumentInit::WithURL(const KURL& url) {
return *this;
}
+void DocumentInit::CalculateAndCacheDocumentOrigin() {
+ DCHECK(!cached_document_origin_);
+ cached_document_origin_ = GetDocumentOrigin();
+}
+
scoped_refptr<SecurityOrigin> DocumentInit::GetDocumentOrigin() const {
- // Origin to commit is specified by the browser process, it must be taken
- // and used directly. It is currently supplied only for session history
- // navigations, where the origin was already calcuated previously and
- // stored on the session history entry.
- if (origin_to_commit_)
- return origin_to_commit_;
+ if (cached_document_origin_)
+ return cached_document_origin_;
+
+ scoped_refptr<SecurityOrigin> document_origin;
+ if (origin_to_commit_) {
+ // Origin to commit is specified by the browser process, it must be taken
+ // and used directly. It is currently supplied only for session history
+ // navigations, where the origin was already calcuated previously and
+ // stored on the session history entry.
+ document_origin = origin_to_commit_;
+ } else if (IsPagePopupRunningInWebTest(GetFrame())) {
+ // If we are a page popup in LayoutTests ensure we use the popup
+ // owner's security origin so the tests can possibly access the
+ // document via internals API.
+ document_origin = GetFrame()
+ ->PagePopupOwner()
+ ->GetDocument()
+ .GetSecurityOrigin()
+ ->IsolatedCopy();
+ } else if (owner_document_) {
+ document_origin = owner_document_->GetMutableSecurityOrigin();
+ } else {
+ // Otherwise, create an origin that propagates precursor information
+ // as needed. For non-opaque origins, this creates a standard tuple
+ // origin, but for opaque origins, it creates an origin with the
+ // initiator origin as the precursor.
+ document_origin = SecurityOrigin::CreateWithReferenceOrigin(
+ url_, initiator_origin_.get());
+ }
+
+ if (IsSandboxed(network::mojom::blink::WebSandboxFlags::kOrigin)) {
+ auto sandbox_origin = document_origin->DeriveNewOpaqueOrigin();
+
+ // If we're supposed to inherit our security origin from our
+ // owner, but we're also sandboxed, the only things we inherit are
+ // the origin's potential trustworthiness and the ability to
+ // load local resources. The latter lets about:blank iframes in
+ // file:// URL documents load images and other resources from
+ // the file system.
+ //
+ // Note: Sandboxed about:srcdoc iframe without "allow-same-origin" aren't
+ // allowed to load user's file, even if its parent can.
+ if (owner_document_) {
+ if (document_origin->IsPotentiallyTrustworthy())
+ sandbox_origin->SetOpaqueOriginIsPotentiallyTrustworthy(true);
+ if (document_origin->CanLoadLocalResources() && !IsSrcdocDocument())
+ sandbox_origin->GrantLoadLocalResources();
+ }
+ document_origin = sandbox_origin;
+ }
+
+ if (TreeRootDocumentLoader() &&
+ TreeRootDocumentLoader()->GetFrame()->GetSettings()) {
+ Settings* settings = TreeRootDocumentLoader()->GetFrame()->GetSettings();
+ if (!settings->GetWebSecurityEnabled()) {
+ // Web security is turned off. We should let this document access
+ // every other document. This is used primary by testing harnesses for
+ // web sites.
+ document_origin->GrantUniversalAccess();
+ } else if (document_origin->IsLocal()) {
+ if (settings->GetAllowUniversalAccessFromFileURLs()) {
+ // Some clients want local URLs to have universal access, but that
+ // setting is dangerous for other clients.
+ document_origin->GrantUniversalAccess();
+ } else if (!settings->GetAllowFileAccessFromFileURLs()) {
+ // Some clients do not want local URLs to have access to other local
+ // URLs.
+ document_origin->BlockLocalAccessFromLocalOrigin();
+ }
+ }
+ }
- if (owner_document_)
- return owner_document_->GetMutableSecurityOrigin();
+ if (grant_load_local_resources_)
+ document_origin->GrantLoadLocalResources();
- // Otherwise, create an origin that propagates precursor information
- // as needed. For non-opaque origins, this creates a standard tuple
- // origin, but for opaque origins, it creates an origin with the
- // initiator origin as the precursor.
- return SecurityOrigin::CreateWithReferenceOrigin(url_,
- initiator_origin_.get());
+ if (document_origin->IsOpaque() && ShouldSetURL()) {
+ KURL url = url_.IsEmpty() ? BlankURL() : url_;
+ if (SecurityOrigin::Create(url)->IsPotentiallyTrustworthy())
+ document_origin->SetOpaqueOriginIsPotentiallyTrustworthy(true);
+ }
+ return document_origin;
}
DocumentInit& DocumentInit::WithOwnerDocument(Document* owner_document) {
@@ -309,11 +414,6 @@ DocumentInit& DocumentInit::WithSrcdocDocument(bool is_srcdoc_document) {
return *this;
}
-DocumentInit& DocumentInit::WithBlockedByCSP(bool blocked_by_csp) {
- blocked_by_csp_ = blocked_by_csp;
- return *this;
-}
-
DocumentInit& DocumentInit::WithGrantLoadLocalResources(
bool grant_load_local_resources) {
grant_load_local_resources_ = grant_load_local_resources;
@@ -346,8 +446,10 @@ V0CustomElementRegistrationContext* DocumentInit::RegistrationContext(
return registration_context_;
}
-Document* DocumentInit::ContextDocument() const {
- return context_document_;
+ExecutionContext* DocumentInit::GetExecutionContext() const {
+ if (execution_context_)
+ return execution_context_;
+ return GetFrame() ? GetFrame()->DomWindow() : nullptr;
}
DocumentInit& DocumentInit::WithFeaturePolicyHeader(const String& header) {
@@ -376,27 +478,8 @@ DocumentInit& DocumentInit::WithSandboxFlags(
return *this;
}
-DocumentInit& DocumentInit::WithContentSecurityPolicy(
- ContentSecurityPolicy* policy) {
- content_security_policy_ = policy;
- return *this;
-}
-
-DocumentInit& DocumentInit::WithContentSecurityPolicyFromContextDoc() {
- content_security_policy_from_context_doc_ = true;
- return *this;
-}
-
ContentSecurityPolicy* DocumentInit::GetContentSecurityPolicy() const {
- DCHECK(
- !(content_security_policy_ && content_security_policy_from_context_doc_));
- if (context_document_ && content_security_policy_from_context_doc_) {
- // Return a copy of the context documents' CSP. The return value will be
- // modified, so this must be a copy.
- ContentSecurityPolicy* csp = MakeGarbageCollected<ContentSecurityPolicy>();
- csp->CopyStateFrom(context_document_->GetContentSecurityPolicy());
- return csp;
- }
+ DCHECK(content_security_policy_);
return content_security_policy_;
}
@@ -433,34 +516,55 @@ DocumentInit& DocumentInit::WithWebBundleClaimedUrl(
return *this;
}
-bool IsPagePopupRunningInWebTest(LocalFrame* frame) {
- return frame && frame->GetPage()->GetChromeClient().IsPopup() &&
- WebTestSupport::IsRunningWebTest();
-}
-
-WindowAgentFactory* DocumentInit::GetWindowAgentFactory() const {
- // If we are a page popup in LayoutTests ensure we use the popup
- // owner's frame for looking up the Agent so the tests can possibly
- // access the document via internals API.
- LocalFrame* frame = nullptr;
- if (IsPagePopupRunningInWebTest(GetFrame()))
- frame = GetFrame()->PagePopupOwner()->GetDocument().GetFrame();
- else if (GetFrame())
- frame = GetFrame();
- else if (Document* context_document = ContextDocument())
- return context_document->GetWindowAgentFactory();
- return frame ? &frame->window_agent_factory() : nullptr;
-}
-
-Settings* DocumentInit::GetSettingsForWindowAgentFactory() const {
- LocalFrame* frame = nullptr;
- if (IsPagePopupRunningInWebTest(GetFrame()))
- frame = GetFrame()->PagePopupOwner()->GetDocument().GetFrame();
- else if (GetFrame())
- frame = GetFrame();
- else if (Document* context_document = ContextDocument())
- frame = context_document->GetFrame();
- return frame ? frame->GetSettings() : nullptr;
+bool DocumentInit::ShouldReuseDOMWindow() const {
+ DCHECK(GetFrame());
+ // Secure transitions can only happen when navigating from the initial empty
+ // document.
+ if (!GetFrame()->Loader().StateMachine()->IsDisplayingInitialEmptyDocument())
+ return false;
+ return GetFrame()->GetDocument()->GetSecurityOrigin()->CanAccess(
+ GetDocumentOrigin().get());
+}
+
+bool DocumentInit::IsSandboxed(
+ network::mojom::blink::WebSandboxFlags mask) const {
+ return (GetSandboxFlags() & mask) !=
+ network::mojom::blink::WebSandboxFlags::kNone;
+}
+
+Document* DocumentInit::CreateDocument() const {
+#if DCHECK_IS_ON()
+ DCHECK(document_loader_ || execution_context_ || for_test_);
+#endif
+ switch (type_) {
+ case Type::kHTML:
+ return MakeGarbageCollected<HTMLDocument>(*this);
+ case Type::kXHTML:
+ return XMLDocument::CreateXHTML(*this);
+ case Type::kImage:
+ return MakeGarbageCollected<ImageDocument>(*this);
+ case Type::kPlugin: {
+ if (IsSandboxed(network::mojom::blink::WebSandboxFlags::kPlugins))
+ return MakeGarbageCollected<SinkDocument>(*this);
+ return MakeGarbageCollected<PluginDocument>(*this);
+ }
+ case Type::kMedia:
+ return MakeGarbageCollected<MediaDocument>(*this);
+ case Type::kSVG:
+ return XMLDocument::CreateSVG(*this);
+ case Type::kXML:
+ return MakeGarbageCollected<XMLDocument>(*this);
+ case Type::kViewSource:
+ return MakeGarbageCollected<HTMLViewSourceDocument>(*this);
+ case Type::kText:
+ return MakeGarbageCollected<TextDocument>(*this);
+ case Type::kUnspecified:
+ FALLTHROUGH;
+ default:
+ break;
+ }
+ NOTREACHED();
+ return nullptr;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/document_init.h b/chromium/third_party/blink/renderer/core/dom/document_init.h
index 45eb8b5f1ab..44b442a2ab7 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_init.h
+++ b/chromium/third_party/blink/renderer/core/dom/document_init.h
@@ -47,27 +47,35 @@ namespace blink {
class ContentSecurityPolicy;
class Document;
class DocumentLoader;
+class ExecutionContext;
class HTMLImportsController;
class LocalFrame;
class PluginData;
-class Settings;
class UseCounter;
-class WindowAgentFactory;
class CORE_EXPORT DocumentInit final {
STACK_ALLOCATED();
public:
- // Use either of the following methods to create a DocumentInit instance, and
- // then add a chain of calls to the .WithFooBar() methods to add optional
+ // Create a DocumentInit instance, then add a chain of calls to add optional
// parameters to it.
//
// Example:
//
// DocumentInit init = DocumentInit::Create()
- // .WithDocumentLoader(loader)
- // .WithContextDocument(context_document)
+ // .WithExecutionContext(context)
// .WithURL(url);
+ //
+ // Before creating a Document from this DocumentInit, the caller must invoke
+ // exactly one of:
+ // * ForTest() - for unit-test-only cases
+ // * WithDocumentLoader() - for navigations originating from DocumentLoader
+ // * WithExecutionContext() - for all other cases
+ //
+ // Invoking init.CreateDocument() will construct a Document of the appropriate
+ // subclass for the init's Type.
+ // However, when the document type is known, it is acceptable to invoke the
+ // constructor for Document (or the appropriate subclass) directly:
// Document* document = MakeGarbageCollected<Document>(init);
static DocumentInit Create();
@@ -87,23 +95,25 @@ class CORE_EXPORT DocumentInit final {
kUnspecified
};
+ DocumentInit& ForTest();
+
+ // Actually constructs the Document based on the provided state.
+ Document* CreateDocument() const;
+
DocumentInit& WithImportsController(HTMLImportsController*);
HTMLImportsController* ImportsController() const {
return imports_controller_;
}
- bool HasSecurityContext() const { return MasterDocumentLoader(); }
+ bool HasSecurityContext() const { return TreeRootDocumentLoader(); }
bool IsSrcdocDocument() const;
bool ShouldSetURL() const;
network::mojom::blink::WebSandboxFlags GetSandboxFlags() const;
mojom::blink::InsecureRequestPolicy GetInsecureRequestPolicy() const;
const SecurityContext::InsecureNavigationsSet* InsecureNavigationsToUpgrade()
const;
- bool GrantLoadLocalResources() const { return grant_load_local_resources_; }
-
- Settings* GetSettings() const;
- DocumentInit& WithDocumentLoader(DocumentLoader*);
+ DocumentInit& WithDocumentLoader(DocumentLoader*, ContentSecurityPolicy*);
LocalFrame* GetFrame() const;
UseCounter* GetUseCounter() const;
@@ -123,15 +133,17 @@ class CORE_EXPORT DocumentInit final {
bool IsForExternalHandler() const { return is_for_external_handler_; }
Color GetPluginBackgroundColor() const { return plugin_background_color_; }
- // Used by the DOMImplementation and DOMParser to pass their parent Document
- // so that the created Document will return the Document when the
- // ContextDocument() method is called.
- DocumentInit& WithContextDocument(Document*);
- Document* ContextDocument() const;
+ // Used when creating Documents not attached to a window.
+ DocumentInit& WithExecutionContext(ExecutionContext*);
+ ExecutionContext* GetExecutionContext() const;
DocumentInit& WithURL(const KURL&);
const KURL& Url() const { return url_; }
+ // Pre-calculates the origin. This is needed for DocumentLoader, which wants
+ // to inspect the origin multiple times and should receive the same object
+ // back each time.
+ void CalculateAndCacheDocumentOrigin();
scoped_refptr<SecurityOrigin> GetDocumentOrigin() const;
// Specifies the Document to inherit security configurations from.
@@ -155,7 +167,6 @@ class CORE_EXPORT DocumentInit final {
network::mojom::IPAddressSpace GetIPAddressSpace() const;
DocumentInit& WithSrcdocDocument(bool is_srcdoc_document);
- DocumentInit& WithBlockedByCSP(bool blocked_by_csp);
DocumentInit& WithGrantLoadLocalResources(bool grant_load_local_resources);
DocumentInit& WithRegistrationContext(V0CustomElementRegistrationContext*);
@@ -175,8 +186,6 @@ class CORE_EXPORT DocumentInit final {
DocumentInit& WithSandboxFlags(network::mojom::blink::WebSandboxFlags flags);
- DocumentInit& WithContentSecurityPolicy(ContentSecurityPolicy* policy);
- DocumentInit& WithContentSecurityPolicyFromContextDoc();
ContentSecurityPolicy* GetContentSecurityPolicy() const;
DocumentInit& WithFramePolicy(
@@ -199,8 +208,7 @@ class CORE_EXPORT DocumentInit final {
DocumentInit& WithWebBundleClaimedUrl(const KURL& web_bundle_claimed_url);
const KURL& GetWebBundleClaimedUrl() const { return web_bundle_claimed_url_; }
- WindowAgentFactory* GetWindowAgentFactory() const;
- Settings* GetSettingsForWindowAgentFactory() const;
+ bool ShouldReuseDOMWindow() const;
private:
DocumentInit() = default;
@@ -209,7 +217,9 @@ class CORE_EXPORT DocumentInit final {
// DocumentLoader driving the commit. For an import, XSLT-generated
// document, etc., it will be the DocumentLoader that drove the commit
// of its owning Document.
- DocumentLoader* MasterDocumentLoader() const;
+ DocumentLoader* TreeRootDocumentLoader() const;
+
+ bool IsSandboxed(network::mojom::blink::WebSandboxFlags) const;
static PluginData* GetPluginData(LocalFrame* frame, const KURL& url);
@@ -221,10 +231,13 @@ class CORE_EXPORT DocumentInit final {
HTMLImportsController* imports_controller_ = nullptr;
- Document* context_document_ = nullptr;
+ ExecutionContext* execution_context_ = nullptr;
KURL url_;
Document* owner_document_ = nullptr;
+ // Used to cache the final origin for the Document to be created.
+ scoped_refptr<SecurityOrigin> cached_document_origin_;
+
// Initiator origin is used for calculating the document origin when the
// navigation is started in a different process. In such cases, the document
// which initiates the navigation sends its origin to the browser process and
@@ -249,10 +262,6 @@ class CORE_EXPORT DocumentInit final {
// the parent document, not from loading a URL.
bool is_srcdoc_document_ = false;
- // Whether the actual document was blocked by csp and we are creating a dummy
- // empty document instead.
- bool blocked_by_csp_ = false;
-
// Whether the document should be able to access local file:// resources.
bool grant_load_local_resources_ = false;
@@ -272,7 +281,6 @@ class CORE_EXPORT DocumentInit final {
// Loader's CSP
ContentSecurityPolicy* content_security_policy_ = nullptr;
- bool content_security_policy_from_context_doc_ = false;
network::mojom::IPAddressSpace ip_address_space_ =
network::mojom::IPAddressSpace::kUnknown;
@@ -291,6 +299,10 @@ class CORE_EXPORT DocumentInit final {
bool is_for_external_handler_ = false;
Color plugin_background_color_;
+
+#if DCHECK_IS_ON()
+ bool for_test_ = false;
+#endif
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/document_lifecycle.cc b/chromium/third_party/blink/renderer/core/dom/document_lifecycle.cc
index 3b9b819c42b..f472e18820e 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_lifecycle.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document_lifecycle.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/dom/document_lifecycle.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -304,7 +305,7 @@ bool DocumentLifecycle::CanRewindTo(LifecycleState next_state) const {
if (StateTransitionDisallowed())
return false;
- // This transition is bogus, but we've whitelisted it anyway.
+ // This transition is bogus, but we've allowed it anyway.
if (g_deprecated_transition_stack &&
state_ == g_deprecated_transition_stack->From() &&
next_state == g_deprecated_transition_stack->To())
diff --git a/chromium/third_party/blink/renderer/core/dom/document_parser.cc b/chromium/third_party/blink/renderer/core/dom/document_parser.cc
index 10e2cff64e3..9ab921a9538 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_parser.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document_parser.cc
@@ -42,7 +42,7 @@ DocumentParser::DocumentParser(Document* document)
DocumentParser::~DocumentParser() = default;
-void DocumentParser::Trace(Visitor* visitor) {
+void DocumentParser::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(clients_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/document_parser.h b/chromium/third_party/blink/renderer/core/dom/document_parser.h
index 9fe3e606be2..3a61a1b374f 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_parser.h
+++ b/chromium/third_party/blink/renderer/core/dom/document_parser.h
@@ -41,7 +41,7 @@ class CORE_EXPORT DocumentParser : public GarbageCollected<DocumentParser>,
public NameClient {
public:
virtual ~DocumentParser();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override { return "DocumentParser"; }
virtual ScriptableDocumentParser* AsScriptableDocumentParser() {
diff --git a/chromium/third_party/blink/renderer/core/dom/document_parser_client.h b/chromium/third_party/blink/renderer/core/dom/document_parser_client.h
index bdc55f19124..05f4f3d95b1 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_parser_client.h
+++ b/chromium/third_party/blink/renderer/core/dom/document_parser_client.h
@@ -14,7 +14,7 @@ class DocumentParserClient : public GarbageCollectedMixin {
// This callback is called when all data pushed to parser has been consumed.
virtual void NotifyParserStopped() = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
protected:
DocumentParserClient() = default;
diff --git a/chromium/third_party/blink/renderer/core/dom/document_parser_timing.cc b/chromium/third_party/blink/renderer/core/dom/document_parser_timing.cc
index ef292f8c1c1..e3cbf2e74bc 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_parser_timing.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document_parser_timing.cc
@@ -66,7 +66,7 @@ void DocumentParserTiming::RecordParserBlockedOnScriptExecutionDuration(
NotifyDocumentParserTimingChanged();
}
-void DocumentParserTiming::Trace(Visitor* visitor) {
+void DocumentParserTiming::Trace(Visitor* visitor) const {
Supplement<Document>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/document_parser_timing.h b/chromium/third_party/blink/renderer/core/dom/document_parser_timing.h
index 96484aeb313..97e73c3817e 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_parser_timing.h
+++ b/chromium/third_party/blink/renderer/core/dom/document_parser_timing.h
@@ -97,7 +97,7 @@ class DocumentParserTiming final
return parser_blocked_on_script_execution_from_document_write_duration_;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void NotifyDocumentParserTimingChanged();
diff --git a/chromium/third_party/blink/renderer/core/dom/document_test.cc b/chromium/third_party/blink/renderer/core/dom/document_test.cc
index e908501969a..2fc8912f931 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document_test.cc
@@ -56,8 +56,8 @@
#include "third_party/blink/renderer/core/dom/range.h"
#include "third_party/blink/renderer/core/dom/synchronous_mutation_observer.h"
#include "third_party/blink/renderer/core/dom/text.h"
-#include "third_party/blink/renderer/core/execution_context/agent.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/viewport_data.h"
@@ -73,7 +73,6 @@
#include "third_party/blink/renderer/core/testing/scoped_mock_overlay_scrollbars.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/scheduler/public/event_loop.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
@@ -127,7 +126,7 @@ class TestSynchronousMutationObserver
node_to_be_removed_(node_with_index.GetNode()),
offset_(offset) {}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(node_);
visitor->Trace(node_to_be_removed_);
}
@@ -149,7 +148,7 @@ class TestSynchronousMutationObserver
old_length_(old_length),
new_length_(new_length) {}
- void Trace(Visitor* visitor) { visitor->Trace(node_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(node_); }
};
explicit TestSynchronousMutationObserver(Document&);
@@ -189,7 +188,7 @@ class TestSynchronousMutationObserver
return updated_character_data_records_;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Implement |SynchronousMutationObserver| member functions.
@@ -268,7 +267,7 @@ void TestSynchronousMutationObserver::NodeWillBeRemoved(Node& node) {
removed_nodes_.push_back(&node);
}
-void TestSynchronousMutationObserver::Trace(Visitor* visitor) {
+void TestSynchronousMutationObserver::Trace(Visitor* visitor) const {
visitor->Trace(children_changed_nodes_);
visitor->Trace(merge_text_nodes_records_);
visitor->Trace(move_tree_to_new_document_nodes_);
@@ -311,7 +310,7 @@ class MockDocumentValidationMessageClient
void DidChangeFocusTo(const Element*) override {}
void WillBeDestroyed() override {}
- // virtual void Trace(Visitor* visitor) {
+ // virtual void Trace(Visitor* visitor) const {
// ValidationMessageClient::trace(visitor); }
};
@@ -507,77 +506,6 @@ TEST_F(DocumentTest, LinkManifest) {
EXPECT_EQ(link, GetDocument().LinkManifest());
}
-TEST_F(DocumentTest, referrerPolicyParsing) {
- EXPECT_EQ(network::mojom::ReferrerPolicy::kDefault,
- GetDocument().GetReferrerPolicy());
-
- struct TestCase {
- const char* policy;
- network::mojom::ReferrerPolicy expected;
- bool is_legacy;
- } tests[] = {
- {"", network::mojom::ReferrerPolicy::kDefault, false},
- // Test that invalid policy values are ignored.
- {"not-a-real-policy", network::mojom::ReferrerPolicy::kDefault, false},
- {"not-a-real-policy,also-not-a-real-policy",
- network::mojom::ReferrerPolicy::kDefault, false},
- {"not-a-real-policy,unsafe-url", network::mojom::ReferrerPolicy::kAlways,
- false},
- {"unsafe-url,not-a-real-policy", network::mojom::ReferrerPolicy::kAlways,
- false},
- // Test parsing each of the policy values.
- {"always", network::mojom::ReferrerPolicy::kAlways, true},
- {"default", network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade,
- true},
- {"never", network::mojom::ReferrerPolicy::kNever, true},
- {"no-referrer", network::mojom::ReferrerPolicy::kNever, false},
- {"default", network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade,
- true},
- {"no-referrer-when-downgrade",
- network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, false},
- {"origin", network::mojom::ReferrerPolicy::kOrigin, false},
- {"origin-when-crossorigin",
- network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, true},
- {"origin-when-cross-origin",
- network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, false},
- {"same-origin", network::mojom::ReferrerPolicy::kSameOrigin, false},
- {"strict-origin", network::mojom::ReferrerPolicy::kStrictOrigin, false},
- {"strict-origin-when-cross-origin",
- network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin, false},
- {"unsafe-url", network::mojom::ReferrerPolicy::kAlways},
- };
-
- for (auto test : tests) {
- GetDocument().SetReferrerPolicy(network::mojom::ReferrerPolicy::kDefault);
- if (test.is_legacy) {
- // Legacy keyword support must be explicitly enabled for the policy to
- // parse successfully.
- GetDocument().GetExecutionContext()->ParseAndSetReferrerPolicy(
- test.policy);
- EXPECT_EQ(network::mojom::ReferrerPolicy::kDefault,
- GetDocument().GetReferrerPolicy());
- GetDocument().GetExecutionContext()->ParseAndSetReferrerPolicy(
- test.policy, true);
- } else {
- GetDocument().GetExecutionContext()->ParseAndSetReferrerPolicy(
- test.policy);
- }
- EXPECT_EQ(test.expected, GetDocument().GetReferrerPolicy()) << test.policy;
- }
-}
-
-TEST_F(DocumentTest, OutgoingReferrer) {
- NavigateTo(KURL("https://www.example.com/hoge#fuga?piyo"));
- EXPECT_EQ("https://www.example.com/hoge", GetDocument().OutgoingReferrer());
-}
-
-TEST_F(DocumentTest, OutgoingReferrerWithUniqueOrigin) {
- NavigateTo(KURL("https://www.example.com/hoge#fuga?piyo"),
- {{http_names::kContentSecurityPolicy, "sandbox allow-scripts"}});
- EXPECT_TRUE(GetDocument().GetSecurityOrigin()->IsOpaque());
- EXPECT_EQ(String(), GetDocument().OutgoingReferrer());
-}
-
TEST_F(DocumentTest, StyleVersion) {
SetHtmlInnerHTML(R"HTML(
<style>
@@ -723,7 +651,7 @@ TEST_F(DocumentTest, SynchronousMutationNotifierMoveTreeToNewDocument) {
move_sample->appendChild(GetDocument().createTextNode("b456"));
GetDocument().body()->AppendChild(move_sample);
- Document& another_document = *MakeGarbageCollected<Document>();
+ Document& another_document = *Document::CreateForTest();
another_document.AppendChild(move_sample);
EXPECT_EQ(1u, observer.MoveTreeToNewDocumentNodes().size());
@@ -816,18 +744,6 @@ TEST_F(DocumentTest, SynchronousMutationNotifierUpdateCharacterData) {
EXPECT_EQ(3u, observer.UpdatedCharacterDataRecords()[3]->new_length_);
}
-TEST_F(DocumentTest, AttachExecutionContext) {
- EXPECT_TRUE(
- GetDocument().GetAgent()->event_loop()->IsSchedulerAttachedForTest(
- GetDocument().GetScheduler()));
- Document* doc = GetDocument().implementation().createHTMLDocument("foo");
- EXPECT_EQ(GetDocument().GetAgent(), doc->GetAgent());
- GetDocument().Shutdown();
- EXPECT_FALSE(doc->GetAgent()->event_loop()->IsSchedulerAttachedForTest(
- doc->GetScheduler()));
- doc->Shutdown();
-}
-
// This tests that meta-theme-color can be found correctly
TEST_F(DocumentTest, ThemeColor) {
{
@@ -965,100 +881,6 @@ TEST_F(DocumentTest, ViewportPropagationNoRecalc) {
EXPECT_EQ(1, new_element_count - old_element_count);
}
-// Test fixture parameterized on whether the "IsolatedWorldCSP" feature is
-// enabled.
-class IsolatedWorldCSPTest : public DocumentTest,
- public testing::WithParamInterface<bool>,
- private ScopedIsolatedWorldCSPForTest {
- public:
- IsolatedWorldCSPTest() : ScopedIsolatedWorldCSPForTest(GetParam()) {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(IsolatedWorldCSPTest);
-};
-
-// Tests ExecutionContext::GetContentSecurityPolicyForWorld().
-TEST_P(IsolatedWorldCSPTest, CSPForWorld) {
- using ::testing::ElementsAre;
-
- // Set a CSP for the main world.
- const char* kMainWorldCSP = "connect-src https://google.com;";
- GetDocument().GetContentSecurityPolicy()->DidReceiveHeader(
- kMainWorldCSP, ContentSecurityPolicyType::kEnforce,
- ContentSecurityPolicySource::kHTTP);
-
- LocalFrame* frame = GetDocument().GetFrame();
- ScriptState* main_world_script_state = ToScriptStateForMainWorld(frame);
- v8::Isolate* isolate = main_world_script_state->GetIsolate();
-
- constexpr int kIsolatedWorldWithoutCSPId = 1;
- scoped_refptr<DOMWrapperWorld> world_without_csp =
- DOMWrapperWorld::EnsureIsolatedWorld(isolate, kIsolatedWorldWithoutCSPId);
- ASSERT_TRUE(world_without_csp->IsIsolatedWorld());
- ScriptState* isolated_world_without_csp_script_state =
- ToScriptState(frame, *world_without_csp);
-
- const char* kIsolatedWorldCSP = "script-src 'none';";
- constexpr int kIsolatedWorldWithCSPId = 2;
- scoped_refptr<DOMWrapperWorld> world_with_csp =
- DOMWrapperWorld::EnsureIsolatedWorld(isolate, kIsolatedWorldWithCSPId);
- ASSERT_TRUE(world_with_csp->IsIsolatedWorld());
- ScriptState* isolated_world_with_csp_script_state =
- ToScriptState(frame, *world_with_csp);
- IsolatedWorldCSP::Get().SetContentSecurityPolicy(
- kIsolatedWorldWithCSPId, kIsolatedWorldCSP,
- SecurityOrigin::Create(KURL("chrome-extension://123")));
-
- // Returns the csp headers being used for the current world.
- auto get_csp_headers = [this]() {
- return GetDocument().GetContentSecurityPolicyForWorld()->Headers();
- };
-
- {
- SCOPED_TRACE("In main world.");
- ScriptState::Scope scope(main_world_script_state);
- EXPECT_THAT(get_csp_headers(),
- ElementsAre(CSPHeaderAndType(
- {kMainWorldCSP, ContentSecurityPolicyType::kEnforce})));
- }
-
- {
- SCOPED_TRACE("In isolated world without csp.");
- ScriptState::Scope scope(isolated_world_without_csp_script_state);
-
- // If we are in an isolated world with no CSP defined, we use the main world
- // CSP.
- EXPECT_THAT(get_csp_headers(),
- ElementsAre(CSPHeaderAndType(
- {kMainWorldCSP, ContentSecurityPolicyType::kEnforce})));
- }
-
- {
- bool is_isolated_world_csp_enabled = GetParam();
- SCOPED_TRACE(base::StringPrintf(
- "In isolated world with csp and 'IsolatedWorldCSP' %s",
- is_isolated_world_csp_enabled ? "enabled" : "disabled"));
- ScriptState::Scope scope(isolated_world_with_csp_script_state);
-
- if (!is_isolated_world_csp_enabled) {
- // With 'IsolatedWorldCSP' feature disabled, we should just bypass the
- // main world CSP by using an empty CSP.
- EXPECT_TRUE(get_csp_headers().IsEmpty());
- } else {
- // With 'IsolatedWorldCSP' feature enabled, we use the isolated world's
- // CSP if it specified one.
- EXPECT_THAT(
- get_csp_headers(),
- ElementsAre(CSPHeaderAndType(
- {kIsolatedWorldCSP, ContentSecurityPolicyType::kEnforce})));
- }
- }
-}
-
-INSTANTIATE_TEST_SUITE_P(All,
- IsolatedWorldCSPTest,
- testing::Values(true, false));
-
TEST_F(DocumentTest, CanExecuteScriptsWithSandboxAndIsolatedWorld) {
NavigateTo(KURL("https://www.example.com/"),
{{http_names::kContentSecurityPolicy, "sandbox"}});
@@ -1093,19 +915,19 @@ TEST_F(DocumentTest, CanExecuteScriptsWithSandboxAndIsolatedWorld) {
// Since the page is sandboxed, main world script execution shouldn't be
// allowed.
ScriptState::Scope scope(main_world_script_state);
- EXPECT_FALSE(GetDocument().CanExecuteScripts(kAboutToExecuteScript));
+ EXPECT_FALSE(frame->DomWindow()->CanExecuteScripts(kAboutToExecuteScript));
}
{
// Isolated worlds without a dedicated CSP should also not be allowed to
// run scripts.
ScriptState::Scope scope(isolated_world_without_csp_script_state);
- EXPECT_FALSE(GetDocument().CanExecuteScripts(kAboutToExecuteScript));
+ EXPECT_FALSE(frame->DomWindow()->CanExecuteScripts(kAboutToExecuteScript));
}
{
// An isolated world with a CSP should bypass the main world CSP, and be
// able to run scripts.
ScriptState::Scope scope(isolated_world_with_csp_script_state);
- EXPECT_TRUE(GetDocument().CanExecuteScripts(kAboutToExecuteScript));
+ EXPECT_TRUE(frame->DomWindow()->CanExecuteScripts(kAboutToExecuteScript));
}
}
diff --git a/chromium/third_party/blink/renderer/core/dom/document_timing.cc b/chromium/third_party/blink/renderer/core/dom/document_timing.cc
index cb5d4b364e4..8628a6170bb 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_timing.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document_timing.cc
@@ -17,7 +17,7 @@ DocumentTiming::DocumentTiming(Document& document) : document_(document) {
MarkDomLoading();
}
-void DocumentTiming::Trace(Visitor* visitor) {
+void DocumentTiming::Trace(Visitor* visitor) const {
visitor->Trace(document_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/document_timing.h b/chromium/third_party/blink/renderer/core/dom/document_timing.h
index b3401679130..a3396fb2411 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_timing.h
+++ b/chromium/third_party/blink/renderer/core/dom/document_timing.h
@@ -56,7 +56,7 @@ class DocumentTiming final {
}
base::TimeTicks DomComplete() const { return dom_complete_; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
LocalFrame* GetFrame() const;
diff --git a/chromium/third_party/blink/renderer/core/dom/dom_implementation.cc b/chromium/third_party/blink/renderer/core/dom/dom_implementation.cc
index 141dc77b6bf..488f4b0d6ba 100644
--- a/chromium/third_party/blink/renderer/core/dom/dom_implementation.cc
+++ b/chromium/third_party/blink/renderer/core/dom/dom_implementation.cc
@@ -32,28 +32,18 @@
#include "third_party/blink/renderer/core/dom/document_init.h"
#include "third_party/blink/renderer/core/dom/document_type.h"
#include "third_party/blink/renderer/core/dom/element.h"
-#include "third_party/blink/renderer/core/dom/sink_document.h"
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/dom/xml_document.h"
-#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h"
#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/html_head_element.h"
#include "third_party/blink/renderer/core/html/html_title_element.h"
-#include "third_party/blink/renderer/core/html/html_view_source_document.h"
-#include "third_party/blink/renderer/core/html/image_document.h"
-#include "third_party/blink/renderer/core/html/media/media_document.h"
#include "third_party/blink/renderer/core/html/plugin_document.h"
#include "third_party/blink/renderer/core/html/text_document.h"
#include "third_party/blink/renderer/core/html_names.h"
-#include "third_party/blink/renderer/core/loader/frame_loader.h"
#include "third_party/blink/renderer/core/svg_names.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
-#include "third_party/blink/renderer/platform/graphics/image.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
-#include "third_party/blink/renderer/platform/network/mime/content_type.h"
-#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
@@ -71,6 +61,8 @@ DocumentType* DOMImplementation::createDocumentType(
if (!Document::ParseQualifiedName(qualified_name, prefix, local_name,
exception_state))
return nullptr;
+ if (!document_->GetExecutionContext())
+ return nullptr;
return MakeGarbageCollected<DocumentType>(document_, qualified_name,
public_id, system_id);
@@ -81,10 +73,14 @@ XMLDocument* DOMImplementation::createDocument(
const AtomicString& qualified_name,
DocumentType* doctype,
ExceptionState& exception_state) {
+ if (!document_->GetExecutionContext())
+ return nullptr;
+
XMLDocument* doc = nullptr;
- DocumentInit init = DocumentInit::Create()
- .WithContextDocument(document_->ContextDocument())
- .WithOwnerDocument(document_->ContextDocument());
+ DocumentInit init =
+ DocumentInit::Create()
+ .WithExecutionContext(document_->GetExecutionContext())
+ .WithOwnerDocument(document_);
if (namespace_uri == svg_names::kNamespaceURI) {
doc = XMLDocument::CreateSVG(init);
} else if (namespace_uri == html_names::xhtmlNamespaceURI) {
@@ -112,84 +108,14 @@ XMLDocument* DOMImplementation::createDocument(
return doc;
}
-bool DOMImplementation::IsXMLMIMEType(const String& mime_type) {
- if (EqualIgnoringASCIICase(mime_type, "text/xml") ||
- EqualIgnoringASCIICase(mime_type, "application/xml") ||
- EqualIgnoringASCIICase(mime_type, "text/xsl"))
- return true;
-
- // Per RFCs 3023 and 2045, an XML MIME type is of the form:
- // ^[0-9a-zA-Z_\\-+~!$\\^{}|.%'`#&*]+/[0-9a-zA-Z_\\-+~!$\\^{}|.%'`#&*]+\+xml$
-
- int length = mime_type.length();
- if (length < 7)
- return false;
-
- if (mime_type[0] == '/' || mime_type[length - 5] == '/' ||
- !mime_type.EndsWithIgnoringASCIICase("+xml"))
- return false;
-
- bool has_slash = false;
- for (int i = 0; i < length - 4; ++i) {
- UChar ch = mime_type[i];
- if (ch >= '0' && ch <= '9')
- continue;
- if (ch >= 'a' && ch <= 'z')
- continue;
- if (ch >= 'A' && ch <= 'Z')
- continue;
- switch (ch) {
- case '_':
- case '-':
- case '+':
- case '~':
- case '!':
- case '$':
- case '^':
- case '{':
- case '}':
- case '|':
- case '.':
- case '%':
- case '\'':
- case '`':
- case '#':
- case '&':
- case '*':
- continue;
- case '/':
- if (has_slash)
- return false;
- has_slash = true;
- continue;
- default:
- return false;
- }
- }
-
- return true;
-}
-
-static bool IsTextPlainType(const String& mime_type) {
- return mime_type.StartsWithIgnoringASCIICase("text/") &&
- !(EqualIgnoringASCIICase(mime_type, "text/html") ||
- EqualIgnoringASCIICase(mime_type, "text/xml") ||
- EqualIgnoringASCIICase(mime_type, "text/xsl"));
-}
-
-bool DOMImplementation::IsTextMIMEType(const String& mime_type) {
- return MIMETypeRegistry::IsSupportedJavaScriptMIMEType(mime_type) ||
- MIMETypeRegistry::IsJSONMimeType(mime_type) ||
- IsTextPlainType(mime_type);
-}
-
Document* DOMImplementation::createHTMLDocument(const String& title) {
+ if (!document_->GetExecutionContext())
+ return nullptr;
DocumentInit init =
DocumentInit::Create()
- .WithContextDocument(document_->ContextDocument())
- .WithOwnerDocument(document_->ContextDocument())
- .WithRegistrationContext(document_->RegistrationContext())
- .WithContentSecurityPolicyFromContextDoc();
+ .WithExecutionContext(document_->GetExecutionContext())
+ .WithOwnerDocument(document_)
+ .WithRegistrationContext(document_->RegistrationContext());
auto* d = MakeGarbageCollected<HTMLDocument>(init);
d->open();
d->write("<!doctype html><html><head></head><body></body></html>");
@@ -204,46 +130,7 @@ Document* DOMImplementation::createHTMLDocument(const String& title) {
return d;
}
-Document* DOMImplementation::createDocument(const DocumentInit& init) {
- switch (init.GetType()) {
- case DocumentInit::Type::kHTML:
- return MakeGarbageCollected<HTMLDocument>(init);
- case DocumentInit::Type::kXHTML:
- return XMLDocument::CreateXHTML(init);
- case DocumentInit::Type::kImage:
- return MakeGarbageCollected<ImageDocument>(init);
- case DocumentInit::Type::kPlugin: {
- Document* document = MakeGarbageCollected<PluginDocument>(init);
- // TODO(crbug.com/1029822): Final sandbox flags are calculated during
- // document construction, so we have to construct a PluginDocument then
- // replace it with a SinkDocument when plugins are sanboxed. If we move
- // final sandbox flag calcuation earlier, we could construct the
- // SinkDocument directly.
- if (document->IsSandboxed(
- network::mojom::blink::WebSandboxFlags::kPlugins))
- document = MakeGarbageCollected<SinkDocument>(init);
- return document;
- }
- case DocumentInit::Type::kMedia:
- return MakeGarbageCollected<MediaDocument>(init);
- case DocumentInit::Type::kSVG:
- return XMLDocument::CreateSVG(init);
- case DocumentInit::Type::kXML:
- return MakeGarbageCollected<XMLDocument>(init);
- case DocumentInit::Type::kViewSource:
- return MakeGarbageCollected<HTMLViewSourceDocument>(init);
- case DocumentInit::Type::kText:
- return MakeGarbageCollected<TextDocument>(init);
- case DocumentInit::Type::kUnspecified:
- FALLTHROUGH;
- default:
- break;
- }
- NOTREACHED();
- return nullptr;
-}
-
-void DOMImplementation::Trace(Visitor* visitor) {
+void DOMImplementation::Trace(Visitor* visitor) const {
visitor->Trace(document_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/dom_implementation.h b/chromium/third_party/blink/renderer/core/dom/dom_implementation.h
index 72599ffa7ed..28134f38d18 100644
--- a/chromium/third_party/blink/renderer/core/dom/dom_implementation.h
+++ b/chromium/third_party/blink/renderer/core/dom/dom_implementation.h
@@ -30,7 +30,6 @@
namespace blink {
class Document;
-class DocumentInit;
class DocumentType;
class ExceptionState;
class XMLDocument;
@@ -55,13 +54,7 @@ class CORE_EXPORT DOMImplementation final : public ScriptWrappable {
// From the HTMLDOMImplementation interface
Document* createHTMLDocument(const String& title = String());
- // Other methods (not part of DOM)
- static Document* createDocument(const DocumentInit&);
-
- static bool IsXMLMIMEType(const String&);
- static bool IsTextMIMEType(const String&);
-
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Document> document_;
diff --git a/chromium/third_party/blink/renderer/core/dom/dom_implementation_test.cc b/chromium/third_party/blink/renderer/core/dom/dom_implementation_test.cc
deleted file mode 100644
index dae71bf36d0..00000000000
--- a/chromium/third_party/blink/renderer/core/dom/dom_implementation_test.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2013, Opera Software ASA. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Opera Software ASA nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/core/dom/dom_implementation.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-TEST(DOMImplementationTest, TextMIMEType) {
- EXPECT_TRUE(DOMImplementation::IsTextMIMEType("text/plain"));
- EXPECT_TRUE(DOMImplementation::IsTextMIMEType("text/javascript"));
- EXPECT_TRUE(DOMImplementation::IsTextMIMEType("TEXT/JavaScript"));
- EXPECT_TRUE(DOMImplementation::IsTextMIMEType("application/json"));
- EXPECT_TRUE(DOMImplementation::IsTextMIMEType("application/jSON"));
- EXPECT_TRUE(DOMImplementation::IsTextMIMEType("application/json;foo=2"));
- EXPECT_FALSE(DOMImplementation::IsTextMIMEType("application/json "));
- EXPECT_TRUE(DOMImplementation::IsTextMIMEType("application/+json"));
- EXPECT_TRUE(DOMImplementation::IsTextMIMEType(
- "application/x-javascript-like+json;a=2;c=4"));
- EXPECT_TRUE(DOMImplementation::IsTextMIMEType("application/javascript"));
- EXPECT_TRUE(DOMImplementation::IsTextMIMEType("Application/Javascript"));
- EXPECT_TRUE(
- DOMImplementation::IsTextMIMEType("application/x-custom+json;b=3"));
- EXPECT_TRUE(DOMImplementation::IsTextMIMEType("application/x-custom+json"));
- // Outside of RFC-2045 grammar, but robustly accept/allow.
- EXPECT_TRUE(DOMImplementation::IsTextMIMEType("application/x-what+json;"));
- EXPECT_TRUE(DOMImplementation::IsTextMIMEType("application/json;"));
- EXPECT_FALSE(DOMImplementation::IsTextMIMEType("application/json "));
- EXPECT_FALSE(
- DOMImplementation::IsTextMIMEType("application/x-custom;a=a+json"));
- EXPECT_FALSE(
- DOMImplementation::IsTextMIMEType("application/x-custom;a=a+json ;"));
- EXPECT_FALSE(
- DOMImplementation::IsTextMIMEType("application/x-custom+jsonsoup"));
- EXPECT_FALSE(
- DOMImplementation::IsTextMIMEType("application/x-custom+jsonsoup "));
- EXPECT_FALSE(DOMImplementation::IsTextMIMEType("text/html"));
- EXPECT_FALSE(DOMImplementation::IsTextMIMEType("text/xml"));
- EXPECT_FALSE(DOMImplementation::IsTextMIMEType("text/xsl"));
-}
-
-TEST(DOMImplementationTest, TextXMLType) {
- EXPECT_TRUE(DOMImplementation::IsXMLMIMEType("text/xml"));
- EXPECT_TRUE(DOMImplementation::IsXMLMIMEType("Text/xml"));
- EXPECT_TRUE(DOMImplementation::IsXMLMIMEType("tEXt/XML"));
- EXPECT_TRUE(DOMImplementation::IsXMLMIMEType("application/xml"));
- EXPECT_TRUE(DOMImplementation::IsXMLMIMEType("application/XML"));
- EXPECT_TRUE(DOMImplementation::IsXMLMIMEType("application/x-tra+xML"));
- EXPECT_TRUE(DOMImplementation::IsXMLMIMEType("application/xslt+xml"));
- EXPECT_TRUE(DOMImplementation::IsXMLMIMEType("application/rdf+Xml"));
- EXPECT_TRUE(DOMImplementation::IsXMLMIMEType("image/svg+xml"));
- EXPECT_TRUE(DOMImplementation::IsXMLMIMEType("text/xsl"));
- EXPECT_TRUE(DOMImplementation::IsXMLMIMEType("text/XSL"));
- EXPECT_TRUE(DOMImplementation::IsXMLMIMEType("application/x+xml"));
-
- EXPECT_FALSE(
- DOMImplementation::IsXMLMIMEType("application/x-custom;a=a+xml"));
- EXPECT_FALSE(
- DOMImplementation::IsXMLMIMEType("application/x-custom;a=a+xml ;"));
- EXPECT_FALSE(DOMImplementation::IsXMLMIMEType("application/x-custom+xml2"));
- EXPECT_FALSE(DOMImplementation::IsXMLMIMEType("application/x-custom+xml2 "));
- EXPECT_FALSE(DOMImplementation::IsXMLMIMEType("application/x-custom+exml"));
- EXPECT_FALSE(DOMImplementation::IsXMLMIMEType("text/html"));
- EXPECT_FALSE(DOMImplementation::IsXMLMIMEType("application/xml;"));
- EXPECT_FALSE(DOMImplementation::IsXMLMIMEType("application/xml "));
- EXPECT_FALSE(DOMImplementation::IsXMLMIMEType("application/x-what+xml;"));
- EXPECT_FALSE(DOMImplementation::IsXMLMIMEType("application/x-tra+xML;a=2"));
- EXPECT_FALSE(DOMImplementation::IsXMLMIMEType("application/+xML"));
- EXPECT_FALSE(DOMImplementation::IsXMLMIMEType("application/+xml"));
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/dom_token_list.cc b/chromium/third_party/blink/renderer/core/dom/dom_token_list.cc
index 14897c38a18..032b3ef1b49 100644
--- a/chromium/third_party/blink/renderer/core/dom/dom_token_list.cc
+++ b/chromium/third_party/blink/renderer/core/dom/dom_token_list.cc
@@ -78,7 +78,7 @@ bool CheckTokensSyntax(const Vector<String>& tokens,
} // anonymous namespace
-void DOMTokenList::Trace(Visitor* visitor) {
+void DOMTokenList::Trace(Visitor* visitor) const {
visitor->Trace(element_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/dom_token_list.h b/chromium/third_party/blink/renderer/core/dom/dom_token_list.h
index 713f4d1b5c3..eb73388ce2b 100644
--- a/chromium/third_party/blink/renderer/core/dom/dom_token_list.h
+++ b/chromium/third_party/blink/renderer/core/dom/dom_token_list.h
@@ -46,7 +46,7 @@ class CORE_EXPORT DOMTokenList : public ScriptWrappable {
DOMTokenList(Element& element, const QualifiedName& attr)
: element_(element), attribute_name_(attr) {}
~DOMTokenList() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
unsigned length() const { return token_set_.size(); }
const AtomicString item(unsigned index) const;
diff --git a/chromium/third_party/blink/renderer/core/dom/element.cc b/chromium/third_party/blink/renderer/core/dom/element.cc
index bb0519270fa..0e058c6830d 100644
--- a/chromium/third_party/blink/renderer/core/dom/element.cc
+++ b/chromium/third_party/blink/renderer/core/dom/element.cc
@@ -66,7 +66,6 @@
#include "third_party/blink/renderer/core/display_lock/display_lock_context.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_document_state.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
-#include "third_party/blink/renderer/core/display_lock/render_subtree_activation_event.h"
#include "third_party/blink/renderer/core/dom/attr.h"
#include "third_party/blink/renderer/core/dom/dataset_dom_string_map.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -289,6 +288,10 @@ bool DefinitelyNewFormattingContext(const Node& node,
auto display = style.Display();
if (display == EDisplay::kInline || display == EDisplay::kContents)
return false;
+ // ::marker may establish a formatting context but still have some dependency
+ // on the originating list item, so return false.
+ if (node.IsMarkerPseudoElement())
+ return false;
// The only block-container display types that potentially don't establish a
// new formatting context, are 'block' and 'list-item'.
if (display != EDisplay::kBlock && display != EDisplay::kListItem) {
@@ -518,8 +521,11 @@ void EnqueueAutofocus(Element& element) {
doc.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
- "Blocked autofocusing on a form control because the form's frame is "
- "sandboxed and the 'allow-scripts' permission is not set."));
+ String::Format(
+ "Blocked autofocusing on a <%s> element because the element's "
+ "frame "
+ "is sandboxed and the 'allow-scripts' permission is not set.",
+ element.TagQName().ToString().Ascii().c_str())));
return;
}
@@ -532,7 +538,9 @@ void EnqueueAutofocus(Element& element) {
doc.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
- "Blocked autofocusing on a form control in a cross-origin subframe."));
+ String::Format("Blocked autofocusing on a <%s> element in a "
+ "cross-origin subframe.",
+ element.TagQName().ToString().Ascii().c_str())));
return;
}
@@ -637,7 +645,8 @@ Node* Element::Clone(Document& factory, CloneChildrenFlag flag) const {
// 7. If node is a shadow host and the clone shadows flag is set, run these
// steps:
if (flag == CloneChildrenFlag::kCloneWithShadows) {
- DCHECK(RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled());
+ DCHECK(RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled(
+ GetExecutionContext()));
auto* shadow_root = GetShadowRoot();
if (shadow_root && (shadow_root->GetType() == ShadowRootType::kOpen ||
shadow_root->GetType() == ShadowRootType::kClosed)) {
@@ -2947,9 +2956,9 @@ scoped_refptr<ComputedStyle> Element::StyleForLayoutObject() {
element_animations->UpdateAnimationFlags(*style);
}
- style->UpdateIsStackingContext(this == GetDocument().documentElement(),
- IsInTopLayer(),
- IsA<SVGForeignObjectElement>(*this));
+ style->UpdateIsStackingContextWithoutContainment(
+ this == GetDocument().documentElement(), IsInTopLayer(),
+ IsA<SVGForeignObjectElement>(*this));
return style;
}
@@ -3531,7 +3540,7 @@ ElementInternals& Element::EnsureElementInternals() {
}
ShadowRoot* Element::createShadowRoot(ExceptionState& exception_state) {
- DCHECK(RuntimeEnabledFeatures::ShadowDOMV0Enabled(&GetDocument()));
+ DCHECK(RuntimeEnabledFeatures::ShadowDOMV0Enabled(GetExecutionContext()));
if (ShadowRoot* root = GetShadowRoot()) {
if (root->IsUserAgent()) {
exception_state.ThrowDOMException(
@@ -3566,7 +3575,7 @@ ShadowRoot* Element::createShadowRoot(ExceptionState& exception_state) {
}
ShadowRoot& Element::CreateShadowRootInternal() {
- DCHECK(RuntimeEnabledFeatures::ShadowDOMV0Enabled(&GetDocument()));
+ DCHECK(RuntimeEnabledFeatures::ShadowDOMV0Enabled(GetExecutionContext()));
DCHECK(!ClosedShadowRoot());
DCHECK(AreAuthorShadowsAllowed());
DCHECK(!AlwaysCreateUserAgentShadowRoot());
@@ -3669,14 +3678,18 @@ void Element::AttachDeclarativeShadowRoot(HTMLTemplateElement* template_element,
SlotAssignmentMode slot_assignment) {
DCHECK(template_element);
DCHECK(type == ShadowRootType::kOpen || type == ShadowRootType::kClosed);
+ UseCounter::Count(GetDocument(), WebFeature::kDeclarativeShadowRoot);
// 12. Run attach a shadow root with shadow host equal to declarative shadow
// host element, mode equal to declarative shadow mode, and delegates focus
// equal to declarative shadow delegates focus. If an exception was thrown by
- // attach a shadow root, catch it, and report the exception.
+ // attach a shadow root, catch it, and ignore the exception.
if (const char* error_message = ErrorMessageForAttachShadow()) {
- // TODO(1067488): Fire this exception at Window.
- LOG(ERROR) << error_message;
+ template_element->SetDeclarativeShadowRootType(
+ DeclarativeShadowRootType::kNone);
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kOther,
+ mojom::blink::ConsoleMessageLevel::kError, error_message));
return;
}
ShadowRoot& shadow_root =
@@ -4334,11 +4347,15 @@ bool Element::IsFocusableStyleAfterUpdate() const {
// creation. We need to ensure to update style and layout tree to have
// up-to-date information.
//
+ // Note also that there may be situations where focus / keyboard navigation
+ // causes us to have dirty style, so we update StyleAndLayoutTreeForNode here.
+ // If the style and layout tree are clean, then this should be a quick
+ // operation. See crbug.com/1079385 for details.
+ //
// Note that this isn't a part of `IsFocusableStyle()` because there are
// callers of that function which cannot do a layout tree update (e.g.
// accessibility).
- if (RuntimeEnabledFeatures::CSSContentVisibilityEnabled())
- GetDocument().UpdateStyleAndLayoutTreeForNode(this);
+ GetDocument().UpdateStyleAndLayoutTreeForNode(this);
return IsFocusableStyle();
}
@@ -4628,17 +4645,31 @@ void Element::setInnerHTML(const String& html,
if (DocumentFragment* fragment = CreateFragmentForInnerOuterHTML(
html, this, kAllowScriptingContent, "innerHTML", exception_state)) {
ContainerNode* container = this;
- if (auto* template_element = DynamicTo<HTMLTemplateElement>(*this))
- container = template_element->content();
+ if (auto* template_element = DynamicTo<HTMLTemplateElement>(*this)) {
+ // Allow replacing innerHTML on declarative shadow templates, prior to
+ // their closing tag being parsed.
+ container = template_element->IsDeclarativeShadowRoot()
+ ? template_element->DeclarativeShadowContent()
+ : template_element->content();
+ }
ReplaceChildrenWithFragment(container, fragment, exception_state);
}
}
}
String Element::getInnerHTML(const GetInnerHTMLOptions* options) const {
+ DCHECK(RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled(
+ GetExecutionContext()));
+ ClosedRootsSet include_closed_roots;
+ if (options->hasClosedRoots()) {
+ for (auto& shadow_root : options->closedRoots()) {
+ include_closed_roots.insert(shadow_root);
+ }
+ }
return CreateMarkup(
this, kChildrenOnly, kDoNotResolveURLs,
- options->includeShadowRoots() ? kIncludeShadowRoots : kNoShadowRoots);
+ options->includeShadowRoots() ? kIncludeShadowRoots : kNoShadowRoots,
+ include_closed_roots);
}
void Element::setOuterHTML(const String& html,
@@ -6127,10 +6158,13 @@ void Element::StyleAttributeChanged(
} else if (modification_reason == AttributeModificationReason::kByCloning ||
(ContainingShadowRoot() &&
ContainingShadowRoot()->IsUserAgent()) ||
- GetDocument().GetContentSecurityPolicyForWorld()->AllowInline(
- ContentSecurityPolicy::InlineType::kStyleAttribute, this,
- new_style_string, String() /* nonce */, GetDocument().Url(),
- start_line_number)) {
+ (GetExecutionContext() &&
+ GetExecutionContext()
+ ->GetContentSecurityPolicyForWorld()
+ ->AllowInline(
+ ContentSecurityPolicy::InlineType::kStyleAttribute, this,
+ new_style_string, String() /* nonce */,
+ GetDocument().Url(), start_line_number))) {
SetInlineStyleFromString(new_style_string);
}
@@ -6353,7 +6387,7 @@ void Element::LogUpdateAttributeIfIsolatedWorldAndInDocument(
activity_logger->LogEvent("blinkSetAttribute", argv.size(), argv.data());
}
-void Element::Trace(Visitor* visitor) {
+void Element::Trace(Visitor* visitor) const {
visitor->Trace(element_data_);
ContainerNode::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/element.h b/chromium/third_party/blink/renderer/core/dom/element.h
index 7e952657c13..f9401e4024e 100644
--- a/chromium/third_party/blink/renderer/core/dom/element.h
+++ b/chromium/third_party/blink/renderer/core/dom/element.h
@@ -784,6 +784,7 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
virtual bool IsClearButtonElement() const { return false; }
virtual bool IsScriptElement() const { return false; }
virtual bool IsVTTCueBackgroundBox() const { return false; }
+ virtual bool IsSliderThumbElement() const { return false; }
// Elements that may have an insertion mode other than "in body" should
// override this and return true.
@@ -897,7 +898,7 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
const char element[],
const AttributeModificationParams&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
SpellcheckAttributeState GetSpellcheckAttributeState() const;
diff --git a/chromium/third_party/blink/renderer/core/dom/element_data.cc b/chromium/third_party/blink/renderer/core/dom/element_data.cc
index f9cca268d29..97d429dbe4a 100644
--- a/chromium/third_party/blink/renderer/core/dom/element_data.cc
+++ b/chromium/third_party/blink/renderer/core/dom/element_data.cc
@@ -110,11 +110,11 @@ bool ElementData::IsEquivalent(const ElementData* other) const {
return true;
}
-void ElementData::Trace(Visitor* visitor) {
+void ElementData::Trace(Visitor* visitor) const {
if (bit_field_.get_concurrently<IsUniqueFlag>()) {
- static_cast<UniqueElementData*>(this)->TraceAfterDispatch(visitor);
+ static_cast<const UniqueElementData*>(this)->TraceAfterDispatch(visitor);
} else {
- static_cast<ShareableElementData*>(this)->TraceAfterDispatch(visitor);
+ static_cast<const ShareableElementData*>(this)->TraceAfterDispatch(visitor);
}
}
diff --git a/chromium/third_party/blink/renderer/core/dom/element_data.h b/chromium/third_party/blink/renderer/core/dom/element_data.h
index ad658e442bc..38a2d3cda70 100644
--- a/chromium/third_party/blink/renderer/core/dom/element_data.h
+++ b/chromium/third_party/blink/renderer/core/dom/element_data.h
@@ -82,7 +82,7 @@ class ElementData : public GarbageCollected<ElementData> {
bool IsUnique() const { return bit_field_.get<IsUniqueFlag>(); }
void TraceAfterDispatch(blink::Visitor*) const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
protected:
using BitField = WTF::ConcurrentlyReadBitField<uint32_t>;
diff --git a/chromium/third_party/blink/renderer/core/dom/element_data_cache.cc b/chromium/third_party/blink/renderer/core/dom/element_data_cache.cc
index a729e0fef94..e8fd58cad32 100644
--- a/chromium/third_party/blink/renderer/core/dom/element_data_cache.cc
+++ b/chromium/third_party/blink/renderer/core/dom/element_data_cache.cc
@@ -64,7 +64,7 @@ ElementDataCache::CachedShareableElementDataWithAttributes(
ElementDataCache::ElementDataCache() = default;
-void ElementDataCache::Trace(Visitor* visitor) {
+void ElementDataCache::Trace(Visitor* visitor) const {
visitor->Trace(shareable_element_data_cache_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/element_data_cache.h b/chromium/third_party/blink/renderer/core/dom/element_data_cache.h
index 5cb8058be09..521c9e3e77d 100644
--- a/chromium/third_party/blink/renderer/core/dom/element_data_cache.h
+++ b/chromium/third_party/blink/renderer/core/dom/element_data_cache.h
@@ -44,7 +44,7 @@ class ElementDataCache final : public GarbageCollected<ElementDataCache> {
ShareableElementData* CachedShareableElementDataWithAttributes(
const Vector<Attribute>&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
typedef HeapHashMap<unsigned, Member<ShareableElementData>, AlreadyHashed>
diff --git a/chromium/third_party/blink/renderer/core/dom/element_test.cc b/chromium/third_party/blink/renderer/core/dom/element_test.cc
index 83346d25b0b..d85e520c18b 100644
--- a/chromium/third_party/blink/renderer/core/dom/element_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/element_test.cc
@@ -493,7 +493,7 @@ class ScriptOnDestroyPlugin : public GarbageCollected<ScriptOnDestroyPlugin>,
void DidFinishLoading() override {}
void DidFailLoading(const WebURLError&) override {}
- void Trace(Visitor*) {}
+ void Trace(Visitor*) const {}
bool DestroyCalled() const { return destroy_called_; }
diff --git a/chromium/third_party/blink/renderer/core/dom/empty_node_list.cc b/chromium/third_party/blink/renderer/core/dom/empty_node_list.cc
index 7edbab93e93..06cd5870463 100644
--- a/chromium/third_party/blink/renderer/core/dom/empty_node_list.cc
+++ b/chromium/third_party/blink/renderer/core/dom/empty_node_list.cc
@@ -42,7 +42,7 @@ Node* EmptyNodeList::VirtualOwnerNode() const {
return &OwnerNode();
}
-void EmptyNodeList::Trace(Visitor* visitor) {
+void EmptyNodeList::Trace(Visitor* visitor) const {
visitor->Trace(owner_);
NodeList::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/empty_node_list.h b/chromium/third_party/blink/renderer/core/dom/empty_node_list.h
index 08daad6eefb..aeaddf6b9ac 100644
--- a/chromium/third_party/blink/renderer/core/dom/empty_node_list.h
+++ b/chromium/third_party/blink/renderer/core/dom/empty_node_list.h
@@ -44,7 +44,7 @@ class EmptyNodeList final : public NodeList {
Node& OwnerNode() const { return *owner_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
unsigned length() const override { return 0; }
diff --git a/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.cc b/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.cc
index 711feae9b09..a4573199630 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.cc
@@ -25,7 +25,7 @@ AddEventListenerOptionsResolved::AddEventListenerOptionsResolved(
AddEventListenerOptionsResolved::~AddEventListenerOptionsResolved() = default;
-void AddEventListenerOptionsResolved::Trace(Visitor* visitor) {
+void AddEventListenerOptionsResolved::Trace(Visitor* visitor) const {
AddEventListenerOptions::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h b/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h
index 1eb95afb2c8..959c9f1fe62 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h
@@ -32,7 +32,7 @@ class CORE_EXPORT AddEventListenerOptionsResolved
void SetPassiveSpecified(bool specified) { passive_specified_ = specified; }
bool PassiveSpecified() const { return passive_specified_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool passive_forced_for_document_target_;
diff --git a/chromium/third_party/blink/renderer/core/dom/events/custom_event.cc b/chromium/third_party/blink/renderer/core/dom/events/custom_event.cc
index 9da77b8f300..60f32cd4466 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/custom_event.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/custom_event.cc
@@ -75,7 +75,7 @@ const AtomicString& CustomEvent::InterfaceName() const {
return event_interface_names::kCustomEvent;
}
-void CustomEvent::Trace(Visitor* visitor) {
+void CustomEvent::Trace(Visitor* visitor) const {
visitor->Trace(detail_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/events/custom_event.h b/chromium/third_party/blink/renderer/core/dom/events/custom_event.h
index f456e3d543f..22026a6fc41 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/custom_event.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/custom_event.h
@@ -63,7 +63,7 @@ class CORE_EXPORT CustomEvent final : public Event {
ScriptValue detail(ScriptState*) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
WorldSafeV8Reference<v8::Value> detail_;
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event.cc b/chromium/third_party/blink/renderer/core/dom/events/event.cc
index 1e5f4e14e3c..28476f5436d 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/event.cc
@@ -385,7 +385,7 @@ DispatchEventResult Event::DispatchEvent(EventDispatcher& dispatcher) {
return dispatcher.Dispatch();
}
-void Event::Trace(Visitor* visitor) {
+void Event::Trace(Visitor* visitor) const {
visitor->Trace(current_target_);
visitor->Trace(target_);
visitor->Trace(underlying_event_);
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event.h b/chromium/third_party/blink/renderer/core/dom/events/event.h
index d261a7f2252..5e8d0c99eb5 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/event.h
@@ -307,7 +307,7 @@ class CORE_EXPORT Event : public ScriptWrappable {
probe::AsyncTaskId* async_task_id() { return &async_task_id_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
virtual void ReceivedTarget();
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc b/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
index dc55e6a462a..52a3c1d3e53 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
@@ -210,7 +210,7 @@ DispatchEventResult EventDispatcher::Dispatch() {
DispatchEventPostProcess(activation_target,
pre_dispatch_event_handler_result);
if (eventTiming)
- eventTiming->DidDispatchEvent(*event_);
+ eventTiming->DidDispatchEvent(*event_, node_->GetDocument());
return EventTarget::GetDispatchEventResult(*event_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.h b/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.h
index 048327a6a80..d7d2b1f0221 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.h
@@ -43,7 +43,7 @@ class Node;
class EventDispatchHandlingState
: public GarbageCollected<EventDispatchHandlingState> {
public:
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
enum EventDispatchContinuation { kContinueDispatching, kDoneDispatching };
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_listener.h b/chromium/third_party/blink/renderer/core/dom/events/event_listener.h
index 9faaae7f295..6235bc2b4cf 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_listener.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_listener.h
@@ -76,7 +76,7 @@ class CORE_EXPORT EventListener : public GarbageCollected<EventListener>,
// produce the same result as b.Matches(a).
virtual bool Matches(const EventListener&) const = 0;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
const char* NameInHeapSnapshot() const override { return "EventListener"; }
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.cc b/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.cc
index 1d59550227a..334ed946a08 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.cc
@@ -224,7 +224,7 @@ void EventListenerMap::CopyEventListenersNotCreatedFromMarkupToTarget(
}
}
-void EventListenerMap::Trace(Visitor* visitor) {
+void EventListenerMap::Trace(Visitor* visitor) const {
visitor->Trace(entries_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.h b/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.h
index ae83fe10ce2..bdccfd2e1bd 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_listener_map.h
@@ -71,7 +71,7 @@ class CORE_EXPORT EventListenerMap final {
void CopyEventListenersNotCreatedFromMarkupToTarget(EventTarget*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
friend class EventListenerIterator;
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_path.cc b/chromium/third_party/blink/renderer/core/dom/events/event_path.cc
index fc934283780..241b224c6f4 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_path.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_path.cc
@@ -425,7 +425,7 @@ void EventPath::CheckReachability(TreeScope& tree_scope,
}
#endif
-void EventPath::Trace(Visitor* visitor) {
+void EventPath::Trace(Visitor* visitor) const {
visitor->Trace(node_event_contexts_);
visitor->Trace(node_);
visitor->Trace(event_);
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_path.h b/chromium/third_party/blink/renderer/core/dom/events/event_path.h
index b2e6efc9acd..691512e7049 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_path.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_path.h
@@ -82,7 +82,7 @@ class CORE_EXPORT EventPath final : public GarbageCollected<EventPath> {
static EventTarget& EventTargetRespectingTargetRules(Node&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void Clear() {
node_event_contexts_.clear();
tree_scope_event_contexts_.clear();
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_queue.cc b/chromium/third_party/blink/renderer/core/dom/events/event_queue.cc
index 419938ad5e9..7fa5be79d87 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_queue.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_queue.cc
@@ -45,7 +45,7 @@ EventQueue::EventQueue(ExecutionContext* context, TaskType task_type)
EventQueue::~EventQueue() = default;
-void EventQueue::Trace(Visitor* visitor) {
+void EventQueue::Trace(Visitor* visitor) const {
visitor->Trace(queued_events_);
ExecutionContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_queue.h b/chromium/third_party/blink/renderer/core/dom/events/event_queue.h
index 4c0f2995b2d..2ee41cd26e6 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_queue.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_queue.h
@@ -44,7 +44,7 @@ class CORE_EXPORT EventQueue final : public GarbageCollected<EventQueue>,
EventQueue(ExecutionContext*, TaskType);
~EventQueue();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool EnqueueEvent(const base::Location&, Event&);
void CancelAllEvents();
bool HasPendingEvents() const;
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_target.cc b/chromium/third_party/blink/renderer/core/dom/events/event_target.cc
index a38b4bde76e..9b78967e245 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_target.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_target.cc
@@ -249,7 +249,7 @@ EventTargetData::EventTargetData() = default;
EventTargetData::~EventTargetData() = default;
-void EventTargetData::Trace(Visitor* visitor) {
+void EventTargetData::Trace(Visitor* visitor) const {
visitor->Trace(event_listener_map);
}
@@ -656,7 +656,7 @@ RegisteredEventListener* EventTarget::GetAttributeRegisteredEventListener(
for (auto& event_listener : *listener_vector) {
EventListener* listener = event_listener.Callback();
- if (listener->IsEventHandler() &&
+ if (GetExecutionContext() && listener->IsEventHandler() &&
listener->BelongsToTheCurrentWorld(GetExecutionContext()))
return &event_listener;
}
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_target.h b/chromium/third_party/blink/renderer/core/dom/events/event_target.h
index 0963aaaab0a..d6d9b763b1b 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_target.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_target.h
@@ -82,7 +82,7 @@ class CORE_EXPORT EventTargetData final
EventTargetData();
~EventTargetData();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
EventListenerMap event_listener_map;
std::unique_ptr<FiringEventIteratorVector> firing_event_iterators;
@@ -238,7 +238,7 @@ class CORE_EXPORT EventTargetWithInlineData : public EventTarget {
public:
~EventTargetWithInlineData() override = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(event_target_data_);
EventTarget::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.cc b/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.cc
index 83a530add58..d557318bd9c 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.cc
@@ -16,7 +16,7 @@ ExecutionContext* EventTargetImpl::GetExecutionContext() const {
return ExecutionContextClient::GetExecutionContext();
}
-void EventTargetImpl::Trace(Visitor* visitor) {
+void EventTargetImpl::Trace(Visitor* visitor) const {
EventTargetWithInlineData::Trace(visitor);
ExecutionContextClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.h b/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.h
index df9434937be..d43402a6e16 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_target_impl.h
@@ -30,7 +30,7 @@ class CORE_EXPORT EventTargetImpl final : public EventTargetWithInlineData,
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/events/node_event_context.cc b/chromium/third_party/blink/renderer/core/dom/events/node_event_context.cc
index ff6a94ff4e0..4e01c92f074 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/node_event_context.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/node_event_context.cc
@@ -38,7 +38,7 @@ namespace blink {
NodeEventContext::NodeEventContext(Node& node, EventTarget& current_target)
: node_(node), current_target_(current_target) {}
-void NodeEventContext::Trace(Visitor* visitor) {
+void NodeEventContext::Trace(Visitor* visitor) const {
visitor->Trace(node_);
visitor->Trace(current_target_);
visitor->Trace(tree_scope_event_context_);
diff --git a/chromium/third_party/blink/renderer/core/dom/events/node_event_context.h b/chromium/third_party/blink/renderer/core/dom/events/node_event_context.h
index b9c93d32fa1..291909703a3 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/node_event_context.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/node_event_context.h
@@ -43,7 +43,7 @@ class CORE_EXPORT NodeEventContext {
public:
// FIXME: Use ContainerNode instead of Node.
NodeEventContext(Node&, EventTarget& current_target);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
Node& GetNode() const { return *node_; }
diff --git a/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.cc b/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.cc
index 13c187c56c4..9bbc3b8837d 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.cc
@@ -54,7 +54,7 @@ RegisteredEventListener::RegisteredEventListener(
RegisteredEventListener& RegisteredEventListener::operator=(
const RegisteredEventListener& that) = default;
-void RegisteredEventListener::Trace(Visitor* visitor) {
+void RegisteredEventListener::Trace(Visitor* visitor) const {
visitor->Trace(callback_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.h b/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.h
index baeea9d843a..2098939a962 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/registered_event_listener.h
@@ -46,7 +46,7 @@ class RegisteredEventListener final {
const AddEventListenerOptionsResolved* options);
RegisteredEventListener& operator=(const RegisteredEventListener& that);
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
AddEventListenerOptionsResolved* Options() const;
diff --git a/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.cc b/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.cc
index 8d0dd9bf75e..4c50097b8e1 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.cc
@@ -93,7 +93,7 @@ TreeScopeEventContext::TreeScopeEventContext(TreeScope& tree_scope)
pre_order_(-1),
post_order_(-1) {}
-void TreeScopeEventContext::Trace(Visitor* visitor) {
+void TreeScopeEventContext::Trace(Visitor* visitor) const {
visitor->Trace(tree_scope_);
visitor->Trace(target_);
visitor->Trace(related_target_);
diff --git a/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.h b/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.h
index fed43112b53..72e2fac9430 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.h
@@ -48,7 +48,7 @@ class CORE_EXPORT TreeScopeEventContext final
: public GarbageCollected<TreeScopeEventContext> {
public:
explicit TreeScopeEventContext(TreeScope&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
TreeScope& GetTreeScope() const { return *tree_scope_; }
ContainerNode& RootNode() const { return tree_scope_->RootNode(); }
diff --git a/chromium/third_party/blink/renderer/core/dom/events/window_event_context.cc b/chromium/third_party/blink/renderer/core/dom/events/window_event_context.cc
index abf6206b1b8..81d04eee403 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/window_event_context.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/window_event_context.cc
@@ -61,7 +61,7 @@ bool WindowEventContext::HandleLocalEvents(Event& event) {
return true;
}
-void WindowEventContext::Trace(Visitor* visitor) {
+void WindowEventContext::Trace(Visitor* visitor) const {
visitor->Trace(window_);
visitor->Trace(target_);
visitor->Trace(related_target_);
diff --git a/chromium/third_party/blink/renderer/core/dom/events/window_event_context.h b/chromium/third_party/blink/renderer/core/dom/events/window_event_context.h
index 3f95a3ee64a..c5ce6665149 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/window_event_context.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/window_event_context.h
@@ -46,7 +46,7 @@ class WindowEventContext : public GarbageCollected<WindowEventContext> {
EventTarget* RelatedTarget() const;
bool HandleLocalEvents(Event&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<LocalDOMWindow> window_;
diff --git a/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc b/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc
index 219f5212afe..e52487d16b1 100644
--- a/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc
+++ b/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc
@@ -142,8 +142,7 @@ LayoutText* FirstLetterPseudoElement::FirstLetterTextLayoutObject(
break;
first_letter_text_layout_object =
first_letter_text_layout_object->NextSibling();
- } else if (first_letter_text_layout_object
- ->IsListMarkerIncludingNGOutsideAndInside()) {
+ } else if (first_letter_text_layout_object->IsListMarkerIncludingAll()) {
// The list item marker may have out-of-flow siblings inside an anonymous
// block. Skip them to make sure we leave the anonymous block before
// continuing looking for the first letter text.
@@ -188,7 +187,7 @@ LayoutText* FirstLetterPseudoElement::FirstLetterTextLayoutObject(
}
// No first letter text to display, we're done.
- // FIXME: This black-list of disallowed LayoutText subclasses is fragile.
+ // FIXME: This list of disallowed LayoutText subclasses is fragile.
// crbug.com/422336.
// Should counter be on this list? What about LayoutTextFragment?
if (!first_letter_text_layout_object ||
diff --git a/chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.cc b/chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.cc
index 163ec4338a1..0cc61db0087 100644
--- a/chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.cc
+++ b/chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.cc
@@ -8,7 +8,7 @@
namespace blink {
-void FlatTreeNodeData::Trace(Visitor* visitor) {
+void FlatTreeNodeData::Trace(Visitor* visitor) const {
visitor->Trace(assigned_slot_);
visitor->Trace(previous_in_assigned_nodes_);
visitor->Trace(next_in_assigned_nodes_);
diff --git a/chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.h b/chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.h
index 7ca08c254f6..4a8b63a2d69 100644
--- a/chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.h
+++ b/chromium/third_party/blink/renderer/core/dom/flat_tree_node_data.h
@@ -22,7 +22,7 @@ class FlatTreeNodeData final : public GarbageCollected<FlatTreeNodeData> {
next_in_assigned_nodes_ = nullptr;
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
#if DCHECK_IS_ON()
bool IsCleared() const {
diff --git a/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc b/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc
index 094fef963e3..b6724f0e50d 100644
--- a/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc
+++ b/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc
@@ -31,35 +31,12 @@ FrameRequestCallbackCollection::RegisterFrameCallback(FrameCallback* callback) {
}
void FrameRequestCallbackCollection::CancelFrameCallback(CallbackId id) {
- CancelCallbackInternal(id, "CancelAnimationFrame", "cancelAnimationFrame");
-}
-
-void FrameRequestCallbackCollection::CancelPostFrameCallback(CallbackId id) {
- CancelCallbackInternal(id, "CancelPostAnimationFrame",
- "cancelPostAnimationFrame");
-}
-
-void FrameRequestCallbackCollection::CancelCallbackInternal(
- CallbackId id,
- const char* trace_event_name,
- const char* probe_name) {
for (wtf_size_t i = 0; i < frame_callbacks_.size(); ++i) {
if (frame_callbacks_[i]->Id() == id) {
- probe::AsyncTaskCanceledBreakable(context_, probe_name,
+ probe::AsyncTaskCanceledBreakable(context_, "cancelAnimationFrame",
frame_callbacks_[i]->async_task_id());
frame_callbacks_.EraseAt(i);
- TRACE_EVENT_INSTANT1("devtools.timeline", trace_event_name,
- TRACE_EVENT_SCOPE_THREAD, "data",
- inspector_animation_frame_event::Data(context_, id));
- return;
- }
- }
- for (wtf_size_t i = 0; i < post_frame_callbacks_.size(); ++i) {
- if (post_frame_callbacks_[i]->Id() == id) {
- probe::AsyncTaskCanceledBreakable(
- context_, probe_name, post_frame_callbacks_[i]->async_task_id());
- post_frame_callbacks_.EraseAt(i);
- TRACE_EVENT_INSTANT1("devtools.timeline", trace_event_name,
+ TRACE_EVENT_INSTANT1("devtools.timeline", "CancelAnimationFrame",
TRACE_EVENT_SCOPE_THREAD, "data",
inspector_animation_frame_event::Data(context_, id));
return;
@@ -67,14 +44,13 @@ void FrameRequestCallbackCollection::CancelCallbackInternal(
}
for (const auto& callback : callbacks_to_invoke_) {
if (callback->Id() == id) {
- probe::AsyncTaskCanceledBreakable(context_, probe_name,
+ probe::AsyncTaskCanceledBreakable(context_, "cancelAnimationFrame",
callback->async_task_id());
- TRACE_EVENT_INSTANT1("devtools.timeline", trace_event_name,
+ TRACE_EVENT_INSTANT1("devtools.timeline", "CancelAnimationFrame",
TRACE_EVENT_SCOPE_THREAD, "data",
inspector_animation_frame_event::Data(context_, id));
callback->SetIsCancelled(true);
- // will be removed at the end of ExecuteCallbacks() or
- // ExecutePostFrameCallbacks()
+ // will be removed at the end of ExecuteCallbacks()
return;
}
}
@@ -85,29 +61,11 @@ void FrameRequestCallbackCollection::ExecuteFrameCallbacks(
double high_res_now_ms_legacy) {
TRACE_EVENT0("blink",
"FrameRequestCallbackCollection::ExecuteFrameCallbacks");
- ExecuteCallbacksInternal(frame_callbacks_, "FireAnimationFrame",
- "requestAnimationFrame", high_res_now_ms,
- high_res_now_ms_legacy);
-}
-
-void FrameRequestCallbackCollection::ExecutePostFrameCallbacks(
- double high_res_now_ms,
- double high_res_now_ms_legacy) {
- ExecuteCallbacksInternal(post_frame_callbacks_, "FirePostAnimationFrame",
- "requestPostAnimationFrame", high_res_now_ms,
- high_res_now_ms_legacy);
-}
-void FrameRequestCallbackCollection::ExecuteCallbacksInternal(
- CallbackList& callbacks,
- const char* trace_event_name,
- const char* probe_name,
- double high_res_now_ms,
- double high_res_now_ms_legacy) {
// First, generate a list of callbacks to consider. Callbacks registered from
// this point on are considered only for the "next" frame, not this one.
DCHECK(callbacks_to_invoke_.IsEmpty());
- swap(callbacks_to_invoke_, callbacks);
+ swap(callbacks_to_invoke_, frame_callbacks_);
for (const auto& callback : callbacks_to_invoke_) {
// When the ExecutionContext is destroyed (e.g. an iframe is detached),
@@ -124,10 +82,11 @@ void FrameRequestCallbackCollection::ExecuteCallbacksInternal(
continue;
}
TRACE_EVENT1(
- "devtools.timeline", trace_event_name, "data",
+ "devtools.timeline", "FireAnimationFrame", "data",
inspector_animation_frame_event::Data(context_, callback->Id()));
probe::AsyncTask async_task(context_, callback->async_task_id());
- probe::UserCallback probe(context_, probe_name, AtomicString(), true);
+ probe::UserCallback probe(context_, "requestAnimationFrame", AtomicString(),
+ true);
if (callback->GetUseLegacyTimeBase())
callback->Invoke(high_res_now_ms_legacy);
else
@@ -137,25 +96,8 @@ void FrameRequestCallbackCollection::ExecuteCallbacksInternal(
callbacks_to_invoke_.clear();
}
-FrameRequestCallbackCollection::CallbackId
-FrameRequestCallbackCollection::RegisterPostFrameCallback(
- FrameCallback* callback) {
- CallbackId id = ++next_callback_id_;
- callback->SetIsCancelled(false);
- callback->SetId(id);
- post_frame_callbacks_.push_back(callback);
-
- TRACE_EVENT_INSTANT1("devtools.timeline", "RequestPostAnimationFrame",
- TRACE_EVENT_SCOPE_THREAD, "data",
- inspector_animation_frame_event::Data(context_, id));
- probe::AsyncTaskScheduledBreakable(context_, "requestPostAnimationFrame",
- callback->async_task_id());
- return id;
-}
-
-void FrameRequestCallbackCollection::Trace(Visitor* visitor) {
+void FrameRequestCallbackCollection::Trace(Visitor* visitor) const {
visitor->Trace(frame_callbacks_);
- visitor->Trace(post_frame_callbacks_);
visitor->Trace(callbacks_to_invoke_);
visitor->Trace(context_);
}
@@ -165,7 +107,7 @@ FrameRequestCallbackCollection::V8FrameCallback::V8FrameCallback(
: callback_(callback) {}
void FrameRequestCallbackCollection::V8FrameCallback::Trace(
- blink::Visitor* visitor) {
+ blink::Visitor* visitor) const {
visitor->Trace(callback_);
FrameRequestCallbackCollection::FrameCallback::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.h b/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.h
index 74a2fc35e7f..02e0111bf9c 100644
--- a/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.h
+++ b/chromium/third_party/blink/renderer/core/dom/frame_request_callback_collection.h
@@ -30,7 +30,7 @@ class GC_PLUGIN_IGNORE("crbug.com/841830")
class CORE_EXPORT FrameCallback : public GarbageCollected<FrameCallback>,
public NameClient {
public:
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
const char* NameInHeapSnapshot() const override { return "FrameCallback"; }
virtual ~FrameCallback() = default;
virtual void Invoke(double) = 0;
@@ -60,7 +60,7 @@ class GC_PLUGIN_IGNORE("crbug.com/841830")
// |V8FrameRequestCallback| to |Framecallback|.
class CORE_EXPORT V8FrameCallback : public FrameCallback {
public:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override {
return "V8FrameCallback";
}
@@ -79,36 +79,19 @@ class GC_PLUGIN_IGNORE("crbug.com/841830")
void ExecuteFrameCallbacks(double high_res_now_ms,
double high_res_now_ms_legacy);
- CallbackId RegisterPostFrameCallback(FrameCallback*);
- void CancelPostFrameCallback(CallbackId);
- void ExecutePostFrameCallbacks(double high_res_now_ms,
- double high_rest_now_ms_legacy);
-
bool HasFrameCallback() const { return frame_callbacks_.size(); }
- bool HasPostFrameCallback() const { return post_frame_callbacks_.size(); }
- bool IsEmpty() const {
- return !HasFrameCallback() && !HasPostFrameCallback();
- }
+ bool IsEmpty() const { return !HasFrameCallback(); }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override {
return "FrameRequestCallbackCollection";
}
private:
using CallbackList = HeapVector<Member<FrameCallback>>;
- void ExecuteCallbacksInternal(CallbackList& callbacks,
- const char* trace_event_name,
- const char* probe_name,
- double high_res_now_ms,
- double high_res_now_ms_legacy);
- void CancelCallbackInternal(CallbackId id,
- const char* trace_event_name,
- const char* probe_name);
CallbackList frame_callbacks_;
- CallbackList post_frame_callbacks_;
- // only non-empty while inside ExecuteCallbacks or ExecutePostFrameCallbacks.
+ // only non-empty while inside ExecuteCallbacks.
CallbackList callbacks_to_invoke_;
CallbackId next_callback_id_ = 0;
diff --git a/chromium/third_party/blink/renderer/core/dom/get_inner_html_options.idl b/chromium/third_party/blink/renderer/core/dom/get_inner_html_options.idl
index 47b06446229..8fc02fc6447 100644
--- a/chromium/third_party/blink/renderer/core/dom/get_inner_html_options.idl
+++ b/chromium/third_party/blink/renderer/core/dom/get_inner_html_options.idl
@@ -4,4 +4,5 @@
dictionary GetInnerHTMLOptions {
boolean includeShadowRoots = true;
+ sequence<ShadowRoot> closedRoots;
};
diff --git a/chromium/third_party/blink/renderer/core/dom/global_event_handlers.h b/chromium/third_party/blink/renderer/core/dom/global_event_handlers.h
index ba4d55ea4ec..5f95a146dba 100644
--- a/chromium/third_party/blink/renderer/core/dom/global_event_handlers.h
+++ b/chromium/third_party/blink/renderer/core/dom/global_event_handlers.h
@@ -103,8 +103,6 @@ class GlobalEventHandlers {
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerup, kPointerup)
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(progress, kProgress)
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(ratechange, kRatechange)
- DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(rendersubtreeactivation,
- kRendersubtreeactivation)
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(reset, kReset)
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(resize, kResize)
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(scroll, kScroll)
diff --git a/chromium/third_party/blink/renderer/core/dom/global_event_handlers.idl b/chromium/third_party/blink/renderer/core/dom/global_event_handlers.idl
index 7fb4221167b..0ebea14f693 100644
--- a/chromium/third_party/blink/renderer/core/dom/global_event_handlers.idl
+++ b/chromium/third_party/blink/renderer/core/dom/global_event_handlers.idl
@@ -80,7 +80,6 @@
attribute EventHandler onplaying;
attribute EventHandler onprogress;
attribute EventHandler onratechange;
- [RuntimeEnabled=CSSContentVisibilityActivationEvent] attribute EventHandler onrendersubtreeactivation;
attribute EventHandler onreset;
attribute EventHandler onresize;
attribute EventHandler onscroll;
diff --git a/chromium/third_party/blink/renderer/core/dom/id_target_observer.cc b/chromium/third_party/blink/renderer/core/dom/id_target_observer.cc
index 2df3ab5fa08..2bd14af61c6 100644
--- a/chromium/third_party/blink/renderer/core/dom/id_target_observer.cc
+++ b/chromium/third_party/blink/renderer/core/dom/id_target_observer.cc
@@ -37,7 +37,7 @@ IdTargetObserver::IdTargetObserver(IdTargetObserverRegistry& observer_registry,
IdTargetObserver::~IdTargetObserver() = default;
-void IdTargetObserver::Trace(Visitor* visitor) {
+void IdTargetObserver::Trace(Visitor* visitor) const {
visitor->Trace(registry_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/id_target_observer.h b/chromium/third_party/blink/renderer/core/dom/id_target_observer.h
index e240e1ad670..1ca91df64e0 100644
--- a/chromium/third_party/blink/renderer/core/dom/id_target_observer.h
+++ b/chromium/third_party/blink/renderer/core/dom/id_target_observer.h
@@ -36,7 +36,7 @@ class IdTargetObserverRegistry;
class IdTargetObserver : public GarbageCollected<IdTargetObserver> {
public:
virtual ~IdTargetObserver();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
virtual void IdTargetChanged() = 0;
virtual void Unregister();
diff --git a/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.cc b/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.cc
index c18273af4d1..c5d8545fc73 100644
--- a/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.cc
+++ b/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.cc
@@ -29,7 +29,7 @@
namespace blink {
-void IdTargetObserverRegistry::Trace(Visitor* visitor) {
+void IdTargetObserverRegistry::Trace(Visitor* visitor) const {
visitor->Trace(registry_);
visitor->Trace(notifying_observers_in_set_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.h b/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.h
index f5a4ba6975c..ea74a3a2d08 100644
--- a/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.h
+++ b/chromium/third_party/blink/renderer/core/dom/id_target_observer_registry.h
@@ -44,7 +44,7 @@ class IdTargetObserverRegistry final
public:
IdTargetObserverRegistry() : notifying_observers_in_set_(nullptr) {}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void NotifyObservers(const AtomicString& id);
bool HasObservers(const AtomicString& id) const;
diff --git a/chromium/third_party/blink/renderer/core/dom/live_node_list.cc b/chromium/third_party/blink/renderer/core/dom/live_node_list.cc
index 13c0cdb2861..f64d7fe2c70 100644
--- a/chromium/third_party/blink/renderer/core/dom/live_node_list.cc
+++ b/chromium/third_party/blink/renderer/core/dom/live_node_list.cc
@@ -81,7 +81,7 @@ Element* LiveNodeList::TraverseBackwardToOffset(
current_element, &RootNode(), offset, current_offset, IsMatch(*this));
}
-void LiveNodeList::Trace(Visitor* visitor) {
+void LiveNodeList::Trace(Visitor* visitor) const {
visitor->Trace(collection_items_cache_);
LiveNodeListBase::Trace(visitor);
NodeList::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/dom/live_node_list.h b/chromium/third_party/blink/renderer/core/dom/live_node_list.h
index af5bcea9f72..5bdd794e432 100644
--- a/chromium/third_party/blink/renderer/core/dom/live_node_list.h
+++ b/chromium/third_party/blink/renderer/core/dom/live_node_list.h
@@ -71,7 +71,7 @@ class CORE_EXPORT LiveNodeList : public NodeList, public LiveNodeListBase {
Element& current_node,
unsigned& current_offset) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Node* VirtualOwnerNode() const final;
diff --git a/chromium/third_party/blink/renderer/core/dom/live_node_list_base.h b/chromium/third_party/blink/renderer/core/dom/live_node_list_base.h
index 0884032b5af..6a1eaece0bd 100644
--- a/chromium/third_party/blink/renderer/core/dom/live_node_list_base.h
+++ b/chromium/third_party/blink/renderer/core/dom/live_node_list_base.h
@@ -77,7 +77,7 @@ class CORE_EXPORT LiveNodeListBase : public GarbageCollectedMixin {
static bool ShouldInvalidateTypeOnAttributeChange(NodeListInvalidationType,
const QualifiedName&);
- void Trace(Visitor* visitor) override { visitor->Trace(owner_node_); }
+ void Trace(Visitor* visitor) const override { visitor->Trace(owner_node_); }
protected:
Document& GetDocument() const { return owner_node_->GetDocument(); }
diff --git a/chromium/third_party/blink/renderer/core/dom/live_node_list_registry.cc b/chromium/third_party/blink/renderer/core/dom/live_node_list_registry.cc
index 343ba669ba0..492e0bc9bf9 100644
--- a/chromium/third_party/blink/renderer/core/dom/live_node_list_registry.cc
+++ b/chromium/third_party/blink/renderer/core/dom/live_node_list_registry.cc
@@ -30,7 +30,7 @@ void LiveNodeListRegistry::Remove(const LiveNodeListBase* list,
RecomputeMask();
}
-void LiveNodeListRegistry::Trace(Visitor* visitor) {
+void LiveNodeListRegistry::Trace(Visitor* visitor) const {
visitor->RegisterWeakCallbackMethod<
LiveNodeListRegistry, &LiveNodeListRegistry::ProcessCustomWeakness>(this);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/live_node_list_registry.h b/chromium/third_party/blink/renderer/core/dom/live_node_list_registry.h
index d93b1bc2bda..b6ee3178084 100644
--- a/chromium/third_party/blink/renderer/core/dom/live_node_list_registry.h
+++ b/chromium/third_party/blink/renderer/core/dom/live_node_list_registry.h
@@ -43,7 +43,7 @@ class CORE_EXPORT LiveNodeListRegistry {
return mask_ & MaskForInvalidationType(type);
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
static inline unsigned MaskForInvalidationType(
diff --git a/chromium/third_party/blink/renderer/core/dom/live_node_list_registry_test.cc b/chromium/third_party/blink/renderer/core/dom/live_node_list_registry_test.cc
index 70a22ee0f9d..d3a66beb6cb 100644
--- a/chromium/third_party/blink/renderer/core/dom/live_node_list_registry_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/live_node_list_registry_test.cc
@@ -103,7 +103,7 @@ TEST_F(LiveNodeListRegistryTest, ExplicitRemove) {
struct LiveNodeListRegistryWrapper final
: public GarbageCollected<LiveNodeListRegistryWrapper> {
LiveNodeListRegistry registry;
- void Trace(Visitor* visitor) { visitor->Trace(registry); }
+ void Trace(Visitor* visitor) const { visitor->Trace(registry); }
};
// The set of types which match should be updated as elements are removed due to
diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_observer.cc b/chromium/third_party/blink/renderer/core/dom/mutation_observer.cc
index 24a4c117fe8..d33303fb1bc 100644
--- a/chromium/third_party/blink/renderer/core/dom/mutation_observer.cc
+++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer.cc
@@ -74,7 +74,7 @@ class MutationObserver::V8DelegateImpl final
callback_->InvokeAndReportException(&observer, records, &observer);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(callback_);
MutationObserver::Delegate::Trace(visitor);
ExecutionContextClient::Trace(visitor);
@@ -342,7 +342,7 @@ void MutationObserver::DeliverMutations() {
slot->DispatchSlotChangeEvent();
}
-void MutationObserver::Trace(Visitor* visitor) {
+void MutationObserver::Trace(Visitor* visitor) const {
visitor->Trace(delegate_);
visitor->Trace(records_);
visitor->Trace(registrations_);
diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_observer.h b/chromium/third_party/blink/renderer/core/dom/mutation_observer.h
index 060b575349a..ae49ed221bd 100644
--- a/chromium/third_party/blink/renderer/core/dom/mutation_observer.h
+++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer.h
@@ -86,7 +86,7 @@ class CORE_EXPORT MutationObserver final
virtual ExecutionContext* GetExecutionContext() const = 0;
virtual void Deliver(const MutationRecordVector& records,
MutationObserver&) = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
const char* NameInHeapSnapshot() const override {
return "MutationObserver::Delegate";
}
@@ -118,7 +118,7 @@ class CORE_EXPORT MutationObserver final
void ContextLifecycleStateChanged(mojom::FrameLifecycleState) final;
void ContextDestroyed() final {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
struct ObserverLessThan;
diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.cc b/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.cc
index a9773f16e62..7f91edaacab 100644
--- a/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.cc
+++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.cc
@@ -89,7 +89,7 @@ void MutationObserverInterestGroup::EnqueueMutationRecord(
}
}
-void MutationObserverInterestGroup::Trace(Visitor* visitor) {
+void MutationObserverInterestGroup::Trace(Visitor* visitor) const {
visitor->Trace(observers_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.h b/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.h
index 966474e7110..79e891333db 100644
--- a/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.h
+++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.h
@@ -83,7 +83,7 @@ class MutationObserverInterestGroup final
bool IsOldValueRequested();
void EnqueueMutationRecord(MutationRecord*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
static MutationObserverInterestGroup* CreateIfNeeded(
diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.cc b/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.cc
index b45ff0cdf98..1d85ae58670 100644
--- a/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.cc
+++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.cc
@@ -139,7 +139,7 @@ void MutationObserverRegistration::AddRegistrationNodesToSet(
nodes.insert(iter->Get());
}
-void MutationObserverRegistration::Trace(Visitor* visitor) {
+void MutationObserverRegistration::Trace(Visitor* visitor) const {
visitor->Trace(observer_);
visitor->Trace(registration_node_);
visitor->Trace(registration_node_keep_alive_);
diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.h b/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.h
index 13fd9185897..28a7ead5bc9 100644
--- a/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.h
+++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer_registration.h
@@ -81,7 +81,7 @@ class CORE_EXPORT MutationObserverRegistration final
void Dispose();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override {
return "MutationObserverRegistration";
}
diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_observer_test.cc b/chromium/third_party/blink/renderer/core/dom/mutation_observer_test.cc
index 9ee4b3d8ea6..42817babbbc 100644
--- a/chromium/third_party/blink/renderer/core/dom/mutation_observer_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer_test.cc
@@ -25,7 +25,7 @@ class EmptyMutationCallback : public MutationObserver::Delegate {
void Deliver(const MutationRecordVector&, MutationObserver&) override {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(document_);
MutationObserver::Delegate::Trace(visitor);
}
@@ -37,7 +37,7 @@ class EmptyMutationCallback : public MutationObserver::Delegate {
} // namespace
TEST(MutationObserverTest, DisconnectCrash) {
- Persistent<Document> document = MakeGarbageCollected<HTMLDocument>();
+ Persistent<Document> document = HTMLDocument::CreateForTest();
auto* root =
To<HTMLElement>(document->CreateRawElement(html_names::kHTMLTag));
document->AppendChild(root);
diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_record.cc b/chromium/third_party/blink/renderer/core/dom/mutation_record.cc
index 15ab35192c8..1dad4155a44 100644
--- a/chromium/third_party/blink/renderer/core/dom/mutation_record.cc
+++ b/chromium/third_party/blink/renderer/core/dom/mutation_record.cc
@@ -53,7 +53,7 @@ class ChildListRecord : public MutationRecord {
previous_sibling_(previous_sibling),
next_sibling_(next_sibling) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(target_);
visitor->Trace(added_nodes_);
visitor->Trace(removed_nodes_);
@@ -82,7 +82,7 @@ class RecordWithEmptyNodeLists : public MutationRecord {
RecordWithEmptyNodeLists(Node* target, const String& old_value)
: target_(target), old_value_(old_value) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(target_);
visitor->Trace(added_nodes_);
visitor->Trace(removed_nodes_);
@@ -145,7 +145,7 @@ class MutationRecordWithNullOldValue : public MutationRecord {
public:
MutationRecordWithNullOldValue(MutationRecord* record) : record_(record) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(record_);
MutationRecord::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/named_node_map.cc b/chromium/third_party/blink/renderer/core/dom/named_node_map.cc
index e1120392bec..b69b487ad87 100644
--- a/chromium/third_party/blink/renderer/core/dom/named_node_map.cc
+++ b/chromium/third_party/blink/renderer/core/dom/named_node_map.cc
@@ -127,7 +127,7 @@ bool NamedNodeMap::NamedPropertyQuery(const AtomicString& name,
return properties.Contains(name);
}
-void NamedNodeMap::Trace(Visitor* visitor) {
+void NamedNodeMap::Trace(Visitor* visitor) const {
visitor->Trace(element_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/named_node_map.h b/chromium/third_party/blink/renderer/core/dom/named_node_map.h
index 331b99482c1..f05330ec4af 100644
--- a/chromium/third_party/blink/renderer/core/dom/named_node_map.h
+++ b/chromium/third_party/blink/renderer/core/dom/named_node_map.h
@@ -65,7 +65,7 @@ class NamedNodeMap final : public ScriptWrappable {
void NamedPropertyEnumerator(Vector<String>& names, ExceptionState&) const;
bool NamedPropertyQuery(const AtomicString&, ExceptionState&) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Element> element_;
diff --git a/chromium/third_party/blink/renderer/core/dom/node.cc b/chromium/third_party/blink/renderer/core/dom/node.cc
index 87bf4f19bb6..846967e815e 100644
--- a/chromium/third_party/blink/renderer/core/dom/node.cc
+++ b/chromium/third_party/blink/renderer/core/dom/node.cc
@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_get_root_node_options.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
+#include "third_party/blink/renderer/core/animation/scroll_timeline.h"
#include "third_party/blink/renderer/core/css/css_selector.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
@@ -132,6 +133,7 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
+#include "third_party/blink/renderer/platform/wtf/text/character_visitor.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -161,9 +163,9 @@ ScrollCustomizationCallbacks& GetScrollCustomizationCallbacks() {
void AppendUnsafe(StringBuilder& builder, const String& off_thread_string) {
StringImpl* impl = off_thread_string.Impl();
if (impl) {
- builder.Append(impl->Is8Bit()
- ? StringView(impl->Characters8(), impl->length())
- : StringView(impl->Characters16(), impl->length()));
+ WTF::VisitCharacters(*impl, [&](const auto* chars, unsigned length) {
+ builder.Append(chars, length);
+ });
}
}
@@ -840,8 +842,9 @@ static Node* ConvertNodesIntoNode(
const HeapVector<NodeOrStringOrTrustedScript>& nodes,
Document& document,
ExceptionState& exception_state) {
- bool needs_check =
- IsA<HTMLScriptElement>(parent) && document.IsTrustedTypesEnabledForDoc();
+ bool needs_check = IsA<HTMLScriptElement>(parent) &&
+ document.GetExecutionContext() &&
+ document.GetExecutionContext()->RequireTrustedTypes();
if (nodes.size() == 1)
return NodeOrStringToNode(nodes[0], document, needs_check, exception_state);
@@ -977,9 +980,9 @@ Node* Node::cloneNode(bool deep, ExceptionState& exception_state) const {
// true, and the clone shadows flag set if this is a DocumentFragment whose
// host is an HTML template element.
auto* fragment = DynamicTo<DocumentFragment>(this);
- bool clone_shadows_flag =
- fragment && fragment->IsTemplateContent() &&
- RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled();
+ bool clone_shadows_flag = fragment && fragment->IsTemplateContent() &&
+ RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled(
+ GetExecutionContext());
return Clone(GetDocument(),
deep ? (clone_shadows_flag ? CloneChildrenFlag::kCloneWithShadows
: CloneChildrenFlag::kClone)
@@ -2613,9 +2616,7 @@ const AtomicString& Node::InterfaceName() const {
}
ExecutionContext* Node::GetExecutionContext() const {
- if (auto* document = GetDocument().ContextDocument())
- return document->domWindow();
- return nullptr;
+ return GetDocument().GetExecutionContext();
}
void Node::WillMoveToNewDocument(Document& old_document,
@@ -3208,13 +3209,14 @@ void Node::SetCustomElementState(CustomElementState new_state) {
if (element->IsDefined() != was_defined) {
element->PseudoStateChanged(CSSSelector::kPseudoDefined);
- if (RuntimeEnabledFeatures::CustomElementsV0Enabled(&GetDocument()))
+ if (RuntimeEnabledFeatures::CustomElementsV0Enabled(GetExecutionContext()))
element->PseudoStateChanged(CSSSelector::kPseudoUnresolved);
}
}
void Node::SetV0CustomElementState(V0CustomElementState new_state) {
- DCHECK(RuntimeEnabledFeatures::CustomElementsV0Enabled(&GetDocument()));
+ DCHECK(
+ RuntimeEnabledFeatures::CustomElementsV0Enabled(GetExecutionContext()));
V0CustomElementState old_state = GetV0CustomElementState();
switch (new_state) {
@@ -3362,7 +3364,14 @@ void Node::RemovedFromFlatTree() {
GetDocument().GetStyleEngine().RemovedFromFlatTree(*this);
}
-void Node::Trace(Visitor* visitor) {
+void Node::RegisterScrollTimeline(ScrollTimeline* timeline) {
+ EnsureRareData().RegisterScrollTimeline(timeline);
+}
+void Node::UnregisterScrollTimeline(ScrollTimeline* timeline) {
+ EnsureRareData().UnregisterScrollTimeline(timeline);
+}
+
+void Node::Trace(Visitor* visitor) const {
visitor->Trace(parent_or_shadow_host_node_);
visitor->Trace(previous_);
visitor->Trace(next_);
diff --git a/chromium/third_party/blink/renderer/core/dom/node.h b/chromium/third_party/blink/renderer/core/dom/node.h
index 087c2133f2c..e7343a67894 100644
--- a/chromium/third_party/blink/renderer/core/dom/node.h
+++ b/chromium/third_party/blink/renderer/core/dom/node.h
@@ -67,6 +67,7 @@ class NodeOrStringOrTrustedScript;
class NodeRareData;
class QualifiedName;
class RegisteredEventListener;
+class ScrollTimeline;
class SVGQualifiedName;
class ScrollState;
class ScrollStateCallback;
@@ -930,7 +931,10 @@ class CORE_EXPORT Node : public EventTarget {
// If the node is a plugin, then this returns its WebPluginContainer.
WebPluginContainerImpl* GetWebPluginContainer() const;
- void Trace(Visitor*) override;
+ void RegisterScrollTimeline(ScrollTimeline*);
+ void UnregisterScrollTimeline(ScrollTimeline*);
+
+ void Trace(Visitor*) const override;
private:
enum NodeFlags : uint32_t {
diff --git a/chromium/third_party/blink/renderer/core/dom/node_iterator.cc b/chromium/third_party/blink/renderer/core/dom/node_iterator.cc
index a54a1aafc19..9f726a462bd 100644
--- a/chromium/third_party/blink/renderer/core/dom/node_iterator.cc
+++ b/chromium/third_party/blink/renderer/core/dom/node_iterator.cc
@@ -199,7 +199,7 @@ void NodeIterator::UpdateForNodeRemoval(Node& removed_node,
}
}
-void NodeIterator::Trace(Visitor* visitor) {
+void NodeIterator::Trace(Visitor* visitor) const {
visitor->Trace(reference_node_);
visitor->Trace(candidate_node_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/dom/node_iterator.h b/chromium/third_party/blink/renderer/core/dom/node_iterator.h
index feac6b5b5de..7850effd10a 100644
--- a/chromium/third_party/blink/renderer/core/dom/node_iterator.h
+++ b/chromium/third_party/blink/renderer/core/dom/node_iterator.h
@@ -52,7 +52,7 @@ class NodeIterator final : public ScriptWrappable, public NodeIteratorBase {
// This function is called before any node is removed from the document tree.
void NodeWillBeRemoved(Node&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class NodePointer {
@@ -69,7 +69,7 @@ class NodeIterator final : public ScriptWrappable, public NodeIteratorBase {
Member<Node> node;
bool is_pointer_before_node;
- void Trace(Visitor* visitor) { visitor->Trace(node); }
+ void Trace(Visitor* visitor) const { visitor->Trace(node); }
};
void UpdateForNodeRemoval(Node& node_to_be_removed, NodePointer&) const;
diff --git a/chromium/third_party/blink/renderer/core/dom/node_iterator_base.cc b/chromium/third_party/blink/renderer/core/dom/node_iterator_base.cc
index 066ff9de138..ffe3a3413dc 100644
--- a/chromium/third_party/blink/renderer/core/dom/node_iterator_base.cc
+++ b/chromium/third_party/blink/renderer/core/dom/node_iterator_base.cc
@@ -89,7 +89,7 @@ unsigned NodeIteratorBase::AcceptNode(Node* node,
return result;
}
-void NodeIteratorBase::Trace(Visitor* visitor) {
+void NodeIteratorBase::Trace(Visitor* visitor) const {
visitor->Trace(root_);
visitor->Trace(filter_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/node_iterator_base.h b/chromium/third_party/blink/renderer/core/dom/node_iterator_base.h
index f2791240123..ab407442c4e 100644
--- a/chromium/third_party/blink/renderer/core/dom/node_iterator_base.h
+++ b/chromium/third_party/blink/renderer/core/dom/node_iterator_base.h
@@ -41,7 +41,7 @@ class NodeIteratorBase : public GarbageCollectedMixin {
unsigned whatToShow() const { return what_to_show_; }
V8NodeFilter* filter() const { return filter_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
NodeIteratorBase(Node*, unsigned what_to_show, V8NodeFilter*);
diff --git a/chromium/third_party/blink/renderer/core/dom/node_lists_node_data.cc b/chromium/third_party/blink/renderer/core/dom/node_lists_node_data.cc
index 055dc5af715..4c8cb218011 100644
--- a/chromium/third_party/blink/renderer/core/dom/node_lists_node_data.cc
+++ b/chromium/third_party/blink/renderer/core/dom/node_lists_node_data.cc
@@ -45,7 +45,7 @@ void NodeListsNodeData::InvalidateCaches(const QualifiedName* attr_name) {
cache.value->InvalidateCache();
}
-void NodeListsNodeData::Trace(Visitor* visitor) {
+void NodeListsNodeData::Trace(Visitor* visitor) const {
visitor->Trace(child_node_list_);
visitor->Trace(atomic_name_caches_);
visitor->Trace(tag_collection_ns_caches_);
diff --git a/chromium/third_party/blink/renderer/core/dom/node_lists_node_data.h b/chromium/third_party/blink/renderer/core/dom/node_lists_node_data.h
index 375ba7f6d5c..3818015bb38 100644
--- a/chromium/third_party/blink/renderer/core/dom/node_lists_node_data.h
+++ b/chromium/third_party/blink/renderer/core/dom/node_lists_node_data.h
@@ -166,7 +166,7 @@ class NodeListsNodeData final : public GarbageCollected<NodeListsNodeData> {
}
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// Can be a ChildNodeList or an EmptyNodeList.
diff --git a/chromium/third_party/blink/renderer/core/dom/node_rare_data.cc b/chromium/third_party/blink/renderer/core/dom/node_rare_data.cc
index 50a72f9dee0..83269e1b799 100644
--- a/chromium/third_party/blink/renderer/core/dom/node_rare_data.cc
+++ b/chromium/third_party/blink/renderer/core/dom/node_rare_data.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/dom/node_rare_data.h"
+#include "third_party/blink/renderer/core/animation/scroll_timeline.h"
#include "third_party/blink/renderer/core/dom/container_node.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/element_rare_data.h"
@@ -43,14 +44,14 @@
namespace blink {
struct SameSizeAsNodeRareData {
- Member<void*> willbe_member_[4];
+ Member<void*> willbe_member_[5];
unsigned bitfields_;
};
static_assert(sizeof(NodeRareData) == sizeof(SameSizeAsNodeRareData),
"NodeRareData should stay small");
-void NodeMutationObserverData::Trace(Visitor* visitor) {
+void NodeMutationObserverData::Trace(Visitor* visitor) const {
visitor->Trace(registry_);
visitor->Trace(transient_registry_);
}
@@ -77,14 +78,14 @@ void NodeMutationObserverData::RemoveRegistration(
registry_.EraseAt(registry_.Find(registration));
}
-void NodeData::Trace(Visitor* visitor) {
+void NodeData::Trace(Visitor* visitor) const {
if (bit_field_.get_concurrently<IsRareData>()) {
if (bit_field_.get_concurrently<IsElementRareData>())
- static_cast<ElementRareData*>(this)->TraceAfterDispatch(visitor);
+ static_cast<const ElementRareData*>(this)->TraceAfterDispatch(visitor);
else
- static_cast<NodeRareData*>(this)->TraceAfterDispatch(visitor);
+ static_cast<const NodeRareData*>(this)->TraceAfterDispatch(visitor);
} else {
- static_cast<NodeRenderingData*>(this)->TraceAfterDispatch(visitor);
+ static_cast<const NodeRenderingData*>(this)->TraceAfterDispatch(visitor);
}
}
@@ -108,11 +109,23 @@ NodeRenderingData& NodeRenderingData::SharedEmptyData() {
return *shared_empty_data;
}
+void NodeRareData::RegisterScrollTimeline(ScrollTimeline* timeline) {
+ if (!scroll_timelines_) {
+ scroll_timelines_ =
+ MakeGarbageCollected<HeapHashSet<Member<ScrollTimeline>>>();
+ }
+ scroll_timelines_->insert(timeline);
+}
+void NodeRareData::UnregisterScrollTimeline(ScrollTimeline* timeline) {
+ scroll_timelines_->erase(timeline);
+}
+
void NodeRareData::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(mutation_observer_data_);
visitor->Trace(flat_tree_node_data_);
visitor->Trace(node_layout_data_);
visitor->Trace(node_lists_);
+ visitor->Trace(scroll_timelines_);
NodeData::TraceAfterDispatch(visitor);
}
@@ -124,7 +137,7 @@ void NodeRareData::FinalizeGarbageCollectedObject() {
}
void NodeRareData::IncrementConnectedSubframeCount() {
- SECURITY_CHECK((connected_frame_count_ + 1) <= Page::kMaxNumberOfFrames);
+ SECURITY_CHECK((connected_frame_count_ + 1) <= Page::MaxNumberOfFrames());
++connected_frame_count_;
}
@@ -139,10 +152,6 @@ FlatTreeNodeData& NodeRareData::EnsureFlatTreeNodeData() {
return *flat_tree_node_data_;
}
-// Ensure the 10 bits reserved for the connected_frame_count_ cannot overflow.
-static_assert(Page::kMaxNumberOfFrames <
- (1 << NodeRareData::kConnectedFrameCountBits),
- "Frame limit should fit in rare data count");
static_assert(static_cast<int>(NodeRareData::kNumberOfElementFlags) ==
static_cast<int>(ElementFlags::kNumberOfElementFlags),
"kNumberOfElementFlags must match.");
diff --git a/chromium/third_party/blink/renderer/core/dom/node_rare_data.h b/chromium/third_party/blink/renderer/core/dom/node_rare_data.h
index f38a3374e33..98589395482 100644
--- a/chromium/third_party/blink/renderer/core/dom/node_rare_data.h
+++ b/chromium/third_party/blink/renderer/core/dom/node_rare_data.h
@@ -37,6 +37,7 @@ class FlatTreeNodeData;
class LayoutObject;
class MutationObserverRegistration;
class NodeListsNodeData;
+class ScrollTimeline;
class NodeMutationObserverData final
: public GarbageCollected<NodeMutationObserverData> {
@@ -56,7 +57,7 @@ class NodeMutationObserverData final
void AddRegistration(MutationObserverRegistration* registration);
void RemoveRegistration(MutationObserverRegistration* registration);
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
private:
HeapVector<Member<MutationObserverRegistration>> registry_;
@@ -78,7 +79,7 @@ class GC_PLUGIN_IGNORE(
IsRareData::encode(is_rare_data)) {
DCHECK(!is_element_rare_data || is_rare_data);
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void TraceAfterDispatch(blink::Visitor*) const {}
enum {
@@ -200,6 +201,8 @@ class GC_PLUGIN_IGNORE("Manual dispatch implemented in NodeData.") NodeRareData
void TraceAfterDispatch(blink::Visitor*) const;
void FinalizeGarbageCollectedObject();
+ void RegisterScrollTimeline(ScrollTimeline*);
+ void UnregisterScrollTimeline(ScrollTimeline*);
protected:
explicit NodeRareData(NodeRenderingData* node_layout_data,
@@ -217,6 +220,9 @@ class GC_PLUGIN_IGNORE("Manual dispatch implemented in NodeData.") NodeRareData
Member<NodeListsNodeData> node_lists_;
Member<NodeMutationObserverData> mutation_observer_data_;
Member<FlatTreeNodeData> flat_tree_node_data_;
+ // Keeps strong scroll timeline pointers linked to this node to ensure
+ // the timelines are alive as long as the node is alive.
+ Member<HeapHashSet<Member<ScrollTimeline>>> scroll_timelines_;
DISALLOW_COPY_AND_ASSIGN(NodeRareData);
};
diff --git a/chromium/third_party/blink/renderer/core/dom/node_traversal.h b/chromium/third_party/blink/renderer/core/dom/node_traversal.h
index 3dd5e077aa9..764f7ac701b 100644
--- a/chromium/third_party/blink/renderer/core/dom/node_traversal.h
+++ b/chromium/third_party/blink/renderer/core/dom/node_traversal.h
@@ -62,8 +62,7 @@ class NodeTraversal {
// Like next, but skips children and starts with the next sibling.
CORE_EXPORT static Node* NextSkippingChildren(const Node&);
- CORE_EXPORT static Node* NextSkippingChildren(const Node&,
- const Node* stay_within);
+ static Node* NextSkippingChildren(const Node&, const Node* stay_within);
static Node* FirstWithin(const Node& current) { return current.firstChild(); }
@@ -75,9 +74,8 @@ class NodeTraversal {
static Node* Previous(const Node&, const Node* stay_within = nullptr);
// Like previous, but skips children and starts with the next sibling.
- CORE_EXPORT static Node* PreviousSkippingChildren(
- const Node&,
- const Node* stay_within = nullptr);
+ static Node* PreviousSkippingChildren(const Node&,
+ const Node* stay_within = nullptr);
// Like next, but visits parents after their children.
static Node* NextPostOrder(const Node&, const Node* stay_within = nullptr);
@@ -87,10 +85,12 @@ class NodeTraversal {
const Node* stay_within = nullptr);
// Pre-order traversal including the pseudo-elements.
- static Node* PreviousIncludingPseudo(const Node&,
- const Node* stay_within = nullptr);
- static Node* NextIncludingPseudo(const Node&,
- const Node* stay_within = nullptr);
+ CORE_EXPORT static Node* PreviousIncludingPseudo(
+ const Node&,
+ const Node* stay_within = nullptr);
+ CORE_EXPORT static Node* NextIncludingPseudo(
+ const Node&,
+ const Node* stay_within = nullptr);
static Node* NextIncludingPseudoSkippingChildren(
const Node&,
const Node* stay_within = nullptr);
diff --git a/chromium/third_party/blink/renderer/core/dom/nth_index_cache.cc b/chromium/third_party/blink/renderer/core/dom/nth_index_cache.cc
index 8f3bda8c688..8a0b76be174 100644
--- a/chromium/third_party/blink/renderer/core/dom/nth_index_cache.cc
+++ b/chromium/third_party/blink/renderer/core/dom/nth_index_cache.cc
@@ -257,7 +257,7 @@ NthIndexData::NthIndexData(ContainerNode& parent, const QualifiedName& type) {
count_ = count;
}
-void NthIndexData::Trace(Visitor* visitor) {
+void NthIndexData::Trace(Visitor* visitor) const {
visitor->Trace(element_index_map_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/nth_index_cache.h b/chromium/third_party/blink/renderer/core/dom/nth_index_cache.h
index 002e8c3f808..b3c38ed3740 100644
--- a/chromium/third_party/blink/renderer/core/dom/nth_index_cache.h
+++ b/chromium/third_party/blink/renderer/core/dom/nth_index_cache.h
@@ -25,7 +25,7 @@ class CORE_EXPORT NthIndexData final : public GarbageCollected<NthIndexData> {
unsigned NthOfTypeIndex(Element&) const;
unsigned NthLastOfTypeIndex(Element&) const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
HeapHashMap<Member<Element>, unsigned> element_index_map_;
diff --git a/chromium/third_party/blink/renderer/core/dom/presentation_attribute_style.cc b/chromium/third_party/blink/renderer/core/dom/presentation_attribute_style.cc
index 4548e75a33a..452c8adf643 100644
--- a/chromium/third_party/blink/renderer/core/dom/presentation_attribute_style.cc
+++ b/chromium/third_party/blink/renderer/core/dom/presentation_attribute_style.cc
@@ -59,7 +59,7 @@ static bool operator!=(const PresentationAttributeCacheKey& a,
struct PresentationAttributeCacheEntry final
: public GarbageCollected<PresentationAttributeCacheEntry> {
public:
- void Trace(Visitor* visitor) { visitor->Trace(value); }
+ void Trace(Visitor* visitor) const { visitor->Trace(value); }
PresentationAttributeCacheKey key;
Member<CSSPropertyValueSet> value;
diff --git a/chromium/third_party/blink/renderer/core/dom/processing_instruction.cc b/chromium/third_party/blink/renderer/core/dom/processing_instruction.cc
index 7dbe5566bec..739226d95f9 100644
--- a/chromium/third_party/blink/renderer/core/dom/processing_instruction.cc
+++ b/chromium/third_party/blink/renderer/core/dom/processing_instruction.cc
@@ -292,7 +292,7 @@ void ProcessingInstruction::RemovePendingSheet() {
style_engine_context_);
}
-void ProcessingInstruction::Trace(Visitor* visitor) {
+void ProcessingInstruction::Trace(Visitor* visitor) const {
visitor->Trace(sheet_);
visitor->Trace(listener_for_xslt_);
CharacterData::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/dom/processing_instruction.h b/chromium/third_party/blink/renderer/core/dom/processing_instruction.h
index 311382b610a..5c38d137c2b 100644
--- a/chromium/third_party/blink/renderer/core/dom/processing_instruction.h
+++ b/chromium/third_party/blink/renderer/core/dom/processing_instruction.h
@@ -41,7 +41,7 @@ class CORE_EXPORT ProcessingInstruction final : public CharacterData,
public:
ProcessingInstruction(Document&, const String& target, const String& data);
~ProcessingInstruction() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const String& target() const { return target_; }
const String& LocalHref() const { return local_href_; }
@@ -61,7 +61,7 @@ class CORE_EXPORT ProcessingInstruction final : public CharacterData,
// Detach event listener from its processing instruction.
virtual void Detach() = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
void SetEventListenerForXSLT(DetachableEventListener* listener) {
diff --git a/chromium/third_party/blink/renderer/core/dom/pseudo_element.cc b/chromium/third_party/blink/renderer/core/dom/pseudo_element.cc
index 2f7c2899e92..fd27ee5dc99 100644
--- a/chromium/third_party/blink/renderer/core/dom/pseudo_element.cc
+++ b/chromium/third_party/blink/renderer/core/dom/pseudo_element.cc
@@ -35,7 +35,7 @@
#include "third_party/blink/renderer/core/layout/generated_children.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_quote.h"
-#include "third_party/blink/renderer/core/layout/ng/list/list_marker.h"
+#include "third_party/blink/renderer/core/layout/list_marker.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style/content_data.h"
@@ -94,6 +94,17 @@ const AtomicString& PseudoElement::PseudoElementNameForEvents(
return PseudoElementTagName(pseudo_id).LocalName();
}
+bool PseudoElement::IsWebExposed(PseudoId pseudo_id, const Node* parent) {
+ switch (pseudo_id) {
+ case kPseudoIdMarker:
+ if (parent && parent->IsPseudoElement())
+ return RuntimeEnabledFeatures::CSSMarkerNestedPseudoElementEnabled();
+ return RuntimeEnabledFeatures::CSSMarkerPseudoElementEnabled();
+ default:
+ return true;
+ }
+}
+
PseudoElement::PseudoElement(Element* parent, PseudoId pseudo_id)
: Element(PseudoElementTagName(pseudo_id),
&parent->GetDocument(),
diff --git a/chromium/third_party/blink/renderer/core/dom/pseudo_element.h b/chromium/third_party/blink/renderer/core/dom/pseudo_element.h
index 2f38fb6a975..286d278c975 100644
--- a/chromium/third_party/blink/renderer/core/dom/pseudo_element.h
+++ b/chromium/third_party/blink/renderer/core/dom/pseudo_element.h
@@ -53,6 +53,7 @@ class CORE_EXPORT PseudoElement : public Element {
const ComputedStyle&);
static const AtomicString& PseudoElementNameForEvents(PseudoId);
+ static bool IsWebExposed(PseudoId, const Node*);
// Pseudo element are not allowed to be the inner node for hit testing. Find
// the closest ancestor which is a real dom node.
diff --git a/chromium/third_party/blink/renderer/core/dom/pseudo_element_data.h b/chromium/third_party/blink/renderer/core/dom/pseudo_element_data.h
index 23af73fd418..01f13551040 100644
--- a/chromium/third_party/blink/renderer/core/dom/pseudo_element_data.h
+++ b/chromium/third_party/blink/renderer/core/dom/pseudo_element_data.h
@@ -23,7 +23,7 @@ class PseudoElementData final : public GarbageCollected<PseudoElementData> {
bool HasPseudoElements() const;
void ClearPseudoElements();
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(generated_before_);
visitor->Trace(generated_after_);
visitor->Trace(generated_marker_);
diff --git a/chromium/third_party/blink/renderer/core/dom/range.cc b/chromium/third_party/blink/renderer/core/dom/range.cc
index 71bad3d8be8..5b0e9013efa 100644
--- a/chromium/third_party/blink/renderer/core/dom/range.cc
+++ b/chromium/third_party/blink/renderer/core/dom/range.cc
@@ -1782,7 +1782,7 @@ void Range::RemoveFromSelectionIfInDifferentRoot(Document& old_document) {
selection.ClearDocumentCachedRange();
}
-void Range::Trace(Visitor* visitor) {
+void Range::Trace(Visitor* visitor) const {
visitor->Trace(owner_document_);
visitor->Trace(start_);
visitor->Trace(end_);
diff --git a/chromium/third_party/blink/renderer/core/dom/range.h b/chromium/third_party/blink/renderer/core/dom/range.h
index e3d643b525d..47e208f3b17 100644
--- a/chromium/third_party/blink/renderer/core/dom/range.h
+++ b/chromium/third_party/blink/renderer/core/dom/range.h
@@ -170,7 +170,7 @@ class CORE_EXPORT Range final : public ScriptWrappable {
static Node* CheckNodeWOffset(Node*, unsigned offset, ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SetDocument(Document&);
diff --git a/chromium/third_party/blink/renderer/core/dom/range_boundary_point.h b/chromium/third_party/blink/renderer/core/dom/range_boundary_point.h
index 9026294bea5..d3180af1283 100644
--- a/chromium/third_party/blink/renderer/core/dom/range_boundary_point.h
+++ b/chromium/third_party/blink/renderer/core/dom/range_boundary_point.h
@@ -59,7 +59,7 @@ class RangeBoundaryPoint {
void InvalidateOffset();
void MarkValid() const;
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(container_node_);
visitor->Trace(child_before_boundary_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/range_test.cc b/chromium/third_party/blink/renderer/core/dom/range_test.cc
index 173d2e2e524..e08d4717703 100644
--- a/chromium/third_party/blink/renderer/core/dom/range_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/range_test.cc
@@ -222,7 +222,7 @@ TEST_F(RangeTest, updateOwnerDocumentIfNeeded) {
auto* range = MakeGarbageCollected<Range>(GetDocument(), Position(bar, 0),
Position(foo, 1));
- auto* another_document = MakeGarbageCollected<Document>();
+ auto* another_document = Document::CreateForTest();
another_document->AppendChild(foo);
EXPECT_EQ(bar, range->startContainer());
diff --git a/chromium/third_party/blink/renderer/core/dom/scriptable_document_parser.cc b/chromium/third_party/blink/renderer/core/dom/scriptable_document_parser.cc
index be1db3140f0..e8efc50c0a8 100644
--- a/chromium/third_party/blink/renderer/core/dom/scriptable_document_parser.cc
+++ b/chromium/third_party/blink/renderer/core/dom/scriptable_document_parser.cc
@@ -42,7 +42,7 @@ bool ScriptableDocumentParser::IsParsingAtLineNumber() const {
return IsParsing() && !IsWaitingForScripts() && !IsExecutingScript();
}
-void ScriptableDocumentParser::Trace(Visitor* visitor) {
+void ScriptableDocumentParser::Trace(Visitor* visitor) const {
visitor->Trace(inline_script_cache_handler_);
DecodedDataDocumentParser::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/scriptable_document_parser.h b/chromium/third_party/blink/renderer/core/dom/scriptable_document_parser.h
index 64afdc19a08..855791a9809 100644
--- a/chromium/third_party/blink/renderer/core/dom/scriptable_document_parser.h
+++ b/chromium/third_party/blink/renderer/core/dom/scriptable_document_parser.h
@@ -37,7 +37,7 @@ class SourceKeyedCachedMetadataHandler;
class CORE_EXPORT ScriptableDocumentParser : public DecodedDataDocumentParser {
public:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Only used by Document::open for deciding if its safe to act on a
// JavaScript document.open() call right now, or it should be ignored.
diff --git a/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.cc b/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.cc
index 7e54b479fe7..78c2ab118f7 100644
--- a/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.cc
+++ b/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.cc
@@ -64,7 +64,7 @@ ScriptedAnimationController::ScriptedAnimationController(LocalDOMWindow* window)
UpdateStateIfNeeded();
}
-void ScriptedAnimationController::Trace(Visitor* visitor) {
+void ScriptedAnimationController::Trace(Visitor* visitor) const {
ExecutionContextLifecycleStateObserver::Trace(visitor);
visitor->Trace(callback_collection_);
visitor->Trace(event_queue_);
@@ -107,18 +107,6 @@ bool ScriptedAnimationController::HasFrameCallback() const {
!vfc_execution_queue_.IsEmpty();
}
-ScriptedAnimationController::CallbackId
-ScriptedAnimationController::RegisterPostFrameCallback(
- FrameRequestCallbackCollection::FrameCallback* callback) {
- CallbackId id = callback_collection_.RegisterPostFrameCallback(callback);
- ScheduleAnimationIfNeeded();
- return id;
-}
-
-void ScriptedAnimationController::CancelPostFrameCallback(CallbackId id) {
- callback_collection_.CancelPostFrameCallback(id);
-}
-
void ScriptedAnimationController::RunTasks() {
Vector<base::OnceClosure> tasks;
tasks.swap(task_queue_);
@@ -245,7 +233,7 @@ void ScriptedAnimationController::ServiceScriptedAnimations(
if (RuntimeEnabledFeatures::RequestVideoFrameCallbackEnabled()) {
// Run the fulfilled HTMLVideoELement.requestVideoFrameCallback() callbacks.
- // See https://wicg.github.io/video-raf/.
+ // See https://wicg.github.io/video-rvfc/.
ExecuteVideoFrameCallbacks();
}
@@ -259,15 +247,6 @@ void ScriptedAnimationController::ServiceScriptedAnimations(
ScheduleAnimationIfNeeded();
}
-void ScriptedAnimationController::RunPostFrameCallbacks() {
- if (!callback_collection_.HasPostFrameCallback())
- return;
- DCHECK(current_frame_time_ms_ > 0.);
- DCHECK(current_frame_legacy_time_ms_ > 0.);
- callback_collection_.ExecutePostFrameCallbacks(current_frame_time_ms_,
- current_frame_legacy_time_ms_);
-}
-
void ScriptedAnimationController::EnqueueTask(base::OnceClosure task) {
task_queue_.push_back(std::move(task));
ScheduleAnimationIfNeeded();
@@ -302,21 +281,10 @@ void ScriptedAnimationController::ScheduleAnimationIfNeeded() {
if (!frame)
return;
- // If there is any pre-frame work to do, schedule an animation
- // unconditionally.
if (HasScheduledFrameTasks()) {
frame->View()->ScheduleAnimation();
return;
}
-
- // If there is post-frame work to do, only schedule an animation if we're not
- // currently running one -- if we're currently running an animation, then any
- // scheduled post-frame tasks will get run at the end of the current frame, so
- // no need to schedule another one.
- if (callback_collection_.HasPostFrameCallback() &&
- !frame->GetPage()->Animator().IsServicingAnimations()) {
- frame->View()->ScheduleAnimation();
- }
}
LocalDOMWindow* ScriptedAnimationController::GetWindow() const {
diff --git a/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.h b/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.h
index d3ac68f2b31..eea4b9d6df3 100644
--- a/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.h
+++ b/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.h
@@ -54,7 +54,7 @@ class CORE_EXPORT ScriptedAnimationController
explicit ScriptedAnimationController(LocalDOMWindow*);
~ScriptedAnimationController() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override {
return "ScriptedAnimationController";
}
@@ -73,10 +73,6 @@ class CORE_EXPORT ScriptedAnimationController
// Returns true if any callback is currently registered.
bool HasFrameCallback() const;
- CallbackId RegisterPostFrameCallback(
- FrameRequestCallbackCollection::FrameCallback*);
- void CancelPostFrameCallback(CallbackId);
-
// Queues up the execution of video.requestVideoFrameCallback() callbacks for
// a specific HTMLVideoELement, as part of the next rendering steps.
void ScheduleVideoFrameCallbacksExecution(ExecuteVfcCallback);
@@ -95,7 +91,6 @@ class CORE_EXPORT ScriptedAnimationController
// Invokes callbacks, dispatches events, etc. The order is defined by HTML:
// https://html.spec.whatwg.org/C/#event-loop-processing-model
void ServiceScriptedAnimations(base::TimeTicks monotonic_time_now);
- void RunPostFrameCallbacks();
void ContextLifecycleStateChanged(mojom::FrameLifecycleState) final;
void ContextDestroyed() final {}
diff --git a/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc b/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc
index 16323896e32..c7141f3a48e 100644
--- a/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc
+++ b/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc
@@ -78,7 +78,7 @@ ScriptedIdleTaskController::V8IdleTask::V8IdleTask(
V8IdleRequestCallback* callback)
: callback_(callback) {}
-void ScriptedIdleTaskController::V8IdleTask::Trace(Visitor* visitor) {
+void ScriptedIdleTaskController::V8IdleTask::Trace(Visitor* visitor) const {
visitor->Trace(callback_);
ScriptedIdleTaskController::IdleTask::Trace(visitor);
}
@@ -96,7 +96,7 @@ ScriptedIdleTaskController::ScriptedIdleTaskController(
ScriptedIdleTaskController::~ScriptedIdleTaskController() = default;
-void ScriptedIdleTaskController::Trace(Visitor* visitor) {
+void ScriptedIdleTaskController::Trace(Visitor* visitor) const {
visitor->Trace(idle_tasks_);
ExecutionContextLifecycleStateObserver::Trace(visitor);
}
@@ -241,12 +241,19 @@ void ScriptedIdleTaskController::ContextUnpaused() {
DCHECK(paused_);
paused_ = false;
- // Run any pending timeouts.
- Vector<CallbackId> pending_timeouts;
- pending_timeouts_.swap(pending_timeouts);
- for (auto& id : pending_timeouts)
- RunCallback(id, base::TimeTicks::Now(),
- IdleDeadline::CallbackType::kCalledByTimeout);
+ // Run any pending timeouts as separate tasks, since it's not allowed to
+ // execute script from lifecycle callbacks.
+ for (auto& id : pending_timeouts_) {
+ scoped_refptr<internal::IdleRequestCallbackWrapper> callback_wrapper =
+ internal::IdleRequestCallbackWrapper::Create(id, this);
+ GetExecutionContext()
+ ->GetTaskRunner(TaskType::kIdleTask)
+ ->PostTask(
+ FROM_HERE,
+ WTF::Bind(&internal::IdleRequestCallbackWrapper::TimeoutFired,
+ callback_wrapper));
+ }
+ pending_timeouts_.clear();
// Repost idle tasks for any remaining callbacks.
for (auto& idle_task : idle_tasks_) {
diff --git a/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h b/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h
index 82a8edee323..32fcd25ef57 100644
--- a/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h
+++ b/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h
@@ -40,7 +40,7 @@ class CORE_EXPORT ScriptedIdleTaskController
explicit ScriptedIdleTaskController(ExecutionContext*);
~ScriptedIdleTaskController() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override {
return "ScriptedIdleTaskController";
}
@@ -51,7 +51,7 @@ class CORE_EXPORT ScriptedIdleTaskController
// on idle. The tasks need to define what to do on idle in |invoke|.
class IdleTask : public GarbageCollected<IdleTask>, public NameClient {
public:
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
const char* NameInHeapSnapshot() const override { return "IdleTask"; }
virtual ~IdleTask() = default;
virtual void invoke(IdleDeadline*) = 0;
@@ -73,7 +73,7 @@ class CORE_EXPORT ScriptedIdleTaskController
~V8IdleTask() override = default;
void invoke(IdleDeadline*) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<V8IdleRequestCallback> callback_;
diff --git a/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc b/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc
index 911c7e2cf0d..6a5130c343c 100644
--- a/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc
@@ -6,10 +6,12 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_idle_request_callback.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_idle_request_options.h"
#include "third_party/blink/renderer/core/testing/null_execution_context.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/test/fake_task_runner.h"
#include "third_party/blink/renderer/platform/testing/scoped_scheduler_overrider.h"
namespace blink {
@@ -38,7 +40,7 @@ class MockScriptedIdleTaskControllerScheduler final : public ThreadScheduler {
}
scoped_refptr<base::SingleThreadTaskRunner> DeprecatedDefaultTaskRunner()
override {
- return nullptr;
+ return task_runner_;
}
void Shutdown() override {}
bool ShouldYieldForHighPriorityWork() override { return should_yield_; }
@@ -83,9 +85,15 @@ class MockScriptedIdleTaskControllerScheduler final : public ThreadScheduler {
void RunIdleTask() { std::move(idle_task_).Run(base::TimeTicks()); }
bool HasIdleTask() const { return !!idle_task_; }
+ void AdvanceTimeAndRun(base::TimeDelta delta) {
+ task_runner_->AdvanceTimeAndRun(delta);
+ }
+
private:
bool should_yield_;
Thread::IdleTask idle_task_;
+ scoped_refptr<scheduler::FakeTaskRunner> task_runner_ =
+ base::MakeRefCounted<scheduler::FakeTaskRunner>();
DISALLOW_COPY_AND_ASSIGN(MockScriptedIdleTaskControllerScheduler);
};
@@ -146,4 +154,36 @@ TEST_F(ScriptedIdleTaskControllerTest, DontRunCallbackWhenAskedToYield) {
EXPECT_TRUE(scheduler.HasIdleTask());
}
+TEST_F(ScriptedIdleTaskControllerTest, RunCallbacksAsyncWhenUnpaused) {
+ MockScriptedIdleTaskControllerScheduler scheduler(ShouldYield::YIELD);
+ ScopedSchedulerOverrider scheduler_overrider(&scheduler);
+ ScriptedIdleTaskController* controller =
+ ScriptedIdleTaskController::Create(execution_context_);
+
+ // Register an idle task with a deadline.
+ Persistent<MockIdleTask> idle_task(MakeGarbageCollected<MockIdleTask>());
+ IdleRequestOptions* options = IdleRequestOptions::Create();
+ options->setTimeout(1);
+ int id = controller->RegisterCallback(idle_task, options);
+ EXPECT_NE(0, id);
+
+ // Hitting the deadline while the frame is paused shouldn't cause any tasks to
+ // run.
+ controller->ContextLifecycleStateChanged(mojom::FrameLifecycleState::kPaused);
+ EXPECT_CALL(*idle_task, invoke(testing::_)).Times(0);
+ scheduler.AdvanceTimeAndRun(base::TimeDelta::FromMilliseconds(1));
+ testing::Mock::VerifyAndClearExpectations(idle_task);
+
+ // Even if we unpause, no tasks should run immediately.
+ EXPECT_CALL(*idle_task, invoke(testing::_)).Times(0);
+ controller->ContextLifecycleStateChanged(
+ mojom::FrameLifecycleState::kRunning);
+ testing::Mock::VerifyAndClearExpectations(idle_task);
+
+ // Idle callback should have been scheduled as an asynchronous task.
+ EXPECT_CALL(*idle_task, invoke(testing::_)).Times(1);
+ scheduler.AdvanceTimeAndRun(base::TimeDelta::FromMilliseconds(0));
+ testing::Mock::VerifyAndClearExpectations(idle_task);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/shadow_root.cc b/chromium/third_party/blink/renderer/core/dom/shadow_root.cc
index 230773200bf..443bafef7de 100644
--- a/chromium/third_party/blink/renderer/core/dom/shadow_root.cc
+++ b/chromium/third_party/blink/renderer/core/dom/shadow_root.cc
@@ -220,7 +220,7 @@ void ShadowRoot::SetNeedsDistributionRecalc() {
host().MarkAncestorsWithChildNeedsDistributionRecalc();
}
-void ShadowRoot::Trace(Visitor* visitor) {
+void ShadowRoot::Trace(Visitor* visitor) const {
visitor->Trace(style_sheet_list_);
visitor->Trace(slot_assignment_);
visitor->Trace(shadow_root_v0_);
diff --git a/chromium/third_party/blink/renderer/core/dom/shadow_root.h b/chromium/third_party/blink/renderer/core/dom/shadow_root.h
index 3ace8451c73..a296f9216c4 100644
--- a/chromium/third_party/blink/renderer/core/dom/shadow_root.h
+++ b/chromium/third_party/blink/renderer/core/dom/shadow_root.h
@@ -169,7 +169,7 @@ class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope {
style_sheet_list_ = style_sheet_list;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~ShadowRoot() override;
diff --git a/chromium/third_party/blink/renderer/core/dom/shadow_root_v0.h b/chromium/third_party/blink/renderer/core/dom/shadow_root_v0.h
index 974294b2ed8..4aae91a74b0 100644
--- a/chromium/third_party/blink/renderer/core/dom/shadow_root_v0.h
+++ b/chromium/third_party/blink/renderer/core/dom/shadow_root_v0.h
@@ -79,7 +79,7 @@ class CORE_EXPORT ShadowRootV0 final : public GarbageCollected<ShadowRootV0> {
void SetNeedsSelectFeatureSet() { needs_select_feature_set_ = true; }
SelectRuleFeatureSet& SelectFeatures() { return select_features_; }
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(shadow_root_);
visitor->Trace(descendant_insertion_points_);
visitor->Trace(node_to_insertion_points_);
diff --git a/chromium/third_party/blink/renderer/core/dom/slot_assignment.cc b/chromium/third_party/blink/renderer/core/dom/slot_assignment.cc
index 833615ffc61..8f177a44961 100644
--- a/chromium/third_party/blink/renderer/core/dom/slot_assignment.cc
+++ b/chromium/third_party/blink/renderer/core/dom/slot_assignment.cc
@@ -412,7 +412,7 @@ void SlotAssignment::ClearCandidateNodes(
candidate_assigned_slot_map_.RemoveAll(candidates);
}
-void SlotAssignment::Trace(Visitor* visitor) {
+void SlotAssignment::Trace(Visitor* visitor) const {
visitor->Trace(slots_);
visitor->Trace(slot_map_);
visitor->Trace(owner_);
diff --git a/chromium/third_party/blink/renderer/core/dom/slot_assignment.h b/chromium/third_party/blink/renderer/core/dom/slot_assignment.h
index 1a507643eb2..88778633d6f 100644
--- a/chromium/third_party/blink/renderer/core/dom/slot_assignment.h
+++ b/chromium/third_party/blink/renderer/core/dom/slot_assignment.h
@@ -49,7 +49,7 @@ class SlotAssignment final : public GarbageCollected<SlotAssignment> {
void CallSlotChangeAfterRemoved(HTMLSlotElement& slot);
void CallSlotChangeIfNeeded(HTMLSlotElement& slot, Node& child);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
bool NeedsAssignmentRecalc() const { return needs_assignment_recalc_; }
void SetNeedsAssignmentRecalc();
diff --git a/chromium/third_party/blink/renderer/core/dom/slot_assignment_engine.cc b/chromium/third_party/blink/renderer/core/dom/slot_assignment_engine.cc
index abd79ee482f..22bb66b5342 100644
--- a/chromium/third_party/blink/renderer/core/dom/slot_assignment_engine.cc
+++ b/chromium/third_party/blink/renderer/core/dom/slot_assignment_engine.cc
@@ -55,7 +55,7 @@ void SlotAssignmentEngine::RecalcSlotAssignments() {
DCHECK(shadow_roots_needing_recalc_.IsEmpty());
}
-void SlotAssignmentEngine::Trace(Visitor* visitor) {
+void SlotAssignmentEngine::Trace(Visitor* visitor) const {
visitor->Trace(shadow_roots_needing_recalc_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/slot_assignment_engine.h b/chromium/third_party/blink/renderer/core/dom/slot_assignment_engine.h
index 2991f9e7c8b..7c0d86250e6 100644
--- a/chromium/third_party/blink/renderer/core/dom/slot_assignment_engine.h
+++ b/chromium/third_party/blink/renderer/core/dom/slot_assignment_engine.h
@@ -29,7 +29,7 @@ class CORE_EXPORT SlotAssignmentEngine final
void RecalcSlotAssignments();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
HeapHashSet<WeakMember<ShadowRoot>> shadow_roots_needing_recalc_;
diff --git a/chromium/third_party/blink/renderer/core/dom/static_node_list.h b/chromium/third_party/blink/renderer/core/dom/static_node_list.h
index ec11d4c1c20..f0df16bfd9d 100644
--- a/chromium/third_party/blink/renderer/core/dom/static_node_list.h
+++ b/chromium/third_party/blink/renderer/core/dom/static_node_list.h
@@ -46,7 +46,7 @@ class StaticNodeTypeList final : public NodeList {
unsigned length() const override;
NodeType* item(unsigned index) const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<NodeType>> nodes_;
@@ -79,7 +79,7 @@ NodeType* StaticNodeTypeList<NodeType>::item(unsigned index) const {
}
template <typename NodeType>
-void StaticNodeTypeList<NodeType>::Trace(Visitor* visitor) {
+void StaticNodeTypeList<NodeType>::Trace(Visitor* visitor) const {
visitor->Trace(nodes_);
NodeList::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/static_range.cc b/chromium/third_party/blink/renderer/core/dom/static_range.cc
index 0015892f1bf..1643e26fabd 100644
--- a/chromium/third_party/blink/renderer/core/dom/static_range.cc
+++ b/chromium/third_party/blink/renderer/core/dom/static_range.cc
@@ -58,7 +58,7 @@ Range* StaticRange::toRange(ExceptionState& exception_state) const {
return range;
}
-void StaticRange::Trace(Visitor* visitor) {
+void StaticRange::Trace(Visitor* visitor) const {
visitor->Trace(owner_document_);
visitor->Trace(start_container_);
visitor->Trace(end_container_);
diff --git a/chromium/third_party/blink/renderer/core/dom/static_range.h b/chromium/third_party/blink/renderer/core/dom/static_range.h
index e7f39ebeb8e..5a232800f34 100644
--- a/chromium/third_party/blink/renderer/core/dom/static_range.h
+++ b/chromium/third_party/blink/renderer/core/dom/static_range.h
@@ -57,7 +57,7 @@ class CORE_EXPORT StaticRange final : public ScriptWrappable {
Range* toRange(ExceptionState& = ASSERT_NO_EXCEPTION) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Document> owner_document_; // Required by |toRange()|.
diff --git a/chromium/third_party/blink/renderer/core/dom/static_range_test.cc b/chromium/third_party/blink/renderer/core/dom/static_range_test.cc
index c46da517509..2bdded8ad16 100644
--- a/chromium/third_party/blink/renderer/core/dom/static_range_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/static_range_test.cc
@@ -33,7 +33,7 @@ class StaticRangeTest : public testing::Test {
};
void StaticRangeTest::SetUp() {
- document_ = MakeGarbageCollected<HTMLDocument>();
+ document_ = HTMLDocument::CreateForTest();
auto* html = MakeGarbageCollected<HTMLHtmlElement>(*document_);
html->AppendChild(MakeGarbageCollected<HTMLBodyElement>(*document_));
document_->AppendChild(html);
diff --git a/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_observer.cc b/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_observer.cc
index ce72d1f7c2c..7deddd69373 100644
--- a/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_observer.cc
+++ b/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_observer.cc
@@ -25,7 +25,7 @@ void SynchronousMutationObserver::SetDocument(Document* document) {
document_->SynchronousMutationObserverList().AddObserver(this);
}
-void SynchronousMutationObserver::Trace(Visitor* visitor) {
+void SynchronousMutationObserver::Trace(Visitor* visitor) const {
visitor->Trace(document_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_observer.h b/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_observer.h
index 6999e725ad8..82a35ed8d0e 100644
--- a/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_observer.h
+++ b/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_observer.h
@@ -81,7 +81,7 @@ class CORE_EXPORT SynchronousMutationObserver : public GarbageCollectedMixin {
Document* GetDocument() const { return document_; }
void SetDocument(Document*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
SynchronousMutationObserver() = default;
diff --git a/chromium/third_party/blink/renderer/core/dom/template_content_document_fragment.h b/chromium/third_party/blink/renderer/core/dom/template_content_document_fragment.h
index 767acd24947..f21e8216fbe 100644
--- a/chromium/third_party/blink/renderer/core/dom/template_content_document_fragment.h
+++ b/chromium/third_party/blink/renderer/core/dom/template_content_document_fragment.h
@@ -38,7 +38,7 @@ class TemplateContentDocumentFragment final : public DocumentFragment {
Element* Host() const { return host_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(host_);
DocumentFragment::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/text.cc b/chromium/third_party/blink/renderer/core/dom/text.cc
index d572463a14c..c5424bb2807 100644
--- a/chromium/third_party/blink/renderer/core/dom/text.cc
+++ b/chromium/third_party/blink/renderer/core/dom/text.cc
@@ -470,7 +470,7 @@ Text* Text::CloneWithData(Document& factory, const String& data) const {
return Create(factory, data);
}
-void Text::Trace(Visitor* visitor) {
+void Text::Trace(Visitor* visitor) const {
CharacterData::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/text.h b/chromium/third_party/blink/renderer/core/dom/text.h
index 519f53553de..dc6dab36b64 100644
--- a/chromium/third_party/blink/renderer/core/dom/text.h
+++ b/chromium/third_party/blink/renderer/core/dom/text.h
@@ -73,7 +73,7 @@ class CORE_EXPORT Text : public CharacterData {
bool CanContainRangeEndPoint() const final { return true; }
NodeType getNodeType() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String nodeName() const override;
diff --git a/chromium/third_party/blink/renderer/core/dom/tree_ordered_list.cc b/chromium/third_party/blink/renderer/core/dom/tree_ordered_list.cc
index 2b1b89d164c..21df7ccbf7f 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_ordered_list.cc
+++ b/chromium/third_party/blink/renderer/core/dom/tree_ordered_list.cc
@@ -63,7 +63,7 @@ void TreeOrderedList::Remove(const Node* node) {
nodes_.erase(const_cast<Node*>(node));
}
-void TreeOrderedList::Trace(Visitor* visitor) {
+void TreeOrderedList::Trace(Visitor* visitor) const {
visitor->Trace(nodes_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/tree_ordered_list.h b/chromium/third_party/blink/renderer/core/dom/tree_ordered_list.h
index 0cf13075075..057cf5b5a16 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_ordered_list.h
+++ b/chromium/third_party/blink/renderer/core/dom/tree_ordered_list.h
@@ -63,7 +63,7 @@ class TreeOrderedList final {
const_reverse_iterator rbegin() const { return nodes_.rbegin(); }
const_reverse_iterator rend() const { return nodes_.rend(); }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
HeapListHashSet<Member<Node>, 32> nodes_;
diff --git a/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.cc b/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.cc
index 0c426cfba52..425d212519a 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.cc
+++ b/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.cc
@@ -201,11 +201,11 @@ Element* TreeOrderedMap::GetCachedFirstElementWithoutAccessingNodeTree(
return entry->element;
}
-void TreeOrderedMap::Trace(Visitor* visitor) {
+void TreeOrderedMap::Trace(Visitor* visitor) const {
visitor->Trace(map_);
}
-void TreeOrderedMap::MapEntry::Trace(Visitor* visitor) {
+void TreeOrderedMap::MapEntry::Trace(Visitor* visitor) const {
visitor->Trace(element);
visitor->Trace(ordered_list);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.h b/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.h
index 939b145467c..0a1a03abd3a 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.h
+++ b/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.h
@@ -65,7 +65,7 @@ class TreeOrderedMap : public GarbageCollected<TreeOrderedMap> {
// TreeOrderedMap exactly.
Element* GetCachedFirstElementWithoutAccessingNodeTree(const AtomicString&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
#if DCHECK_IS_ON()
// While removing a ContainerNode, ID lookups won't be precise should the tree
@@ -99,7 +99,7 @@ class TreeOrderedMap : public GarbageCollected<TreeOrderedMap> {
explicit MapEntry(Element& first_element)
: element(first_element), count(1) {}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
Member<Element> element;
unsigned count;
diff --git a/chromium/third_party/blink/renderer/core/dom/tree_scope.cc b/chromium/third_party/blink/renderer/core/dom/tree_scope.cc
index f1aef848635..448e0ce19b3 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_scope.cc
+++ b/chromium/third_party/blink/renderer/core/dom/tree_scope.cc
@@ -610,7 +610,7 @@ void TreeScope::SetNeedsStyleRecalcForViewportUnits() {
}
}
-void TreeScope::Trace(Visitor* visitor) {
+void TreeScope::Trace(Visitor* visitor) const {
visitor->Trace(root_node_);
visitor->Trace(document_);
visitor->Trace(parent_tree_scope_);
diff --git a/chromium/third_party/blink/renderer/core/dom/tree_scope.h b/chromium/third_party/blink/renderer/core/dom/tree_scope.h
index b4b192c98ae..1487a3d76b0 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_scope.h
+++ b/chromium/third_party/blink/renderer/core/dom/tree_scope.h
@@ -130,7 +130,7 @@ class CORE_EXPORT TreeScope : public GarbageCollectedMixin {
Element* GetElementByAccessKey(const String& key) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
ScopedStyleResolver* GetScopedStyleResolver() const {
return scoped_style_resolver_.Get();
diff --git a/chromium/third_party/blink/renderer/core/dom/tree_scope_adopter_test.cc b/chromium/third_party/blink/renderer/core/dom/tree_scope_adopter_test.cc
index c57b6230bdf..6aaf589502f 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_scope_adopter_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/tree_scope_adopter_test.cc
@@ -15,8 +15,8 @@ namespace blink {
// TODO(hayato): It's hard to see what's happening in these tests.
// It would be better to refactor these tests.
TEST(TreeScopeAdopterTest, SimpleMove) {
- auto* doc1 = MakeGarbageCollected<Document>();
- auto* doc2 = MakeGarbageCollected<Document>();
+ auto* doc1 = Document::CreateForTest();
+ auto* doc2 = Document::CreateForTest();
Element* html1 = doc1->CreateRawElement(html_names::kHTMLTag);
doc1->AppendChild(html1);
@@ -43,8 +43,8 @@ TEST(TreeScopeAdopterTest, SimpleMove) {
}
TEST(TreeScopeAdopterTest, AdoptV1ShadowRootToV0Document) {
- auto* doc1 = MakeGarbageCollected<Document>();
- auto* doc2 = MakeGarbageCollected<Document>();
+ auto* doc1 = Document::CreateForTest();
+ auto* doc2 = Document::CreateForTest();
Element* html1 = doc1->CreateRawElement(html_names::kHTMLTag);
doc1->AppendChild(html1);
@@ -79,8 +79,8 @@ TEST(TreeScopeAdopterTest, AdoptV1ShadowRootToV0Document) {
}
TEST(TreeScopeAdopterTest, AdoptV0ShadowRootToV1Document) {
- auto* doc1 = MakeGarbageCollected<Document>();
- auto* doc2 = MakeGarbageCollected<Document>();
+ auto* doc1 = Document::CreateForTest();
+ auto* doc2 = Document::CreateForTest();
Element* html1 = doc1->CreateRawElement(html_names::kHTMLTag);
doc1->AppendChild(html1);
@@ -115,7 +115,7 @@ TEST(TreeScopeAdopterTest, AdoptV0ShadowRootToV1Document) {
}
TEST(TreeScopeAdopterTest, AdoptV0InV1ToNewDocument) {
- auto* old_doc = MakeGarbageCollected<Document>();
+ auto* old_doc = Document::CreateForTest();
Element* html = old_doc->CreateRawElement(html_names::kHTMLTag);
old_doc->AppendChild(html);
Element* host1 = old_doc->CreateRawElement(html_names::kDivTag);
@@ -134,7 +134,7 @@ TEST(TreeScopeAdopterTest, AdoptV0InV1ToNewDocument) {
// └──/shadow-root-v0
EXPECT_TRUE(old_doc->MayContainV0Shadow());
- auto* new_doc = MakeGarbageCollected<Document>();
+ auto* new_doc = Document::CreateForTest();
EXPECT_FALSE(new_doc->MayContainV0Shadow());
TreeScopeAdopter adopter(*host1, *new_doc);
diff --git a/chromium/third_party/blink/renderer/core/dom/tree_scope_test.cc b/chromium/third_party/blink/renderer/core/dom/tree_scope_test.cc
index c7d7a2e2803..4dcbf01ee5b 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_scope_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/tree_scope_test.cc
@@ -13,7 +13,7 @@
namespace blink {
TEST(TreeScopeTest, CommonAncestorOfSameTrees) {
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
EXPECT_EQ(document, document->CommonAncestorTreeScope(*document));
Element* html = document->CreateRawElement(html_names::kHTMLTag);
@@ -27,7 +27,7 @@ TEST(TreeScopeTest, CommonAncestorOfInclusiveTrees) {
// | : Common ancestor is document.
// shadowRoot
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
Element* html = document->CreateRawElement(html_names::kHTMLTag);
document->AppendChild(html);
ShadowRoot& shadow_root = html->CreateV0ShadowRootForTesting();
@@ -41,7 +41,7 @@ TEST(TreeScopeTest, CommonAncestorOfSiblingTrees) {
// / \ : Common ancestor is document.
// A B
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
Element* html = document->CreateRawElement(html_names::kHTMLTag);
document->AppendChild(html);
Element* head = document->CreateRawElement(html_names::kHeadTag);
@@ -63,7 +63,7 @@ TEST(TreeScopeTest, CommonAncestorOfTreesAtDifferentDepths) {
// /
// A
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
Element* html = document->CreateRawElement(html_names::kHTMLTag);
document->AppendChild(html);
Element* head = document->CreateRawElement(html_names::kHeadTag);
@@ -83,8 +83,8 @@ TEST(TreeScopeTest, CommonAncestorOfTreesAtDifferentDepths) {
}
TEST(TreeScopeTest, CommonAncestorOfTreesInDifferentDocuments) {
- auto* document1 = MakeGarbageCollected<Document>();
- auto* document2 = MakeGarbageCollected<Document>();
+ auto* document1 = Document::CreateForTest();
+ auto* document2 = Document::CreateForTest();
EXPECT_EQ(nullptr, document1->CommonAncestorTreeScope(*document2));
EXPECT_EQ(nullptr, document2->CommonAncestorTreeScope(*document1));
}
diff --git a/chromium/third_party/blink/renderer/core/dom/tree_walker.cc b/chromium/third_party/blink/renderer/core/dom/tree_walker.cc
index 605d031aca9..631859d21db 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_walker.cc
+++ b/chromium/third_party/blink/renderer/core/dom/tree_walker.cc
@@ -248,7 +248,7 @@ Children:
return nullptr;
}
-void TreeWalker::Trace(Visitor* visitor) {
+void TreeWalker::Trace(Visitor* visitor) const {
visitor->Trace(current_);
ScriptWrappable::Trace(visitor);
NodeIteratorBase::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/dom/tree_walker.h b/chromium/third_party/blink/renderer/core/dom/tree_walker.h
index ac007d9a210..3169039986b 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_walker.h
+++ b/chromium/third_party/blink/renderer/core/dom/tree_walker.h
@@ -51,7 +51,7 @@ class TreeWalker final : public ScriptWrappable, public NodeIteratorBase {
Node* previousNode(ExceptionState&);
Node* nextNode(ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Node* SetCurrent(Node*);
diff --git a/chromium/third_party/blink/renderer/core/dom/user_action_element_set.cc b/chromium/third_party/blink/renderer/core/dom/user_action_element_set.cc
index 1f19a82a2ef..e8e58588085 100644
--- a/chromium/third_party/blink/renderer/core/dom/user_action_element_set.cc
+++ b/chromium/third_party/blink/renderer/core/dom/user_action_element_set.cc
@@ -102,7 +102,7 @@ inline void UserActionElementSet::SetFlags(Element* element, unsigned flags) {
elements_.insert(element, flags);
}
-void UserActionElementSet::Trace(Visitor* visitor) {
+void UserActionElementSet::Trace(Visitor* visitor) const {
visitor->Trace(elements_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/user_action_element_set.h b/chromium/third_party/blink/renderer/core/dom/user_action_element_set.h
index 23181dacb0f..96b75d992c1 100644
--- a/chromium/third_party/blink/renderer/core/dom/user_action_element_set.h
+++ b/chromium/third_party/blink/renderer/core/dom/user_action_element_set.h
@@ -72,7 +72,7 @@ class UserActionElementSet final {
void DidDetach(Element&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
enum ElementFlags {
diff --git a/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.cc b/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.cc
index 3e92ef8c5d3..f7e50266302 100644
--- a/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.cc
+++ b/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.cc
@@ -250,7 +250,7 @@ void V0InsertionPoint::RemovedFrom(ContainerNode& insertion_point) {
HTMLElement::RemovedFrom(insertion_point);
}
-void V0InsertionPoint::Trace(Visitor* visitor) {
+void V0InsertionPoint::Trace(Visitor* visitor) const {
visitor->Trace(distributed_nodes_);
HTMLElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.h b/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.h
index a5c14c426b1..b7375fb9de9 100644
--- a/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.h
+++ b/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.h
@@ -83,7 +83,7 @@ class CORE_EXPORT V0InsertionPoint : public HTMLElement {
void RecalcStyleForInsertionPointChildren(const StyleRecalcChange);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
V0InsertionPoint(const QualifiedName&, Document&);
diff --git a/chromium/third_party/blink/renderer/core/dom/visited_link_state.cc b/chromium/third_party/blink/renderer/core/dom/visited_link_state.cc
index f9ef3adb366..f7580fe1417 100644
--- a/chromium/third_party/blink/renderer/core/dom/visited_link_state.cc
+++ b/chromium/third_party/blink/renderer/core/dom/visited_link_state.cc
@@ -136,7 +136,7 @@ EInsideLink VisitedLinkState::DetermineLinkStateSlowCase(
return EInsideLink::kInsideUnvisitedLink;
}
-void VisitedLinkState::Trace(Visitor* visitor) {
+void VisitedLinkState::Trace(Visitor* visitor) const {
visitor->Trace(document_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/visited_link_state.h b/chromium/third_party/blink/renderer/core/dom/visited_link_state.h
index 1f5f33108ce..7e2fd53488e 100644
--- a/chromium/third_party/blink/renderer/core/dom/visited_link_state.h
+++ b/chromium/third_party/blink/renderer/core/dom/visited_link_state.h
@@ -53,7 +53,7 @@ class VisitedLinkState final : public GarbageCollected<VisitedLinkState> {
return EInsideLink::kNotInsideLink;
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
const Document& GetDocument() const { return *document_; }
diff --git a/chromium/third_party/blink/renderer/core/dom/weak_identifier_map.h b/chromium/third_party/blink/renderer/core/dom/weak_identifier_map.h
index 9b6f9608965..a78305b0967 100644
--- a/chromium/third_party/blink/renderer/core/dom/weak_identifier_map.h
+++ b/chromium/third_party/blink/renderer/core/dom/weak_identifier_map.h
@@ -22,7 +22,7 @@ class WeakIdentifierMap final
public:
WeakIdentifierMap() = default;
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(object_to_identifier_);
visitor->Trace(identifier_to_object_);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/weak_identifier_map_test.cc b/chromium/third_party/blink/renderer/core/dom/weak_identifier_map_test.cc
index 46c8725a88c..fe6f60247f7 100644
--- a/chromium/third_party/blink/renderer/core/dom/weak_identifier_map_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/weak_identifier_map_test.cc
@@ -13,7 +13,7 @@ class WeakIdentifierMapTest : public ::testing::Test {
public:
class TestClass final : public GarbageCollected<TestClass> {
public:
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
};
using TestMap = WeakIdentifierMap<TestClass>;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/append_node_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/append_node_command.cc
index b8cf7542912..baa0db5594c 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/append_node_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/append_node_command.cc
@@ -53,7 +53,7 @@ void AppendNodeCommand::DoUnapply() {
node_->remove(IGNORE_EXCEPTION_FOR_TESTING);
}
-void AppendNodeCommand::Trace(Visitor* visitor) {
+void AppendNodeCommand::Trace(Visitor* visitor) const {
visitor->Trace(parent_);
visitor->Trace(node_);
SimpleEditCommand::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/append_node_command.h b/chromium/third_party/blink/renderer/core/editing/commands/append_node_command.h
index 63889881626..4e11cd1425b 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/append_node_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/append_node_command.h
@@ -34,7 +34,7 @@ class AppendNodeCommand final : public SimpleEditCommand {
public:
AppendNodeCommand(ContainerNode* parent, Node*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/apply_style_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
index 351fcdabeee..e4f9e6909e7 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
@@ -956,7 +956,7 @@ class InlineRunToApplyStyle {
return start && end && start->isConnected() && end->isConnected();
}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(start);
visitor->Trace(end);
visitor->Trace(past_end_node);
@@ -2094,7 +2094,7 @@ void ApplyStyleCommand::JoinChildTextNodes(ContainerNode* node,
UpdateStartEnd(EphemeralRange(new_start, new_end));
}
-void ApplyStyleCommand::Trace(Visitor* visitor) {
+void ApplyStyleCommand::Trace(Visitor* visitor) const {
visitor->Trace(style_);
visitor->Trace(start_);
visitor->Trace(end_);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/apply_style_command.h b/chromium/third_party/blink/renderer/core/editing/commands/apply_style_command.h
index f13afac64d8..daa86e76364 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/apply_style_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/apply_style_command.h
@@ -60,7 +60,7 @@ class CORE_EXPORT ApplyStyleCommand final : public CompositeEditCommand {
bool (*is_inline_element_to_remove)(const Element*),
InputEvent::InputType);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc
index 1675649b6d8..f112ca455f0 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc
@@ -39,12 +39,28 @@
#include "third_party/blink/renderer/core/html/html_quote_element.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/layout/layout_list_item.h"
+#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
namespace {
+base::Optional<int> GetListItemNumber(const Node* node) {
+ if (!node)
+ return base::nullopt;
+ // Because of elements with "display:list-item" has list item number,
+ // we use layout object instead of checking |HTMLLIElement|.
+ const LayoutObject* const layout_object = node->GetLayoutObject();
+ if (!layout_object)
+ return base::nullopt;
+ if (layout_object->IsLayoutNGListItem())
+ return ToLayoutNGListItem(layout_object)->Value();
+ if (layout_object->IsListItem())
+ return ToLayoutListItem(layout_object)->Value();
+ return base::nullopt;
+}
+
bool IsFirstVisiblePositionInNode(const VisiblePosition& visible_position,
const ContainerNode* node) {
if (visible_position.IsNull())
@@ -234,11 +250,10 @@ void BreakBlockquoteCommand::DoApply(EditingState* editing_state) {
// find the first one so that we know where to start numbering.
while (list_child_node && !IsA<HTMLLIElement>(*list_child_node))
list_child_node = list_child_node->nextSibling();
- if (IsListItem(list_child_node))
- SetNodeAttribute(
- &cloned_child, html_names::kStartAttr,
- AtomicString::Number(
- ToLayoutListItem(list_child_node->GetLayoutObject())->Value()));
+ if (auto list_item_number = GetListItemNumber(list_child_node)) {
+ SetNodeAttribute(&cloned_child, html_names::kStartAttr,
+ AtomicString::Number(*list_item_number));
+ }
}
AppendNode(&cloned_child, cloned_ancestor, editing_state);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
index c7e9e877fd1..08a19440da1 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
@@ -835,6 +835,25 @@ void CompositeEditCommand::DeleteInsignificantText(Text* text_node,
if (!text_layout_object)
return;
+ if (!text_layout_object->HasInlineFragments()) {
+ // whole text node is empty
+ // Removing a Text node won't dispatch synchronous events.
+ RemoveNode(text_node, ASSERT_NO_EDITING_ABORT);
+ return;
+ }
+ unsigned length = text_node->length();
+ if (start >= length || end > length)
+ return;
+
+ if (text_layout_object->IsInLayoutNGInlineFormattingContext()) {
+ const String string = PlainText(
+ EphemeralRange(Position(*text_node, start), Position(*text_node, end)));
+ if (string.IsEmpty())
+ return DeleteTextFromNode(text_node, start, end - start);
+ // Replace the text between start and end with collapsed version.
+ return ReplaceTextInNode(text_node, start, end - start, string);
+ }
+
Vector<InlineTextBox*> sorted_text_boxes;
wtf_size_t sorted_text_boxes_position = 0;
@@ -850,17 +869,6 @@ void CompositeEditCommand::DeleteInsignificantText(Text* text_node,
? 0
: sorted_text_boxes[sorted_text_boxes_position];
- if (!box) {
- // whole text node is empty
- // Removing a Text node won't dispatch synchronous events.
- RemoveNode(text_node, ASSERT_NO_EDITING_ABORT);
- return;
- }
-
- unsigned length = text_node->length();
- if (start >= length || end > length)
- return;
-
unsigned removed = 0;
InlineTextBox* prev_box = nullptr;
String str;
@@ -981,6 +989,14 @@ HTMLBRElement* CompositeEditCommand::InsertBlockPlaceholder(
return placeholder;
}
+static bool IsEmptyListItem(const LayoutBlockFlow& block_flow) {
+ if (block_flow.IsLayoutNGListItem())
+ return !block_flow.FirstChild();
+ if (block_flow.IsListItem())
+ return ToLayoutListItem(block_flow).IsEmpty();
+ return false;
+}
+
HTMLBRElement* CompositeEditCommand::AddBlockPlaceholderIfNeeded(
Element* container,
EditingState* editing_state) {
@@ -995,8 +1011,7 @@ HTMLBRElement* CompositeEditCommand::AddBlockPlaceholderIfNeeded(
// append the placeholder to make sure it follows
// any unrendered blocks
- if (block->Size().Height() == 0 ||
- (block->IsListItem() && ToLayoutListItem(block)->IsEmpty()))
+ if (block->Size().Height() == 0 || IsEmptyListItem(*block))
return AppendBlockPlaceholder(container, editing_state);
return nullptr;
@@ -2028,7 +2043,7 @@ bool CompositeEditCommand::IsNodeVisiblyContainedWithin(
return start_is_visually_same && end_is_visually_same;
}
-void CompositeEditCommand::Trace(Visitor* visitor) {
+void CompositeEditCommand::Trace(Visitor* visitor) const {
visitor->Trace(commands_);
visitor->Trace(starting_selection_);
visitor->Trace(ending_selection_);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command.h b/chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command.h
index 959858879af..23ff04a5a65 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command.h
@@ -82,7 +82,7 @@ class CORE_EXPORT CompositeEditCommand : public EditCommand {
virtual void AppliedEditing();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit CompositeEditCommand(Document&);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/delete_from_text_node_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/delete_from_text_node_command.cc
index 87275b86395..1a2209a988e 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/delete_from_text_node_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/delete_from_text_node_command.cc
@@ -67,7 +67,7 @@ void DeleteFromTextNodeCommand::DoUnapply() {
node_->insertData(offset_, text_, IGNORE_EXCEPTION_FOR_TESTING);
}
-void DeleteFromTextNodeCommand::Trace(Visitor* visitor) {
+void DeleteFromTextNodeCommand::Trace(Visitor* visitor) const {
visitor->Trace(node_);
SimpleEditCommand::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/delete_from_text_node_command.h b/chromium/third_party/blink/renderer/core/editing/commands/delete_from_text_node_command.h
index ca9fb0ebf4c..4df0636c1e0 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/delete_from_text_node_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/delete_from_text_node_command.h
@@ -36,7 +36,7 @@ class DeleteFromTextNodeCommand final : public SimpleEditCommand {
public:
DeleteFromTextNodeCommand(Text*, unsigned offset, unsigned count);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc
index 44c3eff34e5..7c266bc02c8 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc
@@ -1269,7 +1269,7 @@ bool DeleteSelectionCommand::PreservesTypingStyle() const {
return typing_style_;
}
-void DeleteSelectionCommand::Trace(Visitor* visitor) {
+void DeleteSelectionCommand::Trace(Visitor* visitor) const {
visitor->Trace(selection_to_delete_);
visitor->Trace(upstream_start_);
visitor->Trace(downstream_start_);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command.h b/chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command.h
index 66e8a82259d..c7787fef003 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command.h
@@ -47,7 +47,7 @@ class CORE_EXPORT DeleteSelectionCommand final : public CompositeEditCommand {
const DeleteSelectionOptions&,
InputEvent::InputType input_type = InputEvent::InputType::kNone);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/edit_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/edit_command.cc
index 2a02a559e80..df53c546d46 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/edit_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/edit_command.cc
@@ -101,7 +101,7 @@ void SimpleEditCommand::DoReapply() {
DoApply(&editing_state);
}
-void EditCommand::Trace(Visitor* visitor) {
+void EditCommand::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(parent_);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/edit_command.h b/chromium/third_party/blink/renderer/core/editing/commands/edit_command.h
index be659a9bbcd..2672b79f51d 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/edit_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/edit_command.h
@@ -55,7 +55,7 @@ class CORE_EXPORT EditCommand : public GarbageCollected<EditCommand> {
// |TypingCommand| will return the text of the last |commands_|.
virtual String TextDataForInputEvent() const;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
bool SelectionIsDirectional() const { return selection_is_directional_; }
void SetSelectionIsDirectional(bool is_directional) {
selection_is_directional_ = is_directional;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc b/chromium/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc
index e73728712a4..4a71147d353 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc
@@ -79,10 +79,6 @@ Node* HighestNodeToRemoveInPruning(Node* node, const Node* exclude_node) {
return nullptr;
}
-Element* EnclosingTableCell(const Position& p) {
- return To<Element>(EnclosingNodeOfType(p, IsTableCell));
-}
-
bool IsTableStructureNode(const Node* node) {
LayoutObject* layout_object = node->GetLayoutObject();
return (layout_object &&
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.h b/chromium/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.h
index f97d04b6bd6..94b6c10ba56 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.h
@@ -60,7 +60,6 @@ class SetSelectionOptions;
Node* HighestNodeToRemoveInPruning(Node*, const Node* exclude_node = nullptr);
-Element* EnclosingTableCell(const Position&);
Node* EnclosingEmptyListItem(const VisiblePosition&);
bool IsTableStructureNode(const Node*);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.cc
index 89293666dba..c423f98545e 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.cc
@@ -74,7 +74,7 @@ void InsertIntoTextNodeCommand::DoUnapply() {
node_->deleteData(offset_, text_.length(), IGNORE_EXCEPTION_FOR_TESTING);
}
-void InsertIntoTextNodeCommand::Trace(Visitor* visitor) {
+void InsertIntoTextNodeCommand::Trace(Visitor* visitor) const {
visitor->Trace(node_);
SimpleEditCommand::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.h b/chromium/third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.h
index ec07349ecd5..fb40fba606e 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.h
@@ -36,7 +36,7 @@ class InsertIntoTextNodeCommand final : public SimpleEditCommand {
public:
InsertIntoTextNodeCommand(Text* node, unsigned offset, const String& text);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_list_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/insert_list_command.cc
index e569395f451..69a21798f83 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_list_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_list_command.cc
@@ -733,7 +733,7 @@ void InsertListCommand::MoveParagraphOverPositionIntoEmptyListItem(
.Build()));
}
-void InsertListCommand::Trace(Visitor* visitor) {
+void InsertListCommand::Trace(Visitor* visitor) const {
CompositeEditCommand::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_list_command.h b/chromium/third_party/blink/renderer/core/editing/commands/insert_list_command.h
index 3f2d325c62d..74f44e0980c 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_list_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_list_command.h
@@ -41,7 +41,7 @@ class CORE_EXPORT InsertListCommand final : public CompositeEditCommand {
bool PreservesTypingStyle() const override { return true; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_node_before_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/insert_node_before_command.cc
index bbc8b431f9f..45035bfc579 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_node_before_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_node_before_command.cc
@@ -71,7 +71,7 @@ void InsertNodeBeforeCommand::DoUnapply() {
insert_child_->remove(IGNORE_EXCEPTION_FOR_TESTING);
}
-void InsertNodeBeforeCommand::Trace(Visitor* visitor) {
+void InsertNodeBeforeCommand::Trace(Visitor* visitor) const {
visitor->Trace(insert_child_);
visitor->Trace(ref_child_);
SimpleEditCommand::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_node_before_command.h b/chromium/third_party/blink/renderer/core/editing/commands/insert_node_before_command.h
index dc7c1459477..489d0564210 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_node_before_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_node_before_command.h
@@ -36,7 +36,7 @@ class InsertNodeBeforeCommand final : public SimpleEditCommand {
Node* child_to_insert_before,
ShouldAssumeContentIsAlwaysEditable);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.cc
index 8e5acdce6ee..61dc7e98aec 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.cc
@@ -610,7 +610,7 @@ void InsertParagraphSeparatorCommand::DoApply(EditingState* editing_state) {
ApplyStyleAfterInsertion(start_block, editing_state);
}
-void InsertParagraphSeparatorCommand::Trace(Visitor* visitor) {
+void InsertParagraphSeparatorCommand::Trace(Visitor* visitor) const {
visitor->Trace(style_);
CompositeEditCommand::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.h b/chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.h
index 9d0aceaeb32..7769466aad4 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.h
@@ -40,7 +40,7 @@ class CORE_EXPORT InsertParagraphSeparatorCommand final
bool use_default_paragraph_element = false,
bool paste_blockquote_into_unquoted_area = false);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/merge_identical_elements_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/merge_identical_elements_command.cc
index 5b3ace88ee5..f989169fa72 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/merge_identical_elements_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/merge_identical_elements_command.cc
@@ -84,7 +84,7 @@ void MergeIdenticalElementsCommand::DoUnapply() {
element1_->AppendChild(child.Release(), exception_state);
}
-void MergeIdenticalElementsCommand::Trace(Visitor* visitor) {
+void MergeIdenticalElementsCommand::Trace(Visitor* visitor) const {
visitor->Trace(element1_);
visitor->Trace(element2_);
visitor->Trace(at_child_);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/merge_identical_elements_command.h b/chromium/third_party/blink/renderer/core/editing/commands/merge_identical_elements_command.h
index 86187a52c09..aa657124927 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/merge_identical_elements_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/merge_identical_elements_command.h
@@ -34,7 +34,7 @@ class MergeIdenticalElementsCommand final : public SimpleEditCommand {
public:
MergeIdenticalElementsCommand(Element*, Element*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/remove_css_property_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/remove_css_property_command.cc
index 7b65cefbd68..9fd66c3b024 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/remove_css_property_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/remove_css_property_command.cc
@@ -67,7 +67,7 @@ void RemoveCSSPropertyCommand::DoUnapply() {
GetDocument().GetSecureContextMode(), IGNORE_EXCEPTION_FOR_TESTING);
}
-void RemoveCSSPropertyCommand::Trace(Visitor* visitor) {
+void RemoveCSSPropertyCommand::Trace(Visitor* visitor) const {
visitor->Trace(element_);
SimpleEditCommand::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/remove_css_property_command.h b/chromium/third_party/blink/renderer/core/editing/commands/remove_css_property_command.h
index 86957fdb523..c02fc8217a4 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/remove_css_property_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/remove_css_property_command.h
@@ -37,7 +37,7 @@ class RemoveCSSPropertyCommand final : public SimpleEditCommand {
public:
RemoveCSSPropertyCommand(Document&, Element*, CSSPropertyID);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~RemoveCSSPropertyCommand() override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/remove_node_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/remove_node_command.cc
index 136ac086313..231a8e58b79 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/remove_node_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/remove_node_command.cc
@@ -74,7 +74,7 @@ void RemoveNodeCommand::DoUnapply() {
parent->InsertBefore(node_.Get(), ref_child, IGNORE_EXCEPTION_FOR_TESTING);
}
-void RemoveNodeCommand::Trace(Visitor* visitor) {
+void RemoveNodeCommand::Trace(Visitor* visitor) const {
visitor->Trace(node_);
visitor->Trace(parent_);
visitor->Trace(ref_child_);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/remove_node_command.h b/chromium/third_party/blink/renderer/core/editing/commands/remove_node_command.h
index 7a5109953b1..2b6d06b36aa 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/remove_node_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/remove_node_command.h
@@ -34,7 +34,7 @@ class RemoveNodeCommand final : public SimpleEditCommand {
public:
explicit RemoveNodeCommand(Node*, ShouldAssumeContentIsAlwaysEditable);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/remove_node_preserving_children_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/remove_node_preserving_children_command.cc
index f3f0cdf3cf9..7e86829516d 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/remove_node_preserving_children_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/remove_node_preserving_children_command.cc
@@ -65,7 +65,7 @@ void RemoveNodePreservingChildrenCommand::DoApply(EditingState* editing_state) {
RemoveNode(node_, editing_state, should_assume_content_is_always_editable_);
}
-void RemoveNodePreservingChildrenCommand::Trace(Visitor* visitor) {
+void RemoveNodePreservingChildrenCommand::Trace(Visitor* visitor) const {
visitor->Trace(node_);
CompositeEditCommand::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/remove_node_preserving_children_command.h b/chromium/third_party/blink/renderer/core/editing/commands/remove_node_preserving_children_command.h
index 8efe5eca7dd..6ba69e5d19e 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/remove_node_preserving_children_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/remove_node_preserving_children_command.h
@@ -35,7 +35,7 @@ class RemoveNodePreservingChildrenCommand final : public CompositeEditCommand {
RemoveNodePreservingChildrenCommand(Node*,
ShouldAssumeContentIsAlwaysEditable);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/replace_node_with_span_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/replace_node_with_span_command.cc
index 27f7fa76f71..822cbe34923 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/replace_node_with_span_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/replace_node_with_span_command.cc
@@ -82,7 +82,7 @@ void ReplaceNodeWithSpanCommand::DoUnapply() {
*span_element_);
}
-void ReplaceNodeWithSpanCommand::Trace(Visitor* visitor) {
+void ReplaceNodeWithSpanCommand::Trace(Visitor* visitor) const {
visitor->Trace(element_to_replace_);
visitor->Trace(span_element_);
SimpleEditCommand::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/replace_node_with_span_command.h b/chromium/third_party/blink/renderer/core/editing/commands/replace_node_with_span_command.h
index 17520a58520..67b128c1e25 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/replace_node_with_span_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/replace_node_with_span_command.h
@@ -46,7 +46,7 @@ class ReplaceNodeWithSpanCommand final : public SimpleEditCommand {
HTMLSpanElement* SpanElement() { return span_element_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc
index f2ad9e8cd10..c668cc479d7 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc
@@ -1378,7 +1378,7 @@ void ReplaceSelectionCommand::DoApply(EditingState* editing_state) {
Element* block_start = EnclosingBlock(insertion_pos.AnchorNode());
if ((IsHTMLListElement(inserted_nodes.RefNode()) ||
(IsHTMLListElement(inserted_nodes.RefNode()->firstChild()))) &&
- block_start && block_start->GetLayoutObject()->IsListItem() &&
+ block_start && block_start->GetLayoutObject()->IsListItemIncludingNG() &&
HasEditableStyle(*block_start->parentNode())) {
inserted_nodes.SetRefNode(InsertAsListItems(
To<HTMLElement>(inserted_nodes.RefNode()), block_start, insertion_pos,
@@ -2104,7 +2104,7 @@ EphemeralRange ReplaceSelectionCommand::InsertedRange() const {
return EphemeralRange(start_of_inserted_range_, end_of_inserted_range_);
}
-void ReplaceSelectionCommand::Trace(Visitor* visitor) {
+void ReplaceSelectionCommand::Trace(Visitor* visitor) const {
visitor->Trace(start_of_inserted_content_);
visitor->Trace(end_of_inserted_content_);
visitor->Trace(insertion_style_);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command.h b/chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command.h
index 3913dccb1ce..aa1fdc8e547 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command.h
@@ -55,7 +55,7 @@ class CORE_EXPORT ReplaceSelectionCommand final : public CompositeEditCommand {
EphemeralRange InsertedRange() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/selection_for_undo_step.cc b/chromium/third_party/blink/renderer/core/editing/commands/selection_for_undo_step.cc
index 3246609fcd1..5cb701a6caf 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/selection_for_undo_step.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/selection_for_undo_step.cc
@@ -78,7 +78,7 @@ bool SelectionForUndoStep::IsValidFor(const Document& document) const {
return base_.IsValidFor(document) && extent_.IsValidFor(document);
}
-void SelectionForUndoStep::Trace(Visitor* visitor) {
+void SelectionForUndoStep::Trace(Visitor* visitor) const {
visitor->Trace(base_);
visitor->Trace(extent_);
}
@@ -112,7 +112,7 @@ SelectionForUndoStep::Builder::SetBaseAndExtentAsForwardSelection(
return *this;
}
-void SelectionForUndoStep::Builder::Trace(Visitor* visitor) {
+void SelectionForUndoStep::Builder::Trace(Visitor* visitor) const {
visitor->Trace(selection_);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/selection_for_undo_step.h b/chromium/third_party/blink/renderer/core/editing/commands/selection_for_undo_step.h
index bea92651ffb..45e57db8117 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/selection_for_undo_step.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/selection_for_undo_step.h
@@ -54,7 +54,7 @@ class SelectionForUndoStep final {
bool IsValidFor(const Document&) const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// |base_| and |extent_| can be disconnected from document.
@@ -84,7 +84,7 @@ class SelectionForUndoStep::Builder final {
Builder& SetBaseAndExtentAsForwardSelection(const Position& base,
const Position& extent);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
SelectionForUndoStep selection_;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/set_character_data_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/set_character_data_command.cc
index 876e2c11c63..f852a9e742c 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/set_character_data_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/set_character_data_command.cc
@@ -65,7 +65,7 @@ void SetCharacterDataCommand::DoUnapply() {
IGNORE_EXCEPTION_FOR_TESTING);
}
-void SetCharacterDataCommand::Trace(Visitor* visitor) {
+void SetCharacterDataCommand::Trace(Visitor* visitor) const {
visitor->Trace(node_);
SimpleEditCommand::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/set_character_data_command.h b/chromium/third_party/blink/renderer/core/editing/commands/set_character_data_command.h
index b8f4dbc62e7..c8ac0b90d6c 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/set_character_data_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/set_character_data_command.h
@@ -16,7 +16,7 @@ class CORE_EXPORT SetCharacterDataCommand final : public SimpleEditCommand {
unsigned count,
const String& text);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// EditCommand implementation
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/set_node_attribute_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/set_node_attribute_command.cc
index bb75d5e5532..8093442c4d9 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/set_node_attribute_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/set_node_attribute_command.cc
@@ -50,7 +50,7 @@ void SetNodeAttributeCommand::DoUnapply() {
old_value_ = g_null_atom;
}
-void SetNodeAttributeCommand::Trace(Visitor* visitor) {
+void SetNodeAttributeCommand::Trace(Visitor* visitor) const {
visitor->Trace(element_);
SimpleEditCommand::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/set_node_attribute_command.h b/chromium/third_party/blink/renderer/core/editing/commands/set_node_attribute_command.h
index e74601eb4e7..1919d31534b 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/set_node_attribute_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/set_node_attribute_command.h
@@ -37,7 +37,7 @@ class SetNodeAttributeCommand final : public SimpleEditCommand {
const QualifiedName& attribute,
const AtomicString& value);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/simplify_markup_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/simplify_markup_command.cc
index 20560ed9726..a0b213ee089 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/simplify_markup_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/simplify_markup_command.cc
@@ -154,7 +154,7 @@ int SimplifyMarkupCommand::PruneSubsequentAncestorsToRemove(
return past_last_node_to_remove - start_node_index - 1;
}
-void SimplifyMarkupCommand::Trace(Visitor* visitor) {
+void SimplifyMarkupCommand::Trace(Visitor* visitor) const {
visitor->Trace(first_node_);
visitor->Trace(node_after_last_);
CompositeEditCommand::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/simplify_markup_command.h b/chromium/third_party/blink/renderer/core/editing/commands/simplify_markup_command.h
index 0b0e7e87eab..bad83648967 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/simplify_markup_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/simplify_markup_command.h
@@ -34,7 +34,7 @@ class SimplifyMarkupCommand final : public CompositeEditCommand {
public:
SimplifyMarkupCommand(Document&, Node* first_node, Node* node_after_last);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/split_element_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/split_element_command.cc
index 9ae01d0c840..12791863b71 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/split_element_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/split_element_command.cc
@@ -102,7 +102,7 @@ void SplitElementCommand::DoReapply() {
ExecuteApply();
}
-void SplitElementCommand::Trace(Visitor* visitor) {
+void SplitElementCommand::Trace(Visitor* visitor) const {
visitor->Trace(element1_);
visitor->Trace(element2_);
visitor->Trace(at_child_);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/split_element_command.h b/chromium/third_party/blink/renderer/core/editing/commands/split_element_command.h
index 0ccc3ed85a0..d4cb90c6b5d 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/split_element_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/split_element_command.h
@@ -34,7 +34,7 @@ class SplitElementCommand final : public SimpleEditCommand {
public:
SplitElementCommand(Element*, Node* split_point_child);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command.cc
index 2d8c4ccc459..5708baeb8cd 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command.cc
@@ -101,7 +101,7 @@ void SplitTextNodeCommand::InsertText1AndTrimText2() {
GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
}
-void SplitTextNodeCommand::Trace(Visitor* visitor) {
+void SplitTextNodeCommand::Trace(Visitor* visitor) const {
visitor->Trace(text1_);
visitor->Trace(text2_);
SimpleEditCommand::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command.h b/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command.h
index 1f1f51529ba..145d28048e4 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command.h
@@ -36,7 +36,7 @@ class CORE_EXPORT SplitTextNodeCommand final : public SimpleEditCommand {
public:
SplitTextNodeCommand(Text*, int offset);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_containing_element_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_containing_element_command.cc
index 77a2d6368ac..07fb912f10f 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_containing_element_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_containing_element_command.cc
@@ -64,7 +64,7 @@ void SplitTextNodeContainingElementCommand::DoApply(EditingState*) {
SplitElement(parent, text_.Get());
}
-void SplitTextNodeContainingElementCommand::Trace(Visitor* visitor) {
+void SplitTextNodeContainingElementCommand::Trace(Visitor* visitor) const {
visitor->Trace(text_);
CompositeEditCommand::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_containing_element_command.h b/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_containing_element_command.h
index d6a2690b614..c76362d7299 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_containing_element_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_containing_element_command.h
@@ -35,7 +35,7 @@ class SplitTextNodeContainingElementCommand final
public:
SplitTextNodeContainingElementCommand(Text*, int offset);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/undo_stack.cc b/chromium/third_party/blink/renderer/core/editing/commands/undo_stack.cc
index 724afa5e2f6..e813d596e32 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/undo_stack.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/undo_stack.cc
@@ -90,7 +90,7 @@ void UndoStack::Clear() {
redo_stack_.clear();
}
-void UndoStack::Trace(Visitor* visitor) {
+void UndoStack::Trace(Visitor* visitor) const {
visitor->Trace(undo_stack_);
visitor->Trace(redo_stack_);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/undo_stack.h b/chromium/third_party/blink/renderer/core/editing/commands/undo_stack.h
index 5ccd7161951..01a36837913 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/undo_stack.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/undo_stack.h
@@ -73,7 +73,7 @@ class UndoStack final : public GarbageCollected<UndoStack> {
UndoStepRange UndoSteps() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
bool in_redo_;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/undo_step.cc b/chromium/third_party/blink/renderer/core/editing/commands/undo_step.cc
index e1a71e04ee7..4ab76ddd115 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/undo_step.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/undo_step.cc
@@ -139,7 +139,7 @@ void UndoStep::SetEndingSelection(const SelectionForUndoStep& selection) {
ending_root_editable_element_ = RootEditableElementOf(selection.Base());
}
-void UndoStep::Trace(Visitor* visitor) {
+void UndoStep::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(starting_selection_);
visitor->Trace(ending_selection_);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/undo_step.h b/chromium/third_party/blink/renderer/core/editing/commands/undo_step.h
index e609a4b8d4d..43e3fa0621b 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/undo_step.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/undo_step.h
@@ -73,7 +73,7 @@ class UndoStep final : public GarbageCollected<UndoStep> {
uint64_t SequenceNumber() const { return sequence_number_; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<Document> document_;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/wrap_contents_in_dummy_span_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/wrap_contents_in_dummy_span_command.cc
index ee81b0a6045..19d733cf41c 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/wrap_contents_in_dummy_span_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/wrap_contents_in_dummy_span_command.cc
@@ -78,7 +78,7 @@ void WrapContentsInDummySpanCommand::DoReapply() {
ExecuteApply();
}
-void WrapContentsInDummySpanCommand::Trace(Visitor* visitor) {
+void WrapContentsInDummySpanCommand::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(dummy_span_);
SimpleEditCommand::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/wrap_contents_in_dummy_span_command.h b/chromium/third_party/blink/renderer/core/editing/commands/wrap_contents_in_dummy_span_command.h
index b4a9276966a..17984352d1d 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/wrap_contents_in_dummy_span_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/wrap_contents_in_dummy_span_command.h
@@ -36,7 +36,7 @@ class WrapContentsInDummySpanCommand final : public SimpleEditCommand {
public:
explicit WrapContentsInDummySpanCommand(Element*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoApply(EditingState*) override;
diff --git a/chromium/third_party/blink/renderer/core/editing/dom_selection.cc b/chromium/third_party/blink/renderer/core/editing/dom_selection.cc
index c690a203b05..7d5f0b5eeb1 100644
--- a/chromium/third_party/blink/renderer/core/editing/dom_selection.cc
+++ b/chromium/third_party/blink/renderer/core/editing/dom_selection.cc
@@ -671,8 +671,9 @@ void DOMSelection::addRange(Range* new_range) {
// TODO(tkent): "Merge the ranges if they intersect" was removed. We show a
// warning message for a while, and continue to collect the usage data.
// <https://code.google.com/p/chromium/issues/detail?id=353069>.
- Deprecation::CountDeprecation(tree_scope_->GetDocument(),
- WebFeature::kSelectionAddRangeIntersect);
+ Deprecation::CountDeprecation(
+ tree_scope_->GetDocument().GetExecutionContext(),
+ WebFeature::kSelectionAddRangeIntersect);
}
// https://www.w3.org/TR/selection-api/#dom-selection-deletefromdocument
@@ -853,7 +854,7 @@ void DOMSelection::AddConsoleWarning(const String& message) {
}
}
-void DOMSelection::Trace(Visitor* visitor) {
+void DOMSelection::Trace(Visitor* visitor) const {
visitor->Trace(tree_scope_);
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/editing/dom_selection.h b/chromium/third_party/blink/renderer/core/editing/dom_selection.h
index f3a9e52c76e..0805b441652 100644
--- a/chromium/third_party/blink/renderer/core/editing/dom_selection.h
+++ b/chromium/third_party/blink/renderer/core/editing/dom_selection.h
@@ -100,7 +100,7 @@ class CORE_EXPORT DOMSelection final : public ScriptWrappable,
// Microsoft Selection Object API
void empty();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool IsAvailable() const;
diff --git a/chromium/third_party/blink/renderer/core/editing/drag_caret.cc b/chromium/third_party/blink/renderer/core/editing/drag_caret.cc
index d29c09c69fb..5d7d3fee4d4 100644
--- a/chromium/third_party/blink/renderer/core/editing/drag_caret.cc
+++ b/chromium/third_party/blink/renderer/core/editing/drag_caret.cc
@@ -92,7 +92,7 @@ void DragCaret::NodeWillBeRemoved(Node& node) {
Clear();
}
-void DragCaret::Trace(Visitor* visitor) {
+void DragCaret::Trace(Visitor* visitor) const {
visitor->Trace(position_);
SynchronousMutationObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/drag_caret.h b/chromium/third_party/blink/renderer/core/editing/drag_caret.h
index ca85fa1e99b..41f39419d49 100644
--- a/chromium/third_party/blink/renderer/core/editing/drag_caret.h
+++ b/chromium/third_party/blink/renderer/core/editing/drag_caret.h
@@ -66,7 +66,7 @@ class DragCaret final : public GarbageCollected<DragCaret>,
void SetCaretPosition(const PositionWithAffinity&);
void Clear() { SetCaretPosition(PositionWithAffinity()); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Implementations of |SynchronousMutationObserver|
diff --git a/chromium/third_party/blink/renderer/core/editing/editing_style.cc b/chromium/third_party/blink/renderer/core/editing/editing_style.cc
index dcc0eeebd82..622c1e23b3b 100644
--- a/chromium/third_party/blink/renderer/core/editing/editing_style.cc
+++ b/chromium/third_party/blink/renderer/core/editing/editing_style.cc
@@ -192,7 +192,9 @@ class HTMLElementEquivalent : public GarbageCollected<HTMLElementEquivalent> {
virtual bool ValueIsPresentInStyle(HTMLElement*, CSSPropertyValueSet*) const;
virtual void AddToStyle(Element*, EditingStyle*) const;
- virtual void Trace(Visitor* visitor) { visitor->Trace(identifier_value_); }
+ virtual void Trace(Visitor* visitor) const {
+ visitor->Trace(identifier_value_);
+ }
protected:
const CSSPropertyID property_id_;
@@ -266,7 +268,7 @@ class HTMLTextDecorationEquivalent final : public HTMLElementEquivalent {
bool PropertyExistsInStyle(const CSSPropertyValueSet*) const override;
bool ValueIsPresentInStyle(HTMLElement*, CSSPropertyValueSet*) const override;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
HTMLElementEquivalent::Trace(visitor);
}
};
@@ -320,7 +322,7 @@ class HTMLAttributeEquivalent : public HTMLElementEquivalent {
virtual const CSSValue* AttributeValueAsCSSValue(Element*) const;
inline const QualifiedName& AttributeName() const { return attr_name_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
HTMLElementEquivalent::Trace(visitor);
}
@@ -380,7 +382,7 @@ class HTMLFontSizeEquivalent final : public HTMLAttributeEquivalent {
const CSSValue* AttributeValueAsCSSValue(Element*) const override;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
HTMLAttributeEquivalent::Trace(visitor);
}
};
@@ -1591,7 +1593,7 @@ int EditingStyle::LegacyFontSize(Document* document) const {
kAlwaysUseLegacyFontSize);
}
-void EditingStyle::Trace(Visitor* visitor) {
+void EditingStyle::Trace(Visitor* visitor) const {
visitor->Trace(mutable_style_);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/editing_style.h b/chromium/third_party/blink/renderer/core/editing/editing_style.h
index 23815f2e154..240cb4bd201 100644
--- a/chromium/third_party/blink/renderer/core/editing/editing_style.h
+++ b/chromium/third_party/blink/renderer/core/editing/editing_style.h
@@ -157,7 +157,7 @@ class CORE_EXPORT EditingStyle final : public GarbageCollected<EditingStyle> {
bool important,
SecureContextMode);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
static EditingTriState SelectionHasStyle(const LocalFrame&,
CSSPropertyID,
const String& value);
diff --git a/chromium/third_party/blink/renderer/core/editing/editing_utilities.cc b/chromium/third_party/blink/renderer/core/editing/editing_utilities.cc
index d198257b409..97ae8719049 100644
--- a/chromium/third_party/blink/renderer/core/editing/editing_utilities.cc
+++ b/chromium/third_party/blink/renderer/core/editing/editing_utilities.cc
@@ -1079,6 +1079,13 @@ Element* TableElementJustBefore(
visible_position);
}
+Element* EnclosingTableCell(const Position& p) {
+ return To<Element>(EnclosingNodeOfType(p, IsTableCell));
+}
+Element* EnclosingTableCell(const PositionInFlatTree& p) {
+ return To<Element>(EnclosingNodeOfType(p, IsTableCell));
+}
+
Element* TableElementJustAfter(const VisiblePosition& visible_position) {
Position downstream(
MostForwardCaretPosition(visible_position.DeepEquivalent()));
@@ -1115,7 +1122,8 @@ bool IsHTMLListElement(const Node* n) {
}
bool IsListItem(const Node* n) {
- return n && n->GetLayoutObject() && n->GetLayoutObject()->IsListItem();
+ return n && n->GetLayoutObject() &&
+ n->GetLayoutObject()->IsListItemIncludingNG();
}
bool IsPresentationalHTMLElement(const Node* node) {
@@ -1700,7 +1708,7 @@ static scoped_refptr<Image> ImageFromNode(const Node& node) {
if (layout_object->IsCanvas()) {
return To<HTMLCanvasElement>(const_cast<Node&>(node))
- .Snapshot(kFrontBuffer, kPreferNoAcceleration);
+ .Snapshot(kFrontBuffer);
}
if (!layout_object->IsImage())
diff --git a/chromium/third_party/blink/renderer/core/editing/editing_utilities.h b/chromium/third_party/blink/renderer/core/editing/editing_utilities.h
index 5597e7282e2..3abc2ad2985 100644
--- a/chromium/third_party/blink/renderer/core/editing/editing_utilities.h
+++ b/chromium/third_party/blink/renderer/core/editing/editing_utilities.h
@@ -123,6 +123,8 @@ HTMLSpanElement* TabSpanElement(const Node*);
Element* TableElementJustAfter(const VisiblePosition&);
CORE_EXPORT Element* TableElementJustBefore(const VisiblePosition&);
CORE_EXPORT Element* TableElementJustBefore(const VisiblePositionInFlatTree&);
+Element* EnclosingTableCell(const Position&);
+Element* EnclosingTableCell(const PositionInFlatTree&);
template <typename Strategy>
ContainerNode* ParentCrossingShadowBoundaries(const Node&);
diff --git a/chromium/third_party/blink/renderer/core/editing/editor.cc b/chromium/third_party/blink/renderer/core/editing/editor.cc
index c594c5bfdb5..02b5f192133 100644
--- a/chromium/third_party/blink/renderer/core/editing/editor.cc
+++ b/chromium/third_party/blink/renderer/core/editing/editor.cc
@@ -820,7 +820,7 @@ Range* Editor::FindRangeOfString(
EphemeralRangeInFlatTree::RangeOfContents(document);
EphemeralRangeInFlatTree search_range(document_range);
- bool forward = !(options & kBackwards);
+ const bool forward = !(options & kBackwards);
bool start_in_reference_range = false;
if (reference_range.IsNotNull()) {
start_in_reference_range = options & kStartInSelection;
@@ -846,7 +846,10 @@ Range* Editor::FindRangeOfString(
// the reference range, find again. Build a selection with the found range
// to remove collapsed whitespace. Compare ranges instead of selection
// objects to ignore the way that the current selection was made.
- if (result_range && start_in_reference_range &&
+ const bool find_next_if_selection_matches =
+ !(options & kDontFindNextIfSelectionMatches);
+ if (find_next_if_selection_matches && result_range &&
+ start_in_reference_range &&
NormalizeRange(EphemeralRangeInFlatTree(result_range)) ==
reference_range) {
if (forward)
@@ -908,7 +911,7 @@ void Editor::ReplaceSelection(const String& text) {
InputEvent::InputType::kInsertReplacementText);
}
-void Editor::Trace(Visitor* visitor) {
+void Editor::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(last_edit_command_);
visitor->Trace(undo_stack_);
diff --git a/chromium/third_party/blink/renderer/core/editing/editor.h b/chromium/third_party/blink/renderer/core/editing/editor.h
index e6bcb5dd76a..23acef1bd05 100644
--- a/chromium/third_party/blink/renderer/core/editing/editor.h
+++ b/chromium/third_party/blink/renderer/core/editing/editor.h
@@ -221,7 +221,7 @@ class CORE_EXPORT Editor final : public GarbageCollected<Editor> {
void SetTypingStyle(EditingStyle*);
void ClearTypingStyle();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void RevealSelectionAfterEditingOperation(
const mojom::blink::ScrollAlignment& = ScrollAlignment::ToEdgeIfNeeded());
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.cc b/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.cc
index a0a94dd76bd..92d13e13c4c 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.cc
+++ b/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.cc
@@ -28,6 +28,10 @@ namespace {
// Returns true if the search should ignore the given |node|'s contents. In
// other words, we don't need to recurse into the node's children.
bool ShouldIgnoreContents(const Node& node) {
+ if (node.getNodeType() == Node::kCommentNode) {
+ return true;
+ }
+
const auto* element = DynamicTo<HTMLElement>(node);
if (!element)
return false;
@@ -244,8 +248,10 @@ void FindBuffer::CollectTextUntilBlockBoundary(
}
// Move the node so we wouldn't encounter this node or its descendants
// later.
- if (!IsA<HTMLWBRElement>(To<HTMLElement>(*node)))
+ if (IsA<HTMLElement>(*node) &&
+ !IsA<HTMLWBRElement>(To<HTMLElement>(*node))) {
buffer_.push_back(kMaxCodepoint);
+ }
node = FlatTreeTraversal::NextSkippingChildren(*node);
continue;
}
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/find_options.h b/chromium/third_party/blink/renderer/core/editing/finder/find_options.h
index 60582843d84..0d85e61cd80 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/find_options.h
+++ b/chromium/third_party/blink/renderer/core/editing/finder/find_options.h
@@ -37,6 +37,7 @@ enum FindOptionFlag {
// TODO(yosin) Once find UI works on flat tree and it doesn't use
// |rangeOfString()|, we should get rid of |FindAPICall| enum member.
kFindAPICall = 1 << 5, // Used for Window.find or execCommand('find')
+ kDontFindNextIfSelectionMatches = 1 << 6,
};
typedef unsigned FindOptions;
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.cc b/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.cc
index 996895991f7..b77573118ee 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.cc
+++ b/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.cc
@@ -49,7 +49,7 @@ class FindTaskController::FindTask final : public GarbageCollected<FindTask> {
}
}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(controller_);
visitor->Trace(document_);
}
@@ -105,7 +105,7 @@ class FindTaskController::FindTask final : public GarbageCollected<FindTask> {
blink::FindOptions find_options =
(options_->forward ? 0 : kBackwards) |
(options_->match_case ? 0 : kCaseInsensitive) |
- (options_->find_next ? 0 : kStartInSelection);
+ (options_->new_session ? kStartInSelection : 0);
auto start_time = base::TimeTicks::Now();
while (search_start != search_end) {
@@ -320,7 +320,7 @@ void FindTaskController::DidFindMatch(int identifier, Range* result_range) {
text_finder_->DidFindMatch(identifier, current_match_count_, result_range);
}
-void FindTaskController::Trace(Visitor* visitor) {
+void FindTaskController::Trace(Visitor* visitor) const {
visitor->Trace(owner_frame_);
visitor->Trace(text_finder_);
visitor->Trace(find_task_);
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.h b/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.h
index 9a240d89c6e..9e8d4277746 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.h
+++ b/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.h
@@ -79,7 +79,7 @@ class CORE_EXPORT FindTaskController final
// DidFinishTask.
class FindTask;
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
void ResetLastFindRequestCompletedWithNoMatches();
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/text_finder.cc b/chromium/third_party/blink/renderer/core/editing/finder/text_finder.cc
index 8198fbac2a7..f63f1d27be1 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/text_finder.cc
+++ b/chromium/third_party/blink/renderer/core/editing/finder/text_finder.cc
@@ -69,7 +69,7 @@ namespace blink {
TextFinder::FindMatch::FindMatch(Range* range, int ordinal)
: range_(range), ordinal_(ordinal) {}
-void TextFinder::FindMatch::Trace(Visitor* visitor) {
+void TextFinder::FindMatch::Trace(Visitor* visitor) const {
visitor->Trace(range_);
}
@@ -135,7 +135,7 @@ bool TextFinder::Find(int identifier,
const mojom::blink::FindOptions& options,
bool wrap_within_frame,
bool* active_now) {
- if (!options.find_next) {
+ if (options.new_session) {
// This find-in-page is redone due to the frame finishing loading.
// If we can, just reuse the old active match;
if (options.force && active_match_) {
@@ -169,17 +169,20 @@ bool TextFinder::Find(int identifier,
(options.forward ? 0 : kBackwards) |
(options.match_case ? 0 : kCaseInsensitive) |
(wrap_within_frame ? kWrapAround : 0) |
- (options.find_next ? 0 : kStartInSelection);
+ (options.find_next_if_selection_matches
+ ? 0
+ : kDontFindNextIfSelectionMatches) |
+ (options.new_session ? kStartInSelection : 0);
active_match_ = Editor::FindRangeOfString(
*OwnerFrame().GetFrame()->GetDocument(), search_text,
EphemeralRangeInFlatTree(active_match_.Get()), find_options);
if (!active_match_) {
- if (current_active_match_frame_ && !options.find_next)
+ if (current_active_match_frame_ && options.new_session)
should_locate_active_rect_ = true;
- // If we're finding next the next active match might not be in the current
+ // In an existing session the next active match might not be in
// frame. In this case we don't want to clear the matches cache.
- if (!options.find_next)
+ if (options.new_session)
ClearFindMatchesCache();
InvalidatePaintForTickmarks();
@@ -213,7 +216,7 @@ bool TextFinder::Find(int identifier,
// Set this frame as focused.
OwnerFrame().ViewImpl()->SetFocusedFrame(&OwnerFrame());
- if (!options.find_next || active_selection || !is_active) {
+ if (options.new_session || active_selection || !is_active) {
// This is either an initial Find operation, a Find-next from a new
// start point due to a selection, or new matches were found during
// Find-next due to DOM alteration (that couldn't be set as active), so
@@ -759,7 +762,7 @@ void TextFinder::InvalidatePaintForTickmarks() {
OwnerFrame().GetFrame()->ContentLayoutObject()->InvalidatePaintForTickmarks();
}
-void TextFinder::Trace(Visitor* visitor) {
+void TextFinder::Trace(Visitor* visitor) const {
visitor->Trace(owner_frame_);
visitor->Trace(find_task_controller_);
visitor->Trace(active_match_);
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/text_finder.h b/chromium/third_party/blink/renderer/core/editing/finder/text_finder.h
index ebffeb7cfaf..a32357fbad8 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/text_finder.h
+++ b/chromium/third_party/blink/renderer/core/editing/finder/text_finder.h
@@ -122,7 +122,7 @@ class CORE_EXPORT TextFinder final : public GarbageCollected<TextFinder> {
public:
FindMatch(Range*, int ordinal);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
Member<Range> range_;
@@ -134,7 +134,7 @@ class CORE_EXPORT TextFinder final : public GarbageCollected<TextFinder> {
FloatRect rect_;
};
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// Notifies the delegate about a new selection rect.
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/text_finder_test.cc b/chromium/third_party/blink/renderer/core/editing/finder/text_finder_test.cc
index f41fd4e4c0c..00050f2cb53 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/text_finder_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/finder/text_finder_test.cc
@@ -108,7 +108,7 @@ TEST_F(TextFinderTest, FindTextSimple) {
EXPECT_EQ(text_node, active_match->endContainer());
EXPECT_EQ(10u, active_match->endOffset());
- find_options->find_next = true;
+ find_options->new_session = false;
ASSERT_TRUE(GetTextFinder().Find(identifier, search_text, *find_options,
wrap_within_frame));
active_match = GetTextFinder().ActiveMatch();
@@ -142,7 +142,7 @@ TEST_F(TextFinderTest, FindTextSimple) {
EXPECT_EQ(text_node, active_match->endContainer());
EXPECT_EQ(20u, active_match->endOffset());
- find_options->find_next = true;
+ find_options->new_session = false;
ASSERT_TRUE(GetTextFinder().Find(identifier, search_text, *find_options,
wrap_within_frame));
active_match = GetTextFinder().ActiveMatch();
@@ -248,7 +248,7 @@ TEST_F(TextFinderTest, FindTextInShadowDOM) {
EXPECT_EQ(text_in_i_element, active_match->endContainer());
EXPECT_EQ(3u, active_match->endOffset());
- find_options->find_next = true;
+ find_options->new_session = false;
ASSERT_TRUE(GetTextFinder().Find(identifier, search_text, *find_options,
wrap_within_frame));
active_match = GetTextFinder().ActiveMatch();
@@ -291,7 +291,7 @@ TEST_F(TextFinderTest, FindTextInShadowDOM) {
EXPECT_EQ(text_in_b_element, active_match->endContainer());
EXPECT_EQ(3u, active_match->endOffset());
- find_options->find_next = true;
+ find_options->new_session = false;
ASSERT_TRUE(GetTextFinder().Find(identifier, search_text, *find_options,
wrap_within_frame));
active_match = GetTextFinder().ActiveMatch();
@@ -502,7 +502,7 @@ TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOM) {
GetTextFinder().StartScopingStringMatches(identifier, search_text,
*find_options);
- find_options->find_next = true;
+ find_options->new_session = false;
ASSERT_TRUE(GetTextFinder().Find(identifier, search_text, *find_options,
wrap_within_frame, &active_now));
EXPECT_TRUE(active_now);
@@ -525,7 +525,7 @@ TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOM) {
EXPECT_EQ(8u, active_match->endOffset());
// Restart full search and check that added text is found.
- find_options->find_next = false;
+ find_options->new_session = true;
GetTextFinder().ResetMatchCount();
GetTextFinder().CancelPendingScopingEffort();
GetTextFinder().StartScopingStringMatches(identifier, search_text,
@@ -559,7 +559,7 @@ TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOMAfterNoMatches) {
GetTextFinder().StartScopingStringMatches(identifier, search_text,
*find_options);
- find_options->find_next = true;
+ find_options->new_session = false;
ASSERT_FALSE(GetTextFinder().Find(identifier, search_text, *find_options,
wrap_within_frame, &active_now));
EXPECT_FALSE(active_now);
@@ -579,7 +579,7 @@ TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOMAfterNoMatches) {
EXPECT_EQ(8u, active_match->endOffset());
// Restart full search and check that added text is found.
- find_options->find_next = false;
+ find_options->new_session = true;
GetTextFinder().ResetMatchCount();
GetTextFinder().CancelPendingScopingEffort();
GetTextFinder().StartScopingStringMatches(identifier, search_text,
@@ -717,4 +717,20 @@ TEST_F(TextFinderTest, BeforeMatchEventRemoveElement) {
// TODO(jarhar): Write more tests here once we decide on a behavior here:
// https://github.com/WICG/display-locking/issues/150
+TEST_F(TextFinderTest, FindTextAcrossCommentNode) {
+ GetDocument().body()->setInnerHTML(
+ "<span>abc</span><!--comment--><span>def</span>");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
+
+ int identifier = 0;
+ WebString search_text(String("abcdef"));
+ auto find_options = mojom::blink::FindOptions::New();
+ find_options->run_synchronously_for_testing = true;
+ bool wrap_within_frame = true;
+
+ EXPECT_TRUE(GetTextFinder().Find(identifier, search_text, *find_options,
+ wrap_within_frame));
+ EXPECT_TRUE(GetTextFinder().ActiveMatch());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/frame_caret.cc b/chromium/third_party/blink/renderer/core/editing/frame_caret.cc
index 8ef1bffd0f3..38359f4d181 100644
--- a/chromium/third_party/blink/renderer/core/editing/frame_caret.cc
+++ b/chromium/third_party/blink/renderer/core/editing/frame_caret.cc
@@ -61,7 +61,7 @@ FrameCaret::FrameCaret(LocalFrame& frame,
FrameCaret::~FrameCaret() = default;
-void FrameCaret::Trace(Visitor* visitor) {
+void FrameCaret::Trace(Visitor* visitor) const {
visitor->Trace(selection_editor_);
visitor->Trace(frame_);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/frame_caret.h b/chromium/third_party/blink/renderer/core/editing/frame_caret.h
index 2f65e692d18..ca5f3a71e5b 100644
--- a/chromium/third_party/blink/renderer/core/editing/frame_caret.h
+++ b/chromium/third_party/blink/renderer/core/editing/frame_caret.h
@@ -89,7 +89,7 @@ class CORE_EXPORT FrameCaret final : public GarbageCollected<FrameCaret> {
void RecreateCaretBlinkTimerForTesting(
scoped_refptr<base::SingleThreadTaskRunner>);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
friend class FrameCaretTest;
diff --git a/chromium/third_party/blink/renderer/core/editing/frame_selection.cc b/chromium/third_party/blink/renderer/core/editing/frame_selection.cc
index 902dfcae37a..981bc83ab22 100644
--- a/chromium/third_party/blink/renderer/core/editing/frame_selection.cc
+++ b/chromium/third_party/blink/renderer/core/editing/frame_selection.cc
@@ -425,10 +425,14 @@ bool FrameSelection::Modify(SelectionModifyAlteration alter,
// Provides details to accessibility about the selection change throughout the
// current call stack.
base::AutoReset<bool> is_being_modified_resetter(&is_being_modified_, true);
+ const PlatformWordBehavior platform_word_behavior =
+ frame_->GetEditor().Behavior().ShouldSkipSpaceWhenMovingRight()
+ ? PlatformWordBehavior::kWordSkipSpaces
+ : PlatformWordBehavior::kWordDontSkipSpaces;
ScopedBlinkAXEventIntent scoped_blink_ax_event_intent(
BlinkAXEventIntent::FromModifiedSelection(
alter, direction, granularity, set_selection_by,
- selection_modifier.DirectionOfSelection()),
+ selection_modifier.DirectionOfSelection(), platform_word_behavior),
&GetDocument());
// For MacOS only selection is directionless at the beginning.
@@ -1119,7 +1123,7 @@ void FrameSelection::ShowTreeForThis() const {
#endif
-void FrameSelection::Trace(Visitor* visitor) {
+void FrameSelection::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(layout_selection_);
visitor->Trace(selection_editor_);
diff --git a/chromium/third_party/blink/renderer/core/editing/frame_selection.h b/chromium/third_party/blink/renderer/core/editing/frame_selection.h
index 34ba4c42c30..baac8129f46 100644
--- a/chromium/third_party/blink/renderer/core/editing/frame_selection.h
+++ b/chromium/third_party/blink/renderer/core/editing/frame_selection.h
@@ -287,7 +287,7 @@ class CORE_EXPORT FrameSelection final
LayoutSelectionStatus ComputeLayoutSelectionStatus(
const NGInlineCursor& cursor) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class CaretDisplayItemClientTest;
diff --git a/chromium/third_party/blink/renderer/core/editing/frame_selection_test.cc b/chromium/third_party/blink/renderer/core/editing/frame_selection_test.cc
index fa8bf166d20..0f6029166e5 100644
--- a/chromium/third_party/blink/renderer/core/editing/frame_selection_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/frame_selection_test.cc
@@ -143,7 +143,8 @@ TEST_F(FrameSelectionTest, PaintCaretShouldNotLayout) {
frame_rect.SetHeight(frame_rect.Height() + 1);
GetDummyPageHolder().GetFrameView().SetFrameRect(frame_rect);
}
- auto paint_controller = std::make_unique<PaintController>();
+ auto paint_controller =
+ std::make_unique<PaintController>(PaintController::kTransient);
{
GraphicsContext context(*paint_controller);
paint_controller->UpdateCurrentPaintChunkProperties(
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/edit_context.cc b/chromium/third_party/blink/renderer/core/editing/ime/edit_context.cc
index bb5164cc9fc..32578077127 100644
--- a/chromium/third_party/blink/renderer/core/editing/ime/edit_context.cc
+++ b/chromium/third_party/blink/renderer/core/editing/ime/edit_context.cc
@@ -6,7 +6,6 @@
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/public/web/web_ime_text_span.h"
#include "third_party/blink/public/web/web_range.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_edit_context_init.h"
#include "third_party/blink/renderer/core/css/css_color_value.h"
@@ -21,6 +20,7 @@
#include "third_party/blink/renderer/platform/geometry/double_rect.h"
#include "third_party/blink/renderer/platform/wtf/decimal.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "ui/base/ime/ime_text_span.h"
namespace blink {
@@ -74,7 +74,18 @@ bool EditContext::IsEditContextActive() const {
return true;
}
-bool EditContext::IsInputPanelPolicyManual() const {
+ui::mojom::VirtualKeyboardVisibilityRequest
+EditContext::GetLastVirtualKeyboardVisibilityRequest() const {
+ return GetInputMethodController().GetLastVirtualKeyboardVisibilityRequest();
+}
+
+void EditContext::SetVirtualKeyboardVisibilityRequest(
+ ui::mojom::VirtualKeyboardVisibilityRequest vk_visibility_request) {
+ GetInputMethodController().SetVirtualKeyboardVisibilityRequest(
+ vk_visibility_request);
+}
+
+bool EditContext::IsVirtualKeyboardPolicyManual() const {
return GetInputMethodController()
.GetActiveEditContext()
->inputPanelPolicy() == "manual";
@@ -109,7 +120,7 @@ void EditContext::DispatchTextUpdateEvent(const String& text,
}
void EditContext::DispatchTextFormatEvent(
- const WebVector<WebImeTextSpan>& ime_text_spans) {
+ const WebVector<ui::ImeTextSpan>& ime_text_spans) {
// Loop through the vector and fire textformatupdate event for individual text
// spans as there could be multiple formats in the spans.
// TODO(snianu): Try to accumulate the ranges with similar formats and fire
@@ -123,13 +134,13 @@ void EditContext::DispatchTextFormatEvent(
ime_text_span.end_offset + composition_range_start_;
switch (ime_text_span.thickness) {
- case ui::mojom::ImeTextSpanThickness::kNone:
+ case ui::ImeTextSpan::Thickness::kNone:
underline_style = "None";
break;
- case ui::mojom::ImeTextSpanThickness::kThin:
+ case ui::ImeTextSpan::Thickness::kThin:
underline_style = "Thin";
break;
- case ui::mojom::ImeTextSpanThickness::kThick:
+ case ui::ImeTextSpan::Thickness::kThick:
underline_style = "Thick";
break;
default:
@@ -364,7 +375,7 @@ void EditContext::GetLayoutBounds(WebRect* web_control_bounds,
bool EditContext::SetComposition(
const WebString& text,
- const WebVector<WebImeTextSpan>& ime_text_spans,
+ const WebVector<ui::ImeTextSpan>& ime_text_spans,
const WebRange& replacement_range,
int selection_start,
int selection_end) {
@@ -401,7 +412,7 @@ bool EditContext::SetComposition(
bool EditContext::SetCompositionFromExistingText(
int composition_start,
int composition_end,
- const WebVector<WebImeTextSpan>& ime_text_spans) {
+ const WebVector<ui::ImeTextSpan>& ime_text_spans) {
if (composition_start < 0 || composition_end < 0)
return false;
@@ -434,7 +445,7 @@ bool EditContext::SetCompositionFromExistingText(
}
bool EditContext::CommitText(const WebString& text,
- const WebVector<WebImeTextSpan>& ime_text_spans,
+ const WebVector<ui::ImeTextSpan>& ime_text_spans,
const WebRange& replacement_range,
int relative_caret_position) {
// Fire textupdate and textformatupdate events to JS.
@@ -545,6 +556,9 @@ WebTextInputInfo EditContext::TextInputInfo() {
info.action = GetEditContextEnterKeyHint();
info.input_mode = GetInputModeOfEditContext();
info.type = TextInputType();
+ info.virtual_keyboard_policy = IsVirtualKeyboardPolicyManual()
+ ? ui::mojom::VirtualKeyboardPolicy::MANUAL
+ : ui::mojom::VirtualKeyboardPolicy::AUTO;
info.value = text();
info.flags = TextInputFlags();
info.selection_start = selection_start_;
@@ -581,7 +595,7 @@ WebRange EditContext::GetSelectionOffsets() const {
return WebRange(selection_start_, selection_end_);
}
-void EditContext::Trace(Visitor* visitor) {
+void EditContext::Trace(Visitor* visitor) const {
ActiveScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/edit_context.h b/chromium/third_party/blink/renderer/core/editing/ime/edit_context.h
index 74e27ec35a2..b8e4ef8c2c7 100644
--- a/chromium/third_party/blink/renderer/core/editing/ime/edit_context.h
+++ b/chromium/third_party/blink/renderer/core/editing/ime/edit_context.h
@@ -9,12 +9,12 @@
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/public/platform/web_text_input_mode.h"
#include "third_party/blink/public/platform/web_text_input_type.h"
-#include "third_party/blink/public/web/web_ime_text_span.h"
#include "third_party/blink/public/web/web_input_method_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
+#include "ui/base/ime/ime_text_span.h"
namespace blink {
@@ -141,16 +141,16 @@ class CORE_EXPORT EditContext final : public EventTargetWithInlineData,
// ActiveScriptWrappable overrides.
bool HasPendingActivity() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// WebInputMethodController overrides.
bool SetComposition(const WebString& text,
- const WebVector<WebImeTextSpan>& ime_text_spans,
+ const WebVector<ui::ImeTextSpan>& ime_text_spans,
const WebRange& replacement_range,
int selection_start,
int selection_end) override;
bool CommitText(const WebString& text,
- const WebVector<WebImeTextSpan>& ime_text_spans,
+ const WebVector<ui::ImeTextSpan>& ime_text_spans,
const WebRange& replacement_range,
int relative_caret_position) override;
bool FinishComposingText(
@@ -173,10 +173,17 @@ class CORE_EXPORT EditContext final : public EventTargetWithInlineData,
bool SetCompositionFromExistingText(
int composition_start,
int composition_end,
- const WebVector<WebImeTextSpan>& ime_text_spans);
+ const WebVector<ui::ImeTextSpan>& ime_text_spans);
- bool IsInputPanelPolicyManual() const override;
+ bool IsVirtualKeyboardPolicyManual() const override;
bool IsEditContextActive() const override;
+ // Returns whether show()/hide() API is called from virtualkeyboard or not.
+ ui::mojom::VirtualKeyboardVisibilityRequest
+ GetLastVirtualKeyboardVisibilityRequest() const override;
+ // Sets the VirtualKeyboard visibility request(show/hide/none).
+ void SetVirtualKeyboardVisibilityRequest(
+ ui::mojom::VirtualKeyboardVisibilityRequest vk_visibility_request)
+ override;
// Called from WebLocalFrame for English compositions
// such as shape-writing, handwriting panels etc.
// Extends the current selection range and removes the
@@ -206,7 +213,8 @@ class CORE_EXPORT EditContext final : public EventTargetWithInlineData,
// TextFormatUpdateEvent (e.g. backgroundColor, textDecoration, etc.). The
// consumer of the EditContext should update their view accordingly to provide
// the user with visual feedback as prescribed by the software keyboard.
- void DispatchTextFormatEvent(const WebVector<WebImeTextSpan>& ime_text_spans);
+ void DispatchTextFormatEvent(
+ const WebVector<ui::ImeTextSpan>& ime_text_spans);
// The textupdate event will be fired on the EditContext when user input has
// resulted in characters being applied to the editable region. The event
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span.cc b/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span.cc
index 359a07258ff..9b13c0aa578 100644
--- a/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span.cc
+++ b/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span.cc
@@ -5,7 +5,8 @@
#include "third_party/blink/renderer/core/editing/ime/ime_text_span.h"
#include <algorithm>
-#include "third_party/blink/public/web/web_ime_text_span.h"
+#include "ui/base/ime/ime_text_span.h"
+#include "ui/base/ime/mojom/ime_types.mojom-blink.h"
namespace blink {
@@ -19,6 +20,7 @@ ImeTextSpan::ImeTextSpan(Type type,
const Color& background_color,
const Color& suggestion_highlight_color,
bool remove_on_finish_composing,
+ bool interim_char_selection,
const Vector<String>& suggestions)
: type_(type),
underline_color_(underline_color),
@@ -28,6 +30,7 @@ ImeTextSpan::ImeTextSpan(Type type,
background_color_(background_color),
suggestion_highlight_color_(suggestion_highlight_color),
remove_on_finish_composing_(remove_on_finish_composing),
+ interim_char_selection_(interim_char_selection),
suggestions_(suggestions) {
// Sanitize offsets by ensuring a valid range corresponding to the last
// possible position.
@@ -49,33 +52,70 @@ Vector<String> ConvertStdVectorOfStdStringsToVectorOfStrings(
return output;
}
-ImeTextSpan::Type ConvertWebTypeToType(WebImeTextSpan::Type type) {
+ImeTextSpan::Type ConvertUiTypeToType(ui::ImeTextSpan::Type type) {
switch (type) {
- case WebImeTextSpan::Type::kComposition:
+ case ui::ImeTextSpan::Type::kComposition:
return ImeTextSpan::Type::kComposition;
- case WebImeTextSpan::Type::kSuggestion:
+ case ui::ImeTextSpan::Type::kSuggestion:
return ImeTextSpan::Type::kSuggestion;
- case WebImeTextSpan::Type::kMisspellingSuggestion:
+ case ui::ImeTextSpan::Type::kMisspellingSuggestion:
return ImeTextSpan::Type::kMisspellingSuggestion;
+ case ui::ImeTextSpan::Type::kAutocorrect:
+ return ImeTextSpan::Type::kAutocorrect;
}
NOTREACHED();
return ImeTextSpan::Type::kComposition;
}
+ui::mojom::ImeTextSpanThickness ConvertUiThicknessToThickness(
+ ui::ImeTextSpan::Thickness thickness) {
+ switch (thickness) {
+ case ui::ImeTextSpan::Thickness::kNone:
+ return ui::mojom::ImeTextSpanThickness::kNone;
+ case ui::ImeTextSpan::Thickness::kThin:
+ return ui::mojom::ImeTextSpanThickness::kThin;
+ case ui::ImeTextSpan::Thickness::kThick:
+ return ui::mojom::ImeTextSpanThickness::kThick;
+ }
+
+ NOTREACHED();
+ return ui::mojom::ImeTextSpanThickness::kNone;
+}
+
+ui::mojom::ImeTextSpanUnderlineStyle ConvertUiUnderlineToUnderline(
+ ui::ImeTextSpan::UnderlineStyle underline) {
+ switch (underline) {
+ case ui::ImeTextSpan::UnderlineStyle::kNone:
+ return ui::mojom::ImeTextSpanUnderlineStyle::kNone;
+ case ui::ImeTextSpan::UnderlineStyle::kSolid:
+ return ui::mojom::ImeTextSpanUnderlineStyle::kSolid;
+ case ui::ImeTextSpan::UnderlineStyle::kDot:
+ return ui::mojom::ImeTextSpanUnderlineStyle::kDot;
+ case ui::ImeTextSpan::UnderlineStyle::kDash:
+ return ui::mojom::ImeTextSpanUnderlineStyle::kDash;
+ case ui::ImeTextSpan::UnderlineStyle::kSquiggle:
+ return ui::mojom::ImeTextSpanUnderlineStyle::kSquiggle;
+ }
+
+ NOTREACHED();
+ return ui::mojom::ImeTextSpanUnderlineStyle::kNone;
+}
+
} // namespace
-ImeTextSpan::ImeTextSpan(const WebImeTextSpan& ime_text_span)
- : ImeTextSpan(ConvertWebTypeToType(ime_text_span.type),
+ImeTextSpan::ImeTextSpan(const ui::ImeTextSpan& ime_text_span)
+ : ImeTextSpan(ConvertUiTypeToType(ime_text_span.type),
ime_text_span.start_offset,
ime_text_span.end_offset,
Color(ime_text_span.underline_color),
- ime_text_span.thickness,
- ime_text_span.underline_style,
+ ConvertUiThicknessToThickness(ime_text_span.thickness),
+ ConvertUiUnderlineToUnderline(ime_text_span.underline_style),
Color(ime_text_span.text_color),
Color(ime_text_span.background_color),
Color(ime_text_span.suggestion_highlight_color),
ime_text_span.remove_on_finish_composing,
+ ime_text_span.interim_char_selection,
ConvertStdVectorOfStdStringsToVectorOfStrings(
ime_text_span.suggestions)) {}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span.h b/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span.h
index 5e8f42e51bf..84dd57c9bf5 100644
--- a/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span.h
+++ b/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span.h
@@ -33,15 +33,22 @@
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "ui/base/ime/mojom/ime_types.mojom-blink-forward.h"
-namespace blink {
+namespace ui {
+struct ImeTextSpan;
+} // namespace ui
-struct WebImeTextSpan;
+namespace blink {
class CORE_EXPORT ImeTextSpan {
DISALLOW_NEW();
public:
- enum class Type { kComposition, kSuggestion, kMisspellingSuggestion };
+ enum class Type {
+ kComposition,
+ kSuggestion,
+ kMisspellingSuggestion,
+ kAutocorrect,
+ };
ImeTextSpan(Type,
unsigned start_offset,
@@ -53,9 +60,10 @@ class CORE_EXPORT ImeTextSpan {
const Color& background_color,
const Color& suggestion_highlight_color = Color::kTransparent,
bool remove_on_finish_composing = false,
+ bool interim_char_selection_ = false,
const Vector<String>& suggestions = Vector<String>());
- ImeTextSpan(const WebImeTextSpan&);
+ explicit ImeTextSpan(const ui::ImeTextSpan&);
Type GetType() const { return type_; }
unsigned StartOffset() const { return start_offset_; }
@@ -73,6 +81,7 @@ class CORE_EXPORT ImeTextSpan {
bool NeedsRemovalOnFinishComposing() const {
return remove_on_finish_composing_;
}
+ bool InterimCharSelection() const { return interim_char_selection_; }
const Vector<String>& Suggestions() const { return suggestions_; }
private:
@@ -86,6 +95,7 @@ class CORE_EXPORT ImeTextSpan {
Color background_color_;
Color suggestion_highlight_color_;
bool remove_on_finish_composing_;
+ bool interim_char_selection_;
Vector<String> suggestions_;
};
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc b/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc
index 8095b83030d..dd685f29df7 100644
--- a/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc
@@ -28,6 +28,16 @@ ImeTextSpan CreateImeTextSpan(
Color::kTransparent, Color::kTransparent);
}
+ImeTextSpan CreateImeTextSpan(unsigned start_offset,
+ unsigned end_offset,
+ bool interim_char_selection) {
+ return ImeTextSpan(
+ ImeTextSpan::Type::kComposition, start_offset, end_offset,
+ Color::kTransparent, ui::mojom::ImeTextSpanThickness::kNone,
+ ui::mojom::ImeTextSpanUnderlineStyle::kNone, Color::kTransparent,
+ Color::kTransparent, Color::kTransparent, false, interim_char_selection);
+}
+
TEST(ImeTextSpanTest, OneChar) {
ImeTextSpan ime_text_span = CreateImeTextSpan(0, 1);
EXPECT_EQ(0u, ime_text_span.StartOffset());
@@ -103,5 +113,12 @@ TEST(ImeTextSpanTest, UnderlineStyles) {
ime_text_span.UnderlineStyle());
}
+TEST(ImeTextSpanTest, InterimCharSelection) {
+ ImeTextSpan ime_text_span = CreateImeTextSpan(0, 1, false);
+ EXPECT_EQ(false, ime_text_span.InterimCharSelection());
+ ime_text_span = CreateImeTextSpan(0, 1, true);
+ EXPECT_EQ(true, ime_text_span.InterimCharSelection());
+}
+
} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_vector_builder.cc b/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_vector_builder.cc
index 37b719c2726..102e016237c 100644
--- a/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_vector_builder.cc
+++ b/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_vector_builder.cc
@@ -33,7 +33,7 @@
namespace blink {
Vector<ImeTextSpan> ImeTextSpanVectorBuilder::Build(
- const WebVector<WebImeTextSpan>& ime_text_spans) {
+ const WebVector<ui::ImeTextSpan>& ime_text_spans) {
Vector<ImeTextSpan> result;
wtf_size_t size = SafeCast<wtf_size_t>(ime_text_spans.size());
result.ReserveCapacity(size);
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_vector_builder.h b/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_vector_builder.h
index 10e5ad55d95..b424e37d5a2 100644
--- a/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_vector_builder.h
+++ b/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_vector_builder.h
@@ -32,14 +32,14 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_IME_IME_TEXT_SPAN_VECTOR_BUILDER_H_
#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/public/web/web_ime_text_span.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/editing/ime/ime_text_span.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "ui/base/ime/ime_text_span.h"
namespace blink {
-// This class is used for converting from WebVector<WebImeTextSpan>
+// This class is used for converting from WebVector<ui::ImeTextSpan>
// to Vector<ImeTextSpan>.
class ImeTextSpanVectorBuilder {
@@ -47,7 +47,7 @@ class ImeTextSpanVectorBuilder {
public:
CORE_EXPORT static Vector<ImeTextSpan> Build(
- const WebVector<WebImeTextSpan>&);
+ const WebVector<ui::ImeTextSpan>&);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/input_method_controller.cc b/chromium/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
index deacb4fbef0..03e502f5203 100644
--- a/chromium/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
+++ b/chromium/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
@@ -34,7 +34,6 @@
#include "third_party/blink/renderer/core/dom/range.h"
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/editing/commands/delete_selection_command.h"
-#include "third_party/blink/renderer/core/editing/commands/typing_command.h"
#include "third_party/blink/renderer/core/editing/commands/undo_stack.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/editor.h"
@@ -52,6 +51,7 @@
#include "third_party/blink/renderer/core/events/composition_event.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/html_text_area_element.h"
@@ -68,31 +68,6 @@ namespace blink {
namespace {
-void DispatchCompositionUpdateEvent(LocalFrame& frame, const String& text) {
- Element* target = frame.GetDocument()->FocusedElement();
- if (!target)
- return;
-
- auto* event = MakeGarbageCollected<CompositionEvent>(
- event_type_names::kCompositionupdate, frame.DomWindow(), text);
- target->DispatchEvent(*event);
-}
-
-void DispatchCompositionEndEvent(LocalFrame& frame, const String& text) {
- // Verify that the caller is using an EventQueueScope to suppress the input
- // event from being fired until the proper time (e.g. after applying an IME
- // selection update, if necessary).
- DCHECK(ScopedEventQueue::Instance()->ShouldQueueEvents());
-
- Element* target = frame.GetDocument()->FocusedElement();
- if (!target)
- return;
-
- auto* event = MakeGarbageCollected<CompositionEvent>(
- event_type_names::kCompositionend, frame.DomWindow(), text);
- EventDispatcher::DispatchScopedEvent(*target, *event);
-}
-
bool NeedsIncrementalInsertion(const LocalFrame& frame,
const String& new_text) {
// No need to apply incremental insertion if it doesn't support formated text.
@@ -107,94 +82,6 @@ bool NeedsIncrementalInsertion(const LocalFrame& frame,
return true;
}
-void DispatchBeforeInputFromComposition(EventTarget* target,
- InputEvent::InputType input_type,
- const String& data) {
- if (!target)
- return;
- // TODO(editing-dev): Pass appropriate |ranges| after it's defined on spec.
- // http://w3c.github.io/editing/input-events.html#dom-inputevent-inputtype
- InputEvent* before_input_event = InputEvent::CreateBeforeInput(
- input_type, data, InputEvent::kNotCancelable,
- InputEvent::EventIsComposing::kIsComposing, nullptr);
- target->DispatchEvent(*before_input_event);
-}
-
-// Used to insert/replace text during composition update and confirm
-// composition.
-// Procedure:
-// 1. Fire 'beforeinput' event for (TODO(editing-dev): deleted composed text)
-// and inserted text
-// 2. Fire 'compositionupdate' event
-// 3. Fire TextEvent and modify DOM
-// 4. Fire 'input' event; dispatched by Editor::AppliedEditing()
-void InsertTextDuringCompositionWithEvents(
- LocalFrame& frame,
- const String& text,
- TypingCommand::Options options,
- TypingCommand::TextCompositionType composition_type) {
- // Verify that the caller is using an EventQueueScope to suppress the input
- // event from being fired until the proper time (e.g. after applying an IME
- // selection update, if necessary).
- DCHECK(ScopedEventQueue::Instance()->ShouldQueueEvents());
- DCHECK(composition_type ==
- TypingCommand::TextCompositionType::kTextCompositionUpdate ||
- composition_type ==
- TypingCommand::TextCompositionType::kTextCompositionConfirm ||
- composition_type ==
- TypingCommand::TextCompositionType::kTextCompositionCancel)
- << "compositionType should be TextCompositionUpdate or "
- "TextCompositionConfirm or TextCompositionCancel, but got "
- << static_cast<int>(composition_type);
- if (!frame.GetDocument())
- return;
-
- Element* target = frame.GetDocument()->FocusedElement();
- if (!target)
- return;
-
- DispatchBeforeInputFromComposition(
- target, InputEvent::InputType::kInsertCompositionText, text);
-
- // 'beforeinput' event handler may destroy document.
- if (!frame.GetDocument())
- return;
-
- DispatchCompositionUpdateEvent(frame, text);
- // 'compositionupdate' event handler may destroy document.
- if (!frame.GetDocument())
- return;
-
- // TODO(editing-dev): The use of UpdateStyleAndLayout
- // needs to be audited. see http://crbug.com/590369 for more details.
- frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kInput);
-
- const bool is_incremental_insertion = NeedsIncrementalInsertion(frame, text);
-
- switch (composition_type) {
- case TypingCommand::TextCompositionType::kTextCompositionUpdate:
- case TypingCommand::TextCompositionType::kTextCompositionConfirm:
- // Calling |TypingCommand::insertText()| with empty text will result in an
- // incorrect ending selection. We need to delete selection first.
- // https://crbug.com/693481
- if (text.IsEmpty())
- TypingCommand::DeleteSelection(*frame.GetDocument(), 0);
- frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
- TypingCommand::InsertText(*frame.GetDocument(), text, options,
- composition_type, is_incremental_insertion);
- break;
- case TypingCommand::TextCompositionType::kTextCompositionCancel:
- // TODO(editing-dev): Use TypingCommand::insertText after TextEvent was
- // removed. (Removed from spec since 2012)
- // See text_event.idl.
- frame.GetEventHandler().HandleTextInputEvent(text, nullptr,
- kTextEventInputComposition);
- break;
- default:
- NOTREACHED();
- }
-}
-
AtomicString GetInputModeAttribute(Element* element) {
if (!element)
return AtomicString();
@@ -239,6 +126,21 @@ AtomicString GetEnterKeyHintAttribute(Element* element) {
return element->FastGetAttribute(html_names::kEnterkeyhintAttr).LowerASCII();
}
+AtomicString GetVirtualKeyboardPolicyAttribute(Element* element) {
+ if (!element)
+ return AtomicString();
+
+ if (!element->MayTriggerVirtualKeyboard())
+ return g_null_atom;
+
+ const AtomicString& virtual_keyboard_policy_value =
+ element->FastGetAttribute(html_names::kVirtualkeyboardpolicyAttr);
+ if (virtual_keyboard_policy_value.IsNull())
+ return AtomicString();
+
+ return virtual_keyboard_policy_value.LowerASCII();
+}
+
constexpr int kInvalidDeletionLength = -1;
constexpr bool IsInvalidDeletionLength(const int length) {
return length == kInvalidDeletionLength;
@@ -388,6 +290,19 @@ int ComputeAutocapitalizeFlags(const Element* element) {
return flags;
}
+SuggestionMarker::SuggestionType ConvertImeTextSpanType(
+ ImeTextSpan::Type type) {
+ switch (type) {
+ case ImeTextSpan::Type::kAutocorrect:
+ return SuggestionMarker::SuggestionType::kAutocorrect;
+ case ImeTextSpan::Type::kMisspellingSuggestion:
+ return SuggestionMarker::SuggestionType::kMisspelling;
+ case ImeTextSpan::Type::kComposition:
+ case ImeTextSpan::Type::kSuggestion:
+ return SuggestionMarker::SuggestionType::kNotMisspelling;
+ }
+}
+
} // anonymous namespace
enum class InputMethodController::TypingContinuation { kContinue, kEnd };
@@ -396,7 +311,9 @@ InputMethodController::InputMethodController(LocalDOMWindow& window,
LocalFrame& frame)
: ExecutionContextLifecycleObserver(&window),
frame_(frame),
- has_composition_(false) {}
+ has_composition_(false),
+ last_vk_visibility_request_(
+ ui::mojom::VirtualKeyboardVisibilityRequest::NONE) {}
InputMethodController::~InputMethodController() = default;
@@ -422,6 +339,122 @@ LocalFrame& InputMethodController::GetFrame() const {
return *frame_;
}
+void InputMethodController::DispatchCompositionUpdateEvent(LocalFrame& frame,
+ const String& text) {
+ Element* target = frame.GetDocument()->FocusedElement();
+ if (!target)
+ return;
+
+ auto* event = MakeGarbageCollected<CompositionEvent>(
+ event_type_names::kCompositionupdate, frame.DomWindow(), text);
+ target->DispatchEvent(*event);
+}
+
+void InputMethodController::DispatchCompositionEndEvent(LocalFrame& frame,
+ const String& text) {
+ // Verify that the caller is using an EventQueueScope to suppress the input
+ // event from being fired until the proper time (e.g. after applying an IME
+ // selection update, if necessary).
+ DCHECK(ScopedEventQueue::Instance()->ShouldQueueEvents());
+
+ Element* target = frame.GetDocument()->FocusedElement();
+ if (!target)
+ return;
+
+ auto* event = MakeGarbageCollected<CompositionEvent>(
+ event_type_names::kCompositionend, frame.DomWindow(), text);
+ EventDispatcher::DispatchScopedEvent(*target, *event);
+}
+
+void InputMethodController::DispatchBeforeInputFromComposition(
+ EventTarget* target,
+ InputEvent::InputType input_type,
+ const String& data) {
+ if (!target)
+ return;
+ // TODO(editing-dev): Pass appropriate |ranges| after it's defined on spec.
+ // http://w3c.github.io/editing/input-events.html#dom-inputevent-inputtype
+ InputEvent* before_input_event = InputEvent::CreateBeforeInput(
+ input_type, data, InputEvent::kNotCancelable,
+ InputEvent::EventIsComposing::kIsComposing, nullptr);
+ target->DispatchEvent(*before_input_event);
+}
+
+// Used to insert/replace text during composition update and confirm
+// composition.
+// Procedure:
+// 1. Fire 'beforeinput' event for (TODO(editing-dev): deleted composed text)
+// and inserted text
+// 2. Fire 'compositionupdate' event
+// 3. Fire TextEvent and modify DOM
+// 4. Fire 'input' event; dispatched by Editor::AppliedEditing()
+void InputMethodController::InsertTextDuringCompositionWithEvents(
+ LocalFrame& frame,
+ const String& text,
+ TypingCommand::Options options,
+ TypingCommand::TextCompositionType composition_type) {
+ // Verify that the caller is using an EventQueueScope to suppress the input
+ // event from being fired until the proper time (e.g. after applying an IME
+ // selection update, if necessary).
+ DCHECK(ScopedEventQueue::Instance()->ShouldQueueEvents());
+ DCHECK(composition_type ==
+ TypingCommand::TextCompositionType::kTextCompositionUpdate ||
+ composition_type ==
+ TypingCommand::TextCompositionType::kTextCompositionConfirm ||
+ composition_type ==
+ TypingCommand::TextCompositionType::kTextCompositionCancel)
+ << "compositionType should be TextCompositionUpdate or "
+ "TextCompositionConfirm or TextCompositionCancel, but got "
+ << static_cast<int>(composition_type);
+ if (!frame.GetDocument())
+ return;
+
+ Element* target = frame.GetDocument()->FocusedElement();
+ if (!target)
+ return;
+
+ DispatchBeforeInputFromComposition(
+ target, InputEvent::InputType::kInsertCompositionText, text);
+
+ // 'beforeinput' event handler may destroy document.
+ if (!IsAvailable())
+ return;
+
+ DispatchCompositionUpdateEvent(frame, text);
+ // 'compositionupdate' event handler may destroy document.
+ if (!IsAvailable())
+ return;
+
+ // TODO(editing-dev): The use of UpdateStyleAndLayout
+ // needs to be audited. see http://crbug.com/590369 for more details.
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kInput);
+
+ const bool is_incremental_insertion = NeedsIncrementalInsertion(frame, text);
+
+ switch (composition_type) {
+ case TypingCommand::TextCompositionType::kTextCompositionUpdate:
+ case TypingCommand::TextCompositionType::kTextCompositionConfirm:
+ // Calling |TypingCommand::insertText()| with empty text will result in an
+ // incorrect ending selection. We need to delete selection first.
+ // https://crbug.com/693481
+ if (text.IsEmpty())
+ TypingCommand::DeleteSelection(*frame.GetDocument(), 0);
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
+ TypingCommand::InsertText(*frame.GetDocument(), text, options,
+ composition_type, is_incremental_insertion);
+ break;
+ case TypingCommand::TextCompositionType::kTextCompositionCancel:
+ // TODO(editing-dev): Use TypingCommand::insertText after TextEvent was
+ // removed. (Removed from spec since 2012)
+ // See text_event.idl.
+ frame.GetEventHandler().HandleTextInputEvent(text, nullptr,
+ kTextEventInputComposition);
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
void InputMethodController::Clear() {
RemoveSuggestionMarkerInCompositionRange();
@@ -434,6 +467,44 @@ void InputMethodController::Clear() {
DocumentMarker::MarkerTypes::Composition());
}
+void InputMethodController::ClearImeTextSpansByType(ImeTextSpan::Type type,
+ unsigned text_start,
+ unsigned text_end) {
+ Element* target = GetDocument().FocusedElement();
+ if (!target)
+ return;
+
+ Element* editable = GetFrame()
+ .Selection()
+ .ComputeVisibleSelectionInDOMTreeDeprecated()
+ .RootEditableElement();
+ if (!editable)
+ return;
+
+ DCHECK(!GetDocument().NeedsLayoutTreeUpdate());
+
+ const EphemeralRange range =
+ PlainTextRange(text_start, text_end).CreateRange(*editable);
+ if (range.IsNull() ||
+ RootEditableElementOf(range.StartPosition()) != editable ||
+ RootEditableElementOf(range.EndPosition()) != editable) {
+ return;
+ }
+
+ switch (type) {
+ case ImeTextSpan::Type::kAutocorrect:
+ case ImeTextSpan::Type::kMisspellingSuggestion:
+ case ImeTextSpan::Type::kSuggestion:
+ GetDocument().Markers().RemoveSuggestionMarkerByType(
+ ToEphemeralRangeInFlatTree(range), ConvertImeTextSpanType(type));
+ break;
+ case ImeTextSpan::Type::kComposition:
+ GetDocument().Markers().RemoveMarkersInRange(
+ range, DocumentMarker::MarkerTypes::Composition());
+ break;
+ }
+}
+
void InputMethodController::ContextDestroyed() {
Clear();
composition_range_ = nullptr;
@@ -634,18 +705,26 @@ void InputMethodController::AddImeTextSpans(
continue;
switch (ime_text_span.GetType()) {
- case ImeTextSpan::Type::kComposition:
+ case ImeTextSpan::Type::kComposition: {
+ Color background_color =
+ GetDocument().GetPage() && ime_text_span.InterimCharSelection()
+ ? LayoutTheme::GetTheme().ActiveSelectionBackgroundColor(
+ GetDocument()
+ .GetPage()
+ ->GetVisualViewport()
+ .UsedColorScheme())
+ : ime_text_span.BackgroundColor();
GetDocument().Markers().AddCompositionMarker(
ephemeral_line_range, ime_text_span.UnderlineColor(),
ime_text_span.Thickness(), ime_text_span.UnderlineStyle(),
- ime_text_span.TextColor(), ime_text_span.BackgroundColor());
+ ime_text_span.TextColor(), background_color);
break;
+ }
+ case ImeTextSpan::Type::kAutocorrect:
case ImeTextSpan::Type::kSuggestion:
case ImeTextSpan::Type::kMisspellingSuggestion:
const SuggestionMarker::SuggestionType suggestion_type =
- ime_text_span.GetType() == ImeTextSpan::Type::kMisspellingSuggestion
- ? SuggestionMarker::SuggestionType::kMisspelling
- : SuggestionMarker::SuggestionType::kNotMisspelling;
+ ConvertImeTextSpanType(ime_text_span.GetType());
// If spell-checking is disabled for an element, we ignore suggestion
// markers used to mark misspelled words, but allow other ones (e.g.,
@@ -714,6 +793,8 @@ bool InputMethodController::InsertText(const String& text) {
if (DispatchBeforeInputInsertText(GetDocument().FocusedElement(), text) !=
DispatchEventResult::kNotCanceled)
return false;
+ if (!IsAvailable())
+ return false;
GetEditor().InsertText(text, nullptr);
return true;
}
@@ -1027,6 +1108,34 @@ void InputMethodController::SetCompositionFromExistingText(
DispatchCompositionUpdateEvent(GetFrame(), ComposingText());
}
+void InputMethodController::AddImeTextSpansToExistingText(
+ const Vector<ImeTextSpan>& ime_text_spans,
+ unsigned text_start,
+ unsigned text_end) {
+ Element* target = GetDocument().FocusedElement();
+ if (!target)
+ return;
+
+ Element* editable = GetFrame()
+ .Selection()
+ .ComputeVisibleSelectionInDOMTreeDeprecated()
+ .RootEditableElement();
+ if (!editable)
+ return;
+
+ DCHECK(!GetDocument().NeedsLayoutTreeUpdate());
+
+ const EphemeralRange range =
+ PlainTextRange(text_start, text_end).CreateRange(*editable);
+ if (range.IsNull() ||
+ RootEditableElementOf(range.StartPosition()) != editable ||
+ RootEditableElementOf(range.EndPosition()) != editable) {
+ return;
+ }
+
+ AddImeTextSpans(ime_text_spans, editable, text_start);
+}
+
EphemeralRange InputMethodController::CompositionEphemeralRange() const {
if (!HasComposition())
return EphemeralRange();
@@ -1399,6 +1508,7 @@ WebTextInputInfo InputMethodController::TextInputInfo() const {
info.action = InputActionOfFocusedElement();
info.input_mode = InputModeOfFocusedElement();
+ info.virtual_keyboard_policy = VirtualKeyboardPolicyOfFocusedElement();
info.type = TextInputType();
info.flags = TextInputFlags();
if (info.type == kWebTextInputTypeNone)
@@ -1556,6 +1666,32 @@ WebTextInputMode InputMethodController::InputModeOfFocusedElement() const {
return kWebTextInputModeDefault;
}
+ui::mojom::VirtualKeyboardPolicy
+InputMethodController::VirtualKeyboardPolicyOfFocusedElement() const {
+ // Return the default value if ExecutionContext is not defined.
+ if (!IsAvailable())
+ return ui::mojom::VirtualKeyboardPolicy::AUTO;
+
+ AtomicString vk_policy =
+ GetVirtualKeyboardPolicyAttribute(GetDocument().FocusedElement());
+
+ if (vk_policy == keywords::kManual)
+ return ui::mojom::VirtualKeyboardPolicy::MANUAL;
+ return ui::mojom::VirtualKeyboardPolicy::AUTO;
+}
+
+void InputMethodController::SetVirtualKeyboardVisibilityRequest(
+ ui::mojom::VirtualKeyboardVisibilityRequest vk_visibility_request) {
+ // show/hide API behavior is only applicable for elements/editcontexts that
+ // have manual VK policy.
+ if ((VirtualKeyboardPolicyOfFocusedElement() ==
+ ui::mojom::VirtualKeyboardPolicy::MANUAL) ||
+ (GetActiveEditContext() &&
+ GetActiveEditContext()->IsVirtualKeyboardPolicyManual())) {
+ last_vk_visibility_request_ = vk_visibility_request;
+ } // else we don't change the last VK visibility request.
+}
+
WebTextInputType InputMethodController::TextInputType() const {
if (!GetFrame().Selection().IsAvailable()) {
// "mouse-capture-inside-shadow.html" reaches here.
@@ -1621,7 +1757,7 @@ void InputMethodController::WillChangeFocus() {
FinishComposingText(kKeepSelection);
}
-void InputMethodController::Trace(Visitor* visitor) {
+void InputMethodController::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(composition_range_);
visitor->Trace(active_edit_context_);
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/input_method_controller.h b/chromium/third_party/blink/renderer/core/editing/ime/input_method_controller.h
index 545a199670e..c9d2b226bbd 100644
--- a/chromium/third_party/blink/renderer/core/editing/ime/input_method_controller.h
+++ b/chromium/third_party/blink/renderer/core/editing/ime/input_method_controller.h
@@ -33,9 +33,11 @@
#include "third_party/blink/public/platform/web_text_input_type.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/editing/commands/typing_command.h"
#include "third_party/blink/renderer/core/editing/forward.h"
#include "third_party/blink/renderer/core/editing/ime/ime_text_span.h"
#include "third_party/blink/renderer/core/editing/plain_text_range.h"
+#include "third_party/blink/renderer/core/events/input_event.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -61,7 +63,7 @@ class CORE_EXPORT InputMethodController final
explicit InputMethodController(LocalDOMWindow&, LocalFrame&);
virtual ~InputMethodController();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// international text input composition
bool HasComposition() const;
@@ -72,6 +74,12 @@ class CORE_EXPORT InputMethodController final
void SetCompositionFromExistingText(const Vector<ImeTextSpan>& ime_text_spans,
unsigned composition_start,
unsigned composition_end);
+ void AddImeTextSpansToExistingText(const Vector<ImeTextSpan>& ime_text_spans,
+ unsigned text_start,
+ unsigned text_end);
+ void ClearImeTextSpansByType(ImeTextSpan::Type type,
+ unsigned text_start,
+ unsigned text_end);
// Deletes ongoing composing text if any, inserts specified text, and
// changes the selection according to relativeCaretPosition, which is
@@ -124,6 +132,16 @@ class CORE_EXPORT InputMethodController final
// EditContext's control and selection bounds if available.
void GetLayoutBounds(WebRect* control_bounds, WebRect* selection_bounds);
+ // Sets the state of the VK show()/hide() calls from virtualkeyboard.
+ void SetVirtualKeyboardVisibilityRequest(
+ ui::mojom::VirtualKeyboardVisibilityRequest vk_visibility_request);
+
+ // Returns whether show()/hide() API is called from virtualkeyboard or not.
+ ui::mojom::VirtualKeyboardVisibilityRequest
+ GetLastVirtualKeyboardVisibilityRequest() const {
+ return last_vk_visibility_request_;
+ }
+
private:
friend class InputMethodControllerTest;
@@ -134,6 +152,7 @@ class CORE_EXPORT InputMethodController final
Member<Range> composition_range_;
Member<EditContext> active_edit_context_;
bool has_composition_;
+ ui::mojom::VirtualKeyboardVisibilityRequest last_vk_visibility_request_;
Editor& GetEditor() const;
LocalFrame& GetFrame() const;
@@ -187,6 +206,8 @@ class CORE_EXPORT InputMethodController final
int TextInputFlags() const;
ui::TextInputAction InputActionOfFocusedElement() const;
WebTextInputMode InputModeOfFocusedElement() const;
+ ui::mojom::VirtualKeyboardPolicy VirtualKeyboardPolicyOfFocusedElement()
+ const;
// Implements |ExecutionContextLifecycleObserver|.
void ContextDestroyed() final;
@@ -207,8 +228,21 @@ class CORE_EXPORT InputMethodController final
// 3) SetComposingText() (SetComposition())
void RemoveSuggestionMarkerInCompositionRange();
+ void DispatchCompositionUpdateEvent(LocalFrame& frame, const String& text);
+ void DispatchBeforeInputFromComposition(EventTarget* target,
+ InputEvent::InputType input_type,
+ const String& data);
+ void InsertTextDuringCompositionWithEvents(
+ LocalFrame& frame,
+ const String& text,
+ TypingCommand::Options options,
+ TypingCommand::TextCompositionType composition_type);
+ void DispatchCompositionEndEvent(LocalFrame& frame, const String& text);
+
FRIEND_TEST_ALL_PREFIXES(InputMethodControllerTest,
InputModeOfFocusedElement);
+ FRIEND_TEST_ALL_PREFIXES(InputMethodControllerTest,
+ VirtualKeyboardPolicyOfFocusedElement);
DISALLOW_COPY_AND_ASSIGN(InputMethodController);
};
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc b/chromium/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
index d7f61e65188..67230502f98 100644
--- a/chromium/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
@@ -20,8 +20,10 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/html_text_area_element.h"
+#include "third_party/blink/renderer/core/layout/layout_theme.h"
using ui::mojom::ImeTextSpanThickness;
using ui::mojom::ImeTextSpanUnderlineStyle;
@@ -184,6 +186,25 @@ TEST_F(InputMethodControllerTest, SetCompositionFromExistingText) {
EXPECT_EQ(5u, plain_text_range.End());
}
+TEST_F(InputMethodControllerTest, AddImeTextSpansToExistingText) {
+ InsertHTMLElement("<div id='sample' contenteditable>hello world</div>",
+ "sample");
+ Vector<ImeTextSpan> ime_text_spans;
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kAutocorrect, 0, 5, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
+ Controller().AddImeTextSpansToExistingText(ime_text_spans, 0, 5);
+
+ EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
+ EXPECT_EQ(0u, GetDocument().Markers().Markers()[0]->StartOffset());
+ EXPECT_EQ(5u, GetDocument().Markers().Markers()[0]->EndOffset());
+ EXPECT_EQ(DocumentMarker::MarkerType::kSuggestion,
+ GetDocument().Markers().Markers()[0]->GetType());
+ EXPECT_EQ(SuggestionMarker::SuggestionType::kAutocorrect,
+ To<SuggestionMarker>(GetDocument().Markers().Markers()[0].Get())
+ ->GetSuggestionType());
+}
+
TEST_F(InputMethodControllerTest, SetCompositionAfterEmoji) {
// "trophy" = U+1F3C6 = 0xF0 0x9F 0x8F 0x86 (UTF8).
Element* div = InsertHTMLElement(
@@ -1401,6 +1422,28 @@ TEST_F(InputMethodControllerTest, SetCompositionPlainTextWithIme_Text_Span) {
EXPECT_EQ(1u, GetDocument().Markers().Markers()[0]->EndOffset());
}
+TEST_F(InputMethodControllerTest,
+ SetCompositionPlainTextWithIme_Text_Span_Interim_Char_Selection) {
+ InsertHTMLElement("<div id='sample' contenteditable></div>", "sample");
+
+ Vector<ImeTextSpan> ime_text_spans;
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 1, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0, 0,
+ false, true /*interim_char_selection*/));
+
+ Controller().SetComposition("a", ime_text_spans, 0, 1);
+
+ ASSERT_EQ(1u, GetDocument().Markers().Markers().size());
+
+ auto* styleable_marker =
+ DynamicTo<StyleableMarker>(GetDocument().Markers().Markers()[0].Get());
+ Color background_color =
+ LayoutTheme::GetTheme().ActiveSelectionBackgroundColor(
+ GetFrame().GetPage()->GetVisualViewport().UsedColorScheme());
+ EXPECT_EQ(background_color, styleable_marker->BackgroundColor());
+}
+
TEST_F(InputMethodControllerTest, CommitPlainTextWithIme_Text_SpanInsert) {
InsertHTMLElement("<div id='sample' contenteditable>Initial text.</div>",
"sample");
@@ -2404,6 +2447,26 @@ TEST_F(InputMethodControllerTest, RemoveSuggestionMarkerInRangeOnFinish) {
GetDocument().Markers().Markers()[0]->GetType());
}
+TEST_F(InputMethodControllerTest, ClearImeTextSpansByType) {
+ InsertHTMLElement(
+ "<div id='sample' contenteditable spellcheck='true'>hello</div>",
+ "sample");
+ ImeTextSpan::Type type = ImeTextSpan::Type::kAutocorrect;
+ unsigned start = 0;
+ unsigned end = 1;
+ Vector<ImeTextSpan> ime_text_spans;
+ ime_text_spans.push_back(ImeTextSpan(
+ type, start, end, Color::kTransparent, ImeTextSpanThickness::kNone,
+ ImeTextSpanUnderlineStyle::kNone, Color::kTransparent,
+ Color::kTransparent, Color ::kTransparent));
+
+ Controller().AddImeTextSpansToExistingText(ime_text_spans, start, end);
+ EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
+
+ Controller().ClearImeTextSpansByType(type, start, end);
+ EXPECT_EQ(0u, GetDocument().Markers().Markers().size());
+}
+
// For http://crbug.com/712761
TEST_F(InputMethodControllerTest, TextInputTypeAtBeforeEditable) {
GetDocument().body()->setContentEditable("true", ASSERT_NO_EXCEPTION);
@@ -3305,4 +3368,13 @@ TEST_F(InputMethodControllerTest, SetCompositionInMyanmar) {
div->innerHTML());
}
+TEST_F(InputMethodControllerTest, VirtualKeyboardPolicyOfFocusedElement) {
+ EXPECT_EQ(ui::mojom::VirtualKeyboardPolicy::AUTO,
+ Controller().VirtualKeyboardPolicyOfFocusedElement());
+ InsertHTMLElement("<input id='a' virtualkeyboardpolicy='manual'>", "a")
+ ->focus();
+ EXPECT_EQ(ui::mojom::VirtualKeyboardPolicy::MANUAL,
+ Controller().VirtualKeyboardPolicyOfFocusedElement());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/inline_box_position_test.cc b/chromium/third_party/blink/renderer/core/editing/inline_box_position_test.cc
index 9aa084812dd..fe6587ae6a5 100644
--- a/chromium/third_party/blink/renderer/core/editing/inline_box_position_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/inline_box_position_test.cc
@@ -45,8 +45,6 @@ TEST_F(InlineBoxPositionTest, ComputeInlineBoxPositionBidiIsolate) {
// http://crbug.com/716093
TEST_F(InlineBoxPositionTest, ComputeInlineBoxPositionMixedEditable) {
- if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
- return;
// InlineBoxPosition is a legacy-only data structure.
ScopedLayoutNGForTest scoped_layout_ng(false);
@@ -56,6 +54,10 @@ TEST_F(InlineBoxPositionTest, ComputeInlineBoxPositionMixedEditable) {
Element* const input = GetDocument().QuerySelector("input");
const InlineBox* const input_wrapper_box =
ToLayoutBox(input->GetLayoutObject())->InlineBoxWrapper();
+ if (!input_wrapper_box) {
+ EXPECT_TRUE(RuntimeEnabledFeatures::LayoutNGEnabled());
+ return;
+ }
const InlineBoxPosition& actual = ComputeInlineBoxPosition(
PositionWithAffinity(Position::LastPositionInNode(*sample)));
@@ -66,8 +68,6 @@ TEST_F(InlineBoxPositionTest, ComputeInlineBoxPositionMixedEditable) {
// http://crbug.com/841363
TEST_F(InlineBoxPositionTest, InFlatTreeAfterInputWithPlaceholderDoesntCrash) {
- if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
- return;
// InlineBoxPosition is a legacy-only data structure.
ScopedLayoutNGForTest scoped_layout_ng(false);
@@ -75,6 +75,10 @@ TEST_F(InlineBoxPositionTest, InFlatTreeAfterInputWithPlaceholderDoesntCrash) {
const Element* const input = GetDocument().QuerySelector("input");
const LayoutBox* const input_layout = ToLayoutBox(input->GetLayoutObject());
const InlineBox* const input_wrapper = input_layout->InlineBoxWrapper();
+ if (!input_wrapper) {
+ EXPECT_TRUE(RuntimeEnabledFeatures::LayoutNGEnabled());
+ return;
+ }
const PositionInFlatTreeWithAffinity after_input(
PositionInFlatTree::AfterNode(*input));
diff --git a/chromium/third_party/blink/renderer/core/editing/layout_selection.cc b/chromium/third_party/blink/renderer/core/editing/layout_selection.cc
index a1e219fd9d2..563d438fce3 100644
--- a/chromium/third_party/blink/renderer/core/editing/layout_selection.cc
+++ b/chromium/third_party/blink/renderer/core/editing/layout_selection.cc
@@ -76,7 +76,7 @@ class SelectionPaintRange : public GarbageCollected<SelectionPaintRange> {
start_offset(passed_start_offset),
end_node(passed_end_node),
end_offset(passed_end_offset) {}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(start_node);
visitor->Trace(end_node);
}
@@ -872,7 +872,7 @@ void LayoutSelection::InvalidatePaintForSelection() {
&visitor);
}
-void LayoutSelection::Trace(Visitor* visitor) {
+void LayoutSelection::Trace(Visitor* visitor) const {
visitor->Trace(frame_selection_);
visitor->Trace(paint_range_);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/layout_selection.h b/chromium/third_party/blink/renderer/core/editing/layout_selection.h
index 5939c51400a..1cd02edd5a3 100644
--- a/chromium/third_party/blink/renderer/core/editing/layout_selection.h
+++ b/chromium/third_party/blink/renderer/core/editing/layout_selection.h
@@ -54,7 +54,7 @@ class LayoutSelection final : public GarbageCollected<LayoutSelection> {
void ContextDestroyed();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void AssertIsValid() const;
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl.cc b/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl.cc
index 6a42c9525aa..b67bc05df3e 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl.cc
@@ -67,7 +67,7 @@ bool ActiveSuggestionMarkerListImpl::ShiftMarkers(const String&,
&markers_, offset, old_length, new_length);
}
-void ActiveSuggestionMarkerListImpl::Trace(Visitor* visitor) {
+void ActiveSuggestionMarkerListImpl::Trace(Visitor* visitor) const {
visitor->Trace(markers_);
DocumentMarkerList::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl.h b/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl.h
index ca8dcf2df5b..d4e3665f7ee 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl.h
+++ b/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl.h
@@ -42,7 +42,7 @@ class CORE_EXPORT ActiveSuggestionMarkerListImpl final
unsigned old_length,
unsigned new_length) final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<DocumentMarker>> markers_;
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl.cc b/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl.cc
index b2b6fb6a537..981c8b41009 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl.cc
@@ -64,7 +64,7 @@ bool CompositionMarkerListImpl::ShiftMarkers(const String&,
&markers_, offset, old_length, new_length);
}
-void CompositionMarkerListImpl::Trace(Visitor* visitor) {
+void CompositionMarkerListImpl::Trace(Visitor* visitor) const {
visitor->Trace(markers_);
DocumentMarkerList::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl.h b/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl.h
index 94fe76fb969..a47b6e05559 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl.h
+++ b/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl.h
@@ -39,7 +39,7 @@ class CORE_EXPORT CompositionMarkerListImpl final : public DocumentMarkerList {
unsigned old_length,
unsigned new_length) final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<DocumentMarker>> markers_;
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/document_marker.h b/chromium/third_party/blink/renderer/core/editing/markers/document_marker.h
index 42389c3d168..3f2b519f3ae 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/document_marker.h
+++ b/chromium/third_party/blink/renderer/core/editing/markers/document_marker.h
@@ -167,7 +167,7 @@ class CORE_EXPORT DocumentMarker : public GarbageCollected<DocumentMarker> {
void SetEndOffset(unsigned offset) { end_offset_ = offset; }
void ShiftOffsets(int delta);
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
DocumentMarker(unsigned start_offset, unsigned end_offset);
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc b/chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc
index 412c7fbbb37..48d17cbde94 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc
@@ -776,7 +776,7 @@ void DocumentMarkerController::DidProcessMarkerMap(const LivenessBroker&) {
Clear();
}
-void DocumentMarkerController::Trace(Visitor* visitor) {
+void DocumentMarkerController::Trace(Visitor* visitor) const {
// Note: To make |DidProcessMarkerMap()| called after weak members callback
// of |markers_|, we should register it before tracing |markers_|.
visitor->template RegisterWeakCallbackMethod<
@@ -840,6 +840,25 @@ void DocumentMarkerController::RemoveSuggestionMarkerInRangeOnFinish(
}
}
+void DocumentMarkerController::RemoveSuggestionMarkerByType(
+ const EphemeralRangeInFlatTree& range,
+ const SuggestionMarker::SuggestionType& type) {
+ // MarkersIntersectingRange() might be expensive. In practice, we hope we will
+ // only check one node for the range.
+ const HeapVector<std::pair<Member<const Text>, Member<DocumentMarker>>>&
+ node_marker_pairs = MarkersIntersectingRange(
+ range, DocumentMarker::MarkerTypes::Suggestion());
+ for (const auto& node_marker_pair : node_marker_pairs) {
+ const Text& text = *node_marker_pair.first;
+ DocumentMarkerList* const list =
+ ListForType(markers_.at(&text), DocumentMarker::kSuggestion);
+ // RemoveMarkerByType() might be expensive. In practice, we have at most
+ // one suggestion marker needs to be removed.
+ To<SuggestionMarkerListImpl>(list)->RemoveMarkerByType(type);
+ InvalidatePaintForNode(text);
+ }
+}
+
void DocumentMarkerController::RemoveSuggestionMarkerByTag(const Text& text,
int32_t marker_tag) {
MarkerLists* markers = markers_.at(&text);
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller.h b/chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller.h
index 0295a9180be..1cf39a1435b 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller.h
+++ b/chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller.h
@@ -90,6 +90,9 @@ class CORE_EXPORT DocumentMarkerController final
DocumentMarker::MarkerTypes = DocumentMarker::MarkerTypes::All());
void RemoveSpellingMarkersUnderWords(const Vector<String>& words);
void RemoveSuggestionMarkerByTag(const Text&, int32_t marker_tag);
+ void RemoveSuggestionMarkerByType(
+ const EphemeralRangeInFlatTree& range,
+ const SuggestionMarker::SuggestionType& type);
// Removes suggestion marker with |RemoveOnFinishComposing::kRemove|.
void RemoveSuggestionMarkerInRangeOnFinish(const EphemeralRangeInFlatTree&);
void RepaintMarkers(
@@ -153,7 +156,7 @@ class CORE_EXPORT DocumentMarkerController final
void InvalidateRectsForAllTextMatchMarkers();
void InvalidateRectsForTextMatchMarkersInNode(const Text&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
#if DCHECK_IS_ON()
void ShowMarkers() const;
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller_test.cc b/chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller_test.cc
index b2685cff5aa..7910be57811 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller_test.cc
@@ -84,7 +84,7 @@ TEST_F(DocumentMarkerControllerTest, DidMoveToNewDocument) {
auto* parent = To<Element>(GetDocument().body()->firstChild()->firstChild());
MarkNodeContents(parent);
EXPECT_EQ(1u, MarkerController().Markers().size());
- Persistent<Document> another_document = MakeGarbageCollected<Document>();
+ Persistent<Document> another_document = Document::CreateForTest();
another_document->adoptNode(parent, ASSERT_NO_EXCEPTION);
// No more reference to marked node.
@@ -382,6 +382,20 @@ TEST_F(DocumentMarkerControllerTest, RemoveSuggestionMarkerByTag) {
EXPECT_EQ(0u, MarkerController().Markers().size());
}
+TEST_F(DocumentMarkerControllerTest, RemoveSuggestionMarkerByType) {
+ SetBodyContent("<div contenteditable>foo</div>");
+ Element* div = GetDocument().QuerySelector("div");
+ Node* text = div->firstChild();
+ EphemeralRange range(Position(text, 0), Position(text, 1));
+ MarkerController().AddSuggestionMarker(range, SuggestionMarkerProperties());
+
+ ASSERT_EQ(1u, MarkerController().Markers().size());
+ auto* marker = To<SuggestionMarker>(MarkerController().Markers()[0].Get());
+ MarkerController().RemoveSuggestionMarkerByType(
+ ToEphemeralRangeInFlatTree(range), marker->GetSuggestionType());
+ EXPECT_EQ(0u, MarkerController().Markers().size());
+}
+
TEST_F(DocumentMarkerControllerTest, RemoveSuggestionMarkerInRangeOnFinish) {
SetBodyContent("<div contenteditable>foo</div>");
Element* div = GetDocument().QuerySelector("div");
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/document_marker_list.h b/chromium/third_party/blink/renderer/core/editing/markers/document_marker_list.h
index bc9852f432a..3ca83a282ac 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/document_marker_list.h
+++ b/chromium/third_party/blink/renderer/core/editing/markers/document_marker_list.h
@@ -61,7 +61,7 @@ class CORE_EXPORT DocumentMarkerList
unsigned old_length,
unsigned new_length) = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
DocumentMarkerList();
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/spell_check_marker_list_impl.cc b/chromium/third_party/blink/renderer/core/editing/markers/spell_check_marker_list_impl.cc
index aac0d2b71b2..3d4f48a46d8 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/spell_check_marker_list_impl.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/spell_check_marker_list_impl.cc
@@ -106,7 +106,7 @@ bool SpellCheckMarkerListImpl::ShiftMarkers(const String&,
&markers_, offset, old_length, new_length);
}
-void SpellCheckMarkerListImpl::Trace(Visitor* visitor) {
+void SpellCheckMarkerListImpl::Trace(Visitor* visitor) const {
visitor->Trace(markers_);
DocumentMarkerList::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/spell_check_marker_list_impl.h b/chromium/third_party/blink/renderer/core/editing/markers/spell_check_marker_list_impl.h
index 2997bad0e4f..e795b9c1b34 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/spell_check_marker_list_impl.h
+++ b/chromium/third_party/blink/renderer/core/editing/markers/spell_check_marker_list_impl.h
@@ -37,7 +37,7 @@ class CORE_EXPORT SpellCheckMarkerListImpl : public DocumentMarkerList {
unsigned old_length,
unsigned new_length) final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// SpellCheckMarkerListImpl-specific
// Returns true if a marker was removed, false otherwise.
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker.cc b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker.cc
index 8d4ce2822ae..3317c1c3b50 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker.cc
@@ -32,6 +32,10 @@ int32_t SuggestionMarker::Tag() const {
return tag_;
}
+SuggestionMarker::SuggestionType SuggestionMarker::GetSuggestionType() const {
+ return suggestion_type_;
+}
+
DocumentMarker::MarkerType SuggestionMarker::GetType() const {
return DocumentMarker::kSuggestion;
}
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker.h b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker.h
index f463b8bafb9..37561aa59dd 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker.h
+++ b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker.h
@@ -13,14 +13,15 @@ namespace blink {
class SuggestionMarkerProperties;
// A subclass of StyleableMarker used to store information specific to
-// suggestion markers (used to represent Android SuggestionSpans). In addition
+// suggestion markers (used to represent Android SuggestionSpans or ChromeOS's
+// custom text spans). In addition
// to the formatting information StyleableMarker holds, we also store a list of
// suggested replacements for the marked region of text. In addition, each
// SuggestionMarker is tagged with an integer so browser code can identify which
// SuggestionMarker a suggestion replace operation pertains to.
class CORE_EXPORT SuggestionMarker final : public StyleableMarker {
public:
- enum class SuggestionType { kMisspelling, kNotMisspelling };
+ enum class SuggestionType { kMisspelling, kNotMisspelling, kAutocorrect };
enum class RemoveOnFinishComposing { kRemove, kDoNotRemove };
SuggestionMarker(unsigned start_offset,
@@ -32,6 +33,7 @@ class CORE_EXPORT SuggestionMarker final : public StyleableMarker {
// SuggestionMarker-specific
int32_t Tag() const;
+ SuggestionType GetSuggestionType() const;
const Vector<String>& Suggestions() const;
bool IsMisspelling() const;
bool NeedsRemovalOnFinishComposing() const;
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.cc b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.cc
index 53eba9c9a11..e2c09f772a2 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.cc
@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.h"
-#include "third_party/blink/renderer/core/editing/markers/suggestion_marker.h"
#include "third_party/blink/renderer/core/editing/markers/suggestion_marker_replacement_scope.h"
#include "third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor.h"
@@ -191,7 +190,7 @@ bool SuggestionMarkerListImpl::ShiftMarkersForNonSuggestionEditingOperation(
return did_shift_marker;
}
-void SuggestionMarkerListImpl::Trace(Visitor* visitor) {
+void SuggestionMarkerListImpl::Trace(Visitor* visitor) const {
visitor->Trace(markers_);
DocumentMarkerList::Trace(visitor);
}
@@ -207,4 +206,16 @@ bool SuggestionMarkerListImpl::RemoveMarkerByTag(int32_t tag) {
return false;
}
+bool SuggestionMarkerListImpl::RemoveMarkerByType(
+ const SuggestionMarker::SuggestionType& type) {
+ for (auto* it = markers_.begin(); it != markers_.end(); it++) {
+ if (To<SuggestionMarker>(it->Get())->GetSuggestionType() == type) {
+ markers_.erase(it);
+ return true;
+ }
+ }
+
+ return false;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.h b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.h
index 001734b8d25..8b1931e790d 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.h
+++ b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_MARKERS_SUGGESTION_MARKER_LIST_IMPL_H_
#include "third_party/blink/renderer/core/editing/markers/document_marker_list.h"
+#include "third_party/blink/renderer/core/editing/markers/suggestion_marker.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -41,10 +42,11 @@ class CORE_EXPORT SuggestionMarkerListImpl final : public DocumentMarkerList {
unsigned old_length,
unsigned new_length) final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// SuggestionMarkerListImpl-specific
bool RemoveMarkerByTag(int32_t tag);
+ bool RemoveMarkerByType(const SuggestionMarker::SuggestionType& type);
private:
bool ShiftMarkersForSuggestionReplacement(unsigned offset,
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl_test.cc b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl_test.cc
index a994e4dca17..86295c3bd42 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl_test.cc
@@ -23,6 +23,13 @@ class SuggestionMarkerListImplTest : public testing::Test {
SuggestionMarkerProperties());
}
+ SuggestionMarker* CreateMarker(unsigned start_offset,
+ unsigned end_offset,
+ const SuggestionMarkerProperties& properties) {
+ return MakeGarbageCollected<SuggestionMarker>(start_offset, end_offset,
+ properties);
+ }
+
Persistent<SuggestionMarkerListImpl> marker_list_;
};
@@ -343,4 +350,35 @@ TEST_F(SuggestionMarkerListImplTest, RemoveMarkerByTag_Found) {
EXPECT_EQ(20u, markers[0]->EndOffset());
}
+TEST_F(SuggestionMarkerListImplTest, RemoveMarkerByType_NotFound) {
+ SuggestionMarker* const marker = CreateMarker(0, 10);
+ marker_list_->Add(marker);
+ EXPECT_TRUE(marker->GetSuggestionType() !=
+ SuggestionMarker::SuggestionType::kAutocorrect);
+ EXPECT_FALSE(marker_list_->RemoveMarkerByType(
+ SuggestionMarker::SuggestionType::kAutocorrect));
+}
+
+TEST_F(SuggestionMarkerListImplTest, RemoveMarkerByType_Found) {
+ SuggestionMarker* const marker1 = CreateMarker(0, 10);
+ SuggestionMarker* const marker2 =
+ CreateMarker(10, 20,
+ SuggestionMarkerProperties::Builder()
+ .SetType(SuggestionMarker::SuggestionType::kAutocorrect)
+ .Build());
+
+ marker_list_->Add(marker1);
+ marker_list_->Add(marker2);
+
+ EXPECT_TRUE(marker1->GetSuggestionType() !=
+ SuggestionMarker::SuggestionType::kAutocorrect);
+ EXPECT_TRUE(marker_list_->RemoveMarkerByType(marker1->GetSuggestionType()));
+
+ DocumentMarkerVector markers = marker_list_->GetMarkers();
+ EXPECT_EQ(1u, markers.size());
+
+ EXPECT_EQ(10u, markers[0]->StartOffset());
+ EXPECT_EQ(20u, markers[0]->EndOffset());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/text_marker_base_list_impl.cc b/chromium/third_party/blink/renderer/core/editing/markers/text_marker_base_list_impl.cc
index d12dec87ad4..35044d65cb0 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/text_marker_base_list_impl.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/text_marker_base_list_impl.cc
@@ -59,7 +59,7 @@ bool TextMarkerBaseListImpl::ShiftMarkers(const String&,
&markers_, offset, old_length, new_length);
}
-void TextMarkerBaseListImpl::Trace(Visitor* visitor) {
+void TextMarkerBaseListImpl::Trace(Visitor* visitor) const {
visitor->Trace(markers_);
DocumentMarkerList::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/text_marker_base_list_impl.h b/chromium/third_party/blink/renderer/core/editing/markers/text_marker_base_list_impl.h
index b68fe968a40..466585300c9 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/text_marker_base_list_impl.h
+++ b/chromium/third_party/blink/renderer/core/editing/markers/text_marker_base_list_impl.h
@@ -35,7 +35,7 @@ class CORE_EXPORT TextMarkerBaseListImpl : public DocumentMarkerList {
unsigned old_length,
unsigned new_length) final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
TextMarkerBaseListImpl() = default;
diff --git a/chromium/third_party/blink/renderer/core/editing/position.cc b/chromium/third_party/blink/renderer/core/editing/position.cc
index eb060bff194..b3569b7b9e4 100644
--- a/chromium/third_party/blink/renderer/core/editing/position.cc
+++ b/chromium/third_party/blink/renderer/core/editing/position.cc
@@ -50,7 +50,7 @@ bool CanBeAnchorNode<EditingInFlatTreeStrategy>(Node* node) {
#endif
template <typename Strategy>
-void PositionTemplate<Strategy>::Trace(Visitor* visitor) {
+void PositionTemplate<Strategy>::Trace(Visitor* visitor) const {
visitor->Trace(anchor_node_);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/position.h b/chromium/third_party/blink/renderer/core/editing/position.h
index c9cde1a6d58..71a7014a59b 100644
--- a/chromium/third_party/blink/renderer/core/editing/position.h
+++ b/chromium/third_party/blink/renderer/core/editing/position.h
@@ -221,7 +221,7 @@ class PositionTemplate {
void ShowTreeForThisInFlatTree() const;
#endif
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
bool IsAfterAnchorOrAfterChildren() const {
diff --git a/chromium/third_party/blink/renderer/core/editing/position_with_affinity.cc b/chromium/third_party/blink/renderer/core/editing/position_with_affinity.cc
index 368575bf704..cced27e2a2d 100644
--- a/chromium/third_party/blink/renderer/core/editing/position_with_affinity.cc
+++ b/chromium/third_party/blink/renderer/core/editing/position_with_affinity.cc
@@ -28,7 +28,7 @@ PositionWithAffinityTemplate<Strategy>::~PositionWithAffinityTemplate() =
default;
template <typename Strategy>
-void PositionWithAffinityTemplate<Strategy>::Trace(Visitor* visitor) {
+void PositionWithAffinityTemplate<Strategy>::Trace(Visitor* visitor) const {
visitor->Trace(position_);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/position_with_affinity.h b/chromium/third_party/blink/renderer/core/editing/position_with_affinity.h
index b1510b866aa..8a16beba809 100644
--- a/chromium/third_party/blink/renderer/core/editing/position_with_affinity.h
+++ b/chromium/third_party/blink/renderer/core/editing/position_with_affinity.h
@@ -47,7 +47,7 @@ class PositionWithAffinityTemplate {
Node* AnchorNode() const { return position_.AnchorNode(); }
Document* GetDocument() const { return position_.GetDocument(); }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
PositionTemplate<Strategy> position_;
diff --git a/chromium/third_party/blink/renderer/core/editing/reveal_selection_scope.cc b/chromium/third_party/blink/renderer/core/editing/reveal_selection_scope.cc
index 18e7a3bf8cf..0a6c7284493 100644
--- a/chromium/third_party/blink/renderer/core/editing/reveal_selection_scope.cc
+++ b/chromium/third_party/blink/renderer/core/editing/reveal_selection_scope.cc
@@ -55,7 +55,7 @@ Editor& RevealSelectionScope::GetEditor() {
return frame_->GetEditor();
}
-void RevealSelectionScope::Trace(Visitor* visitor) {
+void RevealSelectionScope::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/reveal_selection_scope.h b/chromium/third_party/blink/renderer/core/editing/reveal_selection_scope.h
index 12517cdf9f4..322212644fb 100644
--- a/chromium/third_party/blink/renderer/core/editing/reveal_selection_scope.h
+++ b/chromium/third_party/blink/renderer/core/editing/reveal_selection_scope.h
@@ -45,7 +45,7 @@ class RevealSelectionScope {
explicit RevealSelectionScope(LocalFrame&);
~RevealSelectionScope();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Editor& GetEditor();
diff --git a/chromium/third_party/blink/renderer/core/editing/selection_adjuster.cc b/chromium/third_party/blink/renderer/core/editing/selection_adjuster.cc
index d1dca159087..f9b357f2a7b 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_adjuster.cc
+++ b/chromium/third_party/blink/renderer/core/editing/selection_adjuster.cc
@@ -185,14 +185,25 @@ class GranularityAdjuster final {
// |kNextWordIfOnBoundary|);
const VisiblePositionTemplate<Strategy> original_end =
CreateVisiblePosition(passed_end);
+ bool is_end_of_paragraph = IsEndOfParagraph(original_end);
+ // Get last word of paragraph. If original_end is already known to be
+ // the last word, use that. If not the last word, find it with
+ // EndOfWordPosition
const VisiblePositionTemplate<Strategy> word_end =
- CreateVisiblePosition(EndOfWordPosition(
- passed_end.GetPosition(), ChooseWordSide(original_end)));
- if (!IsEndOfParagraph(original_end))
+ is_end_of_paragraph
+ ? original_end
+ : CreateVisiblePosition(EndOfWordPosition(
+ passed_end.GetPosition(), ChooseWordSide(original_end)));
+ if (!is_end_of_paragraph)
return word_end.DeepEquivalent();
if (IsEmptyTableCell(start.AnchorNode()))
return word_end.DeepEquivalent();
+ // If the end was in a table cell, we don't want the \t from between
+ // cells or \n after the row, so return last word
+ if (EnclosingTableCell(original_end.DeepEquivalent()))
+ return word_end.DeepEquivalent();
+
// Select the paragraph break (the space from the end of a paragraph
// to the start of the next one) to match TextEdit.
const VisiblePositionTemplate<Strategy> end = NextPositionOf(word_end);
diff --git a/chromium/third_party/blink/renderer/core/editing/selection_controller.cc b/chromium/third_party/blink/renderer/core/editing/selection_controller.cc
index 0736b1ce96c..d2557a45f23 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_controller.cc
+++ b/chromium/third_party/blink/renderer/core/editing/selection_controller.cc
@@ -70,7 +70,7 @@ SelectionController::SelectionController(LocalFrame& frame)
mouse_down_allows_multi_click_(false),
selection_state_(SelectionState::kHaveNotStartedSelection) {}
-void SelectionController::Trace(Visitor* visitor) {
+void SelectionController::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(original_base_in_flat_tree_);
ExecutionContextLifecycleObserver::Trace(visitor);
@@ -951,8 +951,9 @@ bool SelectionController::HandleTripleClick(
return false;
Node* const inner_node = event.InnerNode();
- if (!(inner_node && inner_node->GetLayoutObject() &&
- mouse_down_may_start_select_))
+ Node* inner_pseudo = event.GetHitTestResult().InnerPossiblyPseudoNode();
+ if (!(inner_node && inner_node->GetLayoutObject() && inner_pseudo &&
+ inner_pseudo->GetLayoutObject() && mouse_down_may_start_select_))
return false;
const PositionInFlatTreeWithAffinity pos =
diff --git a/chromium/third_party/blink/renderer/core/editing/selection_controller.h b/chromium/third_party/blink/renderer/core/editing/selection_controller.h
index 3b7ac5e7ed6..28e58a2aee9 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_controller.h
+++ b/chromium/third_party/blink/renderer/core/editing/selection_controller.h
@@ -49,7 +49,7 @@ class CORE_EXPORT SelectionController final
public:
explicit SelectionController(LocalFrame&);
virtual ~SelectionController();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool HandleMousePressEvent(const MouseEventWithHitTestResults&);
void HandleMouseDraggedEvent(const MouseEventWithHitTestResults&,
diff --git a/chromium/third_party/blink/renderer/core/editing/selection_controller_test.cc b/chromium/third_party/blink/renderer/core/editing/selection_controller_test.cc
index bcc0c15b983..8823a704c39 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_controller_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/selection_controller_test.cc
@@ -275,13 +275,13 @@ TEST_F(SelectionControllerTest,
EXPECT_TRUE(SelectClosestWordFromHitTestResult(
result, AppendTrailingWhitespace::kDontAppend,
SelectInputEventType::kMouse));
- EXPECT_EQ("<pre>(1)^\n(|2)</pre>", GetSelectionTextFromBody());
+ EXPECT_EQ("<pre>(1)^\n|(2)</pre>", GetSelectionTextFromBody());
// Select word by tap
EXPECT_FALSE(SelectClosestWordFromHitTestResult(
result, AppendTrailingWhitespace::kDontAppend,
SelectInputEventType::kTouch));
- EXPECT_EQ("<pre>(1)^\n(|2)</pre>", GetSelectionTextFromBody())
+ EXPECT_EQ("<pre>(1)^\n|(2)</pre>", GetSelectionTextFromBody())
<< "selection isn't changed";
}
@@ -304,17 +304,140 @@ TEST_F(SelectionControllerTest,
EXPECT_TRUE(SelectClosestWordFromHitTestResult(
result, AppendTrailingWhitespace::kDontAppend,
SelectInputEventType::kMouse));
- // TODO(yosin): This should be "<pre>ab:^\ncd|</pre>"
- EXPECT_EQ("<pre>ab:^\nc|d</pre>", GetSelectionTextFromBody());
+ EXPECT_EQ("<pre>ab:^\n|cd</pre>", GetSelectionTextFromBody());
// Select word by tap
EXPECT_FALSE(SelectClosestWordFromHitTestResult(
result, AppendTrailingWhitespace::kDontAppend,
SelectInputEventType::kTouch));
- EXPECT_EQ("<pre>ab:^\nc|d</pre>", GetSelectionTextFromBody())
+ EXPECT_EQ("<pre>ab:^\n|cd</pre>", GetSelectionTextFromBody())
<< "selection isn't changed";
}
+// For http://crbug.com/1092554
+TEST_F(SelectionControllerTest, SelectWordToEndOfLine) {
+ LoadAhem();
+ InsertStyleElement("body { margin: 0; padding: 0; font: 10px/10px Ahem; }");
+ SetBodyContent("<div>abc def<br/>ghi</div>");
+
+ // Select foo
+ blink::WebMouseEvent double_click(
+ blink::WebMouseEvent::Type::kMouseDown, 0,
+ blink::WebInputEvent::GetStaticTimeStampForTests());
+ // Frame scale defaults to 0, which would cause a divide-by-zero problem.
+ double_click.SetFrameScale(1);
+ HitTestLocation location((IntPoint(20, 5)));
+ double_click.button = blink::WebMouseEvent::Button::kLeft;
+ double_click.click_count = 2;
+ HitTestResult result =
+ GetFrame().GetEventHandler().HitTestResultAtLocation(location);
+ GetFrame().GetEventHandler().GetSelectionController().HandleMousePressEvent(
+ MouseEventWithHitTestResults(double_click, location, result));
+ ASSERT_EQ("<div>ab|c def<br>ghi</div>",
+ GetSelectionTextFromBody(
+ SelectionInDOMTree::Builder()
+ .Collapse(GetPositionFromHitTestResult(result))
+ .Build()));
+
+ // Select word by mouse
+ EXPECT_TRUE(SelectClosestWordFromHitTestResult(
+ result, AppendTrailingWhitespace::kDontAppend,
+ SelectInputEventType::kMouse));
+ EXPECT_EQ("<div>^abc| def<br>ghi</div>", GetSelectionTextFromBody());
+
+ // Select to end of line
+ blink::WebMouseEvent single_shift_click(
+ blink::WebMouseEvent::Type::kMouseDown,
+ blink::WebInputEvent::Modifiers::kShiftKey,
+ blink::WebInputEvent::GetStaticTimeStampForTests());
+ // Frame scale defaults to 0, which would cause a divide-by-zero problem.
+ single_shift_click.SetFrameScale(1);
+ HitTestLocation single_click_location((IntPoint(400, 5)));
+ single_shift_click.button = blink::WebMouseEvent::Button::kLeft;
+ single_shift_click.click_count = 1;
+ HitTestResult single_click_result =
+ GetFrame().GetEventHandler().HitTestResultAtLocation(
+ single_click_location);
+ GetFrame().GetEventHandler().GetSelectionController().HandleMousePressEvent(
+ MouseEventWithHitTestResults(single_shift_click, single_click_location,
+ single_click_result));
+ EXPECT_EQ("<div>^abc def<br>|ghi</div>", GetSelectionTextFromBody());
+}
+
+// For http://crbug.com/892750
+TEST_F(SelectionControllerTest, SelectWordToEndOfTableCell) {
+ LoadAhem();
+ InsertStyleElement(
+ "body { margin: 0; padding: 0; font: 10px/10px Ahem; } td {width: "
+ "200px}");
+ SetBodyContent("<table><td>foo</td><td>bar</td></table>");
+
+ // Select foo
+ blink::WebMouseEvent double_click(
+ blink::WebMouseEvent::Type::kMouseDown, 0,
+ blink::WebInputEvent::GetStaticTimeStampForTests());
+ // Frame scale defaults to 0, which would cause a divide-by-zero problem.
+ double_click.SetFrameScale(1);
+ HitTestLocation location((IntPoint(20, 5)));
+ double_click.button = WebMouseEvent::Button::kLeft;
+ double_click.click_count = 2;
+ HitTestResult result =
+ GetFrame().GetEventHandler().HitTestResultAtLocation(location);
+ GetFrame().GetEventHandler().GetSelectionController().HandleMousePressEvent(
+ MouseEventWithHitTestResults(double_click, location, result));
+ ASSERT_EQ("<table><tbody><tr><td>fo|o</td><td>bar</td></tr></tbody></table>",
+ GetSelectionTextFromBody(
+ SelectionInDOMTree::Builder()
+ .Collapse(GetPositionFromHitTestResult(result))
+ .Build()));
+ // Select word by mouse
+ EXPECT_TRUE(SelectClosestWordFromHitTestResult(
+ result, AppendTrailingWhitespace::kDontAppend,
+ SelectInputEventType::kMouse));
+ EXPECT_EQ("<table><tbody><tr><td>^foo|</td><td>bar</td></tr></tbody></table>",
+ GetSelectionTextFromBody());
+
+ // Select to end of cell 1
+ blink::WebMouseEvent cell1_single_shift_click(
+ blink::WebMouseEvent::Type::kMouseDown,
+ blink::WebInputEvent::Modifiers::kShiftKey,
+ blink::WebInputEvent::GetStaticTimeStampForTests());
+ // Frame scale defaults to 0, which would cause a divide-by-zero problem.
+ cell1_single_shift_click.SetFrameScale(1);
+ HitTestLocation cell1_single_click_location((IntPoint(175, 5)));
+ cell1_single_shift_click.button = blink::WebMouseEvent::Button::kLeft;
+ cell1_single_shift_click.click_count = 1;
+ HitTestResult cell1_single_click_result =
+ GetFrame().GetEventHandler().HitTestResultAtLocation(
+ cell1_single_click_location);
+ GetFrame().GetEventHandler().GetSelectionController().HandleMousePressEvent(
+ MouseEventWithHitTestResults(cell1_single_shift_click,
+ cell1_single_click_location,
+ cell1_single_click_result));
+ EXPECT_EQ("<table><tbody><tr><td>^foo|</td><td>bar</td></tr></tbody></table>",
+ GetSelectionTextFromBody());
+
+ // Select to end of cell 2
+ blink::WebMouseEvent cell2_single_shift_click(
+ blink::WebMouseEvent::Type::kMouseDown,
+ blink::WebInputEvent::Modifiers::kShiftKey,
+ blink::WebInputEvent::GetStaticTimeStampForTests());
+ // Frame scale defaults to 0, which would cause a divide-by-zero problem.
+ cell2_single_shift_click.SetFrameScale(1);
+ HitTestLocation cell2_single_click_location((IntPoint(375, 5)));
+ cell2_single_shift_click.button = blink::WebMouseEvent::Button::kLeft;
+ cell2_single_shift_click.click_count = 1;
+ HitTestResult cell2_single_click_result =
+ GetFrame().GetEventHandler().HitTestResultAtLocation(
+ cell2_single_click_location);
+ GetFrame().GetEventHandler().GetSelectionController().HandleMousePressEvent(
+ MouseEventWithHitTestResults(cell2_single_shift_click,
+ cell2_single_click_location,
+ cell2_single_click_result));
+ EXPECT_EQ("<table><tbody><tr><td>^foo</td><td>bar|</td></tr></tbody></table>",
+ GetSelectionTextFromBody());
+}
+
TEST_P(ParameterizedSelectionControllerTest, Scroll) {
SetBodyInnerHTML(R"HTML(
<style>
diff --git a/chromium/third_party/blink/renderer/core/editing/selection_editor.cc b/chromium/third_party/blink/renderer/core/editing/selection_editor.cc
index 3b89e99469c..8937677efc9 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_editor.cc
+++ b/chromium/third_party/blink/renderer/core/editing/selection_editor.cc
@@ -538,7 +538,7 @@ void SelectionEditor::ClearDocumentCachedRange() {
cached_range_ = nullptr;
}
-void SelectionEditor::Trace(Visitor* visitor) {
+void SelectionEditor::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(selection_);
visitor->Trace(cached_visible_selection_in_dom_tree_);
diff --git a/chromium/third_party/blink/renderer/core/editing/selection_editor.h b/chromium/third_party/blink/renderer/core/editing/selection_editor.h
index fb05474d37f..00673fb856c 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_editor.h
+++ b/chromium/third_party/blink/renderer/core/editing/selection_editor.h
@@ -64,7 +64,7 @@ class SelectionEditor final : public GarbageCollected<SelectionEditor>,
void MarkCacheDirty();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Document& GetDocument() const;
diff --git a/chromium/third_party/blink/renderer/core/editing/selection_modifier_line.cc b/chromium/third_party/blink/renderer/core/editing/selection_modifier_line.cc
index 786f9af68d4..2eb648112fa 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_modifier_line.cc
+++ b/chromium/third_party/blink/renderer/core/editing/selection_modifier_line.cc
@@ -70,10 +70,12 @@ class AbstractLineBox {
cursor_.Current().Style().GetWritingMode());
if (!logical_size.block_size)
return false;
- // Use |ClosestLeafChildForPoint| to check if there's any leaf child.
- const bool only_editable_leaves = false;
- return ClosestLeafChildForPoint(cursor_, PhysicalOffset(),
- only_editable_leaves);
+ for (NGInlineCursor cursor(cursor_); cursor; cursor.MoveToNext()) {
+ const NGInlineCursorPosition& current = cursor.Current();
+ if (current.GetLayoutObject() && current.IsInlineLeaf())
+ return true;
+ }
+ return false;
}
AbstractLineBox PreviousLine() const {
@@ -119,18 +121,22 @@ class AbstractLineBox {
line_direction_point - absolute_block_point.top);
}
- const LayoutObject* ClosestLeafChildForPoint(
- const PhysicalOffset& point,
+ PositionWithAffinity PositionForPoint(
+ const PhysicalOffset& point_in_container,
bool only_editable_leaves) const {
- DCHECK(!IsNull());
if (IsOldLayout()) {
- return GetRootInlineBox().ClosestLeafChildForPoint(
- GetBlock().FlipForWritingMode(point), only_editable_leaves);
+ const LayoutObject* closest_leaf_child =
+ GetRootInlineBox().ClosestLeafChildForPoint(
+ GetBlock().FlipForWritingMode(point_in_container),
+ only_editable_leaves);
+ if (!closest_leaf_child)
+ return PositionWithAffinity();
+ const Node* node = closest_leaf_child->GetNode();
+ if (node && EditingIgnoresContent(*node))
+ return PositionWithAffinity(Position::InParentBeforeNode(*node));
+ return closest_leaf_child->PositionForPoint(point_in_container);
}
- const PhysicalOffset local_physical_point =
- point - cursor_.Current().OffsetInContainerBlock();
- return ClosestLeafChildForPoint(cursor_, local_physical_point,
- only_editable_leaves);
+ return PositionForPoint(cursor_, point_in_container, only_editable_leaves);
}
private:
@@ -180,47 +186,58 @@ class AbstractLineBox {
HasEditableStyle(*layout_object->GetNode());
}
- static const LayoutObject* ClosestLeafChildForPoint(
- const NGInlineCursor& line,
- const PhysicalOffset& point,
- bool only_editable_leaves) {
+ static PositionWithAffinity PositionForPoint(const NGInlineCursor& line,
+ const PhysicalOffset& point,
+ bool only_editable_leaves) {
+ DCHECK(line.Current().IsLineBox());
const PhysicalSize unit_square(LayoutUnit(1), LayoutUnit(1));
const LogicalOffset logical_point = point.ConvertToLogical(
line.Current().Style().GetWritingMode(), line.Current().BaseDirection(),
line.Current().Size(), unit_square);
const LayoutUnit inline_offset = logical_point.inline_offset;
- const LayoutObject* closest_leaf_child = nullptr;
+ NGInlineCursor closest_leaf_child;
LayoutUnit closest_leaf_distance;
- NGInlineCursor cursor(line);
- for (cursor.MoveToNext(); cursor; cursor.MoveToNext()) {
+ for (NGInlineCursor cursor = line.CursorForDescendants(); cursor;
+ cursor.MoveToNext()) {
if (!cursor.Current().GetLayoutObject())
continue;
if (!cursor.Current().IsInlineLeaf())
continue;
- if (only_editable_leaves && !IsEditable(cursor))
+ if (only_editable_leaves && !IsEditable(cursor)) {
+ // This condition allows us to move editable to editable with skipping
+ // non-editable element.
+ // [1] editing/selection/modify_move/move_backward_line_table.html
continue;
+ }
const LogicalRect fragment_logical_rect =
- cursor.Current().RectInContainerBlock().ConvertToLogical(
- line.Current().Style().GetWritingMode(),
- line.Current().BaseDirection(), line.Current().Size(),
- cursor.Current().Size());
+ line.Current().ConvertChildToLogical(
+ cursor.Current().RectInContainerBlock());
const LayoutUnit inline_min = fragment_logical_rect.offset.inline_offset;
const LayoutUnit inline_max = fragment_logical_rect.offset.inline_offset +
fragment_logical_rect.size.inline_size;
- if (inline_offset >= inline_min && inline_offset < inline_max)
- return cursor.Current().GetLayoutObject();
+ if (inline_offset >= inline_min && inline_offset < inline_max) {
+ closest_leaf_child = cursor;
+ break;
+ }
const LayoutUnit distance =
inline_offset < inline_min
? inline_min - inline_offset
: inline_offset - inline_max + LayoutUnit(1);
if (!closest_leaf_child || distance < closest_leaf_distance) {
- closest_leaf_child = cursor.Current().GetLayoutObject();
+ closest_leaf_child = cursor;
closest_leaf_distance = distance;
}
}
- return closest_leaf_child;
+ if (!closest_leaf_child)
+ return PositionWithAffinity();
+ const Node* const node = closest_leaf_child.Current().GetNode();
+ if (!node)
+ return PositionWithAffinity();
+ if (EditingIgnoresContent(*node))
+ return PositionWithAffinity(Position::BeforeNode(*node));
+ return closest_leaf_child.PositionForPointInChild(point);
}
enum class Type { kNull, kOldLayout, kLayoutNG };
@@ -439,15 +456,9 @@ VisiblePosition SelectionModifier::PreviousLinePosition(
PhysicalOffset point_in_line =
line.AbsoluteLineDirectionPointToLocalPointInBlock(
line_direction_point);
- const LayoutObject* closest_leaf_child =
- line.ClosestLeafChildForPoint(point_in_line, IsEditablePosition(p));
- if (closest_leaf_child) {
- const Node* node = closest_leaf_child->GetNode();
- if (node && EditingIgnoresContent(*node))
- return VisiblePosition::InParentBeforeNode(*node);
- return CreateVisiblePosition(
- closest_leaf_child->PositionForPoint(point_in_line));
- }
+ if (auto position =
+ line.PositionForPoint(point_in_line, IsEditablePosition(p)))
+ return CreateVisiblePosition(position);
}
// Could not find a previous line. This means we must already be on the first
@@ -509,15 +520,9 @@ VisiblePosition SelectionModifier::NextLinePosition(
PhysicalOffset point_in_line =
line.AbsoluteLineDirectionPointToLocalPointInBlock(
line_direction_point);
- const LayoutObject* closest_leaf_child =
- line.ClosestLeafChildForPoint(point_in_line, IsEditablePosition(p));
- if (closest_leaf_child) {
- const Node* node = closest_leaf_child->GetNode();
- if (node && EditingIgnoresContent(*node))
- return VisiblePosition::InParentBeforeNode(*node);
- return CreateVisiblePosition(
- closest_leaf_child->PositionForPoint(point_in_line));
- }
+ if (auto position =
+ line.PositionForPoint(point_in_line, IsEditablePosition(p)))
+ return CreateVisiblePosition(position);
}
// Could not find a next line. This means we must already be on the last line.
diff --git a/chromium/third_party/blink/renderer/core/editing/selection_modifier_test.cc b/chromium/third_party/blink/renderer/core/editing/selection_modifier_test.cc
index 1b0ac200a06..227a2a9858e 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_modifier_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/selection_modifier_test.cc
@@ -10,7 +10,21 @@
namespace blink {
-class SelectionModifierTest : public EditingTestBase {};
+class SelectionModifierTest : public EditingTestBase {
+ protected:
+ std::string MoveBackwardByLine(SelectionModifier& modifier) {
+ modifier.Modify(SelectionModifyAlteration::kMove,
+ SelectionModifyDirection::kBackward,
+ TextGranularity::kLine);
+ return GetSelectionTextFromBody(modifier.Selection().AsSelection());
+ }
+
+ std::string MoveForwardByLine(SelectionModifier& modifier) {
+ modifier.Modify(SelectionModifyAlteration::kMove,
+ SelectionModifyDirection::kForward, TextGranularity::kLine);
+ return GetSelectionTextFromBody(modifier.Selection().AsSelection());
+ }
+};
TEST_F(SelectionModifierTest, ExtendForwardByWordNone) {
SetBodyContent("abc");
@@ -30,6 +44,48 @@ TEST_F(SelectionModifierTest, MoveForwardByWordNone) {
EXPECT_EQ(SelectionInDOMTree(), modifier.Selection().AsSelection());
}
+TEST_F(SelectionModifierTest, MoveByLineHorizontal) {
+ LoadAhem();
+ InsertStyleElement(
+ "p {"
+ "font: 10px/20px Ahem;"
+ "padding: 10px;"
+ "writing-mode: horizontal-tb;"
+ "}");
+ const SelectionInDOMTree selection =
+ SetSelectionTextToBody("<p>ab|c<br>d<br><br>ghi</p>");
+ SelectionModifier modifier(GetFrame(), selection);
+
+ EXPECT_EQ("<p>abc<br>d|<br><br>ghi</p>", MoveForwardByLine(modifier));
+ EXPECT_EQ("<p>abc<br>d<br>|<br>ghi</p>", MoveForwardByLine(modifier));
+ EXPECT_EQ("<p>abc<br>d<br><br>gh|i</p>", MoveForwardByLine(modifier));
+
+ EXPECT_EQ("<p>abc<br>d<br>|<br>ghi</p>", MoveBackwardByLine(modifier));
+ EXPECT_EQ("<p>abc<br>d|<br><br>ghi</p>", MoveBackwardByLine(modifier));
+ EXPECT_EQ("<p>ab|c<br>d<br><br>ghi</p>", MoveBackwardByLine(modifier));
+}
+
+TEST_F(SelectionModifierTest, MoveByLineVertical) {
+ LoadAhem();
+ InsertStyleElement(
+ "p {"
+ "font: 10px/20px Ahem;"
+ "padding: 10px;"
+ "writing-mode: vertical-rl;"
+ "}");
+ const SelectionInDOMTree selection =
+ SetSelectionTextToBody("<p>ab|c<br>d<br><br>ghi</p>");
+ SelectionModifier modifier(GetFrame(), selection);
+
+ EXPECT_EQ("<p>abc<br>d|<br><br>ghi</p>", MoveForwardByLine(modifier));
+ EXPECT_EQ("<p>abc<br>d<br>|<br>ghi</p>", MoveForwardByLine(modifier));
+ EXPECT_EQ("<p>abc<br>d<br><br>gh|i</p>", MoveForwardByLine(modifier));
+
+ EXPECT_EQ("<p>abc<br>d<br>|<br>ghi</p>", MoveBackwardByLine(modifier));
+ EXPECT_EQ("<p>abc<br>d|<br><br>ghi</p>", MoveBackwardByLine(modifier));
+ EXPECT_EQ("<p>ab|c<br>d<br><br>ghi</p>", MoveBackwardByLine(modifier));
+}
+
TEST_F(SelectionModifierTest, PreviousLineWithDisplayNone) {
InsertStyleElement("body{font-family: monospace}");
const SelectionInDOMTree selection = SetSelectionTextToBody(
diff --git a/chromium/third_party/blink/renderer/core/editing/selection_template.cc b/chromium/third_party/blink/renderer/core/editing/selection_template.cc
index 8a6a042da43..b671302c771 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_template.cc
+++ b/chromium/third_party/blink/renderer/core/editing/selection_template.cc
@@ -49,7 +49,7 @@ bool SelectionTemplate<Strategy>::operator!=(
}
template <typename Strategy>
-void SelectionTemplate<Strategy>::Trace(Visitor* visitor) {
+void SelectionTemplate<Strategy>::Trace(Visitor* visitor) const {
visitor->Trace(base_);
visitor->Trace(extent_);
}
@@ -424,7 +424,7 @@ SelectionInFlatTree ConvertToSelectionInFlatTree(
template <typename Strategy>
void SelectionTemplate<Strategy>::InvalidSelectionResetter::Trace(
- blink::Visitor* visitor) {
+ blink::Visitor* visitor) const {
visitor->Trace(document_);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/selection_template.h b/chromium/third_party/blink/renderer/core/editing/selection_template.h
index 8e302f604d6..8730562adb1 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_template.h
+++ b/chromium/third_party/blink/renderer/core/editing/selection_template.h
@@ -84,7 +84,7 @@ class SelectionTemplate final {
explicit InvalidSelectionResetter(const SelectionTemplate&);
~InvalidSelectionResetter();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
const Member<const Document> document_;
@@ -121,7 +121,7 @@ class SelectionTemplate final {
// Returns |SelectionType| for |this| based on |base_| and |extent_|.
SelectionType Type() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void PrintTo(std::ostream*, const char* type) const;
#if DCHECK_IS_ON()
diff --git a/chromium/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc b/chromium/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc
index a9a285fed92..9e5974f2884 100644
--- a/chromium/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc
+++ b/chromium/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc
@@ -141,9 +141,11 @@ class MarkupAccumulator::ElementSerializationData final {
MarkupAccumulator::MarkupAccumulator(AbsoluteURLs resolve_urls_method,
SerializationType serialization_type,
- IncludeShadowRoots include_shadow_roots)
+ IncludeShadowRoots include_shadow_roots,
+ ClosedRootsSet include_closed_roots)
: formatter_(resolve_urls_method, serialization_type),
- include_shadow_roots_(include_shadow_roots) {}
+ include_shadow_roots_(include_shadow_roots),
+ include_closed_roots_(include_closed_roots) {}
MarkupAccumulator::~MarkupAccumulator() = default;
@@ -545,11 +547,10 @@ bool MarkupAccumulator::SerializeAsHTML() const {
std::pair<Node*, Element*> MarkupAccumulator::GetAuxiliaryDOMTree(
const Element& element) const {
ShadowRoot* shadow_root = element.GetShadowRoot();
- if (!shadow_root || include_shadow_roots_ != kIncludeShadowRoots ||
- shadow_root->GetType() != ShadowRootType::kOpen) {
+ if (!shadow_root || include_shadow_roots_ != kIncludeShadowRoots)
return std::pair<Node*, Element*>();
- }
- DCHECK(RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled());
+ DCHECK(RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled(
+ element.GetExecutionContext()));
AtomicString shadowroot_type;
switch (shadow_root->GetType()) {
case ShadowRootType::V0:
@@ -563,6 +564,11 @@ std::pair<Node*, Element*> MarkupAccumulator::GetAuxiliaryDOMTree(
shadowroot_type = "closed";
break;
}
+ if (shadow_root->GetType() == ShadowRootType::kClosed &&
+ !include_closed_roots_.Contains(shadow_root)) {
+ return std::pair<Node*, Element*>();
+ }
+
// Wrap the shadowroot into a declarative Shadow DOM <template shadowroot>
// element.
auto* template_element = MakeGarbageCollected<Element>(
diff --git a/chromium/third_party/blink/renderer/core/editing/serializers/markup_accumulator.h b/chromium/third_party/blink/renderer/core/editing/serializers/markup_accumulator.h
index 454bb5d4eff..3a9652fe992 100644
--- a/chromium/third_party/blink/renderer/core/editing/serializers/markup_accumulator.h
+++ b/chromium/third_party/blink/renderer/core/editing/serializers/markup_accumulator.h
@@ -46,7 +46,10 @@ class MarkupAccumulator {
STACK_ALLOCATED();
public:
- MarkupAccumulator(AbsoluteURLs, SerializationType, IncludeShadowRoots);
+ MarkupAccumulator(AbsoluteURLs,
+ SerializationType,
+ IncludeShadowRoots,
+ ClosedRootsSet = ClosedRootsSet());
virtual ~MarkupAccumulator();
template <typename Strategy>
@@ -60,6 +63,7 @@ class MarkupAccumulator {
MarkupFormatter formatter_;
StringBuilder markup_;
IncludeShadowRoots include_shadow_roots_;
+ ClosedRootsSet include_closed_roots_;
private:
bool SerializeAsHTML() const;
diff --git a/chromium/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc b/chromium/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc
index 7993c70f88d..ca8a51f1832 100644
--- a/chromium/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc
+++ b/chromium/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc
@@ -44,6 +44,7 @@
#include "third_party/blink/renderer/core/xmlns_names.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
+#include "third_party/blink/renderer/platform/wtf/text/character_visitor.h"
namespace blink {
@@ -110,15 +111,11 @@ void MarkupFormatter::AppendCharactersReplacingEntities(
return;
DCHECK_LE(offset + length, source.length());
- if (source.Is8Bit()) {
+ WTF::VisitCharacters(source, [&](const auto* chars, unsigned) {
AppendCharactersReplacingEntitiesInternal(
- result, source.Characters8() + offset, length, kEntityMaps,
- base::size(kEntityMaps), entity_mask);
- } else {
- AppendCharactersReplacingEntitiesInternal(
- result, source.Characters16() + offset, length, kEntityMaps,
- base::size(kEntityMaps), entity_mask);
- }
+ result, chars + offset, length, kEntityMaps, base::size(kEntityMaps),
+ entity_mask);
+ });
}
MarkupFormatter::MarkupFormatter(AbsoluteURLs resolve_urls_method,
@@ -383,17 +380,17 @@ EntityMask MarkupFormatter::EntityMaskForText(const Text& text) const {
if (text.parentElement())
parent_name = &(text.parentElement())->TagQName();
- if (parent_name &&
- (*parent_name == html_names::kScriptTag ||
- *parent_name == html_names::kStyleTag ||
- *parent_name == html_names::kXmpTag ||
- *parent_name == html_names::kIFrameTag ||
- *parent_name == html_names::kPlaintextTag ||
- *parent_name == html_names::kNoembedTag ||
- *parent_name == html_names::kNoframesTag ||
- (*parent_name == html_names::kNoscriptTag &&
- text.GetDocument().GetFrame() &&
- text.GetDocument().CanExecuteScripts(kNotAboutToExecuteScript))))
+ if (parent_name && (*parent_name == html_names::kScriptTag ||
+ *parent_name == html_names::kStyleTag ||
+ *parent_name == html_names::kXmpTag ||
+ *parent_name == html_names::kIFrameTag ||
+ *parent_name == html_names::kPlaintextTag ||
+ *parent_name == html_names::kNoembedTag ||
+ *parent_name == html_names::kNoframesTag ||
+ (*parent_name == html_names::kNoscriptTag &&
+ text.GetExecutionContext() &&
+ text.GetExecutionContext()->CanExecuteScripts(
+ kNotAboutToExecuteScript))))
return kEntityMaskInCDATA;
return kEntityMaskInHTMLPCDATA;
}
diff --git a/chromium/third_party/blink/renderer/core/editing/serializers/serialization.cc b/chromium/third_party/blink/renderer/core/editing/serializers/serialization.cc
index f688bb9a361..76173c1011a 100644
--- a/chromium/third_party/blink/renderer/core/editing/serializers/serialization.cc
+++ b/chromium/third_party/blink/renderer/core/editing/serializers/serialization.cc
@@ -91,7 +91,7 @@ class AttributeChange {
void Apply() { element_->setAttribute(name_, AtomicString(value_)); }
- void Trace(Visitor* visitor) { visitor->Trace(element_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(element_); }
private:
Member<Element> element_;
@@ -414,8 +414,9 @@ DocumentFragment* CreateFragmentFromMarkupWithContext(
node_after_context))
return nullptr;
- auto* tagged_document =
- MakeGarbageCollected<Document>(DocumentInit::Create());
+ auto* tagged_document = MakeGarbageCollected<Document>(
+ DocumentInit::Create().WithExecutionContext(
+ document.GetExecutionContext()));
tagged_document->SetContextFeatures(document.GetContextFeatures());
auto* root =
@@ -450,7 +451,8 @@ DocumentFragment* CreateFragmentFromMarkupWithContext(
String CreateMarkup(const Node* node,
ChildrenOnly children_only,
AbsoluteURLs should_resolve_urls,
- IncludeShadowRoots include_shadow_roots) {
+ IncludeShadowRoots include_shadow_roots,
+ ClosedRootsSet include_closed_roots) {
if (!node)
return "";
@@ -458,7 +460,7 @@ String CreateMarkup(const Node* node,
IsA<HTMLDocument>(node->GetDocument())
? SerializationType::kHTML
: SerializationType::kXML,
- include_shadow_roots);
+ include_shadow_roots, include_closed_roots);
return accumulator.SerializeNodes<EditingStrategy>(*node, children_only);
}
@@ -608,6 +610,11 @@ DocumentFragment* CreateFragmentForInnerOuterHTML(
const char* method,
ExceptionState& exception_state) {
DCHECK(context_element);
+ if (IsA<HTMLTemplateElement>(*context_element) &&
+ !context_element->GetExecutionContext()) {
+ return nullptr;
+ }
+
Document& document =
IsA<HTMLTemplateElement>(*context_element)
? context_element->GetDocument().EnsureTemplateDocument()
diff --git a/chromium/third_party/blink/renderer/core/editing/serializers/serialization.h b/chromium/third_party/blink/renderer/core/editing/serializers/serialization.h
index e5d456a8d0f..2838ebf353a 100644
--- a/chromium/third_party/blink/renderer/core/editing/serializers/serialization.h
+++ b/chromium/third_party/blink/renderer/core/editing/serializers/serialization.h
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/dom/parser_content_policy.h"
+#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/editing/forward.h"
#include "third_party/blink/renderer/core/editing/serializers/create_markup_options.h"
#include "third_party/blink/renderer/core/editing/serializers/html_interchange.h"
@@ -84,10 +85,13 @@ void ReplaceChildrenWithFragment(ContainerNode*,
ExceptionState&);
void ReplaceChildrenWithText(ContainerNode*, const String&, ExceptionState&);
-CORE_EXPORT String CreateMarkup(const Node*,
- ChildrenOnly = kIncludeNode,
- AbsoluteURLs = kDoNotResolveURLs,
- IncludeShadowRoots = kNoShadowRoots);
+using ClosedRootsSet = HeapHashSet<Member<ShadowRoot>>;
+CORE_EXPORT String
+CreateMarkup(const Node*,
+ ChildrenOnly = kIncludeNode,
+ AbsoluteURLs = kDoNotResolveURLs,
+ IncludeShadowRoots = kNoShadowRoots,
+ ClosedRootsSet include_closed_roots = ClosedRootsSet());
CORE_EXPORT String
CreateMarkup(const Position& start,
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.cc b/chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.cc
index 5fd35434c38..9635315def7 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.cc
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.cc
@@ -28,7 +28,7 @@ const int kInvalidChunkIndex = -1;
} // namespace
-void ColdModeSpellCheckRequester::Trace(Visitor* visitor) {
+void ColdModeSpellCheckRequester::Trace(Visitor* visitor) const {
visitor->Trace(window_);
visitor->Trace(root_editable_);
visitor->Trace(remaining_check_range_);
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.h b/chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.h
index 100eeba1a7b..d64c213ecf2 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.h
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.h
@@ -35,7 +35,7 @@ class ColdModeSpellCheckRequester
void ClearProgress();
bool FullyChecked() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
SpellCheckRequester& GetSpellCheckRequester() const;
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.cc b/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.cc
index 79a955961fe..40f70b0d27d 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.cc
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.cc
@@ -47,7 +47,7 @@ class IdleSpellCheckController::IdleCallback final
explicit IdleCallback(IdleSpellCheckController* controller)
: controller_(controller) {}
- void Trace(Visitor* visitor) final {
+ void Trace(Visitor* visitor) const final {
visitor->Trace(controller_);
ScriptedIdleTaskController::IdleTask::Trace(visitor);
}
@@ -62,7 +62,7 @@ class IdleSpellCheckController::IdleCallback final
IdleSpellCheckController::~IdleSpellCheckController() = default;
-void IdleSpellCheckController::Trace(Visitor* visitor) {
+void IdleSpellCheckController::Trace(Visitor* visitor) const {
visitor->Trace(cold_mode_requester_);
visitor->Trace(spell_check_requeseter_);
ExecutionContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h b/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h
index b2c3f7120bf..a5986a08d1d 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h
@@ -60,7 +60,7 @@ class CORE_EXPORT IdleSpellCheckController final
void SkipColdModeTimerForTesting();
int IdleCallbackHandle() const { return idle_callback_handle_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class IdleCallback;
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.cc b/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.cc
index a0a3ffc5ee9..8f8459f321d 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.cc
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.cc
@@ -94,7 +94,7 @@ SpellCheckRequest::SpellCheckRequest(Range* checking_range,
SpellCheckRequest::~SpellCheckRequest() = default;
-void SpellCheckRequest::Trace(Visitor* visitor) {
+void SpellCheckRequest::Trace(Visitor* visitor) const {
visitor->Trace(requester_);
visitor->Trace(checking_range_);
visitor->Trace(root_editable_element_);
@@ -193,13 +193,6 @@ bool SpellCheckRequester::RequestCheckingFor(const EphemeralRange& range,
if (!request)
return false;
- const base::TimeTicks current_request_time = base::TimeTicks::Now();
- if (request_num == 0 && last_request_time_ > base::TimeTicks()) {
- UMA_HISTOGRAM_TIMES("WebCore.SpellChecker.RequestInterval",
- current_request_time - last_request_time_);
- }
- last_request_time_ = current_request_time;
-
DCHECK_EQ(request->Sequence(),
SpellCheckRequest::kUnrequestedTextCheckingSequence);
int sequence = ++last_request_sequence_;
@@ -314,7 +307,7 @@ void SpellCheckRequester::DidCheckCancel(int sequence) {
DidCheck(sequence);
}
-void SpellCheckRequester::Trace(Visitor* visitor) {
+void SpellCheckRequester::Trace(Visitor* visitor) const {
visitor->Trace(window_);
visitor->Trace(processing_request_);
visitor->Trace(request_queue_);
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.h b/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.h
index 18bb605fa35..71904582cf9 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.h
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.h
@@ -68,7 +68,7 @@ class CORE_EXPORT SpellCheckRequest final
int RequestNumber() const { return request_number_; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<SpellCheckRequester> requester_;
@@ -84,7 +84,7 @@ class CORE_EXPORT SpellCheckRequester final
public:
explicit SpellCheckRequester(LocalDOMWindow&);
~SpellCheckRequester();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// Returns true if a request is initiated. Returns false otherwise.
bool RequestCheckingFor(const EphemeralRange&);
@@ -117,7 +117,6 @@ class CORE_EXPORT SpellCheckRequester final
int last_request_sequence_;
int last_processed_sequence_;
- base::TimeTicks last_request_time_;
TaskHandle timer_to_process_queued_request_;
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc b/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
index 57e3e2f7b46..b7180ef2252 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
@@ -607,7 +607,7 @@ void SpellChecker::RemoveMarkers(const EphemeralRange& range,
GetFrame().GetDocument()->Markers().RemoveMarkersInRange(range, marker_types);
}
-void SpellChecker::Trace(Visitor* visitor) {
+void SpellChecker::Trace(Visitor* visitor) const {
visitor->Trace(window_);
visitor->Trace(spell_check_requester_);
visitor->Trace(idle_spell_check_controller_);
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.h b/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.h
index 8144c0f224e..c467defbfd1 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.h
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.h
@@ -51,7 +51,7 @@ class CORE_EXPORT SpellChecker final : public GarbageCollected<SpellChecker> {
public:
explicit SpellChecker(LocalDOMWindow&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
WebSpellCheckPanelHostClient& SpellCheckPanelHostClient() const;
WebTextCheckClient* GetTextCheckerClient() const;
diff --git a/chromium/third_party/blink/renderer/core/editing/state_machines/backward_code_point_state_machine.cc b/chromium/third_party/blink/renderer/core/editing/state_machines/backward_code_point_state_machine.cc
index 99bca785c64..a63484d5787 100644
--- a/chromium/third_party/blink/renderer/core/editing/state_machines/backward_code_point_state_machine.cc
+++ b/chromium/third_party/blink/renderer/core/editing/state_machines/backward_code_point_state_machine.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/editing/state_machines/backward_code_point_state_machine.h"
+#include "base/notreached.h"
+
namespace blink {
enum class BackwardCodePointStateMachine::BackwardCodePointState {
diff --git a/chromium/third_party/blink/renderer/core/editing/state_machines/forward_code_point_state_machine.cc b/chromium/third_party/blink/renderer/core/editing/state_machines/forward_code_point_state_machine.cc
index 1375df8ab12..4ae08593bd7 100644
--- a/chromium/third_party/blink/renderer/core/editing/state_machines/forward_code_point_state_machine.cc
+++ b/chromium/third_party/blink/renderer/core/editing/state_machines/forward_code_point_state_machine.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/editing/state_machines/forward_code_point_state_machine.h"
+#include "base/notreached.h"
+
namespace blink {
enum class ForwardCodePointStateMachine::ForwardCodePointState {
diff --git a/chromium/third_party/blink/renderer/core/editing/state_machines/text_segmentation_machine_state.cc b/chromium/third_party/blink/renderer/core/editing/state_machines/text_segmentation_machine_state.cc
index ec327cb054a..9912151b3b9 100644
--- a/chromium/third_party/blink/renderer/core/editing/state_machines/text_segmentation_machine_state.cc
+++ b/chromium/third_party/blink/renderer/core/editing/state_machines/text_segmentation_machine_state.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/editing/state_machines/text_segmentation_machine_state.h"
#include <ostream> // NOLINT
+#include "base/check_op.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc b/chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc
index aa9d982eeb3..c0f08731484 100644
--- a/chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc
+++ b/chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc
@@ -250,7 +250,7 @@ void TextSuggestionController::HandlePotentialSuggestionTap(
text_suggestion_host_->StartSuggestionMenuTimer();
}
-void TextSuggestionController::Trace(Visitor* visitor) {
+void TextSuggestionController::Trace(Visitor* visitor) const {
visitor->Trace(window_);
visitor->Trace(text_suggestion_host_);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.h b/chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.h
index 40b2620e9df..adf8768bd9e 100644
--- a/chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.h
+++ b/chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.h
@@ -43,7 +43,7 @@ class CORE_EXPORT TextSuggestionController final
void OnSuggestionMenuClosed();
void SuggestionMenuTimeoutCallback(size_t max_number_of_suggestions);
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
friend class TextSuggestionControllerTest;
diff --git a/chromium/third_party/blink/renderer/core/editing/visible_position.cc b/chromium/third_party/blink/renderer/core/editing/visible_position.cc
index e2d8c4ebd6a..8d5860fe9bc 100644
--- a/chromium/third_party/blink/renderer/core/editing/visible_position.cc
+++ b/chromium/third_party/blink/renderer/core/editing/visible_position.cc
@@ -66,7 +66,7 @@ VisiblePositionTemplate<Strategy>::VisiblePositionTemplate(
}
template <typename Strategy>
-void VisiblePositionTemplate<Strategy>::Trace(Visitor* visitor) {
+void VisiblePositionTemplate<Strategy>::Trace(Visitor* visitor) const {
visitor->Trace(position_with_affinity_);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/visible_position.h b/chromium/third_party/blink/renderer/core/editing/visible_position.h
index 11a1fd482e3..5fb6fe9ec1c 100644
--- a/chromium/third_party/blink/renderer/core/editing/visible_position.h
+++ b/chromium/third_party/blink/renderer/core/editing/visible_position.h
@@ -100,7 +100,7 @@ class VisiblePositionTemplate final {
static VisiblePositionTemplate<Strategy> InParentBeforeNode(const Node&);
static VisiblePositionTemplate<Strategy> LastPositionInNode(const Node&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
#if DCHECK_IS_ON()
void ShowTreeForThis() const;
diff --git a/chromium/third_party/blink/renderer/core/editing/visible_position_test.cc b/chromium/third_party/blink/renderer/core/editing/visible_position_test.cc
index 3d71e51c2d0..46cb89b1c01 100644
--- a/chromium/third_party/blink/renderer/core/editing/visible_position_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/visible_position_test.cc
@@ -12,6 +12,132 @@ namespace blink {
class VisiblePositionTest : public EditingTestBase {};
+TEST_F(VisiblePositionTest, EmptyEditable) {
+ SetBodyContent("<div id=target contenteditable></div>");
+ const Element& target = *GetElementById("target");
+
+ EXPECT_EQ(Position(target, 0),
+ CreateVisiblePosition(Position(target, 0)).DeepEquivalent());
+ EXPECT_EQ(Position(target, 0),
+ CreateVisiblePosition(Position::FirstPositionInNode(target))
+ .DeepEquivalent());
+ EXPECT_EQ(Position(target, 0),
+ CreateVisiblePosition(Position::LastPositionInNode(target))
+ .DeepEquivalent());
+}
+
+TEST_F(VisiblePositionTest, EmptyEditableWithBlockChild) {
+ // Note: Placeholder <br> is needed to have non-zero editable.
+ SetBodyContent("<div id=target contenteditable><div><br></div></div>");
+ const Element& target = *GetElementById("target");
+ const Node& div = *target.firstChild();
+ const Node& br = *div.firstChild();
+
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position(target, 0)).DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position::FirstPositionInNode(target))
+ .DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position::LastPositionInNode(target))
+ .DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position(target, 1)).DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position(div, 0)).DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position::BeforeNode(div)).DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position::AfterNode(div)).DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position::BeforeNode(br)).DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position::AfterNode(br)).DeepEquivalent());
+}
+
+TEST_F(VisiblePositionTest, EmptyEditableWithInlineChild) {
+ SetBodyContent("<div id=target contenteditable><span></span></div>");
+ const Element& target = *GetElementById("target");
+ const Node& span = *target.firstChild();
+
+ EXPECT_EQ(Position(target, 0),
+ CreateVisiblePosition(Position(target, 0)).DeepEquivalent());
+ EXPECT_EQ(Position(target, 0),
+ CreateVisiblePosition(Position::FirstPositionInNode(target))
+ .DeepEquivalent());
+ EXPECT_EQ(Position(target, 0),
+ CreateVisiblePosition(Position::LastPositionInNode(target))
+ .DeepEquivalent());
+ EXPECT_EQ(Position(target, 0),
+ CreateVisiblePosition(Position(target, 1)).DeepEquivalent());
+ EXPECT_EQ(Position(target, 0),
+ CreateVisiblePosition(Position(span, 0)).DeepEquivalent());
+ EXPECT_EQ(Position(target, 0),
+ CreateVisiblePosition(Position::BeforeNode(span)).DeepEquivalent());
+ EXPECT_EQ(Position(target, 0),
+ CreateVisiblePosition(Position::AfterNode(span)).DeepEquivalent());
+}
+
+TEST_F(VisiblePositionTest, PlaceholderBR) {
+ SetBodyContent("<div id=target><br id=br></div>");
+ const Element& target = *GetElementById("target");
+ const Element& br = *GetElementById("br");
+
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position(target, 0)).DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position::FirstPositionInNode(target))
+ .DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position::LastPositionInNode(target))
+ .DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position(target, 1)).DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position(br, 0)).DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position::BeforeNode(br)).DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position::AfterNode(br)).DeepEquivalent());
+}
+
+TEST_F(VisiblePositionTest, PlaceholderBRWithCollapsedSpace) {
+ SetBodyContent("<div id=target> <br id=br> </div>");
+ const Element& target = *GetElementById("target");
+ const Element& br = *GetElementById("br");
+
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position(target, 0)).DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position::FirstPositionInNode(target))
+ .DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position::LastPositionInNode(target))
+ .DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position(target, 1)).DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position(target, 2)).DeepEquivalent());
+ EXPECT_EQ(
+ Position::BeforeNode(br),
+ CreateVisiblePosition(Position(target.firstChild(), 0)).DeepEquivalent());
+ EXPECT_EQ(
+ Position::BeforeNode(br),
+ CreateVisiblePosition(Position(target.firstChild(), 1)).DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position(br, 0)).DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position::BeforeNode(br)).DeepEquivalent());
+ EXPECT_EQ(Position::BeforeNode(br),
+ CreateVisiblePosition(Position::AfterNode(br)).DeepEquivalent());
+ EXPECT_EQ(
+ Position::BeforeNode(br),
+ CreateVisiblePosition(Position(target.lastChild(), 0)).DeepEquivalent());
+ EXPECT_EQ(
+ Position::BeforeNode(br),
+ CreateVisiblePosition(Position(target.lastChild(), 1)).DeepEquivalent());
+}
+
TEST_F(VisiblePositionTest, ShadowV0DistributedNodes) {
const char* body_content =
"<p id='host'>00<b id='one'>11</b><b id='two'>22</b>33</p>";
diff --git a/chromium/third_party/blink/renderer/core/editing/visible_selection.cc b/chromium/third_party/blink/renderer/core/editing/visible_selection.cc
index 6ce08a7c752..c6ab0e1cb4d 100644
--- a/chromium/third_party/blink/renderer/core/editing/visible_selection.cc
+++ b/chromium/third_party/blink/renderer/core/editing/visible_selection.cc
@@ -361,7 +361,7 @@ VisibleSelectionTemplate<Strategy>::VisibleExtent() const {
}
template <typename Strategy>
-void VisibleSelectionTemplate<Strategy>::Trace(Visitor* visitor) {
+void VisibleSelectionTemplate<Strategy>::Trace(Visitor* visitor) const {
visitor->Trace(base_);
visitor->Trace(extent_);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/visible_selection.h b/chromium/third_party/blink/renderer/core/editing/visible_selection.h
index 14eaf8f1814..95dfd066969 100644
--- a/chromium/third_party/blink/renderer/core/editing/visible_selection.h
+++ b/chromium/third_party/blink/renderer/core/editing/visible_selection.h
@@ -95,7 +95,7 @@ class VisibleSelectionTemplate {
const PositionTemplate<Strategy>& extent,
TextAffinity);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
#if DCHECK_IS_ON()
void ShowTreeForThis() const;
diff --git a/chromium/third_party/blink/renderer/core/editing/visible_units.cc b/chromium/third_party/blink/renderer/core/editing/visible_units.cc
index b95c6220bbd..f308a027492 100644
--- a/chromium/third_party/blink/renderer/core/editing/visible_units.cc
+++ b/chromium/third_party/blink/renderer/core/editing/visible_units.cc
@@ -56,6 +56,7 @@
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/line/inline_iterator.h"
#include "third_party/blink/renderer/core/layout/line/inline_text_box.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h"
#include "third_party/blink/renderer/core/svg_element_type_helpers.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/text/text_boundaries.h"
@@ -452,6 +453,20 @@ bool HasRenderedNonAnonymousDescendantsWithHeight(
const LayoutObject* layout_object) {
if (DisplayLockUtilities::NearestLockedInclusiveAncestor(*layout_object))
return false;
+ if (auto* block_flow = DynamicTo<LayoutBlockFlow>(layout_object)) {
+ // Returns false for empty content editable, e.g.
+ // - <div contenteditable></div>
+ // - <div contenteditable><span></span></div>
+ // Note: tests[1][2] require this.
+ // [1] editing/style/underline.html
+ // [2] editing/inserting/return-with-object-element.html
+ if (block_flow->HasNGInlineNodeData() &&
+ block_flow->GetNGInlineNodeData()
+ ->ItemsData(false)
+ .text_content.IsEmpty() &&
+ block_flow->HasLineIfEmpty())
+ return false;
+ }
const LayoutObject* stop = layout_object->NextInPreOrderAfterChildren();
// TODO(editing-dev): Avoid single-character parameter names.
for (LayoutObject* o = layout_object->SlowFirstChild(); o && o != stop;
diff --git a/chromium/third_party/blink/renderer/core/editing/visible_units_line.cc b/chromium/third_party/blink/renderer/core/editing/visible_units_line.cc
index 766bba980ae..f18f9d02490 100644
--- a/chromium/third_party/blink/renderer/core/editing/visible_units_line.cc
+++ b/chromium/third_party/blink/renderer/core/editing/visible_units_line.cc
@@ -46,6 +46,109 @@ namespace {
struct VisualOrdering;
+// See also InlineBidiResolver::NeedsTrailingSpace()
+bool NeedsTrailingSpace(const ComputedStyle& style) {
+ return style.BreakOnlyAfterWhiteSpace() && style.AutoWrap();
+}
+
+static PositionWithAffinity AdjustForSoftLineWrap(
+ const NGInlineCursorPosition& line_box,
+ const PositionWithAffinity& position) {
+ DCHECK(line_box.IsLineBox());
+ if (position.IsNull())
+ return PositionWithAffinity();
+ if (!NeedsTrailingSpace(line_box.Style()) ||
+ !line_box.HasSoftWrapToNextLine())
+ return position;
+ // Returns a position after first space causing soft line wrap for editable.
+ if (!NGOffsetMapping::AcceptsPosition(position.GetPosition()))
+ return position;
+ const NGOffsetMapping* mapping =
+ NGOffsetMapping::GetFor(position.GetPosition());
+ const auto offset = mapping->GetTextContentOffset(position.GetPosition());
+ if (offset == mapping->GetText().length())
+ return position;
+ const Position adjusted_position = mapping->GetFirstPosition(*offset + 1);
+ if (adjusted_position.IsNull())
+ return position;
+ DCHECK(IsA<Text>(adjusted_position.AnchorNode())) << adjusted_position;
+ if (!IsA<Text>(adjusted_position.AnchorNode()))
+ return position;
+ if (!adjusted_position.AnchorNode()
+ ->GetLayoutObject()
+ ->StyleRef()
+ .IsCollapsibleWhiteSpace(mapping->GetText()[*offset]))
+ return position;
+ return PositionWithAffinity(adjusted_position,
+ TextAffinity::kUpstreamIfPossible);
+}
+
+template <typename Strategy, typename Ordering>
+static PositionWithAffinityTemplate<Strategy> EndPositionForLine(
+ const PositionWithAffinityTemplate<Strategy>& c) {
+ if (c.IsNull())
+ return PositionWithAffinityTemplate<Strategy>();
+ const PositionWithAffinityTemplate<Strategy> adjusted =
+ ComputeInlineAdjustedPosition(c);
+
+ if (const LayoutBlockFlow* context =
+ NGInlineFormattingContextOf(adjusted.GetPosition())) {
+ DCHECK((std::is_same<Ordering, VisualOrdering>::value) ||
+ !RuntimeEnabledFeatures::BidiCaretAffinityEnabled())
+ << "Logical line boundary for BidiCaretAffinity is not implemented yet";
+
+ const NGCaretPosition caret_position = ComputeNGCaretPosition(adjusted);
+ if (caret_position.IsNull()) {
+ // TODO(crbug.com/947593): Support |ComputeNGCaretPosition()| on content
+ // hidden by 'text-overflow:ellipsis' so that we always have a non-null
+ // |caret_position| here.
+ return PositionWithAffinityTemplate<Strategy>();
+ }
+ NGInlineCursor line_box = caret_position.cursor;
+ line_box.MoveToContainingLine();
+ const PositionWithAffinity end_position = line_box.PositionForEndOfLine();
+ return FromPositionInDOMTree<Strategy>(
+ AdjustForSoftLineWrap(line_box.Current(), end_position));
+ }
+
+ const InlineBox* inline_box =
+ adjusted.IsNotNull() ? ComputeInlineBoxPosition(c).inline_box : nullptr;
+ if (!inline_box) {
+ // There are VisiblePositions at offset 0 in blocks without
+ // RootInlineBoxes, like empty editable blocks and bordered blocks.
+ const PositionTemplate<Strategy> p = c.GetPosition();
+ if (p.AnchorNode()->GetLayoutObject() &&
+ p.AnchorNode()->GetLayoutObject()->IsLayoutBlock() &&
+ !p.ComputeEditingOffset())
+ return c;
+ return PositionWithAffinityTemplate<Strategy>();
+ }
+
+ const RootInlineBox& root_box = inline_box->Root();
+ const InlineBox* const end_box = Ordering::EndNonPseudoBoxOf(root_box);
+ if (!end_box)
+ return PositionWithAffinityTemplate<Strategy>();
+
+ const Node* const end_node = end_box->GetLineLayoutItem().NonPseudoNode();
+ DCHECK(end_node);
+ if (IsA<HTMLBRElement>(*end_node)) {
+ return Ordering::AdjustForSoftLineWrap(
+ PositionTemplate<Strategy>::BeforeNode(*end_node), c);
+ }
+
+ auto* end_text_node = DynamicTo<Text>(end_node);
+ if (end_box->IsInlineTextBox() && end_text_node) {
+ const InlineTextBox* end_text_box = ToInlineTextBox(end_box);
+ int end_offset = end_text_box->Start();
+ if (!end_text_box->IsLineBreak())
+ end_offset += end_text_box->Len();
+ return Ordering::AdjustForSoftLineWrap(
+ PositionTemplate<Strategy>(end_text_node, end_offset), c);
+ }
+ return Ordering::AdjustForSoftLineWrap(
+ PositionTemplate<Strategy>::AfterNode(*end_node), c);
+}
+
template <typename Strategy, typename Ordering>
PositionWithAffinityTemplate<Strategy> StartPositionForLine(
const PositionWithAffinityTemplate<Strategy>& c) {
@@ -70,9 +173,7 @@ PositionWithAffinityTemplate<Strategy> StartPositionForLine(
NGInlineCursor line_box = caret_position.cursor;
line_box.MoveToContainingLine();
DCHECK(line_box.Current().IsLineBox()) << line_box;
- const PhysicalOffset start_point = line_box.Current().LineStartPoint();
- return FromPositionInDOMTree<Strategy>(
- line_box.PositionForPointInInlineBox(start_point));
+ return FromPositionInDOMTree<Strategy>(line_box.PositionForStartOfLine());
}
const InlineBox* inline_box =
@@ -116,6 +217,27 @@ struct LogicalOrdering {
static const InlineBox* EndNonPseudoBoxOf(const RootInlineBox& root_box) {
return root_box.GetLogicalEndNonPseudoBox();
}
+
+ // Make sure the end of line is at the same line as the given input
+ // position. For a wrapping line, the logical end position for the
+ // not-last-2-lines might incorrectly hand back the logical beginning of the
+ // next line. For example,
+ // <div contenteditable dir="rtl" style="line-break:before-white-space">xyz
+ // a xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz </div>
+ // In this case, use the previous position of the computed logical end
+ // position.
+ template <typename Strategy>
+ static PositionWithAffinityTemplate<Strategy> AdjustForSoftLineWrap(
+ const PositionTemplate<Strategy>& candidate,
+ const PositionWithAffinityTemplate<Strategy>& current_position) {
+ const PositionWithAffinityTemplate<Strategy> candidate_position =
+ PositionWithAffinityTemplate<Strategy>(
+ candidate, TextAffinity::kUpstreamIfPossible);
+ if (InSameLogicalLine(current_position, candidate_position))
+ return candidate_position;
+ return PreviousPositionOf(CreateVisiblePosition(candidate_position))
+ .ToPositionWithAffinity();
+ }
};
// Provides start end end of line in visual order for implementing expanding
@@ -148,6 +270,31 @@ struct VisualOrdering {
}
return nullptr;
}
+
+ // Make sure the end of line is at the same line as the given input
+ // position. Else use the previous position to obtain end of line. This
+ // condition happens when the input position is before the space character
+ // at the end of a soft-wrapped non-editable line. In this scenario,
+ // |EndPositionForLine()| would incorrectly hand back a position in the next
+ // line instead. This fix is to account for the discrepancy between lines
+ // with "webkit-line-break:after-white-space" style versus lines without
+ // that style, which would break before a space by default.
+ template <typename Strategy>
+ static PositionWithAffinityTemplate<Strategy> AdjustForSoftLineWrap(
+ const PositionTemplate<Strategy>& candidate,
+ const PositionWithAffinityTemplate<Strategy>& current_position) {
+ const PositionWithAffinityTemplate<Strategy> candidate_position =
+ PositionWithAffinityTemplate<Strategy>(
+ candidate, TextAffinity::kUpstreamIfPossible);
+ if (InSameLine(current_position, candidate_position))
+ return candidate_position;
+ const PositionWithAffinityTemplate<Strategy>& adjusted_position =
+ PreviousPositionOf(CreateVisiblePosition(current_position))
+ .ToPositionWithAffinity();
+ if (adjusted_position.IsNull())
+ return PositionWithAffinityTemplate<Strategy>();
+ return EndPositionForLine<Strategy, VisualOrdering>(adjusted_position);
+ }
};
template <typename Strategy>
@@ -229,75 +376,6 @@ VisiblePositionInFlatTree LogicalStartOfLine(
LogicalStartOfLine(current_position.ToPositionWithAffinity()));
}
-template <typename Strategy, typename Ordering>
-static PositionWithAffinityTemplate<Strategy> EndPositionForLine(
- const PositionWithAffinityTemplate<Strategy>& c) {
- if (c.IsNull())
- return PositionWithAffinityTemplate<Strategy>();
- const PositionWithAffinityTemplate<Strategy> adjusted =
- ComputeInlineAdjustedPosition(c);
-
- if (const LayoutBlockFlow* context =
- NGInlineFormattingContextOf(adjusted.GetPosition())) {
- DCHECK((std::is_same<Ordering, VisualOrdering>::value) ||
- !RuntimeEnabledFeatures::BidiCaretAffinityEnabled())
- << "Logical line boundary for BidiCaretAffinity is not implemented yet";
-
- const NGCaretPosition caret_position = ComputeNGCaretPosition(adjusted);
- if (caret_position.IsNull()) {
- // TODO(crbug.com/947593): Support |ComputeNGCaretPosition()| on content
- // hidden by 'text-overflow:ellipsis' so that we always have a non-null
- // |caret_position| here.
- return PositionWithAffinityTemplate<Strategy>();
- }
- NGInlineCursor line_box = caret_position.cursor;
- line_box.MoveToContainingLine();
- const PhysicalOffset end_point = line_box.Current().LineEndPoint();
- return FromPositionInDOMTree<Strategy>(
- line_box.PositionForPointInInlineBox(end_point));
- }
-
- const InlineBox* inline_box =
- adjusted.IsNotNull() ? ComputeInlineBoxPosition(c).inline_box : nullptr;
- if (!inline_box) {
- // There are VisiblePositions at offset 0 in blocks without
- // RootInlineBoxes, like empty editable blocks and bordered blocks.
- const PositionTemplate<Strategy> p = c.GetPosition();
- if (p.AnchorNode()->GetLayoutObject() &&
- p.AnchorNode()->GetLayoutObject()->IsLayoutBlock() &&
- !p.ComputeEditingOffset())
- return c;
- return PositionWithAffinityTemplate<Strategy>();
- }
-
- const RootInlineBox& root_box = inline_box->Root();
- const InlineBox* const end_box = Ordering::EndNonPseudoBoxOf(root_box);
- if (!end_box)
- return PositionWithAffinityTemplate<Strategy>();
-
- const Node* const end_node = end_box->GetLineLayoutItem().NonPseudoNode();
- DCHECK(end_node);
- if (IsA<HTMLBRElement>(*end_node)) {
- return PositionWithAffinityTemplate<Strategy>(
- PositionTemplate<Strategy>::BeforeNode(*end_node),
- TextAffinity::kUpstreamIfPossible);
- }
-
- auto* end_text_node = DynamicTo<Text>(end_node);
- if (end_box->IsInlineTextBox() && end_text_node) {
- const InlineTextBox* end_text_box = ToInlineTextBox(end_box);
- int end_offset = end_text_box->Start();
- if (!end_text_box->IsLineBreak())
- end_offset += end_text_box->Len();
- return PositionWithAffinityTemplate<Strategy>(
- PositionTemplate<Strategy>(end_text_node, end_offset),
- TextAffinity::kUpstreamIfPossible);
- }
- return PositionWithAffinityTemplate<Strategy>(
- PositionTemplate<Strategy>::AfterNode(*end_node),
- TextAffinity::kUpstreamIfPossible);
-}
-
// TODO(yosin) Rename this function to reflect the fact it ignores bidi levels.
template <typename Strategy>
static PositionWithAffinityTemplate<Strategy> EndOfLineAlgorithm(
@@ -307,26 +385,8 @@ static PositionWithAffinityTemplate<Strategy> EndOfLineAlgorithm(
const PositionWithAffinityTemplate<Strategy>& candidate_position =
EndPositionForLine<Strategy, VisualOrdering>(current_position);
- // Make sure the end of line is at the same line as the given input
- // position. Else use the previous position to obtain end of line. This
- // condition happens when the input position is before the space character
- // at the end of a soft-wrapped non-editable line. In this scenario,
- // |endPositionForLine()| would incorrectly hand back a position in the next
- // line instead. This fix is to account for the discrepancy between lines
- // with "webkit-line-break:after-white-space" style versus lines without
- // that style, which would break before a space by default.
- if (InSameLine(current_position, candidate_position)) {
- return AdjustForwardPositionToAvoidCrossingEditingBoundaries(
- candidate_position, current_position.GetPosition());
- }
- const PositionWithAffinityTemplate<Strategy>& adjusted_position =
- PreviousPositionOf(CreateVisiblePosition(current_position))
- .ToPositionWithAffinity();
- if (adjusted_position.IsNull())
- return PositionWithAffinityTemplate<Strategy>();
return AdjustForwardPositionToAvoidCrossingEditingBoundaries(
- EndPositionForLine<Strategy, VisualOrdering>(adjusted_position),
- current_position.GetPosition());
+ candidate_position, current_position.GetPosition());
}
static PositionWithAffinity EndOfLine(const PositionWithAffinity& position) {
@@ -366,33 +426,20 @@ static PositionWithAffinityTemplate<Strategy> LogicalEndOfLineAlgorithm(
const PositionWithAffinityTemplate<Strategy>& current_position) {
// TODO(yosin) this is the current behavior that might need to be fixed.
// Please refer to https://bugs.webkit.org/show_bug.cgi?id=49107 for detail.
- PositionWithAffinityTemplate<Strategy> vis_pos =
+ const PositionWithAffinityTemplate<Strategy> candidate_position =
EndPositionForLine<Strategy, LogicalOrdering>(current_position);
- // Make sure the end of line is at the same line as the given input
- // position. For a wrapping line, the logical end position for the
- // not-last-2-lines might incorrectly hand back the logical beginning of the
- // next line. For example,
- // <div contenteditable dir="rtl" style="line-break:before-white-space">xyz
- // a xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz </div>
- // In this case, use the previous position of the computed logical end
- // position.
- if (!InSameLogicalLine(current_position, vis_pos)) {
- vis_pos = PreviousPositionOf(CreateVisiblePosition(vis_pos))
- .ToPositionWithAffinity();
- }
-
if (ContainerNode* editable_root =
HighestEditableRoot(current_position.GetPosition())) {
if (!editable_root->contains(
- vis_pos.GetPosition().ComputeContainerNode())) {
+ candidate_position.GetPosition().ComputeContainerNode())) {
return PositionWithAffinityTemplate<Strategy>(
PositionTemplate<Strategy>::LastPositionInNode(*editable_root));
}
}
return AdjustForwardPositionToAvoidCrossingEditingBoundaries(
- vis_pos, current_position.GetPosition());
+ candidate_position, current_position.GetPosition());
}
static PositionWithAffinity LogicalEndOfLine(
@@ -435,10 +482,11 @@ static bool InSameLineAlgorithm(
if (block1 || block2) {
if (block1 != block2)
return false;
- // TODO(editing-dev): We may incorrectly return false if a position is in
- // an empty NG block with height, in which case there is no line box. We
- // must handle this case when enabling Layout NG for contenteditable.
- return InSameNGLineBox(position1, position2);
+ if (!InSameNGLineBox(position1, position2))
+ return false;
+ // See (ParameterizedVisibleUnitsLineTest.InSameLineWithMixedEditability
+ return RootEditableElementOf(position1.GetPosition()) ==
+ RootEditableElementOf(position2.GetPosition());
}
// Neither positions are in LayoutNG. Fall through to legacy handling.
diff --git a/chromium/third_party/blink/renderer/core/editing/visible_units_line_test.cc b/chromium/third_party/blink/renderer/core/editing/visible_units_line_test.cc
index 1e6bf188ee5..c1dfc5abed1 100644
--- a/chromium/third_party/blink/renderer/core/editing/visible_units_line_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/visible_units_line_test.cc
@@ -51,6 +51,20 @@ class VisibleUnitsLineTest : public EditingTestBase {
static bool LayoutNGEnabled() {
return RuntimeEnabledFeatures::LayoutNGEnabled();
}
+
+ std::string TestEndOfLine(const std::string& input) {
+ const Position& caret = SetCaretTextToBody(input);
+ const Position& result =
+ EndOfLine(CreateVisiblePosition(caret)).DeepEquivalent();
+ return GetCaretTextFromBody(result);
+ }
+
+ std::string TestLogicalEndOfLine(const std::string& input) {
+ const Position& caret = SetCaretTextToBody(input);
+ const Position& result =
+ LogicalEndOfLine(CreateVisiblePosition(caret)).DeepEquivalent();
+ return GetCaretTextFromBody(result);
+ }
};
class ParameterizedVisibleUnitsLineTest
@@ -649,6 +663,139 @@ TEST_F(VisibleUnitsLineTest, startOfLine) {
StartOfLine(CreateVisiblePositionInFlatTree(*seven, 1)).DeepEquivalent());
}
+TEST_P(ParameterizedVisibleUnitsLineTest, EndOfLineWithSoftLineWrap3) {
+ LoadAhem();
+ InsertStyleElement(
+ "div {"
+ "font: 10px/1 Ahem; width: 3ch; word-break: break-all; }");
+
+ EXPECT_EQ("<div>abc|def</div>", TestEndOfLine("<div>|abcdef</div>"));
+ EXPECT_EQ(
+ "<div dir=\"rtl\"><bdo dir=\"rtl\">abc|def</bdo></div>",
+ TestEndOfLine("<div dir=\"rtl\"><bdo dir=\"rtl\">|abcdef</bdo></div>"));
+
+ // Note: Both legacy and NG layout don't have text boxes for spaces cause
+ // soft line wrap.
+ EXPECT_EQ("<div>abc| def ghi</div>",
+ TestEndOfLine("<div>|abc def ghi</div>"));
+ EXPECT_EQ("<div>abc| def ghi</div>",
+ TestEndOfLine("<div>ab|c def ghi</div>"));
+ EXPECT_EQ("<div>abc| def ghi</div>",
+ TestEndOfLine("<div>abc| def ghi</div>"));
+ EXPECT_EQ("<div>abc def| ghi</div>",
+ TestEndOfLine("<div>abc |def ghi</div>"));
+
+ EXPECT_EQ("<div dir=\"rtl\"><bdo dir=\"rtl\">abc| def ghi</bdo></div>",
+ TestEndOfLine(
+ "<div dir=\"rtl\"><bdo dir=\"rtl\">|abc def ghi</bdo></div>"));
+ EXPECT_EQ("<div dir=\"rtl\"><bdo dir=\"rtl\">abc| def ghi</bdo></div>",
+ TestEndOfLine(
+ "<div dir=\"rtl\"><bdo dir=\"rtl\">ab|c def ghi</bdo></div>"));
+ EXPECT_EQ("<div dir=\"rtl\"><bdo dir=\"rtl\">abc| def ghi</bdo></div>",
+ TestEndOfLine(
+ "<div dir=\"rtl\"><bdo dir=\"rtl\">abc| def ghi</bdo></div>"));
+ EXPECT_EQ("<div dir=\"rtl\"><bdo dir=\"rtl\">abc def| ghi</bdo></div>",
+ TestEndOfLine(
+ "<div dir=\"rtl\"><bdo dir=\"rtl\">abc |def ghi</bdo></div>"));
+
+ // On content editable, caret is after a space.
+ // Note: Legacy layout has text boxes at end of line for space cause soft line
+ // wrap for editable text, e.g.
+ // LayoutText {#text} at (10,9) size 18x32
+ // text run at (10,9) width 18: "abc"
+ // text run at (28,9) width 0: " "
+ // text run at (10,19) width 18: "def"
+ // text run at (28,19) width 0: " "
+ // text run at (10,29) width 18: "ghi"
+ EXPECT_EQ("<div contenteditable>abc |def ghi</div>",
+ TestEndOfLine("<div contenteditable>|abc def ghi</div>"));
+ EXPECT_EQ("<div contenteditable>abc |def ghi</div>",
+ TestEndOfLine("<div contenteditable>ab|c def ghi</div>"));
+ EXPECT_EQ("<div contenteditable>abc |def ghi</div>",
+ TestEndOfLine("<div contenteditable>abc| def ghi</div>"));
+ EXPECT_EQ("<div contenteditable>abc def |ghi</div>",
+ TestEndOfLine("<div contenteditable>abc |def ghi</div>"));
+}
+
+TEST_P(ParameterizedVisibleUnitsLineTest, EndOfLineWithSoftLineWrap4) {
+ LoadAhem();
+ InsertStyleElement("div { font: 10px/1 Ahem; width: 4ch; }");
+
+ EXPECT_EQ("<div>abc| def ghi</div>",
+ TestEndOfLine("<div>|abc def ghi</div>"));
+ EXPECT_EQ("<div>abc| def ghi</div>",
+ TestEndOfLine("<div>ab|c def ghi</div>"));
+ EXPECT_EQ("<div>abc| def ghi</div>",
+ TestEndOfLine("<div>abc| def ghi</div>"));
+ EXPECT_EQ("<div>abc def| ghi</div>",
+ TestEndOfLine("<div>abc |def ghi</div>"));
+
+ // On content editable, caret is after a space.
+ EXPECT_EQ("<div contenteditable>abc |def ghi</div>",
+ TestEndOfLine("<div contenteditable>|abc def ghi</div>"));
+ EXPECT_EQ("<div contenteditable>abc |def ghi</div>",
+ TestEndOfLine("<div contenteditable>ab|c def ghi</div>"));
+ EXPECT_EQ("<div contenteditable>abc |def ghi</div>",
+ TestEndOfLine("<div contenteditable>abc| def ghi</div>"));
+ EXPECT_EQ("<div contenteditable>abc def |ghi</div>",
+ TestEndOfLine("<div contenteditable>abc |def ghi</div>"));
+}
+
+TEST_P(ParameterizedVisibleUnitsLineTest, LogicalEndOfLineWithSoftLineWrap3) {
+ LoadAhem();
+ InsertStyleElement(
+ "div {"
+ "font: 10px/1 Ahem; width: 3ch; word-break: break-all; }");
+
+ EXPECT_EQ("<div>abc|def</div>", TestLogicalEndOfLine("<div>|abcdef</div>"));
+ EXPECT_EQ("<div dir=\"rtl\"><bdo dir=\"rtl\">abc|def</bdo></div>",
+ TestLogicalEndOfLine(
+ "<div dir=\"rtl\"><bdo dir=\"rtl\">|abcdef</bdo></div>"));
+
+ EXPECT_EQ("<div>abc| def ghi</div>",
+ TestLogicalEndOfLine("<div>|abc def ghi</div>"));
+ EXPECT_EQ("<div>abc| def ghi</div>",
+ TestLogicalEndOfLine("<div>ab|c def ghi</div>"));
+ EXPECT_EQ("<div>abc| def ghi</div>",
+ TestLogicalEndOfLine("<div>abc| def ghi</div>"));
+ EXPECT_EQ("<div>abc def| ghi</div>",
+ TestLogicalEndOfLine("<div>abc |def ghi</div>"));
+
+ // On content editable, caret is after a space.
+ EXPECT_EQ("<div contenteditable>abc |def ghi</div>",
+ TestLogicalEndOfLine("<div contenteditable>|abc def ghi</div>"));
+ EXPECT_EQ("<div contenteditable>abc |def ghi</div>",
+ TestLogicalEndOfLine("<div contenteditable>ab|c def ghi</div>"));
+ EXPECT_EQ("<div contenteditable>abc |def ghi</div>",
+ TestLogicalEndOfLine("<div contenteditable>abc| def ghi</div>"));
+ EXPECT_EQ("<div contenteditable>abc def |ghi</div>",
+ TestLogicalEndOfLine("<div contenteditable>abc |def ghi</div>"));
+}
+
+TEST_P(ParameterizedVisibleUnitsLineTest, LogicalEndOfLineWithSoftLineWrap4) {
+ LoadAhem();
+ InsertStyleElement("div { font: 10px/1 Ahem; width: 4ch; }");
+
+ EXPECT_EQ("<div>abc| def ghi</div>",
+ TestLogicalEndOfLine("<div>|abc def ghi</div>"));
+ EXPECT_EQ("<div>abc| def ghi</div>",
+ TestLogicalEndOfLine("<div>ab|c def ghi</div>"));
+ EXPECT_EQ("<div>abc| def ghi</div>",
+ TestLogicalEndOfLine("<div>abc| def ghi</div>"));
+ EXPECT_EQ("<div>abc def| ghi</div>",
+ TestLogicalEndOfLine("<div>abc |def ghi</div>"));
+
+ // On content editable, caret is after a space.
+ EXPECT_EQ("<div contenteditable>abc |def ghi</div>",
+ TestLogicalEndOfLine("<div contenteditable>|abc def ghi</div>"));
+ EXPECT_EQ("<div contenteditable>abc |def ghi</div>",
+ TestLogicalEndOfLine("<div contenteditable>ab|c def ghi</div>"));
+ EXPECT_EQ("<div contenteditable>abc |def ghi</div>",
+ TestLogicalEndOfLine("<div contenteditable>abc| def ghi</div>"));
+ EXPECT_EQ("<div contenteditable>abc def |ghi</div>",
+ TestLogicalEndOfLine("<div contenteditable>abc |def ghi</div>"));
+}
+
TEST_P(ParameterizedVisibleUnitsLineTest, InSameLineSkippingEmptyEditableDiv) {
// This test records the InSameLine() results in
// editing/selection/skip-over-contenteditable.html
@@ -680,8 +827,6 @@ TEST_P(ParameterizedVisibleUnitsLineTest, InSameLineWithMixedEditability) {
PositionWithAffinity position1(selection.Base());
PositionWithAffinity position2(selection.Extent());
// "Same line" is restricted by editability boundaries.
- // TODO(editing-dev): Make sure this test doesn't fail when we stop wrapping
- // inline contenteditables with inline blocks.
EXPECT_FALSE(InSameLine(position1, position2));
}
diff --git a/chromium/third_party/blink/renderer/core/events/animation_event.cc b/chromium/third_party/blink/renderer/core/events/animation_event.cc
index 69a5caa4862..e1ee9e496fe 100644
--- a/chromium/third_party/blink/renderer/core/events/animation_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/animation_event.cc
@@ -67,7 +67,7 @@ const AtomicString& AnimationEvent::InterfaceName() const {
return event_interface_names::kAnimationEvent;
}
-void AnimationEvent::Trace(Visitor* visitor) {
+void AnimationEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/animation_event.h b/chromium/third_party/blink/renderer/core/events/animation_event.h
index 9189ed645cb..1fed9e00b85 100644
--- a/chromium/third_party/blink/renderer/core/events/animation_event.h
+++ b/chromium/third_party/blink/renderer/core/events/animation_event.h
@@ -66,7 +66,7 @@ class AnimationEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String animation_name_;
diff --git a/chromium/third_party/blink/renderer/core/events/animation_playback_event.cc b/chromium/third_party/blink/renderer/core/events/animation_playback_event.cc
index e669632cac3..8ffc6ee1718 100644
--- a/chromium/third_party/blink/renderer/core/events/animation_playback_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/animation_playback_event.cc
@@ -25,11 +25,12 @@ AnimationPlaybackEvent::AnimationPlaybackEvent(
const AtomicString& type,
const AnimationPlaybackEventInit* initializer)
: Event(type, initializer) {
- if (initializer->hasCurrentTime() && !std::isnan(initializer->currentTime()))
- current_time_ = initializer->currentTime();
- if (initializer->hasTimelineTime() &&
- !std::isnan(initializer->timelineTime()))
+ if (initializer->hasCurrentTimeNonNull()) {
+ current_time_ = initializer->currentTimeNonNull();
+ }
+ if (initializer->hasTimelineTimeNonNull()) {
timeline_time_ = initializer->timelineTime();
+ }
DCHECK(!current_time_ || !std::isnan(current_time_.value()));
DCHECK(!timeline_time_ || !std::isnan(timeline_time_.value()));
}
@@ -40,7 +41,7 @@ const AtomicString& AnimationPlaybackEvent::InterfaceName() const {
return event_interface_names::kAnimationPlaybackEvent;
}
-void AnimationPlaybackEvent::Trace(Visitor* visitor) {
+void AnimationPlaybackEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/animation_playback_event.h b/chromium/third_party/blink/renderer/core/events/animation_playback_event.h
index 3a779e353b0..e26cefaf653 100644
--- a/chromium/third_party/blink/renderer/core/events/animation_playback_event.h
+++ b/chromium/third_party/blink/renderer/core/events/animation_playback_event.h
@@ -34,7 +34,7 @@ class AnimationPlaybackEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
base::Optional<double> current_time_;
diff --git a/chromium/third_party/blink/renderer/core/events/application_cache_error_event.cc b/chromium/third_party/blink/renderer/core/events/application_cache_error_event.cc
index 1897d0bdb1d..bd21996bb52 100644
--- a/chromium/third_party/blink/renderer/core/events/application_cache_error_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/application_cache_error_event.cc
@@ -69,7 +69,7 @@ ApplicationCacheErrorEvent::ApplicationCacheErrorEvent(
ApplicationCacheErrorEvent::~ApplicationCacheErrorEvent() = default;
-void ApplicationCacheErrorEvent::Trace(Visitor* visitor) {
+void ApplicationCacheErrorEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/application_cache_error_event.h b/chromium/third_party/blink/renderer/core/events/application_cache_error_event.h
index 5ef73cb7675..9154973aa7d 100644
--- a/chromium/third_party/blink/renderer/core/events/application_cache_error_event.h
+++ b/chromium/third_party/blink/renderer/core/events/application_cache_error_event.h
@@ -42,7 +42,7 @@ class ApplicationCacheErrorEvent final : public Event {
return event_interface_names::kApplicationCacheErrorEvent;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String reason_;
diff --git a/chromium/third_party/blink/renderer/core/events/before_text_inserted_event.cc b/chromium/third_party/blink/renderer/core/events/before_text_inserted_event.cc
index 7478354ccaf..5adfd1920e1 100644
--- a/chromium/third_party/blink/renderer/core/events/before_text_inserted_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/before_text_inserted_event.cc
@@ -43,7 +43,7 @@ const AtomicString& BeforeTextInsertedEvent::InterfaceName() const {
return event_interface_names::kEvent;
}
-void BeforeTextInsertedEvent::Trace(Visitor* visitor) {
+void BeforeTextInsertedEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/before_text_inserted_event.h b/chromium/third_party/blink/renderer/core/events/before_text_inserted_event.h
index 9adbb14e036..f67bb1374f9 100644
--- a/chromium/third_party/blink/renderer/core/events/before_text_inserted_event.h
+++ b/chromium/third_party/blink/renderer/core/events/before_text_inserted_event.h
@@ -41,7 +41,7 @@ class BeforeTextInsertedEvent final : public Event {
const String& GetText() const { return text_; }
void SetText(const String& s) { text_ = s; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String text_;
diff --git a/chromium/third_party/blink/renderer/core/events/before_unload_event.cc b/chromium/third_party/blink/renderer/core/events/before_unload_event.cc
index 2c6feb6f2f5..97a4d820b3c 100644
--- a/chromium/third_party/blink/renderer/core/events/before_unload_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/before_unload_event.cc
@@ -33,7 +33,7 @@ bool BeforeUnloadEvent::IsBeforeUnloadEvent() const {
return true;
}
-void BeforeUnloadEvent::Trace(Visitor* visitor) {
+void BeforeUnloadEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/before_unload_event.h b/chromium/third_party/blink/renderer/core/events/before_unload_event.h
index 9042923492e..4b300a1ba09 100644
--- a/chromium/third_party/blink/renderer/core/events/before_unload_event.h
+++ b/chromium/third_party/blink/renderer/core/events/before_unload_event.h
@@ -60,7 +60,7 @@ class BeforeUnloadEvent final : public Event {
return true;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String return_value_;
diff --git a/chromium/third_party/blink/renderer/core/events/clipboard_event.cc b/chromium/third_party/blink/renderer/core/events/clipboard_event.cc
index 5a78499ebd6..b05f068f3b4 100644
--- a/chromium/third_party/blink/renderer/core/events/clipboard_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/clipboard_event.cc
@@ -46,7 +46,7 @@ bool ClipboardEvent::IsClipboardEvent() const {
return true;
}
-void ClipboardEvent::Trace(Visitor* visitor) {
+void ClipboardEvent::Trace(Visitor* visitor) const {
visitor->Trace(clipboard_data_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/clipboard_event.h b/chromium/third_party/blink/renderer/core/events/clipboard_event.h
index f213d187404..50feb06a240 100644
--- a/chromium/third_party/blink/renderer/core/events/clipboard_event.h
+++ b/chromium/third_party/blink/renderer/core/events/clipboard_event.h
@@ -52,7 +52,7 @@ class ClipboardEvent final : public Event {
DataTransfer* clipboardData() const { return clipboard_data_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const AtomicString& InterfaceName() const override;
diff --git a/chromium/third_party/blink/renderer/core/events/composition_event.cc b/chromium/third_party/blink/renderer/core/events/composition_event.cc
index 7ab4246ba5f..e862e0d0d91 100644
--- a/chromium/third_party/blink/renderer/core/events/composition_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/composition_event.cc
@@ -78,7 +78,7 @@ bool CompositionEvent::IsCompositionEvent() const {
return true;
}
-void CompositionEvent::Trace(Visitor* visitor) {
+void CompositionEvent::Trace(Visitor* visitor) const {
UIEvent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/composition_event.h b/chromium/third_party/blink/renderer/core/events/composition_event.h
index 0ec3e0b93ed..ca9160af04a 100644
--- a/chromium/third_party/blink/renderer/core/events/composition_event.h
+++ b/chromium/third_party/blink/renderer/core/events/composition_event.h
@@ -63,7 +63,7 @@ class CompositionEvent final : public UIEvent {
bool IsCompositionEvent() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String data_;
diff --git a/chromium/third_party/blink/renderer/core/events/drag_event.cc b/chromium/third_party/blink/renderer/core/events/drag_event.cc
index c3fa0a5a18e..8a3fb6f6a9f 100644
--- a/chromium/third_party/blink/renderer/core/events/drag_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/drag_event.cc
@@ -29,7 +29,7 @@ bool DragEvent::IsMouseEvent() const {
return false;
}
-void DragEvent::Trace(Visitor* visitor) {
+void DragEvent::Trace(Visitor* visitor) const {
visitor->Trace(data_transfer_);
MouseEvent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/drag_event.h b/chromium/third_party/blink/renderer/core/events/drag_event.h
index cd002a4b3d3..1ca64b90f46 100644
--- a/chromium/third_party/blink/renderer/core/events/drag_event.h
+++ b/chromium/third_party/blink/renderer/core/events/drag_event.h
@@ -49,7 +49,7 @@ class CORE_EXPORT DragEvent final : public MouseEvent {
DispatchEventResult DispatchEvent(EventDispatcher&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<DataTransfer> data_transfer_;
diff --git a/chromium/third_party/blink/renderer/core/events/drag_event_init.idl b/chromium/third_party/blink/renderer/core/events/drag_event_init.idl
index 91ec2b6627d..4615d68368a 100644
--- a/chromium/third_party/blink/renderer/core/events/drag_event_init.idl
+++ b/chromium/third_party/blink/renderer/core/events/drag_event_init.idl
@@ -5,5 +5,5 @@
// https://html.spec.whatwg.org/C/#drageventinit
dictionary DragEventInit : MouseEventInit {
- [ImplementedAs=getDataTransfer] DataTransfer? dataTransfer;
+ [ImplementedAs=getDataTransfer] DataTransfer? dataTransfer = null;
};
diff --git a/chromium/third_party/blink/renderer/core/events/error_event.cc b/chromium/third_party/blink/renderer/core/events/error_event.cc
index 6809893c57d..5a0fa0add3f 100644
--- a/chromium/third_party/blink/renderer/core/events/error_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/error_event.cc
@@ -123,7 +123,7 @@ ScriptValue ErrorEvent::error(ScriptState* script_state) const {
return ScriptValue(script_state->GetIsolate(), error_.Get(script_state));
}
-void ErrorEvent::Trace(Visitor* visitor) {
+void ErrorEvent::Trace(Visitor* visitor) const {
visitor->Trace(error_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/error_event.h b/chromium/third_party/blink/renderer/core/events/error_event.h
index 7a2163ecadd..52a7cced577 100644
--- a/chromium/third_party/blink/renderer/core/events/error_event.h
+++ b/chromium/third_party/blink/renderer/core/events/error_event.h
@@ -106,7 +106,7 @@ class CORE_EXPORT ErrorEvent final : public Event {
void SetUnsanitizedMessage(const String&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String unsanitized_message_;
diff --git a/chromium/third_party/blink/renderer/core/events/event_type_names.json5 b/chromium/third_party/blink/renderer/core/events/event_type_names.json5
index be9f251243f..0bfeff2a077 100644
--- a/chromium/third_party/blink/renderer/core/events/event_type_names.json5
+++ b/chromium/third_party/blink/renderer/core/events/event_type_names.json5
@@ -136,6 +136,7 @@
"gattserverdisconnected",
"geofenceenter",
"geofenceleave",
+ "geometrychange",
"gesturelongpress",
"gesturescrollend",
"gesturescrollstart",
@@ -199,7 +200,6 @@
"open",
"orientationchange",
"overscroll",
- "overlaygeometrychange",
"pagehide",
"pageshow",
"paste",
@@ -239,7 +239,6 @@
"removesourcebuffer",
"removestream",
"removetrack",
- "rendersubtreeactivation",
"repeatEvent",
"reset",
"resetpose",
diff --git a/chromium/third_party/blink/renderer/core/events/focus_event.cc b/chromium/third_party/blink/renderer/core/events/focus_event.cc
index e0c0d634786..72b492c0e65 100644
--- a/chromium/third_party/blink/renderer/core/events/focus_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/focus_event.cc
@@ -66,7 +66,7 @@ FocusEvent::FocusEvent(const AtomicString& type,
related_target_ = initializer->relatedTarget();
}
-void FocusEvent::Trace(Visitor* visitor) {
+void FocusEvent::Trace(Visitor* visitor) const {
visitor->Trace(related_target_);
UIEvent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/focus_event.h b/chromium/third_party/blink/renderer/core/events/focus_event.h
index 10d5e52355d..3224a232f14 100644
--- a/chromium/third_party/blink/renderer/core/events/focus_event.h
+++ b/chromium/third_party/blink/renderer/core/events/focus_event.h
@@ -74,7 +74,7 @@ class FocusEvent final : public UIEvent {
DispatchEventResult DispatchEvent(EventDispatcher&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<EventTarget> related_target_;
diff --git a/chromium/third_party/blink/renderer/core/events/gesture_event.cc b/chromium/third_party/blink/renderer/core/events/gesture_event.cc
index e195eb8fa6d..6caeb19a343 100644
--- a/chromium/third_party/blink/renderer/core/events/gesture_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/gesture_event.cc
@@ -98,7 +98,7 @@ bool GestureEvent::IsGestureEvent() const {
return true;
}
-void GestureEvent::Trace(Visitor* visitor) {
+void GestureEvent::Trace(Visitor* visitor) const {
UIEvent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/gesture_event.h b/chromium/third_party/blink/renderer/core/events/gesture_event.h
index 357a626e978..1304c87b303 100644
--- a/chromium/third_party/blink/renderer/core/events/gesture_event.h
+++ b/chromium/third_party/blink/renderer/core/events/gesture_event.h
@@ -47,7 +47,7 @@ class CORE_EXPORT GestureEvent final : public UIEventWithKeyState {
const WebGestureEvent& NativeEvent() const { return native_event_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
WebGestureEvent native_event_;
diff --git a/chromium/third_party/blink/renderer/core/events/hash_change_event.h b/chromium/third_party/blink/renderer/core/events/hash_change_event.h
index 5d31f5b93b9..c84d59b8417 100644
--- a/chromium/third_party/blink/renderer/core/events/hash_change_event.h
+++ b/chromium/third_party/blink/renderer/core/events/hash_change_event.h
@@ -65,7 +65,7 @@ class HashChangeEvent final : public Event {
return event_interface_names::kHashChangeEvent;
}
- void Trace(Visitor* visitor) override { Event::Trace(visitor); }
+ void Trace(Visitor* visitor) const override { Event::Trace(visitor); }
private:
String old_url_;
diff --git a/chromium/third_party/blink/renderer/core/events/input_event.cc b/chromium/third_party/blink/renderer/core/events/input_event.cc
index 484326cfd43..3eda1bf3c1d 100644
--- a/chromium/third_party/blink/renderer/core/events/input_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/input_event.cc
@@ -181,7 +181,7 @@ bool InputEvent::IsInputEvent() const {
return true;
}
-void InputEvent::Trace(Visitor* visitor) {
+void InputEvent::Trace(Visitor* visitor) const {
UIEvent::Trace(visitor);
visitor->Trace(data_transfer_);
visitor->Trace(ranges_);
diff --git a/chromium/third_party/blink/renderer/core/events/input_event.h b/chromium/third_party/blink/renderer/core/events/input_event.h
index 003708a81a7..0e95a48b96c 100644
--- a/chromium/third_party/blink/renderer/core/events/input_event.h
+++ b/chromium/third_party/blink/renderer/core/events/input_event.h
@@ -111,7 +111,7 @@ class InputEvent final : public UIEvent {
DispatchEventResult DispatchEvent(EventDispatcher&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
InputType input_type_;
diff --git a/chromium/third_party/blink/renderer/core/events/keyboard_event.cc b/chromium/third_party/blink/renderer/core/events/keyboard_event.cc
index 54f140ee186..d54d9321d2f 100644
--- a/chromium/third_party/blink/renderer/core/events/keyboard_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/keyboard_event.cc
@@ -219,7 +219,7 @@ void KeyboardEvent::InitLocationModifiers(unsigned location) {
}
}
-void KeyboardEvent::Trace(Visitor* visitor) {
+void KeyboardEvent::Trace(Visitor* visitor) const {
UIEventWithKeyState::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/keyboard_event.h b/chromium/third_party/blink/renderer/core/events/keyboard_event.h
index 402486842d2..039c16c5424 100644
--- a/chromium/third_party/blink/renderer/core/events/keyboard_event.h
+++ b/chromium/third_party/blink/renderer/core/events/keyboard_event.h
@@ -97,7 +97,7 @@ class CORE_EXPORT KeyboardEvent final : public UIEventWithKeyState {
unsigned which() const override;
bool isComposing() const { return is_composing_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void InitLocationModifiers(unsigned location);
diff --git a/chromium/third_party/blink/renderer/core/events/message_event.cc b/chromium/third_party/blink/renderer/core/events/message_event.cc
index becc0cd8511..1db4a982b1d 100644
--- a/chromium/third_party/blink/renderer/core/events/message_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/message_event.cc
@@ -390,7 +390,7 @@ void MessageEvent::EntangleMessagePorts(ExecutionContext* context) {
is_ports_dirty_ = true;
}
-void MessageEvent::Trace(Visitor* visitor) {
+void MessageEvent::Trace(Visitor* visitor) const {
visitor->Trace(data_as_v8_value_);
visitor->Trace(data_as_serialized_script_value_);
visitor->Trace(data_as_blob_);
diff --git a/chromium/third_party/blink/renderer/core/events/message_event.h b/chromium/third_party/blink/renderer/core/events/message_event.h
index f8310326df6..e4b5e05710d 100644
--- a/chromium/third_party/blink/renderer/core/events/message_event.h
+++ b/chromium/third_party/blink/renderer/core/events/message_event.h
@@ -193,7 +193,7 @@ class CORE_EXPORT MessageEvent final : public Event {
void EntangleMessagePorts(ExecutionContext*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void LockToAgentCluster();
diff --git a/chromium/third_party/blink/renderer/core/events/message_event.idl b/chromium/third_party/blink/renderer/core/events/message_event.idl
index c325dfb22ee..7632cc9d985 100644
--- a/chromium/third_party/blink/renderer/core/events/message_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/message_event.idl
@@ -37,7 +37,7 @@
// TODO(bashi): |source| should be of type MessageEventSource.
readonly attribute EventTarget? source;
[CachedAttribute=isPortsDirty] readonly attribute FrozenArray<MessagePort> ports;
- [RuntimeEnabled=UserActivationAPI] readonly attribute UserActivation? userActivation;
+ readonly attribute UserActivation? userActivation;
// TODO(foolip): |source| should be of type MessageEventSource.
[MeasureAs=InitMessageEvent] void initMessageEvent(
diff --git a/chromium/third_party/blink/renderer/core/events/message_event_init.idl b/chromium/third_party/blink/renderer/core/events/message_event_init.idl
index f98dd7449ed..7d2952e74a8 100644
--- a/chromium/third_party/blink/renderer/core/events/message_event_init.idl
+++ b/chromium/third_party/blink/renderer/core/events/message_event_init.idl
@@ -11,5 +11,5 @@ dictionary MessageEventInit : EventInit {
// TODO(bashi): |source| should be (WindowProxy or MessagePort)?
EventTarget? source = null;
sequence<MessagePort> ports = [];
- [RuntimeEnabled=UserActivationAPI] UserActivation? userActivation = null;
+ UserActivation? userActivation = null;
};
diff --git a/chromium/third_party/blink/renderer/core/events/mouse_event.cc b/chromium/third_party/blink/renderer/core/events/mouse_event.cc
index 22d238ff173..8aaa851a56e 100644
--- a/chromium/third_party/blink/renderer/core/events/mouse_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/mouse_event.cc
@@ -388,7 +388,7 @@ Node* MouseEvent::fromElement() const {
return target() ? target()->ToNode() : nullptr;
}
-void MouseEvent::Trace(Visitor* visitor) {
+void MouseEvent::Trace(Visitor* visitor) const {
visitor->Trace(related_target_);
UIEventWithKeyState::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/mouse_event.h b/chromium/third_party/blink/renderer/core/events/mouse_event.h
index f9e084b3378..83b6168b658 100644
--- a/chromium/third_party/blink/renderer/core/events/mouse_event.h
+++ b/chromium/third_party/blink/renderer/core/events/mouse_event.h
@@ -185,7 +185,7 @@ class CORE_EXPORT MouseEvent : public UIEventWithKeyState {
DispatchEventResult DispatchEvent(EventDispatcher&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
DoublePoint screen_location_;
DoublePoint client_location_;
diff --git a/chromium/third_party/blink/renderer/core/events/mutation_event.cc b/chromium/third_party/blink/renderer/core/events/mutation_event.cc
index bd20b674660..b87779ca8e7 100644
--- a/chromium/third_party/blink/renderer/core/events/mutation_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/mutation_event.cc
@@ -69,7 +69,7 @@ const AtomicString& MutationEvent::InterfaceName() const {
return event_interface_names::kMutationEvent;
}
-void MutationEvent::Trace(Visitor* visitor) {
+void MutationEvent::Trace(Visitor* visitor) const {
visitor->Trace(related_node_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/mutation_event.h b/chromium/third_party/blink/renderer/core/events/mutation_event.h
index 9e46d5f6f93..b5bdd3351f2 100644
--- a/chromium/third_party/blink/renderer/core/events/mutation_event.h
+++ b/chromium/third_party/blink/renderer/core/events/mutation_event.h
@@ -80,7 +80,7 @@ class MutationEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Node> related_node_;
diff --git a/chromium/third_party/blink/renderer/core/events/overscroll_event.cc b/chromium/third_party/blink/renderer/core/events/overscroll_event.cc
index dbfe9d301ca..85f3926a84d 100644
--- a/chromium/third_party/blink/renderer/core/events/overscroll_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/overscroll_event.cc
@@ -23,7 +23,7 @@ OverscrollEvent::OverscrollEvent(const AtomicString& type,
delta_x_(initializer->deltaX()),
delta_y_(initializer->deltaY()) {}
-void OverscrollEvent::Trace(Visitor* visitor) {
+void OverscrollEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/overscroll_event.h b/chromium/third_party/blink/renderer/core/events/overscroll_event.h
index 0db38ffbc7e..44b99b0d75f 100644
--- a/chromium/third_party/blink/renderer/core/events/overscroll_event.h
+++ b/chromium/third_party/blink/renderer/core/events/overscroll_event.h
@@ -39,7 +39,7 @@ class OverscrollEvent final : public Event {
double deltaX() const { return delta_x_; }
double deltaY() const { return delta_y_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
double delta_x_ = 0;
diff --git a/chromium/third_party/blink/renderer/core/events/page_transition_event.cc b/chromium/third_party/blink/renderer/core/events/page_transition_event.cc
index 038365fd079..38cae1ca4bf 100644
--- a/chromium/third_party/blink/renderer/core/events/page_transition_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/page_transition_event.cc
@@ -57,7 +57,7 @@ const AtomicString& PageTransitionEvent::InterfaceName() const {
return event_interface_names::kPageTransitionEvent;
}
-void PageTransitionEvent::Trace(Visitor* visitor) {
+void PageTransitionEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/page_transition_event.h b/chromium/third_party/blink/renderer/core/events/page_transition_event.h
index d899c9cffdd..bccced8705a 100644
--- a/chromium/third_party/blink/renderer/core/events/page_transition_event.h
+++ b/chromium/third_party/blink/renderer/core/events/page_transition_event.h
@@ -67,7 +67,7 @@ class PageTransitionEvent final : public Event {
bool persisted() const { return persisted_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// TODO(rakina): change to PageTransitionEventPersistence.
diff --git a/chromium/third_party/blink/renderer/core/events/pointer_event.cc b/chromium/third_party/blink/renderer/core/events/pointer_event.cc
index 892bbc4bcfb..f325f854621 100644
--- a/chromium/third_party/blink/renderer/core/events/pointer_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/pointer_event.cc
@@ -133,7 +133,7 @@ base::TimeTicks PointerEvent::OldestPlatformTimeStamp() const {
return this->PlatformTimeStamp();
}
-void PointerEvent::Trace(Visitor* visitor) {
+void PointerEvent::Trace(Visitor* visitor) const {
visitor->Trace(coalesced_events_);
visitor->Trace(predicted_events_);
MouseEvent::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/events/pointer_event.h b/chromium/third_party/blink/renderer/core/events/pointer_event.h
index c9e2c5f6e00..997eb463da8 100644
--- a/chromium/third_party/blink/renderer/core/events/pointer_event.h
+++ b/chromium/third_party/blink/renderer/core/events/pointer_event.h
@@ -76,7 +76,7 @@ class CORE_EXPORT PointerEvent final : public MouseEvent {
DispatchEventResult DispatchEvent(EventDispatcher&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
PointerId pointer_id_;
diff --git a/chromium/third_party/blink/renderer/core/events/pop_state_event.cc b/chromium/third_party/blink/renderer/core/events/pop_state_event.cc
index 19e98fea0b3..2115046b035 100644
--- a/chromium/third_party/blink/renderer/core/events/pop_state_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/pop_state_event.cc
@@ -96,7 +96,7 @@ const AtomicString& PopStateEvent::InterfaceName() const {
return event_interface_names::kPopStateEvent;
}
-void PopStateEvent::Trace(Visitor* visitor) {
+void PopStateEvent::Trace(Visitor* visitor) const {
visitor->Trace(state_);
visitor->Trace(history_);
Event::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/events/pop_state_event.h b/chromium/third_party/blink/renderer/core/events/pop_state_event.h
index f788e5ace29..de394604c38 100644
--- a/chromium/third_party/blink/renderer/core/events/pop_state_event.h
+++ b/chromium/third_party/blink/renderer/core/events/pop_state_event.h
@@ -62,7 +62,7 @@ class CORE_EXPORT PopStateEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
WorldSafeV8Reference<v8::Value> state_;
diff --git a/chromium/third_party/blink/renderer/core/events/progress_event.cc b/chromium/third_party/blink/renderer/core/events/progress_event.cc
index 8cb07d97a5e..10dcd2ef14f 100644
--- a/chromium/third_party/blink/renderer/core/events/progress_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/progress_event.cc
@@ -53,7 +53,7 @@ const AtomicString& ProgressEvent::InterfaceName() const {
return event_interface_names::kProgressEvent;
}
-void ProgressEvent::Trace(Visitor* visitor) {
+void ProgressEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/progress_event.h b/chromium/third_party/blink/renderer/core/events/progress_event.h
index 9a3c3c26f8b..61f401b3485 100644
--- a/chromium/third_party/blink/renderer/core/events/progress_event.h
+++ b/chromium/third_party/blink/renderer/core/events/progress_event.h
@@ -65,7 +65,7 @@ class CORE_EXPORT ProgressEvent : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool length_computable_;
diff --git a/chromium/third_party/blink/renderer/core/events/promise_rejection_event.cc b/chromium/third_party/blink/renderer/core/events/promise_rejection_event.cc
index 3f44a93a846..8c3cb3e9e60 100644
--- a/chromium/third_party/blink/renderer/core/events/promise_rejection_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/promise_rejection_event.cc
@@ -55,7 +55,7 @@ bool PromiseRejectionEvent::CanBeDispatchedInWorld(
return world_->GetWorldId() == world.GetWorldId();
}
-void PromiseRejectionEvent::Trace(Visitor* visitor) {
+void PromiseRejectionEvent::Trace(Visitor* visitor) const {
visitor->Trace(promise_);
visitor->Trace(reason_);
Event::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/events/promise_rejection_event.h b/chromium/third_party/blink/renderer/core/events/promise_rejection_event.h
index e56860a85f5..4dfbd60087f 100644
--- a/chromium/third_party/blink/renderer/core/events/promise_rejection_event.h
+++ b/chromium/third_party/blink/renderer/core/events/promise_rejection_event.h
@@ -42,7 +42,7 @@ class CORE_EXPORT PromiseRejectionEvent final : public Event {
// observed across different worlds.
bool CanBeDispatchedInWorld(const DOMWrapperWorld&) const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~PromiseRejectionEvent() override;
diff --git a/chromium/third_party/blink/renderer/core/events/resource_progress_event.cc b/chromium/third_party/blink/renderer/core/events/resource_progress_event.cc
index 7aef88ab13d..5a477cd787d 100644
--- a/chromium/third_party/blink/renderer/core/events/resource_progress_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/resource_progress_event.cc
@@ -45,7 +45,7 @@ const AtomicString& ResourceProgressEvent::InterfaceName() const {
return event_interface_names::kResourceProgressEvent;
}
-void ResourceProgressEvent::Trace(Visitor* visitor) {
+void ResourceProgressEvent::Trace(Visitor* visitor) const {
ProgressEvent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/resource_progress_event.h b/chromium/third_party/blink/renderer/core/events/resource_progress_event.h
index f1ac2639491..c7448ca0669 100644
--- a/chromium/third_party/blink/renderer/core/events/resource_progress_event.h
+++ b/chromium/third_party/blink/renderer/core/events/resource_progress_event.h
@@ -57,7 +57,7 @@ class CORE_EXPORT ResourceProgressEvent final : public ProgressEvent {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String url_;
diff --git a/chromium/third_party/blink/renderer/core/events/security_policy_violation_event.h b/chromium/third_party/blink/renderer/core/events/security_policy_violation_event.h
index de7414c378e..566ee3030f2 100644
--- a/chromium/third_party/blink/renderer/core/events/security_policy_violation_event.h
+++ b/chromium/third_party/blink/renderer/core/events/security_policy_violation_event.h
@@ -72,7 +72,7 @@ class SecurityPolicyViolationEvent final : public Event {
return event_interface_names::kSecurityPolicyViolationEvent;
}
- void Trace(Visitor* visitor) override { Event::Trace(visitor); }
+ void Trace(Visitor* visitor) const override { Event::Trace(visitor); }
private:
String document_uri_;
diff --git a/chromium/third_party/blink/renderer/core/events/security_policy_violation_event_init.idl b/chromium/third_party/blink/renderer/core/events/security_policy_violation_event_init.idl
index 1a4efec8efe..541b3fd4b73 100644
--- a/chromium/third_party/blink/renderer/core/events/security_policy_violation_event_init.idl
+++ b/chromium/third_party/blink/renderer/core/events/security_policy_violation_event_init.idl
@@ -8,14 +8,14 @@ dictionary SecurityPolicyViolationEventInit : EventInit {
// TODO(foolip): The spec says "USVString documentURL".
required DOMString documentURI;
// TODO(foolip): The spec says USVString.
- DOMString referrer;
+ DOMString referrer = "";
// TODO(foolip): The spec says "USVString blockedURL".
DOMString blockedURI = "";
required DOMString effectiveDirective;
required DOMString originalPolicy;
// TODO(foolip): The spec says USVString.
DOMString sourceFile = "";
- DOMString sample;
+ DOMString sample = "";
required SecurityPolicyViolationEventDisposition disposition;
required unsigned short statusCode;
// TODO(foolip): The spec says "unsigned long lineno"
diff --git a/chromium/third_party/blink/renderer/core/events/text_event.cc b/chromium/third_party/blink/renderer/core/events/text_event.cc
index 3e58609459e..ba23b5cea72 100644
--- a/chromium/third_party/blink/renderer/core/events/text_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/text_event.cc
@@ -119,7 +119,7 @@ const AtomicString& TextEvent::InterfaceName() const {
return event_interface_names::kTextEvent;
}
-void TextEvent::Trace(Visitor* visitor) {
+void TextEvent::Trace(Visitor* visitor) const {
visitor->Trace(pasting_fragment_);
UIEvent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/text_event.h b/chromium/third_party/blink/renderer/core/events/text_event.h
index f853b6eb8a7..1f56a675543 100644
--- a/chromium/third_party/blink/renderer/core/events/text_event.h
+++ b/chromium/third_party/blink/renderer/core/events/text_event.h
@@ -87,7 +87,7 @@ class TextEvent final : public UIEvent {
bool ShouldMatchStyle() const { return should_match_style_; }
DocumentFragment* PastingFragment() const { return pasting_fragment_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
TextEventInputType input_type_;
diff --git a/chromium/third_party/blink/renderer/core/events/touch_event.cc b/chromium/third_party/blink/renderer/core/events/touch_event.cc
index dda3cf9d4f2..043598295ff 100644
--- a/chromium/third_party/blink/renderer/core/events/touch_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/touch_event.cc
@@ -173,7 +173,7 @@ bool TouchEvent::IsTouchStartOrFirstTouchMove() const {
return GetWebTouchEvent(*native_event_)->touch_start_or_first_touch_move;
}
-void TouchEvent::Trace(Visitor* visitor) {
+void TouchEvent::Trace(Visitor* visitor) const {
visitor->Trace(touches_);
visitor->Trace(target_touches_);
visitor->Trace(changed_touches_);
diff --git a/chromium/third_party/blink/renderer/core/events/touch_event.h b/chromium/third_party/blink/renderer/core/events/touch_event.h
index adb67d575da..df26bceba68 100644
--- a/chromium/third_party/blink/renderer/core/events/touch_event.h
+++ b/chromium/third_party/blink/renderer/core/events/touch_event.h
@@ -98,7 +98,7 @@ class CORE_EXPORT TouchEvent final : public UIEventWithKeyState {
DispatchEventResult DispatchEvent(EventDispatcher&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool IsTouchStartOrFirstTouchMove() const;
diff --git a/chromium/third_party/blink/renderer/core/events/touch_event_context.cc b/chromium/third_party/blink/renderer/core/events/touch_event_context.cc
index 6043493d59d..3249e60a8d8 100644
--- a/chromium/third_party/blink/renderer/core/events/touch_event_context.cc
+++ b/chromium/third_party/blink/renderer/core/events/touch_event_context.cc
@@ -45,7 +45,7 @@ void TouchEventContext::HandleLocalEvents(Event& event) const {
touch_event.SetChangedTouches(changed_touches_);
}
-void TouchEventContext::Trace(Visitor* visitor) {
+void TouchEventContext::Trace(Visitor* visitor) const {
visitor->Trace(touches_);
visitor->Trace(target_touches_);
visitor->Trace(changed_touches_);
diff --git a/chromium/third_party/blink/renderer/core/events/touch_event_context.h b/chromium/third_party/blink/renderer/core/events/touch_event_context.h
index b3ef5037392..6228438e7b9 100644
--- a/chromium/third_party/blink/renderer/core/events/touch_event_context.h
+++ b/chromium/third_party/blink/renderer/core/events/touch_event_context.h
@@ -43,7 +43,7 @@ class TouchEventContext : public GarbageCollected<TouchEventContext> {
TouchList& TargetTouches() { return *target_touches_; }
TouchList& ChangedTouches() { return *changed_touches_; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<TouchList> touches_;
diff --git a/chromium/third_party/blink/renderer/core/events/transition_event.cc b/chromium/third_party/blink/renderer/core/events/transition_event.cc
index 90f65a1cc3a..2c31fb3e2c8 100644
--- a/chromium/third_party/blink/renderer/core/events/transition_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/transition_event.cc
@@ -73,7 +73,7 @@ const AtomicString& TransitionEvent::InterfaceName() const {
return event_interface_names::kTransitionEvent;
}
-void TransitionEvent::Trace(Visitor* visitor) {
+void TransitionEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/transition_event.h b/chromium/third_party/blink/renderer/core/events/transition_event.h
index 2c2574b1837..9bd66c46b62 100644
--- a/chromium/third_party/blink/renderer/core/events/transition_event.h
+++ b/chromium/third_party/blink/renderer/core/events/transition_event.h
@@ -68,7 +68,7 @@ class TransitionEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String property_name_;
diff --git a/chromium/third_party/blink/renderer/core/events/ui_event.cc b/chromium/third_party/blink/renderer/core/events/ui_event.cc
index e54451dc2ae..b95fa8d362c 100644
--- a/chromium/third_party/blink/renderer/core/events/ui_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/ui_event.cc
@@ -95,7 +95,7 @@ unsigned UIEvent::which() const {
return 0;
}
-void UIEvent::Trace(Visitor* visitor) {
+void UIEvent::Trace(Visitor* visitor) const {
visitor->Trace(view_);
visitor->Trace(source_capabilities_);
Event::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/events/ui_event.h b/chromium/third_party/blink/renderer/core/events/ui_event.h
index 63cfd9dc243..43a8e317c67 100644
--- a/chromium/third_party/blink/renderer/core/events/ui_event.h
+++ b/chromium/third_party/blink/renderer/core/events/ui_event.h
@@ -87,7 +87,7 @@ class CORE_EXPORT UIEvent : public Event {
virtual unsigned which() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<AbstractView> view_;
diff --git a/chromium/third_party/blink/renderer/core/events/visual_viewport_resize_event.h b/chromium/third_party/blink/renderer/core/events/visual_viewport_resize_event.h
index fa57fc5c2e2..e29d44e238c 100644
--- a/chromium/third_party/blink/renderer/core/events/visual_viewport_resize_event.h
+++ b/chromium/third_party/blink/renderer/core/events/visual_viewport_resize_event.h
@@ -16,7 +16,7 @@ class VisualViewportResizeEvent final : public Event {
void DoneDispatchingEventAtCurrentTarget() override;
- void Trace(Visitor* visitor) override { Event::Trace(visitor); }
+ void Trace(Visitor* visitor) const override { Event::Trace(visitor); }
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/events/visual_viewport_scroll_event.h b/chromium/third_party/blink/renderer/core/events/visual_viewport_scroll_event.h
index 7ec4ab25aba..2872a6970a1 100644
--- a/chromium/third_party/blink/renderer/core/events/visual_viewport_scroll_event.h
+++ b/chromium/third_party/blink/renderer/core/events/visual_viewport_scroll_event.h
@@ -16,7 +16,7 @@ class VisualViewportScrollEvent final : public Event {
void DoneDispatchingEventAtCurrentTarget() override;
- void Trace(Visitor* visitor) override { Event::Trace(visitor); }
+ void Trace(Visitor* visitor) const override { Event::Trace(visitor); }
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/events/wheel_event.cc b/chromium/third_party/blink/renderer/core/events/wheel_event.cc
index b1a96aac0ba..6e331ecc234 100644
--- a/chromium/third_party/blink/renderer/core/events/wheel_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/wheel_event.cc
@@ -182,7 +182,7 @@ DispatchEventResult WheelEvent::DispatchEvent(EventDispatcher& dispatcher) {
return dispatcher.Dispatch();
}
-void WheelEvent::Trace(Visitor* visitor) {
+void WheelEvent::Trace(Visitor* visitor) const {
MouseEvent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/events/wheel_event.h b/chromium/third_party/blink/renderer/core/events/wheel_event.h
index 357825d5275..64fea3f1862 100644
--- a/chromium/third_party/blink/renderer/core/events/wheel_event.h
+++ b/chromium/third_party/blink/renderer/core/events/wheel_event.h
@@ -91,7 +91,7 @@ class CORE_EXPORT WheelEvent final : public MouseEvent {
// So we need to override its parent's DispatchEvent.
DispatchEventResult DispatchEvent(EventDispatcher&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
IntPoint wheel_delta_;
diff --git a/chromium/third_party/blink/renderer/core/execution_context/agent.cc b/chromium/third_party/blink/renderer/core/execution_context/agent.cc
index d25e979d9a4..117861e69a4 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/agent.cc
+++ b/chromium/third_party/blink/renderer/core/execution_context/agent.cc
@@ -10,6 +10,14 @@
namespace blink {
+namespace {
+bool is_cross_origin_isolated = false;
+
+#if DCHECK_IS_ON()
+bool is_cross_origin_isolated_set = false;
+#endif
+} // namespace
+
Agent::Agent(v8::Isolate* isolate,
const base::UnguessableToken& cluster_id,
std::unique_ptr<v8::MicrotaskQueue> microtask_queue)
@@ -19,14 +27,28 @@ Agent::Agent(v8::Isolate* isolate,
Agent::~Agent() = default;
-void Agent::Trace(Visitor* visitor) {}
+void Agent::Trace(Visitor* visitor) const {}
+
+void Agent::AttachContext(ExecutionContext* context) {
+ event_loop_->AttachScheduler(context->GetScheduler());
+}
+
+void Agent::DetachContext(ExecutionContext* context) {
+ event_loop_->DetachScheduler(context->GetScheduler());
+}
-void Agent::AttachDocument(Document* document) {
- event_loop_->AttachScheduler(document->GetScheduler());
+// static
+bool Agent::IsCrossOriginIsolated() {
+ return is_cross_origin_isolated;
}
-void Agent::DetachDocument(Document* document) {
- event_loop_->DetachScheduler(document->GetScheduler());
+// static
+void Agent::SetIsCrossOriginIsolated(bool value) {
+#if DCHECK_IS_ON()
+ DCHECK(!is_cross_origin_isolated_set);
+ is_cross_origin_isolated_set = true;
+#endif
+ is_cross_origin_isolated = value;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/execution_context/agent.h b/chromium/third_party/blink/renderer/core/execution_context/agent.h
index 8adc23aa3ad..5c09ad19508 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/agent.h
+++ b/chromium/third_party/blink/renderer/core/execution_context/agent.h
@@ -19,7 +19,7 @@ namespace scheduler {
class EventLoop;
}
-class Document;
+class ExecutionContext;
// Corresponding spec concept is:
// https://html.spec.whatwg.org/C#integration-with-the-javascript-agent-formalism
@@ -43,13 +43,25 @@ class CORE_EXPORT Agent : public GarbageCollected<Agent> {
return event_loop_;
}
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
- void AttachDocument(Document*);
- void DetachDocument(Document*);
+ void AttachContext(ExecutionContext*);
+ void DetachContext(ExecutionContext*);
const base::UnguessableToken& cluster_id() const { return cluster_id_; }
+ // Representing agent cluster's "cross-origin isolated" concept.
+ // TODO(yhirano): Have the spec URL.
+ // This property is renderer process global because we ensure that a
+ // renderer process host only cross-origin isolated agents or only
+ // non-cross-origin isolated agents, not both.
+ // This variable is initialized before any frame is created, and will not
+ // be modified after that. Hence this can be accessed from the main thread
+ // and worker/worklet threads.
+ static bool IsCrossOriginIsolated();
+ // Only called from blink::SetIsCrossOriginIsolated.
+ static void SetIsCrossOriginIsolated(bool value);
+
private:
scoped_refptr<scheduler::EventLoop> event_loop_;
const base::UnguessableToken cluster_id_;
diff --git a/chromium/third_party/blink/renderer/core/execution_context/agent_metrics_collector.cc b/chromium/third_party/blink/renderer/core/execution_context/agent_metrics_collector.cc
index e2709000828..9b56d0545fb 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/agent_metrics_collector.cc
+++ b/chromium/third_party/blink/renderer/core/execution_context/agent_metrics_collector.cc
@@ -9,8 +9,8 @@
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
-#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/execution_context/window_agent.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/web_test_support.h"
@@ -42,8 +42,7 @@ AgentMetricsCollector::AgentMetricsCollector()
: nullptr,
this,
&AgentMetricsCollector::ReportingTimerFired)),
- clock_(base::DefaultTickClock::GetInstance()),
- agent_metrics_collector_host_(nullptr) {
+ clock_(base::DefaultTickClock::GetInstance()) {
// From now until we call CreatedNewAgent will be reported as having 0
// agents.
time_last_reported_ = clock_->NowTicks();
@@ -55,33 +54,33 @@ AgentMetricsCollector::~AgentMetricsCollector() {
ReportMetrics();
}
-void AgentMetricsCollector::DidAttachDocument(const Document& doc) {
+void AgentMetricsCollector::DidAttachWindow(const LocalDOMWindow& window) {
ReportMetrics();
- AgentToDocumentsMap::AddResult result =
- agent_to_documents_map_.insert(doc.GetAgent(), nullptr);
+ AgentToWindowsMap::AddResult result =
+ agent_to_windows_map_.insert(window.GetAgent(), nullptr);
if (result.is_new_entry)
- result.stored_value->value = MakeGarbageCollected<DocumentSet>();
+ result.stored_value->value = MakeGarbageCollected<WindowSet>();
- result.stored_value->value->insert(&doc);
+ result.stored_value->value->insert(&window);
ReportToBrowser();
}
-void AgentMetricsCollector::DidDetachDocument(const Document& doc) {
+void AgentMetricsCollector::DidDetachWindow(const LocalDOMWindow& window) {
ReportMetrics();
- auto agent_itr = agent_to_documents_map_.find(doc.GetAgent());
- DCHECK(agent_itr != agent_to_documents_map_.end());
+ auto agent_itr = agent_to_windows_map_.find(window.GetAgent());
+ DCHECK(agent_itr != agent_to_windows_map_.end());
- DocumentSet& documents = *agent_itr->value.Get();
- auto document_itr = documents.find(&doc);
- DCHECK(document_itr != documents.end());
+ WindowSet& windows = *agent_itr->value.Get();
+ auto window_itr = windows.find(&window);
+ DCHECK(window_itr != windows.end());
- documents.erase(document_itr);
+ windows.erase(window_itr);
- if (documents.IsEmpty())
- agent_to_documents_map_.erase(agent_itr);
+ if (windows.IsEmpty())
+ agent_to_windows_map_.erase(agent_itr);
ReportToBrowser();
}
@@ -119,19 +118,19 @@ void AgentMetricsCollector::ReportMetrics() {
void AgentMetricsCollector::AddTimeToTotalAgents(int time_delta_to_add) {
DEFINE_STATIC_LOCAL(LinearHistogram, agents_per_renderer_histogram,
(kAgentsPerRendererByTimeHistogram, 1, 100, 101));
- agents_per_renderer_histogram.CountMany(agent_to_documents_map_.size(),
+ agents_per_renderer_histogram.CountMany(agent_to_windows_map_.size(),
time_delta_to_add);
}
void AgentMetricsCollector::ReportToBrowser() {
Vector<String> agents;
- for (const auto& kv : agent_to_documents_map_) {
- const Member<DocumentSet>& doc_set = kv.value;
+ for (const auto& kv : agent_to_windows_map_) {
+ const Member<WindowSet>& window_set = kv.value;
String tuple_origin;
- DCHECK(!doc_set->IsEmpty());
- const auto& doc = *doc_set->begin();
- auto* security_origin = doc->GetSecurityOrigin();
+ DCHECK(!window_set->IsEmpty());
+ const auto& window = *window_set->begin();
+ auto* security_origin = window->GetSecurityOrigin();
if (security_origin && !security_origin->IsOpaque() &&
!security_origin->IsLocal()) {
// We shouldn't ever host multiple tuple-origins in an Agent. However,
@@ -172,8 +171,8 @@ AgentMetricsCollector::GetAgentMetricsCollectorHost() {
return agent_metrics_collector_host_.get();
}
-void AgentMetricsCollector::Trace(Visitor* visitor) {
- visitor->Trace(agent_to_documents_map_);
+void AgentMetricsCollector::Trace(Visitor* visitor) const {
+ visitor->Trace(agent_to_windows_map_);
visitor->Trace(agent_metrics_collector_host_);
}
diff --git a/chromium/third_party/blink/renderer/core/execution_context/agent_metrics_collector.h b/chromium/third_party/blink/renderer/core/execution_context/agent_metrics_collector.h
index 6776517dc78..f031291f2e2 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/agent_metrics_collector.h
+++ b/chromium/third_party/blink/renderer/core/execution_context/agent_metrics_collector.h
@@ -18,16 +18,16 @@ class TickClock;
namespace blink {
class Agent;
-class Document;
+class LocalDOMWindow;
class TimerBase;
// This class tracks agent-related metrics for reporting in TRACE and UMA
-// metrics. It listens for documents being attached/detached to an execution
-// context and tracks which agent these documents are associated with.
+// metrics. It listens for windows being attached/detached to an execution
+// context and tracks which agent these windows are associated with.
//
// We report metrics periodically to track how long we spent in any given state.
// For example, suppose that for 10 seconds a page had just one agent, then an
-// ad frame loads causing a document to load with a second agent. After 5
+// ad frame loads causing a windows to load with a second agent. After 5
// seconds, the user closes the browser. In this case, we report:
//
// Histogram
@@ -35,7 +35,7 @@ class TimerBase;
// 2 -----O 5
//
// We therefore keep track of how much time has elapsed since the previous
-// report. Metrics are reported whenever a document is added or removed, as
+// report. Metrics are reported whenever a windows is added or removed, as
// well as at a regular interval.
//
// This class is based on the metrics tracked in:
@@ -47,14 +47,14 @@ class AgentMetricsCollector final
AgentMetricsCollector();
~AgentMetricsCollector();
- void DidAttachDocument(const Document&);
- void DidDetachDocument(const Document&);
+ void DidAttachWindow(const LocalDOMWindow&);
+ void DidDetachWindow(const LocalDOMWindow&);
void ReportMetrics();
void SetTickClockForTesting(const base::TickClock* clock) { clock_ = clock; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void AddTimeToTotalAgents(int time_delta_to_add);
@@ -68,19 +68,19 @@ class AgentMetricsCollector final
std::unique_ptr<TaskRunnerTimer<AgentMetricsCollector>> reporting_timer_;
base::TimeTicks time_last_reported_;
- // Keep a map from each agent to all the documents associated with that
- // agent. When the last document from the set is removed, we delete the key
+ // Keep a map from each agent to all the windows associated with that
+ // agent. When the last window from the set is removed, we delete the key
// from the map.
- using DocumentSet = HeapHashSet<WeakMember<const Document>>;
- using AgentToDocumentsMap =
- HeapHashMap<WeakMember<Agent>, Member<DocumentSet>>;
- AgentToDocumentsMap agent_to_documents_map_;
+ using WindowSet = HeapHashSet<WeakMember<const LocalDOMWindow>>;
+ using AgentToWindowsMap = HeapHashMap<WeakMember<Agent>, Member<WindowSet>>;
+ AgentToWindowsMap agent_to_windows_map_;
const base::TickClock* clock_;
+ // AgentMetricsCollector is not tied to ExecutionContext
HeapMojoRemote<blink::mojom::blink::AgentMetricsCollectorHost,
HeapMojoWrapperMode::kWithoutContextObserver>
- agent_metrics_collector_host_;
+ agent_metrics_collector_host_{nullptr};
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/execution_context/execution_context.cc b/chromium/third_party/blink/renderer/core/execution_context/execution_context.cc
index fa809d6a4bc..5248f2cfbc7 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/execution_context.cc
+++ b/chromium/third_party/blink/renderer/core/execution_context/execution_context.cc
@@ -55,15 +55,18 @@
namespace blink {
-ExecutionContext::ExecutionContext(v8::Isolate* isolate)
+ExecutionContext::ExecutionContext(v8::Isolate* isolate, Agent* agent)
: isolate_(isolate),
+ agent_(agent),
circular_sequential_id_(0),
in_dispatch_error_event_(false),
lifecycle_state_(mojom::FrameLifecycleState::kRunning),
is_context_destroyed_(false),
csp_delegate_(MakeGarbageCollected<ExecutionContextCSPDelegate>(*this)),
window_interaction_tokens_(0),
- referrer_policy_(network::mojom::ReferrerPolicy::kDefault) {}
+ referrer_policy_(network::mojom::ReferrerPolicy::kDefault) {
+ DCHECK(agent_);
+}
ExecutionContext::~ExecutionContext() = default;
@@ -91,7 +94,8 @@ ExecutionContext* ExecutionContext::ForRelevantRealm(
}
void ExecutionContext::SetLifecycleState(mojom::FrameLifecycleState state) {
- DCHECK(lifecycle_state_ != state);
+ if (lifecycle_state_ == state)
+ return;
lifecycle_state_ = state;
context_lifecycle_observer_list_.ForEachObserver(
[&](ContextLifecycleObserver* observer) {
@@ -151,6 +155,11 @@ unsigned ExecutionContext::ContextLifecycleStateObserverCountForTesting()
return lifecycle_state_observers;
}
+bool ExecutionContext::IsCrossOriginIsolated() const {
+ // TODO(yhirano): Take cross-origin isolated permission into account.
+ return Agent::IsCrossOriginIsolated();
+}
+
void ExecutionContext::AddConsoleMessageImpl(mojom::ConsoleMessageSource source,
mojom::ConsoleMessageLevel level,
const String& message,
@@ -199,7 +208,7 @@ bool ExecutionContext::DispatchErrorEventInternal(
}
bool ExecutionContext::IsContextPaused() const {
- return lifecycle_state_ != mojom::FrameLifecycleState::kRunning;
+ return lifecycle_state_ == mojom::blink::FrameLifecycleState::kPaused;
}
int ExecutionContext::CircularSequentialID() {
@@ -327,7 +336,8 @@ void ExecutionContext::RemoveURLFromMemoryCache(const KURL& url) {
GetMemoryCache()->RemoveURLFromCache(url);
}
-void ExecutionContext::Trace(Visitor* visitor) {
+void ExecutionContext::Trace(Visitor* visitor) const {
+ visitor->Trace(agent_);
visitor->Trace(public_url_manager_);
visitor->Trace(pending_exceptions_);
visitor->Trace(csp_delegate_);
diff --git a/chromium/third_party/blink/renderer/core/execution_context/execution_context.h b/chromium/third_party/blink/renderer/core/execution_context/execution_context.h
index 67c8ee23660..9d597f54721 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/execution_context.h
+++ b/chromium/third_party/blink/renderer/core/execution_context/execution_context.h
@@ -117,10 +117,9 @@ class CORE_EXPORT ExecutionContext : public Supplementable<ExecutionContext>,
public ConsoleLogger,
public UseCounter,
public FeaturePolicyParserDelegate {
- MERGE_GARBAGE_COLLECTED_MIXINS();
public:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
static ExecutionContext* From(const ScriptState*);
static ExecutionContext* From(v8::Local<v8::Context>);
@@ -276,7 +275,7 @@ class CORE_EXPORT ExecutionContext : public Supplementable<ExecutionContext>,
TaskType) = 0;
v8::Isolate* GetIsolate() const { return isolate_; }
- Agent* GetAgent() const { return GetSecurityContext().GetAgent(); }
+ Agent* GetAgent() const { return agent_; }
v8::MicrotaskQueue* GetMicrotaskQueue() const;
@@ -339,10 +338,17 @@ class CORE_EXPORT ExecutionContext : public Supplementable<ExecutionContext>,
}
unsigned ContextLifecycleStateObserverCountForTesting() const;
+ // Implementation of WindowOrWorkerGlobalScope.crossOriginIsolated.
+ bool IsCrossOriginIsolated() const;
+
protected:
- explicit ExecutionContext(v8::Isolate* isolate);
+ explicit ExecutionContext(v8::Isolate* isolate, Agent*);
~ExecutionContext() override;
+ // Resetting the Agent is only necessary for a special case related to the
+ // GetShouldReuseGlobalForUnownedMainFrame() Setting.
+ void ResetAgent(Agent* agent) { agent_ = agent; }
+
private:
// ConsoleLogger implementation.
void AddConsoleMessageImpl(mojom::ConsoleMessageSource,
@@ -359,6 +365,8 @@ class CORE_EXPORT ExecutionContext : public Supplementable<ExecutionContext>,
v8::Isolate* const isolate_;
+ Member<Agent> agent_;
+
bool DispatchErrorEventInternal(ErrorEvent*, SanitizeScriptErrors);
unsigned circular_sequential_id_;
diff --git a/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.cc b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.cc
index a0a4c1b0566..6e0f64281db 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.cc
+++ b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.cc
@@ -32,7 +32,7 @@ LocalFrame* ExecutionContextClient::GetFrame() const {
return window ? window->GetFrame() : nullptr;
}
-void ExecutionContextClient::Trace(Visitor* visitor) {
+void ExecutionContextClient::Trace(Visitor* visitor) const {
visitor->Trace(execution_context_);
}
@@ -58,7 +58,7 @@ LocalFrame* ExecutionContextLifecycleObserver::GetFrame() const {
return window ? window->GetFrame() : nullptr;
}
-void ExecutionContextLifecycleObserver::Trace(Visitor* visitor) {
+void ExecutionContextLifecycleObserver::Trace(Visitor* visitor) const {
ContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h
index 1ec555f1dd8..f552ea8042a 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h
+++ b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h
@@ -77,7 +77,7 @@ class CORE_EXPORT ExecutionContextClient : public GarbageCollectedMixin {
// Returns null otherwise.
LocalFrame* GetFrame() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit ExecutionContextClient(ExecutionContext*);
@@ -124,7 +124,7 @@ class CORE_EXPORT ExecutionContextLifecycleObserver
bool IsExecutionContextLifecycleObserver() const override { return true; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit ExecutionContextLifecycleObserver(
diff --git a/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h
index 58fe02e5f54..f8f23a436fb 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h
+++ b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h
@@ -67,7 +67,7 @@ class CORE_EXPORT ExecutionContextLifecycleStateObserver
#endif
virtual void ContextLifecycleStateChanged(
- mojom::blink::FrameLifecycleState state) = 0;
+ mojom::blink::FrameLifecycleState state) {}
void SetExecutionContext(ExecutionContext*) override;
diff --git a/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer_test.cc b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer_test.cc
index f15af12c7b3..b04b1d69667 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer_test.cc
+++ b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer_test.cc
@@ -49,7 +49,7 @@ class MockExecutionContextLifecycleStateObserver final
explicit MockExecutionContextLifecycleStateObserver(ExecutionContext* context)
: ExecutionContextLifecycleStateObserver(context) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
ExecutionContextLifecycleStateObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/execution_context/security_context.cc b/chromium/third_party/blink/renderer/core/execution_context/security_context.cc
index 625a8f1339b..38f5893938a 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/security_context.cc
+++ b/chromium/third_party/blink/renderer/core/execution_context/security_context.cc
@@ -36,7 +36,6 @@
#include "third_party/blink/public/mojom/feature_policy/policy_value.mojom-blink.h"
#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/core/execution_context/agent.h"
#include "third_party/blink/renderer/core/execution_context/security_context_init.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
@@ -73,14 +72,11 @@ SecurityContext::SecurityContext(const SecurityContextInit& init,
mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone),
require_safe_types_(false),
context_type_for_asserts_(context_type),
- agent_(init.GetAgent()),
secure_context_mode_(init.GetSecureContextMode()),
- origin_trial_context_(init.GetOriginTrialContext()),
- bind_csp_immediately_(init.BindCSPImmediately()) {}
+ origin_trial_context_(init.GetOriginTrialContext()) {}
-void SecurityContext::Trace(Visitor* visitor) {
+void SecurityContext::Trace(Visitor* visitor) const {
visitor->Trace(content_security_policy_);
- visitor->Trace(agent_);
visitor->Trace(origin_trial_context_);
}
diff --git a/chromium/third_party/blink/renderer/core/execution_context/security_context.h b/chromium/third_party/blink/renderer/core/execution_context/security_context.h
index f3621b043d1..af54ce73ac2 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/security_context.h
+++ b/chromium/third_party/blink/renderer/core/execution_context/security_context.h
@@ -47,7 +47,6 @@
namespace blink {
-class Agent;
class ContentSecurityPolicy;
class FeaturePolicy;
class PolicyValue;
@@ -82,7 +81,7 @@ class CORE_EXPORT SecurityContext {
SecurityContext(const SecurityContextInit&, SecurityContextType context_type);
virtual ~SecurityContext() = default;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
using InsecureNavigationsSet = HashSet<unsigned, WTF::AlreadyHashed>;
static WTF::Vector<unsigned> SerializeInsecureNavigationSet(
@@ -175,8 +174,6 @@ class CORE_EXPORT SecurityContext {
FeatureStatus IsFeatureEnabled(mojom::blink::DocumentPolicyFeature,
PolicyValue threshold_value) const;
- Agent* GetAgent() const { return agent_; }
-
OriginTrialContext* GetOriginTrialContext() const {
return origin_trial_context_;
}
@@ -191,8 +188,6 @@ class CORE_EXPORT SecurityContext {
secure_context_mode_ = mode;
}
- bool BindCSPImmediately() const { return bind_csp_immediately_; }
-
protected:
network::mojom::blink::WebSandboxFlags sandbox_flags_;
scoped_refptr<SecurityOrigin> security_origin_;
@@ -209,10 +204,8 @@ class CORE_EXPORT SecurityContext {
InsecureNavigationsSet insecure_navigations_to_upgrade_;
bool require_safe_types_;
const SecurityContextType context_type_for_asserts_;
- Member<Agent> agent_;
SecureContextMode secure_context_mode_;
Member<OriginTrialContext> origin_trial_context_;
- bool bind_csp_immediately_ = false;
DISALLOW_COPY_AND_ASSIGN(SecurityContext);
};
diff --git a/chromium/third_party/blink/renderer/core/execution_context/security_context_init.cc b/chromium/third_party/blink/renderer/core/execution_context/security_context_init.cc
index 960e816f9b1..dacd09c3834 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/security_context_init.cc
+++ b/chromium/third_party/blink/renderer/core/execution_context/security_context_init.cc
@@ -9,11 +9,11 @@
#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/document_init.h"
#include "third_party/blink/renderer/core/dom/element.h"
-#include "third_party/blink/renderer/core/execution_context/window_agent.h"
-#include "third_party/blink/renderer/core/execution_context/window_agent_factory.h"
+#include "third_party/blink/renderer/core/execution_context/agent.h"
#include "third_party/blink/renderer/core/feature_policy/document_policy_parser.h"
#include "third_party/blink/renderer/core/feature_policy/feature_policy_parser.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/sandbox_flags.h"
@@ -25,7 +25,6 @@
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/web_test_support.h"
namespace blink {
namespace {
@@ -57,18 +56,16 @@ DocumentPolicy::ParsedDocumentPolicy FilterByOriginTrial(
// This is the constructor used by RemoteSecurityContext
SecurityContextInit::SecurityContextInit()
- : SecurityContextInit(nullptr, nullptr, nullptr) {}
+ : SecurityContextInit(nullptr, nullptr) {}
// This constructor is used for non-Document contexts (i.e., workers and tests).
// This does a simpler check than Documents to set secure_context_mode_. This
// is only sufficient until there are APIs that are available in workers or
// worklets that require a privileged context test that checks ancestors.
SecurityContextInit::SecurityContextInit(scoped_refptr<SecurityOrigin> origin,
- OriginTrialContext* origin_trials,
- Agent* agent)
+ OriginTrialContext* origin_trials)
: security_origin_(std::move(origin)),
origin_trials_(origin_trials),
- agent_(agent),
secure_context_mode_(security_origin_ &&
security_origin_->IsPotentiallyTrustworthy()
? SecureContextMode::kSecureContext
@@ -76,17 +73,16 @@ SecurityContextInit::SecurityContextInit(scoped_refptr<SecurityOrigin> origin,
// A helper class that allows the security context be initialized in the
// process of constructing the document.
-SecurityContextInit::SecurityContextInit(const DocumentInit& initializer) {
- // Content Security Policy can provide sandbox flags. In CSP
- // 'self' will be determined when the policy is bound. That occurs
- // once the document is constructed.
- InitializeContentSecurityPolicy(initializer);
-
- // Sandbox flags can come from initializer, loader or CSP.
- InitializeSandboxFlags(initializer);
-
- // The origin can be opaque based on sandbox flags.
- InitializeOrigin(initializer);
+SecurityContextInit::SecurityContextInit(const DocumentInit& initializer)
+ : execution_context_(initializer.GetExecutionContext()),
+ csp_(initializer.GetContentSecurityPolicy()),
+ sandbox_flags_(initializer.GetSandboxFlags()),
+ security_origin_(initializer.GetDocumentOrigin()) {
+ // Derive possibly a new security origin that contains the agent cluster id.
+ if (execution_context_) {
+ security_origin_ = security_origin_->GetOriginForAgentCluster(
+ execution_context_->GetAgent()->cluster_id());
+ }
// The secure context state is based on the origin.
InitializeSecureContextMode(initializer);
@@ -100,169 +96,24 @@ SecurityContextInit::SecurityContextInit(const DocumentInit& initializer) {
// Initialize document policy.
InitializeDocumentPolicy(initializer);
+}
- // Initialize the agent. Depends on security origin.
- InitializeAgent(initializer);
+void SecurityContextInit::CountFeaturePolicyUsage(
+ mojom::blink::WebFeature feature) {
+ if (execution_context_)
+ execution_context_->CountFeaturePolicyUsage(feature);
}
bool SecurityContextInit::FeaturePolicyFeatureObserved(
mojom::blink::FeaturePolicyFeature feature) {
- if (parsed_feature_policies_.Contains(feature))
- return true;
- parsed_feature_policies_.insert(feature);
- return false;
+ return execution_context_ &&
+ execution_context_->FeaturePolicyFeatureObserved(feature);
}
bool SecurityContextInit::FeatureEnabled(OriginTrialFeature feature) const {
return origin_trials_->IsFeatureEnabled(feature);
}
-void SecurityContextInit::ApplyPendingDataToDocument(Document& document) const {
- for (auto feature : feature_count_)
- UseCounter::Count(document, feature);
- for (auto feature : parsed_feature_policies_)
- document.GetExecutionContext()->FeaturePolicyFeatureObserved(feature);
- for (const auto& message : feature_policy_parse_messages_) {
- document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
- mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError,
- "Error with Feature-Policy header: " + message));
- }
- for (const auto& message : report_only_feature_policy_parse_messages_) {
- document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
- mojom::blink::ConsoleMessageSource::kSecurity,
- mojom::blink::ConsoleMessageLevel::kError,
- "Error with Feature-Policy-Report-Only header: " + message));
- }
- if (!report_only_feature_policy_header_.empty())
- UseCounter::Count(document, WebFeature::kFeaturePolicyReportOnlyHeader);
-
- if (!document_policy_.feature_state.empty())
- UseCounter::Count(document, WebFeature::kDocumentPolicyHeader);
-
- if (!report_only_document_policy_.feature_state.empty())
- UseCounter::Count(document, WebFeature::kDocumentPolicyReportOnlyHeader);
-
- for (const auto& policy_entry : document_policy_.feature_state) {
- UMA_HISTOGRAM_ENUMERATION("Blink.UseCounter.DocumentPolicy.Header",
- policy_entry.first);
- }
-}
-
-void SecurityContextInit::InitializeContentSecurityPolicy(
- const DocumentInit& initializer) {
- // --------------
- // THE MAIN PATH:
- // --------------
- //
- // This path is used (among others) to load a document inside a frame. In this
- // case, the CSP is computed by:
- // - FrameLoader::CreateCSPForInitialEmptyDocument() or
- // - FrameLoader::CreateCSP().
- csp_ = initializer.GetContentSecurityPolicy();
- if (csp_)
- return;
-
- // A few users of DocumentInit do not specify the CSP to be used. An empty CSP
- // is used in this case.
- // TODO(arthursonzogni): Audit every users of DocumentInit::Create() that do
- // not specify a CSP to be used. Ideally they should be forced to explicitly
- // choose one.
- csp_ = MakeGarbageCollected<ContentSecurityPolicy>();
- bind_csp_immediately_ = true;
-}
-
-void SecurityContextInit::InitializeSandboxFlags(
- const DocumentInit& initializer) {
- sandbox_flags_ = initializer.GetSandboxFlags() | csp_->GetSandboxMask();
- auto* frame = initializer.GetFrame();
- if (frame && frame->Loader().GetDocumentLoader()->Archive()) {
- // The URL of a Document loaded from a MHTML archive is controlled by
- // the Content-Location header. This would allow UXSS, since
- // Content-Location can be arbitrarily controlled to control the
- // Document's URL and origin. Instead, force a Document loaded from a
- // MHTML archive to be sandboxed, providing exceptions only for creating
- // new windows.
- sandbox_flags_ |= (network::mojom::blink::WebSandboxFlags::kAll &
- ~(network::mojom::blink::WebSandboxFlags::kPopups |
- network::mojom::blink::WebSandboxFlags::
- kPropagatesToAuxiliaryBrowsingContexts));
- }
-}
-
-void SecurityContextInit::InitializeOrigin(const DocumentInit& initializer) {
- scoped_refptr<SecurityOrigin> document_origin =
- initializer.GetDocumentOrigin();
- if ((sandbox_flags_ & network::mojom::blink::WebSandboxFlags::kOrigin) !=
- network::mojom::blink::WebSandboxFlags::kNone) {
- scoped_refptr<SecurityOrigin> sandboxed_origin =
- initializer.OriginToCommit() ? initializer.OriginToCommit()
- : document_origin->DeriveNewOpaqueOrigin();
-
- // If we're supposed to inherit our security origin from our
- // owner, but we're also sandboxed, the only things we inherit are
- // the origin's potential trustworthiness and the ability to
- // load local resources. The latter lets about:blank iframes in
- // file:// URL documents load images and other resources from
- // the file system.
- //
- // Note: Sandboxed about:srcdoc iframe without "allow-same-origin" aren't
- // allowed to load user's file, even if its parent can.
- if (initializer.OwnerDocument()) {
- if (document_origin->IsPotentiallyTrustworthy())
- sandboxed_origin->SetOpaqueOriginIsPotentiallyTrustworthy(true);
- if (document_origin->CanLoadLocalResources() &&
- !initializer.IsSrcdocDocument())
- sandboxed_origin->GrantLoadLocalResources();
- }
- security_origin_ = sandboxed_origin;
- } else {
- security_origin_ = document_origin;
- }
-
- // If we are a page popup in LayoutTests ensure we use the popup
- // owner's security origin so the tests can possibly access the
- // document via internals API.
- auto* frame = initializer.GetFrame();
- if (frame && frame->GetPage()->GetChromeClient().IsPopup() &&
- WebTestSupport::IsRunningWebTest()) {
- security_origin_ = frame->PagePopupOwner()
- ->GetDocument()
- .GetSecurityOrigin()
- ->IsolatedCopy();
- }
-
- if (initializer.HasSecurityContext()) {
- if (Settings* settings = initializer.GetSettings()) {
- if (!settings->GetWebSecurityEnabled()) {
- // Web security is turned off. We should let this document access
- // every other document. This is used primary by testing harnesses for
- // web sites.
- security_origin_->GrantUniversalAccess();
- } else if (security_origin_->IsLocal()) {
- if (settings->GetAllowUniversalAccessFromFileURLs()) {
- // Some clients want local URLs to have universal access, but that
- // setting is dangerous for other clients.
- security_origin_->GrantUniversalAccess();
- } else if (!settings->GetAllowFileAccessFromFileURLs()) {
- // Some clients do not want local URLs to have access to other local
- // URLs.
- security_origin_->BlockLocalAccessFromLocalOrigin();
- }
- }
- }
- }
-
- if (initializer.GrantLoadLocalResources())
- security_origin_->GrantLoadLocalResources();
-
- if (security_origin_->IsOpaque() && initializer.ShouldSetURL()) {
- KURL url = initializer.Url().IsEmpty() ? BlankURL() : initializer.Url();
- if (SecurityOrigin::Create(url)->IsPotentiallyTrustworthy())
- security_origin_->SetOpaqueOriginIsPotentiallyTrustworthy(true);
- }
-}
-
void SecurityContextInit::InitializeDocumentPolicy(
const DocumentInit& initializer) {
if (!RuntimeEnabledFeatures::DocumentPolicyEnabled(this))
@@ -273,6 +124,13 @@ void SecurityContextInit::InitializeDocumentPolicy(
// Needs to filter out features that are not in origin trial after
// we have origin trial information available.
document_policy_ = FilterByOriginTrial(initializer.GetDocumentPolicy(), this);
+ if (!document_policy_.feature_state.empty()) {
+ UseCounter::Count(execution_context_, WebFeature::kDocumentPolicyHeader);
+ for (const auto& policy_entry : document_policy_.feature_state) {
+ UMA_HISTOGRAM_ENUMERATION("Blink.UseCounter.DocumentPolicy.Header",
+ policy_entry.first);
+ }
+ }
// Handle Report-Only-Document-Policy HTTP header.
// Console messages generated from logger are discarded, because currently
@@ -288,6 +146,10 @@ void SecurityContextInit::InitializeDocumentPolicy(
if (report_only_parsed_policy) {
report_only_document_policy_ =
FilterByOriginTrial(*report_only_parsed_policy, this);
+ if (!report_only_document_policy_.feature_state.empty()) {
+ UseCounter::Count(execution_context_,
+ WebFeature::kDocumentPolicyReportOnlyHeader);
+ }
}
}
@@ -305,13 +167,39 @@ void SecurityContextInit::InitializeFeaturePolicy(
if (frame && frame->IsMainFrame() && !frame->OpenerFeatureState().empty())
frame_for_opener_feature_state_ = frame;
+ PolicyParserMessageBuffer feature_policy_logger(
+ "Error with Feature-Policy header: ");
+ PolicyParserMessageBuffer report_only_feature_policy_logger(
+ "Error with Report-Only-Feature-Policy header: ");
+
feature_policy_header_ = FeaturePolicyParser::ParseHeader(
initializer.FeaturePolicyHeader(), security_origin_,
- &feature_policy_parse_messages_, this);
+ feature_policy_logger, this);
report_only_feature_policy_header_ = FeaturePolicyParser::ParseHeader(
initializer.ReportOnlyFeaturePolicyHeader(), security_origin_,
- &report_only_feature_policy_parse_messages_, this);
+ report_only_feature_policy_logger, this);
+
+ if (!report_only_feature_policy_header_.empty()) {
+ UseCounter::Count(execution_context_,
+ WebFeature::kFeaturePolicyReportOnlyHeader);
+ }
+
+ if (execution_context_) {
+ for (const auto& message : feature_policy_logger.GetMessages()) {
+ execution_context_->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kSecurity, message.level,
+ message.content));
+ }
+ for (const auto& message :
+ report_only_feature_policy_logger.GetMessages()) {
+ execution_context_->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kSecurity, message.level,
+ message.content));
+ }
+ }
if (sandbox_flags_ != network::mojom::blink::WebSandboxFlags::kNone &&
RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) {
@@ -441,12 +329,15 @@ void SecurityContextInit::InitializeSecureContextMode(
}
bool is_secure = secure_context_mode_ == SecureContextMode::kSecureContext;
if (GetSandboxFlags() != network::mojom::blink::WebSandboxFlags::kNone) {
- feature_count_.insert(
+ UseCounter::Count(
+ execution_context_,
is_secure ? WebFeature::kSecureContextCheckForSandboxedOriginPassed
: WebFeature::kSecureContextCheckForSandboxedOriginFailed);
}
- feature_count_.insert(is_secure ? WebFeature::kSecureContextCheckPassed
- : WebFeature::kSecureContextCheckFailed);
+
+ UseCounter::Count(execution_context_,
+ is_secure ? WebFeature::kSecureContextCheckPassed
+ : WebFeature::kSecureContextCheckFailed);
}
void SecurityContextInit::InitializeOriginTrials(
@@ -463,36 +354,8 @@ void SecurityContextInit::InitializeOriginTrials(
if (!tokens)
return;
origin_trials_->AddTokens(
- security_origin_.get(),
- secure_context_mode_ == SecureContextMode::kSecureContext, *tokens);
-}
-
-void SecurityContextInit::InitializeAgent(const DocumentInit& initializer) {
- // If we are allowed to share our document with other windows then we need
- // to look at the window agent factory, otherwise we should create our own
- // window agent.
- if (auto* window_agent_factory = initializer.GetWindowAgentFactory()) {
- bool has_potential_universal_access_privilege = false;
- if (auto* settings = initializer.GetSettingsForWindowAgentFactory()) {
- // TODO(keishi): Also check if AllowUniversalAccessFromFileURLs might
- // dynamically change.
- if (!settings->GetWebSecurityEnabled() ||
- settings->GetAllowUniversalAccessFromFileURLs())
- has_potential_universal_access_privilege = true;
- }
- agent_ = window_agent_factory->GetAgentForOrigin(
- has_potential_universal_access_privilege,
- V8PerIsolateData::MainThreadIsolate(), security_origin_.get());
- } else {
- // ContextDocument is null only for Documents created in unit tests.
- // In that case, use a throw away WindowAgent.
- agent_ = MakeGarbageCollected<WindowAgent>(
- V8PerIsolateData::MainThreadIsolate());
- }
-
- // Derive possibly a new security origin that contains the cluster id.
- security_origin_ =
- security_origin_->GetOriginForAgentCluster(agent_->cluster_id());
+ *tokens, security_origin_.get(),
+ secure_context_mode_ == SecureContextMode::kSecureContext);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/execution_context/security_context_init.h b/chromium/third_party/blink/renderer/core/execution_context/security_context_init.h
index e6157437da6..b365afcc8a2 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/security_context_init.h
+++ b/chromium/third_party/blink/renderer/core/execution_context/security_context_init.h
@@ -9,14 +9,13 @@
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/core/feature_policy/feature_policy_parser_delegate.h"
+#include "third_party/blink/renderer/core/feature_policy/policy_helper.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
-class Agent;
class ContentSecurityPolicy;
class Document;
class DocumentInit;
@@ -30,9 +29,7 @@ class CORE_EXPORT SecurityContextInit : public FeaturePolicyParserDelegate {
public:
SecurityContextInit();
- SecurityContextInit(scoped_refptr<SecurityOrigin>,
- OriginTrialContext*,
- Agent*);
+ SecurityContextInit(scoped_refptr<SecurityOrigin>, OriginTrialContext*);
explicit SecurityContextInit(const DocumentInit&);
const scoped_refptr<SecurityOrigin>& GetSecurityOrigin() const {
@@ -63,53 +60,36 @@ class CORE_EXPORT SecurityContextInit : public FeaturePolicyParserDelegate {
OriginTrialContext* GetOriginTrialContext() const { return origin_trials_; }
- Agent* GetAgent() const { return agent_; }
SecureContextMode GetSecureContextMode() const {
DCHECK(secure_context_mode_.has_value());
return secure_context_mode_.value();
}
- void CountFeaturePolicyUsage(mojom::WebFeature feature) override {
- feature_count_.insert(feature);
- }
-
+ void CountFeaturePolicyUsage(mojom::blink::WebFeature feature) override;
bool FeaturePolicyFeatureObserved(
mojom::blink::FeaturePolicyFeature) override;
bool FeatureEnabled(OriginTrialFeature feature) const override;
- void ApplyPendingDataToDocument(Document&) const;
-
- bool BindCSPImmediately() const { return bind_csp_immediately_; }
-
private:
- void InitializeContentSecurityPolicy(const DocumentInit&);
- void InitializeOrigin(const DocumentInit&);
- void InitializeSandboxFlags(const DocumentInit&);
void InitializeDocumentPolicy(const DocumentInit&);
void InitializeFeaturePolicy(const DocumentInit&);
void InitializeSecureContextMode(const DocumentInit&);
void InitializeOriginTrials(const DocumentInit&);
- void InitializeAgent(const DocumentInit&);
- scoped_refptr<SecurityOrigin> security_origin_;
+ ExecutionContext* execution_context_ = nullptr;
+ ContentSecurityPolicy* csp_ = nullptr;
network::mojom::blink::WebSandboxFlags sandbox_flags_ =
network::mojom::blink::WebSandboxFlags::kNone;
+ scoped_refptr<SecurityOrigin> security_origin_;
DocumentPolicy::ParsedDocumentPolicy document_policy_;
DocumentPolicy::ParsedDocumentPolicy report_only_document_policy_;
bool initialized_feature_policy_state_ = false;
- Vector<String> feature_policy_parse_messages_;
- Vector<String> report_only_feature_policy_parse_messages_;
ParsedFeaturePolicy feature_policy_header_;
ParsedFeaturePolicy report_only_feature_policy_header_;
LocalFrame* frame_for_opener_feature_state_ = nullptr;
Frame* parent_frame_ = nullptr;
ParsedFeaturePolicy container_policy_;
- ContentSecurityPolicy* csp_ = nullptr;
OriginTrialContext* origin_trials_ = nullptr;
- Agent* agent_ = nullptr;
- HashSet<mojom::blink::FeaturePolicyFeature> parsed_feature_policies_;
- HashSet<mojom::WebFeature> feature_count_;
- bool bind_csp_immediately_ = false;
base::Optional<SecureContextMode> secure_context_mode_;
};
diff --git a/chromium/third_party/blink/renderer/core/execution_context/window_agent.cc b/chromium/third_party/blink/renderer/core/execution_context/window_agent.cc
index ffc29f72255..e431afba436 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/window_agent.cc
+++ b/chromium/third_party/blink/renderer/core/execution_context/window_agent.cc
@@ -12,7 +12,7 @@ WindowAgent::WindowAgent(v8::Isolate* isolate)
WindowAgent::~WindowAgent() = default;
-void WindowAgent::Trace(Visitor* visitor) {
+void WindowAgent::Trace(Visitor* visitor) const {
Agent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/execution_context/window_agent.h b/chromium/third_party/blink/renderer/core/execution_context/window_agent.h
index bdabde9a120..71cf2de6fa3 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/window_agent.h
+++ b/chromium/third_party/blink/renderer/core/execution_context/window_agent.h
@@ -33,7 +33,7 @@ class WindowAgent final : public Agent {
~WindowAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// TODO(keishi): Move per-agent data here with the correct granularity.
diff --git a/chromium/third_party/blink/renderer/core/execution_context/window_agent_factory.cc b/chromium/third_party/blink/renderer/core/execution_context/window_agent_factory.cc
index bd423bf4123..1f28a744860 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/window_agent_factory.cc
+++ b/chromium/third_party/blink/renderer/core/execution_context/window_agent_factory.cc
@@ -63,7 +63,7 @@ WindowAgent* WindowAgentFactory::GetAgentForOrigin(
return inserted.stored_value->value;
}
-void WindowAgentFactory::Trace(Visitor* visitor) {
+void WindowAgentFactory::Trace(Visitor* visitor) const {
visitor->Trace(universal_access_agent_);
visitor->Trace(file_url_agent_);
visitor->Trace(opaque_origin_agents_);
diff --git a/chromium/third_party/blink/renderer/core/execution_context/window_agent_factory.h b/chromium/third_party/blink/renderer/core/execution_context/window_agent_factory.h
index 2e1bfb36450..f80b2945671 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/window_agent_factory.h
+++ b/chromium/third_party/blink/renderer/core/execution_context/window_agent_factory.h
@@ -52,7 +52,7 @@ class WindowAgentFactory final : public GarbageCollected<WindowAgentFactory> {
v8::Isolate* isolate,
const SecurityOrigin* origin);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
struct SchemeAndRegistrableDomain {
diff --git a/chromium/third_party/blink/renderer/core/exported/BUILD.gn b/chromium/third_party/blink/renderer/core/exported/BUILD.gn
index f1ed480efe6..e597f828369 100644
--- a/chromium/third_party/blink/renderer/core/exported/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/exported/BUILD.gn
@@ -62,6 +62,7 @@ blink_core_sources("exported") {
"web_remote_frame_impl.cc",
"web_remote_frame_impl.h",
"web_render_theme.cc",
+ "web_savable_resources_test_support.cc",
"web_scoped_page_pauser.cc",
"web_scoped_window_focus_allowed_indicator.cc",
"web_script_controller.cc",
@@ -86,7 +87,7 @@ blink_core_sources("exported") {
}
deps = [
- "//ui/base/cursor",
+ "//ui/base/cursor:cursor_base",
"//ui/base/cursor/mojom:cursor_type_blink",
]
diff --git a/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
index e8cc8ddcd59..adc00866f43 100644
--- a/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -74,6 +74,7 @@
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/core/html/html_frame_element_base.h"
@@ -204,6 +205,20 @@ WebString ConvertToPublic(
return "navigate-to";
case CSPDirectiveName::FrameAncestors:
return "frame-ancestors";
+ case CSPDirectiveName::ImgSrc:
+ return "img-src";
+ case CSPDirectiveName::MediaSrc:
+ return "media-src";
+ case CSPDirectiveName::ObjectSrc:
+ return "object-src";
+ case CSPDirectiveName::ScriptSrc:
+ return "script-src";
+ case CSPDirectiveName::StyleSrc:
+ return "style-src";
+ case CSPDirectiveName::WorkerSrc:
+ return "worker-src";
+ case CSPDirectiveName::ConnectSrc:
+ return "connect-src";
case CSPDirectiveName::Unknown:
NOTREACHED();
return "";
@@ -238,7 +253,7 @@ LocalFrameClientImpl::LocalFrameClientImpl(WebLocalFrameImpl* frame)
LocalFrameClientImpl::~LocalFrameClientImpl() = default;
-void LocalFrameClientImpl::Trace(Visitor* visitor) {
+void LocalFrameClientImpl::Trace(Visitor* visitor) const {
visitor->Trace(web_frame_);
LocalFrameClient::Trace(visitor);
}
@@ -391,13 +406,6 @@ Frame* LocalFrameClientImpl::Opener() const {
return ToCoreFrame(web_frame_->Opener());
}
-void LocalFrameClientImpl::SetOpener(Frame* opener) {
- WebFrame* opener_frame = WebFrame::FromFrame(opener);
- if (web_frame_->Client() && web_frame_->Opener() != opener_frame)
- web_frame_->Client()->DidChangeOpener(opener_frame);
- web_frame_->SetOpener(opener_frame);
-}
-
Frame* LocalFrameClientImpl::Parent() const {
return ToCoreFrame(web_frame_->Parent());
}
@@ -562,7 +570,7 @@ void LocalFrameClientImpl::BeginNavigation(
navigation_info->triggering_event_info = triggering_event_info;
navigation_info->should_check_main_world_content_security_policy =
should_check_main_world_content_security_policy;
- navigation_info->blob_url_token = blob_url_token.PassPipe();
+ navigation_info->blob_url_token = std::move(blob_url_token);
navigation_info->input_start = input_start_time;
if (origin_document && origin_document->GetFrame()) {
navigation_info->initiator_frame =
@@ -943,15 +951,6 @@ void LocalFrameClientImpl::DidChangeName(const String& name) {
web_frame_->Client()->DidChangeName(name);
}
-void LocalFrameClientImpl::DidChangeFramePolicy(
- Frame* child_frame,
- const FramePolicy& frame_policy) {
- if (!web_frame_->Client())
- return;
- web_frame_->Client()->DidChangeFramePolicy(WebFrame::FromFrame(child_frame),
- frame_policy);
-}
-
void LocalFrameClientImpl::DidSetFramePolicyHeaders(
network::mojom::blink::WebSandboxFlags sandbox_flags,
const ParsedFeaturePolicy& feature_policy_header,
@@ -1051,9 +1050,9 @@ String LocalFrameClientImpl::evaluateInInspectorOverlayForTesting(
}
bool LocalFrameClientImpl::HandleCurrentKeyboardEvent() {
- if (web_frame_->Client())
- return web_frame_->Client()->HandleCurrentKeyboardEvent();
- return false;
+ return web_frame_->LocalRoot()
+ ->FrameWidgetImpl()
+ ->HandleCurrentKeyboardEvent();
}
void LocalFrameClientImpl::DidChangeSelection(bool is_selection_empty) {
@@ -1122,6 +1121,14 @@ LocalFrameClientImpl::CreateWorkerContentSettingsClient() {
return web_frame_->Client()->CreateWorkerContentSettingsClient();
}
+std::unique_ptr<media::SpeechRecognitionClient>
+LocalFrameClientImpl::CreateSpeechRecognitionClient(
+ media::SpeechRecognitionClient::OnReadyCallback callback) {
+ DCHECK(web_frame_->Client());
+ return web_frame_->Client()->CreateSpeechRecognitionClient(
+ std::move(callback));
+}
+
void LocalFrameClientImpl::SetMouseCapture(bool capture) {
web_frame_->Client()->SetMouseCapture(capture);
}
diff --git a/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.h b/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.h
index cac29c6af0f..23a196c7216 100644
--- a/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.h
+++ b/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.h
@@ -54,12 +54,12 @@ class WebLocalFrameImpl;
class WebSpellCheckPanelHostClient;
enum class GlobalObjectReusePolicy;
-class LocalFrameClientImpl final : public LocalFrameClient {
+class CORE_EXPORT LocalFrameClientImpl final : public LocalFrameClient {
public:
explicit LocalFrameClientImpl(WebLocalFrameImpl*);
~LocalFrameClientImpl() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
WebLocalFrameImpl* GetWebFrame() const override;
@@ -87,7 +87,6 @@ class LocalFrameClientImpl final : public LocalFrameClient {
bool HasWebView() const override;
bool InShadowTree() const override;
Frame* Opener() const override;
- void SetOpener(Frame*) override;
Frame* Parent() const override;
Frame* Top() const override;
Frame* NextSibling() const override;
@@ -201,7 +200,6 @@ class LocalFrameClientImpl final : public LocalFrameClient {
bool AllowContentInitiatedDataUrlNavigations(const KURL&) override;
void DidChangeName(const String&) override;
- void DidChangeFramePolicy(Frame* child_frame, const FramePolicy&) override;
void DidSetFramePolicyHeaders(
network::mojom::blink::WebSandboxFlags,
const ParsedFeaturePolicy& fp_header,
@@ -268,6 +266,9 @@ class LocalFrameClientImpl final : public LocalFrameClient {
std::unique_ptr<WebContentSettingsClient> CreateWorkerContentSettingsClient()
override;
+ std::unique_ptr<media::SpeechRecognitionClient> CreateSpeechRecognitionClient(
+ media::SpeechRecognitionClient::OnReadyCallback callback) override;
+
void SetMouseCapture(bool capture) override;
bool UsePrintingLayout() const override;
diff --git a/chromium/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc
index 8681f8fc39a..7fdd2692f55 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc
@@ -338,7 +338,7 @@ WebDevToolsAgentImpl::WebDevToolsAgentImpl(
WebDevToolsAgentImpl::~WebDevToolsAgentImpl() {}
-void WebDevToolsAgentImpl::Trace(Visitor* visitor) {
+void WebDevToolsAgentImpl::Trace(Visitor* visitor) const {
visitor->Trace(agent_);
visitor->Trace(network_agents_);
visitor->Trace(page_agents_);
diff --git a/chromium/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h b/chromium/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h
index 78f38f0b9c3..6bde1bb591c 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h
+++ b/chromium/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h
@@ -69,7 +69,7 @@ class CORE_EXPORT WebDevToolsAgentImpl final
WebDevToolsAgentImpl(WebLocalFrameImpl*, bool include_view_agents);
~WebDevToolsAgentImpl() override;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
DevToolsAgent* GetDevToolsAgent() const { return agent_.Get(); }
void WillBeDestroyed();
diff --git a/chromium/third_party/blink/renderer/core/exported/web_document.cc b/chromium/third_party/blink/renderer/core/exported/web_document.cc
index fa67cdafef0..2a8df3bf4c0 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_document.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_document.cc
@@ -90,7 +90,7 @@ WebSecurityOrigin WebDocument::GetSecurityOrigin() const {
bool WebDocument::IsSecureContext() const {
const Document* document = ConstUnwrap<Document>();
- return document && document->IsSecureContext();
+ return document && document->GetExecutionContext()->IsSecureContext();
}
WebString WebDocument::Encoding() const {
@@ -233,11 +233,12 @@ void WebDocument::WatchCSSSelectors(const WebVector<WebString>& web_selectors) {
}
network::mojom::ReferrerPolicy WebDocument::GetReferrerPolicy() const {
- return ConstUnwrap<Document>()->GetReferrerPolicy();
+ return ConstUnwrap<Document>()->GetExecutionContext()->GetReferrerPolicy();
}
WebString WebDocument::OutgoingReferrer() {
- return WebString(Unwrap<Document>()->OutgoingReferrer());
+ return WebString(
+ Unwrap<Document>()->GetExecutionContext()->OutgoingReferrer());
}
WebVector<WebDraggableRegion> WebDocument::DraggableRegions() const {
diff --git a/chromium/third_party/blink/renderer/core/exported/web_document_loader_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_document_loader_impl.cc
index 5f0864cc2c8..277bc8b1718 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_document_loader_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_document_loader_impl.cc
@@ -196,7 +196,7 @@ bool WebDocumentLoaderImpl::IsListingFtpDirectory() const {
return DocumentLoader::IsListingFtpDirectory();
}
-void WebDocumentLoaderImpl::Trace(Visitor* visitor) {
+void WebDocumentLoaderImpl::Trace(Visitor* visitor) const {
DocumentLoader::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/exported/web_document_loader_impl.h b/chromium/third_party/blink/renderer/core/exported/web_document_loader_impl.h
index cfef7567b18..16549497a87 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_document_loader_impl.h
+++ b/chromium/third_party/blink/renderer/core/exported/web_document_loader_impl.h
@@ -90,7 +90,7 @@ class CORE_EXPORT WebDocumentLoaderImpl final : public DocumentLoader,
bool HadUserGesture() const override;
bool IsListingFtpDirectory() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~WebDocumentLoaderImpl() override;
diff --git a/chromium/third_party/blink/renderer/core/exported/web_document_subresource_filter_test.cc b/chromium/third_party/blink/renderer/core/exported/web_document_subresource_filter_test.cc
index a14aabd78ea..78eb4796198 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_document_subresource_filter_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_document_subresource_filter_test.cc
@@ -36,7 +36,7 @@ class TestDocumentSubresourceFilter : public WebDocumentSubresourceFilter {
queried_subresource_paths_.push_back(resource_path);
}
String resource_string = resource_url.GetString();
- for (const String& suffix : blacklisted_suffixes_) {
+ for (const String& suffix : blocklisted_suffixes_) {
if (resource_string.EndsWith(suffix))
return load_policy_;
}
@@ -51,8 +51,8 @@ class TestDocumentSubresourceFilter : public WebDocumentSubresourceFilter {
bool ShouldLogToConsole() override { return false; }
- void AddToBlacklist(const String& suffix) {
- blacklisted_suffixes_.push_back(suffix);
+ void AddToBlocklist(const String& suffix) {
+ blocklisted_suffixes_.push_back(suffix);
}
const Vector<String>& QueriedSubresourcePaths() const {
@@ -62,7 +62,7 @@ class TestDocumentSubresourceFilter : public WebDocumentSubresourceFilter {
private:
// Using STL types for compatibility with gtest/gmock.
Vector<String> queried_subresource_paths_;
- Vector<String> blacklisted_suffixes_;
+ Vector<String> blocklisted_suffixes_;
LoadPolicy load_policy_;
};
@@ -74,7 +74,7 @@ class SubresourceFilteringWebFrameClient
bool) override {
subresource_filter_ =
new TestDocumentSubresourceFilter(load_policy_for_next_load_);
- subresource_filter_->AddToBlacklist("1x1.png");
+ subresource_filter_->AddToBlocklist("1x1.png");
Frame()->GetDocumentLoader()->SetSubresourceFilter(subresource_filter_);
}
diff --git a/chromium/third_party/blink/renderer/core/exported/web_dom_message_event.cc b/chromium/third_party/blink/renderer/core/exported/web_dom_message_event.cc
index 7b2058b124a..e7ff1a4c527 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_dom_message_event.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_dom_message_event.cc
@@ -67,61 +67,8 @@ WebDOMMessageEvent::WebDOMMessageEvent(
ports, nullptr /*user_activation*/);
}
-WebDOMMessageEvent::WebDOMMessageEvent(TransferableMessage message,
- const WebString& origin,
- const WebFrame* source_frame,
- const WebDocument& target_document)
- : WebDOMMessageEvent(MessageEvent::Create(),
- message.locked_agent_cluster_id) {
- DOMWindow* window = nullptr;
- if (source_frame)
- window = WebFrame::ToCoreFrame(*source_frame)->DomWindow();
- BlinkTransferableMessage msg = ToBlinkTransferableMessage(std::move(message));
- MessagePortArray* ports = nullptr;
- if (!target_document.IsNull()) {
- Document* core_document = target_document;
- ports = MessagePort::EntanglePorts(*core_document->GetExecutionContext(),
- std::move(msg.ports));
- }
-
- UserActivation* user_activation = nullptr;
- if (msg.user_activation) {
- user_activation = MakeGarbageCollected<UserActivation>(
- msg.user_activation->has_been_active, msg.user_activation->was_active);
- }
-
- // TODO(esprehn): Chromium always passes empty string for lastEventId, is that
- // right?
- Unwrap<MessageEvent>()->initMessageEvent(
- "message", false, false, std::move(msg.message), origin,
- "" /*lastEventId*/, window, ports, user_activation,
- msg.transfer_user_activation, msg.allow_autoplay);
-
- // If the agent cluster id had a value it means this was locked when it
- // was serialized.
- if (locked_agent_cluster_id_.has_value())
- Unwrap<MessageEvent>()->LockToAgentCluster();
-}
-
WebString WebDOMMessageEvent::Origin() const {
return WebString(ConstUnwrap<MessageEvent>()->origin());
}
-TransferableMessage WebDOMMessageEvent::AsMessage() {
- BlinkTransferableMessage msg;
- msg.message = Unwrap<MessageEvent>()->DataAsSerializedScriptValue();
- msg.ports = Unwrap<MessageEvent>()->ReleaseChannels();
- msg.transfer_user_activation =
- Unwrap<MessageEvent>()->transferUserActivation();
- msg.allow_autoplay = Unwrap<MessageEvent>()->allowAutoplay();
- msg.locked_agent_cluster_id = locked_agent_cluster_id_;
- UserActivation* user_activation = Unwrap<MessageEvent>()->userActivation();
- TransferableMessage transferable_msg = ToTransferableMessage(std::move(msg));
- if (user_activation) {
- transferable_msg.user_activation = mojom::UserActivationSnapshot::New(
- user_activation->hasBeenActive(), user_activation->isActive());
- }
- return transferable_msg;
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/web_external_widget_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_external_widget_impl.cc
index 7ba828c0f6f..9b889b9037f 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_external_widget_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_external_widget_impl.cc
@@ -6,6 +6,7 @@
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/ukm_manager.h"
+#include "third_party/blink/public/mojom/input/input_handler.mojom-blink.h"
#include "third_party/blink/public/platform/scheduler/web_render_widget_scheduling_state.h"
#include "third_party/blink/renderer/platform/widget/widget_base.h"
@@ -97,6 +98,65 @@ void WebExternalWidgetImpl::SetCursor(const ui::Cursor& cursor) {
widget_base_->SetCursor(cursor);
}
+bool WebExternalWidgetImpl::HandlingInputEvent() {
+ return widget_base_->input_handler().handling_input_event();
+}
+
+void WebExternalWidgetImpl::SetHandlingInputEvent(bool handling) {
+ widget_base_->input_handler().set_handling_input_event(handling);
+}
+
+void WebExternalWidgetImpl::ProcessInputEventSynchronously(
+ const WebCoalescedInputEvent& event,
+ HandledEventCallback callback) {
+ widget_base_->input_handler().HandleInputEvent(event, std::move(callback));
+}
+
+void WebExternalWidgetImpl::UpdateTextInputState() {
+ widget_base_->UpdateTextInputState();
+}
+
+void WebExternalWidgetImpl::UpdateCompositionInfo() {
+ widget_base_->UpdateCompositionInfo(/*immediate_request=*/false);
+}
+
+void WebExternalWidgetImpl::UpdateSelectionBounds() {
+ widget_base_->UpdateSelectionBounds();
+}
+
+void WebExternalWidgetImpl::ShowVirtualKeyboard() {
+ widget_base_->ShowVirtualKeyboard();
+}
+
+void WebExternalWidgetImpl::ForceTextInputStateUpdate() {
+ widget_base_->ForceTextInputStateUpdate();
+}
+
+void WebExternalWidgetImpl::RequestCompositionUpdates(bool immediate_request,
+ bool monitor_updates) {
+ widget_base_->RequestCompositionUpdates(immediate_request, monitor_updates);
+}
+
+void WebExternalWidgetImpl::SetFocus(bool focus) {
+ widget_base_->SetFocus(focus);
+}
+
+bool WebExternalWidgetImpl::HasFocus() {
+ return widget_base_->has_focus();
+}
+
+void WebExternalWidgetImpl::DidOverscrollForTesting(
+ const gfx::Vector2dF& overscroll_delta,
+ const gfx::Vector2dF& accumulated_overscroll,
+ const gfx::PointF& position,
+ const gfx::Vector2dF& velocity) {
+ cc::OverscrollBehavior overscroll_behavior =
+ widget_base_->LayerTreeHost()->overscroll_behavior();
+ widget_base_->input_handler().DidOverscrollFromBlink(
+ overscroll_delta, accumulated_overscroll, position, velocity,
+ overscroll_behavior);
+}
+
void WebExternalWidgetImpl::SetRootLayer(scoped_refptr<cc::Layer> layer) {
widget_base_->LayerTreeHost()->SetNonBlinkManagedRootLayer(layer);
}
@@ -115,4 +175,50 @@ void WebExternalWidgetImpl::DidCommitAndDrawCompositorFrame() {
client_->DidCommitAndDrawCompositorFrame();
}
+bool WebExternalWidgetImpl::WillHandleGestureEvent(
+ const WebGestureEvent& event) {
+ return client_->WillHandleGestureEvent(event);
+}
+
+bool WebExternalWidgetImpl::WillHandleMouseEvent(const WebMouseEvent& event) {
+ return false;
+}
+
+void WebExternalWidgetImpl::ObserveGestureEventAndResult(
+ const WebGestureEvent& gesture_event,
+ const gfx::Vector2dF& unused_delta,
+ const cc::OverscrollBehavior& overscroll_behavior,
+ bool event_processed) {
+ client_->DidHandleGestureScrollEvent(gesture_event, unused_delta,
+ overscroll_behavior, event_processed);
+}
+
+bool WebExternalWidgetImpl::SupportsBufferedTouchEvents() {
+ return client_->SupportsBufferedTouchEvents();
+}
+
+void WebExternalWidgetImpl::QueueSyntheticEvent(
+ std::unique_ptr<blink::WebCoalescedInputEvent>) {}
+
+void WebExternalWidgetImpl::GetWidgetInputHandler(
+ mojo::PendingReceiver<mojom::blink::WidgetInputHandler> request,
+ mojo::PendingRemote<mojom::blink::WidgetInputHandlerHost> host) {
+ client_->GetWidgetInputHandler(std::move(request), std::move(host));
+}
+
+bool WebExternalWidgetImpl::HasCurrentImeGuard(
+ bool request_to_show_virtual_keyboard) {
+ return client_->HasCurrentImeGuard(request_to_show_virtual_keyboard);
+}
+
+void WebExternalWidgetImpl::SendCompositionRangeChanged(
+ const gfx::Range& range,
+ const std::vector<gfx::Rect>& character_bounds) {
+ client_->SendCompositionRangeChanged(range, character_bounds);
+}
+
+void WebExternalWidgetImpl::FocusChanged(bool enabled) {
+ client_->FocusChanged(enabled);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/web_external_widget_impl.h b/chromium/third_party/blink/renderer/core/exported/web_external_widget_impl.h
index 7b6ce058a13..61958dffb1f 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_external_widget_impl.h
+++ b/chromium/third_party/blink/renderer/core/exported/web_external_widget_impl.h
@@ -45,6 +45,24 @@ class WebExternalWidgetImpl : public WebExternalWidget,
scheduler::WebRenderWidgetSchedulingState* RendererWidgetSchedulingState()
override;
void SetCursor(const ui::Cursor& cursor) override;
+ bool HandlingInputEvent() override;
+ void SetHandlingInputEvent(bool handling) override;
+ void ProcessInputEventSynchronously(const WebCoalescedInputEvent&,
+ HandledEventCallback) override;
+ void DidOverscrollForTesting(
+ const gfx::Vector2dF& overscroll_delta,
+ const gfx::Vector2dF& accumulated_overscroll,
+ const gfx::PointF& position_in_viewport,
+ const gfx::Vector2dF& velocity_in_viewport) override;
+ void UpdateTextInputState() override;
+ void UpdateCompositionInfo() override;
+ void UpdateSelectionBounds() override;
+ void ShowVirtualKeyboard() override;
+ void ForceTextInputStateUpdate() override;
+ void RequestCompositionUpdates(bool immediate_request,
+ bool monitor_updates) override;
+ bool HasFocus() override;
+ void SetFocus(bool focus) override;
// WebExternalWidget overrides:
void SetRootLayer(scoped_refptr<cc::Layer>) override;
@@ -58,6 +76,24 @@ class WebExternalWidgetImpl : public WebExternalWidget,
void RequestNewLayerTreeFrameSink(
LayerTreeFrameSinkCallback callback) override;
void DidCommitAndDrawCompositorFrame() override;
+ bool WillHandleGestureEvent(const WebGestureEvent& event) override;
+ bool WillHandleMouseEvent(const WebMouseEvent& event) override;
+ void ObserveGestureEventAndResult(
+ const WebGestureEvent& gesture_event,
+ const gfx::Vector2dF& unused_delta,
+ const cc::OverscrollBehavior& overscroll_behavior,
+ bool event_processed) override;
+ bool SupportsBufferedTouchEvents() override;
+ void QueueSyntheticEvent(
+ std::unique_ptr<blink::WebCoalescedInputEvent>) override;
+ void GetWidgetInputHandler(
+ mojo::PendingReceiver<mojom::blink::WidgetInputHandler> request,
+ mojo::PendingRemote<mojom::blink::WidgetInputHandlerHost> host) override;
+ bool HasCurrentImeGuard(bool request_to_show_virtual_keyboard) override;
+ void SendCompositionRangeChanged(
+ const gfx::Range& range,
+ const std::vector<gfx::Rect>& character_bounds) override;
+ void FocusChanged(bool enabled) override;
private:
WebExternalWidgetClient* const client_;
diff --git a/chromium/third_party/blink/renderer/core/exported/web_form_element_observer_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_form_element_observer_impl.cc
index af156496334..c4f6df8a2f8 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_form_element_observer_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_form_element_observer_impl.cc
@@ -27,7 +27,7 @@ class WebFormElementObserverImpl::ObserverCallback
void Disconnect();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<HTMLElement> element_;
@@ -98,7 +98,7 @@ void WebFormElementObserverImpl::ObserverCallback::Disconnect() {
}
void WebFormElementObserverImpl::ObserverCallback::Trace(
- blink::Visitor* visitor) {
+ blink::Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(parents_);
visitor->Trace(mutation_observer_);
@@ -138,7 +138,7 @@ void WebFormElementObserverImpl::Disconnect() {
self_keep_alive_.Clear();
}
-void WebFormElementObserverImpl::Trace(Visitor* visitor) {
+void WebFormElementObserverImpl::Trace(Visitor* visitor) const {
visitor->Trace(mutation_callback_);
}
diff --git a/chromium/third_party/blink/renderer/core/exported/web_form_element_observer_impl.h b/chromium/third_party/blink/renderer/core/exported/web_form_element_observer_impl.h
index 90c03eeb302..b8ae2bf04a7 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_form_element_observer_impl.h
+++ b/chromium/third_party/blink/renderer/core/exported/web_form_element_observer_impl.h
@@ -29,7 +29,7 @@ class CORE_EXPORT WebFormElementObserverImpl final
// WebFormElementObserver implementation.
void Disconnect() override;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
class ObserverCallback;
diff --git a/chromium/third_party/blink/renderer/core/exported/web_frame_test.cc b/chromium/third_party/blink/renderer/core/exported/web_frame_test.cc
index 195abffa156..89127f5cf59 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_frame_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -41,6 +41,7 @@
#include "build/build_config.h"
#include "cc/input/overscroll_behavior.h"
#include "cc/layers/picture_layer.h"
+#include "cc/paint/paint_op_buffer.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/scroll_node.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
@@ -82,6 +83,7 @@
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_navigation_timings.h"
+#include "third_party/blink/public/web/web_print_page_description.h"
#include "third_party/blink/public/web/web_print_params.h"
#include "third_party/blink/public/web/web_range.h"
#include "third_party/blink/public/web/web_remote_frame.h"
@@ -94,6 +96,7 @@
#include "third_party/blink/public/web/web_text_checking_completion.h"
#include "third_party/blink/public/web/web_text_checking_result.h"
#include "third_party/blink/public/web/web_view_client.h"
+#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_factory.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
@@ -117,6 +120,7 @@
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h"
#include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h"
+#include "third_party/blink/renderer/core/events/message_event.h"
#include "third_party/blink/renderer/core/events/mouse_event.h"
#include "third_party/blink/renderer/core/exported/web_remote_frame_impl.h"
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
@@ -176,6 +180,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/testing/histogram_tester.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
@@ -186,6 +191,7 @@
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
+#include "ui/base/ime/mojom/text_input_state.mojom-blink.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "v8/include/v8.h"
@@ -1122,24 +1128,26 @@ TEST_F(WebFrameTest, PostMessageEvent) {
frame_test_helpers::WebViewHelper web_view_helper;
web_view_helper.InitializeAndLoad(base_url_ + "postmessage_test.html");
- WebSerializedScriptValue data(WebSerializedScriptValue::CreateInvalid());
- WebDOMMessageEvent message(data, "http://origin.com");
auto* frame =
To<LocalFrame>(web_view_helper.GetWebView()->GetPage()->MainFrame());
+ scoped_refptr<SerializedScriptValue> data = SerializedScriptValue::Create();
+ MessageEvent* message_event = MessageEvent::Create(
+ /*ports=*/nullptr, std::move(data), "http://origin.com");
+
// Send a message with the correct origin.
scoped_refptr<SecurityOrigin> correct_origin =
SecurityOrigin::Create(ToKURL(base_url_));
- frame->PostMessageEvent(base::nullopt, g_empty_string,
- correct_origin->ToString(),
- ToBlinkTransferableMessage(message.AsMessage()));
+ frame->PostMessageEvent(
+ base::nullopt, g_empty_string, correct_origin->ToString(),
+ BlinkTransferableMessage::FromMessageEvent(message_event));
// Send another message with incorrect origin.
scoped_refptr<SecurityOrigin> incorrect_origin =
SecurityOrigin::Create(ToKURL(chrome_url_));
- frame->PostMessageEvent(base::nullopt, g_empty_string,
- incorrect_origin->ToString(),
- ToBlinkTransferableMessage(message.AsMessage()));
+ frame->PostMessageEvent(
+ base::nullopt, g_empty_string, incorrect_origin->ToString(),
+ BlinkTransferableMessage::FromMessageEvent(message_event));
// Verify that only the first addition is in the body of the page.
std::string content = WebFrameContentDumper::DumpWebViewAsText(
@@ -4561,6 +4569,11 @@ TEST_F(WebFrameTest, ContextNotificationsIsolatedWorlds) {
ASSERT_NE(web_view_helper.LocalMainFrame()->MainWorldScriptContext(),
v8::Local<v8::Context>::New(isolate, notification->context));
+ // Check that the context we got has the right isolated world id.
+ ASSERT_EQ(isolated_world_id,
+ web_view_helper.LocalMainFrame()->GetScriptContextWorldId(
+ v8::Local<v8::Context>::New(isolate, notification->context)));
+
web_view_helper.Reset();
// We should have gotten three release notifications (one for each of the
@@ -5195,7 +5208,7 @@ TEST_F(WebFrameTest, FindInPageJavaScriptUpdatesDOM) {
EXPECT_TRUE(find_in_page_client.FindResultsAreReady());
// Find in a <div> element.
- options->find_next = true;
+ options->new_session = false;
EXPECT_TRUE(frame->GetFindInPage()->FindInternal(
kFindIdentifier, search_text, *options, false, &active_now));
EXPECT_TRUE(active_now);
@@ -5248,7 +5261,7 @@ TEST_F(WebFrameTest, FindInPageJavaScriptUpdatesDOMProperOrdinal) {
auto options = mojom::blink::FindOptions::New();
options->run_synchronously_for_testing = true;
- options->find_next = false;
+ options->new_session = true;
options->forward = true;
// The first search that will start the scoping process.
frame->GetFindInPage()->Find(kFindIdentifier, search_pattern,
@@ -5259,7 +5272,7 @@ TEST_F(WebFrameTest, FindInPageJavaScriptUpdatesDOMProperOrdinal) {
EXPECT_EQ(2, find_in_page_client.Count());
EXPECT_EQ(1, find_in_page_client.ActiveIndex());
- options->find_next = true;
+ options->new_session = false;
// The second search will jump to the next match without any scoping.
frame->GetFindInPage()->Find(kFindIdentifier, search_pattern,
options->Clone());
@@ -5327,7 +5340,7 @@ TEST_F(WebFrameTest, FindInPageForcedRedoOfFindInPage) {
auto options = mojom::blink::FindOptions::New();
options->run_synchronously_for_testing = true;
- options->find_next = false;
+ options->new_session = true;
options->forward = true;
// First run.
frame->GetFindInPage()->Find(kFindIdentifier, search_pattern,
@@ -5343,7 +5356,7 @@ TEST_F(WebFrameTest, FindInPageForcedRedoOfFindInPage) {
EXPECT_EQ(2, find_in_page_client.Count());
EXPECT_EQ(1, find_in_page_client.ActiveIndex());
- options->find_next = true;
+ options->new_session = false;
options->force = false;
frame->GetFindInPage()->Find(kFindIdentifier, search_pattern,
@@ -5352,7 +5365,7 @@ TEST_F(WebFrameTest, FindInPageForcedRedoOfFindInPage) {
EXPECT_EQ(2, find_in_page_client.Count());
EXPECT_EQ(2, find_in_page_client.ActiveIndex());
- options->find_next = false;
+ options->new_session = true;
options->force = true;
frame->GetFindInPage()->Find(kFindIdentifier, search_pattern,
@@ -5820,24 +5833,24 @@ TEST_F(WebFrameTest, MoveRangeSelectionExtentScollsInputField) {
TEST_F(WebFrameTest, SmartClipData) {
static const char kExpectedClipText[] = "\nPrice 10,000,000won";
static const char kExpectedClipHtml[] =
- "<div id=\"div4\" style=\"padding: 10px; margin: 10px; border: 2px "
- "solid skyblue; float: left; width: 190px; height: 30px; "
- "color: rgb(0, 0, 0); font-family: myahem; font-size: 8px; font-style: "
- "normal; font-variant-ligatures: normal; font-variant-caps: normal; "
- "font-weight: 400; letter-spacing: "
- "normal; orphans: 2; text-align: start; "
- "text-indent: 0px; text-transform: none; white-space: normal; widows: "
- "2; word-spacing: 0px; -webkit-text-stroke-width: 0px; "
- "text-decoration-style: initial; text-decoration-color: initial;\">Air "
- "conditioner</div><div id=\"div5\" style=\"padding: 10px; margin: 10px; "
- "border: 2px solid skyblue; float: left; width: 190px; height: 30px; "
- "color: rgb(0, 0, 0); font-family: myahem; font-size: 8px; font-style: "
- "normal; font-variant-ligatures: normal; font-variant-caps: normal; "
- "font-weight: 400; letter-spacing: normal; orphans: 2; text-align: "
- "start; text-indent: 0px; text-transform: none; white-space: normal; "
- "widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; "
- "text-decoration-style: initial; text-decoration-color: initial;\">Price "
- "10,000,000won</div>";
+ "<div id=\"div4\" style=\"padding: 10px; margin: 10px; border: 2px solid "
+ "skyblue; float: left; width: 190px; height: 30px; color: rgb(0, 0, 0); "
+ "font-family: myahem; font-size: 8px; font-style: normal; "
+ "font-variant-ligatures: normal; font-variant-caps: normal; font-weight: "
+ "400; letter-spacing: normal; orphans: 2; text-align: start; "
+ "text-indent: 0px; text-transform: none; white-space: normal; widows: 2; "
+ "word-spacing: 0px; -webkit-text-stroke-width: 0px; "
+ "text-decoration-thickness: initial; text-decoration-style: initial; "
+ "text-decoration-color: initial;\">Air conditioner</div><div id=\"div5\" "
+ "style=\"padding: 10px; margin: 10px; border: 2px solid skyblue; float: "
+ "left; width: 190px; height: 30px; color: rgb(0, 0, 0); font-family: "
+ "myahem; font-size: 8px; font-style: normal; font-variant-ligatures: "
+ "normal; font-variant-caps: normal; font-weight: 400; letter-spacing: "
+ "normal; orphans: 2; text-align: start; text-indent: 0px; "
+ "text-transform: none; white-space: normal; widows: 2; word-spacing: "
+ "0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: "
+ "initial; text-decoration-style: initial; text-decoration-color: "
+ "initial;\">Price 10,000,000won</div>";
WebString clip_text;
WebString clip_html;
WebRect clip_rect;
@@ -5857,24 +5870,24 @@ TEST_F(WebFrameTest, SmartClipData) {
TEST_F(WebFrameTest, SmartClipDataWithPinchZoom) {
static const char kExpectedClipText[] = "\nPrice 10,000,000won";
static const char kExpectedClipHtml[] =
- "<div id=\"div4\" style=\"padding: 10px; margin: 10px; border: 2px "
- "solid skyblue; float: left; width: 190px; height: 30px; "
- "color: rgb(0, 0, 0); font-family: myahem; font-size: 8px; font-style: "
- "normal; font-variant-ligatures: normal; font-variant-caps: normal; "
- "font-weight: 400; letter-spacing: "
- "normal; orphans: 2; text-align: start; "
- "text-indent: 0px; text-transform: none; white-space: normal; widows: "
- "2; word-spacing: 0px; -webkit-text-stroke-width: 0px; "
- "text-decoration-style: initial; text-decoration-color: initial;\">Air "
- "conditioner</div><div id=\"div5\" style=\"padding: 10px; margin: 10px; "
- "border: 2px solid skyblue; float: left; width: 190px; height: 30px; "
- "color: rgb(0, 0, 0); font-family: myahem; font-size: 8px; font-style: "
- "normal; font-variant-ligatures: normal; font-variant-caps: normal; "
- "font-weight: 400; letter-spacing: normal; orphans: 2; text-align: "
- "start; text-indent: 0px; text-transform: none; white-space: normal; "
- "widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; "
- "text-decoration-style: initial; text-decoration-color: initial;\">Price "
- "10,000,000won</div>";
+ "<div id=\"div4\" style=\"padding: 10px; margin: 10px; border: 2px solid "
+ "skyblue; float: left; width: 190px; height: 30px; color: rgb(0, 0, 0); "
+ "font-family: myahem; font-size: 8px; font-style: normal; "
+ "font-variant-ligatures: normal; font-variant-caps: normal; font-weight: "
+ "400; letter-spacing: normal; orphans: 2; text-align: start; "
+ "text-indent: 0px; text-transform: none; white-space: normal; widows: 2; "
+ "word-spacing: 0px; -webkit-text-stroke-width: 0px; "
+ "text-decoration-thickness: initial; text-decoration-style: initial; "
+ "text-decoration-color: initial;\">Air conditioner</div><div id=\"div5\" "
+ "style=\"padding: 10px; margin: 10px; border: 2px solid skyblue; float: "
+ "left; width: 190px; height: 30px; color: rgb(0, 0, 0); font-family: "
+ "myahem; font-size: 8px; font-style: normal; font-variant-ligatures: "
+ "normal; font-variant-caps: normal; font-weight: 400; letter-spacing: "
+ "normal; orphans: 2; text-align: start; text-indent: 0px; "
+ "text-transform: none; white-space: normal; widows: 2; word-spacing: "
+ "0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: "
+ "initial; text-decoration-style: initial; text-decoration-color: "
+ "initial;\">Price 10,000,000won</div>";
WebString clip_text;
WebString clip_html;
WebRect clip_rect;
@@ -9480,7 +9493,7 @@ class RemoteNavigationClient
bool initiator_frame_has_download_sandbox_flag,
bool blocking_downloads_in_sandbox_enabled,
bool initiator_frame_is_ad,
- mojo::ScopedMessagePipeHandle,
+ CrossVariantMojoRemote<mojom::blink::BlobURLTokenInterfaceBase>,
const base::Optional<WebImpression>& impression) override {
last_request_.CopyFrom(request);
}
@@ -9664,46 +9677,6 @@ TEST_F(WebFrameTest, RemoteFrameInitialCommitType) {
helper.Reset();
}
-class GestureEventTestWebWidgetClient
- : public frame_test_helpers::TestWebWidgetClient {
- public:
- GestureEventTestWebWidgetClient() : did_handle_gesture_event_(false) {}
- ~GestureEventTestWebWidgetClient() override = default;
-
- // frame_test_helpers::TestWebWidgetClient:
- void DidHandleGestureEvent(const WebGestureEvent& event,
- bool event_cancelled) override {
- did_handle_gesture_event_ = true;
- }
- bool DidHandleGestureEvent() const { return did_handle_gesture_event_; }
-
- private:
- bool did_handle_gesture_event_;
-};
-
-TEST_F(WebFrameTest, FrameWidgetTest) {
- frame_test_helpers::WebViewHelper helper;
- helper.InitializeRemote();
-
- GestureEventTestWebWidgetClient child_widget_client;
- WebLocalFrame* child_frame = frame_test_helpers::CreateLocalChild(
- *helper.RemoteMainFrame(), WebString(), WebFrameOwnerProperties(),
- nullptr, nullptr, &child_widget_client);
-
- helper.GetWebView()->Resize(WebSize(1000, 1000));
-
- WebGestureEvent event(WebInputEvent::Type::kGestureTap,
- WebInputEvent::kNoModifiers,
- WebInputEvent::GetStaticTimeStampForTests(),
- WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(gfx::PointF(20, 20));
- child_frame->FrameWidget()->HandleInputEvent(
- WebCoalescedInputEvent(event, ui::LatencyInfo()));
- EXPECT_TRUE(child_widget_client.DidHandleGestureEvent());
-
- helper.Reset();
-}
-
TEST_F(WebFrameTest, DetachRemoteFrame) {
frame_test_helpers::WebViewHelper helper;
helper.InitializeRemote();
@@ -10012,11 +9985,12 @@ TEST_F(WebFrameTest, PausedPageLoadWithRemoteMainFrame) {
class OverscrollWebWidgetClient
: public frame_test_helpers::TestWebWidgetClient {
public:
- MOCK_METHOD4(DidOverscroll,
+ MOCK_METHOD5(DidOverscroll,
void(const gfx::Vector2dF&,
const gfx::Vector2dF&,
const gfx::PointF&,
- const gfx::Vector2dF&));
+ const gfx::Vector2dF&,
+ cc::OverscrollBehavior));
};
class WebFrameOverscrollTest
@@ -10088,40 +10062,44 @@ TEST_P(WebFrameOverscrollTest,
ScrollBegin(&web_view_helper, -300, -316);
EXPECT_CALL(client,
DidOverscroll(gfx::Vector2dF(8, 16), gfx::Vector2dF(8, 16),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ gfx::PointF(100, 100), gfx::Vector2dF(),
+ kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, -308, -316);
Mock::VerifyAndClearExpectations(&client);
EXPECT_CALL(client,
DidOverscroll(gfx::Vector2dF(0, 13), gfx::Vector2dF(8, 29),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ gfx::PointF(100, 100), gfx::Vector2dF(),
+ kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, 0, -13);
Mock::VerifyAndClearExpectations(&client);
EXPECT_CALL(client,
DidOverscroll(gfx::Vector2dF(20, 13), gfx::Vector2dF(28, 42),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ gfx::PointF(100, 100), gfx::Vector2dF(),
+ kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, -20, -13);
Mock::VerifyAndClearExpectations(&client);
// Overscroll is not reported.
- EXPECT_CALL(client, DidOverscroll(_, _, _, _)).Times(0);
+ EXPECT_CALL(client, DidOverscroll(_, _, _, _, _)).Times(0);
ScrollUpdate(&web_view_helper, 0, 1);
Mock::VerifyAndClearExpectations(&client);
- EXPECT_CALL(client, DidOverscroll(_, _, _, _)).Times(0);
+ EXPECT_CALL(client, DidOverscroll(_, _, _, _, _)).Times(0);
ScrollUpdate(&web_view_helper, 1, 0);
Mock::VerifyAndClearExpectations(&client);
// Overscroll is reported.
EXPECT_CALL(client,
DidOverscroll(gfx::Vector2dF(0, -701), gfx::Vector2dF(0, -701),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ gfx::PointF(100, 100), gfx::Vector2dF(),
+ kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, 0, 1000);
Mock::VerifyAndClearExpectations(&client);
// Overscroll is not reported.
- EXPECT_CALL(client, DidOverscroll(_, _, _, _)).Times(0);
+ EXPECT_CALL(client, DidOverscroll(_, _, _, _, _)).Times(0);
ScrollEnd(&web_view_helper);
Mock::VerifyAndClearExpectations(&client);
}
@@ -10140,7 +10118,7 @@ TEST_P(WebFrameOverscrollTest,
ScrollBegin(&web_view_helper, 0, -316);
// Scroll the Div to the end.
- EXPECT_CALL(client, DidOverscroll(_, _, _, _)).Times(0);
+ EXPECT_CALL(client, DidOverscroll(_, _, _, _, _)).Times(0);
ScrollUpdate(&web_view_helper, 0, -316);
Mock::VerifyAndClearExpectations(&client);
@@ -10150,7 +10128,8 @@ TEST_P(WebFrameOverscrollTest,
// Now On Scrolling DIV, scroll is bubbled and root layer is over-scrolled.
EXPECT_CALL(client,
DidOverscroll(gfx::Vector2dF(0, 100), gfx::Vector2dF(0, 100),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ gfx::PointF(100, 100), gfx::Vector2dF(),
+ kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, 0, -100);
ScrollUpdate(&web_view_helper, 0, -100);
Mock::VerifyAndClearExpectations(&client);
@@ -10189,7 +10168,7 @@ TEST_P(WebFrameOverscrollTest, RootLayerOverscrolledOnInnerDivOverScroll) {
ScrollBegin(&web_view_helper, 0, -316);
// Scroll the Div to the end.
- EXPECT_CALL(client, DidOverscroll(_, _, _, _)).Times(0);
+ EXPECT_CALL(client, DidOverscroll(_, _, _, _, _)).Times(0);
ScrollUpdate(&web_view_helper, 0, -316);
Mock::VerifyAndClearExpectations(&client);
@@ -10199,7 +10178,8 @@ TEST_P(WebFrameOverscrollTest, RootLayerOverscrolledOnInnerDivOverScroll) {
// Now On Scrolling DIV, scroll is bubbled and root layer is over-scrolled.
EXPECT_CALL(client,
DidOverscroll(gfx::Vector2dF(0, 50), gfx::Vector2dF(0, 50),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ gfx::PointF(100, 100), gfx::Vector2dF(),
+ kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, 0, -150);
Mock::VerifyAndClearExpectations(&client);
}
@@ -10217,7 +10197,7 @@ TEST_P(WebFrameOverscrollTest, RootLayerOverscrolledOnInnerIFrameOverScroll) {
ScrollBegin(&web_view_helper, 0, -320);
// Scroll the IFrame to the end.
- EXPECT_CALL(client, DidOverscroll(_, _, _, _)).Times(0);
+ EXPECT_CALL(client, DidOverscroll(_, _, _, _, _)).Times(0);
// This scroll will fully scroll the iframe but will be consumed before being
// counted as overscroll.
@@ -10234,7 +10214,8 @@ TEST_P(WebFrameOverscrollTest, RootLayerOverscrolledOnInnerIFrameOverScroll) {
// Now On Scrolling IFrame, scroll is bubbled and root layer is over-scrolled.
EXPECT_CALL(client,
DidOverscroll(gfx::Vector2dF(0, 50), gfx::Vector2dF(0, 50),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ gfx::PointF(100, 100), gfx::Vector2dF(),
+ kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, 0, -150);
Mock::VerifyAndClearExpectations(&client);
@@ -10256,32 +10237,34 @@ TEST_P(WebFrameOverscrollTest, ScaledPageRootLayerOverscrolled) {
// The point is (99, 99) because we clamp in the division by 3 to 33 so when
// we go back to viewport coordinates it becomes (99, 99).
ScrollBegin(&web_view_helper, 0, 30);
- EXPECT_CALL(client,
- DidOverscroll(gfx::Vector2dF(0, -30), gfx::Vector2dF(0, -30),
- gfx::PointF(99, 99), gfx::Vector2dF()));
+ EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(0, -30),
+ gfx::Vector2dF(0, -30), gfx::PointF(99, 99),
+ gfx::Vector2dF(), kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, 0, 30);
Mock::VerifyAndClearExpectations(&client);
- EXPECT_CALL(client,
- DidOverscroll(gfx::Vector2dF(0, -30), gfx::Vector2dF(0, -60),
- gfx::PointF(99, 99), gfx::Vector2dF()));
+ EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(0, -30),
+ gfx::Vector2dF(0, -60), gfx::PointF(99, 99),
+ gfx::Vector2dF(), kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, 0, 30);
Mock::VerifyAndClearExpectations(&client);
EXPECT_CALL(client,
DidOverscroll(gfx::Vector2dF(-30, -30), gfx::Vector2dF(-30, -90),
- gfx::PointF(99, 99), gfx::Vector2dF()));
+ gfx::PointF(99, 99), gfx::Vector2dF(),
+ kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, 30, 30);
Mock::VerifyAndClearExpectations(&client);
EXPECT_CALL(client,
DidOverscroll(gfx::Vector2dF(-30, 0), gfx::Vector2dF(-60, -90),
- gfx::PointF(99, 99), gfx::Vector2dF()));
+ gfx::PointF(99, 99), gfx::Vector2dF(),
+ kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, 30, 0);
Mock::VerifyAndClearExpectations(&client);
// Overscroll is not reported.
- EXPECT_CALL(client, DidOverscroll(_, _, _, _)).Times(0);
+ EXPECT_CALL(client, DidOverscroll(_, _, _, _, _)).Times(0);
ScrollEnd(&web_view_helper);
Mock::VerifyAndClearExpectations(&client);
}
@@ -10299,49 +10282,52 @@ TEST_P(WebFrameOverscrollTest, NoOverscrollForSmallvalues) {
ScrollBegin(&web_view_helper, 10, 10);
EXPECT_CALL(client,
DidOverscroll(gfx::Vector2dF(-10, -10), gfx::Vector2dF(-10, -10),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ gfx::PointF(100, 100), gfx::Vector2dF(),
+ kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, 10, 10);
Mock::VerifyAndClearExpectations(&client);
- EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(0, -0.10),
- gfx::Vector2dF(-10, -10.10),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(0, -0.10),
+ gfx::Vector2dF(-10, -10.10), gfx::PointF(100, 100),
+ gfx::Vector2dF(), kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, 0, 0.10);
Mock::VerifyAndClearExpectations(&client);
EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(-0.10, 0),
gfx::Vector2dF(-10.10, -10.10),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ gfx::PointF(100, 100), gfx::Vector2dF(),
+ kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, 0.10, 0);
Mock::VerifyAndClearExpectations(&client);
// For residual values overscrollDelta should be reset and DidOverscroll
// shouldn't be called.
- EXPECT_CALL(client, DidOverscroll(_, _, _, _)).Times(0);
+ EXPECT_CALL(client, DidOverscroll(_, _, _, _, _)).Times(0);
ScrollUpdate(&web_view_helper, 0, 0.09);
Mock::VerifyAndClearExpectations(&client);
- EXPECT_CALL(client, DidOverscroll(_, _, _, _)).Times(0);
+ EXPECT_CALL(client, DidOverscroll(_, _, _, _, _)).Times(0);
ScrollUpdate(&web_view_helper, 0.09, 0.09);
Mock::VerifyAndClearExpectations(&client);
- EXPECT_CALL(client, DidOverscroll(_, _, _, _)).Times(0);
+ EXPECT_CALL(client, DidOverscroll(_, _, _, _, _)).Times(0);
ScrollUpdate(&web_view_helper, 0.09, 0);
Mock::VerifyAndClearExpectations(&client);
- EXPECT_CALL(client, DidOverscroll(_, _, _, _)).Times(0);
+ EXPECT_CALL(client, DidOverscroll(_, _, _, _, _)).Times(0);
ScrollUpdate(&web_view_helper, 0, -0.09);
Mock::VerifyAndClearExpectations(&client);
- EXPECT_CALL(client, DidOverscroll(_, _, _, _)).Times(0);
+ EXPECT_CALL(client, DidOverscroll(_, _, _, _, _)).Times(0);
ScrollUpdate(&web_view_helper, -0.09, -0.09);
Mock::VerifyAndClearExpectations(&client);
- EXPECT_CALL(client, DidOverscroll(_, _, _, _)).Times(0);
+ EXPECT_CALL(client, DidOverscroll(_, _, _, _, _)).Times(0);
ScrollUpdate(&web_view_helper, -0.09, 0);
Mock::VerifyAndClearExpectations(&client);
- EXPECT_CALL(client, DidOverscroll(_, _, _, _)).Times(0);
+ EXPECT_CALL(client, DidOverscroll(_, _, _, _, _)).Times(0);
ScrollEnd(&web_view_helper);
Mock::VerifyAndClearExpectations(&client);
}
@@ -10359,14 +10345,15 @@ TEST_P(WebFrameOverscrollTest, OverscrollBehaviorGoesToCompositor) {
WebLocalFrame* mainFrame =
web_view_helper.GetWebView()->MainFrame()->ToWebLocalFrame();
EXPECT_EQ(web_view_helper.GetLayerTreeHost()->overscroll_behavior(),
- cc::OverscrollBehavior());
+ kOverscrollBehaviorAuto);
mainFrame->ExecuteScript(
WebScriptSource(WebString("document.body.style="
"'overscroll-behavior: auto;'")));
ScrollBegin(&web_view_helper, 100, 116);
- EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(-100, -100),
- gfx::Vector2dF(-100, -100),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(-100, -100),
+ gfx::Vector2dF(-100, -100), gfx::PointF(100, 100),
+ gfx::Vector2dF(), kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, 100, 100);
Mock::VerifyAndClearExpectations(&client);
EXPECT_EQ(web_view_helper.GetLayerTreeHost()->overscroll_behavior(),
@@ -10376,9 +10363,10 @@ TEST_P(WebFrameOverscrollTest, OverscrollBehaviorGoesToCompositor) {
WebScriptSource(WebString("document.body.style="
"'overscroll-behavior: contain;'")));
ScrollBegin(&web_view_helper, 100, 116);
- EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(-100, -100),
- gfx::Vector2dF(-200, -200),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(-100, -100),
+ gfx::Vector2dF(-200, -200), gfx::PointF(100, 100),
+ gfx::Vector2dF(), kOverscrollBehaviorContain));
ScrollUpdate(&web_view_helper, 100, 100);
Mock::VerifyAndClearExpectations(&client);
EXPECT_EQ(web_view_helper.GetLayerTreeHost()->overscroll_behavior(),
@@ -10388,9 +10376,10 @@ TEST_P(WebFrameOverscrollTest, OverscrollBehaviorGoesToCompositor) {
WebScriptSource(WebString("document.body.style="
"'overscroll-behavior: none;'")));
ScrollBegin(&web_view_helper, 100, 116);
- EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(-100, -100),
- gfx::Vector2dF(-300, -300),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(-100, -100),
+ gfx::Vector2dF(-300, -300), gfx::PointF(100, 100),
+ gfx::Vector2dF(), kOverscrollBehaviorNone));
ScrollUpdate(&web_view_helper, 100, 100);
Mock::VerifyAndClearExpectations(&client);
EXPECT_EQ(web_view_helper.GetLayerTreeHost()->overscroll_behavior(),
@@ -10422,9 +10411,10 @@ TEST_P(WebFrameOverscrollTest, OnlyMainFrameOverscrollBehaviorHasEffect) {
"'overscroll-behavior: none;'")));
ScrollBegin(&web_view_helper, 100, 116);
- EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(-100, -100),
- gfx::Vector2dF(-100, -100),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(-100, -100),
+ gfx::Vector2dF(-100, -100), gfx::PointF(100, 100),
+ gfx::Vector2dF(), kOverscrollBehaviorAuto));
ScrollUpdate(&web_view_helper, 100, 100);
Mock::VerifyAndClearExpectations(&client);
EXPECT_EQ(web_view_helper.GetLayerTreeHost()->overscroll_behavior(),
@@ -10433,9 +10423,10 @@ TEST_P(WebFrameOverscrollTest, OnlyMainFrameOverscrollBehaviorHasEffect) {
mainFrame->ExecuteScript(
WebScriptSource(WebString("document.body.style="
"'overscroll-behavior: contain;'")));
- EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(-100, -100),
- gfx::Vector2dF(-200, -200),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(-100, -100),
+ gfx::Vector2dF(-200, -200), gfx::PointF(100, 100),
+ gfx::Vector2dF(), kOverscrollBehaviorContain));
ScrollUpdate(&web_view_helper, 100, 100);
Mock::VerifyAndClearExpectations(&client);
EXPECT_EQ(web_view_helper.GetLayerTreeHost()->overscroll_behavior(),
@@ -10458,7 +10449,7 @@ TEST_F(WebFrameTest, MaxFrames) {
WebLocalFrameImpl* frame =
frame_test_helpers::CreateLocalChild(*web_view_helper.RemoteMainFrame());
- while (page->SubframeCount() < Page::kMaxNumberOfFrames) {
+ while (page->SubframeCount() < Page::MaxNumberOfFrames()) {
frame_test_helpers::CreateRemoteChild(*web_view_helper.RemoteMainFrame());
}
auto* iframe = MakeGarbageCollected<HTMLIFrameElement>(
@@ -10606,7 +10597,7 @@ class WebRemoteFrameVisibilityChangeTest : public WebFrameTest {
->MainFrameImpl();
web_view_helper_.Resize(WebSize(640, 480));
remote_frame_host_.Init(
- remote_frame_client_.GetAssociatedInterfaceProvider());
+ remote_frame_client_.GetRemoteAssociatedInterfaces());
web_remote_frame_ = frame_test_helpers::CreateRemote(&remote_frame_client_);
}
@@ -10914,10 +10905,7 @@ class TestLocalFrameHostForSaveImageFromDataURL : public FakeLocalFrameHost {
// FakeLocalFrameHost:
void DownloadURL(mojom::blink::DownloadURLParamsPtr params) override {
- mojo::PendingRemote<mojom::blink::Blob> blob_data_remote(
- std::move(params->data_url_blob), mojom::blink::Blob::Version_);
-
- mojo::Remote<mojom::blink::Blob> blob(std::move(blob_data_remote));
+ mojo::Remote<mojom::blink::Blob> blob(std::move(params->data_url_blob));
mojo::ScopedDataPipeProducerHandle producer_handle;
mojo::ScopedDataPipeConsumerHandle consumer_handle;
auto result =
@@ -12464,19 +12452,19 @@ TEST_F(WebFrameTest, ClearClosedOpener) {
class ShowVirtualKeyboardObserverWidgetClient
: public frame_test_helpers::TestWebWidgetClient {
public:
- ShowVirtualKeyboardObserverWidgetClient()
- : did_show_virtual_keyboard_(false) {}
+ ShowVirtualKeyboardObserverWidgetClient() = default;
~ShowVirtualKeyboardObserverWidgetClient() override = default;
// frame_test_helpers::TestWebWidgetClient:
- void ShowVirtualKeyboardOnElementFocus() override {
- did_show_virtual_keyboard_ = true;
+ void TextInputStateChanged(
+ ui::mojom::blink::TextInputStatePtr state) override {
+ did_show_virtual_keyboard_ |= state->show_ime_if_needed;
}
bool DidShowVirtualKeyboard() const { return did_show_virtual_keyboard_; }
private:
- bool did_show_virtual_keyboard_;
+ bool did_show_virtual_keyboard_ = false;
};
TEST_F(WebFrameTest, ShowVirtualKeyboardOnElementFocus) {
@@ -12499,9 +12487,13 @@ TEST_F(WebFrameTest, ShowVirtualKeyboardOnElementFocus) {
WebScriptSource("window.focus();"
"document.querySelector('input').focus();"));
+ RunPendingTasks();
// Verify that the right WebWidgetClient has been notified.
+#if defined(OS_CHROMEOS)
+ EXPECT_FALSE(web_widget_client.DidShowVirtualKeyboard());
+#else
EXPECT_TRUE(web_widget_client.DidShowVirtualKeyboard());
-
+#endif
web_view_helper.Reset();
}
@@ -12695,8 +12687,7 @@ class TestFallbackWebFrameClient
TestWebFrameClient::BeginNavigation(std::move(info));
return;
}
- Frame()->WillStartNavigation(
- *info, false /* is_history_navigation_in_new_child_frame */);
+ Frame()->WillStartNavigation(*info);
}
private:
@@ -12832,7 +12823,8 @@ static void TestFramePrinting(WebLocalFrameImpl* frame) {
print_params.print_content_area.height = page_size.height;
EXPECT_EQ(1, frame->PrintBegin(print_params, WebNode()));
PaintRecorder recorder;
- frame->PrintPagesForTesting(recorder.beginRecording(IntRect()), page_size);
+ frame->PrintPagesForTesting(recorder.beginRecording(IntRect()), page_size,
+ page_size);
frame->PrintEnd();
}
@@ -12852,6 +12844,90 @@ TEST_F(WebFrameTest, PrintIframeUnderDetached) {
web_view_helper.LocalMainFrame()->FirstChild()->FirstChild()));
}
+namespace {
+
+struct TextRunDOMNodeIdInfo {
+ int glyph_len;
+ DOMNodeId dom_node_id;
+};
+
+// Given a PaintRecord and a starting DOMNodeId, recursively iterate over all of
+// the (nested) paint ops, and populate |text_runs| with the number of glyphs
+// and the DOMNodeId of each text run.
+void RecursiveCollectTextRunDOMNodeIds(
+ sk_sp<const PaintRecord> paint_record,
+ DOMNodeId dom_node_id,
+ std::vector<TextRunDOMNodeIdInfo>* text_runs) {
+ for (cc::PaintOpBuffer::Iterator it(paint_record.get()); it; ++it) {
+ if ((*it)->GetType() == cc::PaintOpType::DrawRecord) {
+ cc::DrawRecordOp* draw_record_op = static_cast<cc::DrawRecordOp*>(*it);
+ RecursiveCollectTextRunDOMNodeIds(draw_record_op->record, dom_node_id,
+ text_runs);
+ } else if ((*it)->GetType() == cc::PaintOpType::SetNodeId) {
+ cc::SetNodeIdOp* set_node_id_op = static_cast<cc::SetNodeIdOp*>(*it);
+ dom_node_id = set_node_id_op->node_id;
+ } else if ((*it)->GetType() == cc::PaintOpType::DrawTextBlob) {
+ cc::DrawTextBlobOp* draw_text_op = static_cast<cc::DrawTextBlobOp*>(*it);
+ SkTextBlob::Iter iter(*draw_text_op->blob);
+ SkTextBlob::Iter::Run run;
+ while (iter.next(&run)) {
+ TextRunDOMNodeIdInfo text_run_info;
+ text_run_info.glyph_len = run.fGlyphCount;
+ text_run_info.dom_node_id = dom_node_id;
+ text_runs->push_back(text_run_info);
+ }
+ }
+ }
+}
+
+} // namespace
+
+TEST_F(WebFrameTest, FirstLetterHasDOMNodeIdWhenPrinting) {
+ // When printing, every DrawText painting op needs to have an associated
+ // DOM Node ID. This test ensures that when the first-letter style is used,
+ // the drawing op for the first letter is correctly associated with the same
+ // DOM Node ID as the following text.
+
+ // Load a web page with two elements containing the text
+ // "Hello" and "World", where "World" has a first-letter style.
+ RegisterMockedHttpURLLoad("first-letter.html");
+ frame_test_helpers::WebViewHelper web_view_helper;
+ web_view_helper.InitializeAndLoad(base_url_ + "first-letter.html");
+
+ // Print the page and capture the PaintRecord.
+ WebPrintParams print_params;
+ WebSize page_size(500, 500);
+ print_params.print_content_area.width = page_size.width;
+ print_params.print_content_area.height = page_size.height;
+ WebLocalFrameImpl* frame = web_view_helper.LocalMainFrame();
+ EXPECT_EQ(1, frame->PrintBegin(print_params, WebNode()));
+ PaintRecorder recorder;
+ frame->PrintPagesForTesting(recorder.beginRecording(IntRect()), page_size,
+ page_size);
+ frame->PrintEnd();
+ sk_sp<PaintRecord> paint_record = recorder.finishRecordingAsPicture();
+
+ // Unpack the paint record and collect info about the text runs.
+ std::vector<TextRunDOMNodeIdInfo> text_runs;
+ RecursiveCollectTextRunDOMNodeIds(paint_record, 0, &text_runs);
+
+ // The first text run should be "Hello".
+ ASSERT_EQ(3U, text_runs.size());
+ EXPECT_EQ(5, text_runs[0].glyph_len);
+ EXPECT_NE(kInvalidDOMNodeId, text_runs[0].dom_node_id);
+
+ // The second text run should be "W", the first letter of "World".
+ EXPECT_EQ(1, text_runs[1].glyph_len);
+ EXPECT_NE(kInvalidDOMNodeId, text_runs[1].dom_node_id);
+
+ // The last text run should be "orld", the rest of "World".
+ EXPECT_EQ(4, text_runs[2].glyph_len);
+ EXPECT_NE(kInvalidDOMNodeId, text_runs[2].dom_node_id);
+
+ // The second and third text runs should have the same DOM Node ID.
+ EXPECT_EQ(text_runs[1].dom_node_id, text_runs[2].dom_node_id);
+}
+
TEST_F(WebFrameTest, ExecuteCommandProducesUserGesture) {
frame_test_helpers::WebViewHelper web_view_helper;
web_view_helper.InitializeAndLoad("about:blank");
@@ -13027,6 +13103,58 @@ TEST_F(WebFrameSimTest, GetPageSizeType) {
}
}
+TEST_F(WebFrameSimTest, PageOrientation) {
+ ScopedNamedPagesForTest named_pages_enabler(true);
+ WebSize page_size(500, 500);
+ WebView().MainFrameWidget()->Resize(page_size);
+
+ SimRequest request("https://example.com/test.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ @page upright { page-orientation: upright; }
+ @page clockwise { page-orientation: rotate-right; }
+ @page counter-clockwise { page-orientation: rotate-left; }
+ div { height: 10px; }
+ </style>
+ <!-- First page: -->
+ <div style="page:upright;"></div>
+ <!-- Second page: -->
+ <div style="page:counter-clockwise;"></div>
+ <!-- Third page: -->
+ <div style="page:clockwise;"></div>
+ <div style="page:clockwise;"></div>
+ <!-- Fourth page: -->
+ <div></div>
+ )HTML");
+
+ Compositor().BeginFrame();
+ RunPendingTasks();
+
+ auto* frame = WebView().MainFrame()->ToWebLocalFrame();
+ WebPrintParams print_params;
+ print_params.print_content_area.width = page_size.width;
+ print_params.print_content_area.height = page_size.height;
+ EXPECT_EQ(4, frame->PrintBegin(print_params, WebNode()));
+
+ WebPrintPageDescription description;
+
+ frame->GetPageDescription(0, &description);
+ EXPECT_EQ(description.orientation, PageOrientation::kUpright);
+
+ frame->GetPageDescription(1, &description);
+ EXPECT_EQ(description.orientation, PageOrientation::kRotateLeft);
+
+ frame->GetPageDescription(2, &description);
+ EXPECT_EQ(description.orientation, PageOrientation::kRotateRight);
+
+ frame->GetPageDescription(3, &description);
+ EXPECT_EQ(description.orientation, PageOrientation::kUpright);
+
+ frame->PrintEnd();
+}
+
TEST_F(WebFrameTest, MediaQueriesInLocalFrameInsideRemote) {
frame_test_helpers::WebViewHelper helper;
helper.InitializeRemote();
@@ -13222,4 +13350,31 @@ TEST_F(WebFrameTest, FocusElementCallsFocusedElementChanged) {
EXPECT_TRUE(frame_host.did_notify_);
}
+// Tests that form.submit() cancels any navigations already sent to the browser
+// process.
+TEST_F(WebFrameTest, FormSubmitCancelsNavigation) {
+ frame_test_helpers::TestWebFrameClient web_frame_client;
+ frame_test_helpers::WebViewHelper web_view_helper;
+ web_view_helper.Initialize(&web_frame_client);
+ RegisterMockedHttpURLLoad("foo.html");
+ RegisterMockedHttpURLLoad("bar.html");
+ auto* main_frame = web_view_helper.GetWebView()->MainFrameImpl();
+ auto* local_frame = main_frame->GetFrame();
+ auto* document = local_frame->GetDocument();
+
+ document->documentElement()->setInnerHTML(
+ "<form id=formid action='http://internal.test/bar.html'></form>");
+ ASSERT_FALSE(local_frame->Loader().HasProvisionalNavigation());
+
+ FrameLoadRequest request(document,
+ ResourceRequest("http://internal.test/foo.html"));
+ local_frame->Navigate(request, WebFrameLoadType::kStandard);
+ ASSERT_TRUE(local_frame->Loader().HasProvisionalNavigation());
+
+ main_frame->ExecuteScript(WebScriptSource(WebString("formid.submit()")));
+ EXPECT_FALSE(local_frame->Loader().HasProvisionalNavigation());
+
+ RunPendingTasks();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/web_hit_test_result.cc b/chromium/third_party/blink/renderer/core/exported/web_hit_test_result.cc
index a5b6c36bab2..371f23473e6 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_hit_test_result.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_hit_test_result.cc
@@ -42,7 +42,7 @@ class WebHitTestResultPrivate final
WebHitTestResultPrivate(const HitTestResult&);
WebHitTestResultPrivate(const WebHitTestResultPrivate&);
- void Trace(Visitor* visitor) { visitor->Trace(result_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(result_); }
const HitTestResult& Result() const { return result_; }
private:
diff --git a/chromium/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc
index 93c945ace72..5b46ed3aaee 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc
@@ -33,7 +33,7 @@ WebInputMethodControllerImpl::WebInputMethodControllerImpl(
WebInputMethodControllerImpl::~WebInputMethodControllerImpl() = default;
-void WebInputMethodControllerImpl::Trace(Visitor* visitor) {
+void WebInputMethodControllerImpl::Trace(Visitor* visitor) const {
visitor->Trace(web_frame_);
}
@@ -41,9 +41,20 @@ bool WebInputMethodControllerImpl::IsEditContextActive() const {
return GetInputMethodController().GetActiveEditContext();
}
+ui::mojom::VirtualKeyboardVisibilityRequest
+WebInputMethodControllerImpl::GetLastVirtualKeyboardVisibilityRequest() const {
+ return GetInputMethodController().GetLastVirtualKeyboardVisibilityRequest();
+}
+
+void WebInputMethodControllerImpl::SetVirtualKeyboardVisibilityRequest(
+ ui::mojom::VirtualKeyboardVisibilityRequest vk_visibility_request) {
+ GetInputMethodController().SetVirtualKeyboardVisibilityRequest(
+ vk_visibility_request);
+}
+
bool WebInputMethodControllerImpl::SetComposition(
const WebString& text,
- const WebVector<WebImeTextSpan>& ime_text_spans,
+ const WebVector<ui::ImeTextSpan>& ime_text_spans,
const WebRange& replacement_range,
int selection_start,
int selection_end) {
@@ -124,7 +135,7 @@ bool WebInputMethodControllerImpl::FinishComposingText(
bool WebInputMethodControllerImpl::CommitText(
const WebString& text,
- const WebVector<WebImeTextSpan>& ime_text_spans,
+ const WebVector<ui::ImeTextSpan>& ime_text_spans,
const WebRange& replacement_range,
int relative_caret_position) {
LocalFrame::NotifyUserActivation(GetFrame());
@@ -179,11 +190,11 @@ void WebInputMethodControllerImpl::GetLayoutBounds(WebRect* control_bounds,
GetInputMethodController().GetLayoutBounds(control_bounds, selection_bounds);
}
-bool WebInputMethodControllerImpl::IsInputPanelPolicyManual() const {
+bool WebInputMethodControllerImpl::IsVirtualKeyboardPolicyManual() const {
if (IsEditContextActive()) {
return GetInputMethodController()
.GetActiveEditContext()
- ->IsInputPanelPolicyManual();
+ ->IsVirtualKeyboardPolicyManual();
}
return false; // Default should always be automatic.
}
diff --git a/chromium/third_party/blink/renderer/core/exported/web_input_method_controller_impl.h b/chromium/third_party/blink/renderer/core/exported/web_input_method_controller_impl.h
index afb2d962e6d..9d987fe745a 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_input_method_controller_impl.h
+++ b/chromium/third_party/blink/renderer/core/exported/web_input_method_controller_impl.h
@@ -6,12 +6,15 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_INPUT_METHOD_CONTROLLER_IMPL_H_
#include "base/macros.h"
-#include "third_party/blink/public/web/web_ime_text_span.h"
#include "third_party/blink/public/web/web_input_method_controller.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+namespace ui {
+struct ImeTextSpan;
+} // namespace ui
+
namespace blink {
class InputMethodController;
@@ -31,12 +34,12 @@ class CORE_EXPORT WebInputMethodControllerImpl
// WebInputMethodController overrides.
bool SetComposition(const WebString& text,
- const WebVector<WebImeTextSpan>& ime_text_spans,
+ const WebVector<ui::ImeTextSpan>& ime_text_spans,
const WebRange& replacement_range,
int selection_start,
int selection_end) override;
bool CommitText(const WebString& text,
- const WebVector<WebImeTextSpan>& ime_text_spans,
+ const WebVector<ui::ImeTextSpan>& ime_text_spans,
const WebRange& replacement_range,
int relative_caret_position) override;
bool FinishComposingText(
@@ -51,10 +54,15 @@ class CORE_EXPORT WebInputMethodControllerImpl
void GetLayoutBounds(WebRect* control_bounds,
WebRect* selection_bounds) override;
- bool IsInputPanelPolicyManual() const override;
+ bool IsVirtualKeyboardPolicyManual() const override;
bool IsEditContextActive() const override;
+ ui::mojom::VirtualKeyboardVisibilityRequest
+ GetLastVirtualKeyboardVisibilityRequest() const override;
+ void SetVirtualKeyboardVisibilityRequest(
+ ui::mojom::VirtualKeyboardVisibilityRequest vk_visibility_request)
+ override;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
LocalFrame* GetFrame() const;
diff --git a/chromium/third_party/blink/renderer/core/exported/web_navigation_params.cc b/chromium/third_party/blink/renderer/core/exported/web_navigation_params.cc
index b7b31685fa0..8d64cd995ab 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_navigation_params.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_navigation_params.cc
@@ -129,11 +129,12 @@ WebNavigationParams::PrefetchedSignedExchange::PrefetchedSignedExchange(
const WebString& header_integrity,
const WebURL& inner_url,
const WebURLResponse& inner_response,
- mojo::ScopedMessagePipeHandle loader_factory_handle)
+ CrossVariantMojoRemote<network::mojom::URLLoaderFactoryInterfaceBase>
+ loader_factory)
: outer_url(outer_url),
header_integrity(header_integrity),
inner_url(inner_url),
inner_response(inner_response),
- loader_factory_handle(std::move(loader_factory_handle)) {}
+ loader_factory(std::move(loader_factory)) {}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
index 2c6f9c8b977..efb3e76c258 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -34,6 +34,7 @@
#include "cc/animation/animation_host.h"
#include "cc/layers/picture_layer.h"
#include "cc/trees/ukm_manager.h"
+#include "third_party/blink/public/mojom/input/input_handler.mojom-blink.h"
#include "third_party/blink/public/platform/scheduler/web_render_widget_scheduling_state.h"
#include "third_party/blink/public/platform/web_float_rect.h"
#include "third_party/blink/public/web/web_view_client.h"
@@ -70,6 +71,7 @@
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
+#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/keyboard_codes.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/web_test_support.h"
@@ -216,20 +218,17 @@ class PagePopupChromeClient final : public EmptyChromeClient {
void SetToolTip(LocalFrame&,
const String& tooltip_text,
TextDirection dir) override {
- if (popup_->WidgetClient()) {
- popup_->WidgetClient()->SetToolTipText(tooltip_text,
- ToBaseTextDirection(dir));
- }
+ popup_->widget_base_->SetToolTipText(tooltip_text, dir);
}
void InjectGestureScrollEvent(LocalFrame& local_frame,
WebGestureDevice device,
const gfx::Vector2dF& delta,
- ScrollGranularity granularity,
+ ui::ScrollGranularity granularity,
cc::ElementId scrollable_area_element_id,
WebInputEvent::Type injected_type) override {
- popup_->WidgetClient()->InjectGestureScrollEvent(
- device, delta, granularity, scrollable_area_element_id, injected_type);
+ popup_->InjectGestureScrollEvent(device, delta, granularity,
+ scrollable_area_element_id, injected_type);
}
WebPagePopupImpl* popup_;
@@ -314,15 +313,37 @@ void WebPagePopupImpl::Initialize(WebViewImpl* web_view,
ProvideContextFeaturesTo(*page_, std::make_unique<PagePopupFeaturesClient>());
DEFINE_STATIC_LOCAL(Persistent<LocalFrameClient>, empty_local_frame_client,
(MakeGarbageCollected<EmptyLocalFrameClient>()));
+
// Creating new WindowAgentFactory because page popup content is owned by the
- // user agent and should be isolated from the main frame.
+ // user agent and should be isolated from the main frame. However, if we are a
+ // page popup in LayoutTests ensure we use the popup owner's frame for looking
+ // up the Agent so tests can possibly access the document via internals API.
+ WindowAgentFactory* window_agent_factory = nullptr;
+ if (WebTestSupport::IsRunningWebTest()) {
+ Document& owner_document = popup_client_->OwnerElement().GetDocument();
+ window_agent_factory = &owner_document.GetFrame()->window_agent_factory();
+ }
+
auto* frame = MakeGarbageCollected<LocalFrame>(
empty_local_frame_client, *page_,
/* FrameOwner* */ nullptr, base::UnguessableToken::Create(),
- /* WindowAgentFactory* */ nullptr,
+ window_agent_factory,
/* InterfaceRegistry* */ nullptr);
frame->SetPagePopupOwner(popup_client_->OwnerElement());
frame->SetView(MakeGarbageCollected<LocalFrameView>(*frame));
+
+ if (WebTestSupport::IsRunningWebTest()) {
+ // In order for the shared WindowAgentFactory for tests to work correctly,
+ // we need to also copy settings used in WindowAgent selection over to the
+ // popup frame.
+ Settings* owner_settings =
+ popup_client_->OwnerElement().GetDocument().GetFrame()->GetSettings();
+ frame->GetSettings()->SetWebSecurityEnabled(
+ owner_settings->GetWebSecurityEnabled());
+ frame->GetSettings()->SetAllowUniversalAccessFromFileURLs(
+ owner_settings->GetAllowUniversalAccessFromFileURLs());
+ }
+
frame->Init();
frame->View()->SetParentVisible(true);
frame->View()->SetSelfVisible(true);
@@ -368,6 +389,53 @@ void WebPagePopupImpl::SetCursor(const ui::Cursor& cursor) {
widget_base_->SetCursor(cursor);
}
+bool WebPagePopupImpl::HandlingInputEvent() {
+ return widget_base_->input_handler().handling_input_event();
+}
+
+void WebPagePopupImpl::SetHandlingInputEvent(bool handling) {
+ widget_base_->input_handler().set_handling_input_event(handling);
+}
+
+void WebPagePopupImpl::ProcessInputEventSynchronously(
+ const WebCoalescedInputEvent& event,
+ HandledEventCallback callback) {
+ widget_base_->input_handler().HandleInputEvent(event, std::move(callback));
+}
+
+void WebPagePopupImpl::UpdateTextInputState() {
+ widget_base_->UpdateTextInputState();
+}
+
+void WebPagePopupImpl::UpdateCompositionInfo() {
+ widget_base_->UpdateCompositionInfo(/*immediate_request=*/false);
+}
+
+void WebPagePopupImpl::UpdateSelectionBounds() {
+ widget_base_->UpdateSelectionBounds();
+}
+
+void WebPagePopupImpl::ShowVirtualKeyboard() {
+ widget_base_->ShowVirtualKeyboard();
+}
+
+void WebPagePopupImpl::ForceTextInputStateUpdate() {
+ widget_base_->ForceTextInputStateUpdate();
+}
+
+void WebPagePopupImpl::RequestCompositionUpdates(bool immediate_request,
+ bool monitor_updates) {
+ widget_base_->RequestCompositionUpdates(immediate_request, monitor_updates);
+}
+
+void WebPagePopupImpl::SetFocus(bool focus) {
+ widget_base_->SetFocus(focus);
+}
+
+bool WebPagePopupImpl::HasFocus() {
+ return widget_base_->has_focus();
+}
+
void WebPagePopupImpl::SetCompositorVisible(bool visible) {
widget_base_->SetCompositorVisible(visible);
}
@@ -413,6 +481,21 @@ AXObject* WebPagePopupImpl::RootAXObject() {
}
void WebPagePopupImpl::SetWindowRect(const IntRect& rect_in_screen) {
+ if (!closing_) {
+ IntRect owner_window_rect_in_screen = OwnerWindowRectInScreen();
+ Document& document = popup_client_->OwnerElement().GetDocument();
+ if (owner_window_rect_in_screen.Contains(rect_in_screen)) {
+ UseCounter::Count(document,
+ WebFeature::kPopupDoesNotExceedOwnerWindowBounds);
+ } else {
+ WebFeature feature =
+ document.GetFrame()->IsMainFrame()
+ ? WebFeature::kPopupExceedsOwnerWindowBounds
+ : WebFeature::kPopupExceedsOwnerWindowBoundsForIframe;
+ UseCounter::Count(document, feature);
+ }
+ }
+
WidgetClient()->SetWindowRect(rect_in_screen);
}
@@ -496,6 +579,45 @@ void WebPagePopupImpl::DispatchRafAlignedInput(base::TimeTicks frame_time) {
WidgetClient()->DispatchRafAlignedInput(frame_time);
}
+bool WebPagePopupImpl::WillHandleGestureEvent(const WebGestureEvent& event) {
+ return WidgetClient()->WillHandleGestureEvent(event);
+}
+
+bool WebPagePopupImpl::WillHandleMouseEvent(const WebMouseEvent& event) {
+ return WidgetClient()->WillHandleMouseEvent(event);
+}
+
+void WebPagePopupImpl::ObserveGestureEventAndResult(
+ const WebGestureEvent& gesture_event,
+ const gfx::Vector2dF& unused_delta,
+ const cc::OverscrollBehavior& overscroll_behavior,
+ bool event_processed) {
+ WidgetClient()->DidHandleGestureScrollEvent(
+ gesture_event, unused_delta, overscroll_behavior, event_processed);
+}
+
+void WebPagePopupImpl::QueueSyntheticEvent(
+ std::unique_ptr<blink::WebCoalescedInputEvent> event) {
+ WidgetClient()->QueueSyntheticEvent(std::move(event));
+}
+
+void WebPagePopupImpl::GetWidgetInputHandler(
+ mojo::PendingReceiver<mojom::blink::WidgetInputHandler> request,
+ mojo::PendingRemote<mojom::blink::WidgetInputHandlerHost> host) {
+ WidgetClient()->GetWidgetInputHandler(std::move(request), std::move(host));
+}
+
+bool WebPagePopupImpl::HasCurrentImeGuard(
+ bool request_to_show_virtual_keyboard) {
+ return WidgetClient()->HasCurrentImeGuard(request_to_show_virtual_keyboard);
+}
+
+void WebPagePopupImpl::SendCompositionRangeChanged(
+ const gfx::Range& range,
+ const std::vector<gfx::Rect>& character_bounds) {
+ WidgetClient()->SendCompositionRangeChanged(range, character_bounds);
+}
+
WebInputEventResult WebPagePopupImpl::HandleCharEvent(
const WebKeyboardEvent& event) {
if (suppress_next_keypress_event_) {
@@ -509,12 +631,16 @@ WebInputEventResult WebPagePopupImpl::HandleGestureEvent(
const WebGestureEvent& event) {
if (closing_)
return WebInputEventResult::kNotHandled;
- if ((event.GetType() == WebInputEvent::Type::kGestureTap ||
- event.GetType() == WebInputEvent::Type::kGestureTapDown) &&
- !IsViewportPointInWindow(event.PositionInWidget().x(),
- event.PositionInWidget().y())) {
- Cancel();
- return WebInputEventResult::kNotHandled;
+ if (event.GetType() == WebInputEvent::Type::kGestureTap ||
+ event.GetType() == WebInputEvent::Type::kGestureTapDown) {
+ if (!IsViewportPointInWindow(event.PositionInWidget().x(),
+ event.PositionInWidget().y())) {
+ Cancel();
+ return WebInputEventResult::kNotHandled;
+ }
+ CheckScreenPointInOwnerWindowAndCount(
+ event.PositionInScreen(),
+ WebFeature::kPopupGestureTapExceedsOwnerWindowBounds);
}
WebGestureEvent scaled_event =
TransformWebGestureEvent(MainFrame().View(), event);
@@ -524,18 +650,26 @@ WebInputEventResult WebPagePopupImpl::HandleGestureEvent(
void WebPagePopupImpl::HandleMouseDown(LocalFrame& main_frame,
const WebMouseEvent& event) {
if (IsViewportPointInWindow(event.PositionInWidget().x(),
- event.PositionInWidget().y()))
+ event.PositionInWidget().y())) {
+ CheckScreenPointInOwnerWindowAndCount(
+ event.PositionInScreen(),
+ WebFeature::kPopupMouseDownExceedsOwnerWindowBounds);
PageWidgetEventHandler::HandleMouseDown(main_frame, event);
- else
+ } else {
Cancel();
+ }
}
WebInputEventResult WebPagePopupImpl::HandleMouseWheel(
LocalFrame& main_frame,
const WebMouseWheelEvent& event) {
if (IsViewportPointInWindow(event.PositionInWidget().x(),
- event.PositionInWidget().y()))
+ event.PositionInWidget().y())) {
+ CheckScreenPointInOwnerWindowAndCount(
+ event.PositionInScreen(),
+ WebFeature::kPopupMouseWheelExceedsOwnerWindowBounds);
return PageWidgetEventHandler::HandleMouseWheel(main_frame, event);
+ }
Cancel();
return WebInputEventResult::kNotHandled;
}
@@ -569,6 +703,23 @@ bool WebPagePopupImpl::IsViewportPointInWindow(int x, int y) {
.Contains(IntPoint(point_in_window.x, point_in_window.y));
}
+void WebPagePopupImpl::CheckScreenPointInOwnerWindowAndCount(
+ const gfx::PointF& point_in_screen,
+ WebFeature feature) const {
+ if (closing_)
+ return;
+
+ IntRect owner_window_rect = OwnerWindowRectInScreen();
+ if (!owner_window_rect.Contains(point_in_screen.x(), point_in_screen.y()))
+ UseCounter::Count(popup_client_->OwnerElement().GetDocument(), feature);
+}
+
+IntRect WebPagePopupImpl::OwnerWindowRectInScreen() const {
+ LocalFrameView* view = popup_client_->OwnerElement().GetDocument().View();
+ IntRect frame_rect = view->FrameRect();
+ return view->FrameToScreen(frame_rect);
+}
+
WebInputEventResult WebPagePopupImpl::DispatchBufferedTouchEvents() {
if (closing_)
return WebInputEventResult::kNotHandled;
@@ -583,12 +734,13 @@ WebInputEventResult WebPagePopupImpl::HandleInputEvent(
return PageWidgetDelegate::HandleInputEvent(*this, event, &MainFrame());
}
-void WebPagePopupImpl::SetFocus(bool enable) {
+void WebPagePopupImpl::FocusChanged(bool enable) {
if (!page_)
return;
if (enable)
page_->GetFocusController().SetActive(true);
page_->GetFocusController().SetFocused(enable);
+ WidgetClient()->FocusChanged(enable);
}
WebURL WebPagePopupImpl::GetURLForDebugTrace() {
@@ -657,7 +809,7 @@ void WebPagePopupImpl::ClosePopup() {
// because web authors can't listen the events.
EventDispatchForbiddenScope::AllowUserAgentEvents allow_events;
- MainFrame().Loader().StopAllLoaders();
+ MainFrame().Loader().StopAllLoaders(/*abort_client=*/true);
PagePopupController::From(*page_)->ClearPagePopupClient();
DestroyPage();
}
@@ -701,6 +853,16 @@ WebRect WebPagePopupImpl::WindowRectInScreen() const {
return WidgetClient()->WindowRect();
}
+void WebPagePopupImpl::InjectGestureScrollEvent(
+ WebGestureDevice device,
+ const gfx::Vector2dF& delta,
+ ScrollGranularity granularity,
+ cc::ElementId scrollable_area_element_id,
+ WebInputEvent::Type injected_type) {
+ widget_base_->input_handler().InjectGestureScrollEvent(
+ device, delta, granularity, scrollable_area_element_id, injected_type);
+}
+
// WebPagePopup ----------------------------------------------------------------
WebPagePopup* WebPagePopup::Create(
diff --git a/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.h b/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.h
index 723cb08faba..1c33fbff637 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.h
+++ b/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.h
@@ -36,6 +36,7 @@
#include "third_party/blink/public/platform/cross_variant_mojo_util.h"
#include "third_party/blink/public/web/web_page_popup.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/frame/web_feature_forward.h"
#include "third_party/blink/renderer/core/page/page_popup.h"
#include "third_party/blink/renderer/core/page/page_widget_delegate.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
@@ -120,6 +121,24 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup,
void RecordTimeToFirstActivePaint(base::TimeDelta duration) override;
void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final;
WebInputEventResult DispatchBufferedTouchEvents() override;
+ bool WillHandleGestureEvent(const WebGestureEvent& event) override;
+ bool WillHandleMouseEvent(const WebMouseEvent& event) override;
+ void ObserveGestureEventAndResult(
+ const WebGestureEvent& gesture_event,
+ const gfx::Vector2dF& unused_delta,
+ const cc::OverscrollBehavior& overscroll_behavior,
+ bool event_processed) override;
+ bool SupportsBufferedTouchEvents() override { return true; }
+ void QueueSyntheticEvent(
+ std::unique_ptr<blink::WebCoalescedInputEvent>) override;
+ void GetWidgetInputHandler(
+ mojo::PendingReceiver<mojom::blink::WidgetInputHandler> request,
+ mojo::PendingRemote<mojom::blink::WidgetInputHandlerHost> host) override;
+ bool HasCurrentImeGuard(bool request_to_show_virtual_keyboard) override;
+ void SendCompositionRangeChanged(
+ const gfx::Range& range,
+ const std::vector<gfx::Rect>& character_bounds) override;
+ void FocusChanged(bool enabled) override;
// WebWidget implementation.
// NOTE: The WebWidget may still be used after requesting the popup to be
@@ -135,6 +154,7 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup,
base::OnceCallback<void()> cleanup_task) override;
WebInputEventResult HandleInputEvent(const WebCoalescedInputEvent&) override;
void SetFocus(bool) override;
+ bool HasFocus() override;
WebURL GetURLForDebugTrace() override;
WebHitTestResult HitTestResultAt(const gfx::PointF&) override { return {}; }
cc::LayerTreeHost* InitializeCompositing(
@@ -144,6 +164,17 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup,
scheduler::WebRenderWidgetSchedulingState* RendererWidgetSchedulingState()
override;
void SetCursor(const ui::Cursor& cursor) override;
+ bool HandlingInputEvent() override;
+ void SetHandlingInputEvent(bool handling) override;
+ void ProcessInputEventSynchronously(const WebCoalescedInputEvent&,
+ HandledEventCallback) override;
+ void UpdateTextInputState() override;
+ void ForceTextInputStateUpdate() override;
+ void UpdateCompositionInfo() override;
+ void UpdateSelectionBounds() override;
+ void ShowVirtualKeyboard() override;
+ void RequestCompositionUpdates(bool immediate_request,
+ bool monitor_updates) override;
// PageWidgetEventHandler functions
WebInputEventResult HandleCharEvent(const WebKeyboardEvent&) override;
@@ -158,6 +189,9 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup,
Element* FocusedElement() const;
bool IsViewportPointInWindow(int x, int y);
+ void CheckScreenPointInOwnerWindowAndCount(const gfx::PointF& point_in_screen,
+ WebFeature feature) const;
+ IntRect OwnerWindowRectInScreen() const;
// PagePopup function
AXObject* RootAXObject() override;
@@ -174,6 +208,12 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup,
WebRect WindowRectInScreen() const;
+ void InjectGestureScrollEvent(WebGestureDevice device,
+ const gfx::Vector2dF& delta,
+ ui::ScrollGranularity granularity,
+ cc::ElementId scrollable_area_element_id,
+ WebInputEvent::Type injected_type);
+
WebPagePopupClient* web_page_popup_client_;
WebViewImpl* web_view_;
// WebPagePopupImpl wraps its own Page that renders the content in the popup.
diff --git a/chromium/third_party/blink/renderer/core/exported/web_performance.cc b/chromium/third_party/blink/renderer/core/exported/web_performance.cc
index e29242e7423..03e5fcc3196 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_performance.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_performance.cc
@@ -69,6 +69,22 @@ base::TimeTicks WebPerformance::NavigationStartAsMonotonicTime() const {
return private_->timing()->NavigationStartAsMonotonicTime();
}
+WebPerformance::BackForwardCacheRestoreTimings
+WebPerformance::BackForwardCacheRestore() const {
+ PerformanceTiming::BackForwardCacheRestoreTimings restore_timings =
+ private_->timing()->BackForwardCacheRestore();
+
+ WebVector<BackForwardCacheRestoreTiming> timings(restore_timings.size());
+ for (size_t i = 0; i < restore_timings.size(); i++) {
+ timings[i].navigation_start =
+ MillisecondsToSeconds(restore_timings[i].navigation_start);
+ timings[i].first_paint =
+ MillisecondsToSeconds(restore_timings[i].first_paint);
+ timings[i].first_input_delay = restore_timings[i].first_input_delay;
+ }
+ return timings;
+}
+
double WebPerformance::InputForNavigationStart() const {
return MillisecondsToSeconds(private_->timing()->inputStart());
}
@@ -191,6 +207,28 @@ uint64_t WebPerformance::LargestTextPaintSize() const {
return private_->timing()->LargestTextPaintSize();
}
+double WebPerformance::ExperimentalLargestImagePaint() const {
+ return MillisecondsToSeconds(
+ private_->timing()->ExperimentalLargestImagePaint());
+}
+
+uint64_t WebPerformance::ExperimentalLargestImagePaintSize() const {
+ return private_->timing()->ExperimentalLargestImagePaintSize();
+}
+
+double WebPerformance::ExperimentalLargestTextPaint() const {
+ return MillisecondsToSeconds(
+ private_->timing()->ExperimentalLargestTextPaint());
+}
+
+uint64_t WebPerformance::ExperimentalLargestTextPaintSize() const {
+ return private_->timing()->ExperimentalLargestTextPaintSize();
+}
+
+double WebPerformance::FirstEligibleToPaint() const {
+ return MillisecondsToSeconds(private_->timing()->FirstEligibleToPaint());
+}
+
double WebPerformance::FirstInputOrScrollNotifiedTimestamp() const {
return MillisecondsToSeconds(
private_->timing()->FirstInputOrScrollNotifiedTimestamp());
@@ -212,6 +250,19 @@ base::Optional<base::TimeDelta> WebPerformance::LongestInputTimestamp() const {
return private_->timing()->LongestInputTimestamp();
}
+base::Optional<base::TimeDelta> WebPerformance::FirstInputProcessingTime()
+ const {
+ return private_->timing()->FirstInputProcessingTime();
+}
+
+base::Optional<base::TimeDelta> WebPerformance::FirstScrollDelay() const {
+ return private_->timing()->FirstScrollDelay();
+}
+
+base::Optional<base::TimeDelta> WebPerformance::FirstScrollTimestamp() const {
+ return private_->timing()->FirstScrollTimestamp();
+}
+
double WebPerformance::ParseStart() const {
return MillisecondsToSeconds(private_->timing()->ParseStart());
}
@@ -243,6 +294,11 @@ double WebPerformance::ParseBlockedOnScriptExecutionFromDocumentWriteDuration()
->ParseBlockedOnScriptExecutionFromDocumentWriteDuration());
}
+base::Optional<base::TimeTicks> WebPerformance::LastPortalActivatedPaint()
+ const {
+ return private_->timing()->LastPortalActivatedPaint();
+}
+
WebPerformance::WebPerformance(WindowPerformance* performance)
: private_(performance) {}
diff --git a/chromium/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
index 27ea627f185..146d8228c4b 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -490,14 +490,12 @@ void WebPluginContainerImpl::ReportGeometry() {
}
v8::Local<v8::Object> WebPluginContainerImpl::V8ObjectForElement() {
- LocalFrame* frame = element_->GetDocument().GetFrame();
- if (!frame)
- return v8::Local<v8::Object>();
-
- if (!element_->GetDocument().CanExecuteScripts(kNotAboutToExecuteScript))
+ ExecutionContext* context = element_->GetExecutionContext();
+ if (!context || !context->CanExecuteScripts(kNotAboutToExecuteScript))
return v8::Local<v8::Object>();
- ScriptState* script_state = ToScriptStateForMainWorld(frame);
+ ScriptState* script_state =
+ ToScriptState(context, DOMWrapperWorld::MainWorld());
if (!script_state)
return v8::Local<v8::Object>();
@@ -795,7 +793,7 @@ void WebPluginContainerImpl::SetFrameRect(const IntRect& rect) {
PropagateFrameRects();
}
-void WebPluginContainerImpl::Trace(Visitor* visitor) {
+void WebPluginContainerImpl::Trace(Visitor* visitor) const {
visitor->Trace(element_);
ExecutionContextClient::Trace(visitor);
}
@@ -892,12 +890,6 @@ void WebPluginContainerImpl::HandleKeyboardEvent(KeyboardEvent& event) {
return;
}
- // Give the client a chance to issue edit comamnds.
- WebLocalFrameImpl* web_frame =
- WebLocalFrameImpl::FromFrame(element_->GetDocument().GetFrame());
- if (web_plugin_->SupportsEditCommands())
- web_frame->Client()->HandleCurrentKeyboardEvent();
-
ui::Cursor dummy_cursor;
if (web_plugin_->HandleInputEvent(
WebCoalescedInputEvent(web_event, ui::LatencyInfo()),
diff --git a/chromium/third_party/blink/renderer/core/exported/web_plugin_container_impl.h b/chromium/third_party/blink/renderer/core/exported/web_plugin_container_impl.h
index 8ef5dc8600d..91781374384 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_plugin_container_impl.h
+++ b/chromium/third_party/blink/renderer/core/exported/web_plugin_container_impl.h
@@ -186,7 +186,7 @@ class CORE_EXPORT WebPluginContainerImpl final
void DidFinishLoading();
void DidFailLoading(const ResourceError&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// USING_PRE_FINALIZER does not allow for virtual dispatch from the finalizer
// method. Here we call Dispose() which does the correct virtual dispatch.
void PreFinalize() { Dispose(); }
diff --git a/chromium/third_party/blink/renderer/core/exported/web_plugin_container_test.cc b/chromium/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
index 9fe809420be..871bb4a6454 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
@@ -1465,7 +1465,8 @@ TEST_F(WebPluginContainerTest, CompositedPluginCAP) {
const auto* plugin =
static_cast<const CompositedPlugin*>(container->Plugin());
- auto paint_controller = std::make_unique<PaintController>();
+ auto paint_controller =
+ std::make_unique<PaintController>(PaintController::kTransient);
paint_controller->UpdateCurrentPaintChunkProperties(
nullptr, PropertyTreeState::Root());
GraphicsContext graphics_context(*paint_controller);
diff --git a/chromium/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
index 733203da2de..053daa4b95d 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
@@ -78,6 +78,7 @@ WebRemoteFrame* WebRemoteFrame::CreateForPortal(
frame_token, portal_element);
}
+// static
WebRemoteFrameImpl* WebRemoteFrameImpl::CreateMainFrame(
WebView* web_view,
WebRemoteFrameClient* client,
@@ -117,7 +118,8 @@ WebRemoteFrameImpl* WebRemoteFrameImpl::CreateForPortal(
Element* element = portal_element;
DCHECK(element->HasTagName(html_names::kPortalTag));
- DCHECK(RuntimeEnabledFeatures::PortalsEnabled(&element->GetDocument()));
+ DCHECK(
+ RuntimeEnabledFeatures::PortalsEnabled(element->GetExecutionContext()));
HTMLPortalElement* portal = static_cast<HTMLPortalElement*>(element);
LocalFrame* host_frame = portal->GetDocument().GetFrame();
frame->InitializeCoreFrame(*host_frame->GetPage(), portal, g_null_atom,
@@ -128,7 +130,7 @@ WebRemoteFrameImpl* WebRemoteFrameImpl::CreateForPortal(
WebRemoteFrameImpl::~WebRemoteFrameImpl() = default;
-void WebRemoteFrameImpl::Trace(Visitor* visitor) {
+void WebRemoteFrameImpl::Trace(Visitor* visitor) const {
visitor->Trace(frame_client_);
visitor->Trace(frame_);
WebFrame::TraceFrames(visitor, this);
@@ -329,12 +331,6 @@ void WebRemoteFrameImpl::UpdateUserActivationState(
GetFrame()->UpdateUserActivationState(update_type);
}
-void WebRemoteFrameImpl::TransferUserActivationFrom(
- blink::WebRemoteFrame* source_frame) {
- GetFrame()->TransferUserActivationFrom(
- To<WebRemoteFrameImpl>(source_frame)->GetFrame());
-}
-
void WebRemoteFrameImpl::SetHadStickyUserActivationBeforeNavigation(
bool value) {
GetFrame()->SetHadStickyUserActivationBeforeNavigation(value);
diff --git a/chromium/third_party/blink/renderer/core/exported/web_remote_frame_impl.h b/chromium/third_party/blink/renderer/core/exported/web_remote_frame_impl.h
index e4ad3dd92ca..e58c2ab9948 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_remote_frame_impl.h
+++ b/chromium/third_party/blink/renderer/core/exported/web_remote_frame_impl.h
@@ -105,7 +105,6 @@ class CORE_EXPORT WebRemoteFrameImpl final
bool IsIgnoredForHitTest() const override;
void UpdateUserActivationState(
mojom::blink::UserActivationUpdateType) override;
- void TransferUserActivationFrom(blink::WebRemoteFrame* source_frame) override;
void SetHadStickyUserActivationBeforeNavigation(bool value) override;
v8::Local<v8::Object> GlobalProxy() const override;
WebRect GetCompositingRect() override;
@@ -120,7 +119,7 @@ class CORE_EXPORT WebRemoteFrameImpl final
static WebRemoteFrameImpl* FromFrame(RemoteFrame&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
friend class RemoteFrameClientImpl;
diff --git a/chromium/third_party/blink/renderer/core/exported/web_savable_resources_test_support.cc b/chromium/third_party/blink/renderer/core/exported/web_savable_resources_test_support.cc
new file mode 100644
index 00000000000..dfc5be299f1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/exported/web_savable_resources_test_support.cc
@@ -0,0 +1,19 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/public/web/web_savable_resources_test_support.h"
+
+#include "third_party/blink/public/mojom/frame/frame.mojom-blink.h"
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/web_element.h"
+#include "third_party/blink/renderer/core/frame/savable_resources.h"
+
+namespace blink {
+
+WebString GetSubResourceLinkFromElementForTesting(const WebElement& element) {
+ return WebString(SavableResources::GetSubResourceLinkFromElement(
+ static_cast<Element*>(element)));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/web_settings_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_settings_impl.cc
index f11e51633f3..ed851b476b2 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_settings_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_settings_impl.cc
@@ -588,10 +588,6 @@ bool WebSettingsImpl::ShrinksViewportContentToFit() const {
return settings_->GetShrinksViewportContentToFit();
}
-void WebSettingsImpl::SetShouldRespectImageOrientation(bool enabled) {
- settings_->SetShouldRespectImageOrientation(enabled);
-}
-
void WebSettingsImpl::SetPictureInPictureEnabled(bool enabled) {
settings_->SetPictureInPictureEnabled(enabled);
}
@@ -784,6 +780,10 @@ void WebSettingsImpl::SetNavigationControls(
settings_->SetNavigationControls(navigation_controls);
}
+void WebSettingsImpl::SetAriaModalPrunesAXTree(bool enabled) {
+ settings_->SetAriaModalPrunesAXTree(enabled);
+}
+
STATIC_ASSERT_ENUM(WebSettings::ImageAnimationPolicy::kAllowed,
kImageAnimationPolicyAllowed);
STATIC_ASSERT_ENUM(WebSettings::ImageAnimationPolicy::kAnimateOnce,
diff --git a/chromium/third_party/blink/renderer/core/exported/web_settings_impl.h b/chromium/third_party/blink/renderer/core/exported/web_settings_impl.h
index c3f38e93e45..2c94bd8a360 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_settings_impl.h
+++ b/chromium/third_party/blink/renderer/core/exported/web_settings_impl.h
@@ -146,7 +146,6 @@ class CORE_EXPORT WebSettingsImpl final : public WebSettings {
UScriptCode = USCRIPT_COMMON) override;
void SetShouldPrintBackgrounds(bool) override;
void SetShouldClearDocumentBackground(bool) override;
- void SetShouldRespectImageOrientation(bool) override;
void SetShowContextMenuOnMouseUp(bool) override;
void SetShrinksViewportContentToFit(bool) override;
void SetSmartInsertDeleteEnabled(bool) override;
@@ -224,6 +223,8 @@ class CORE_EXPORT WebSettingsImpl final : public WebSettings {
void SetPreferredColorScheme(PreferredColorScheme) override;
void SetNavigationControls(NavigationControls) override;
+ void SetAriaModalPrunesAXTree(bool) override;
+
bool RenderVSyncNotificationEnabled() const {
return render_v_sync_notification_enabled_;
}
diff --git a/chromium/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc
index 9942e60d41f..dbd47258fc9 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc
@@ -31,6 +31,8 @@
#include "third_party/blink/renderer/core/exported/web_shared_worker_impl.h"
#include <memory>
+#include <utility>
+
#include "base/memory/ptr_util.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/network/public/mojom/fetch_api.mojom-shared.h"
@@ -39,7 +41,6 @@
#include "third_party/blink/public/mojom/loader/fetch_client_settings_object.mojom-blink.h"
#include "third_party/blink/public/mojom/script/script_type.mojom-blink.h"
#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
-#include "third_party/blink/public/mojom/worker/worker_content_settings_proxy.mojom-blink.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
@@ -175,8 +176,10 @@ void WebSharedWorkerImpl::StartWorkerContext(
const WebFetchClientSettingsObject& outside_fetch_client_settings_object,
const base::UnguessableToken& appcache_host_id,
const base::UnguessableToken& devtools_worker_token,
- mojo::ScopedMessagePipeHandle content_settings_handle,
- mojo::ScopedMessagePipeHandle browser_interface_broker,
+ CrossVariantMojoRemote<
+ mojom::blink::WorkerContentSettingsProxyInterfaceBase> content_settings,
+ CrossVariantMojoRemote<mojom::blink::BrowserInterfaceBrokerInterfaceBase>
+ browser_interface_broker,
bool pause_worker_context_on_start) {
DCHECK(IsMainThread());
CHECK(constructor_origin.Get()->CanAccessSharedWorkers());
@@ -233,17 +236,13 @@ void WebSharedWorkerImpl::StartWorkerContext(
outside_settings_object->GetHttpsState(),
MakeGarbageCollected<WorkerClients>(),
std::make_unique<SharedWorkerContentSettingsProxy>(
- mojo::PendingRemote<mojom::blink::WorkerContentSettingsProxy>(
- std::move(content_settings_handle), 0u)),
+ std::move(content_settings)),
base::nullopt /* response_address_space */,
nullptr /* origin_trial_tokens */, devtools_worker_token,
std::move(worker_settings), kV8CacheOptionsDefault,
nullptr /* worklet_module_response_map */,
- mojo::PendingRemote<mojom::blink::BrowserInterfaceBroker>(
- std::move(browser_interface_broker),
- mojom::blink::BrowserInterfaceBroker::Version_),
- BeginFrameProviderParams(), nullptr /* parent_feature_policy */,
- base::UnguessableToken());
+ std::move(browser_interface_broker), BeginFrameProviderParams(),
+ nullptr /* parent_feature_policy */, base::UnguessableToken());
reporting_proxy_ = MakeGarbageCollected<SharedWorkerReportingProxy>(
this, ParentExecutionContextTaskRunners::Create());
@@ -293,8 +292,8 @@ void WebSharedWorkerImpl::StartWorkerContext(
}
// We are now ready to inspect worker thread.
- client_->WorkerReadyForInspection(devtools_agent_remote.PassPipe(),
- devtools_agent_host_receiver.PassPipe());
+ client_->WorkerReadyForInspection(std::move(devtools_agent_remote),
+ std::move(devtools_agent_host_receiver));
}
void WebSharedWorkerImpl::TerminateWorkerContext() {
diff --git a/chromium/third_party/blink/renderer/core/exported/web_shared_worker_impl.h b/chromium/third_party/blink/renderer/core/exported/web_shared_worker_impl.h
index 98374fb9031..2a9de264ba1 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_shared_worker_impl.h
+++ b/chromium/third_party/blink/renderer/core/exported/web_shared_worker_impl.h
@@ -40,8 +40,10 @@
#include "services/network/public/mojom/content_security_policy.mojom-blink-forward.h"
#include "services/network/public/mojom/fetch_api.mojom-shared.h"
#include "services/network/public/mojom/ip_address_space.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/browser_interface_broker.mojom-blink.h"
#include "third_party/blink/public/mojom/script/script_type.mojom-blink.h"
#include "third_party/blink/public/mojom/user_agent/user_agent_metadata.mojom-blink.h"
+#include "third_party/blink/public/mojom/worker/worker_content_settings_proxy.mojom-blink.h"
#include "third_party/blink/public/platform/web_fetch_client_settings_object.h"
#include "third_party/blink/public/web/web_shared_worker_client.h"
#include "third_party/blink/renderer/core/core_export.h"
@@ -84,8 +86,11 @@ class CORE_EXPORT WebSharedWorkerImpl final : public WebSharedWorker {
const WebFetchClientSettingsObject& outside_fetch_client_settings_object,
const base::UnguessableToken& appcache_host_id,
const base::UnguessableToken& devtools_worker_token,
- mojo::ScopedMessagePipeHandle content_settings_handle,
- mojo::ScopedMessagePipeHandle browser_interface_broker,
+ CrossVariantMojoRemote<
+ mojom::blink::WorkerContentSettingsProxyInterfaceBase>
+ ontent_settings,
+ CrossVariantMojoRemote<mojom::blink::BrowserInterfaceBrokerInterfaceBase>
+ browser_interface_broker,
bool pause_worker_context_on_start) override;
void Connect(MessagePortChannel) override;
void TerminateWorkerContext() override;
diff --git a/chromium/third_party/blink/renderer/core/exported/web_view_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_view_impl.cc
index ebebe2f3b21..27adaed62fe 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -140,6 +140,7 @@
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
#include "third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
+#include "third_party/blink/renderer/core/paint/paint_timing.h"
#include "third_party/blink/renderer/core/paint/paint_timing_detector.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
@@ -489,7 +490,7 @@ WebInputEventResult WebViewImpl::HandleGestureEvent(
}
}
event_result = WebInputEventResult::kHandledSystem;
- MainFrameImpl()->FrameWidgetImpl()->Client()->DidHandleGestureEvent(
+ MainFrameImpl()->FrameWidgetImpl()->DidHandleGestureEvent(
event, event_cancelled);
return event_result;
case WebInputEvent::Type::kGestureScrollBegin:
@@ -504,7 +505,7 @@ WebInputEventResult WebViewImpl::HandleGestureEvent(
->GetFrame()
->GetEventHandler()
.HandleGestureScrollEvent(scaled_event);
- MainFrameImpl()->FrameWidgetImpl()->Client()->DidHandleGestureEvent(
+ MainFrameImpl()->FrameWidgetImpl()->DidHandleGestureEvent(
event, event_cancelled);
return event_result;
default:
@@ -617,8 +618,8 @@ WebInputEventResult WebViewImpl::HandleGestureEvent(
}
default: { NOTREACHED(); }
}
- MainFrameImpl()->FrameWidgetImpl()->Client()->DidHandleGestureEvent(
- event, event_cancelled);
+ MainFrameImpl()->FrameWidgetImpl()->DidHandleGestureEvent(event,
+ event_cancelled);
return event_result;
}
@@ -1592,27 +1593,27 @@ void WebViewImpl::UpdateLifecycle(WebLifecycleUpdate requested_update,
if (LocalFrameView* view = MainFrameImpl()->GetFrameView()) {
LocalFrame* frame = MainFrameImpl()->GetFrame();
- WebWidgetClient* client =
- WebLocalFrameImpl::FromFrame(frame)->FrameWidgetImpl()->Client();
+ WebFrameWidgetBase* frame_widget =
+ WebLocalFrameImpl::FromFrame(frame)->LocalRootFrameWidget();
if (should_dispatch_first_visually_non_empty_layout_ &&
view->IsVisuallyNonEmpty()) {
should_dispatch_first_visually_non_empty_layout_ = false;
// TODO(esprehn): Move users of this callback to something
// better, the heuristic for "visually non-empty" is bad.
- client->DidMeaningfulLayout(WebMeaningfulLayout::kVisuallyNonEmpty);
+ frame_widget->DidMeaningfulLayout(WebMeaningfulLayout::kVisuallyNonEmpty);
}
if (should_dispatch_first_layout_after_finished_parsing_ &&
frame->GetDocument()->HasFinishedParsing()) {
should_dispatch_first_layout_after_finished_parsing_ = false;
- client->DidMeaningfulLayout(WebMeaningfulLayout::kFinishedParsing);
+ frame_widget->DidMeaningfulLayout(WebMeaningfulLayout::kFinishedParsing);
}
if (should_dispatch_first_layout_after_finished_loading_ &&
frame->GetDocument()->IsLoadCompleted()) {
should_dispatch_first_layout_after_finished_loading_ = false;
- client->DidMeaningfulLayout(WebMeaningfulLayout::kFinishedLoading);
+ frame_widget->DidMeaningfulLayout(WebMeaningfulLayout::kFinishedLoading);
}
}
}
@@ -1937,26 +1938,6 @@ bool WebViewImpl::SelectionBounds(WebRect& anchor_web,
return true;
}
-void WebViewImpl::DidAcquirePointerLock() {
- if (MainFrameImpl())
- MainFrameImpl()->FrameWidget()->DidAcquirePointerLock();
-}
-
-void WebViewImpl::DidNotAcquirePointerLock() {
- if (MainFrameImpl())
- MainFrameImpl()->FrameWidget()->DidNotAcquirePointerLock();
-}
-
-void WebViewImpl::DidLosePointerLock() {
- // Make sure that the main frame wasn't swapped-out when the pointer lock is
- // lost. There's a race that can happen when a pointer lock is requested, but
- // the browser swaps out the main frame while the pointer lock request is in
- // progress. This won't be needed once the main frame is refactored to not use
- // the WebViewImpl as its WebWidget.
- if (MainFrameImpl())
- MainFrameImpl()->FrameWidget()->DidLosePointerLock();
-}
-
// WebView --------------------------------------------------------------------
WebSettingsImpl* WebViewImpl::SettingsImpl() {
@@ -2024,6 +2005,16 @@ void WebViewImpl::DidAttachLocalMainFrame() {
}
}
+void WebViewImpl::DidAttachRemoteMainFrame() {
+ DCHECK(!MainFrameImpl());
+
+ RemoteFrame* remote_frame = DynamicTo<RemoteFrame>(GetPage()->MainFrame());
+ DCHECK(remote_frame);
+
+ remote_frame->GetRemoteAssociatedInterfaces()->GetInterface(
+ remote_main_frame_host_remote_.BindNewEndpointAndPassReceiver());
+}
+
void WebViewImpl::DidDetachLocalMainFrame() {
// The WebWidgetClient that generated the |scoped_defer_main_frame_update_|
// for a local main frame is going away.
@@ -2031,6 +2022,10 @@ void WebViewImpl::DidDetachLocalMainFrame() {
local_main_frame_host_remote_.reset();
}
+void WebViewImpl::DidDetachRemoteMainFrame() {
+ remote_main_frame_host_remote_.reset();
+}
+
WebLocalFrame* WebViewImpl::FocusedFrame() {
Frame* frame = FocusedCoreFrame();
// TODO(yabinh): focusedCoreFrame() should always return a local frame, and
@@ -2323,20 +2318,6 @@ double WebViewImpl::SetZoomLevel(double zoom_level) {
return zoom_level_;
}
-float WebViewImpl::TextZoomFactor() {
- return MainFrameImpl()->GetFrame()->TextZoomFactor();
-}
-
-float WebViewImpl::SetTextZoomFactor(float text_zoom_factor) {
- LocalFrame* frame = MainFrameImpl()->GetFrame();
- if (frame->GetWebPluginContainer())
- return 1;
-
- frame->SetTextZoomFactor(text_zoom_factor);
-
- return text_zoom_factor;
-}
-
float WebViewImpl::PageScaleFactor() const {
if (!GetPage())
return 1;
@@ -2402,16 +2383,45 @@ void WebViewImpl::SetZoomFactorForDeviceScaleFactor(
void WebViewImpl::SetPageLifecycleState(
mojom::blink::PageLifecycleStatePtr state,
+ base::Optional<base::TimeTicks> navigation_start,
SetPageLifecycleStateCallback callback) {
Page* page = GetPage();
if (!page)
return;
- if (state->visibility != lifecycle_state_->visibility) {
- SetVisibilityState(state->visibility, /*is_initial_state =*/false);
- }
- if (state->is_frozen != lifecycle_state_->is_frozen) {
- Scheduler()->SetPageFrozen(state->is_frozen);
+ bool storing_in_bfcache = state->is_in_back_forward_cache &&
+ !lifecycle_state_->is_in_back_forward_cache;
+ bool restoring_from_bfcache = !state->is_in_back_forward_cache &&
+ lifecycle_state_->is_in_back_forward_cache;
+ bool hiding_page =
+ (state->visibility != mojom::blink::PageVisibilityState::kVisible) &&
+ (lifecycle_state_->visibility ==
+ mojom::blink::PageVisibilityState::kVisible);
+ bool showing_page =
+ (state->visibility == mojom::blink::PageVisibilityState::kVisible) &&
+ (lifecycle_state_->visibility !=
+ mojom::blink::PageVisibilityState::kVisible);
+ bool freezing_page = state->is_frozen && !lifecycle_state_->is_frozen;
+ bool resuming_page = !state->is_frozen && lifecycle_state_->is_frozen;
+
+ if (hiding_page) {
+ SetVisibilityState(state->visibility, /*is_initial_state=*/false);
+ }
+ if (storing_in_bfcache)
+ DispatchPagehide();
+ if (freezing_page)
+ Scheduler()->SetPageFrozen(true);
+ if (storing_in_bfcache)
+ HookBackForwardCacheEviction(true);
+ if (restoring_from_bfcache)
+ HookBackForwardCacheEviction(false);
+ if (resuming_page)
+ Scheduler()->SetPageFrozen(false);
+ if (restoring_from_bfcache)
+ DispatchPageshow(navigation_start.value());
+ if (showing_page) {
+ SetVisibilityState(mojom::blink::PageVisibilityState::kVisible,
+ /*is_initial_state=*/false);
}
lifecycle_state_ = std::move(state);
@@ -2419,6 +2429,60 @@ void WebViewImpl::SetPageLifecycleState(
std::move(callback).Run();
}
+void WebViewImpl::DispatchPagehide() {
+ for (Frame* frame = GetPage()->MainFrame(); frame;
+ frame = frame->Tree().TraverseNext()) {
+ if (frame->DomWindow() && frame->DomWindow()->IsLocalDOMWindow()) {
+ frame->DomWindow()->ToLocalDOMWindow()->DispatchPagehideEvent(
+ PageTransitionEventPersistence::kPageTransitionEventPersisted);
+ }
+ }
+}
+
+void WebViewImpl::DispatchPageshow(base::TimeTicks navigation_start) {
+ for (Frame* frame = GetPage()->MainFrame(); frame;
+ frame = frame->Tree().TraverseNext()) {
+ auto* local_frame = DynamicTo<LocalFrame>(frame);
+ // Record the metics.
+ if (local_frame && local_frame->View()) {
+ Document* document = local_frame->GetDocument();
+ if (document) {
+ PaintTiming::From(*document).OnRestoredFromBackForwardCache();
+ InteractiveDetector::From(*document)->OnRestoredFromBackForwardCache();
+ }
+ DocumentLoader* loader = local_frame->Loader().GetDocumentLoader();
+ if (loader) {
+ loader->GetTiming().MarkBackForwardCacheRestoreNavigationStart(
+ navigation_start);
+ }
+ }
+ if (frame->DomWindow() && frame->DomWindow()->IsLocalDOMWindow()) {
+ frame->DomWindow()->ToLocalDOMWindow()->DispatchPersistedPageshowEvent(
+ navigation_start);
+ if (frame->IsMainFrame()) {
+ UMA_HISTOGRAM_BOOLEAN(
+ "BackForwardCache.MainFrameHasPageshowListenersOnRestore",
+ frame->DomWindow()->ToLocalDOMWindow()->HasEventListeners(
+ event_type_names::kPageshow));
+ }
+ }
+ }
+}
+
+void WebViewImpl::HookBackForwardCacheEviction(bool hook) {
+ DCHECK(GetPage());
+ for (Frame* frame = GetPage()->MainFrame(); frame;
+ frame = frame->Tree().TraverseNext()) {
+ auto* local_frame = DynamicTo<LocalFrame>(frame);
+ if (!local_frame)
+ continue;
+ if (hook)
+ local_frame->HookBackForwardCacheEviction();
+ else
+ local_frame->RemoveBackForwardCacheEviction();
+ }
+}
+
void WebViewImpl::EnableAutoResizeMode(const WebSize& min_size,
const WebSize& max_size) {
should_auto_resize_ = true;
@@ -2685,6 +2749,16 @@ void WebViewImpl::EnablePreferredSizeChangedMode() {
UpdatePreferredSize();
}
+void WebViewImpl::Focus() {
+ if (GetPage()->MainFrame()->IsLocalFrame()) {
+ DCHECK(local_main_frame_host_remote_);
+ local_main_frame_host_remote_->FocusPage();
+ } else {
+ DCHECK(remote_main_frame_host_remote_);
+ remote_main_frame_host_remote_->FocusPage();
+ }
+}
+
float WebViewImpl::DefaultMinimumPageScaleFactor() const {
return GetPageScaleConstraintsSet().DefaultConstraints().minimum_scale;
}
@@ -2833,15 +2907,6 @@ void WebViewImpl::PerformCustomContextMenuAction(unsigned action) {
}
}
-void WebViewImpl::ShowContextMenu(WebMenuSourceType source_type) {
- if (!MainFrameImpl())
- return;
-
- // If MainFrameImpl() is non-null, then FrameWidget() will also be non-null.
- DCHECK(MainFrameImpl()->FrameWidget());
- MainFrameImpl()->FrameWidget()->ShowContextMenu(source_type);
-}
-
WebURL WebViewImpl::GetURLForDebugTrace() {
WebFrame* main_frame = MainFrame();
if (main_frame->IsWebLocalFrame())
@@ -3349,64 +3414,6 @@ void WebViewImpl::SetPageFrozen(bool frozen) {
Scheduler()->SetPageFrozen(frozen);
}
-void WebViewImpl::PutPageIntoBackForwardCache() {
- DCHECK(GetPage());
-
- SetVisibilityState(mojom::blink::PageVisibilityState::kHidden,
- /*is_initial_state=*/false);
-
- for (Frame* frame = GetPage()->MainFrame(); frame;
- frame = frame->Tree().TraverseNext()) {
- if (frame->DomWindow() && frame->DomWindow()->IsLocalDOMWindow()) {
- frame->DomWindow()->ToLocalDOMWindow()->DispatchPagehideEvent(
- PageTransitionEventPersistence::kPageTransitionEventPersisted);
- }
- }
-
- // Freeze the page.
- Scheduler()->SetPageFrozen(/*frozen =*/true);
- // Hook eviction.
- for (Frame* frame = GetPage()->MainFrame(); frame;
- frame = frame->Tree().TraverseNext()) {
- auto* local_frame = DynamicTo<LocalFrame>(frame);
- if (!local_frame)
- continue;
- local_frame->HookBackForwardCacheEviction();
- }
-}
-
-void WebViewImpl::RestorePageFromBackForwardCache(
- base::TimeTicks navigation_start) {
- DCHECK(GetPage());
-
- // Unhook eviction.
- for (Frame* frame = GetPage()->MainFrame(); frame;
- frame = frame->Tree().TraverseNext()) {
- auto* local_frame = DynamicTo<LocalFrame>(frame);
- if (!local_frame)
- continue;
- local_frame->RemoveBackForwardCacheEviction();
- }
-
- // Resume the page.
- Scheduler()->SetPageFrozen(/*frozen =*/false);
- for (Frame* frame = GetPage()->MainFrame(); frame;
- frame = frame->Tree().TraverseNext()) {
- if (frame->DomWindow() && frame->DomWindow()->IsLocalDOMWindow()) {
- frame->DomWindow()->ToLocalDOMWindow()->DispatchPersistedPageshowEvent(
- navigation_start);
- if (frame->IsMainFrame()) {
- UMA_HISTOGRAM_BOOLEAN(
- "BackForwardCache.MainFrameHasPageshowListenersOnRestore",
- frame->DomWindow()->ToLocalDOMWindow()->HasEventListeners(
- event_type_names::kPageshow));
- }
- }
- }
- SetVisibilityState(mojom::blink::PageVisibilityState::kVisible,
- /*is_initial_state=*/false);
-}
-
WebFrameWidget* WebViewImpl::MainFrameWidget() {
return web_widget_;
}
diff --git a/chromium/third_party/blink/renderer/core/exported/web_view_impl.h b/chromium/third_party/blink/renderer/core/exported/web_view_impl.h
index ae5bf526b8a..e2124434e0d 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_view_impl.h
+++ b/chromium/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -125,6 +125,9 @@ class CORE_EXPORT WebViewImpl final : public WebView,
// WebView methods:
void DidAttachLocalMainFrame() override;
+ void DidDetachLocalMainFrame() override;
+ void DidAttachRemoteMainFrame() override;
+ void DidDetachRemoteMainFrame() override;
void SetPrerendererClient(WebPrerendererClient*) override;
WebSettings* GetSettings() override;
WebString PageEncoding() const override;
@@ -156,8 +159,6 @@ class CORE_EXPORT WebViewImpl final : public WebView,
bool zoom_into_legible_scale) override;
double ZoomLevel() override;
double SetZoomLevel(double) override;
- float TextZoomFactor() override;
- float SetTextZoomFactor(float) override;
float PageScaleFactor() const override;
float MinimumPageScaleFactor() const override;
float MaximumPageScaleFactor() const override;
@@ -176,6 +177,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
WebSize ContentsPreferredMinimumSize() override;
void UpdatePreferredSize() override;
void EnablePreferredSizeChangedMode() override;
+ void Focus() override;
void SetDeviceScaleFactor(float) override;
void SetZoomFactorForDeviceScaleFactor(float) override;
float ZoomFactorForDeviceScaleFactor() override {
@@ -197,9 +199,6 @@ class CORE_EXPORT WebViewImpl final : public WebView,
WebPagePopupImpl* GetPagePopup() const override { return page_popup_.get(); }
void AcceptLanguagesChanged() override;
void SetPageFrozen(bool frozen) override;
- void PutPageIntoBackForwardCache() override;
- void RestorePageFromBackForwardCache(
- base::TimeTicks navigation_start) override;
WebFrameWidget* MainFrameWidget() override;
void SetBaseBackgroundColor(SkColor) override;
void SetInsidePortal(bool inside_portal) override;
@@ -221,8 +220,13 @@ class CORE_EXPORT WebViewImpl final : public WebView,
// mojom::blink::PageBroadcast method:
void SetPageLifecycleState(mojom::blink::PageLifecycleStatePtr state,
+ base::Optional<base::TimeTicks> navigation_start,
SetPageLifecycleStateCallback callback) override;
+ void DispatchPagehide();
+ void DispatchPageshow(base::TimeTicks navigation_start);
+ void HookBackForwardCacheEviction(bool hook);
+
float DefaultMinimumPageScaleFactor() const;
float DefaultMaximumPageScaleFactor() const;
float ClampPageScaleFactorToLimits(float) const;
@@ -447,10 +451,6 @@ class CORE_EXPORT WebViewImpl final : public WebView,
ViewData& AsView() { return as_view_; }
const ViewData& AsView() const { return as_view_; }
- // Called while the main LocalFrame is being detached. The MainFrameImpl() is
- // still valid until after this method is called.
- void DidDetachLocalMainFrame();
-
// These are temporary methods to allow WebViewFrameWidget to delegate to
// WebViewImpl. We expect to eventually move these out.
void SetSuppressFrameRequestsWorkaroundFor704763Only(bool);
@@ -475,10 +475,6 @@ class CORE_EXPORT WebViewImpl final : public WebView,
void MouseCaptureLost();
void SetFocus(bool enable) override;
bool SelectionBounds(WebRect& anchor, WebRect& focus) const;
- void DidAcquirePointerLock();
- void DidNotAcquirePointerLock();
- void DidLosePointerLock();
- void ShowContextMenu(WebMenuSourceType);
WebURL GetURLForDebugTrace();
void SetPageScaleFactorAndLocation(float scale,
@@ -720,6 +716,11 @@ class CORE_EXPORT WebViewImpl final : public WebView,
mojo::AssociatedRemote<mojom::blink::LocalMainFrameHost>
local_main_frame_host_remote_;
+ // Handle to the remote main frame host. Only valid when the MainFrame is
+ // remote.
+ mojo::AssociatedRemote<mojom::blink::RemoteMainFrameHost>
+ remote_main_frame_host_remote_;
+
// Set when a measurement begins, reset when the measurement is taken.
base::Optional<base::TimeTicks> update_layers_start_time_;
diff --git a/chromium/third_party/blink/renderer/core/exported/web_view_test.cc b/chromium/third_party/blink/renderer/core/exported/web_view_test.cc
index cd29a295327..cbd6c1b384f 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_view_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -54,12 +54,12 @@
#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/common/input/web_keyboard_event.h"
#include "third_party/blink/public/common/page/page_zoom.h"
+#include "third_party/blink/public/common/page/web_drag_operation.h"
#include "third_party/blink/public/mojom/frame/frame_owner_element_type.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/tree_scope_type.mojom-blink.h"
#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/public/mojom/manifest/display_mode.mojom-shared.h"
#include "third_party/blink/public/platform/web_drag_data.h"
-#include "third_party/blink/public/platform/web_drag_operation.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/public/public_buildflags.h"
@@ -213,40 +213,6 @@ class AutoResizeWebViewClient : public frame_test_helpers::TestWebViewClient {
TestData test_data_;
};
-class TapHandlingWebWidgetClient
- : public frame_test_helpers::TestWebWidgetClient {
- public:
- // WebWidgetClient overrides.
- void DidHandleGestureEvent(const WebGestureEvent& event,
- bool event_cancelled) override {
- if (event.GetType() == WebInputEvent::Type::kGestureTap) {
- tap_x_ = event.PositionInWidget().x();
- tap_y_ = event.PositionInWidget().y();
- } else if (event.GetType() == WebInputEvent::Type::kGestureLongPress) {
- longpress_x_ = event.PositionInWidget().x();
- longpress_y_ = event.PositionInWidget().y();
- }
- }
-
- // Local methods
- void Reset() {
- tap_x_ = -1;
- tap_y_ = -1;
- longpress_x_ = -1;
- longpress_y_ = -1;
- }
- int TapX() { return tap_x_; }
- int TapY() { return tap_y_; }
- int LongpressX() { return longpress_x_; }
- int LongpressY() { return longpress_y_; }
-
- private:
- int tap_x_;
- int tap_y_;
- int longpress_x_;
- int longpress_y_;
-};
-
class WebViewTest : public testing::Test {
public:
WebViewTest() : base_url_("http://www.test.com/") {}
@@ -624,6 +590,19 @@ TEST_F(WebViewTest, SetBaseBackgroundColorWithColorScheme) {
web_view->SetBaseBackgroundColor(SK_ColorBLUE);
EXPECT_EQ(Color::kBlack, frame_view->BaseBackgroundColor());
+ color_scheme_helper.SetForcedColors(*(web_view->GetPage()),
+ ForcedColors::kActive);
+ UpdateAllLifecyclePhases();
+
+ Color system_background_color = LayoutTheme::GetTheme().SystemColor(
+ CSSValueID::kCanvas, WebColorScheme::kLight);
+ EXPECT_EQ(system_background_color, frame_view->BaseBackgroundColor());
+
+ color_scheme_helper.SetForcedColors(*(web_view->GetPage()),
+ ForcedColors::kNone);
+ UpdateAllLifecyclePhases();
+ EXPECT_EQ(Color::kBlack, frame_view->BaseBackgroundColor());
+
color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kLight);
UpdateAllLifecyclePhases();
EXPECT_EQ(Color(0, 0, 255), frame_view->BaseBackgroundColor());
@@ -1186,7 +1165,7 @@ TEST_F(WebViewTest, FinishComposingTextDoesNotAssert) {
// The test requires non-empty composition.
std::string composition_text("hello");
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
active_input_method_controller->SetComposition(
WebString::FromUTF8(composition_text.c_str()), empty_ime_text_spans,
WebRange(), 5, 5);
@@ -1243,7 +1222,7 @@ TEST_F(WebViewTest, FinishComposingTextCursorPositionChange) {
web_view->MainFrameImpl()
->FrameWidget()
->GetActiveWebInputMethodController();
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
active_input_method_controller->SetComposition(
WebString::FromUTF8(composition_text.c_str()), empty_ime_text_spans,
WebRange(), 3, 3);
@@ -1292,7 +1271,7 @@ TEST_F(WebViewTest, SetCompositionForNewCaretPositions) {
->FrameWidget()
->GetActiveWebInputMethodController();
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
active_input_method_controller->CommitText("hello", empty_ime_text_spans,
WebRange(), 0);
@@ -1408,7 +1387,7 @@ TEST_F(WebViewTest, SetCompositionWithEmptyText) {
->FrameWidget()
->GetActiveWebInputMethodController();
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
active_input_method_controller->CommitText("hello", empty_ime_text_spans,
WebRange(), 0);
@@ -1449,7 +1428,7 @@ TEST_F(WebViewTest, CommitTextForNewCaretPositions) {
->FrameWidget()
->GetActiveWebInputMethodController();
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
// Caret is on the left of composing text.
active_input_method_controller->CommitText("ab", empty_ime_text_spans,
@@ -1522,7 +1501,7 @@ TEST_F(WebViewTest, CommitTextWhileComposing) {
->FrameWidget()
->GetActiveWebInputMethodController();
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
active_input_method_controller->SetComposition(
WebString::FromUTF8("abc"), empty_ime_text_spans, WebRange(), 0, 0);
WebTextInputInfo info = active_input_method_controller->TextInputInfo();
@@ -1623,7 +1602,7 @@ TEST_F(WebViewTest, InsertNewLinePlacementAfterFinishComposingText) {
base_url_ + "text_area_populated.html");
web_view->MainFrameImpl()->GetFrame()->SetInitialFocus(false);
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
WebLocalFrameImpl* frame = web_view->MainFrameImpl();
WebInputMethodController* active_input_method_controller =
@@ -1725,11 +1704,11 @@ TEST_F(WebViewTest, SetCompositionFromExistingText) {
WebViewImpl* web_view = web_view_helper_.InitializeAndLoad(
base_url_ + "input_field_populated.html");
web_view->MainFrameImpl()->GetFrame()->SetInitialFocus(false);
- WebVector<WebImeTextSpan> ime_text_spans(static_cast<size_t>(1));
+ WebVector<ui::ImeTextSpan> ime_text_spans(static_cast<size_t>(1));
ime_text_spans[0] =
- WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4,
- ui::mojom::ImeTextSpanThickness::kThin,
- ui::mojom::ImeTextSpanUnderlineStyle::kSolid, 0, 0);
+ ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition, 0, 4,
+ ui::ImeTextSpan::Thickness::kThin,
+ ui::ImeTextSpan::UnderlineStyle::kSolid, 0, 0);
WebLocalFrameImpl* frame = web_view->MainFrameImpl();
WebInputMethodController* active_input_method_controller =
frame->GetInputMethodController();
@@ -1740,7 +1719,7 @@ TEST_F(WebViewTest, SetCompositionFromExistingText) {
EXPECT_EQ(10, info.selection_end);
EXPECT_EQ(8, info.composition_start);
EXPECT_EQ(12, info.composition_end);
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
frame->SetCompositionFromExistingText(0, 0, empty_ime_text_spans);
info = active_input_method_controller->TextInputInfo();
EXPECT_EQ(4, info.selection_start);
@@ -1754,17 +1733,17 @@ TEST_F(WebViewTest, SetCompositionFromExistingTextInTextArea) {
WebViewImpl* web_view = web_view_helper_.InitializeAndLoad(
base_url_ + "text_area_populated.html");
web_view->MainFrameImpl()->GetFrame()->SetInitialFocus(false);
- WebVector<WebImeTextSpan> ime_text_spans(static_cast<size_t>(1));
+ WebVector<ui::ImeTextSpan> ime_text_spans(static_cast<size_t>(1));
ime_text_spans[0] =
- WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4,
- ui::mojom::ImeTextSpanThickness::kThin,
- ui::mojom::ImeTextSpanUnderlineStyle::kSolid, 0, 0);
+ ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition, 0, 4,
+ ui::ImeTextSpan::Thickness::kThin,
+ ui::ImeTextSpan::UnderlineStyle::kSolid, 0, 0);
WebLocalFrameImpl* frame = web_view->MainFrameImpl();
WebInputMethodController* active_input_method_controller =
frame->FrameWidget()->GetActiveWebInputMethodController();
frame->SetEditableSelectionOffsets(27, 27);
std::string new_line_text("\n");
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
active_input_method_controller->CommitText(
WebString::FromUTF8(new_line_text.c_str()), empty_ime_text_spans,
WebRange(), 0);
@@ -1797,11 +1776,11 @@ TEST_F(WebViewTest, SetCompositionFromExistingTextInRichText) {
WebViewImpl* web_view = web_view_helper_.InitializeAndLoad(
base_url_ + "content_editable_rich_text.html");
web_view->MainFrameImpl()->GetFrame()->SetInitialFocus(false);
- WebVector<WebImeTextSpan> ime_text_spans(static_cast<size_t>(1));
+ WebVector<ui::ImeTextSpan> ime_text_spans(static_cast<size_t>(1));
ime_text_spans[0] =
- WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4,
- ui::mojom::ImeTextSpanThickness::kThin,
- ui::mojom::ImeTextSpanUnderlineStyle::kSolid, 0, 0);
+ ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition, 0, 4,
+ ui::ImeTextSpan::Thickness::kThin,
+ ui::ImeTextSpan::UnderlineStyle::kSolid, 0, 0);
WebLocalFrameImpl* frame = web_view->MainFrameImpl();
frame->SetEditableSelectionOffsets(1, 1);
WebDocument document = web_view->MainFrameImpl()->GetDocument();
@@ -1818,7 +1797,7 @@ TEST_F(WebViewTest, SetEditableSelectionOffsetsKeepsComposition) {
std::string composition_text_first("hello ");
std::string composition_text_second("world");
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
WebInputMethodController* active_input_method_controller =
web_view->MainFrameImpl()
->FrameWidget()
@@ -2630,8 +2609,6 @@ TEST_F(WebViewTest, PrintWithXHRInFlight) {
static void DragAndDropURL(WebViewImpl* web_view, const std::string& url) {
WebDragData drag_data;
- drag_data.Initialize();
-
WebDragData::Item item;
item.storage_type = WebDragData::Item::kStorageTypeString;
item.string_type = "text/uri-list";
@@ -2729,33 +2706,6 @@ ExternalDateTimeChooser* WebViewTest::GetExternalDateTimeChooser(
.GetExternalDateTimeChooserForTesting();
}
-TEST_F(WebViewTest, ClientTapHandling) {
- TapHandlingWebWidgetClient client;
- WebView* web_view = web_view_helper_.InitializeAndLoad("about:blank", nullptr,
- nullptr, &client);
- WebGestureEvent event(WebInputEvent::Type::kGestureTap,
- WebInputEvent::kNoModifiers,
- WebInputEvent::GetStaticTimeStampForTests(),
- WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(gfx::PointF(3, 8));
- web_view->MainFrameWidget()->HandleInputEvent(
- WebCoalescedInputEvent(event, ui::LatencyInfo()));
- RunPendingTasks();
- EXPECT_EQ(3, client.TapX());
- EXPECT_EQ(8, client.TapY());
- client.Reset();
- event.SetType(WebInputEvent::Type::kGestureLongPress);
- event.SetPositionInWidget(gfx::PointF(25, 7));
- web_view->MainFrameWidget()->HandleInputEvent(
- WebCoalescedInputEvent(event, ui::LatencyInfo()));
- RunPendingTasks();
- EXPECT_EQ(25, client.LongpressX());
- EXPECT_EQ(7, client.LongpressY());
-
- // Explicitly reset to break dependency on locally scoped client.
- web_view_helper_.Reset();
-}
-
TEST_F(WebViewTest, ClientTapHandlingNullWebViewClient) {
// Note: this test doesn't use WebViewHelper since WebViewHelper creates an
// internal WebViewClient on demand if the supplied WebViewClient is null.
@@ -3092,7 +3042,7 @@ TEST_F(WebViewTest, FinishComposingTextDoesNotDismissHandles) {
WebInputMethodController* active_input_method_controller =
frame->FrameWidget()->GetActiveWebInputMethodController();
EXPECT_TRUE(TapElementById(WebInputEvent::Type::kGestureTap, target));
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
frame->SetEditableSelectionOffsets(8, 8);
EXPECT_TRUE(active_input_method_controller->SetComposition(
"12345", empty_ime_text_spans, WebRange(), 8, 13));
@@ -3530,7 +3480,7 @@ TEST_F(WebViewTest, LosingFocusDoesNotTriggerAutofillTextChange) {
web_view->MainFrameImpl()->GetFrame()->SetInitialFocus(false);
// Set up a composition that needs to be committed.
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
frame->SetEditableSelectionOffsets(4, 10);
frame->SetCompositionFromExistingText(8, 12, empty_ime_text_spans);
WebTextInputInfo info = frame->GetInputMethodController()->TextInputInfo();
@@ -3574,7 +3524,7 @@ TEST_F(WebViewTest, CompositionNotCancelledByBackspace) {
// Test both input elements.
for (int i = 0; i < 2; ++i) {
// Select composition and do sanity check.
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
frame->SetEditableSelectionOffsets(6, 6);
WebInputMethodController* active_input_method_controller =
frame->FrameWidget()->GetActiveWebInputMethodController();
@@ -3628,7 +3578,7 @@ TEST_F(WebViewTest, FinishComposingTextDoesntTriggerAutofillTextChange) {
// Set up a composition that needs to be committed.
std::string composition_text("testingtext");
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
active_input_method_controller->SetComposition(
WebString::FromUTF8(composition_text.c_str()), empty_ime_text_spans,
WebRange(), 0, composition_text.length());
@@ -3661,7 +3611,7 @@ TEST_F(WebViewTest,
frame->SetAutofillClient(&client);
web_view->MainFrameImpl()->GetFrame()->SetInitialFocus(false);
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
client.ClearChangeCounts();
frame->SetCompositionFromExistingText(8, 12, empty_ime_text_spans);
@@ -3697,7 +3647,7 @@ class ViewCreatingWebViewClient : public frame_test_helpers::TestWebViewClient {
}
// WebWidgetClient methods
- void DidFocus(WebLocalFrame*) override { did_focus_called_ = true; }
+ void DidFocus() override { did_focus_called_ = true; }
bool DidFocusCalled() const { return did_focus_called_; }
WebView* CreatedWebView() const { return web_view_helper_.GetWebView(); }
@@ -4109,6 +4059,7 @@ class FakeFrameWidgetHost : public mojom::blink::FrameWidgetHost {
void AutoscrollStart(const gfx::PointF& position) override {}
void AutoscrollFling(const gfx::Vector2dF& position) override {}
void AutoscrollEnd() override {}
+ void DidFirstVisuallyNonEmptyPaint() override {}
private:
mojo::AssociatedReceiver<mojom::blink::FrameWidgetHost>
@@ -4329,6 +4280,7 @@ TEST_F(WebViewTest, SetHasTouchEventHandlers) {
// Free the webView before the TouchEventHandlerWebViewClient gets freed.
web_view_helper_.Reset();
+ web_view_impl->Close();
}
// This test checks that deleting nodes which have only non-JS-registered touch
@@ -4485,7 +4437,7 @@ TEST_F(WebViewTest, CompositionIsUserGesture) {
EXPECT_TRUE(
frame->FrameWidget()->GetActiveWebInputMethodController()->SetComposition(
WebString::FromUTF8(std::string("hello").c_str()),
- WebVector<WebImeTextSpan>(), WebRange(), 3, 3));
+ WebVector<ui::ImeTextSpan>(), WebRange(), 3, 3));
EXPECT_TRUE(frame->HasTransientUserActivation());
EXPECT_EQ(1, client.TextChanges());
EXPECT_TRUE(frame->HasMarkedText());
@@ -5016,7 +4968,7 @@ TEST_F(WebViewTest, PasswordFieldEditingIsUserGesture) {
frame->SetAutofillClient(&client);
web_view->MainFrameImpl()->GetFrame()->SetInitialFocus(false);
- WebVector<WebImeTextSpan> empty_ime_text_spans;
+ WebVector<ui::ImeTextSpan> empty_ime_text_spans;
EXPECT_EQ(0, client.TextChanges());
EXPECT_TRUE(
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/document_policy_parser_test.cc b/chromium/third_party/blink/renderer/core/feature_policy/document_policy_parser_test.cc
index 2c8efefcef1..2c81b5feea8 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/document_policy_parser_test.cc
+++ b/chromium/third_party/blink/renderer/core/feature_policy/document_policy_parser_test.cc
@@ -4,19 +4,35 @@
#include "third_party/blink/renderer/core/feature_policy/document_policy_parser.h"
+#include <vector>
+
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/feature_policy/document_policy.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h"
namespace blink {
-namespace {
constexpr const mojom::blink::DocumentPolicyFeature kBoolFeature =
static_cast<mojom::blink::DocumentPolicyFeature>(1);
constexpr const mojom::blink::DocumentPolicyFeature kDoubleFeature =
static_cast<mojom::blink::DocumentPolicyFeature>(2);
-class DocumentPolicyParserTest : public ::testing::Test {
+// This is the test version of |PolicyParserMessageBuffer::Message| as
+// WTF::String cannot be statically allocated.
+struct MessageForTest {
+ mojom::ConsoleMessageLevel level;
+ const char* content;
+};
+
+struct ParseTestCase {
+ const char* test_name;
+ const char* input_string;
+ DocumentPolicy::ParsedDocumentPolicy parsed_policy;
+ std::vector<MessageForTest> messages;
+};
+
+class DocumentPolicyParserTest
+ : public ::testing::TestWithParam<ParseTestCase> {
protected:
DocumentPolicyParserTest()
: name_feature_map(DocumentPolicyNameFeatureMap{
@@ -51,311 +67,301 @@ class DocumentPolicyParserTest : public ::testing::Test {
const DocumentPolicyFeatureInfoMap feature_info_map;
DocumentPolicyFeatureSet available_features;
- protected:
- struct ParseTestCase {
- const char* test_name;
- const char* input_string;
- DocumentPolicy::ParsedDocumentPolicy parsed_policy;
- Vector<PolicyParserMessageBuffer::Message> messages;
- };
+ public:
+ static const ParseTestCase kCases[];
+};
- // |kPolicyParseTestCases| is made as a member of
- // |DocumentPolicyParserTest| because |PolicyParserMessageBuffer::Message| has
- // a member of type WTF::String which cannot be statically allocated.
- const std::vector<ParseTestCase> kPolicyParseTestCases = {
- //
- // Parse valid policy strings.
- //
- {
- "Parse an empty policy string.",
- "",
- /* parsed_policy */
- {
- /* feature_state */ {},
- /* endpoint_map */ {},
- },
- /* messages */ {},
- },
- {
- "Parse an empty policy string.",
- " ",
- /* parsed_policy */
- {
- /* feature_state */ {},
- /* endpoint_map */ {},
- },
- /* messages */ {},
- },
- {
- "Parse bool feature with value true.",
- "f-bool",
- /* parsed_policy */
- {
- /* feature_state */ {{kBoolFeature, PolicyValue(true)}},
- /* endpoint_map */ {},
- },
- /* messages */ {},
- },
- {
- "Parse bool feature with value false.",
- "no-f-bool",
- /* parsed_policy */
- {
- /* feature_state */ {{kBoolFeature, PolicyValue(false)}},
- /* endpoint_map */ {},
- },
- /* messages */ {},
- },
- {
- "Parse double feature with value 1.0.",
- "f-double;value=1.0",
- /* parsed_policy */
- {
- /* feature_state */ {{kDoubleFeature, PolicyValue(1.0)}},
- /* endpoint_map */ {},
- },
- /* messages */ {},
- },
- {
- "Parse double feature with value literal 2.",
- "f-double;value=2",
- /* parsed_policy */
- {
- /* feature_state */ {{kDoubleFeature, PolicyValue(2.0)}},
- /* endpoint_map */ {},
- },
- /* messages */ {},
- },
- {
- "Parse double feature and bool feature.",
- "f-double;value=1,no-f-bool",
- /* parsed_policy */
- {
- /* feature_state */ {{kBoolFeature, PolicyValue(false)},
- {kDoubleFeature, PolicyValue(1.0)}},
- /* endpoint_map */ {},
- },
- /* messages */ {},
- },
- {
- "Parse bool feature and double feature.",
- "no-f-bool,f-double;value=1",
- /* parsed_policy */
- {
- /* feature_state */ {{kBoolFeature, PolicyValue(false)},
- {kDoubleFeature, PolicyValue(1.0)}},
- /* endpoint_map */ {},
- },
- /* messages */ {},
- },
- {
- "White-space is allowed in some positions in structured-header.",
- "no-f-bool, f-double;value=1",
- /* parsed_policy */
- {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
- {kDoubleFeature, PolicyValue(1.0)}},
- /* endpoint_map */ {}},
- /* messages */ {},
- },
- {
- "Unrecognized parameters are ignored, but the feature entry should "
- "remain valid.",
- "no-f-bool,f-double;value=1;unknown_param=xxx",
- /* parsed_policy */
- {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
- {kDoubleFeature, PolicyValue(1.0)}},
- /* endpoint_map */ {}},
- /* messages */
- {{mojom::blink::ConsoleMessageLevel::kWarning,
- "Unrecognized parameter name unknown_param for feature f-double."}},
- },
- {
- "Parse policy with report endpoint specified.",
- "no-f-bool,f-double;value=1;report-to=default",
- /* parsed_policy */
- {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
- {kDoubleFeature, PolicyValue(1.0)}},
- /* endpoint_map */ {{kDoubleFeature, "default"}}},
- /* messages */ {},
- },
- {
- "Parse policy with report endpoint specified.",
- "no-f-bool;report-to=default,f-double;value=1",
- /* parsed_policy */
- {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
- {kDoubleFeature, PolicyValue(1.0)}},
- /* endpoint_map */ {{kBoolFeature, "default"}}},
- /* messages */ {},
- },
- {
- "Parse policy with default report endpoint specified. 'none' "
- "keyword should overwrite default value assignment.",
- "no-f-bool;report-to=none, f-double;value=2.0, *;report-to=default",
- /* parsed_policy */
- {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
- {kDoubleFeature, PolicyValue(2.0)}},
- /* endpoint_map */ {{kDoubleFeature, "default"}}},
- /* messages */ {},
- },
- {
- "Parse policy with default report endpoint specified.",
- "no-f-bool;report-to=not_none, f-double;value=2.0, "
- "*;report-to=default",
- /* parsed_policy */
- {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
- {kDoubleFeature, PolicyValue(2.0)}},
- /* endpoint_map */ {{kBoolFeature, "not_none"},
- {kDoubleFeature, "default"}}},
- /* messages */ {},
- },
- {
- "Parse policy with default report endpoint 'none'.",
- "no-f-bool;report-to=not_none, f-double;value=2.0, *;report-to=none",
- /* parsed_policy */
- {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
- {kDoubleFeature, PolicyValue(2.0)}},
- /* endpoint_map */ {{kBoolFeature, "not_none"}}},
- /* messages */ {},
- },
- {
- "Default endpoint can be specified anywhere in the header, not "
- "necessary at the end.",
- "no-f-bool;report-to=not_none, *;report-to=default, "
- "f-double;value=2.0",
- /* parsed_policy */
- {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
- {kDoubleFeature, PolicyValue(2.0)}},
- /* endpoint_map */ {{kBoolFeature, "not_none"},
- {kDoubleFeature, "default"}}},
- /* messages */ {},
- },
- {
- "Default endpoint can be specified multiple times in the header. "
- "According to SH rules, last value wins.",
- "no-f-bool;report-to=not_none, f-double;value=2.0, "
- "*;report-to=default, *;report-to=none",
- /* parsed_policy */
- {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
- {kDoubleFeature, PolicyValue(2.0)}},
- /* endpoint_map */ {{kBoolFeature, "not_none"}}},
- /* messages */ {},
- },
- {
- "Even if default endpoint is not specified, none still should be "
- "treated as a reserved keyword for endpoint names.",
- "no-f-bool;report-to=none",
- /* parsed_policy */
- {/* feature_state */ {{kBoolFeature, PolicyValue(false)}},
- /* endpoint_map */ {}},
- /* messages */ {},
- },
+const ParseTestCase DocumentPolicyParserTest::kCases[] = {
+ //
+ // Parse valid policy strings.
+ //
+ {
+ "ParseEmptyPolicyString",
+ "",
+ /* parsed_policy */
+ {
+ /* feature_state */ {},
+ /* endpoint_map */ {},
+ },
+ /* messages */ {},
+ },
+ {
+ "ParseWhitespaceOnlyString",
+ " ",
+ /* parsed_policy */
+ {
+ /* feature_state */ {},
+ /* endpoint_map */ {},
+ },
+ /* messages */ {},
+ },
+ {
+ "ParseBoolFeatureWithValueTrue",
+ "f-bool",
+ /* parsed_policy */
+ {
+ /* feature_state */ {{kBoolFeature, PolicyValue(true)}},
+ /* endpoint_map */ {},
+ },
+ /* messages */ {},
+ },
+ {
+ "ParseBoolFeatureWithValueFalse",
+ "no-f-bool",
+ /* parsed_policy */
+ {
+ /* feature_state */ {{kBoolFeature, PolicyValue(false)}},
+ /* endpoint_map */ {},
+ },
+ /* messages */ {},
+ },
+ {
+ "ParseDoubleFeature1",
+ "f-double;value=1.0",
+ /* parsed_policy */
+ {
+ /* feature_state */ {{kDoubleFeature, PolicyValue(1.0)}},
+ /* endpoint_map */ {},
+ },
+ /* messages */ {},
+ },
+ {
+ "ParseDoubleFeature2",
+ "f-double;value=2",
+ /* parsed_policy */
+ {
+ /* feature_state */ {{kDoubleFeature, PolicyValue(2.0)}},
+ /* endpoint_map */ {},
+ },
+ /* messages */ {},
+ },
+ {
+ "ParseDoubleFeatureAndBoolFeature",
+ "f-double;value=1,no-f-bool",
+ /* parsed_policy */
+ {
+ /* feature_state */ {{kBoolFeature, PolicyValue(false)},
+ {kDoubleFeature, PolicyValue(1.0)}},
+ /* endpoint_map */ {},
+ },
+ /* messages */ {},
+ },
+ {
+ "ParseBoolFeatureAndDoubleFeature",
+ "no-f-bool,f-double;value=1",
+ /* parsed_policy */
+ {
+ /* feature_state */ {{kBoolFeature, PolicyValue(false)},
+ {kDoubleFeature, PolicyValue(1.0)}},
+ /* endpoint_map */ {},
+ },
+ /* messages */ {},
+ },
+ {
+ "WhitespaceIsAllowedInSomePositionsInStructuredHeader",
+ "no-f-bool, f-double;value=1",
+ /* parsed_policy */
+ {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
+ {kDoubleFeature, PolicyValue(1.0)}},
+ /* endpoint_map */ {}},
+ /* messages */ {},
+ },
+ {
+ "UnrecognizedParametersAreIgnoredButTheFeatureEntryShould"
+ "RemainValid",
+ "no-f-bool,f-double;value=1;unknown_param=xxx",
+ /* parsed_policy */
+ {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
+ {kDoubleFeature, PolicyValue(1.0)}},
+ /* endpoint_map */ {}},
+ /* messages */
+ {{mojom::blink::ConsoleMessageLevel::kWarning,
+ "Unrecognized parameter name unknown_param for feature f-double."}},
+ },
+ {
+ "ParsePolicyWithReportEndpointSpecified1",
+ "no-f-bool,f-double;value=1;report-to=default",
+ /* parsed_policy */
+ {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
+ {kDoubleFeature, PolicyValue(1.0)}},
+ /* endpoint_map */ {{kDoubleFeature, "default"}}},
+ /* messages */ {},
+ },
+ {
+ "ParsePolicyWithReportEndpointSpecified2",
+ "no-f-bool;report-to=default,f-double;value=1",
+ /* parsed_policy */
+ {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
+ {kDoubleFeature, PolicyValue(1.0)}},
+ /* endpoint_map */ {{kBoolFeature, "default"}}},
+ /* messages */ {},
+ },
+ {
+ "ParsePolicyWithDefaultReportEndpointAndNone"
+ "KeywordShouldOverwriteDefaultValue",
+ "no-f-bool;report-to=none, f-double;value=2.0, *;report-to=default",
+ /* parsed_policy */
+ {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
+ {kDoubleFeature, PolicyValue(2.0)}},
+ /* endpoint_map */ {{kDoubleFeature, "default"}}},
+ /* messages */ {},
+ },
+ {
+ "ParsePolicyWithDefaultReportEndpointSpecified",
+ "no-f-bool;report-to=not_none, f-double;value=2.0, "
+ "*;report-to=default",
+ /* parsed_policy */
+ {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
+ {kDoubleFeature, PolicyValue(2.0)}},
+ /* endpoint_map */ {{kBoolFeature, "not_none"},
+ {kDoubleFeature, "default"}}},
+ /* messages */ {},
+ },
+ {
+ "ParsePolicyWithDefaultReportEndpointSpecifiedAsNone",
+ "no-f-bool;report-to=not_none, f-double;value=2.0, *;report-to=none",
+ /* parsed_policy */
+ {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
+ {kDoubleFeature, PolicyValue(2.0)}},
+ /* endpoint_map */ {{kBoolFeature, "not_none"}}},
+ /* messages */ {},
+ },
+ {
+ "DefaultEndpointCanBeSpecifiedAnywhereInTheHeader",
+ "no-f-bool;report-to=not_none, *;report-to=default, "
+ "f-double;value=2.0",
+ /* parsed_policy */
+ {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
+ {kDoubleFeature, PolicyValue(2.0)}},
+ /* endpoint_map */ {{kBoolFeature, "not_none"},
+ {kDoubleFeature, "default"}}},
+ /* messages */ {},
+ },
+ {
+ "DefaultEndpointCanBeSpecifiedMultipleTimesInTheHeader",
+ "no-f-bool;report-to=not_none, f-double;value=2.0, "
+ "*;report-to=default, *;report-to=none",
+ /* parsed_policy */
+ {/* feature_state */ {{kBoolFeature, PolicyValue(false)},
+ {kDoubleFeature, PolicyValue(2.0)}},
+ /* endpoint_map */ {{kBoolFeature, "not_none"}}},
+ /* messages */ {},
+ },
+ {
+ "EvenIfDefaultEndpointIsNotSpecifiedNoneStillShouldBe"
+ "TreatedAsReservedKeywordForEndpointNames",
+ "no-f-bool;report-to=none",
+ /* parsed_policy */
+ {/* feature_state */ {{kBoolFeature, PolicyValue(false)}},
+ /* endpoint_map */ {}},
+ /* messages */ {},
+ },
- //
- // Parse invalid policies.
- //
- {
- "Parse policy with unrecognized feature name.",
- "bad-feature-name",
- /* parsed_policy */
- {
- /* feature_state */ {},
- /* endpoint_map */ {},
- },
- /* messages */
- {{mojom::blink::ConsoleMessageLevel::kWarning,
- "Unrecognized document policy feature name "
- "bad-feature-name."}},
- },
- {
- "Parse policy with unrecognized feature name.",
- "no-bad-feature-name",
- /* parsed_policy */
- {
- /* feature_state */ {},
- /* endpoint_map */ {},
- },
- /* messages */
- {{mojom::blink::ConsoleMessageLevel::kWarning,
- "Unrecognized document policy feature name "
- "no-bad-feature-name."}},
- },
- {
- "Parse policy with wrong type of param. Expected double type but get "
- "boolean type.",
- "f-double;value=?0",
- /* parsed_policy */
- {
- /* feature_state */ {},
- /* endpoint_map */ {},
- },
- /* messages */
- {{mojom::blink::ConsoleMessageLevel::kWarning,
- "Parameter value in feature f-double should be Double, but get "
- "Boolean."}},
- },
- {
- "Policy member should be token instead of string.",
- "\"f-bool\"",
- /* parsed_policy */
- {
- /* feature_state */ {},
- /* endpoint_map */ {},
- },
- /* messages */
- {{mojom::blink::ConsoleMessageLevel::kWarning,
- "The item in directive should be token type."}},
- },
- {
- "Feature token should not be empty.",
- "();value=2",
- /* parsed_policy */
- {
- /* feature_state */ {},
- /* endpoint_map */ {},
- },
- /* messages */
- {{mojom::blink::ConsoleMessageLevel::kWarning,
- "Directives must not be inner lists."}},
- },
- {
- "Too many feature tokens.",
- "(f-bool f-double);value=2",
- /* parsed_policy */
- {
- /* feature_state */ {},
- /* endpoint_map */ {},
- },
- /* messages */
- {{mojom::blink::ConsoleMessageLevel::kWarning,
- "Directives must not be inner lists."}},
- },
- {
- "Missing mandatory parameter.",
- "f-double;report-to=default",
- /* parsed_policy */
- {
- /* feature_state */ {},
- /* endpoint_map */ {},
- },
- /* messages */
- {{mojom::blink::ConsoleMessageLevel::kWarning,
- "Policy value parameter missing for feature f-double. Expected "
- "something like \"f-double;value=...\"."}},
- },
- {
- "\"report-to\" parameter value type should be token instead of "
- "string.",
- "f-bool;report-to=\"default\"",
- /* parsed_policy */
- {
- /* feature_state */ {},
- /* endpoint_map */ {},
- },
- /* messages */
- {{mojom::blink::ConsoleMessageLevel::kWarning,
- "\"report-to\" parameter should be a token in feature f-bool."}},
- },
- };
+ //
+ // Parse invalid policies.
+ //
+ {
+ "ParsePolicyWithUnrecognizedFeatureName1",
+ "bad-feature-name",
+ /* parsed_policy */
+ {
+ /* feature_state */ {},
+ /* endpoint_map */ {},
+ },
+ /* messages */
+ {{mojom::blink::ConsoleMessageLevel::kWarning,
+ "Unrecognized document policy feature name "
+ "bad-feature-name."}},
+ },
+ {
+ "ParsePolicyWithUnrecognizedFeatureName2",
+ "no-bad-feature-name",
+ /* parsed_policy */
+ {
+ /* feature_state */ {},
+ /* endpoint_map */ {},
+ },
+ /* messages */
+ {{mojom::blink::ConsoleMessageLevel::kWarning,
+ "Unrecognized document policy feature name "
+ "no-bad-feature-name."}},
+ },
+ {
+ "ParsePolicyWithWrongTypeOfParamExpectedDoubleTypeButGet"
+ "BooleanType",
+ "f-double;value=?0",
+ /* parsed_policy */
+ {
+ /* feature_state */ {},
+ /* endpoint_map */ {},
+ },
+ /* messages */
+ {{mojom::blink::ConsoleMessageLevel::kWarning,
+ "Parameter value in feature f-double should be Double, but get "
+ "Boolean."}},
+ },
+ {
+ "PolicyMemberShouldBeTokenInsteadOfString",
+ "\"f-bool\"",
+ /* parsed_policy */
+ {
+ /* feature_state */ {},
+ /* endpoint_map */ {},
+ },
+ /* messages */
+ {{mojom::blink::ConsoleMessageLevel::kWarning,
+ "The item in directive should be token type."}},
+ },
+ {
+ "FeatureTokenShouldNotBeEmpty",
+ "();value=2",
+ /* parsed_policy */
+ {
+ /* feature_state */ {},
+ /* endpoint_map */ {},
+ },
+ /* messages */
+ {{mojom::blink::ConsoleMessageLevel::kWarning,
+ "Directives must not be inner lists."}},
+ },
+ {
+ "TooManyFeatureTokens",
+ "(f-bool f-double);value=2",
+ /* parsed_policy */
+ {
+ /* feature_state */ {},
+ /* endpoint_map */ {},
+ },
+ /* messages */
+ {{mojom::blink::ConsoleMessageLevel::kWarning,
+ "Directives must not be inner lists."}},
+ },
+ {
+ "MissingMandatoryParameter",
+ "f-double;report-to=default",
+ /* parsed_policy */
+ {
+ /* feature_state */ {},
+ /* endpoint_map */ {},
+ },
+ /* messages */
+ {{mojom::blink::ConsoleMessageLevel::kWarning,
+ "Policy value parameter missing for feature f-double. Expected "
+ "something like \"f-double;value=...\"."}},
+ },
+ {
+ "ReportToParameterValueTypeShouldBeTokenInsteadOf"
+ "String",
+ "f-bool;report-to=\"default\"",
+ /* parsed_policy */
+ {
+ /* feature_state */ {},
+ /* endpoint_map */ {},
+ },
+ /* messages */
+ {{mojom::blink::ConsoleMessageLevel::kWarning,
+ "\"report-to\" parameter should be a token in feature f-bool."}},
+ },
};
const std::pair<DocumentPolicy::FeatureState, std::string>
@@ -411,35 +417,45 @@ TEST_F(DocumentPolicyParserTest, SerializeResultShouldMatch) {
}
}
-TEST_F(DocumentPolicyParserTest, ParseResultShouldMatch) {
- for (const auto& test_case : kPolicyParseTestCases) {
- const String& test_name = test_case.test_name;
+INSTANTIATE_TEST_SUITE_P(
+ All,
+ DocumentPolicyParserTest,
+ ::testing::ValuesIn(DocumentPolicyParserTest::kCases),
+ [](const ::testing::TestParamInfo<ParseTestCase>& param_info) {
+ return param_info.param.test_name;
+ });
- PolicyParserMessageBuffer logger;
- const auto result = Parse(test_case.input_string, logger);
+TEST_P(DocumentPolicyParserTest, ParseResultShouldMatch) {
+ const ParseTestCase& test_case = GetParam();
+ PolicyParserMessageBuffer logger;
- // All tesecases should not return base::nullopt because they all comply to
- // structured header syntax.
- ASSERT_TRUE(result.has_value());
+ const auto result = Parse(test_case.input_string, logger);
+
+ // All tese cases should not return base::nullopt because they all comply to
+ // structured header syntax.
+ ASSERT_TRUE(result.has_value());
+
+ EXPECT_EQ(result->endpoint_map, test_case.parsed_policy.endpoint_map)
+ << "\n endpoint map should match";
+ EXPECT_EQ(result->feature_state, test_case.parsed_policy.feature_state)
+ << "\n feature state should match";
+ EXPECT_EQ(logger.GetMessages().size(), test_case.messages.size())
+ << "\n messages length should match";
+
+ const auto& actual_messages = logger.GetMessages();
+ const std::vector<MessageForTest>& expected_messages = test_case.messages;
+
+ ASSERT_EQ(actual_messages.size(), expected_messages.size())
+ << "message count should match";
+ for (size_t i = 0; i < expected_messages.size(); ++i) {
+ const auto& actual_message = actual_messages[i];
+ const MessageForTest& expected_message = expected_messages[i];
- EXPECT_EQ(result->endpoint_map, test_case.parsed_policy.endpoint_map)
- << test_name << "\n endpoint map should match";
- EXPECT_EQ(result->feature_state, test_case.parsed_policy.feature_state)
- << test_name << "\n feature state should match";
- EXPECT_EQ(logger.GetMessages().size(), test_case.messages.size())
- << test_name << "\n messages length should match";
- for (auto *it_actual = logger.GetMessages().begin(),
- *it_expected = test_case.messages.begin();
- it_actual != logger.GetMessages().end() &&
- it_expected != test_case.messages.end();
- it_actual++, it_expected++) {
- EXPECT_EQ(it_actual->level, it_expected->level)
- << test_name << "\n message level should match";
- EXPECT_EQ(it_actual->content, it_expected->content)
- << test_name << "\n message content should match";
- }
+ EXPECT_EQ(actual_message.level, expected_message.level)
+ << "\n message level should match";
+ EXPECT_EQ(actual_message.content, String(expected_message.content))
+ << "\n message content should match";
}
}
-} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/dom_document_policy.h b/chromium/third_party/blink/renderer/core/feature_policy/dom_document_policy.h
index 7b2e7ab79e2..6f3b3421f03 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/dom_document_policy.h
+++ b/chromium/third_party/blink/renderer/core/feature_policy/dom_document_policy.h
@@ -19,7 +19,7 @@ class CORE_EXPORT DOMDocumentPolicy final : public DOMFeaturePolicy {
// Create a new DOMDocumentPolicy, which is associated with |document|.
explicit DOMDocumentPolicy(Document* document) : document_(document) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(document_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/dom_feature_policy.cc b/chromium/third_party/blink/renderer/core/feature_policy/dom_feature_policy.cc
index 21ed39cb154..9be229b0add 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/dom_feature_policy.cc
+++ b/chromium/third_party/blink/renderer/core/feature_policy/dom_feature_policy.cc
@@ -105,7 +105,7 @@ void DOMFeaturePolicy::AddWarningForUnrecognizedFeature(
"Unrecognized feature: '" + feature + "'."));
}
-void DOMFeaturePolicy::Trace(Visitor* visitor) {
+void DOMFeaturePolicy::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/dom_feature_policy.h b/chromium/third_party/blink/renderer/core/feature_policy/dom_feature_policy.h
index 41b956de3d0..5d5c22466d5 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/dom_feature_policy.h
+++ b/chromium/third_party/blink/renderer/core/feature_policy/dom_feature_policy.h
@@ -49,7 +49,7 @@ class CORE_EXPORT DOMFeaturePolicy : public ScriptWrappable {
const ParsedFeaturePolicy& container_policy = {},
scoped_refptr<const SecurityOrigin> src_origin = nullptr);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
virtual const FeaturePolicy* GetPolicy() const = 0;
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy.dict b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy.dict
index 9c3841fb26e..35d012172c7 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy.dict
+++ b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy.dict
@@ -6,6 +6,8 @@
"ambient-light-sensor"
"autoplay"
"camera"
+"clipboard-read"
+"clipboard-write"
"document-domain"
"document-write"
"encrypted-media"
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy.idl b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy.idl
index 4a07bbf70c1..1e3e14ddb3d 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy.idl
+++ b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy.idl
@@ -5,7 +5,6 @@
// https://wicg.github.io/feature-policy/#the-policy-object
[
Exposed=Window,
- RuntimeEnabled=FeaturePolicyJavaScriptInterface,
ImplementedAs=DOMFeaturePolicy
] interface FeaturePolicy {
[MeasureAs=FeaturePolicyJSAPI, CallWith=ScriptState] boolean allowsFeature(DOMString feature, optional DOMString origin);
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_attr_fuzzer.cc b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_attr_fuzzer.cc
index f3f4c57a50f..add93d94878 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_attr_fuzzer.cc
+++ b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_attr_fuzzer.cc
@@ -16,14 +16,13 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
static blink::BlinkFuzzerTestSupport test_support =
blink::BlinkFuzzerTestSupport();
- WTF::Vector<WTF::String> messages;
+ blink::PolicyParserMessageBuffer logger;
// TODO(csharrison): Be smarter about parsing these origins for performance.
scoped_refptr<const blink::SecurityOrigin> parent_origin =
blink::SecurityOrigin::CreateFromString("https://example.com/");
scoped_refptr<const blink::SecurityOrigin> child_origin =
blink::SecurityOrigin::CreateFromString("https://example.net/");
- blink::FeaturePolicyParser::ParseAttribute(WTF::String(data, size),
- parent_origin.get(),
- child_origin.get(), &messages);
+ blink::FeaturePolicyParser::ParseAttribute(
+ WTF::String(data, size), parent_origin.get(), child_origin.get(), logger);
return 0;
}
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5 b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5
index 39ecf9542e6..8f92970f0ab 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5
+++ b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5
@@ -119,6 +119,14 @@
depends_on: ["FeaturePolicyForClientHints"],
},
{
+ name: "ClipboardRead",
+ feature_policy_name: "clipboard-read",
+ },
+ {
+ name: "ClipboardWrite",
+ feature_policy_name: "clipboard-write",
+ },
+ {
name: "ConversionMeasurement",
feature_policy_name: "conversion-measurement",
depends_on: ["ConversionMeasurement"],
@@ -189,16 +197,6 @@
depends_on: ["IdleDetection"],
},
{
- name: "LazyLoad",
- feature_policy_name: "lazyload",
- depends_on: ["ExperimentalProductivityFeatures"],
- },
- {
- name: "LoadingFrameDefaultEager",
- feature_policy_name: "loading-frame-default-eager",
- depends_on: ["ExperimentalProductivityFeatures"]
- },
- {
name: "Magnetometer",
feature_policy_name: "magnetometer",
},
@@ -266,6 +264,11 @@
depends_on: ["Serial"],
},
{
+ name: "StorageAccessAPI",
+ feature_policy_name: "storage-access-api",
+ depends_on: ["StorageAccessAPI"],
+ },
+ {
name: "SyncScript",
feature_policy_name: "sync-script",
depends_on: ["ExperimentalProductivityFeatures"],
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_fuzzer.cc b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_fuzzer.cc
index 213666cc030..f3da0d30050 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_fuzzer.cc
+++ b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_fuzzer.cc
@@ -16,11 +16,11 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
static blink::BlinkFuzzerTestSupport test_support =
blink::BlinkFuzzerTestSupport();
- WTF::Vector<WTF::String> messages;
+ blink::PolicyParserMessageBuffer logger;
// TODO(csharrison): Be smarter about parsing this origin for performance.
scoped_refptr<const blink::SecurityOrigin> origin =
blink::SecurityOrigin::CreateFromString("https://example.com/");
blink::FeaturePolicyParser::ParseHeader(WTF::String(data, size), origin.get(),
- &messages);
+ logger);
return 0;
}
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser.cc b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser.cc
index 8bf93369dde..5712bb5dac8 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser.cc
+++ b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser.cc
@@ -9,7 +9,6 @@
#include <bitset>
#include "base/metrics/histogram_macros.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
-#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
@@ -25,15 +24,25 @@
namespace blink {
namespace {
+namespace internal {
+// Following is the intermediate represetnation(IR) of feature policy.
+// Parsing of syntax structures is done in this IR, but semantic checks, e.g.
+// whether feature_name is valid, are not yet performed.
+struct FeaturePolicyDeclarationNode {
+ String feature_name;
+ Vector<String> allowlist;
+};
+using FeaturePolicyNode = Vector<FeaturePolicyDeclarationNode>;
+} // namespace internal
class ParsingContext {
public:
- ParsingContext(Vector<String>* messages,
+ ParsingContext(PolicyParserMessageBuffer& logger,
scoped_refptr<const SecurityOrigin> self_origin,
scoped_refptr<const SecurityOrigin> src_origin,
const FeatureNameMap& feature_names,
FeaturePolicyParserDelegate* delegate)
- : messages_(messages),
+ : logger_(logger),
self_origin_(self_origin),
src_origin_(src_origin),
feature_names_(feature_names),
@@ -44,14 +53,15 @@ class ParsingContext {
ParsedFeaturePolicy Parse(const String& policy);
private:
+ ParsedFeaturePolicy ParseIR(const internal::FeaturePolicyNode& root);
+ internal::FeaturePolicyNode ParseToIR(const String& policy);
+
// normally 1 char = 1 byte
// max length to parse = 2^16 = 64 kB
static constexpr wtf_size_t MAX_LENGTH_PARSE = 1 << 16;
- // Parse a single feature entry. e.g. feature_a ORIGIN_A ORIGIN_B.
- // feature_entry = feature_name ' ' allowlist
base::Optional<ParsedFeaturePolicyDeclaration> ParseFeature(
- const String& input);
+ const internal::FeaturePolicyDeclarationNode&);
struct ParsedAllowlist {
std::vector<url::Origin> allowed_origins;
@@ -68,11 +78,6 @@ class ParsingContext {
// Parse allowlist for feature.
ParsedAllowlist ParseAllowlist(const Vector<String>& origin_strings);
- inline void Log(const String& message) {
- if (messages_)
- messages_->push_back(message);
- }
-
bool FeatureObserved(mojom::blink::FeaturePolicyFeature feature);
void ReportFeaturePolicyWebFeatureUsage(mojom::blink::WebFeature feature);
@@ -90,7 +95,7 @@ class ParsingContext {
// yet.
void ReportAllowlistTypeUsage();
- Vector<String>* messages_;
+ PolicyParserMessageBuffer& logger_;
scoped_refptr<const SecurityOrigin> self_origin_;
scoped_refptr<const SecurityOrigin> src_origin_;
const FeatureNameMap& feature_names_;
@@ -189,11 +194,12 @@ base::Optional<mojom::blink::FeaturePolicyFeature>
ParsingContext::ParseFeatureName(const String& feature_name) {
DCHECK(!feature_name.IsEmpty());
if (!feature_names_.Contains(feature_name)) {
- Log("Unrecognized feature: '" + feature_name + "'.");
+ logger_.Warn("Unrecognized feature: '" + feature_name + "'.");
return base::nullopt;
}
if (DisabledByOriginTrial(feature_name, delegate_)) {
- Log("Origin trial controlled feature not enabled: '" + feature_name + "'.");
+ logger_.Warn("Origin trial controlled feature not enabled: '" +
+ feature_name + "'.");
return base::nullopt;
}
mojom::blink::FeaturePolicyFeature feature = feature_names_.at(feature_name);
@@ -224,7 +230,7 @@ ParsingContext::ParsedAllowlist ParsingContext::ParseAllowlist(
DCHECK(!origin_string.IsEmpty());
if (!origin_string.ContainsOnlyASCIIOrEmpty()) {
- Log("Non-ASCII characters in origin.");
+ logger_.Warn("Non-ASCII characters in origin.");
continue;
}
@@ -274,7 +280,7 @@ ParsingContext::ParsedAllowlist ParsingContext::ParseAllowlist(
target_origin = parsed_origin->ToUrlOrigin();
allowlist_includes_origin_ = true;
} else {
- Log("Unrecognized origin: '" + origin_string + "'.");
+ logger_.Warn("Unrecognized origin: '" + origin_string + "'.");
continue;
}
}
@@ -303,31 +309,14 @@ ParsingContext::ParsedAllowlist ParsingContext::ParseAllowlist(
}
base::Optional<ParsedFeaturePolicyDeclaration> ParsingContext::ParseFeature(
- const String& input) {
- // Split removes extra whitespaces by default
- Vector<String> tokens;
- input.Split(' ', tokens);
-
- // Empty policy. Skip.
- if (tokens.IsEmpty())
- return base::nullopt;
-
- // Break tokens into head & tail, where
- // head = feature_name
- // tail = origins
- // After feature_name has been parsed, take tail of tokens vector by
- // erasing the first element.
+ const internal::FeaturePolicyDeclarationNode& declaration_node) {
base::Optional<mojom::blink::FeaturePolicyFeature> feature =
- ParseFeatureName(/* feature_name */ tokens.front());
-
- tokens.erase(tokens.begin());
-
- ParsedAllowlist parsed_allowlist =
- ParseAllowlist(/* origin_strings */ tokens);
-
+ ParseFeatureName(declaration_node.feature_name);
if (!feature)
return base::nullopt;
+ ParsedAllowlist parsed_allowlist = ParseAllowlist(declaration_node.allowlist);
+
// If same feature appeared more than once, only the first one counts.
if (FeatureObserved(*feature))
return base::nullopt;
@@ -341,13 +330,32 @@ base::Optional<ParsedFeaturePolicyDeclaration> ParsingContext::ParseFeature(
}
ParsedFeaturePolicy ParsingContext::Parse(const String& policy) {
+ return ParseIR(ParseToIR(policy));
+}
+
+ParsedFeaturePolicy ParsingContext::ParseIR(
+ const internal::FeaturePolicyNode& root) {
ParsedFeaturePolicy parsed_policy;
+ for (const internal::FeaturePolicyDeclarationNode& declaration_node : root) {
+ base::Optional<ParsedFeaturePolicyDeclaration> parsed_feature =
+ ParseFeature(declaration_node);
+ if (parsed_feature) {
+ ReportFeatureUsage(parsed_feature->feature);
+ parsed_policy.push_back(*parsed_feature);
+ }
+ }
+ ReportAllowlistTypeUsage();
+ return parsed_policy;
+}
+
+internal::FeaturePolicyNode ParsingContext::ParseToIR(const String& policy) {
+ internal::FeaturePolicyNode root;
if (policy.length() > MAX_LENGTH_PARSE) {
- Log("Feature policy declaration exceeds size limit(" +
- String::Number(policy.length()) + ">" +
- String::Number(MAX_LENGTH_PARSE) + ")");
- return parsed_policy;
+ logger_.Error("Feature policy declaration exceeds size limit(" +
+ String::Number(policy.length()) + ">" +
+ String::Number(MAX_LENGTH_PARSE) + ")");
+ return {};
}
// RFC2616, section 4.2 specifies that headers appearing multiple times can be
@@ -374,18 +382,26 @@ ParsedFeaturePolicy ParsingContext::Parse(const String& policy) {
}
for (const String& feature_entry : feature_entries) {
- base::Optional<ParsedFeaturePolicyDeclaration> parsed_feature =
- ParseFeature(feature_entry);
- if (parsed_feature) {
- ReportFeatureUsage(parsed_feature->feature);
- parsed_policy.push_back(*parsed_feature);
- }
+ Vector<String> tokens;
+ feature_entry.Split(' ', tokens);
+
+ if (tokens.IsEmpty())
+ continue;
+
+ internal::FeaturePolicyDeclarationNode declaration_node;
+ // Break tokens into head & tail, where
+ // head = feature_name
+ // tail = allowlist
+ // After feature_name has been set, take tail of tokens vector by
+ // erasing the first element.
+ declaration_node.feature_name = std::move(tokens.front());
+ tokens.erase(tokens.begin());
+ declaration_node.allowlist = std::move(tokens);
+ root.push_back(declaration_node);
}
}
- ReportAllowlistTypeUsage();
-
- return parsed_policy;
+ return root;
}
} // namespace
@@ -393,9 +409,9 @@ ParsedFeaturePolicy ParsingContext::Parse(const String& policy) {
ParsedFeaturePolicy FeaturePolicyParser::ParseHeader(
const String& policy,
scoped_refptr<const SecurityOrigin> origin,
- Vector<String>* messages,
+ PolicyParserMessageBuffer& logger,
FeaturePolicyParserDelegate* delegate) {
- return Parse(policy, origin, nullptr, messages, GetDefaultFeatureNameMap(),
+ return Parse(policy, origin, nullptr, logger, GetDefaultFeatureNameMap(),
delegate);
}
@@ -403,10 +419,10 @@ ParsedFeaturePolicy FeaturePolicyParser::ParseAttribute(
const String& policy,
scoped_refptr<const SecurityOrigin> self_origin,
scoped_refptr<const SecurityOrigin> src_origin,
- Vector<String>* messages,
- Document* document) {
- return Parse(policy, self_origin, src_origin, messages,
- GetDefaultFeatureNameMap(), document);
+ PolicyParserMessageBuffer& logger,
+ FeaturePolicyParserDelegate* delegate) {
+ return Parse(policy, self_origin, src_origin, logger,
+ GetDefaultFeatureNameMap(), delegate);
}
// static
@@ -414,10 +430,10 @@ ParsedFeaturePolicy FeaturePolicyParser::Parse(
const String& policy,
scoped_refptr<const SecurityOrigin> self_origin,
scoped_refptr<const SecurityOrigin> src_origin,
- Vector<String>* messages,
+ PolicyParserMessageBuffer& logger,
const FeatureNameMap& feature_names,
FeaturePolicyParserDelegate* delegate) {
- return ParsingContext(messages, self_origin, src_origin, feature_names,
+ return ParsingContext(logger, self_origin, src_origin, feature_names,
delegate)
.Parse(policy);
}
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser.h b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser.h
index 18b37104b47..5c7bcf73ec3 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser.h
+++ b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser.h
@@ -18,7 +18,6 @@
namespace blink {
-class Document;
class ExecutionContext;
class FeaturePolicyParserDelegate;
@@ -54,30 +53,27 @@ class CORE_EXPORT FeaturePolicyParser {
public:
// Converts a header policy string into a vector of allowlists, one for each
- // feature specified. Unrecognized features are filtered out. If |messages| is
- // not null, then any message in the input will cause a warning message to be
- // appended to it. The optional ExecutionContext is used to determine if any
- // origin trials affect the parsing.
- // Example of a feature policy string:
+ // feature specified. Unrecognized features are filtered out. The optional
+ // ExecutionContext is used to determine if any origin trials affect the
+ // parsing. Example of a feature policy string:
// "vibrate a.com b.com; fullscreen 'none'; payment 'self', payment *".
static ParsedFeaturePolicy ParseHeader(
const String& policy,
scoped_refptr<const SecurityOrigin>,
- Vector<String>* messages,
+ PolicyParserMessageBuffer& logger,
FeaturePolicyParserDelegate* delegate = nullptr);
// Converts a container policy string into a vector of allowlists, given self
// and src origins provided, one for each feature specified. Unrecognized
- // features are filtered out. If |messages| is not null, then any message in
- // the input will cause as warning message to be appended to it. Example of a
+ // features are filtered out. Example of a
// feature policy string:
// "vibrate a.com 'src'; fullscreen 'none'; payment 'self', payment *".
static ParsedFeaturePolicy ParseAttribute(
const String& policy,
scoped_refptr<const SecurityOrigin> self_origin,
scoped_refptr<const SecurityOrigin> src_origin,
- Vector<String>* messages,
- Document* document = nullptr);
+ PolicyParserMessageBuffer& logger,
+ FeaturePolicyParserDelegate* delegate = nullptr);
// Converts a feature policy string into a vector of allowlists (see comments
// above), with an explicit FeatureNameMap. This algorithm is called by both
@@ -89,7 +85,7 @@ class CORE_EXPORT FeaturePolicyParser {
const String& policy,
scoped_refptr<const SecurityOrigin> self_origin,
scoped_refptr<const SecurityOrigin> src_origin,
- Vector<String>* messages,
+ PolicyParserMessageBuffer& logger,
const FeatureNameMap& feature_names,
FeaturePolicyParserDelegate* delegate = nullptr);
};
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_test.cc b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_test.cc
index 341e364e72b..7f8639a5c9b 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_test.cc
+++ b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_test.cc
@@ -9,6 +9,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
@@ -21,6 +22,7 @@
#define ORIGIN_A "https://example.com/"
#define ORIGIN_B "https://example.net/"
#define ORIGIN_C "https://example.org/"
+#define OPAQUE_ORIGIN ""
class GURL;
@@ -72,7 +74,7 @@ const char kAllowlistHeaderHistogram[] =
} // namespace
-class FeaturePolicyParserTest : public testing::Test {
+class FeaturePolicyParserTest : public ::testing::Test {
protected:
FeaturePolicyParserTest() = default;
@@ -95,237 +97,339 @@ class FeaturePolicyParserTest : public testing::Test {
{"geolocation", blink::mojom::blink::FeaturePolicyFeature::kGeolocation}};
};
+struct ParsedPolicyDeclarationForTest {
+ mojom::blink::FeaturePolicyFeature feature;
+ bool fallback_value;
+ bool opaque_value;
+ std::vector<const char*> origins;
+};
+
+using ParsedPolicyForTest = std::vector<ParsedPolicyDeclarationForTest>;
+
+struct FeaturePolicyParserTestCase {
+ const char* test_name;
+
+ // Test inputs.
+ const char* policy_string;
+ const char* self_origin;
+ const char* src_origin;
+
+ // Test expectation.
+ ParsedPolicyForTest expected_parse_result;
+};
+
+class FeaturePolicyParserParsingTest
+ : public FeaturePolicyParserTest,
+ public ::testing::WithParamInterface<FeaturePolicyParserTestCase> {
+ protected:
+ ParsedFeaturePolicy Parse(const char* policy_string,
+ const char* self_origin_string,
+ const char* src_origin_string,
+ PolicyParserMessageBuffer& logger,
+ const FeatureNameMap& feature_names) {
+ scoped_refptr<const SecurityOrigin> self_origin =
+ SecurityOrigin::CreateFromString(self_origin_string);
+
+ scoped_refptr<const SecurityOrigin> src_origin;
+ if (String(src_origin_string) == OPAQUE_ORIGIN) {
+ src_origin = SecurityOrigin::CreateUniqueOpaque();
+ } else {
+ src_origin = src_origin_string
+ ? SecurityOrigin::CreateFromString(src_origin_string)
+ : nullptr;
+ }
+
+ return FeaturePolicyParser::Parse(policy_string, self_origin, src_origin,
+ logger, feature_names);
+ }
+
+ public:
+ static const FeaturePolicyParserTestCase kCases[];
+};
+
+const FeaturePolicyParserTestCase FeaturePolicyParserParsingTest::kCases[] = {
+ {
+ /* test_name */ "EmptyPolicy",
+ /* policy_string */ "",
+ /* self_origin */ ORIGIN_A,
+ /* src_origin */ ORIGIN_B,
+ /* expected_parse_result */ {},
+ },
+ {
+ /* test_name */ "SimplePolicyWithSelf",
+ /* policy_string */ "geolocation 'self'",
+ /* self_origin */ ORIGIN_A,
+ /* src_origin */ ORIGIN_B,
+ /* expected_parse_result */
+ {
+ {
+ mojom::blink::FeaturePolicyFeature::kGeolocation,
+ /* fallback_value */ false,
+ /* opaque_value */ false,
+ {ORIGIN_A},
+ },
+ },
+ },
+ {
+ /* test_name */ "SimplePolicyWithStar",
+ /* policy_string */ "geolocation *",
+ /* self_origin */ ORIGIN_A,
+ /* src_origin */ ORIGIN_B,
+ /* expected_parse_result */
+ {
+ {
+ mojom::blink::FeaturePolicyFeature::kGeolocation,
+ /* fallback_value */ true,
+ /* opaque_value */ true,
+ {},
+ },
+ },
+ },
+ {
+ /* test_name */ "ComplicatedPolicy",
+ /* policy_string */
+ "geolocation *; "
+ "fullscreen " ORIGIN_B " " ORIGIN_C "; "
+ "payment 'self'",
+ /* self_origin */ ORIGIN_A,
+ /* src_origin */ ORIGIN_B,
+ /* expected_parse_result */
+ {
+ {
+ mojom::blink::FeaturePolicyFeature::kGeolocation,
+ /* fallback_value */ true,
+ /* opaque_value */ true,
+ {},
+ },
+ {
+ mojom::blink::FeaturePolicyFeature::kFullscreen,
+ /* fallback_value */ false,
+ /* opaque_value */ false,
+ {ORIGIN_B, ORIGIN_C},
+ },
+ {
+ mojom::blink::FeaturePolicyFeature::kPayment,
+ /* fallback_value */ false,
+ /* opaque_value */ false,
+ {ORIGIN_A},
+ },
+ },
+ },
+ {
+ /* test_name */ "MultiplePolicies",
+ /* policy_string */
+ "geolocation * " ORIGIN_B "; "
+ "fullscreen " ORIGIN_B " none " ORIGIN_C ","
+ "payment 'self' badorigin",
+ /* self_origin */ ORIGIN_A,
+ /* src_origin */ ORIGIN_B,
+ /* expected_parse_result */
+ {
+ {
+ mojom::blink::FeaturePolicyFeature::kGeolocation,
+ /* fallback_value */ true,
+ /* opaque_value */ true,
+ {},
+ },
+ {
+ mojom::blink::FeaturePolicyFeature::kFullscreen,
+ /* fallback_value */ false,
+ /* opaque_value */ false,
+ {ORIGIN_B, ORIGIN_C},
+ },
+ {
+ mojom::blink::FeaturePolicyFeature::kPayment,
+ /* fallback_value */ false,
+ /* opaque_value */ false,
+ {ORIGIN_A},
+ },
+ },
+ },
+ {
+ /* test_name */ "HeaderPoliciesWithNoOptionalOriginLists",
+ /* policy_string */ "geolocation;fullscreen;payment",
+ /* self_origin */ ORIGIN_A,
+ /* src_origin */ nullptr,
+ /* expected_parse_result */
+ {
+ {
+ mojom::blink::FeaturePolicyFeature::kGeolocation,
+ /* fallback_value */ false,
+ /* opaque_value */ false,
+ {ORIGIN_A},
+ },
+ {
+ mojom::blink::FeaturePolicyFeature::kFullscreen,
+ /* fallback_value */ false,
+ /* opaque_value */ false,
+ {ORIGIN_A},
+ },
+ {
+ mojom::blink::FeaturePolicyFeature::kPayment,
+ /* fallback_value */ false,
+ /* opaque_value */ false,
+ {ORIGIN_A},
+ },
+ },
+ },
+ {
+ /* test_name */ "EmptyPolicyOpaqueSrcOrigin",
+ /* policy_string */ "",
+ /* self_origin */ ORIGIN_A,
+ /* src_origin */ OPAQUE_ORIGIN,
+ /* expected_parse_result */ {},
+ },
+ {
+ /* test_name */ "SimplePolicyOpaqueSrcOrigin",
+ /* policy_string */ "geolocation",
+ /* self_origin */ ORIGIN_A,
+ /* src_origin */ OPAQUE_ORIGIN,
+ /* expected_parse_result */
+ {
+ {
+ mojom::blink::FeaturePolicyFeature::kGeolocation,
+ /* fallback_value */ false,
+ /* opaque_value */ true,
+ {},
+ },
+ },
+ },
+ {
+ /* test_name */ "SimplePolicyWithSrcOpaqueSrcOrigin",
+ /* policy_string */ "geolocation 'src'",
+ /* self_origin */ ORIGIN_A,
+ /* src_origin */ OPAQUE_ORIGIN,
+ /* expected_parse_result */
+ {
+ {
+ mojom::blink::FeaturePolicyFeature::kGeolocation,
+ /* fallback_value */ false,
+ /* opaque_value */ true,
+ {},
+ },
+ },
+ },
+ {
+ /* test_name */ "SimplePolicyWithStarOpaqueSrcOrigin",
+ /* policy_string */ "geolocation *",
+ /* self_origin */ ORIGIN_A,
+ /* src_origin */ OPAQUE_ORIGIN,
+ /* expected_parse_result */
+ {
+ {
+ mojom::blink::FeaturePolicyFeature::kGeolocation,
+ /* fallback_value */ true,
+ /* opaque_value */ true,
+ {},
+ },
+ },
+ },
+ {
+ /* test_name */ "PolicyWithExplicitOriginsOpaqueSrcOrigin",
+ /* policy_string */ "geolocation " ORIGIN_B " " ORIGIN_C,
+ /* self_origin */ ORIGIN_A,
+ /* src_origin */ OPAQUE_ORIGIN,
+ /* expected_parse_result */
+ {
+ {
+ mojom::blink::FeaturePolicyFeature::kGeolocation,
+ /* fallback_value */ false,
+ /* opaque_value */ false,
+ {ORIGIN_B, ORIGIN_C},
+ },
+ },
+ },
+ {
+ /* test_name */ "PolicyWithMultipleOriginsIncludingSrc"
+ "OpaqueSrcOrigin",
+ /* policy_string */ "geolocation " ORIGIN_B " 'src'",
+ /* self_origin */ ORIGIN_A,
+ /* src_origin */ OPAQUE_ORIGIN,
+ /* expected_parse_result */
+ {
+ {
+ mojom::blink::FeaturePolicyFeature::kGeolocation,
+ /* fallback_value */ false,
+ /* opaque_value */ true,
+ {ORIGIN_B},
+ },
+ },
+ },
+};
+
+INSTANTIATE_TEST_SUITE_P(
+ All,
+ FeaturePolicyParserParsingTest,
+ ::testing::ValuesIn(FeaturePolicyParserParsingTest::kCases),
+ [](const testing::TestParamInfo<FeaturePolicyParserTestCase>& param_info) {
+ return param_info.param.test_name;
+ });
+
+TEST_P(FeaturePolicyParserParsingTest, PolicyParsedCorrectly) {
+ PolicyParserMessageBuffer logger;
+ const FeaturePolicyParserTestCase& test_case = GetParam();
+ ASSERT_NE(test_case.self_origin, nullptr);
+ const ParsedFeaturePolicy actual =
+ Parse(test_case.policy_string, test_case.self_origin,
+ test_case.src_origin, logger, test_feature_name_map);
+ const ParsedPolicyForTest& expected = test_case.expected_parse_result;
+ ASSERT_EQ(actual.size(), expected.size());
+ for (size_t i = 0; i < actual.size(); ++i) {
+ const auto& actual_declaration = actual[i];
+ const auto& expected_declaration = expected[i];
+
+ EXPECT_EQ(actual_declaration.feature, expected_declaration.feature);
+ EXPECT_EQ(actual_declaration.fallback_value,
+ expected_declaration.fallback_value);
+ EXPECT_EQ(actual_declaration.opaque_value,
+ expected_declaration.opaque_value);
+
+ ASSERT_EQ(actual_declaration.allowed_origins.size(),
+ expected_declaration.origins.size());
+ for (size_t j = 0; j < actual_declaration.allowed_origins.size(); ++j) {
+ EXPECT_TRUE(actual_declaration.allowed_origins[j].IsSameOriginWith(
+ url::Origin::Create(GURL(expected_declaration.origins[j]))));
+ }
+ }
+}
+
TEST_F(FeaturePolicyParserTest, ParseValidPolicy) {
- Vector<String> messages;
for (const char* policy_string : kValidPolicies) {
- messages.clear();
+ PolicyParserMessageBuffer logger;
FeaturePolicyParser::Parse(policy_string, origin_a_.get(), origin_b_.get(),
- &messages, test_feature_name_map);
- EXPECT_EQ(0UL, messages.size()) << "Should parse " << policy_string;
+ logger, test_feature_name_map);
+ EXPECT_EQ(0UL, logger.GetMessages().size())
+ << "Should parse " << policy_string;
}
}
TEST_F(FeaturePolicyParserTest, ParseInvalidPolicy) {
- Vector<String> messages;
for (const char* policy_string : kInvalidPolicies) {
- messages.clear();
+ PolicyParserMessageBuffer logger;
FeaturePolicyParser::Parse(policy_string, origin_a_.get(), origin_b_.get(),
- &messages, test_feature_name_map);
- EXPECT_LT(0UL, messages.size()) << "Should fail to parse " << policy_string;
+ logger, test_feature_name_map);
+ EXPECT_LT(0UL, logger.GetMessages().size())
+ << "Should fail to parse " << policy_string;
}
}
TEST_F(FeaturePolicyParserTest, ParseTooLongPolicy) {
- Vector<String> messages;
+ PolicyParserMessageBuffer logger;
auto policy_string = "geolocation http://" + std::string(1 << 17, 'a');
FeaturePolicyParser::Parse(policy_string.c_str(), origin_a_.get(),
- origin_b_.get(), &messages, test_feature_name_map);
- EXPECT_EQ(1UL, messages.size())
+ origin_b_.get(), logger, test_feature_name_map);
+ EXPECT_EQ(1UL, logger.GetMessages().size())
<< "Should fail to parse string with size " << policy_string.size();
}
-TEST_F(FeaturePolicyParserTest, PolicyParsedCorrectly) {
- Vector<String> messages;
-
- // Empty policy.
- ParsedFeaturePolicy parsed_policy = FeaturePolicyParser::Parse(
- "", origin_a_.get(), origin_b_.get(), &messages, test_feature_name_map);
- EXPECT_EQ(0UL, parsed_policy.size());
-
- // Simple policy with 'self'.
- parsed_policy = FeaturePolicyParser::Parse("geolocation 'self'",
- origin_a_.get(), origin_b_.get(),
- &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
- parsed_policy[0].feature);
- EXPECT_FALSE(parsed_policy[0].fallback_value);
- EXPECT_FALSE(parsed_policy[0].opaque_value);
- EXPECT_EQ(1UL, parsed_policy[0].allowed_origins.size());
- EXPECT_TRUE(parsed_policy[0].allowed_origins.begin()->IsSameOriginWith(
- expected_url_origin_a_));
-
- // Simple policy with *.
- parsed_policy = FeaturePolicyParser::Parse("geolocation *", origin_a_.get(),
- origin_b_.get(), &messages,
- test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
- parsed_policy[0].feature);
- EXPECT_TRUE(parsed_policy[0].fallback_value);
- EXPECT_TRUE(parsed_policy[0].opaque_value);
- EXPECT_EQ(0UL, parsed_policy[0].allowed_origins.size());
-
- // Complicated policy.
- parsed_policy = FeaturePolicyParser::Parse(
- "geolocation *; "
- "fullscreen https://example.net https://example.org; "
- "payment 'self'",
- origin_a_.get(), origin_b_.get(), &messages, test_feature_name_map);
- EXPECT_EQ(3UL, parsed_policy.size());
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
- parsed_policy[0].feature);
- EXPECT_TRUE(parsed_policy[0].fallback_value);
- EXPECT_TRUE(parsed_policy[0].opaque_value);
- EXPECT_EQ(0UL, parsed_policy[0].allowed_origins.size());
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
- parsed_policy[1].feature);
- EXPECT_FALSE(parsed_policy[1].fallback_value);
- EXPECT_FALSE(parsed_policy[1].opaque_value);
- EXPECT_EQ(2UL, parsed_policy[1].allowed_origins.size());
- auto it = parsed_policy[1].allowed_origins.begin();
- EXPECT_TRUE(it->IsSameOriginWith(expected_url_origin_b_));
- EXPECT_TRUE((++it)->IsSameOriginWith(expected_url_origin_c_));
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kPayment,
- parsed_policy[2].feature);
- EXPECT_FALSE(parsed_policy[2].fallback_value);
- EXPECT_FALSE(parsed_policy[2].opaque_value);
- EXPECT_EQ(1UL, parsed_policy[2].allowed_origins.size());
- EXPECT_TRUE(parsed_policy[2].allowed_origins.begin()->IsSameOriginWith(
- expected_url_origin_a_));
-
- // Multiple policies.
- parsed_policy = FeaturePolicyParser::Parse(
- "geolocation * https://example.net; "
- "fullscreen https://example.net none https://example.org,"
- "payment 'self' badorigin",
- origin_a_.get(), origin_b_.get(), &messages, test_feature_name_map);
- EXPECT_EQ(3UL, parsed_policy.size());
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
- parsed_policy[0].feature);
- EXPECT_TRUE(parsed_policy[0].fallback_value);
- EXPECT_TRUE(parsed_policy[0].opaque_value);
- EXPECT_EQ(0UL, parsed_policy[0].allowed_origins.size());
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
- parsed_policy[1].feature);
- EXPECT_FALSE(parsed_policy[1].fallback_value);
- EXPECT_FALSE(parsed_policy[1].opaque_value);
- EXPECT_EQ(2UL, parsed_policy[1].allowed_origins.size());
- it = parsed_policy[1].allowed_origins.begin();
- EXPECT_TRUE(it->IsSameOriginWith(expected_url_origin_b_));
- EXPECT_TRUE((++it)->IsSameOriginWith(expected_url_origin_c_));
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kPayment,
- parsed_policy[2].feature);
- EXPECT_FALSE(parsed_policy[2].fallback_value);
- EXPECT_FALSE(parsed_policy[2].opaque_value);
- EXPECT_EQ(1UL, parsed_policy[2].allowed_origins.size());
- EXPECT_TRUE(parsed_policy[2].allowed_origins.begin()->IsSameOriginWith(
- expected_url_origin_a_));
-
- // Header policies with no optional origin lists.
- parsed_policy = FeaturePolicyParser::Parse("geolocation;fullscreen;payment",
- origin_a_.get(), nullptr,
- &messages, test_feature_name_map);
- EXPECT_EQ(3UL, parsed_policy.size());
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
- parsed_policy[0].feature);
- EXPECT_FALSE(parsed_policy[0].fallback_value);
- EXPECT_FALSE(parsed_policy[0].opaque_value);
- EXPECT_EQ(1UL, parsed_policy[0].allowed_origins.size());
- EXPECT_TRUE(parsed_policy[0].allowed_origins.begin()->IsSameOriginWith(
- expected_url_origin_a_));
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
- parsed_policy[1].feature);
- EXPECT_FALSE(parsed_policy[1].fallback_value);
- EXPECT_FALSE(parsed_policy[1].opaque_value);
- EXPECT_EQ(1UL, parsed_policy[1].allowed_origins.size());
- EXPECT_TRUE(parsed_policy[1].allowed_origins.begin()->IsSameOriginWith(
- expected_url_origin_a_));
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kPayment,
- parsed_policy[2].feature);
- EXPECT_FALSE(parsed_policy[2].opaque_value);
- EXPECT_EQ(1UL, parsed_policy[2].allowed_origins.size());
- EXPECT_TRUE(parsed_policy[2].allowed_origins.begin()->IsSameOriginWith(
- expected_url_origin_a_));
-}
-
-TEST_F(FeaturePolicyParserTest, PolicyParsedCorrectlyForOpaqueOrigins) {
- Vector<String> messages;
-
- scoped_refptr<SecurityOrigin> opaque_origin =
- SecurityOrigin::CreateUniqueOpaque();
-
- // Empty policy.
- ParsedFeaturePolicy parsed_policy =
- FeaturePolicyParser::Parse("", origin_a_.get(), opaque_origin.get(),
- &messages, test_feature_name_map);
- EXPECT_EQ(0UL, parsed_policy.size());
-
- // Simple policy.
- parsed_policy = FeaturePolicyParser::Parse("geolocation", origin_a_.get(),
- opaque_origin.get(), &messages,
- test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
- parsed_policy[0].feature);
- EXPECT_FALSE(parsed_policy[0].fallback_value);
- EXPECT_TRUE(parsed_policy[0].opaque_value);
- EXPECT_EQ(0UL, parsed_policy[0].allowed_origins.size());
-
- // Simple policy with 'src'.
- parsed_policy = FeaturePolicyParser::Parse(
- "geolocation 'src'", origin_a_.get(), opaque_origin.get(), &messages,
- test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
- parsed_policy[0].feature);
- EXPECT_FALSE(parsed_policy[0].fallback_value);
- EXPECT_TRUE(parsed_policy[0].opaque_value);
- EXPECT_EQ(0UL, parsed_policy[0].allowed_origins.size());
-
- // Simple policy with *.
- parsed_policy = FeaturePolicyParser::Parse("geolocation *", origin_a_.get(),
- opaque_origin.get(), &messages,
- test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
- parsed_policy[0].feature);
- EXPECT_TRUE(parsed_policy[0].fallback_value);
- EXPECT_TRUE(parsed_policy[0].opaque_value);
- EXPECT_EQ(0UL, parsed_policy[0].allowed_origins.size());
-
- // Policy with explicit origins
- parsed_policy = FeaturePolicyParser::Parse(
- "geolocation https://example.net https://example.org", origin_a_.get(),
- opaque_origin.get(), &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
- parsed_policy[0].feature);
- EXPECT_FALSE(parsed_policy[0].fallback_value);
- EXPECT_FALSE(parsed_policy[0].opaque_value);
- EXPECT_EQ(2UL, parsed_policy[0].allowed_origins.size());
- auto it = parsed_policy[0].allowed_origins.begin();
- EXPECT_TRUE(it->IsSameOriginWith(expected_url_origin_b_));
- EXPECT_TRUE((++it)->IsSameOriginWith(expected_url_origin_c_));
-
- // Policy with multiple origins, including 'src'.
- parsed_policy = FeaturePolicyParser::Parse(
- "geolocation https://example.net 'src'", origin_a_.get(),
- opaque_origin.get(), &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
- parsed_policy[0].feature);
- EXPECT_FALSE(parsed_policy[0].fallback_value);
- EXPECT_TRUE(parsed_policy[0].opaque_value);
- EXPECT_EQ(1UL, parsed_policy[0].allowed_origins.size());
- EXPECT_TRUE(parsed_policy[0].allowed_origins.begin()->IsSameOriginWith(
- expected_url_origin_b_));
-}
-
// Test histogram counting the use of feature policies in header.
TEST_F(FeaturePolicyParserTest, HeaderHistogram) {
const char* histogram_name = "Blink.UseCounter.FeaturePolicy.Header";
HistogramTester tester;
- Vector<String> messages;
+ PolicyParserMessageBuffer logger;
FeaturePolicyParser::Parse("payment; fullscreen", origin_a_.get(), nullptr,
- &messages, test_feature_name_map);
+ logger, test_feature_name_map);
tester.ExpectTotalCount(histogram_name, 2);
tester.ExpectBucketCount(
histogram_name,
@@ -340,15 +444,15 @@ TEST_F(FeaturePolicyParserTest, HeaderHistogram) {
TEST_F(FeaturePolicyParserTest, HistogramMultiple) {
const char* histogram_name = "Blink.UseCounter.FeaturePolicy.Header";
HistogramTester tester;
- Vector<String> messages;
+ PolicyParserMessageBuffer logger;
// If the same feature is listed multiple times, it should only be counted
// once.
FeaturePolicyParser::Parse("geolocation 'self'; payment; geolocation *",
- origin_a_.get(), nullptr, &messages,
+ origin_a_.get(), nullptr, logger,
test_feature_name_map);
FeaturePolicyParser::Parse("fullscreen 'self', fullscreen *", origin_a_.get(),
- nullptr, &messages, test_feature_name_map);
+ nullptr, logger, test_feature_name_map);
tester.ExpectTotalCount(histogram_name, 3);
tester.ExpectBucketCount(
histogram_name,
@@ -365,15 +469,15 @@ TEST_F(FeaturePolicyParserTest, HistogramMultiple) {
TEST_F(FeaturePolicyParserTest, AllowHistogramSameDocument) {
const char* histogram_name = "Blink.UseCounter.FeaturePolicy.Allow";
HistogramTester tester;
- Vector<String> messages;
+ PolicyParserMessageBuffer logger;
auto dummy = std::make_unique<DummyPageHolder>();
FeaturePolicyParser::Parse("payment; fullscreen", origin_a_.get(),
- origin_b_.get(), &messages, test_feature_name_map,
- &dummy->GetDocument());
+ origin_b_.get(), logger, test_feature_name_map,
+ dummy->GetFrame().DomWindow());
FeaturePolicyParser::Parse("fullscreen; geolocation", origin_a_.get(),
- origin_b_.get(), &messages, test_feature_name_map,
- &dummy->GetDocument());
+ origin_b_.get(), logger, test_feature_name_map,
+ dummy->GetFrame().DomWindow());
tester.ExpectTotalCount(histogram_name, 3);
tester.ExpectBucketCount(
histogram_name,
@@ -393,16 +497,16 @@ TEST_F(FeaturePolicyParserTest, AllowHistogramSameDocument) {
TEST_F(FeaturePolicyParserTest, AllowHistogramDifferentDocument) {
const char* histogram_name = "Blink.UseCounter.FeaturePolicy.Allow";
HistogramTester tester;
- Vector<String> messages;
+ PolicyParserMessageBuffer logger;
auto dummy = std::make_unique<DummyPageHolder>();
auto dummy2 = std::make_unique<DummyPageHolder>();
FeaturePolicyParser::Parse("payment; fullscreen", origin_a_.get(),
- origin_b_.get(), &messages, test_feature_name_map,
- &dummy->GetDocument());
+ origin_b_.get(), logger, test_feature_name_map,
+ dummy->GetFrame().DomWindow());
FeaturePolicyParser::Parse("fullscreen; geolocation", origin_a_.get(),
- origin_b_.get(), &messages, test_feature_name_map,
- &dummy2->GetDocument());
+ origin_b_.get(), logger, test_feature_name_map,
+ dummy2->GetFrame().DomWindow());
tester.ExpectTotalCount(histogram_name, 4);
tester.ExpectBucketCount(
histogram_name,
@@ -419,13 +523,13 @@ TEST_F(FeaturePolicyParserTest, AllowHistogramDifferentDocument) {
// Tests the use counter for comma separator in declarations.
TEST_F(FeaturePolicyParserTest, CommaSeparatedUseCounter) {
- Vector<String> messages;
+ PolicyParserMessageBuffer logger;
// Declarations without a semicolon should not trigger the use counter.
{
auto dummy = std::make_unique<DummyPageHolder>();
- FeaturePolicyParser::ParseHeader("payment", origin_a_.get(), &messages,
- &dummy->GetDocument());
+ FeaturePolicyParser::ParseHeader("payment", origin_a_.get(), logger,
+ dummy->GetFrame().DomWindow());
EXPECT_FALSE(dummy->GetDocument().IsUseCounted(
WebFeature::kFeaturePolicyCommaSeparatedDeclarations));
}
@@ -434,7 +538,7 @@ TEST_F(FeaturePolicyParserTest, CommaSeparatedUseCounter) {
{
auto dummy = std::make_unique<DummyPageHolder>();
FeaturePolicyParser::ParseHeader("payment, fullscreen", origin_a_.get(),
- &messages, &dummy->GetDocument());
+ logger, dummy->GetFrame().DomWindow());
EXPECT_TRUE(dummy->GetDocument().IsUseCounted(
WebFeature::kFeaturePolicyCommaSeparatedDeclarations))
<< "'payment, fullscreen' should trigger the comma separated use "
@@ -444,13 +548,13 @@ TEST_F(FeaturePolicyParserTest, CommaSeparatedUseCounter) {
// Tests the use counter for semicolon separator in declarations.
TEST_F(FeaturePolicyParserTest, SemicolonSeparatedUseCounter) {
- Vector<String> messages;
+ PolicyParserMessageBuffer logger;
// Declarations without a semicolon should not trigger the use counter.
{
auto dummy = std::make_unique<DummyPageHolder>();
- FeaturePolicyParser::ParseHeader("payment", origin_a_.get(), &messages,
- &dummy->GetDocument());
+ FeaturePolicyParser::ParseHeader("payment", origin_a_.get(), logger,
+ dummy->GetFrame().DomWindow());
EXPECT_FALSE(dummy->GetDocument().IsUseCounted(
WebFeature::kFeaturePolicySemicolonSeparatedDeclarations));
}
@@ -459,7 +563,7 @@ TEST_F(FeaturePolicyParserTest, SemicolonSeparatedUseCounter) {
{
auto dummy = std::make_unique<DummyPageHolder>();
FeaturePolicyParser::ParseHeader("payment; fullscreen", origin_a_.get(),
- &messages, &dummy->GetDocument());
+ logger, dummy->GetFrame().DomWindow());
EXPECT_TRUE(dummy->GetDocument().IsUseCounted(
WebFeature::kFeaturePolicySemicolonSeparatedDeclarations))
<< "'payment; fullscreen' should trigger the semicolon separated use "
@@ -564,14 +668,14 @@ INSTANTIATE_TEST_SUITE_P(
});
TEST_P(FeaturePolicyAllowlistHistogramTest, HeaderHistogram) {
- Vector<String> messages;
+ PolicyParserMessageBuffer logger;
HistogramTester tester;
AllowlistHistogramData data = GetParam();
auto dummy = std::make_unique<DummyPageHolder>();
FeaturePolicyParser::ParseHeader(data.policy_declaration, origin_a_.get(),
- &messages, &dummy->GetDocument());
+ logger, dummy->GetFrame().DomWindow());
for (FeaturePolicyAllowlistType expected_bucket : data.expected_buckets) {
tester.ExpectBucketCount(kAllowlistHeaderHistogram,
static_cast<int>(expected_bucket), 1);
@@ -581,13 +685,13 @@ TEST_P(FeaturePolicyAllowlistHistogramTest, HeaderHistogram) {
}
TEST_F(FeaturePolicyAllowlistHistogramTest, MixedInHeaderHistogram) {
- Vector<String> messages;
+ PolicyParserMessageBuffer logger;
HistogramTester tester;
auto dummy = std::make_unique<DummyPageHolder>();
const char* declaration = "fullscreen *; geolocation 'self' " ORIGIN_A;
- FeaturePolicyParser::ParseHeader(declaration, origin_a_.get(), &messages,
- &dummy->GetDocument());
+ FeaturePolicyParser::ParseHeader(declaration, origin_a_.get(), logger,
+ dummy->GetFrame().DomWindow());
tester.ExpectBucketCount(kAllowlistHeaderHistogram,
static_cast<int>(FeaturePolicyAllowlistType::kStar),
@@ -600,15 +704,15 @@ TEST_F(FeaturePolicyAllowlistHistogramTest, MixedInHeaderHistogram) {
}
TEST_P(FeaturePolicyAllowlistHistogramTest, AttributeHistogram) {
- Vector<String> messages;
+ PolicyParserMessageBuffer logger;
HistogramTester tester;
AllowlistHistogramData data = GetParam();
auto dummy = std::make_unique<DummyPageHolder>();
FeaturePolicyParser::ParseAttribute(data.policy_declaration, origin_a_.get(),
- origin_b_.get(), &messages,
- &dummy->GetDocument());
+ origin_b_.get(), logger,
+ dummy->GetFrame().DomWindow());
for (FeaturePolicyAllowlistType expected_bucket : data.expected_buckets) {
tester.ExpectBucketCount(kAllowlistAttributeHistogram,
static_cast<int>(expected_bucket), 1);
@@ -618,14 +722,14 @@ TEST_P(FeaturePolicyAllowlistHistogramTest, AttributeHistogram) {
}
TEST_F(FeaturePolicyAllowlistHistogramTest, MixedInAttributeHistogram) {
- Vector<String> messages;
+ PolicyParserMessageBuffer logger;
HistogramTester tester;
auto dummy = std::make_unique<DummyPageHolder>();
const char* declaration = "fullscreen *; geolocation 'src' " ORIGIN_A;
FeaturePolicyParser::ParseAttribute(declaration, origin_a_.get(),
- origin_b_.get(), &messages,
- &dummy->GetDocument());
+ origin_b_.get(), logger,
+ dummy->GetFrame().DomWindow());
tester.ExpectBucketCount(kAllowlistAttributeHistogram,
static_cast<int>(FeaturePolicyAllowlistType::kStar),
@@ -638,14 +742,14 @@ TEST_F(FeaturePolicyAllowlistHistogramTest, MixedInAttributeHistogram) {
}
TEST_F(FeaturePolicyAllowlistHistogramTest, SrcInAttributeHistogram) {
- Vector<String> messages;
+ PolicyParserMessageBuffer logger;
HistogramTester tester;
auto dummy = std::make_unique<DummyPageHolder>();
const char* declaration = "fullscreen 'src'";
FeaturePolicyParser::ParseAttribute(declaration, origin_a_.get(),
- origin_b_.get(), &messages,
- &dummy->GetDocument());
+ origin_b_.get(), logger,
+ dummy->GetFrame().DomWindow());
tester.ExpectBucketCount(kAllowlistAttributeHistogram,
static_cast<int>(FeaturePolicyAllowlistType::kSrc),
@@ -879,23 +983,23 @@ TEST_F(FeaturePolicyViolationHistogramTest, PotentialViolation) {
"Blink.UseCounter.FeaturePolicy.PotentialViolation";
auto dummy_page_holder_ = std::make_unique<DummyPageHolder>();
// Probing feature state should not count.
- dummy_page_holder_->GetDocument().IsFeatureEnabled(
+ dummy_page_holder_->GetFrame().DomWindow()->IsFeatureEnabled(
mojom::blink::FeaturePolicyFeature::kPayment);
tester.ExpectTotalCount(histogram_name, 0);
// Checking the feature state with reporting intent should record a potential
// violation.
- dummy_page_holder_->GetDocument().IsFeatureEnabled(
+ dummy_page_holder_->GetFrame().DomWindow()->IsFeatureEnabled(
mojom::blink::FeaturePolicyFeature::kPayment,
ReportOptions::kReportOnFailure);
tester.ExpectTotalCount(histogram_name, 1);
// The potential violation for an already recorded violation does not count
// again.
- dummy_page_holder_->GetDocument().IsFeatureEnabled(
+ dummy_page_holder_->GetFrame().DomWindow()->IsFeatureEnabled(
mojom::blink::FeaturePolicyFeature::kPayment,
ReportOptions::kReportOnFailure);
tester.ExpectTotalCount(histogram_name, 1);
// Sanity check: check some other feature to increase the count.
- dummy_page_holder_->GetDocument().IsFeatureEnabled(
+ dummy_page_holder_->GetFrame().DomWindow()->IsFeatureEnabled(
mojom::blink::FeaturePolicyFeature::kFullscreen,
ReportOptions::kReportOnFailure);
tester.ExpectTotalCount(histogram_name, 2);
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/iframe_policy.h b/chromium/third_party/blink/renderer/core/feature_policy/iframe_policy.h
index 4ee1e44fe22..bff648b3294 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/iframe_policy.h
+++ b/chromium/third_party/blink/renderer/core/feature_policy/iframe_policy.h
@@ -38,7 +38,7 @@ class IFramePolicy final : public DOMFeaturePolicy {
container_policy, src_origin->ToUrlOrigin());
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(parent_document_);
DOMFeaturePolicy::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/policy_helper.h b/chromium/third_party/blink/renderer/core/feature_policy/policy_helper.h
index c7041b1238a..c0320c66261 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/policy_helper.h
+++ b/chromium/third_party/blink/renderer/core/feature_policy/policy_helper.h
@@ -7,11 +7,11 @@
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h"
-#include "third_party/blink/public/mojom/feature_policy/document_policy_feature.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/feature_policy/document_policy_feature.mojom-blink.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink-forward.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
-#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -60,11 +60,7 @@ class PolicyParserMessageBuffer {
using FeatureNameMap = HashMap<String, mojom::blink::FeaturePolicyFeature>;
-// TODO(crbug.com/1069021): Use WTF::HashSet as DocumentPolicyFeatureSet
-// container will cause unknown timeout in release build only.
-using DocumentPolicyFeatureSet =
- LinkedHashSet<mojom::blink::DocumentPolicyFeature,
- IntHash<mojom::blink::DocumentPolicyFeature>>;
+using DocumentPolicyFeatureSet = HashSet<mojom::blink::DocumentPolicyFeature>;
class FeatureContext;
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/policy_test.cc b/chromium/third_party/blink/renderer/core/feature_policy/policy_test.cc
index 0630be0a044..869bc616961 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/policy_test.cc
+++ b/chromium/third_party/blink/renderer/core/feature_policy/policy_test.cc
@@ -28,13 +28,13 @@ class PolicyTest : public testing::Test {
page_holder_ = std::make_unique<DummyPageHolder>();
auto origin = SecurityOrigin::CreateFromString(kSelfOrigin);
- Vector<String> messages;
+
auto feature_policy = FeaturePolicy::CreateFromParentPolicy(
nullptr, ParsedFeaturePolicy(), origin->ToUrlOrigin());
auto header = FeaturePolicyParser::ParseHeader(
"fullscreen *; payment 'self'; midi 'none'; camera 'self' "
"https://example.com https://example.net",
- origin.get(), &messages);
+ origin.get(), dummy_logger_);
feature_policy->SetHeaderPolicy(header);
auto& security_context = page_holder_->GetDocument().GetSecurityContext();
@@ -44,6 +44,9 @@ class PolicyTest : public testing::Test {
DOMFeaturePolicy* GetPolicy() const { return policy_; }
+ PolicyParserMessageBuffer dummy_logger_ =
+ PolicyParserMessageBuffer("", true /* discard_message */);
+
protected:
std::unique_ptr<DummyPageHolder> page_holder_;
Persistent<Document> document_;
@@ -170,7 +173,7 @@ TEST_F(IFramePolicyTest, TestCombinedPolicy) {
ParsedFeaturePolicy container_policy = FeaturePolicyParser::ParseAttribute(
"geolocation 'src'; payment 'none'; midi; camera 'src'",
SecurityOrigin::CreateFromString(kSelfOrigin),
- SecurityOrigin::CreateFromString(kOriginA), nullptr);
+ SecurityOrigin::CreateFromString(kOriginA), dummy_logger_);
GetPolicy()->UpdateContainerPolicy(
container_policy, SecurityOrigin::CreateFromString(kOriginA));
Vector<String> allowed_features = GetPolicy()->allowedFeatures(nullptr);
diff --git a/chromium/third_party/blink/renderer/core/fetch/BUILD.gn b/chromium/third_party/blink/renderer/core/fetch/BUILD.gn
index 596433ac5ea..5b2297669c1 100644
--- a/chromium/third_party/blink/renderer/core/fetch/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/fetch/BUILD.gn
@@ -14,6 +14,8 @@ blink_core_sources("fetch") {
"body_stream_buffer.h",
"bytes_consumer_tee.cc",
"bytes_consumer_tee.h",
+ "bytes_uploader.cc",
+ "bytes_uploader.h",
"fetch_data_loader.cc",
"fetch_data_loader.h",
"fetch_header_list.cc",
diff --git a/chromium/third_party/blink/renderer/core/fetch/DEPS b/chromium/third_party/blink/renderer/core/fetch/DEPS
index 82e8abc9aab..b43df3036d0 100644
--- a/chromium/third_party/blink/renderer/core/fetch/DEPS
+++ b/chromium/third_party/blink/renderer/core/fetch/DEPS
@@ -3,8 +3,16 @@ include_rules = [
"+mojo/public/cpp/system/data_pipe.h",
"+mojo/public/cpp/system/data_pipe_utils.h",
"+mojo/public/cpp/system/simple_watcher.h",
+ "+net/base/net_errors.h",
"+net/base/request_priority.h",
+ "+net/http/http_response_info.h",
"+services/network/public/cpp",
"+services/network/public/mojom",
"+url/gurl.h",
]
+
+specific_include_rules = {
+ "bytes_uploader_test\.cc": [
+ "+base/test/mock_callback.h",
+ ],
+}
diff --git a/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.cc b/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.cc
index 148926a43aa..2c7713ace06 100644
--- a/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.cc
@@ -99,7 +99,7 @@ BytesConsumer::PublicState BlobBytesConsumer::GetPublicState() const {
return nested_consumer_->GetPublicState();
}
-void BlobBytesConsumer::Trace(Visitor* visitor) {
+void BlobBytesConsumer::Trace(Visitor* visitor) const {
visitor->Trace(execution_context_);
visitor->Trace(nested_consumer_);
visitor->Trace(client_);
diff --git a/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.h b/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.h
index 4cc789a8858..6c125ef6d54 100644
--- a/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.h
+++ b/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.h
@@ -37,7 +37,7 @@ class CORE_EXPORT BlobBytesConsumer final : public BytesConsumer {
Error GetError() const override;
String DebugName() const override { return "BlobBytesConsumer"; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<ExecutionContext> execution_context_;
diff --git a/chromium/third_party/blink/renderer/core/fetch/body.cc b/chromium/third_party/blink/renderer/core/fetch/body.cc
index 437db5482c5..28635ccf614 100644
--- a/chromium/third_party/blink/renderer/core/fetch/body.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/body.cc
@@ -64,7 +64,7 @@ class BodyConsumerBase : public GarbageCollected<BodyConsumerBase>,
WrapPersistent(this), object));
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(resolver_);
FetchDataLoader::Client::Trace(visitor);
}
@@ -162,7 +162,7 @@ class BodyJsonConsumer final : public BodyConsumerBase {
ScriptPromise Body::arrayBuffer(ScriptState* script_state,
ExceptionState& exception_state) {
- RejectInvalidConsumption(script_state, exception_state);
+ RejectInvalidConsumption(exception_state);
if (exception_state.HadException())
return ScriptPromise();
@@ -195,7 +195,7 @@ ScriptPromise Body::arrayBuffer(ScriptState* script_state,
ScriptPromise Body::blob(ScriptState* script_state,
ExceptionState& exception_state) {
- RejectInvalidConsumption(script_state, exception_state);
+ RejectInvalidConsumption(exception_state);
if (exception_state.HadException())
return ScriptPromise();
@@ -225,7 +225,7 @@ ScriptPromise Body::blob(ScriptState* script_state,
ScriptPromise Body::formData(ScriptState* script_state,
ExceptionState& exception_state) {
- RejectInvalidConsumption(script_state, exception_state);
+ RejectInvalidConsumption(exception_state);
if (exception_state.HadException())
return ScriptPromise();
@@ -295,7 +295,7 @@ ScriptPromise Body::formData(ScriptState* script_state,
ScriptPromise Body::json(ScriptState* script_state,
ExceptionState& exception_state) {
- RejectInvalidConsumption(script_state, exception_state);
+ RejectInvalidConsumption(exception_state);
if (exception_state.HadException())
return ScriptPromise();
@@ -324,7 +324,7 @@ ScriptPromise Body::json(ScriptState* script_state,
ScriptPromise Body::text(ScriptState* script_state,
ExceptionState& exception_state) {
- RejectInvalidConsumption(script_state, exception_state);
+ RejectInvalidConsumption(exception_state);
if (exception_state.HadException())
return ScriptPromise();
@@ -365,25 +365,14 @@ ReadableStream* Body::body() {
return BodyBuffer()->Stream();
}
-Body::BodyUsed Body::IsBodyUsed(ExceptionState& exception_state) {
+bool Body::IsBodyUsed() const {
auto* body_buffer = BodyBuffer();
- if (!body_buffer)
- return BodyUsed::kUnused;
- base::Optional<bool> stream_disturbed =
- body_buffer->IsStreamDisturbed(exception_state);
- if (exception_state.HadException())
- return BodyUsed::kBroken;
- return stream_disturbed.value() ? BodyUsed::kUsed : BodyUsed::kUnused;
+ return body_buffer && body_buffer->IsStreamDisturbed();
}
-Body::BodyLocked Body::IsBodyLocked(ExceptionState& exception_state) {
+bool Body::IsBodyLocked() const {
auto* body_buffer = BodyBuffer();
- if (!body_buffer)
- return BodyLocked::kUnlocked;
- base::Optional<bool> is_locked = body_buffer->IsStreamLocked(exception_state);
- if (exception_state.HadException())
- return BodyLocked::kBroken;
- return is_locked.value() ? BodyLocked::kLocked : BodyLocked::kUnlocked;
+ return body_buffer && body_buffer->IsStreamLocked();
}
bool Body::HasPendingActivity() const {
@@ -395,31 +384,16 @@ bool Body::HasPendingActivity() const {
return body_buffer->HasPendingActivity();
}
-bool Body::IsBodyUsedForDCheck(ExceptionState& exception_state) {
- return BodyBuffer() &&
- BodyBuffer()->IsStreamDisturbedForDCheck(exception_state);
-}
-
Body::Body(ExecutionContext* context) : ExecutionContextClient(context) {}
-void Body::RejectInvalidConsumption(ScriptState* script_state,
- ExceptionState& exception_state) {
- const auto used = IsBodyUsed(exception_state);
- if (exception_state.HadException()) {
- DCHECK_EQ(used, BodyUsed::kBroken);
- return;
- }
- DCHECK_NE(used, BodyUsed::kBroken);
-
- if (IsBodyLocked(exception_state) == BodyLocked::kLocked) {
- DCHECK(!exception_state.HadException());
+void Body::RejectInvalidConsumption(ExceptionState& exception_state) const {
+ if (IsBodyLocked()) {
exception_state.ThrowTypeError("body stream is locked");
}
- if (exception_state.HadException())
- return;
- if (used == BodyUsed::kUsed)
+ if (IsBodyUsed()) {
exception_state.ThrowTypeError("body stream already read");
+ }
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/fetch/body.h b/chromium/third_party/blink/renderer/core/fetch/body.h
index fa3449c1273..3db2c704600 100644
--- a/chromium/third_party/blink/renderer/core/fetch/body.h
+++ b/chromium/third_party/blink/renderer/core/fetch/body.h
@@ -31,9 +31,6 @@ class ScriptState;
// implementation.
class CORE_EXPORT Body : public ExecutionContextClient {
public:
- enum class BodyUsed { kUsed, kUnused, kBroken };
- enum class BodyLocked { kLocked, kUnlocked, kBroken };
-
explicit Body(ExecutionContext*);
ScriptPromise arrayBuffer(ScriptState*, ExceptionState&);
@@ -47,25 +44,16 @@ class CORE_EXPORT Body : public ExecutionContextClient {
// This should only be called from the generated bindings. All other code
// should use IsBodyUsed() instead.
- bool bodyUsed(ExceptionState& exception_state) {
- return IsBodyUsed(exception_state) == BodyUsed::kUsed;
- }
+ bool bodyUsed() const { return IsBodyUsed(); }
- // Returns kUsed, kUnused or kBroken. kBroken implies there is an exception
- // pending and the caller should return to JavaScript immediately.
- virtual BodyUsed IsBodyUsed(ExceptionState&);
+ // True if the body has been read from.
+ virtual bool IsBodyUsed() const;
- // Returns kLocked, kUnlocked or kBroken. kBroken implies there is an
- // exception pending and the caller should return to JavaScript immediately.
- BodyLocked IsBodyLocked(ExceptionState&);
+ // True if the body is locked.
+ bool IsBodyLocked() const;
bool HasPendingActivity() const;
- protected:
- // A version of IsBodyUsed() which catches exceptions and returns
- // false. Should never be used outside DCHECK().
- virtual bool IsBodyUsedForDCheck(ExceptionState& exception_state);
-
private:
// TODO(e_hakkinen): Fix |MimeType()| to always contain parameters and
// remove |ContentType()|.
@@ -76,7 +64,7 @@ class CORE_EXPORT Body : public ExecutionContextClient {
// error conditions. This method wraps those up into one call which throws
// an exception if consumption cannot proceed. The caller must check
// |exception_state| on return.
- void RejectInvalidConsumption(ScriptState*, ExceptionState& exception_state);
+ void RejectInvalidConsumption(ExceptionState& exception_state) const;
DISALLOW_COPY_AND_ASSIGN(Body);
};
diff --git a/chromium/third_party/blink/renderer/core/fetch/body.idl b/chromium/third_party/blink/renderer/core/fetch/body.idl
index 79a89529153..1f30a408bc8 100644
--- a/chromium/third_party/blink/renderer/core/fetch/body.idl
+++ b/chromium/third_party/blink/renderer/core/fetch/body.idl
@@ -7,7 +7,7 @@
[
ActiveScriptWrappable
] interface mixin Body {
- [RaisesException] readonly attribute boolean bodyUsed;
+ readonly attribute boolean bodyUsed;
[CallWith=ScriptState, NewObject, RaisesException] Promise<ArrayBuffer> arrayBuffer();
[CallWith=ScriptState, NewObject, RaisesException] Promise<Blob> blob();
[CallWith=ScriptState, NewObject, RaisesException] Promise<FormData> formData();
diff --git a/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.cc b/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.cc
index 815ad1d51fd..b292b445240 100644
--- a/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fetch/body.h"
#include "third_party/blink/renderer/core/fetch/bytes_consumer_tee.h"
+#include "third_party/blink/renderer/core/fetch/bytes_uploader.h"
#include "third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h"
#include "third_party/blink/renderer/core/streams/readable_stream.h"
#include "third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h"
@@ -84,7 +85,7 @@ class BodyStreamBuffer::LoaderClient final
void Abort() override { NOTREACHED(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(buffer_);
visitor->Trace(client_);
ExecutionContextLifecycleObserver::Trace(visitor);
@@ -169,13 +170,9 @@ BodyStreamBuffer::BodyStreamBuffer(ScriptState* script_state,
scoped_refptr<BlobDataHandle> BodyStreamBuffer::DrainAsBlobDataHandle(
BytesConsumer::BlobSizePolicy policy,
ExceptionState& exception_state) {
- DCHECK(!IsStreamLockedForDCheck(exception_state));
- DCHECK(!IsStreamDisturbedForDCheck(exception_state));
- const base::Optional<bool> is_closed = IsStreamClosed(exception_state);
- if (exception_state.HadException() || is_closed.value())
- return nullptr;
- const base::Optional<bool> is_errored = IsStreamErrored(exception_state);
- if (exception_state.HadException() || is_errored.value())
+ DCHECK(!IsStreamLocked());
+ DCHECK(!IsStreamDisturbed());
+ if (IsStreamClosed() || IsStreamErrored())
return nullptr;
if (made_from_readable_stream_)
@@ -194,13 +191,9 @@ scoped_refptr<BlobDataHandle> BodyStreamBuffer::DrainAsBlobDataHandle(
scoped_refptr<EncodedFormData> BodyStreamBuffer::DrainAsFormData(
ExceptionState& exception_state) {
- DCHECK(!IsStreamLockedForDCheck(exception_state));
- DCHECK(!IsStreamDisturbedForDCheck(exception_state));
- const base::Optional<bool> is_closed = IsStreamClosed(exception_state);
- if (exception_state.HadException() || is_closed.value())
- return nullptr;
- const base::Optional<bool> is_errored = IsStreamErrored(exception_state);
- if (exception_state.HadException() || is_errored.value())
+ DCHECK(!IsStreamLocked());
+ DCHECK(!IsStreamDisturbed());
+ if (IsStreamClosed() || IsStreamErrored())
return nullptr;
if (made_from_readable_stream_)
@@ -216,6 +209,22 @@ scoped_refptr<EncodedFormData> BodyStreamBuffer::DrainAsFormData(
return nullptr;
}
+void BodyStreamBuffer::DrainAsChunkedDataPipeGetter(
+ ScriptState* script_state,
+ mojo::PendingReceiver<network::mojom::blink::ChunkedDataPipeGetter>
+ pending_receiver,
+ ExceptionState& exception_state) {
+ DCHECK(!IsStreamLocked());
+ auto* consumer = MakeGarbageCollected<ReadableStreamBytesConsumer>(
+ script_state, stream_, exception_state);
+ if (exception_state.HadException())
+ return;
+ stream_uploader_ = MakeGarbageCollected<BytesUploader>(
+ consumer, std::move(pending_receiver),
+ ExecutionContext::From(script_state)
+ ->GetTaskRunner(TaskType::kNetworking));
+}
+
void BodyStreamBuffer::StartLoading(FetchDataLoader* loader,
FetchDataLoader::Client* client,
ExceptionState& exception_state) {
@@ -241,8 +250,8 @@ void BodyStreamBuffer::StartLoading(FetchDataLoader* loader,
void BodyStreamBuffer::Tee(BodyStreamBuffer** branch1,
BodyStreamBuffer** branch2,
ExceptionState& exception_state) {
- DCHECK(!IsStreamLockedForDCheck(exception_state));
- DCHECK(!IsStreamDisturbedForDCheck(exception_state));
+ DCHECK(!IsStreamLocked());
+ DCHECK(!IsStreamDisturbed());
*branch1 = nullptr;
*branch2 = nullptr;
scoped_refptr<BlobDataHandle> side_data_blob = TakeSideDataBlob();
@@ -339,41 +348,24 @@ void BodyStreamBuffer::ContextDestroyed() {
UnderlyingSourceBase::ContextDestroyed();
}
-base::Optional<bool> BodyStreamBuffer::IsStreamReadable(
- ExceptionState& exception_state) {
- return BooleanStreamOperation(&ReadableStream::IsReadable, exception_state);
-}
-
-base::Optional<bool> BodyStreamBuffer::IsStreamClosed(
- ExceptionState& exception_state) {
- return BooleanStreamOperation(&ReadableStream::IsClosed, exception_state);
-}
-
-base::Optional<bool> BodyStreamBuffer::IsStreamErrored(
- ExceptionState& exception_state) {
- return BooleanStreamOperation(&ReadableStream::IsErrored, exception_state);
+bool BodyStreamBuffer::IsStreamReadable() const {
+ return stream_->IsReadable();
}
-base::Optional<bool> BodyStreamBuffer::IsStreamLocked(
- ExceptionState& exception_state) {
- return BooleanStreamOperation(&ReadableStream::IsLocked, exception_state);
+bool BodyStreamBuffer::IsStreamClosed() const {
+ return stream_->IsClosed();
}
-bool BodyStreamBuffer::IsStreamLockedForDCheck(
- ExceptionState& exception_state) {
- auto result = IsStreamLocked(exception_state);
- return !result || *result;
+bool BodyStreamBuffer::IsStreamErrored() const {
+ return stream_->IsErrored();
}
-base::Optional<bool> BodyStreamBuffer::IsStreamDisturbed(
- ExceptionState& exception_state) {
- return BooleanStreamOperation(&ReadableStream::IsDisturbed, exception_state);
+bool BodyStreamBuffer::IsStreamLocked() const {
+ return stream_->IsLocked();
}
-bool BodyStreamBuffer::IsStreamDisturbedForDCheck(
- ExceptionState& exception_state) {
- auto result = IsStreamDisturbed(exception_state);
- return !result || *result;
+bool BodyStreamBuffer::IsStreamDisturbed() const {
+ return stream_->IsDisturbed();
}
void BodyStreamBuffer::CloseAndLockAndDisturb(ExceptionState& exception_state) {
@@ -384,25 +376,11 @@ void BodyStreamBuffer::CloseAndLockAndDisturb(ExceptionState& exception_state) {
return;
}
- if (stream_->IsBroken()) {
- stream_broken_ = true;
- exception_state.ThrowDOMException(
- DOMExceptionCode::kInvalidStateError,
- "Body stream has been lost and cannot be disturbed");
- return;
- }
-
- base::Optional<bool> is_readable = IsStreamReadable(exception_state);
- if (exception_state.HadException())
- return;
-
- DCHECK(is_readable.has_value());
- if (is_readable.value()) {
+ if (IsStreamReadable()) {
// Note that the stream cannot be "draining", because it doesn't have
// the internal buffer.
Close();
}
- DCHECK(!stream_broken_);
stream_->LockAndDisturb(script_state_, exception_state);
}
@@ -417,9 +395,10 @@ scoped_refptr<BlobDataHandle> BodyStreamBuffer::TakeSideDataBlob() {
return std::move(side_data_blob_);
}
-void BodyStreamBuffer::Trace(Visitor* visitor) {
+void BodyStreamBuffer::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(stream_);
+ visitor->Trace(stream_uploader_);
visitor->Trace(consumer_);
visitor->Trace(loader_);
visitor->Trace(signal_);
@@ -520,40 +499,30 @@ void BodyStreamBuffer::StopLoading() {
loader_ = nullptr;
}
-base::Optional<bool> BodyStreamBuffer::BooleanStreamOperation(
- base::Optional<bool> (ReadableStream::*predicate)(ScriptState*,
- ExceptionState&) const,
+BytesConsumer* BodyStreamBuffer::ReleaseHandle(
ExceptionState& exception_state) {
+ DCHECK(!IsStreamLocked());
+ DCHECK(!IsStreamDisturbed());
+
if (stream_broken_) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
"Body stream has suffered a fatal error and cannot be inspected");
- return base::nullopt;
- }
- ScriptState::Scope scope(script_state_);
- base::Optional<bool> result =
- (stream_->*predicate)(script_state_, exception_state);
- if (exception_state.HadException()) {
- stream_broken_ = true;
- return base::nullopt;
+ return nullptr;
}
- return result;
-}
-
-BytesConsumer* BodyStreamBuffer::ReleaseHandle(
- ExceptionState& exception_state) {
- DCHECK(!IsStreamLockedForDCheck(exception_state));
- DCHECK(!IsStreamDisturbedForDCheck(exception_state));
-
- side_data_blob_.reset();
- if (stream_broken_) {
+ if (!GetExecutionContext()) {
+ // Avoid crashing if ContextDestroyed() has been called.
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
- "Body stream has suffered a fatal error and cannot be inspected");
+ "Cannot release body in a window or worker than has been detached");
return nullptr;
}
+ // Do this after state checks to avoid side-effects when the method does
+ // nothing.
+ side_data_blob_.reset();
+
if (made_from_readable_stream_) {
ScriptState::Scope scope(script_state_);
auto* consumer = MakeGarbageCollected<ReadableStreamBytesConsumer>(
@@ -565,12 +534,8 @@ BytesConsumer* BodyStreamBuffer::ReleaseHandle(
return consumer;
}
// We need to call these before calling CloseAndLockAndDisturb.
- const base::Optional<bool> is_closed = IsStreamClosed(exception_state);
- if (exception_state.HadException())
- return nullptr;
- const base::Optional<bool> is_errored = IsStreamErrored(exception_state);
- if (exception_state.HadException())
- return nullptr;
+ const bool is_closed = IsStreamClosed();
+ const bool is_errored = IsStreamErrored();
BytesConsumer* consumer = consumer_.Release();
@@ -578,12 +543,12 @@ BytesConsumer* BodyStreamBuffer::ReleaseHandle(
if (exception_state.HadException())
return nullptr;
- if (is_closed.value()) {
+ if (is_closed) {
// Note that the stream cannot be "draining", because it doesn't have
// the internal buffer.
return BytesConsumer::CreateClosed();
}
- if (is_errored.value())
+ if (is_errored)
return BytesConsumer::CreateErrored(BytesConsumer::Error("error"));
DCHECK(consumer);
diff --git a/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.h b/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.h
index bac00bcb6b1..38a45519c06 100644
--- a/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.h
+++ b/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.h
@@ -6,8 +6,9 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BODY_STREAM_BUFFER_H_
#include <memory>
-#include "base/optional.h"
#include "base/util/type_safety/pass_key.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "services/network/public/mojom/chunked_data_pipe_getter.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/core/core_export.h"
@@ -21,6 +22,7 @@
namespace blink {
+class BytesUploader;
class EncodedFormData;
class ExceptionState;
class ReadableStream;
@@ -62,6 +64,10 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
BytesConsumer::BlobSizePolicy,
ExceptionState&);
scoped_refptr<EncodedFormData> DrainAsFormData(ExceptionState&);
+ void DrainAsChunkedDataPipeGetter(
+ ScriptState*,
+ mojo::PendingReceiver<network::mojom::blink::ChunkedDataPipeGetter>,
+ ExceptionState&);
void StartLoading(FetchDataLoader*,
FetchDataLoader::Client* /* client */,
ExceptionState&);
@@ -77,13 +83,11 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
void OnStateChange() override;
String DebugName() const override { return "BodyStreamBuffer"; }
- base::Optional<bool> IsStreamReadable(ExceptionState&);
- base::Optional<bool> IsStreamClosed(ExceptionState&);
- base::Optional<bool> IsStreamErrored(ExceptionState&);
- base::Optional<bool> IsStreamLocked(ExceptionState&);
- bool IsStreamLockedForDCheck(ExceptionState&);
- base::Optional<bool> IsStreamDisturbed(ExceptionState&);
- bool IsStreamDisturbedForDCheck(ExceptionState&);
+ bool IsStreamReadable() const;
+ bool IsStreamClosed() const;
+ bool IsStreamErrored() const;
+ bool IsStreamLocked() const;
+ bool IsStreamDisturbed() const;
void CloseAndLockAndDisturb(ExceptionState&);
ScriptState* GetScriptState() { return script_state_; }
@@ -97,7 +101,9 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
return side_data_blob_;
}
- void Trace(Visitor*) override;
+ bool IsMadeFromReadableStream() const { return made_from_readable_stream_; }
+
+ void Trace(Visitor*) const override;
private:
class LoaderClient;
@@ -116,17 +122,9 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
void EndLoading();
void StopLoading();
- // Implementation of IsStream*() methods. Delegates to |predicate|, one of the
- // methods defined in ReadableStream. Sets |stream_broken_| and throws if
- // |predicate| throws. Throws an exception if called when |stream_broken_|
- // is already true.
- base::Optional<bool> BooleanStreamOperation(
- base::Optional<bool> (ReadableStream::*predicate)(ScriptState*,
- ExceptionState&) const,
- ExceptionState& exception_state);
-
Member<ScriptState> script_state_;
Member<ReadableStream> stream_;
+ Member<BytesUploader> stream_uploader_;
Member<BytesConsumer> consumer_;
// We need this member to keep it alive while loading.
Member<FetchDataLoader> loader_;
@@ -140,6 +138,8 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
bool stream_needs_more_ = false;
bool made_from_readable_stream_;
bool in_process_data_ = false;
+
+ // TODO(ricea): Remove remaining uses of |stream_broken_|.
bool stream_broken_ = false;
DISALLOW_COPY_AND_ASSIGN(BodyStreamBuffer);
diff --git a/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc b/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc
index 821593825d6..d198c1ca8e8 100644
--- a/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc
@@ -133,8 +133,8 @@ TEST_F(BodyStreamBufferTest, Tee) {
BodyStreamBuffer* new2;
buffer->Tee(&new1, &new2, exception_state);
- EXPECT_TRUE(buffer->IsStreamLocked(exception_state).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(exception_state).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
@@ -199,18 +199,18 @@ TEST_F(BodyStreamBufferTest, TeeFromHandleMadeFromStream) {
BodyStreamBuffer* new2;
buffer->Tee(&new1, &new2, exception_state);
- EXPECT_TRUE(buffer->IsStreamLocked(exception_state).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
// Note that this behavior is slightly different from for the behavior of
// a BodyStreamBuffer made from a BytesConsumer. See the above test. In this
// test, the stream will get disturbed when the microtask is performed.
// TODO(yhirano): A uniformed behavior is preferred.
- EXPECT_FALSE(buffer->IsStreamDisturbed(exception_state).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
v8::MicrotasksScope::PerformCheckpoint(scope.GetScriptState()->GetIsolate());
- EXPECT_TRUE(buffer->IsStreamLocked(exception_state).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(exception_state).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
new1->StartLoading(FetchDataLoader::CreateLoaderAsString(
@@ -238,8 +238,8 @@ TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandle) {
blob_data_handle),
/* abort_signal = */ nullptr, side_data_blob);
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
scoped_refptr<BlobDataHandle> output_blob_data_handle =
@@ -247,8 +247,8 @@ TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandle) {
BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize,
ASSERT_NO_EXCEPTION);
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
EXPECT_EQ(blob_data_handle, output_blob_data_handle);
@@ -264,8 +264,8 @@ TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandleReturnsNull) {
BodyStreamBuffer::Create(scope.GetScriptState(), src,
/* abort_signal = */ nullptr, side_data_blob);
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
@@ -273,8 +273,8 @@ TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandleReturnsNull) {
BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize,
ASSERT_NO_EXCEPTION));
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
}
@@ -290,18 +290,18 @@ TEST_F(BodyStreamBufferTest,
MakeGarbageCollected<BodyStreamBuffer>(scope.GetScriptState(), stream);
EXPECT_FALSE(buffer->HasPendingActivity());
- EXPECT_FALSE(buffer->IsStreamLocked(exception_state).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(exception_state).value_or(true));
- EXPECT_TRUE(buffer->IsStreamReadable(exception_state).value_or(false));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
+ EXPECT_TRUE(buffer->IsStreamReadable());
EXPECT_FALSE(buffer->DrainAsBlobDataHandle(
BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize,
exception_state));
EXPECT_FALSE(buffer->HasPendingActivity());
- EXPECT_FALSE(buffer->IsStreamLocked(exception_state).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(exception_state).value_or(true));
- EXPECT_TRUE(buffer->IsStreamReadable(exception_state).value_or(false));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
+ EXPECT_TRUE(buffer->IsStreamReadable());
}
TEST_F(BodyStreamBufferTest, DrainAsFormData) {
@@ -319,15 +319,15 @@ TEST_F(BodyStreamBufferTest, DrainAsFormData) {
input_form_data),
/* abort_signal = */ nullptr, side_data_blob);
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
scoped_refptr<EncodedFormData> output_form_data =
buffer->DrainAsFormData(ASSERT_NO_EXCEPTION);
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
EXPECT_EQ(output_form_data->FlattenToString(),
@@ -344,15 +344,15 @@ TEST_F(BodyStreamBufferTest, DrainAsFormDataReturnsNull) {
BodyStreamBuffer::Create(scope.GetScriptState(), src,
/* abort_signal = */ nullptr, side_data_blob);
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
EXPECT_FALSE(buffer->DrainAsFormData(ASSERT_NO_EXCEPTION));
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
}
@@ -367,16 +367,16 @@ TEST_F(BodyStreamBufferTest,
MakeGarbageCollected<BodyStreamBuffer>(scope.GetScriptState(), stream);
EXPECT_FALSE(buffer->HasPendingActivity());
- EXPECT_FALSE(buffer->IsStreamLocked(exception_state).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(exception_state).value_or(true));
- EXPECT_TRUE(buffer->IsStreamReadable(exception_state).value_or(false));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
+ EXPECT_TRUE(buffer->IsStreamReadable());
EXPECT_FALSE(buffer->DrainAsFormData(exception_state));
EXPECT_FALSE(buffer->HasPendingActivity());
- EXPECT_FALSE(buffer->IsStreamLocked(exception_state).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(exception_state).value_or(true));
- EXPECT_TRUE(buffer->IsStreamReadable(exception_state).value_or(false));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
+ EXPECT_TRUE(buffer->IsStreamReadable());
}
TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsArrayBuffer) {
@@ -405,16 +405,16 @@ TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsArrayBuffer) {
ASSERT_NO_EXCEPTION);
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_TRUE(buffer->HasPendingActivity());
checkpoint.Call(1);
test::RunPendingTasks();
checkpoint.Call(2);
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
ASSERT_TRUE(array_buffer);
EXPECT_EQ("hello", String(static_cast<const char*>(array_buffer->Data()),
@@ -447,16 +447,16 @@ TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsBlob) {
client, ASSERT_NO_EXCEPTION);
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_TRUE(buffer->HasPendingActivity());
checkpoint.Call(1);
test::RunPendingTasks();
checkpoint.Call(2);
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(5u, blob_data_handle->size());
}
@@ -486,16 +486,16 @@ TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsString) {
client, ASSERT_NO_EXCEPTION);
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_TRUE(buffer->HasPendingActivity());
checkpoint.Call(1);
test::RunPendingTasks();
checkpoint.Call(2);
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
}
@@ -514,10 +514,10 @@ TEST_F(BodyStreamBufferTest, LoadClosedHandle) {
scope.GetScriptState(), BytesConsumer::CreateClosed(),
/* abort_signal = */ nullptr, side_data_blob);
- EXPECT_TRUE(buffer->IsStreamClosed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamClosed());
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
@@ -527,8 +527,8 @@ TEST_F(BodyStreamBufferTest, LoadClosedHandle) {
client, ASSERT_NO_EXCEPTION);
checkpoint.Call(2);
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
}
@@ -548,10 +548,10 @@ TEST_F(BodyStreamBufferTest, LoadErroredHandle) {
BytesConsumer::CreateErrored(BytesConsumer::Error()),
/* abort_signal = */ nullptr, side_data_blob);
- EXPECT_TRUE(buffer->IsStreamErrored(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamErrored());
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
@@ -561,8 +561,8 @@ TEST_F(BodyStreamBufferTest, LoadErroredHandle) {
client, ASSERT_NO_EXCEPTION);
checkpoint.Call(2);
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_tee.cc b/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_tee.cc
index 1492d51b897..37ded968847 100644
--- a/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_tee.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_tee.cc
@@ -113,7 +113,7 @@ class TeeHelper final : public GarbageCollected<TeeHelper>,
BytesConsumer* Destination1() const { return destination1_; }
BytesConsumer* Destination2() const { return destination2_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(src_);
visitor->Trace(destination1_);
visitor->Trace(destination2_);
@@ -138,7 +138,7 @@ class TeeHelper final : public GarbageCollected<TeeHelper>,
const char* data() const { return buffer_.data(); }
wtf_size_t size() const { return buffer_.size(); }
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
private:
Vector<char> buffer_;
@@ -268,7 +268,7 @@ class TeeHelper final : public GarbageCollected<TeeHelper>,
bool IsCancelled() const { return is_cancelled_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(execution_context_);
visitor->Trace(tee_);
visitor->Trace(client_);
diff --git a/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h b/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h
index 41ade535ece..f3aae804144 100644
--- a/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h
+++ b/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h
@@ -42,7 +42,7 @@ class BytesConsumerTestUtil {
USING_GARBAGE_COLLECTED_MIXIN(MockFetchDataLoaderClient);
public:
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
FetchDataLoader::Client::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/bytes_uploader.cc b/chromium/third_party/blink/renderer/core/fetch/bytes_uploader.cc
new file mode 100644
index 00000000000..1cb306e41fc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/fetch/bytes_uploader.cc
@@ -0,0 +1,169 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/fetch/bytes_uploader.h"
+
+#include "base/numerics/checked_math.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/single_thread_task_runner.h"
+#include "net/base/net_errors.h"
+#include "third_party/blink/public/platform/task_type.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h"
+
+namespace blink {
+
+BytesUploader::BytesUploader(
+ BytesConsumer* consumer,
+ mojo::PendingReceiver<network::mojom::blink::ChunkedDataPipeGetter>
+ pending_receiver,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : consumer_(consumer),
+ receiver_(this, std::move(pending_receiver)),
+ upload_pipe_watcher_(FROM_HERE,
+ mojo::SimpleWatcher::ArmingPolicy::MANUAL,
+ std::move(task_runner)) {
+ DCHECK(consumer_);
+ DCHECK_EQ(consumer_->GetPublicState(),
+ BytesConsumer::PublicState::kReadableOrWaiting);
+}
+
+BytesUploader::~BytesUploader() = default;
+
+void BytesUploader::Trace(blink::Visitor* visitor) const {
+ visitor->Trace(consumer_);
+ BytesConsumer::Client::Trace(visitor);
+}
+
+void BytesUploader::GetSize(GetSizeCallback get_size_callback) {
+ DCHECK(!get_size_callback_);
+ get_size_callback_ = std::move(get_size_callback);
+}
+
+void BytesUploader::StartReading(
+ mojo::ScopedDataPipeProducerHandle upload_pipe) {
+ DVLOG(3) << this << " StartReading()";
+ DCHECK(get_size_callback_);
+ DCHECK(upload_pipe);
+ if (upload_pipe_) {
+ // Replay was asked by net/ service.
+ CloseOnError();
+ return;
+ }
+ upload_pipe_ = std::move(upload_pipe);
+ upload_pipe_watcher_.Watch(upload_pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
+ WTF::BindRepeating(&BytesUploader::OnPipeWriteable,
+ WrapWeakPersistent(this)));
+ consumer_->SetClient(this);
+ if (consumer_->GetPublicState() ==
+ BytesConsumer::PublicState::kReadableOrWaiting) {
+ WriteDataOnPipe();
+ }
+}
+
+void BytesUploader::OnStateChange() {
+ DVLOG(3) << this << " OnStateChange(). consumer_->GetPublicState()="
+ << consumer_->GetPublicState();
+ DCHECK(get_size_callback_);
+ switch (consumer_->GetPublicState()) {
+ case BytesConsumer::PublicState::kReadableOrWaiting:
+ WriteDataOnPipe();
+ return;
+ case BytesConsumer::PublicState::kClosed:
+ Close();
+ return;
+ case BytesConsumer::PublicState::kErrored:
+ CloseOnError();
+ return;
+ }
+ NOTREACHED();
+}
+
+void BytesUploader::OnPipeWriteable(MojoResult unused) {
+ WriteDataOnPipe();
+}
+
+void BytesUploader::WriteDataOnPipe() {
+ DVLOG(3) << this << " WriteDataOnPipe(). consumer_->GetPublicState()="
+ << consumer_->GetPublicState();
+ DCHECK(upload_pipe_);
+ DCHECK(get_size_callback_);
+ if (!upload_pipe_.is_valid())
+ return;
+
+ while (true) {
+ const char* buffer;
+ size_t available;
+ auto consumer_result = consumer_->BeginRead(&buffer, &available);
+ DVLOG(3) << " consumer_->BeginRead()=" << consumer_result
+ << ", available=" << available;
+ switch (consumer_result) {
+ case BytesConsumer::Result::kError:
+ CloseOnError();
+ return;
+ case BytesConsumer::Result::kShouldWait:
+ return;
+ case BytesConsumer::Result::kDone:
+ Close();
+ return;
+ case BytesConsumer::Result::kOk:
+ break;
+ }
+ DCHECK_EQ(consumer_result, BytesConsumer::Result::kOk);
+ uint32_t written_bytes = base::saturated_cast<uint32_t>(available);
+ const MojoResult mojo_result = upload_pipe_->WriteData(
+ buffer, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
+ DVLOG(3) << " upload_pipe_->WriteData()=" << mojo_result
+ << ", mojo_written=" << written_bytes
+ << ", consumer_->EndRead()=" << consumer_result;
+ if (mojo_result == MOJO_RESULT_SHOULD_WAIT) {
+ // Wait for the pipe to have more capacity available
+ consumer_result = consumer_->EndRead(0);
+ upload_pipe_watcher_.ArmOrNotify();
+ return;
+ }
+ if (mojo_result != MOJO_RESULT_OK) {
+ CloseOnError();
+ return;
+ }
+
+ consumer_result = consumer_->EndRead(written_bytes);
+ if (!base::CheckAdd(total_size_, written_bytes)
+ .AssignIfValid(&total_size_)) {
+ CloseOnError();
+ return;
+ }
+
+ switch (consumer_result) {
+ case BytesConsumer::Result::kError:
+ CloseOnError();
+ return;
+ case BytesConsumer::Result::kShouldWait:
+ NOTREACHED();
+ return;
+ case BytesConsumer::Result::kDone:
+ Close();
+ return;
+ case BytesConsumer::Result::kOk:
+ break;
+ }
+ }
+}
+
+void BytesUploader::Close() {
+ DVLOG(3) << this << " Close(). total_size=" << total_size_;
+ DCHECK(get_size_callback_);
+ std::move(get_size_callback_).Run(net::OK, total_size_);
+}
+
+void BytesUploader::CloseOnError() {
+ DVLOG(3) << this << " CloseOnError(). total_size=" << total_size_;
+ DCHECK(consumer_);
+ consumer_->Cancel();
+ DCHECK(get_size_callback_);
+ std::move(get_size_callback_).Run(net::ERR_FAILED, total_size_);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/fetch/bytes_uploader.h b/chromium/third_party/blink/renderer/core/fetch/bytes_uploader.h
new file mode 100644
index 00000000000..304814b39b9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/fetch/bytes_uploader.h
@@ -0,0 +1,67 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BYTES_UPLOADER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BYTES_UPLOADER_H_
+
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "mojo/public/cpp/system/simple_watcher.h"
+#include "services/network/public/mojom/chunked_data_pipe_getter.mojom-blink.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+} // namespace base
+
+namespace blink {
+
+class CORE_EXPORT BytesUploader
+ : public GarbageCollected<BytesUploader>,
+ public BytesConsumer::Client,
+ public network::mojom::blink::ChunkedDataPipeGetter {
+ USING_GARBAGE_COLLECTED_MIXIN(BytesUploader);
+
+ public:
+ BytesUploader(
+ BytesConsumer* consumer,
+ mojo::PendingReceiver<network::mojom::blink::ChunkedDataPipeGetter>
+ pending_receiver,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+ ~BytesUploader() override;
+ BytesUploader(const BytesUploader&) = delete;
+ BytesUploader& operator=(const BytesUploader&) = delete;
+
+ void Trace(blink::Visitor*) const override;
+
+ private:
+ // BytesConsumer::Client implementation
+ void OnStateChange() override;
+ String DebugName() const override { return "BytesUploader"; }
+
+ // mojom::ChunkedDataPipeGetter implementation:
+ void GetSize(GetSizeCallback get_size_callback) override;
+ void StartReading(mojo::ScopedDataPipeProducerHandle upload_pipe) override;
+
+ void OnPipeWriteable(MojoResult unused);
+ void WriteDataOnPipe();
+
+ void Close();
+ // TODO(yoichio): Add a string parameter and show it on console.
+ void CloseOnError();
+
+ Member<BytesConsumer> consumer_;
+ mojo::Receiver<network::mojom::blink::ChunkedDataPipeGetter> receiver_;
+ mojo::ScopedDataPipeProducerHandle upload_pipe_;
+ mojo::SimpleWatcher upload_pipe_watcher_;
+ GetSizeCallback get_size_callback_;
+ uint64_t total_size_ = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BYTES_UPLOADER_H_
diff --git a/chromium/third_party/blink/renderer/core/fetch/bytes_uploader_test.cc b/chromium/third_party/blink/renderer/core/fetch/bytes_uploader_test.cc
new file mode 100644
index 00000000000..61eed927154
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/fetch/bytes_uploader_test.cc
@@ -0,0 +1,238 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/fetch/bytes_uploader.h"
+
+#include "base/test/mock_callback.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "net/base/net_errors.h"
+#include "services/network/public/mojom/chunked_data_pipe_getter.mojom-blink.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+
+using network::mojom::blink::ChunkedDataPipeGetter;
+using testing::_;
+using testing::InSequence;
+using testing::Invoke;
+using testing::Return;
+namespace blink {
+
+typedef testing::StrictMock<testing::MockFunction<void(int)>> Checkpoint;
+
+class MockBytesConsumer : public BytesConsumer {
+ public:
+ MockBytesConsumer() = default;
+ ~MockBytesConsumer() override = default;
+
+ MOCK_METHOD2(BeginRead, Result(const char**, size_t*));
+ MOCK_METHOD1(EndRead, Result(size_t));
+ MOCK_METHOD1(SetClient, void(Client*));
+ MOCK_METHOD0(ClearClient, void());
+ MOCK_METHOD0(Cancel, void());
+ MOCK_CONST_METHOD0(GetPublicState, PublicState());
+ MOCK_CONST_METHOD0(GetError, Error());
+ MOCK_CONST_METHOD0(DebugName, String());
+};
+
+class BytesUploaderTest : public ::testing::Test {
+ public:
+ void InitializeBytesUploader(uint32_t capacity = 100u) {
+ mock_bytes_consumer_ = MakeGarbageCollected<MockBytesConsumer>();
+ EXPECT_CALL(*mock_bytes_consumer_, GetPublicState())
+ .WillRepeatedly(Return(BytesConsumer::PublicState::kReadableOrWaiting));
+
+ bytes_uploader_ = MakeGarbageCollected<BytesUploader>(
+ mock_bytes_consumer_, remote_.BindNewPipeAndPassReceiver(),
+ Thread::Current()->GetTaskRunner());
+
+ const MojoCreateDataPipeOptions data_pipe_options{
+ sizeof(MojoCreateDataPipeOptions), MOJO_CREATE_DATA_PIPE_FLAG_NONE, 1,
+ capacity};
+ ASSERT_EQ(MOJO_RESULT_OK,
+ mojo::CreateDataPipe(&data_pipe_options, &writable_, &readable_));
+ }
+
+ MockBytesConsumer& Mock() const { return *mock_bytes_consumer_; }
+ mojo::ScopedDataPipeProducerHandle& Writable() { return writable_; }
+ mojo::ScopedDataPipeConsumerHandle& Readable() { return readable_; }
+ mojo::Remote<ChunkedDataPipeGetter>& Remote() { return remote_; }
+
+ private:
+ Persistent<BytesUploader> bytes_uploader_;
+ Persistent<MockBytesConsumer> mock_bytes_consumer_;
+
+ mojo::ScopedDataPipeProducerHandle writable_;
+ mojo::ScopedDataPipeConsumerHandle readable_;
+ mojo::Remote<ChunkedDataPipeGetter> remote_;
+};
+
+TEST_F(BytesUploaderTest, Create) {
+ MockBytesConsumer* mock_bytes_consumer =
+ MakeGarbageCollected<MockBytesConsumer>();
+ Checkpoint checkpoint;
+ {
+ InSequence s;
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(*mock_bytes_consumer, GetPublicState())
+ .WillRepeatedly(Return(BytesConsumer::PublicState::kReadableOrWaiting));
+ }
+
+ checkpoint.Call(1);
+ mojo::PendingRemote<ChunkedDataPipeGetter> pending_remote;
+ BytesUploader* bytes_uploader_ = MakeGarbageCollected<BytesUploader>(
+ mock_bytes_consumer, pending_remote.InitWithNewPipeAndPassReceiver(),
+ Thread::Current()->GetTaskRunner());
+ ASSERT_TRUE(bytes_uploader_);
+}
+
+// TODO(yoichio): Needs BytesConsumer state tests.
+
+TEST_F(BytesUploaderTest, ReadEmpty) {
+ InitializeBytesUploader();
+
+ base::MockCallback<ChunkedDataPipeGetter::GetSizeCallback> get_size_callback;
+ Checkpoint checkpoint;
+ {
+ InSequence s;
+
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(checkpoint, Call(2));
+ EXPECT_CALL(Mock(), SetClient(_));
+ EXPECT_CALL(Mock(), GetPublicState())
+ .WillRepeatedly(Return(BytesConsumer::PublicState::kReadableOrWaiting));
+ EXPECT_CALL(Mock(), BeginRead(_, _))
+ .WillOnce(Return(BytesConsumer::Result::kDone));
+ EXPECT_CALL(get_size_callback, Run(net::OK, 0u));
+
+ EXPECT_CALL(checkpoint, Call(3));
+ }
+
+ checkpoint.Call(1);
+ Remote()->GetSize(get_size_callback.Get());
+ Remote()->StartReading(std::move(Writable()));
+
+ checkpoint.Call(2);
+ test::RunPendingTasks();
+
+ checkpoint.Call(3);
+ char buffer[20] = {};
+ uint32_t num_bytes = sizeof(buffer);
+ MojoResult rv =
+ Readable()->ReadData(buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
+ EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, rv);
+}
+
+TEST_F(BytesUploaderTest, ReadSmall) {
+ InitializeBytesUploader();
+
+ base::MockCallback<ChunkedDataPipeGetter::GetSizeCallback> get_size_callback;
+ Checkpoint checkpoint;
+ {
+ InSequence s;
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(checkpoint, Call(2));
+ EXPECT_CALL(Mock(), SetClient(_));
+ EXPECT_CALL(Mock(), GetPublicState())
+ .WillRepeatedly(Return(BytesConsumer::PublicState::kReadableOrWaiting));
+ EXPECT_CALL(Mock(), BeginRead(_, _))
+ .WillOnce(Invoke([](const char** buffer, size_t* size) {
+ *size = 6;
+ *buffer = "foobar";
+ return BytesConsumer::Result::kOk;
+ }));
+ EXPECT_CALL(Mock(), EndRead(6u))
+ .WillOnce(Return(BytesConsumer::Result::kDone));
+ EXPECT_CALL(get_size_callback, Run(net::OK, 6u));
+
+ EXPECT_CALL(checkpoint, Call(3));
+ }
+
+ checkpoint.Call(1);
+ Remote()->GetSize(get_size_callback.Get());
+ Remote()->StartReading(std::move(Writable()));
+
+ checkpoint.Call(2);
+ test::RunPendingTasks();
+
+ checkpoint.Call(3);
+ char buffer[20] = {};
+ uint32_t num_bytes = sizeof(buffer);
+ EXPECT_EQ(MOJO_RESULT_OK,
+ Readable()->ReadData(buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE));
+ EXPECT_EQ(6u, num_bytes);
+ EXPECT_STREQ("foobar", buffer);
+}
+
+TEST_F(BytesUploaderTest, ReadOverPipeCapacity) {
+ InitializeBytesUploader(10u);
+
+ base::MockCallback<ChunkedDataPipeGetter::GetSizeCallback> get_size_callback;
+ Checkpoint checkpoint;
+ {
+ InSequence s;
+
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(checkpoint, Call(2));
+ EXPECT_CALL(Mock(), SetClient(_));
+ EXPECT_CALL(Mock(), GetPublicState())
+ .WillRepeatedly(Return(BytesConsumer::PublicState::kReadableOrWaiting));
+ EXPECT_CALL(Mock(), BeginRead(_, _))
+ .WillOnce(Invoke([](const char** buffer, size_t* size) {
+ *size = 12;
+ *buffer = "foobarFOOBAR";
+ return BytesConsumer::Result::kOk;
+ }));
+ EXPECT_CALL(Mock(), EndRead(10u))
+ .WillOnce(Return(BytesConsumer::Result::kOk));
+
+ EXPECT_CALL(Mock(), BeginRead(_, _))
+ .WillOnce(Invoke([](const char** buffer, size_t* size) {
+ *size = 2;
+ *buffer = "AR";
+ return BytesConsumer::Result::kOk;
+ }));
+ EXPECT_CALL(Mock(), EndRead(0u))
+ .WillOnce(Return(BytesConsumer::Result::kOk));
+
+ EXPECT_CALL(checkpoint, Call(3));
+ EXPECT_CALL(checkpoint, Call(4));
+ EXPECT_CALL(Mock(), BeginRead(_, _))
+ .WillOnce(Invoke([](const char** buffer, size_t* size) {
+ *size = 2;
+ *buffer = "AR";
+ return BytesConsumer::Result::kOk;
+ }));
+ EXPECT_CALL(Mock(), EndRead(2u))
+ .WillOnce(Return(BytesConsumer::Result::kDone));
+ EXPECT_CALL(get_size_callback, Run(net::OK, 12u));
+ }
+
+ checkpoint.Call(1);
+ Remote()->GetSize(get_size_callback.Get());
+ Remote()->StartReading(std::move(Writable()));
+
+ checkpoint.Call(2);
+ test::RunPendingTasks();
+
+ checkpoint.Call(3);
+ char buffer[20] = {};
+ uint32_t num_bytes = sizeof(buffer);
+ EXPECT_EQ(MOJO_RESULT_OK,
+ Readable()->ReadData(buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE));
+ EXPECT_EQ(10u, num_bytes);
+ EXPECT_STREQ("foobarFOOB", buffer);
+
+ checkpoint.Call(4);
+ test::RunPendingTasks();
+ char buffer2[20] = {};
+ num_bytes = sizeof(buffer2);
+ EXPECT_EQ(MOJO_RESULT_OK, Readable()->ReadData(buffer2, &num_bytes,
+ MOJO_READ_DATA_FLAG_NONE));
+ EXPECT_EQ(2u, num_bytes);
+ EXPECT_STREQ("AR", buffer2);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.cc b/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.cc
index 50cfd7c5141..99cbd31de9a 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.cc
@@ -104,7 +104,7 @@ class FetchDataLoaderAsBlobHandle final : public FetchDataLoader,
String DebugName() const override { return "FetchDataLoaderAsBlobHandle"; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
visitor->Trace(client_);
FetchDataLoader::Trace(visitor);
@@ -182,7 +182,7 @@ class FetchDataLoaderAsArrayBuffer final : public FetchDataLoader,
String DebugName() const override { return "FetchDataLoaderAsArrayBuffer"; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
visitor->Trace(client_);
FetchDataLoader::Trace(visitor);
@@ -266,7 +266,7 @@ class FetchDataLoaderAsFailure final : public FetchDataLoader,
void Cancel() override { consumer_->Cancel(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
visitor->Trace(client_);
FetchDataLoader::Trace(visitor);
@@ -352,7 +352,7 @@ class FetchDataLoaderAsFormData final : public FetchDataLoader,
multipart_parser_->Cancel();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
visitor->Trace(client_);
visitor->Trace(form_data_);
@@ -507,7 +507,7 @@ class FetchDataLoaderAsString final : public FetchDataLoader,
void Cancel() override { consumer_->Cancel(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
visitor->Trace(client_);
FetchDataLoader::Trace(visitor);
@@ -644,7 +644,7 @@ class FetchDataLoaderAsDataPipe final : public FetchDataLoader,
void Cancel() override { StopInternal(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
visitor->Trace(client_);
FetchDataLoader::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.h b/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.h
index 070f97a1d98..75a9bc80693 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.h
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.h
@@ -66,7 +66,7 @@ class CORE_EXPORT FetchDataLoader : public GarbageCollected<FetchDataLoader> {
// This function is called when an abort has been signalled.
virtual void Abort() = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
static FetchDataLoader* CreateLoaderAsBlobHandle(const String& mime_type);
@@ -91,7 +91,7 @@ class CORE_EXPORT FetchDataLoader : public GarbageCollected<FetchDataLoader> {
virtual void Cancel() = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc b/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc
index 69aa8773da3..acb6e795a05 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc
@@ -94,7 +94,7 @@ class FetchDataLoaderTest : public testing::Test {
BytesConsumer* GetDestination() { return destination_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(destination_);
visitor->Trace(completion_notifier_);
FetchDataLoader::Client::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_header_list.h b/chromium/third_party/blink/renderer/core/fetch/fetch_header_list.h
index d1a561786f6..3a8199c994f 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_header_list.h
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_header_list.h
@@ -51,7 +51,7 @@ class CORE_EXPORT FetchHeaderList final
static bool IsValidHeaderName(const String&);
static bool IsValidHeaderValue(const String&);
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
private:
// While using STL data structures in Blink is not very common or
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc b/chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc
index 7bae19a506f..e9b0475fe6a 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc
@@ -102,7 +102,7 @@ class FetchManager::Loader final
bool is_isolated_world,
AbortSignal*);
~Loader() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// ThreadableLoaderClient implementation.
bool WillFollowRedirect(const KURL&, const ResourceResponse&) override;
@@ -203,7 +203,7 @@ class FetchManager::Loader final
bool IsFinished() const { return finished_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(body_);
visitor->Trace(updater_);
visitor->Trace(response_);
@@ -274,7 +274,7 @@ FetchManager::Loader::~Loader() {
DCHECK(!threadable_loader_);
}
-void FetchManager::Loader::Trace(Visitor* visitor) {
+void FetchManager::Loader::Trace(Visitor* visitor) const {
visitor->Trace(fetch_manager_);
visitor->Trace(resolver_);
visitor->Trace(fetch_request_data_);
@@ -407,6 +407,20 @@ void FetchManager::Loader::DidReceiveResponse(
}
}
+ // TODO(crbug.com/1072350): Remove this once enough data is collected.
+ if (fetch_request_data_->Method() != http_names::kGET &&
+ fetch_request_data_->Method() != http_names::kHEAD &&
+ fetch_request_data_->Mode() == network::mojom::RequestMode::kNoCors &&
+ tainting == FetchRequestData::kOpaqueTainting) {
+ UseCounter::Count(execution_context_,
+ WebFeature::kFetchAPINonGetOrHeadOpaqueResponse);
+ if (url_list_.size() > 1) {
+ UseCounter::Count(
+ execution_context_,
+ WebFeature::kFetchAPINonGetOrHeadOpaqueResponseWithRedirect);
+ }
+ }
+
place_holder_body_ = MakeGarbageCollected<PlaceHolderBytesConsumer>();
FetchResponseData* response_data = FetchResponseData::CreateWithBuffer(
BodyStreamBuffer::Create(script_state, place_holder_body_, signal_));
@@ -535,7 +549,9 @@ void FetchManager::Loader::Start(ExceptionState& exception_state) {
// "- should fetching |request| be blocked as content security returns
// blocked"
if (!execution_context_->GetContentSecurityPolicyForWorld()
- ->AllowConnectToSource(fetch_request_data_->Url())) {
+ ->AllowConnectToSource(fetch_request_data_->Url(),
+ fetch_request_data_->Url(),
+ RedirectStatus::kNoRedirect)) {
// "A network error."
PerformNetworkError(
"Refused to connect to '" + fetch_request_data_->Url().ElidedString() +
@@ -713,10 +729,29 @@ void FetchManager::Loader::PerformHTTPFetch(ExceptionState& exception_state) {
if (fetch_request_data_->Method() != http_names::kGET &&
fetch_request_data_->Method() != http_names::kHEAD) {
if (fetch_request_data_->Buffer()) {
- request.SetHttpBody(
- fetch_request_data_->Buffer()->DrainAsFormData(exception_state));
+ scoped_refptr<EncodedFormData> form_data =
+ fetch_request_data_->Buffer()->DrainAsFormData(exception_state);
+
if (exception_state.HadException())
return;
+ if (form_data) {
+ request.SetHttpBody(form_data);
+ } else if (RuntimeEnabledFeatures::OutOfBlinkCorsEnabled() &&
+ RuntimeEnabledFeatures::FetchUploadStreamingEnabled(
+ execution_context_)) {
+ UseCounter::Count(execution_context_,
+ WebFeature::kFetchUploadStreaming);
+ mojo::PendingRemote<network::mojom::blink::ChunkedDataPipeGetter>
+ pending_remote;
+ fetch_request_data_->Buffer()->DrainAsChunkedDataPipeGetter(
+ resolver_->GetScriptState(),
+ pending_remote.InitWithNewPipeAndPassReceiver(), exception_state);
+ if (exception_state.HadException())
+ return;
+ request.MutableBody().SetStreamBody(std::move(pending_remote));
+ request.SetAllowHTTP1ForStreamingUpload(
+ fetch_request_data_->AllowHTTP1ForStreamingUpload());
+ }
}
}
request.SetCacheMode(fetch_request_data_->CacheMode());
@@ -878,7 +913,7 @@ void FetchManager::OnLoaderFinished(Loader* loader) {
loader->Dispose();
}
-void FetchManager::Trace(Visitor* visitor) {
+void FetchManager::Trace(Visitor* visitor) const {
visitor->Trace(loaders_);
ExecutionContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_manager.h b/chromium/third_party/blink/renderer/core/fetch/fetch_manager.h
index 6b5c87c25ff..e97080faf3e 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_manager.h
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_manager.h
@@ -32,7 +32,7 @@ class CORE_EXPORT FetchManager final
ExceptionState&);
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class Loader;
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.cc b/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.cc
index 2bc52ecc3a0..ea2c33a39eb 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.cc
@@ -18,6 +18,7 @@
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h"
+#include "third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/network/http_names.h"
@@ -66,17 +67,31 @@ bool IsExcludedHeaderForServiceWorkerFetchEvent(const String& header_name) {
return false;
}
+void SignalSize(
+ std::unique_ptr<mojo::Remote<network::mojom::blink::ChunkedDataPipeGetter>>,
+ Persistent<DataPipeBytesConsumer::CompletionNotifier> notifier,
+ int32_t status,
+ uint64_t size) {
+ if (status != 0) {
+ // error case
+ notifier->SignalError(BytesConsumer::Error());
+ return;
+ }
+ notifier->SignalSize(size);
+}
+
} // namespace
FetchRequestData* FetchRequestData::Create(
ScriptState* script_state,
- const mojom::blink::FetchAPIRequest& fetch_api_request,
+ mojom::blink::FetchAPIRequestPtr fetch_api_request,
ForServiceWorkerFetchEvent for_service_worker_fetch_event) {
+ DCHECK(fetch_api_request);
FetchRequestData* request = MakeGarbageCollected<FetchRequestData>(
script_state ? ExecutionContext::From(script_state) : nullptr);
- request->url_ = fetch_api_request.url;
- request->method_ = AtomicString(fetch_api_request.method);
- for (const auto& pair : fetch_api_request.headers) {
+ request->url_ = fetch_api_request->url;
+ request->method_ = AtomicString(fetch_api_request->method);
+ for (const auto& pair : fetch_api_request->headers) {
// TODO(leonhsl): Check sources of |fetch_api_request.headers| to make clear
// whether we really need this filter.
if (EqualIgnoringASCIICase(pair.key, "referer"))
@@ -88,19 +103,56 @@ FetchRequestData* FetchRequestData::Create(
request->header_list_->Append(pair.key, pair.value);
}
- if (fetch_api_request.blob) {
- DCHECK(!fetch_api_request.body);
+ if (fetch_api_request->blob) {
+ DCHECK(fetch_api_request->body.IsEmpty());
request->SetBuffer(BodyStreamBuffer::Create(
script_state,
MakeGarbageCollected<BlobBytesConsumer>(
- ExecutionContext::From(script_state), fetch_api_request.blob),
- nullptr /* AbortSignal */));
- } else if (fetch_api_request.body) {
- request->SetBuffer(BodyStreamBuffer::Create(
- script_state,
- MakeGarbageCollected<FormDataBytesConsumer>(
- ExecutionContext::From(script_state), fetch_api_request.body),
+ ExecutionContext::From(script_state), fetch_api_request->blob),
nullptr /* AbortSignal */));
+ } else if (fetch_api_request->body.FormBody()) {
+ request->SetBuffer(
+ BodyStreamBuffer::Create(script_state,
+ MakeGarbageCollected<FormDataBytesConsumer>(
+ ExecutionContext::From(script_state),
+ fetch_api_request->body.FormBody()),
+ nullptr /* AbortSignal */));
+ } else if (fetch_api_request->body.StreamBody()) {
+ mojo::ScopedDataPipeConsumerHandle readable;
+ mojo::ScopedDataPipeProducerHandle writable;
+ MojoCreateDataPipeOptions options{sizeof(MojoCreateDataPipeOptions),
+ MOJO_CREATE_DATA_PIPE_FLAG_NONE, 1, 0};
+ const MojoResult result =
+ mojo::CreateDataPipe(&options, &writable, &readable);
+ if (result == MOJO_RESULT_OK) {
+ DataPipeBytesConsumer::CompletionNotifier* completion_notifier = nullptr;
+ // Explicitly creating a ReadableStream here in order to remember
+ // that the request is created from a ReadableStream.
+ auto* stream = BodyStreamBuffer::Create(
+ script_state,
+ MakeGarbageCollected<DataPipeBytesConsumer>(
+ ExecutionContext::From(script_state)
+ ->GetTaskRunner(TaskType::kNetworking),
+ std::move(readable), &completion_notifier),
+ /*AbortSignal=*/nullptr)
+ ->Stream();
+ request->SetBuffer(
+ MakeGarbageCollected<BodyStreamBuffer>(script_state, stream,
+ /*AbortSignal=*/nullptr));
+
+ auto body_remote = std::make_unique<
+ mojo::Remote<network::mojom::blink::ChunkedDataPipeGetter>>(
+ fetch_api_request->body.TakeStreamBody());
+ auto* body_remote_raw = body_remote.get();
+ (*body_remote_raw)
+ ->GetSize(WTF::Bind(SignalSize, std::move(body_remote),
+ WrapPersistent(completion_notifier)));
+ (*body_remote_raw)->StartReading(std::move(writable));
+ } else {
+ request->SetBuffer(BodyStreamBuffer::Create(
+ script_state, BytesConsumer::CreateErrored(BytesConsumer::Error()),
+ nullptr /* AbortSignal */));
+ }
}
// Context is always set to FETCH later, so we don't copy it
@@ -108,25 +160,27 @@ FetchRequestData* FetchRequestData::Create(
// TODO(crbug.com/1045925): Remove this comment too when
// we deprecate SetContext.
- request->SetDestination(fetch_api_request.destination);
+ request->SetDestination(fetch_api_request->destination);
request->SetReferrerString(AtomicString(Referrer::NoReferrer()));
- if (fetch_api_request.referrer) {
- if (!fetch_api_request.referrer->url.IsEmpty())
- request->SetReferrerString(AtomicString(fetch_api_request.referrer->url));
- request->SetReferrerPolicy(fetch_api_request.referrer->policy);
+ if (fetch_api_request->referrer) {
+ if (!fetch_api_request->referrer->url.IsEmpty()) {
+ request->SetReferrerString(
+ AtomicString(fetch_api_request->referrer->url));
+ }
+ request->SetReferrerPolicy(fetch_api_request->referrer->policy);
}
- request->SetMode(fetch_api_request.mode);
- request->SetCredentials(fetch_api_request.credentials_mode);
- request->SetCacheMode(fetch_api_request.cache_mode);
- request->SetRedirect(fetch_api_request.redirect_mode);
+ request->SetMode(fetch_api_request->mode);
+ request->SetCredentials(fetch_api_request->credentials_mode);
+ request->SetCacheMode(fetch_api_request->cache_mode);
+ request->SetRedirect(fetch_api_request->redirect_mode);
request->SetMimeType(request->header_list_->ExtractMIMEType());
- request->SetIntegrity(fetch_api_request.integrity);
- request->SetKeepalive(fetch_api_request.keepalive);
- request->SetIsHistoryNavigation(fetch_api_request.is_history_navigation);
- request->SetPriority(
- ConvertRequestPriorityToResourceLoadPriority(fetch_api_request.priority));
- if (fetch_api_request.fetch_window_id)
- request->SetWindowId(fetch_api_request.fetch_window_id.value());
+ request->SetIntegrity(fetch_api_request->integrity);
+ request->SetKeepalive(fetch_api_request->keepalive);
+ request->SetIsHistoryNavigation(fetch_api_request->is_history_navigation);
+ request->SetPriority(ConvertRequestPriorityToResourceLoadPriority(
+ fetch_api_request->priority));
+ if (fetch_api_request->fetch_window_id)
+ request->SetWindowId(fetch_api_request->fetch_window_id.value());
return request;
}
@@ -154,6 +208,8 @@ FetchRequestData* FetchRequestData::CloneExceptBody() {
request->is_history_navigation_ = is_history_navigation_;
request->window_id_ = window_id_;
request->trust_token_params_ = trust_token_params_;
+ request->allow_http1_for_streaming_upload_ =
+ allow_http1_for_streaming_upload_;
return request;
}
@@ -213,7 +269,7 @@ FetchRequestData::FetchRequestData(ExecutionContext* execution_context)
url_loader_factory_(execution_context),
execution_context_(execution_context) {}
-void FetchRequestData::Trace(Visitor* visitor) {
+void FetchRequestData::Trace(Visitor* visitor) const {
visitor->Trace(buffer_);
visitor->Trace(header_list_);
visitor->Trace(url_loader_factory_);
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.h b/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.h
index cf2e86c21b8..2bf540d0ccc 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.h
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.h
@@ -40,7 +40,7 @@ class CORE_EXPORT FetchRequestData final
enum class ForServiceWorkerFetchEvent { kFalse, kTrue };
static FetchRequestData* Create(ScriptState*,
- const mojom::blink::FetchAPIRequest&,
+ mojom::blink::FetchAPIRequestPtr,
ForServiceWorkerFetchEvent);
FetchRequestData* Clone(ScriptState*, ExceptionState&);
FetchRequestData* Pass(ScriptState*, ExceptionState&);
@@ -138,7 +138,14 @@ class CORE_EXPORT FetchRequestData final
trust_token_params_ = std::move(trust_token_params);
}
- void Trace(Visitor*);
+ void SetAllowHTTP1ForStreamingUpload(bool allow) {
+ allow_http1_for_streaming_upload_ = allow;
+ }
+ bool AllowHTTP1ForStreamingUpload() const {
+ return allow_http1_for_streaming_upload_;
+ }
+
+ void Trace(Visitor*) const;
private:
FetchRequestData* CloneExceptBody();
@@ -183,6 +190,7 @@ class CORE_EXPORT FetchRequestData final
url_loader_factory_;
base::UnguessableToken window_id_;
Member<ExecutionContext> execution_context_;
+ bool allow_http1_for_streaming_upload_ = false;
DISALLOW_COPY_AND_ASSIGN(FetchRequestData);
};
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_request_data_test.cc b/chromium/third_party/blink/renderer/core/fetch/fetch_request_data_test.cc
index 57ab1b71c1b..78efa87e618 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_request_data_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_request_data_test.cc
@@ -40,7 +40,7 @@ class FetchRequestDataTestingPlatformSupport : public TestingPlatformSupport {
TEST(FetchRequestDataTest, For_ServiceWorkerFetchEvent_Headers) {
{
FetchRequestData* request_data = FetchRequestData::Create(
- nullptr /* script_state */, *PrepareFetchAPIRequest(),
+ nullptr /* script_state */, PrepareFetchAPIRequest(),
FetchRequestData::ForServiceWorkerFetchEvent::kTrue);
EXPECT_EQ(2U, request_data->HeaderList()->size());
EXPECT_TRUE(request_data->HeaderList()->Has("x-hi-hi"));
@@ -54,7 +54,7 @@ TEST(FetchRequestDataTest, For_ServiceWorkerFetchEvent_Headers) {
platform;
FetchRequestData* request_data = FetchRequestData::Create(
- nullptr /* script_state */, *PrepareFetchAPIRequest(),
+ nullptr /* script_state */, PrepareFetchAPIRequest(),
FetchRequestData::ForServiceWorkerFetchEvent::kTrue);
EXPECT_EQ(1U, request_data->HeaderList()->size());
EXPECT_TRUE(request_data->HeaderList()->Has("x-hi-hi"));
@@ -67,7 +67,7 @@ TEST(FetchRequestDataTest, For_ServiceWorkerFetchEvent_Headers) {
TEST(FetchRequestDataTest, Not_For_ServiceWorkerFetchEvent_Headers) {
{
FetchRequestData* request_data = FetchRequestData::Create(
- nullptr /* script_state */, *PrepareFetchAPIRequest(),
+ nullptr /* script_state */, PrepareFetchAPIRequest(),
FetchRequestData::ForServiceWorkerFetchEvent::kFalse);
EXPECT_EQ(4U, request_data->HeaderList()->size());
EXPECT_TRUE(request_data->HeaderList()->Has("x-hi-hi"));
@@ -81,7 +81,7 @@ TEST(FetchRequestDataTest, Not_For_ServiceWorkerFetchEvent_Headers) {
platform;
FetchRequestData* request_data = FetchRequestData::Create(
- nullptr /* script_state */, *PrepareFetchAPIRequest(),
+ nullptr /* script_state */, PrepareFetchAPIRequest(),
FetchRequestData::ForServiceWorkerFetchEvent::kFalse);
EXPECT_EQ(4U, request_data->HeaderList()->size());
EXPECT_TRUE(request_data->HeaderList()->Has("x-hi-hi"));
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.cc b/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.cc
index 7c96506830c..c595b241206 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.cc
@@ -194,6 +194,10 @@ FetchResponseData* FetchResponseData::Clone(ScriptState* script_state,
new_response->response_time_ = response_time_;
new_response->cache_storage_cache_name_ = cache_storage_cache_name_;
new_response->cors_exposed_header_names_ = cors_exposed_header_names_;
+ new_response->connection_info_ = connection_info_;
+ new_response->alpn_negotiated_protocol_ = alpn_negotiated_protocol_;
+ new_response->loaded_with_credentials_ = loaded_with_credentials_;
+ new_response->was_fetched_via_spdy_ = was_fetched_via_spdy_;
switch (type_) {
case Type::kBasic:
@@ -257,11 +261,15 @@ mojom::blink::FetchAPIResponsePtr FetchResponseData::PopulateFetchAPIResponse(
response->status_text = status_message_;
response->response_type = type_;
response->response_source = response_source_;
+ response->mime_type = mime_type_;
response->response_time = response_time_;
response->cache_storage_cache_name = cache_storage_cache_name_;
response->cors_exposed_header_names =
HeaderSetToVector(cors_exposed_header_names_);
+ response->connection_info = connection_info_;
+ response->alpn_negotiated_protocol = alpn_negotiated_protocol_;
response->loaded_with_credentials = loaded_with_credentials_;
+ response->was_fetched_via_spdy = was_fetched_via_spdy_;
for (const auto& header : HeaderList()->List())
response->headers.insert(header.first, header.second);
response->parsed_headers = ParseHeaders(
@@ -308,6 +316,16 @@ void FetchResponseData::InitFromResourceResponse(
SetResponseSource(network::mojom::FetchResponseSource::kNetwork);
}
+ SetConnectionInfo(response.ConnectionInfo());
+
+ // Some non-http responses, like data: url responses, will have a null
+ // |alpn_negotiated_protocol|. In these cases we leave the default
+ // value of "unknown".
+ if (!response.AlpnNegotiatedProtocol().IsNull())
+ SetAlpnNegotiatedProtocol(response.AlpnNegotiatedProtocol());
+
+ SetWasFetchedViaSpdy(response.WasFetchedViaSPDY());
+
// TODO(wanderview): Remove |tainting| and use |response.GetType()|
// instead once the OOR-CORS disabled path is removed.
SetLoadedWithCredentials(
@@ -326,7 +344,10 @@ FetchResponseData::FetchResponseData(Type type,
status_message_(status_message),
header_list_(MakeGarbageCollected<FetchHeaderList>()),
response_time_(base::Time::Now()),
- loaded_with_credentials_(false) {}
+ connection_info_(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN),
+ alpn_negotiated_protocol_("unknown"),
+ loaded_with_credentials_(false),
+ was_fetched_via_spdy_(false) {}
void FetchResponseData::ReplaceBodyStreamBuffer(BodyStreamBuffer* buffer) {
if (type_ == Type::kBasic || type_ == Type::kCors) {
@@ -339,7 +360,7 @@ void FetchResponseData::ReplaceBodyStreamBuffer(BodyStreamBuffer* buffer) {
}
}
-void FetchResponseData::Trace(Visitor* visitor) {
+void FetchResponseData::Trace(Visitor* visitor) const {
visitor->Trace(header_list_);
visitor->Trace(internal_response_);
visitor->Trace(buffer_);
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.h b/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.h
index 1eb7454afb0..0c4bfcb335e 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.h
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.h
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
+#include "net/http/http_response_info.h"
#include "services/network/public/mojom/fetch_api.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_response.mojom-blink-forward.h"
@@ -103,10 +104,19 @@ class CORE_EXPORT FetchResponseData final
void SetCorsExposedHeaderNames(const HTTPHeaderSet& header_names) {
cors_exposed_header_names_ = header_names;
}
- bool LoadedWithCredentials() const { return loaded_with_credentials_; }
+ void SetConnectionInfo(
+ net::HttpResponseInfo::ConnectionInfo connection_info) {
+ connection_info_ = connection_info;
+ }
+ void SetAlpnNegotiatedProtocol(AtomicString alpn_negotiated_protocol) {
+ alpn_negotiated_protocol_ = alpn_negotiated_protocol;
+ }
void SetLoadedWithCredentials(bool loaded_with_credentials) {
loaded_with_credentials_ = loaded_with_credentials;
}
+ void SetWasFetchedViaSpdy(bool was_fetched_via_spdy) {
+ was_fetched_via_spdy_ = was_fetched_via_spdy;
+ }
// If the type is Default, replaces |buffer_|.
// If the type is Basic or CORS, replaces |buffer_| and
@@ -125,7 +135,7 @@ class CORE_EXPORT FetchResponseData final
FetchRequestData::Tainting tainting,
const ResourceResponse& response);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
network::mojom::FetchResponseType type_;
@@ -141,7 +151,10 @@ class CORE_EXPORT FetchResponseData final
base::Time response_time_;
String cache_storage_cache_name_;
HTTPHeaderSet cors_exposed_header_names_;
+ net::HttpResponseInfo::ConnectionInfo connection_info_;
+ AtomicString alpn_negotiated_protocol_;
bool loaded_with_credentials_;
+ bool was_fetched_via_spdy_;
DISALLOW_COPY_AND_ASSIGN(FetchResponseData);
};
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_response_data_test.cc b/chromium/third_party/blink/renderer/core/fetch/fetch_response_data_test.cc
index d7f8d314135..ac21aeea0c9 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_response_data_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_response_data_test.cc
@@ -267,8 +267,6 @@ TEST_F(FetchResponseDataTest, DefaultResponseTime) {
TEST_F(FetchResponseDataTest, ContentSecurityPolicy) {
base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(
- network::features::kOutOfBlinkFrameAncestors);
FetchResponseData* internal_response = CreateInternalResponse();
internal_response->HeaderList()->Append("content-security-policy",
"frame-ancestors 'none'");
diff --git a/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc b/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc
index 80ce8b92387..71d540e5326 100644
--- a/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc
@@ -313,7 +313,7 @@ class DataPipeAndDataBytesConsumer final : public BytesConsumer {
String DebugName() const override { return "DataPipeAndDataBytesConsumer"; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(execution_context_);
visitor->Trace(client_);
visitor->Trace(simple_consumer_);
@@ -479,7 +479,7 @@ class ComplexFormDataBytesConsumer final : public BytesConsumer {
Error GetError() const override { return blob_bytes_consumer_->GetError(); }
String DebugName() const override { return "ComplexFormDataBytesConsumer"; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(blob_bytes_consumer_);
BytesConsumer::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h b/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h
index fd06b7d51cd..35f4eba6473 100644
--- a/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h
+++ b/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h
@@ -54,7 +54,7 @@ class FormDataBytesConsumer final : public BytesConsumer {
Error GetError() const override { return impl_->GetError(); }
String DebugName() const override { return impl_->DebugName(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(impl_);
BytesConsumer::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer_test.cc b/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer_test.cc
index 56cf200312c..31a95c200fb 100644
--- a/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer_test.cc
@@ -103,7 +103,7 @@ scoped_refptr<EncodedFormData> DataPipeFormData() {
new SimpleDataPipeGetter(
String(" hello world"),
data_pipe_getter_remote.InitWithNewPipeAndPassReceiver());
- body.AppendDataPipe(data_pipe_getter_remote.PassPipe());
+ body.AppendDataPipe(std::move(data_pipe_getter_remote));
// Add another data pipe.
mojo::PendingRemote<network::mojom::blink::DataPipeGetter>
@@ -112,7 +112,7 @@ scoped_refptr<EncodedFormData> DataPipeFormData() {
new SimpleDataPipeGetter(
String(" here's another data pipe "),
data_pipe_getter_remote2.InitWithNewPipeAndPassReceiver());
- body.AppendDataPipe(data_pipe_getter_remote2.PassPipe());
+ body.AppendDataPipe(std::move(data_pipe_getter_remote2));
// Add some more data.
body.AppendData(WebData("bar baz", 7));
diff --git a/chromium/third_party/blink/renderer/core/fetch/global_fetch.cc b/chromium/third_party/blink/renderer/core/fetch/global_fetch.cc
index 80d8de09a20..aed0c0976b8 100644
--- a/chromium/third_party/blink/renderer/core/fetch/global_fetch.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/global_fetch.cc
@@ -88,7 +88,7 @@ class GlobalFetchImpl final : public GarbageCollected<GlobalFetchImpl<T>>,
return promise;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(fetch_manager_);
ScopedFetcher::Trace(visitor);
Supplement<T>::Trace(visitor);
@@ -118,7 +118,7 @@ GlobalFetch::ScopedFetcher* GlobalFetch::ScopedFetcher::From(
worker.GetExecutionContext());
}
-void GlobalFetch::ScopedFetcher::Trace(Visitor* visitor) {}
+void GlobalFetch::ScopedFetcher::Trace(Visitor* visitor) const {}
ScriptPromise GlobalFetch::fetch(ScriptState* script_state,
LocalDOMWindow& window,
diff --git a/chromium/third_party/blink/renderer/core/fetch/global_fetch.h b/chromium/third_party/blink/renderer/core/fetch/global_fetch.h
index f401074a8ec..8f9afe857de 100644
--- a/chromium/third_party/blink/renderer/core/fetch/global_fetch.h
+++ b/chromium/third_party/blink/renderer/core/fetch/global_fetch.h
@@ -33,7 +33,7 @@ class CORE_EXPORT GlobalFetch {
static ScopedFetcher* From(LocalDOMWindow&);
static ScopedFetcher* From(WorkerGlobalScope&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
static ScriptPromise fetch(ScriptState*,
diff --git a/chromium/third_party/blink/renderer/core/fetch/headers.cc b/chromium/third_party/blink/renderer/core/fetch/headers.cc
index 893ecc97fe9..ae3e5e8062b 100644
--- a/chromium/third_party/blink/renderer/core/fetch/headers.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/headers.cc
@@ -292,7 +292,7 @@ Headers::Headers()
Headers::Headers(FetchHeaderList* header_list)
: header_list_(header_list), guard_(kNoneGuard) {}
-void Headers::Trace(Visitor* visitor) {
+void Headers::Trace(Visitor* visitor) const {
visitor->Trace(header_list_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/headers.h b/chromium/third_party/blink/renderer/core/fetch/headers.h
index 045bec08cdf..34c4be0f4b5 100644
--- a/chromium/third_party/blink/renderer/core/fetch/headers.h
+++ b/chromium/third_party/blink/renderer/core/fetch/headers.h
@@ -60,7 +60,7 @@ class CORE_EXPORT Headers final : public ScriptWrappable,
void FillWith(const HeadersInit&, ExceptionState&);
FetchHeaderList* HeaderList() const { return header_list_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// These methods should only be called when size() would return 0.
diff --git a/chromium/third_party/blink/renderer/core/fetch/multipart_parser.cc b/chromium/third_party/blink/renderer/core/fetch/multipart_parser.cc
index 2f3383b1201..43024b42f90 100644
--- a/chromium/third_party/blink/renderer/core/fetch/multipart_parser.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/multipart_parser.cc
@@ -333,7 +333,7 @@ void MultipartParser::ParseTransportPadding(const char** bytes_pointer,
++(*bytes_pointer);
}
-void MultipartParser::Trace(Visitor* visitor) {
+void MultipartParser::Trace(Visitor* visitor) const {
visitor->Trace(client_);
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/multipart_parser.h b/chromium/third_party/blink/renderer/core/fetch/multipart_parser.h
index 210efffac61..0cc92c076a9 100644
--- a/chromium/third_party/blink/renderer/core/fetch/multipart_parser.h
+++ b/chromium/third_party/blink/renderer/core/fetch/multipart_parser.h
@@ -40,7 +40,7 @@ class CORE_EXPORT MultipartParser final
virtual void PartDataInMultipartReceived(const char* bytes, size_t) = 0;
// The method is called whenever all data of a complete part is parsed.
virtual void PartDataInMultipartFullyReceived() = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
MultipartParser(Vector<char> boundary, Client*);
@@ -50,7 +50,7 @@ class CORE_EXPORT MultipartParser final
bool IsCancelled() const { return state_ == State::kCancelled; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
class Matcher {
diff --git a/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.cc b/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.cc
index a5c44e81103..f0cba0e09bf 100644
--- a/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.cc
@@ -91,7 +91,7 @@ void PlaceHolderBytesConsumer::Update(BytesConsumer* consumer) {
}
}
-void PlaceHolderBytesConsumer::Trace(Visitor* visitor) {
+void PlaceHolderBytesConsumer::Trace(Visitor* visitor) const {
visitor->Trace(underlying_);
visitor->Trace(client_);
BytesConsumer::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.h b/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.h
index 09ef3a30d6a..c2c4ec025c9 100644
--- a/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.h
+++ b/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.h
@@ -31,7 +31,7 @@ class CORE_EXPORT PlaceHolderBytesConsumer final : public BytesConsumer {
// This function can be called at most once.
void Update(BytesConsumer* consumer);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<BytesConsumer> underlying_;
diff --git a/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc b/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc
index 383f9d4bde4..293826bee32 100644
--- a/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc
@@ -58,7 +58,7 @@ class ReadableStreamBytesConsumer::OnFulfilled final : public ScriptFunction {
return v;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
ScriptFunction::Trace(visitor);
}
@@ -84,7 +84,7 @@ class ReadableStreamBytesConsumer::OnRejected final : public ScriptFunction {
return v;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
ScriptFunction::Trace(visitor);
}
@@ -177,7 +177,7 @@ BytesConsumer::Error ReadableStreamBytesConsumer::GetError() const {
return Error("Failed to read from a ReadableStream.");
}
-void ReadableStreamBytesConsumer::Trace(Visitor* visitor) {
+void ReadableStreamBytesConsumer::Trace(Visitor* visitor) const {
visitor->Trace(reader_);
visitor->Trace(client_);
visitor->Trace(pending_buffer_);
diff --git a/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h b/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h
index 8a74a038f90..246b4292395 100644
--- a/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h
+++ b/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h
@@ -38,7 +38,7 @@ class CORE_EXPORT ReadableStreamBytesConsumer final : public BytesConsumer {
Error GetError() const override;
String DebugName() const override { return "ReadableStreamBytesConsumer"; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class OnFulfilled;
diff --git a/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc b/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc
index fd8affae8f9..eeeeae9434d 100644
--- a/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc
@@ -39,7 +39,7 @@ class MockClient : public GarbageCollected<MockClient>,
MOCK_METHOD0(OnStateChange, void());
String DebugName() const override { return "MockClient"; }
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
TEST(ReadableStreamBytesConsumerTest, Create) {
diff --git a/chromium/third_party/blink/renderer/core/fetch/request.cc b/chromium/third_party/blink/renderer/core/fetch/request.cc
index a6bec95916d..9fdf4da73a9 100644
--- a/chromium/third_party/blink/renderer/core/fetch/request.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/request.cc
@@ -175,6 +175,14 @@ static BodyStreamBuffer* ExtractBody(ScriptState* script_state,
execution_context, std::move(form_data)),
nullptr /* AbortSignal */);
content_type = "application/x-www-form-urlencoded;charset=UTF-8";
+ } else if (RuntimeEnabledFeatures::OutOfBlinkCorsEnabled() &&
+ RuntimeEnabledFeatures::FetchUploadStreamingEnabled(
+ execution_context) &&
+ V8ReadableStream::HasInstance(body, isolate)) {
+ ReadableStream* readable_stream =
+ V8ReadableStream::ToImpl(body.As<v8::Object>());
+ return_buffer =
+ MakeGarbageCollected<BodyStreamBuffer>(script_state, readable_stream);
} else {
String string = NativeValueTraits<IDLUSVString>::NativeValue(
isolate, body, exception_state);
@@ -199,16 +207,13 @@ Request* Request::CreateRequestWithRequestOrString(
// Setup RequestInit's body first
// - "If |input| is a Request object and it is disturbed, throw a
// TypeError."
- if (input_request &&
- input_request->IsBodyUsed(exception_state) == BodyUsed::kUsed) {
- DCHECK(!exception_state.HadException());
+ if (input_request && input_request->IsBodyUsed()) {
exception_state.ThrowTypeError(
"Cannot construct a Request with a Request object that has already "
"been used.");
return nullptr;
}
- if (exception_state.HadException())
- return nullptr;
+
// - "Let |temporaryBody| be |input|'s request's body if |input| is a
// Request object, and null otherwise."
BodyStreamBuffer* temporary_body =
@@ -543,8 +548,6 @@ Request* Request::CreateRequestWithRequestOrString(
return nullptr;
}
- VLOG(1) << "a";
-
if (params.type == TrustTokenOperationType::kIssuance &&
!IsTrustTokenIssuanceAvailableInExecutionContext(*execution_context)) {
exception_state.ThrowTypeError(
@@ -555,6 +558,10 @@ Request* Request::CreateRequestWithRequestOrString(
request->SetTrustTokenParams(std::move(params));
}
+ if (init->hasAllowHTTP1ForStreamingUpload()) {
+ request->SetAllowHTTP1ForStreamingUpload(
+ init->allowHTTP1ForStreamingUpload());
+ }
// "Let |r| be a new Request object associated with |request| and a new
// Headers object whose guard is "request"."
@@ -645,6 +652,21 @@ Request* Request::CreateRequestWithRequestOrString(
return nullptr;
}
+ // If body is non-null and body’s source is null, then:
+ if (temporary_body && temporary_body->IsMadeFromReadableStream()) {
+ // If r’s request’s mode is neither "same-origin" nor "cors", then throw a
+ // TypeError.
+ if (request->Mode() != network::mojom::RequestMode::kSameOrigin &&
+ request->Mode() != network::mojom::RequestMode::kCors) {
+ exception_state.ThrowTypeError(
+ "If request is made from ReadableStream, mode should be"
+ "\"same-origin\" or \"cors\"");
+ return nullptr;
+ }
+ // Set r’s request’s use-CORS-preflight flag.
+ request->SetMode(network::mojom::RequestMode::kCorsWithForcedPreflight);
+ }
+
// "Set |r|'s request's body to |temporaryBody|.
if (temporary_body)
r->request_->SetBuffer(temporary_body);
@@ -717,10 +739,11 @@ Request* Request::Create(ScriptState* script_state, FetchRequestData* request) {
Request* Request::Create(
ScriptState* script_state,
- const mojom::blink::FetchAPIRequest& fetch_api_request,
+ mojom::blink::FetchAPIRequestPtr fetch_api_request,
ForServiceWorkerFetchEvent for_service_worker_fetch_event) {
- FetchRequestData* data = FetchRequestData::Create(
- script_state, fetch_api_request, for_service_worker_fetch_event);
+ FetchRequestData* data =
+ FetchRequestData::Create(script_state, std::move(fetch_api_request),
+ for_service_worker_fetch_event);
return MakeGarbageCollected<Request>(script_state, data);
}
@@ -827,6 +850,7 @@ String Request::credentials() const {
// mode:"
switch (request_->Credentials()) {
case network::mojom::CredentialsMode::kOmit:
+ case network::mojom::CredentialsMode::kOmitBug_775438_Workaround:
return "omit";
case network::mojom::CredentialsMode::kSameOrigin:
return "same-origin";
@@ -889,14 +913,10 @@ bool Request::isHistoryNavigation() const {
Request* Request::clone(ScriptState* script_state,
ExceptionState& exception_state) {
- if (IsBodyLocked(exception_state) == BodyLocked::kLocked ||
- IsBodyUsed(exception_state) == BodyUsed::kUsed) {
- DCHECK(!exception_state.HadException());
+ if (IsBodyLocked() || IsBodyUsed()) {
exception_state.ThrowTypeError("Request body is already used");
return nullptr;
}
- if (exception_state.HadException())
- return nullptr;
FetchRequestData* request = request_->Clone(script_state, exception_state);
if (exception_state.HadException())
@@ -911,7 +931,7 @@ Request* Request::clone(ScriptState* script_state,
FetchRequestData* Request::PassRequestData(ScriptState* script_state,
ExceptionState& exception_state) {
- DCHECK(!IsBodyUsedForDCheck(exception_state));
+ DCHECK(!IsBodyUsed());
FetchRequestData* data = request_->Pass(script_state, exception_state);
if (exception_state.HadException())
return nullptr;
@@ -994,7 +1014,7 @@ network::mojom::RequestDestination Request::GetRequestDestination() const {
return request_->Destination();
}
-void Request::Trace(Visitor* visitor) {
+void Request::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ActiveScriptWrappable<Request>::Trace(visitor);
Body::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/fetch/request.h b/chromium/third_party/blink/renderer/core/fetch/request.h
index 23147aebd4f..6fa038826a5 100644
--- a/chromium/third_party/blink/renderer/core/fetch/request.h
+++ b/chromium/third_party/blink/renderer/core/fetch/request.h
@@ -59,7 +59,7 @@ class CORE_EXPORT Request final : public ScriptWrappable,
ExceptionState&);
static Request* Create(ScriptState*, FetchRequestData*);
static Request* Create(ScriptState*,
- const mojom::blink::FetchAPIRequest&,
+ mojom::blink::FetchAPIRequestPtr,
ForServiceWorkerFetchEvent);
Request(ScriptState*, FetchRequestData*, Headers*, AbortSignal*);
@@ -103,7 +103,7 @@ class CORE_EXPORT Request final : public ScriptWrappable,
mojom::RequestContextType GetRequestContextType() const;
network::mojom::RequestDestination GetRequestDestination() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const FetchRequestData* GetRequest() const { return request_; }
diff --git a/chromium/third_party/blink/renderer/core/fetch/request_init.idl b/chromium/third_party/blink/renderer/core/fetch/request_init.idl
index 3f4f4ba2177..d59ac05c1c4 100644
--- a/chromium/third_party/blink/renderer/core/fetch/request_init.idl
+++ b/chromium/third_party/blink/renderer/core/fetch/request_init.idl
@@ -27,7 +27,7 @@ dictionary RequestInit {
// contexts, this has to be enforced after the fact because the
// SecureContext IDL attribute doesn't affect dictionary members.
[RuntimeEnabled=TrustTokens] TrustToken trustToken;
-
+ [RuntimeEnabled=FetchUploadStreaming] boolean allowHTTP1ForStreamingUpload;
// TODO(domfarolino): add support for RequestInit window member.
//any window; // can only be set to null
};
diff --git a/chromium/third_party/blink/renderer/core/fetch/request_test.cc b/chromium/third_party/blink/renderer/core/fetch/request_test.cc
index 6e05308c72c..0b294198d88 100644
--- a/chromium/third_party/blink/renderer/core/fetch/request_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/request_test.cc
@@ -82,9 +82,10 @@ TEST(ServiceWorkerRequestTest, FromAndToFetchAPIRequest) {
}
fetch_api_request->referrer =
mojom::blink::Referrer::New(KURL(NullURL(), referrer), kReferrerPolicy);
+ const auto fetch_api_request_headers = fetch_api_request->headers;
Request* request =
- Request::Create(scope.GetScriptState(), *fetch_api_request,
+ Request::Create(scope.GetScriptState(), std::move(fetch_api_request),
Request::ForServiceWorkerFetchEvent::kFalse);
DCHECK(request);
EXPECT_EQ(url, request->url());
@@ -118,7 +119,7 @@ TEST(ServiceWorkerRequestTest, FromAndToFetchAPIRequest) {
EXPECT_EQ(referrer, second_fetch_api_request->referrer->url);
EXPECT_EQ(network::mojom::ReferrerPolicy::kAlways,
second_fetch_api_request->referrer->policy);
- EXPECT_EQ(fetch_api_request->headers, second_fetch_api_request->headers);
+ EXPECT_EQ(fetch_api_request_headers, second_fetch_api_request->headers);
}
TEST(ServiceWorkerRequestTest, ToFetchAPIRequestStripsURLFragment) {
diff --git a/chromium/third_party/blink/renderer/core/fetch/response.cc b/chromium/third_party/blink/renderer/core/fetch/response.cc
index f3bd7020c3f..619232c20d5 100644
--- a/chromium/third_party/blink/renderer/core/fetch/response.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/response.cc
@@ -293,12 +293,9 @@ Response* Response::Create(ScriptState* script_state,
// then IsStreamLocked and IsStreamDisturbed will always be false.
// So we don't have to check BodyStreamBuffer is a ReadableStream
// or not.
- if (body->IsStreamLocked(exception_state).value_or(true) ||
- body->IsStreamDisturbed(exception_state).value_or(true)) {
- if (!exception_state.HadException()) {
- exception_state.ThrowTypeError(
- "Response body object should not be disturbed or locked");
- }
+ if (body->IsStreamLocked() || body->IsStreamDisturbed()) {
+ exception_state.ThrowTypeError(
+ "Response body object should not be disturbed or locked");
return nullptr;
}
@@ -384,19 +381,24 @@ FetchResponseData* Response::CreateUnfilteredFetchResponseDataWithoutBody(
response->SetResponseTime(fetch_api_response.response_time);
response->SetCacheStorageCacheName(
fetch_api_response.cache_storage_cache_name);
+ response->SetConnectionInfo(fetch_api_response.connection_info);
+ response->SetAlpnNegotiatedProtocol(
+ WTF::AtomicString(fetch_api_response.alpn_negotiated_protocol));
response->SetLoadedWithCredentials(
fetch_api_response.loaded_with_credentials);
+ response->SetWasFetchedViaSpdy(fetch_api_response.was_fetched_via_spdy);
for (const auto& header : fetch_api_response.headers)
response->HeaderList()->Append(header.key, header.value);
- // TODO(wanderview): This sets the mime type of the Response based on the
- // current headers. This should be correct for most cases, but technically
- // the mime type should really be frozen at the initial Response
- // construction. We should plumb the value through the cache_storage
- // persistence layer and include the explicit mime type in FetchAPIResponse
- // to set here. See: crbug.com/938939
- response->SetMimeType(response->HeaderList()->ExtractMIMEType());
+ // Use the |mime_type| provided by the FetchAPIResponse if its set.
+ // Otherwise fall back to extracting the mime type from the headers. This
+ // can happen when the response is loaded from an older cache_storage
+ // instance that did not yet store the mime_type value.
+ if (!fetch_api_response.mime_type.IsNull())
+ response->SetMimeType(fetch_api_response.mime_type);
+ else
+ response->SetMimeType(response->HeaderList()->ExtractMIMEType());
return response;
}
@@ -469,16 +471,11 @@ Headers* Response::headers() const {
Response* Response::clone(ScriptState* script_state,
ExceptionState& exception_state) {
- if (IsBodyLocked(exception_state) == BodyLocked::kLocked ||
- IsBodyUsed(exception_state) == BodyUsed::kUsed) {
- DCHECK(!exception_state.HadException());
+ if (IsBodyLocked() || IsBodyUsed()) {
exception_state.ThrowTypeError("Response body is already used");
return nullptr;
}
- if (exception_state.HadException())
- return nullptr;
-
FetchResponseData* response = response_->Clone(script_state, exception_state);
if (exception_state.HadException())
return nullptr;
@@ -520,16 +517,9 @@ bool Response::HasBody() const {
return response_->InternalBuffer();
}
-Body::BodyUsed Response::IsBodyUsed(ExceptionState& exception_state) {
+bool Response::IsBodyUsed() const {
auto* body_buffer = InternalBodyBuffer();
- if (!body_buffer)
- return BodyUsed::kUnused;
- base::Optional<bool> stream_disturbed =
- body_buffer->IsStreamDisturbed(exception_state);
- if (exception_state.HadException())
- return BodyUsed::kBroken;
- DCHECK(stream_disturbed.has_value());
- return stream_disturbed.value() ? BodyUsed::kUsed : BodyUsed::kUnused;
+ return body_buffer && body_buffer->IsStreamDisturbed();
}
String Response::MimeType() const {
@@ -554,7 +544,7 @@ FetchHeaderList* Response::InternalHeaderList() const {
return response_->InternalHeaderList();
}
-void Response::Trace(Visitor* visitor) {
+void Response::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ActiveScriptWrappable<Response>::Trace(visitor);
Body::Trace(visitor);
@@ -562,9 +552,4 @@ void Response::Trace(Visitor* visitor) {
visitor->Trace(headers_);
}
-bool Response::IsBodyUsedForDCheck(ExceptionState& exception_state) {
- return InternalBodyBuffer() &&
- InternalBodyBuffer()->IsStreamDisturbedForDCheck(exception_state);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/fetch/response.h b/chromium/third_party/blink/renderer/core/fetch/response.h
index 9d0987f51a7..2899fe168e8 100644
--- a/chromium/third_party/blink/renderer/core/fetch/response.h
+++ b/chromium/third_party/blink/renderer/core/fetch/response.h
@@ -114,7 +114,7 @@ class CORE_EXPORT Response final : public ScriptWrappable,
return response_->InternalBuffer();
}
- BodyUsed IsBodyUsed(ExceptionState&) override;
+ bool IsBodyUsed() const override;
String ContentType() const override;
String MimeType() const override;
@@ -124,12 +124,7 @@ class CORE_EXPORT Response final : public ScriptWrappable,
FetchHeaderList* InternalHeaderList() const;
- void Trace(Visitor*) override;
-
- protected:
- // A version of IsBodyUsed() which catches exceptions and returns
- // false. Should never be used outside DCHECK().
- bool IsBodyUsedForDCheck(ExceptionState&) override;
+ void Trace(Visitor*) const override;
private:
const Member<FetchResponseData> response_;
diff --git a/chromium/third_party/blink/renderer/core/fetch/trust_token.idl b/chromium/third_party/blink/renderer/core/fetch/trust_token.idl
index a2b595ec9ac..e4014edc3c7 100644
--- a/chromium/third_party/blink/renderer/core/fetch/trust_token.idl
+++ b/chromium/third_party/blink/renderer/core/fetch/trust_token.idl
@@ -25,10 +25,12 @@ dictionary TrustToken {
// 2. |additionalSignedHeaders|
// 3. |includeTimestampHeader|
// 4. |signRequestData|
+ // 5. |additionalSigningData|
//
// Additionally, |issuer| is required when |type| is "send-srr".
USVString issuer;
sequence<USVString> additionalSignedHeaders;
boolean includeTimestampHeader = false;
SignRequestData signRequestData = "omit";
+ DOMString additionalSigningData;
};
diff --git a/chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.cc b/chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.cc
index c0064cafe44..d7af058e35d 100644
--- a/chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.cc
@@ -85,6 +85,9 @@ bool ConvertTrustTokenToMojom(const TrustToken& in,
return false;
}
+ if (in.hasAdditionalSigningData())
+ out->possibly_unsafe_additional_signing_data = in.additionalSigningData();
+
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file_list.cc b/chromium/third_party/blink/renderer/core/fileapi/file_list.cc
index 4d9ef43b18a..97fb32eef43 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file_list.cc
+++ b/chromium/third_party/blink/renderer/core/fileapi/file_list.cc
@@ -51,7 +51,7 @@ Vector<base::FilePath> FileList::PathsForUserVisibleFiles() const {
return paths;
}
-void FileList::Trace(Visitor* visitor) {
+void FileList::Trace(Visitor* visitor) const {
visitor->Trace(files_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file_list.h b/chromium/third_party/blink/renderer/core/fileapi/file_list.h
index b66623bfd8d..3892b434d9d 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file_list.h
+++ b/chromium/third_party/blink/renderer/core/fileapi/file_list.h
@@ -48,7 +48,7 @@ class CORE_EXPORT FileList final : public ScriptWrappable {
void Append(File* file) { files_.push_back(file); }
Vector<base::FilePath> PathsForUserVisibleFiles() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<File>> files_;
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file_reader.cc b/chromium/third_party/blink/renderer/core/fileapi/file_reader.cc
index 2ba5fc1b845..978d71510a5 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file_reader.cc
+++ b/chromium/third_party/blink/renderer/core/fileapi/file_reader.cc
@@ -125,7 +125,7 @@ class FileReader::ThrottlingController final
: Supplement<ExecutionContext>(context),
max_running_readers_(kMaxOutstandingRequestsPerThread) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(pending_readers_);
visitor->Trace(running_readers_);
Supplement<ExecutionContext>::Trace(visitor);
@@ -476,7 +476,7 @@ void FileReader::FireEvent(const AtomicString& type) {
}
}
-void FileReader::Trace(Visitor* visitor) {
+void FileReader::Trace(Visitor* visitor) const {
visitor->Trace(error_);
EventTargetWithInlineData::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file_reader.h b/chromium/third_party/blink/renderer/core/fileapi/file_reader.h
index 7e763d550e8..15a95f9689d 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file_reader.h
+++ b/chromium/third_party/blink/renderer/core/fileapi/file_reader.h
@@ -103,7 +103,7 @@ class CORE_EXPORT FileReader final : public EventTargetWithInlineData,
DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
DEFINE_ATTRIBUTE_EVENT_LISTENER(loadend, kLoadend)
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class ThrottlingController;
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file_reader_loader_client.h b/chromium/third_party/blink/renderer/core/fileapi/file_reader_loader_client.h
index 6b5da439b52..a94329dda7a 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file_reader_loader_client.h
+++ b/chromium/third_party/blink/renderer/core/fileapi/file_reader_loader_client.h
@@ -31,6 +31,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FILEAPI_FILE_READER_LOADER_CLIENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FILEAPI_FILE_READER_LOADER_CLIENT_H_
+#include "base/notreached.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
diff --git a/chromium/third_party/blink/renderer/core/fileapi/public_url_manager.cc b/chromium/third_party/blink/renderer/core/fileapi/public_url_manager.cc
index e23e101178e..40e119645e2 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/public_url_manager.cc
+++ b/chromium/third_party/blink/renderer/core/fileapi/public_url_manager.cc
@@ -152,7 +152,7 @@ void PublicURLManager::ContextDestroyed() {
mojo_urls_.clear();
}
-void PublicURLManager::Trace(Visitor* visitor) {
+void PublicURLManager::Trace(Visitor* visitor) const {
visitor->Trace(url_store_);
ExecutionContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/fileapi/public_url_manager.h b/chromium/third_party/blink/renderer/core/fileapi/public_url_manager.h
index dd9b508d52a..76a238490ed 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/public_url_manager.h
+++ b/chromium/third_party/blink/renderer/core/fileapi/public_url_manager.h
@@ -72,7 +72,7 @@ class CORE_EXPORT PublicURLManager final
// ExecutionContextLifecycleObserver interface.
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void SetURLStoreForTesting(
HeapMojoAssociatedRemote<mojom::blink::BlobURLStore> url_store) {
diff --git a/chromium/third_party/blink/renderer/core/frame/BUILD.gn b/chromium/third_party/blink/renderer/core/frame/BUILD.gn
index bf09a36ee47..f2b1deb2c4b 100644
--- a/chromium/third_party/blink/renderer/core/frame/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/frame/BUILD.gn
@@ -175,6 +175,8 @@ blink_core_sources("frame") {
"rotation_viewport_anchor.h",
"sandbox_flags.cc",
"sandbox_flags.h",
+ "savable_resources.cc",
+ "savable_resources.h",
"scheduling.cc",
"scheduling.h",
"screen.cc",
@@ -185,8 +187,8 @@ blink_core_sources("frame") {
"settings_delegate.h",
"smart_clip.cc",
"smart_clip.h",
- "sticky_frame_tracker.cc",
- "sticky_frame_tracker.h",
+ "sticky_ad_detector.cc",
+ "sticky_ad_detector.h",
"test_report_body.cc",
"test_report_body.h",
"use_counter_helper.cc",
@@ -195,6 +197,8 @@ blink_core_sources("frame") {
"user_activation.h",
"viewport_data.cc",
"viewport_data.h",
+ "virtual_keyboard_overlay_changed_observer.cc",
+ "virtual_keyboard_overlay_changed_observer.h",
"visual_viewport.cc",
"visual_viewport.h",
"web_feature.h",
@@ -216,7 +220,7 @@ blink_core_sources("frame") {
deps = [
"//skia",
- "//ui/base/cursor",
+ "//ui/base/cursor:cursor_base",
"//ui/base/cursor/mojom:cursor_type_blink",
]
}
diff --git a/chromium/third_party/blink/renderer/core/frame/ad_tracker.cc b/chromium/third_party/blink/renderer/core/frame/ad_tracker.cc
index 3d57716273c..38112b215c8 100644
--- a/chromium/third_party/blink/renderer/core/frame/ad_tracker.cc
+++ b/chromium/third_party/blink/renderer/core/frame/ad_tracker.cc
@@ -158,9 +158,12 @@ void AdTracker::Will(const probe::CallFunction& probe) {
probe.function->GetScriptOrigin().ResourceName();
String script_url;
if (!resource_name.IsEmpty()) {
- script_url = ToCoreString(
- resource_name->ToString(ToIsolate(local_root_)->GetCurrentContext())
- .ToLocalChecked());
+ v8::MaybeLocal<v8::String> resource_name_string =
+ resource_name->ToString(ToIsolate(local_root_)->GetCurrentContext());
+ // Rarely, ToString() can return an empty result, even if |resource_name|
+ // isn't empty (crbug.com/1086832).
+ if (!resource_name_string.IsEmpty())
+ script_url = ToCoreString(resource_name_string.ToLocalChecked());
}
WillExecuteScript(probe.context, script_url);
}
@@ -282,7 +285,7 @@ void AdTracker::AppendToKnownAdScripts(ExecutionContext& execution_context,
add_result.stored_value->value.insert(url);
}
-void AdTracker::Trace(Visitor* visitor) {
+void AdTracker::Trace(Visitor* visitor) const {
visitor->Trace(local_root_);
visitor->Trace(known_ad_scripts_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/ad_tracker.h b/chromium/third_party/blink/renderer/core/frame/ad_tracker.h
index 10be17661e4..4d4a61571dd 100644
--- a/chromium/third_party/blink/renderer/core/frame/ad_tracker.h
+++ b/chromium/third_party/blink/renderer/core/frame/ad_tracker.h
@@ -85,7 +85,7 @@ class CORE_EXPORT AdTracker : public GarbageCollected<AdTracker> {
// frequently then consider just the bottom of the stack for performance sake.
bool IsAdScriptInStack(StackType stack_type);
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
void Shutdown();
explicit AdTracker(LocalFrame*);
diff --git a/chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc b/chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc
index 1b8bcca9fd8..b868fcb4ec2 100644
--- a/chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc
@@ -113,7 +113,7 @@ class TestAdTracker : public AdTracker {
void SetAdSuffix(const String& ad_suffix) { ad_suffix_ = ad_suffix; }
~TestAdTracker() override {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(execution_context_);
AdTracker::Trace(visitor);
}
@@ -1257,8 +1257,12 @@ TEST_F(AdTrackerSimTest, StyleRecalcCausedByAdScript) {
)HTML");
stylesheet.Complete(kStylesheetWithVanillaResources);
+ Compositor().BeginFrame();
base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(ad_tracker_->UrlHasBeenRequested(kVanillaFontURL));
+ // @font-face rules have fetches set up for src descriptors when the font face
+ // is initialized in FontFace::InitCSSFontFace(). The fetch is not actually
+ // performed, but the AdTracker is notified.
+ EXPECT_TRUE(ad_tracker_->UrlHasBeenRequested(kVanillaFontURL));
EXPECT_FALSE(ad_tracker_->UrlHasBeenRequested(kVanillaImageURL));
// We override these to ensure the ad script appears on top of the stack when
diff --git a/chromium/third_party/blink/renderer/core/frame/bar_prop.cc b/chromium/third_party/blink/renderer/core/frame/bar_prop.cc
index e1c3b2ba5d1..e679afd7fb9 100644
--- a/chromium/third_party/blink/renderer/core/frame/bar_prop.cc
+++ b/chromium/third_party/blink/renderer/core/frame/bar_prop.cc
@@ -37,7 +37,7 @@ namespace blink {
BarProp::BarProp(LocalFrame* frame, Type type)
: ExecutionContextClient(frame), type_(type) {}
-void BarProp::Trace(Visitor* visitor) {
+void BarProp::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/bar_prop.h b/chromium/third_party/blink/renderer/core/frame/bar_prop.h
index 8ddf97912d0..7d9c374ad07 100644
--- a/chromium/third_party/blink/renderer/core/frame/bar_prop.h
+++ b/chromium/third_party/blink/renderer/core/frame/bar_prop.h
@@ -55,7 +55,7 @@ class BarProp final : public ScriptWrappable, public ExecutionContextClient {
bool visible() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Type type_;
diff --git a/chromium/third_party/blink/renderer/core/frame/browser_controls.cc b/chromium/third_party/blink/renderer/core/frame/browser_controls.cc
index a780ffcc61d..91c0890b27b 100644
--- a/chromium/third_party/blink/renderer/core/frame/browser_controls.cc
+++ b/chromium/third_party/blink/renderer/core/frame/browser_controls.cc
@@ -23,7 +23,7 @@ BrowserControls::BrowserControls(const Page& page)
accumulated_scroll_delta_(0),
permitted_state_(cc::BrowserControlsState::kBoth) {}
-void BrowserControls::Trace(Visitor* visitor) {
+void BrowserControls::Trace(Visitor* visitor) const {
visitor->Trace(page_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/browser_controls.h b/chromium/third_party/blink/renderer/core/frame/browser_controls.h
index a1361b15617..21039fe35cc 100644
--- a/chromium/third_party/blink/renderer/core/frame/browser_controls.h
+++ b/chromium/third_party/blink/renderer/core/frame/browser_controls.h
@@ -27,7 +27,7 @@ class CORE_EXPORT BrowserControls final
public:
explicit BrowserControls(const Page&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// The height the top controls are hidden; used for viewport adjustments
// while the controls are resizing.
diff --git a/chromium/third_party/blink/renderer/core/frame/browser_controls_test.cc b/chromium/third_party/blink/renderer/core/frame/browser_controls_test.cc
index 5bb535b1c29..5d47a23be63 100644
--- a/chromium/third_party/blink/renderer/core/frame/browser_controls_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/browser_controls_test.cc
@@ -76,7 +76,7 @@ class BrowserControlsTest : public testing::Test,
}
~BrowserControlsTest() override {
- platform_->GetURLLoaderMockFactory()
+ WebURLLoaderMockFactory::GetSingletonInstance()
->UnregisterAllURLsAndClearMemoryCache();
}
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.cc b/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
index 5c8a945baf9..1404acbaf83 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
+++ b/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
@@ -29,6 +29,7 @@
#include <utility>
#include "base/debug/dump_without_crashing.h"
+#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/web_sandbox_flags.h"
#include "services/network/public/mojom/web_sandbox_flags.mojom-blink.h"
#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
@@ -286,7 +287,7 @@ void ContentSecurityPolicy::ApplyPolicySideEffectsToDelegate() {
ContentSecurityPolicy::~ContentSecurityPolicy() = default;
-void ContentSecurityPolicy::Trace(Visitor* visitor) {
+void ContentSecurityPolicy::Trace(Visitor* visitor) const {
visitor->Trace(delegate_);
visitor->Trace(policies_);
visitor->Trace(console_messages_);
@@ -551,7 +552,7 @@ bool ContentSecurityPolicy::AllowInline(
// Step 3. For each policy in element’s Document's global object’s CSP list:
// [spec text]
for (const auto& policy : policies_) {
- // May be whitelisted by hash, if 'unsafe-hashes' is present in a policy.
+ // May be allowed by hash, if 'unsafe-hashes' is present in a policy.
// Check against the digest of the |content| and also check whether inline
// script is allowed.
is_allowed &=
@@ -643,23 +644,6 @@ bool ContentSecurityPolicy::AllowPluginTypeForDocument(
return true;
}
-bool ContentSecurityPolicy::AllowRequestWithoutIntegrity(
- mojom::RequestContextType context,
- network::mojom::RequestDestination request_destination,
- const KURL& url,
- RedirectStatus redirect_status,
- ReportingDisposition reporting_disposition,
- CheckHeaderType check_header_type) const {
- for (const auto& policy : policies_) {
- if (CheckHeaderTypeMatches(check_header_type, policy->HeaderType()) &&
- !policy->AllowRequestWithoutIntegrity(context, request_destination, url,
- redirect_status,
- reporting_disposition))
- return false;
- }
- return true;
-}
-
static base::Optional<ContentSecurityPolicy::DirectiveType>
GetDirectiveTypeFromRequestContextType(mojom::RequestContextType context) {
switch (context) {
@@ -732,24 +716,18 @@ bool ContentSecurityPolicy::AllowRequest(
const String& nonce,
const IntegrityMetadataSet& integrity_metadata,
ParserDisposition parser_disposition,
+ const KURL& url_before_redirects,
RedirectStatus redirect_status,
ReportingDisposition reporting_disposition,
CheckHeaderType check_header_type) const {
- if (integrity_metadata.IsEmpty() &&
- !AllowRequestWithoutIntegrity(context, request_destination, url,
- redirect_status, reporting_disposition,
- check_header_type)) {
- return false;
- }
-
base::Optional<ContentSecurityPolicy::DirectiveType> type =
GetDirectiveTypeFromRequestContextType(context);
if (!type)
return true;
- return AllowFromSource(*type, url, redirect_status, reporting_disposition,
- check_header_type, nonce, integrity_metadata,
- parser_disposition);
+ return AllowFromSource(*type, url, url_before_redirects, redirect_status,
+ reporting_disposition, check_header_type, nonce,
+ integrity_metadata, parser_disposition);
}
void ContentSecurityPolicy::UsesScriptHashAlgorithms(uint8_t algorithms) {
@@ -763,6 +741,7 @@ void ContentSecurityPolicy::UsesStyleHashAlgorithms(uint8_t algorithms) {
bool ContentSecurityPolicy::AllowFromSource(
ContentSecurityPolicy::DirectiveType type,
const KURL& url,
+ const KURL& url_before_redirects,
RedirectStatus redirect_status,
ReportingDisposition reporting_disposition,
CheckHeaderType check_header_type,
@@ -803,9 +782,9 @@ bool ContentSecurityPolicy::AllowFromSource(
for (const auto& policy : policies_) {
if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType()))
continue;
- is_allowed &= policy->AllowFromSource(type, url, redirect_status,
- reporting_disposition, nonce, hashes,
- parser_disposition);
+ is_allowed &= policy->AllowFromSource(
+ type, url, url_before_redirects, redirect_status, reporting_disposition,
+ nonce, hashes, parser_disposition);
}
return is_allowed;
@@ -815,40 +794,45 @@ bool ContentSecurityPolicy::AllowBaseURI(const KURL& url) const {
// `base-uri` isn't affected by 'upgrade-insecure-requests', so we use
// CheckHeaderType::kCheckAll to check both report-only and enforce headers
// here.
- return AllowFromSource(ContentSecurityPolicy::DirectiveType::kBaseURI, url);
+ return AllowFromSource(ContentSecurityPolicy::DirectiveType::kBaseURI, url,
+ url, RedirectStatus::kNoRedirect);
}
bool ContentSecurityPolicy::AllowConnectToSource(
const KURL& url,
+ const KURL& url_before_redirects,
RedirectStatus redirect_status,
ReportingDisposition reporting_disposition,
CheckHeaderType check_header_type) const {
return AllowFromSource(ContentSecurityPolicy::DirectiveType::kConnectSrc, url,
- redirect_status, reporting_disposition,
- check_header_type);
+ url_before_redirects, redirect_status,
+ reporting_disposition, check_header_type);
}
bool ContentSecurityPolicy::AllowFormAction(const KURL& url) const {
- return AllowFromSource(ContentSecurityPolicy::DirectiveType::kFormAction,
- url);
+ return AllowFromSource(ContentSecurityPolicy::DirectiveType::kFormAction, url,
+ url, RedirectStatus::kNoRedirect);
}
bool ContentSecurityPolicy::AllowImageFromSource(
const KURL& url,
+ const KURL& url_before_redirects,
RedirectStatus redirect_status,
ReportingDisposition reporting_disposition,
CheckHeaderType check_header_type) const {
return AllowFromSource(ContentSecurityPolicy::DirectiveType::kImgSrc, url,
- redirect_status, reporting_disposition,
- check_header_type);
+ url_before_redirects, redirect_status,
+ reporting_disposition, check_header_type);
}
bool ContentSecurityPolicy::AllowMediaFromSource(const KURL& url) const {
- return AllowFromSource(ContentSecurityPolicy::DirectiveType::kMediaSrc, url);
+ return AllowFromSource(ContentSecurityPolicy::DirectiveType::kMediaSrc, url,
+ url, RedirectStatus::kNoRedirect);
}
bool ContentSecurityPolicy::AllowObjectFromSource(const KURL& url) const {
- return AllowFromSource(ContentSecurityPolicy::DirectiveType::kObjectSrc, url);
+ return AllowFromSource(ContentSecurityPolicy::DirectiveType::kObjectSrc, url,
+ url, RedirectStatus::kNoRedirect);
}
bool ContentSecurityPolicy::AllowScriptFromSource(
@@ -856,17 +840,20 @@ bool ContentSecurityPolicy::AllowScriptFromSource(
const String& nonce,
const IntegrityMetadataSet& hashes,
ParserDisposition parser_disposition,
+ const KURL& url_before_redirects,
RedirectStatus redirect_status,
ReportingDisposition reporting_disposition,
CheckHeaderType check_header_type) const {
return AllowFromSource(ContentSecurityPolicy::DirectiveType::kScriptSrcElem,
- url, redirect_status, reporting_disposition,
- check_header_type, nonce, hashes, parser_disposition);
+ url, url_before_redirects, redirect_status,
+ reporting_disposition, check_header_type, nonce,
+ hashes, parser_disposition);
}
bool ContentSecurityPolicy::AllowWorkerContextFromSource(
const KURL& url) const {
- return AllowFromSource(ContentSecurityPolicy::DirectiveType::kWorkerSrc, url);
+ return AllowFromSource(ContentSecurityPolicy::DirectiveType::kWorkerSrc, url,
+ url, RedirectStatus::kNoRedirect);
}
bool ContentSecurityPolicy::AllowTrustedTypePolicy(const String& policy_name,
@@ -1015,9 +1002,13 @@ static void GatherSecurityPolicyViolationEventData(
init->setBlockedURI("eval");
break;
case ContentSecurityPolicy::kURLViolation:
- init->setBlockedURI(
- StripURLForUseInReport(delegate->GetSecurityOrigin(), blocked_url,
- redirect_status, effective_type));
+ // We pass RedirectStatus::kNoRedirect so that StripURLForUseInReport
+ // does not strip path and query from the URL. This is safe since
+ // blocked_url at this point is always the original url (before
+ // redirects).
+ init->setBlockedURI(StripURLForUseInReport(
+ delegate->GetSecurityOrigin(), blocked_url,
+ RedirectStatus::kNoRedirect, effective_type));
break;
case ContentSecurityPolicy::kTrustedTypesSinkViolation:
init->setBlockedURI("trusted-types-sink");
@@ -1147,7 +1138,7 @@ void ContentSecurityPolicy::ReportViolation(
// |delegate_|.
ContentSecurityPolicyDelegate* relevant_delegate =
context_frame
- ? &context_frame->GetDocument()->GetContentSecurityPolicyDelegate()
+ ? &context_frame->DomWindow()->GetContentSecurityPolicyDelegate()
: delegate_.Get();
DCHECK(relevant_delegate);
GatherSecurityPolicyViolationEventData(
@@ -1228,7 +1219,7 @@ void ContentSecurityPolicy::PostViolationReport(
bool is_frame_ancestors_violation = !!context_frame;
ContentSecurityPolicyDelegate* relevant_delegate =
is_frame_ancestors_violation
- ? &context_frame->GetDocument()->GetContentSecurityPolicyDelegate()
+ ? &context_frame->DomWindow()->GetContentSecurityPolicyDelegate()
: delegate_.Get();
DCHECK(relevant_delegate);
@@ -1239,10 +1230,10 @@ void ContentSecurityPolicy::PostViolationReport(
}
void ContentSecurityPolicy::ReportMixedContent(
- const KURL& mixed_url,
+ const KURL& blocked_url,
RedirectStatus redirect_status) const {
for (const auto& policy : policies_)
- policy->ReportMixedContent(mixed_url, redirect_status);
+ policy->ReportMixedContent(blocked_url, redirect_status);
}
void ContentSecurityPolicy::ReportReportOnlyInMeta(const String& header) {
@@ -1365,14 +1356,6 @@ void ContentSecurityPolicy::ReportInvalidSandboxFlags(
invalid_flags);
}
-void ContentSecurityPolicy::ReportInvalidRequireSRIForTokens(
- const String& invalid_tokens) {
- LogToConsole(
- "Error while parsing the 'require-sri-for' Content Security Policy "
- "directive: " +
- invalid_tokens);
-}
-
void ContentSecurityPolicy::ReportInvalidDirectiveValueCharacter(
const String& directive_name,
const String& value) {
@@ -1536,8 +1519,6 @@ const char* ContentSecurityPolicy::GetDirectiveName(const DirectiveType& type) {
return "plugin-types";
case DirectiveType::kReportURI:
return "report-uri";
- case DirectiveType::kRequireSRIFor:
- return "require-sri-for";
case DirectiveType::kTrustedTypes:
return "trusted-types";
case DirectiveType::kSandbox:
@@ -1607,8 +1588,6 @@ ContentSecurityPolicy::DirectiveType ContentSecurityPolicy::GetDirectiveType(
return DirectiveType::kPrefetchSrc;
if (name == "report-uri")
return DirectiveType::kReportURI;
- if (name == "require-sri-for")
- return DirectiveType::kRequireSRIFor;
if (name == "require-trusted-types-for")
return DirectiveType::kRequireTrustedTypesFor;
if (name == "trusted-types")
@@ -1640,6 +1619,7 @@ ContentSecurityPolicy::DirectiveType ContentSecurityPolicy::GetDirectiveType(
}
bool ContentSecurityPolicy::Subsumes(const ContentSecurityPolicy& other) const {
+ DCHECK(!base::FeatureList::IsEnabled(network::features::kOutOfBlinkCSPEE));
if (!policies_.size() || !other.policies_.size())
return !policies_.size();
// Required-CSP must specify only one policy.
@@ -1702,6 +1682,9 @@ bool ContentSecurityPolicy::IsValidCSPAttr(const String& attr,
return true;
}
+ if (base::FeatureList::IsEnabled(network::features::kOutOfBlinkCSPEE))
+ return true;
+
auto* context_policy = MakeGarbageCollected<ContentSecurityPolicy>();
context_policy->AddPolicyFromHeaderValue(context_required_csp,
ContentSecurityPolicyType::kEnforce,
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.h b/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.h
index 29fe4bae016..f18fc9a763d 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.h
+++ b/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.h
@@ -181,7 +181,6 @@ class CORE_EXPORT ContentSecurityPolicy final
kPrefetchSrc,
kReportTo,
kReportURI,
- kRequireSRIFor,
kTrustedTypes,
kSandbox,
kScriptSrc,
@@ -214,7 +213,7 @@ class CORE_EXPORT ContentSecurityPolicy final
ContentSecurityPolicy();
~ContentSecurityPolicy();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
bool IsBound();
void BindToDelegate(ContentSecurityPolicyDelegate&);
@@ -271,13 +270,15 @@ class CORE_EXPORT ContentSecurityPolicy final
bool AllowBaseURI(const KURL&) const;
bool AllowConnectToSource(
const KURL&,
- RedirectStatus = RedirectStatus::kNoRedirect,
+ const KURL& url_before_redirects,
+ RedirectStatus,
ReportingDisposition = ReportingDisposition::kReport,
CheckHeaderType = CheckHeaderType::kCheckAll) const;
bool AllowFormAction(const KURL&) const;
bool AllowImageFromSource(
const KURL&,
- RedirectStatus = RedirectStatus::kNoRedirect,
+ const KURL& url_before_redirects,
+ RedirectStatus,
ReportingDisposition = ReportingDisposition::kReport,
CheckHeaderType = CheckHeaderType::kCheckAll) const;
bool AllowMediaFromSource(const KURL&) const;
@@ -287,7 +288,8 @@ class CORE_EXPORT ContentSecurityPolicy final
const String& nonce,
const IntegrityMetadataSet&,
ParserDisposition,
- RedirectStatus = RedirectStatus::kNoRedirect,
+ const KURL& url_before_redirects,
+ RedirectStatus,
ReportingDisposition = ReportingDisposition::kReport,
CheckHeaderType = CheckHeaderType::kCheckAll) const;
bool AllowWorkerContextFromSource(const KURL&) const;
@@ -334,7 +336,8 @@ class CORE_EXPORT ContentSecurityPolicy final
mojom::RequestContextType,
network::mojom::RequestDestination,
const KURL&,
- RedirectStatus = RedirectStatus::kNoRedirect,
+ const KURL& url_before_redirects,
+ RedirectStatus,
ReportingDisposition = ReportingDisposition::kReport,
CheckHeaderType = CheckHeaderType::kCheckAll) const;
@@ -346,7 +349,8 @@ class CORE_EXPORT ContentSecurityPolicy final
const String& nonce,
const IntegrityMetadataSet&,
ParserDisposition,
- RedirectStatus = RedirectStatus::kNoRedirect,
+ const KURL& url_before_redirects,
+ RedirectStatus,
ReportingDisposition = ReportingDisposition::kReport,
CheckHeaderType = CheckHeaderType::kCheckAll) const;
@@ -380,7 +384,6 @@ class CORE_EXPORT ContentSecurityPolicy final
const String& value,
const char);
void ReportInvalidPluginTypes(const String&);
- void ReportInvalidRequireSRIForTokens(const String&);
void ReportInvalidSandboxFlags(const String&);
void ReportInvalidSourceExpression(const String& directive_name,
const String& source);
@@ -419,7 +422,7 @@ class CORE_EXPORT ContentSecurityPolicy final
// Called when mixed content is detected on a page; will trigger a violation
// report if the 'block-all-mixed-content' directive is specified for a
// policy.
- void ReportMixedContent(const KURL& mixed_url, RedirectStatus) const;
+ void ReportMixedContent(const KURL& blocked_url, RedirectStatus) const;
void ReportBlockedScriptExecutionToInspector(
const String& directive_text) const;
@@ -546,7 +549,8 @@ class CORE_EXPORT ContentSecurityPolicy final
bool AllowFromSource(ContentSecurityPolicy::DirectiveType,
const KURL&,
- RedirectStatus = RedirectStatus::kNoRedirect,
+ const KURL& url_before_redirects,
+ RedirectStatus,
ReportingDisposition = ReportingDisposition::kReport,
CheckHeaderType = CheckHeaderType::kCheckAll,
const String& = String(),
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc b/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc
index b3e0efc8097..200ce509916 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/document_init.h"
#include "third_party/blink/renderer/core/frame/csp/csp_directive_list.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/html/html_script_element.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/core/testing/null_execution_context.h"
@@ -85,7 +86,7 @@ TEST_F(ContentSecurityPolicyTest, ParseInsecureRequestPolicy) {
security_context.SetSecurityOriginForTesting(secure_origin);
csp->BindToDelegate(
- dummy->GetDocument().GetContentSecurityPolicyDelegate());
+ dummy->GetFrame().DomWindow()->GetContentSecurityPolicyDelegate());
EXPECT_EQ(test.expected_policy,
security_context.GetInsecureRequestPolicy());
bool expect_upgrade =
@@ -134,18 +135,19 @@ TEST_F(ContentSecurityPolicyTest, CopyStateFrom) {
csp2->CopyStateFrom(csp.Get());
EXPECT_FALSE(csp2->AllowScriptFromSource(
example_url, String(), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
+ example_url, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly));
EXPECT_TRUE(csp2->AllowPluginType("application/x-type-1",
"application/x-type-1", example_url,
ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(csp2->AllowImageFromSource(
- example_url, ResourceRequest::RedirectStatus::kNoRedirect,
+ example_url, example_url, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly));
EXPECT_FALSE(csp2->AllowImageFromSource(
- not_example_url, ResourceRequest::RedirectStatus::kNoRedirect,
+ not_example_url, not_example_url,
+ ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly));
EXPECT_FALSE(csp2->AllowPluginType("application/x-type-2",
@@ -168,17 +170,18 @@ TEST_F(ContentSecurityPolicyTest, CopyPluginTypesFrom) {
csp2->CopyPluginTypesFrom(csp.Get());
EXPECT_TRUE(csp2->AllowScriptFromSource(
example_url, String(), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
+ example_url, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(csp2->AllowPluginType("application/x-type-1",
"application/x-type-1", example_url,
ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(csp2->AllowImageFromSource(
- example_url, ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(csp2->AllowImageFromSource(
- not_example_url, ResourceRequest::RedirectStatus::kNoRedirect,
+ example_url, example_url, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
+ EXPECT_TRUE(
+ csp2->AllowImageFromSource(not_example_url, not_example_url,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp2->AllowPluginType("application/x-type-2",
"application/x-type-2", example_url,
ReportingDisposition::kSuppressReporting));
@@ -279,19 +282,19 @@ TEST_F(ContentSecurityPolicyTest, ObjectSrc) {
EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::OBJECT,
network::mojom::RequestDestination::kEmpty,
url, String(), IntegrityMetadataSet(),
- kParserInserted,
+ kParserInserted, url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::EMBED,
network::mojom::RequestDestination::kEmbed,
url, String(), IntegrityMetadataSet(),
- kParserInserted,
+ kParserInserted, url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::PLUGIN,
network::mojom::RequestDestination::kEmpty, url,
String(), IntegrityMetadataSet(),
- kParserInserted,
+ kParserInserted, url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
}
@@ -305,456 +308,34 @@ TEST_F(ContentSecurityPolicyTest, ConnectSrc) {
EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::SUBRESOURCE,
network::mojom::RequestDestination::kEmpty,
url, String(), IntegrityMetadataSet(),
- kParserInserted,
+ kParserInserted, url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::XML_HTTP_REQUEST,
network::mojom::RequestDestination::kEmpty,
url, String(), IntegrityMetadataSet(),
- kParserInserted,
+ kParserInserted, url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::BEACON,
network::mojom::RequestDestination::kEmpty,
url, String(), IntegrityMetadataSet(),
- kParserInserted,
+ kParserInserted, url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::FETCH,
network::mojom::RequestDestination::kEmpty,
url, String(), IntegrityMetadataSet(),
- kParserInserted,
+ kParserInserted, url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::PLUGIN,
network::mojom::RequestDestination::kEmpty, url,
String(), IntegrityMetadataSet(),
- kParserInserted,
+ kParserInserted, url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
}
-// Tests that requests for scripts and styles are blocked
-// if `require-sri-for` delivered in HTTP header requires integrity be present
-TEST_F(ContentSecurityPolicyTest, RequireSRIForInHeaderMissingIntegrity) {
- const KURL url("https://example.test");
- // Enforce
- Persistent<ContentSecurityPolicy> policy =
- MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- policy->DidReceiveHeader("require-sri-for script style",
- ContentSecurityPolicyType::kEnforce,
- ContentSecurityPolicySource::kHTTP);
- EXPECT_FALSE(
- policy->AllowRequest(mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, url,
- String(), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_FALSE(
- policy->AllowRequest(mojom::RequestContextType::IMPORT,
- network::mojom::RequestDestination::kEmpty, url,
- String(), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_FALSE(
- policy->AllowRequest(mojom::RequestContextType::STYLE,
- network::mojom::RequestDestination::kStyle, url,
- String(), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_FALSE(policy->AllowRequest(
- mojom::RequestContextType::SERVICE_WORKER,
- network::mojom::RequestDestination::kServiceWorker, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_FALSE(policy->AllowRequest(
- mojom::RequestContextType::SHARED_WORKER,
- network::mojom::RequestDestination::kSharedWorker, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_FALSE(
- policy->AllowRequest(mojom::RequestContextType::WORKER,
- network::mojom::RequestDestination::kWorker, url,
- String(), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::IMAGE,
- network::mojom::RequestDestination::kImage,
- url, String(), IntegrityMetadataSet(),
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- // Report
- policy = MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- policy->DidReceiveHeader("require-sri-for script style",
- ContentSecurityPolicyType::kReport,
- ContentSecurityPolicySource::kHTTP);
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript,
- url, String(), IntegrityMetadataSet(),
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::IMPORT,
- network::mojom::RequestDestination::kEmpty,
- url, String(), IntegrityMetadataSet(),
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::STYLE,
- network::mojom::RequestDestination::kStyle,
- url, String(), IntegrityMetadataSet(),
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SERVICE_WORKER,
- network::mojom::RequestDestination::kServiceWorker, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SHARED_WORKER,
- network::mojom::RequestDestination::kSharedWorker, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::WORKER,
- network::mojom::RequestDestination::kWorker,
- url, String(), IntegrityMetadataSet(),
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::IMAGE,
- network::mojom::RequestDestination::kImage,
- url, String(), IntegrityMetadataSet(),
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
-}
-
-// Tests that requests for scripts and styles are allowed
-// if `require-sri-for` delivered in HTTP header requires integrity be present
-TEST_F(ContentSecurityPolicyTest, RequireSRIForInHeaderPresentIntegrity) {
- const KURL url("https://example.test");
- IntegrityMetadataSet integrity_metadata;
- integrity_metadata.insert(
- IntegrityMetadata("1234", IntegrityAlgorithm::kSha384).ToPair());
- csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- // Enforce
- Persistent<ContentSecurityPolicy> policy =
- MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- policy->DidReceiveHeader("require-sri-for script style",
- ContentSecurityPolicyType::kEnforce,
- ContentSecurityPolicySource::kHTTP);
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::IMPORT,
- network::mojom::RequestDestination::kEmpty,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::STYLE,
- network::mojom::RequestDestination::kStyle,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(
- policy->AllowRequest(mojom::RequestContextType::SERVICE_WORKER,
- network::mojom::RequestDestination::kServiceWorker,
- url, String(), integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(
- policy->AllowRequest(mojom::RequestContextType::SHARED_WORKER,
- network::mojom::RequestDestination::kSharedWorker,
- url, String(), integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::WORKER,
- network::mojom::RequestDestination::kWorker,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::IMAGE,
- network::mojom::RequestDestination::kImage,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- // Content-Security-Policy-Report-Only is not supported in meta element,
- // so nothing should be blocked
- policy = MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- policy->DidReceiveHeader("require-sri-for script style",
- ContentSecurityPolicyType::kReport,
- ContentSecurityPolicySource::kHTTP);
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::IMPORT,
- network::mojom::RequestDestination::kEmpty,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::STYLE,
- network::mojom::RequestDestination::kStyle,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(
- policy->AllowRequest(mojom::RequestContextType::SERVICE_WORKER,
- network::mojom::RequestDestination::kServiceWorker,
- url, String(), integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(
- policy->AllowRequest(mojom::RequestContextType::SHARED_WORKER,
- network::mojom::RequestDestination::kSharedWorker,
- url, String(), integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::WORKER,
- network::mojom::RequestDestination::kWorker,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::IMAGE,
- network::mojom::RequestDestination::kImage,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
-}
-
-// Tests that requests for scripts and styles are blocked
-// if `require-sri-for` delivered in meta tag requires integrity be present
-TEST_F(ContentSecurityPolicyTest, RequireSRIForInMetaMissingIntegrity) {
- const KURL url("https://example.test");
- // Enforce
- Persistent<ContentSecurityPolicy> policy =
- MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- policy->DidReceiveHeader("require-sri-for script style",
- ContentSecurityPolicyType::kEnforce,
- ContentSecurityPolicySource::kMeta);
- EXPECT_FALSE(
- policy->AllowRequest(mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, url,
- String(), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_FALSE(
- policy->AllowRequest(mojom::RequestContextType::IMPORT,
- network::mojom::RequestDestination::kEmpty, url,
- String(), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_FALSE(
- policy->AllowRequest(mojom::RequestContextType::STYLE,
- network::mojom::RequestDestination::kStyle, url,
- String(), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_FALSE(policy->AllowRequest(
- mojom::RequestContextType::SERVICE_WORKER,
- network::mojom::RequestDestination::kServiceWorker, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_FALSE(policy->AllowRequest(
- mojom::RequestContextType::SHARED_WORKER,
- network::mojom::RequestDestination::kSharedWorker, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_FALSE(
- policy->AllowRequest(mojom::RequestContextType::WORKER,
- network::mojom::RequestDestination::kWorker, url,
- String(), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::IMAGE,
- network::mojom::RequestDestination::kImage,
- url, String(), IntegrityMetadataSet(),
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- // Content-Security-Policy-Report-Only is not supported in meta element,
- // so nothing should be blocked
- policy = MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- policy->DidReceiveHeader("require-sri-for script style",
- ContentSecurityPolicyType::kReport,
- ContentSecurityPolicySource::kMeta);
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript,
- url, String(), IntegrityMetadataSet(),
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::IMPORT,
- network::mojom::RequestDestination::kEmpty,
- url, String(), IntegrityMetadataSet(),
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::STYLE,
- network::mojom::RequestDestination::kStyle,
- url, String(), IntegrityMetadataSet(),
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SERVICE_WORKER,
- network::mojom::RequestDestination::kServiceWorker, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SHARED_WORKER,
- network::mojom::RequestDestination::kSharedWorker, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::WORKER,
- network::mojom::RequestDestination::kWorker,
- url, String(), IntegrityMetadataSet(),
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::IMAGE,
- network::mojom::RequestDestination::kImage,
- url, String(), IntegrityMetadataSet(),
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
-}
-
-// Tests that requests for scripts and styles are allowed
-// if `require-sri-for` delivered meta tag requires integrity be present
-TEST_F(ContentSecurityPolicyTest, RequireSRIForInMetaPresentIntegrity) {
- const KURL url("https://example.test");
- IntegrityMetadataSet integrity_metadata;
- integrity_metadata.insert(
- IntegrityMetadata("1234", IntegrityAlgorithm::kSha384).ToPair());
- csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- // Enforce
- Persistent<ContentSecurityPolicy> policy =
- MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- policy->DidReceiveHeader("require-sri-for script style",
- ContentSecurityPolicyType::kEnforce,
- ContentSecurityPolicySource::kMeta);
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::IMPORT,
- network::mojom::RequestDestination::kEmpty,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::STYLE,
- network::mojom::RequestDestination::kStyle,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(
- policy->AllowRequest(mojom::RequestContextType::SERVICE_WORKER,
- network::mojom::RequestDestination::kServiceWorker,
- url, String(), integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(
- policy->AllowRequest(mojom::RequestContextType::SHARED_WORKER,
- network::mojom::RequestDestination::kSharedWorker,
- url, String(), integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::WORKER,
- network::mojom::RequestDestination::kWorker,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::IMAGE,
- network::mojom::RequestDestination::kImage,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- // Content-Security-Policy-Report-Only is not supported in meta element,
- // so nothing should be blocked
- policy = MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- policy->DidReceiveHeader("require-sri-for script style",
- ContentSecurityPolicyType::kReport,
- ContentSecurityPolicySource::kMeta);
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::IMPORT,
- network::mojom::RequestDestination::kEmpty,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::STYLE,
- network::mojom::RequestDestination::kStyle,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(
- policy->AllowRequest(mojom::RequestContextType::SERVICE_WORKER,
- network::mojom::RequestDestination::kServiceWorker,
- url, String(), integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(
- policy->AllowRequest(mojom::RequestContextType::SHARED_WORKER,
- network::mojom::RequestDestination::kSharedWorker,
- url, String(), integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::WORKER,
- network::mojom::RequestDestination::kWorker,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::IMAGE,
- network::mojom::RequestDestination::kImage,
- url, String(), integrity_metadata,
- kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
-}
TEST_F(ContentSecurityPolicyTest, NonceSinglePolicy) {
struct TestCase {
@@ -788,9 +369,11 @@ TEST_F(ContentSecurityPolicyTest, NonceSinglePolicy) {
execution_context->GetContentSecurityPolicyDelegate());
policy->DidReceiveHeader(test.policy, ContentSecurityPolicyType::kEnforce,
ContentSecurityPolicySource::kHTTP);
- EXPECT_EQ(test.allowed, policy->AllowScriptFromSource(
- resource, String(test.nonce),
- IntegrityMetadataSet(), kParserInserted));
+ EXPECT_EQ(test.allowed,
+ policy->AllowScriptFromSource(
+ resource, String(test.nonce), IntegrityMetadataSet(),
+ kParserInserted, resource,
+ ResourceRequest::RedirectStatus::kNoRedirect));
// If this is expected to generate a violation, we should have sent a
// report.
EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size());
@@ -803,7 +386,7 @@ TEST_F(ContentSecurityPolicyTest, NonceSinglePolicy) {
ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(policy->AllowScriptFromSource(
resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kReport,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly));
// If this is expected to generate a violation, we should have sent a
@@ -832,8 +415,8 @@ TEST_F(ContentSecurityPolicyTest, NonceInline) {
// We need document for HTMLScriptElement tests.
auto dummy = std::make_unique<DummyPageHolder>();
- auto& document = dummy->GetDocument();
- document.GetSecurityContext().SetSecurityOriginForTesting(secure_origin);
+ auto* window = dummy->GetFrame().DomWindow();
+ window->GetSecurityContext().SetSecurityOriginForTesting(secure_origin);
for (const auto& test : cases) {
SCOPED_TRACE(testing::Message() << "Policy: `" << test.policy
@@ -841,12 +424,12 @@ TEST_F(ContentSecurityPolicyTest, NonceInline) {
unsigned expected_reports = test.allowed ? 0u : 1u;
auto* element = MakeGarbageCollected<HTMLScriptElement>(
- document, CreateElementFlags::ByParser());
+ *window->document(), CreateElementFlags());
// Enforce 'script-src'
Persistent<ContentSecurityPolicy> policy =
MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(document.GetContentSecurityPolicyDelegate());
+ policy->BindToDelegate(window->GetContentSecurityPolicyDelegate());
policy->DidReceiveHeader(String("script-src ") + test.policy,
ContentSecurityPolicyType::kEnforce,
ContentSecurityPolicySource::kHTTP);
@@ -858,7 +441,7 @@ TEST_F(ContentSecurityPolicyTest, NonceInline) {
// Enforce 'style-src'
policy = MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(document.GetContentSecurityPolicyDelegate());
+ policy->BindToDelegate(window->GetContentSecurityPolicyDelegate());
policy->DidReceiveHeader(String("style-src ") + test.policy,
ContentSecurityPolicyType::kEnforce,
ContentSecurityPolicySource::kHTTP);
@@ -870,7 +453,7 @@ TEST_F(ContentSecurityPolicyTest, NonceInline) {
// Report 'script-src'
policy = MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(document.GetContentSecurityPolicyDelegate());
+ policy->BindToDelegate(window->GetContentSecurityPolicyDelegate());
policy->DidReceiveHeader(String("script-src ") + test.policy,
ContentSecurityPolicyType::kReport,
ContentSecurityPolicySource::kHTTP);
@@ -881,7 +464,7 @@ TEST_F(ContentSecurityPolicyTest, NonceInline) {
// Report 'style-src'
policy = MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(document.GetContentSecurityPolicyDelegate());
+ policy->BindToDelegate(window->GetContentSecurityPolicyDelegate());
policy->DidReceiveHeader(String("style-src ") + test.policy,
ContentSecurityPolicyType::kReport,
ContentSecurityPolicySource::kHTTP);
@@ -961,12 +544,13 @@ TEST_F(ContentSecurityPolicyTest, NonceMultiplePolicy) {
EXPECT_EQ(test.allowed1,
policy->AllowScriptFromSource(
resource, String(test.nonce), IntegrityMetadataSet(),
- kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
+ kParserInserted, resource,
+ ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kReport,
ContentSecurityPolicy::CheckHeaderType::kCheckEnforce));
EXPECT_TRUE(policy->AllowScriptFromSource(
resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kReport,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly));
EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size());
@@ -981,13 +565,14 @@ TEST_F(ContentSecurityPolicyTest, NonceMultiplePolicy) {
ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(policy->AllowScriptFromSource(
resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kReport,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly));
EXPECT_EQ(test.allowed2,
policy->AllowScriptFromSource(
resource, String(test.nonce), IntegrityMetadataSet(),
- kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
+ kParserInserted, resource,
+ ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kReport,
ContentSecurityPolicy::CheckHeaderType::kCheckEnforce));
EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size());
@@ -1003,7 +588,8 @@ TEST_F(ContentSecurityPolicyTest, NonceMultiplePolicy) {
EXPECT_EQ(test.allowed1 && test.allowed2,
policy->AllowScriptFromSource(
resource, String(test.nonce), IntegrityMetadataSet(),
- kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
+ kParserInserted, resource,
+ ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kReport,
ContentSecurityPolicy::CheckHeaderType::kCheckEnforce));
EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size());
@@ -1018,7 +604,7 @@ TEST_F(ContentSecurityPolicyTest, NonceMultiplePolicy) {
ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(policy->AllowScriptFromSource(
resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kReport,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly));
EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size());
@@ -1099,7 +685,6 @@ TEST_F(ContentSecurityPolicyTest, DirectiveType) {
{ContentSecurityPolicy::DirectiveType::kObjectSrc, "object-src"},
{ContentSecurityPolicy::DirectiveType::kPluginTypes, "plugin-types"},
{ContentSecurityPolicy::DirectiveType::kReportURI, "report-uri"},
- {ContentSecurityPolicy::DirectiveType::kRequireSRIFor, "require-sri-for"},
{ContentSecurityPolicy::DirectiveType::kSandbox, "sandbox"},
{ContentSecurityPolicy::DirectiveType::kScriptSrc, "script-src"},
{ContentSecurityPolicy::DirectiveType::kScriptSrcAttr, "script-src-attr"},
@@ -1171,18 +756,20 @@ TEST_F(ContentSecurityPolicyTest, RequestsAllowedWhenBypassingCSP) {
ContentSecurityPolicyType::kEnforce,
ContentSecurityPolicySource::kHTTP);
+ const KURL example_url("https://example.com/");
EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::OBJECT,
network::mojom::RequestDestination::kEmpty,
- KURL(base, "https://example.com/"), String(),
- IntegrityMetadataSet(), kParserInserted,
+ example_url, String(), IntegrityMetadataSet(),
+ kParserInserted, example_url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
+ const KURL not_example_url("https://not-example.com/");
EXPECT_FALSE(csp->AllowRequest(
mojom::RequestContextType::OBJECT,
- network::mojom::RequestDestination::kEmpty,
- KURL(base, "https://not-example.com/"), String(), IntegrityMetadataSet(),
- kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
+ network::mojom::RequestDestination::kEmpty, not_example_url, String(),
+ IntegrityMetadataSet(), kParserInserted, not_example_url,
+ ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
// Register "https" as bypassing CSP, which should now bypass it entirely
@@ -1190,16 +777,16 @@ TEST_F(ContentSecurityPolicyTest, RequestsAllowedWhenBypassingCSP) {
EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::OBJECT,
network::mojom::RequestDestination::kEmpty,
- KURL(base, "https://example.com/"), String(),
- IntegrityMetadataSet(), kParserInserted,
+ example_url, String(), IntegrityMetadataSet(),
+ kParserInserted, example_url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(csp->AllowRequest(
mojom::RequestContextType::OBJECT,
- network::mojom::RequestDestination::kEmpty,
- KURL(base, "https://not-example.com/"), String(), IntegrityMetadataSet(),
- kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
+ network::mojom::RequestDestination::kEmpty, not_example_url, String(),
+ IntegrityMetadataSet(), kParserInserted, not_example_url,
+ ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
SchemeRegistry::RemoveURLSchemeRegisteredAsBypassingContentSecurityPolicy(
@@ -1216,38 +803,36 @@ TEST_F(ContentSecurityPolicyTest, FilesystemAllowedWhenBypassingCSP) {
ContentSecurityPolicyType::kEnforce,
ContentSecurityPolicySource::kHTTP);
- EXPECT_FALSE(
- csp->AllowRequest(mojom::RequestContextType::OBJECT,
- network::mojom::RequestDestination::kEmpty,
- KURL(base, "filesystem:https://example.com/file.txt"),
- String(), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
+ const KURL example_url("filesystem:https://example.com/file.txt");
+ EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::OBJECT,
+ network::mojom::RequestDestination::kEmpty,
+ example_url, String(), IntegrityMetadataSet(),
+ kParserInserted, example_url,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
+ const KURL not_example_url("filesystem:https://not-example.com/file.txt");
EXPECT_FALSE(csp->AllowRequest(
mojom::RequestContextType::OBJECT,
- network::mojom::RequestDestination::kEmpty,
- KURL(base, "filesystem:https://not-example.com/file.txt"), String(),
- IntegrityMetadataSet(), kParserInserted,
+ network::mojom::RequestDestination::kEmpty, not_example_url, String(),
+ IntegrityMetadataSet(), kParserInserted, not_example_url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
// Register "https" as bypassing CSP, which should now bypass it entirely
SchemeRegistry::RegisterURLSchemeAsBypassingContentSecurityPolicy("https");
- EXPECT_TRUE(
- csp->AllowRequest(mojom::RequestContextType::OBJECT,
- network::mojom::RequestDestination::kEmpty,
- KURL(base, "filesystem:https://example.com/file.txt"),
- String(), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
+ EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::OBJECT,
+ network::mojom::RequestDestination::kEmpty,
+ example_url, String(), IntegrityMetadataSet(),
+ kParserInserted, example_url,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(csp->AllowRequest(
mojom::RequestContextType::OBJECT,
- network::mojom::RequestDestination::kEmpty,
- KURL(base, "filesystem:https://not-example.com/file.txt"), String(),
- IntegrityMetadataSet(), kParserInserted,
+ network::mojom::RequestDestination::kEmpty, not_example_url, String(),
+ IntegrityMetadataSet(), kParserInserted, not_example_url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
@@ -1266,39 +851,39 @@ TEST_F(ContentSecurityPolicyTest, BlobAllowedWhenBypassingCSP) {
ContentSecurityPolicyType::kEnforce,
ContentSecurityPolicySource::kHTTP);
- EXPECT_FALSE(csp->AllowRequest(
- mojom::RequestContextType::OBJECT,
- network::mojom::RequestDestination::kEmpty,
- KURL(base, "blob:https://example.com/"), String(), IntegrityMetadataSet(),
- kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
-
+ const KURL example_url("blob:https://example.com/");
EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::OBJECT,
network::mojom::RequestDestination::kEmpty,
- KURL(base, "blob:https://not-example.com/"),
- String(), IntegrityMetadataSet(),
- kParserInserted,
+ example_url, String(), IntegrityMetadataSet(),
+ kParserInserted, example_url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
- // Register "https" as bypassing CSP, which should now bypass it entirely
- SchemeRegistry::RegisterURLSchemeAsBypassingContentSecurityPolicy("https");
-
- EXPECT_TRUE(csp->AllowRequest(
+ const KURL not_example_url("blob:https://not-example.com/");
+ EXPECT_FALSE(csp->AllowRequest(
mojom::RequestContextType::OBJECT,
- network::mojom::RequestDestination::kEmpty,
- KURL(base, "blob:https://example.com/"), String(), IntegrityMetadataSet(),
- kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
+ network::mojom::RequestDestination::kEmpty, not_example_url, String(),
+ IntegrityMetadataSet(), kParserInserted, not_example_url,
+ ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
+ // Register "https" as bypassing CSP, which should now bypass it entirely
+ SchemeRegistry::RegisterURLSchemeAsBypassingContentSecurityPolicy("https");
+
EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::OBJECT,
network::mojom::RequestDestination::kEmpty,
- KURL(base, "blob:https://not-example.com/"),
- String(), IntegrityMetadataSet(),
- kParserInserted,
+ example_url, String(), IntegrityMetadataSet(),
+ kParserInserted, example_url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
+ EXPECT_TRUE(csp->AllowRequest(
+ mojom::RequestContextType::OBJECT,
+ network::mojom::RequestDestination::kEmpty, not_example_url, String(),
+ IntegrityMetadataSet(), kParserInserted, not_example_url,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
+
SchemeRegistry::RemoveURLSchemeRegisteredAsBypassingContentSecurityPolicy(
"https");
}
@@ -1329,19 +914,19 @@ TEST_F(ContentSecurityPolicyTest, CSPBypassDisabledWhenSchemeIsPrivileged) {
EXPECT_TRUE(csp->AllowScriptFromSource(
allowed_url, String(), IntegrityMetadataSet(), kNotParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
+ allowed_url, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp->AllowScriptFromSource(
- http_url, String(), IntegrityMetadataSet(), kNotParserInserted,
+ http_url, String(), IntegrityMetadataSet(), kNotParserInserted, http_url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp->AllowScriptFromSource(
- blob_url, String(), IntegrityMetadataSet(), kNotParserInserted,
+ blob_url, String(), IntegrityMetadataSet(), kNotParserInserted, blob_url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp->AllowScriptFromSource(
filesystem_url, String(), IntegrityMetadataSet(), kNotParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
+ filesystem_url, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
SchemeRegistry::RemoveURLSchemeRegisteredAsBypassingContentSecurityPolicy(
@@ -1680,9 +1265,11 @@ TEST_F(ContentSecurityPolicyTest, DirectiveNameCaseInsensitive) {
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
EXPECT_TRUE(csp->AllowScriptFromSource(
- example_url, String(), IntegrityMetadataSet(), kParserInserted));
+ example_url, String(), IntegrityMetadataSet(), kParserInserted,
+ example_url, ResourceRequest::RedirectStatus::kNoRedirect));
EXPECT_FALSE(csp->AllowScriptFromSource(
- not_example_url, String(), IntegrityMetadataSet(), kParserInserted));
+ not_example_url, String(), IntegrityMetadataSet(), kParserInserted,
+ not_example_url, ResourceRequest::RedirectStatus::kNoRedirect));
// Duplicate directive that is in a different case pattern is
// correctly treated as a duplicate directive and ignored.
@@ -1693,9 +1280,11 @@ TEST_F(ContentSecurityPolicyTest, DirectiveNameCaseInsensitive) {
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
EXPECT_TRUE(csp->AllowScriptFromSource(
- example_url, String(), IntegrityMetadataSet(), kParserInserted));
+ example_url, String(), IntegrityMetadataSet(), kParserInserted,
+ example_url, ResourceRequest::RedirectStatus::kNoRedirect));
EXPECT_FALSE(csp->AllowScriptFromSource(
- not_example_url, String(), IntegrityMetadataSet(), kParserInserted));
+ not_example_url, String(), IntegrityMetadataSet(), kParserInserted,
+ not_example_url, ResourceRequest::RedirectStatus::kNoRedirect));
}
// Tests that using an empty CSP works and doesn't impose any policy
@@ -1705,13 +1294,13 @@ TEST_F(ContentSecurityPolicyTest, EmptyCSPIsNoOp) {
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
const KURL example_url("http://example.com");
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
String source;
String context_url;
String nonce;
OrdinalNumber ordinal_number;
- auto* element = MakeGarbageCollected<HTMLScriptElement>(
- *document, CreateElementFlags::ByParser());
+ auto* element =
+ MakeGarbageCollected<HTMLScriptElement>(*document, CreateElementFlags());
EXPECT_TRUE(csp->Headers().IsEmpty());
EXPECT_TRUE(csp->AllowInline(ContentSecurityPolicy::InlineType::kNavigation,
@@ -1747,18 +1336,23 @@ TEST_F(ContentSecurityPolicyTest, EmptyCSPIsNoOp) {
ContentSecurityPolicy::DirectiveType::kStyleSrcElem,
ContentSecurityPolicy::DirectiveType::kWorkerSrc};
for (auto type : types_to_test) {
- EXPECT_TRUE(csp->AllowFromSource(type, example_url));
+ EXPECT_TRUE(
+ csp->AllowFromSource(type, example_url, example_url,
+ ResourceRequest::RedirectStatus::kNoRedirect));
}
EXPECT_TRUE(csp->AllowObjectFromSource(example_url));
- EXPECT_TRUE(csp->AllowImageFromSource(example_url));
+ EXPECT_TRUE(csp->AllowImageFromSource(
+ example_url, example_url, ResourceRequest::RedirectStatus::kNoRedirect));
EXPECT_TRUE(csp->AllowMediaFromSource(example_url));
- EXPECT_TRUE(csp->AllowConnectToSource(example_url));
+ EXPECT_TRUE(csp->AllowConnectToSource(
+ example_url, example_url, ResourceRequest::RedirectStatus::kNoRedirect));
EXPECT_TRUE(csp->AllowFormAction(example_url));
EXPECT_TRUE(csp->AllowBaseURI(example_url));
EXPECT_TRUE(csp->AllowWorkerContextFromSource(example_url));
EXPECT_TRUE(csp->AllowScriptFromSource(
- example_url, nonce, IntegrityMetadataSet(), kParserInserted));
+ example_url, nonce, IntegrityMetadataSet(), kParserInserted, example_url,
+ ResourceRequest::RedirectStatus::kNoRedirect));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", true));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false));
@@ -1770,13 +1364,11 @@ TEST_F(ContentSecurityPolicyTest, EmptyCSPIsNoOp) {
ordinal_number));
EXPECT_TRUE(csp->AllowAncestors(document->GetFrame(), example_url));
EXPECT_FALSE(csp->IsFrameAncestorsEnforced());
- EXPECT_TRUE(csp->AllowRequestWithoutIntegrity(
- mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, example_url));
EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::SCRIPT,
network::mojom::RequestDestination::kScript,
example_url, nonce, IntegrityMetadataSet(),
- kParserInserted));
+ kParserInserted, example_url,
+ ResourceRequest::RedirectStatus::kNoRedirect));
EXPECT_FALSE(csp->IsActive());
EXPECT_FALSE(csp->IsActiveForConnections());
EXPECT_TRUE(csp->FallbackUrlForPlugin().IsEmpty());
@@ -1804,7 +1396,7 @@ TEST_F(ContentSecurityPolicyTest, OpaqueOriginBeforeBind) {
EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::SUBRESOURCE,
network::mojom::RequestDestination::kEmpty, url,
String(), IntegrityMetadataSet(),
- kParserInserted,
+ kParserInserted, url,
ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
}
@@ -1845,7 +1437,7 @@ TEST_F(ContentSecurityPolicyTest, ReasonableRestrictionMetrics) {
ContentSecurityPolicySource::kHTTP);
auto dummy = std::make_unique<DummyPageHolder>();
csp->BindToDelegate(
- dummy->GetDocument().GetContentSecurityPolicyDelegate());
+ dummy->GetFrame().DomWindow()->GetContentSecurityPolicyDelegate());
EXPECT_EQ(test.expected_object,
dummy->GetDocument().IsUseCounted(
@@ -1871,7 +1463,7 @@ TEST_F(ContentSecurityPolicyTest, ReasonableRestrictionMetrics) {
ContentSecurityPolicySource::kHTTP);
auto dummy = std::make_unique<DummyPageHolder>();
csp->BindToDelegate(
- dummy->GetDocument().GetContentSecurityPolicyDelegate());
+ dummy->GetFrame().DomWindow()->GetContentSecurityPolicyDelegate());
EXPECT_EQ(test.expected_object,
dummy->GetDocument().IsUseCounted(
@@ -1921,7 +1513,7 @@ TEST_F(ContentSecurityPolicyTest, BetterThanReasonableRestrictionMetrics) {
ContentSecurityPolicySource::kHTTP);
auto dummy = std::make_unique<DummyPageHolder>();
csp->BindToDelegate(
- dummy->GetDocument().GetContentSecurityPolicyDelegate());
+ dummy->GetFrame().DomWindow()->GetContentSecurityPolicyDelegate());
EXPECT_EQ(test.expected,
dummy->GetDocument().IsUseCounted(
@@ -1937,7 +1529,7 @@ TEST_F(ContentSecurityPolicyTest, BetterThanReasonableRestrictionMetrics) {
ContentSecurityPolicySource::kHTTP);
auto dummy = std::make_unique<DummyPageHolder>();
csp->BindToDelegate(
- dummy->GetDocument().GetContentSecurityPolicyDelegate());
+ dummy->GetFrame().DomWindow()->GetContentSecurityPolicyDelegate());
EXPECT_EQ(test.expected,
dummy->GetDocument().IsUseCounted(
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive.h b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive.h
index 668ab028ce5..bdbfdbd70a8 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive.h
+++ b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive.h
@@ -20,7 +20,7 @@ class CORE_EXPORT CSPDirective : public GarbageCollected<CSPDirective> {
ContentSecurityPolicy* policy)
: name_(name), text_(name + ' ' + value), policy_(policy) {}
virtual ~CSPDirective() = default;
- virtual void Trace(Visitor* visitor) { visitor->Trace(policy_); }
+ virtual void Trace(Visitor* visitor) const { visitor->Trace(policy_); }
const String& GetName() const { return name_; }
const String& GetText() const { return text_; }
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
index 93b36d543ab..57631449aeb 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
+++ b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
@@ -142,7 +142,6 @@ CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy,
has_sandbox_policy_(false),
strict_mixed_content_checking_enforced_(false),
upgrade_insecure_requests_(false),
- require_sri_for_(RequireSRIForToken::kNone),
use_reporting_api_(false) {}
CSPDirectiveList* CSPDirectiveList::Create(ContentSecurityPolicy* policy,
@@ -315,15 +314,16 @@ bool CSPDirectiveList::CheckDynamic(SourceListDirective* directive) const {
}
void CSPDirectiveList::ReportMixedContent(
- const KURL& mixed_url,
+ const KURL& blocked_url,
ResourceRequest::RedirectStatus redirect_status) const {
if (StrictMixedContentChecking()) {
policy_->ReportViolation(
ContentSecurityPolicy::GetDirectiveName(
ContentSecurityPolicy::DirectiveType::kBlockAllMixedContent),
ContentSecurityPolicy::DirectiveType::kBlockAllMixedContent, String(),
- mixed_url, report_endpoints_, use_reporting_api_, header_, header_type_,
- ContentSecurityPolicy::kURLViolation, std::unique_ptr<SourceLocation>(),
+ blocked_url, report_endpoints_, use_reporting_api_, header_,
+ header_type_, ContentSecurityPolicy::kURLViolation,
+ std::unique_ptr<SourceLocation>(),
nullptr, // contextFrame,
redirect_status);
}
@@ -379,90 +379,6 @@ bool CSPDirectiveList::CheckAncestors(SourceListDirective* directive,
return true;
}
-bool CSPDirectiveList::CheckRequestWithoutIntegrity(
- mojom::RequestContextType context,
- network::mojom::RequestDestination request_destination) const {
- if (require_sri_for_ == RequireSRIForToken::kNone)
- return true;
- // SRI specification
- // (https://w3c.github.io/webappsec-subresource-integrity/#apply-algorithm-to-request)
- // says to match token with request's destination with the token.
- // Keep this logic aligned with ContentSecurityPolicy::allowRequest
- if ((require_sri_for_ & RequireSRIForToken::kScript) &&
- (context == mojom::RequestContextType::SCRIPT ||
- context == mojom::RequestContextType::IMPORT ||
- context == mojom::RequestContextType::SERVICE_WORKER ||
- context == mojom::RequestContextType::SHARED_WORKER ||
- context == mojom::RequestContextType::WORKER ||
- request_destination == network::mojom::RequestDestination::kScript ||
- request_destination ==
- network::mojom::RequestDestination::kServiceWorker ||
- request_destination ==
- network::mojom::RequestDestination::kSharedWorker ||
- request_destination == network::mojom::RequestDestination::kWorker)) {
- return false;
- }
- if ((require_sri_for_ & RequireSRIForToken::kStyle) &&
- context == mojom::RequestContextType::STYLE)
- return false;
- return true;
-}
-
-bool CSPDirectiveList::CheckRequestWithoutIntegrityAndReportViolation(
- mojom::RequestContextType context,
- network::mojom::RequestDestination request_destination,
- const KURL& url,
- ResourceRequest::RedirectStatus redirect_status) const {
- if (CheckRequestWithoutIntegrity(context, request_destination))
- return true;
- String resource_type;
- switch (context) {
- case mojom::RequestContextType::SCRIPT:
- case mojom::RequestContextType::IMPORT:
- resource_type = "script";
- break;
- case mojom::RequestContextType::STYLE:
- resource_type = "stylesheet";
- break;
- case mojom::RequestContextType::SERVICE_WORKER:
- resource_type = "service worker";
- break;
- case mojom::RequestContextType::SHARED_WORKER:
- resource_type = "shared worker";
- break;
- case mojom::RequestContextType::WORKER:
- resource_type = "worker";
- break;
- default:
- break;
- }
-
- ReportViolation(ContentSecurityPolicy::GetDirectiveName(
- ContentSecurityPolicy::DirectiveType::kRequireSRIFor),
- ContentSecurityPolicy::DirectiveType::kRequireSRIFor,
- "Refused to load the " + resource_type + " '" +
- url.ElidedString() +
- "' because 'require-sri-for' directive requires "
- "integrity attribute be present for all " +
- resource_type + "s.",
- url, redirect_status);
- return DenyIfEnforcingPolicy();
-}
-
-bool CSPDirectiveList::AllowRequestWithoutIntegrity(
- mojom::RequestContextType context,
- network::mojom::RequestDestination request_destination,
- const KURL& url,
- ResourceRequest::RedirectStatus redirect_status,
- ReportingDisposition reporting_disposition) const {
- if (reporting_disposition == ReportingDisposition::kReport) {
- return CheckRequestWithoutIntegrityAndReportViolation(
- context, request_destination, url, redirect_status);
- }
- return DenyIfEnforcingPolicy() ||
- CheckRequestWithoutIntegrity(context, request_destination);
-}
-
bool CSPDirectiveList::CheckMediaType(MediaListDirective* directive,
const String& type,
const String& type_attribute) const {
@@ -600,11 +516,12 @@ bool CSPDirectiveList::CheckSourceAndReportViolation(
SourceListDirective* directive,
const KURL& url,
const ContentSecurityPolicy::DirectiveType effective_type,
+ const KURL& url_before_redirects,
ResourceRequest::RedirectStatus redirect_status) const {
if (!directive)
return true;
- // We ignore URL-based whitelists if we're allowing dynamic script injection.
+ // We ignore URL-based allowlists if we're allowing dynamic script injection.
if (CheckSource(directive, url, redirect_status) && !CheckDynamic(directive))
return true;
@@ -645,9 +562,10 @@ bool CSPDirectiveList::CheckSourceAndReportViolation(
prefix = prefix + "navigate to '";
String suffix = String();
- if (CheckDynamic(directive))
+ if (CheckDynamic(directive)) {
suffix =
- " 'strict-dynamic' is present, so host-based whitelisting is disabled.";
+ " 'strict-dynamic' is present, so host-based allowlisting is disabled.";
+ }
String directive_name = directive->GetName();
String effective_directive_name =
@@ -663,7 +581,7 @@ bool CSPDirectiveList::CheckSourceAndReportViolation(
"' because it violates the following Content Security "
"Policy directive: \"" +
directive->GetText() + "\"." + suffix + "\n",
- url, redirect_status);
+ url_before_redirects, redirect_status);
return DenyIfEnforcingPolicy();
}
@@ -822,6 +740,7 @@ bool CSPDirectiveList::AllowPluginType(
bool CSPDirectiveList::AllowFromSource(
ContentSecurityPolicy::DirectiveType type,
const KURL& url,
+ const KURL& url_before_redirects,
ResourceRequest::RedirectStatus redirect_status,
ReportingDisposition reporting_disposition,
const String& nonce,
@@ -867,7 +786,7 @@ bool CSPDirectiveList::AllowFromSource(
bool result =
reporting_disposition == ReportingDisposition::kReport
? CheckSourceAndReportViolation(OperativeDirective(type), url, type,
- redirect_status)
+ url_before_redirects, redirect_status)
: CheckSource(OperativeDirective(type), url, redirect_status);
if (type == ContentSecurityPolicy::DirectiveType::kBaseURI) {
@@ -1059,61 +978,6 @@ bool CSPDirectiveList::ParseDirective(const UChar* begin,
return true;
}
-void CSPDirectiveList::ParseRequireSRIFor(const String& name,
- const String& value) {
- if (require_sri_for_ != 0) {
- policy_->ReportDuplicateDirective(name);
- return;
- }
- StringBuilder token_errors;
- unsigned number_of_token_errors = 0;
- Vector<UChar> characters;
- value.AppendTo(characters);
-
- const UChar* position = characters.data();
- const UChar* end = position + characters.size();
-
- while (position < end) {
- SkipWhile<UChar, IsASCIISpace>(position, end);
-
- const UChar* token_begin = position;
- SkipWhile<UChar, IsNotASCIISpace>(position, end);
-
- if (token_begin < position) {
- String token =
- String(token_begin, static_cast<wtf_size_t>(position - token_begin));
- if (EqualIgnoringASCIICase(token, "script")) {
- require_sri_for_ |= RequireSRIForToken::kScript;
- } else if (EqualIgnoringASCIICase(token, "style")) {
- require_sri_for_ |= RequireSRIForToken::kStyle;
- } else {
- if (number_of_token_errors)
- token_errors.Append(", \'");
- else
- token_errors.Append('\'');
- token_errors.Append(token);
- token_errors.Append('\'');
- number_of_token_errors++;
- }
- }
- }
-
- if (number_of_token_errors == 0)
- return;
-
- String invalid_tokens_error_message;
- if (number_of_token_errors > 1)
- token_errors.Append(" are invalid 'require-sri-for' tokens.");
- else
- token_errors.Append(" is an invalid 'require-sri-for' token.");
-
- invalid_tokens_error_message = token_errors.ToString();
-
- DCHECK(!invalid_tokens_error_message.IsEmpty());
-
- policy_->ReportInvalidRequireSRIForTokens(invalid_tokens_error_message);
-}
-
void CSPDirectiveList::ParseReportTo(const String& name, const String& value) {
if (!use_reporting_api_) {
use_reporting_api_ = true;
@@ -1416,9 +1280,7 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) {
ContentSecurityPolicy::DirectiveType::kRequireTrustedTypesFor) {
RequireTrustedTypesFor(name, value);
} else if (policy_->ExperimentalFeaturesEnabled()) {
- if (type == ContentSecurityPolicy::DirectiveType::kRequireSRIFor) {
- ParseRequireSRIFor(name, value);
- } else if (type == ContentSecurityPolicy::DirectiveType::kPrefetchSrc) {
+ if (type == ContentSecurityPolicy::DirectiveType::kPrefetchSrc) {
SetCSPDirective<SourceListDirective>(name, value, prefetch_src_);
} else {
policy_->ReportUnsupportedDirective(name);
@@ -1581,7 +1443,7 @@ SourceListDirectiveVector CSPDirectiveList::GetSourceVector(
}
bool CSPDirectiveList::Subsumes(const CSPDirectiveListVector& other) {
- // A white-list of directives that we consider for subsumption.
+ // A list of directives that we consider for subsumption.
// See more about source lists here:
// https://w3c.github.io/webappsec-csp/#framework-directive-source-list
static ContentSecurityPolicy::DirectiveType directives[] = {
@@ -1704,7 +1566,7 @@ bool CSPDirectiveList::IsScriptRestrictionReasonable() const {
(script_src->AllowDynamic() || !script_src->AllowsURLBasedMatching());
}
-void CSPDirectiveList::Trace(Visitor* visitor) {
+void CSPDirectiveList::Trace(Visitor* visitor) const {
visitor->Trace(policy_);
visitor->Trace(plugin_types_);
visitor->Trace(base_uri_);
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.h b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
index 0b176a4f801..6c2f61a54ee 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
+++ b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
@@ -79,6 +79,7 @@ class CORE_EXPORT CSPDirectiveList final
bool AllowFromSource(ContentSecurityPolicy::DirectiveType,
const KURL&,
+ const KURL& url_before_redirects,
ResourceRequest::RedirectStatus,
ReportingDisposition,
const String& nonce = String(),
@@ -98,12 +99,6 @@ class CORE_EXPORT CSPDirectiveList final
bool AllowDynamic(ContentSecurityPolicy::DirectiveType) const;
bool AllowDynamicWorker() const;
- bool AllowRequestWithoutIntegrity(mojom::RequestContextType,
- network::mojom::RequestDestination,
- const KURL&,
- ResourceRequest::RedirectStatus,
- ReportingDisposition) const;
-
bool AllowTrustedTypeAssignmentFailure(const String& message,
const String& sample,
const String& sample_prefix) const;
@@ -111,7 +106,7 @@ class CORE_EXPORT CSPDirectiveList final
bool StrictMixedContentChecking() const {
return strict_mixed_content_checking_enforced_;
}
- void ReportMixedContent(const KURL& mixed_url,
+ void ReportMixedContent(const KURL& blocked_url,
ResourceRequest::RedirectStatus) const;
bool ShouldDisableEval() const {
@@ -132,7 +127,6 @@ class CORE_EXPORT CSPDirectiveList final
}
const Vector<String>& ReportEndpoints() const { return report_endpoints_; }
bool UseReportingApi() const { return use_reporting_api_; }
- uint8_t RequireSRIForTokens() const { return require_sri_for_; }
bool IsFrameAncestorsEnforced() const {
return frame_ancestors_.Get() && !IsReportOnly();
}
@@ -187,20 +181,17 @@ class CORE_EXPORT CSPDirectiveList final
return trusted_types_ && trusted_types_->IsAllowDuplicates();
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
FRIEND_TEST_ALL_PREFIXES(CSPDirectiveListTest, IsMatchingNoncePresent);
FRIEND_TEST_ALL_PREFIXES(CSPDirectiveListTest, GetSourceVector);
FRIEND_TEST_ALL_PREFIXES(CSPDirectiveListTest, OperativeDirectiveGivenType);
- enum RequireSRIForToken { kNone = 0, kScript = 1 << 0, kStyle = 1 << 1 };
-
bool ParseDirective(const UChar* begin,
const UChar* end,
String* name,
String* value);
- void ParseRequireSRIFor(const String& name, const String& value);
void ParseReportURI(const String& name, const String& value);
void ParseReportTo(const String& name, const String& value);
void ParseAndAppendReportEndpoints(const String& value);
@@ -266,8 +257,6 @@ class CORE_EXPORT CSPDirectiveList final
const String& type,
const String& type_attribute) const;
bool CheckAncestors(SourceListDirective*, LocalFrame*) const;
- bool CheckRequestWithoutIntegrity(mojom::RequestContextType,
- network::mojom::RequestDestination) const;
void SetEvalDisabledErrorMessage(const String& error_message) {
eval_disabled_error_message_ = error_message;
@@ -295,6 +284,7 @@ class CORE_EXPORT CSPDirectiveList final
bool CheckSourceAndReportViolation(SourceListDirective*,
const KURL&,
const ContentSecurityPolicy::DirectiveType,
+ const KURL& url_before_redirects,
ResourceRequest::RedirectStatus) const;
bool CheckMediaTypeAndReportViolation(MediaListDirective*,
const String& type,
@@ -303,11 +293,6 @@ class CORE_EXPORT CSPDirectiveList final
bool CheckAncestorsAndReportViolation(SourceListDirective*,
LocalFrame*,
const KURL&) const;
- bool CheckRequestWithoutIntegrityAndReportViolation(
- mojom::RequestContextType,
- network::mojom::RequestDestination,
- const KURL&,
- ResourceRequest::RedirectStatus) const;
bool DenyIfEnforcingPolicy() const { return IsReportOnly(); }
@@ -361,8 +346,6 @@ class CORE_EXPORT CSPDirectiveList final
Member<StringListDirective> trusted_types_;
Member<RequireTrustedTypesForDirective> require_trusted_types_for_;
- uint8_t require_sri_for_;
-
// If a "report-to" directive is used:
// - |report_endpoints_| is a list of token parsed from the "report-to"
// directive's value, and
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc
index 73efdbb4fc1..ed5009c055b 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc
@@ -213,21 +213,23 @@ TEST_F(CSPDirectiveListTest, AllowScriptFromSourceNoNonce) {
// Report-only
Member<CSPDirectiveList> directive_list =
CreateList(test.list, ContentSecurityPolicyType::kReport);
- EXPECT_EQ(test.expected,
- directive_list->AllowFromSource(
- ContentSecurityPolicy::DirectiveType::kScriptSrcElem,
- script_src, ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting, String(),
- IntegrityMetadataSet(), kParserInserted));
+ EXPECT_EQ(
+ test.expected,
+ directive_list->AllowFromSource(
+ ContentSecurityPolicy::DirectiveType::kScriptSrcElem, script_src,
+ script_src, ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting, String(),
+ IntegrityMetadataSet(), kParserInserted));
// Enforce
directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce);
- EXPECT_EQ(test.expected,
- directive_list->AllowFromSource(
- ContentSecurityPolicy::DirectiveType::kScriptSrcElem,
- script_src, ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting, String(),
- IntegrityMetadataSet(), kParserInserted));
+ EXPECT_EQ(
+ test.expected,
+ directive_list->AllowFromSource(
+ ContentSecurityPolicy::DirectiveType::kScriptSrcElem, script_src,
+ script_src, ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting, String(),
+ IntegrityMetadataSet(), kParserInserted));
}
}
@@ -246,7 +248,7 @@ TEST_F(CSPDirectiveListTest, AllowFromSourceWithNonce) {
{"https://example.com", "https://not.example.com/file", "boo", false},
{"https://example.com", "https://not.example.com/file", "", false},
- // Doesn't affect URLs that match the whitelist.
+ // Doesn't affect URLs that match the allowlist.
{"https://example.com 'nonce-yay'", "https://example.com/file", "yay",
true},
{"https://example.com 'nonce-yay'", "https://example.com/file", "boo",
@@ -270,22 +272,24 @@ TEST_F(CSPDirectiveListTest, AllowFromSourceWithNonce) {
// Report-only 'script-src'
Member<CSPDirectiveList> directive_list = CreateList(
String("script-src ") + test.list, ContentSecurityPolicyType::kReport);
- EXPECT_EQ(test.expected,
- directive_list->AllowFromSource(
- ContentSecurityPolicy::DirectiveType::kScriptSrcElem,
- resource, ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting, String(test.nonce),
- IntegrityMetadataSet(), kParserInserted));
+ EXPECT_EQ(
+ test.expected,
+ directive_list->AllowFromSource(
+ ContentSecurityPolicy::DirectiveType::kScriptSrcElem, resource,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting, String(test.nonce),
+ IntegrityMetadataSet(), kParserInserted));
// Enforce 'script-src'
directive_list = CreateList(String("script-src ") + test.list,
ContentSecurityPolicyType::kEnforce);
- EXPECT_EQ(test.expected,
- directive_list->AllowFromSource(
- ContentSecurityPolicy::DirectiveType::kScriptSrcElem,
- resource, ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting, String(test.nonce),
- IntegrityMetadataSet(), kParserInserted));
+ EXPECT_EQ(
+ test.expected,
+ directive_list->AllowFromSource(
+ ContentSecurityPolicy::DirectiveType::kScriptSrcElem, resource,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting, String(test.nonce),
+ IntegrityMetadataSet(), kParserInserted));
// Report-only 'style-src'
directive_list = CreateList(String("style-src ") + test.list,
@@ -294,7 +298,7 @@ TEST_F(CSPDirectiveListTest, AllowFromSourceWithNonce) {
test.expected,
directive_list->AllowFromSource(
ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource,
- ResourceRequest::RedirectStatus::kNoRedirect,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting, String(test.nonce)));
// Enforce 'style-src'
@@ -304,7 +308,7 @@ TEST_F(CSPDirectiveListTest, AllowFromSourceWithNonce) {
test.expected,
directive_list->AllowFromSource(
ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource,
- ResourceRequest::RedirectStatus::kNoRedirect,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting, String(test.nonce)));
// Report-only 'style-src'
@@ -314,29 +318,30 @@ TEST_F(CSPDirectiveListTest, AllowFromSourceWithNonce) {
test.expected,
directive_list->AllowFromSource(
ContentSecurityPolicy::DirectiveType::kScriptSrcElem, resource,
- ResourceRequest::RedirectStatus::kNoRedirect,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting, String(test.nonce)));
EXPECT_EQ(
test.expected,
directive_list->AllowFromSource(
ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource,
- ResourceRequest::RedirectStatus::kNoRedirect,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting, String(test.nonce)));
// Enforce 'style-src'
directive_list = CreateList(String("default-src ") + test.list,
ContentSecurityPolicyType::kEnforce);
- EXPECT_EQ(test.expected,
- directive_list->AllowFromSource(
- ContentSecurityPolicy::DirectiveType::kScriptSrcElem,
- resource, ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting, String(test.nonce),
- IntegrityMetadataSet(), kParserInserted));
+ EXPECT_EQ(
+ test.expected,
+ directive_list->AllowFromSource(
+ ContentSecurityPolicy::DirectiveType::kScriptSrcElem, resource,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting, String(test.nonce),
+ IntegrityMetadataSet(), kParserInserted));
EXPECT_EQ(
test.expected,
directive_list->AllowFromSource(
ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource,
- ResourceRequest::RedirectStatus::kNoRedirect,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting, String(test.nonce)));
}
}
@@ -358,7 +363,7 @@ TEST_F(CSPDirectiveListTest, AllowScriptFromSourceWithHash) {
false},
{"https://example.com", "https://not.example.com/file", "", false},
- // Doesn't affect URLs that match the whitelist.
+ // Doesn't affect URLs that match the allowlist.
{"https://example.com 'sha256-yay'", "https://example.com/file",
"sha256-yay", true},
{"https://example.com 'sha256-yay'", "https://example.com/file",
@@ -366,7 +371,7 @@ TEST_F(CSPDirectiveListTest, AllowScriptFromSourceWithHash) {
{"https://example.com 'sha256-yay'", "https://example.com/file", "",
true},
- // Does affect URLs that don't match the whitelist.
+ // Does affect URLs that don't match the allowlist.
{"https://example.com 'sha256-yay'", "https://not.example.com/file",
"sha256-yay", true},
{"https://example.com 'sha256-yay'", "https://not.example.com/file",
@@ -388,7 +393,7 @@ TEST_F(CSPDirectiveListTest, AllowScriptFromSourceWithHash) {
// But they also don't interfere.
{"'sha256-yay'", "https://a.com/file", "sha256-yay asdf256-boo", true},
- // Additional whitelisted hashes in the CSP don't interfere.
+ // Additional allowlisted hashes in the CSP don't interfere.
{"'sha256-yay' 'sha384-boo'", "https://a.com/file", "sha256-yay", true},
{"'sha256-yay' 'sha384-boo'", "https://a.com/file", "sha384-boo", true},
@@ -422,184 +427,24 @@ TEST_F(CSPDirectiveListTest, AllowScriptFromSourceWithHash) {
// Report-only 'script-src'
Member<CSPDirectiveList> directive_list = CreateList(
String("script-src ") + test.list, ContentSecurityPolicyType::kReport);
- EXPECT_EQ(test.expected,
- directive_list->AllowFromSource(
- ContentSecurityPolicy::DirectiveType::kScriptSrcElem,
- resource, ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting, String(),
- integrity_metadata, kParserInserted));
+ EXPECT_EQ(
+ test.expected,
+ directive_list->AllowFromSource(
+ ContentSecurityPolicy::DirectiveType::kScriptSrcElem, resource,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting, String(),
+ integrity_metadata, kParserInserted));
// Enforce 'script-src'
directive_list = CreateList(String("script-src ") + test.list,
ContentSecurityPolicyType::kEnforce);
- EXPECT_EQ(test.expected,
- directive_list->AllowFromSource(
- ContentSecurityPolicy::DirectiveType::kScriptSrcElem,
- resource, ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting, String(),
- integrity_metadata, kParserInserted));
- }
-}
-
-TEST_F(CSPDirectiveListTest, allowRequestWithoutIntegrity) {
- struct TestCase {
- const char* list;
- const char* url;
- const mojom::RequestContextType context;
- const network::mojom::RequestDestination request_destination;
- bool expected;
- } cases[] = {
- {"require-sri-for script", "https://example.com/file",
- mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, false},
-
- // Extra WSP
- {"require-sri-for script script ", "https://example.com/file",
- mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, false},
- {"require-sri-for style script", "https://example.com/file",
- mojom::RequestContextType::STYLE,
- network::mojom::RequestDestination::kStyle, false},
-
- {"require-sri-for style script", "https://example.com/file",
- mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, false},
- {"require-sri-for style script", "https://example.com/file",
- mojom::RequestContextType::IMPORT,
- network::mojom::RequestDestination::kEmpty, false},
- {"require-sri-for style script", "https://example.com/file",
- mojom::RequestContextType::IMAGE,
- network::mojom::RequestDestination::kImage, true},
-
- {"require-sri-for script", "https://example.com/file",
- mojom::RequestContextType::AUDIO,
- network::mojom::RequestDestination::kAudio, true},
- {"require-sri-for script", "https://example.com/file",
- mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, false},
- {"require-sri-for script", "https://example.com/file",
- mojom::RequestContextType::IMPORT,
- network::mojom::RequestDestination::kEmpty, false},
- {"require-sri-for script", "https://example.com/file",
- mojom::RequestContextType::SERVICE_WORKER,
- network::mojom::RequestDestination::kServiceWorker, false},
- {"require-sri-for script", "https://example.com/file",
- mojom::RequestContextType::SHARED_WORKER,
- network::mojom::RequestDestination::kSharedWorker, false},
- {"require-sri-for script", "https://example.com/file",
- mojom::RequestContextType::WORKER,
- network::mojom::RequestDestination::kWorker, false},
- {"require-sri-for script", "https://example.com/file",
- mojom::RequestContextType::STYLE,
- network::mojom::RequestDestination::kStyle, true},
-
- {"require-sri-for style", "https://example.com/file",
- mojom::RequestContextType::AUDIO,
- network::mojom::RequestDestination::kAudio, true},
- {"require-sri-for style", "https://example.com/file",
- mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, true},
- {"require-sri-for style", "https://example.com/file",
- mojom::RequestContextType::IMPORT,
- network::mojom::RequestDestination::kEmpty, true},
- {"require-sri-for style", "https://example.com/file",
- mojom::RequestContextType::SERVICE_WORKER,
- network::mojom::RequestDestination::kServiceWorker, true},
- {"require-sri-for style", "https://example.com/file",
- mojom::RequestContextType::SHARED_WORKER,
- network::mojom::RequestDestination::kSharedWorker, true},
- {"require-sri-for style", "https://example.com/file",
- mojom::RequestContextType::WORKER,
- network::mojom::RequestDestination::kWorker, true},
- {"require-sri-for style", "https://example.com/file",
- mojom::RequestContextType::STYLE,
- network::mojom::RequestDestination::kStyle, false},
-
- // Multiple tokens
- {"require-sri-for script style", "https://example.com/file",
- mojom::RequestContextType::STYLE,
- network::mojom::RequestDestination::kStyle, false},
- {"require-sri-for script style", "https://example.com/file",
- mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, false},
- {"require-sri-for script style", "https://example.com/file",
- mojom::RequestContextType::IMPORT,
- network::mojom::RequestDestination::kEmpty, false},
- {"require-sri-for script style", "https://example.com/file",
- mojom::RequestContextType::IMAGE,
- network::mojom::RequestDestination::kImage, true},
-
- // Matching is case-insensitive
- {"require-sri-for Script", "https://example.com/file",
- mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, false},
-
- // Unknown tokens do not affect result
- {"require-sri-for blabla12 as", "https://example.com/file",
- mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, true},
- {"require-sri-for blabla12 as script", "https://example.com/file",
- mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, false},
- {"require-sri-for script style img", "https://example.com/file",
- mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, false},
- {"require-sri-for script style img", "https://example.com/file",
- mojom::RequestContextType::IMPORT,
- network::mojom::RequestDestination::kEmpty, false},
- {"require-sri-for script style img", "https://example.com/file",
- mojom::RequestContextType::STYLE,
- network::mojom::RequestDestination::kStyle, false},
- {"require-sri-for script style img", "https://example.com/file",
- mojom::RequestContextType::IMAGE,
- network::mojom::RequestDestination::kImage, true},
-
- // Empty token list has no effect
- {"require-sri-for ", "https://example.com/file",
- mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, true},
- {"require-sri-for ", "https://example.com/file",
- mojom::RequestContextType::IMPORT,
- network::mojom::RequestDestination::kEmpty, true},
- {"require-sri-for ", "https://example.com/file",
- mojom::RequestContextType::STYLE,
- network::mojom::RequestDestination::kStyle, true},
- {"require-sri-for ", "https://example.com/file",
- mojom::RequestContextType::SERVICE_WORKER,
- network::mojom::RequestDestination::kServiceWorker, true},
- {"require-sri-for ", "https://example.com/file",
- mojom::RequestContextType::SHARED_WORKER,
- network::mojom::RequestDestination::kSharedWorker, true},
- {"require-sri-for ", "https://example.com/file",
- mojom::RequestContextType::WORKER,
- network::mojom::RequestDestination::kWorker, true},
-
- // Order does not matter
- {"require-sri-for a b script", "https://example.com/file",
- mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, false},
- {"require-sri-for a script b", "https://example.com/file",
- mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript, false},
- };
-
- for (const auto& test : cases) {
- const KURL resource(test.url);
- // Report-only
- Member<CSPDirectiveList> directive_list =
- CreateList(test.list, ContentSecurityPolicyType::kReport);
- EXPECT_EQ(true, directive_list->AllowRequestWithoutIntegrity(
- test.context, test.request_destination, resource,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
-
- // Enforce
- directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce);
- EXPECT_EQ(test.expected,
- directive_list->AllowRequestWithoutIntegrity(
- test.context, test.request_destination, resource,
- ResourceRequest::RedirectStatus::kNoRedirect,
- ReportingDisposition::kSuppressReporting));
+ EXPECT_EQ(
+ test.expected,
+ directive_list->AllowFromSource(
+ ContentSecurityPolicy::DirectiveType::kScriptSrcElem, resource,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting, String(),
+ integrity_metadata, kParserInserted));
}
}
@@ -644,7 +489,7 @@ TEST_F(CSPDirectiveListTest, WorkerSrc) {
EXPECT_EQ(test.allowed,
directive_list->AllowFromSource(
ContentSecurityPolicy::DirectiveType::kWorkerSrc, resource,
- ResourceRequest::RedirectStatus::kNoRedirect,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
}
}
@@ -690,7 +535,7 @@ TEST_F(CSPDirectiveListTest, WorkerSrcChildSrcFallback) {
EXPECT_EQ(test.allowed,
directive_list->AllowFromSource(
ContentSecurityPolicy::DirectiveType::kWorkerSrc, resource,
- ResourceRequest::RedirectStatus::kNoRedirect,
+ resource, ResourceRequest::RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting));
}
}
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/csp_source.cc b/chromium/third_party/blink/renderer/core/frame/csp/csp_source.cc
index 691cc1d7f4f..6ff88834c16 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/csp_source.cc
+++ b/chromium/third_party/blink/renderer/core/frame/csp/csp_source.cc
@@ -302,7 +302,7 @@ network::mojom::blink::CSPSourcePtr CSPSource::ExposeForNavigationalChecks()
);
}
-void CSPSource::Trace(Visitor* visitor) {
+void CSPSource::Trace(Visitor* visitor) const {
visitor->Trace(policy_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/csp_source.h b/chromium/third_party/blink/renderer/core/frame/csp/csp_source.h
index c48fa3e6e03..8f4cb053333 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/csp_source.h
+++ b/chromium/third_party/blink/renderer/core/frame/csp/csp_source.h
@@ -67,7 +67,7 @@ class CORE_EXPORT CSPSource final : public GarbageCollected<CSPSource> {
network::mojom::blink::CSPSourcePtr ExposeForNavigationalChecks() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
FRIEND_TEST_ALL_PREFIXES(CSPSourceTest, IsSimilar);
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc b/chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc
index 8e61fb6093c..5b037da4f64 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc
+++ b/chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc
@@ -34,7 +34,7 @@ ExecutionContextCSPDelegate::ExecutionContextCSPDelegate(
ExecutionContext& execution_context)
: execution_context_(&execution_context) {}
-void ExecutionContextCSPDelegate::Trace(Visitor* visitor) {
+void ExecutionContextCSPDelegate::Trace(Visitor* visitor) const {
visitor->Trace(execution_context_);
ContentSecurityPolicyDelegate::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.h b/chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.h
index 221dcd6038f..01b1df5a950 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.h
+++ b/chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.h
@@ -22,7 +22,7 @@ class ExecutionContextCSPDelegate final
public:
explicit ExecutionContextCSPDelegate(ExecutionContext&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// ContentSecurityPolicyDelegate overrides:
const SecurityOrigin* GetSecurityOrigin() override;
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.cc b/chromium/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.cc
index c9bdc143404..78779311464 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.cc
+++ b/chromium/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.cc
@@ -19,7 +19,7 @@ NavigationInitiatorImpl::NavigationInitiatorImpl(Document& document)
DCHECK(document.GetExecutionContext());
}
-void NavigationInitiatorImpl::Trace(Visitor* visitor) {
+void NavigationInitiatorImpl::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(navigation_initiator_receivers_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.h b/chromium/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.h
index 5516abd9505..146e1de8049 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.h
+++ b/chromium/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.h
@@ -21,7 +21,7 @@ class NavigationInitiatorImpl
public mojom::blink::NavigationInitiator {
public:
explicit NavigationInitiatorImpl(Document& document);
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
// mojom::blink::NavigationInitiator override:
void SendViolationReport(
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.cc b/chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.cc
index bf7e58714fa..3d0dca4726d 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.cc
+++ b/chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.cc
@@ -29,7 +29,7 @@ bool RequireTrustedTypesForDirective::require() const {
return require_trusted_types_for_script_;
}
-void RequireTrustedTypesForDirective::Trace(Visitor* visitor) {
+void RequireTrustedTypesForDirective::Trace(Visitor* visitor) const {
CSPDirective::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.h b/chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.h
index 933ee499bf6..cdba8df6b65 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.h
+++ b/chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.h
@@ -16,7 +16,7 @@ class CORE_EXPORT RequireTrustedTypesForDirective final : public CSPDirective {
RequireTrustedTypesForDirective(const String& name,
const String& value,
ContentSecurityPolicy*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool require() const;
private:
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive.cc b/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive.cc
index f1b00288541..03b26bfe485 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive.cc
+++ b/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive.cc
@@ -918,7 +918,7 @@ HeapVector<Member<CSPSource>> SourceListDirective::GetIntersectCSPSources(
return normalized;
}
-void SourceListDirective::Trace(Visitor* visitor) {
+void SourceListDirective::Trace(Visitor* visitor) const {
visitor->Trace(policy_);
visitor->Trace(list_);
CSPDirective::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive.h b/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive.h
index 08d3092a3c9..4472f7b8bf8 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive.h
+++ b/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive.h
@@ -25,7 +25,7 @@ class CORE_EXPORT SourceListDirective final : public CSPDirective {
SourceListDirective(const String& name,
const String& value,
ContentSecurityPolicy*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Parse(const UChar* begin, const UChar* end);
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/string_list_directive.cc b/chromium/third_party/blink/renderer/core/frame/csp/string_list_directive.cc
index 049db709c2c..b2977416d76 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/string_list_directive.cc
+++ b/chromium/third_party/blink/renderer/core/frame/csp/string_list_directive.cc
@@ -58,21 +58,26 @@ bool StringListDirective::AllowOrProcessValue(const String& src) {
allow_any_ = true;
return false;
}
+ if (src == "'none'") {
+ if (list_.size() > 1) {
+ Policy()->ReportInvalidSourceExpression(GetName(), src);
+ }
+ return false;
+ }
return IsPolicyName(src);
}
-bool StringListDirective::Allows(const String& string_piece,
- bool is_duplicate) {
+bool StringListDirective::Allows(const String& value, bool is_duplicate) {
if (is_duplicate && !allow_duplicates_)
return false;
- if (is_duplicate && string_piece == "default")
+ if (is_duplicate && value == "default")
return false;
- if (!IsPolicyName(string_piece))
+ if (!IsPolicyName(value))
return false;
- return allow_any_ || list_.Contains(string_piece);
+ return allow_any_ || list_.Contains(value);
}
-void StringListDirective::Trace(Visitor* visitor) {
+void StringListDirective::Trace(Visitor* visitor) const {
CSPDirective::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/string_list_directive.h b/chromium/third_party/blink/renderer/core/frame/csp/string_list_directive.h
index 0547c8d7175..dca41c37754 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/string_list_directive.h
+++ b/chromium/third_party/blink/renderer/core/frame/csp/string_list_directive.h
@@ -18,7 +18,7 @@ class CORE_EXPORT StringListDirective final : public CSPDirective {
StringListDirective(const String& name,
const String& value,
ContentSecurityPolicy*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool Allows(const String& string_piece, bool is_duplicate);
bool IsAllowDuplicates() const { return allow_duplicates_; }
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/string_list_directive_test.cc b/chromium/third_party/blink/renderer/core/frame/csp/string_list_directive_test.cc
index 4d59a0a8f5d..7800b9c3e3c 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/string_list_directive_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/csp/string_list_directive_test.cc
@@ -5,10 +5,20 @@
#include "third_party/blink/renderer/core/frame/csp/string_list_directive.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
namespace blink {
-TEST(StringListDirectiveTest, TestAllowLists) {
+class StringListDirectiveTest : public testing::Test {
+ public:
+ StringListDirectiveTest()
+ : csp_(MakeGarbageCollected<ContentSecurityPolicy>()) {}
+
+ protected:
+ Persistent<ContentSecurityPolicy> csp_;
+};
+
+TEST_F(StringListDirectiveTest, TestAllowLists) {
struct {
const char* directive;
const char* should_be_allowed;
@@ -25,11 +35,15 @@ TEST(StringListDirectiveTest, TestAllowLists) {
{"'allow-duplicates' bla", "bla", "blub", true},
{"'allow-duplicates'", "", "bla blub", true},
{"'allow-duplicates' bla blubb", "bla blubb", "blubber", true},
+ {"'none'", "", "default none abc", false},
+ {"'none' default", "default", "none abc", false},
+ {"* 'none'", "default none abc", "", false},
+ {"'allow-duplicates' 'none'", "", "default none abc", true},
};
for (const auto& test_case : test_cases) {
StringListDirective directive("trusted-types", test_case.directive,
- nullptr);
+ csp_.Get());
Vector<String> allowed;
String(test_case.should_be_allowed).Split(' ', allowed);
diff --git a/chromium/third_party/blink/renderer/core/frame/dactyloscoper.cc b/chromium/third_party/blink/renderer/core/frame/dactyloscoper.cc
index b5c9d54e2ab..fc180a5470b 100644
--- a/chromium/third_party/blink/renderer/core/frame/dactyloscoper.cc
+++ b/chromium/third_party/blink/renderer/core/frame/dactyloscoper.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/frame/dactyloscoper.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
+#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
@@ -28,4 +30,20 @@ void Dactyloscoper::Record(ExecutionContext* context, WebFeature feature) {
}
}
+// static
+void Dactyloscoper::RecordDirectSurface(ExecutionContext* context,
+ WebFeature feature,
+ unsigned value) {
+ if (!context)
+ return;
+ auto* window = DynamicTo<LocalDOMWindow>(context);
+ if (!window)
+ return;
+ if (Document* document = window->document()) {
+ IdentifiabilityMetricBuilder(document->UkmSourceID())
+ .SetWebfeature(feature, value)
+ .Record(document->UkmRecorder());
+ }
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/dactyloscoper.h b/chromium/third_party/blink/renderer/core/frame/dactyloscoper.h
index 2f86088579f..e9e322f22d0 100644
--- a/chromium/third_party/blink/renderer/core/frame/dactyloscoper.h
+++ b/chromium/third_party/blink/renderer/core/frame/dactyloscoper.h
@@ -24,6 +24,8 @@ class CORE_EXPORT Dactyloscoper {
static void Record(ExecutionContext*, WebFeature);
+ static void RecordDirectSurface(ExecutionContext*, WebFeature, unsigned);
+
private:
DISALLOW_COPY_AND_ASSIGN(Dactyloscoper);
};
diff --git a/chromium/third_party/blink/renderer/core/frame/deprecation.cc b/chromium/third_party/blink/renderer/core/frame/deprecation.cc
index 8e50dac623d..635a4c9c438 100644
--- a/chromium/third_party/blink/renderer/core/frame/deprecation.cc
+++ b/chromium/third_party/blink/renderer/core/frame/deprecation.cc
@@ -9,7 +9,6 @@
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/public/mojom/reporting/reporting.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/deprecation_report_body.h"
#include "third_party/blink/renderer/core/frame/frame_console.h"
@@ -661,18 +660,6 @@ void Deprecation::CountDeprecation(ExecutionContext* context,
context->CountDeprecation(feature);
}
-void Deprecation::CountDeprecation(const Document& document,
- WebFeature feature) {
- Deprecation::CountDeprecation(document.Loader(), feature);
-}
-
-void Deprecation::CountDeprecation(Document* document, WebFeature feature) {
- if (!document)
- return;
-
- Deprecation::CountDeprecation(document->GetExecutionContext(), feature);
-}
-
void Deprecation::CountDeprecation(DocumentLoader* loader, WebFeature feature) {
Deprecation::CountDeprecation(loader, feature, /*count_usage=*/true);
}
@@ -701,19 +688,18 @@ void Deprecation::CountDeprecation(DocumentLoader* loader,
GenerateReport(frame, feature);
}
-void Deprecation::CountDeprecationCrossOriginIframe(const Document& document,
+void Deprecation::CountDeprecationCrossOriginIframe(LocalDOMWindow* window,
WebFeature feature) {
- LocalFrame* frame = document.GetFrame();
- if (!frame)
+ DCHECK(window);
+ if (!window->GetFrame())
return;
- // Check to see if the frame can script into the top level document.
- const SecurityOrigin* security_origin =
- frame->GetSecurityContext()->GetSecurityOrigin();
- Frame& top = frame->Tree().Top();
- if (!security_origin->CanAccess(
- top.GetSecurityContext()->GetSecurityOrigin()))
- CountDeprecation(document, feature);
+ // Check to see if the frame can script into the top level window.
+ Frame& top = window->GetFrame()->Tree().Top();
+ if (!window->GetSecurityOrigin()->CanAccess(
+ top.GetSecurityContext()->GetSecurityOrigin())) {
+ CountDeprecation(window, feature);
+ }
}
void Deprecation::GenerateReport(const LocalFrame* frame, WebFeature feature) {
diff --git a/chromium/third_party/blink/renderer/core/frame/deprecation.h b/chromium/third_party/blink/renderer/core/frame/deprecation.h
index 50c2b489c78..445ca18fa6d 100644
--- a/chromium/third_party/blink/renderer/core/frame/deprecation.h
+++ b/chromium/third_party/blink/renderer/core/frame/deprecation.h
@@ -18,10 +18,10 @@ namespace mojom {
enum class FeaturePolicyFeature;
} // namespace mojom
-class Document;
class DocumentLoader;
class ExecutionContext;
class KURL;
+class LocalDOMWindow;
class LocalFrame;
class Report;
@@ -45,17 +45,12 @@ class CORE_EXPORT Deprecation final {
// deprecation warnings when we're actively interested in removing them from
// the platform.
static void CountDeprecation(ExecutionContext*, WebFeature);
- static void CountDeprecation(const Document&, WebFeature);
static void CountDeprecation(DocumentLoader*, WebFeature);
static void DeprecationWarningOnly(DocumentLoader*, WebFeature);
- // TODO(crbug.com/1029822): Temporary helpers to ease migrating
- // ExecutionContext to LocalDOMWindow.
- static void CountDeprecation(Document*, WebFeature);
-
// Count only features if they're being used in an iframe which does not
- // have script access into the top level document.
- static void CountDeprecationCrossOriginIframe(const Document&, WebFeature);
+ // have script access into the top level window.
+ static void CountDeprecationCrossOriginIframe(LocalDOMWindow*, WebFeature);
static String DeprecationMessage(WebFeature);
diff --git a/chromium/third_party/blink/renderer/core/frame/device_single_window_event_controller.cc b/chromium/third_party/blink/renderer/core/frame/device_single_window_event_controller.cc
index d6f4996103c..24d2aed3c2d 100644
--- a/chromium/third_party/blink/renderer/core/frame/device_single_window_event_controller.cc
+++ b/chromium/third_party/blink/renderer/core/frame/device_single_window_event_controller.cc
@@ -95,7 +95,7 @@ bool DeviceSingleWindowEventController::CheckPolicyFeatures(
});
}
-void DeviceSingleWindowEventController::Trace(Visitor* visitor) {
+void DeviceSingleWindowEventController::Trace(Visitor* visitor) const {
PlatformEventController::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/device_single_window_event_controller.h b/chromium/third_party/blink/renderer/core/frame/device_single_window_event_controller.h
index 990e573e107..c5bc23e299d 100644
--- a/chromium/third_party/blink/renderer/core/frame/device_single_window_event_controller.h
+++ b/chromium/third_party/blink/renderer/core/frame/device_single_window_event_controller.h
@@ -23,7 +23,7 @@ class CORE_EXPORT DeviceSingleWindowEventController
// Inherited from PlatformEventController.
void DidUpdateData() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Inherited from LocalDOMWindow::EventListenerObserver.
void DidAddEventListener(LocalDOMWindow*, const AtomicString&) override;
diff --git a/chromium/third_party/blink/renderer/core/frame/display_cutout_client_impl.cc b/chromium/third_party/blink/renderer/core/frame/display_cutout_client_impl.cc
index 1ce3fd755a7..42541dc0084 100644
--- a/chromium/third_party/blink/renderer/core/frame/display_cutout_client_impl.cc
+++ b/chromium/third_party/blink/renderer/core/frame/display_cutout_client_impl.cc
@@ -47,7 +47,7 @@ void DisplayCutoutClientImpl::SetSafeArea(
vars.SetVariable(kSafeAreaInsetRightName, GetPx(safe_area->right));
}
-void DisplayCutoutClientImpl::Trace(Visitor* visitor) {
+void DisplayCutoutClientImpl::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/display_cutout_client_impl.h b/chromium/third_party/blink/renderer/core/frame/display_cutout_client_impl.h
index 868a6d2a286..07a2b21e5a7 100644
--- a/chromium/third_party/blink/renderer/core/frame/display_cutout_client_impl.h
+++ b/chromium/third_party/blink/renderer/core/frame/display_cutout_client_impl.h
@@ -32,7 +32,7 @@ class CORE_EXPORT DisplayCutoutClientImpl final
// Notify the renderer that the safe areas have changed.
void SetSafeArea(mojom::blink::DisplayCutoutSafeAreaPtr safe_area) override;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<LocalFrame> frame_;
diff --git a/chromium/third_party/blink/renderer/core/frame/dom_timer.cc b/chromium/third_party/blink/renderer/core/frame/dom_timer.cc
index 0f441655cbc..30dfd23faa5 100644
--- a/chromium/third_party/blink/renderer/core/frame/dom_timer.cc
+++ b/chromium/third_party/blink/renderer/core/frame/dom_timer.cc
@@ -174,7 +174,7 @@ void DOMTimer::Fired() {
SetExecutionContext(nullptr);
}
-void DOMTimer::Trace(Visitor* visitor) {
+void DOMTimer::Trace(Visitor* visitor) const {
visitor->Trace(action_);
ExecutionContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/dom_timer.h b/chromium/third_party/blink/renderer/core/frame/dom_timer.h
index 3c7f6cb162f..cc1bb83a72c 100644
--- a/chromium/third_party/blink/renderer/core/frame/dom_timer.h
+++ b/chromium/third_party/blink/renderer/core/frame/dom_timer.h
@@ -72,7 +72,7 @@ class CORE_EXPORT DOMTimer final : public GarbageCollected<DOMTimer>,
// already have been finalized & must not be accessed.
void Dispose();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override { return "DOMTimer"; }
void Stop() override;
diff --git a/chromium/third_party/blink/renderer/core/frame/dom_timer_coordinator.cc b/chromium/third_party/blink/renderer/core/frame/dom_timer_coordinator.cc
index 8a88f5d0774..56120442f45 100644
--- a/chromium/third_party/blink/renderer/core/frame/dom_timer_coordinator.cc
+++ b/chromium/third_party/blink/renderer/core/frame/dom_timer_coordinator.cc
@@ -35,7 +35,7 @@ DOMTimer* DOMTimerCoordinator::RemoveTimeoutByID(int timeout_id) {
return removed_timer;
}
-void DOMTimerCoordinator::Trace(Visitor* visitor) {
+void DOMTimerCoordinator::Trace(Visitor* visitor) const {
visitor->Trace(timers_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/dom_timer_coordinator.h b/chromium/third_party/blink/renderer/core/frame/dom_timer_coordinator.h
index ca8dd281d22..349df57d1b9 100644
--- a/chromium/third_party/blink/renderer/core/frame/dom_timer_coordinator.h
+++ b/chromium/third_party/blink/renderer/core/frame/dom_timer_coordinator.h
@@ -49,7 +49,7 @@ class DOMTimerCoordinator {
// deeper timer nesting level, see DOMTimer::DOMTimer.
void SetTimerNestingLevel(int level) { timer_nesting_level_ = level; }
- void Trace(Visitor*); // Oilpan.
+ void Trace(Visitor*) const; // Oilpan.
private:
int NextID();
diff --git a/chromium/third_party/blink/renderer/core/frame/dom_visual_viewport.cc b/chromium/third_party/blink/renderer/core/frame/dom_visual_viewport.cc
index 1d506e52c96..8bd3e2d6465 100644
--- a/chromium/third_party/blink/renderer/core/frame/dom_visual_viewport.cc
+++ b/chromium/third_party/blink/renderer/core/frame/dom_visual_viewport.cc
@@ -43,7 +43,7 @@ DOMVisualViewport::DOMVisualViewport(LocalDOMWindow* window)
DOMVisualViewport::~DOMVisualViewport() = default;
-void DOMVisualViewport::Trace(Visitor* visitor) {
+void DOMVisualViewport::Trace(Visitor* visitor) const {
visitor->Trace(window_);
EventTargetWithInlineData::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/dom_visual_viewport.h b/chromium/third_party/blink/renderer/core/frame/dom_visual_viewport.h
index 56ec60551e9..77752604750 100644
--- a/chromium/third_party/blink/renderer/core/frame/dom_visual_viewport.h
+++ b/chromium/third_party/blink/renderer/core/frame/dom_visual_viewport.h
@@ -50,7 +50,7 @@ class CORE_EXPORT DOMVisualViewport final : public EventTargetWithInlineData {
explicit DOMVisualViewport(LocalDOMWindow*);
~DOMVisualViewport() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// EventTarget overrides:
const AtomicString& InterfaceName() const override;
diff --git a/chromium/third_party/blink/renderer/core/frame/dom_window.cc b/chromium/third_party/blink/renderer/core/frame/dom_window.cc
index f0981e2ce1b..e79a1af625b 100644
--- a/chromium/third_party/blink/renderer/core/frame/dom_window.cc
+++ b/chromium/third_party/blink/renderer/core/frame/dom_window.cc
@@ -228,8 +228,8 @@ String DOMWindow::CrossDomainAccessErrorMessage(
// access. See https://crbug.com/601629.
DCHECK(GetFrame()->IsRemoteFrame() ||
!active_origin->CanAccess(target_origin) ||
- (local_dom_window && accessing_window->document()->GetAgent() !=
- local_dom_window->document()->GetAgent()));
+ (local_dom_window &&
+ accessing_window->GetAgent() != local_dom_window->GetAgent()));
String message = "Blocked a frame with origin \"" +
active_origin->ToString() +
@@ -322,6 +322,9 @@ void DOMWindow::Close(LocalDOMWindow* incumbent_window) {
if (!page)
return;
+ if (page->InsidePortal())
+ return;
+
Document* active_document = incumbent_window->document();
if (!(active_document && active_document->GetFrame() &&
active_document->GetFrame()->CanNavigate(*GetFrame()))) {
@@ -361,10 +364,11 @@ void DOMWindow::Close(LocalDOMWindow* incumbent_window) {
}
void DOMWindow::focus(v8::Isolate* isolate) {
- if (!GetFrame())
+ Frame* frame = GetFrame();
+ if (!frame)
return;
- Page* page = GetFrame()->GetPage();
+ Page* page = frame->GetPage();
if (!page)
return;
@@ -388,9 +392,9 @@ void DOMWindow::focus(v8::Isolate* isolate) {
}
// If we're a top level window, bring the window to the front.
- if (GetFrame()->IsMainFrame() && allow_focus) {
- page->GetChromeClient().Focus(incumbent_window->GetFrame());
- } else if (auto* local_frame = DynamicTo<LocalFrame>(GetFrame())) {
+ if (frame->IsMainFrame() && allow_focus) {
+ frame->FocusPage(incumbent_window->GetFrame());
+ } else if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
// We are depending on user activation twice since IsFocusAllowed() will
// check for activation. This should be addressed in
// https://crbug.com/959815.
@@ -480,7 +484,7 @@ void DOMWindow::DoPostMessage(scoped_refptr<SerializedScriptValue> message,
}
if (!source_document->GetContentSecurityPolicy()->AllowConnectToSource(
- target_url, RedirectStatus::kNoRedirect,
+ target_url, target_url, RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting)) {
UseCounter::Count(
source_document,
@@ -528,10 +532,10 @@ void DOMWindow::DoPostMessage(scoped_refptr<SerializedScriptValue> message,
GetFrame()->Client()->TransferUserActivationFrom(source->GetFrame());
}
- SchedulePostMessage(event, std::move(target), source_document);
+ SchedulePostMessage(event, std::move(target), source);
}
-void DOMWindow::Trace(Visitor* visitor) {
+void DOMWindow::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(window_proxy_manager_);
visitor->Trace(input_capabilities_);
diff --git a/chromium/third_party/blink/renderer/core/frame/dom_window.h b/chromium/third_party/blink/renderer/core/frame/dom_window.h
index d4fff638cd1..5758b6b104c 100644
--- a/chromium/third_party/blink/renderer/core/frame/dom_window.h
+++ b/chromium/third_party/blink/renderer/core/frame/dom_window.h
@@ -15,7 +15,6 @@
namespace blink {
-class Document;
class InputDeviceCapabilitiesConstants;
class LocalDOMWindow;
class Location;
@@ -58,7 +57,7 @@ class CORE_EXPORT DOMWindow : public EventTargetWithInlineData {
}
// GarbageCollected overrides:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
virtual bool IsLocalDOMWindow() const = 0;
virtual bool IsRemoteDOMWindow() const = 0;
@@ -136,7 +135,7 @@ class CORE_EXPORT DOMWindow : public EventTargetWithInlineData {
virtual void SchedulePostMessage(MessageEvent*,
scoped_refptr<const SecurityOrigin> target,
- Document* source) = 0;
+ LocalDOMWindow* source) = 0;
void DisconnectFromFrame() { frame_ = nullptr; }
diff --git a/chromium/third_party/blink/renderer/core/frame/event_handler_registry.cc b/chromium/third_party/blink/renderer/core/frame/event_handler_registry.cc
index 08d723da0be..f33133d5f97 100644
--- a/chromium/third_party/blink/renderer/core/frame/event_handler_registry.cc
+++ b/chromium/third_party/blink/renderer/core/frame/event_handler_registry.cc
@@ -344,7 +344,7 @@ void EventHandlerRegistry::NotifyDidAddOrRemoveEventHandlerTarget(
}
}
-void EventHandlerRegistry::Trace(Visitor* visitor) {
+void EventHandlerRegistry::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->template RegisterWeakCallbackMethod<
EventHandlerRegistry, &EventHandlerRegistry::ProcessCustomWeakness>(this);
diff --git a/chromium/third_party/blink/renderer/core/frame/event_handler_registry.h b/chromium/third_party/blink/renderer/core/frame/event_handler_registry.h
index d41ca26df6d..6df2f6a60e8 100644
--- a/chromium/third_party/blink/renderer/core/frame/event_handler_registry.h
+++ b/chromium/third_party/blink/renderer/core/frame/event_handler_registry.h
@@ -79,7 +79,7 @@ class CORE_EXPORT EventHandlerRegistry final
// references to handlers that are no longer related to it.
void DocumentDetached(Document&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
enum ChangeOperation {
diff --git a/chromium/third_party/blink/renderer/core/frame/find_in_page.cc b/chromium/third_party/blink/renderer/core/frame/find_in_page.cc
index 8f65b9cb858..e8a29fb90b1 100644
--- a/chromium/third_party/blink/renderer/core/frame/find_in_page.cc
+++ b/chromium/third_party/blink/renderer/core/frame/find_in_page.cc
@@ -70,7 +70,7 @@ void FindInPage::Find(int request_id,
blink::WebPlugin* plugin = GetWebPluginForFind();
// Check if the plugin still exists in the document.
if (plugin) {
- if (options->find_next) {
+ if (!options->new_session) {
// Just navigate back/forward.
plugin->SelectFindResult(options->forward, request_id);
LocalFrame* core_frame = frame_->GetFrame();
@@ -95,20 +95,20 @@ void FindInPage::Find(int request_id,
bool result = false;
bool active_now = false;
- if (!options->find_next) {
+ if (options->new_session) {
// If this is an initial find request, cancel any pending scoping effort
// done by the previous find request.
EnsureTextFinder().CancelPendingScopingEffort();
}
- // Search for an active match only if this frame is focused or if this is a
- // find next
- if (frame_->IsFocused() || options->find_next) {
+ // Search for an active match only if this frame is focused or if this is an
+ // existing session.
+ if (frame_->IsFocused() || !options->new_session) {
result = FindInternal(request_id, search_text, *options,
false /* wrap_within_frame */, &active_now);
}
- if (result && !options->find_next) {
+ if (result && options->new_session) {
// Indicate that at least one match has been found. 1 here means
// possibly more matches could be coming.
ReportFindInPageMatchCount(request_id, 1 /* count */,
@@ -117,8 +117,7 @@ void FindInPage::Find(int request_id,
// There are three cases in which scoping is needed:
//
- // (1) This is an initial find request (|options.findNext| is false). This
- // will be the first scoping effort for this find session.
+ // (1) This is a new find session. This will be its first scoping effort.
//
// (2) Something has been selected since the last search. This means that we
// cannot just increment the current match ordinal; we need to re-generate
@@ -133,7 +132,7 @@ void FindInPage::Find(int request_id,
//
// If none of these cases are true, then we just report the current match
// count without scoping.
- if (/* (1) */ options->find_next && /* (2) */ current_selection.IsNull() &&
+ if (/* (1) */ !options->new_session && /* (2) */ current_selection.IsNull() &&
/* (3) */ !(result && !active_now)) {
// Force report of the actual count.
EnsureTextFinder().IncreaseMatchCount(request_id, 0);
@@ -150,13 +149,13 @@ bool WebLocalFrameImpl::FindForTesting(int identifier,
const WebString& search_text,
bool match_case,
bool forward,
- bool find_next,
+ bool new_session,
bool force,
bool wrap_within_frame) {
auto options = mojom::blink::FindOptions::New();
options->match_case = match_case;
options->forward = forward;
- options->find_next = find_next;
+ options->new_session = new_session;
options->force = force;
options->run_synchronously_for_testing = true;
bool result = find_in_page_->FindInternal(identifier, search_text, *options,
diff --git a/chromium/third_party/blink/renderer/core/frame/find_in_page.h b/chromium/third_party/blink/renderer/core/frame/find_in_page.h
index 281aeaa6234..9895cd21167 100644
--- a/chromium/third_party/blink/renderer/core/frame/find_in_page.h
+++ b/chromium/third_party/blink/renderer/core/frame/find_in_page.h
@@ -93,7 +93,7 @@ class CORE_EXPORT FindInPage final : public GarbageCollected<FindInPage>,
void Dispose();
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(text_finder_);
visitor->Trace(frame_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/frame.cc b/chromium/third_party/blink/renderer/core/frame/frame.cc
index e7f1f74c95a..288d2dcedae 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame.cc
@@ -59,13 +59,31 @@
namespace blink {
+// static
+Frame* Frame::ResolveFrame(const base::UnguessableToken& frame_token) {
+ if (!frame_token)
+ return nullptr;
+
+ // The frame token could refer to either a RemoteFrame or a LocalFrame, so
+ // need to check both.
+ auto* remote = RemoteFrame::FromFrameToken(frame_token);
+ if (remote)
+ return remote;
+
+ auto* local = LocalFrame::FromFrameToken(frame_token);
+ if (local)
+ return local;
+
+ return nullptr;
+}
+
Frame::~Frame() {
InstanceCounters::DecrementCounter(InstanceCounters::kFrameCounter);
DCHECK(!owner_);
DCHECK(IsDetached());
}
-void Frame::Trace(Visitor* visitor) {
+void Frame::Trace(Visitor* visitor) const {
visitor->Trace(tree_node_);
visitor->Trace(page_);
visitor->Trace(owner_);
@@ -94,7 +112,7 @@ void Frame::Detach(FrameDetachType type) {
if (!client_)
return;
- client_->SetOpener(nullptr);
+ SetOpener(nullptr);
// After this, we must no longer talk to the client since this clears
// its owning reference back to our owning LocalFrame.
client_->Detached(type);
@@ -375,6 +393,27 @@ void Frame::CancelFormSubmission() {
form_submit_navigation_task_.Cancel();
}
+bool Frame::IsFormSubmissionPending() {
+ return form_submit_navigation_task_.IsActive();
+}
+
+void Frame::FocusPage(LocalFrame* originating_frame) {
+ // We only allow focus to move to the |frame|'s page when the request comes
+ // from a user gesture. (See https://bugs.webkit.org/show_bug.cgi?id=33389.)
+ if (originating_frame &&
+ LocalFrame::HasTransientUserActivation(originating_frame)) {
+ // Ask the broswer process to focus the page.
+ GetPage()->GetChromeClient().FocusPage();
+
+ // Tattle on the frame that called |window.focus()|.
+ originating_frame->GetLocalFrameHostRemote().DidCallFocus();
+ }
+
+ // Always report the attempt to focus the page to the Chrome client for
+ // testing purposes (i.e. see WebViewTest.FocusExistingFrameOnNavigate()).
+ GetPage()->GetChromeClient().DidFocusPage();
+}
+
STATIC_ASSERT_ENUM(FrameDetachType::kRemove,
WebLocalFrameClient::DetachType::kRemove);
STATIC_ASSERT_ENUM(FrameDetachType::kSwap,
diff --git a/chromium/third_party/blink/renderer/core/frame/frame.h b/chromium/third_party/blink/renderer/core/frame/frame.h
index bcf52f149d9..36453c3ef4b 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame.h
+++ b/chromium/third_party/blink/renderer/core/frame/frame.h
@@ -31,6 +31,7 @@
#include "base/optional.h"
#include "base/unguessable_token.h"
+#include "mojo/public/mojom/base/text_direction.mojom-blink-forward.h"
#include "third_party/blink/public/common/feature_policy/document_policy.h"
#include "third_party/blink/public/common/frame/user_activation_state.h"
#include "third_party/blink/public/common/frame/user_activation_update_source.h"
@@ -77,9 +78,13 @@ enum class FrameDetachType { kRemove, kSwap };
// input, layout, or painting probably belongs on LocalFrame.
class CORE_EXPORT Frame : public GarbageCollected<Frame> {
public:
+ // Returns the Frame instance for the given |frame_token|.
+ // Note that this Frame can be either a LocalFrame or Remote instance.
+ static Frame* ResolveFrame(const base::UnguessableToken& frame_token);
+
virtual ~Frame();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
virtual bool IsLocalFrame() const = 0;
virtual bool IsRemoteFrame() const = 0;
@@ -217,6 +222,9 @@ class CORE_EXPORT Frame : public GarbageCollected<Frame> {
virtual void SetIsInert(bool) = 0;
void UpdateInertIfPossible();
+ // Changes the text direction of the selected input node.
+ virtual void SetTextDirection(base::i18n::TextDirection) = 0;
+
virtual void SetInheritedEffectiveTouchAction(TouchAction) = 0;
void UpdateInheritedEffectiveTouchActionIfPossible();
TouchAction InheritedEffectiveTouchAction() const {
@@ -282,6 +290,12 @@ class CORE_EXPORT Frame : public GarbageCollected<Frame> {
void ScheduleFormSubmission(FrameScheduler* scheduler,
FormSubmission* form_submission);
void CancelFormSubmission();
+ bool IsFormSubmissionPending();
+
+ // Asks the browser process to activate the page associated to the current
+ // Frame, reporting |originating_frame| as the local frame originating this
+ // request.
+ void FocusPage(LocalFrame* originating_frame);
// Called when the focus controller changes the focus to this frame.
virtual void DidFocus() = 0;
@@ -289,6 +303,10 @@ class CORE_EXPORT Frame : public GarbageCollected<Frame> {
virtual IntSize GetMainFrameViewportSize() const = 0;
virtual IntPoint GetMainFrameScrollOffset() const = 0;
+ // Sets this frame's opener to another frame, or disowned the opener
+ // if opener is null. See http://html.spec.whatwg.org/#dom-opener.
+ virtual void SetOpener(Frame* opener) = 0;
+
protected:
// |inheriting_agent_factory| should basically be set to the parent frame or
// opener's WindowAgentFactory. Pass nullptr if the frame is isolated from
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_client.h b/chromium/third_party/blink/renderer/core/frame/frame_client.h
index 5efbc23b286..76bedeedb5e 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_client.h
+++ b/chromium/third_party/blink/renderer/core/frame/frame_client.h
@@ -23,8 +23,8 @@ class CORE_EXPORT FrameClient : public GarbageCollected<FrameClient> {
virtual void Detached(FrameDetachType) = 0;
+ // TODO(https://crbug.com/1051144): Move this getter to the Frame class.
virtual Frame* Opener() const = 0;
- virtual void SetOpener(Frame*) = 0;
virtual Frame* Parent() const = 0;
virtual Frame* Top() const = 0;
@@ -43,7 +43,7 @@ class CORE_EXPORT FrameClient : public GarbageCollected<FrameClient> {
virtual ~FrameClient() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_console.cc b/chromium/third_party/blink/renderer/core/frame/frame_console.cc
index 9c14e3a9bd1..42d746b1dbc 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_console.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame_console.cc
@@ -133,7 +133,7 @@ void FrameConsole::DidFailLoading(DocumentLoader* loader,
message.ToString(), error.FailingURL(), loader, request_identifier));
}
-void FrameConsole::Trace(Visitor* visitor) {
+void FrameConsole::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_console.h b/chromium/third_party/blink/renderer/core/frame/frame_console.h
index bf7a3835b64..21357417f74 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_console.h
+++ b/chromium/third_party/blink/renderer/core/frame/frame_console.h
@@ -68,7 +68,7 @@ class CORE_EXPORT FrameConsole final : public GarbageCollected<FrameConsole> {
uint64_t request_identifier,
const ResourceError&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<LocalFrame> frame_;
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_lifecycle.cc b/chromium/third_party/blink/renderer/core/frame/frame_lifecycle.cc
index 5a3fbf903f4..8c5728b55ef 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_lifecycle.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame_lifecycle.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/frame/frame_lifecycle.h"
+#include "base/check_op.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_overlay.cc b/chromium/third_party/blink/renderer/core/frame/frame_overlay.cc
index 79834d7f276..1a14c0d3169 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_overlay.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame_overlay.cc
@@ -53,6 +53,9 @@ FrameOverlay::FrameOverlay(LocalFrame* local_frame,
}
void FrameOverlay::UpdatePrePaint() {
+ // Invalidate DisplayItemClient.
+ Invalidate();
+
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
delegate_->Invalidate();
return;
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_overlay_test.cc b/chromium/third_party/blink/renderer/core/frame/frame_overlay_test.cc
index 19d9efcc421..497c732a65d 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_overlay_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame_overlay_test.cc
@@ -112,6 +112,7 @@ TEST_P(FrameOverlayTest, AcceleratedCompositing) {
graphics_layer->GetPropertyTreeState());
graphics_layer->Paint();
graphics_layer->CapturePaintRecord()->Playback(&canvas);
+ graphics_layer->GetPaintController().FinishCycle();
}
}
@@ -161,6 +162,7 @@ TEST_P(FrameOverlayTest, DeviceEmulationScale) {
EXPECT_EQ(state, graphics_layer->GetPropertyTreeState());
graphics_layer->Paint();
check_paint_results(graphics_layer->GetPaintController());
+ graphics_layer->GetPaintController().FinishCycle();
}
}
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_owner.h b/chromium/third_party/blink/renderer/core/frame/frame_owner.h
index a96fde63504..bb0ef04a521 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_owner.h
+++ b/chromium/third_party/blink/renderer/core/frame/frame_owner.h
@@ -26,7 +26,7 @@ class CORE_EXPORT FrameOwner : public GarbageCollectedMixin {
public:
virtual ~FrameOwner() = default;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
virtual bool IsLocal() const = 0;
virtual bool IsRemote() const = 0;
@@ -123,7 +123,7 @@ class CORE_EXPORT DummyFrameOwner final
USING_GARBAGE_COLLECTED_MIXIN(DummyFrameOwner);
public:
- void Trace(Visitor* visitor) override { FrameOwner::Trace(visitor); }
+ void Trace(Visitor* visitor) const override { FrameOwner::Trace(visitor); }
// FrameOwner overrides:
Frame* ContentFrame() const override { return nullptr; }
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_serializer.cc b/chromium/third_party/blink/renderer/core/frame/frame_serializer.cc
index 9b434d7397d..654997d4486 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_serializer.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame_serializer.cc
@@ -192,7 +192,7 @@ void SerializerMarkupAccumulator::AppendExtraForHeadElement(
AppendStylesheets(document_, true /*style_element_only*/);
// The stylesheets defined in imported documents are not incorporated into
- // master document. So we need to scan all of them.
+ // the tree-root document. So we need to scan all of them.
if (HTMLImportsController* controller = document_->ImportsController()) {
for (wtf_size_t i = 0; i < controller->LoaderCount(); ++i) {
if (Document* imported_document =
@@ -488,7 +488,7 @@ void FrameSerializer::SerializeCSSRule(CSSRule* rule) {
DCHECK(rule->parentStyleSheet()->OwnerDocument());
Document& document = *rule->parentStyleSheet()->OwnerDocument();
- switch (rule->type()) {
+ switch (rule->GetType()) {
case CSSRule::kStyleRule:
RetrieveResourcesForProperties(
&To<CSSStyleRule>(rule)->GetStyleRule()->Properties(), document);
@@ -524,6 +524,7 @@ void FrameSerializer::SerializeCSSRule(CSSRule* rule) {
case CSSRule::kPropertyRule:
case CSSRule::kKeyframesRule:
case CSSRule::kKeyframeRule:
+ case CSSRule::kScrollTimelineRule:
case CSSRule::kNamespaceRule:
case CSSRule::kViewportRule:
break;
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.cc b/chromium/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.cc
index ac111ef3ef1..d2c8fb5de06 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.cc
@@ -142,7 +142,7 @@ bool FrameSerializerDelegateImpl::ShouldIgnorePopupOverlayElement(
return false;
// The z-index should be greater than the threshold.
- if (box->Style()->ZIndex() < kPopupOverlayZIndexThreshold)
+ if (box->Style()->EffectiveZIndex() < kPopupOverlayZIndexThreshold)
return false;
popup_overlays_skipped_ = true;
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_serializer_test.cc b/chromium/third_party/blink/renderer/core/frame/frame_serializer_test.cc
index 00c020825e2..2906ce483c1 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_serializer_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame_serializer_test.cc
@@ -70,7 +70,7 @@ class FrameSerializerTest : public testing::Test,
}
void TearDown() override {
- platform_->GetURLLoaderMockFactory()
+ WebURLLoaderMockFactory::GetSingletonInstance()
->UnregisterAllURLsAndClearMemoryCache();
}
@@ -99,7 +99,7 @@ class FrameSerializerTest : public testing::Test,
response.SetMimeType("text/html");
response.SetHttpStatusCode(status_code);
- platform_->GetURLLoaderMockFactory()->RegisterErrorURL(
+ WebURLLoaderMockFactory::GetSingletonInstance()->RegisterErrorURL(
KURL(base_url_, file), response, WebURLError(error));
}
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.cc b/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.cc
index 1800471a1a3..a34b9492abd 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.cc
@@ -35,6 +35,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "build/build_config.h"
#include "cc/test/fake_layer_tree_frame_sink.h"
#include "cc/test/test_ukm_recorder_factory.h"
#include "cc/trees/layer_tree_host.h"
@@ -45,6 +46,7 @@
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/frame/frame_policy.h"
#include "third_party/blink/public/mojom/frame/tree_scope_type.mojom-blink.h"
+#include "third_party/blink/public/mojom/page/widget.mojom-blink.h"
#include "third_party/blink/public/platform/interface_registry.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_data.h"
@@ -69,6 +71,7 @@
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "ui/base/ime/mojom/text_input_state.mojom-blink.h"
namespace blink {
namespace frame_test_helpers {
@@ -94,7 +97,7 @@ namespace {
void RunServeAsyncRequestsTask(scoped_refptr<base::TaskRunner> task_runner) {
// TODO(kinuko,toyoshim): Create a mock factory and use it instead of
// getting the platform's one. (crbug.com/751425)
- Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
+ WebURLLoaderMockFactory::GetSingletonInstance()->ServeAsynchronousRequests();
if (TestWebFrameClient::IsLoading()) {
task_runner->PostTask(FROM_HERE,
WTF::Bind(&RunServeAsyncRequestsTask, task_runner));
@@ -122,6 +125,9 @@ cc::LayerTreeSettings GetSynchronousSingleThreadLayerTreeSettings() {
// test makes progress.
settings.single_thread_proxy_scheduler = false;
settings.use_layer_lists = true;
+#if defined(OS_MACOSX)
+ settings.enable_elastic_overscroll = true;
+#endif
return settings;
}
@@ -197,7 +203,7 @@ void FillNavigationParamsResponse(WebNavigationParams* params) {
// Empty documents and srcdoc will be handled by DocumentLoader.
if (DocumentLoader::WillLoadUrlAsEmpty(kurl) || kurl.IsAboutSrcdocURL())
return;
- Platform::Current()->GetURLLoaderMockFactory()->FillNavigationParamsResponse(
+ WebURLLoaderMockFactory::GetSingletonInstance()->FillNavigationParamsResponse(
params);
}
@@ -259,6 +265,10 @@ WebLocalFrameImpl* CreateProvisional(WebRemoteFrame& old_frame,
frame_widget_host_receiver =
frame_widget_host.BindNewEndpointAndPassDedicatedReceiverForTesting();
+ mojo::AssociatedRemote<mojom::blink::Widget> widget_remote;
+ mojo::PendingAssociatedReceiver<mojom::blink::Widget> widget_receiver =
+ widget_remote.BindNewEndpointAndPassDedicatedReceiverForTesting();
+
// Create a local root, if necessary.
if (!frame->Parent()) {
widget_client = std::make_unique<TestWebWidgetClient>();
@@ -266,9 +276,8 @@ WebLocalFrameImpl* CreateProvisional(WebRemoteFrame& old_frame,
// Eliminate this once WebView is no longer a WebWidget.
WebFrameWidget* frame_widget = WebFrameWidget::CreateForMainFrame(
widget_client.get(), frame, frame_widget_host.Unbind(),
- std::move(frame_widget_receiver),
- CrossVariantMojoAssociatedRemote<mojom::WidgetHostInterfaceBase>(),
- CrossVariantMojoAssociatedReceiver<mojom::WidgetInterfaceBase>());
+ std::move(frame_widget_receiver), widget_client->BindNewWidgetHost(),
+ std::move(widget_receiver));
widget_client->SetFrameWidget(frame_widget);
// The WebWidget requires the compositor to be set before it is used.
widget_client->set_layer_tree_host(frame_widget->InitializeCompositing(
@@ -281,9 +290,8 @@ WebLocalFrameImpl* CreateProvisional(WebRemoteFrame& old_frame,
WebFrameWidget* frame_widget = WebFrameWidget::CreateForChildLocalRoot(
widget_client.get(), frame, frame_widget_host.Unbind(),
- std::move(frame_widget_receiver),
- CrossVariantMojoAssociatedRemote<mojom::WidgetHostInterfaceBase>(),
- CrossVariantMojoAssociatedReceiver<mojom::WidgetInterfaceBase>());
+ std::move(frame_widget_receiver), widget_client->BindNewWidgetHost(),
+ std::move(widget_receiver));
widget_client->SetFrameWidget(frame_widget);
// The WebWidget requires the compositor to be set before it is used.
widget_client->set_layer_tree_host(frame_widget->InitializeCompositing(
@@ -304,7 +312,7 @@ WebRemoteFrameImpl* CreateRemote(TestWebRemoteFrameClient* client) {
auto* frame = MakeGarbageCollected<WebRemoteFrameImpl>(
mojom::blink::TreeScopeType::kDocument, client,
InterfaceRegistry::GetEmptyInterfaceRegistry(),
- client->GetAssociatedInterfaceProvider(),
+ client->GetRemoteAssociatedInterfaces(),
base::UnguessableToken::Create());
client->Bind(frame, std::move(owned_client));
return frame;
@@ -340,11 +348,14 @@ WebLocalFrameImpl* CreateLocalChild(WebRemoteFrame& parent,
frame_widget_host_receiver =
frame_widget_host.BindNewEndpointAndPassDedicatedReceiverForTesting();
+ mojo::AssociatedRemote<mojom::blink::Widget> widget_remote;
+ mojo::PendingAssociatedReceiver<mojom::blink::Widget> widget_receiver =
+ widget_remote.BindNewEndpointAndPassDedicatedReceiverForTesting();
+
WebFrameWidget* frame_widget = WebFrameWidget::CreateForChildLocalRoot(
widget_client, frame, frame_widget_host.Unbind(),
- std::move(frame_widget_receiver),
- CrossVariantMojoAssociatedRemote<mojom::WidgetHostInterfaceBase>(),
- CrossVariantMojoAssociatedReceiver<mojom::WidgetInterfaceBase>());
+ std::move(frame_widget_receiver), widget_client->BindNewWidgetHost(),
+ std::move(widget_receiver));
// The WebWidget requires the compositor to be set before it is used.
widget_client->SetFrameWidget(frame_widget);
widget_client->set_layer_tree_host(frame_widget->InitializeCompositing(
@@ -370,8 +381,8 @@ WebRemoteFrameImpl* CreateRemoteChild(
mojom::blink::TreeScopeType::kDocument, name, FramePolicy(),
mojom::blink::FrameOwnerElementType::kIframe, client,
InterfaceRegistry::GetEmptyInterfaceRegistry(),
- client->GetAssociatedInterfaceProvider(),
- base::UnguessableToken::Create(), nullptr));
+ client->GetRemoteAssociatedInterfaces(), base::UnguessableToken::Create(),
+ nullptr));
client->Bind(frame, std::move(owned_client));
if (!security_origin)
security_origin = SecurityOrigin::CreateUniqueOpaque();
@@ -421,13 +432,16 @@ WebViewImpl* WebViewHelper::InitializeWithOpener(
frame_widget_host_receiver =
frame_widget_host.BindNewEndpointAndPassDedicatedReceiverForTesting();
+ mojo::AssociatedRemote<mojom::blink::Widget> widget_remote;
+ mojo::PendingAssociatedReceiver<mojom::blink::Widget> widget_receiver =
+ widget_remote.BindNewEndpointAndPassDedicatedReceiverForTesting();
+
// TODO(dcheng): The main frame widget currently has a special case.
// Eliminate this once WebView is no longer a WebWidget.
WebFrameWidget* widget = blink::WebFrameWidget::CreateForMainFrame(
test_web_widget_client_, frame, frame_widget_host.Unbind(),
std::move(frame_widget_receiver),
- CrossVariantMojoAssociatedRemote<mojom::WidgetHostInterfaceBase>(),
- CrossVariantMojoAssociatedReceiver<mojom::WidgetInterfaceBase>());
+ test_web_widget_client_->BindNewWidgetHost(), std::move(widget_receiver));
// The WebWidget requires the compositor to be set before it is used.
test_web_widget_client_->SetFrameWidget(widget);
test_web_widget_client_->set_layer_tree_host(widget->InitializeCompositing(
@@ -505,7 +519,7 @@ WebViewImpl* WebViewHelper::InitializeRemoteWithOpener(
WebRemoteFrameImpl* frame = WebRemoteFrameImpl::CreateMainFrame(
web_view_, web_remote_frame_client,
InterfaceRegistry::GetEmptyInterfaceRegistry(),
- web_remote_frame_client->GetAssociatedInterfaceProvider(),
+ web_remote_frame_client->GetRemoteAssociatedInterfaces(),
base::UnguessableToken::Create(), opener);
web_remote_frame_client->Bind(frame,
std::move(owned_web_remote_frame_client));
@@ -644,8 +658,7 @@ void TestWebFrameClient::BeginNavigation(
return;
}
- if (!frame_->WillStartNavigation(
- *info, false /* is_history_navigation_in_new_child_frame */))
+ if (!frame_->WillStartNavigation(*info))
return;
navigation_callback_.Reset(
@@ -715,6 +728,12 @@ void TestWebWidgetClient::SetFrameWidget(WebFrameWidget* widget) {
frame_widget_ = widget;
}
+mojo::PendingAssociatedRemote<mojom::blink::WidgetHost>
+TestWebWidgetClient::BindNewWidgetHost() {
+ receiver_.reset();
+ return receiver_.BindNewEndpointAndPassDedicatedRemoteForTesting();
+}
+
void TestWebWidgetClient::SetPageScaleStateAndLimits(
float page_scale_factor,
bool is_pinch_gesture_active,
@@ -724,15 +743,9 @@ void TestWebWidgetClient::SetPageScaleStateAndLimits(
maximum);
}
-void TestWebWidgetClient::InjectGestureScrollEvent(
- WebGestureDevice device,
- const gfx::Vector2dF& delta,
- ScrollGranularity granularity,
- cc::ElementId scrollable_area_element_id,
- WebInputEvent::Type injected_type) {
- InjectedScrollGestureData data{delta, granularity, scrollable_area_element_id,
- injected_type};
- injected_scroll_gesture_data_.push_back(data);
+void TestWebWidgetClient::QueueSyntheticEvent(
+ std::unique_ptr<blink::WebCoalescedInputEvent> event) {
+ injected_scroll_events_.push_back(std::move(event));
}
bool TestWebWidgetClient::HaveScrollEventHandlers() const {
@@ -765,6 +778,22 @@ void TestWebWidgetClient::RequestNewLayerTreeFrameSink(
std::move(callback).Run(cc::FakeLayerTreeFrameSink::Create3d(), nullptr);
}
+void TestWebWidgetClient::SetCursor(const ui::Cursor& cursor) {}
+
+void TestWebWidgetClient::SetToolTipText(
+ const String& tooltip_text,
+ base::i18n::TextDirection text_direction_hint) {}
+
+void TestWebWidgetClient::TextInputStateChanged(
+ ui::mojom::blink::TextInputStatePtr state) {}
+
+void TestWebWidgetClient::SelectionBoundsChanged(
+ const gfx::Rect& anchor_rect,
+ base::i18n::TextDirection anchor_dir,
+ const gfx::Rect& focus_rect,
+ base::i18n::TextDirection focus_dir,
+ bool is_anchor_first) {}
+
void TestWebViewClient::DestroyChildViews() {
child_web_views_.clear();
}
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.h b/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.h
index dc312fbf279..0a6833e424b 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.h
+++ b/chromium/third_party/blink/renderer/core/frame/frame_test_helpers.h
@@ -176,14 +176,8 @@ WebRemoteFrameImpl* CreateRemoteChild(WebRemoteFrame& parent,
scoped_refptr<SecurityOrigin> = nullptr,
TestWebRemoteFrameClient* = nullptr);
-struct InjectedScrollGestureData {
- gfx::Vector2dF delta;
- ScrollGranularity granularity;
- CompositorElementId scrollable_area_element_id;
- WebInputEvent::Type type;
-};
-
-class TestWebWidgetClient : public WebWidgetClient {
+class TestWebWidgetClient : public WebWidgetClient,
+ public mojom::blink::WidgetHost {
public:
TestWebWidgetClient();
~TestWebWidgetClient() override = default;
@@ -209,9 +203,9 @@ class TestWebWidgetClient : public WebWidgetClient {
int FinishedLoadingLayoutCount() const {
return finished_loading_layout_count_;
}
- const Vector<InjectedScrollGestureData>& GetInjectedScrollGestureData()
- const {
- return injected_scroll_gesture_data_;
+ const Vector<std::unique_ptr<blink::WebCoalescedInputEvent>>&
+ GetInjectedScrollEvents() const {
+ return injected_scroll_events_;
}
cc::TaskGraphRunner* task_graph_runner() { return &test_task_graph_runner_; }
@@ -220,6 +214,8 @@ class TestWebWidgetClient : public WebWidgetClient {
layer_tree_host_ = layer_tree_host;
}
+ mojo::PendingAssociatedRemote<mojom::blink::WidgetHost> BindNewWidgetHost();
+
protected:
// WebWidgetClient overrides;
void ScheduleAnimation() override { animation_scheduled_ = true; }
@@ -227,26 +223,37 @@ class TestWebWidgetClient : public WebWidgetClient {
bool is_pinch_gesture_active,
float minimum,
float maximum) override;
- void InjectGestureScrollEvent(WebGestureDevice device,
- const gfx::Vector2dF& delta,
- ScrollGranularity granularity,
- cc::ElementId scrollable_area_element_id,
- WebInputEvent::Type injected_type) override;
+ void QueueSyntheticEvent(
+ std::unique_ptr<blink::WebCoalescedInputEvent>) override;
void DidMeaningfulLayout(WebMeaningfulLayout) override;
viz::FrameSinkId GetFrameSinkId() override;
void RequestNewLayerTreeFrameSink(
LayerTreeFrameSinkCallback callback) override;
+ // mojom::blink::WidgetHost overrides:
+ void SetCursor(const ui::Cursor& cursor) override;
+ void SetToolTipText(const String& tooltip_text,
+ base::i18n::TextDirection text_direction_hint) override;
+ void TextInputStateChanged(
+ ui::mojom::blink::TextInputStatePtr state) override;
+ void SelectionBoundsChanged(const gfx::Rect& anchor_rect,
+ base::i18n::TextDirection anchor_dir,
+ const gfx::Rect& focus_rect,
+ base::i18n::TextDirection focus_dir,
+ bool is_anchor_first) override;
+
private:
WebFrameWidget* frame_widget_ = nullptr;
cc::LayerTreeHost* layer_tree_host_ = nullptr;
cc::TestTaskGraphRunner test_task_graph_runner_;
blink::scheduler::WebFakeThreadScheduler fake_thread_scheduler_;
- Vector<InjectedScrollGestureData> injected_scroll_gesture_data_;
+ Vector<std::unique_ptr<blink::WebCoalescedInputEvent>>
+ injected_scroll_events_;
bool animation_scheduled_ = false;
int visually_non_empty_layout_count_ = 0;
int finished_parsing_layout_count_ = 0;
int finished_loading_layout_count_ = 0;
+ mojo::AssociatedReceiver<mojom::blink::WidgetHost> receiver_{this};
};
class TestWebViewClient : public WebViewClient {
@@ -463,12 +470,7 @@ class TestWebRemoteFrameClient : public WebRemoteFrameClient {
// WebRemoteFrameClient:
void FrameDetached(DetachType) override;
- void ForwardPostMessage(WebLocalFrame* source_frame,
- WebRemoteFrame* target_frame,
- WebSecurityOrigin target_origin,
- WebDOMMessageEvent) override {}
-
- AssociatedInterfaceProvider* GetAssociatedInterfaceProvider() {
+ AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() override {
return associated_interface_provider_.get();
}
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_view.cc b/chromium/third_party/blink/renderer/core/frame/frame_view.cc
index e52d60795fb..781b93f0039 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_view.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame_view.cc
@@ -42,18 +42,17 @@ bool FrameView::DisplayLockedInParentFrame() {
return owner && DisplayLockUtilities::NearestLockedInclusiveAncestor(*owner);
}
-bool FrameView::UpdateViewportIntersection(unsigned flags,
+void FrameView::UpdateViewportIntersection(unsigned flags,
bool needs_occlusion_tracking) {
- bool can_skip_sticky_frame_tracking =
- flags & IntersectionObservation::kCanSkipStickyFrameTracking;
-
if (!(flags & IntersectionObservation::kImplicitRootObserversNeedUpdate))
- return can_skip_sticky_frame_tracking;
+ return;
+
// This should only run in child frames.
Frame& frame = GetFrame();
HTMLFrameOwnerElement* owner_element = frame.DeprecatedLocalOwner();
if (!owner_element)
- return can_skip_sticky_frame_tracking;
+ return;
+
Document& owner_document = owner_element->GetDocument();
IntPoint viewport_offset;
IntRect viewport_intersection, mainframe_document_intersection;
@@ -64,8 +63,7 @@ bool FrameView::UpdateViewportIntersection(unsigned flags,
bool should_compute_occlusion =
needs_occlusion_tracking &&
occlusion_state == FrameOcclusionState::kGuaranteedNotOccluded &&
- parent_lifecycle_state >= DocumentLifecycle::kPrePaintClean &&
- RuntimeEnabledFeatures::IntersectionObserverV2Enabled();
+ parent_lifecycle_state >= DocumentLifecycle::kPrePaintClean;
LayoutEmbeddedContent* owner_layout_object =
owner_element->GetLayoutEmbeddedContent();
@@ -81,9 +79,9 @@ bool FrameView::UpdateViewportIntersection(unsigned flags,
if (should_compute_occlusion)
geometry_flags |= IntersectionGeometry::kShouldComputeVisibility;
- IntersectionGeometry geometry(nullptr, *owner_element, {},
+ IntersectionGeometry geometry(nullptr, *owner_element, {} /* root_margin */,
{IntersectionObserver::kMinimumThreshold},
- geometry_flags);
+ {} /* target_margin */, geometry_flags);
PhysicalRect new_rect_in_parent = geometry.IntersectionRect();
if (new_rect_in_parent.size != rect_in_parent_.size ||
((new_rect_in_parent.X() - rect_in_parent_.X()).Abs() +
@@ -106,30 +104,12 @@ bool FrameView::UpdateViewportIntersection(unsigned flags,
PhysicalOffset content_box_offset =
owner_layout_object->PhysicalContentBoxOffset();
- if (NeedsViewportOffset() || !can_skip_sticky_frame_tracking) {
+ if (NeedsViewportOffset()) {
viewport_offset = -RoundedIntPoint(
owner_layout_object->AbsoluteToLocalPoint(
PhysicalOffset(),
kTraverseDocumentBoundaries | kApplyRemoteRootFrameOffset) -
content_box_offset);
- if (!can_skip_sticky_frame_tracking) {
- // If the frame is small, skip tracking this frame and its subframes.
- if (frame.GetMainFrameViewportSize().IsEmpty() ||
- !StickyFrameTracker::IsLarge(
- frame.GetMainFrameViewportSize(),
- new_rect_in_parent.PixelSnappedSize())) {
- can_skip_sticky_frame_tracking = true;
- }
- // If the frame is a large sticky ad, record a use counter and skip
- // tracking its subframes; otherwise continue tracking its subframes.
- else if (frame.IsAdSubframe() &&
- GetStickyFrameTracker()->UpdateStickyStatus(
- frame.GetMainFrameScrollOffset(), viewport_offset)) {
- UseCounter::Count(owner_element->GetDocument(),
- WebFeature::kLargeStickyAd);
- can_skip_sticky_frame_tracking = true;
- }
- }
}
// Generate matrix to transform from the space of the containing document
@@ -180,10 +160,10 @@ bool FrameView::UpdateViewportIntersection(unsigned flags,
occlusion_state = FrameOcclusionState::kUnknown;
}
- SetViewportIntersection(
- {viewport_offset, viewport_intersection, mainframe_document_intersection,
- WebRect(), occlusion_state, frame.GetMainFrameViewportSize(),
- frame.GetMainFrameScrollOffset(), can_skip_sticky_frame_tracking});
+ SetViewportIntersection({viewport_offset, viewport_intersection,
+ mainframe_document_intersection, WebRect(),
+ occlusion_state, frame.GetMainFrameViewportSize(),
+ frame.GetMainFrameScrollOffset()});
UpdateFrameVisibility(!viewport_intersection.IsEmpty());
@@ -203,7 +183,6 @@ bool FrameView::UpdateViewportIntersection(unsigned flags,
parent_frame->View()->CanThrottleRenderingForPropagation();
}
UpdateRenderThrottlingStatus(hidden_for_throttling, subtree_throttled);
- return can_skip_sticky_frame_tracking;
}
void FrameView::UpdateFrameVisibility(bool intersects_viewport) {
@@ -259,10 +238,4 @@ bool FrameView::RectInParentIsStable(
return parent->RectInParentIsStable(event_timestamp);
}
-StickyFrameTracker* FrameView::GetStickyFrameTracker() {
- if (!sticky_frame_tracker_)
- sticky_frame_tracker_ = std::make_unique<StickyFrameTracker>();
- return sticky_frame_tracker_.get();
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_view.h b/chromium/third_party/blink/renderer/core/frame/frame_view.h
index aa5e42ac59a..24de3107916 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_view.h
+++ b/chromium/third_party/blink/renderer/core/frame/frame_view.h
@@ -8,7 +8,6 @@
#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h"
#include "third_party/blink/public/platform/viewport_intersection_state.h"
#include "third_party/blink/renderer/core/frame/embedded_content_view.h"
-#include "third_party/blink/renderer/core/frame/sticky_frame_tracker.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
@@ -17,11 +16,7 @@ namespace blink {
class Frame;
struct IntrinsicSizingInfo;
-// clang::lto_visibility_public is necessary to prevent the compiler from
-// performing a vtable optimization that crashes the renderer. See
-// crbug.com/1062006.
-class CORE_EXPORT [[clang::lto_visibility_public]] FrameView
- : public EmbeddedContentView {
+class CORE_EXPORT FrameView : public EmbeddedContentView {
public:
FrameView(const IntRect& frame_rect) : EmbeddedContentView(frame_rect) {}
~FrameView() override = default;
@@ -67,8 +62,7 @@ class CORE_EXPORT [[clang::lto_visibility_public]] FrameView
const ViewportIntersectionState& intersection_state) = 0;
virtual void VisibilityForThrottlingChanged() = 0;
virtual bool LifecycleUpdatesThrottled() const { return false; }
- // Returns whether we can skip tracking sticky frames.
- bool UpdateViewportIntersection(unsigned, bool);
+ void UpdateViewportIntersection(unsigned, bool);
// FrameVisibility is tracked by the browser process, which may suppress
// lifecycle updates for a frame outside the viewport.
void UpdateFrameVisibility(bool);
@@ -78,15 +72,12 @@ class CORE_EXPORT [[clang::lto_visibility_public]] FrameView
virtual void VisibilityChanged(blink::mojom::FrameVisibility visibilty) = 0;
private:
- StickyFrameTracker* GetStickyFrameTracker();
-
PhysicalRect rect_in_parent_;
base::TimeTicks rect_in_parent_stable_since_;
blink::mojom::FrameVisibility frame_visibility_ =
blink::mojom::FrameVisibility::kRenderedInViewport;
bool hidden_for_throttling_;
bool subtree_throttled_;
- std::unique_ptr<StickyFrameTracker> sticky_frame_tracker_;
};
template <>
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_view_auto_size_info.cc b/chromium/third_party/blink/renderer/core/frame/frame_view_auto_size_info.cc
index ea22088c7f5..f5af179cec0 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_view_auto_size_info.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame_view_auto_size_info.cc
@@ -19,7 +19,7 @@ FrameViewAutoSizeInfo::FrameViewAutoSizeInfo(LocalFrameView* view)
DCHECK(frame_view_);
}
-void FrameViewAutoSizeInfo::Trace(Visitor* visitor) {
+void FrameViewAutoSizeInfo::Trace(Visitor* visitor) const {
visitor->Trace(frame_view_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_view_auto_size_info.h b/chromium/third_party/blink/renderer/core/frame/frame_view_auto_size_info.h
index b83e4ecbbd9..514e6789c82 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_view_auto_size_info.h
+++ b/chromium/third_party/blink/renderer/core/frame/frame_view_auto_size_info.h
@@ -23,7 +23,7 @@ class FrameViewAutoSizeInfo final
void ConfigureAutoSizeMode(const IntSize& min_size, const IntSize& max_size);
void AutoSizeIfNeeded();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<LocalFrameView> frame_view_;
diff --git a/chromium/third_party/blink/renderer/core/frame/history.cc b/chromium/third_party/blink/renderer/core/frame/history.cc
index e21cc0f38a8..7f994d17b37 100644
--- a/chromium/third_party/blink/renderer/core/frame/history.cc
+++ b/chromium/third_party/blink/renderer/core/frame/history.cc
@@ -25,8 +25,6 @@
#include "third_party/blink/renderer/core/frame/history.h"
-#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
-#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h"
#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-shared.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -67,7 +65,7 @@ bool EqualIgnoringQueryAndFragment(const KURL& a, const KURL& b) {
History::History(LocalFrame* frame)
: ExecutionContextClient(frame), last_state_object_requested_(nullptr) {}
-void History::Trace(Visitor* visitor) {
+void History::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
}
@@ -79,14 +77,7 @@ unsigned History::length(ExceptionState& exception_state) const {
"fully active");
return 0;
}
-
- unsigned result = GetFrame()->Client()->BackForwardLength();
- Document* document = DomWindow()->document();
- IdentifiabilityMetricBuilder(document->UkmSourceID())
- .SetWebfeature(WebFeature::kHistoryLength,
- IdentifiabilityDigestHelper(result))
- .Record(document->UkmRecorder());
- return result;
+ return GetFrame()->Client()->BackForwardLength();
}
ScriptValue History::state(ScriptState* script_state,
diff --git a/chromium/third_party/blink/renderer/core/frame/history.h b/chromium/third_party/blink/renderer/core/frame/history.h
index 8621718a727..2a10265f73b 100644
--- a/chromium/third_party/blink/renderer/core/frame/history.h
+++ b/chromium/third_party/blink/renderer/core/frame/history.h
@@ -76,7 +76,7 @@ class CORE_EXPORT History final : public ScriptWrappable,
bool IsSameAsCurrentState(SerializedScriptValue*) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
FRIEND_TEST_ALL_PREFIXES(HistoryTest, CanChangeToURL);
diff --git a/chromium/third_party/blink/renderer/core/frame/history.idl b/chromium/third_party/blink/renderer/core/frame/history.idl
index 7bf5beeb13e..eee7797a3cc 100644
--- a/chromium/third_party/blink/renderer/core/frame/history.idl
+++ b/chromium/third_party/blink/renderer/core/frame/history.idl
@@ -30,7 +30,7 @@ enum ScrollRestoration {"auto", "manual"};
[
Exposed=Window
] interface History {
- [MeasureAs=HistoryLength, RaisesException] readonly attribute unsigned long length;
+ [HighEntropy=Direct, MeasureAs=HistoryLength, RaisesException] readonly attribute unsigned long length;
[Measure, RaisesException] attribute ScrollRestoration scrollRestoration;
[CallWith=ScriptState, RaisesException] readonly attribute any state;
[CallWith=ScriptState, RaisesException] void go(optional long delta = 0);
diff --git a/chromium/third_party/blink/renderer/core/frame/local_dom_window.cc b/chromium/third_party/blink/renderer/core/frame/local_dom_window.cc
index 41cbe27f5e2..3ac97b71b1b 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/chromium/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -37,8 +37,10 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_screen_info.h"
#include "third_party/blink/renderer/bindings/core/v8/binding_security.h"
+#include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_scroll_to_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_void_function.h"
@@ -53,7 +55,6 @@
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/css/style_media.h"
#include "third_party/blink/renderer/core/dom/document_init.h"
-#include "third_party/blink/renderer/core/dom/dom_implementation.h"
#include "third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
#include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h"
@@ -68,6 +69,7 @@
#include "third_party/blink/renderer/core/events/hash_change_event.h"
#include "third_party/blink/renderer/core/events/message_event.h"
#include "third_party/blink/renderer/core/events/pop_state_event.h"
+#include "third_party/blink/renderer/core/execution_context/agent_metrics_collector.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/execution_context/security_context_init.h"
#include "third_party/blink/renderer/core/execution_context/window_agent.h"
@@ -102,6 +104,7 @@
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/loader/appcache/application_cache.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
+#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/create_window.h"
#include "third_party/blink/renderer/core/page/page.h"
@@ -117,20 +120,19 @@
#include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/scheduler/public/dummy_schedulers.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+#include "third_party/blink/renderer/platform/widget/frame_widget.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
+#include "v8/include/v8.h"
namespace blink {
-// Timeout for link preloads to be used after window.onload
-static constexpr base::TimeDelta kUnusedPreloadTimeout =
- base::TimeDelta::FromSeconds(3);
-
static void UpdateSuddenTerminationStatus(
LocalDOMWindow* dom_window,
bool added_listener,
@@ -227,29 +229,28 @@ static void UntrackAllBeforeUnloadEventListeners(LocalDOMWindow* dom_window) {
blink::mojom::SuddenTerminationDisablerType::kBeforeUnloadHandler);
}
-LocalDOMWindow::LocalDOMWindow(LocalFrame& frame)
+LocalDOMWindow::LocalDOMWindow(LocalFrame& frame, WindowAgent* agent)
: DOMWindow(frame),
- ExecutionContext(V8PerIsolateData::MainThreadIsolate()),
+ ExecutionContext(V8PerIsolateData::MainThreadIsolate(), agent),
visualViewport_(MakeGarbageCollected<DOMVisualViewport>(this)),
- unused_preloads_timer_(frame.GetTaskRunner(TaskType::kInternalDefault),
- this,
- &LocalDOMWindow::WarnUnusedPreloads),
should_print_when_finished_loading_(false),
input_method_controller_(
MakeGarbageCollected<InputMethodController>(*this, frame)),
spell_checker_(MakeGarbageCollected<SpellChecker>(*this)),
text_suggestion_controller_(
- MakeGarbageCollected<TextSuggestionController>(*this)) {}
-
-void LocalDOMWindow::ClearDocument() {
- if (!document_)
- return;
+ MakeGarbageCollected<TextSuggestionController>(*this)),
+ isolated_world_csp_map_(
+ MakeGarbageCollected<
+ HeapHashMap<int, Member<ContentSecurityPolicy>>>()) {}
- DCHECK(!document_->IsActive());
-
- unused_preloads_timer_.Stop();
- document_->ClearDOMWindow();
- document_ = nullptr;
+void LocalDOMWindow::ResetWindowAgent(WindowAgent* agent) {
+ GetAgent()->DetachContext(this);
+ if (auto* agent_metrics = GetFrame()->GetPage()->GetAgentMetricsCollector())
+ agent_metrics->DidDetachWindow(*this);
+ ResetAgent(agent);
+ GetAgent()->AttachContext(this);
+ if (auto* agent_metrics = GetFrame()->GetPage()->GetAgentMetricsCollector())
+ agent_metrics->DidAttachWindow(*this);
}
void LocalDOMWindow::AcceptLanguagesChanged() {
@@ -259,6 +260,34 @@ void LocalDOMWindow::AcceptLanguagesChanged() {
DispatchEvent(*Event::Create(event_type_names::kLanguagechange));
}
+ScriptValue LocalDOMWindow::event(ScriptState* script_state) const {
+ // If current event is null, return undefined.
+ if (!current_event_) {
+ return ScriptValue(script_state->GetIsolate(),
+ ToV8(ToV8UndefinedGenerator(), script_state));
+ }
+
+ // Track usage of window.event when the event's target is inside V0 shadow
+ // tree.
+ if (current_event_->target()) {
+ Node* target_node = current_event_->target()->ToNode();
+ if (target_node && target_node->IsInV0ShadowTree()) {
+ UseCounter::Count(document(), WebFeature::kWindowEventInV0ShadowTree);
+ }
+ }
+
+ return ScriptValue(script_state->GetIsolate(),
+ ToV8(CurrentEvent(), script_state));
+}
+
+Event* LocalDOMWindow::CurrentEvent() const {
+ return current_event_.Get();
+}
+
+void LocalDOMWindow::SetCurrentEvent(Event* new_event) {
+ current_event_ = new_event;
+}
+
TrustedTypePolicyFactory* LocalDOMWindow::trustedTypes() const {
if (!trusted_types_) {
trusted_types_ =
@@ -295,7 +324,31 @@ bool LocalDOMWindow::ShouldInstallV8Extensions() const {
}
ContentSecurityPolicy* LocalDOMWindow::GetContentSecurityPolicyForWorld() {
- return document()->GetContentSecurityPolicyForWorld();
+ v8::Isolate* isolate = GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Context> v8_context = isolate->GetCurrentContext();
+
+ // This can be called before we enter v8, hence the context might be empty,
+ // which implies we are not in an isolated world.
+ if (v8_context.IsEmpty())
+ return GetContentSecurityPolicy();
+
+ DOMWrapperWorld& world = DOMWrapperWorld::Current(isolate);
+ if (!world.IsIsolatedWorld())
+ return GetContentSecurityPolicy();
+
+ int32_t world_id = world.GetWorldId();
+ auto it = isolated_world_csp_map_->find(world_id);
+ if (it != isolated_world_csp_map_->end())
+ return it->value;
+
+ ContentSecurityPolicy* policy =
+ IsolatedWorldCSP::Get().CreateIsolatedWorldCSP(*this, world_id);
+ if (!policy)
+ return GetContentSecurityPolicy();
+
+ isolated_world_csp_map_->insert(world_id, policy);
+ return policy;
}
const KURL& LocalDOMWindow::Url() const {
@@ -339,15 +392,64 @@ const SecurityContext& LocalDOMWindow::GetSecurityContext() const {
bool LocalDOMWindow::CanExecuteScripts(
ReasonForCallingCanExecuteScripts reason) {
- return document()->CanExecuteScripts(reason);
+ if (!GetFrame())
+ return false;
+
+ // Normally, scripts are not allowed in sandboxed contexts that disallow them.
+ // However, there is an exception for cases when the script should bypass the
+ // main world's CSP (such as for privileged isolated worlds). See
+ // https://crbug.com/811528.
+ if (IsSandboxed(network::mojom::blink::WebSandboxFlags::kScripts) &&
+ !ContentSecurityPolicy::ShouldBypassMainWorld(this)) {
+ // FIXME: This message should be moved off the console once a solution to
+ // https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
+ if (reason == kAboutToExecuteScript) {
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kSecurity,
+ mojom::blink::ConsoleMessageLevel::kError,
+ "Blocked script execution in '" + Url().ElidedString() +
+ "' because the document's frame is sandboxed and the "
+ "'allow-scripts' permission is not set."));
+ }
+ return false;
+ }
+
+ WebContentSettingsClient* settings_client =
+ GetFrame()->GetContentSettingsClient();
+ bool script_enabled = GetFrame()->GetSettings()->GetScriptEnabled();
+ if (settings_client)
+ script_enabled = settings_client->AllowScript(script_enabled);
+ if (!script_enabled && reason == kAboutToExecuteScript && settings_client)
+ settings_client->DidNotAllowScript();
+ return script_enabled;
}
void LocalDOMWindow::ExceptionThrown(ErrorEvent* event) {
MainThreadDebugger::Instance()->ExceptionThrown(this, event);
}
+// https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
String LocalDOMWindow::OutgoingReferrer() const {
- return document()->OutgoingReferrer();
+ // Step 3.1: "If environment's global object is a Window object, then"
+ // Step 3.1.1: "Let document be the associated Document of environment's
+ // global object."
+
+ // Step 3.1.2: "If document's origin is an opaque origin, return no referrer."
+ if (GetSecurityOrigin()->IsOpaque())
+ return String();
+
+ // Step 3.1.3: "While document is an iframe srcdoc document, let document be
+ // document's browsing context's browsing context container's node document."
+ LocalFrame* referrer_frame = GetFrame();
+ while (referrer_frame->GetDocument()->IsSrcdocDocument()) {
+ // Srcdoc documents must be local within the containing frame.
+ referrer_frame = To<LocalFrame>(referrer_frame->Tree().Parent());
+ // Srcdoc documents cannot be top-level documents, by definition,
+ // because they need to be contained in iframes with the srcdoc.
+ DCHECK(referrer_frame);
+ }
+ // Step: 3.1.4: "Let referrerSource be document's URL."
+ return referrer_frame->GetDocument()->Url().StrippedForUseAsReferrer();
}
network::mojom::ReferrerPolicy LocalDOMWindow::GetReferrerPolicy() const {
@@ -551,27 +653,67 @@ void LocalDOMWindow::CountUse(mojom::WebFeature feature) {
}
void LocalDOMWindow::CountDeprecation(mojom::WebFeature feature) {
- document()->CountDeprecation(feature);
+ // TODO(yoichio): We should remove these counters when v0 APIs are removed.
+ // crbug.com/946875.
+ if (feature == WebFeature::kHTMLImports &&
+ GetOriginTrialContext()->IsFeatureEnabled(
+ OriginTrialFeature::kHTMLImports)) {
+ CountUse(WebFeature::kHTMLImportsOnReverseOriginTrials);
+ } else if (feature == WebFeature::kElementCreateShadowRoot &&
+ GetOriginTrialContext()->IsFeatureEnabled(
+ OriginTrialFeature::kShadowDOMV0)) {
+ CountUse(WebFeature::kElementCreateShadowRootOnReverseOriginTrials);
+ } else if (feature == WebFeature::kDocumentRegisterElement &&
+ GetOriginTrialContext()->IsFeatureEnabled(
+ OriginTrialFeature::kCustomElementsV0)) {
+ CountUse(WebFeature::kDocumentRegisterElementOnReverseOriginTrials);
+ }
+
+ if (!GetFrame())
+ return;
+
+ // Don't count usage of WebComponentsV0 for chrome:// URLs, but still report
+ // the deprecation messages.
+ auto* loader = GetFrame()->Loader().GetDocumentLoader();
+ if (Url().ProtocolIs("chrome") &&
+ (feature == WebFeature::kHTMLImports ||
+ feature == WebFeature::kElementCreateShadowRoot ||
+ feature == WebFeature::kDocumentRegisterElement)) {
+ Deprecation::DeprecationWarningOnly(loader, feature);
+ } else {
+ Deprecation::CountDeprecation(loader, feature);
+ }
+}
+
+void LocalDOMWindow::CountUseOnlyInCrossOriginIframe(
+ mojom::blink::WebFeature feature) {
+ if (GetFrame() && GetFrame()->IsCrossOriginToMainFrame())
+ CountUse(feature);
}
Document* LocalDOMWindow::InstallNewDocument(const DocumentInit& init) {
DCHECK_EQ(init.GetFrame(), GetFrame());
+ DCHECK(!document_ || !document_->IsActive());
- ClearDocument();
+ bool is_first_document = !document_;
- document_ = DOMImplementation::createDocument(init);
+ // Explicitly null document_ here so that it is always null when Document's
+ // constructor is running. This ensures that no code running from the
+ // constructor obeserves a situation where dom_window_->document() is a
+ // a different Document.
+ document_ = nullptr;
+ document_ = init.CreateDocument();
document_->Initialize();
- // The CSP delegate doesn't have access to all of the state it needs until
- // document_ is set.
- if (GetSecurityContext().BindCSPImmediately()) {
- GetSecurityContext().GetContentSecurityPolicy()->BindToDelegate(
- GetContentSecurityPolicyDelegate());
- }
-
if (!GetFrame())
return document_;
+ if (is_first_document) {
+ GetAgent()->AttachContext(this);
+ if (auto* agent_metrics = GetFrame()->GetPage()->GetAgentMetricsCollector())
+ agent_metrics->DidAttachWindow(*this);
+ }
+
GetFrame()->GetScriptController().UpdateDocument();
document_->GetViewportData().UpdateViewportDescription();
if (FrameScheduler* frame_scheduler = GetFrame()->GetFrameScheduler()) {
@@ -720,12 +862,18 @@ MediaQueryList* LocalDOMWindow::matchMedia(const String& media) {
}
void LocalDOMWindow::FrameDestroyed() {
+ // Some unit tests manually call FrameDestroyed(). Don't run it a second time.
+ if (!GetFrame())
+ return;
// In the Reset() case, this Document::Shutdown() early-exits because it was
// already called earlier in the commit process.
// TODO(japhet): Can we merge this function and Reset()? At least, this
// function should be renamed to Detach(), since in the Reset() case the frame
// is not being destroyed.
document()->Shutdown();
+ GetAgent()->DetachContext(this);
+ if (auto* agent_metrics = GetFrame()->GetPage()->GetAgentMetricsCollector())
+ agent_metrics->DidDetachWindow(*this);
NotifyContextDestroyed();
RemoveAllEventListeners();
DisconnectFromFrame();
@@ -855,13 +1003,13 @@ FrameConsole* LocalDOMWindow::GetFrameConsole() const {
return &GetFrame()->Console();
}
-ApplicationCache* LocalDOMWindow::applicationCache() const {
+ApplicationCache* LocalDOMWindow::applicationCache() {
DCHECK(RuntimeEnabledFeatures::AppCacheEnabled(this));
if (!IsCurrentlyDisplayedInFrame())
return nullptr;
- if (!isSecureContext()) {
+ if (!IsSecureContext()) {
Deprecation::CountDeprecation(
- document(), WebFeature::kApplicationCacheAPIInsecureOrigin);
+ this, WebFeature::kApplicationCacheAPIInsecureOrigin);
}
if (!application_cache_)
application_cache_ = MakeGarbageCollected<ApplicationCache>(GetFrame());
@@ -877,18 +1025,17 @@ Navigator* LocalDOMWindow::navigator() const {
void LocalDOMWindow::SchedulePostMessage(
MessageEvent* event,
scoped_refptr<const SecurityOrigin> target,
- Document* source) {
+ LocalDOMWindow* source) {
// Allowing unbounded amounts of messages to build up for a suspended context
// is problematic; consider imposing a limit or other restriction if this
// surfaces often as a problem (see crbug.com/587012).
- std::unique_ptr<SourceLocation> location =
- SourceLocation::Capture(source->GetExecutionContext());
- document_->GetTaskRunner(TaskType::kPostedMessage)
- ->PostTask(FROM_HERE,
- WTF::Bind(&LocalDOMWindow::DispatchPostMessage,
- WrapPersistent(this), WrapPersistent(event),
- std::move(target), std::move(location),
- source->GetExecutionContext()->GetAgentClusterID()));
+ std::unique_ptr<SourceLocation> location = SourceLocation::Capture(source);
+ GetTaskRunner(TaskType::kPostedMessage)
+ ->PostTask(
+ FROM_HERE,
+ WTF::Bind(&LocalDOMWindow::DispatchPostMessage, WrapPersistent(this),
+ WrapPersistent(event), std::move(target),
+ std::move(location), source->GetAgent()->cluster_id()));
probe::AsyncTaskScheduled(this, "postMessage", event->async_task_id());
}
@@ -936,7 +1083,7 @@ void LocalDOMWindow::DispatchMessageEventWithOriginCheck(
KURL sender(event->origin());
if (!document()->GetContentSecurityPolicy()->AllowConnectToSource(
- sender, RedirectStatus::kNoRedirect,
+ sender, sender, RedirectStatus::kNoRedirect,
ReportingDisposition::kSuppressReporting)) {
UseCounter::Count(
document(), WebFeature::kPostMessageIncomingWouldBeBlockedByConnectSrc);
@@ -992,11 +1139,13 @@ Element* LocalDOMWindow::frameElement() const {
void LocalDOMWindow::blur() {}
void LocalDOMWindow::print(ScriptState* script_state) {
- // Don't print after detach begins, even if GetFrame() hasn't been nulled out yet.
- // TODO(crbug.com/1063150): When a frame is being detached for a swap, the document has already
- // been Shutdown() and is no longer in a consistent state, even though GetFrame() is not yet
- // nulled out. This is an ordering violation, and checking whether we're in the middle of detach
- // here is probably not the right long-term fix.
+ // Don't print after detach begins, even if GetFrame() hasn't been nulled out
+ // yet.
+ // TODO(crbug.com/1063150): When a frame is being detached for a swap, the
+ // document has already been Shutdown() and is no longer in a consistent
+ // state, even though GetFrame() is not yet nulled out. This is an ordering
+ // violation, and checking whether we're in the middle of detach here is
+ // probably not the right long-term fix.
if (!GetFrame() || !GetFrame()->IsAttached())
return;
@@ -1011,10 +1160,9 @@ void LocalDOMWindow::print(ScriptState* script_state) {
}
if (!GetFrame()->IsMainFrame() && !GetFrame()->IsCrossOriginToMainFrame()) {
- document()->CountUse(WebFeature::kSameOriginIframeWindowPrint);
+ CountUse(WebFeature::kSameOriginIframeWindowPrint);
}
- document()->CountUseOnlyInCrossOriginIframe(
- WebFeature::kCrossOriginWindowPrint);
+ CountUseOnlyInCrossOriginIframe(WebFeature::kCrossOriginWindowPrint);
should_print_when_finished_loading_ = false;
GetFrame()->GetPage()->GetChromeClient().Print(GetFrame());
@@ -1023,7 +1171,7 @@ void LocalDOMWindow::print(ScriptState* script_state) {
void LocalDOMWindow::stop() {
if (!GetFrame())
return;
- GetFrame()->Loader().StopAllLoaders();
+ GetFrame()->Loader().StopAllLoaders(/*abort_client=*/true);
}
void LocalDOMWindow::alert(ScriptState* script_state, const String& message) {
@@ -1052,10 +1200,9 @@ void LocalDOMWindow::alert(ScriptState* script_state, const String& message) {
return;
if (!GetFrame()->IsMainFrame() && !GetFrame()->IsCrossOriginToMainFrame()) {
- document()->CountUse(WebFeature::kSameOriginIframeWindowAlert);
+ CountUse(WebFeature::kSameOriginIframeWindowAlert);
}
- document()->CountUseOnlyInCrossOriginIframe(
- WebFeature::kCrossOriginWindowAlert);
+ CountUseOnlyInCrossOriginIframe(WebFeature::kCrossOriginWindowAlert);
page->GetChromeClient().OpenJavaScriptAlert(GetFrame(), message);
}
@@ -1086,10 +1233,9 @@ bool LocalDOMWindow::confirm(ScriptState* script_state, const String& message) {
return false;
if (!GetFrame()->IsMainFrame() && !GetFrame()->IsCrossOriginToMainFrame()) {
- document()->CountUse(WebFeature::kSameOriginIframeWindowConfirm);
+ CountUse(WebFeature::kSameOriginIframeWindowConfirm);
}
- document()->CountUseOnlyInCrossOriginIframe(
- WebFeature::kCrossOriginWindowConfirm);
+ CountUseOnlyInCrossOriginIframe(WebFeature::kCrossOriginWindowConfirm);
return page->GetChromeClient().OpenJavaScriptConfirm(GetFrame(), message);
}
@@ -1127,10 +1273,9 @@ String LocalDOMWindow::prompt(ScriptState* script_state,
return return_value;
if (!GetFrame()->IsMainFrame() && !GetFrame()->IsCrossOriginToMainFrame()) {
- document()->CountUse(WebFeature::kSameOriginIframeWindowPrompt);
+ CountUse(WebFeature::kSameOriginIframeWindowPrompt);
}
- document()->CountUseOnlyInCrossOriginIframe(
- WebFeature::kCrossOriginWindowPrompt);
+ CountUseOnlyInCrossOriginIframe(WebFeature::kCrossOriginWindowPrompt);
return String();
}
@@ -1311,6 +1456,40 @@ double LocalDOMWindow::scrollY() const {
GetFrame()->PageZoomFactor());
}
+HeapVector<Member<DOMRect>> LocalDOMWindow::getWindowSegments() const {
+ HeapVector<Member<DOMRect>> window_segments;
+ LocalFrame* frame = GetFrame();
+ if (!frame)
+ return window_segments;
+
+ Page* page = frame->GetPage();
+ if (!page)
+ return window_segments;
+
+ WebVector<WebRect> web_segments =
+ frame->GetWidgetForLocalRoot()->WindowSegments();
+
+ // The rect passed to us from content is in DIP, relative to the main
+ // frame/widget. This doesn't take the page's zoom factor into account so we
+ // must scale by the inverse of the page zoom in order to get correct client
+ // coordinates.
+ // Note that when use-zoom-for-dsf is enabled, WindowToViewportScalar will
+ // be the device scale factor, and PageZoomFactor will be the combination
+ // of the device scale factor and the zoom percent of the page.
+ ChromeClient& chrome_client = page->GetChromeClient();
+ const float window_to_viewport_factor =
+ chrome_client.WindowToViewportScalar(frame, 1.0f);
+ const float page_zoom_factor = frame->PageZoomFactor();
+ const float scale_factor = window_to_viewport_factor / page_zoom_factor;
+ for (auto const& web_segment : web_segments) {
+ blink::FloatQuad quad = blink::FloatQuad(web_segment);
+ quad.Scale(scale_factor, scale_factor);
+ window_segments.push_back(DOMRect::FromFloatRect(quad.BoundingBox()));
+ }
+
+ return window_segments;
+}
+
DOMVisualViewport* LocalDOMWindow::visualViewport() {
return visualViewport_;
}
@@ -1587,22 +1766,6 @@ void LocalDOMWindow::cancelAnimationFrame(int id) {
document->CancelAnimationFrame(id);
}
-int LocalDOMWindow::requestPostAnimationFrame(
- V8FrameRequestCallback* callback) {
- if (Document* doc = document()) {
- FrameRequestCallbackCollection::V8FrameCallback* frame_callback =
- MakeGarbageCollected<FrameRequestCallbackCollection::V8FrameCallback>(
- callback);
- return doc->RequestPostAnimationFrame(frame_callback);
- }
- return 0;
-}
-
-void LocalDOMWindow::cancelPostAnimationFrame(int id) {
- if (Document* doc = this->document())
- doc->CancelPostAnimationFrame(id);
-}
-
void LocalDOMWindow::queueMicrotask(V8VoidFunction* callback) {
Microtask::EnqueueMicrotask(
WTF::Bind(&V8VoidFunction::InvokeAndReportException,
@@ -1617,13 +1780,20 @@ void LocalDOMWindow::SetOriginPolicyIds(const Vector<String>& ids) {
origin_policy_ids_ = ids;
}
+bool LocalDOMWindow::originIsolationRestricted() const {
+ return origin_isolation_restricted_;
+}
+
+void LocalDOMWindow::SetOriginIsolationRestricted(bool value) {
+ origin_isolation_restricted_ = value;
+}
+
int LocalDOMWindow::requestIdleCallback(V8IdleRequestCallback* callback,
const IdleRequestOptions* options) {
- if (Document* document = this->document()) {
- return document->RequestIdleCallback(
- ScriptedIdleTaskController::V8IdleTask::Create(callback), options);
- }
- return 0;
+ if (!GetFrame())
+ return 0;
+ return document_->RequestIdleCallback(
+ ScriptedIdleTaskController::V8IdleTask::Create(callback), options);
}
void LocalDOMWindow::cancelIdleCallback(int id) {
@@ -1660,10 +1830,11 @@ External* LocalDOMWindow::external() {
}
bool LocalDOMWindow::isSecureContext() const {
- if (!GetFrame())
- return false;
+ return GetFrame() && IsSecureContext();
+}
- return document()->IsSecureContext();
+void LocalDOMWindow::ClearIsolatedWorldCSPForTesting(int32_t world_id) {
+ isolated_world_csp_map_->erase(world_id);
}
void LocalDOMWindow::AddedEventListener(
@@ -1719,22 +1890,6 @@ void LocalDOMWindow::RemovedEventListener(
}
}
-void LocalDOMWindow::WarnUnusedPreloads(TimerBase* base) {
- if (!document() || !document()->Fetcher())
- return;
- Vector<KURL> urls = document()->Fetcher()->GetUrlsOfUnusedPreloads();
- for (const KURL& url : urls) {
- String message =
- "The resource " + url.GetString() + " was preloaded using link " +
- "preload but not used within a few seconds from the window's load " +
- "event. Please make sure it has an appropriate `as` value and it is " +
- "preloaded intentionally.";
- GetFrameConsole()->AddMessage(MakeGarbageCollected<ConsoleMessage>(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
- }
-}
-
void LocalDOMWindow::DispatchLoadEvent() {
Event& load_event = *Event::Create(event_type_names::kLoad);
DocumentLoader* document_loader =
@@ -1745,13 +1900,6 @@ void LocalDOMWindow::DispatchLoadEvent() {
timing.MarkLoadEventStart();
DispatchEvent(load_event, document());
timing.MarkLoadEventEnd();
- // If fetcher->countPreloads() is not empty here, it's full of link
- // preloads, as speculatove preloads were cleared at DCL.
- if (GetFrame() &&
- document_loader == GetFrame()->Loader().GetDocumentLoader() &&
- document()->Fetcher()->CountPreloads()) {
- unused_preloads_timer_.StartOneShot(kUnusedPreloadTimeout, FROM_HERE);
- }
} else {
DispatchEvent(load_event, document());
}
@@ -1851,23 +1999,20 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
return nullptr;
if (!incumbent_window->GetFrame())
return nullptr;
- Document* active_document = incumbent_window->document();
- if (!active_document)
- return nullptr;
LocalFrame* entered_window_frame = entered_window->GetFrame();
if (!entered_window_frame)
return nullptr;
- UseCounter::Count(*active_document, WebFeature::kDOMWindowOpen);
+ UseCounter::Count(*incumbent_window, WebFeature::kDOMWindowOpen);
if (!features.IsEmpty())
- UseCounter::Count(*active_document, WebFeature::kDOMWindowOpenFeatures);
+ UseCounter::Count(*incumbent_window, WebFeature::kDOMWindowOpenFeatures);
KURL completed_url =
url_string.IsEmpty()
? KURL(g_empty_string)
: entered_window_frame->GetDocument()->CompleteURL(url_string);
if (!completed_url.IsEmpty() && !completed_url.IsValid()) {
- UseCounter::Count(active_document, WebFeature::kWindowOpenWithInvalidURL);
+ UseCounter::Count(incumbent_window, WebFeature::kWindowOpenWithInvalidURL);
exception_state.ThrowDOMException(
DOMExceptionCode::kSyntaxError,
"Unable to open a window with invalid URL '" +
@@ -1877,7 +2022,7 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
WebWindowFeatures window_features = GetWindowFeaturesFromString(features);
- FrameLoadRequest frame_request(active_document,
+ FrameLoadRequest frame_request(incumbent_window->document(),
ResourceRequest(completed_url));
frame_request.SetFeaturesForWindowOpen(window_features);
@@ -1888,9 +2033,9 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
// for generating an embedder-initiated navigation's referrer, so we need to
// ensure the proper referrer is set now.
Referrer referrer = SecurityPolicy::GenerateReferrer(
- active_document->GetReferrerPolicy(), completed_url,
+ incumbent_window->GetReferrerPolicy(), completed_url,
window_features.noreferrer ? Referrer::NoReferrer()
- : active_document->OutgoingReferrer());
+ : incumbent_window->OutgoingReferrer());
frame_request.GetResourceRequest().SetReferrerString(referrer.referrer);
frame_request.GetResourceRequest().SetReferrerPolicy(
referrer.referrer_policy);
@@ -1908,7 +2053,7 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
if (window_features.x_set || window_features.y_set) {
// This runs after FindOrCreateFrameForNavigation() so blocked popups are
// not counted.
- UseCounter::Count(*active_document,
+ UseCounter::Count(*incumbent_window,
WebFeature::kDOMWindowOpenPositioningFeatures);
}
@@ -1929,11 +2074,11 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
if (window_features.noopener)
return nullptr;
if (!result.new_window)
- result.frame->Client()->SetOpener(GetFrame());
+ result.frame->SetOpener(GetFrame());
return result.frame->DomWindow();
}
-void LocalDOMWindow::Trace(Visitor* visitor) {
+void LocalDOMWindow::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(screen_);
visitor->Trace(history_);
@@ -1951,13 +2096,25 @@ void LocalDOMWindow::Trace(Visitor* visitor) {
visitor->Trace(application_cache_);
visitor->Trace(visualViewport_);
visitor->Trace(event_listener_observers_);
+ visitor->Trace(current_event_);
visitor->Trace(trusted_types_);
visitor->Trace(input_method_controller_);
visitor->Trace(spell_checker_);
visitor->Trace(text_suggestion_controller_);
+ visitor->Trace(isolated_world_csp_map_);
DOMWindow::Trace(visitor);
ExecutionContext::Trace(visitor);
Supplementable<LocalDOMWindow>::Trace(visitor);
}
+ukm::UkmRecorder* LocalDOMWindow::UkmRecorder() {
+ DCHECK(document_);
+ return document_->UkmRecorder();
+}
+
+ukm::SourceId LocalDOMWindow::UkmSourceID() const {
+ DCHECK(document_);
+ return document_->UkmSourceID();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/local_dom_window.h b/chromium/third_party/blink/renderer/core/frame/local_dom_window.h
index bdc61595261..fe3649e40ae 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_dom_window.h
+++ b/chromium/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -27,12 +27,16 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_LOCAL_DOM_WINDOW_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_LOCAL_DOM_WINDOW_H_
+#include "services/metrics/public/cpp/ukm_recorder.h"
+#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/events/page_transition_event.h"
#include "third_party/blink/renderer/core/frame/dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/geometry/dom_rect.h"
#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/supplementable.h"
@@ -74,6 +78,7 @@ class TrustedTypePolicyFactory;
class V8FrameRequestCallback;
class V8IdleRequestCallback;
class V8VoidFunction;
+class WindowAgent;
enum PageTransitionEventPersistence {
kPageTransitionEventNotPersisted = 0,
@@ -99,16 +104,16 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
static LocalDOMWindow* From(const ScriptState*);
- explicit LocalDOMWindow(LocalFrame&);
+ explicit LocalDOMWindow(LocalFrame&, WindowAgent*);
~LocalDOMWindow() override;
LocalFrame* GetFrame() const { return To<LocalFrame>(DOMWindow::GetFrame()); }
- void Trace(Visitor*) override;
+ void ResetWindowAgent(WindowAgent*);
+
+ void Trace(Visitor*) const override;
// ExecutionContext overrides:
- // TODO(crbug.com/1029822): Most of these just call in to Document, but should
- // move entirely here.
bool IsDocument() const final { return true; }
bool IsContextThread() const final;
bool ShouldInstallV8Extensions() const final;
@@ -155,6 +160,10 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
void CountUse(mojom::WebFeature feature) final;
void CountDeprecation(mojom::WebFeature feature) final;
+ // Count |feature| only when this window is associated with a cross-origin
+ // iframe.
+ void CountUseOnlyInCrossOriginIframe(mojom::blink::WebFeature feature);
+
Document* InstallNewDocument(const DocumentInit&);
// EventTarget overrides:
@@ -191,6 +200,8 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
DOMVisualViewport* visualViewport();
+ HeapVector<Member<DOMRect>> getWindowSegments() const;
+
const AtomicString& name() const;
void setName(const AtomicString&);
@@ -209,7 +220,7 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
// WebKit extensions
double devicePixelRatio() const;
- ApplicationCache* applicationCache() const;
+ ApplicationCache* applicationCache();
// This is the interface orientation in degrees. Some examples are:
// 0 is straight up; -90 is when the device is rotated 90 clockwise;
@@ -266,8 +277,6 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
int requestAnimationFrame(V8FrameRequestCallback*);
int webkitRequestAnimationFrame(V8FrameRequestCallback*);
void cancelAnimationFrame(int id);
- int requestPostAnimationFrame(V8FrameRequestCallback*);
- void cancelPostAnimationFrame(int id);
// https://html.spec.whatwg.org/C/#windoworworkerglobalscope-mixin
void queueMicrotask(V8VoidFunction*);
@@ -276,6 +285,10 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
const Vector<String>& originPolicyIds() const;
void SetOriginPolicyIds(const Vector<String>&);
+ // https://github.com/whatwg/html/pull/5545
+ bool originIsolationRestricted() const;
+ void SetOriginIsolationRestricted(bool);
+
// Idle callback extensions
int requestIdleCallback(V8IdleRequestCallback*, const IdleRequestOptions*);
void cancelIdleCallback(int id);
@@ -351,6 +364,11 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
void AcceptLanguagesChanged();
+ // https://dom.spec.whatwg.org/#dom-window-event
+ ScriptValue event(ScriptState*) const;
+ Event* CurrentEvent() const;
+ void SetCurrentEvent(Event*);
+
TrustedTypePolicyFactory* trustedTypes() const;
// Returns true if this window is cross-site to the main frame. Defaults to
@@ -373,6 +391,12 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
}
SpellChecker& GetSpellChecker() const { return *spell_checker_; }
+ void ClearIsolatedWorldCSPForTesting(int32_t world_id);
+
+ // These delegate to the document_.
+ ukm::UkmRecorder* UkmRecorder();
+ ukm::SourceId UkmSourceID() const;
+
protected:
// EventTarget overrides.
void AddedEventListener(const AtomicString& event_type,
@@ -383,26 +407,23 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
// Protected DOMWindow overrides.
void SchedulePostMessage(MessageEvent*,
scoped_refptr<const SecurityOrigin> target,
- Document* source) override;
+ LocalDOMWindow* source) override;
private:
// Intentionally private to prevent redundant checks when the type is
// already LocalDOMWindow.
bool IsLocalDOMWindow() const override { return true; }
bool IsRemoteDOMWindow() const override { return false; }
- void WarnUnusedPreloads(TimerBase*);
void Dispose();
void DispatchLoadEvent();
- void ClearDocument();
// Return the viewport size including scrollbars.
IntSize GetViewportSize() const;
Member<Document> document_;
Member<DOMVisualViewport> visualViewport_;
- TaskRunnerTimer<LocalDOMWindow> unused_preloads_timer_;
bool should_print_when_finished_loading_;
bool has_load_event_fired_ = false;
@@ -430,12 +451,18 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
Vector<String> origin_policy_ids_;
+ bool origin_isolation_restricted_ = false;
+
mutable Member<ApplicationCache> application_cache_;
scoped_refptr<SerializedScriptValue> pending_state_object_;
HeapHashSet<WeakMember<EventListenerObserver>> event_listener_observers_;
+ // https://dom.spec.whatwg.org/#window-current-event
+ // We represent the "undefined" value as nullptr.
+ Member<Event> current_event_;
+
mutable Member<TrustedTypePolicyFactory> trusted_types_;
// A dummy scheduler to return when the window is detached.
@@ -451,6 +478,10 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
Member<SpellChecker> spell_checker_;
Member<TextSuggestionController> text_suggestion_controller_;
+ // Map from isolated world IDs to their ContentSecurityPolicy instances.
+ Member<HeapHashMap<int, Member<ContentSecurityPolicy>>>
+ isolated_world_csp_map_;
+
// Tracks which features have already been potentially violated in this
// document. This helps to count them only once per page load.
// We don't use std::bitset to avoid to include feature_policy.mojom-blink.h.
diff --git a/chromium/third_party/blink/renderer/core/frame/local_dom_window_test.cc b/chromium/third_party/blink/renderer/core/frame/local_dom_window_test.cc
new file mode 100644
index 00000000000..b31dd861763
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/local_dom_window_test.cc
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2014, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+
+#include "base/strings/stringprintf.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h"
+#include "third_party/blink/renderer/core/execution_context/agent.h"
+#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/scheduler/public/event_loop.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+
+namespace blink {
+
+using network::mojom::ContentSecurityPolicySource;
+using network::mojom::ContentSecurityPolicyType;
+
+class LocalDOMWindowTest : public PageTestBase {};
+
+TEST_F(LocalDOMWindowTest, AttachExecutionContext) {
+ auto* scheduler = GetFrame().GetFrameScheduler();
+ auto* window = GetFrame().DomWindow();
+ EXPECT_TRUE(
+ window->GetAgent()->event_loop()->IsSchedulerAttachedForTest(scheduler));
+ window->FrameDestroyed();
+ EXPECT_FALSE(
+ window->GetAgent()->event_loop()->IsSchedulerAttachedForTest(scheduler));
+}
+
+TEST_F(LocalDOMWindowTest, referrerPolicyParsing) {
+ LocalDOMWindow* window = GetFrame().DomWindow();
+ EXPECT_EQ(network::mojom::ReferrerPolicy::kDefault,
+ window->GetReferrerPolicy());
+
+ struct TestCase {
+ const char* policy;
+ network::mojom::ReferrerPolicy expected;
+ bool is_legacy;
+ } tests[] = {
+ {"", network::mojom::ReferrerPolicy::kDefault, false},
+ // Test that invalid policy values are ignored.
+ {"not-a-real-policy", network::mojom::ReferrerPolicy::kDefault, false},
+ {"not-a-real-policy,also-not-a-real-policy",
+ network::mojom::ReferrerPolicy::kDefault, false},
+ {"not-a-real-policy,unsafe-url", network::mojom::ReferrerPolicy::kAlways,
+ false},
+ {"unsafe-url,not-a-real-policy", network::mojom::ReferrerPolicy::kAlways,
+ false},
+ // Test parsing each of the policy values.
+ {"always", network::mojom::ReferrerPolicy::kAlways, true},
+ {"default", network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade,
+ true},
+ {"never", network::mojom::ReferrerPolicy::kNever, true},
+ {"no-referrer", network::mojom::ReferrerPolicy::kNever, false},
+ {"default", network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade,
+ true},
+ {"no-referrer-when-downgrade",
+ network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, false},
+ {"origin", network::mojom::ReferrerPolicy::kOrigin, false},
+ {"origin-when-crossorigin",
+ network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, true},
+ {"origin-when-cross-origin",
+ network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, false},
+ {"same-origin", network::mojom::ReferrerPolicy::kSameOrigin, false},
+ {"strict-origin", network::mojom::ReferrerPolicy::kStrictOrigin, false},
+ {"strict-origin-when-cross-origin",
+ network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin, false},
+ {"unsafe-url", network::mojom::ReferrerPolicy::kAlways},
+ };
+
+ for (auto test : tests) {
+ window->SetReferrerPolicy(network::mojom::ReferrerPolicy::kDefault);
+ if (test.is_legacy) {
+ // Legacy keyword support must be explicitly enabled for the policy to
+ // parse successfully.
+ window->ParseAndSetReferrerPolicy(test.policy);
+ EXPECT_EQ(network::mojom::ReferrerPolicy::kDefault,
+ window->GetReferrerPolicy());
+ window->ParseAndSetReferrerPolicy(test.policy, true);
+ } else {
+ window->ParseAndSetReferrerPolicy(test.policy);
+ }
+ EXPECT_EQ(test.expected, window->GetReferrerPolicy()) << test.policy;
+ }
+}
+
+TEST_F(LocalDOMWindowTest, OutgoingReferrer) {
+ NavigateTo(KURL("https://www.example.com/hoge#fuga?piyo"));
+ EXPECT_EQ("https://www.example.com/hoge",
+ GetFrame().DomWindow()->OutgoingReferrer());
+}
+
+TEST_F(LocalDOMWindowTest, OutgoingReferrerWithUniqueOrigin) {
+ NavigateTo(KURL("https://www.example.com/hoge#fuga?piyo"),
+ {{http_names::kContentSecurityPolicy, "sandbox allow-scripts"}});
+ EXPECT_TRUE(GetFrame().DomWindow()->GetSecurityOrigin()->IsOpaque());
+ EXPECT_EQ(String(), GetFrame().DomWindow()->OutgoingReferrer());
+}
+
+// Test fixture parameterized on whether the "IsolatedWorldCSP" feature is
+// enabled.
+class IsolatedWorldCSPTest : public PageTestBase,
+ public testing::WithParamInterface<bool>,
+ private ScopedIsolatedWorldCSPForTest {
+ public:
+ IsolatedWorldCSPTest() : ScopedIsolatedWorldCSPForTest(GetParam()) {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IsolatedWorldCSPTest);
+};
+
+// Tests ExecutionContext::GetContentSecurityPolicyForWorld().
+TEST_P(IsolatedWorldCSPTest, CSPForWorld) {
+ using ::testing::ElementsAre;
+
+ // Set a CSP for the main world.
+ const char* kMainWorldCSP = "connect-src https://google.com;";
+ GetFrame().DomWindow()->GetContentSecurityPolicy()->DidReceiveHeader(
+ kMainWorldCSP, ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
+
+ LocalFrame* frame = &GetFrame();
+ ScriptState* main_world_script_state = ToScriptStateForMainWorld(frame);
+ v8::Isolate* isolate = main_world_script_state->GetIsolate();
+
+ constexpr int kIsolatedWorldWithoutCSPId = 1;
+ scoped_refptr<DOMWrapperWorld> world_without_csp =
+ DOMWrapperWorld::EnsureIsolatedWorld(isolate, kIsolatedWorldWithoutCSPId);
+ ASSERT_TRUE(world_without_csp->IsIsolatedWorld());
+ ScriptState* isolated_world_without_csp_script_state =
+ ToScriptState(frame, *world_without_csp);
+
+ const char* kIsolatedWorldCSP = "script-src 'none';";
+ constexpr int kIsolatedWorldWithCSPId = 2;
+ scoped_refptr<DOMWrapperWorld> world_with_csp =
+ DOMWrapperWorld::EnsureIsolatedWorld(isolate, kIsolatedWorldWithCSPId);
+ ASSERT_TRUE(world_with_csp->IsIsolatedWorld());
+ ScriptState* isolated_world_with_csp_script_state =
+ ToScriptState(frame, *world_with_csp);
+ IsolatedWorldCSP::Get().SetContentSecurityPolicy(
+ kIsolatedWorldWithCSPId, kIsolatedWorldCSP,
+ SecurityOrigin::Create(KURL("chrome-extension://123")));
+
+ // Returns the csp headers being used for the current world.
+ auto get_csp_headers = [this]() {
+ auto* csp = GetFrame().DomWindow()->GetContentSecurityPolicyForWorld();
+ return csp->Headers();
+ };
+
+ {
+ SCOPED_TRACE("In main world.");
+ ScriptState::Scope scope(main_world_script_state);
+ EXPECT_THAT(get_csp_headers(),
+ ElementsAre(CSPHeaderAndType(
+ {kMainWorldCSP, ContentSecurityPolicyType::kEnforce})));
+ }
+
+ {
+ SCOPED_TRACE("In isolated world without csp.");
+ ScriptState::Scope scope(isolated_world_without_csp_script_state);
+
+ // If we are in an isolated world with no CSP defined, we use the main world
+ // CSP.
+ EXPECT_THAT(get_csp_headers(),
+ ElementsAre(CSPHeaderAndType(
+ {kMainWorldCSP, ContentSecurityPolicyType::kEnforce})));
+ }
+
+ {
+ bool is_isolated_world_csp_enabled = GetParam();
+ SCOPED_TRACE(base::StringPrintf(
+ "In isolated world with csp and 'IsolatedWorldCSP' %s",
+ is_isolated_world_csp_enabled ? "enabled" : "disabled"));
+ ScriptState::Scope scope(isolated_world_with_csp_script_state);
+
+ if (!is_isolated_world_csp_enabled) {
+ // With 'IsolatedWorldCSP' feature disabled, we should just bypass the
+ // main world CSP by using an empty CSP.
+ EXPECT_TRUE(get_csp_headers().IsEmpty());
+ } else {
+ // With 'IsolatedWorldCSP' feature enabled, we use the isolated world's
+ // CSP if it specified one.
+ EXPECT_THAT(
+ get_csp_headers(),
+ ElementsAre(CSPHeaderAndType(
+ {kIsolatedWorldCSP, ContentSecurityPolicyType::kEnforce})));
+ }
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(All,
+ IsolatedWorldCSPTest,
+ testing::Values(true, false));
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame.cc b/chromium/third_party/blink/renderer/core/frame/local_frame.cc
index 923913ab9dd..6032e38bfd6 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame.cc
@@ -35,6 +35,7 @@
#include <utility>
#include "base/metrics/histogram_functions.h"
+#include "base/unguessable_token.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "services/data_decoder/public/mojom/resource_snapshot_for_web_bundle.mojom-blink.h"
@@ -44,10 +45,13 @@
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/common/input/web_input_event_attribution.h"
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom-blink.h"
+#include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h"
#include "third_party/blink/public/mojom/favicon/favicon_url.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/blocked_navigation_types.mojom-blink.h"
+#include "third_party/blink/public/mojom/frame/frame.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/media_player_action.mojom-blink.h"
@@ -60,7 +64,9 @@
#include "third_party/blink/public/platform/web_float_rect.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url_request.h"
+#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/web_content_capture_client.h"
+#include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_plugin.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
@@ -73,6 +79,7 @@
#include "third_party/blink/renderer/core/dom/document_init.h"
#include "third_party/blink/renderer/core/dom/document_parser.h"
#include "third_party/blink/renderer/core/dom/document_type.h"
+#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/ignore_opens_during_unload_count_incrementer.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
@@ -83,6 +90,7 @@
#include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h"
#include "third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.h"
#include "third_party/blink/renderer/core/editing/surrounding_text.h"
+#include "third_party/blink/renderer/core/editing/writing_direction.h"
#include "third_party/blink/renderer/core/execution_context/window_agent.h"
#include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
#include "third_party/blink/renderer/core/fileapi/public_url_manager.h"
@@ -105,8 +113,10 @@
#include "third_party/blink/renderer/core/frame/report.h"
#include "third_party/blink/renderer/core/frame/reporting_context.h"
#include "third_party/blink/renderer/core/frame/root_frame_viewport.h"
+#include "third_party/blink/renderer/core/frame/savable_resources.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/user_activation.h"
+#include "third_party/blink/renderer/core/frame/virtual_keyboard_overlay_changed_observer.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
@@ -117,6 +127,7 @@
#include "third_party/blink/renderer/core/html/plugin_document.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/core/inspector/inspector_issue_reporter.h"
#include "third_party/blink/renderer/core/inspector/inspector_issue_storage.h"
#include "third_party/blink/renderer/core/inspector/inspector_task_runner.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
@@ -132,8 +143,10 @@
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/drag_controller.h"
#include "third_party/blink/renderer/core/page/focus_controller.h"
+#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/plugin_data.h"
#include "third_party/blink/renderer/core/page/plugin_script_forbidden_scope.h"
+#include "third_party/blink/renderer/core/page/pointer_lock_controller.h"
#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
#include "third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.h"
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
@@ -162,6 +175,7 @@
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "ui/gfx/geometry/point.h"
#if defined(OS_MACOSX)
@@ -173,6 +187,15 @@ namespace blink {
namespace {
+// Maintain a global (statically-allocated) hash map indexed by the the result
+// of hashing the |frame_token| passed on creation of a LocalFrame object.
+using LocalFramesByTokenMap = HeapHashMap<uint64_t, WeakMember<LocalFrame>>;
+static LocalFramesByTokenMap& GetLocalFramesMap() {
+ DEFINE_STATIC_LOCAL(Persistent<LocalFramesByTokenMap>, map,
+ (MakeGarbageCollected<LocalFramesByTokenMap>()));
+ return *map;
+}
+
// Maximum number of burst download requests allowed.
const int kBurstDownloadLimit = 10;
@@ -196,15 +219,12 @@ uint32_t GetCurrentCursorPositionInFrame(LocalFrame* local_frame) {
// Convert a data url to a message pipe handle that corresponds to a remote
// blob, so that it can be passed across processes.
-mojo::ScopedMessagePipeHandle DataURLToMessagePipeHandle(
- const String& data_url) {
+mojo::PendingRemote<mojom::blink::Blob> DataURLToBlob(const String& data_url) {
auto blob_data = std::make_unique<BlobData>();
blob_data->AppendBytes(data_url.Utf8().data(), data_url.length());
scoped_refptr<BlobDataHandle> blob_data_handle =
BlobDataHandle::Create(std::move(blob_data), data_url.length());
- mojo::PendingRemote<mojom::blink::Blob> data_url_blob =
- blob_data_handle->CloneBlobRemote();
- return data_url_blob.PassPipe();
+ return blob_data_handle->CloneBlobRemote();
}
HitTestResult HitTestResultForRootFramePos(
@@ -297,11 +317,20 @@ class ResourceSnapshotForWebBundleImpl
template class CORE_TEMPLATE_EXPORT Supplement<LocalFrame>;
+// static
+LocalFrame* LocalFrame::FromFrameToken(
+ const base::UnguessableToken& frame_token) {
+ LocalFramesByTokenMap& local_frames_map = GetLocalFramesMap();
+ auto it = local_frames_map.find(base::UnguessableTokenHash()(frame_token));
+ return it == local_frames_map.end() ? nullptr : it->value.Get();
+}
+
void LocalFrame::Init() {
CoreInitializer::GetInstance().InitLocalFrame(*this);
GetRemoteNavigationAssociatedInterfaces()->GetInterface(
- local_frame_host_remote_.BindNewEndpointAndPassReceiver());
+ local_frame_host_remote_.BindNewEndpointAndPassReceiver(
+ GetTaskRunner(blink::TaskType::kInternalDefault)));
GetInterfaceRegistry()->AddAssociatedInterface(WTF::BindRepeating(
&LocalFrame::BindToReceiver, WrapWeakPersistent(this)));
@@ -371,11 +400,12 @@ LocalFrame::~LocalFrame() {
InstanceCounters::DecrementCounter(InstanceCounters::kAdSubframeCounter);
}
-void LocalFrame::Trace(Visitor* visitor) {
+void LocalFrame::Trace(Visitor* visitor) const {
visitor->Trace(ad_tracker_);
visitor->Trace(probe_sink_);
visitor->Trace(performance_monitor_);
visitor->Trace(idleness_detector_);
+ visitor->Trace(inspector_issue_reporter_);
visitor->Trace(inspector_trace_events_);
visitor->Trace(loader_);
visitor->Trace(view_);
@@ -390,6 +420,15 @@ void LocalFrame::Trace(Visitor* visitor) {
visitor->Trace(content_capture_manager_);
visitor->Trace(system_clipboard_);
visitor->Trace(raw_system_clipboard_);
+ visitor->Trace(virtual_keyboard_overlay_changed_observers_);
+ visitor->Trace(pause_handle_receivers_);
+ visitor->Trace(reporting_service_);
+#if defined(OS_MACOSX)
+ visitor->Trace(text_input_host_);
+#endif
+ visitor->Trace(local_frame_host_remote_);
+ visitor->Trace(receiver_);
+ visitor->Trace(main_frame_receiver_);
Frame::Trace(visitor);
Supplementable<LocalFrame>::Trace(visitor);
}
@@ -449,12 +488,18 @@ void LocalFrame::DetachImpl(FrameDetachType type) {
ad_tracker_->Shutdown();
}
idleness_detector_->Shutdown();
+ if (inspector_issue_reporter_)
+ probe_sink_->RemoveInspectorIssueReporter(inspector_issue_reporter_);
if (inspector_trace_events_)
probe_sink_->RemoveInspectorTraceEvents(inspector_trace_events_);
inspector_task_runner_->Dispose();
PluginScriptForbiddenScope forbid_plugin_destructor_scripting;
- loader_.StopAllLoaders();
+ // In a kSwap detach, if we have a navigation going, its moved to the frame
+ // being swapped in, so we don't need to notify the client about the
+ // navigation stopping here. That will be up to the provisional frame being
+ // swapped in, which knows the actual state of the navigation.
+ loader_.StopAllLoaders(/*abort_client=*/type == FrameDetachType::kRemove);
// Don't allow any new child frames to load in this frame: attaching a new
// child frame during or after detaching children results in an attached
// frame on a detached DOM tree, which is bad.
@@ -595,13 +640,52 @@ void LocalFrame::DidAttachDocument() {
// even after the frame reattaches.
GetEventHandler().Clear();
Selection().DidAttachDocument(document);
- if (IsCrossOriginToParentFrame() && !first_url_cross_origin_to_parent_) {
- first_url_cross_origin_to_parent_ = GetDocument()->Url().GetString();
- }
}
-base::Optional<String> LocalFrame::FirstUrlCrossOriginToParent() const {
- return first_url_cross_origin_to_parent_;
+bool LocalFrame::CanAccessEvent(
+ const WebInputEventAttribution& attribution) const {
+ switch (attribution.type()) {
+ case WebInputEventAttribution::kTargetedFrame: {
+ auto* frame_document = GetDocument();
+ if (!frame_document)
+ return false;
+
+ // FIXME(acomminos): In the presence of a pointer lock, bail out. We
+ // currently do not propagate which frame had the lock at the time of
+ // event dispatch in the compositor. See https://crbug.com/1092617.
+ if (auto* page = frame_document->GetPage()) {
+ auto& pointer_lock_controller = page->GetPointerLockController();
+ if (pointer_lock_controller.GetElement()) {
+ return false;
+ }
+ }
+
+ auto* frame_origin =
+ frame_document->GetSecurityContext().GetSecurityOrigin();
+
+ cc::ElementId element_id = attribution.target_frame_id();
+ if (!element_id)
+ return false;
+
+ DOMNodeId target_document_id =
+ DOMNodeIdFromCompositorElementId(element_id);
+ Document* target_document =
+ DynamicTo<Document>(DOMNodeIds::NodeForId(target_document_id));
+ if (!target_document || !target_document->IsActive())
+ return false;
+
+ const auto* target_document_origin = target_document->GetSecurityOrigin();
+ if (!target_document_origin)
+ return false;
+
+ return frame_origin->CanAccess(target_document_origin);
+ }
+ case WebInputEventAttribution::kFocusedFrame:
+ return GetPage() ? GetPage()->GetFocusController().FocusedFrame() == this
+ : false;
+ case WebInputEventAttribution::kUnknown:
+ return false;
+ }
}
void LocalFrame::Reload(WebFrameLoadType load_type) {
@@ -692,6 +776,34 @@ void LocalFrame::RemoveBackForwardCacheEviction() {
}
}
+void LocalFrame::SetTextDirection(base::i18n::TextDirection direction) {
+ // The Editor::SetBaseWritingDirection() function checks if we can change
+ // the text direction of the selected node and updates its DOM "dir"
+ // attribute and its CSS "direction" property.
+ // So, we just call the function as Safari does.
+ Editor& editor = GetEditor();
+ if (!editor.CanEdit())
+ return;
+
+ switch (direction) {
+ case base::i18n::TextDirection::UNKNOWN_DIRECTION:
+ editor.SetBaseWritingDirection(WritingDirection::kNatural);
+ break;
+
+ case base::i18n::TextDirection::LEFT_TO_RIGHT:
+ editor.SetBaseWritingDirection(WritingDirection::kLeftToRight);
+ break;
+
+ case base::i18n::TextDirection::RIGHT_TO_LEFT:
+ editor.SetBaseWritingDirection(WritingDirection::kRightToLeft);
+ break;
+
+ default:
+ NOTIMPLEMENTED();
+ break;
+ }
+}
+
void LocalFrame::SetIsInert(bool inert) {
is_inert_ = inert;
PropagateInertToChildFrames();
@@ -1050,9 +1162,15 @@ LocalFrame::LocalFrame(LocalFrameClient* client,
: InterfaceRegistry::GetEmptyInterfaceRegistry()),
is_save_data_enabled_(GetNetworkStateNotifier().SaveDataEnabled()),
lifecycle_state_(mojom::FrameLifecycleState::kRunning) {
+ auto frame_tracking_result = GetLocalFramesMap().insert(
+ base::UnguessableTokenHash()(frame_token), this);
+ CHECK(frame_tracking_result.stored_value) << "Inserting a duplicate item.";
if (IsLocalRoot()) {
probe_sink_ = MakeGarbageCollected<CoreProbeSink>();
performance_monitor_ = MakeGarbageCollected<PerformanceMonitor>(this);
+ inspector_issue_reporter_ = MakeGarbageCollected<InspectorIssueReporter>(
+ &page.GetInspectorIssueStorage());
+ probe_sink_->AddInspectorIssueReporter(inspector_issue_reporter_);
inspector_trace_events_ = MakeGarbageCollected<InspectorTraceEvents>();
probe_sink_->AddInspectorTraceEvents(inspector_trace_events_);
if (RuntimeEnabledFeatures::AdTaggingEnabled()) {
@@ -1084,7 +1202,8 @@ LocalFrame::LocalFrame(LocalFrameClient* client,
// It should be bound before accessing TextInputHost which is the interface to
// respond to GetCharacterIndexAtPoint.
GetBrowserInterfaceBroker().GetInterface(
- text_input_host_.BindNewPipeAndPassReceiver());
+ text_input_host_.BindNewPipeAndPassReceiver(
+ GetTaskRunner(blink::TaskType::kInternalDefault)));
#endif
}
@@ -1523,17 +1642,11 @@ void LocalFrame::SetViewportIntersectionFromParent(
DCHECK(IsLocalRoot());
// TODO(https://crbug/1085175): Re-enable main frame document intersections
// here once intersections are in the root document coordinate system.
- bool can_skip_sticky_frame_tracking =
- intersection_state.can_skip_sticky_frame_tracking ||
- !base::FeatureList::IsEnabled(
- features::kForceExtraRenderingToTrackStickyFrame);
// We only schedule an update if the viewport intersection or occlusion state
- // has changed, or if we cannot skip sticky frame tracking; neither the
- // viewport offset nor the compositing bounds will affect
- // IntersectionObserver.
+ // has changed; neither the viewport offset nor the compositing bounds will
+ // affect IntersectionObserver.
bool needs_update =
- !can_skip_sticky_frame_tracking ||
intersection_state_.viewport_intersection !=
intersection_state.viewport_intersection ||
intersection_state_.occlusion_state != intersection_state.occlusion_state;
@@ -1565,6 +1678,21 @@ IntPoint LocalFrame::GetMainFrameScrollOffset() const {
local_root.intersection_state_.main_frame_scroll_offset);
}
+void LocalFrame::SetOpener(Frame* opener_frame) {
+ // Only a local frame should be able to update another frame's opener.
+ DCHECK(!opener_frame || opener_frame->IsLocalFrame());
+
+ auto* opener_web_frame = WebFrame::FromFrame(opener_frame);
+ auto* web_frame = WebFrame::FromFrame(this);
+ if (web_frame && web_frame->Opener() != opener_web_frame) {
+ GetLocalFrameHostRemote().DidChangeOpener(
+ opener_frame ? base::Optional<base::UnguessableToken>(
+ opener_frame->GetFrameToken())
+ : base::nullopt);
+ web_frame->SetOpener(opener_web_frame);
+ }
+}
+
FrameOcclusionState LocalFrame::GetOcclusionState() const {
// TODO(dcheng): Get rid of this branch for the main frame.
if (IsMainFrame())
@@ -1596,7 +1724,8 @@ void LocalFrame::ForceSynchronousDocumentInstall(
DomWindow()->InstallNewDocument(
DocumentInit::Create()
- .WithDocumentLoader(loader_.GetDocumentLoader())
+ .WithDocumentLoader(loader_.GetDocumentLoader(),
+ MakeGarbageCollected<ContentSecurityPolicy>())
.WithTypeFrom(mime_type));
loader_.StateMachine()->AdvanceTo(
FrameLoaderStateMachine::kCommittedFirstRealLoad);
@@ -1668,7 +1797,8 @@ void LocalFrame::PauseSubresourceLoading(
auto handle = GetFrameScheduler()->GetPauseSubresourceLoadingHandle();
if (!handle)
return;
- pause_handle_receivers_.Add(std::move(handle), std::move(receiver));
+ pause_handle_receivers_.Add(std::move(handle), std::move(receiver),
+ GetTaskRunner(blink::TaskType::kInternalDefault));
}
void LocalFrame::ResumeSubresourceLoading() {
@@ -1711,17 +1841,19 @@ void LocalFrame::UpdateActiveSchedulerTrackedFeatures(uint64_t features_mask) {
}
const base::UnguessableToken& LocalFrame::GetAgentClusterId() const {
- return GetDocument() ? GetDocument()->GetWindowAgent().cluster_id()
- : base::UnguessableToken::Null();
+ if (LocalDOMWindow* window = DomWindow()) {
+ return window->GetAgentClusterID();
+ }
+ return base::UnguessableToken::Null();
}
-const mojo::Remote<mojom::blink::ReportingServiceProxy>&
-LocalFrame::GetReportingService() const {
- if (!reporting_service_) {
+mojom::blink::ReportingServiceProxy* LocalFrame::GetReportingService() {
+ if (!reporting_service_.is_bound()) {
Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
- reporting_service_.BindNewPipeAndPassReceiver());
+ reporting_service_.BindNewPipeAndPassReceiver(
+ GetTaskRunner(blink::TaskType::kInternalDefault)));
}
- return reporting_service_;
+ return reporting_service_.get();
}
// static
@@ -1834,29 +1966,45 @@ void LocalFrame::ForciblyPurgeV8Memory() {
WindowProxyManager* window_proxy_manager = GetWindowProxyManager();
window_proxy_manager->ClearForV8MemoryPurge();
- Loader().StopAllLoaders();
+ Loader().StopAllLoaders(/*abort_client=*/true);
}
-void LocalFrame::DispatchBeforeUnloadEventForFreeze() {
- auto* document_resource_coordinator = GetDocument()->GetResourceCoordinator();
- if (document_resource_coordinator &&
- lifecycle_state_ == mojom::FrameLifecycleState::kRunning &&
- !RuntimeEnabledFeatures::BackForwardCacheEnabled()) {
- // TODO(yuzus): Skip this block if DidFreeze is triggered by bfcache.
-
- // Determine if there is a beforeunload handler by dispatching a
- // beforeunload that will *not* launch a user dialog. If
- // |proceed| is false then there is a non-empty beforeunload
- // handler indicating potentially unsaved user state.
- bool unused_did_allow_navigation = false;
- bool proceed = GetDocument()->DispatchBeforeUnloadEvent(
- nullptr, false /* is_reload */, unused_did_allow_navigation);
-
- // DispatchBeforeUnloadEvent dispatches JS events, which may detach |this|.
+void LocalFrame::OnPageLifecycleStateUpdated() {
+ if (frozen_ != GetPage()->Frozen()) {
+ if (GetPage()->Frozen()) {
+ DidFreeze();
+ } else {
+ DidResume();
+ }
+ // The event handlers might have detached the frame.
if (!IsAttached())
return;
- document_resource_coordinator->SetHasNonEmptyBeforeUnload(!proceed);
+
+ frozen_ = GetPage()->Frozen();
}
+
+ SetContextPaused(GetPage()->Paused());
+
+ mojom::blink::FrameLifecycleState frame_lifecycle_state =
+ mojom::blink::FrameLifecycleState::kRunning;
+ if (GetPage()->Paused()) {
+ frame_lifecycle_state = mojom::blink::FrameLifecycleState::kPaused;
+ } else if (GetPage()->Frozen()) {
+ frame_lifecycle_state = mojom::blink::FrameLifecycleState::kFrozen;
+ }
+
+ DomWindow()->SetLifecycleState(frame_lifecycle_state);
+}
+
+void LocalFrame::SetContextPaused(bool is_paused) {
+ if (is_paused == paused_)
+ return;
+ paused_ = is_paused;
+
+ GetDocument()->Fetcher()->SetDefersLoading(is_paused);
+ Loader().SetDefersLoading(is_paused);
+ // TODO(altimin): Move this to PageScheduler level.
+ GetFrameScheduler()->SetPaused(is_paused);
}
void LocalFrame::DidFreeze() {
@@ -1890,75 +2038,6 @@ void LocalFrame::DidResume() {
}
}
-void LocalFrame::PauseContext() {
- GetDocument()->Fetcher()->SetDefersLoading(true);
- DomWindow()->SetLifecycleState(lifecycle_state_);
- Loader().SetDefersLoading(true);
- GetFrameScheduler()->SetPaused(true);
-}
-
-void LocalFrame::UnpauseContext() {
- GetDocument()->Fetcher()->SetDefersLoading(false);
- DomWindow()->SetLifecycleState(mojom::FrameLifecycleState::kRunning);
- Loader().SetDefersLoading(false);
- GetFrameScheduler()->SetPaused(false);
-}
-
-void LocalFrame::SetLifecycleState(mojom::FrameLifecycleState state) {
- // Don't allow lifecycle state changes for detached frames.
- if (!IsAttached())
- return;
- // If we have asked to be frozen we will only do this once the
- // load event has fired.
- if ((state == mojom::FrameLifecycleState::kFrozen ||
- state == mojom::FrameLifecycleState::kFrozenAutoResumeMedia) &&
- IsLoading() && !RuntimeEnabledFeatures::BackForwardCacheEnabled()) {
- // TODO(yuzus): We violate the spec and when bfcache is enabled,
- // |pending_lifecycle_state_| is not set.
- // With bfcache, the decision as to whether the frame gets frozen or not is
- // already made on the browser side and should not be overridden here.
- // https://wicg.github.io/page-lifecycle/#update-document-frozenness-steps
- pending_lifecycle_state_ = state;
- return;
- }
- pending_lifecycle_state_ = base::nullopt;
-
- if (state == lifecycle_state_)
- return;
-
- bool is_frozen = lifecycle_state_ != mojom::FrameLifecycleState::kRunning;
- bool freeze = state != mojom::FrameLifecycleState::kRunning;
-
- // TODO(dtapuska): Determine if we should dispatch events if we are
- // transitioning across frozen states. ie. kPaused->kFrozen should
- // pause media.
-
- // If we are transitioning from one frozen state to another just return.
- if (is_frozen == freeze)
- return;
- mojom::FrameLifecycleState old_state = lifecycle_state_;
- lifecycle_state_ = state;
-
- if (freeze) {
- if (lifecycle_state_ != mojom::FrameLifecycleState::kPaused) {
- DidFreeze();
- // DidFreeze can dispatch JS events, which may detach |this|.
- if (!IsAttached())
- return;
- }
- PauseContext();
- } else {
- UnpauseContext();
- if (old_state != mojom::FrameLifecycleState::kPaused) {
- DidResume();
- // DidResume can dispatch JS events, which may detach |this|.
- if (!IsAttached())
- return;
- }
- }
- GetLocalFrameHostRemote().LifecycleStateChanged(state);
-}
-
void LocalFrame::MaybeLogAdClickNavigation() {
if (HasTransientUserActivation(this) && IsAdSubframe())
UseCounter::Count(GetDocument(), WebFeature::kAdClickNavigation);
@@ -1994,11 +2073,6 @@ void LocalFrame::CountUseIfFeatureWouldBeBlockedByFeaturePolicy(
void LocalFrame::FinishedLoading(FrameLoader::NavigationFinishState state) {
DomWindow()->FinishedLoading(state);
-
- if (pending_lifecycle_state_) {
- DCHECK(!IsLoading());
- SetLifecycleState(pending_lifecycle_state_.value());
- }
}
void LocalFrame::UpdateFaviconURL() {
@@ -2028,6 +2102,9 @@ void LocalFrame::UpdateFaviconURL() {
DCHECK_EQ(icon_urls.size(), urls.size());
GetLocalFrameHostRemote().UpdateFaviconURL(std::move(urls));
+
+ if (GetPage())
+ GetPage()->GetPageScheduler()->OnTitleOrFaviconUpdated();
}
void LocalFrame::SetIsCapturingMediaCallback(
@@ -2225,9 +2302,9 @@ mojom::blink::LocalFrameHost& LocalFrame::GetLocalFrameHostRemote() {
void LocalFrame::SetEmbeddingToken(
const base::UnguessableToken& embedding_token) {
- DCHECK(Tree().Parent());
- DCHECK(Tree().Parent()->IsRemoteFrame());
embedding_token_ = embedding_token;
+ if (auto* owner = DynamicTo<HTMLFrameOwnerElement>(Owner()))
+ owner->SetEmbeddingToken(embedding_token);
}
const base::Optional<base::UnguessableToken>& LocalFrame::GetEmbeddingToken()
@@ -2273,6 +2350,44 @@ void LocalFrame::NotifyUserActivation() {
NotifyUserActivation(false);
}
+void LocalFrame::RegisterVirtualKeyboardOverlayChangedObserver(
+ VirtualKeyboardOverlayChangedObserver* observer) {
+ virtual_keyboard_overlay_changed_observers_.insert(observer);
+}
+
+void LocalFrame::NotifyVirtualKeyboardOverlayRectObservers(
+ const gfx::Rect& rect) const {
+ HeapVector<Member<VirtualKeyboardOverlayChangedObserver>, 32> observers;
+ CopyToVector(virtual_keyboard_overlay_changed_observers_, observers);
+ for (VirtualKeyboardOverlayChangedObserver* observer : observers)
+ observer->VirtualKeyboardOverlayChanged(rect);
+}
+
+void LocalFrame::NotifyVirtualKeyboardOverlayRect(
+ const gfx::Rect& keyboard_rect) {
+ Page* page = this->GetPage();
+ if (!page)
+ return;
+
+ // The rect passed to us from content is in DIP, relative to the main frame.
+ // This doesn't take the page's zoom factor into account so we must scale by
+ // the inverse of the page zoom in order to get correct client coordinates.
+ // Note that when use-zoom-for-dsf is enabled, WindowToViewportScalar will
+ // be the true device scale factor, and PageZoomFactor will be the combination
+ // of the device scale factor and the zoom percent of the page.
+ LocalFrame& local_frame_root = LocalFrameRoot();
+ const float window_to_viewport_factor =
+ page->GetChromeClient().WindowToViewportScalar(&local_frame_root, 1.0f);
+ const float zoom_factor = local_frame_root.PageZoomFactor();
+ const float scale_factor = zoom_factor / window_to_viewport_factor;
+ gfx::Rect scaled_rect(keyboard_rect.x() / scale_factor,
+ keyboard_rect.y() / scale_factor,
+ keyboard_rect.width() / scale_factor,
+ keyboard_rect.height() / scale_factor);
+
+ NotifyVirtualKeyboardOverlayRectObservers(scaled_rect);
+}
+
void LocalFrame::AddMessageToConsole(mojom::blink::ConsoleMessageLevel level,
const WTF::String& message,
bool discard_duplicates) {
@@ -2284,12 +2399,13 @@ void LocalFrame::AddMessageToConsole(mojom::blink::ConsoleMessageLevel level,
void LocalFrame::AddInspectorIssue(mojom::blink::InspectorIssueInfoPtr info) {
if (GetPage()) {
- GetPage()->GetInspectorIssueStorage().AddInspectorIssue(DomWindow(), std::move(info));
+ GetPage()->GetInspectorIssueStorage().AddInspectorIssue(DomWindow(),
+ std::move(info));
}
}
void LocalFrame::StopLoading() {
- Loader().StopAllLoaders();
+ Loader().StopAllLoaders(/*abort_client=*/true);
// The stopLoading handler may run script, which may cause this frame to be
// detached/deleted. If that happens, return immediately.
@@ -2394,7 +2510,7 @@ void LocalFrame::SaveImageAt(const gfx::Point& window_point) {
return;
auto params = mojom::blink::DownloadURLParams::New();
- params->data_url_blob = DataURLToMessagePipeHandle(url);
+ params->data_url_blob = DataURLToBlob(url);
GetLocalFrameHostRemote().DownloadURL(std::move(params));
}
@@ -2477,21 +2593,20 @@ void LocalFrame::MediaPlayerActionAtViewportPoint(
void LocalFrame::DownloadURL(
const ResourceRequest& request,
network::mojom::blink::RedirectMode cross_origin_redirect_behavior) {
- DCHECK(GetDocument());
mojo::PendingRemote<mojom::blink::BlobURLToken> blob_url_token;
if (request.Url().ProtocolIs("blob")) {
- GetDocument()->GetPublicURLManager().Resolve(
+ DomWindow()->GetPublicURLManager().Resolve(
request.Url(), blob_url_token.InitWithNewPipeAndPassReceiver());
}
DownloadURL(request, cross_origin_redirect_behavior,
- blob_url_token.PassPipe());
+ std::move(blob_url_token));
}
void LocalFrame::DownloadURL(
const ResourceRequest& request,
network::mojom::blink::RedirectMode cross_origin_redirect_behavior,
- mojo::ScopedMessagePipeHandle blob_url_token) {
+ mojo::PendingRemote<mojom::blink::BlobURLToken> blob_url_token) {
if (ShouldThrottleDownload())
return;
@@ -2500,7 +2615,7 @@ void LocalFrame::DownloadURL(
// Pass data URL through blob.
if (url.ProtocolIs("data")) {
params->url = KURL();
- params->data_url_blob = DataURLToMessagePipeHandle(url.GetString());
+ params->data_url_blob = DataURLToBlob(url.GetString());
} else {
params->url = url;
}
@@ -2675,6 +2790,38 @@ void LocalFrame::BindReportingObserver(
ReportingContext::From(DomWindow())->Bind(std::move(receiver));
}
+void LocalFrame::UpdateOpener(
+ const base::Optional<base::UnguessableToken>& opener_frame_token) {
+ if (auto* web_frame = WebFrame::FromFrame(this)) {
+ auto* opener_frame = LocalFrame::ResolveFrame(
+ opener_frame_token.value_or(base::UnguessableToken()));
+ auto* opener_web_frame = WebFrame::FromFrame(opener_frame);
+ web_frame->SetOpener(opener_web_frame);
+ }
+}
+
+void LocalFrame::GetSavableResourceLinks(
+ GetSavableResourceLinksCallback callback) {
+ Vector<KURL> resources_list;
+ Vector<mojom::blink::SavableSubframePtr> subframes;
+ SavableResources::Result result(&resources_list, &subframes);
+
+ if (!SavableResources::GetSavableResourceLinksForFrame(this, &result)) {
+ std::move(callback).Run(nullptr);
+ return;
+ }
+
+ auto referrer = mojom::blink::Referrer::New(GetDocument()->Url(),
+ DomWindow()->GetReferrerPolicy());
+
+ auto reply = mojom::blink::GetSavableResourceLinksReply::New();
+ reply->resources_list = std::move(resources_list);
+ reply->referrer = std::move(referrer);
+ reply->subframes = std::move(subframes);
+
+ std::move(callback).Run(std::move(reply));
+}
+
bool LocalFrame::ShouldThrottleDownload() {
const auto now = base::TimeTicks::Now();
if (num_burst_download_requests_ == 0) {
@@ -2696,7 +2843,7 @@ bool LocalFrame::ShouldThrottleDownload() {
#if defined(OS_MACOSX)
mojom::blink::TextInputHost& LocalFrame::GetTextInputHost() {
- DCHECK(text_input_host_);
+ DCHECK(text_input_host_.is_bound());
return *text_input_host_.get();
}
#endif
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame.h b/chromium/third_party/blink/renderer/core/frame/local_frame.h
index a222d33ca63..6f18995c66a 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame.h
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame.h
@@ -35,11 +35,10 @@
#include "base/time/default_tick_clock.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
-#include "mojo/public/cpp/bindings/associated_receiver.h"
-#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/unique_receiver_set.h"
+#include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/frame.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink-forward.h"
@@ -63,8 +62,14 @@
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/instrumentation/instance_counters.h"
#include "third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/supplementable.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#if defined(OS_MACOSX)
#include "third_party/blink/public/mojom/input/text_input_host.mojom-blink.h"
#endif
@@ -102,6 +107,7 @@ class FrameOverlay;
class FrameSelection;
class FrameWidget;
class InputMethodController;
+class InspectorIssueReporter;
class InspectorTraceEvents;
class CoreProbeSink;
class IdlenessDetector;
@@ -120,7 +126,9 @@ class ScriptController;
class SmoothScrollSequencer;
class SpellChecker;
class TextSuggestionController;
+class VirtualKeyboardOverlayChangedObserver;
class WebContentSettingsClient;
+class WebInputEventAttribution;
class WebPluginContainerImpl;
class WebPrescientNetworking;
class WebURLLoaderFactory;
@@ -135,6 +143,9 @@ class CORE_EXPORT LocalFrame final : public Frame,
USING_GARBAGE_COLLECTED_MIXIN(LocalFrame);
public:
+ // Returns the LocalFrame instance for the given |frame_token|.
+ static LocalFrame* FromFrameToken(const base::UnguessableToken& frame_token);
+
// For a description of |inheriting_agent_factory| go see the comment on the
// Frame constructor.
LocalFrame(
@@ -152,7 +163,7 @@ class CORE_EXPORT LocalFrame final : public Frame,
// Frame overrides:
~LocalFrame() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Navigate(FrameLoadRequest&, WebFrameLoadType) override;
bool ShouldClose() override;
const SecurityContext* GetSecurityContext() const override;
@@ -163,6 +174,8 @@ class CORE_EXPORT LocalFrame final : public Frame,
void DidChangeVisibilityState() override;
void HookBackForwardCacheEviction() override;
void RemoveBackForwardCacheEviction() override;
+
+ void SetTextDirection(base::i18n::TextDirection direction) override;
// This sets the is_inert_ flag and also recurses through this frame's
// subtree, updating the inert bit on all descendant frames.
void SetIsInert(bool) override;
@@ -239,6 +252,16 @@ class CORE_EXPORT LocalFrame final : public Frame,
UserActivationUpdateSource update_source =
UserActivationUpdateSource::kRenderer);
+ // Registers an observer that will be notified if a VK occludes
+ // the content when it raises/dismisses. The observer is a HeapHashSet
+ // data structure that doesn't allow duplicates.
+ void RegisterVirtualKeyboardOverlayChangedObserver(
+ VirtualKeyboardOverlayChangedObserver*);
+
+ // Notify |virtual_keyboard_overlay_changed_observers_| that keyboard overlay
+ // rect has changed.
+ void NotifyVirtualKeyboardOverlayRectObservers(const gfx::Rect&) const;
+
// =========================================================================
// All public functions below this point are candidates to move out of
// LocalFrame into another class.
@@ -286,7 +309,6 @@ class CORE_EXPORT LocalFrame final : public Frame,
void RemoveSpellingMarkersUnderWords(const Vector<String>& words);
bool ShouldThrottleRendering() const;
- void DispatchBeforeUnloadEventForFreeze();
// Returns frame scheduler for this frame.
// FrameScheduler is destroyed during frame detach and nullptr will be
@@ -370,6 +392,8 @@ class CORE_EXPORT LocalFrame final : public Frame,
IntSize GetMainFrameViewportSize() const override;
IntPoint GetMainFrameScrollOffset() const override;
+ void SetOpener(Frame* opener) override;
+
// See viewport_intersection_state.h for more info on these methods.
gfx::Point RemoteViewportOffset() const {
return intersection_state_.viewport_offset;
@@ -381,10 +405,6 @@ class CORE_EXPORT LocalFrame final : public Frame,
return intersection_state_.main_frame_document_intersection;
}
- bool CanSkipStickyFrameTracking() const {
- return intersection_state_.can_skip_sticky_frame_tracking;
- }
-
FrameOcclusionState GetOcclusionState() const;
bool NeedsOcclusionTracking() const;
@@ -430,8 +450,7 @@ class CORE_EXPORT LocalFrame final : public Frame,
SmoothScrollSequencer& GetSmoothScrollSequencer();
- const mojo::Remote<mojom::blink::ReportingServiceProxy>& GetReportingService()
- const;
+ mojom::blink::ReportingServiceProxy* GetReportingService();
// Returns the frame host ptr. The interface returned is backed by an
// associated interface with the legacy Chrome IPC channel.
@@ -452,7 +471,7 @@ class CORE_EXPORT LocalFrame final : public Frame,
// To be called from OomInterventionImpl.
void ForciblyPurgeV8Memory();
- void SetLifecycleState(mojom::FrameLifecycleState state);
+ void OnPageLifecycleStateUpdated();
void WasHidden();
void WasShown();
@@ -511,7 +530,7 @@ class CORE_EXPORT LocalFrame final : public Frame,
void DownloadURL(
const ResourceRequest& request,
network::mojom::blink::RedirectMode cross_origin_redirect_behavior,
- mojo::ScopedMessagePipeHandle blob_url_token);
+ mojo::PendingRemote<mojom::blink::BlobURLToken> blob_url_token);
// blink::mojom::LocalFrame overrides:
void GetTextSurroundingSelection(
@@ -521,6 +540,7 @@ class CORE_EXPORT LocalFrame final : public Frame,
void SetFrameOwnerProperties(
mojom::blink::FrameOwnerPropertiesPtr properties) final;
void NotifyUserActivation() final;
+ void NotifyVirtualKeyboardOverlayRect(const gfx::Rect& keyboard_rect) final;
void AddMessageToConsole(mojom::blink::ConsoleMessageLevel level,
const WTF::String& message,
bool discard_duplicates) final;
@@ -562,6 +582,9 @@ class CORE_EXPORT LocalFrame final : public Frame,
BlinkTransferableMessage message) final;
void BindReportingObserver(
mojo::PendingReceiver<mojom::blink::ReportingObserver> receiver) final;
+ void UpdateOpener(
+ const base::Optional<base::UnguessableToken>& opener_routing_id) final;
+ void GetSavableResourceLinks(GetSavableResourceLinksCallback callback) final;
// blink::mojom::LocalMainFrame overrides:
void AnimateDoubleTapZoom(const gfx::Point& point,
@@ -586,9 +609,10 @@ class CORE_EXPORT LocalFrame final : public Frame,
// Indicate that this frame was attached as a MainFrame.
void WasAttachedAsLocalMainFrame();
- // Returns the first URL loaded in this frame that is cross-origin to the
- // parent frame.
- base::Optional<String> FirstUrlCrossOriginToParent() const;
+ // Return true if the frame is able to access an event with the given
+ // attribution (i.e. the event is targeted for an origin that the frame may
+ // access).
+ bool CanAccessEvent(const WebInputEventAttribution&) const;
private:
friend class FrameNavigationDisabler;
@@ -636,8 +660,7 @@ class CORE_EXPORT LocalFrame final : public Frame,
void DidFreeze();
void DidResume();
- void PauseContext();
- void UnpauseContext();
+ void SetContextPaused(bool);
void EvictFromBackForwardCache();
@@ -661,8 +684,17 @@ class CORE_EXPORT LocalFrame final : public Frame,
// Holds all PauseSubresourceLoadingHandles allowing either |this| to delete
// them explicitly or the pipe closing to delete them.
- mojo::UniqueReceiverSet<blink::mojom::blink::PauseSubresourceLoadingHandle>
- pause_handle_receivers_;
+ //
+ // LocalFrame can be reused by multiple ExecutionContext.
+ HeapMojoUniqueReceiverSet<
+ blink::mojom::blink::PauseSubresourceLoadingHandle,
+ std::default_delete<blink::mojom::blink::PauseSubresourceLoadingHandle>,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ pause_handle_receivers_{nullptr};
+
+ // Keeps track of all the registered VK observers.
+ HeapHashSet<WeakMember<VirtualKeyboardOverlayChangedObserver>>
+ virtual_keyboard_overlay_changed_observers_;
mutable FrameLoader loader_;
@@ -690,11 +722,22 @@ class CORE_EXPORT LocalFrame final : public Frame,
bool in_view_source_mode_;
+ // Whether this frame is frozen or not. This is a copy of Page::IsFrozen()
+ // and is stored here to ensure that we do not dispatch onfreeze() twice
+ // in a row and every onfreeze() has a single corresponding onresume().
+ bool frozen_ = false;
+
+ // Whether this frame is paused or not. This is a copy of Page::IsPaused()
+ // and is stored here to ensure that we do not call SetContextPaused() twice
+ // in a row with the same argument.
+ bool paused_ = false;
+
Member<CoreProbeSink> probe_sink_;
scoped_refptr<InspectorTaskRunner> inspector_task_runner_;
Member<PerformanceMonitor> performance_monitor_;
Member<AdTracker> ad_tracker_;
Member<IdlenessDetector> idleness_detector_;
+ Member<InspectorIssueReporter> inspector_issue_reporter_;
Member<InspectorTraceEvents> inspector_trace_events_;
// SmoothScrollSequencer is only populated for local roots; all local frames
// use the instance owned by their local root.
@@ -704,10 +747,17 @@ class CORE_EXPORT LocalFrame final : public Frame,
InterfaceRegistry* const interface_registry_;
// This is declared mutable so that the service endpoint can be cached by
// const methods.
- mutable mojo::Remote<mojom::blink::ReportingServiceProxy> reporting_service_;
+ //
+ // LocalFrame can be reused by multiple ExecutionContext.
+ mutable HeapMojoRemote<mojom::blink::ReportingServiceProxy,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ reporting_service_{nullptr};
#if defined(OS_MACOSX)
- mojo::Remote<mojom::blink::TextInputHost> text_input_host_;
+ // LocalFrame can be reused by multiple ExecutionContext.
+ HeapMojoRemote<mojom::blink::TextInputHost,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ text_input_host_{nullptr};
#endif
ViewportIntersectionState intersection_state_;
@@ -734,14 +784,23 @@ class CORE_EXPORT LocalFrame final : public Frame,
base::Optional<base::UnguessableToken> embedding_token_;
mojom::FrameLifecycleState lifecycle_state_;
- base::Optional<mojom::FrameLifecycleState> pending_lifecycle_state_;
std::unique_ptr<WebPrescientNetworking> prescient_networking_;
- mojo::AssociatedRemote<mojom::blink::LocalFrameHost> local_frame_host_remote_;
- mojo::AssociatedReceiver<mojom::blink::LocalFrame> receiver_{this};
- mojo::AssociatedReceiver<mojom::blink::LocalMainFrame> main_frame_receiver_{
- this};
+ // LocalFrame can be reused by multiple ExecutionContext.
+ HeapMojoAssociatedRemote<mojom::blink::LocalFrameHost,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ local_frame_host_remote_{nullptr};
+ // LocalFrame can be reused by multiple ExecutionContext.
+ HeapMojoAssociatedReceiver<mojom::blink::LocalFrame,
+ LocalFrame,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ receiver_{this, nullptr};
+ // LocalFrame can be reused by multiple ExecutionContext.
+ HeapMojoAssociatedReceiver<mojom::blink::LocalMainFrame,
+ LocalFrame,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ main_frame_receiver_{this, nullptr};
// Variable to control burst of download requests.
int num_burst_download_requests_ = 0;
@@ -751,14 +810,6 @@ class CORE_EXPORT LocalFrame final : public Frame,
Member<SystemClipboard> system_clipboard_;
// Access to the global raw/unsanitized system clipboard
Member<RawSystemClipboard> raw_system_clipboard_;
-
- // Stores the first URL that was loaded in this frame that is cross-origin
- // to the parent frame. For this URL we know that the parent origin provided
- // it by either setting the |src| attribute or by navigating the iframe.
- // Thus we can safely reveal it to the parent origin in Web APIs.
- // TODO(ulan): Move this to the browser process once performance.measureMemory
- // starts using Performance Manager to support cross-site iframes.
- base::Optional<String> first_url_cross_origin_to_parent_;
};
inline FrameLoader& LocalFrame::Loader() const {
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_back_forward_cache_test.cc b/chromium/third_party/blink/renderer/core/frame/local_frame_back_forward_cache_test.cc
index e2f19ca275b..04dc3b1f28b 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame_back_forward_cache_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame_back_forward_cache_test.cc
@@ -59,7 +59,8 @@ TEST_F(LocalFrameBackForwardCacheTest, EvictionOnV8ExecutionAtMicrotask) {
LocalFrame* frame = web_view_helper.GetWebView()->MainFrameImpl()->GetFrame();
// Freeze the frame and hook eviction.
- frame->SetLifecycleState(mojom::FrameLifecycleState::kFrozen);
+ frame->GetPage()->GetPageScheduler()->SetPageVisible(false);
+ frame->GetPage()->GetPageScheduler()->SetPageFrozen(true);
frame->HookBackForwardCacheEviction();
auto* script_state = ToScriptStateForMainWorld(frame);
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_client.h b/chromium/third_party/blink/renderer/core/frame/local_frame_client.h
index b9a8d9bce7a..27ab3b3056c 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame_client.h
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -312,8 +312,6 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
virtual void DidChangeName(const String&) {}
- virtual void DidChangeFramePolicy(Frame* child_frame, const FramePolicy&) {}
-
virtual void DidSetFramePolicyHeaders(
network::mojom::blink::WebSandboxFlags,
const ParsedFeaturePolicy& feature_policy_header,
@@ -405,6 +403,12 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
return nullptr;
}
+ virtual std::unique_ptr<media::SpeechRecognitionClient>
+ CreateSpeechRecognitionClient(
+ media::SpeechRecognitionClient::OnReadyCallback callback) {
+ return nullptr;
+ }
+
virtual void SetMouseCapture(bool) {}
// Returns whether we are associated with a print context who suggests to use
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_test.cc b/chromium/third_party/blink/renderer/core/frame/local_frame_test.cc
index d1f8b812ac8..4345235f354 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame_test.cc
@@ -260,7 +260,8 @@ TEST_F(LocalFrameTest, CharacterIndexAtPointWithPinchZoom) {
TestTextInputHostWaiter waiter;
waiter.Init(run_loop.QuitClosure(), main_frame->GetBrowserInterfaceBroker());
main_frame->GetBrowserInterfaceBroker().GetInterface(
- main_frame->text_input_host_.BindNewPipeAndPassReceiver());
+ main_frame->text_input_host_.BindNewPipeAndPassReceiver(
+ main_frame->GetTaskRunner(blink::TaskType::kInternalDefault)));
// Since we're zoomed in to 2X, each char of Ahem is 20px wide/tall in
// viewport space. We expect to hit the fifth char on the first line.
main_frame->GetCharacterIndexAtPoint(gfx::Point(100, 15));
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc b/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc
index 5cbb3af800a..cf0a0891a63 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc
@@ -291,10 +291,6 @@ void LocalFrameUkmAggregator::RecordImplCompositorSample(
RecordSample(kWaitForCommit, requested, started);
RecordSample(kImplCompositorCommit, started, completed);
}
-
- // This will go away in M-84 when we are confident the WaitForCommit and
- // ImplCompositorCommit metrics sum to this metric after reporting.
- RecordSample(kProxyCommit, requested, completed);
}
void LocalFrameUkmAggregator::RecordEndOfFrameMetrics(
@@ -431,7 +427,6 @@ void LocalFrameUkmAggregator::ReportPreFCPEvent() {
CASE_FOR_ID(HandleInputEvents);
CASE_FOR_ID(Animate);
CASE_FOR_ID(UpdateLayers);
- CASE_FOR_ID(ProxyCommit);
CASE_FOR_ID(WaitForCommit);
case kCount:
case kMainFrame:
@@ -477,7 +472,6 @@ void LocalFrameUkmAggregator::ReportUpdateTimeEvent() {
CASE_FOR_ID(HandleInputEvents, i);
CASE_FOR_ID(Animate, i);
CASE_FOR_ID(UpdateLayers, i);
- CASE_FOR_ID(ProxyCommit, i);
CASE_FOR_ID(WaitForCommit, i);
case kCount:
case kMainFrame:
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h b/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h
index d5d0f2e5315..e6061a32222 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h
@@ -142,7 +142,6 @@ class CORE_EXPORT LocalFrameUkmAggregator
kHandleInputEvents,
kAnimate,
kUpdateLayers,
- kProxyCommit,
kWaitForCommit,
kCount,
kMainFrame
@@ -180,7 +179,6 @@ class CORE_EXPORT LocalFrameUkmAggregator
{"HandleInputEvents", true},
{"Animate", true},
{"UpdateLayers", false},
- {"ProxyCommit", true},
{"WaitForCommit", true}};
return *data;
}
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_view.cc b/chromium/third_party/blink/renderer/core/frame/local_frame_view.cc
index a64c209a396..9a4c7a52494 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -77,6 +77,7 @@
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
#include "third_party/blink/renderer/core/html/html_frame_element.h"
#include "third_party/blink/renderer/core/html/html_plugin_element.h"
+#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
#include "third_party/blink/renderer/core/html/portal/document_portals.h"
#include "third_party/blink/renderer/core/html/portal/html_portal_element.h"
@@ -122,6 +123,7 @@
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
#include "third_party/blink/renderer/core/paint/frame_painter.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
+#include "third_party/blink/renderer/core/paint/paint_layer_painter.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/paint/paint_timing.h"
#include "third_party/blink/renderer/core/paint/paint_timing_detector.h"
@@ -291,7 +293,7 @@ LocalFrameView::~LocalFrameView() {
#endif
}
-void LocalFrameView::Trace(Visitor* visitor) {
+void LocalFrameView::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(fragment_anchor_);
visitor->Trace(scrollable_areas_);
@@ -305,6 +307,7 @@ void LocalFrameView::Trace(Visitor* visitor) {
visitor->Trace(layout_shift_tracker_);
visitor->Trace(paint_timing_detector_);
visitor->Trace(lifecycle_observers_);
+ visitor->Trace(fullscreen_video_elements_);
}
template <typename Function>
@@ -460,8 +463,8 @@ bool LocalFrameView::LifecycleUpdatesActive() const {
return !lifecycle_updates_throttled_;
}
-void LocalFrameView::SetLifecycleUpdatesThrottledForTesting() {
- lifecycle_updates_throttled_ = true;
+void LocalFrameView::SetLifecycleUpdatesThrottledForTesting(bool throttled) {
+ lifecycle_updates_throttled_ = throttled;
}
void LocalFrameView::InvalidateRect(const IntRect& rect) {
@@ -950,8 +953,6 @@ void LocalFrameView::UpdateLayout() {
TRACE_DISABLED_BY_DEFAULT("blink.debug.layout.trees"), "LayoutTree", this,
TracedLayoutObject::Create(*GetLayoutView(), true));
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- GetLayoutView()->Compositor()->DidLayout();
layout_count_for_testing_++;
if (AXObjectCache* cache = document->ExistingAXObjectCache()) {
@@ -1024,6 +1025,20 @@ void LocalFrameView::DidFinishForcedLayout(DocumentUpdateReason reason) {
}
}
+void LocalFrameView::MarkFirstEligibleToPaint() {
+ if (frame_ && frame_->GetDocument()) {
+ PaintTiming& timing = PaintTiming::From(*frame_->GetDocument());
+ timing.MarkFirstEligibleToPaint();
+ }
+}
+
+void LocalFrameView::MarkIneligibleToPaint() {
+ if (frame_ && frame_->GetDocument()) {
+ PaintTiming& timing = PaintTiming::From(*frame_->GetDocument());
+ timing.MarkIneligibleToPaint();
+ }
+}
+
void LocalFrameView::SetNeedsPaintPropertyUpdate() {
if (auto* layout_view = GetLayoutView())
layout_view->SetNeedsPaintPropertyUpdate();
@@ -1067,14 +1082,9 @@ FloatSize LocalFrameView::ViewportSizeForViewportUnits() const {
}
FloatSize LocalFrameView::ViewportSizeForMediaQueries() const {
- FloatSize viewport_size(layout_size_);
- if (!frame_->GetDocument()->Printing()) {
- float zoom = GetFrame().PageZoomFactor();
- viewport_size.SetWidth(
- AdjustForAbsoluteZoom::AdjustInt(layout_size_.Width(), zoom));
- viewport_size.SetHeight(
- AdjustForAbsoluteZoom::AdjustInt(layout_size_.Height(), zoom));
- }
+ FloatSize viewport_size(GetLayoutSize());
+ if (!frame_->GetDocument() || !frame_->GetDocument()->Printing())
+ viewport_size.Scale(1 / GetFrame().PageZoomFactor());
return viewport_size;
}
@@ -1099,6 +1109,7 @@ void LocalFrameView::RunIntersectionObserverSteps() {
if (frame_->IsMainFrame()) {
EnsureOverlayInterstitialAdDetector().MaybeFireDetection(frame_.Get());
+ EnsureStickyAdDetector().MaybeFireDetection(frame_.Get());
// Report the main frame's document intersection with itself.
LayoutObject* layout_object = GetLayoutView();
@@ -1113,11 +1124,7 @@ void LocalFrameView::RunIntersectionObserverSteps() {
SCOPED_UMA_AND_UKM_TIMER(EnsureUkmAggregator(),
LocalFrameUkmAggregator::kIntersectionObservation);
- unsigned flags = 0;
- if (frame_->CanSkipStickyFrameTracking())
- flags |= IntersectionObservation::kCanSkipStickyFrameTracking;
-
- bool needs_occlusion_tracking = UpdateViewportIntersectionsForSubtree(flags);
+ bool needs_occlusion_tracking = UpdateViewportIntersectionsForSubtree(0);
if (FrameOwner* owner = frame_->Owner())
owner->SetNeedsOcclusionTracking(needs_occlusion_tracking);
#if DCHECK_IS_ON()
@@ -1209,18 +1216,6 @@ void LocalFrameView::AddPartToUpdate(LayoutEmbeddedObject& object) {
part_update_set_.insert(&object);
}
-void LocalFrameView::SetDisplayShape(DisplayShape display_shape) {
- if (display_shape == display_shape_)
- return;
-
- display_shape_ = display_shape;
-
- if (frame_->GetDocument()) {
- frame_->GetDocument()->MediaQueryAffectingValueChanged(
- MediaValueChange::kOther);
- }
-}
-
void LocalFrameView::SetMediaType(const AtomicString& media_type) {
DCHECK(frame_->GetDocument());
media_type_ = media_type;
@@ -1246,11 +1241,6 @@ void LocalFrameView::AdjustMediaTypeForPrinting(bool printing) {
SetMediaType(media_type_when_not_printing_);
media_type_when_not_printing_ = g_null_atom;
}
-
- frame_->GetDocument()->GetStyleEngine().MarkViewportStyleDirty();
- frame_->GetDocument()->GetStyleEngine().MarkAllElementsForStyleRecalc(
- StyleChangeReasonForTracing::Create(
- style_change_reason::kStyleSheetChange));
}
void LocalFrameView::AddBackgroundAttachmentFixedObject(LayoutObject* object) {
@@ -1436,8 +1426,11 @@ bool LocalFrameView::InvalidateViewportConstrainedObjects() {
DCHECK(layout_object->HasLayer());
PaintLayer* layer = ToLayoutBoxModelObject(layout_object)->Layer();
- if (layer->IsPaintInvalidationContainer())
- continue;
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ DisableCompositingQueryAsserts disabler;
+ if (layer->IsPaintInvalidationContainer())
+ continue;
+ }
// If the layer has no visible content, then we shouldn't invalidate; but
// if we're not compositing-inputs-clean, then we can't query
@@ -1445,6 +1438,7 @@ bool LocalFrameView::InvalidateViewportConstrainedObjects() {
layout_object->SetSubtreeShouldCheckForPaintInvalidation();
if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
!layer->SelfOrDescendantNeedsRepaint()) {
+ DisableCompositingQueryAsserts disabler;
// Paint properties of the layer relative to its containing graphics
// layer may change if the paint properties escape the graphics layer's
// property state. Need to check raster invalidation for relative paint
@@ -1785,14 +1779,11 @@ void LocalFrameView::SetNeedsLayout() {
layout_view->SetNeedsLayout(layout_invalidation_reason::kUnknown);
}
-bool LocalFrameView::HasOpaqueBackground() const {
- return !base_background_color_.HasAlpha();
-}
-
Color LocalFrameView::BaseBackgroundColor() const {
- if (use_dark_scheme_background_ &&
+ if (use_color_adjust_background_ &&
base_background_color_ != Color::kTransparent) {
- return Color::kBlack;
+ DCHECK(frame_->GetDocument());
+ return frame_->GetDocument()->GetStyleEngine().ColorAdjustBackgroundColor();
}
return base_background_color_;
}
@@ -1818,11 +1809,12 @@ void LocalFrameView::SetBaseBackgroundColor(const Color& background_color) {
GetPage()->Animator().ScheduleVisualUpdate(frame_.Get());
}
-void LocalFrameView::SetUseDarkSchemeBackground(bool dark_scheme) {
- if (use_dark_scheme_background_ == dark_scheme)
+void LocalFrameView::SetUseColorAdjustBackground(bool color_adjust,
+ bool color_scheme_changed) {
+ if (use_color_adjust_background_ == color_adjust && !color_scheme_changed)
return;
- use_dark_scheme_background_ = dark_scheme;
+ use_color_adjust_background_ = color_adjust;
if (auto* layout_view = GetLayoutView())
layout_view->SetBackgroundNeedsFullPaintInvalidation();
}
@@ -2501,8 +2493,7 @@ bool LocalFrameView::RunStyleAndLayoutLifecyclePhases(
// PerformRootScrollerSelection can dirty layout if an effective root
// scroller is changed so make sure we get back to LayoutClean.
- if (RuntimeEnabledFeatures::ImplicitRootScrollerEnabled() ||
- RuntimeEnabledFeatures::SetRootScrollerEnabled()) {
+ if (RuntimeEnabledFeatures::ImplicitRootScrollerEnabled()) {
ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
if (frame_view.NeedsLayout())
frame_view.UpdateLayout();
@@ -2679,18 +2670,13 @@ void LocalFrameView::RunPaintLifecyclePhase() {
// Notify the controller that the artifact has been pushed and some
// lifecycle state can be freed (such as raster invalidations).
- if (paint_controller_)
+ if (paint_controller_) {
paint_controller_->FinishCycle();
+ paint_controller_->ClearPropertyTreeChangedStateTo(
+ PropertyTreeState::Root());
+ }
if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- // Property tree changed state is typically cleared through
- // |PaintController::FinishCycle| but that will be a no-op because
- // the paint controller is transient, so force the changed state to be
- // cleared here.
- if (paint_controller_) {
- paint_controller_->ClearPropertyTreeChangedStateTo(
- PropertyTreeState::Root());
- }
auto* root = GetLayoutView()->Compositor()->PaintRootGraphicsLayer();
if (root) {
ForAllGraphicsLayers(*root, [](GraphicsLayer& layer) {
@@ -2794,8 +2780,6 @@ static void ForAllDrawableGraphicsLayers(
ForAllDrawableGraphicsLayers(child, main_layer_function,
contents_layer_function);
}
- ForAllDrawableGraphicsLayers(layer->MaskLayer(), main_layer_function,
- contents_layer_function);
}
static void CollectDrawableLayersForLayerListRecursively(
@@ -2849,8 +2833,11 @@ void LocalFrameView::PaintTree() {
DCHECK(layout_view);
paint_frame_count_++;
ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+ frame_view.MarkFirstEligibleToPaint();
frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kInPaint);
});
+ ForAllThrottledLocalFrameViews(
+ [](LocalFrameView& frame_view) { frame_view.MarkIneligibleToPaint(); });
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
if (!paint_controller_)
@@ -2871,29 +2858,44 @@ void LocalFrameView::PaintTree() {
BuildDarkModeSettings(*settings, *GetLayoutView()));
}
- PaintInternal(graphics_context, kGlobalPaintNormalPhase,
- CullRect::Infinite());
+ bool painted_full_screen_overlay = false;
+ if (frame_->IsMainFrame()) {
+ PaintLayer* full_screen_layer = GetFullScreenOverlayLayer();
+ if (full_screen_layer) {
+ PaintLayerPainter(*full_screen_layer)
+ .Paint(graphics_context, CullRect::Infinite(),
+ kGlobalPaintNormalPhase, 0);
+ painted_full_screen_overlay = true;
+ visual_viewport_needs_repaint_ = false;
+ }
+ }
- GetPage()->GetLinkHighlight().Paint(graphics_context);
+ if (!painted_full_screen_overlay) {
+ PaintInternal(graphics_context, kGlobalPaintNormalPhase,
+ CullRect::Infinite());
- GetPage()->GetValidationMessageClient().PaintOverlay(graphics_context);
- ForAllNonThrottledLocalFrameViews(
- [&graphics_context](LocalFrameView& view) {
- view.frame_->PaintFrameColorOverlay(graphics_context);
- });
+ GetPage()->GetValidationMessageClient().PaintOverlay(graphics_context);
+ ForAllNonThrottledLocalFrameViews(
+ [&graphics_context](LocalFrameView& view) {
+ view.frame_->PaintFrameColorOverlay(graphics_context);
+ });
- // Devtools overlays query the inspected page's paint data so this update
- // needs to be after other paintings.
- if (has_dev_tools_overlays)
- web_local_frame_impl->PaintDevToolsOverlays(graphics_context);
+ // Devtools overlays query the inspected page's paint data so this
+ // update needs to be after other paintings.
+ if (has_dev_tools_overlays)
+ web_local_frame_impl->PaintDevToolsOverlays(graphics_context);
- if (frame_->IsMainFrame()) {
- frame_->GetPage()->GetVisualViewport().Paint(graphics_context);
- visual_viewport_needs_repaint_ = false;
- } else {
- DCHECK(!visual_viewport_needs_repaint_);
+ if (frame_->IsMainFrame()) {
+ frame_->GetPage()->GetVisualViewport().Paint(graphics_context);
+ visual_viewport_needs_repaint_ = false;
+ }
}
+ // Link highlights paint after all other paintings.
+ GetPage()->GetLinkHighlight().Paint(graphics_context);
+
+ DCHECK(!visual_viewport_needs_repaint_);
+
paint_controller_->CommitNewDisplayItems();
}
} else {
@@ -2987,10 +2989,6 @@ void LocalFrameView::PushPaintArtifactToCompositor() {
}
}
- PaintArtifactCompositor::Settings settings;
- settings.prefer_compositing_to_lcd_text =
- page->GetSettings().GetPreferCompositingToLCDTextEnabled();
-
if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
(!paint_controller_ || visual_viewport_needs_repaint_)) {
// Before CompositeAfterPaint, we need a transient PaintController to
@@ -3030,7 +3028,7 @@ void LocalFrameView::PushPaintArtifactToCompositor() {
paint_artifact_compositor_->Update(
paint_controller_->GetPaintArtifactShared(), viewport_properties,
- settings, scroll_translation_nodes);
+ scroll_translation_nodes);
probe::LayerTreePainted(&GetFrame());
}
@@ -3265,60 +3263,6 @@ void LocalFrameView::ForceLayoutForPagination(
AdjustViewSizeAndLayout();
}
-IntRect LocalFrameView::ConvertFromLayoutObject(
- const LayoutObject& layout_object,
- const IntRect& layout_object_rect) const {
- // Convert from page ("absolute") to LocalFrameView coordinates.
- return PixelSnappedIntRect(
- layout_object.LocalToAbsoluteRect(PhysicalRect(layout_object_rect)));
-}
-
-IntRect LocalFrameView::ConvertToLayoutObject(const LayoutObject& layout_object,
- const IntRect& frame_rect) const {
- return PixelSnappedIntRect(
- layout_object.AbsoluteToLocalRect(PhysicalRect(frame_rect)));
-}
-
-IntPoint LocalFrameView::ConvertFromLayoutObject(
- const LayoutObject& layout_object,
- const IntPoint& layout_object_point) const {
- return RoundedIntPoint(ConvertFromLayoutObject(
- layout_object, PhysicalOffset(layout_object_point)));
-}
-
-IntPoint LocalFrameView::ConvertToLayoutObject(
- const LayoutObject& layout_object,
- const IntPoint& frame_point) const {
- return RoundedIntPoint(
- ConvertToLayoutObject(layout_object, PhysicalOffset(frame_point)));
-}
-
-PhysicalOffset LocalFrameView::ConvertFromLayoutObject(
- const LayoutObject& layout_object,
- const PhysicalOffset& layout_object_offset) const {
- return layout_object.LocalToAbsolutePoint(layout_object_offset);
-}
-
-PhysicalOffset LocalFrameView::ConvertToLayoutObject(
- const LayoutObject& layout_object,
- const PhysicalOffset& frame_offset) const {
- return PhysicalOffset::FromFloatPointRound(
- ConvertToLayoutObject(layout_object, FloatPoint(frame_offset)));
-}
-
-FloatPoint LocalFrameView::ConvertToLayoutObject(
- const LayoutObject& layout_object,
- const FloatPoint& frame_point) const {
- return layout_object.AbsoluteToLocalFloatPoint(frame_point);
-}
-
-IntPoint LocalFrameView::ConvertSelfToChild(const EmbeddedContentView& child,
- const IntPoint& point) const {
- IntPoint new_point(point);
- new_point.MoveBy(-child.Location());
- return new_point;
-}
-
IntRect LocalFrameView::RootFrameToDocument(const IntRect& rect_in_root_frame) {
IntPoint offset = RootFrameToDocument(rect_in_root_frame.Location());
IntRect local_rect = rect_in_root_frame;
@@ -3409,7 +3353,7 @@ PhysicalRect LocalFrameView::FrameToDocument(
IntRect LocalFrameView::ConvertToContainingEmbeddedContentView(
const IntRect& local_rect) const {
- if (LocalFrameView* parent = ParentFrameView()) {
+ if (ParentFrameView()) {
auto* layout_object = GetLayoutEmbeddedContent();
if (!layout_object)
return local_rect;
@@ -3419,7 +3363,8 @@ IntRect LocalFrameView::ConvertToContainingEmbeddedContentView(
rect.Move(
(layout_object->BorderLeft() + layout_object->PaddingLeft()).ToInt(),
(layout_object->BorderTop() + layout_object->PaddingTop()).ToInt());
- return parent->ConvertFromLayoutObject(*layout_object, rect);
+ return PixelSnappedIntRect(
+ layout_object->LocalToAbsoluteRect(PhysicalRect(rect)));
}
return local_rect;
@@ -3427,19 +3372,17 @@ IntRect LocalFrameView::ConvertToContainingEmbeddedContentView(
IntRect LocalFrameView::ConvertFromContainingEmbeddedContentView(
const IntRect& parent_rect) const {
- if (LocalFrameView* parent = ParentFrameView()) {
+ if (ParentFrameView()) {
IntRect local_rect = parent_rect;
- local_rect.SetLocation(
- parent->ConvertSelfToChild(*this, local_rect.Location()));
+ local_rect.MoveBy(-Location());
return local_rect;
}
-
return parent_rect;
}
PhysicalOffset LocalFrameView::ConvertToContainingEmbeddedContentView(
const PhysicalOffset& local_offset) const {
- if (LocalFrameView* parent = ParentFrameView()) {
+ if (ParentFrameView()) {
auto* layout_object = GetLayoutEmbeddedContent();
if (!layout_object)
return local_offset;
@@ -3450,7 +3393,7 @@ PhysicalOffset LocalFrameView::ConvertToContainingEmbeddedContentView(
point += PhysicalOffset(
layout_object->BorderLeft() + layout_object->PaddingLeft(),
layout_object->BorderTop() + layout_object->PaddingTop());
- return parent->ConvertFromLayoutObject(*layout_object, point);
+ return layout_object->LocalToAbsolutePoint(point);
}
return local_offset;
@@ -3488,14 +3431,14 @@ FloatPoint LocalFrameView::ConvertFromContainingEmbeddedContentView(
DoublePoint LocalFrameView::ConvertFromContainingEmbeddedContentView(
const DoublePoint& parent_point) const {
- if (LocalFrameView* parent = ParentFrameView()) {
+ if (ParentFrameView()) {
// Get our layoutObject in the parent view
auto* layout_object = GetLayoutEmbeddedContent();
if (!layout_object)
return parent_point;
- DoublePoint point = DoublePoint(parent->ConvertToLayoutObject(
- *layout_object, FloatPoint(parent_point)));
+ DoublePoint point(
+ layout_object->AbsoluteToLocalFloatPoint(FloatPoint(parent_point)));
// Subtract borders and padding
point.Move(
(-layout_object->BorderLeft() - layout_object->PaddingLeft())
@@ -4111,8 +4054,7 @@ bool LocalFrameView::UpdateViewportIntersectionsForSubtree(
intersection_observation_state_ = kNotNeeded;
}
- if (UpdateViewportIntersection(flags, needs_occlusion_tracking))
- flags |= IntersectionObservation::kCanSkipStickyFrameTracking;
+ UpdateViewportIntersection(flags, needs_occlusion_tracking);
for (Frame* child = frame_->Tree().FirstChild(); child;
child = child->Tree().NextSibling()) {
@@ -4160,8 +4102,13 @@ void LocalFrameView::CrossOriginToMainFrameChanged() {
}
void LocalFrameView::CrossOriginToParentFrameChanged() {
- if (auto* owner = frame_->DeprecatedLocalOwner())
- owner->FrameCrossOriginToParentFrameChanged();
+ if (base::FeatureList::IsEnabled(
+ blink::features::kCompositeCrossOriginIframes)) {
+ if (LayoutView* layout_view = GetLayoutView()) {
+ if (PaintLayer* root_layer = layout_view->Layer())
+ root_layer->SetNeedsCompositingInputsUpdate();
+ }
+ }
}
void LocalFrameView::VisibilityForThrottlingChanged() {
@@ -4224,6 +4171,9 @@ void LocalFrameView::InvalidateForThrottlingChange() {
layout_view->AddSubtreePaintPropertyUpdateReason(
SubtreePaintPropertyUpdateReason::kPreviouslySkipped);
}
+ // Ensure we'll recompute viewport intersection for the frame subtree during
+ // the scheduled visual update.
+ SetIntersectionObservationState(kRequired);
}
void LocalFrameView::SetNeedsForcedCompositingUpdate() {
@@ -4291,9 +4241,6 @@ unsigned LocalFrameView::GetIntersectionObservationFlags(
// applies to the entire frame tree.
flags |= (parent_flags & IntersectionObservation::kIgnoreDelay);
- flags |=
- (parent_flags & IntersectionObservation::kCanSkipStickyFrameTracking);
-
return flags;
}
@@ -4376,13 +4323,12 @@ void LocalFrameView::BeginLifecycleUpdates() {
// updates start. Doing so allows us to update the page lifecycle but not
// present the results to screen until we see first contentful paint is
// available or until a timer expires.
- // This is enabled only if kAvoidFlashBetweenNavigation is enabled, and
+ // This is enabled only if kPaintHolding is enabled, and
// the document loading is regular HTML served over HTTP/HTTPs.
// And only defer commits once. This method gets called multiple times,
// and we do not want to defer a second time if we have already done
// so once and resumed commits already.
if (document &&
- base::FeatureList::IsEnabled(blink::features::kPaintHolding) &&
document->DeferredCompositorCommitIsAllowed() &&
!have_deferred_commits_) {
chrome_client.StartDeferringCommits(GetFrame(),
@@ -4552,6 +4498,21 @@ void LocalFrameView::EnqueueStartOfLifecycleTask(base::OnceClosure closure) {
start_of_lifecycle_tasks_.push_back(std::move(closure));
}
+void LocalFrameView::NotifyVideoIsDominantVisibleStatus(
+ HTMLVideoElement* element,
+ bool is_dominant) {
+ if (is_dominant) {
+ fullscreen_video_elements_.insert(element);
+ return;
+ }
+
+ fullscreen_video_elements_.erase(element);
+}
+
+bool LocalFrameView::HasDominantVideoElement() const {
+ return !fullscreen_video_elements_.IsEmpty();
+}
+
#if DCHECK_IS_ON()
LocalFrameView::DisallowLayoutInvalidationScope::
DisallowLayoutInvalidationScope(LocalFrameView* view)
@@ -4614,4 +4575,59 @@ LocalFrameView::GetScrollTranslationNodes() {
return scroll_translation_nodes;
}
+StickyAdDetector& LocalFrameView::EnsureStickyAdDetector() {
+ if (!sticky_ad_detector_) {
+ sticky_ad_detector_ = std::make_unique<StickyAdDetector>();
+ }
+ return *sticky_ad_detector_.get();
+}
+
+static PaintLayer* GetFullScreenOverlayVideoLayer(Document& document) {
+ // Recursively find the document that is in fullscreen.
+ Document* content_document = &document;
+ Element* fullscreen_element =
+ Fullscreen::FullscreenElementFrom(*content_document);
+ while (auto* frame_owner =
+ DynamicTo<HTMLFrameOwnerElement>(fullscreen_element)) {
+ content_document = frame_owner->contentDocument();
+ if (!content_document)
+ return nullptr;
+ fullscreen_element = Fullscreen::FullscreenElementFrom(*content_document);
+ }
+ auto* video_element = DynamicTo<HTMLVideoElement>(fullscreen_element);
+ if (!video_element || !video_element->UsesOverlayFullscreenVideo())
+ return nullptr;
+ return video_element->GetLayoutBoxModelObject()->Layer();
+}
+
+static PaintLayer* GetXrOverlayLayer(Document& document) {
+ // immersive-ar DOM overlay mode is very similar to fullscreen video, using
+ // the AR camera image instead of a video element as a background that's
+ // separately composited in the browser. The fullscreened DOM content is shown
+ // on top of that, same as HTML video controls.
+ if (!document.IsXrOverlay())
+ return nullptr;
+
+ Element* fullscreen_element = Fullscreen::FullscreenElementFrom(document);
+ if (!fullscreen_element)
+ return nullptr;
+
+ const auto* object = fullscreen_element->GetLayoutBoxModelObject();
+ if (!object) {
+ // Currently, only HTML fullscreen elements are supported for this mode,
+ // not others such as SVG or MathML.
+ DVLOG(1) << "no LayoutBoxModelObject for element " << fullscreen_element;
+ return nullptr;
+ }
+
+ return object->Layer();
+}
+
+PaintLayer* LocalFrameView::GetFullScreenOverlayLayer() const {
+ DCHECK(frame_->IsMainFrame());
+ if (auto* layer = GetXrOverlayLayer(*frame_->GetDocument()))
+ return layer;
+ return GetFullScreenOverlayVideoLayer(*frame_->GetDocument());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_view.h b/chromium/third_party/blink/renderer/core/frame/local_frame_view.h
index 6d0cfa5b5c7..5fa8fa10a9c 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame_view.h
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -31,12 +31,13 @@
#include "third_party/blink/public/common/metrics/document_update_reason.h"
#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink-forward.h"
-#include "third_party/blink/public/platform/shape_properties.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/frame_view.h"
#include "third_party/blink/renderer/core/frame/layout_subtree_root_list.h"
#include "third_party/blink/renderer/core/frame/overlay_interstitial_ad_detector.h"
+#include "third_party/blink/renderer/core/frame/sticky_ad_detector.h"
+#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/layout/depth_ordered_layout_object_list.h"
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
#include "third_party/blink/renderer/core/paint/layout_object_counter.h"
@@ -160,7 +161,7 @@ class CORE_EXPORT LocalFrameView final
void UpdateLayout();
bool DidFirstLayout() const;
bool LifecycleUpdatesActive() const;
- void SetLifecycleUpdatesThrottledForTesting();
+ void SetLifecycleUpdatesThrottledForTesting(bool throttled = true);
void ScheduleRelayout();
void ScheduleRelayoutOfSubtree(LayoutObject*);
bool LayoutPending() const;
@@ -251,13 +252,11 @@ class CORE_EXPORT LocalFrameView final
void PropagateFrameRects() override;
void InvalidateAllCustomScrollbarsOnActiveChanged();
- // True if the LocalFrameView's base background color is completely opaque.
- bool HasOpaqueBackground() const;
-
Color BaseBackgroundColor() const;
void SetBaseBackgroundColor(const Color&);
void UpdateBaseBackgroundColorRecursively(const Color&);
- void SetUseDarkSchemeBackground(bool dark_scheme);
+ void SetUseColorAdjustBackground(bool color_adjust,
+ bool color_scheme_changed);
void AdjustViewSize();
void AdjustViewSizeAndLayout();
@@ -275,9 +274,6 @@ class CORE_EXPORT LocalFrameView final
void SetMediaType(const AtomicString&);
void AdjustMediaTypeForPrinting(bool printing);
- DisplayShape GetDisplayShape() { return display_shape_; }
- void SetDisplayShape(DisplayShape);
-
// For any viewport-constrained object, we need to know if it's due to fixed
// or sticky so that we can support HasStickyViewportConstrainedObject().
enum ViewportConstrainedType { kFixed = 0, kSticky = 1 };
@@ -374,13 +370,7 @@ class CORE_EXPORT LocalFrameView final
// desired state.
bool UpdateLifecycleToLayoutClean(DocumentUpdateReason reason);
- bool InLifecycleUpdate() { return in_lifecycle_update_; }
void SetInLifecycleUpdateForTest(bool val) { in_lifecycle_update_ = val; }
- void SetLifecycleDataForTesting(const LifecycleData& lifecycle_data) {
- lifecycle_data_ = lifecycle_data;
- }
-
- const LifecycleData& CurrentLifecycleData() const { return lifecycle_data_; }
// This for doing work that needs to run synchronously at the end of lifecyle
// updates, but needs to happen outside of the lifecycle code. It's OK to
@@ -417,19 +407,6 @@ class CORE_EXPORT LocalFrameView final
void InvokeFragmentAnchor();
void DismissFragmentAnchor();
- // Methods to convert points and rects between the coordinate space of the
- // layoutObject, and this view.
- IntRect ConvertFromLayoutObject(const LayoutObject&, const IntRect&) const;
- IntRect ConvertToLayoutObject(const LayoutObject&, const IntRect&) const;
- IntPoint ConvertFromLayoutObject(const LayoutObject&, const IntPoint&) const;
- IntPoint ConvertToLayoutObject(const LayoutObject&, const IntPoint&) const;
- PhysicalOffset ConvertFromLayoutObject(const LayoutObject&,
- const PhysicalOffset&) const;
- PhysicalOffset ConvertToLayoutObject(const LayoutObject&,
- const PhysicalOffset&) const;
- FloatPoint ConvertToLayoutObject(const LayoutObject&,
- const FloatPoint&) const;
-
bool ShouldSetCursor() const;
void SetCursor(const ui::Cursor&);
@@ -518,8 +495,6 @@ class CORE_EXPORT LocalFrameView final
IntPoint ConvertFromRootFrame(const IntPoint&) const;
FloatPoint ConvertFromRootFrame(const FloatPoint&) const;
PhysicalOffset ConvertFromRootFrame(const PhysicalOffset&) const;
- IntPoint ConvertSelfToChild(const EmbeddedContentView&,
- const IntPoint&) const;
IntRect RootFrameToDocument(const IntRect&);
IntPoint RootFrameToDocument(const IntPoint&);
@@ -562,7 +537,7 @@ class CORE_EXPORT LocalFrameView final
// once intersections are in the root document coordinate system.
bool ShouldReportMainFrameIntersection() const override { return false; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void NotifyPageThatContentAreaWillPaint() const;
// Returns the scrollable area for the frame. For the root frame, this will
@@ -596,6 +571,21 @@ class CORE_EXPORT LocalFrameView final
void BeginLifecycleUpdates();
+ // Records a timestamp in PaintTiming when the frame is first not
+ // render-throttled (since it last was throttled if applicable).
+ void MarkFirstEligibleToPaint();
+
+ // Resets the optional timestamp in PaintTiming to null to indicate
+ // that the frame is now render-throttled, unless the frame already has
+ // a first contentful paint. This is a necessary workaround, as when
+ // constructing the frame, HTMLConstructionSite::InsertHTMLBodyElement
+ // initiates a call via Document::WillInsertBody to begin lifecycle
+ // updates, and hence |lifecycle_updates_throttled_| is set to false, which
+ // can cause the frame to be briefly unthrottled and receive a paint
+ // eligibility timestamp, even if the frame is throttled shortly thereafter
+ // and not actually painted.
+ void MarkIneligibleToPaint();
+
// Shorthands of LayoutView's corresponding methods.
void SetNeedsPaintPropertyUpdate();
@@ -705,6 +695,16 @@ class CORE_EXPORT LocalFrameView final
return std::move(start_of_lifecycle_tasks_);
}
+ // Called when the "dominant visible" status has changed for a
+ // HTMLVideoElement in the page. "dominant visible" means the element is
+ // mostly filling the viewport.
+ void NotifyVideoIsDominantVisibleStatus(HTMLVideoElement* element,
+ bool is_dominant);
+
+ bool HasDominantVideoElement() const;
+
+ PaintLayer* GetFullScreenOverlayLayer() const;
+
protected:
void FrameRectsChanged(const IntRect&) override;
void SelfVisibleChanged() override;
@@ -863,6 +863,9 @@ class CORE_EXPORT LocalFrameView final
WTF::Vector<const TransformPaintPropertyNode*> GetScrollTranslationNodes();
+ // Return the sticky-ad detector for this frame, creating it if necessary.
+ StickyAdDetector& EnsureStickyAdDetector();
+
LayoutSize size_;
typedef HashSet<scoped_refptr<LayoutEmbeddedObject>> EmbeddedObjectSet;
@@ -870,8 +873,6 @@ class CORE_EXPORT LocalFrameView final
Member<LocalFrame> frame_;
- DisplayShape display_shape_;
-
bool can_have_scrollbars_;
bool has_pending_layout_;
@@ -885,7 +886,7 @@ class CORE_EXPORT LocalFrameView final
TaskRunnerTimer<LocalFrameView> update_plugins_timer_;
bool first_layout_;
- bool use_dark_scheme_background_ = false;
+ bool use_color_adjust_background_ = false;
Color base_background_color_;
IntSize last_viewport_size_;
float last_zoom_factor_;
@@ -1008,6 +1009,8 @@ class CORE_EXPORT LocalFrameView final
HeapHashSet<WeakMember<LifecycleNotificationObserver>> lifecycle_observers_;
+ HeapHashSet<WeakMember<HTMLVideoElement>> fullscreen_video_elements_;
+
// If set, this indicates that the rendering throttling status for the local
// root frame has changed. In this scenario, if we have become unthrottled,
// this is a no-op since we run paint anyway. However, if we have become
@@ -1018,6 +1021,8 @@ class CORE_EXPORT LocalFrameView final
std::unique_ptr<OverlayInterstitialAdDetector>
overlay_interstitial_ad_detector_;
+ std::unique_ptr<StickyAdDetector> sticky_ad_detector_;
+
// These tasks will be run at the beginning of the next lifecycle.
WTF::Vector<base::OnceClosure> start_of_lifecycle_tasks_;
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_view_test.cc b/chromium/third_party/blink/renderer/core/frame/local_frame_view_test.cc
index 73c958ac79d..b82551f82de 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame_view_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame_view_test.cc
@@ -10,10 +10,12 @@
#include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h"
#include "third_party/blink/renderer/core/html/html_anchor_element.h"
#include "third_party/blink/renderer/core/html/html_element.h"
+#include "third_party/blink/renderer/core/html/html_iframe_element.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/paint/paint_property_tree_printer.h"
+#include "third_party/blink/renderer/core/paint/paint_timing.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
@@ -391,5 +393,169 @@ TEST_F(SimTest, ForcedLayoutWithIncompleteSVGChildFrame) {
svg_resource.Finish();
}
+TEST_F(LocalFrameViewTest, TogglePaintEligibility) {
+ SetBodyInnerHTML("<iframe><p>Hello</p></iframe>");
+
+ PaintTiming& parent_timing = PaintTiming::From(GetDocument());
+ PaintTiming& child_timing = PaintTiming::From(ChildDocument());
+
+ // Allow throttling.
+ DocumentLifecycle::AllowThrottlingScope throttling_scope(
+ GetDocument().Lifecycle());
+
+ // Mainframes are unthrottled by default.
+ EXPECT_FALSE(GetDocument().View()->ShouldThrottleRendering());
+ EXPECT_FALSE(parent_timing.FirstEligibleToPaint().is_null());
+
+ GetDocument().View()->MarkFirstEligibleToPaint();
+ EXPECT_FALSE(parent_timing.FirstEligibleToPaint().is_null());
+
+ // Subframes are throttled by default (when throttling is allowed).
+ EXPECT_TRUE(ChildDocument().View()->ShouldThrottleRendering());
+
+ // Toggle paint elgibility to true.
+ ChildDocument().View()->SetLifecycleUpdatesThrottledForTesting(
+ false /* throttled */);
+ ChildDocument().View()->UpdateRenderThrottlingStatus(
+ false /* hidden_for_throttling */, false /* subtree_throttled */);
+ ChildDocument().View()->MarkFirstEligibleToPaint();
+ EXPECT_FALSE(ChildDocument().View()->ShouldThrottleRendering());
+ EXPECT_FALSE(child_timing.FirstEligibleToPaint().is_null());
+
+ // Toggle paint elgibility to false.
+ ChildDocument().View()->SetLifecycleUpdatesThrottledForTesting(
+ true /* throttled */);
+ ChildDocument().View()->UpdateRenderThrottlingStatus(
+ true /* hidden_for_throttling */, true /* subtree_throttled */);
+ ChildDocument().View()->MarkIneligibleToPaint();
+ EXPECT_TRUE(ChildDocument().View()->ShouldThrottleRendering());
+ EXPECT_TRUE(child_timing.FirstEligibleToPaint().is_null());
+}
+
+TEST_F(SimTest, PaintEligibilityNoSubframe) {
+ SimRequest resource("https://example.com/", "text/html");
+
+ LoadURL("https://example.com/");
+ resource.Complete("<p>Hello</p>");
+
+ PaintTiming& timing = PaintTiming::From(GetDocument());
+
+ // Allow throttling.
+ DocumentLifecycle::AllowThrottlingScope throttling_scope(
+ GetDocument().Lifecycle());
+
+ EXPECT_FALSE(GetDocument().View()->ShouldThrottleRendering());
+ EXPECT_TRUE(timing.FirstEligibleToPaint().is_null());
+
+ Compositor().BeginFrame();
+
+ EXPECT_FALSE(GetDocument().View()->ShouldThrottleRendering());
+ EXPECT_FALSE(timing.FirstEligibleToPaint().is_null());
+}
+
+TEST_F(SimTest, SameOriginPaintEligibility) {
+ SimRequest resource("https://example.com/", "text/html");
+
+ LoadURL("https://example.com/");
+ resource.Complete(R"HTML(
+ <iframe id=frame top=4000px left=4000px>
+ <p>Hello</p>
+ </iframe>
+ )HTML");
+
+ auto* frame_element =
+ To<HTMLIFrameElement>(GetDocument().getElementById("frame"));
+ auto* frame_document = frame_element->contentDocument();
+ PaintTiming& frame_timing = PaintTiming::From(*frame_document);
+
+ // Allow throttling.
+ DocumentLifecycle::AllowThrottlingScope throttling_scope(
+ GetDocument().Lifecycle());
+
+ EXPECT_FALSE(GetDocument().View()->ShouldThrottleRendering());
+
+ // Same origin frames are not throttled.
+ EXPECT_FALSE(frame_document->View()->ShouldThrottleRendering());
+ EXPECT_TRUE(frame_timing.FirstEligibleToPaint().is_null());
+
+ Compositor().BeginFrame();
+
+ EXPECT_FALSE(GetDocument().View()->ShouldThrottleRendering());
+ EXPECT_FALSE(frame_document->View()->ShouldThrottleRendering());
+ EXPECT_FALSE(frame_timing.FirstEligibleToPaint().is_null());
+}
+
+TEST_F(SimTest, CrossOriginPaintEligibility) {
+ SimRequest resource("https://example.com/", "text/html");
+
+ LoadURL("https://example.com/");
+ resource.Complete(R"HTML(
+ <iframe id=frame srcdoc ="<p>Hello</p>" sandbox top=4000px left=4000px>
+ </iframe>
+ )HTML");
+
+ auto* frame_element =
+ To<HTMLIFrameElement>(GetDocument().getElementById("frame"));
+ auto* frame_document = frame_element->contentDocument();
+ PaintTiming& frame_timing = PaintTiming::From(*frame_document);
+
+ // Allow throttling.
+ DocumentLifecycle::AllowThrottlingScope throttling_scope(
+ GetDocument().Lifecycle());
+
+ EXPECT_FALSE(GetDocument().View()->ShouldThrottleRendering());
+
+ // Hidden cross origin frames are throttled.
+ EXPECT_TRUE(frame_document->View()->ShouldThrottleRendering());
+ EXPECT_TRUE(frame_timing.FirstEligibleToPaint().is_null());
+
+ Compositor().BeginFrame();
+
+ EXPECT_FALSE(GetDocument().View()->ShouldThrottleRendering());
+ EXPECT_TRUE(frame_document->View()->ShouldThrottleRendering());
+ EXPECT_TRUE(frame_timing.FirstEligibleToPaint().is_null());
+}
+
+TEST_F(SimTest, NestedCrossOriginPaintEligibility) {
+ // Create a document with doubly nested iframes.
+ SimRequest main_resource("https://example.com/", "text/html");
+ SimRequest frame_resource("https://example.com/iframe.html", "text/html");
+
+ LoadURL("https://example.com/");
+ main_resource.Complete("<iframe id=outer src=iframe.html></iframe>");
+ frame_resource.Complete(R"HTML(
+ <iframe id=inner srcdoc ="<p>Hello</p>" sandbox top=4000px left=4000px>
+ </iframe>
+ )HTML");
+
+ auto* outer_frame_element =
+ To<HTMLIFrameElement>(GetDocument().getElementById("outer"));
+ auto* outer_frame_document = outer_frame_element->contentDocument();
+ PaintTiming& outer_frame_timing = PaintTiming::From(*outer_frame_document);
+
+ auto* inner_frame_element =
+ To<HTMLIFrameElement>(outer_frame_document->getElementById("inner"));
+ auto* inner_frame_document = inner_frame_element->contentDocument();
+ PaintTiming& inner_frame_timing = PaintTiming::From(*inner_frame_document);
+
+ // Allow throttling.
+ DocumentLifecycle::AllowThrottlingScope throttling_scope(
+ GetDocument().Lifecycle());
+
+ EXPECT_FALSE(GetDocument().View()->ShouldThrottleRendering());
+ EXPECT_FALSE(outer_frame_document->View()->ShouldThrottleRendering());
+ EXPECT_TRUE(outer_frame_timing.FirstEligibleToPaint().is_null());
+ EXPECT_TRUE(inner_frame_document->View()->ShouldThrottleRendering());
+ EXPECT_TRUE(inner_frame_timing.FirstEligibleToPaint().is_null());
+
+ Compositor().BeginFrame();
+
+ EXPECT_FALSE(GetDocument().View()->ShouldThrottleRendering());
+ EXPECT_FALSE(outer_frame_document->View()->ShouldThrottleRendering());
+ EXPECT_FALSE(outer_frame_timing.FirstEligibleToPaint().is_null());
+ EXPECT_TRUE(inner_frame_document->View()->ShouldThrottleRendering());
+ EXPECT_TRUE(inner_frame_timing.FirstEligibleToPaint().is_null());
+}
+
} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/location.cc b/chromium/third_party/blink/renderer/core/frame/location.cc
index ec10b320410..43850e0f817 100644
--- a/chromium/third_party/blink/renderer/core/frame/location.cc
+++ b/chromium/third_party/blink/renderer/core/frame/location.cc
@@ -49,7 +49,7 @@ Location::Location(DOMWindow* dom_window)
: dom_window_(dom_window),
fragment_directive_(MakeGarbageCollected<FragmentDirective>()) {}
-void Location::Trace(Visitor* visitor) {
+void Location::Trace(Visitor* visitor) const {
visitor->Trace(dom_window_);
visitor->Trace(fragment_directive_);
ScriptWrappable::Trace(visitor);
@@ -243,14 +243,14 @@ void Location::reload() {
}
void Location::SetLocation(const String& url,
- LocalDOMWindow* current_window,
+ LocalDOMWindow* incumbent_window,
LocalDOMWindow* entered_window,
ExceptionState* exception_state,
SetLocationPolicy set_location_policy) {
if (!IsAttached())
return;
- if (!current_window->GetFrame())
+ if (!incumbent_window->GetFrame())
return;
Document* entered_document = entered_window->document();
@@ -261,8 +261,8 @@ void Location::SetLocation(const String& url,
if (completed_url.IsNull())
return;
- if (!current_window->GetFrame()->CanNavigate(*dom_window_->GetFrame(),
- completed_url)) {
+ if (!incumbent_window->GetFrame()->CanNavigate(*dom_window_->GetFrame(),
+ completed_url)) {
if (exception_state) {
exception_state->ThrowSecurityError(
"The current window does not have permission to navigate the target "
@@ -282,14 +282,13 @@ void Location::SetLocation(const String& url,
// URLs. Although the spec states we should perform this check on task
// execution, there are concerns about the correctness of that statement,
// see http://github.com/whatwg/html/issues/2591.
- Document* current_document = current_window->document();
- if (current_document && completed_url.ProtocolIsJavaScript()) {
+ if (completed_url.ProtocolIsJavaScript()) {
String script_source = DecodeURLEscapeSequences(
completed_url.GetString(), DecodeURLMode::kUTF8OrIsomorphic);
- if (!current_document->GetContentSecurityPolicyForWorld()->AllowInline(
+ if (!incumbent_window->GetContentSecurityPolicyForWorld()->AllowInline(
ContentSecurityPolicy::InlineType::kNavigation,
nullptr /* element */, script_source, String() /* nonce */,
- current_document->Url(), OrdinalNumber())) {
+ incumbent_window->Url(), OrdinalNumber())) {
return;
}
}
@@ -305,14 +304,14 @@ void Location::SetLocation(const String& url,
activity_logger->LogEvent("blinkSetAttribute", argv.size(), argv.data());
}
- FrameLoadRequest request(current_window->document(),
+ FrameLoadRequest request(incumbent_window->document(),
ResourceRequest(completed_url));
request.SetClientRedirectReason(ClientNavigationReason::kFrameNavigation);
WebFrameLoadType frame_load_type = WebFrameLoadType::kStandard;
if (set_location_policy == SetLocationPolicy::kReplaceThisFrame)
frame_load_type = WebFrameLoadType::kReplaceCurrentItem;
- current_window->GetFrame()->MaybeLogAdClickNavigation();
+ incumbent_window->GetFrame()->MaybeLogAdClickNavigation();
dom_window_->GetFrame()->Navigate(request, frame_load_type);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/location.h b/chromium/third_party/blink/renderer/core/frame/location.h
index 64013637445..906d4002e77 100644
--- a/chromium/third_party/blink/renderer/core/frame/location.h
+++ b/chromium/third_party/blink/renderer/core/frame/location.h
@@ -92,7 +92,7 @@ class CORE_EXPORT Location final : public ScriptWrappable {
String toString() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Note: it is only valid to call this if this is a Location object for a
@@ -106,7 +106,7 @@ class CORE_EXPORT Location final : public ScriptWrappable {
// ensure we use the correct Javascript world for CSP checks.
enum class SetLocationPolicy { kNormal, kReplaceThisFrame };
void SetLocation(const String&,
- LocalDOMWindow* current_window,
+ LocalDOMWindow* incumbent_window,
LocalDOMWindow* entered_window,
ExceptionState* = nullptr,
SetLocationPolicy = SetLocationPolicy::kNormal);
diff --git a/chromium/third_party/blink/renderer/core/frame/mhtml_loading_test.cc b/chromium/third_party/blink/renderer/core/frame/mhtml_loading_test.cc
index 2c22e859220..5476dc5d64b 100644
--- a/chromium/third_party/blink/renderer/core/frame/mhtml_loading_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/mhtml_loading_test.cc
@@ -116,8 +116,8 @@ TEST_F(MHTMLLoadingTest, EnforceSandboxFlags) {
ASSERT_TRUE(GetPage());
LocalFrame* frame = To<LocalFrame>(GetPage()->MainFrame());
ASSERT_TRUE(frame);
- Document* document = frame->GetDocument();
- ASSERT_TRUE(document);
+ LocalDOMWindow* window = frame->DomWindow();
+ ASSERT_TRUE(window);
// Full sandboxing with the exception to new top-level windows should be
// turned on.
@@ -125,36 +125,36 @@ TEST_F(MHTMLLoadingTest, EnforceSandboxFlags) {
~(network::mojom::blink::WebSandboxFlags::kPopups |
network::mojom::blink::WebSandboxFlags::
kPropagatesToAuxiliaryBrowsingContexts),
- document->GetSandboxFlags());
+ window->GetSandboxFlags());
// MHTML document should be loaded into unique origin.
- EXPECT_TRUE(document->GetSecurityOrigin()->IsOpaque());
+ EXPECT_TRUE(window->GetSecurityOrigin()->IsOpaque());
// Script execution should be disabled.
- EXPECT_FALSE(document->CanExecuteScripts(kNotAboutToExecuteScript));
+ EXPECT_FALSE(window->CanExecuteScripts(kNotAboutToExecuteScript));
// The element to be created by the script is not there.
- EXPECT_FALSE(document->getElementById("mySpan"));
+ EXPECT_FALSE(window->document()->getElementById("mySpan"));
// Make sure the subframe is also sandboxed.
LocalFrame* child_frame =
To<LocalFrame>(GetPage()->MainFrame()->Tree().FirstChild());
ASSERT_TRUE(child_frame);
- Document* child_document = child_frame->GetDocument();
- ASSERT_TRUE(child_document);
+ LocalDOMWindow* child_window = child_frame->DomWindow();
+ ASSERT_TRUE(child_window);
EXPECT_EQ(network::mojom::blink::WebSandboxFlags::kAll &
~(network::mojom::blink::WebSandboxFlags::kPopups |
network::mojom::blink::WebSandboxFlags::
kPropagatesToAuxiliaryBrowsingContexts),
- child_document->GetSandboxFlags());
+ child_window->GetSandboxFlags());
// MHTML document should be loaded into unique origin.
- EXPECT_TRUE(child_document->GetSecurityOrigin()->IsOpaque());
+ EXPECT_TRUE(child_window->GetSecurityOrigin()->IsOpaque());
// Script execution should be disabled.
- EXPECT_FALSE(child_document->CanExecuteScripts(kNotAboutToExecuteScript));
+ EXPECT_FALSE(child_window->CanExecuteScripts(kNotAboutToExecuteScript));
// The element to be created by the script is not there.
- EXPECT_FALSE(child_document->getElementById("mySpan"));
+ EXPECT_FALSE(child_window->document()->getElementById("mySpan"));
}
TEST_F(MHTMLLoadingTest, EnforceSandboxFlagsInXSLT) {
@@ -164,8 +164,8 @@ TEST_F(MHTMLLoadingTest, EnforceSandboxFlagsInXSLT) {
ASSERT_TRUE(GetPage());
LocalFrame* frame = To<LocalFrame>(GetPage()->MainFrame());
ASSERT_TRUE(frame);
- Document* document = frame->GetDocument();
- ASSERT_TRUE(document);
+ LocalDOMWindow* window = frame->DomWindow();
+ ASSERT_TRUE(window);
// Full sandboxing with the exception to new top-level windows should be
// turned on.
@@ -173,12 +173,12 @@ TEST_F(MHTMLLoadingTest, EnforceSandboxFlagsInXSLT) {
~(network::mojom::blink::WebSandboxFlags::kPopups |
network::mojom::blink::WebSandboxFlags::
kPropagatesToAuxiliaryBrowsingContexts),
- document->GetSandboxFlags());
+ window->GetSandboxFlags());
// MHTML document should be loaded into unique origin.
- EXPECT_TRUE(document->GetSecurityOrigin()->IsOpaque());
+ EXPECT_TRUE(window->GetSecurityOrigin()->IsOpaque());
// Script execution should be disabled.
- EXPECT_FALSE(document->CanExecuteScripts(kNotAboutToExecuteScript));
+ EXPECT_FALSE(window->CanExecuteScripts(kNotAboutToExecuteScript));
}
TEST_F(MHTMLLoadingTest, ShadowDom) {
diff --git a/chromium/third_party/blink/renderer/core/frame/navigation_rate_limiter.cc b/chromium/third_party/blink/renderer/core/frame/navigation_rate_limiter.cc
index c46a968b9a4..768fe10160a 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigation_rate_limiter.cc
+++ b/chromium/third_party/blink/renderer/core/frame/navigation_rate_limiter.cc
@@ -16,7 +16,7 @@ NavigationRateLimiter::NavigationRateLimiter(Frame& frame)
time_first_count_(base::TimeTicks::Now()),
enabled(frame_->GetSettings()->GetShouldProtectAgainstIpcFlooding()) {}
-void NavigationRateLimiter::Trace(Visitor* visitor) {
+void NavigationRateLimiter::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/navigation_rate_limiter.h b/chromium/third_party/blink/renderer/core/frame/navigation_rate_limiter.h
index 41568264e30..7ff7bc349ed 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigation_rate_limiter.h
+++ b/chromium/third_party/blink/renderer/core/frame/navigation_rate_limiter.h
@@ -26,7 +26,7 @@ class NavigationRateLimiter final {
// is allowed to proceed.
bool CanProceed();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<Frame> frame_;
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator.cc b/chromium/third_party/blink/renderer/core/frame/navigator.cc
index 8918712cc0a..b9eb3a925a3 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator.cc
+++ b/chromium/third_party/blink/renderer/core/frame/navigator.cc
@@ -39,8 +39,9 @@
namespace blink {
Navigator::Navigator(LocalFrame* frame)
- : NavigatorLanguage(frame ? frame->DomWindow() : nullptr),
- ExecutionContextClient(frame) {}
+ : ExecutionContextClient(frame),
+ NavigatorDeviceMemory(frame ? frame->GetDocument() : nullptr),
+ NavigatorLanguage(frame ? frame->DomWindow() : nullptr) {}
String Navigator::productSub() const {
return "20030107";
@@ -114,11 +115,12 @@ String Navigator::GetAcceptLanguages() {
return accept_languages;
}
-void Navigator::Trace(Visitor* visitor) {
+void Navigator::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
NavigatorLanguage::Trace(visitor);
ExecutionContextClient::Trace(visitor);
Supplementable<Navigator>::Trace(visitor);
+ NavigatorDeviceMemory::Trace(visitor);
}
ExecutionContext* Navigator::GetUAExecutionContext() const {
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator.h b/chromium/third_party/blink/renderer/core/frame/navigator.h
index 4a4dd79a03f..ad4589f7e72 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator.h
+++ b/chromium/third_party/blink/renderer/core/frame/navigator.h
@@ -39,13 +39,13 @@ namespace blink {
class LocalFrame;
class CORE_EXPORT Navigator final : public ScriptWrappable,
+ public ExecutionContextClient,
public NavigatorConcurrentHardware,
public NavigatorDeviceMemory,
public NavigatorID,
public NavigatorLanguage,
public NavigatorOnLine,
public NavigatorUA,
- public ExecutionContextClient,
public Supplementable<Navigator> {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(Navigator);
@@ -69,7 +69,7 @@ class CORE_EXPORT Navigator final : public ScriptWrappable,
UserAgentMetadata GetUserAgentMetadata() const override;
void SetUserAgentMetadataForTesting(UserAgentMetadata);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
ExecutionContext* GetUAExecutionContext() const override;
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_device_memory.cc b/chromium/third_party/blink/renderer/core/frame/navigator_device_memory.cc
index 90cfd199881..1add37e4515 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator_device_memory.cc
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_device_memory.cc
@@ -5,11 +5,33 @@
#include "third_party/blink/renderer/core/frame/navigator_device_memory.h"
#include "third_party/blink/public/common/device_memory/approximated_device_memory.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
+#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-shared.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
namespace blink {
+NavigatorDeviceMemory::NavigatorDeviceMemory(Document* document)
+ : document_(document) {}
+
float NavigatorDeviceMemory::deviceMemory() const {
- return ApproximatedDeviceMemory::GetApproximatedDeviceMemory();
+ float result = ApproximatedDeviceMemory::GetApproximatedDeviceMemory();
+ if (document_) {
+ IdentifiabilityMetricBuilder(
+ base::UkmSourceId::FromInt64(document_->UkmSourceID()))
+ .Set(IdentifiableSurface::FromTypeAndInput(
+ IdentifiableSurface::Type::kWebFeature,
+ static_cast<uint64_t>(WebFeature::kNavigatorDeviceMemory)),
+ IdentifiabilityDigestHelper(result))
+ .Record(document_->UkmRecorder());
+ }
+ return result;
+}
+
+void NavigatorDeviceMemory::Trace(Visitor* visitor) const {
+ visitor->Trace(document_);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_device_memory.h b/chromium/third_party/blink/renderer/core/frame/navigator_device_memory.h
index db0df64655d..1f5e86f26b5 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator_device_memory.h
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_device_memory.h
@@ -6,12 +6,19 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_DEVICE_MEMORY_H_
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/dom/document.h"
namespace blink {
-class CORE_EXPORT NavigatorDeviceMemory {
+class CORE_EXPORT NavigatorDeviceMemory : public GarbageCollectedMixin {
public:
+ explicit NavigatorDeviceMemory();
+ explicit NavigatorDeviceMemory(Document* document);
float deviceMemory() const;
+ void Trace(Visitor*) const override;
+
+ private:
+ WeakMember<Document> document_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_language.cc b/chromium/third_party/blink/renderer/core/frame/navigator_language.cc
index 061e738dfb9..14883715ff9 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator_language.cc
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_language.cc
@@ -95,7 +95,7 @@ void NavigatorLanguage::EnsureUpdatedLanguage() {
}
}
-void NavigatorLanguage::Trace(Visitor* visitor) {
+void NavigatorLanguage::Trace(Visitor* visitor) const {
visitor->Trace(execution_context_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_language.h b/chromium/third_party/blink/renderer/core/frame/navigator_language.h
index f122170940b..0f9c5d11d9a 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator_language.h
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_language.h
@@ -24,7 +24,7 @@ class CORE_EXPORT NavigatorLanguage : public GarbageCollectedMixin {
// Accepts a comma-separated list of languages.
void SetLanguagesForTesting(const String& languages);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
virtual String GetAcceptLanguages() = 0;
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.cc b/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.cc
index 84f746ac71b..7c1b21cc2bc 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.cc
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.cc
@@ -29,7 +29,7 @@ Scheduling* NavigatorScheduling::scheduling() {
return scheduling_;
}
-void NavigatorScheduling::Trace(Visitor* visitor) {
+void NavigatorScheduling::Trace(Visitor* visitor) const {
visitor->Trace(scheduling_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.h b/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.h
index ac4caf75fb3..4ec994eb5cb 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.h
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_scheduling.h
@@ -26,7 +26,7 @@ class CORE_EXPORT NavigatorScheduling final
explicit NavigatorScheduling(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
static NavigatorScheduling& From(Navigator&);
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_ua_data.cc b/chromium/third_party/blink/renderer/core/frame/navigator_ua_data.cc
index 050c34a84ae..e2a5e3598fb 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator_ua_data.cc
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_ua_data.cc
@@ -104,7 +104,7 @@ ScriptPromise NavigatorUAData::getHighEntropyValues(
return promise;
}
-void NavigatorUAData::Trace(Visitor* visitor) {
+void NavigatorUAData::Trace(Visitor* visitor) const {
visitor->Trace(brand_set_);
visitor->Trace(empty_brand_set_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_ua_data.h b/chromium/third_party/blink/renderer/core/frame/navigator_ua_data.h
index e14afb7d942..38e91f75940 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator_ua_data.h
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_ua_data.h
@@ -40,7 +40,7 @@ class NavigatorUAData : public ScriptWrappable, ExecutionContextClient {
bool mobile() const;
ScriptPromise getHighEntropyValues(ScriptState*, Vector<String>&) const;
- void Trace(Visitor* visitor) final;
+ void Trace(Visitor* visitor) const final;
private:
HeapVector<Member<NavigatorUABrandVersion>> brand_set_;
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_user_activation.cc b/chromium/third_party/blink/renderer/core/frame/navigator_user_activation.cc
index 6d62537d078..16ca16fee40 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator_user_activation.cc
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_user_activation.cc
@@ -30,7 +30,7 @@ UserActivation* NavigatorUserActivation::userActivation() {
return user_activation_;
}
-void NavigatorUserActivation::Trace(Visitor* visitor) {
+void NavigatorUserActivation::Trace(Visitor* visitor) const {
visitor->Trace(user_activation_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_user_activation.h b/chromium/third_party/blink/renderer/core/frame/navigator_user_activation.h
index 229091242b6..13ae605d54f 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator_user_activation.h
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_user_activation.h
@@ -26,7 +26,7 @@ class CORE_EXPORT NavigatorUserActivation final
explicit NavigatorUserActivation(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
static NavigatorUserActivation& From(Navigator&);
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_user_activation.idl b/chromium/third_party/blink/renderer/core/frame/navigator_user_activation.idl
index 92a7bc2f0e6..2f7ea2a631c 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator_user_activation.idl
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_user_activation.idl
@@ -4,8 +4,7 @@
// https://github.com/dtapuska/useractivation
[
- ImplementedAs=NavigatorUserActivation,
- RuntimeEnabled=UserActivationAPI
+ ImplementedAs=NavigatorUserActivation
] partial interface Navigator {
// User activation
readonly attribute UserActivation userActivation;
diff --git a/chromium/third_party/blink/renderer/core/frame/overlay_interstitial_ad_detector.cc b/chromium/third_party/blink/renderer/core/frame/overlay_interstitial_ad_detector.cc
index 9d343f2fded..d2253eb1f95 100644
--- a/chromium/third_party/blink/renderer/core/frame/overlay_interstitial_ad_detector.cc
+++ b/chromium/third_party/blink/renderer/core/frame/overlay_interstitial_ad_detector.cc
@@ -11,7 +11,7 @@
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_object_inlines.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
-#include "third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h"
+#include "third_party/blink/renderer/core/paint/paint_timing.h"
#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
namespace blink {
@@ -21,31 +21,13 @@ namespace {
constexpr base::TimeDelta kFireInterval = base::TimeDelta::FromSeconds(1);
constexpr double kLargeAdSizeToViewportSizeThreshold = 0.1;
-bool IsIframeAd(Element* element) {
- HTMLFrameOwnerElement* frame_owner_element =
- DynamicTo<HTMLFrameOwnerElement>(element);
- if (!frame_owner_element)
- return false;
-
- Frame* frame = frame_owner_element->ContentFrame();
- return frame && frame->IsAdSubframe();
-}
-
-bool IsImageAd(Element* element) {
- HTMLImageElement* image_element = DynamicTo<HTMLImageElement>(element);
- if (!image_element)
- return false;
-
- return image_element->IsAdRelated();
-}
-
// An overlay interstitial element shouldn't move with scrolling and should be
// able to overlap with other contents. So, either:
// 1) one of its container ancestors (including itself) has fixed position.
// 2) <body> or <html> has style="overflow:hidden", and among its container
// ancestors (including itself), the 2nd to the top (where the top should always
// be the <body>) has absolute position.
-bool IsImmobileAndCanOverlapWithOtherContent(Element* element) {
+bool IsOverlayCandidate(Element* element) {
const ComputedStyle* style = nullptr;
LayoutView* layout_view = element->GetDocument().GetLayoutView();
LayoutObject* object = element->GetLayoutObject();
@@ -72,123 +54,148 @@ bool IsImmobileAndCanOverlapWithOtherContent(Element* element) {
return false;
}
-bool IsOverlayAdCandidate(Element* element) {
- return (IsIframeAd(element) || IsImageAd(element)) &&
- IsImmobileAndCanOverlapWithOtherContent(element);
-}
-
} // namespace
void OverlayInterstitialAdDetector::MaybeFireDetection(LocalFrame* main_frame) {
DCHECK(main_frame);
DCHECK(main_frame->IsMainFrame());
- if (done_detection_)
+ if (popup_ad_detected_)
return;
DCHECK(main_frame->GetDocument());
DCHECK(main_frame->ContentLayoutObject());
+ // Skip any measurement before the FCP.
+ if (PaintTiming::From(*main_frame->GetDocument())
+ .FirstContentfulPaint()
+ .is_null()) {
+ return;
+ }
+
base::Time current_time = base::Time::Now();
+ if (started_detection_ && current_time < last_detection_time_ + kFireInterval)
+ return;
- if (!started_detection_ ||
- current_time - last_detection_time_ >= kFireInterval) {
- IntSize main_frame_size = main_frame->GetMainFrameViewportSize();
-
- if (started_detection_ &&
- main_frame_size != last_detection_main_frame_size_) {
- // Reset the candidate when the the viewport size has changed. Changing
- // the viewport size could influence the layout and may trick the detector
- // into believing that an element appeared and was dismissed, but what
- // could have happened is that the element no longer covers the center,
- // but still exists (e.g. a sticky ad at the top).
- candidate_id_ = kInvalidDOMNodeId;
- }
+ TRACE_EVENT0("blink,benchmark",
+ "OverlayInterstitialAdDetector::MaybeFireDetection");
- HitTestLocation location(DoublePoint(main_frame_size.Width() / 2.0,
- main_frame_size.Height() / 2.0));
- HitTestResult result;
- main_frame->ContentLayoutObject()->HitTestNoLifecycleUpdate(location,
- result);
- started_detection_ = true;
+ started_detection_ = true;
+ last_detection_time_ = current_time;
- last_detection_time_ = current_time;
- last_detection_main_frame_size_ = main_frame_size;
+ IntSize main_frame_size = main_frame->GetMainFrameViewportSize();
+ last_detection_main_frame_size_ = main_frame_size;
- Element* element = result.InnerElement();
- if (!element)
- return;
+ if (main_frame_size != last_detection_main_frame_size_) {
+ // Reset the candidate when the the viewport size has changed. Changing
+ // the viewport size could influence the layout and may trick the detector
+ // into believing that an element appeared and was dismissed, but what
+ // could have happened is that the element no longer covers the center,
+ // but still exists (e.g. a sticky ad at the top).
+ candidate_id_ = kInvalidDOMNodeId;
+ }
+
+ // We want to explicitly prevent mid-roll ads from being categorized as
+ // pop-ups. Skip the detection if we are in the middle of a video play.
+ if (main_frame->View()->HasDominantVideoElement())
+ return;
- DOMNodeId element_id = DOMNodeIds::IdForNode(element);
-
- bool is_new_element = (element_id != candidate_id_);
-
- if (is_new_element && candidate_id_ != kInvalidDOMNodeId) {
- // If the main frame scrolling offset hasn't changed since the candidate's
- // appearance, we consider it to be a overlay interstitial; otherwise, we
- // skip that candidate because it could be a parallax/scroller ad.
- if (main_frame->GetMainFrameScrollOffset().Y() ==
- candidate_start_main_frame_scroll_offset_) {
- OnPopupAdDetected(main_frame);
- return;
- }
- last_unqualified_element_id_ = candidate_id_;
- candidate_id_ = kInvalidDOMNodeId;
+ HitTestLocation location(DoublePoint(main_frame_size.Width() / 2.0,
+ main_frame_size.Height() / 2.0));
+ HitTestResult result;
+ main_frame->ContentLayoutObject()->HitTestNoLifecycleUpdate(location, result);
+
+ Element* element = result.InnerElement();
+ if (!element)
+ return;
+
+ DOMNodeId element_id = DOMNodeIds::IdForNode(element);
+
+ // Skip considering the overlay for a pop-up candidate if we haven't seen or
+ // have just seen the first meaningful paint. If we have just seen the first
+ // meaningful paint, however, we would consider future overlays for pop-up
+ // candidates.
+ if (!main_content_has_loaded_) {
+ if (!PaintTiming::From(*main_frame->GetDocument())
+ .FirstMeaningfulPaint()
+ .is_null()) {
+ main_content_has_loaded_ = true;
}
- if (!is_new_element)
- return;
+ last_unqualified_element_id_ = element_id;
+ return;
+ }
- if (element_id == last_unqualified_element_id_)
- return;
+ bool is_new_element = (element_id != candidate_id_);
- if (!element->GetLayoutObject())
- return;
+ // The popup candidate has just been dismissed.
+ if (is_new_element && candidate_id_ != kInvalidDOMNodeId) {
+ // If the main frame scrolling offset hasn't changed since the candidate's
+ // appearance, we consider it to be a overlay interstitial; otherwise, we
+ // skip that candidate because it could be a parallax/scroller ad.
+ if (main_frame->GetMainFrameScrollOffset().Y() ==
+ candidate_start_main_frame_scroll_offset_) {
+ OnPopupDetected(main_frame, candidate_is_ad_);
+ }
- // Skip considering the overlay for a pop-up candidate if we haven't seen or
- // have just seen the first meaningful paint. If we have just seen the first
- // meaningful paint, however, we would consider future overlays for pop-up
- // candidates.
- if (!main_content_has_loaded_) {
- if (FirstMeaningfulPaintDetector::From(*(main_frame->GetDocument()))
- .SeenFirstMeaningfulPaint()) {
- main_content_has_loaded_ = true;
- }
- last_unqualified_element_id_ = element_id;
+ if (popup_ad_detected_)
return;
- }
- IntRect overlay_rect =
- element->GetLayoutObject()->AbsoluteBoundingBoxRect();
-
- bool is_large =
- !overlay_rect.IsEmpty() &&
- (overlay_rect.Size().Area() >
- main_frame_size.Area() * kLargeAdSizeToViewportSizeThreshold);
-
- bool has_gesture = LocalFrame::HasTransientUserActivation(main_frame);
-
- if (!has_gesture && is_large && IsOverlayAdCandidate(element)) {
- // If main page is not scrollable, immediately determinine the overlay
- // to be a popup. There's is no need to check any state at the dismissal
- // time.
- if (!main_frame->GetDocument()
- ->GetLayoutView()
- ->HasScrollableOverflowY()) {
- OnPopupAdDetected(main_frame);
- return;
- }
- candidate_id_ = element_id;
- candidate_start_main_frame_scroll_offset_ =
- main_frame->GetMainFrameScrollOffset().Y();
- } else {
- last_unqualified_element_id_ = element_id;
+ last_unqualified_element_id_ = candidate_id_;
+ candidate_id_ = kInvalidDOMNodeId;
+ candidate_is_ad_ = false;
+ }
+
+ if (!is_new_element)
+ return;
+
+ if (element_id == last_unqualified_element_id_)
+ return;
+
+ if (!element->GetLayoutObject())
+ return;
+
+ IntRect overlay_rect = element->GetLayoutObject()->AbsoluteBoundingBoxRect();
+
+ bool is_large =
+ (overlay_rect.Size().Area() >
+ main_frame_size.Area() * kLargeAdSizeToViewportSizeThreshold);
+
+ bool has_gesture = LocalFrame::HasTransientUserActivation(main_frame);
+ bool is_ad = element->IsAdRelated();
+
+ if (!has_gesture && is_large && (!popup_detected_ || is_ad) &&
+ IsOverlayCandidate(element)) {
+ // If main page is not scrollable, immediately determinine the overlay
+ // to be a popup. There's is no need to check any state at the dismissal
+ // time.
+ if (!main_frame->GetDocument()->GetLayoutView()->HasScrollableOverflowY()) {
+ OnPopupDetected(main_frame, is_ad);
}
+
+ if (popup_ad_detected_)
+ return;
+
+ candidate_id_ = element_id;
+ candidate_is_ad_ = is_ad;
+ candidate_start_main_frame_scroll_offset_ =
+ main_frame->GetMainFrameScrollOffset().Y();
+ } else {
+ last_unqualified_element_id_ = element_id;
}
}
-void OverlayInterstitialAdDetector::OnPopupAdDetected(LocalFrame* main_frame) {
- UseCounter::Count(main_frame->GetDocument(), WebFeature::kOverlayPopupAd);
- done_detection_ = true;
+void OverlayInterstitialAdDetector::OnPopupDetected(LocalFrame* main_frame,
+ bool is_ad) {
+ if (!popup_detected_) {
+ UseCounter::Count(main_frame->GetDocument(), WebFeature::kOverlayPopup);
+ popup_detected_ = true;
+ }
+
+ if (is_ad) {
+ DCHECK(!popup_ad_detected_);
+ UseCounter::Count(main_frame->GetDocument(), WebFeature::kOverlayPopupAd);
+ popup_ad_detected_ = true;
+ }
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/overlay_interstitial_ad_detector.h b/chromium/third_party/blink/renderer/core/frame/overlay_interstitial_ad_detector.h
index e3a2bb379a2..095a8b694db 100644
--- a/chromium/third_party/blink/renderer/core/frame/overlay_interstitial_ad_detector.h
+++ b/chromium/third_party/blink/renderer/core/frame/overlay_interstitial_ad_detector.h
@@ -38,6 +38,9 @@ class LocalFrame;
// count it as an overlay pop-up; otherwise, we skip that candidate because it
// could be a parallax/scroller ad.
//
+// Besides, we explicitly prevent mid-roll ads (during a video play) from being
+// categorized as pop-ups.
+//
// We could potentially miss some true positive cases: the user could click at
// an empty space which activates the user gesture, and coincidentally the
// pop-up automatically shows up; the user could make some scrolling
@@ -49,9 +52,10 @@ class CORE_EXPORT OverlayInterstitialAdDetector {
~OverlayInterstitialAdDetector() = default;
void MaybeFireDetection(LocalFrame* main_frame);
- void OnPopupAdDetected(LocalFrame* main_frame);
private:
+ void OnPopupDetected(LocalFrame* main_frame, bool is_ad);
+
bool started_detection_ = false;
bool main_content_has_loaded_ = false;
@@ -60,6 +64,7 @@ class CORE_EXPORT OverlayInterstitialAdDetector {
IntSize last_detection_main_frame_size_;
DOMNodeId candidate_id_;
+ bool candidate_is_ad_ = false;
// The following members are valid only when |candidate_| is not nullptr.
int candidate_start_main_frame_scroll_offset_ = 0;
@@ -78,7 +83,8 @@ class CORE_EXPORT OverlayInterstitialAdDetector {
// can skip it on its next occurrence without computing the style again.
DOMNodeId last_unqualified_element_id_;
- bool done_detection_ = false;
+ bool popup_detected_ = false;
+ bool popup_ad_detected_ = false;
DISALLOW_COPY_AND_ASSIGN(OverlayInterstitialAdDetector);
};
diff --git a/chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.cc b/chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.cc
index 4f303ba6317..f1b6c81c684 100644
--- a/chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.cc
+++ b/chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.cc
@@ -47,7 +47,7 @@ PageScaleConstraintsSet::PageScaleConstraintsSet(Page* page)
needs_reset_(false),
constraints_dirty_(false) {}
-void PageScaleConstraintsSet::Trace(Visitor* visitor) {
+void PageScaleConstraintsSet::Trace(Visitor* visitor) const {
visitor->Trace(page_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.h b/chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.h
index 641e88a1ec6..c9813566623 100644
--- a/chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.h
+++ b/chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.h
@@ -53,7 +53,7 @@ class CORE_EXPORT PageScaleConstraintsSet
public:
explicit PageScaleConstraintsSet(Page* page);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void SetDefaultConstraints(const PageScaleConstraints&);
const PageScaleConstraints& DefaultConstraints() const;
diff --git a/chromium/third_party/blink/renderer/core/frame/pausable_script_executor.cc b/chromium/third_party/blink/renderer/core/frame/pausable_script_executor.cc
index 8a5f658b7ea..dba36726da5 100644
--- a/chromium/third_party/blink/renderer/core/frame/pausable_script_executor.cc
+++ b/chromium/third_party/blink/renderer/core/frame/pausable_script_executor.cc
@@ -36,7 +36,7 @@ class WebScriptExecutor : public PausableScriptExecutor::Executor {
Vector<v8::Local<v8::Value>> Execute(LocalFrame*) override;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(sources_);
PausableScriptExecutor::Executor::Trace(visitor);
}
@@ -85,7 +85,7 @@ class V8FunctionExecutor : public PausableScriptExecutor::Executor {
Vector<v8::Local<v8::Value>> Execute(LocalFrame*) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
TraceWrapperV8Reference<v8::Function> function_;
@@ -125,7 +125,7 @@ Vector<v8::Local<v8::Value>> V8FunctionExecutor::Execute(LocalFrame* frame) {
return results;
}
-void V8FunctionExecutor::Trace(Visitor* visitor) {
+void V8FunctionExecutor::Trace(Visitor* visitor) const {
visitor->Trace(function_);
visitor->Trace(receiver_);
visitor->Trace(args_);
@@ -261,7 +261,7 @@ void PausableScriptExecutor::Dispose() {
task_handle_.Cancel();
}
-void PausableScriptExecutor::Trace(Visitor* visitor) {
+void PausableScriptExecutor::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(executor_);
ExecutionContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/frame/pausable_script_executor.h b/chromium/third_party/blink/renderer/core/frame/pausable_script_executor.h
index 6c3444de353..dd46694ebb8 100644
--- a/chromium/third_party/blink/renderer/core/frame/pausable_script_executor.h
+++ b/chromium/third_party/blink/renderer/core/frame/pausable_script_executor.h
@@ -44,7 +44,7 @@ class CORE_EXPORT PausableScriptExecutor final
virtual Vector<v8::Local<v8::Value>> Execute(LocalFrame*) = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
PausableScriptExecutor(LocalFrame*,
@@ -62,7 +62,7 @@ class CORE_EXPORT PausableScriptExecutor final
void RunAsync(BlockingOption);
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
diff --git a/chromium/third_party/blink/renderer/core/frame/performance_monitor.cc b/chromium/third_party/blink/renderer/core/frame/performance_monitor.cc
index 14e9d641b5e..f12e4c18788 100644
--- a/chromium/third_party/blink/renderer/core/frame/performance_monitor.cc
+++ b/chromium/third_party/blink/renderer/core/frame/performance_monitor.cc
@@ -342,7 +342,7 @@ void PerformanceMonitor::InnerReportGenericViolation(
}
}
-void PerformanceMonitor::Trace(Visitor* visitor) {
+void PerformanceMonitor::Trace(Visitor* visitor) const {
visitor->Trace(local_root_);
visitor->Trace(task_execution_context_);
visitor->Trace(subscriptions_);
diff --git a/chromium/third_party/blink/renderer/core/frame/performance_monitor.h b/chromium/third_party/blink/renderer/core/frame/performance_monitor.h
index eadc7cf8495..65c410cea9f 100644
--- a/chromium/third_party/blink/renderer/core/frame/performance_monitor.h
+++ b/chromium/third_party/blink/renderer/core/frame/performance_monitor.h
@@ -63,7 +63,7 @@ class CORE_EXPORT PerformanceMonitor final
const String& text,
base::TimeDelta time,
SourceLocation*) {}
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
static void ReportGenericViolation(ExecutionContext*,
@@ -104,7 +104,7 @@ class CORE_EXPORT PerformanceMonitor final
explicit PerformanceMonitor(LocalFrame*);
~PerformanceMonitor() override;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
friend class PerformanceMonitorTest;
diff --git a/chromium/third_party/blink/renderer/core/frame/picture_in_picture_controller.cc b/chromium/third_party/blink/renderer/core/frame/picture_in_picture_controller.cc
index 71bcdc95faa..3d59f505142 100644
--- a/chromium/third_party/blink/renderer/core/frame/picture_in_picture_controller.cc
+++ b/chromium/third_party/blink/renderer/core/frame/picture_in_picture_controller.cc
@@ -41,7 +41,7 @@ bool PictureInPictureController::IsElementInPictureInPicture(
return controller && controller->IsPictureInPictureElement(element);
}
-void PictureInPictureController::Trace(Visitor* visitor) {
+void PictureInPictureController::Trace(Visitor* visitor) const {
Supplement<Document>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/picture_in_picture_controller.h b/chromium/third_party/blink/renderer/core/frame/picture_in_picture_controller.h
index 152a0eaa218..0167f41cf42 100644
--- a/chromium/third_party/blink/renderer/core/frame/picture_in_picture_controller.h
+++ b/chromium/third_party/blink/renderer/core/frame/picture_in_picture_controller.h
@@ -79,7 +79,7 @@ class CORE_EXPORT PictureInPictureController
// Notifies that one of the states used by Picture-in-Picture has changed.
virtual void OnPictureInPictureStateChange() = 0;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit PictureInPictureController(Document&);
diff --git a/chromium/third_party/blink/renderer/core/frame/platform_event_controller.cc b/chromium/third_party/blink/renderer/core/frame/platform_event_controller.cc
index 33f9529c925..55847480b8e 100644
--- a/chromium/third_party/blink/renderer/core/frame/platform_event_controller.cc
+++ b/chromium/third_party/blink/renderer/core/frame/platform_event_controller.cc
@@ -56,7 +56,7 @@ void PlatformEventController::PageVisibilityChanged() {
StopUpdating();
}
-void PlatformEventController::Trace(Visitor* visitor) {
+void PlatformEventController::Trace(Visitor* visitor) const {
visitor->Trace(window_);
PageVisibilityObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/platform_event_controller.h b/chromium/third_party/blink/renderer/core/frame/platform_event_controller.h
index d52c3c5f487..d72534ca1f6 100644
--- a/chromium/third_party/blink/renderer/core/frame/platform_event_controller.h
+++ b/chromium/third_party/blink/renderer/core/frame/platform_event_controller.h
@@ -28,7 +28,7 @@ class CORE_EXPORT PlatformEventController : public PageVisibilityObserver {
// This is called when new data becomes available.
virtual void DidUpdateData() = 0;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
LocalDOMWindow& GetWindow() const { return *window_; }
protected:
diff --git a/chromium/third_party/blink/renderer/core/frame/platform_event_dispatcher.cc b/chromium/third_party/blink/renderer/core/frame/platform_event_dispatcher.cc
index a84604b4dd9..415a59bf318 100644
--- a/chromium/third_party/blink/renderer/core/frame/platform_event_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/core/frame/platform_event_dispatcher.cc
@@ -62,7 +62,7 @@ void PlatformEventDispatcher::NotifyControllers() {
}
}
-void PlatformEventDispatcher::Trace(Visitor* visitor) {
+void PlatformEventDispatcher::Trace(Visitor* visitor) const {
visitor->Trace(controllers_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/platform_event_dispatcher.h b/chromium/third_party/blink/renderer/core/frame/platform_event_dispatcher.h
index 0cff75e29ee..916e5c44c71 100644
--- a/chromium/third_party/blink/renderer/core/frame/platform_event_dispatcher.h
+++ b/chromium/third_party/blink/renderer/core/frame/platform_event_dispatcher.h
@@ -33,7 +33,7 @@ class CORE_EXPORT PlatformEventDispatcher : public GarbageCollectedMixin {
// no more registered controllers.
void RemoveController(PlatformEventController*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
PlatformEventDispatcher();
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_dom_window.cc b/chromium/third_party/blink/renderer/core/frame/remote_dom_window.cc
index 22123570212..3085e3f0f4b 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_dom_window.cc
+++ b/chromium/third_party/blink/renderer/core/frame/remote_dom_window.cc
@@ -5,8 +5,8 @@
#include "third_party/blink/renderer/core/frame/remote_dom_window.h"
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/events/message_event.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/remote_frame_client.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -17,7 +17,7 @@ ExecutionContext* RemoteDOMWindow::GetExecutionContext() const {
return nullptr;
}
-void RemoteDOMWindow::Trace(Visitor* visitor) {
+void RemoteDOMWindow::Trace(Visitor* visitor) const {
DOMWindow::Trace(visitor);
}
@@ -34,7 +34,7 @@ void RemoteDOMWindow::FrameDetached() {
void RemoteDOMWindow::SchedulePostMessage(
MessageEvent* event,
scoped_refptr<const SecurityOrigin> target,
- Document* source) {
+ LocalDOMWindow* source) {
// To match same-process behavior, the IPC to forward postMessage
// cross-process should only be sent after the current script finishes
// running, to preserve relative ordering of IPCs. See
@@ -55,7 +55,7 @@ void RemoteDOMWindow::SchedulePostMessage(
void RemoteDOMWindow::ForwardPostMessage(
MessageEvent* event,
scoped_refptr<const SecurityOrigin> target,
- Document* source) {
+ LocalDOMWindow* source) {
// If the target frame was detached after the message was scheduled,
// don't deliver the message.
if (!GetFrame())
@@ -63,9 +63,9 @@ void RemoteDOMWindow::ForwardPostMessage(
base::Optional<base::UnguessableToken> agent_cluster;
if (event->IsLockedToAgentCluster())
- agent_cluster = source->GetExecutionContext()->GetAgentClusterID();
- GetFrame()->Client()->ForwardPostMessage(event, std::move(target),
- agent_cluster, source->GetFrame());
+ agent_cluster = source->GetAgentClusterID();
+ GetFrame()->ForwardPostMessage(event, agent_cluster, std::move(target),
+ source->GetFrame());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_dom_window.h b/chromium/third_party/blink/renderer/core/frame/remote_dom_window.h
index a88ca19aedd..eed4d8aece4 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_dom_window.h
+++ b/chromium/third_party/blink/renderer/core/frame/remote_dom_window.h
@@ -23,7 +23,7 @@ class RemoteDOMWindow final : public DOMWindow {
ExecutionContext* GetExecutionContext() const override;
// DOMWindow overrides:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void blur() override;
void FrameDetached();
@@ -32,7 +32,7 @@ class RemoteDOMWindow final : public DOMWindow {
// Protected DOMWindow overrides:
void SchedulePostMessage(MessageEvent*,
scoped_refptr<const SecurityOrigin> target,
- Document* source) override;
+ LocalDOMWindow* source) override;
private:
// Intentionally private to prevent redundant checks when the type is
@@ -42,7 +42,7 @@ class RemoteDOMWindow final : public DOMWindow {
void ForwardPostMessage(MessageEvent*,
scoped_refptr<const SecurityOrigin> target,
- Document* source);
+ LocalDOMWindow* source);
};
template <>
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame.cc b/chromium/third_party/blink/renderer/core/frame/remote_frame.cc
index 3c80fea603e..12574ce5ad2 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame.cc
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -16,6 +16,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_fullscreen_options.h"
#include "third_party/blink/renderer/bindings/core/v8/window_proxy.h"
#include "third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h"
+#include "third_party/blink/renderer/core/events/message_event.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -24,6 +25,7 @@
#include "third_party/blink/renderer/core/frame/remote_frame_client.h"
#include "third_party/blink/renderer/core/frame/remote_frame_owner.h"
#include "third_party/blink/renderer/core/frame/remote_frame_view.h"
+#include "third_party/blink/renderer/core/frame/user_activation.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
@@ -34,6 +36,7 @@
#include "third_party/blink/renderer/core/loader/frame_load_request.h"
#include "third_party/blink/renderer/core/loader/frame_loader.h"
#include "third_party/blink/renderer/core/loader/mixed_content_checker.h"
+#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/plugin_script_forbidden_scope.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
@@ -93,9 +96,14 @@ RemoteFrame::RemoteFrame(
frame_token,
MakeGarbageCollected<RemoteWindowProxyManager>(*this),
inheriting_agent_factory) {
- auto frame_tracking_result = GetRemoteFramesMap().insert(
- base::UnguessableTokenHash()(frame_token), this);
- CHECK(frame_tracking_result.stored_value) << "Inserting a duplicate item.";
+ // TODO(crbug.com/1094850): Remove this check once the renderer is correctly
+ // handling errors during the creation of HTML portal elements, which would
+ // otherwise cause RemoteFrame() being created with empty frame tokens.
+ if (!frame_token.is_empty()) {
+ auto frame_tracking_result = GetRemoteFramesMap().insert(
+ base::UnguessableTokenHash()(frame_token), this);
+ CHECK(frame_tracking_result.stored_value) << "Inserting a duplicate item.";
+ }
dom_window_ = MakeGarbageCollected<RemoteDOMWindow>(*this);
@@ -115,7 +123,7 @@ RemoteFrame::~RemoteFrame() {
DCHECK(!view_);
}
-void RemoteFrame::Trace(Visitor* visitor) {
+void RemoteFrame::Trace(Visitor* visitor) const {
visitor->Trace(view_);
visitor->Trace(security_context_);
Frame::Trace(visitor);
@@ -279,7 +287,8 @@ void RemoteFrame::AddResourceTimingFromChild(
// WorkerTimingContainer for navigation from the calling function.
DOMWindowPerformance::performance(*owner_element->GetDocument().domWindow())
->AddResourceTiming(std::move(timing), owner_element->localName(),
- /*worker_timing_receiver=*/mojo::NullReceiver());
+ /*worker_timing_receiver=*/mojo::NullReceiver(),
+ owner_element->GetDocument().GetExecutionContext());
}
void RemoteFrame::DidStartLoading() {
@@ -322,10 +331,34 @@ void RemoteFrame::CreateView() {
DeprecatedLocalOwner()->SetEmbeddedContentView(view_);
}
+void RemoteFrame::ForwardPostMessage(
+ MessageEvent* message_event,
+ base::Optional<base::UnguessableToken> cluster_id,
+ scoped_refptr<const SecurityOrigin> target_security_origin,
+ LocalFrame* source_frame) {
+ base::Optional<base::UnguessableToken> source_token;
+ if (source_frame)
+ source_token = source_frame->GetFrameToken();
+
+ String source_origin = message_event->origin();
+ String target_origin = g_empty_string;
+ if (target_security_origin)
+ target_origin = target_security_origin->ToString();
+
+ GetRemoteFrameHostRemote().RouteMessageEvent(
+ source_token, source_origin, target_origin,
+ BlinkTransferableMessage::FromMessageEvent(message_event, cluster_id));
+}
+
mojom::blink::RemoteFrameHost& RemoteFrame::GetRemoteFrameHostRemote() {
return *remote_frame_host_remote_.get();
}
+AssociatedInterfaceProvider* RemoteFrame::GetRemoteAssociatedInterfaces() {
+ DCHECK(Client());
+ return Client()->GetRemoteAssociatedInterfaces();
+}
+
RemoteFrameClient* RemoteFrame::Client() const {
return static_cast<RemoteFrameClient*>(Frame::Client());
}
@@ -586,7 +619,7 @@ void RemoteFrame::IntrinsicSizingInfoOfChildChanged(
// Update the proxy's SecurityContext with new sandbox flags or feature policy
// that were set during navigation. Unlike changes to the FrameOwner, which are
-// handled by RenderFrameProxy::OnDidUpdateFramePolicy, these changes should be
+// handled by RemoteFrame::DidUpdateFramePolicy, these changes should be
// considered effective immediately.
//
// These flags / policy are needed on the remote frame's SecurityContext to
@@ -630,6 +663,24 @@ void RemoteFrame::DidUpdateFramePolicy(const FramePolicy& frame_policy) {
To<RemoteFrameOwner>(Owner())->SetFramePolicy(frame_policy);
}
+void RemoteFrame::UpdateOpener(
+ const base::Optional<base::UnguessableToken>& opener_frame_token) {
+ if (auto* web_frame = WebFrame::FromFrame(this)) {
+ auto* opener_frame = LocalFrame::ResolveFrame(
+ opener_frame_token.value_or(base::UnguessableToken()));
+ auto* opener_web_frame = WebFrame::FromFrame(opener_frame);
+ web_frame->SetOpener(opener_web_frame);
+ }
+}
+
+void RemoteFrame::TransferUserActivationToRenderer(
+ const base::UnguessableToken& source_frame_token) {
+ RemoteFrame* source_frame = RemoteFrame::FromFrameToken(source_frame_token);
+ if (!source_frame)
+ return;
+ TransferUserActivationFrom(source_frame);
+}
+
IntSize RemoteFrame::GetMainFrameViewportSize() const {
HTMLFrameOwnerElement* owner = DeprecatedLocalOwner();
DCHECK(owner);
@@ -644,6 +695,27 @@ IntPoint RemoteFrame::GetMainFrameScrollOffset() const {
return owner->GetDocument().GetFrame()->GetMainFrameScrollOffset();
}
+void RemoteFrame::SetOpener(Frame* opener_frame) {
+ auto* opener_web_frame = WebFrame::FromFrame(opener_frame);
+ auto* web_frame = WebFrame::FromFrame(this);
+
+ if (web_frame && web_frame->Opener() != opener_web_frame) {
+ // A proxy shouldn't normally be disowning its opener. It is possible to
+ // get here when a proxy that is being detached clears its opener, in which
+ // case there is no need to notify the browser process.
+ if (opener_frame) {
+ // Only a LocalFrame (i.e., the caller of window.open) should be able to
+ // update another frame's opener.
+ DCHECK(opener_frame->IsLocalFrame());
+ GetRemoteFrameHostRemote().DidChangeOpener(
+ opener_frame ? base::Optional<base::UnguessableToken>(
+ opener_frame->GetFrameToken())
+ : base::nullopt);
+ }
+ web_frame->SetOpener(opener_web_frame);
+ }
+}
+
bool RemoteFrame::IsIgnoredForHitTest() const {
HTMLFrameOwnerElement* owner = DeprecatedLocalOwner();
if (!owner || !owner->GetLayoutObject())
@@ -667,13 +739,22 @@ void RemoteFrame::SetCcLayer(cc::Layer* cc_layer,
IsIgnoredForHitTest());
}
}
-
- To<HTMLFrameOwnerElement>(Owner())->SetNeedsCompositingUpdate();
+ HTMLFrameOwnerElement* owner = To<HTMLFrameOwnerElement>(Owner());
+ owner->SetNeedsCompositingUpdate();
+
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ // New layers for remote frames are controlled by Blink's embedder.
+ // To ensure the new surface is painted, we need to repaint the frame
+ // owner's PaintLayer.
+ LayoutBoxModelObject* layout_object = owner->GetLayoutBoxModelObject();
+ if (layout_object && layout_object->Layer())
+ layout_object->Layer()->SetNeedsRepaint();
+ }
}
void RemoteFrame::AdvanceFocus(mojom::blink::FocusType type,
LocalFrame* source) {
- Client()->AdvanceFocus(type, source);
+ GetRemoteFrameHostRemote().AdvanceFocus(type, source->GetFrameToken());
}
void RemoteFrame::DetachChildren() {
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame.h b/chromium/third_party/blink/renderer/core/frame/remote_frame.h
index dc29695ff00..1c2e010a73d 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame.h
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame.h
@@ -28,6 +28,7 @@ namespace blink {
class AssociatedInterfaceProvider;
class InterfaceRegistry;
class LocalFrame;
+class MessageEvent;
class RemoteFrameClient;
struct FrameLoadRequest;
@@ -49,7 +50,7 @@ class CORE_EXPORT RemoteFrame final : public Frame,
~RemoteFrame() override;
// Frame overrides:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Navigate(FrameLoadRequest&, WebFrameLoadType) override;
const RemoteSecurityContext* GetSecurityContext() const override;
bool DetachDocument() override;
@@ -57,6 +58,7 @@ class CORE_EXPORT RemoteFrame final : public Frame,
bool ShouldClose() override;
void HookBackForwardCacheEviction() override {}
void RemoveBackForwardCacheEviction() override {}
+ void SetTextDirection(base::i18n::TextDirection) override {}
void SetIsInert(bool) override;
void SetInheritedEffectiveTouchAction(TouchAction) override;
bool BubbleLogicalScrollFromChildFrame(
@@ -80,8 +82,16 @@ class CORE_EXPORT RemoteFrame final : public Frame,
void SetView(RemoteFrameView*);
void CreateView();
+ void ForwardPostMessage(
+ MessageEvent* message_event,
+ base::Optional<base::UnguessableToken> cluster_id,
+ scoped_refptr<const SecurityOrigin> target_security_origin,
+ LocalFrame* source_frame);
+
mojom::blink::RemoteFrameHost& GetRemoteFrameHostRemote();
+ AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces();
+
RemoteFrameView* View() const override;
RemoteFrameClient* Client() const;
@@ -143,11 +153,18 @@ class CORE_EXPORT RemoteFrame final : public Frame,
// sandbox flags or container policy. The new policy won't take effect until
// the next navigation.
void DidUpdateFramePolicy(const FramePolicy& frame_policy) override;
+ void UpdateOpener(const base::Optional<base::UnguessableToken>&
+ opener_frame_token) override;
+
+ void TransferUserActivationToRenderer(
+ const base::UnguessableToken& source_frame_token) override;
// Called only when this frame has a local frame owner.
IntSize GetMainFrameViewportSize() const override;
IntPoint GetMainFrameScrollOffset() const override;
+ void SetOpener(Frame* opener) override;
+
private:
// Frame protected overrides:
void DetachImpl(FrameDetachType) override;
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_client.h b/chromium/third_party/blink/renderer/core/frame/remote_frame_client.h
index 056e0d5969f..4addd8dce36 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame_client.h
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_client.h
@@ -20,11 +20,9 @@ class PaintCanvas;
}
namespace blink {
+class AssociatedInterfaceProvider;
class IntRect;
-class LocalFrame;
-class MessageEvent;
class ResourceRequest;
-class SecurityOrigin;
class WebLocalFrame;
class RemoteFrameClient : public FrameClient {
@@ -41,13 +39,6 @@ class RemoteFrameClient : public FrameClient {
const base::Optional<WebImpression>& impression) = 0;
unsigned BackForwardLength() override = 0;
- // Forwards a postMessage for a remote frame.
- virtual void ForwardPostMessage(
- MessageEvent*,
- scoped_refptr<const SecurityOrigin> target,
- base::Optional<base::UnguessableToken> cluster_id,
- LocalFrame* source_frame) const = 0;
-
// Forwards a change to the rects of a remote frame. |local_frame_rect| is the
// size of the frame in its parent's coordinate space prior to applying CSS
// transforms. |screen_space_rect| is in the screen's coordinate space, after
@@ -58,9 +49,9 @@ class RemoteFrameClient : public FrameClient {
virtual void UpdateRemoteViewportIntersection(
const ViewportIntersectionState& intersection_state) = 0;
- virtual void AdvanceFocus(mojom::blink::FocusType, LocalFrame* source) = 0;
-
virtual uint32_t Print(const IntRect&, cc::PaintCanvas*) const = 0;
+
+ virtual AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() = 0;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc b/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc
index 312b23cd3ab..f989b4bc77d 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc
@@ -5,7 +5,12 @@
#include "third_party/blink/renderer/core/frame/remote_frame_client_impl.h"
#include <memory>
+#include <utility>
+
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h"
#include "third_party/blink/public/web/web_remote_frame_client.h"
+#include "third_party/blink/public/web/web_view.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
#include "third_party/blink/renderer/core/events/mouse_event.h"
#include "third_party/blink/renderer/core/events/web_input_event_conversion.h"
@@ -17,8 +22,6 @@
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
-#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
-#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
namespace blink {
@@ -39,7 +42,7 @@ Frame* ToCoreFrame(WebFrame* frame) {
RemoteFrameClientImpl::RemoteFrameClientImpl(WebRemoteFrameImpl* web_frame)
: web_frame_(web_frame) {}
-void RemoteFrameClientImpl::Trace(Visitor* visitor) {
+void RemoteFrameClientImpl::Trace(Visitor* visitor) const {
visitor->Trace(web_frame_);
RemoteFrameClient::Trace(visitor);
}
@@ -56,8 +59,14 @@ void RemoteFrameClientImpl::Detached(FrameDetachType type) {
client->FrameDetached(static_cast<WebRemoteFrameClient::DetachType>(type));
- if (type == FrameDetachType::kRemove)
- web_frame_->DetachFromParent();
+ if (web_frame_->Parent()) {
+ if (type == FrameDetachType::kRemove)
+ web_frame_->DetachFromParent();
+ } else if (web_frame_->View()) {
+ // If the RemoteFrame being detached is also the main frame in the renderer
+ // process, we need to notify the webview to allow it to clean things up.
+ web_frame_->View()->DidDetachRemoteMainFrame();
+ }
// Clear our reference to RemoteFrame at the very end, in case the client
// refers to it.
@@ -68,13 +77,6 @@ Frame* RemoteFrameClientImpl::Opener() const {
return ToCoreFrame(web_frame_->Opener());
}
-void RemoteFrameClientImpl::SetOpener(Frame* opener) {
- WebFrame* opener_frame = WebFrame::FromFrame(opener);
- if (web_frame_->Client() && web_frame_->Opener() != opener_frame)
- web_frame_->Client()->DidChangeOpener(opener_frame);
- web_frame_->SetOpener(opener_frame);
-}
-
Frame* RemoteFrameClientImpl::Parent() const {
return ToCoreFrame(web_frame_->Parent());
}
@@ -115,7 +117,7 @@ void RemoteFrameClientImpl::Navigate(
should_replace_current_entry, is_opener_navigation,
initiator_frame_has_download_sandbox_flag,
blocking_downloads_in_sandbox_enabled, initiator_frame_is_ad,
- blob_url_token.PassPipe(), impression);
+ std::move(blob_url_token), impression);
}
}
@@ -127,19 +129,6 @@ unsigned RemoteFrameClientImpl::BackForwardLength() {
return 2;
}
-void RemoteFrameClientImpl::ForwardPostMessage(
- MessageEvent* event,
- scoped_refptr<const SecurityOrigin> target,
- base::Optional<base::UnguessableToken> cluster_id,
- LocalFrame* source_frame) const {
- if (web_frame_->Client()) {
- web_frame_->Client()->ForwardPostMessage(
- WebLocalFrameImpl::FromFrame(source_frame), web_frame_,
- WebSecurityOrigin(std::move(target)),
- WebDOMMessageEvent(event, cluster_id));
- }
-}
-
void RemoteFrameClientImpl::FrameRectsChanged(
const IntRect& local_frame_rect,
const IntRect& screen_space_rect) {
@@ -151,15 +140,14 @@ void RemoteFrameClientImpl::UpdateRemoteViewportIntersection(
web_frame_->Client()->UpdateRemoteViewportIntersection(intersection_state);
}
-void RemoteFrameClientImpl::AdvanceFocus(mojom::blink::FocusType type,
- LocalFrame* source) {
- web_frame_->Client()->AdvanceFocus(type,
- WebLocalFrameImpl::FromFrame(source));
-}
-
uint32_t RemoteFrameClientImpl::Print(const IntRect& rect,
cc::PaintCanvas* canvas) const {
return web_frame_->Client()->Print(rect, canvas);
}
+AssociatedInterfaceProvider*
+RemoteFrameClientImpl::GetRemoteAssociatedInterfaces() {
+ return web_frame_->Client()->GetRemoteAssociatedInterfaces();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h b/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h
index a0591ce692f..c3c2837a7e8 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h
@@ -19,13 +19,12 @@ class RemoteFrameClientImpl final : public RemoteFrameClient {
public:
explicit RemoteFrameClientImpl(WebRemoteFrameImpl*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// FrameClient overrides:
bool InShadowTree() const override;
void Detached(FrameDetachType) override;
Frame* Opener() const override;
- void SetOpener(Frame*) override;
Frame* Parent() const override;
Frame* Top() const override;
Frame* NextSibling() const override;
@@ -42,16 +41,12 @@ class RemoteFrameClientImpl final : public RemoteFrameClient {
mojo::PendingRemote<mojom::blink::BlobURLToken>,
const base::Optional<WebImpression>& impression) override;
unsigned BackForwardLength() override;
- void ForwardPostMessage(MessageEvent*,
- scoped_refptr<const SecurityOrigin> target,
- base::Optional<base::UnguessableToken> cluster_id,
- LocalFrame* source) const override;
void FrameRectsChanged(const IntRect& local_frame_rect,
const IntRect& screen_space_rect) override;
void UpdateRemoteViewportIntersection(
const ViewportIntersectionState& intersection_state) override;
- void AdvanceFocus(mojom::blink::FocusType, LocalFrame*) override;
uint32_t Print(const IntRect&, cc::PaintCanvas*) const override;
+ AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() override;
WebRemoteFrameImpl* GetWebFrame() const { return web_frame_; }
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.cc b/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.cc
index 4abf53df891..6cb1145f07d 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.cc
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.cc
@@ -34,7 +34,7 @@ RemoteFrameOwner::RemoteFrameOwner(
required_csp_(frame_owner_properties.required_csp),
frame_owner_element_type_(frame_owner_element_type) {}
-void RemoteFrameOwner::Trace(Visitor* visitor) {
+void RemoteFrameOwner::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
FrameOwner::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.h b/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.h
index 17605568826..d57342746f5 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.h
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_owner.h
@@ -83,7 +83,7 @@ class CORE_EXPORT RemoteFrameOwner final
required_csp_ = required_csp;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Intentionally private to prevent redundant checks when the type is
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_view.cc b/chromium/third_party/blink/renderer/core/frame/remote_frame_view.cc
index 1e58c5d6d81..2477633501b 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame_view.cc
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_view.cc
@@ -120,19 +120,17 @@ void RemoteFrameView::UpdateCompositingRect() {
// If the local frame root is an OOPIF itself, then we use the root's
// intersection rect. This represents a conservative maximum for the area
// that needs to be rastered by the OOPIF compositor.
- IntSize viewport_size = local_root_view->Size();
+ IntRect viewport_rect(IntPoint(), local_root_view->Size());
if (local_root_view->GetPage()->MainFrame() != local_root_view->GetFrame()) {
- viewport_size =
- local_root_view->GetFrame().RemoteViewportIntersection().Size();
+ viewport_rect = local_root_view->GetFrame().RemoteViewportIntersection();
}
- // The viewport size needs to account for intermediate CSS transforms before
+ // The viewport rect needs to account for intermediate CSS transforms before
// being compared to the frame size.
- PhysicalRect viewport_rect =
+ PhysicalRect local_viewport_rect =
remote_frame_->OwnerLayoutObject()->AncestorToLocalRect(
- nullptr, PhysicalRect(PhysicalOffset(), PhysicalSize(viewport_size)),
- kApplyRemoteRootFrameOffset | kTraverseDocumentBoundaries);
- compositing_rect_ = EnclosingIntRect(viewport_rect);
+ nullptr, PhysicalRect(viewport_rect), kTraverseDocumentBoundaries);
+ compositing_rect_ = EnclosingIntRect(local_viewport_rect);
IntSize frame_size = Size();
// Iframes that fit within the window viewport get fully rastered. For
@@ -143,8 +141,8 @@ void RemoteFrameView::UpdateCompositingRect() {
// it seems to make guttering rare with slow to medium speed wheel scrolling.
// Can we collect UMA data to estimate how much extra rastering this causes,
// and possibly how common guttering is?
- compositing_rect_.InflateX(ceilf(viewport_rect.Width() * 0.15f));
- compositing_rect_.InflateY(ceilf(viewport_rect.Height() * 0.15f));
+ compositing_rect_.InflateX(ceilf(local_viewport_rect.Width() * 0.15f));
+ compositing_rect_.InflateY(ceilf(local_viewport_rect.Height() * 0.15f));
compositing_rect_.SetWidth(
std::min(frame_size.Width(), compositing_rect_.Width()));
compositing_rect_.SetHeight(
@@ -321,7 +319,7 @@ uint32_t RemoteFrameView::CapturePaintPreview(const IntRect& rect,
return content_id;
}
-void RemoteFrameView::Trace(Visitor* visitor) {
+void RemoteFrameView::Trace(Visitor* visitor) const {
visitor->Trace(remote_frame_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_view.h b/chromium/third_party/blink/renderer/core/frame/remote_frame_view.h
index c226f2ccb39..f94f6aa350d 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame_view.h
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_view.h
@@ -78,7 +78,7 @@ class RemoteFrameView final : public GarbageCollected<RemoteFrameView>,
uint32_t Print(const IntRect&, cc::PaintCanvas*) const;
uint32_t CapturePaintPreview(const IntRect&, cc::PaintCanvas*) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
bool NeedsViewportOffset() const override { return true; }
diff --git a/chromium/third_party/blink/renderer/core/frame/report.h b/chromium/third_party/blink/renderer/core/frame/report.h
index 27ca7ab2617..aa8f5022ebd 100644
--- a/chromium/third_party/blink/renderer/core/frame/report.h
+++ b/chromium/third_party/blink/renderer/core/frame/report.h
@@ -36,7 +36,7 @@ class CORE_EXPORT Report : public ScriptWrappable {
String url() const { return url_; }
ReportBody* body() const { return body_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(body_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/reporting_context.cc b/chromium/third_party/blink/renderer/core/frame/reporting_context.cc
index 0da2f0398e5..dfc324b0755 100644
--- a/chromium/third_party/blink/renderer/core/frame/reporting_context.cc
+++ b/chromium/third_party/blink/renderer/core/frame/reporting_context.cc
@@ -114,7 +114,7 @@ void ReportingContext::Notify(mojom::blink::ReportPtr report) {
report->url.GetString(), body));
}
-void ReportingContext::Trace(Visitor* visitor) {
+void ReportingContext::Trace(Visitor* visitor) const {
visitor->Trace(observers_);
visitor->Trace(report_buffer_);
visitor->Trace(execution_context_);
diff --git a/chromium/third_party/blink/renderer/core/frame/reporting_context.h b/chromium/third_party/blink/renderer/core/frame/reporting_context.h
index ec572629ed7..2f4c5559e58 100644
--- a/chromium/third_party/blink/renderer/core/frame/reporting_context.h
+++ b/chromium/third_party/blink/renderer/core/frame/reporting_context.h
@@ -50,7 +50,7 @@ class CORE_EXPORT ReportingContext final
// mojom::blink::ReportingObserver implementation.
void Notify(mojom::blink::ReportPtr report) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Counts the use of a report type via UseCounter.
diff --git a/chromium/third_party/blink/renderer/core/frame/reporting_observer.cc b/chromium/third_party/blink/renderer/core/frame/reporting_observer.cc
index 8421647b389..4df5e09020a 100644
--- a/chromium/third_party/blink/renderer/core/frame/reporting_observer.cc
+++ b/chromium/third_party/blink/renderer/core/frame/reporting_observer.cc
@@ -60,8 +60,8 @@ void ReportingObserver::QueueReport(Report* report) {
}
bool ReportingObserver::ObservedType(const String& type) {
- return !options_->hasTypes() || options_->types().IsEmpty() ||
- options_->types().Find(type) != kNotFound;
+ return !options_->hasTypesNonNull() || options_->typesNonNull().IsEmpty() ||
+ options_->typesNonNull().Find(type) != kNotFound;
}
bool ReportingObserver::Buffered() {
@@ -88,7 +88,7 @@ HeapVector<Member<Report>> ReportingObserver::takeRecords() {
return reports;
}
-void ReportingObserver::Trace(Visitor* visitor) {
+void ReportingObserver::Trace(Visitor* visitor) const {
visitor->Trace(execution_context_);
visitor->Trace(callback_);
visitor->Trace(options_);
diff --git a/chromium/third_party/blink/renderer/core/frame/reporting_observer.h b/chromium/third_party/blink/renderer/core/frame/reporting_observer.h
index 23bb86d8b9f..7dfe12a685e 100644
--- a/chromium/third_party/blink/renderer/core/frame/reporting_observer.h
+++ b/chromium/third_party/blink/renderer/core/frame/reporting_observer.h
@@ -58,7 +58,7 @@ class CORE_EXPORT ReportingObserver final
void disconnect();
HeapVector<Member<Report>> takeRecords();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<ExecutionContext> execution_context_;
diff --git a/chromium/third_party/blink/renderer/core/frame/resize_viewport_anchor.h b/chromium/third_party/blink/renderer/core/frame/resize_viewport_anchor.h
index a2ec79b4827..c4c5ad66e69 100644
--- a/chromium/third_party/blink/renderer/core/frame/resize_viewport_anchor.h
+++ b/chromium/third_party/blink/renderer/core/frame/resize_viewport_anchor.h
@@ -41,7 +41,7 @@ class CORE_EXPORT ResizeViewportAnchor final
void ResizeFrameView(const IntSize&);
- void Trace(Visitor* visitor) { visitor->Trace(page_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(page_); }
private:
void BeginScope() { scope_count_++; }
diff --git a/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.cc b/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.cc
index b27420f1e02..df72dc0330a 100644
--- a/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.cc
+++ b/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.cc
@@ -514,6 +514,7 @@ cc::Layer* RootFrameViewport::LayerForScrollCorner() const {
return LayoutViewport().LayerForScrollCorner();
}
+// This method distributes the scroll between the visual and layout viewport.
ScrollResult RootFrameViewport::UserScroll(
ScrollGranularity granularity,
const FloatSize& delta,
@@ -526,13 +527,7 @@ ScrollResult RootFrameViewport::UserScroll(
UpdateScrollAnimator();
- // Distribute the scroll between the visual and layout viewport.
-
- float step_x = ScrollStep(granularity, kHorizontalScrollbar);
- float step_y = ScrollStep(granularity, kVerticalScrollbar);
-
- FloatSize pixel_delta(delta);
- pixel_delta.Scale(step_x, step_y);
+ FloatSize pixel_delta = ResolveScrollDelta(granularity, delta);
// Precompute the amount of possible scrolling since, when animated,
// ScrollAnimator::userScroll will report having consumed the total given
@@ -682,7 +677,7 @@ base::Optional<FloatPoint> RootFrameViewport::GetSnapPositionAndSetTarget(
return LayoutViewport().GetSnapPositionAndSetTarget(strategy);
}
-void RootFrameViewport::Trace(Visitor* visitor) {
+void RootFrameViewport::Trace(Visitor* visitor) const {
visitor->Trace(visual_viewport_);
visitor->Trace(layout_viewport_);
ScrollableArea::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.h b/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.h
index 7ced411e8b4..1cac09e11f3 100644
--- a/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.h
+++ b/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.h
@@ -35,7 +35,7 @@ class CORE_EXPORT RootFrameViewport final
RootFrameViewport(ScrollableArea& visual_viewport,
ScrollableArea& layout_viewport);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void SetLayoutViewport(ScrollableArea&);
ScrollableArea& LayoutViewport() const;
diff --git a/chromium/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc b/chromium/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc
index e7fdd6c72b3..7ea3db17119 100644
--- a/chromium/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc
@@ -84,7 +84,9 @@ class ScrollableAreaStub : public GarbageCollected<ScrollableAreaStub>,
}
bool ScrollAnimatorEnabled() const override { return true; }
- void Trace(Visitor* visitor) override { ScrollableArea::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ ScrollableArea::Trace(visitor);
+ }
protected:
CompositorElementId GetScrollElementId() const override {
diff --git a/chromium/third_party/blink/renderer/core/frame/savable_resources.cc b/chromium/third_party/blink/renderer/core/frame/savable_resources.cc
new file mode 100644
index 00000000000..b4a4f6a9f18
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/savable_resources.cc
@@ -0,0 +1,174 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/frame/savable_resources.h"
+
+#include "third_party/blink/public/mojom/frame/frame.mojom-blink.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
+#include "third_party/blink/renderer/core/html/html_all_collection.h"
+#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
+#include "third_party/blink/renderer/core/html_names.h"
+#include "third_party/blink/renderer/core/input_type_names.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+namespace {
+
+// Returns |true| if |frame| contains (or should be assumed to contain)
+// a html document.
+bool DoesFrameContainHtmlDocument(Frame* frame, Element* element) {
+ if (frame->IsLocalFrame()) {
+ Document* document =
+ LocalFrame::FromFrameToken(frame->GetFrameToken())->GetDocument();
+ return document->IsHTMLDocument() || document->IsXHTMLDocument();
+ }
+
+ // Cannot inspect contents of a remote frame, so we use a heuristic:
+ // Assume that <iframe> and <frame> elements contain a html document,
+ // and other elements (i.e. <object>) contain plugins or other resources.
+ // If the heuristic is wrong (i.e. the remote frame in <object> does
+ // contain an html document), then things will still work, but with the
+ // following caveats: 1) original frame content will be saved and 2) links
+ // in frame's html doc will not be rewritten to point to locally saved
+ // files.
+ return element->HasTagName(html_names::kIFrameTag) ||
+ element->HasTagName(html_names::kFrameTag);
+}
+
+// If present and valid, then push the link associated with |element|
+// into either SavableResources::Result::subframes_ or
+// SavableResources::Result::resources_list_.
+void GetSavableResourceLinkForElement(Element* element,
+ const Document& current_document,
+ SavableResources::Result* result) {
+ // Get absolute URL.
+ String link_attribute_value =
+ SavableResources::GetSubResourceLinkFromElement(element);
+ KURL element_url = current_document.CompleteURL(link_attribute_value);
+
+ // See whether to report this element as a subframe.
+ if (auto* frame_owner = DynamicTo<HTMLFrameOwnerElement>(element)) {
+ Frame* content_frame = frame_owner->ContentFrame();
+ if (content_frame && DoesFrameContainHtmlDocument(content_frame, element)) {
+ mojom::blink::SavableSubframePtr subframe =
+ mojom::blink::SavableSubframe::New(element_url,
+ content_frame->GetFrameToken());
+ result->AppendSubframe(std::move(subframe));
+ return;
+ }
+ }
+
+ // Check whether the node has sub resource URL or not.
+ if (link_attribute_value.IsNull())
+ return;
+
+ // Ignore invalid URL.
+ if (!element_url.IsValid())
+ return;
+
+ // Ignore those URLs which are not standard protocols. Because FTP
+ // protocol does no have cache mechanism, we will skip all
+ // sub-resources if they use FTP protocol.
+ if (!element_url.ProtocolIsInHTTPFamily() &&
+ !element_url.ProtocolIs(url::kFileScheme))
+ return;
+
+ result->AppendResourceLink(element_url);
+}
+
+} // namespace
+
+// static
+bool SavableResources::GetSavableResourceLinksForFrame(
+ LocalFrame* current_frame,
+ SavableResources::Result* result) {
+ // Get current frame's URL.
+ KURL current_frame_url = current_frame->GetDocument()->Url();
+
+ // If url of current frame is invalid, ignore it.
+ if (!current_frame_url.IsValid())
+ return false;
+
+ // If url of current frame is not a savable protocol, ignore it.
+ if (!Platform::Current()->IsURLSavableForSavableResource(current_frame_url))
+ return false;
+
+ // Get current using document.
+ Document* current_document = current_frame->GetDocument();
+ DCHECK(current_document);
+
+ // Go through all descent nodes.
+ HTMLAllCollection* collection = current_document->all();
+
+ // Go through all elements in this frame.
+ for (unsigned i = 0; i < collection->length(); ++i) {
+ GetSavableResourceLinkForElement(collection->item(i), *current_document,
+ result);
+ }
+
+ return true;
+}
+
+// static
+String SavableResources::GetSubResourceLinkFromElement(Element* element) {
+ const char* attribute_name = nullptr;
+ if (element->HasTagName(html_names::kImgTag) ||
+ element->HasTagName(html_names::kFrameTag) ||
+ element->HasTagName(html_names::kIFrameTag) ||
+ element->HasTagName(html_names::kScriptTag)) {
+ attribute_name = "src";
+ } else if (element->HasTagName(html_names::kInputTag)) {
+ HTMLInputElement* input = To<HTMLInputElement>(element);
+ if (input->type() == input_type_names::kImage) {
+ attribute_name = "src";
+ }
+ } else if (element->HasTagName(html_names::kBodyTag) ||
+ element->HasTagName(html_names::kTableTag) ||
+ element->HasTagName(html_names::kTrTag) ||
+ element->HasTagName(html_names::kTdTag)) {
+ attribute_name = "background";
+ } else if (element->HasTagName(html_names::kBlockquoteTag) ||
+ element->HasTagName(html_names::kQTag) ||
+ element->HasTagName(html_names::kDelTag) ||
+ element->HasTagName(html_names::kInsTag)) {
+ attribute_name = "cite";
+ } else if (element->HasTagName(html_names::kObjectTag)) {
+ attribute_name = "data";
+ } else if (element->HasTagName(html_names::kLinkTag)) {
+ // If the link element is not linked to css, ignore it.
+ String type = element->getAttribute("type");
+ String rel = element->getAttribute("rel");
+ if ((type.ContainsOnlyASCIIOrEmpty() && type.LowerASCII() == "text/css") ||
+ (rel.ContainsOnlyASCIIOrEmpty() && rel.LowerASCII() == "stylesheet")) {
+ // TODO(jnd): Add support for extracting links of sub-resources which
+ // are inside style-sheet such as @import, url(), etc.
+ // See bug: http://b/issue?id=1111667.
+ attribute_name = "href";
+ }
+ }
+ if (!attribute_name)
+ return String();
+ String value = element->getAttribute(attribute_name);
+ // If value has content and not start with "javascript:" then return it,
+ // otherwise return an empty string.
+ if (!value.IsNull() && !value.IsEmpty() &&
+ !value.StartsWith("javascript:", kTextCaseASCIIInsensitive))
+ return value;
+
+ return String();
+}
+
+void SavableResources::Result::AppendSubframe(
+ mojom::blink::SavableSubframePtr subframe) {
+ subframes_->emplace_back(std::move(subframe));
+}
+
+void SavableResources::Result::AppendResourceLink(const KURL& url) {
+ resources_list_->emplace_back(url);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/savable_resources.h b/chromium/third_party/blink/renderer/core/frame/savable_resources.h
new file mode 100644
index 00000000000..d2729f384a5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/savable_resources.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_SAVABLE_RESOURCES_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_SAVABLE_RESOURCES_H_
+
+#include "base/macros.h"
+
+#include "third_party/blink/public/mojom/frame/frame.mojom-blink.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+class Element;
+class LocalFrame;
+
+class SavableResources {
+ STATIC_ONLY(SavableResources);
+
+ public:
+ // Class for storage the result of getting all savable resource links
+ // for current page. The consumer of the SavableResources::Result is
+ // responsible for keeping these pointers valid for the lifetime of the
+ // SavableResources::Result instance.
+ class Result {
+ STACK_ALLOCATED();
+
+ public:
+ Result(Vector<KURL>* resources_list,
+ Vector<mojom::blink::SavableSubframePtr>* subframes)
+ : resources_list_(resources_list), subframes_(subframes) {}
+
+ void AppendSubframe(mojom::blink::SavableSubframePtr subframe);
+ void AppendResourceLink(const KURL& url);
+
+ private:
+ // Links of all savable resources.
+ Vector<KURL>* resources_list_;
+
+ // Subframes.
+ Vector<mojom::blink::SavableSubframePtr>* subframes_;
+ };
+
+ // Get all the savable resource links from the specified |frame|.
+ // Returns true if the saved resources links have been saved successfully.
+ // Otherwise returns false (i.e. if the frame contains a non-savable content).
+ static bool GetSavableResourceLinksForFrame(LocalFrame* frame,
+ SavableResources::Result* result);
+
+ // Returns the value in an elements resource url attribute. For IMG, SCRIPT or
+ // INPUT TYPE=image, returns the value in "src". For LINK TYPE=text/css,
+ // returns the value in "href". For BODY, TABLE, TR, TD, returns the value in
+ // "background". For BLOCKQUOTE, Q, DEL, INS, returns the value in "cite"
+ // attribute. Otherwise returns an empty String.
+ static String GetSubResourceLinkFromElement(Element* element);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_SAVABLE_RESOURCES_H_
diff --git a/chromium/third_party/blink/renderer/core/frame/scheduling.cc b/chromium/third_party/blink/renderer/core/frame/scheduling.cc
index d270b559c30..dbd3e254260 100644
--- a/chromium/third_party/blink/renderer/core/frame/scheduling.cc
+++ b/chromium/third_party/blink/renderer/core/frame/scheduling.cc
@@ -23,11 +23,14 @@ bool Scheduling::isInputPending(ScriptState* script_state,
return false;
auto* scheduler = ThreadScheduler::Current();
- auto info = scheduler->GetPendingUserInputInfo(options->includeContinuous());
-
- // TODO(acomminos): Attribution first requires a reverse mapping between
- // cc::ElementId instances and their underlying Document* objects.
- (void)info;
+ auto info = scheduler->GetPendingUserInputInfo(
+ options ? options->includeContinuous() : false);
+
+ for (const auto& attribution : info) {
+ if (frame->CanAccessEvent(attribution)) {
+ return true;
+ }
+ }
return false;
}
diff --git a/chromium/third_party/blink/renderer/core/frame/scheduling.h b/chromium/third_party/blink/renderer/core/frame/scheduling.h
index b2f35f168d7..2f1ab3bb6c7 100644
--- a/chromium/third_party/blink/renderer/core/frame/scheduling.h
+++ b/chromium/third_party/blink/renderer/core/frame/scheduling.h
@@ -19,7 +19,8 @@ class Scheduling : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- bool isInputPending(ScriptState*, const IsInputPendingOptions* options) const;
+ bool isInputPending(ScriptState*,
+ const IsInputPendingOptions* options = nullptr) const;
bool isFramePending() const;
};
diff --git a/chromium/third_party/blink/renderer/core/frame/scheduling.idl b/chromium/third_party/blink/renderer/core/frame/scheduling.idl
index ea3bd840d17..8898c015eab 100644
--- a/chromium/third_party/blink/renderer/core/frame/scheduling.idl
+++ b/chromium/third_party/blink/renderer/core/frame/scheduling.idl
@@ -8,5 +8,5 @@
RuntimeEnabled=ExperimentalIsInputPending
] interface Scheduling {
[RuntimeEnabled=ExperimentalIsInputPending] boolean isFramePending();
- [CallWith=ScriptState, MeasureAs=SchedulingIsInputPending, RuntimeEnabled=ExperimentalIsInputPending] boolean isInputPending(IsInputPendingOptions options);
+ [CallWith=ScriptState, MeasureAs=SchedulingIsInputPending, RuntimeEnabled=ExperimentalIsInputPending] boolean isInputPending(optional IsInputPendingOptions options);
};
diff --git a/chromium/third_party/blink/renderer/core/frame/screen.cc b/chromium/third_party/blink/renderer/core/frame/screen.cc
index 4410029341a..dda1f9a7c23 100644
--- a/chromium/third_party/blink/renderer/core/frame/screen.cc
+++ b/chromium/third_party/blink/renderer/core/frame/screen.cc
@@ -28,7 +28,10 @@
#include "third_party/blink/renderer/core/frame/screen.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
#include "third_party/blink/public/platform/web_screen_info.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
@@ -165,7 +168,7 @@ int Screen::availWidth() const {
return GetScreenInfo(*frame).available_rect.width;
}
-void Screen::Trace(Visitor* visitor) {
+void Screen::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
Supplementable<Screen>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/frame/screen.h b/chromium/third_party/blink/renderer/core/frame/screen.h
index 57b9235cf77..686ddd53eec 100644
--- a/chromium/third_party/blink/renderer/core/frame/screen.h
+++ b/chromium/third_party/blink/renderer/core/frame/screen.h
@@ -32,6 +32,7 @@
#include "base/optional.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/frame/web_feature_forward.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/supplementable.h"
@@ -60,7 +61,7 @@ class CORE_EXPORT Screen final : public ScriptWrappable,
int availHeight() const;
int availWidth() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Proposed extensions to the Screen interface.
// https://github.com/webscreens/screen-enumeration
diff --git a/chromium/third_party/blink/renderer/core/frame/screen.idl b/chromium/third_party/blink/renderer/core/frame/screen.idl
index 9a5e18dbb72..a3e7a8b86f8 100644
--- a/chromium/third_party/blink/renderer/core/frame/screen.idl
+++ b/chromium/third_party/blink/renderer/core/frame/screen.idl
@@ -31,21 +31,22 @@
[
Exposed=Window
] interface Screen {
- [HighEntropy, Measure] readonly attribute long availWidth;
- [HighEntropy, Measure] readonly attribute long availHeight;
- [HighEntropy, Measure] readonly attribute long width;
- [HighEntropy, Measure] readonly attribute long height;
- [HighEntropy, Measure] readonly attribute unsigned long colorDepth;
+ [HighEntropy=Direct, MeasureAs=V8Screen_AvailWidth_AttributeGetter] readonly attribute long availWidth;
+ [HighEntropy=Direct, MeasureAs=V8Screen_AvailHeight_AttributeGetter] readonly attribute long availHeight;
+ [HighEntropy=Direct, MeasureAs=V8Screen_Width_AttributeGetter] readonly attribute long width;
+ [HighEntropy=Direct, MeasureAs=V8Screen_Height_AttributeGetter] readonly attribute long height;
+ [HighEntropy=Direct, MeasureAs=V8Screen_ColorDepth_AttributeGetter] readonly attribute unsigned long colorDepth;
+ // pixelDepth() is an alias for colorDepth(), no need to instrument it twice.
[HighEntropy, Measure] readonly attribute unsigned long pixelDepth;
// Non-standard
- [HighEntropy, Measure] readonly attribute long availLeft;
- [HighEntropy, Measure] readonly attribute long availTop;
+ [HighEntropy=Direct, MeasureAs=V8Screen_AvailLeft_AttributeGetter] readonly attribute long availLeft;
+ [HighEntropy=Direct, MeasureAs=V8Screen_AvailTop_AttributeGetter] readonly attribute long availTop;
// Proposed
// https://github.com/webscreens/screen-enumeration
- [RuntimeEnabled=WindowPlacement] readonly attribute long left;
- [RuntimeEnabled=WindowPlacement] readonly attribute long top;
+ [HighEntropy=Direct, MeasureAs=WindowScreenLeft, RuntimeEnabled=WindowPlacement] readonly attribute long left;
+ [HighEntropy=Direct, MeasureAs=WindowScreenTop, RuntimeEnabled=WindowPlacement] readonly attribute long top;
[RuntimeEnabled=WindowPlacement] readonly attribute boolean internal;
[RuntimeEnabled=WindowPlacement] readonly attribute boolean primary;
[RuntimeEnabled=WindowPlacement] readonly attribute float scaleFactor;
diff --git a/chromium/third_party/blink/renderer/core/frame/settings.json5 b/chromium/third_party/blink/renderer/core/frame/settings.json5
index e6ab013ef0e..771316eeff5 100644
--- a/chromium/third_party/blink/renderer/core/frame/settings.json5
+++ b/chromium/third_party/blink/renderer/core/frame/settings.json5
@@ -65,12 +65,17 @@
type: "int",
},
+ // Sets the minimum font-size in CSS px. That means the minimum font-size is
+ // applied before applying the device scale factor or page zoom.
{
name: "minimumFontSize",
initial: 0,
invalidate: "Style",
type: "int",
},
+
+ // Sets the minimum font-size in CSS px, but only applies to relative font
+ // units like 'small', em, and percentage sizes.
{
name: "minimumLogicalFontSize",
initial: 0,
@@ -251,11 +256,6 @@
initial: false,
},
- {
- name: "shouldRespectImageOrientation",
- initial: false,
- },
-
// This value indicates the number of simultaneous multi-touch points supported
// by the currently connected screen/digitizer that supports the most points.
// From Pointer Events spec:
@@ -905,12 +905,6 @@
invalidate: "ForceDark",
},
{
- name: "forceDarkModeClassifierType",
- initial: "DarkModeClassifierType::kGeneric",
- type: "DarkModeClassifierType",
- invalidate: "ForceDark",
- },
- {
name: "forceDarkModeImagePolicy",
initial: "DarkModeImagePolicy::kFilterNone",
type: "DarkModeImagePolicy",
@@ -1058,7 +1052,7 @@
// evaluating the prefers-color-scheme media query.
{
name: "preferredColorScheme",
- initial: "PreferredColorScheme::kNoPreference",
+ initial: "PreferredColorScheme::kLight",
invalidate: "ColorScheme",
type: "PreferredColorScheme",
},
@@ -1082,12 +1076,20 @@
invalidate: "MediaQuery",
type: "NavigationControls",
},
-
{
name: "accessibilityAlwaysShowFocus",
initial: false,
invalidate: "Style",
type: "bool"
- }
+ },
+ // aria-modal="true" on some platforms requires the accessibility tree to
+ // be pruned so no other background content is exposed to assistive
+ // technology.
+ // https://www.w3.org/TR/core-aam-1.1/#ariaModalTrue
+ {
+ name: "ariaModalPrunesAXTree",
+ initial: false,
+ type: "bool",
+ },
],
}
diff --git a/chromium/third_party/blink/renderer/core/frame/smart_clip.cc b/chromium/third_party/blink/renderer/core/frame/smart_clip.cc
index c863b1b5514..760db53336f 100644
--- a/chromium/third_party/blink/renderer/core/frame/smart_clip.cc
+++ b/chromium/third_party/blink/renderer/core/frame/smart_clip.cc
@@ -245,7 +245,7 @@ String SmartClip::ExtractTextFromNode(Node* node) {
if (current_node.IsTextNode()) {
String node_value = current_node.nodeValue();
- // It's unclear why we blacklist solitary "\n" node values.
+ // It's unclear why we disallowed solitary "\n" node values.
// Maybe we're trying to ignore <br> tags somehow?
if (node_value == "\n")
node_value = "";
diff --git a/chromium/third_party/blink/renderer/core/frame/sticky_ad_detector.cc b/chromium/third_party/blink/renderer/core/frame/sticky_ad_detector.cc
new file mode 100644
index 00000000000..0748d359148
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/sticky_ad_detector.cc
@@ -0,0 +1,137 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/frame/sticky_ad_detector.h"
+
+#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
+#include "third_party/blink/renderer/core/html/html_image_element.h"
+#include "third_party/blink/renderer/core/layout/layout_object.h"
+#include "third_party/blink/renderer/core/layout/layout_object_inlines.h"
+#include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/paint/paint_timing.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
+
+#include <cstdlib>
+
+namespace blink {
+
+namespace {
+
+constexpr base::TimeDelta kFireInterval = base::TimeDelta::FromSeconds(1);
+constexpr double kLargeAdSizeToViewportSizeThreshold = 0.3;
+
+// An sticky element should have a non-default position w.r.t. the viewport. The
+// main page should also be scrollable.
+bool IsStickyAdCandidate(Element* element) {
+ if (!element->IsAdRelated())
+ return false;
+
+ const ComputedStyle* style = nullptr;
+ LayoutView* layout_view = element->GetDocument().GetLayoutView();
+ LayoutObject* object = element->GetLayoutObject();
+
+ DCHECK_NE(object, layout_view);
+
+ for (; object != layout_view; object = object->Container()) {
+ DCHECK(object);
+ style = object->Style();
+ }
+
+ DCHECK(style);
+
+ // 'style' is now the ComputedStyle for the object whose position depends
+ // on the document.
+ return style->GetPosition() != EPosition::kStatic;
+}
+
+} // namespace
+
+void StickyAdDetector::MaybeFireDetection(LocalFrame* main_frame) {
+ DCHECK(main_frame);
+ DCHECK(main_frame->IsMainFrame());
+ if (done_detection_)
+ return;
+
+ DCHECK(main_frame->GetDocument());
+ DCHECK(main_frame->ContentLayoutObject());
+
+ // Skip any measurement before the FCP.
+ if (PaintTiming::From(*main_frame->GetDocument())
+ .FirstContentfulPaint()
+ .is_null()) {
+ return;
+ }
+
+ base::Time current_time = base::Time::Now();
+ if (last_detection_time_.has_value() &&
+ current_time < last_detection_time_.value() + kFireInterval) {
+ return;
+ }
+
+ TRACE_EVENT0("blink,benchmark", "StickyAdDetector::MaybeFireDetection");
+
+ IntSize main_frame_size = main_frame->GetMainFrameViewportSize();
+
+ // Hit test the bottom center of the viewport.
+ HitTestLocation location(DoublePoint(main_frame_size.Width() / 2.0,
+ main_frame_size.Height() * 9.0 / 10));
+
+ HitTestResult result;
+ main_frame->ContentLayoutObject()->HitTestNoLifecycleUpdate(location, result);
+
+ last_detection_time_ = current_time;
+
+ Element* element = result.InnerElement();
+ if (!element)
+ return;
+
+ DOMNodeId element_id = DOMNodeIds::IdForNode(element);
+
+ if (element_id == candidate_id_) {
+ // If the main frame scrolling position has changed by a distance greater
+ // than the height of the candidate, and the candidate is still at the
+ // bottom center, then we record the use counter.
+ if (std::abs(candidate_start_main_frame_scroll_offset_ -
+ main_frame->GetMainFrameScrollOffset().Y()) >
+ candidate_height_) {
+ OnLargeStickyAdDetected(main_frame);
+ }
+ return;
+ }
+
+ // The hit testing returns an element different from the current candidate,
+ // and the main frame scroll offset hasn't changed much. In this case we
+ // we don't consider the candidate to be a sticky ad, because it may have
+ // been dismissed along with scrolling (e.g. parallax/scroller ad), or may
+ // have dismissed itself soon after its appearance.
+ candidate_id_ = kInvalidDOMNodeId;
+
+ if (!element->GetLayoutObject())
+ return;
+
+ IntRect overlay_rect = element->GetLayoutObject()->AbsoluteBoundingBoxRect();
+
+ bool is_large =
+ (overlay_rect.Size().Area() >
+ main_frame_size.Area() * kLargeAdSizeToViewportSizeThreshold);
+
+ bool is_main_page_scrollable =
+ element->GetDocument().GetLayoutView()->HasScrollableOverflowY();
+
+ if (is_large && is_main_page_scrollable && IsStickyAdCandidate(element)) {
+ candidate_id_ = element_id;
+ candidate_height_ = overlay_rect.Size().Height();
+ candidate_start_main_frame_scroll_offset_ =
+ main_frame->GetMainFrameScrollOffset().Y();
+ }
+}
+
+void StickyAdDetector::OnLargeStickyAdDetected(LocalFrame* main_frame) {
+ UseCounter::Count(main_frame->GetDocument(), WebFeature::kLargeStickyAd);
+ done_detection_ = true;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/sticky_ad_detector.h b/chromium/third_party/blink/renderer/core/frame/sticky_ad_detector.h
new file mode 100644
index 00000000000..d9edd070e0d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/sticky_ad_detector.h
@@ -0,0 +1,61 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_STICKY_AD_DETECTOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_STICKY_AD_DETECTOR_H_
+
+#include "base/macros.h"
+#include "base/optional.h"
+#include "base/time/time.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/graphics/dom_node_id.h"
+
+namespace blink {
+
+class LocalFrame;
+
+// Detects large sticky ad at the bottom of the viewport, and record a use
+// counter when an instance is found.
+//
+// Better Ads Standards definition:
+// https://www.betterads.org/desktop-large-sticky-ad/
+// https://www.betterads.org/mobile-large-sticky-ad/
+//
+// Heuristic:
+// We do hit testing at the bottom center of the browser viewport at regular
+// intervals. The top element is a sticky ad candidate if the following
+// conditions are met:
+// 1) It has a non-default position w.r.t. the viewport.
+// 2) It's large in size (> 30% viewport size).
+// 3) The main page is not scrollable.
+//
+// The candidate will be actually counted as a sticky ad instance at a later
+// point, when we detect that the main frame scrolling position has changed by a
+// distance greater than the height of the candidate, and the candidate is still
+// at the bottom center. This allows us to exclude false positives like
+// parallax/scroller ads.
+class CORE_EXPORT StickyAdDetector {
+ public:
+ StickyAdDetector() = default;
+ ~StickyAdDetector() = default;
+
+ void MaybeFireDetection(LocalFrame* main_frame);
+
+ private:
+ void OnLargeStickyAdDetected(LocalFrame* main_frame);
+
+ base::Optional<base::Time> last_detection_time_;
+
+ DOMNodeId candidate_id_;
+ int candidate_height_;
+ int candidate_start_main_frame_scroll_offset_;
+
+ bool done_detection_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(StickyAdDetector);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_STICKY_AD_DETECTOR_H_
diff --git a/chromium/third_party/blink/renderer/core/frame/sticky_frame_tracker.cc b/chromium/third_party/blink/renderer/core/frame/sticky_frame_tracker.cc
deleted file mode 100644
index 17b3b1ab698..00000000000
--- a/chromium/third_party/blink/renderer/core/frame/sticky_frame_tracker.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/frame/sticky_frame_tracker.h"
-
-#include <algorithm>
-
-namespace blink {
-
-namespace {
-
-constexpr static uint32_t kNumScrollEvents = 10;
-constexpr static double kLargeFrameSizeToViewportSizeThreshold = 0.3;
-constexpr static double kStickyFrameOffsetsRangeToScrollOffsetsRangeThreshold =
- 0.5;
-
-} // namespace
-
-// static
-bool StickyFrameTracker::IsLarge(const IntSize& main_frame_viewport_size,
- const IntSize& frame_size) {
- DCHECK(!main_frame_viewport_size.IsEmpty());
- uint64_t main_frame_viewport_area = main_frame_viewport_size.Area();
- uint64_t frame_area = frame_size.Area();
-
- return frame_area >=
- kLargeFrameSizeToViewportSizeThreshold * main_frame_viewport_area;
-}
-
-bool StickyFrameTracker::UpdateStickyStatus(
- const IntPoint& main_frame_scroll_offset,
- const IntPoint& viewport_offset) {
- // If the frame has been detected as sticky, it's always considered sticky.
- if (is_sticky_)
- return true;
-
- if (viewport_offsets_.size() > 0) {
- // If the scroll offset doesn't change, don't add the new data point.
- if (main_frame_scroll_offsets_.back() == main_frame_scroll_offset.Y())
- return false;
-
- // If the scroll offset has changed while the viewport offset doesn't
- // change, then it's considered sticky.
- if (viewport_offsets_.back() == viewport_offset.Y()) {
- SetSticky();
- return true;
- }
- }
-
- viewport_offsets_.push_back(viewport_offset.Y());
- main_frame_scroll_offsets_.push_back(main_frame_scroll_offset.Y());
-
- // We don't have enough data points to determine the stickiness.
- if (viewport_offsets_.size() < kNumScrollEvents)
- return false;
-
- if (viewport_offsets_.size() > kNumScrollEvents) {
- viewport_offsets_.pop_front();
- main_frame_scroll_offsets_.pop_front();
- }
-
- auto viewport_offset_min_max =
- std::minmax_element(viewport_offsets_.begin(), viewport_offsets_.end());
- auto main_frame_scroll_offset_min_max = std::minmax_element(
- main_frame_scroll_offsets_.begin(), main_frame_scroll_offsets_.end());
- int viewport_offset_range =
- *(viewport_offset_min_max.second) - *(viewport_offset_min_max.first);
- int main_frame_scroll_offset_range =
- *(main_frame_scroll_offset_min_max.second) -
- *(main_frame_scroll_offset_min_max.first);
-
- // Both the scroll offset and viewport offset have changed. We check the
- // latest |kNumScrollEvents| values to see whether the movement of frame is
- // too small compared to the movement of scrolling. If so, we consider the
- // frame to be sticky.
- if (viewport_offset_range <
- main_frame_scroll_offset_range *
- kStickyFrameOffsetsRangeToScrollOffsetsRangeThreshold) {
- SetSticky();
- return true;
- }
-
- return false;
-}
-
-void StickyFrameTracker::SetSticky() {
- is_sticky_ = true;
- viewport_offsets_.clear();
- main_frame_scroll_offsets_.clear();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/sticky_frame_tracker.h b/chromium/third_party/blink/renderer/core/frame/sticky_frame_tracker.h
deleted file mode 100644
index c0807a3bd1b..00000000000
--- a/chromium/third_party/blink/renderer/core/frame/sticky_frame_tracker.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_STICKY_FRAME_TRACKER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_STICKY_FRAME_TRACKER_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/geometry/int_point.h"
-#include "third_party/blink/renderer/platform/wtf/deque.h"
-
-namespace blink {
-
-// Keeps track of the viewport position of a frame.
-//
-// This is for catching ads that don't follow the Better Ads Standard --
-// https://www.betterads.org/desktop-large-sticky-ad/.
-//
-// The heuristic for "sticky" is as follows:
-//
-// Given the latest two pairs of main frame scroll offset and frame's position
-// wrt viewport (a.k.a. viewport offset), if the two main frame scroll offsets
-// differ while the viewport offsets are the same, the frame is considered
-// sticky.
-//
-// In addition, we store the latest 10 (|kNumScrollEvents|) main frame scroll
-// offsets and viewport offsets, and keep comparing their range. For the latest
-// 10 recordings, if the frame has a viewport offsets range smaller than 0.5
-// (|kStickyFrameOffsetsRangeToScrollOffsetsRangeThreshold|) of the main frame
-// scroll offsets range, then it's considered sticky as well.
-//
-// Right now we only consider offsets on the vertical dimension. The
-// implementation can be extended to cover both dimensions if needed.
-class CORE_EXPORT StickyFrameTracker {
- public:
- // Returns whether the |frame_size| is considered large compared to
- // |main_frame_viewport_size|.
- static bool IsLarge(const IntSize& main_frame_viewport_size,
- const IntSize& frame_size);
-
- StickyFrameTracker() = default;
- StickyFrameTracker(const StickyFrameTracker&) = delete;
- ~StickyFrameTracker() = default;
-
- // Called when the frame's position with respect to the viewport may have
- // changed. Returns whether the frame is sticky. |main_frame_scroll_offset|
- // is the scroll position in the main page. |viewport_offset| is the position
- // of the top-left corner of this frame (every StickyFrameTracker will only be
- // tracking one frame) relative to the browser viewport.
- bool UpdateStickyStatus(const IntPoint& main_frame_scroll_offset,
- const IntPoint& viewport_offset);
-
- private:
- void SetSticky();
-
- bool is_sticky_ = false;
- Deque<int> viewport_offsets_;
- Deque<int> main_frame_scroll_offsets_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_STICKY_FRAME_TRACKER_H_
diff --git a/chromium/third_party/blink/renderer/core/frame/sticky_frame_tracker_test.cc b/chromium/third_party/blink/renderer/core/frame/sticky_frame_tracker_test.cc
deleted file mode 100644
index 4f5a463382d..00000000000
--- a/chromium/third_party/blink/renderer/core/frame/sticky_frame_tracker_test.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-#include "third_party/blink/renderer/core/frame/sticky_frame_tracker.h"
-
-namespace blink {
-
-class StickyFrameTrackerTest : public testing::Test {};
-
-TEST_F(StickyFrameTrackerTest,
- MainFrameScrollOffsetChange_FrameViewportOffsetDoesNotChange_Sticky) {
- StickyFrameTracker tracker;
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 0), IntPoint(0, 0)));
- EXPECT_TRUE(tracker.UpdateStickyStatus(IntPoint(0, 1), IntPoint(0, 0)));
-}
-
-TEST_F(
- StickyFrameTrackerTest,
- FrameViewportOffsetRangeTooSmallComparedToMainFrameScrollOffsetRange_Sticky) {
- StickyFrameTracker tracker;
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 0), IntPoint(0, 0)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 1), IntPoint(0, 1)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 2), IntPoint(0, 2)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 3), IntPoint(0, 3)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 4), IntPoint(0, 4)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 5), IntPoint(0, 0)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 6), IntPoint(0, 1)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 7), IntPoint(0, 2)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 8), IntPoint(0, 3)));
- EXPECT_TRUE(tracker.UpdateStickyStatus(IntPoint(0, 9), IntPoint(0, 4)));
-}
-
-TEST_F(
- StickyFrameTrackerTest,
- FrameViewportOffsetRangeNotSmallComparedToMainFrameScrollOffsetRange_NotSticky) {
- StickyFrameTracker tracker;
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 0), IntPoint(0, 0)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 1), IntPoint(0, 1)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 2), IntPoint(0, 2)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 3), IntPoint(0, 3)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 4), IntPoint(0, 4)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 5), IntPoint(0, 0)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 6), IntPoint(0, 1)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 7), IntPoint(0, 2)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 8), IntPoint(0, 3)));
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 9), IntPoint(0, 5)));
-}
-
-TEST_F(StickyFrameTrackerTest, OnceStickyAlwaysSticky) {
- StickyFrameTracker tracker;
- EXPECT_FALSE(tracker.UpdateStickyStatus(IntPoint(0, 0), IntPoint(0, 0)));
- EXPECT_TRUE(tracker.UpdateStickyStatus(IntPoint(0, 1), IntPoint(0, 0)));
-
- EXPECT_TRUE(tracker.UpdateStickyStatus(IntPoint(0, 100), IntPoint(0, 100)));
- EXPECT_TRUE(tracker.UpdateStickyStatus(IntPoint(0, 101), IntPoint(0, 101)));
- EXPECT_TRUE(tracker.UpdateStickyStatus(IntPoint(0, 102), IntPoint(0, 102)));
-}
-
-TEST_F(StickyFrameTrackerTest, IsLarge) {
- EXPECT_TRUE(StickyFrameTracker::IsLarge(IntSize(10, 10), IntSize(10, 3)));
- EXPECT_FALSE(StickyFrameTracker::IsLarge(IntSize(10, 10), IntSize(10, 2)));
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/use_counter_helper.cc b/chromium/third_party/blink/renderer/core/frame/use_counter_helper.cc
index d43ec30bcd6..e8efbf81947 100644
--- a/chromium/third_party/blink/renderer/core/frame/use_counter_helper.cc
+++ b/chromium/third_party/blink/renderer/core/frame/use_counter_helper.cc
@@ -116,7 +116,7 @@ void UseCounterHelper::ClearMeasurementForTesting(WebFeature feature) {
features_recorded_.reset(static_cast<size_t>(feature));
}
-void UseCounterHelper::Trace(Visitor* visitor) {
+void UseCounterHelper::Trace(Visitor* visitor) const {
visitor->Trace(observers_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/use_counter_helper.h b/chromium/third_party/blink/renderer/core/frame/use_counter_helper.h
index cf5b705f409..d2be59c0e68 100644
--- a/chromium/third_party/blink/renderer/core/frame/use_counter_helper.h
+++ b/chromium/third_party/blink/renderer/core/frame/use_counter_helper.h
@@ -100,7 +100,7 @@ class CORE_EXPORT UseCounterHelper final {
// remove a reference to the observer and stop notifications.
virtual bool OnCountFeature(WebFeature) = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
// Repeated calls are ignored.
@@ -133,7 +133,7 @@ class CORE_EXPORT UseCounterHelper final {
void ClearMeasurementForTesting(WebFeature);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
friend class UseCounterHelperTest;
diff --git a/chromium/third_party/blink/renderer/core/frame/use_counter_helper_test.cc b/chromium/third_party/blink/renderer/core/frame/use_counter_helper_test.cc
index b7e1b3ff789..bde9f13537d 100644
--- a/chromium/third_party/blink/renderer/core/frame/use_counter_helper_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/use_counter_helper_test.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/css/properties/css_property.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/html/html_html_element.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/page/page.h"
@@ -178,101 +179,111 @@ TEST_F(UseCounterHelperTest, CSSSelectorPseudoIs) {
EXPECT_FALSE(document.IsUseCounted(WebFeature::kCSSSelectorPseudoWhere));
}
-TEST_F(UseCounterHelperTest, CSSContainLayoutNonPositionedDescendants) {
+TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageColumnIndefiniteWidth) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
Document& document = dummy_page_holder->GetDocument();
- WebFeature feature = WebFeature::kCSSContainLayoutPositionedDescendants;
+ WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
EXPECT_FALSE(document.IsUseCounted(feature));
document.documentElement()->setInnerHTML(
- "<div style='contain: layout;'>"
+ "<div style='display: inline-grid; grid-template-columns: 50%;'>"
"</div>");
UpdateAllLifecyclePhases(document);
EXPECT_FALSE(document.IsUseCounted(feature));
}
-TEST_F(UseCounterHelperTest, CSSContainLayoutAbsolutelyPositionedDescendants) {
+TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight1) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
Document& document = dummy_page_holder->GetDocument();
- WebFeature feature = WebFeature::kCSSContainLayoutPositionedDescendants;
+ WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
EXPECT_FALSE(document.IsUseCounted(feature));
document.documentElement()->setInnerHTML(
- "<div style='contain: layout;'>"
- " <div style='position: absolute;'></div>"
+ "<div style='display: inline-grid; grid-template-rows: 50%;'>"
"</div>");
UpdateAllLifecyclePhases(document);
EXPECT_TRUE(document.IsUseCounted(feature));
}
-TEST_F(UseCounterHelperTest,
- CSSContainLayoutAbsolutelyPositionedDescendantsAlreadyContainingBlock) {
+TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight2) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
Document& document = dummy_page_holder->GetDocument();
- WebFeature feature = WebFeature::kCSSContainLayoutPositionedDescendants;
+ WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
EXPECT_FALSE(document.IsUseCounted(feature));
document.documentElement()->setInnerHTML(
- "<div style='position: relative; contain: layout;'>"
- " <div style='position: absolute;'></div>"
+ "<div style='display: inline-grid; grid-template-rows: 50% 50%;'>"
"</div>");
UpdateAllLifecyclePhases(document);
- EXPECT_FALSE(document.IsUseCounted(feature));
+ EXPECT_TRUE(document.IsUseCounted(feature));
}
-TEST_F(UseCounterHelperTest, CSSContainLayoutFixedPositionedDescendants) {
+TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight3) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
Document& document = dummy_page_holder->GetDocument();
- WebFeature feature = WebFeature::kCSSContainLayoutPositionedDescendants;
+ WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
EXPECT_FALSE(document.IsUseCounted(feature));
document.documentElement()->setInnerHTML(
- "<div style='contain: layout;'>"
- " <div style='position: fixed;'></div>"
+ "<div style='display: inline-grid; grid-template-rows: 100% 100%;'>"
"</div>");
UpdateAllLifecyclePhases(document);
EXPECT_TRUE(document.IsUseCounted(feature));
}
-TEST_F(UseCounterHelperTest,
- CSSContainLayoutFixedPositionedDescendantsAlreadyContainingBlock) {
+TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight4) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
Document& document = dummy_page_holder->GetDocument();
- WebFeature feature = WebFeature::kCSSContainLayoutPositionedDescendants;
+ WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
EXPECT_FALSE(document.IsUseCounted(feature));
document.documentElement()->setInnerHTML(
- "<div style='transform: translateX(100px); contain: layout;'>"
- " <div style='position: fixed;'></div>"
+ "<div style='display: inline-grid; grid-template-rows: minmax(50%, "
+ "100%);'>"
"</div>");
UpdateAllLifecyclePhases(document);
+ EXPECT_TRUE(document.IsUseCounted(feature));
+}
+
+TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight5) {
+ auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+ Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
+ Document& document = dummy_page_holder->GetDocument();
+ WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
EXPECT_FALSE(document.IsUseCounted(feature));
+ document.documentElement()->setInnerHTML(
+ "<div style='display: inline-grid; max-height: 0; grid-template-rows: "
+ "100%;'>"
+ "</div>");
+ UpdateAllLifecyclePhases(document);
+ EXPECT_TRUE(document.IsUseCounted(feature));
}
-TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageColumnIndefiniteWidth) {
+TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight6) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
EXPECT_FALSE(document.IsUseCounted(feature));
document.documentElement()->setInnerHTML(
- "<div style='display: inline-grid; grid-template-columns: 50%;'>"
+ "<div style='display: inline-grid; grid-template-rows: 100%;'>"
"</div>");
UpdateAllLifecyclePhases(document);
EXPECT_FALSE(document.IsUseCounted(feature));
}
-TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight) {
+TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight7) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
EXPECT_FALSE(document.IsUseCounted(feature));
document.documentElement()->setInnerHTML(
- "<div style='display: inline-grid; grid-template-rows: 50%;'>"
+ "<div style='display: inline-grid; grid-template-rows: minmax(100%, "
+ "100%);'>"
"</div>");
UpdateAllLifecyclePhases(document);
- EXPECT_TRUE(document.IsUseCounted(feature));
+ EXPECT_FALSE(document.IsUseCounted(feature));
}
TEST_F(UseCounterHelperTest, CSSFlexibleBox) {
@@ -339,26 +350,26 @@ TEST_F(DeprecationTest, InspectorDisablesDeprecation) {
deprecation_.MuteForInspector();
Deprecation::WarnOnDeprecatedProperties(GetFrame(), property);
EXPECT_FALSE(deprecation_.IsSuppressed(property));
- Deprecation::CountDeprecation(dummy_->GetDocument(), feature);
+ Deprecation::CountDeprecation(GetFrame()->DomWindow(), feature);
EXPECT_FALSE(use_counter_.HasRecordedMeasurement(feature));
deprecation_.MuteForInspector();
Deprecation::WarnOnDeprecatedProperties(GetFrame(), property);
EXPECT_FALSE(deprecation_.IsSuppressed(property));
- Deprecation::CountDeprecation(dummy_->GetDocument(), feature);
+ Deprecation::CountDeprecation(GetFrame()->DomWindow(), feature);
EXPECT_FALSE(use_counter_.HasRecordedMeasurement(feature));
deprecation_.UnmuteForInspector();
Deprecation::WarnOnDeprecatedProperties(GetFrame(), property);
EXPECT_FALSE(deprecation_.IsSuppressed(property));
- Deprecation::CountDeprecation(dummy_->GetDocument(), feature);
+ Deprecation::CountDeprecation(GetFrame()->DomWindow(), feature);
EXPECT_FALSE(use_counter_.HasRecordedMeasurement(feature));
deprecation_.UnmuteForInspector();
Deprecation::WarnOnDeprecatedProperties(GetFrame(), property);
// TODO: use the actually deprecated property to get a deprecation message.
EXPECT_FALSE(deprecation_.IsSuppressed(property));
- Deprecation::CountDeprecation(dummy_->GetDocument(), feature);
+ Deprecation::CountDeprecation(GetFrame()->DomWindow(), feature);
EXPECT_TRUE(use_counter_.HasRecordedMeasurement(feature));
}
@@ -476,4 +487,56 @@ TEST_F(UseCounterHelperTest, MaximumCSSSampleId) {
max_sample_id);
}
+TEST_F(UseCounterHelperTest, CSSMarkerPseudoElementUA) {
+ // Check that UA styles for list markers are not counted.
+ auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+ Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
+ Document& document = dummy_page_holder->GetDocument();
+ WebFeature feature = WebFeature::kHasMarkerPseudoElement;
+ EXPECT_FALSE(document.IsUseCounted(feature));
+ document.body()->setInnerHTML(R"HTML(
+ <style>
+ li::before {
+ content: "[before]";
+ display: list-item;
+ }
+ </style>
+ <ul>
+ <li style="list-style: decimal outside"></li>
+ <li style="list-style: decimal inside"></li>
+ <li style="list-style: disc outside"></li>
+ <li style="list-style: disc inside"></li>
+ <li style="list-style: '- ' outside"></li>
+ <li style="list-style: '- ' inside"></li>
+ <li style="list-style: linear-gradient(blue, cyan) outside"></li>
+ <li style="list-style: linear-gradient(blue, cyan) inside"></li>
+ <li style="list-style: none outside"></li>
+ <li style="list-style: none inside"></li>
+ </ul>
+ )HTML");
+ UpdateAllLifecyclePhases(document);
+ EXPECT_FALSE(document.IsUseCounted(feature));
+}
+
+TEST_F(UseCounterHelperTest, CSSMarkerPseudoElementAuthor) {
+ // Check that author styles for list markers are counted.
+ auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+ Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
+ Document& document = dummy_page_holder->GetDocument();
+ WebFeature feature = WebFeature::kHasMarkerPseudoElement;
+ EXPECT_FALSE(document.IsUseCounted(feature));
+ document.body()->setInnerHTML(R"HTML(
+ <style>
+ li::marker {
+ color: blue;
+ }
+ </style>
+ <ul>
+ <li></li>
+ </ul>
+ )HTML");
+ UpdateAllLifecyclePhases(document);
+ EXPECT_TRUE(document.IsUseCounted(feature));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/user_activation.cc b/chromium/third_party/blink/renderer/core/frame/user_activation.cc
index e69d1fcb8a6..d7919c918aa 100644
--- a/chromium/third_party/blink/renderer/core/frame/user_activation.cc
+++ b/chromium/third_party/blink/renderer/core/frame/user_activation.cc
@@ -22,7 +22,7 @@ UserActivation::UserActivation(LocalDOMWindow* window) : window_(window) {}
UserActivation::~UserActivation() = default;
-void UserActivation::Trace(Visitor* visitor) {
+void UserActivation::Trace(Visitor* visitor) const {
visitor->Trace(window_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/user_activation.h b/chromium/third_party/blink/renderer/core/frame/user_activation.h
index 5683c4b1d8e..d6de0be0cf8 100644
--- a/chromium/third_party/blink/renderer/core/frame/user_activation.h
+++ b/chromium/third_party/blink/renderer/core/frame/user_activation.h
@@ -23,7 +23,7 @@ class UserActivation final : public ScriptWrappable {
UserActivation(bool has_been_active, bool is_active);
~UserActivation() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool hasBeenActive() const;
bool isActive() const;
diff --git a/chromium/third_party/blink/renderer/core/frame/user_activation.idl b/chromium/third_party/blink/renderer/core/frame/user_activation.idl
index fc1e3151b04..5b110d1b210 100644
--- a/chromium/third_party/blink/renderer/core/frame/user_activation.idl
+++ b/chromium/third_party/blink/renderer/core/frame/user_activation.idl
@@ -4,7 +4,6 @@
// https://github.com/dtapuska/useractivation
[
- RuntimeEnabled=UserActivationAPI,
Exposed=(Window,Worker,AudioWorklet)
] interface UserActivation {
[Measure] readonly attribute boolean hasBeenActive;
diff --git a/chromium/third_party/blink/renderer/core/frame/viewport_data.cc b/chromium/third_party/blink/renderer/core/frame/viewport_data.cc
index 043605a27b8..2e63af4765b 100644
--- a/chromium/third_party/blink/renderer/core/frame/viewport_data.cc
+++ b/chromium/third_party/blink/renderer/core/frame/viewport_data.cc
@@ -16,7 +16,7 @@ namespace blink {
ViewportData::ViewportData(Document& document) : document_(document) {}
-void ViewportData::Trace(Visitor* visitor) {
+void ViewportData::Trace(Visitor* visitor) const {
visitor->Trace(document_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/viewport_data.h b/chromium/third_party/blink/renderer/core/frame/viewport_data.h
index 050c4c5ec34..9760850c39a 100644
--- a/chromium/third_party/blink/renderer/core/frame/viewport_data.h
+++ b/chromium/third_party/blink/renderer/core/frame/viewport_data.h
@@ -18,7 +18,7 @@ class Document;
class ViewportData final : public GarbageCollected<ViewportData> {
public:
ViewportData(Document& document);
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
void Shutdown();
bool ShouldMergeWithLegacyDescription(ViewportDescription::Type) const;
diff --git a/chromium/third_party/blink/renderer/core/frame/virtual_keyboard_overlay_changed_observer.cc b/chromium/third_party/blink/renderer/core/frame/virtual_keyboard_overlay_changed_observer.cc
new file mode 100644
index 00000000000..6b230b8add6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/virtual_keyboard_overlay_changed_observer.cc
@@ -0,0 +1,17 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/frame/virtual_keyboard_overlay_changed_observer.h"
+
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+
+namespace blink {
+
+VirtualKeyboardOverlayChangedObserver::VirtualKeyboardOverlayChangedObserver(
+ LocalFrame* frame) {
+ if (frame)
+ frame->RegisterVirtualKeyboardOverlayChangedObserver(this);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/virtual_keyboard_overlay_changed_observer.h b/chromium/third_party/blink/renderer/core/frame/virtual_keyboard_overlay_changed_observer.h
new file mode 100644
index 00000000000..a4b25754b71
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/virtual_keyboard_overlay_changed_observer.h
@@ -0,0 +1,43 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_VIRTUAL_KEYBOARD_OVERLAY_CHANGED_OBSERVER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_VIRTUAL_KEYBOARD_OVERLAY_CHANGED_OBSERVER_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+
+namespace gfx {
+class Rect;
+}
+
+namespace blink {
+
+class LocalFrame;
+
+// This observer is used to register for VK overlay geometry change
+// notifications that is sent from Browser process to |LocalFrame|.
+// Browser process receives these VK showing/hiding events from the OS input
+// services. It is reported as a rectangle that occludes the web content.
+class CORE_EXPORT VirtualKeyboardOverlayChangedObserver
+ : public GarbageCollectedMixin {
+ public:
+ // This is used to fire a VK overlay geometry change JS event.
+ // The |Rect| is the VK rectangle that occludes the web content.
+ // This is called while the keyboard is shown or hidden.
+ virtual void VirtualKeyboardOverlayChanged(const gfx::Rect&) = 0;
+
+ protected:
+ // Input to this function should be a valid |LocalFrame| that gets the
+ // VK overlay geometry change notification from the Browser process.
+ // This is created when |VirtualKeyboard| object is initialized which is
+ // part of the |Navigator| object. If this is passed as |nullptr|, then
+ // it won't be registered in |LocalFrame| to get notified about the VK overlay
+ // geometry change.
+ explicit VirtualKeyboardOverlayChangedObserver(LocalFrame*);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_VIRTUAL_KEYBOARD_OVERLAY_CHANGED_OBSERVER_H_
diff --git a/chromium/third_party/blink/renderer/core/frame/visual_viewport.cc b/chromium/third_party/blink/renderer/core/frame/visual_viewport.cc
index 74903f8f5ba..e3f3c4bcd07 100644
--- a/chromium/third_party/blink/renderer/core/frame/visual_viewport.cc
+++ b/chromium/third_party/blink/renderer/core/frame/visual_viewport.cc
@@ -335,7 +335,7 @@ VisualViewport::~VisualViewport() {
SendUMAMetrics();
}
-void VisualViewport::Trace(Visitor* visitor) {
+void VisualViewport::Trace(Visitor* visitor) const {
visitor->Trace(page_);
ScrollableArea::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/visual_viewport.h b/chromium/third_party/blink/renderer/core/frame/visual_viewport.h
index d2cdb057951..694de62d195 100644
--- a/chromium/third_party/blink/renderer/core/frame/visual_viewport.h
+++ b/chromium/third_party/blink/renderer/core/frame/visual_viewport.h
@@ -102,7 +102,7 @@ class CORE_EXPORT VisualViewport : public GarbageCollected<VisualViewport>,
explicit VisualViewport(Page&);
~VisualViewport() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void InitializeScrollbars();
diff --git a/chromium/third_party/blink/renderer/core/frame/visual_viewport_test.cc b/chromium/third_party/blink/renderer/core/frame/visual_viewport_test.cc
index 5fc2bfe737b..d494c382f2c 100644
--- a/chromium/third_party/blink/renderer/core/frame/visual_viewport_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/visual_viewport_test.cc
@@ -2056,63 +2056,6 @@ TEST_P(VisualViewportTest, ResizeWithScrollAnchoring) {
frame_view.LayoutViewport()->GetScrollOffset());
}
-// Ensure that resize anchoring as happens when browser controls hide/show
-// affects the scrollable area that's currently set as the root scroller.
-TEST_P(VisualViewportTest, ResizeAnchoringWithRootScroller) {
- ScopedSetRootScrollerForTest root_scroller(true);
-
- InitializeWithAndroidSettings();
- WebView()->MainFrameWidget()->Resize(IntSize(800, 600));
-
- RegisterMockedHttpURLLoad("root-scroller-div.html");
- NavigateTo(base_url_ + "root-scroller-div.html");
-
- LocalFrameView& frame_view = *WebView()->MainFrameImpl()->GetFrameView();
-
- Element* scroller = GetFrame()->GetDocument()->getElementById("rootScroller");
- NonThrowableExceptionState non_throw;
- GetFrame()->GetDocument()->setRootScroller(scroller, non_throw);
-
- WebView()->SetPageScaleFactor(3.f);
- frame_view.GetScrollableArea()->SetScrollOffset(
- ScrollOffset(0, 400), mojom::blink::ScrollType::kProgrammatic);
-
- VisualViewport& visual_viewport = WebView()->GetPage()->GetVisualViewport();
- visual_viewport.SetScrollOffset(
- ScrollOffset(0, 400), mojom::blink::ScrollType::kProgrammatic,
- mojom::blink::ScrollBehavior::kInstant, ScrollableArea::ScrollCallback());
-
- WebView()->MainFrameWidget()->Resize(IntSize(800, 500));
-
- EXPECT_EQ(ScrollOffset(), frame_view.LayoutViewport()->GetScrollOffset());
-}
-
-// Ensure that resize anchoring as happens when the device is rotated affects
-// the scrollable area that's currently set as the root scroller.
-TEST_P(VisualViewportTest, RotationAnchoringWithRootScroller) {
- ScopedSetRootScrollerForTest root_scroller(true);
-
- InitializeWithAndroidSettings();
- WebView()->MainFrameWidget()->Resize(IntSize(800, 600));
-
- RegisterMockedHttpURLLoad("root-scroller-div.html");
- NavigateTo(base_url_ + "root-scroller-div.html");
-
- LocalFrameView& frame_view = *WebView()->MainFrameImpl()->GetFrameView();
-
- Element* scroller = GetFrame()->GetDocument()->getElementById("rootScroller");
- NonThrowableExceptionState non_throw;
- GetFrame()->GetDocument()->setRootScroller(scroller, non_throw);
- UpdateAllLifecyclePhases();
-
- scroller->setScrollTop(800);
-
- WebView()->MainFrameWidget()->Resize(IntSize(600, 800));
-
- EXPECT_EQ(ScrollOffset(), frame_view.LayoutViewport()->GetScrollOffset());
- EXPECT_EQ(600, scroller->scrollTop());
-}
-
// Make sure a composited background-attachment:fixed background gets resized
// by browser controls.
TEST_P(VisualViewportTest, ResizeCompositedAndFixedBackground) {
diff --git a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.cc b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.cc
index b39722bc337..c81907fdf03 100644
--- a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.cc
+++ b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.cc
@@ -10,12 +10,16 @@
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/swap_promise.h"
#include "cc/trees/ukm_manager.h"
+#include "third_party/blink/public/mojom/input/input_handler.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/scheduler/web_render_widget_scheduling_state.h"
+#include "third_party/blink/public/web/web_autofill_client.h"
#include "third_party/blink/public/web/web_local_frame.h"
+#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_widget_client.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h"
@@ -31,6 +35,7 @@
#include "third_party/blink/renderer/core/layout/hit_test_location.h"
#include "third_party/blink/renderer/core/layout/hit_test_request.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
+#include "third_party/blink/renderer/core/loader/interactive_detector.h"
#include "third_party/blink/renderer/core/page/context_menu_controller.h"
#include "third_party/blink/renderer/core/page/drag_actions.h"
#include "third_party/blink/renderer/core/page/drag_controller.h"
@@ -83,9 +88,12 @@ WebFrameWidgetBase::WebFrameWidgetBase(
: widget_base_(std::make_unique<WidgetBase>(this,
std::move(widget_host),
std::move(widget))),
- client_(&client),
- frame_widget_host_(std::move(frame_widget_host)),
- receiver_(this, std::move(frame_widget)) {}
+ client_(&client) {
+ frame_widget_host_.Bind(std::move(frame_widget_host),
+ ThreadScheduler::Current()->IPCTaskRunner());
+ receiver_.Bind(std::move(frame_widget),
+ ThreadScheduler::Current()->IPCTaskRunner());
+}
WebFrameWidgetBase::~WebFrameWidgetBase() = default;
@@ -163,15 +171,17 @@ WebDragOperation WebFrameWidgetBase::DragTargetDragEnter(
modifiers);
}
-WebDragOperation WebFrameWidgetBase::DragTargetDragOver(
+void WebFrameWidgetBase::DragTargetDragOver(
const gfx::PointF& point_in_viewport,
const gfx::PointF& screen_point,
WebDragOperationsMask operations_allowed,
- int modifiers) {
+ uint32_t modifiers,
+ DragTargetDragOverCallback callback) {
operations_allowed_ = operations_allowed;
- return DragTargetDragEnterOrOver(point_in_viewport, screen_point, kDragOver,
- modifiers);
+ blink::WebDragOperation operation = DragTargetDragEnterOrOver(
+ point_in_viewport, screen_point, kDragOver, modifiers);
+ std::move(callback).Run(operation);
}
void WebFrameWidgetBase::DragTargetDragLeave(
@@ -179,11 +189,11 @@ void WebFrameWidgetBase::DragTargetDragLeave(
const gfx::PointF& screen_point) {
DCHECK(current_drag_data_);
- // TODO(paulmeyer): It shouldn't be possible for |m_currentDragData| to be
+ // TODO(paulmeyer): It shouldn't be possible for |current_drag_data_| to be
// null here, but this is somehow happening (rarely). This suggests that in
// some cases drag-leave is happening before drag-enter, which should be
// impossible. This needs to be investigated further. Once fixed, the extra
- // check for |!m_currentDragData| should be removed. (crbug.com/671152)
+ // check for |!current_drag_data_| should be removed. (crbug.com/671152)
if (IgnoreInputEvents() || !current_drag_data_) {
CancelDrag();
return;
@@ -279,6 +289,12 @@ void WebFrameWidgetBase::SetBackgroundOpaque(bool opaque) {
}
}
+void WebFrameWidgetBase::SetTextDirection(base::i18n::TextDirection direction) {
+ LocalFrame* focusedFrame = FocusedLocalFrameInWidget();
+ if (focusedFrame)
+ focusedFrame->SetTextDirection(direction);
+}
+
void WebFrameWidgetBase::CancelDrag() {
// It's possible for this to be called while we're not doing a drag if
// it's from a previous page that got unloaded.
@@ -373,9 +389,9 @@ Page* WebFrameWidgetBase::GetPage() const {
return View()->GetPage();
}
-const mojo::AssociatedRemote<mojom::blink::FrameWidgetHost>&
+mojom::blink::FrameWidgetHost*
WebFrameWidgetBase::GetAssociatedFrameWidgetHost() const {
- return frame_widget_host_;
+ return frame_widget_host_.get();
}
void WebFrameWidgetBase::DidAcquirePointerLock() {
@@ -401,9 +417,11 @@ void WebFrameWidgetBase::RequestDecode(
Client()->RequestDecode(image, std::move(callback));
}
-void WebFrameWidgetBase::Trace(Visitor* visitor) {
+void WebFrameWidgetBase::Trace(Visitor* visitor) const {
visitor->Trace(local_root_);
visitor->Trace(current_drag_data_);
+ visitor->Trace(frame_widget_host_);
+ visitor->Trace(receiver_);
}
void WebFrameWidgetBase::SetNeedsRecalculateRasterScales() {
@@ -455,6 +473,21 @@ void WebFrameWidgetBase::DidCommitAndDrawCompositorFrame() {
Client()->DidCommitAndDrawCompositorFrame();
}
+void WebFrameWidgetBase::DidObserveFirstScrollDelay(
+ base::TimeDelta first_scroll_delay,
+ base::TimeTicks first_scroll_timestamp) {
+ if (!local_root_ || !(local_root_->GetFrame()) ||
+ !(local_root_->GetFrame()->GetDocument())) {
+ return;
+ }
+ InteractiveDetector* interactive_detector =
+ InteractiveDetector::From(*(local_root_->GetFrame()->GetDocument()));
+ if (interactive_detector) {
+ interactive_detector->DidObserveFirstScrollDelay(first_scroll_delay,
+ first_scroll_timestamp);
+ }
+}
+
void WebFrameWidgetBase::OnDeferMainFrameUpdatesChanged(bool defer) {
Client()->OnDeferMainFrameUpdatesChanged(defer);
}
@@ -480,6 +513,19 @@ void WebFrameWidgetBase::WillBeginMainFrame() {
Client()->WillBeginMainFrame();
}
+void WebFrameWidgetBase::SubmitThroughputData(
+ ukm::SourceId source_id,
+ int aggregated_percent,
+ int impl_percent,
+ base::Optional<int> main_percent) {
+ local_root_->Client()->SubmitThroughputData(source_id, aggregated_percent,
+ impl_percent, main_percent);
+}
+
+void WebFrameWidgetBase::ScheduleAnimationForWebTests() {
+ Client()->ScheduleAnimationForWebTests();
+}
+
int WebFrameWidgetBase::GetLayerTreeId() {
if (!View()->does_composite())
return 0;
@@ -527,6 +573,10 @@ mojom::blink::DisplayMode WebFrameWidgetBase::DisplayMode() const {
return display_mode_;
}
+const WebVector<WebRect>& WebFrameWidgetBase::WindowSegments() const {
+ return window_segments_;
+}
+
void WebFrameWidgetBase::StartDeferringCommits(base::TimeDelta timeout) {
if (!View()->does_composite())
return;
@@ -684,6 +734,59 @@ void WebFrameWidgetBase::DispatchRafAlignedInput(base::TimeTicks frame_time) {
}
}
+bool WebFrameWidgetBase::WillHandleGestureEvent(const WebGestureEvent& event) {
+ return Client()->WillHandleGestureEvent(event);
+}
+
+bool WebFrameWidgetBase::WillHandleMouseEvent(const WebMouseEvent& event) {
+ return Client()->WillHandleMouseEvent(event);
+}
+
+void WebFrameWidgetBase::ObserveGestureEventAndResult(
+ const WebGestureEvent& gesture_event,
+ const gfx::Vector2dF& unused_delta,
+ const cc::OverscrollBehavior& overscroll_behavior,
+ bool event_processed) {
+ Client()->DidHandleGestureScrollEvent(gesture_event, unused_delta,
+ overscroll_behavior, event_processed);
+}
+
+void WebFrameWidgetBase::DidHandleKeyEvent() {
+ ClearEditCommands();
+}
+
+void WebFrameWidgetBase::QueueSyntheticEvent(
+ std::unique_ptr<blink::WebCoalescedInputEvent> event) {
+ Client()->QueueSyntheticEvent(std::move(event));
+}
+
+WebTextInputType WebFrameWidgetBase::GetTextInputType() {
+ if (Client()->ShouldDispatchImeEventsToPepper())
+ return Client()->GetPepperTextInputType();
+
+ WebInputMethodController* controller = GetActiveWebInputMethodController();
+ if (!controller)
+ return WebTextInputType::kWebTextInputTypeNone;
+ return controller->TextInputType();
+}
+
+void WebFrameWidgetBase::GetWidgetInputHandler(
+ mojo::PendingReceiver<mojom::blink::WidgetInputHandler> request,
+ mojo::PendingRemote<mojom::blink::WidgetInputHandlerHost> host) {
+ Client()->GetWidgetInputHandler(std::move(request), std::move(host));
+}
+
+bool WebFrameWidgetBase::HasCurrentImeGuard(
+ bool request_to_show_virtual_keyboard) {
+ return Client()->HasCurrentImeGuard(request_to_show_virtual_keyboard);
+}
+
+void WebFrameWidgetBase::SendCompositionRangeChanged(
+ const gfx::Range& range,
+ const std::vector<gfx::Rect>& character_bounds) {
+ Client()->SendCompositionRangeChanged(range, character_bounds);
+}
+
void WebFrameWidgetBase::ApplyViewportChangesForTesting(
const ApplyViewportChangesArgs& args) {
widget_base_->ApplyViewportChanges(args);
@@ -698,10 +801,54 @@ void WebFrameWidgetBase::SetDisplayMode(mojom::blink::DisplayMode mode) {
}
}
+void WebFrameWidgetBase::SetWindowSegments(WebVector<WebRect> window_segments) {
+ if (!window_segments_.Equals(window_segments))
+ window_segments_ = std::move(window_segments);
+}
+
void WebFrameWidgetBase::SetCursor(const ui::Cursor& cursor) {
widget_base_->SetCursor(cursor);
}
+bool WebFrameWidgetBase::HandlingInputEvent() {
+ return widget_base_->input_handler().handling_input_event();
+}
+
+void WebFrameWidgetBase::SetHandlingInputEvent(bool handling) {
+ widget_base_->input_handler().set_handling_input_event(handling);
+}
+
+void WebFrameWidgetBase::ProcessInputEventSynchronously(
+ const WebCoalescedInputEvent& event,
+ HandledEventCallback callback) {
+ widget_base_->input_handler().HandleInputEvent(event, std::move(callback));
+}
+
+void WebFrameWidgetBase::UpdateTextInputState() {
+ widget_base_->UpdateTextInputState();
+}
+
+void WebFrameWidgetBase::ForceTextInputStateUpdate() {
+ widget_base_->ForceTextInputStateUpdate();
+}
+
+void WebFrameWidgetBase::UpdateCompositionInfo() {
+ widget_base_->UpdateCompositionInfo(/*immediate_request=*/false);
+}
+
+void WebFrameWidgetBase::UpdateSelectionBounds() {
+ widget_base_->UpdateSelectionBounds();
+}
+
+void WebFrameWidgetBase::ShowVirtualKeyboard() {
+ widget_base_->ShowVirtualKeyboard();
+}
+
+void WebFrameWidgetBase::RequestCompositionUpdates(bool immediate_request,
+ bool monitor_updates) {
+ widget_base_->RequestCompositionUpdates(immediate_request, monitor_updates);
+}
+
void WebFrameWidgetBase::AutoscrollStart(const gfx::PointF& position) {
GetAssociatedFrameWidgetHost()->AutoscrollStart(std::move(position));
}
@@ -714,6 +861,24 @@ void WebFrameWidgetBase::AutoscrollEnd() {
GetAssociatedFrameWidgetHost()->AutoscrollEnd();
}
+void WebFrameWidgetBase::DidMeaningfulLayout(WebMeaningfulLayout layout_type) {
+ if (layout_type == blink::WebMeaningfulLayout::kVisuallyNonEmpty) {
+ NotifySwapAndPresentationTime(
+ base::NullCallback(),
+ WTF::Bind(&WebFrameWidgetBase::PresentationCallbackForMeaningfulLayout,
+ WrapPersistent(this)));
+ }
+
+ if (client_)
+ client_->DidMeaningfulLayout(layout_type);
+}
+
+void WebFrameWidgetBase::PresentationCallbackForMeaningfulLayout(
+ blink::WebSwapResult,
+ base::TimeTicks) {
+ GetAssociatedFrameWidgetHost()->DidFirstVisuallyNonEmptyPaint();
+}
+
void WebFrameWidgetBase::RequestAnimationAfterDelay(
const base::TimeDelta& delay) {
DCHECK(request_animation_after_delay_timer_.get());
@@ -765,6 +930,11 @@ WebFrameWidgetBase::EnsureCompositorPaintDispatcher(
return paint_dispatcher_;
}
+void WebFrameWidgetBase::SetDelegatedInkMetadata(
+ std::unique_ptr<viz::DelegatedInkMetadata> metadata) {
+ widget_base_->LayerTreeHost()->SetDelegatedInkMetadata(std::move(metadata));
+}
+
// Enables measuring and reporting both presentation times and swap times in
// swap promises.
class ReportTimeSwapPromise : public cc::SwapPromise {
@@ -919,4 +1089,264 @@ WebFrameWidgetBase::RendererWidgetSchedulingState() {
return widget_base_->RendererWidgetSchedulingState();
}
+void WebFrameWidgetBase::WaitForDebuggerWhenShown() {
+ local_root_->WaitForDebuggerWhenShown();
+}
+
+void WebFrameWidgetBase::SetTextZoomFactor(float text_zoom_factor) {
+ local_root_->GetFrame()->SetTextZoomFactor(text_zoom_factor);
+}
+
+float WebFrameWidgetBase::TextZoomFactor() {
+ return local_root_->GetFrame()->TextZoomFactor();
+}
+
+void WebFrameWidgetBase::SetMainFrameOverlayColor(SkColor color) {
+ DCHECK(!local_root_->Parent());
+ local_root_->GetFrame()->SetMainFrameColorOverlay(color);
+}
+
+void WebFrameWidgetBase::AddEditCommandForNextKeyEvent(const WebString& name,
+ const WebString& value) {
+ edit_commands_.push_back(mojom::blink::EditCommand::New(name, value));
+}
+
+bool WebFrameWidgetBase::HandleCurrentKeyboardEvent() {
+ bool did_execute_command = false;
+ WebLocalFrame* frame = FocusedWebLocalFrameInWidget();
+ if (!frame)
+ frame = local_root_;
+ for (const auto& command : edit_commands_) {
+ // In gtk and cocoa, it's possible to bind multiple edit commands to one
+ // key (but it's the exception). Once one edit command is not executed, it
+ // seems safest to not execute the rest.
+ if (!frame->ExecuteCommand(command->name, command->value))
+ break;
+ did_execute_command = true;
+ }
+
+ return did_execute_command;
+}
+
+void WebFrameWidgetBase::ClearEditCommands() {
+ edit_commands_ = Vector<mojom::blink::EditCommandPtr>();
+}
+
+WebTextInputInfo WebFrameWidgetBase::TextInputInfo() {
+ WebInputMethodController* controller = GetActiveWebInputMethodController();
+ if (!controller)
+ return WebTextInputInfo();
+ return controller->TextInputInfo();
+}
+
+ui::mojom::blink::VirtualKeyboardVisibilityRequest
+WebFrameWidgetBase::GetLastVirtualKeyboardVisibilityRequest() {
+ WebInputMethodController* controller = GetActiveWebInputMethodController();
+ if (!controller)
+ return ui::mojom::blink::VirtualKeyboardVisibilityRequest::NONE;
+ return controller->GetLastVirtualKeyboardVisibilityRequest();
+}
+
+bool WebFrameWidgetBase::ShouldSuppressKeyboardForFocusedElement() {
+ WebLocalFrame* focused_frame = FocusedWebLocalFrameInWidget();
+ if (!focused_frame)
+ return false;
+ return focused_frame->ShouldSuppressKeyboardForFocusedElement();
+}
+
+void WebFrameWidgetBase::GetEditContextBoundsInWindow(
+ base::Optional<gfx::Rect>* edit_context_control_bounds,
+ base::Optional<gfx::Rect>* edit_context_selection_bounds) {
+ WebInputMethodController* controller = GetActiveWebInputMethodController();
+ if (!controller)
+ return;
+ WebRect control_bounds;
+ WebRect selection_bounds;
+ controller->GetLayoutBounds(&control_bounds, &selection_bounds);
+ client_->ConvertViewportToWindow(&control_bounds);
+ edit_context_control_bounds->emplace(control_bounds);
+ if (controller->IsEditContextActive()) {
+ client_->ConvertViewportToWindow(&selection_bounds);
+ edit_context_selection_bounds->emplace(selection_bounds);
+ }
+}
+
+int32_t WebFrameWidgetBase::ComputeWebTextInputNextPreviousFlags() {
+ WebInputMethodController* controller = GetActiveWebInputMethodController();
+ if (!controller)
+ return 0;
+ return controller->ComputeWebTextInputNextPreviousFlags();
+}
+
+void WebFrameWidgetBase::ResetVirtualKeyboardVisibilityRequest() {
+ WebInputMethodController* controller = GetActiveWebInputMethodController();
+ if (!controller)
+ return;
+ controller->SetVirtualKeyboardVisibilityRequest(
+ ui::mojom::blink::VirtualKeyboardVisibilityRequest::NONE);
+ ;
+}
+
+bool WebFrameWidgetBase::GetSelectionBoundsInWindow(
+ gfx::Rect* focus,
+ gfx::Rect* anchor,
+ base::i18n::TextDirection* focus_dir,
+ base::i18n::TextDirection* anchor_dir,
+ bool* is_anchor_first) {
+ if (Client()->ShouldDispatchImeEventsToPepper()) {
+ // TODO(kinaba) http://crbug.com/101101
+ // Current Pepper IME API does not handle selection bounds. So we simply
+ // use the caret position as an empty range for now. It will be updated
+ // after Pepper API equips features related to surrounding text retrieval.
+ gfx::Rect pepper_caret = Client()->GetPepperCaretBounds();
+ if (pepper_caret == *focus && pepper_caret == *anchor)
+ return false;
+ *focus = pepper_caret;
+ *anchor = *focus;
+ return true;
+ }
+ WebRect focus_webrect;
+ WebRect anchor_webrect;
+ SelectionBounds(focus_webrect, anchor_webrect);
+ client_->ConvertViewportToWindow(&focus_webrect);
+ client_->ConvertViewportToWindow(&anchor_webrect);
+
+ // if the bounds are the same return false.
+ if (gfx::Rect(focus_webrect) == *focus &&
+ gfx::Rect(anchor_webrect) == *anchor)
+ return false;
+ *focus = gfx::Rect(focus_webrect);
+ *anchor = gfx::Rect(anchor_webrect);
+
+ WebLocalFrame* focused_frame = FocusedWebLocalFrameInWidget();
+ if (!focused_frame)
+ return true;
+ focused_frame->SelectionTextDirection(*focus_dir, *anchor_dir);
+ *is_anchor_first = focused_frame->IsSelectionAnchorFirst();
+ return true;
+}
+
+void WebFrameWidgetBase::ClearTextInputState() {
+ widget_base_->ClearTextInputState();
+}
+
+void WebFrameWidgetBase::SetFocus(bool focus) {
+ widget_base_->SetFocus(focus);
+}
+
+bool WebFrameWidgetBase::HasFocus() {
+ return widget_base_->has_focus();
+}
+
+void WebFrameWidgetBase::SetToolTipText(const String& tooltip_text,
+ TextDirection dir) {
+ widget_base_->SetToolTipText(tooltip_text, dir);
+}
+
+void WebFrameWidgetBase::DidOverscroll(
+ const gfx::Vector2dF& overscroll_delta,
+ const gfx::Vector2dF& accumulated_overscroll,
+ const gfx::PointF& position,
+ const gfx::Vector2dF& velocity) {
+#if defined(OS_MACOSX)
+ // On OSX the user can disable the elastic overscroll effect. If that's the
+ // case, don't forward the overscroll notification.
+ if (!widget_base_->LayerTreeHost()->GetSettings().enable_elastic_overscroll)
+ return;
+#endif
+
+ cc::OverscrollBehavior overscroll_behavior =
+ widget_base_->LayerTreeHost()->overscroll_behavior();
+ if (!widget_base_->input_handler().DidOverscrollFromBlink(
+ overscroll_delta, accumulated_overscroll, position, velocity,
+ overscroll_behavior))
+ return;
+
+ // If we're currently handling an event, stash the overscroll data such that
+ // it can be bundled in the event ack.
+ Client()->DidOverscroll(overscroll_delta, accumulated_overscroll, position,
+ velocity, overscroll_behavior);
+}
+
+void WebFrameWidgetBase::InjectGestureScrollEvent(
+ blink::WebGestureDevice device,
+ const gfx::Vector2dF& delta,
+ ui::ScrollGranularity granularity,
+ cc::ElementId scrollable_area_element_id,
+ blink::WebInputEvent::Type injected_type) {
+ widget_base_->input_handler().InjectGestureScrollEvent(
+ device, delta, granularity, scrollable_area_element_id, injected_type);
+}
+
+void WebFrameWidgetBase::DidChangeCursor(const ui::Cursor& cursor) {
+ widget_base_->SetCursor(cursor);
+ Client()->DidChangeCursor(cursor);
+}
+
+void WebFrameWidgetBase::FocusChangeComplete() {
+ blink::WebLocalFrame* focused = LocalRoot()->View()->FocusedFrame();
+
+ if (focused && focused->AutofillClient())
+ focused->AutofillClient()->DidCompleteFocusChangeInFrame();
+}
+
+void WebFrameWidgetBase::ShowVirtualKeyboardOnElementFocus() {
+ widget_base_->ShowVirtualKeyboardOnElementFocus();
+}
+
+void WebFrameWidgetBase::ProcessTouchAction(WebTouchAction touch_action) {
+ if (!widget_base_->ProcessTouchAction(touch_action))
+ return;
+ Client()->SetTouchAction(touch_action);
+}
+
+void WebFrameWidgetBase::DidHandleGestureEvent(const WebGestureEvent& event,
+ bool event_cancelled) {
+ if (event_cancelled) {
+ // The delegate() doesn't need to hear about cancelled events.
+ return;
+ }
+
+#if defined(OS_ANDROID) || defined(USE_AURA)
+ if (event.GetType() == WebInputEvent::Type::kGestureTap) {
+ widget_base_->input_handler().ShowVirtualKeyboard();
+ } else if (event.GetType() == WebInputEvent::Type::kGestureLongPress) {
+ WebInputMethodController* controller = GetActiveWebInputMethodController();
+ if (!controller || controller->TextInputInfo().value.IsEmpty())
+ widget_base_->input_handler().UpdateTextInputState();
+ else
+ widget_base_->input_handler().ShowVirtualKeyboard();
+ }
+#endif
+}
+
+gfx::Range WebFrameWidgetBase::CompositionRange() {
+ WebLocalFrame* focused_frame = FocusedWebLocalFrameInWidget();
+ if (!focused_frame)
+ return gfx::Range::InvalidRange();
+ blink::WebInputMethodController* controller =
+ focused_frame->GetInputMethodController();
+ WebRange web_range = controller->CompositionRange();
+ if (web_range.IsNull())
+ return gfx::Range::InvalidRange();
+ return gfx::Range(web_range.StartOffset(), web_range.EndOffset());
+}
+
+void WebFrameWidgetBase::GetCompositionCharacterBoundsInWindow(
+ Vector<gfx::Rect>* bounds) {
+ WebLocalFrame* focused_frame = FocusedWebLocalFrameInWidget();
+ if (!focused_frame)
+ return;
+ blink::WebInputMethodController* controller =
+ focused_frame->GetInputMethodController();
+ blink::WebVector<blink::WebRect> bounds_from_blink;
+ if (!controller->GetCompositionCharacterBounds(bounds_from_blink))
+ return;
+
+ for (size_t i = 0; i < bounds_from_blink.size(); ++i) {
+ Client()->ConvertViewportToWindow(&bounds_from_blink[i]);
+ bounds->push_back(bounds_from_blink[i]);
+ }
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.h b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.h
index 9cfb36d4718..5c9a031e9d2 100644
--- a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.h
+++ b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.h
@@ -10,8 +10,6 @@
#include "cc/input/layer_selection_bound.h"
#include "cc/input/overscroll_behavior.h"
#include "cc/trees/layer_tree_host.h"
-#include "mojo/public/cpp/bindings/associated_receiver.h"
-#include "mojo/public/cpp/bindings/associated_remote.h"
#include "services/network/public/mojom/referrer_policy.mojom-blink-forward.h"
#include "third_party/blink/public/common/input/web_coalesced_input_event.h"
#include "third_party/blink/public/common/input/web_gesture_device.h"
@@ -25,6 +23,10 @@
#include "third_party/blink/renderer/platform/graphics/apply_viewport_changes.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_image.h"
#include "third_party/blink/renderer/platform/heap/member.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
+#include "third_party/blink/renderer/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/widget/frame_widget.h"
#include "third_party/blink/renderer/platform/widget/widget_base_client.h"
@@ -33,7 +35,7 @@
namespace gfx {
class Point;
class PointF;
-}
+} // namespace gfx
namespace blink {
class AnimationWorkletMutatorDispatcherImpl;
@@ -83,6 +85,11 @@ class CORE_EXPORT WebFrameWidgetBase
void AutoscrollFling(const gfx::Vector2dF& position);
void AutoscrollEnd();
+ // Notifies RenderWidgetHostImpl that the frame widget has painted something.
+ void DidMeaningfulLayout(WebMeaningfulLayout layout_type);
+
+ bool HandleCurrentKeyboardEvent();
+
// Creates or returns cached mutator dispatcher. This usually requires a
// round trip to the compositor. The returned WeakPtr must only be
// dereferenced on the output |mutator_task_runner|.
@@ -117,6 +124,37 @@ class CORE_EXPORT WebFrameWidgetBase
cc::EventListenerProperties EventListenerProperties(
cc::EventListenerClass) const final;
mojom::blink::DisplayMode DisplayMode() const override;
+ const WebVector<WebRect>& WindowSegments() const override;
+ void SetDelegatedInkMetadata(
+ std::unique_ptr<viz::DelegatedInkMetadata> metadata) final;
+ void DidOverscroll(const gfx::Vector2dF& overscroll_delta,
+ const gfx::Vector2dF& accumulated_overscroll,
+ const gfx::PointF& position,
+ const gfx::Vector2dF& velocity) override;
+ void InjectGestureScrollEvent(WebGestureDevice device,
+ const gfx::Vector2dF& delta,
+ ui::ScrollGranularity granularity,
+ cc::ElementId scrollable_area_element_id,
+ WebInputEvent::Type injected_type) override;
+ void DidChangeCursor(const ui::Cursor&) override;
+ void GetCompositionCharacterBoundsInWindow(
+ Vector<gfx::Rect>* bounds) override;
+ gfx::Range CompositionRange() override;
+ WebTextInputInfo TextInputInfo() override;
+ ui::mojom::VirtualKeyboardVisibilityRequest
+ GetLastVirtualKeyboardVisibilityRequest() override;
+ bool ShouldSuppressKeyboardForFocusedElement() override;
+ void GetEditContextBoundsInWindow(
+ base::Optional<gfx::Rect>* control_bounds,
+ base::Optional<gfx::Rect>* selection_bounds) override;
+ int32_t ComputeWebTextInputNextPreviousFlags() override;
+ void ResetVirtualKeyboardVisibilityRequest() override;
+ bool GetSelectionBoundsInWindow(gfx::Rect* focus,
+ gfx::Rect* anchor,
+ base::i18n::TextDirection* focus_dir,
+ base::i18n::TextDirection* anchor_dir,
+ bool* is_anchor_first) override;
+ void ClearTextInputState() override;
// WebFrameWidget implementation.
WebLocalFrame* LocalRoot() const override;
@@ -125,19 +163,10 @@ class CORE_EXPORT WebFrameWidgetBase
const gfx::PointF& screen_point,
WebDragOperationsMask operations_allowed,
int modifiers) override;
- WebDragOperation DragTargetDragOver(const gfx::PointF& point_in_viewport,
- const gfx::PointF& screen_point,
- WebDragOperationsMask operations_allowed,
- int modifiers) override;
- void DragTargetDragLeave(const gfx::PointF& point_in_viewport,
- const gfx::PointF& screen_point) override;
void DragTargetDrop(const WebDragData&,
const gfx::PointF& point_in_viewport,
const gfx::PointF& screen_point,
int modifiers) override;
- void DragSourceEndedAt(const gfx::PointF& point_in_viewport,
- const gfx::PointF& screen_point,
- WebDragOperation) override;
void SendOverscrollEventFromImplSide(
const gfx::Vector2dF& overscroll_delta,
cc::ElementId scroll_latched_element_id) override;
@@ -152,6 +181,13 @@ class CORE_EXPORT WebFrameWidgetBase
WebReportTimeCallback presentation_callback) override;
scheduler::WebRenderWidgetSchedulingState* RendererWidgetSchedulingState()
override;
+ void WaitForDebuggerWhenShown() override;
+ void SetTextZoomFactor(float text_zoom_factor) override;
+ float TextZoomFactor() override;
+ void SetMainFrameOverlayColor(SkColor) override;
+ void AddEditCommandForNextKeyEvent(const WebString& name,
+ const WebString& value) override;
+ void ClearEditCommands() override;
// Called when a drag-n-drop operation should begin.
void StartDragging(network::mojom::ReferrerPolicy,
@@ -177,7 +213,21 @@ class CORE_EXPORT WebFrameWidgetBase
void ShowContextMenu(WebMenuSourceType) override;
void SetCompositorVisible(bool visible) override;
void SetDisplayMode(mojom::blink::DisplayMode) override;
+ void SetWindowSegments(WebVector<WebRect> window_segments) override;
void SetCursor(const ui::Cursor& cursor) override;
+ bool HandlingInputEvent() override;
+ void SetHandlingInputEvent(bool handling) override;
+ void ProcessInputEventSynchronously(const WebCoalescedInputEvent&,
+ HandledEventCallback) override;
+ void UpdateTextInputState() override;
+ void ForceTextInputStateUpdate() override;
+ void UpdateCompositionInfo() override;
+ void UpdateSelectionBounds() override;
+ void ShowVirtualKeyboard() override;
+ void RequestCompositionUpdates(bool immediate_request,
+ bool monitor_updates) override;
+ bool HasFocus() override;
+ void SetFocus(bool focus) override;
// WidgetBaseClient methods.
void DispatchRafAlignedInput(base::TimeTicks frame_time) override;
@@ -189,13 +239,56 @@ class CORE_EXPORT WebFrameWidgetBase
void RequestNewLayerTreeFrameSink(
LayerTreeFrameSinkCallback callback) override;
void DidCompletePageScaleAnimation() override;
+ void DidObserveFirstScrollDelay(
+ base::TimeDelta first_scroll_delay,
+ base::TimeTicks first_scroll_timestamp) override;
void DidBeginMainFrame() override;
void WillBeginMainFrame() override;
+ void SubmitThroughputData(ukm::SourceId source_id,
+ int aggregated_percent,
+ int impl_percent,
+ base::Optional<int> main_percent) override;
+ void FocusChangeComplete() override;
+ bool WillHandleGestureEvent(const WebGestureEvent& event) override;
+ bool WillHandleMouseEvent(const WebMouseEvent& event) override;
+ void ObserveGestureEventAndResult(
+ const WebGestureEvent& gesture_event,
+ const gfx::Vector2dF& unused_delta,
+ const cc::OverscrollBehavior& overscroll_behavior,
+ bool event_processed) override;
+ bool SupportsBufferedTouchEvents() override { return true; }
+ void DidHandleKeyEvent() override;
+ void QueueSyntheticEvent(
+ std::unique_ptr<blink::WebCoalescedInputEvent>) override;
+ WebTextInputType GetTextInputType() override;
+ void GetWidgetInputHandler(
+ mojo::PendingReceiver<mojom::blink::WidgetInputHandler> request,
+ mojo::PendingRemote<mojom::blink::WidgetInputHandlerHost> host) override;
+ bool HasCurrentImeGuard(bool request_to_show_virtual_keyboard) override;
+ blink::FrameWidget* FrameWidget() override { return this; }
+ void SendCompositionRangeChanged(
+ const gfx::Range& range,
+ const std::vector<gfx::Rect>& character_bounds) override;
+ void ScheduleAnimationForWebTests() override;
// mojom::blink::FrameWidget methods.
+ void DragTargetDragOver(const gfx::PointF& point_in_viewport,
+ const gfx::PointF& screen_point,
+ WebDragOperationsMask operations_allowed,
+ uint32_t modifiers,
+ DragTargetDragOverCallback callback) override;
+ void DragTargetDragLeave(const gfx::PointF& point_in_viewport,
+ const gfx::PointF& screen_point) override;
+ void DragSourceEndedAt(const gfx::PointF& point_in_viewport,
+ const gfx::PointF& screen_point,
+ WebDragOperation) override;
void DragSourceSystemDragEnded() override;
void SetBackgroundOpaque(bool opaque) override;
+ // For both mainframe and childframe change the text direction of the
+ // currently selected input field (if any).
+ void SetTextDirection(base::i18n::TextDirection direction) override;
+
// Sets the inherited effective touch action on an out-of-process iframe.
void SetInheritedEffectiveTouchActionForSubFrame(
WebTouchAction touch_action) override {}
@@ -221,7 +314,7 @@ class CORE_EXPORT WebFrameWidgetBase
// focused frame has a different local root.
LocalFrame* FocusedLocalFrameInWidget() const;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
// For when the embedder itself change scales on the page (e.g. devtools)
// and wants all of the content at the new scale to be crisp
@@ -280,6 +373,15 @@ class CORE_EXPORT WebFrameWidgetBase
// BeginMainFrame, and update the document lifecycle.
void SynchronouslyCompositeForTesting(base::TimeTicks frame_time);
+ void SetToolTipText(const String& tooltip_text, TextDirection dir);
+
+ void ShowVirtualKeyboardOnElementFocus();
+ void ProcessTouchAction(WebTouchAction touch_action);
+
+ // Called when a gesture event has been processed.
+ void DidHandleGestureEvent(const WebGestureEvent& event,
+ bool event_cancelled);
+
protected:
enum DragAction { kDragEnter, kDragOver };
@@ -301,8 +403,7 @@ class CORE_EXPORT WebFrameWidgetBase
// the page is shutting down, but will be valid at all other times.
Page* GetPage() const;
- const mojo::AssociatedRemote<mojom::blink::FrameWidgetHost>&
- GetAssociatedFrameWidgetHost() const;
+ mojom::blink::FrameWidgetHost* GetAssociatedFrameWidgetHost() const;
// Helper function to process events while pointer locked.
void PointerLockMouseEvent(const WebCoalescedInputEvent&);
@@ -334,6 +435,8 @@ class CORE_EXPORT WebFrameWidgetBase
private:
void CancelDrag();
void RequestAnimationAfterDelayTimerFired(TimerBase*);
+ void PresentationCallbackForMeaningfulLayout(blink::WebSwapResult,
+ base::TimeTicks);
static bool ignore_input_events_;
@@ -346,6 +449,8 @@ class CORE_EXPORT WebFrameWidgetBase
mojom::blink::DisplayMode display_mode_;
+ WebVector<WebRect> window_segments_;
+
// This is owned by the LayerTreeHostImpl, and should only be used on the
// compositor thread, so we keep the TaskRunner where you post tasks to
// make that happen.
@@ -363,13 +468,22 @@ class CORE_EXPORT WebFrameWidgetBase
std::unique_ptr<TaskRunnerTimer<WebFrameWidgetBase>>
request_animation_after_delay_timer_;
- mojo::AssociatedRemote<mojom::blink::FrameWidgetHost> frame_widget_host_;
- mojo::AssociatedReceiver<mojom::blink::FrameWidget> receiver_;
+ // WebFrameWidgetBase is not tied to ExecutionContext
+ HeapMojoAssociatedRemote<mojom::blink::FrameWidgetHost,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ frame_widget_host_{nullptr};
+ // WebFrameWidgetBase is not tied to ExecutionContext
+ HeapMojoAssociatedReceiver<mojom::blink::FrameWidget,
+ WebFrameWidgetBase,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ receiver_{this, nullptr};
// Different consumers in the browser process makes different assumptions, so
// must always send the first IPC regardless of value.
base::Optional<bool> has_touch_handlers_;
+ Vector<mojom::blink::EditCommandPtr> edit_commands_;
+
friend class WebViewImpl;
friend class ReportTimeSwapPromise;
};
diff --git a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
index 12628872674..b6745c8eacf 100644
--- a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
+++ b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -188,7 +188,7 @@ WebFrameWidgetImpl::WebFrameWidgetImpl(
WebFrameWidgetImpl::~WebFrameWidgetImpl() = default;
-void WebFrameWidgetImpl::Trace(Visitor* visitor) {
+void WebFrameWidgetImpl::Trace(Visitor* visitor) const {
visitor->Trace(mouse_capture_element_);
WebFrameWidgetBase::Trace(visitor);
}
@@ -565,7 +565,7 @@ void WebFrameWidgetImpl::MouseCaptureLost() {
mouse_capture_element_ = nullptr;
}
-void WebFrameWidgetImpl::SetFocus(bool enable) {
+void WebFrameWidgetImpl::FocusChanged(bool enable) {
if (enable)
GetPage()->GetFocusController().SetActive(true);
GetPage()->GetFocusController().SetFocused(enable);
@@ -611,6 +611,7 @@ void WebFrameWidgetImpl::SetFocus(bool enable) {
ime_accept_events_ = false;
}
}
+ Client()->FocusChanged(enable);
}
bool WebFrameWidgetImpl::SelectionBounds(WebRect& anchor_web,
@@ -839,7 +840,7 @@ WebInputEventResult WebFrameWidgetImpl::HandleGestureEvent(
pos_in_local_frame_root, block_bounds);
}
event_result = WebInputEventResult::kHandledSystem;
- Client()->DidHandleGestureEvent(event, event_cancelled);
+ DidHandleGestureEvent(event, event_cancelled);
return event_result;
case WebInputEvent::Type::kGestureTwoFingerTap:
case WebInputEvent::Type::kGestureLongPress:
@@ -853,7 +854,7 @@ WebInputEventResult WebFrameWidgetImpl::HandleGestureEvent(
LocalFrame* frame = LocalRootImpl()->GetFrame();
WebGestureEvent scaled_event = TransformWebGestureEvent(frame->View(), event);
event_result = frame->GetEventHandler().HandleGestureEvent(scaled_event);
- Client()->DidHandleGestureEvent(event, event_cancelled);
+ DidHandleGestureEvent(event, event_cancelled);
return event_result;
}
diff --git a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
index 494c1d3f25e..4a37cdc8181 100644
--- a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
+++ b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
@@ -99,7 +99,6 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase,
void SetCursorVisibilityState(bool is_visible) override;
void MouseCaptureLost() override;
- void SetFocus(bool enable) override;
bool SelectionBounds(WebRect& anchor, WebRect& focus) const override;
void SetRemoteViewportIntersection(const ViewportIntersectionState&) override;
void SetIsInertForSubFrame(bool) override;
@@ -145,13 +144,14 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase,
void BeginCommitCompositorFrame() override;
void EndCommitCompositorFrame(base::TimeTicks commit_start_time) override;
void DidBeginMainFrame() override;
+ void FocusChanged(bool enable) override;
void UpdateMainFrameLayoutSize();
// Event related methods:
void MouseContextMenu(const WebMouseEvent&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class WebFrameWidget; // For WebFrameWidget::create.
diff --git a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
index 64803c9f6c9..74cc39af0a7 100644
--- a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+++ b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -129,6 +129,7 @@
#include "third_party/blink/public/web/web_node.h"
#include "third_party/blink/public/web/web_performance.h"
#include "third_party/blink/public/web/web_plugin.h"
+#include "third_party/blink/public/web/web_print_page_description.h"
#include "third_party/blink/public/web/web_print_params.h"
#include "third_party/blink/public/web/web_print_preset_options.h"
#include "third_party/blink/public/web/web_range.h"
@@ -231,6 +232,7 @@
#include "third_party/blink/renderer/core/page/print_context.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
+#include "third_party/blink/renderer/core/paint/paint_timing.h"
#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
@@ -323,7 +325,8 @@ class ChromePrintContext : public PrintContext {
void SpoolAllPagesWithBoundariesForTesting(
cc::PaintCanvas* canvas,
- const FloatSize& page_size_in_pixels) {
+ const FloatSize& page_size_in_pixels,
+ const FloatSize& spool_size_in_pixels) {
DispatchEventsForPrintingOnAllFrames();
if (!GetFrame()->GetDocument() ||
!GetFrame()->GetDocument()->GetLayoutView())
@@ -336,10 +339,8 @@ class ChromePrintContext : public PrintContext {
ComputePageRects(page_size_in_pixels);
- const float page_width = page_size_in_pixels.Width();
- wtf_size_t num_pages = PageRects().size();
- int total_height = num_pages * (page_size_in_pixels.Height() + 1) - 1;
- FloatRect all_pages_rect(0, 0, page_width, total_height);
+ FloatRect all_pages_rect(0, 0, spool_size_in_pixels.Width(),
+ spool_size_in_pixels.Height());
PaintRecordBuilder builder(canvas->GetPrintingMetafile());
GraphicsContext& context = builder.Context();
@@ -349,6 +350,7 @@ class ChromePrintContext : public PrintContext {
// Fill the whole background by white.
context.FillRect(all_pages_rect, Color::kWhite);
+ wtf_size_t num_pages = PageRects().size();
int current_height = 0;
for (wtf_size_t page_index = 0; page_index < num_pages; page_index++) {
// Draw a line for a page boundary if this isn't the first page.
@@ -356,13 +358,31 @@ class ChromePrintContext : public PrintContext {
context.Save();
context.SetStrokeThickness(1);
context.SetStrokeColor(Color(0, 0, 255));
- context.DrawLine(IntPoint(0, current_height - 1),
- IntPoint(page_width, current_height - 1));
+ context.DrawLine(
+ IntPoint(0, current_height - 1),
+ IntPoint(spool_size_in_pixels.Width(), current_height - 1));
context.Restore();
}
AffineTransform transform;
transform.Translate(0, current_height);
+
+ WebPrintPageDescription description;
+ GetFrame()->GetDocument()->GetPageDescription(page_index, &description);
+ if (description.orientation == PageOrientation::kUpright) {
+ current_height += page_size_in_pixels.Height() + 1;
+ } else {
+ if (description.orientation == PageOrientation::kRotateRight) {
+ transform.Translate(page_size_in_pixels.Height(), 0);
+ transform.Rotate(90);
+ } else {
+ DCHECK_EQ(description.orientation, PageOrientation::kRotateLeft);
+ transform.Translate(0, page_size_in_pixels.Width());
+ transform.Rotate(-90);
+ }
+ current_height += page_size_in_pixels.Width() + 1;
+ }
+
#if defined(OS_WIN) || defined(OS_MACOSX)
// Account for the disabling of scaling in spoolPage. In the context of
// SpoolAllPagesWithBoundariesForTesting the scale HAS NOT been
@@ -376,8 +396,6 @@ class ChromePrintContext : public PrintContext {
SpoolPage(context, page_index);
context.Restore();
-
- current_height += page_size_in_pixels.Height() + 1;
}
canvas->drawPicture(context.EndRecording());
}
@@ -465,7 +483,7 @@ class ChromePluginPrintContext final : public ChromePrintContext {
~ChromePluginPrintContext() override = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(plugin_);
ChromePrintContext::Trace(visitor);
}
@@ -513,7 +531,9 @@ class PaintPreviewContext : public PrintContext {
PaintPreviewContext(LocalFrame* frame) : PrintContext(frame, false) {}
~PaintPreviewContext() override = default;
- bool Capture(cc::PaintCanvas* canvas, FloatSize size) {
+ bool Capture(cc::PaintCanvas* canvas,
+ FloatSize size,
+ bool include_linked_destinations) {
// This code is based on ChromePrintContext::SpoolSinglePage()/SpoolPage().
// It differs in that it:
// 1. Uses a different set of flags for painting and the graphics context.
@@ -539,12 +559,14 @@ class PaintPreviewContext : public PrintContext {
// This calls BeginRecording on |builder| with dimensions specified by the
// CullRect.
+ GlobalPaintFlags flags =
+ kGlobalPaintNormalPhase | kGlobalPaintFlattenCompositingLayers;
+ if (include_linked_destinations)
+ flags |= kGlobalPaintAddUrlMetadata;
+
frame_view->PaintContentsOutsideOfLifecycle(
- builder.Context(),
- kGlobalPaintNormalPhase | kGlobalPaintFlattenCompositingLayers |
- kGlobalPaintAddUrlMetadata,
- CullRect(RoundedIntRect(bounds)));
- {
+ builder.Context(), flags, CullRect(RoundedIntRect(bounds)));
+ if (include_linked_destinations) {
// Add anchors.
ScopedPaintChunkProperties scoped_paint_chunk_properties(
builder.Context().GetPaintController(), property_tree_state, builder,
@@ -572,6 +594,12 @@ int WebFrame::InstanceCount() {
return g_frame_count;
}
+// static
+WebFrame* WebFrame::FromFrameToken(const base::UnguessableToken& frame_token) {
+ auto* frame = Frame::ResolveFrame(frame_token);
+ return WebFrame::FromFrame(frame);
+}
+
WebLocalFrame* WebLocalFrame::FrameForCurrentContext() {
v8::Local<v8::Context> context =
v8::Isolate::GetCurrent()->GetCurrentContext();
@@ -777,7 +805,7 @@ void WebLocalFrameImpl::ClearIsolatedWorldCSPForTesting(int32_t world_id) {
return;
}
- GetFrame()->GetDocument()->ClearIsolatedWorldCSPForTesting(world_id);
+ GetFrame()->DomWindow()->ClearIsolatedWorldCSPForTesting(world_id);
}
void WebLocalFrameImpl::SetIsolatedWorldInfo(int32_t world_id,
@@ -800,12 +828,27 @@ void WebLocalFrameImpl::SetIsolatedWorldInfo(int32_t world_id,
CHECK(info.content_security_policy.IsNull() || security_origin);
DOMWrapperWorld::SetIsolatedWorldSecurityOrigin(world_id, security_origin);
+ DOMWrapperWorld::SetNonMainWorldStableId(world_id, info.stable_id);
DOMWrapperWorld::SetNonMainWorldHumanReadableName(world_id,
info.human_readable_name);
IsolatedWorldCSP::Get().SetContentSecurityPolicy(
world_id, info.content_security_policy, security_origin);
}
+WebString WebLocalFrameImpl::GetIsolatedWorldStableId(
+ v8::Local<v8::Context> context) const {
+ const DOMWrapperWorld& world = DOMWrapperWorld::World(context);
+ DCHECK(!world.IsMainWorld());
+ return world.NonMainWorldStableId();
+}
+
+WebString WebLocalFrameImpl::GetIsolatedWorldHumanReadableName(
+ v8::Local<v8::Context> context) const {
+ const DOMWrapperWorld& world = DOMWrapperWorld::World(context);
+ DCHECK(!world.IsMainWorld());
+ return world.NonMainWorldHumanReadableName();
+}
+
void WebLocalFrameImpl::Alert(const WebString& message) {
DCHECK(GetFrame());
ScriptState* script_state = ToScriptStateForMainWorld(GetFrame());
@@ -918,6 +961,12 @@ v8::Local<v8::Context> WebLocalFrameImpl::MainWorldScriptContext() const {
return script_state->GetContext();
}
+int32_t WebLocalFrameImpl::GetScriptContextWorldId(
+ v8::Local<v8::Context> script_context) const {
+ DCHECK_EQ(this, FrameForContext(script_context));
+ return DOMWrapperWorld::World(script_context).GetWorldId();
+}
+
v8::Local<v8::Object> WebLocalFrameImpl::GlobalProxy() const {
return MainWorldScriptContext()->Global();
}
@@ -988,11 +1037,11 @@ bool WebLocalFrameImpl::IsViewSourceModeEnabled() const {
void WebLocalFrameImpl::SetReferrerForRequest(WebURLRequest& request,
const WebURL& referrer_url) {
String referrer = referrer_url.IsEmpty()
- ? GetFrame()->GetDocument()->OutgoingReferrer()
+ ? GetFrame()->DomWindow()->OutgoingReferrer()
: String(referrer_url.GetString());
ResourceRequest& resource_request = request.ToMutableResourceRequest();
resource_request.SetReferrerPolicy(
- GetFrame()->GetDocument()->GetReferrerPolicy());
+ GetFrame()->DomWindow()->GetReferrerPolicy());
resource_request.SetReferrerString(referrer);
}
@@ -1136,32 +1185,9 @@ bool WebLocalFrameImpl::IsSelectionAnchorFirst() const {
return selection.GetSelectionInDOMTree().IsBaseFirst();
}
-void WebLocalFrameImpl::SetTextDirection(base::i18n::TextDirection direction) {
- // The Editor::SetBaseWritingDirection() function checks if we can change
- // the text direction of the selected node and updates its DOM "dir"
- // attribute and its CSS "direction" property.
- // So, we just call the function as Safari does.
- Editor& editor = frame_->GetEditor();
- if (!editor.CanEdit())
- return;
-
- switch (direction) {
- case base::i18n::TextDirection::UNKNOWN_DIRECTION:
- editor.SetBaseWritingDirection(WritingDirection::kNatural);
- break;
-
- case base::i18n::TextDirection::LEFT_TO_RIGHT:
- editor.SetBaseWritingDirection(WritingDirection::kLeftToRight);
- break;
-
- case base::i18n::TextDirection::RIGHT_TO_LEFT:
- editor.SetBaseWritingDirection(WritingDirection::kRightToLeft);
- break;
-
- default:
- NOTIMPLEMENTED();
- break;
- }
+void WebLocalFrameImpl::SetTextDirectionForTesting(
+ base::i18n::TextDirection direction) {
+ frame_->SetTextDirection(direction);
}
void WebLocalFrameImpl::ReplaceMisspelledRange(const WebString& text) {
@@ -1379,7 +1405,7 @@ bool WebLocalFrameImpl::SetEditableSelectionOffsets(int start, int end) {
bool WebLocalFrameImpl::SetCompositionFromExistingText(
int composition_start,
int composition_end,
- const WebVector<WebImeTextSpan>& ime_text_spans) {
+ const WebVector<ui::ImeTextSpan>& ime_text_spans) {
TRACE_EVENT0("blink", "WebLocalFrameImpl::setCompositionFromExistingText");
if (EditContext* edit_context =
GetFrame()->GetInputMethodController().GetActiveEditContext()) {
@@ -1520,19 +1546,29 @@ void WebLocalFrameImpl::DispatchPrintEventRecursively(
}
}
-int WebLocalFrameImpl::PrintBegin(const WebPrintParams& print_params,
- const WebNode& constrain_to_node) {
- WebPluginContainerImpl* plugin_container = nullptr;
+WebPluginContainerImpl* WebLocalFrameImpl::GetPluginToPrintHelper(
+ const WebNode& constrain_to_node) {
if (constrain_to_node.IsNull()) {
// If this is a plugin document, check if the plugin supports its own
// printing. If it does, we will delegate all printing to that.
- plugin_container = GetFrame()->GetWebPluginContainer();
- } else {
- // We only support printing plugin nodes for now.
- plugin_container =
- To<WebPluginContainerImpl>(constrain_to_node.PluginContainer());
+ return GetFrame()->GetWebPluginContainer();
}
+ // We only support printing plugin nodes for now.
+ return To<WebPluginContainerImpl>(constrain_to_node.PluginContainer());
+}
+
+WebPlugin* WebLocalFrameImpl::GetPluginToPrint(
+ const WebNode& constrain_to_node) {
+ WebPluginContainerImpl* plugin_container =
+ GetPluginToPrintHelper(constrain_to_node);
+ return plugin_container ? plugin_container->Plugin() : nullptr;
+}
+
+int WebLocalFrameImpl::PrintBegin(const WebPrintParams& print_params,
+ const WebNode& constrain_to_node) {
+ WebPluginContainerImpl* plugin_container =
+ GetPluginToPrintHelper(constrain_to_node);
if (plugin_container && plugin_container->SupportsPaginatedPrint()) {
print_context_ = MakeGarbageCollected<ChromePluginPrintContext>(
GetFrame(), plugin_container, print_params);
@@ -1584,7 +1620,8 @@ bool WebLocalFrameImpl::GetPrintPresetOptionsForPlugin(
}
bool WebLocalFrameImpl::CapturePaintPreview(const WebRect& bounds,
- cc::PaintCanvas* canvas) {
+ cc::PaintCanvas* canvas,
+ bool include_linked_destinations) {
FloatSize float_bounds(bounds.width, bounds.height);
GetFrame()->GetDocument()->SetIsPaintingPreview(true);
ResourceCacheValidationSuppressor validation_suppressor(
@@ -1592,7 +1629,8 @@ bool WebLocalFrameImpl::CapturePaintPreview(const WebRect& bounds,
GetFrame()->View()->ForceLayoutForPagination(float_bounds, float_bounds, 1);
PaintPreviewContext* paint_preview_context =
MakeGarbageCollected<PaintPreviewContext>(GetFrame());
- bool success = paint_preview_context->Capture(canvas, float_bounds);
+ bool success = paint_preview_context->Capture(canvas, float_bounds,
+ include_linked_destinations);
GetFrame()->GetDocument()->SetIsPaintingPreview(false);
GetFrame()->EndPrinting();
return success;
@@ -1608,13 +1646,37 @@ void WebLocalFrameImpl::GetPageDescription(
GetFrame()->GetDocument()->GetPageDescription(page_index, description);
}
+WebSize WebLocalFrameImpl::SpoolSizeInPixelsForTesting(
+ const WebSize& page_size_in_pixels,
+ int page_count) {
+ int spool_width = page_size_in_pixels.width;
+ int spool_height = 0;
+ for (int page_index = 0; page_index < page_count; page_index++) {
+ // Make room for the 1px tall page separator.
+ if (page_index)
+ spool_height++;
+
+ WebPrintPageDescription description;
+ GetFrame()->GetDocument()->GetPageDescription(page_index, &description);
+ if (description.orientation == PageOrientation::kUpright) {
+ spool_height += page_size_in_pixels.height;
+ } else {
+ spool_height += page_size_in_pixels.width;
+ spool_width = std::max(spool_width, page_size_in_pixels.height);
+ }
+ }
+ return WebSize(spool_width, spool_height);
+}
+
void WebLocalFrameImpl::PrintPagesForTesting(
cc::PaintCanvas* canvas,
- const WebSize& page_size_in_pixels) {
+ const WebSize& page_size_in_pixels,
+ const WebSize& spool_size_in_pixels) {
DCHECK(print_context_);
print_context_->SpoolAllPagesWithBoundariesForTesting(
- canvas, FloatSize(page_size_in_pixels.width, page_size_in_pixels.height));
+ canvas, FloatSize(page_size_in_pixels.width, page_size_in_pixels.height),
+ FloatSize(spool_size_in_pixels.width, spool_size_in_pixels.height));
}
WebRect WebLocalFrameImpl::GetSelectionBoundsRectForTesting() const {
@@ -1789,7 +1851,7 @@ WebLocalFrameImpl::~WebLocalFrameImpl() {
g_frame_count--;
}
-void WebLocalFrameImpl::Trace(Visitor* visitor) {
+void WebLocalFrameImpl::Trace(Visitor* visitor) const {
visitor->Trace(local_frame_client_);
visitor->Trace(find_in_page_);
visitor->Trace(frame_);
@@ -2157,6 +2219,7 @@ void WebLocalFrameImpl::MixedContentFound(
const WebURL& mixed_content_url,
mojom::RequestContextType request_context,
bool was_allowed,
+ const WebURL& url_before_redirects,
bool had_redirect,
const WebSourceLocation& source_location) {
DCHECK(GetFrame());
@@ -2168,37 +2231,27 @@ void WebLocalFrameImpl::MixedContentFound(
}
MixedContentChecker::MixedContentFound(
GetFrame(), main_resource_url, mixed_content_url, request_context,
- was_allowed, had_redirect, std::move(source));
+ was_allowed, url_before_redirects, had_redirect, std::move(source));
}
void WebLocalFrameImpl::DidDropNavigation() {
GetFrame()->Loader().DidDropNavigation();
}
-void WebLocalFrameImpl::MarkAsLoading() {
- GetFrame()->Loader().MarkAsLoading();
-}
-
-bool WebLocalFrameImpl::IsClientNavigationInitialHistoryLoad() {
- return GetFrame()->Loader().IsClientNavigationInitialHistoryLoad();
-}
-
void WebLocalFrameImpl::DownloadURL(
const WebURLRequest& request,
network::mojom::blink::RedirectMode cross_origin_redirect_behavior,
- mojo::ScopedMessagePipeHandle blob_url_token) {
+ CrossVariantMojoRemote<mojom::blink::BlobURLTokenInterfaceBase>
+ blob_url_token) {
GetFrame()->DownloadURL(request.ToResourceRequest(),
cross_origin_redirect_behavior,
std::move(blob_url_token));
}
-bool WebLocalFrameImpl::WillStartNavigation(
- const WebNavigationInfo& info,
- bool is_history_navigation_in_new_child_frame) {
+bool WebLocalFrameImpl::WillStartNavigation(const WebNavigationInfo& info) {
DCHECK(!info.url_request.IsNull());
DCHECK(!info.url_request.Url().ProtocolIs("javascript"));
- return GetFrame()->Loader().WillStartNavigation(
- info, is_history_navigation_in_new_child_frame);
+ return GetFrame()->Loader().WillStartNavigation(info);
}
void WebLocalFrameImpl::SendOrientationChangeEvent() {
@@ -2327,7 +2380,7 @@ void WebLocalFrameImpl::UsageCountChromeLoadTimes(const WebString& metric) {
} else if (metric == "connectionInfo") {
feature = WebFeature::kChromeLoadTimesConnectionInfo;
}
- Deprecation::CountDeprecation(GetFrame()->GetDocument(), feature);
+ Deprecation::CountDeprecation(GetFrame()->DomWindow(), feature);
}
FrameScheduler* WebLocalFrameImpl::Scheduler() const {
@@ -2392,10 +2445,6 @@ static String CreateMarkupInRect(LocalFrame* frame,
return CreateMarkup(end_position, start_position, create_markup_options);
}
-void WebLocalFrameImpl::SetMainFrameOverlayColor(SkColor color) {
- GetFrame()->SetMainFrameColorOverlay(color);
-}
-
bool WebLocalFrameImpl::ShouldSuppressKeyboardForFocusedElement() {
if (!autofill_client_)
return false;
@@ -2414,12 +2463,14 @@ void WebLocalFrameImpl::OnPortalActivated(
portal_client,
TransferableMessage data,
OnPortalActivatedCallback callback) {
+ PaintTiming::From(*frame_->GetDocument()).OnPortalActivate();
LocalDOMWindow* window = GetFrame()->DomWindow();
DOMWindowPortalHost::portalHost(*window)->OnPortalActivated();
GetFrame()->GetPage()->SetInsidePortal(false);
- auto blink_data = ToBlinkTransferableMessage(std::move(data));
+ auto blink_data =
+ BlinkTransferableMessage::FromTransferableMessage(std::move(data));
DCHECK(!blink_data.locked_agent_cluster_id)
<< "portal activation is always cross-agent-cluster and should be "
"diagnosed early";
@@ -2448,8 +2499,9 @@ void WebLocalFrameImpl::ForwardMessageFromHost(
target = target_origin.value();
PortalHost::From(*(GetFrame()->DomWindow()))
- .ReceiveMessage(ToBlinkTransferableMessage(std::move(message)),
- source_origin, target);
+ .ReceiveMessage(
+ BlinkTransferableMessage::FromTransferableMessage(std::move(message)),
+ source_origin, target);
}
void WebLocalFrameImpl::AddMessageToConsoleImpl(
@@ -2524,11 +2576,6 @@ void WebLocalFrameImpl::BindDevToolsAgent(
std::move(devtools_agent_receiver));
}
-void WebLocalFrameImpl::SetLifecycleState(mojom::FrameLifecycleState state) {
- DCHECK(GetFrame());
- GetFrame()->SetLifecycleState(state);
-}
-
void WebLocalFrameImpl::WasHidden() {
if (frame_)
frame_->WasHidden();
diff --git a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h
index 5ee856c20dc..4555bd981a2 100644
--- a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h
+++ b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -41,6 +41,7 @@
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "services/network/public/mojom/web_sandbox_flags.mojom-blink.h"
#include "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/devtools/devtools_agent.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/frame/find_in_page.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink-forward.h"
@@ -136,6 +137,7 @@ class CORE_EXPORT WebLocalFrameImpl final
const WebURL& mixed_content_url,
mojom::RequestContextType,
bool was_allowed,
+ const WebURL& url_before_redirects,
bool had_redirect,
const WebSourceLocation&) override;
void SendOrientationChangeEvent() override;
@@ -150,6 +152,10 @@ class CORE_EXPORT WebLocalFrameImpl final
void ClearIsolatedWorldCSPForTesting(int32_t world_id) override;
void SetIsolatedWorldInfo(int32_t world_id,
const WebIsolatedWorldInfo&) override;
+ WebString GetIsolatedWorldStableId(
+ v8::Local<v8::Context> context) const override;
+ WebString GetIsolatedWorldHumanReadableName(
+ v8::Local<v8::Context> context) const override;
v8::Local<v8::Value> ExecuteScriptAndReturnValue(
const WebScriptSource&) override;
v8::MaybeLocal<v8::Value> CallFunctionEvenIfScriptDisabled(
@@ -158,6 +164,8 @@ class CORE_EXPORT WebLocalFrameImpl final
int argc,
v8::Local<v8::Value> argv[]) override;
v8::Local<v8::Context> MainWorldScriptContext() const override;
+ int32_t GetScriptContextWorldId(
+ v8::Local<v8::Context> script_context) const override;
void RequestExecuteScriptAndReturnValue(const WebScriptSource&,
bool user_gesture,
WebScriptExecutionCallback*) override;
@@ -196,7 +204,7 @@ class CORE_EXPORT WebLocalFrameImpl final
bool SelectionTextDirection(base::i18n::TextDirection& start,
base::i18n::TextDirection& end) const override;
bool IsSelectionAnchorFirst() const override;
- void SetTextDirection(base::i18n::TextDirection) override;
+ void SetTextDirectionForTesting(base::i18n::TextDirection direction) override;
bool HasSelection() const override;
WebRange SelectionRange() const override;
WebString SelectionAsText() const override;
@@ -216,7 +224,7 @@ class CORE_EXPORT WebLocalFrameImpl final
bool SetCompositionFromExistingText(
int composition_start,
int composition_end,
- const WebVector<WebImeTextSpan>& ime_text_spans) override;
+ const WebVector<ui::ImeTextSpan>& ime_text_spans) override;
void ExtendSelectionAndDelete(int before, int after) override;
void MoveRangeSelectionExtent(const gfx::Point&) override;
void ReplaceSelection(const WebString&) override;
@@ -245,7 +253,7 @@ class CORE_EXPORT WebLocalFrameImpl final
bool match_case,
bool forward,
bool force,
- bool find_next,
+ bool new_session,
bool wrap_within_frame) override;
void SetTickmarks(const WebVector<WebRect>&) override;
WebNode ContextMenuNode() const override;
@@ -275,6 +283,7 @@ class CORE_EXPORT WebLocalFrameImpl final
bool HasVisibleContent() const override;
WebRect VisibleContentRect() const override;
void DispatchBeforePrintEvent() override;
+ WebPlugin* GetPluginToPrint(const WebNode& constrain_to_node) override;
int PrintBegin(const WebPrintParams&,
const WebNode& constrain_to_node) override;
float GetPrintPageShrink(int page) override;
@@ -284,17 +293,19 @@ class CORE_EXPORT WebLocalFrameImpl final
bool GetPrintPresetOptionsForPlugin(const WebNode&,
WebPrintPresetOptions*) override;
bool CapturePaintPreview(const WebRect& bounds,
- cc::PaintCanvas* canvas) override;
- void SetMainFrameOverlayColor(SkColor) override;
+ cc::PaintCanvas* canvas,
+ bool include_linked_destinations) override;
bool ShouldSuppressKeyboardForFocusedElement() override;
WebPerformance Performance() const override;
bool IsAdSubframe() const override;
void SetIsAdSubframe(blink::mojom::AdFrameType ad_frame_type) override;
- void WaitForDebuggerWhenShown() override;
- void PrintPagesForTesting(cc::PaintCanvas*, const WebSize&) override;
+ WebSize SpoolSizeInPixelsForTesting(const WebSize& page_size_in_pixels,
+ int page_count) override;
+ void PrintPagesForTesting(cc::PaintCanvas*,
+ const WebSize& page_size_in_pixels,
+ const WebSize& spool_size_in_pixels) override;
WebRect GetSelectionBoundsRectForTesting() const override;
gfx::Point GetPositionInViewportForTesting() const override;
- void SetLifecycleState(mojom::FrameLifecycleState state) override;
void WasHidden() override;
void WasShown() override;
void SetAllowsCrossBrowsingInstanceFrameLookup() override;
@@ -319,16 +330,13 @@ class CORE_EXPORT WebLocalFrameImpl final
const WebURLError&) const override;
void SetCommittedFirstRealLoad() override;
bool HasCommittedFirstRealLoad() override;
- bool WillStartNavigation(
- const WebNavigationInfo&,
- bool is_history_navigation_in_new_child_frame) override;
+ bool WillStartNavigation(const WebNavigationInfo&) override;
void DidDropNavigation() override;
- void MarkAsLoading() override;
- bool IsClientNavigationInitialHistoryLoad() override;
void DownloadURL(
const WebURLRequest& request,
network::mojom::blink::RedirectMode cross_origin_redirect_behavior,
- mojo::ScopedMessagePipeHandle blob_url_token) override;
+ CrossVariantMojoRemote<mojom::blink::BlobURLTokenInterfaceBase>
+ blob_url_token) override;
void InitializeCoreFrame(
Page&,
@@ -402,6 +410,11 @@ class CORE_EXPORT WebLocalFrameImpl final
void SetDevToolsAgentImpl(WebDevToolsAgentImpl*);
WebDevToolsAgentImpl* DevToolsAgentImpl();
+ // Instructs devtools to pause loading of the frame as soon as it's shown
+ // until explicit command from the devtools client. May only be called on a
+ // local root.
+ void WaitForDebuggerWhenShown();
+
// When a Find operation ends, we want to set the selection to what was active
// and set focus to the first focusable node we find (starting with the first
// node in the matched range and going up the inheritance chain). If we find
@@ -444,7 +457,7 @@ class CORE_EXPORT WebLocalFrameImpl final
// Returns true if our print context suggests using printing layout.
bool UsePrintingLayout() const;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
protected:
// WebLocalFrame protected overrides:
@@ -474,6 +487,9 @@ class CORE_EXPORT WebLocalFrameImpl final
// A helper for DispatchBeforePrintEvent() and DispatchAfterPrintEvent().
void DispatchPrintEventRecursively(const AtomicString& event_type);
+ WebPluginContainerImpl* GetPluginToPrintHelper(
+ const WebNode& constrain_to_node);
+
Node* ContextMenuNodeInner() const;
WebLocalFrameClient* client_;
diff --git a/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.cc b/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
index 42afbfb7318..f1a9309a3a3 100644
--- a/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
+++ b/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
@@ -170,8 +170,9 @@ void WebViewFrameWidget::MouseCaptureLost() {
web_view_->MouseCaptureLost();
}
-void WebViewFrameWidget::SetFocus(bool enable) {
+void WebViewFrameWidget::FocusChanged(bool enable) {
web_view_->SetFocus(enable);
+ Client()->FocusChanged(enable);
}
bool WebViewFrameWidget::SelectionBounds(WebRect& anchor,
@@ -183,6 +184,10 @@ WebURL WebViewFrameWidget::GetURLForDebugTrace() {
return web_view_->GetURLForDebugTrace();
}
+WebString WebViewFrameWidget::GetLastToolTipTextForTesting() const {
+ return GetPage()->GetChromeClient().GetLastToolTipTextForTesting();
+}
+
void WebViewFrameWidget::DidDetachLocalFrameTree() {
web_view_->DidDetachLocalMainFrame();
}
@@ -220,7 +225,7 @@ void WebViewFrameWidget::ZoomToFindInPageRect(
web_view_->ZoomToFindInPageRect(rect_in_root_frame);
}
-void WebViewFrameWidget::Trace(Visitor* visitor) {
+void WebViewFrameWidget::Trace(Visitor* visitor) const {
WebFrameWidgetBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.h b/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.h
index 483c9961018..025fa94ceb8 100644
--- a/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.h
+++ b/chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.h
@@ -67,9 +67,9 @@ class CORE_EXPORT WebViewFrameWidget : public WebFrameWidgetBase {
WebInputEventResult DispatchBufferedTouchEvents() override;
void SetCursorVisibilityState(bool is_visible) override;
void MouseCaptureLost() override;
- void SetFocus(bool) override;
bool SelectionBounds(WebRect& anchor, WebRect& focus) const override;
WebURL GetURLForDebugTrace() override;
+ WebString GetLastToolTipTextForTesting() const override;
// WebFrameWidget overrides:
void DidDetachLocalFrameTree() override;
@@ -106,8 +106,9 @@ class CORE_EXPORT WebViewFrameWidget : public WebFrameWidgetBase {
cc::ElementId scroll_latched_element_id) override;
void BeginCommitCompositorFrame() override;
void EndCommitCompositorFrame(base::TimeTicks commit_start_time) override;
+ void FocusChanged(bool enabled) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
PageWidgetEventHandler* GetPageWidgetEventHandler() override;
diff --git a/chromium/third_party/blink/renderer/core/frame/window.idl b/chromium/third_party/blink/renderer/core/frame/window.idl
index b3d5a5549db..f162439c949 100644
--- a/chromium/third_party/blink/renderer/core/frame/window.idl
+++ b/chromium/third_party/blink/renderer/core/frame/window.idl
@@ -73,8 +73,10 @@
[Custom, NotEnumerable, CrossOrigin] getter object (DOMString name);
// the user agent
+ // includes https://github.com/whatwg/html/pull/5545 (originIsolationRestricted)
[Affects=Nothing, LogActivity=GetterOnly] readonly attribute Navigator navigator;
[LogActivity=GetterOnly, SecureContext=RestrictAppCacheToSecureContexts, RuntimeEnabled=AppCache] readonly attribute ApplicationCache applicationCache;
+ [RuntimeEnabled=OriginIsolationHeader, SecureContext] readonly attribute boolean originIsolationRestricted;
// user prompts
[Measure, CallWith=ScriptState] void alert();
@@ -98,8 +100,6 @@
// https://html.spec.whatwg.org/C/#animation-frames
[MeasureAs=UnprefixedRequestAnimationFrame] long requestAnimationFrame(FrameRequestCallback callback);
void cancelAnimationFrame(long handle);
- [RuntimeEnabled=PostAnimationFrame] long requestPostAnimationFrame(FrameRequestCallback callback);
- [RuntimeEnabled=PostAnimationFrame] void cancelPostAnimationFrame(long handle);
// HTML obsolete features
// https://html.spec.whatwg.org/C/#Window-partial
@@ -155,6 +155,10 @@
[Affects=Nothing, HighEntropy, MeasureAs=WindowOuterHeight, Replaceable] readonly attribute long outerHeight;
[Affects=Nothing, HighEntropy, MeasureAs=WindowDevicePixelRatio, Replaceable] readonly attribute double devicePixelRatio;
+ // Window Segments API
+ // https://github.com/webscreens/window-segments
+ [RuntimeEnabled=WindowSegments, Affects=Nothing] FrozenArray<DOMRect> getWindowSegments();
+
// Selection API
// https://w3c.github.io/selection-api/#extensions-to-window-interface
[Affects=Nothing] Selection? getSelection();
@@ -180,9 +184,11 @@
// TODO(yhirano): Move this to url.idl when LegacyWindowAlias is supported.
[DisableInNewIDLCompiler] attribute URLConstructor webkitURL;
+ // https://dom.spec.whatwg.org/#interface-window-extensions
+ [Replaceable, GetterCallWith=ScriptState, MeasureAs=WindowEvent, NotEnumerable] readonly attribute any event;
+
// Non-standard APIs
[MeasureAs=WindowClientInformation, Replaceable] readonly attribute Navigator clientInformation;
- [Replaceable, MeasureAs=WindowEvent, Custom=Getter, NotEnumerable] readonly attribute Event event;
[MeasureAs=WindowFind] boolean find(optional DOMString string = "",
optional boolean caseSensitive = false,
optional boolean backwards = false,
diff --git a/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc b/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc
index a2001fb6fb3..bdb145a8107 100644
--- a/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc
+++ b/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc
@@ -239,4 +239,9 @@ ScriptPromise WindowOrWorkerGlobalScope::createImageBitmap(
script_state, bitmap_source, sx, sy, sw, sh, options, exception_state);
}
+bool WindowOrWorkerGlobalScope::crossOriginIsolated(
+ const ExecutionContext& execution_context) {
+ return execution_context.IsCrossOriginIsolated();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h b/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h
index bdeca3a180d..16250b8c439 100644
--- a/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h
+++ b/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h
@@ -99,6 +99,8 @@ class CORE_EXPORT WindowOrWorkerGlobalScope {
int sh,
const ImageBitmapOptions*,
ExceptionState&);
+
+ static bool crossOriginIsolated(const ExecutionContext&);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl b/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl
index b232605678e..60191c0548c 100644
--- a/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl
+++ b/chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl
@@ -58,4 +58,7 @@ typedef (HTMLImageElement or
ImageBitmapSource imageBitmap, optional ImageBitmapOptions options = {});
[CallWith=ScriptState, RaisesException] Promise<ImageBitmap> createImageBitmap(
ImageBitmapSource imageBitmap, long sx, long sy, long sw, long sh, optional ImageBitmapOptions options = {});
+
+ [RuntimeEnabled=CrossOriginIsolation]
+ readonly attribute boolean crossOriginIsolated;
};
diff --git a/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.cc b/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.cc
index e9bf6992e1a..e4a1f35677e 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.cc
+++ b/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.cc
@@ -74,6 +74,7 @@ void FullscreenElementChanged(Document& document,
DCHECK_NE(old_element, Fullscreen::FullscreenElementFrom(document));
old_element->PseudoStateChanged(CSSSelector::kPseudoFullScreen);
+ old_element->PseudoStateChanged(CSSSelector::kPseudoFullscreen);
old_element->SetContainsFullScreenElement(false);
old_element->SetContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(
@@ -84,6 +85,7 @@ void FullscreenElementChanged(Document& document,
DCHECK_EQ(new_element, Fullscreen::FullscreenElementFrom(document));
new_element->PseudoStateChanged(CSSSelector::kPseudoFullScreen);
+ new_element->PseudoStateChanged(CSSSelector::kPseudoFullscreen);
// OOPIF: For RequestType::PrefixedForCrossProcessDescendant, |new_element|
// is the iframe element for the out-of-process frame that contains the
@@ -218,7 +220,7 @@ bool AllowedToUseFullscreen(const Document& document,
// 2. If Feature Policy is enabled, return the policy for "fullscreen"
// feature.
- return document.IsFeatureEnabled(
+ return document.GetExecutionContext()->IsFeatureEnabled(
mojom::blink::FeaturePolicyFeature::kFullscreen, report_on_failure);
}
@@ -650,6 +652,9 @@ ScriptPromise Fullscreen::RequestFullscreen(Element& pending,
void Fullscreen::DidResolveEnterFullscreenRequest(Document& document,
bool granted) {
+ if (!document.domWindow())
+ return;
+
// We may be called synchronously from within
// |FullscreenController::EnterFullscreen()| if we were already fullscreen,
// but must still not synchronously change the fullscreen element. Instead
@@ -1015,7 +1020,7 @@ void Fullscreen::ElementRemoved(Element& node) {
// layer. This is done in Element::RemovedFrom.
}
-void Fullscreen::Trace(Visitor* visitor) {
+void Fullscreen::Trace(Visitor* visitor) const {
visitor->Trace(pending_requests_);
visitor->Trace(pending_exits_);
Supplement<LocalDOMWindow>::Trace(visitor);
@@ -1029,7 +1034,7 @@ Fullscreen::PendingRequest::PendingRequest(Element* element,
Fullscreen::PendingRequest::~PendingRequest() = default;
-void Fullscreen::PendingRequest::Trace(Visitor* visitor) {
+void Fullscreen::PendingRequest::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(resolver_);
}
diff --git a/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.h b/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.h
index b00d221ff28..7e4a0adb7dd 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.h
+++ b/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.h
@@ -106,7 +106,7 @@ class CORE_EXPORT Fullscreen final : public GarbageCollected<Fullscreen>,
// ExecutionContextLifecycleObserver:
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
static Fullscreen& From(LocalDOMWindow&);
@@ -133,7 +133,7 @@ class CORE_EXPORT Fullscreen final : public GarbageCollected<Fullscreen>,
RequestType type,
ScriptPromiseResolver* resolver);
virtual ~PendingRequest();
- virtual void Trace(Visitor* visitor);
+ virtual void Trace(Visitor* visitor) const;
Element* element() { return element_; }
RequestType type() { return type_; }
diff --git a/chromium/third_party/blink/renderer/core/fullscreen/fullscreen_options.idl b/chromium/third_party/blink/renderer/core/fullscreen/fullscreen_options.idl
index 3fb94501245..0155bd1d6e5 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/fullscreen_options.idl
+++ b/chromium/third_party/blink/renderer/core/fullscreen/fullscreen_options.idl
@@ -14,5 +14,5 @@ dictionary FullscreenOptions {
FullscreenNavigationUI navigationUI = "auto";
// https://github.com/webscreens/window-placement
- [RuntimeEnabled=WindowPlacement] Screen? screen;
+ [RuntimeEnabled=WindowPlacement] Screen screen;
};
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.h b/chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.h
index 6f0194aa793..34a186a2a3b 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.h
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.h
@@ -130,7 +130,9 @@ class CORE_EXPORT DOMMatrixReadOnly : public ScriptWrappable {
AffineTransform GetAffineTransform() const;
- void Trace(Visitor* visitor) override { ScriptWrappable::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ ScriptWrappable::Trace(visitor);
+ }
protected:
void SetMatrixValueFromString(const ExecutionContext*,
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_quad.cc b/chromium/third_party/blink/renderer/core/geometry/dom_quad.cc
index 24e4016c1de..ea4bf8a1cb0 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_quad.cc
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_quad.cc
@@ -45,7 +45,7 @@ class DOMQuadPoint final : public DOMPoint {
quad_->set_needs_bounds_calculation(true);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(quad_);
DOMPoint::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_quad.h b/chromium/third_party/blink/renderer/core/geometry/dom_quad.h
index 86e80f1dbba..6551bf59ce3 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_quad.h
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_quad.h
@@ -43,7 +43,7 @@ class CORE_EXPORT DOMQuad : public ScriptWrappable {
ScriptValue toJSONForBinding(ScriptState*) const;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(p1_);
visitor->Trace(p2_);
visitor->Trace(p3_);
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_rect.h b/chromium/third_party/blink/renderer/core/geometry/dom_rect.h
index fede00578e6..058c60a904e 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_rect.h
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_rect.h
@@ -34,11 +34,11 @@ class CORE_EXPORT DOMRect final : public DOMRectReadOnly {
void setHeight(double height) { height_ = height; }
};
-constexpr bool operator==(const DOMRect& lhs, const DOMRect& rhs) {
+inline bool operator==(const DOMRect& lhs, const DOMRect& rhs) {
return lhs.x() == rhs.x() && lhs.y() == rhs.y() &&
lhs.width() == rhs.width() && lhs.height() == rhs.height();
}
-constexpr bool operator!=(const DOMRect& lhs, const DOMRect& rhs) {
+inline bool operator!=(const DOMRect& lhs, const DOMRect& rhs) {
return !(lhs == rhs);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_rect_list.cc b/chromium/third_party/blink/renderer/core/geometry/dom_rect_list.cc
index 80d4d731227..13786a438b4 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_rect_list.cc
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_rect_list.cc
@@ -47,7 +47,7 @@ DOMRect* DOMRectList::item(unsigned index) {
return list_[index].Get();
}
-void DOMRectList::Trace(Visitor* visitor) {
+void DOMRectList::Trace(Visitor* visitor) const {
visitor->Trace(list_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_rect_list.h b/chromium/third_party/blink/renderer/core/geometry/dom_rect_list.h
index 718ce9e1755..737b4878487 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_rect_list.h
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_rect_list.h
@@ -53,7 +53,7 @@ class CORE_EXPORT DOMRectList final : public ScriptWrappable {
unsigned length() const;
DOMRect* item(unsigned index);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<DOMRect>> list_;
diff --git a/chromium/third_party/blink/renderer/core/html/BUILD.gn b/chromium/third_party/blink/renderer/core/html/BUILD.gn
index 76cfc6e1dd6..a02c6372002 100644
--- a/chromium/third_party/blink/renderer/core/html/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/html/BUILD.gn
@@ -32,6 +32,7 @@ blink_core_sources("html") {
"canvas/image_element_base.h",
"canvas/text_metrics.cc",
"canvas/text_metrics.h",
+ "canvas/ukm_parameters.h",
"collection_items_cache.h",
"collection_type.h",
"cross_origin_attribute.cc",
@@ -464,6 +465,8 @@ blink_core_sources("html") {
"link_resource.h",
"link_style.cc",
"link_style.h",
+ "link_web_bundle.cc",
+ "link_web_bundle.h",
"list_item_ordinal.cc",
"list_item_ordinal.h",
"loading_attribute.cc",
@@ -670,6 +673,7 @@ blink_core_tests("unit_tests") {
"lazy_load_image_observer_test.cc",
"link_element_loading_test.cc",
"link_rel_attribute_test.cc",
+ "link_web_bundle_test.cc",
"media/autoplay_uma_helper_test.cc",
"media/html_media_element_event_listeners_test.cc",
"media/html_media_element_test.cc",
@@ -695,6 +699,7 @@ blink_core_tests("unit_tests") {
"parser/html_tokenizer_test.cc",
"parser/html_tree_builder_simulator_test.cc",
"parser/html_view_source_parser_test.cc",
+ "parser/text_resource_decoder_builder_test.cc",
"parser/text_resource_decoder_test.cc",
"portal/html_portal_element_test.cc",
"shadow/progress_shadow_element_test.cc",
diff --git a/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc b/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc
index 6b73d04db1c..2f0b8b68de7 100644
--- a/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc
+++ b/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc
@@ -98,7 +98,7 @@ AnchorElementMetricsSender::GetAnchorElements() const {
return anchor_elements_;
}
-void AnchorElementMetricsSender::Trace(Visitor* visitor) {
+void AnchorElementMetricsSender::Trace(Visitor* visitor) const {
visitor->Trace(anchor_elements_);
visitor->Trace(metrics_host_);
Supplement<Document>::Trace(visitor);
@@ -113,7 +113,7 @@ bool AnchorElementMetricsSender::AssociateInterface() {
if (!document->GetFrame())
return false;
- document->GetBrowserInterfaceBroker().GetInterface(
+ document->GetFrame()->GetBrowserInterfaceBroker().GetInterface(
metrics_host_.BindNewPipeAndPassReceiver(
document->GetExecutionContext()->GetTaskRunner(
TaskType::kInternalDefault)));
diff --git a/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h b/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h
index d421c1ba7c5..4b8dde7475c 100644
--- a/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h
+++ b/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h
@@ -63,7 +63,7 @@ class CORE_EXPORT AnchorElementMetricsSender final
// Returns the stored |anchor_elements_|.
const HeapHashSet<Member<HTMLAnchorElement>>& GetAnchorElements() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Associates |metrics_host_| with the IPC interface if not already, so it can
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc
index fbe1cc5eb3e..44dc498b064 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc
+++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc
@@ -8,6 +8,9 @@
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_study_participation.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -146,6 +149,7 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(
ToBlobFunctionType function_type,
base::TimeTicks start_time,
ExecutionContext* context,
+ base::Optional<UkmParameters> ukm_params,
ScriptPromiseResolver* resolver)
: CanvasAsyncBlobCreator(image,
options,
@@ -153,6 +157,7 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(
nullptr,
start_time,
context,
+ ukm_params,
resolver) {}
CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(
@@ -162,6 +167,7 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(
V8BlobCallback* callback,
base::TimeTicks start_time,
ExecutionContext* context,
+ base::Optional<UkmParameters> ukm_params,
ScriptPromiseResolver* resolver)
: fail_encoder_initialization_for_test_(false),
enforce_idle_encoding_for_test_(false),
@@ -174,6 +180,7 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(
callback_(callback),
script_promise_resolver_(resolver) {
DCHECK(image);
+ DCHECK(context);
mime_type_ = ImageEncoderUtils::ToEncodingMimeType(
encode_options_->type(),
@@ -467,6 +474,8 @@ void CanvasAsyncBlobCreator::CreateBlobAndReturnResult() {
WrapPersistent(result_blob)));
}
+ RecordIdentifiabilityMetric();
+
RecordScaledDurationHistogram(mime_type_,
base::TimeTicks::Now() - start_time_,
image_->width(), image_->height());
@@ -474,6 +483,36 @@ void CanvasAsyncBlobCreator::CreateBlobAndReturnResult() {
Dispose();
}
+void CanvasAsyncBlobCreator::RecordIdentifiabilityMetric() {
+ if (!ukm_params_.has_value() || !IsUserInIdentifiabilityStudy())
+ return;
+ // Creating this ImageDataBuffer has some overhead, namely getting the SkImage
+ // and computing the pixmap.
+ // We need the StaticBitmapImage to be deleted on the same thread on which it
+ // was created, so we use the same TaskType here in order to get the same
+ // TaskRunner.
+ context_->GetTaskRunner(TaskType::kCanvasBlobSerialization)
+ ->PostTask(
+ FROM_HERE,
+ WTF::Bind(
+ [](scoped_refptr<StaticBitmapImage> image,
+ UkmParameters ukm_params) {
+ std::unique_ptr<ImageDataBuffer> data_buffer =
+ ImageDataBuffer::Create(image);
+ if (!data_buffer)
+ return;
+ blink::IdentifiabilityMetricBuilder(ukm_params.source_id)
+ .Set(blink::IdentifiableSurface::FromTypeAndInput(
+ blink::IdentifiableSurface::Type::kCanvasReadback,
+ 0),
+ blink::IdentifiabilityDigestOfBytes(
+ base::make_span(data_buffer->Pixels(),
+ data_buffer->ComputeByteSize())))
+ .Record(ukm_params.ukm_recorder);
+ },
+ image_, ukm_params_.value()));
+}
+
void CanvasAsyncBlobCreator::CreateNullAndReturnResult() {
RecordIdleTaskStatusHistogram(idle_task_status_);
if (function_type_ == kHTMLCanvasToBlobCallback) {
@@ -604,7 +643,7 @@ void CanvasAsyncBlobCreator::PostDelayedTaskToCurrentThread(
base::TimeDelta::FromMillisecondsD(delay_ms));
}
-void CanvasAsyncBlobCreator::Trace(Visitor* visitor) {
+void CanvasAsyncBlobCreator::Trace(Visitor* visitor) const {
visitor->Trace(context_);
visitor->Trace(encode_options_);
visitor->Trace(callback_);
@@ -615,7 +654,7 @@ sk_sp<SkColorSpace> CanvasAsyncBlobCreator::BlobColorSpaceToSkColorSpace(
String blob_color_space) {
skcms_Matrix3x3 gamut = SkNamedGamut::kSRGB;
if (blob_color_space == kDisplayP3ImageColorSpaceName)
- gamut = SkNamedGamut::kDCIP3;
+ gamut = SkNamedGamut::kDisplayP3;
else if (blob_color_space == kRec2020ImageColorSpaceName)
gamut = SkNamedGamut::kRec2020;
return SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, gamut);
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h
index 9a2c289975a..1a97de918e0 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h
+++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h
@@ -8,11 +8,14 @@
#include <memory>
#include "base/location.h"
+#include "base/optional.h"
#include "base/single_thread_task_runner.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_blob_callback.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_image_encode_options.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/html/canvas/ukm_parameters.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
@@ -60,6 +63,7 @@ class CORE_EXPORT CanvasAsyncBlobCreator
ToBlobFunctionType function_type,
base::TimeTicks start_time,
ExecutionContext*,
+ base::Optional<UkmParameters> ukm_params,
ScriptPromiseResolver*);
CanvasAsyncBlobCreator(scoped_refptr<StaticBitmapImage>,
const ImageEncodeOptions*,
@@ -67,6 +71,7 @@ class CORE_EXPORT CanvasAsyncBlobCreator
V8BlobCallback*,
base::TimeTicks start_time,
ExecutionContext*,
+ base::Optional<UkmParameters> ukm_params,
ScriptPromiseResolver* = nullptr);
virtual ~CanvasAsyncBlobCreator();
@@ -74,7 +79,7 @@ class CORE_EXPORT CanvasAsyncBlobCreator
virtual void SignalTaskSwitchInStartTimeoutEventForTesting() {}
virtual void SignalTaskSwitchInCompleteTimeoutEventForTesting() {}
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
static sk_sp<SkColorSpace> BlobColorSpaceToSkColorSpace(
String blob_color_space);
@@ -132,6 +137,8 @@ class CORE_EXPORT CanvasAsyncBlobCreator
// Used for HTMLCanvasElement only
Member<V8BlobCallback> callback_;
+ base::Optional<UkmParameters> ukm_params_;
+
// Used for OffscreenCanvas only
Member<ScriptPromiseResolver> script_promise_resolver_;
@@ -147,6 +154,8 @@ class CORE_EXPORT CanvasAsyncBlobCreator
void IdleTaskStartTimeoutEvent(double quality);
void IdleTaskCompleteTimeoutEvent();
+
+ void RecordIdentifiabilityMetric();
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator_test.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator_test.cc
index 32388eb43c1..c68359ce45b 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator_test.cc
@@ -35,6 +35,7 @@ class MockCanvasAsyncBlobCreator : public CanvasAsyncBlobCreator {
nullptr,
base::TimeTicks(),
document->GetExecutionContext(),
+ base::make_optional<UkmParameters>(),
nullptr) {
if (fail_encoder_initialization)
fail_encoder_initialization_for_test_ = true;
@@ -129,7 +130,6 @@ class CanvasAsyncBlobCreatorTest : public PageTestBase {
void TearDown() override;
private:
-
Persistent<MockCanvasAsyncBlobCreator> async_blob_creator_;
};
@@ -248,7 +248,8 @@ TEST_F(CanvasAsyncBlobCreatorTest, ColorManagedConvertToBlob) {
color_space_params.push_back(std::pair<sk_sp<SkColorSpace>, SkColorType>(
SkColorSpace::MakeSRGBLinear(), kRGBA_F16_SkColorType));
color_space_params.push_back(std::pair<sk_sp<SkColorSpace>, SkColorType>(
- SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, SkNamedGamut::kDCIP3),
+ SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear,
+ SkNamedGamut::kDisplayP3),
kRGBA_F16_SkColorType));
color_space_params.push_back(std::pair<sk_sp<SkColorSpace>, SkColorType>(
SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, SkNamedGamut::kRec2020),
@@ -263,7 +264,8 @@ TEST_F(CanvasAsyncBlobCreatorTest, ColorManagedConvertToBlob) {
kDisplayP3ImageColorSpaceName,
kRec2020ImageColorSpaceName};
std::list<String> blob_pixel_formats = {
- kRGBA8ImagePixelFormatName, kRGBA16ImagePixelFormatName,
+ kRGBA8ImagePixelFormatName,
+ kRGBA16ImagePixelFormatName,
};
// Maximum differences are both observed locally with
@@ -294,7 +296,8 @@ TEST_F(CanvasAsyncBlobCreatorTest, ColorManagedConvertToBlob) {
source_bitmap_image, options,
CanvasAsyncBlobCreator::ToBlobFunctionType::
kHTMLCanvasConvertToBlobPromise,
- base::TimeTicks(), GetFrame().DomWindow(), nullptr);
+ base::TimeTicks(), GetFrame().DomWindow(),
+ base::make_optional<UkmParameters>(), nullptr);
ASSERT_TRUE(async_blob_creator->EncodeImageForConvertToBlobTest());
sk_sp<SkData> sk_data = SkData::MakeWithCopy(
@@ -325,4 +328,4 @@ TEST_F(CanvasAsyncBlobCreatorTest, ColorManagedConvertToBlob) {
}
}
}
-}
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h
index 774eb849294..946dd195908 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h
+++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h
@@ -32,6 +32,8 @@ class CORE_EXPORT CanvasContextCreationAttributesCore {
bool preserve_drawing_buffer = false;
String power_preference = "default";
bool stencil = false;
+ // Help to determine whether to use GPU or CPU for the canvas.
+ bool will_read_frequently = false;
bool xr_compatible = false;
};
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc
index c86e35e067b..f24674961d0 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc
+++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc
@@ -153,7 +153,7 @@ void CanvasFontCache::PruneAll() {
fonts_resolved_using_default_style_.clear();
}
-void CanvasFontCache::Trace(Visitor* visitor) {
+void CanvasFontCache::Trace(Visitor* visitor) const {
visitor->Trace(fetched_fonts_);
visitor->Trace(document_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h
index 2fd9b9fa15a..9e6b4a82d0f 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h
+++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h
@@ -34,7 +34,7 @@ class CORE_EXPORT CanvasFontCache final
void PruneAll();
unsigned size();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
static unsigned MaxFonts();
unsigned HardMaxFonts();
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc
index 9a34c10bdfe..c41cbb8ec3f 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc
@@ -36,7 +36,7 @@ CanvasRenderingContext* CanvasFontCacheTest::Context2D() const {
// If the following check fails, perhaps you forgot to call createContext
// in your test?
EXPECT_NE(nullptr, CanvasElement().RenderingContext());
- EXPECT_TRUE(CanvasElement().RenderingContext()->Is2d());
+ EXPECT_TRUE(CanvasElement().RenderingContext()->IsRenderingContext2D());
return CanvasElement().RenderingContext();
}
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h
index 8e8782b0461..b1954a1880b 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h
+++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h
@@ -50,7 +50,6 @@ enum SourceImageStatus {
class CORE_EXPORT CanvasImageSource {
public:
virtual scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*,
- AccelerationHint,
const FloatSize&) = 0;
// IMPORTANT: Result must be independent of whether destinationContext is
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc
index 2793b17d823..50af5f3158d 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc
+++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc
@@ -43,20 +43,13 @@ CanvasRenderingContext::CanvasRenderingContext(
CanvasColorParams::GetNativeCanvasPixelFormat(),
kNonOpaque),
creation_attributes_(attrs) {
- // Supported color spaces and pixel formats: sRGB in uint8, e-sRGB in f16,
- // linear sRGB and p3 and rec2020 with linear gamma transfer function in f16.
- // For wide gamut color spaces, user must explicitly request half float
- // storage. Otherwise, we fall back to sRGB in uint8. Invalid requests fall
- // back to sRGB in uint8 too.
- if (creation_attributes_.pixel_format == kF16CanvasPixelFormatName) {
+ if (creation_attributes_.pixel_format == kF16CanvasPixelFormatName)
color_params_.SetCanvasPixelFormat(CanvasPixelFormat::kF16);
- if (creation_attributes_.color_space == kLinearRGBCanvasColorSpaceName)
- color_params_.SetCanvasColorSpace(CanvasColorSpace::kLinearRGB);
- if (creation_attributes_.color_space == kRec2020CanvasColorSpaceName)
- color_params_.SetCanvasColorSpace(CanvasColorSpace::kRec2020);
- else if (creation_attributes_.color_space == kP3CanvasColorSpaceName)
- color_params_.SetCanvasColorSpace(CanvasColorSpace::kP3);
- }
+
+ if (creation_attributes_.color_space == kRec2020CanvasColorSpaceName)
+ color_params_.SetCanvasColorSpace(CanvasColorSpace::kRec2020);
+ else if (creation_attributes_.color_space == kP3CanvasColorSpaceName)
+ color_params_.SetCanvasColorSpace(CanvasColorSpace::kP3);
if (!creation_attributes_.alpha)
color_params_.SetOpacityMode(kOpaque);
@@ -71,8 +64,6 @@ WTF::String CanvasRenderingContext::ColorSpaceAsString() const {
switch (color_params_.ColorSpace()) {
case CanvasColorSpace::kSRGB:
return kSRGBCanvasColorSpaceName;
- case CanvasColorSpace::kLinearRGB:
- return kLinearRGBCanvasColorSpaceName;
case CanvasColorSpace::kRec2020:
return kRec2020CanvasColorSpaceName;
case CanvasColorSpace::kP3:
@@ -177,7 +168,7 @@ bool CanvasRenderingContext::WouldTaintOrigin(CanvasImageSource* image_source) {
return image_source->WouldTaintOrigin();
}
-void CanvasRenderingContext::Trace(Visitor* visitor) {
+void CanvasRenderingContext::Trace(Visitor* visitor) const {
visitor->Trace(host_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h
index e14dd738e8c..dc2b3ba2bbf 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h
+++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h
@@ -46,7 +46,6 @@ class HTMLCanvasElement;
class ImageBitmap;
constexpr const char* kSRGBCanvasColorSpaceName = "srgb";
-constexpr const char* kLinearRGBCanvasColorSpaceName = "linear-rgb";
constexpr const char* kRec2020CanvasColorSpaceName = "rec2020";
constexpr const char* kP3CanvasColorSpaceName = "p3";
@@ -88,7 +87,7 @@ class CORE_EXPORT CanvasRenderingContext : public ScriptWrappable,
const CanvasColorParams& ColorParams() const { return color_params_; }
- virtual scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) = 0;
+ virtual scoped_refptr<StaticBitmapImage> GetImage() = 0;
virtual ContextType GetContextType() const = 0;
virtual bool IsComposited() const = 0;
virtual bool IsAccelerated() const = 0;
@@ -151,7 +150,7 @@ class CORE_EXPORT CanvasRenderingContext : public ScriptWrappable,
void WillProcessTask(const base::PendingTask&, bool) final {}
// Canvas2D-specific interface
- virtual bool Is2d() const { return false; }
+ virtual bool IsRenderingContext2D() const { return false; }
virtual void RestoreCanvasMatrixClipStack(cc::PaintCanvas*) const {}
virtual void Reset() {}
virtual void ClearRect(double x, double y, double width, double height) {}
@@ -201,9 +200,11 @@ class CORE_EXPORT CanvasRenderingContext : public ScriptWrappable,
return creation_attributes_;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
virtual void Stop() = 0;
+ virtual uint64_t IdentifiabilityTextDigest() { return 0; }
+
protected:
CanvasRenderingContext(CanvasRenderingContextHost*,
const CanvasContextCreationAttributesCore&);
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
index 1ef7b373945..466d0eb0199 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
+++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
@@ -22,8 +22,10 @@
namespace blink {
-CanvasRenderingContextHost::CanvasRenderingContextHost(HostType host_type)
- : host_type_(host_type) {}
+CanvasRenderingContextHost::CanvasRenderingContextHost(
+ HostType host_type,
+ base::Optional<UkmParameters> ukm_params)
+ : host_type_(host_type), ukm_params_(ukm_params) {}
void CanvasRenderingContextHost::RecordCanvasSizeToUMA(const IntSize& size) {
if (did_record_canvas_size_to_uma_)
@@ -78,23 +80,23 @@ bool CanvasRenderingContextHost::Is3d() const {
return RenderingContext() && RenderingContext()->Is3d();
}
-bool CanvasRenderingContextHost::Is2d() const {
- return RenderingContext() && RenderingContext()->Is2d();
+bool CanvasRenderingContextHost::IsRenderingContext2D() const {
+ return RenderingContext() && RenderingContext()->IsRenderingContext2D();
}
CanvasResourceProvider*
CanvasRenderingContextHost::GetOrCreateCanvasResourceProvider(
- AccelerationHint hint) {
+ RasterModeHint hint) {
return GetOrCreateCanvasResourceProviderImpl(hint);
}
CanvasResourceProvider*
CanvasRenderingContextHost::GetOrCreateCanvasResourceProviderImpl(
- AccelerationHint hint) {
+ RasterModeHint hint) {
if (!ResourceProvider() && !did_fail_to_create_resource_provider_) {
if (IsValidImageSize(Size())) {
if (Is3d()) {
- CreateCanvasResourceProvider3D(hint);
+ CreateCanvasResourceProvider3D();
} else {
CreateCanvasResourceProvider2D(hint);
}
@@ -105,56 +107,69 @@ CanvasRenderingContextHost::GetOrCreateCanvasResourceProviderImpl(
return ResourceProvider();
}
-void CanvasRenderingContextHost::CreateCanvasResourceProvider3D(
- AccelerationHint hint) {
+void CanvasRenderingContextHost::CreateCanvasResourceProvider3D() {
DCHECK(Is3d());
- uint8_t presentation_mode = CanvasResourceProvider::kDefaultPresentationMode;
- if (RuntimeEnabledFeatures::WebGLImageChromiumEnabled()) {
- presentation_mode |=
- CanvasResourceProvider::kAllowImageChromiumPresentationMode;
- }
- if (RenderingContext() && RenderingContext()->UsingSwapChain()) {
- DCHECK(LowLatencyEnabled());
- // Allow swap chain presentation only if 3d context is using a swap
- // chain since we'll be importing it as a passthrough texture.
- presentation_mode |=
- CanvasResourceProvider::kAllowSwapChainPresentationMode;
- }
- std::unique_ptr<CanvasResourceProvider> provider;
base::WeakPtr<CanvasResourceDispatcher> dispatcher =
GetOrCreateResourceDispatcher()
? GetOrCreateResourceDispatcher()->GetWeakPtr()
: nullptr;
- if (SharedGpuContext::IsGpuCompositingEnabled()) {
- CanvasResourceProvider::ResourceUsage usage;
- if (LowLatencyEnabled() && RenderingContext()) {
- // Allow swap chain presentation only if 3d context is using a swap
- // chain since we'll be importing it as a passthrough texture.
- usage = CanvasResourceProvider::ResourceUsage::
- kAcceleratedDirect3DResourceUsage;
- } else {
- usage = CanvasResourceProvider::ResourceUsage::
- kAcceleratedCompositedResourceUsage;
+
+ std::unique_ptr<CanvasResourceProvider> provider;
+
+ if (SharedGpuContext::IsGpuCompositingEnabled() && LowLatencyEnabled()) {
+ // If LowLatency is enabled, we need a resource that is able to perform well
+ // in such mode. It will first try a PassThrough provider and, if that is
+ // not possible, it will try a SharedImage with the appropriate flags.
+ if ((RenderingContext() && RenderingContext()->UsingSwapChain()) ||
+ RuntimeEnabledFeatures::WebGLImageChromiumEnabled()) {
+ // If either SwapChain is enabled or WebGLImage mode is enabled, we can
+ // try a passthrough provider.
+ DCHECK(LowLatencyEnabled());
+ provider = CanvasResourceProvider::CreatePassThroughProvider(
+ Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(),
+ ColorParams(), RenderingContext()->IsOriginTopLeft(),
+ std::move(dispatcher));
}
- provider = CanvasResourceProvider::Create(
- Size(), usage, SharedGpuContext::ContextProviderWrapper(),
- 0 /* msaa_sample_count */, FilterQuality(), ColorParams(),
- presentation_mode, std::move(dispatcher),
- RenderingContext()->IsOriginTopLeft());
- } else {
- // Here it should try a SoftwareCompositedResourceUsage, but as
- // SharedGpuCOntext::IsGpuCompositingEnabled() is false and that being true
- // is a requirement to try and create a SharedImageProvider if
- // SoftwareCompositeResourceUsage is used, it will go straight ahead to a
- // fallback SharedBitmap and then to a Bitmap provider
- provider = CanvasResourceProvider::CreateSharedBitmapProvider(
- Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(),
- ColorParams(), std::move(dispatcher));
if (!provider) {
- provider = CanvasResourceProvider::CreateBitmapProvider(
- Size(), FilterQuality(), ColorParams());
+ // If PassThrough failed, try a SharedImage with usage display enabled,
+ // and if WebGLImageChromium is enabled, add concurrent read write and
+ // usage scanout (overlay).
+ uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY;
+ if (RuntimeEnabledFeatures::WebGLImageChromiumEnabled()) {
+ shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
+ shared_image_usage_flags |=
+ gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
+ }
+ provider = CanvasResourceProvider::CreateSharedImageProvider(
+ Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(),
+ ColorParams(), RenderingContext()->IsOriginTopLeft(),
+ RasterMode::kGPU, shared_image_usage_flags);
}
+ } else if (SharedGpuContext::IsGpuCompositingEnabled()) {
+ // If there is no LawLatency mode, and GPU is enabled, will try a GPU
+ // SharedImage that should support Usage Display and probably Usage Canbout
+ // if WebGLImageChromium is enabled.
+ uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY;
+ if (RuntimeEnabledFeatures::WebGLImageChromiumEnabled()) {
+ shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
+ }
+ provider = CanvasResourceProvider::CreateSharedImageProvider(
+ Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(),
+ ColorParams(), RenderingContext()->IsOriginTopLeft(), RasterMode::kGPU,
+ shared_image_usage_flags);
+ }
+
+ // If either of the other modes failed and / or it was not possible to do, we
+ // will backup with a SharedBitmap, and if that was not possible with a Bitmap
+ // provider.
+ if (!provider) {
+ provider = CanvasResourceProvider::CreateSharedBitmapProvider(
+ Size(), FilterQuality(), ColorParams(), std::move(dispatcher));
+ }
+ if (!provider) {
+ provider = CanvasResourceProvider::CreateBitmapProvider(
+ Size(), FilterQuality(), ColorParams());
}
ReplaceResourceProvider(std::move(provider));
@@ -167,95 +182,74 @@ void CanvasRenderingContextHost::CreateCanvasResourceProvider3D(
}
void CanvasRenderingContextHost::CreateCanvasResourceProvider2D(
- AccelerationHint hint) {
- DCHECK(Is2d());
- const bool want_acceleration =
- hint == kPreferAcceleration && ShouldAccelerate2dContext();
-
+ RasterModeHint hint) {
+ DCHECK(IsRenderingContext2D());
base::WeakPtr<CanvasResourceDispatcher> dispatcher =
GetOrCreateResourceDispatcher()
? GetOrCreateResourceDispatcher()->GetWeakPtr()
: nullptr;
- uint8_t presentation_mode = CanvasResourceProvider::kDefaultPresentationMode;
- bool composited_mode = false;
- // Allow GMB image resources if the runtime feature is enabled or if
- // we want to use it for low latency mode.
- if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled() ||
- (base::FeatureList::IsEnabled(
- features::kLowLatencyCanvas2dImageChromium) &&
- LowLatencyEnabled() && want_acceleration)) {
- presentation_mode |=
- CanvasResourceProvider::kAllowImageChromiumPresentationMode;
- composited_mode = true;
- }
- if (base::FeatureList::IsEnabled(features::kLowLatencyCanvas2dSwapChain) &&
- LowLatencyEnabled() && want_acceleration) {
- presentation_mode |=
- CanvasResourceProvider::kAllowSwapChainPresentationMode;
- }
-
- bool try_swap_chain = false;
-
- CanvasResourceProvider::ResourceUsage usage;
- if (want_acceleration) {
- if (LowLatencyEnabled()) {
- // Allow swap chains only if the runtime feature is enabled and we're
- // in low latency mode too.
- usage = CanvasResourceProvider::ResourceUsage::
- kAcceleratedDirect2DResourceUsage;
- try_swap_chain = true;
- } else {
- usage = CanvasResourceProvider::ResourceUsage::
- kAcceleratedCompositedResourceUsage;
- }
- } else {
- usage =
- CanvasResourceProvider::ResourceUsage::kSoftwareCompositedResourceUsage;
- }
std::unique_ptr<CanvasResourceProvider> provider;
+ const bool use_gpu =
+ hint == RasterModeHint::kPreferGPU && ShouldAccelerate2dContext();
// It is important to not use the context's IsOriginTopLeft() here
// because that denotes the current state and could change after the
// new resource provider is created e.g. due to switching between
// unaccelerated and accelerated modes during tab switching.
- const bool is_origin_top_left = !want_acceleration || LowLatencyEnabled();
-
- // First try to be optimized for displaying on screen. In the case we are
- // hardware compositing, we also try to enable the usage of the image as
- // scanout buffer (overlay)
- uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY;
- if (composited_mode)
- shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
-
- if (try_swap_chain) {
- // Swap Chain is used for low latency.
- provider = CanvasResourceProvider::Create(
- Size(), usage, SharedGpuContext::ContextProviderWrapper(),
- GetMSAASampleCountFor2dContext(), FilterQuality(), ColorParams(),
- presentation_mode, std::move(dispatcher), is_origin_top_left);
- } else if (want_acceleration) {
+ const bool is_origin_top_left = !use_gpu || LowLatencyEnabled();
+ if (use_gpu && LowLatencyEnabled()) {
+ // If we can use the gpu and low latency is enabled, we will try to use a
+ // SwapChain if possible.
+ if (base::FeatureList::IsEnabled(features::kLowLatencyCanvas2dSwapChain)) {
+ provider = CanvasResourceProvider::CreateSwapChainProvider(
+ Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(),
+ ColorParams(), is_origin_top_left, std::move(dispatcher));
+ }
+ // If SwapChain failed or it was not possible, we will try a SharedImage
+ // with a set of flags trying to add Usage Display and Usage Scanout and
+ // Concurrent Read and Write if possible.
+ if (!provider) {
+ uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY;
+ if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled() ||
+ base::FeatureList::IsEnabled(
+ features::kLowLatencyCanvas2dImageChromium)) {
+ shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
+ shared_image_usage_flags |=
+ gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
+ }
+ provider = CanvasResourceProvider::CreateSharedImageProvider(
+ Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(),
+ ColorParams(), is_origin_top_left, RasterMode::kGPU,
+ shared_image_usage_flags);
+ }
+ } else if (use_gpu) {
+ // First try to be optimized for displaying on screen. In the case we are
+ // hardware compositing, we also try to enable the usage of the image as
+ // scanout buffer (overlay)
+ uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY;
+ if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled())
+ shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
provider = CanvasResourceProvider::CreateSharedImageProvider(
Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(),
- ColorParams(), is_origin_top_left,
- CanvasResourceProvider::RasterMode::kGPU, shared_image_usage_flags);
- } else if (composited_mode) {
+ ColorParams(), is_origin_top_left, RasterMode::kGPU,
+ shared_image_usage_flags);
+ } else if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) {
+ const uint32_t shared_image_usage_flags =
+ gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT;
provider = CanvasResourceProvider::CreateSharedImageProvider(
Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(),
- ColorParams(), is_origin_top_left,
- CanvasResourceProvider::RasterMode::kCPU, shared_image_usage_flags);
+ ColorParams(), is_origin_top_left, RasterMode::kCPU,
+ shared_image_usage_flags);
}
- if (!provider && !try_swap_chain) {
- // If the sharedImage Provider creation above failed, we try a
- // SharedBitmap Provider before falling back to a Bitmap Provider
+ // If either of the other modes failed and / or it was not possible to do, we
+ // will backup with a SharedBitmap, and if that was not possible with a Bitmap
+ // provider.
+ if (!provider) {
provider = CanvasResourceProvider::CreateSharedBitmapProvider(
- Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(),
- ColorParams(), std::move(dispatcher));
+ Size(), FilterQuality(), ColorParams(), std::move(dispatcher));
}
-
- if (!provider && !try_swap_chain) {
- // If any of the above Create was able to create a valid provider, a
- // BitmapProvider will be created here.
+ if (!provider) {
provider = CanvasResourceProvider::CreateBitmapProvider(
Size(), FilterQuality(), ColorParams());
}
@@ -323,7 +317,7 @@ ScriptPromise CanvasRenderingContextHost::convertToBlob(
base::TimeTicks start_time = base::TimeTicks::Now();
scoped_refptr<StaticBitmapImage> image_bitmap =
- RenderingContext()->GetImage(kPreferNoAcceleration);
+ RenderingContext()->GetImage();
if (image_bitmap) {
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
CanvasAsyncBlobCreator::ToBlobFunctionType function_type =
@@ -334,7 +328,7 @@ ScriptPromise CanvasRenderingContextHost::convertToBlob(
}
auto* async_creator = MakeGarbageCollected<CanvasAsyncBlobCreator>(
image_bitmap, options, function_type, start_time,
- ExecutionContext::From(script_state), resolver);
+ ExecutionContext::From(script_state), ukm_params_, resolver);
async_creator->ScheduleAsyncBlobCreation(options->quality());
return resolver->Promise();
}
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h
index 0716b939ac8..6ffb6efe5b4 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h
+++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h
@@ -5,11 +5,14 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_CANVAS_RENDERING_CONTEXT_HOST_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_CANVAS_RENDERING_CONTEXT_HOST_H_
+#include "base/optional.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_image_source.h"
+#include "third_party/blink/renderer/core/html/canvas/ukm_parameters.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
@@ -37,7 +40,8 @@ class CORE_EXPORT CanvasRenderingContextHost : public CanvasResourceHost,
kCanvasHost,
kOffscreenCanvasHost,
};
- CanvasRenderingContextHost(HostType host_type);
+ CanvasRenderingContextHost(HostType host_type,
+ base::Optional<UkmParameters> ukm_params);
void RecordCanvasSizeToUMA(const IntSize&);
@@ -72,7 +76,6 @@ class CORE_EXPORT CanvasRenderingContextHost : public CanvasResourceHost,
virtual FontSelector* GetFontSelector() = 0;
virtual bool ShouldAccelerate2dContext() const = 0;
- virtual unsigned GetMSAASampleCountFor2dContext() const = 0;
virtual bool IsNeutered() const { return false; }
@@ -94,28 +97,31 @@ class CORE_EXPORT CanvasRenderingContextHost : public CanvasResourceHost,
// Partial CanvasResourceHost implementation
void RestoreCanvasMatrixClipStack(cc::PaintCanvas*) const final;
CanvasResourceProvider* GetOrCreateCanvasResourceProviderImpl(
- AccelerationHint hint) final;
+ RasterModeHint hint) final;
CanvasResourceProvider* GetOrCreateCanvasResourceProvider(
- AccelerationHint hint) override;
+ RasterModeHint hint) override;
bool Is3d() const;
- bool Is2d() const;
+ bool IsRenderingContext2D() const;
CanvasColorParams ColorParams() const;
// blink::CanvasImageSource
bool IsOffscreenCanvas() const override;
+ base::Optional<UkmParameters> ukm_parameters() { return ukm_params_; }
+
protected:
~CanvasRenderingContextHost() override {}
scoped_refptr<StaticBitmapImage> CreateTransparentImage(const IntSize&) const;
- void CreateCanvasResourceProvider2D(AccelerationHint hint);
- void CreateCanvasResourceProvider3D(AccelerationHint hint);
+ void CreateCanvasResourceProvider2D(RasterModeHint hint);
+ void CreateCanvasResourceProvider3D();
bool did_fail_to_create_resource_provider_ = false;
bool did_record_canvas_size_to_uma_ = false;
HostType host_type_ = kNone;
+ base::Optional<UkmParameters> ukm_params_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
index a5b05b93340..b19802cfa60 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -42,6 +42,10 @@
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_study_participation.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
+#include "third_party/blink/public/mojom/gpu/gpu.mojom-blink.h"
+#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/resources/grit/blink_image_resources.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
@@ -82,7 +86,6 @@
#include "third_party/blink/renderer/core/paint/paint_timing.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
-#include "third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
@@ -115,7 +118,9 @@ HTMLCanvasElement::HTMLCanvasElement(Document& document)
ExecutionContextLifecycleObserver(GetExecutionContext()),
PageVisibilityObserver(document.GetPage()),
CanvasRenderingContextHost(
- CanvasRenderingContextHost::HostType::kCanvasHost),
+ CanvasRenderingContextHost::HostType::kCanvasHost,
+ base::make_optional<UkmParameters>(
+ {document.UkmRecorder(), document.UkmSourceID()})),
size_(kDefaultCanvasWidth, kDefaultCanvasHeight),
context_creation_was_blocked_(false),
ignore_reset_(false),
@@ -177,8 +182,8 @@ void HTMLCanvasElement::ParseAttribute(
LayoutObject* HTMLCanvasElement::CreateLayoutObject(const ComputedStyle& style,
LegacyLayout legacy) {
- LocalFrame* frame = GetDocument().GetFrame();
- if (frame && GetDocument().CanExecuteScripts(kNotAboutToExecuteScript)) {
+ if (GetExecutionContext() &&
+ GetExecutionContext()->CanExecuteScripts(kNotAboutToExecuteScript)) {
// Allocation of a layout object indicates that the canvas doesn't
// have display:none set, so is conceptually being displayed.
if (context_) {
@@ -256,8 +261,7 @@ void HTMLCanvasElement::RegisterRenderingContextFactory(
void HTMLCanvasElement::RecordIdentifiabilityMetric(
const blink::IdentifiableSurface& surface,
int64_t value) const {
- blink::IdentifiabilityMetricBuilder(
- base::UkmSourceId::FromInt64(GetDocument().UkmSourceID()))
+ blink::IdentifiabilityMetricBuilder(GetDocument().UkmSourceID())
.Set(surface, value)
.Record(GetDocument().UkmRecorder());
}
@@ -285,11 +289,14 @@ CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContextInternal(
// Log the aliased context type used.
if (!context_) {
- RecordIdentifiabilityMetric(
- blink::IdentifiableSurface::FromTypeAndInput(
- blink::IdentifiableSurface::Type::kWebFeature,
- static_cast<uint64_t>(blink::WebFeature::kCanvasRenderingContext)),
- blink::IdentifiabilityDigestHelper(context_type));
+ if (IsUserInIdentifiabilityStudy()) {
+ RecordIdentifiabilityMetric(
+ blink::IdentifiableSurface::FromTypeAndInput(
+ blink::IdentifiableSurface::Type::kWebFeature,
+ static_cast<uint64_t>(
+ blink::WebFeature::kCanvasRenderingContext)),
+ blink::IdentifiabilityDigestHelper(context_type));
+ }
UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.ContextType", context_type);
}
@@ -344,7 +351,7 @@ CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContextInternal(
EVisibility::kVisible);
}
- if (Is2d() && !context_->CreationAttributes().alpha) {
+ if (IsRenderingContext2D() && !context_->CreationAttributes().alpha) {
// In the alpha false case, canvas is initially opaque, so we need to
// trigger an invalidation.
DidDraw();
@@ -367,7 +374,7 @@ CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContextInternal(
// A 2D context does not know before lazy creation whether or not it is
// direct composited. The Canvas2DLayerBridge will handle this
- if (!Is2d())
+ if (!IsRenderingContext2D())
SetNeedsCompositingUpdate();
return context_.Get();
@@ -377,12 +384,6 @@ ScriptPromise HTMLCanvasElement::convertToBlob(
ScriptState* script_state,
const ImageEncodeOptions* options,
ExceptionState& exception_state) {
- RecordIdentifiabilityMetric(
- blink::IdentifiableSurface::FromTypeAndInput(
- blink::IdentifiableSurface::Type::kCanvasReadback,
- context_ ? context_->GetContextType()
- : CanvasRenderingContext::kContextTypeUnknown),
- 0);
return CanvasRenderingContextHost::convertToBlob(script_state, options,
exception_state);
}
@@ -415,12 +416,11 @@ bool HTMLCanvasElement::IsWebGL2Enabled() const {
bool HTMLCanvasElement::IsWebGLBlocked() const {
Document& document = GetDocument();
- LocalFrame* frame = document.GetFrame();
- if (!frame)
- return false;
-
bool blocked = false;
- frame->GetLocalFrameHostRemote().Are3DAPIsBlocked(&blocked);
+ mojo::Remote<mojom::blink::GpuDataManager> gpu_data_manager;
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
+ gpu_data_manager.BindNewPipeAndPassReceiver());
+ gpu_data_manager->Are3DAPIsBlockedForUrl(document.Url(), &blocked);
return blocked;
}
@@ -430,7 +430,7 @@ void HTMLCanvasElement::DidDraw(const FloatRect& rect) {
canvas_is_clear_ = false;
if (GetLayoutObject() && !LowLatencyEnabled())
GetLayoutObject()->SetShouldCheckForPaintInvalidation();
- if (Is2d() && context_->ShouldAntialias() && GetPage() &&
+ if (IsRenderingContext2D() && context_->ShouldAntialias() && GetPage() &&
GetPage()->DeviceScaleFactorDeprecated() > 1.0f) {
FloatRect inflated_rect = rect;
inflated_rect.Inflate(1);
@@ -438,7 +438,7 @@ void HTMLCanvasElement::DidDraw(const FloatRect& rect) {
} else {
dirty_rect_.Unite(rect);
}
- if (Is2d() && canvas2d_bridge_)
+ if (IsRenderingContext2D() && canvas2d_bridge_)
canvas2d_bridge_->DidDraw(rect);
}
@@ -458,7 +458,7 @@ void HTMLCanvasElement::PreFinalizeFrame() {
// Low-latency 2d canvases produce their frames after the resource gets single
// buffered.
if (LowLatencyEnabled() && !dirty_rect_.IsEmpty() &&
- GetOrCreateCanvasResourceProvider(kPreferAcceleration)) {
+ GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU)) {
// TryEnableSingleBuffering() the first time we FinalizeFrame(). This is
// a nop if already single buffered or if single buffering is unsupported.
ResourceProvider()->TryEnableSingleBuffering();
@@ -467,7 +467,7 @@ void HTMLCanvasElement::PreFinalizeFrame() {
void HTMLCanvasElement::PostFinalizeFrame() {
if (LowLatencyEnabled() && !dirty_rect_.IsEmpty() &&
- GetOrCreateCanvasResourceProvider(kPreferAcceleration)) {
+ GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU)) {
const base::TimeTicks start_time = base::TimeTicks::Now();
const scoped_refptr<CanvasResource> canvas_resource =
ResourceProvider()->ProduceCanvasResource();
@@ -502,7 +502,7 @@ void HTMLCanvasElement::DisableAcceleration(
if (unaccelerated_bridge_used_for_testing)
bridge = std::move(unaccelerated_bridge_used_for_testing);
else
- bridge = CreateUnaccelerated2dBuffer();
+ bridge = Create2DLayerBridge(RasterMode::kCPU);
if (bridge && canvas2d_bridge_)
ReplaceExisting2dLayerBridge(std::move(bridge));
@@ -535,7 +535,7 @@ void HTMLCanvasElement::DoDeferredPaintInvalidation() {
}
}
- if (Is2d()) {
+ if (IsRenderingContext2D()) {
FloatRect src_rect(0, 0, Size().Width(), Size().Height());
dirty_rect_.Intersect(src_rect);
@@ -613,7 +613,7 @@ void HTMLCanvasElement::Reset() {
h = kDefaultCanvasHeight;
}
- if (Is2d()) {
+ if (IsRenderingContext2D()) {
context_->Reset();
origin_clean_ = true;
}
@@ -623,7 +623,7 @@ void HTMLCanvasElement::Reset() {
// If the size of an existing buffer matches, we can just clear it instead of
// reallocating. This optimization is only done for 2D canvases for now.
- if (had_resource_provider && old_size == new_size && Is2d()) {
+ if (had_resource_provider && old_size == new_size && IsRenderingContext2D()) {
if (!canvas_is_clear_) {
canvas_is_clear_ = true;
if (canvas2d_bridge_)
@@ -682,7 +682,7 @@ void HTMLCanvasElement::NotifyListenersCanvasChanged() {
if (listener_needs_new_frame_capture) {
SourceImageStatus status;
scoped_refptr<StaticBitmapImage> source_image =
- GetSourceImageForCanvasInternal(&status, kPreferNoAcceleration);
+ GetSourceImageForCanvasInternal(&status);
if (status != kNormalSourceImageStatus)
return;
for (CanvasDrawListener* listener : listeners_) {
@@ -708,6 +708,12 @@ static std::pair<blink::Image*, float> BrokenCanvas(float device_scale_factor) {
return std::make_pair(broken_canvas_lo_res, 1);
}
+static SkFilterQuality FilterQualityFromStyle(const ComputedStyle* style) {
+ if (style && style->ImageRendering() == EImageRendering::kPixelated)
+ return kNone_SkFilterQuality;
+ return kLow_SkFilterQuality;
+}
+
SkFilterQuality HTMLCanvasElement::FilterQuality() const {
if (!isConnected())
return kLow_SkFilterQuality;
@@ -718,23 +724,21 @@ SkFilterQuality HTMLCanvasElement::FilterQuality() const {
HTMLCanvasElement* non_const_this = const_cast<HTMLCanvasElement*>(this);
style = non_const_this->EnsureComputedStyle();
}
- return (style && style->ImageRendering() == EImageRendering::kPixelated)
- ? kNone_SkFilterQuality
- : kLow_SkFilterQuality;
+ return FilterQualityFromStyle(style);
}
bool HTMLCanvasElement::LowLatencyEnabled() const {
return !!frame_dispatcher_;
}
-void HTMLCanvasElement::UpdateFilterQuality() {
+void HTMLCanvasElement::UpdateFilterQuality(SkFilterQuality filter_quality) {
if (IsOffscreenCanvasRegistered())
- UpdateOffscreenCanvasFilterQuality(FilterQuality());
+ UpdateOffscreenCanvasFilterQuality(filter_quality);
if (context_ && Is3d())
- context_->SetFilterQuality(FilterQuality());
+ context_->SetFilterQuality(filter_quality);
else if (canvas2d_bridge_)
- canvas2d_bridge_->UpdateFilterQuality();
+ canvas2d_bridge_->SetFilterQuality(filter_quality);
}
// In some instances we don't actually want to paint to the parent layer
@@ -828,7 +832,7 @@ void HTMLCanvasElement::PaintInternal(GraphicsContext& context,
FloatRect src_rect = FloatRect(FloatPoint(), FloatSize(Size()));
scoped_refptr<StaticBitmapImage> snapshot =
canvas2d_bridge_
- ? canvas2d_bridge_->NewImageSnapshot(kPreferAcceleration)
+ ? canvas2d_bridge_->NewImageSnapshot()
: (ResourceProvider() ? ResourceProvider()->Snapshot() : nullptr);
if (snapshot) {
// GraphicsContext cannot handle gpu resource serialization.
@@ -857,7 +861,7 @@ void HTMLCanvasElement::SetSurfaceSize(const IntSize& size) {
size_ = size;
did_fail_to_create_resource_provider_ = false;
DiscardResourceProvider();
- if (Is2d() && context_->isContextLost())
+ if (IsRenderingContext2D() && context_->isContextLost())
context_->DidSetSurfaceSize();
if (frame_dispatcher_)
frame_dispatcher_->Reshape(size_);
@@ -869,8 +873,7 @@ const AtomicString HTMLCanvasElement::ImageSourceURL() const {
}
scoped_refptr<StaticBitmapImage> HTMLCanvasElement::Snapshot(
- SourceDrawingBuffer source_buffer,
- AccelerationHint hint) const {
+ SourceDrawingBuffer source_buffer) const {
if (size_.IsEmpty())
return nullptr;
@@ -900,11 +903,11 @@ scoped_refptr<StaticBitmapImage> HTMLCanvasElement::Snapshot(
image_bitmap = StaticBitmapImage::Create(std::move(pixel_data), info);
}
}
- } else if (canvas2d_bridge_) { // 2D Canvas
- DCHECK(Is2d());
- image_bitmap = canvas2d_bridge_->NewImageSnapshot(hint);
+ } else if (canvas2d_bridge_) {
+ DCHECK(IsRenderingContext2D());
+ image_bitmap = canvas2d_bridge_->NewImageSnapshot();
} else if (context_) { // Bitmap renderer canvas
- image_bitmap = context_->GetImage(hint);
+ image_bitmap = context_->GetImage();
}
if (!image_bitmap)
@@ -924,8 +927,7 @@ String HTMLCanvasElement::ToDataURLInternal(
ImageEncoderUtils::ToEncodingMimeType(
mime_type, ImageEncoderUtils::kEncodeReasonToDataURL);
- scoped_refptr<StaticBitmapImage> image_bitmap =
- Snapshot(source_buffer, kPreferNoAcceleration);
+ scoped_refptr<StaticBitmapImage> image_bitmap = Snapshot(source_buffer);
if (image_bitmap) {
std::unique_ptr<ImageDataBuffer> data_buffer =
ImageDataBuffer::Create(image_bitmap);
@@ -958,12 +960,22 @@ String HTMLCanvasElement::ToDataURLInternal(
// Currently we only support three encoding types.
NOTREACHED();
}
- RecordIdentifiabilityMetric(
- blink::IdentifiableSurface::FromTypeAndInput(
- blink::IdentifiableSurface::Type::kCanvasReadback,
- context_ ? context_->GetContextType()
- : CanvasRenderingContext::kContextTypeUnknown),
- 0);
+ if (IsUserInIdentifiabilityStudy()) {
+ const uint64_t context_digest =
+ context_ ? context_->IdentifiabilityTextDigest() : 0;
+ const uint64_t canvas_digest =
+ ResourceProvider() ? ResourceProvider()->GetIdentifiabilityDigest()
+ : 0;
+ const uint64_t context_type =
+ context_ ? context_->GetContextType()
+ : CanvasRenderingContext::kContextTypeUnknown;
+ const uint64_t final_digest =
+ ((context_digest ^ canvas_digest) << 4) | context_type;
+ RecordIdentifiabilityMetric(
+ blink::IdentifiableSurface::FromTypeAndInput(
+ blink::IdentifiableSurface::Type::kCanvasReadback, final_digest),
+ blink::IdentifiabilityDigestOfBytes(data_url.Span8()));
+ }
return data_url;
}
@@ -996,6 +1008,9 @@ void HTMLCanvasElement::toBlob(V8BlobCallback* callback,
return;
}
+ if (!GetExecutionContext())
+ return;
+
if (!IsPaintable()) {
// If the canvas element's bitmap has no pixels
GetDocument()
@@ -1019,23 +1034,26 @@ void HTMLCanvasElement::toBlob(V8BlobCallback* callback,
mime_type, ImageEncoderUtils::kEncodeReasonToBlobCallback);
CanvasAsyncBlobCreator* async_creator = nullptr;
- scoped_refptr<StaticBitmapImage> image_bitmap =
- Snapshot(kBackBuffer, kPreferNoAcceleration);
+ scoped_refptr<StaticBitmapImage> image_bitmap = Snapshot(kBackBuffer);
if (image_bitmap) {
auto* options = ImageEncodeOptions::Create();
options->setType(ImageEncodingMimeTypeName(encoding_mime_type));
async_creator = MakeGarbageCollected<CanvasAsyncBlobCreator>(
image_bitmap, options,
CanvasAsyncBlobCreator::kHTMLCanvasToBlobCallback, callback, start_time,
- GetExecutionContext());
+ GetExecutionContext(),
+ base::make_optional<UkmParameters>(
+ {GetDocument().UkmRecorder(), GetDocument().UkmSourceID()}));
}
- RecordIdentifiabilityMetric(
- blink::IdentifiableSurface::FromTypeAndInput(
- blink::IdentifiableSurface::Type::kCanvasReadback,
- context_ ? context_->GetContextType()
- : CanvasRenderingContext::kContextTypeUnknown),
- 0);
+ if (IsUserInIdentifiabilityStudy()) {
+ RecordIdentifiabilityMetric(
+ blink::IdentifiableSurface::FromTypeAndInput(
+ blink::IdentifiableSurface::Type::kCanvasReadback,
+ context_ ? context_->GetContextType()
+ : CanvasRenderingContext::kContextTypeUnknown),
+ 0);
+ }
if (async_creator) {
async_creator->ScheduleAsyncBlobCreation(quality);
@@ -1067,7 +1085,7 @@ bool HTMLCanvasElement::OriginClean() const {
}
bool HTMLCanvasElement::ShouldAccelerate2dContext() const {
- return ShouldAccelerate(kNormalAccelerationCriteria);
+ return ShouldAccelerate();
}
CanvasResourceDispatcher* HTMLCanvasElement::GetOrCreateResourceDispatcher() {
@@ -1083,8 +1101,8 @@ bool HTMLCanvasElement::PushFrame(scoped_refptr<CanvasResource> image,
return false;
}
-bool HTMLCanvasElement::ShouldAccelerate(AccelerationCriteria criteria) const {
- if (context_ && !Is2d())
+bool HTMLCanvasElement::ShouldAccelerate() const {
+ if (context_ && !IsRenderingContext2D())
return false;
// The command line flag --disable-accelerated-2d-canvas toggles this option
@@ -1121,35 +1139,19 @@ bool HTMLCanvasElement::ShouldAccelerate(AccelerationCriteria criteria) const {
return context_provider_wrapper->Utils()->Accelerated2DCanvasFeatureEnabled();
}
-unsigned HTMLCanvasElement::GetMSAASampleCountFor2dContext() const {
- if (!GetDocument().GetSettings())
- return 0;
- return GetDocument().GetSettings()->GetAccelerated2dCanvasMSAASampleCount();
-}
-
-std::unique_ptr<Canvas2DLayerBridge>
-HTMLCanvasElement::CreateAccelerated2dBuffer() {
- auto surface = std::make_unique<Canvas2DLayerBridge>(
- Size(), Canvas2DLayerBridge::kEnableAcceleration, ColorParams());
+std::unique_ptr<Canvas2DLayerBridge> HTMLCanvasElement::Create2DLayerBridge(
+ RasterMode raster_mode) {
+ auto surface =
+ std::make_unique<Canvas2DLayerBridge>(Size(), raster_mode, ColorParams());
if (!surface->IsValid())
return nullptr;
return surface;
}
-std::unique_ptr<Canvas2DLayerBridge>
-HTMLCanvasElement::CreateUnaccelerated2dBuffer() {
- auto surface = std::make_unique<Canvas2DLayerBridge>(
- Size(), Canvas2DLayerBridge::kDisableAcceleration, ColorParams());
- if (surface->IsValid())
- return surface;
-
- return nullptr;
-}
-
void HTMLCanvasElement::SetCanvas2DLayerBridgeInternal(
std::unique_ptr<Canvas2DLayerBridge> external_canvas2d_bridge) {
- DCHECK(Is2d() && !canvas2d_bridge_);
+ DCHECK(IsRenderingContext2D() && !canvas2d_bridge_);
did_fail_to_create_resource_provider_ = true;
if (!IsValidImageSize(Size()))
@@ -1159,10 +1161,19 @@ void HTMLCanvasElement::SetCanvas2DLayerBridgeInternal(
if (external_canvas2d_bridge->IsValid())
canvas2d_bridge_ = std::move(external_canvas2d_bridge);
} else {
- if (ShouldAccelerate(kNormalAccelerationCriteria))
- canvas2d_bridge_ = CreateAccelerated2dBuffer();
- if (!canvas2d_bridge_)
- canvas2d_bridge_ = CreateUnaccelerated2dBuffer();
+ // If the canvas meets the criteria to use accelerated-GPU rendering, and
+ // the user signals that the canvas will not be read frequently through
+ // getImageData, which is a slow operation with GPU, the canvas will try to
+ // use accelerated-GPU rendering.
+ // If any of the two conditions fails, or if the creation of accelerated
+ // resource provider fails, the canvas will fallback to CPU rendering.
+ if (ShouldAccelerate() &&
+ !context_->CreationAttributes().will_read_frequently) {
+ canvas2d_bridge_ = Create2DLayerBridge(RasterMode::kGPU);
+ }
+ if (!canvas2d_bridge_) {
+ canvas2d_bridge_ = Create2DLayerBridge(RasterMode::kCPU);
+ }
}
if (!canvas2d_bridge_)
@@ -1177,25 +1188,16 @@ void HTMLCanvasElement::SetCanvas2DLayerBridgeInternal(
did_fail_to_create_resource_provider_ = false;
UpdateMemoryUsage();
- // Enabling MSAA overrides a request to disable antialiasing. This is true
- // regardless of whether the rendering mode is accelerated or not. For
- // consistency, we don't want to apply AA in accelerated canvases but not in
- // unaccelerated canvases.
- if (!GetMSAASampleCountFor2dContext() && GetDocument().GetSettings() &&
- !GetDocument().GetSettings()->GetAntialiased2dCanvasEnabled()) {
- context_->SetShouldAntialias(false);
- }
-
if (context_)
SetNeedsCompositingUpdate();
}
void HTMLCanvasElement::NotifyGpuContextLost() {
- if (Is2d())
+ if (IsRenderingContext2D())
context_->LoseContext(CanvasRenderingContext::kRealLostContext);
}
-void HTMLCanvasElement::Trace(Visitor* visitor) {
+void HTMLCanvasElement::Trace(Visitor* visitor) const {
visitor->Trace(listeners_);
visitor->Trace(context_);
ExecutionContextLifecycleObserver::Trace(visitor);
@@ -1204,7 +1206,7 @@ void HTMLCanvasElement::Trace(Visitor* visitor) {
}
Canvas2DLayerBridge* HTMLCanvasElement::GetOrCreateCanvas2DLayerBridge() {
- DCHECK(Is2d());
+ DCHECK(IsRenderingContext2D());
if (!canvas2d_bridge_ && !did_fail_to_create_resource_provider_) {
SetCanvas2DLayerBridgeInternal(nullptr);
if (did_fail_to_create_resource_provider_ && !Size().IsEmpty())
@@ -1249,6 +1251,7 @@ void HTMLCanvasElement::ContextDestroyed() {
void HTMLCanvasElement::StyleDidChange(const ComputedStyle* old_style,
const ComputedStyle& new_style) {
+ UpdateFilterQuality(FilterQualityFromStyle(&new_style));
if (context_)
context_->StyleDidChange(old_style, new_style);
}
@@ -1269,9 +1272,9 @@ void HTMLCanvasElement::DidMoveToNewDocument(Document& old_document) {
void HTMLCanvasElement::WillDrawImageTo2DContext(CanvasImageSource* source) {
if (SharedGpuContext::AllowSoftwareToAcceleratedCanvasUpgrade() &&
source->IsAccelerated() && GetOrCreateCanvas2DLayerBridge() &&
- !canvas2d_bridge_->IsAccelerated() &&
- ShouldAccelerate(kIgnoreResourceLimitCriteria)) {
- std::unique_ptr<Canvas2DLayerBridge> surface = CreateAccelerated2dBuffer();
+ !canvas2d_bridge_->IsAccelerated() && ShouldAccelerate()) {
+ std::unique_ptr<Canvas2DLayerBridge> surface =
+ Create2DLayerBridge(RasterMode::kGPU);
if (surface) {
ReplaceExisting2dLayerBridge(std::move(surface));
SetNeedsCompositingUpdate();
@@ -1281,14 +1284,12 @@ void HTMLCanvasElement::WillDrawImageTo2DContext(CanvasImageSource* source) {
scoped_refptr<Image> HTMLCanvasElement::GetSourceImageForCanvas(
SourceImageStatus* status,
- AccelerationHint hint,
const FloatSize&) {
- return GetSourceImageForCanvasInternal(status, hint);
+ return GetSourceImageForCanvasInternal(status);
}
scoped_refptr<StaticBitmapImage>
-HTMLCanvasElement::GetSourceImageForCanvasInternal(SourceImageStatus* status,
- AccelerationHint hint) {
+HTMLCanvasElement::GetSourceImageForCanvasInternal(SourceImageStatus* status) {
if (!width() || !height()) {
*status = kZeroSizeCanvasSourceImageStatus;
return nullptr;
@@ -1312,7 +1313,7 @@ HTMLCanvasElement::GetSourceImageForCanvasInternal(SourceImageStatus* status,
if (HasImageBitmapContext()) {
*status = kNormalSourceImageStatus;
- scoped_refptr<StaticBitmapImage> result = context_->GetImage(hint);
+ scoped_refptr<StaticBitmapImage> result = context_->GetImage();
if (!result)
result = GetTransparentImage();
*status = result ? kNormalSourceImageStatus : kInvalidSourceImageStatus;
@@ -1332,7 +1333,7 @@ HTMLCanvasElement::GetSourceImageForCanvasInternal(SourceImageStatus* status,
else
image = GetTransparentImage();
} else {
- image = RenderingContext()->GetImage(hint);
+ image = RenderingContext()->GetImage();
if (!image)
image = GetTransparentImage();
}
@@ -1352,7 +1353,7 @@ FloatSize HTMLCanvasElement::ElementSize(
const FloatSize&,
const RespectImageOrientationEnum) const {
if (context_ && HasImageBitmapContext()) {
- scoped_refptr<Image> image = context_->GetImage(kPreferNoAcceleration);
+ scoped_refptr<Image> image = context_->GetImage();
if (image)
return FloatSize(image->width(), image->height());
return FloatSize(0, 0);
@@ -1458,7 +1459,7 @@ bool HTMLCanvasElement::IsSupportedInteractiveCanvasFallback(
HitTestCanvasResult* HTMLCanvasElement::GetControlAndIdIfHitRegionExists(
const PhysicalOffset& location) {
- if (Is2d())
+ if (IsRenderingContext2D())
return context_->GetControlAndIdIfHitRegionExists(location);
return MakeGarbageCollected<HitTestCanvasResult>(String(), nullptr);
}
@@ -1505,7 +1506,7 @@ void HTMLCanvasElement::UpdateMemoryUsage() {
int non_gpu_buffer_count = 0;
int gpu_buffer_count = 0;
- if (!Is2d() && !Is3d())
+ if (!IsRenderingContext2D() && !Is3d())
return;
if (ResourceProvider()) {
non_gpu_buffer_count++;
@@ -1525,7 +1526,7 @@ void HTMLCanvasElement::UpdateMemoryUsage() {
intptr_t gpu_memory_usage = 0;
if (gpu_buffer_count) {
- // Switch from non-acceleration mode to acceleration mode
+ // Switch from cpu mode to gpu mode
base::CheckedNumeric<intptr_t> checked_usage =
gpu_buffer_count * bytes_per_pixel;
checked_usage *= width();
@@ -1553,22 +1554,40 @@ void HTMLCanvasElement::UpdateMemoryUsage() {
void HTMLCanvasElement::ReplaceExisting2dLayerBridge(
std::unique_ptr<Canvas2DLayerBridge> new_layer_bridge) {
scoped_refptr<StaticBitmapImage> image;
+ std::unique_ptr<Canvas2DLayerBridge> old_layer_bridge;
if (canvas2d_bridge_) {
- image = canvas2d_bridge_->NewImageSnapshot(kPreferNoAcceleration);
+ image = canvas2d_bridge_->NewImageSnapshot();
// image can be null if allocation failed in which case we should just
// abort the surface switch to retain the old surface which is still
// functional.
if (!image)
return;
+ old_layer_bridge = std::move(canvas2d_bridge_);
+ // Removing connection between old_layer_bridge and CanvasResourceHost;
+ // otherwise, the CanvasResourceHost checks for the old one before
+ // assigning the new canvas layer bridge.
+ old_layer_bridge->SetCanvasResourceHost(nullptr);
}
ReplaceResourceProvider(nullptr);
canvas2d_bridge_ = std::move(new_layer_bridge);
canvas2d_bridge_->SetCanvasResourceHost(this);
+ // If PaintCanvas cannot be get from the new layer bridge, revert the
+ // replacement.
cc::PaintCanvas* canvas = canvas2d_bridge_->GetPaintCanvas();
- // Paint canvas automatically has the clip re-applied. Since image already
- // contains clip, it needs to be drawn before the clip stack is re-applied.
- // Remove clip from canvas and restore it after the image is drawn.
+ if (!canvas) {
+ if (old_layer_bridge) {
+ canvas2d_bridge_ = std::move(old_layer_bridge);
+ canvas2d_bridge_->SetCanvasResourceHost(this);
+ }
+ return;
+ }
+
+ // After validating paint canvas on new layer bridge, removes the clip from
+ // the canvas. Since clips is automatically applied to paint canvas, the image
+ // already contains clip and the image needs to be drawn before the clip stack
+ // is re-applied, it needs to remove clip from canvas and restore it after the
+ // image is drawn.
canvas->restoreToCount(1);
canvas->save();
@@ -1584,9 +1603,9 @@ void HTMLCanvasElement::ReplaceExisting2dLayerBridge(
}
CanvasResourceProvider* HTMLCanvasElement::GetOrCreateCanvasResourceProvider(
- AccelerationHint hint) {
- if (Is2d())
- return GetOrCreateCanvas2DLayerBridge()->GetOrCreateResourceProvider(hint);
+ RasterModeHint hint) {
+ if (IsRenderingContext2D())
+ return GetOrCreateCanvas2DLayerBridge()->GetOrCreateResourceProvider();
return CanvasRenderingContextHost::GetOrCreateCanvasResourceProvider(hint);
}
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.h b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.h
index e36e9a211ab..2aa3fe0864f 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.h
+++ b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.h
@@ -45,6 +45,7 @@
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
+#include "third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource_host.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
@@ -86,11 +87,11 @@ typedef CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextO
#endif
// This contains the information of HTML Canvas Element,
-// There are four different types of context this HTML Canvas can contain.
+// There are four different types of rendering context this HTML Canvas can own.
// It can be a 3D Context (WebGL or WebGL2), 2D Context,
-// BitmapRenderingContext or it can have no context (Offscreencanvas).
+// BitmapRenderingContext or it can have no context (Offscreen placeholder).
// To check the no context case is good to check if there is a placeholder.
-// For 3D and 2D contexts there are Is3D or Is2D functions.
+// For 3D and 2D contexts there are Is3D or IsRenderingContext2D functions.
// The remaining case is BitmaprenderingContext.
//
// TODO (juanmihd): Study if a refactor of context could help in simplifying
@@ -155,7 +156,6 @@ class CORE_EXPORT HTMLCanvasElement final
void DidDraw(const FloatRect&) override;
void DidDraw() override;
- void UpdateFilterQuality();
void Paint(GraphicsContext&,
const PhysicalRect&,
bool flatten_composited_layers);
@@ -202,7 +202,6 @@ class CORE_EXPORT HTMLCanvasElement final
// CanvasImageSource implementation
scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*,
- AccelerationHint,
const FloatSize&) override;
bool WouldTaintOrigin() const override;
FloatSize ElementSize(const FloatSize&,
@@ -221,11 +220,10 @@ class CORE_EXPORT HTMLCanvasElement final
void SetNeedsCompositingUpdate() override;
void UpdateMemoryUsage() override;
bool ShouldAccelerate2dContext() const override;
- unsigned GetMSAASampleCountFor2dContext() const override;
SkFilterQuality FilterQuality() const override;
bool LowLatencyEnabled() const override;
CanvasResourceProvider* GetOrCreateCanvasResourceProvider(
- AccelerationHint hint) override;
+ RasterModeHint hint) override;
bool IsPrinting() const override;
void DisableAcceleration(std::unique_ptr<Canvas2DLayerBridge>
@@ -241,7 +239,7 @@ class CORE_EXPORT HTMLCanvasElement final
// OffscreenCanvasPlaceholder implementation.
void SetOffscreenCanvasResource(scoped_refptr<CanvasResource>,
unsigned resource_id) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void SetResourceProviderForTesting(std::unique_ptr<CanvasResourceProvider>,
std::unique_ptr<Canvas2DLayerBridge>,
@@ -300,8 +298,7 @@ class CORE_EXPORT HTMLCanvasElement final
needs_unbuffered_input_ = value;
}
- scoped_refptr<StaticBitmapImage> Snapshot(SourceDrawingBuffer,
- AccelerationHint) const;
+ scoped_refptr<StaticBitmapImage> Snapshot(SourceDrawingBuffer) const;
// Returns the cc layer containing the contents. It's the cc layer of
// SurfaceLayerBridge() or RenderingContext(), or nullptr if the canvas is not
@@ -323,17 +320,14 @@ class CORE_EXPORT HTMLCanvasElement final
int64_t value) const;
void PaintInternal(GraphicsContext&, const PhysicalRect&);
+ void UpdateFilterQuality(SkFilterQuality filter_quality);
using ContextFactoryVector =
Vector<std::unique_ptr<CanvasRenderingContextFactory>>;
static ContextFactoryVector& RenderingContextFactories();
static CanvasRenderingContextFactory* GetRenderingContextFactory(int);
- enum AccelerationCriteria {
- kNormalAccelerationCriteria,
- kIgnoreResourceLimitCriteria,
- };
- bool ShouldAccelerate(AccelerationCriteria) const;
+ bool ShouldAccelerate() const;
void ParseAttribute(const AttributeModificationParams&) override;
LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
@@ -341,8 +335,8 @@ class CORE_EXPORT HTMLCanvasElement final
void Reset();
- std::unique_ptr<Canvas2DLayerBridge> CreateAccelerated2dBuffer();
- std::unique_ptr<Canvas2DLayerBridge> CreateUnaccelerated2dBuffer();
+ std::unique_ptr<Canvas2DLayerBridge> Create2DLayerBridge(
+ RasterMode raster_mode);
void SetCanvas2DLayerBridgeInternal(std::unique_ptr<Canvas2DLayerBridge>);
void SetSurfaceSize(const IntSize&);
@@ -365,8 +359,7 @@ class CORE_EXPORT HTMLCanvasElement final
const CanvasContextCreationAttributesCore&);
scoped_refptr<StaticBitmapImage> GetSourceImageForCanvasInternal(
- SourceImageStatus*,
- AccelerationHint);
+ SourceImageStatus*);
void OnContentsCcLayerChanged();
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc b/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc
index 099510256d3..e8bb23291fc 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc
+++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc
@@ -254,9 +254,6 @@ ImageDataColorSettings* CanvasColorParamsToImageDataColorSettings(
case CanvasColorSpace::kSRGB:
color_settings->setColorSpace(kSRGBCanvasColorSpaceName);
break;
- case CanvasColorSpace::kLinearRGB:
- color_settings->setColorSpace(kLinearRGBCanvasColorSpaceName);
- break;
case CanvasColorSpace::kRec2020:
color_settings->setColorSpace(kRec2020CanvasColorSpaceName);
break;
@@ -285,9 +282,6 @@ ImageData* ImageData::Create(const IntSize& size,
case CanvasColorSpace::kSRGB:
color_settings->setColorSpace(kSRGBCanvasColorSpaceName);
break;
- case CanvasColorSpace::kLinearRGB:
- color_settings->setColorSpace(kLinearRGBCanvasColorSpaceName);
- break;
case CanvasColorSpace::kRec2020:
color_settings->setColorSpace(kRec2020CanvasColorSpaceName);
break;
@@ -604,8 +598,6 @@ CanvasColorSpace ImageData::GetCanvasColorSpace(
const String& color_space_name) {
if (color_space_name == kSRGBCanvasColorSpaceName)
return CanvasColorSpace::kSRGB;
- if (color_space_name == kLinearRGBCanvasColorSpaceName)
- return CanvasColorSpace::kLinearRGB;
if (color_space_name == kRec2020CanvasColorSpaceName)
return CanvasColorSpace::kRec2020;
if (color_space_name == kP3CanvasColorSpaceName)
@@ -618,8 +610,6 @@ String ImageData::CanvasColorSpaceName(CanvasColorSpace color_space) {
switch (color_space) {
case CanvasColorSpace::kSRGB:
return kSRGBCanvasColorSpaceName;
- case CanvasColorSpace::kLinearRGB:
- return kLinearRGBCanvasColorSpaceName;
case CanvasColorSpace::kRec2020:
return kRec2020CanvasColorSpaceName;
case CanvasColorSpace::kP3:
@@ -848,7 +838,7 @@ bool ImageData::ImageDataInCanvasColorSettings(
return data_transform_successful;
}
-void ImageData::Trace(Visitor* visitor) {
+void ImageData::Trace(Visitor* visitor) const {
visitor->Trace(color_settings_);
visitor->Trace(data_);
visitor->Trace(data_u16_);
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data.h b/chromium/third_party/blink/renderer/core/html/canvas/image_data.h
index 4101d0fa9b2..5a5e0da97a2 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/image_data.h
+++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data.h
@@ -158,7 +158,7 @@ class CORE_EXPORT ImageData final : public ScriptWrappable,
const ImageBitmapOptions*,
ExceptionState&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
WARN_UNUSED_RESULT v8::Local<v8::Object> AssociateWithWrapper(
v8::Isolate*,
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data_color_settings.idl b/chromium/third_party/blink/renderer/core/html/canvas/image_data_color_settings.idl
index e8fc5ced5c1..917e0e182c8 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/image_data_color_settings.idl
+++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data_color_settings.idl
@@ -6,7 +6,6 @@
enum CanvasColorSpace {
"srgb", // default
- "linear-rgb",
"rec2020",
"p3",
};
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc b/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc
index 15db4684f74..dd867b4cdde 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc
@@ -133,7 +133,6 @@ TEST_F(ImageDataTest, TestGetImageDataInCanvasColorSettings) {
unsigned num_image_data_color_spaces = 3;
CanvasColorSpace image_data_color_spaces[] = {
CanvasColorSpace::kSRGB,
- CanvasColorSpace::kLinearRGB,
CanvasColorSpace::kRec2020,
CanvasColorSpace::kP3,
};
@@ -144,17 +143,17 @@ TEST_F(ImageDataTest, TestGetImageDataInCanvasColorSettings) {
kFloat32ArrayStorageFormat,
};
- unsigned num_canvas_color_settings = 4;
+ unsigned num_canvas_color_settings = 3;
CanvasColorSpace canvas_color_spaces[] = {
- CanvasColorSpace::kSRGB, CanvasColorSpace::kSRGB,
- CanvasColorSpace::kLinearRGB, CanvasColorSpace::kRec2020,
+ CanvasColorSpace::kSRGB,
+ CanvasColorSpace::kSRGB,
+ CanvasColorSpace::kRec2020,
CanvasColorSpace::kP3,
};
CanvasPixelFormat canvas_pixel_formats[] = {
CanvasPixelFormat::kRGBA8, CanvasPixelFormat::kF16,
CanvasPixelFormat::kF16, CanvasPixelFormat::kF16,
- CanvasPixelFormat::kF16,
};
// As cross checking the output of Skia color space covnersion API is not in
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc
index 33076248c58..d0bbfde754b 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc
+++ b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc
@@ -47,7 +47,6 @@ bool ImageElementBase::IsImageElement() const {
scoped_refptr<Image> ImageElementBase::GetSourceImageForCanvas(
SourceImageStatus* status,
- AccelerationHint,
const FloatSize& default_object_size) {
ImageResourceContent* image_content = CachedImage();
if (!GetImageLoader().ImageComplete() || !image_content) {
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h
index 05a08421d22..88f23ca7565 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h
+++ b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h
@@ -33,7 +33,6 @@ class CORE_EXPORT ImageElementBase : public CanvasImageSource,
ExceptionState&) override;
scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*,
- AccelerationHint,
const FloatSize&) override;
bool WouldTaintOrigin() const override;
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.cc b/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.cc
index bdbc4c5a9f9..d3fadad089c 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.cc
+++ b/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/html/canvas/text_metrics.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_baselines.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.h"
#include "third_party/blink/renderer/platform/fonts/character_range.h"
namespace blink {
@@ -38,7 +39,7 @@ float TextMetrics::GetFontBaseline(const TextBaseline& text_baseline,
return 0;
}
-void TextMetrics::Trace(Visitor* visitor) {
+void TextMetrics::Trace(Visitor* visitor) const {
visitor->Trace(baselines_);
ScriptWrappable::Trace(visitor);
}
@@ -63,20 +64,56 @@ void TextMetrics::Update(const Font& font,
if (!font_data)
return;
+ // TODO(kojii): Need to figure out the desired behavior of |advances| when
+ // bidi reorder occurs.
TextRun text_run(
text, /* xpos */ 0, /* expansion */ 0,
TextRun::kAllowTrailingExpansion | TextRun::kForbidLeadingExpansion,
direction, false);
text_run.SetNormalizeSpace(true);
- FloatRect bbox = font.BoundingBox(text_run);
- const FontMetrics& font_metrics = font_data->GetFontMetrics();
-
advances_ = font.IndividualCharacterAdvances(text_run);
// x direction
- width_ = bbox.Width();
+ // Run bidi algorithm on the given text. Step 5 of:
+ // https://html.spec.whatwg.org/multipage/canvas.html#text-preparation-algorithm
FloatRect glyph_bounds;
- double real_width = font.Width(text_run, nullptr, &glyph_bounds);
+ String text16 = text;
+ text16.Ensure16Bit();
+ NGBidiParagraph bidi;
+ bidi.SetParagraph(text16, direction);
+ NGBidiParagraph::Runs runs;
+ bidi.GetLogicalRuns(text16, &runs);
+ float xpos = 0;
+ for (const auto& run : runs) {
+ // Measure each run.
+ TextRun text_run(
+ StringView(text, run.start, run.Length()), xpos, /* expansion */ 0,
+ TextRun::kAllowTrailingExpansion | TextRun::kForbidLeadingExpansion,
+ run.Direction(), /* directional_override */ false);
+ text_run.SetNormalizeSpace(true);
+ FloatRect run_glyph_bounds;
+ float run_width = font.Width(text_run, nullptr, &run_glyph_bounds);
+
+ // Accumulate the position and the glyph bounding box.
+ run_glyph_bounds.Move(xpos, 0);
+ glyph_bounds.Unite(run_glyph_bounds);
+ xpos += run_width;
+ }
+ double real_width = xpos;
+#if DCHECK_IS_ON()
+ // This DCHECK is for limited time only; to use |glyph_bounds| instead of
+ // |BoundingBox| and make sure they are compatible.
+ if (runs.size() == 1 && direction == runs[0].Direction()) {
+ FloatRect bbox = font.BoundingBox(text_run);
+ // |GetCharacterRange|, the underlying function of |BoundingBox|, clamps
+ // negative |MaxY| to 0. This is unintentional, and that we are not copying
+ // the behavior.
+ DCHECK_EQ(bbox.Y(), std::min(glyph_bounds.Y(), .0f));
+ DCHECK_EQ(bbox.MaxY(), std::max(glyph_bounds.MaxY(), .0f));
+ DCHECK_EQ(bbox.Width(), real_width);
+ }
+#endif
+ width_ = real_width;
float dx = 0.0f;
if (align == kCenterTextAlign)
@@ -89,13 +126,14 @@ void TextMetrics::Update(const Font& font,
actual_bounding_box_right_ = glyph_bounds.MaxX() - dx;
// y direction
+ const FontMetrics& font_metrics = font_data->GetFontMetrics();
const float ascent = font_metrics.FloatAscent();
const float descent = font_metrics.FloatDescent();
const float baseline_y = GetFontBaseline(baseline, *font_data);
font_bounding_box_ascent_ = ascent - baseline_y;
font_bounding_box_descent_ = descent + baseline_y;
- actual_bounding_box_ascent_ = -bbox.Y() - baseline_y;
- actual_bounding_box_descent_ = bbox.MaxY() + baseline_y;
+ actual_bounding_box_ascent_ = -glyph_bounds.Y() - baseline_y;
+ actual_bounding_box_descent_ = glyph_bounds.MaxY() + baseline_y;
em_height_ascent_ = font_data->EmHeightAscent() - baseline_y;
em_height_descent_ = font_data->EmHeightDescent() + baseline_y;
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.h b/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.h
index 2a3529a53e7..74625069b36 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.h
+++ b/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.h
@@ -62,7 +62,7 @@ class CORE_EXPORT TextMetrics final : public ScriptWrappable {
static float GetFontBaseline(const TextBaseline&, const SimpleFontData&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void Update(const Font&,
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/ukm_parameters.h b/chromium/third_party/blink/renderer/core/html/canvas/ukm_parameters.h
new file mode 100644
index 00000000000..fad8e38b0aa
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/canvas/ukm_parameters.h
@@ -0,0 +1,20 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_UKM_PARAMETERS_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_UKM_PARAMETERS_H_
+
+#include "services/metrics/public/cpp/ukm_recorder.h"
+#include "services/metrics/public/cpp/ukm_source_id.h"
+
+namespace blink {
+
+struct UkmParameters {
+ ukm::UkmRecorder* ukm_recorder;
+ ukm::SourceId source_id;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_UKM_PARAMETERS_H_
diff --git a/chromium/third_party/blink/renderer/core/html/collection_items_cache.h b/chromium/third_party/blink/renderer/core/html/collection_items_cache.h
index c311e300c62..2617e33ed7c 100644
--- a/chromium/third_party/blink/renderer/core/html/collection_items_cache.h
+++ b/chromium/third_party/blink/renderer/core/html/collection_items_cache.h
@@ -47,7 +47,7 @@ class CollectionItemsCache : public CollectionIndexCache<Collection, NodeType> {
CollectionItemsCache();
~CollectionItemsCache();
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(cached_list_);
Base::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element.cc
index eeca328bf00..4992ea23f77 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element.cc
@@ -158,7 +158,8 @@ Element* CustomElement::CreateUncustomizedOrUndefinedElementTemplate(
}
Element* element;
- if (RuntimeEnabledFeatures::CustomElementsV0Enabled(&document)) {
+ if (RuntimeEnabledFeatures::CustomElementsV0Enabled(
+ document.GetExecutionContext())) {
if (V0CustomElement::IsValidName(tag_name.LocalName()) &&
document.RegistrationContext()) {
element = document.RegistrationContext()->CreateCustomTagElement(
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.cc
index 3c4b80f4433..75d40046346 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.cc
@@ -40,7 +40,7 @@ CustomElementDefinition::CustomElementDefinition(
CustomElementDefinition::~CustomElementDefinition() = default;
-void CustomElementDefinition::Trace(Visitor* visitor) {
+void CustomElementDefinition::Trace(Visitor* visitor) const {
visitor->Trace(construction_stack_);
visitor->Trace(default_style_sheets_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.h
index 4df21e145c3..26b288b56ce 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.h
@@ -42,7 +42,7 @@ class CORE_EXPORT CustomElementDefinition
virtual ~CustomElementDefinition();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override {
return "CustomElementDefinition";
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.cc
index dd88199be20..e7d7109daa4 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.cc
@@ -12,7 +12,7 @@ CustomElementReaction::CustomElementReaction(
CustomElementDefinition& definition)
: definition_(definition) {}
-void CustomElementReaction::Trace(Visitor* visitor) {
+void CustomElementReaction::Trace(Visitor* visitor) const {
visitor->Trace(definition_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.h
index d3f60588e0c..59c30538f23 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.h
@@ -22,7 +22,7 @@ class CORE_EXPORT CustomElementReaction
virtual void Invoke(Element&) = 0;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
protected:
Member<CustomElementDefinition> definition_;
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.cc
index 859dd263529..b0a62d6677e 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.cc
@@ -79,7 +79,7 @@ class CustomElementAdoptedCallbackReaction final
DCHECK(definition.HasAdoptedCallback());
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(old_owner_);
visitor->Trace(new_owner_);
CustomElementReaction::Trace(visitor);
@@ -138,7 +138,7 @@ class CustomElementFormAssociatedCallbackReaction final
DCHECK(definition.HasFormAssociatedCallback());
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(form_);
CustomElementReaction::Trace(visitor);
}
@@ -206,7 +206,7 @@ class CustomElementFormStateRestoreCallbackReaction final
DCHECK(mode == "restore" || mode == "autocomplete");
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(value_);
CustomElementReaction::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.cc
index 0f7c3ea14c1..1e78556eabe 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.cc
@@ -14,7 +14,7 @@ CustomElementReactionQueue::CustomElementReactionQueue() : index_(0u) {}
CustomElementReactionQueue::~CustomElementReactionQueue() = default;
-void CustomElementReactionQueue::Trace(Visitor* visitor) {
+void CustomElementReactionQueue::Trace(Visitor* visitor) const {
visitor->Trace(reactions_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.h
index 34dfc38337b..383236bc063 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.h
@@ -20,7 +20,7 @@ class CORE_EXPORT CustomElementReactionQueue final
CustomElementReactionQueue();
~CustomElementReactionQueue();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void Add(CustomElementReaction&);
void InvokeReactions(Element&);
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.cc
index 990283baa64..828b7c84da8 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.cc
@@ -28,7 +28,7 @@ Persistent<CustomElementReactionStack>& GetCustomElementReactionStack() {
CustomElementReactionStack::CustomElementReactionStack() = default;
-void CustomElementReactionStack::Trace(Visitor* visitor) {
+void CustomElementReactionStack::Trace(Visitor* visitor) const {
visitor->Trace(map_);
visitor->Trace(stack_);
visitor->Trace(backup_queue_);
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.h
index 9b10239b270..44b6a986005 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.h
@@ -23,7 +23,7 @@ class CORE_EXPORT CustomElementReactionStack final
public:
CustomElementReactionStack();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override {
return "CustomElementReactionStack";
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack_test.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack_test.cc
index 7bfb1712cfe..b3a8d86dab5 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack_test.cc
@@ -192,7 +192,7 @@ class EnqueueToStack : public Command {
CustomElementReaction* reaction)
: stack_(stack), element_(element), reaction_(reaction) {}
~EnqueueToStack() override = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
Command::Trace(visitor);
visitor->Trace(stack_);
visitor->Trace(element_);
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_test_helpers.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_test_helpers.h
index 6450df0d6ec..ee3a1291d03 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_test_helpers.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_test_helpers.h
@@ -26,7 +26,7 @@ class Command : public GarbageCollected<Command> {
public:
Command() = default;
virtual ~Command() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
virtual void Run(Element&) = 0;
DISALLOW_COPY_AND_ASSIGN(Command);
@@ -74,7 +74,7 @@ class Recurse : public Command {
public:
Recurse(CustomElementReactionQueue* queue) : queue_(queue) {}
~Recurse() override = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
Command::Trace(visitor);
visitor->Trace(queue_);
}
@@ -91,7 +91,7 @@ class Enqueue : public Command {
Enqueue(CustomElementReactionQueue* queue, CustomElementReaction* reaction)
: queue_(queue), reaction_(reaction) {}
~Enqueue() override = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
Command::Trace(visitor);
visitor->Trace(queue_);
visitor->Trace(reaction_);
@@ -113,7 +113,7 @@ class TestReaction : public CustomElementReaction {
CustomElementDescriptor("mock-element", "mock-element"))),
commands_(commands) {}
~TestReaction() override = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
CustomElementReaction::Trace(visitor);
visitor->Trace(commands_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.cc
index f1579312558..1bf7934ec3d 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.cc
@@ -87,7 +87,7 @@ CustomElementRegistry::CustomElementRegistry(const LocalDOMWindow* owner)
Entangle(v0);
}
-void CustomElementRegistry::Trace(Visitor* visitor) {
+void CustomElementRegistry::Trace(Visitor* visitor) const {
visitor->Trace(definitions_);
visitor->Trace(owner_);
visitor->Trace(v0_);
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.h
index 3c959f93747..9f4d9ef6145 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.h
@@ -62,7 +62,7 @@ class CORE_EXPORT CustomElementRegistry final : public ScriptWrappable {
void Entangle(V0CustomElementRegistrationContext*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
CustomElementDefinition* DefineInternal(ScriptState*,
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry_test.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry_test.cc
index c50d69d521f..2696ad7e5f9 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry_test.cc
@@ -78,7 +78,7 @@ TEST_F(CustomElementRegistryTest,
Element* element = CreateElement("a-a").InDocument(&GetDocument());
Registry().AddCandidate(*element);
- auto* other_document = MakeGarbageCollected<HTMLDocument>();
+ auto* other_document = HTMLDocument::CreateForTest();
other_document->AppendChild(element);
EXPECT_EQ(other_document, element->ownerDocument())
<< "sanity: another document should have adopted an element on append";
@@ -173,7 +173,7 @@ class LogUpgradeDefinition : public TestCustomElementDefinition {
},
{}) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
TestCustomElementDefinition::Trace(visitor);
visitor->Trace(element_);
visitor->Trace(adopted_);
@@ -205,7 +205,7 @@ class LogUpgradeDefinition : public TestCustomElementDefinition {
Member<Document> old_owner_;
Member<Document> new_owner_;
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(old_owner_);
visitor->Trace(new_owner_);
}
@@ -398,7 +398,7 @@ TEST_F(CustomElementRegistryTest, adoptedCallback) {
static_cast<LogUpgradeDefinition*>(Registry().DefinitionForName("a-a"));
definition->Clear();
- auto* other_document = MakeGarbageCollected<HTMLDocument>();
+ auto* other_document = HTMLDocument::CreateForTest();
{
CEReactionsScope reactions;
other_document->adoptNode(element, ASSERT_NO_EXCEPTION);
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h
index 915324b0e8b..03a18e0f77b 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h
@@ -154,7 +154,7 @@ class CreateElement {
operator Element*() const {
Document* document = document_;
if (!document)
- document = MakeGarbageCollected<HTMLDocument>();
+ document = HTMLDocument::CreateForTest();
NonThrowableExceptionState no_exceptions;
Element* element = document->CreateElement(
QualifiedName(g_null_atom, local_name_, namespace_uri_),
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter_test.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter_test.cc
index f82ce78f372..924c2b38c7c 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter_test.cc
@@ -43,7 +43,7 @@ TEST_F(CustomElementUpgradeSorterTest, inOtherDocument_notInSet) {
Element* element = GetDocument().CreateElementForBinding(
"a-a", StringOrElementCreationOptions(), no_exceptions);
- auto* other_document = MakeGarbageCollected<HTMLDocument>();
+ auto* other_document = HTMLDocument::CreateForTest();
other_document->AppendChild(element);
EXPECT_EQ(other_document, element->ownerDocument())
<< "sanity: another document should have adopted an element on append";
diff --git a/chromium/third_party/blink/renderer/core/html/custom/element_internals.cc b/chromium/third_party/blink/renderer/core/html/custom/element_internals.cc
index 731e5ebcad3..e879e1fbb08 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/element_internals.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/element_internals.cc
@@ -49,7 +49,7 @@ class CustomStatesTokenList : public DOMTokenList {
ElementInternals::ElementInternals(HTMLElement& target) : target_(target) {
}
-void ElementInternals::Trace(Visitor* visitor) {
+void ElementInternals::Trace(Visitor* visitor) const {
visitor->Trace(target_);
visitor->Trace(value_);
visitor->Trace(state_);
diff --git a/chromium/third_party/blink/renderer/core/html/custom/element_internals.h b/chromium/third_party/blink/renderer/core/html/custom/element_internals.h
index 18519174b08..4f2effbb1e7 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/element_internals.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/element_internals.h
@@ -25,7 +25,7 @@ class CORE_EXPORT ElementInternals : public ScriptWrappable,
public:
ElementInternals(HTMLElement& target);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
HTMLElement& Target() const { return *target_; }
void DidUpgrade();
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.cc
index 08aa4240504..3b91ebaa6a9 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.cc
@@ -48,8 +48,8 @@ V0CustomElementMicrotaskImportStep* V0CustomElement::DidCreateImport(
return V0CustomElementScheduler::ScheduleImport(import);
}
-void V0CustomElement::DidFinishLoadingImport(Document& master) {
- master.CustomElementMicrotaskRunQueue()->RequestDispatchIfNeeded();
+void V0CustomElement::DidFinishLoadingImport(Document& tree_root) {
+ tree_root.CustomElementMicrotaskRunQueue()->RequestDispatchIfNeeded();
}
static inline bool IsValidNCName(const AtomicString& name) {
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.h
index 3fffa8901fd..0c3e255a3ae 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.h
@@ -52,7 +52,7 @@ class CORE_EXPORT V0CustomElement {
// API to notify of document-level changes
static V0CustomElementMicrotaskImportStep* DidCreateImport(HTMLImportChild*);
- static void DidFinishLoadingImport(Document& master);
+ static void DidFinishLoadingImport(Document& tree_root);
// API for registration contexts
static void Define(Element*, V0CustomElementDefinition*);
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.cc
index 8550ba58cb0..47cb0add209 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.cc
@@ -145,7 +145,7 @@ V0CustomElementCallbackInvocation::CreateAttributeChangedInvocation(
old_value, new_value);
}
-void V0CustomElementCallbackInvocation::Trace(Visitor* visitor) {
+void V0CustomElementCallbackInvocation::Trace(Visitor* visitor) const {
visitor->Trace(callbacks_);
V0CustomElementProcessingStep::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.h
index 23e40003a9d..3250a3a330e 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.h
@@ -56,7 +56,7 @@ class V0CustomElementCallbackInvocation : public V0CustomElementProcessingStep {
V0CustomElementLifecycleCallbacks* Callbacks() { return callbacks_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<V0CustomElementLifecycleCallbacks> callbacks_;
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.cc
index 4bdeeaee120..0a9718ddad8 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.cc
@@ -68,7 +68,7 @@ bool V0CustomElementCallbackQueue::ProcessInElementQueue(
return did_work;
}
-void V0CustomElementCallbackQueue::Trace(Visitor* visitor) {
+void V0CustomElementCallbackQueue::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(queue_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.h
index 2ab98cd078f..22290f77bd3 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.h
@@ -63,7 +63,7 @@ class V0CustomElementCallbackQueue
}
bool InCreatedCallback() const { return in_created_callback_; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<Element> element_;
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.cc
index e8b8a80ae74..1795303dde1 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.cc
@@ -37,7 +37,7 @@ V0CustomElementDefinition::V0CustomElementDefinition(
V0CustomElementLifecycleCallbacks* callbacks)
: descriptor_(descriptor), callbacks_(callbacks) {}
-void V0CustomElementDefinition::Trace(Visitor* visitor) {
+void V0CustomElementDefinition::Trace(Visitor* visitor) const {
visitor->Trace(callbacks_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h
index 79b5530aac3..a5af9378ace 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h
@@ -47,7 +47,7 @@ class V0CustomElementDefinition final
return callbacks_.Get();
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
V0CustomElementDescriptor descriptor_;
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_exception.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_exception.cc
index e199eaadd23..d321126ef9f 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_exception.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_exception.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/html/custom/v0_custom_element_exception.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h
index ea4407a710e..06190fc0ea2 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h
@@ -61,7 +61,7 @@ class V0CustomElementLifecycleCallbacks
const AtomicString& old_value,
const AtomicString& new_value) = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
explicit V0CustomElementLifecycleCallbacks(CallbackType type)
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.cc
index fe023ce0db4..1c781204b72 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.cc
@@ -76,7 +76,7 @@ void V0CustomElementMicrotaskDispatcher::DoDispatch() {
phase_ = kQuiescent;
}
-void V0CustomElementMicrotaskDispatcher::Trace(Visitor* visitor) {
+void V0CustomElementMicrotaskDispatcher::Trace(Visitor* visitor) const {
visitor->Trace(elements_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.h
index 9aa1567285a..0eed206c421 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.h
@@ -24,7 +24,7 @@ class V0CustomElementMicrotaskDispatcher final
bool ElementQueueIsEmpty() { return elements_.IsEmpty(); }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void EnsureMicrotaskScheduledForElementQueue();
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.cc
index f4025118dc0..fcf21c00af0 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.cc
@@ -70,7 +70,7 @@ V0CustomElementMicrotaskImportStep::Process() {
return kFinishedProcessing;
}
-void V0CustomElementMicrotaskImportStep::Trace(Visitor* visitor) {
+void V0CustomElementMicrotaskImportStep::Trace(Visitor* visitor) const {
visitor->Trace(import_);
visitor->Trace(queue_);
V0CustomElementMicrotaskStep::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.h
index c4c7efb9f29..566af67cfb2 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.h
@@ -55,7 +55,7 @@ class V0CustomElementMicrotaskImportStep final
void Invalidate();
void ImportDidFinishLoading();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DidUpgradeAllCustomElements();
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.cc
index f043853f4df..25efaad36df 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.cc
@@ -15,7 +15,7 @@ void V0CustomElementMicrotaskQueueBase::Dispatch() {
in_dispatch_ = false;
}
-void V0CustomElementMicrotaskQueueBase::Trace(Visitor* visitor) {
+void V0CustomElementMicrotaskQueueBase::Trace(Visitor* visitor) const {
visitor->Trace(queue_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.h
index 8855eee71d8..da4c6f039b6 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.h
@@ -20,7 +20,7 @@ class V0CustomElementMicrotaskQueueBase
bool IsEmpty() const { return queue_.IsEmpty(); }
void Dispatch();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
#if !defined(NDEBUG)
void Show(unsigned indent);
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc
index 22b212dbb61..f0a9f551f81 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc
@@ -50,7 +50,7 @@ V0CustomElementMicrotaskResolutionStep::Process() {
return V0CustomElementMicrotaskStep::kFinishedProcessing;
}
-void V0CustomElementMicrotaskResolutionStep::Trace(Visitor* visitor) {
+void V0CustomElementMicrotaskResolutionStep::Trace(Visitor* visitor) const {
visitor->Trace(context_);
visitor->Trace(element_);
V0CustomElementMicrotaskStep::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h
index 2d28a2dcb85..5288b6f9562 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h
@@ -48,7 +48,7 @@ class V0CustomElementMicrotaskResolutionStep final
const V0CustomElementDescriptor&);
~V0CustomElementMicrotaskResolutionStep() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Result Process() override;
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.cc
index 5bc637f3a4c..20a96fef1b0 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.cc
@@ -42,7 +42,7 @@ void V0CustomElementMicrotaskRunQueue::RequestDispatchIfNeeded() {
dispatch_is_pending_ = true;
}
-void V0CustomElementMicrotaskRunQueue::Trace(Visitor* visitor) {
+void V0CustomElementMicrotaskRunQueue::Trace(Visitor* visitor) const {
visitor->Trace(sync_queue_);
visitor->Trace(async_queue_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.h
index b46ba996068..d6e3a8a6d06 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.h
@@ -25,7 +25,7 @@ class V0CustomElementMicrotaskRunQueue
void RequestDispatchIfNeeded();
bool IsEmpty() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void Dispatch();
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_step.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_step.h
index 27f49c78ef0..3da59d78f1e 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_step.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_step.h
@@ -46,7 +46,7 @@ class V0CustomElementMicrotaskStep
virtual Result Process() = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
#if !defined(NDEBUG)
virtual void Show(unsigned indent) = 0;
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_observer.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_observer.h
index 1c95d5febcd..c05ea7ddc78 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_observer.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_observer.h
@@ -46,7 +46,7 @@ class V0CustomElementObserver
// API for CustomElement to kick off notifications
static void NotifyElementWasDestroyed(Element*);
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
V0CustomElementObserver() = default;
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.cc
index 63e9648790b..627a3773747 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.cc
@@ -92,7 +92,7 @@ void V0CustomElementProcessingStack::Enqueue(
++element_queue_end_;
}
-void V0CustomElementProcessingStack::Trace(Visitor* visitor) {
+void V0CustomElementProcessingStack::Trace(Visitor* visitor) const {
visitor->Trace(flattened_processing_stack_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h
index 62717b7e79e..c932c36806d 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h
@@ -77,7 +77,7 @@ class CORE_EXPORT V0CustomElementProcessingStack
static V0CustomElementProcessingStack& Instance();
void Enqueue(V0CustomElementCallbackQueue*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// The start of the element queue on the top of the processing
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_step.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_step.h
index 64e2314be3e..23ff9aa87bb 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_step.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_step.h
@@ -45,7 +45,7 @@ class V0CustomElementProcessingStep
virtual void Dispatch(Element*) = 0;
virtual bool IsCreatedCallback() const { return false; }
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
DISALLOW_COPY_AND_ASSIGN(V0CustomElementProcessingStep);
};
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc
index fa37f647b30..07ba6362261 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc
@@ -178,7 +178,7 @@ void V0CustomElementRegistrationContext::SetV1(
registry_.SetV1(v1);
}
-void V0CustomElementRegistrationContext::Trace(Visitor* visitor) {
+void V0CustomElementRegistrationContext::Trace(Visitor* visitor) const {
visitor->Trace(candidates_);
visitor->Trace(registry_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h
index b810d5c081a..9e7baee49de 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h
@@ -65,7 +65,7 @@ class V0CustomElementRegistrationContext final
bool NameIsDefined(const AtomicString& name) const;
void SetV1(const CustomElementRegistry*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// Instance creation
void DidGiveTypeExtension(Element*, const AtomicString& type);
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.cc
index c613e26f294..9d4fb89945c 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.cc
@@ -141,7 +141,7 @@ bool V0CustomElementRegistry::V1NameIsDefined(const AtomicString& name) const {
return v1_.Get() && v1_->NameIsDefined(name);
}
-void V0CustomElementRegistry::Trace(Visitor* visitor) {
+void V0CustomElementRegistry::Trace(Visitor* visitor) const {
visitor->Trace(definitions_);
visitor->Trace(v1_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.h
index 477589e2fdf..8f43354c6af 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.h
@@ -51,7 +51,7 @@ class V0CustomElementRegistry final {
DISALLOW_NEW();
public:
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void DocumentWasDetached() { document_was_detached_ = true; }
protected:
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc
index 7e9edadcea2..91b860eba41 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc
@@ -149,11 +149,11 @@ void V0CustomElementScheduler::EnqueueMicrotaskStep(
Document& document,
V0CustomElementMicrotaskStep* step,
bool import_is_sync) {
- Document& master = document.ImportsController()
- ? *(document.ImportsController()->Master())
- : document;
- master.CustomElementMicrotaskRunQueue()->Enqueue(document.ImportLoader(),
- step, import_is_sync);
+ Document& tree_root = document.ImportsController()
+ ? *(document.ImportsController()->TreeRoot())
+ : document;
+ tree_root.CustomElementMicrotaskRunQueue()->Enqueue(document.ImportLoader(),
+ step, import_is_sync);
}
void V0CustomElementScheduler::CallbackDispatcherDidFinish() {
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.cc
index ee4ffdbb92e..28c5c0fc581 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.cc
@@ -85,7 +85,7 @@ V0CustomElementUpgradeCandidateMap::TakeUpgradeCandidatesFor(
return candidates;
}
-void V0CustomElementUpgradeCandidateMap::Trace(Visitor* visitor) {
+void V0CustomElementUpgradeCandidateMap::Trace(Visitor* visitor) const {
visitor->Trace(upgrade_candidates_);
visitor->Trace(unresolved_definitions_);
V0CustomElementObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.h
index b91c4ab656b..ee0232f17cb 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.h
@@ -53,7 +53,7 @@ class V0CustomElementUpgradeCandidateMap final
void Add(const V0CustomElementDescriptor&, Element*);
ElementSet* TakeUpgradeCandidatesFor(const V0CustomElementDescriptor&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void ElementWasDestroyed(Element*) override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.cc
index 793b040d25e..170107b5c91 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.cc
@@ -45,7 +45,7 @@ namespace blink {
BaseButtonInputType::BaseButtonInputType(HTMLInputElement& element)
: InputType(element), KeyboardClickableInputTypeView(element) {}
-void BaseButtonInputType::Trace(Visitor* visitor) {
+void BaseButtonInputType::Trace(Visitor* visitor) const {
KeyboardClickableInputTypeView::Trace(visitor);
InputType::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.h
index b048c471560..a4a409e6c2f 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.h
@@ -42,7 +42,7 @@ class BaseButtonInputType : public InputType,
USING_GARBAGE_COLLECTED_MIXIN(BaseButtonInputType);
public:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
using InputType::GetElement;
protected:
diff --git a/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc
index 93da5c3d371..d13e518a241 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc
@@ -42,7 +42,7 @@
namespace blink {
-void BaseCheckableInputType::Trace(Visitor* visitor) {
+void BaseCheckableInputType::Trace(Visitor* visitor) const {
InputTypeView::Trace(visitor);
InputType::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.h
index d9696d33e8b..4fc9dec87d3 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.h
@@ -41,7 +41,7 @@ class BaseCheckableInputType : public InputType, public InputTypeView {
USING_GARBAGE_COLLECTED_MIXIN(BaseCheckableInputType);
public:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
using InputType::GetElement;
protected:
diff --git a/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc b/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc
index d7eab0be39e..cfc7dc21375 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc
@@ -47,7 +47,7 @@ ChooserOnlyTemporalInputTypeView::~ChooserOnlyTemporalInputTypeView() {
DCHECK(!date_time_chooser_);
}
-void ChooserOnlyTemporalInputTypeView::Trace(Visitor* visitor) {
+void ChooserOnlyTemporalInputTypeView::Trace(Visitor* visitor) const {
visitor->Trace(input_type_);
visitor->Trace(date_time_chooser_);
InputTypeView::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.h b/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.h
index 5e6f0b64d04..86d74e64c87 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.h
@@ -44,7 +44,7 @@ class ChooserOnlyTemporalInputTypeView final
public:
ChooserOnlyTemporalInputTypeView(HTMLInputElement&, BaseTemporalInputType&);
~ChooserOnlyTemporalInputTypeView() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void CloseDateTimeChooser();
diff --git a/chromium/third_party/blink/renderer/core/html/forms/chooser_resource_loader.cc b/chromium/third_party/blink/renderer/core/html/forms/chooser_resource_loader.cc
index 466a24b1082..61f4faf8d04 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/chooser_resource_loader.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/chooser_resource_loader.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/html/forms/chooser_resource_loader.h"
+#include "base/notreached.h"
#include "build/build_config.h"
#include "third_party/blink/public/resources/grit/blink_resources.h"
#include "third_party/blink/renderer/platform/data_resource_helper.h"
diff --git a/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.cc b/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.cc
index ee7210927ea..953e576733a 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.cc
@@ -73,7 +73,7 @@ bool ClearButtonElement::IsClearButtonElement() const {
return true;
}
-void ClearButtonElement::Trace(Visitor* visitor) {
+void ClearButtonElement::Trace(Visitor* visitor) const {
visitor->Trace(clear_button_owner_);
HTMLDivElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.h b/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.h
index bcedfe36f09..c2ab150daf8 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.h
@@ -45,7 +45,7 @@ class ClearButtonElement final : public HTMLDivElement {
void RemoveClearButtonOwner() { clear_button_owner_ = nullptr; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DetachLayoutTree(bool performing_reattach) override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_chooser.h b/chromium/third_party/blink/renderer/core/html/forms/color_chooser.h
index 051e20a4bdd..07a22f69960 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/color_chooser.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/color_chooser.h
@@ -43,7 +43,7 @@ class CORE_EXPORT ColorChooser : public GarbageCollectedMixin {
public:
ColorChooser();
virtual ~ColorChooser();
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
// Call to update the selection in the UI. Used to reflect value changes made
// by JS.
diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_client.h b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_client.h
index 292e216ff7a..bf1f4190be7 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_client.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_client.h
@@ -46,7 +46,7 @@ class Element;
class CORE_EXPORT ColorChooserClient : public GarbageCollectedMixin {
public:
virtual ~ColorChooserClient();
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
// Called when a color is chosen by the user in the ColorChooser UI.
virtual void DidChooseColor(const Color&) = 0;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.cc b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.cc
index 5dc4c58a213..27ad8e3dd86 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.cc
@@ -63,7 +63,7 @@ ColorChooserPopupUIController::~ColorChooserPopupUIController() {
DCHECK(!popup_);
}
-void ColorChooserPopupUIController::Trace(Visitor* visitor) {
+void ColorChooserPopupUIController::Trace(Visitor* visitor) const {
visitor->Trace(chrome_client_);
visitor->Trace(eye_dropper_chooser_);
ColorChooserUIController::Trace(visitor);
@@ -102,7 +102,9 @@ void ColorChooserPopupUIController::WriteColorPickerDocument(
client_->ElementRectRelativeToViewport(), frame_->View());
PagePopupClient::AddString(
- "<!DOCTYPE html><head><meta charset='UTF-8'><style>\n", data);
+ "<!DOCTYPE html><head><meta charset='UTF-8'><meta name='color-scheme' "
+ "content='light dark'><style>\n",
+ data);
data->Append(ChooserResourceLoader::GetPickerCommonStyleSheet());
data->Append(ChooserResourceLoader::GetColorPickerStyleSheet());
PagePopupClient::AddString(
@@ -161,7 +163,9 @@ void ColorChooserPopupUIController::WriteColorSuggestionPickerDocument(
client_->ElementRectRelativeToViewport(), frame_->View());
PagePopupClient::AddString(
- "<!DOCTYPE html><head><meta charset='UTF-8'><style>\n", data);
+ "<!DOCTYPE html><head><meta charset='UTF-8'><meta name='color-scheme' "
+ "content='light dark'><style>\n",
+ data);
data->Append(ChooserResourceLoader::GetPickerCommonStyleSheet());
data->Append(ChooserResourceLoader::GetColorSuggestionPickerStyleSheet());
if (features::IsFormControlsRefreshEnabled())
@@ -225,6 +229,7 @@ void ColorChooserPopupUIController::SetValue(const String& value) {
void ColorChooserPopupUIController::DidClosePopup() {
popup_ = nullptr;
+ eye_dropper_chooser_.reset();
if (!chooser_)
EndChooser();
diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.h b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.h
index 0984c237224..62be6d5aee9 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.h
@@ -48,7 +48,7 @@ class CORE_EXPORT ColorChooserPopupUIController final
ChromeClient*,
blink::ColorChooserClient*);
~ColorChooserPopupUIController() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// ColorChooserUIController functions:
void OpenUI() override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.cc b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.cc
index 8bce77ac6c3..e94e4ff79df 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.cc
@@ -44,7 +44,7 @@ ColorChooserUIController::ColorChooserUIController(
ColorChooserUIController::~ColorChooserUIController() = default;
-void ColorChooserUIController::Trace(Visitor* visitor) {
+void ColorChooserUIController::Trace(Visitor* visitor) const {
visitor->Trace(receiver_);
visitor->Trace(frame_);
visitor->Trace(client_);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h
index bccebbd339f..dbc461c9ef3 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h
@@ -50,7 +50,7 @@ class CORE_EXPORT ColorChooserUIController
public:
ColorChooserUIController(LocalFrame*, blink::ColorChooserClient*);
~ColorChooserUIController() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Dispose();
diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/color_input_type.cc
index 75a2290469c..5a0bd274f8e 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/color_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/color_input_type.cc
@@ -80,7 +80,7 @@ ColorInputType::ColorInputType(HTMLInputElement& element)
ColorInputType::~ColorInputType() = default;
-void ColorInputType::Trace(Visitor* visitor) {
+void ColorInputType::Trace(Visitor* visitor) const {
visitor->Trace(chooser_);
KeyboardClickableInputTypeView::Trace(visitor);
ColorChooserClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/color_input_type.h
index 2e75cb058aa..e315fa14095 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/color_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/color_input_type.h
@@ -47,7 +47,7 @@ class ColorInputType final : public InputType,
public:
explicit ColorInputType(HTMLInputElement&);
~ColorInputType() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
using InputType::GetElement;
// ColorChooserClient implementation.
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser.h b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser.h
index 07cbacb625f..19416be49e2 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser.h
@@ -84,7 +84,7 @@ class CORE_EXPORT DateTimeChooser : public GarbageCollected<DateTimeChooser> {
// Returns a root AXObject in the DateTimeChooser if it's available.
virtual AXObject* RootAXObject() = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_client.h b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_client.h
index 7c65f22c8f8..d69e3911637 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_client.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_client.h
@@ -42,7 +42,7 @@ class Element;
class CORE_EXPORT DateTimeChooserClient : public GarbageCollectedMixin {
public:
virtual ~DateTimeChooserClient();
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
virtual Element& OwnerElement() const = 0;
// Called when user picked a value.
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc
index ca0dababf14..186015ed290 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc
@@ -69,7 +69,7 @@ DateTimeChooserImpl::DateTimeChooserImpl(
DateTimeChooserImpl::~DateTimeChooserImpl() = default;
-void DateTimeChooserImpl::Trace(Visitor* visitor) {
+void DateTimeChooserImpl::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(client_);
DateTimeChooser::Trace(visitor);
@@ -125,7 +125,7 @@ void DateTimeChooserImpl::WriteDocument(SharedBuffer* data) {
AddString(
"<!DOCTYPE html><head><meta charset='UTF-8'><meta name='color-scheme' "
- "content='light,dark'><style>\n",
+ "content='light dark'><style>\n",
data);
data->Append(ChooserResourceLoader::GetPickerCommonStyleSheet());
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.h b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.h
index 22bca47ad27..698916d4773 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.h
@@ -55,7 +55,7 @@ class CORE_EXPORT DateTimeChooserImpl final : public DateTimeChooser,
void EndChooser() override;
AXObject* RootAXObject() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// PagePopupClient functions:
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc b/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc
index a22fc3b2088..841b8313117 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc
@@ -540,7 +540,7 @@ DateTimeEditElement::DateTimeEditElement(Document& document,
DateTimeEditElement::~DateTimeEditElement() = default;
-void DateTimeEditElement::Trace(Visitor* visitor) {
+void DateTimeEditElement::Trace(Visitor* visitor) const {
visitor->Trace(fields_);
visitor->Trace(edit_control_owner_);
HTMLDivElement::Trace(visitor);
@@ -847,6 +847,13 @@ bool DateTimeEditElement::HasFocusedField() {
return FocusedFieldIndex() != kInvalidFieldIndex;
}
+void PopulateOnlyYearMonthDay(const DateComponents& date,
+ DateTimeFieldsState& date_time_fields_state) {
+ date_time_fields_state.SetYear(date.FullYear());
+ date_time_fields_state.SetMonth(date.Month() + 1);
+ date_time_fields_state.SetDayOfMonth(date.MonthDay());
+}
+
void DateTimeEditElement::SetOnlyYearMonthDay(const DateComponents& date) {
DCHECK_EQ(date.GetType(), DateComponents::kDate);
@@ -854,20 +861,13 @@ void DateTimeEditElement::SetOnlyYearMonthDay(const DateComponents& date) {
return;
DateTimeFieldsState date_time_fields_state = ValueAsDateTimeFieldsState();
- date_time_fields_state.SetYear(date.FullYear());
- date_time_fields_state.SetMonth(date.Month() + 1);
- date_time_fields_state.SetDayOfMonth(date.MonthDay());
+ PopulateOnlyYearMonthDay(date, date_time_fields_state);
SetValueAsDateTimeFieldsState(date_time_fields_state);
edit_control_owner_->EditControlValueChanged();
}
-void DateTimeEditElement::SetOnlyTime(const DateComponents& date) {
- DCHECK_EQ(date.GetType(), DateComponents::kTime);
-
- if (!edit_control_owner_)
- return;
-
- DateTimeFieldsState date_time_fields_state = ValueAsDateTimeFieldsState();
+void PopulateOnlyTime(const DateComponents& date,
+ DateTimeFieldsState& date_time_fields_state) {
date_time_fields_state.SetHour(date.Hour() % 12 ? date.Hour() % 12 : 12);
date_time_fields_state.SetMinute(date.Minute());
date_time_fields_state.SetSecond(date.Second());
@@ -875,6 +875,34 @@ void DateTimeEditElement::SetOnlyTime(const DateComponents& date) {
date_time_fields_state.SetAMPM(date.Hour() >= 12
? DateTimeFieldsState::kAMPMValuePM
: DateTimeFieldsState::kAMPMValueAM);
+}
+
+void DateTimeEditElement::SetOnlyTime(const DateComponents& date) {
+ DCHECK_EQ(date.GetType(), DateComponents::kTime);
+
+ if (!edit_control_owner_)
+ return;
+
+ DateTimeFieldsState date_time_fields_state = ValueAsDateTimeFieldsState();
+ PopulateOnlyTime(date, date_time_fields_state);
+ SetValueAsDateTimeFieldsState(date_time_fields_state);
+ edit_control_owner_->EditControlValueChanged();
+}
+
+void PopulateDateTimeLocal(const DateComponents& date,
+ DateTimeFieldsState& date_time_fields_state) {
+ PopulateOnlyYearMonthDay(date, date_time_fields_state);
+ PopulateOnlyTime(date, date_time_fields_state);
+}
+
+void DateTimeEditElement::SetDateTimeLocal(const DateComponents& date) {
+ DCHECK_EQ(date.GetType(), DateComponents::kDateTimeLocal);
+
+ if (!edit_control_owner_)
+ return;
+
+ DateTimeFieldsState date_time_fields_state = ValueAsDateTimeFieldsState();
+ PopulateDateTimeLocal(date, date_time_fields_state);
SetValueAsDateTimeFieldsState(date_time_fields_state);
edit_control_owner_->EditControlValueChanged();
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.h b/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.h
index b241d8d00df..2b34f4a6ecb 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.h
@@ -85,7 +85,7 @@ class DateTimeEditElement final : public HTMLDivElement,
DateTimeEditElement(Document&, EditControlOwner&);
~DateTimeEditElement() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void AddField(DateTimeFieldElement*);
bool AnyEditableFieldsHaveValues() const;
@@ -107,6 +107,7 @@ class DateTimeEditElement final : public HTMLDivElement,
void SetValueAsDateTimeFieldsState(const DateTimeFieldsState&);
void SetOnlyYearMonthDay(const DateComponents&);
void SetOnlyTime(const DateComponents&);
+ void SetDateTimeLocal(const DateComponents&);
void StepDown();
void StepUp();
String Value() const;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.cc b/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.cc
index 43011524c79..bad44bbb995 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.cc
@@ -48,7 +48,7 @@ DateTimeFieldElement::DateTimeFieldElement(Document& document,
DateTimeField type)
: HTMLSpanElement(document), field_owner_(&field_owner), type_(type) {}
-void DateTimeFieldElement::Trace(Visitor* visitor) {
+void DateTimeFieldElement::Trace(Visitor* visitor) const {
visitor->Trace(field_owner_);
HTMLSpanElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.h b/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.h
index 80abb99baa9..ba6b356d6d7 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.h
@@ -88,7 +88,7 @@ class DateTimeFieldElement : public HTMLSpanElement {
virtual void StepUp() = 0;
virtual String Value() const = 0;
virtual String VisibleValue() const = 0;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
DateTimeField Type() const;
static float ComputeTextWidth(const ComputedStyle&, const String&);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.cc b/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.cc
index 8ad4132abe3..59f7092213d 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.cc
@@ -39,25 +39,25 @@
namespace blink {
-static ui::mojom::TextInputType ToTextInputType(const AtomicString& source) {
+static ui::TextInputType ToTextInputType(const AtomicString& source) {
if (source == input_type_names::kDate)
- return ui::mojom::TextInputType::DATE;
+ return ui::TextInputType::TEXT_INPUT_TYPE_DATE;
if (source == input_type_names::kDatetime)
- return ui::mojom::TextInputType::TIME;
+ return ui::TextInputType::TEXT_INPUT_TYPE_TIME;
if (source == input_type_names::kDatetimeLocal)
- return ui::mojom::TextInputType::DATE_TIME_LOCAL;
+ return ui::TextInputType::TEXT_INPUT_TYPE_DATE_TIME_LOCAL;
if (source == input_type_names::kMonth)
- return ui::mojom::TextInputType::MONTH;
+ return ui::TextInputType::TEXT_INPUT_TYPE_MONTH;
if (source == input_type_names::kTime)
- return ui::mojom::TextInputType::TIME;
+ return ui::TextInputType::TEXT_INPUT_TYPE_TIME;
if (source == input_type_names::kWeek)
- return ui::mojom::TextInputType::WEEK;
- return ui::mojom::TextInputType::NONE;
+ return ui::TextInputType::TEXT_INPUT_TYPE_WEEK;
+ return ui::TextInputType::TEXT_INPUT_TYPE_NONE;
}
ExternalDateTimeChooser::~ExternalDateTimeChooser() = default;
-void ExternalDateTimeChooser::Trace(Visitor* visitor) {
+void ExternalDateTimeChooser::Trace(Visitor* visitor) const {
visitor->Trace(date_time_chooser_);
visitor->Trace(client_);
DateTimeChooser::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.h b/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.h
index af6ff3007cf..4a21bafce46 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.h
@@ -40,7 +40,7 @@ class CORE_EXPORT ExternalDateTimeChooser final : public DateTimeChooser {
public:
explicit ExternalDateTimeChooser(DateTimeChooserClient*);
~ExternalDateTimeChooser() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// |frame| must not be null.
void OpenDateTimeChooser(LocalFrame* frame, const DateTimeChooserParameters&);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser_test.cc b/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser_test.cc
index 4f705495a9b..52d4599de62 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser_test.cc
@@ -34,7 +34,7 @@ class TestDateTimeChooserClient final
explicit TestDateTimeChooserClient(Element* element) : element_(element) {}
~TestDateTimeChooserClient() override {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(element_);
visitor->Trace(date_time_chooser_);
DateTimeChooserClient::Trace(visitor);
@@ -62,7 +62,7 @@ class TestDateTimeChooserClient final
// when it's called twice because |client_| was already nullptr.
TEST_F(ExternalDateTimeChooserTest, EndChooserShouldNotCrash) {
ScopedInputMultipleFieldsUIForTest input_multiple_fields_ui(false);
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* element = document->CreateRawElement(html_names::kInputTag);
auto* client = MakeGarbageCollected<TestDateTimeChooserClient>(element);
auto* external_date_time_chooser =
diff --git a/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.cc b/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.cc
index 25090b9a149..6cd24053348 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.cc
@@ -65,7 +65,7 @@ ExternalPopupMenu::ExternalPopupMenu(LocalFrame& frame,
ExternalPopupMenu::~ExternalPopupMenu() = default;
-void ExternalPopupMenu::Trace(Visitor* visitor) {
+void ExternalPopupMenu::Trace(Visitor* visitor) const {
visitor->Trace(owner_element_);
visitor->Trace(local_frame_);
visitor->Trace(receiver_);
@@ -145,8 +145,9 @@ void ExternalPopupMenu::Show() {
}
void ExternalPopupMenu::DispatchEvent(TimerBase*) {
- WebLocalFrameImpl::FromFrame(local_frame_->LocalFrameRoot())
- ->FrameWidgetImpl()
+ static_cast<WebWidget*>(
+ WebLocalFrameImpl::FromFrame(local_frame_->LocalFrameRoot())
+ ->FrameWidgetImpl())
->HandleInputEvent(
blink::WebCoalescedInputEvent(*synthetic_event_, ui::LatencyInfo()));
synthetic_event_.reset();
@@ -268,10 +269,7 @@ void ExternalPopupMenu::GetPopupMenuInfo(
}
popup_item->enabled = !item_element.IsDisabledFormControl();
const ComputedStyle& style = *owner_element.ItemComputedStyle(item_element);
- popup_item->text_direction =
- style.Direction() == TextDirection::kLtr
- ? mojo_base::mojom::blink::TextDirection::LEFT_TO_RIGHT
- : mojo_base::mojom::blink::TextDirection::RIGHT_TO_LEFT;
+ popup_item->text_direction = ToBaseTextDirection(style.Direction());
popup_item->has_text_direction_override =
IsOverride(style.GetUnicodeBidi());
menu_items->push_back(std::move(popup_item));
diff --git a/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.h b/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.h
index c5429e05b96..5965d566bbe 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.h
@@ -69,7 +69,7 @@ class CORE_EXPORT ExternalPopupMenu final
static int ToPopupMenuItemIndex(int index, HTMLSelectElement&);
static int ToExternalPopupMenuItemIndex(int index, HTMLSelectElement&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// PopupMenu methods:
diff --git a/chromium/third_party/blink/renderer/core/html/forms/file_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/file_input_type.cc
index c6b772fcd4e..1a679c96be4 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/file_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/file_input_type.cc
@@ -75,7 +75,7 @@ FileInputType::FileInputType(HTMLInputElement& element)
KeyboardClickableInputTypeView(element),
file_list_(MakeGarbageCollected<FileList>()) {}
-void FileInputType::Trace(Visitor* visitor) {
+void FileInputType::Trace(Visitor* visitor) const {
visitor->Trace(file_list_);
KeyboardClickableInputTypeView::Trace(visitor);
InputType::Trace(visitor);
@@ -195,7 +195,7 @@ void FileInputType::HandleDOMActivateEvent(Event& event) {
params.requestor = document.Url();
UseCounter::Count(
- document, document.IsSecureContext()
+ document, GetElement().GetExecutionContext()->IsSecureContext()
? WebFeature::kInputTypeFileSecureOriginOpenChooser
: WebFeature::kInputTypeFileInsecureOriginOpenChooser);
chrome_client->OpenFileChooser(document.GetFrame(), NewFileChooser(params));
@@ -320,11 +320,11 @@ FileList* FileInputType::CreateFileList(const FileChooserFileInfoList& files,
}
void FileInputType::CountUsage() {
- Document* document = &GetElement().GetDocument();
- if (document->IsSecureContext())
- UseCounter::Count(*document, WebFeature::kInputTypeFileInsecureOrigin);
+ ExecutionContext* context = GetElement().GetExecutionContext();
+ if (context->IsSecureContext())
+ UseCounter::Count(context, WebFeature::kInputTypeFileInsecureOrigin);
else
- UseCounter::Count(*document, WebFeature::kInputTypeFileSecureOrigin);
+ UseCounter::Count(context, WebFeature::kInputTypeFileSecureOrigin);
}
void FileInputType::CreateShadowSubtree() {
diff --git a/chromium/third_party/blink/renderer/core/html/forms/file_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/file_input_type.h
index 425bf6b8226..8300e6bf3de 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/file_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/file_input_type.h
@@ -53,7 +53,7 @@ class CORE_EXPORT FileInputType final : public InputType,
public:
FileInputType(HTMLInputElement&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
using InputType::GetElement;
static Vector<String> FilesFromFormControlState(const FormControlState&);
static FileList* CreateFileList(const FileChooserFileInfoList& files,
diff --git a/chromium/third_party/blink/renderer/core/html/forms/file_input_type_test.cc b/chromium/third_party/blink/renderer/core/html/forms/file_input_type_test.cc
index ebbb62c3b57..f2ff1ab6c92 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/file_input_type_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/file_input_type_test.cc
@@ -63,7 +63,7 @@ TEST(FileInputTypeTest, createFileList) {
}
TEST(FileInputTypeTest, ignoreDroppedNonNativeFiles) {
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* input =
MakeGarbageCollected<HTMLInputElement>(*document, CreateElementFlags());
InputType* file_input = MakeGarbageCollected<FileInputType>(*input);
@@ -97,7 +97,7 @@ TEST(FileInputTypeTest, ignoreDroppedNonNativeFiles) {
}
TEST(FileInputTypeTest, setFilesFromPaths) {
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* input =
MakeGarbageCollected<HTMLInputElement>(*document, CreateElementFlags());
InputType* file_input = MakeGarbageCollected<FileInputType>(*input);
@@ -156,4 +156,44 @@ TEST(FileInputTypeTest, DropTouchesNoPopupOpeningObserver) {
// UnregisterPopupOpeningObserver() was not called.
}
+TEST(FileInputTypeTest, BeforePseudoCrash) {
+ std::unique_ptr<DummyPageHolder> page_holder =
+ std::make_unique<DummyPageHolder>(IntSize(800, 600));
+ Document& doc = page_holder->GetDocument();
+ doc.documentElement()->setInnerHTML(R"HTML(
+<style>
+.c6 {
+ zoom: 0.01;
+}
+
+.c6::first-letter {
+ position: fixed;
+ border-style: groove;
+}
+
+.c6::before {
+ content: 'c6';
+}
+
+.c7 {
+ zoom: 0.1;
+}
+
+.c7::first-letter {
+ position: fixed;
+ border-style: groove;
+}
+
+.c7::before {
+ content: 'c7';
+}
+
+</style>
+<input type=file class=c6>
+<input type=file class=c7>
+)HTML");
+ doc.View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
+ // The test passes if no CHECK failures and no null pointer dereferences.
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_controller.cc b/chromium/third_party/blink/renderer/core/html/forms/form_controller.cc
index 681786d2c40..bdec179ac44 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/form_controller.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/form_controller.cc
@@ -334,7 +334,7 @@ class FormKeyGenerator final : public GarbageCollected<FormKeyGenerator> {
public:
FormKeyGenerator() = default;
- void Trace(Visitor* visitor) { visitor->Trace(form_to_key_map_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(form_to_key_map_); }
const AtomicString& FormKey(const ListedElement&);
void WillDeleteForm(HTMLFormElement*);
@@ -427,7 +427,7 @@ void FormKeyGenerator::WillDeleteForm(HTMLFormElement* form) {
DocumentState::DocumentState(Document& document) : document_(document) {}
-void DocumentState::Trace(Visitor* visitor) {
+void DocumentState::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(control_list_);
}
@@ -499,7 +499,7 @@ FormController::FormController(Document& document)
FormController::~FormController() = default;
-void FormController::Trace(Visitor* visitor) {
+void FormController::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(document_state_);
visitor->Trace(form_key_generator_);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_controller.h b/chromium/third_party/blink/renderer/core/html/forms/form_controller.h
index d0d93844a8c..da0c9b63069 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/form_controller.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/form_controller.h
@@ -82,7 +82,7 @@ using SavedFormStateMap =
class CORE_EXPORT DocumentState final : public GarbageCollected<DocumentState> {
public:
DocumentState(Document& document);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
using ControlList = HeapVector<Member<ListedElement>, 64>;
void InvalidateControlList();
@@ -100,7 +100,7 @@ class CORE_EXPORT FormController final
public:
FormController(Document& document);
~FormController();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void InvalidateStatefulFormControlList();
// This should be called only by Document::FormElementsState().
diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_controller_test.cc b/chromium/third_party/blink/renderer/core/html/forms/form_controller_test.cc
index e54eefa6018..49990a51e9c 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/form_controller_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/form_controller_test.cc
@@ -16,7 +16,7 @@
namespace blink {
TEST(DocumentStateTest, ToStateVectorConnected) {
- auto& doc = *MakeGarbageCollected<Document>();
+ auto& doc = *Document::CreateForTest();
Element* html = doc.CreateRawElement(html_names::kHTMLTag);
doc.appendChild(html);
Node* body = html->appendChild(doc.CreateRawElement(html_names::kBodyTag));
diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_data.cc b/chromium/third_party/blink/renderer/core/html/forms/form_data.cc
index 1918cac770a..1eb941afd6e 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/form_data.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/form_data.cc
@@ -71,7 +71,7 @@ class FormDataIterationSource final
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(form_data_);
PairIterable<String, FormDataEntryValue>::IterationSource::Trace(visitor);
}
@@ -111,7 +111,7 @@ FormData* FormData::Create(HTMLFormElement* form,
return MakeGarbageCollected<FormData>(*form_data);
}
-void FormData::Trace(Visitor* visitor) {
+void FormData::Trace(Visitor* visitor) const {
visitor->Trace(entries_);
ScriptWrappable::Trace(visitor);
}
@@ -340,7 +340,7 @@ FormData::Entry::Entry(const String& name, Blob* blob, const String& filename)
<< "'name' should be a USVString.";
}
-void FormData::Entry::Trace(Visitor* visitor) {
+void FormData::Entry::Trace(Visitor* visitor) const {
visitor->Trace(blob_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_data.h b/chromium/third_party/blink/renderer/core/html/forms/form_data.h
index 4ebb24e3bc1..432592529c6 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/form_data.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/form_data.h
@@ -66,7 +66,7 @@ class CORE_EXPORT FormData final
// doesn't clone entries in it because they are immutable.
FormData(const FormData& form_data);
FormData();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// FormData IDL interface.
void append(const String& name, const String& value);
@@ -123,7 +123,7 @@ class FormData::Entry final : public GarbageCollected<FormData::Entry> {
public:
Entry(const String& name, const String& value);
Entry(const String& name, Blob* blob, const String& filename);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
bool IsString() const { return !blob_; }
bool isFile() const { return blob_; }
diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_data_event.cc b/chromium/third_party/blink/renderer/core/html/forms/form_data_event.cc
index 3e1d9bf0d70..6f5fac010fd 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/form_data_event.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/form_data_event.cc
@@ -32,7 +32,7 @@ FormDataEvent* FormDataEvent::Create(const AtomicString& type,
return MakeGarbageCollected<FormDataEvent>(type, event_init);
}
-void FormDataEvent::Trace(Visitor* visitor) {
+void FormDataEvent::Trace(Visitor* visitor) const {
visitor->Trace(form_data_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_data_event.h b/chromium/third_party/blink/renderer/core/html/forms/form_data_event.h
index 3d0682353e3..6a0c1adef61 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/form_data_event.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/form_data_event.h
@@ -22,7 +22,7 @@ class FormDataEvent : public Event {
FormDataEvent(FormData& form_data);
FormDataEvent(const AtomicString& type, const FormDataEventInit* event_init);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
FormData* formData() const { return form_data_; }
diff --git a/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.cc
index f8fef662ad8..76a13e9e3c5 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.cc
@@ -46,7 +46,7 @@ void HiddenInputType::CountUsage() {
UseCounter::Count(GetElement().GetDocument(), WebFeature::kInputTypeHidden);
}
-void HiddenInputType::Trace(Visitor* visitor) {
+void HiddenInputType::Trace(Visitor* visitor) const {
InputTypeView::Trace(visitor);
InputType::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.h
index 5e211f67c15..1dd0ed6f47e 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.h
@@ -43,7 +43,7 @@ class HiddenInputType final : public InputType, private InputTypeView {
HiddenInputType(HTMLInputElement& element)
: InputType(element), InputTypeView(element) {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
using InputType::GetElement;
private:
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
index 7ef8db7a852..2afea2e1228 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
@@ -53,7 +53,7 @@ HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tag_name,
HTMLFormControlElement::~HTMLFormControlElement() = default;
-void HTMLFormControlElement::Trace(Visitor* visitor) {
+void HTMLFormControlElement::Trace(Visitor* visitor) const {
ListedElement::Trace(visitor);
HTMLElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.h
index 62c7a77395e..cdf5b4831bc 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.h
@@ -47,7 +47,7 @@ class CORE_EXPORT HTMLFormControlElement : public HTMLElement,
public:
~HTMLFormControlElement() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
String formAction() const;
void setFormAction(const AtomicString&);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc
index db9caa6e8b2..32c40dd71cb 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc
@@ -45,7 +45,7 @@ class MockFormValidationMessageClient
void DocumentDetached(const Document&) override {}
void DidChangeFocusTo(const Element*) override {}
void WillBeDestroyed() override {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(anchor_);
ValidationMessageClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.cc b/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.cc
index 6be7461d61c..86e78a22572 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.cc
@@ -221,7 +221,7 @@ void HTMLFormControlsCollection::SupportedPropertyNames(Vector<String>& names) {
}
}
-void HTMLFormControlsCollection::Trace(Visitor* visitor) {
+void HTMLFormControlsCollection::Trace(Visitor* visitor) const {
visitor->Trace(cached_element_);
HTMLCollection::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.h b/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.h
index 684265f7b26..b85bc929905 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.h
@@ -54,7 +54,7 @@ class HTMLFormControlsCollection final : public HTMLCollection {
HTMLElement* namedItem(const AtomicString& name) const override;
void namedGetter(const AtomicString& name, RadioNodeListOrElement&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void UpdateIdNameCache() const override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_form_element.cc
index 7c149fb0f92..74e1751c345 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_form_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_element.cc
@@ -87,7 +87,7 @@ HTMLFormElement::HTMLFormElement(Document& document)
HTMLFormElement::~HTMLFormElement() = default;
-void HTMLFormElement::Trace(Visitor* visitor) {
+void HTMLFormElement::Trace(Visitor* visitor) const {
visitor->Trace(past_names_map_);
visitor->Trace(radio_button_group_scope_);
visitor->Trace(listed_elements_);
@@ -514,6 +514,11 @@ void HTMLFormElement::ScheduleFormSubmission(
// Cancel pending javascript url navigations for the target frame. This new
// form submission should take precedence over them.
target_local_frame->GetDocument()->CancelPendingJavaScriptUrls();
+
+ // Cancel any pre-existing attempt to navigate the target frame which was
+ // already sent to the browser process so this form submission will take
+ // precedence over it.
+ target_local_frame->Loader().CancelClientNavigation();
}
target_frame->ScheduleFormSubmission(scheduler, form_submission);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_form_element.h
index 620c05a3cc9..44e0c202fda 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_form_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_element.h
@@ -46,7 +46,7 @@ class CORE_EXPORT HTMLFormElement final : public HTMLElement {
public:
explicit HTMLFormElement(Document&);
~HTMLFormElement() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
HTMLFormControlsCollection* elements();
void GetNamedElements(const AtomicString&, HeapVector<Member<Element>>&);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_input_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_input_element.cc
index d5a4f05446e..31676cf8670 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_input_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_input_element.cc
@@ -91,7 +91,7 @@ class ListAttributeTargetObserver : public IdTargetObserver {
public:
ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void IdTargetChanged() override;
private:
@@ -135,7 +135,7 @@ HTMLInputElement::HTMLInputElement(Document& document,
}
}
-void HTMLInputElement::Trace(Visitor* visitor) {
+void HTMLInputElement::Trace(Visitor* visitor) const {
visitor->Trace(input_type_);
visitor->Trace(input_type_view_);
visitor->Trace(list_attribute_target_observer_);
@@ -775,8 +775,8 @@ void HTMLInputElement::ParseAttribute(
SetNeedsStyleRecalc(
kSubtreeStyleChange,
StyleChangeReasonForTracing::FromAttribute(html_names::kValueAttr));
+ needs_to_update_view_value_ = true;
}
- needs_to_update_view_value_ = true;
SetNeedsValidityCheck();
input_type_->WarnIfValueIsInvalidAndElementIsVisible(value);
input_type_->InRangeChanged();
@@ -1833,7 +1833,7 @@ ListAttributeTargetObserver::ListAttributeTargetObserver(
id),
element_(element) {}
-void ListAttributeTargetObserver::Trace(Visitor* visitor) {
+void ListAttributeTargetObserver::Trace(Visitor* visitor) const {
visitor->Trace(element_);
IdTargetObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_input_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_input_element.h
index e2b0b44ab88..ec5959ab37f 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_input_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_input_element.h
@@ -59,7 +59,7 @@ class CORE_EXPORT HTMLInputElement
public:
HTMLInputElement(Document&, const CreateElementFlags);
~HTMLInputElement() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool HasPendingActivity() const final;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_input_element_test.cc b/chromium/third_party/blink/renderer/core/html/forms/html_input_element_test.cc
index baa2c174681..3132d8f878a 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_input_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_input_element_test.cc
@@ -89,14 +89,14 @@ TEST_F(HTMLInputElementTest, create) {
EXPECT_NE(nullptr, input->UserAgentShadowRoot());
input = MakeGarbageCollected<HTMLInputElement>(
- GetDocument(), CreateElementFlags::ByParser());
+ GetDocument(), CreateElementFlags::ByParser(&GetDocument()));
EXPECT_EQ(nullptr, input->UserAgentShadowRoot());
input->ParserSetAttributes(Vector<Attribute>());
EXPECT_NE(nullptr, input->UserAgentShadowRoot());
}
TEST_F(HTMLInputElementTest, NoAssertWhenMovedInNewDocument) {
- auto* document_without_frame = MakeGarbageCollected<Document>();
+ auto* document_without_frame = Document::CreateForTest();
EXPECT_EQ(nullptr, document_without_frame->GetPage());
auto* html = MakeGarbageCollected<HTMLHtmlElement>(*document_without_frame);
html->AppendChild(
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_option_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_option_element.cc
index bce8b9e77da..c69ab0b118c 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_option_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_option_element.cc
@@ -26,8 +26,10 @@
#include "third_party/blink/renderer/core/html/forms/html_option_element.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mutation_observer_init.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/mutation_observer.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/node_traversal.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
@@ -44,6 +46,37 @@
namespace blink {
+class OptionTextObserver : public MutationObserver::Delegate {
+ public:
+ explicit OptionTextObserver(HTMLOptionElement& option)
+ : option_(option), observer_(MutationObserver::Create(this)) {
+ MutationObserverInit* init = MutationObserverInit::Create();
+ init->setCharacterData(true);
+ init->setChildList(true);
+ init->setSubtree(true);
+ observer_->observe(option_, init, ASSERT_NO_EXCEPTION);
+ }
+
+ ExecutionContext* GetExecutionContext() const override {
+ return option_->GetExecutionContext();
+ }
+
+ void Deliver(const MutationRecordVector& records,
+ MutationObserver&) override {
+ option_->DidChangeTextContent();
+ }
+
+ void Trace(Visitor* visitor) const override {
+ visitor->Trace(option_);
+ visitor->Trace(observer_);
+ MutationObserver::Delegate::Trace(visitor);
+ }
+
+ private:
+ Member<HTMLOptionElement> option_;
+ Member<MutationObserver> observer_;
+};
+
HTMLOptionElement::HTMLOptionElement(Document& document)
: HTMLElement(html_names::kOptionTag, document), is_selected_(false) {
EnsureUserAgentShadowRoot();
@@ -81,6 +114,11 @@ HTMLOptionElement* HTMLOptionElement::CreateForJSConstructor(
return element;
}
+void HTMLOptionElement::Trace(Visitor* visitor) const {
+ visitor->Trace(text_observer_);
+ HTMLElement::Trace(visitor);
+}
+
bool HTMLOptionElement::SupportsFocus() const {
HTMLSelectElement* select = OwnerSelectElement();
if (select && select->UsesMenuList())
@@ -280,6 +318,15 @@ void HTMLOptionElement::SetDirty(bool value) {
void HTMLOptionElement::ChildrenChanged(const ChildrenChange& change) {
HTMLElement::ChildrenChanged(change);
+ DidChangeTextContent();
+
+ // If an element is inserted, We need to use MutationObserver to detect
+ // textContent changes.
+ if (change.type == ChildrenChangeType::kElementInserted && !text_observer_)
+ text_observer_ = MakeGarbageCollected<OptionTextObserver>(*this);
+}
+
+void HTMLOptionElement::DidChangeTextContent() {
if (HTMLDataListElement* data_list = OwnerDataListElement())
data_list->OptionElementChildrenChanged();
else if (HTMLSelectElement* select = OwnerSelectElement())
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_option_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_option_element.h
index e895c8546f8..78a6f792afb 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_option_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_option_element.h
@@ -33,6 +33,7 @@ namespace blink {
class ExceptionState;
class HTMLDataListElement;
class HTMLSelectElement;
+class OptionTextObserver;
class CORE_EXPORT HTMLOptionElement final : public HTMLElement {
DEFINE_WRAPPERTYPEINFO();
@@ -53,6 +54,7 @@ class CORE_EXPORT HTMLOptionElement final : public HTMLElement {
ExceptionState&);
explicit HTMLOptionElement(Document&);
+ void Trace(Visitor* visitor) const override;
// A text to be shown to users. The difference from |label()| is |label()|
// returns an empty string if |label| content attribute is empty.
@@ -102,10 +104,13 @@ class CORE_EXPORT HTMLOptionElement final : public HTMLElement {
bool IsMultiSelectFocused() const;
void SetWasOptionInsertedCalled(bool flag) {
- was_option_inserted_called_ = true;
+ was_option_inserted_called_ = flag;
}
bool WasOptionInsertedCalled() const { return was_option_inserted_called_; }
+ // Callback for OptionTextObserver.
+ void DidChangeTextContent();
+
private:
~HTMLOptionElement() override;
@@ -122,6 +127,8 @@ class CORE_EXPORT HTMLOptionElement final : public HTMLElement {
void UpdateLabel();
+ Member<OptionTextObserver> text_observer_;
+
// Represents 'selectedness'.
// https://html.spec.whatwg.org/C/#concept-option-selectedness
bool is_selected_;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_output_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_output_element.cc
index f5da9a76bd8..7404831437e 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_output_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_output_element.cc
@@ -116,7 +116,7 @@ void HTMLOutputElement::setDefaultValue(const String& value) {
setTextContent(value);
}
-void HTMLOutputElement::Trace(Visitor* visitor) {
+void HTMLOutputElement::Trace(Visitor* visitor) const {
visitor->Trace(tokens_);
HTMLFormControlElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_output_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_output_element.h
index 58155db1465..6385fe3c19a 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_output_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_output_element.h
@@ -55,7 +55,7 @@ class CORE_EXPORT HTMLOutputElement final : public HTMLFormControlElement {
return is_default_value_mode_;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void ParseAttribute(const AttributeModificationParams&) override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_output_element_test.cc b/chromium/third_party/blink/renderer/core/html/forms/html_output_element_test.cc
index bd7c8df0d5d..7a6a561b7b9 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_output_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_output_element_test.cc
@@ -14,7 +14,7 @@ namespace blink {
TEST(HTMLLinkElementSizesAttributeTest,
setHTMLForProperty_updatesForAttribute) {
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* element = MakeGarbageCollected<HTMLOutputElement>(*document);
EXPECT_EQ(g_null_atom, element->FastGetAttribute(html_names::kForAttr));
element->htmlFor()->setValue(" strawberry ");
@@ -22,7 +22,7 @@ TEST(HTMLLinkElementSizesAttributeTest,
}
TEST(HTMLOutputElementTest, setForAttribute_updatesHTMLForPropertyValue) {
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* element = MakeGarbageCollected<HTMLOutputElement>(*document);
DOMTokenList* for_tokens = element->htmlFor();
EXPECT_EQ(g_null_atom, for_tokens->value());
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_select_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_select_element.cc
index bf5514858c6..80e83795058 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_select_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -50,7 +50,6 @@
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
#include "third_party/blink/renderer/core/html/forms/html_opt_group_element.h"
#include "third_party/blink/renderer/core/html/forms/html_option_element.h"
-#include "third_party/blink/renderer/core/html/forms/menu_list_inner_element.h"
#include "third_party/blink/renderer/core/html/forms/select_type.h"
#include "third_party/blink/renderer/core/html/html_hr_element.h"
#include "third_party/blink/renderer/core/html/html_slot_element.h"
@@ -230,9 +229,7 @@ int HTMLSelectElement::ActiveSelectionEndListIndex() const {
}
HTMLOptionElement* HTMLSelectElement::ActiveSelectionEnd() const {
- if (active_selection_end_)
- return active_selection_end_.Get();
- return LastSelectedOption();
+ return select_type_->ActiveSelectionEnd();
}
void HTMLSelectElement::add(
@@ -512,25 +509,6 @@ void HTMLSelectElement::SelectAll() {
select_type_->SelectAll();
}
-void HTMLSelectElement::SetActiveSelectionAnchor(HTMLOptionElement* option) {
- active_selection_anchor_ = option;
- select_type_->SaveListboxActiveSelection();
-}
-
-void HTMLSelectElement::SetActiveSelectionEnd(HTMLOptionElement* option) {
- active_selection_end_ = option;
-}
-
-void HTMLSelectElement::ScrollToSelection() {
- if (!IsFinishedParsingChildren())
- return;
- if (UsesMenuList())
- return;
- select_type_->ScrollToOption(ActiveSelectionEnd());
- if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache())
- cache->ListboxActiveIndexChanged(this);
-}
-
const HTMLSelectElement::ListItems& HTMLSelectElement::GetListItems() const {
if (should_recalc_list_items_) {
RecalcListItems();
@@ -789,10 +767,6 @@ void HTMLSelectElement::OptionRemoved(HTMLOptionElement& option) {
if (last_on_change_option_ == &option)
last_on_change_option_.Clear();
select_type_->OptionRemoved(option);
- if (active_selection_anchor_ == &option)
- active_selection_anchor_.Clear();
- if (active_selection_end_ == &option)
- active_selection_end_.Clear();
if (suggested_option_ == &option)
SetSuggestedOption(nullptr);
if (option.Selected())
@@ -846,18 +820,6 @@ void HTMLSelectElement::SelectOption(HTMLOptionElement* element,
if (flags & kDeselectOtherOptionsFlag)
should_update_popup |= DeselectItemsWithoutValidation(element);
- // We should update active selection after finishing OPTION state change
- // because setActiveSelectionAnchorIndex() stores OPTION's selection state.
- if (element) {
- // setActiveSelectionAnchor is O(N).
- if (!active_selection_anchor_ || !IsMultiple() ||
- flags & kDeselectOtherOptionsFlag)
- SetActiveSelectionAnchor(element);
- if (!active_selection_end_ || !IsMultiple() ||
- flags & kDeselectOtherOptionsFlag)
- SetActiveSelectionEnd(element);
- }
-
select_type_->DidSelectOption(element, flags, should_update_popup);
NotifyFormStateChanged();
@@ -1169,10 +1131,8 @@ void HTMLSelectElement::SelectOptionByAccessKey(HTMLOptionElement* option) {
SelectOption(option, flags);
}
option->SetDirty(true);
- if (UsesMenuList())
- return;
select_type_->ListBoxOnChange();
- ScrollToSelection();
+ select_type_->ScrollToSelection();
}
unsigned HTMLSelectElement::length() const {
@@ -1209,11 +1169,9 @@ bool HTMLSelectElement::IsInteractiveContent() const {
return true;
}
-void HTMLSelectElement::Trace(Visitor* visitor) {
+void HTMLSelectElement::Trace(Visitor* visitor) const {
visitor->Trace(list_items_);
visitor->Trace(last_on_change_option_);
- visitor->Trace(active_selection_anchor_);
- visitor->Trace(active_selection_end_);
visitor->Trace(suggested_option_);
visitor->Trace(select_type_);
HTMLFormControlElementWithState::Trace(visitor);
@@ -1241,30 +1199,15 @@ void HTMLSelectElement::UpdateUserAgentShadowTree(ShadowRoot& root) {
will_be_removed->remove();
}
}
- if (UsesMenuList()) {
- Element* inner_element =
- MakeGarbageCollected<MenuListInnerElement>(GetDocument());
- inner_element->setAttribute(html_names::kAriaHiddenAttr, "true");
- // Make sure InnerElement() always has a Text node.
- inner_element->appendChild(Text::Create(GetDocument(), g_empty_string));
- root.insertBefore(inner_element, root.firstChild());
- }
+ select_type_->CreateShadowSubtree(root);
}
Element& HTMLSelectElement::InnerElement() const {
- DCHECK(UsesMenuList());
- auto* inner_element = DynamicTo<Element>(UserAgentShadowRoot()->firstChild());
- DCHECK(inner_element);
- return *inner_element;
+ return select_type_->InnerElement();
}
HTMLOptionElement* HTMLSelectElement::SpatialNavigationFocusedOption() {
- if (!IsSpatialNavigationEnabled(GetDocument().GetFrame()))
- return nullptr;
- HTMLOptionElement* focused_option = ActiveSelectionEnd();
- if (!focused_option)
- focused_option = select_type_->FirstSelectableOption();
- return focused_option;
+ return select_type_->SpatialNavigationFocusedOption();
}
String HTMLSelectElement::ItemText(const Element& element) const {
@@ -1418,9 +1361,12 @@ void HTMLSelectElement::CloneNonAttributePropertiesFrom(
void HTMLSelectElement::ChangeRendering() {
select_type_->DidDetachLayoutTree();
+ bool old_uses_menu_list = UsesMenuList();
UpdateUsesMenuList();
- select_type_->WillBeDestroyed();
- select_type_ = SelectType::Create(*this);
+ if (UsesMenuList() != old_uses_menu_list) {
+ select_type_->WillBeDestroyed();
+ select_type_ = SelectType::Create(*this);
+ }
if (!InActiveDocument())
return;
// TODO(futhark): SetForceReattachLayoutTree() should be the correct way to
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_select_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_select_element.h
index eb28983c7ad..86570a11d94 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_select_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_select_element.h
@@ -122,14 +122,10 @@ class CORE_EXPORT HTMLSelectElement final
Element* namedItem(const AtomicString& name);
HTMLOptionElement* item(unsigned index);
- void ScrollToSelection();
-
bool CanSelectAll() const;
void SelectAll();
int ActiveSelectionEndListIndex() const;
HTMLOptionElement* ActiveSelectionEnd() const;
- void SetActiveSelectionAnchor(HTMLOptionElement*);
- void SetActiveSelectionEnd(HTMLOptionElement*);
// For use in the implementation of HTMLOptionElement.
void OptionSelectionStateChanged(HTMLOptionElement*, bool option_is_selected);
@@ -179,7 +175,7 @@ class CORE_EXPORT HTMLSelectElement final
bool HasNonInBodyInsertionMode() const override { return true; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void CloneNonAttributePropertiesFrom(const Element&,
CloneChildrenFlag) override;
@@ -285,8 +281,6 @@ class CORE_EXPORT HTMLSelectElement final
TypeAhead type_ahead_;
unsigned size_;
Member<HTMLOptionElement> last_on_change_option_;
- Member<HTMLOptionElement> active_selection_anchor_;
- Member<HTMLOptionElement> active_selection_end_;
Member<HTMLOptionElement> suggested_option_;
bool uses_menu_list_ = true;
bool is_multiple_;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_select_element_test.cc b/chromium/third_party/blink/renderer/core/html/forms/html_select_element_test.cc
index 9a0133c5b2d..2c7624c15f2 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_select_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_select_element_test.cc
@@ -394,8 +394,13 @@ TEST_F(HTMLSelectElementTest, PreviousSelectableOption) {
TEST_F(HTMLSelectElementTest, ActiveSelectionEndAfterOptionRemoval) {
SetHtmlInnerHTML(
- "<select><optgroup><option selected>o1</option></optgroup></select>");
+ "<select size=4>"
+ "<optgroup><option selected>o1</option></optgroup></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
+ // ActiveSelectionEnd*() work only in the listbox mode, which Android
+ // doesn't have.
+ if (select->UsesMenuList())
+ return;
auto* option = To<HTMLOptionElement>(select->firstChild()->firstChild());
EXPECT_EQ(1, select->ActiveSelectionEndListIndex());
select->firstChild()->removeChild(option);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/image_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/image_input_type.cc
index 53abd4c58ba..27f89ccb231 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/image_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/image_input_type.cc
@@ -38,6 +38,7 @@
#include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/layout_image.h"
+#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/layout_object_factory.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -110,8 +111,12 @@ bool ImageInputType::TypeShouldForceLegacyLayout() const {
LayoutObject* ImageInputType::CreateLayoutObject(const ComputedStyle& style,
LegacyLayout legacy) const {
- if (use_fallback_content_)
+ if (use_fallback_content_) {
+ if (style.Display() == EDisplay::kInline)
+ return new LayoutInline(&GetElement());
+
return LayoutObjectFactory::CreateBlockFlow(GetElement(), style, legacy);
+ }
LayoutImage* image = new LayoutImage(&GetElement());
image->SetImageResource(MakeGarbageCollected<LayoutImageResource>());
return image;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/input_type.cc
index dbe99ae5e5b..c3f2bd721f5 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/input_type.cc
@@ -77,113 +77,44 @@
namespace blink {
-using InputTypeFactoryFunction = InputType* (*)(HTMLInputElement&);
-using InputTypeFactoryMap = HashMap<AtomicString, InputTypeFactoryFunction>;
-
-static std::unique_ptr<InputTypeFactoryMap> CreateInputTypeFactoryMap() {
- std::unique_ptr<InputTypeFactoryMap> map =
- std::make_unique<InputTypeFactoryMap>();
- map->insert(input_type_names::kButton,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<ButtonInputType>(element);
- });
- map->insert(input_type_names::kCheckbox,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<CheckboxInputType>(element);
- });
- map->insert(input_type_names::kColor,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<ColorInputType>(element);
- });
- map->insert(input_type_names::kDate,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<DateInputType>(element);
- });
- map->insert(input_type_names::kDatetimeLocal,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<DateTimeLocalInputType>(element);
- });
- map->insert(input_type_names::kEmail,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<EmailInputType>(element);
- });
- map->insert(input_type_names::kFile,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<FileInputType>(element);
- });
- map->insert(input_type_names::kHidden,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<HiddenInputType>(element);
- });
- map->insert(input_type_names::kImage,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<ImageInputType>(element);
- });
- map->insert(input_type_names::kMonth,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<MonthInputType>(element);
- });
- map->insert(input_type_names::kNumber,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<NumberInputType>(element);
- });
- map->insert(input_type_names::kPassword,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<PasswordInputType>(element);
- });
- map->insert(input_type_names::kRadio,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<RadioInputType>(element);
- });
- map->insert(input_type_names::kRange,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<RangeInputType>(element);
- });
- map->insert(input_type_names::kReset,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<ResetInputType>(element);
- });
- map->insert(input_type_names::kSearch,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<SearchInputType>(element);
- });
- map->insert(input_type_names::kSubmit,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<SubmitInputType>(element);
- });
- map->insert(input_type_names::kTel,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<TelephoneInputType>(element);
- });
- map->insert(input_type_names::kTime,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<TimeInputType>(element);
- });
- map->insert(input_type_names::kUrl,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<URLInputType>(element);
- });
- map->insert(input_type_names::kWeek,
- [](HTMLInputElement& element) -> InputType* {
- return MakeGarbageCollected<WeekInputType>(element);
- });
- // No need to register "text" because it is the default type.
- return map;
-}
-
-static const InputTypeFactoryMap* FactoryMap() {
- static const InputTypeFactoryMap* factory_map =
- CreateInputTypeFactoryMap().release();
- return factory_map;
-}
+// Listed once to avoid any discrepancy between InputType::Create and
+// InputType::NormalizeTypeName.
+//
+// No need to register "text" because it is the default type.
+#define INPUT_TYPES(INPUT_TYPE) \
+ INPUT_TYPE(kButton, ButtonInputType) \
+ INPUT_TYPE(kCheckbox, CheckboxInputType) \
+ INPUT_TYPE(kColor, ColorInputType) \
+ INPUT_TYPE(kDate, DateInputType) \
+ INPUT_TYPE(kDatetimeLocal, DateTimeLocalInputType) \
+ INPUT_TYPE(kEmail, EmailInputType) \
+ INPUT_TYPE(kFile, FileInputType) \
+ INPUT_TYPE(kHidden, HiddenInputType) \
+ INPUT_TYPE(kImage, ImageInputType) \
+ INPUT_TYPE(kMonth, MonthInputType) \
+ INPUT_TYPE(kNumber, NumberInputType) \
+ INPUT_TYPE(kPassword, PasswordInputType) \
+ INPUT_TYPE(kRadio, RadioInputType) \
+ INPUT_TYPE(kRange, RangeInputType) \
+ INPUT_TYPE(kReset, ResetInputType) \
+ INPUT_TYPE(kSearch, SearchInputType) \
+ INPUT_TYPE(kSubmit, SubmitInputType) \
+ INPUT_TYPE(kTel, TelephoneInputType) \
+ INPUT_TYPE(kTime, TimeInputType) \
+ INPUT_TYPE(kUrl, URLInputType) \
+ INPUT_TYPE(kWeek, WeekInputType)
InputType* InputType::Create(HTMLInputElement& element,
const AtomicString& type_name) {
- InputTypeFactoryFunction factory =
- type_name.IsEmpty() ? nullptr : FactoryMap()->at(type_name);
- if (factory) {
- return factory(element);
- }
+ if (type_name.IsEmpty())
+ return MakeGarbageCollected<TextInputType>(element);
+
+#define INPUT_TYPE_FACTORY(input_type, class_name) \
+ if (type_name == input_type_names::input_type) \
+ return MakeGarbageCollected<class_name>(element);
+ INPUT_TYPES(INPUT_TYPE_FACTORY)
+#undef INPUT_TYPE_FACTORY
+
return MakeGarbageCollected<TextInputType>(element);
}
@@ -191,14 +122,21 @@ const AtomicString& InputType::NormalizeTypeName(
const AtomicString& type_name) {
if (type_name.IsEmpty())
return input_type_names::kText;
- InputTypeFactoryMap::const_iterator it =
- FactoryMap()->find(type_name.LowerASCII());
- return it == FactoryMap()->end() ? input_type_names::kText : it->key;
+
+ AtomicString type_name_lower = type_name.LowerASCII();
+
+#define NORMALIZE_INPUT_TYPE(input_type, class_name) \
+ if (type_name_lower == input_type_names::input_type) \
+ return input_type_names::input_type;
+ INPUT_TYPES(NORMALIZE_INPUT_TYPE)
+#undef NORMALIZE_INPUT_TYPE
+
+ return input_type_names::kText;
}
InputType::~InputType() = default;
-void InputType::Trace(Visitor* visitor) {
+void InputType::Trace(Visitor* visitor) const {
visitor->Trace(element_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/input_type.h b/chromium/third_party/blink/renderer/core/html/forms/input_type.h
index 45ec3898704..3f0c23264ac 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/input_type.h
@@ -57,7 +57,7 @@ class CORE_EXPORT InputType : public GarbageCollected<InputType> {
static InputType* Create(HTMLInputElement&, const AtomicString&);
static const AtomicString& NormalizeTypeName(const AtomicString&);
virtual ~InputType();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
virtual InputTypeView* CreateView() = 0;
virtual const AtomicString& FormControlType() const = 0;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/input_type_view.cc b/chromium/third_party/blink/renderer/core/html/forms/input_type_view.cc
index 336cea6892e..6667c015c14 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/input_type_view.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/input_type_view.cc
@@ -40,7 +40,7 @@ namespace blink {
InputTypeView::~InputTypeView() = default;
-void InputTypeView::Trace(Visitor* visitor) {
+void InputTypeView::Trace(Visitor* visitor) const {
visitor->Trace(element_);
}
@@ -202,7 +202,7 @@ bool InputTypeView::HasBadInput() const {
return false;
}
-void ClickHandlingState::Trace(Visitor* visitor) {
+void ClickHandlingState::Trace(Visitor* visitor) const {
visitor->Trace(checked_radio_button);
EventDispatchHandlingState::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/input_type_view.h b/chromium/third_party/blink/renderer/core/html/forms/input_type_view.h
index cba7ed4d453..1fc760298fc 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/input_type_view.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/input_type_view.h
@@ -59,7 +59,7 @@ class MouseEvent;
class ClickHandlingState final : public EventDispatchHandlingState {
public:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool checked;
bool indeterminate;
@@ -72,7 +72,7 @@ class ClickHandlingState final : public EventDispatchHandlingState {
class CORE_EXPORT InputTypeView : public GarbageCollectedMixin {
public:
virtual ~InputTypeView();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
virtual bool SizeShouldIncludeDecoration(int default_size,
int& preferred_size) const;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc b/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
index 411650375cf..d818498078c 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
@@ -65,7 +65,7 @@ class PopupMenuCSSFontSelector : public CSSFontSelector,
scoped_refptr<FontData> GetFontData(const FontDescription&,
const AtomicString&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void FontsNeedUpdate(FontSelector*, FontInvalidationReason) override;
@@ -93,7 +93,7 @@ void PopupMenuCSSFontSelector::FontsNeedUpdate(FontSelector* font_selector,
DispatchInvalidationCallbacks(reason);
}
-void PopupMenuCSSFontSelector::Trace(Visitor* visitor) {
+void PopupMenuCSSFontSelector::Trace(Visitor* visitor) const {
visitor->Trace(owner_font_selector_);
CSSFontSelector::Trace(visitor);
FontSelectorClient::Trace(visitor);
@@ -207,7 +207,7 @@ InternalPopupMenu::~InternalPopupMenu() {
DCHECK(!popup_);
}
-void InternalPopupMenu::Trace(Visitor* visitor) {
+void InternalPopupMenu::Trace(Visitor* visitor) const {
visitor->Trace(chrome_client_);
visitor->Trace(owner_element_);
PopupMenu::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.h b/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.h
index ccd7c5f5304..b9eec5394fd 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.h
@@ -27,7 +27,7 @@ class CORE_EXPORT InternalPopupMenu final : public PopupMenu,
public:
InternalPopupMenu(ChromeClient*, HTMLSelectElement&);
~InternalPopupMenu() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Update(bool force_update) override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/listed_element.cc b/chromium/third_party/blink/renderer/core/html/forms/listed_element.cc
index 5bfc398d3bb..a55a83f6742 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/listed_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/listed_element.cc
@@ -55,7 +55,7 @@ class FormAttributeTargetObserver : public IdTargetObserver {
public:
FormAttributeTargetObserver(const AtomicString& id, ListedElement*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void IdTargetChanged() override;
private:
@@ -74,7 +74,7 @@ ListedElement::~ListedElement() {
// We can't call setForm here because it contains virtual calls.
}
-void ListedElement::Trace(Visitor* visitor) {
+void ListedElement::Trace(Visitor* visitor) const {
visitor->Trace(form_attribute_target_observer_);
visitor->Trace(form_);
visitor->Trace(validity_state_);
@@ -703,7 +703,7 @@ FormAttributeTargetObserver::FormAttributeTargetObserver(const AtomicString& id,
id),
element_(element) {}
-void FormAttributeTargetObserver::Trace(Visitor* visitor) {
+void FormAttributeTargetObserver::Trace(Visitor* visitor) const {
visitor->Trace(element_);
IdTargetObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/listed_element.h b/chromium/third_party/blink/renderer/core/html/forms/listed_element.h
index 1d3c8f53346..bd6071b5303 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/listed_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/listed_element.h
@@ -170,7 +170,7 @@ class CORE_EXPORT ListedElement : public GarbageCollectedMixin {
// This should be called in Element::FinishParsingChildren() override.
void TakeStateAndRestore();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
ListedElement();
diff --git a/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc b/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc
index abd197d33c8..f96b288b259 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc
@@ -33,6 +33,16 @@ MenuListInnerElement::CustomStyleForLayoutObject() {
style->SetTextOverflow(parent_style.TextOverflow());
style->SetUserModify(EUserModify::kReadOnly);
+ if (style->LineHeight() == ComputedStyleInitialValues::InitialLineHeight()) {
+ // line-height should be consistent with MenuListIntrinsicBlockSize()
+ // in layout_box.cc.
+ const SimpleFontData* font_data = style->GetFont().PrimaryFont();
+ if (font_data)
+ style->SetLineHeight(Length::Fixed(font_data->GetFontMetrics().Height()));
+ else
+ style->SetLineHeight(Length::Fixed(style->FontSize()));
+ }
+
// Use margin:auto instead of align-items:center to get safe centering, i.e.
// when the content overflows, treat it the same as align-items: flex-start.
// But we only do that for the cases where html.css would otherwise use
diff --git a/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc b/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc
index f204c7d2228..8476f173821 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc
@@ -294,6 +294,11 @@ void MultipleFieldsTemporalInputTypeView::PickerIndicatorChooseValue(
if (input_type_->FormControlType() == input_type_names::kTime) {
if (date.ParseTime(value, 0, end) && end == value.length())
edit->SetOnlyTime(date);
+ } else if (features::IsFormControlsRefreshEnabled() &&
+ input_type_->FormControlType() ==
+ input_type_names::kDatetimeLocal) {
+ if (date.ParseDateTimeLocal(value, 0, end) && end == value.length())
+ edit->SetDateTimeLocal(date);
} else {
if (date.ParseDate(value, 0, end) && end == value.length())
edit->SetOnlyYearMonthDay(date);
@@ -354,7 +359,7 @@ MultipleFieldsTemporalInputTypeView::MultipleFieldsTemporalInputTypeView(
MultipleFieldsTemporalInputTypeView::~MultipleFieldsTemporalInputTypeView() =
default;
-void MultipleFieldsTemporalInputTypeView::Trace(Visitor* visitor) {
+void MultipleFieldsTemporalInputTypeView::Trace(Visitor* visitor) const {
visitor->Trace(input_type_);
InputTypeView::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h b/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h
index 2f4522ade10..01acc92336b 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h
@@ -56,7 +56,7 @@ class MultipleFieldsTemporalInputTypeView final
MultipleFieldsTemporalInputTypeView(HTMLInputElement&,
BaseTemporalInputType&);
~MultipleFieldsTemporalInputTypeView() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
String RawValue() const override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/option_list_test.cc b/chromium/third_party/blink/renderer/core/html/forms/option_list_test.cc
index 71941a49f9e..a1f98089e6d 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/option_list_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/option_list_test.cc
@@ -23,7 +23,7 @@ AtomicString Id(const HTMLOptionElement* option) {
class OptionListTest : public testing::Test {
protected:
void SetUp() override {
- auto* document = MakeGarbageCollected<HTMLDocument>();
+ auto* document = HTMLDocument::CreateForTest();
auto* select = MakeGarbageCollected<HTMLSelectElement>(*document);
document->AppendChild(select);
select_ = select;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc b/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc
index e9e58542693..07623a20ded 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc
@@ -190,7 +190,7 @@ void PickerIndicatorElement::DidNotifySubtreeInsertionsToDocument() {
this->picker_indicator_owner_->AriaRoleForPickerIndicator()));
}
-void PickerIndicatorElement::Trace(Visitor* visitor) {
+void PickerIndicatorElement::Trace(Visitor* visitor) const {
visitor->Trace(picker_indicator_owner_);
visitor->Trace(chooser_);
HTMLDivElement::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.h b/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.h
index 4aa8b3237f8..c92e4fd7906 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.h
@@ -59,7 +59,7 @@ class PickerIndicatorElement final : public HTMLDivElement,
PickerIndicatorElement(Document&, PickerIndicatorOwner&);
~PickerIndicatorElement() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void OpenPopup();
void ClosePopup();
diff --git a/chromium/third_party/blink/renderer/core/html/forms/popup_menu.h b/chromium/third_party/blink/renderer/core/html/forms/popup_menu.h
index af7e1aa3b63..0bb4cb9222d 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/popup_menu.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/popup_menu.h
@@ -29,7 +29,7 @@ namespace blink {
class PopupMenu : public GarbageCollected<PopupMenu> {
public:
virtual ~PopupMenu() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
virtual void Show() = 0;
virtual void Hide() = 0;
enum UpdateReason {
diff --git a/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc b/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc
index 9191f0d96a3..1cdacdcbfab 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc
@@ -41,7 +41,7 @@ class RadioButtonGroup : public GarbageCollected<RadioButtonGroup> {
bool Contains(HTMLInputElement*) const;
unsigned size() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void SetNeedsValidityCheckForAllButtons();
@@ -189,7 +189,7 @@ unsigned RadioButtonGroup::size() const {
return members_.size();
}
-void RadioButtonGroup::Trace(Visitor* visitor) {
+void RadioButtonGroup::Trace(Visitor* visitor) const {
visitor->Trace(members_);
visitor->Trace(checked_button_);
}
@@ -289,7 +289,7 @@ void RadioButtonGroupScope::RemoveButton(HTMLInputElement* element) {
}
}
-void RadioButtonGroupScope::Trace(Visitor* visitor) {
+void RadioButtonGroupScope::Trace(Visitor* visitor) const {
visitor->Trace(name_to_group_map_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.h b/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.h
index a6ba8d9f217..f739c99b1bc 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.h
@@ -36,7 +36,7 @@ class RadioButtonGroupScope {
public:
RadioButtonGroupScope();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void AddButton(HTMLInputElement*);
void UpdateCheckedState(HTMLInputElement*);
void RequiredAttributeChanged(HTMLInputElement*);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/range_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/range_input_type.cc
index 253ea5a28d3..3111ce0d95a 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/range_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/range_input_type.cc
@@ -76,7 +76,7 @@ RangeInputType::RangeInputType(HTMLInputElement& element)
InputTypeView(element),
tick_mark_values_dirty_(true) {}
-void RangeInputType::Trace(Visitor* visitor) {
+void RangeInputType::Trace(Visitor* visitor) const {
InputTypeView::Trace(visitor);
InputType::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/range_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/range_input_type.h
index 013379890dc..98010d92176 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/range_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/range_input_type.h
@@ -45,7 +45,7 @@ class RangeInputType final : public InputType, public InputTypeView {
public:
explicit RangeInputType(HTMLInputElement&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
using InputType::GetElement;
private:
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/calendar_picker_refresh.css b/chromium/third_party/blink/renderer/core/html/forms/resources/calendar_picker_refresh.css
index 69a6fc615e6..f72ea7e1c3f 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/resources/calendar_picker_refresh.css
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/calendar_picker_refresh.css
@@ -255,6 +255,19 @@ body {
fill: GrayText;
}
+ .month-popup-button,
+ .month-popup-button:hover,
+ .month-popup-button:disabled {
+ background-color: Canvas;
+ color: CanvasText;
+ forced-color-adjust: none;
+ opacity: 1.0;
+ }
+
+ .month-popup-button:disabled {
+ color: GrayText !important;
+ }
+
.month-popup-button polygon {
fill: WindowText !important;
}
@@ -370,3 +383,128 @@ body {
forced-color-adjust: none;
}
}
+
+@media (prefers-color-scheme: dark) {
+ .calendar-picker {
+ background-color: #4a4a4a;
+ color:#ffffff;
+ }
+
+ .calendar-table-header-view {
+ background-color: #4a4a4a;
+ }
+
+ .calendar-navigation-button {
+ background-color: #4a4a4a;
+ color: #ffffff;
+ }
+
+ .calendar-navigation-button:hover {
+ background-color: rgba(195, 195, 195, 0.3);
+ }
+
+ .calendar-navigation-button:disabled {
+ background-color: #4a4a4a;
+ }
+
+ .month-popup-button:disabled {
+ background-color: #4a4a4a;
+ color: rgba(255, 255, 255, 0.3);
+ }
+
+ .day-cell {
+ background-color: #4a4a4a;
+ color: rgba(255, 255, 255, 0.6);
+ }
+
+ .day-cell.current-month {
+ color: #ffffff;
+ }
+
+ .month-button:hover {
+ background-color: rgba(195, 195, 195, 0.3);
+ }
+
+ :not(.week-picker) > .calendar-table-view > .scroll-view > .scroll-view-content
+ > .calendar-row-cell > .day-cell:not(.selected):hover {
+ background-color: rgba(195, 195, 195, 0.3);
+ }
+
+ .week-picker .calendar-row-cell:hover
+ .day-cell:not(.selected):not(.disabled):not(:nth-child(2)),
+ .week-picker .calendar-row-cell:hover + .calendar-row-cell
+ .day-cell:not(.selected):not(.disabled):nth-child(2),
+ .calendar-row-cell:hover .week-number-cell:not(.selected):not(.disabled) {
+ background-color: rgba(195, 195, 195, 0.3);
+ }
+
+ .day-cell.selected,
+ .month-button.selected,
+ .week-number-cell.selected {
+ background-color: rgba(195, 195, 195, 0.5);
+ color: #FFFFFF;
+ }
+
+ .day-cell.disabled,
+ .day-cell.disabled.today,
+ .month-button[aria-disabled="true"],
+ .week-number-cell.disabled {
+ background-color: #4a4a4a;
+ color: rgba(255, 255, 255, 0.3);
+ }
+
+ .today-button-refresh:hover {
+ background-color: rgba(195, 195, 195, 0.3);
+ }
+
+ .today-button-refresh:disabled {
+ background-color: #4a4a4a;
+ color: rgba(255, 255, 255, 0.3);
+ }
+
+ .year-list-cell .label {
+ background-color: #4a4a4a;
+ color: #ffffff;
+ }
+
+ body {
+ background-color: #4a4a4a;
+ }
+
+ .month-popup-button,
+ .month-popup-button:hover,
+ .month-popup-button:disabled {
+ color: #ffffff;
+ }
+
+ .scrubby-scroll-bar {
+ background-color: #4a4a4a;
+ border-left: 1px solid #4a4a4a;
+ }
+
+ .scrubby-scroll-thumb {
+ background-color: #d8d8d8;
+ }
+
+ .calendar-navigation-button path {
+ fill: #ffffff;
+ }
+
+ .month-popup-button polygon {
+ fill: #ffffff;
+ }
+
+ .month-popup-button:disabled polygon {
+ fill: #ffffff;
+ }
+
+ .year-list-cell .month-chooser {
+ background-color: #4a4a4a;
+ }
+
+ .month-button {
+ background-color: #4a4a4a;
+ color: #ffffff;
+ }
+
+}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.css b/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.css
index 467b28893ee..25638da7926 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.css
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.css
@@ -45,9 +45,15 @@ hue-slider {
}
eye-dropper {
+ background-image: -webkit-image-set(url(eye_dropper_icon.svg) 1x);
+ background-origin: content-box;
+ background-repeat: no-repeat;
+ background-size: contain;
border-radius: 2px;
+ box-sizing: border-box;
height: 32px;
margin-left: 2%;
+ padding: 6px;
position: relative;
width: 32px;
}
@@ -64,14 +70,6 @@ eye-dropper.selected {
background-color: #CECECE;
}
-eye-dropper > svg {
- height: 16px;
- left: 25%;
- position: absolute;
- top: 25%;
- width: 16px;
-}
-
color-viewer {
border: 1px solid rgba(0, 0, 0, 0.19);
border-radius: 50%;
@@ -213,4 +211,27 @@ channel-label {
format-toggler {
border: 1px solid WindowText;
}
-} \ No newline at end of file
+}
+
+@media (prefers-color-scheme: dark) {
+ color-picker {
+ background: #4A4A4A;
+ color: #FFFFFF;
+ border: 1px solid #000000;
+ }
+
+ format-toggler:hover {
+ background-color: #545454;
+ }
+
+ input {
+ background: #4A4A4A;
+ color: #FFFFFF;
+ border: 1px solid #FFFFFF;
+ }
+
+ .up-down-icon path {
+ fill: #FFFFFF;
+ }
+
+ } \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.js b/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.js
index c2c2366c838..27a78541e93 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.js
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.js
@@ -811,56 +811,6 @@ class EyeDropper extends HTMLElement {
}
this.setAttribute('tabIndex', 0);
- this.innerHTML =
- '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" ' +
- 'xmlns="http://www.w3.org/2000/svg"><path d="M13.7344 0C14.0469 0 ' +
- '14.3411 0.0598958 14.6172 0.179688C14.8932 0.299479 15.1328 ' +
- '0.460938 15.3359 0.664062C15.5391 0.867188 15.7005 1.10677 15.8203 ' +
- '1.38281C15.9401 1.65885 16 1.95312 16 2.26562C16 2.56771 15.9427 ' +
- '2.85938 15.8281 3.14062C15.7135 3.41667 15.5495 3.66146 15.3359 ' +
- '3.875L13.4609 5.75C13.6328 5.91667 13.7656 6.10677 13.8594 ' +
- '6.32031C13.9531 6.52865 14 6.75521 14 7C14 7.23958 13.9531 7.46354 ' +
- '13.8594 7.67188C13.7708 7.88021 13.6432 8.06771 13.4766 ' +
- '8.23438L12.25 9.46094L11 8.20312L4.71094 14.4922L4.50781 ' +
- '14.5C4.24219 14.5104 4.01302 14.5547 3.82031 14.6328C3.63281 ' +
- '14.7109 3.46615 14.8073 3.32031 14.9219C3.17969 15.0312 3.04948 ' +
- '15.1484 2.92969 15.2734C2.8151 15.3984 2.69271 15.5156 2.5625 ' +
- '15.625C2.43229 15.7344 2.28906 15.8255 2.13281 15.8984C1.97656 ' +
- '15.9661 1.78646 16 1.5625 16C1.34896 16 1.14583 15.9583 0.953125 ' +
- '15.875C0.765625 15.7917 0.601562 15.6797 0.460938 15.5391C0.320312 ' +
- '15.3984 0.208333 15.2344 0.125 15.0469C0.0416667 14.8542 0 14.651 0 ' +
- '14.4375C0 14.2135 0.0338542 14.0234 0.101562 13.8672C0.174479 ' +
- '13.7057 0.265625 13.5625 0.375 13.4375C0.484375 13.3073 0.601562 ' +
- '13.1849 0.726562 13.0703C0.851562 12.9505 0.96875 12.8203 1.07812 ' +
- '12.6797C1.19271 12.5339 1.28906 12.3672 1.36719 12.1797C1.44531 ' +
- '11.9922 1.48958 11.763 1.5 11.4922L1.50781 11.2891L7.79688 ' +
- '5L6.53906 3.75L7.76562 2.52344C7.93229 2.35677 8.11979 2.22917 ' +
- '8.32812 2.14062C8.53646 2.04688 8.76042 2 9 2C9.24479 2 9.47135 ' +
- '2.04688 9.67969 2.14062C9.89323 2.23438 10.0833 2.36719 10.25 ' +
- '2.53906L12.125 0.664062C12.3385 0.450521 12.5833 0.286458 12.8594 ' +
- '0.171875C13.1406 0.0572917 13.4323 0 13.7344 0ZM10.2891 7.5L8.5 ' +
- '5.71094L2.49219 11.7188C2.46615 11.9844 2.41667 12.2214 2.34375 ' +
- '12.4297C2.27083 12.638 2.17708 12.8333 2.0625 13.0156C1.94792 ' +
- '13.1927 1.8125 13.3646 1.65625 13.5312C1.50521 13.6927 1.34115 ' +
- '13.8646 1.16406 14.0469C1.05469 14.1562 1 14.2891 1 14.4453C1 ' +
- '14.5964 1.05469 14.7266 1.16406 14.8359C1.27344 14.9453 1.40365 15 ' +
- '1.55469 15C1.71094 15 1.84375 14.9453 1.95312 14.8359C2.13542 ' +
- '14.6589 2.3099 14.4948 2.47656 14.3438C2.64323 14.1875 2.8151 ' +
- '14.0521 2.99219 13.9375C3.16927 13.8229 3.36198 13.7292 3.57031 ' +
- '13.6562C3.77865 13.5833 4.01562 13.5339 4.28125 13.5078L10.2891 ' +
- '7.5ZM14.625 3.16406C14.875 2.91406 15 2.61719 15 2.27344C15 2.10156 ' +
- '14.9661 1.9375 14.8984 1.78125C14.8307 1.625 14.7396 1.48958 14.625 ' +
- '1.375C14.5104 1.26042 14.375 1.16927 14.2188 1.10156C14.0625 ' +
- '1.03385 13.8984 1 13.7266 1C13.3828 1 13.0859 1.125 12.8359 ' +
- '1.375L10.25 3.95312L9.51562 3.21875C9.36979 3.07292 9.19792 3 9 ' +
- '3C8.89062 3 8.78646 3.02604 8.6875 3.07812C8.59375 3.13021 8.5026 ' +
- '3.19531 8.41406 3.27344C8.33073 3.35156 8.25 3.4349 8.17188 ' +
- '3.52344C8.09375 3.60677 8.02083 3.68229 7.95312 3.75L12.25 ' +
- '8.04688L12.7812 7.51562C12.9271 7.36979 13 7.19792 13 7C13 6.89583 ' +
- '12.9792 6.80208 12.9375 6.71875C12.901 6.63021 12.8464 6.54948 ' +
- '12.7734 6.47656L12.0469 5.75L14.625 3.16406Z" fill="WindowText"/> ' +
- '</svg>';
-
this.addEventListener('click', this.onClick_);
this.addEventListener('keydown', this.onKeyDown_);
}
@@ -1982,7 +1932,7 @@ class FormatToggler extends HTMLElement {
this.upDownIcon_ = document.createElement('span');
this.upDownIcon_.setAttribute('id', 'up-down-icon');
this.upDownIcon_.innerHTML =
- '<svg width="6" height="8" viewBox="0 0 6 8" fill="none" ' +
+ '<svg class="up-down-icon" width="6" height="8" viewBox="0 0 6 8" fill="none" ' +
'xmlns="http://www.w3.org/2000/svg"><path d="M1.18359 ' +
'3.18359L0.617188 2.61719L3 0.234375L5.38281 2.61719L4.81641 ' +
'3.18359L3 1.36719L1.18359 3.18359ZM4.81641 4.81641L5.38281 ' +
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/eye_dropper_icon.svg b/chromium/third_party/blink/renderer/core/html/forms/resources/eye_dropper_icon.svg
new file mode 100644
index 00000000000..20d39973b8b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/eye_dropper_icon.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0z" fill="none"/><path fill="WindowText" d="M20.71 5.63l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-3.12 3.12-1.93-1.91-1.41 1.41 1.42 1.42L3 16.25V21h4.75l8.92-8.92 1.42 1.42 1.41-1.41-1.92-1.92 3.12-3.12c.4-.4.4-1.03.01-1.42zM6.92 19L5 17.08l8.06-8.06 1.92 1.92L6.92 19z"/></svg> \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.css b/chromium/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.css
index 011130295f3..30837f148de 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.css
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.css
@@ -82,13 +82,18 @@
}
@media (forced-colors: active) {
- .suggestion-list-entry:focus {
+ .controls-refresh .suggestion-list-entry:focus {
background-color: Highlight !important;
- color: Window !important;
forced-color-adjust: none;
}
- .suggestion-list-entry:focus .label {
- color: Window !important;
+ .controls-refresh .suggestion-list-entry:focus .label,
+ .controls-refresh .suggestion-list-entry:focus .title {
+ color: HighlightText !important;
+ }
+
+ .controls-refresh .suggestion-list-entry .label,
+ .controls-refresh .suggestion-list-entry .title {
+ color: WindowText !important;
}
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/time_picker.css b/chromium/third_party/blink/renderer/core/html/forms/resources/time_picker.css
index 2a460119fea..0205061c648 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/resources/time_picker.css
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/time_picker.css
@@ -82,3 +82,23 @@
border-color: WindowText;
}
}
+
+@media (prefers-color-scheme: dark) {
+ .time-picker {
+ background: #4a4a4a;
+ border: 1px solid #bfbfbf;
+ }
+
+ .time-cell {
+ color: #ffffff;
+ }
+
+ .time-cell:hover {
+ background-color: rgba(195, 195, 195, 0.3);
+ }
+
+ .time-cell.selected {
+ background-color: rgba(195, 195, 195, 0.5);
+ color: #FFFFFF;
+ }
+}
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 6048bc713fc..a2770356481 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
@@ -36,6 +36,7 @@
#include "third_party/blink/renderer/core/dom/mutation_observer.h"
#include "third_party/blink/renderer/core/dom/mutation_record.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
+#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/events/gesture_event.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
#include "third_party/blink/renderer/core/events/mouse_event.h"
@@ -43,6 +44,7 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
+#include "third_party/blink/renderer/core/html/forms/menu_list_inner_element.h"
#include "third_party/blink/renderer/core/html/forms/popup_menu.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/input/input_device_capabilities.h"
@@ -72,7 +74,7 @@ HTMLOptionElement* EventTargetOption(const Event& event) {
class MenuListSelectType final : public SelectType {
public:
explicit MenuListSelectType(HTMLSelectElement& select) : SelectType(select) {}
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
bool DefaultEventHandler(const Event& event) override;
void DidSelectOption(HTMLOptionElement* element,
@@ -92,6 +94,8 @@ class MenuListSelectType final : public SelectType {
}
void MaximumOptionWidthMightBeChanged() const override;
+ void CreateShadowSubtree(ShadowRoot& root) override;
+ Element& InnerElement() const override;
void ShowPopup() override;
void HidePopup() override;
void PopupDidHide() override;
@@ -121,7 +125,7 @@ class MenuListSelectType final : public SelectType {
bool snav_arrow_key_selection_ = false;
};
-void MenuListSelectType::Trace(Visitor* visitor) {
+void MenuListSelectType::Trace(Visitor* visitor) const {
visitor->Trace(popup_);
visitor->Trace(popup_updater_);
SelectType::Trace(visitor);
@@ -292,6 +296,22 @@ bool MenuListSelectType::HandlePopupOpenKeyboardEvent() {
return true;
}
+void MenuListSelectType::CreateShadowSubtree(ShadowRoot& root) {
+ Document& doc = select_->GetDocument();
+ Element* inner_element = MakeGarbageCollected<MenuListInnerElement>(doc);
+ inner_element->setAttribute(html_names::kAriaHiddenAttr, "true");
+ // Make sure InnerElement() always has a Text node.
+ inner_element->appendChild(Text::Create(doc, g_empty_string));
+ root.insertBefore(inner_element, root.firstChild());
+}
+
+Element& MenuListSelectType::InnerElement() const {
+ auto* inner_element =
+ DynamicTo<Element>(select_->UserAgentShadowRoot()->firstChild());
+ DCHECK(inner_element);
+ return *inner_element;
+}
+
void MenuListSelectType::ShowPopup() {
if (PopupIsVisible())
return;
@@ -365,7 +385,7 @@ void MenuListSelectType::DidSelectOption(
if (PopupIsVisible() && should_update_popup)
popup_->UpdateFromElement(PopupMenu::kBySelectionChange);
- SelectType::DidSelectOption(element, flags, should_update_popup);
+ select_->SetNeedsValidityCheck();
if (should_dispatch_events) {
select_->DispatchInputEvent();
@@ -577,7 +597,7 @@ class PopupUpdater : public MutationObserver::Delegate {
void Dispose() { observer_->disconnect(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(select_type_);
visitor->Trace(select_);
visitor->Trace(observer_);
@@ -613,13 +633,19 @@ void MenuListSelectType::DidMutateSubtree() {
class ListBoxSelectType final : public SelectType {
public:
explicit ListBoxSelectType(HTMLSelectElement& select) : SelectType(select) {}
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
bool DefaultEventHandler(const Event& event) override;
+ void DidSelectOption(HTMLOptionElement* element,
+ HTMLSelectElement::SelectOptionFlags flags,
+ bool should_update_popup) override;
void OptionRemoved(HTMLOptionElement& option) override;
void DidBlur() override;
void DidSetSuggestedOption(HTMLOptionElement* option) override;
void SaveLastSelection() override;
+ HTMLOptionElement* SpatialNavigationFocusedOption() override;
+ HTMLOptionElement* ActiveSelectionEnd() const override;
+ void ScrollToSelection() override;
void ScrollToOption(HTMLOptionElement* option) override;
void SelectAll() override;
void SaveListboxActiveSelection() override;
@@ -641,17 +667,23 @@ class ListBoxSelectType final : public SelectType {
void UpdateSelectedState(HTMLOptionElement* clicked_option,
SelectionMode mode);
void UpdateListBoxSelection(bool deselect_other_options, bool scroll = true);
+ void SetActiveSelectionAnchor(HTMLOptionElement*);
+ void SetActiveSelectionEnd(HTMLOptionElement*);
void ScrollToOptionTask();
Vector<bool> cached_state_for_active_selection_;
Vector<bool> last_on_change_selection_;
Member<HTMLOptionElement> option_to_scroll_to_;
+ Member<HTMLOptionElement> active_selection_anchor_;
+ Member<HTMLOptionElement> active_selection_end_;
bool is_in_non_contiguous_selection_ = false;
bool active_selection_state_ = false;
};
-void ListBoxSelectType::Trace(Visitor* visitor) {
+void ListBoxSelectType::Trace(Visitor* visitor) const {
visitor->Trace(option_to_scroll_to_);
+ visitor->Trace(active_selection_anchor_);
+ visitor->Trace(active_selection_end_);
SelectType::Trace(visitor);
}
@@ -733,14 +765,14 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) {
if (!select_->IsDisabledFormControl()) {
if (select_->is_multiple_) {
// Only extend selection if there is something selected.
- if (!select_->active_selection_anchor_)
+ if (!active_selection_anchor_)
return false;
- select_->SetActiveSelectionEnd(option);
+ SetActiveSelectionEnd(option);
UpdateListBoxSelection(false);
} else {
- select_->SetActiveSelectionAnchor(option);
- select_->SetActiveSelectionEnd(option);
+ SetActiveSelectionAnchor(option);
+ SetActiveSelectionEnd(option);
UpdateListBoxSelection(true);
}
}
@@ -769,7 +801,7 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) {
bool handled = false;
HTMLOptionElement* end_option = nullptr;
- if (!select_->active_selection_end_) {
+ if (!active_selection_end_) {
// Initialize the end index
if (key == "ArrowDown" || key == "PageDown") {
HTMLOptionElement* start_option = select_->LastSelectedOption();
@@ -793,19 +825,18 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) {
} else {
// Set the end index based on the current end index.
if (key == "ArrowDown") {
- end_option = NextSelectableOption(select_->active_selection_end_.Get());
+ end_option = NextSelectableOption(active_selection_end_);
handled = true;
} else if (key == "ArrowUp") {
- end_option =
- PreviousSelectableOption(select_->active_selection_end_.Get());
+ end_option = PreviousSelectableOption(active_selection_end_);
handled = true;
} else if (key == "PageDown") {
- end_option = NextSelectableOptionPageAway(
- select_->active_selection_end_.Get(), kSkipForwards);
+ end_option =
+ NextSelectableOptionPageAway(active_selection_end_, kSkipForwards);
handled = true;
} else if (key == "PageUp") {
- end_option = NextSelectableOptionPageAway(
- select_->active_selection_end_.Get(), kSkipBackwards);
+ end_option =
+ NextSelectableOptionPageAway(active_selection_end_, kSkipBackwards);
handled = true;
}
}
@@ -821,7 +852,7 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) {
// Check if the selection moves to the boundary.
if (key == "ArrowLeft" || key == "ArrowRight" ||
((key == "ArrowDown" || key == "ArrowUp") &&
- end_option == select_->active_selection_end_))
+ end_option == active_selection_end_))
return false;
}
@@ -833,9 +864,9 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) {
#endif
if (select_->is_multiple_ && keyboard_event->keyCode() == ' ' &&
- is_control_key && select_->active_selection_end_) {
+ is_control_key && active_selection_end_) {
// Use ctrl+space to toggle selection change.
- ToggleSelection(*select_->active_selection_end_);
+ ToggleSelection(*active_selection_end_);
return true;
}
@@ -845,7 +876,7 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) {
// selection.
SaveLastSelection();
- select_->SetActiveSelectionEnd(end_option);
+ SetActiveSelectionEnd(end_option);
is_in_non_contiguous_selection_ = select_->is_multiple_ && is_control_key;
bool select_new_item =
@@ -858,10 +889,10 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) {
// other options, then set the anchor index equal to the end index.
bool deselect_others = !select_->is_multiple_ ||
(!keyboard_event->shiftKey() && select_new_item);
- if (!select_->active_selection_anchor_ || deselect_others) {
+ if (!active_selection_anchor_ || deselect_others) {
if (deselect_others)
select_->DeselectItemsWithoutValidation();
- select_->SetActiveSelectionAnchor(select_->active_selection_end_.Get());
+ SetActiveSelectionAnchor(active_selection_end_.Get());
}
ScrollToOption(end_option);
@@ -872,7 +903,7 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) {
}
UpdateMultiSelectFocus();
} else {
- select_->ScrollToSelection();
+ ScrollToSelection();
}
return true;
@@ -893,7 +924,7 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) {
} else if (select_->is_multiple_ && key_code == ' ' &&
(IsSpatialNavigationEnabled(select_->GetDocument().GetFrame()) ||
is_in_non_contiguous_selection_)) {
- HTMLOptionElement* option = select_->active_selection_end_;
+ HTMLOptionElement* option = active_selection_end_;
// If there's no active selection,
// act as if "ArrowDown" had been pressed.
if (!option)
@@ -909,9 +940,34 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) {
return false;
}
+void ListBoxSelectType::DidSelectOption(
+ HTMLOptionElement* element,
+ HTMLSelectElement::SelectOptionFlags flags,
+ bool should_update_popup) {
+ // We should update active selection after finishing OPTION state change
+ // because SetActiveSelectionAnchor() stores OPTION's selection state.
+ if (element) {
+ const bool is_single = !select_->IsMultiple();
+ const bool deselect_other_options =
+ flags & HTMLSelectElement::kDeselectOtherOptionsFlag;
+ // SetActiveSelectionAnchor is O(N).
+ if (!active_selection_anchor_ || is_single || deselect_other_options)
+ SetActiveSelectionAnchor(element);
+ if (!active_selection_end_ || is_single || deselect_other_options)
+ SetActiveSelectionEnd(element);
+ }
+
+ ScrollToSelection();
+ select_->SetNeedsValidityCheck();
+}
+
void ListBoxSelectType::OptionRemoved(HTMLOptionElement& option) {
if (option_to_scroll_to_ == &option)
option_to_scroll_to_.Clear();
+ if (active_selection_anchor_ == &option)
+ active_selection_anchor_.Clear();
+ if (active_selection_end_ == &option)
+ active_selection_end_.Clear();
}
void ListBoxSelectType::DidBlur() {
@@ -939,11 +995,42 @@ void ListBoxSelectType::UpdateMultiSelectFocus() {
for (auto* const option : select_->GetOptionList()) {
if (option->IsDisabledFormControl() || !option->GetLayoutObject())
continue;
- bool is_focused = (option == select_->active_selection_end_) &&
- is_in_non_contiguous_selection_;
+ bool is_focused =
+ (option == active_selection_end_) && is_in_non_contiguous_selection_;
option->SetMultiSelectFocusedState(is_focused);
}
- select_->ScrollToSelection();
+ ScrollToSelection();
+}
+
+HTMLOptionElement* ListBoxSelectType::SpatialNavigationFocusedOption() {
+ if (!IsSpatialNavigationEnabled(select_->GetDocument().GetFrame()))
+ return nullptr;
+ if (HTMLOptionElement* option = ActiveSelectionEnd())
+ return option;
+ return FirstSelectableOption();
+}
+
+void ListBoxSelectType::SetActiveSelectionAnchor(HTMLOptionElement* option) {
+ active_selection_anchor_ = option;
+ SaveListboxActiveSelection();
+}
+
+void ListBoxSelectType::SetActiveSelectionEnd(HTMLOptionElement* option) {
+ active_selection_end_ = option;
+}
+
+HTMLOptionElement* ListBoxSelectType::ActiveSelectionEnd() const {
+ if (active_selection_end_)
+ return active_selection_end_;
+ return select_->LastSelectedOption();
+}
+
+void ListBoxSelectType::ScrollToSelection() {
+ if (!select_->IsFinishedParsingChildren())
+ return;
+ ScrollToOption(ActiveSelectionEnd());
+ if (AXObjectCache* cache = select_->GetDocument().ExistingAXObjectCache())
+ cache->ListboxActiveIndexChanged(select_);
}
void ListBoxSelectType::ScrollToOption(HTMLOptionElement* option) {
@@ -997,8 +1084,8 @@ void ListBoxSelectType::SelectAll() {
SaveLastSelection();
active_selection_state_ = true;
- select_->SetActiveSelectionAnchor(NextSelectableOption(nullptr));
- select_->SetActiveSelectionEnd(PreviousSelectableOption(nullptr));
+ SetActiveSelectionAnchor(NextSelectableOption(nullptr));
+ SetActiveSelectionEnd(PreviousSelectableOption(nullptr));
UpdateListBoxSelection(false, false);
ListBoxOnChange();
@@ -1060,9 +1147,8 @@ void ListBoxSelectType::UpdateSelectedState(HTMLOptionElement* clicked_option,
// If the anchor hasn't been set, and we're doing kDeselectOthers or kRange,
// then initialize the anchor to the first selected OPTION.
- if (!select_->active_selection_anchor_ &&
- mode != SelectionMode::kNotChangeOthers)
- select_->SetActiveSelectionAnchor(select_->SelectedOption());
+ if (!active_selection_anchor_ && mode != SelectionMode::kNotChangeOthers)
+ SetActiveSelectionAnchor(select_->SelectedOption());
// Set the selection state of the clicked OPTION.
if (!clicked_option->IsDisabledFormControl()) {
@@ -1073,18 +1159,18 @@ void ListBoxSelectType::UpdateSelectedState(HTMLOptionElement* clicked_option,
// If there was no selectedIndex() for the previous initialization, or if
// we're doing kDeselectOthers, or kNotChangeOthers (using cmd or ctrl),
// then initialize the anchor OPTION to the clicked OPTION.
- if (!select_->active_selection_anchor_ || mode != SelectionMode::kRange)
- select_->SetActiveSelectionAnchor(clicked_option);
+ if (!active_selection_anchor_ || mode != SelectionMode::kRange)
+ SetActiveSelectionAnchor(clicked_option);
- select_->SetActiveSelectionEnd(clicked_option);
+ SetActiveSelectionEnd(clicked_option);
UpdateListBoxSelection(mode != SelectionMode::kNotChangeOthers);
}
void ListBoxSelectType::UpdateListBoxSelection(bool deselect_other_options,
bool scroll) {
DCHECK(select_->GetLayoutObject());
- HTMLOptionElement* const anchor_option = select_->active_selection_anchor_;
- HTMLOptionElement* const end_option = select_->active_selection_end_;
+ HTMLOptionElement* const anchor_option = active_selection_anchor_;
+ HTMLOptionElement* const end_option = active_selection_end_;
const int anchor_index = anchor_option ? anchor_option->index() : -1;
const int end_index = end_option ? end_option->index() : -1;
const int start = std::min(anchor_index, end_index);
@@ -1113,7 +1199,7 @@ void ListBoxSelectType::UpdateListBoxSelection(bool deselect_other_options,
UpdateMultiSelectFocus();
select_->SetNeedsValidityCheck();
if (scroll)
- select_->ScrollToSelection();
+ ScrollToSelection();
select_->NotifyFormStateChanged();
}
@@ -1191,17 +1277,10 @@ void SelectType::WillBeDestroyed() {
will_be_destroyed_ = true;
}
-void SelectType::Trace(Visitor* visitor) {
+void SelectType::Trace(Visitor* visitor) const {
visitor->Trace(select_);
}
-void SelectType::DidSelectOption(HTMLOptionElement*,
- HTMLSelectElement::SelectOptionFlags,
- bool) {
- select_->ScrollToSelection();
- select_->SetNeedsValidityCheck();
-}
-
void SelectType::OptionRemoved(HTMLOptionElement& option) {}
void SelectType::DidDetachLayoutTree() {}
@@ -1224,6 +1303,17 @@ const ComputedStyle* SelectType::OptionStyle() const {
void SelectType::MaximumOptionWidthMightBeChanged() const {}
+HTMLOptionElement* SelectType::SpatialNavigationFocusedOption() {
+ return nullptr;
+}
+
+HTMLOptionElement* SelectType::ActiveSelectionEnd() const {
+ NOTREACHED();
+ return nullptr;
+}
+
+void SelectType::ScrollToSelection() {}
+
void SelectType::ScrollToOption(HTMLOptionElement* option) {}
void SelectType::SelectAll() {
@@ -1238,6 +1328,15 @@ void SelectType::ListBoxOnChange() {}
void SelectType::ClearLastOnChangeSelection() {}
+void SelectType::CreateShadowSubtree(ShadowRoot& root) {}
+
+Element& SelectType::InnerElement() const {
+ NOTREACHED();
+ // Returning select_ doesn't make sense, but we need to return an element
+ // to compile this source. This function must not be called.
+ return *select_;
+}
+
void SelectType::ShowPopup() {
NOTREACHED();
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/select_type.h b/chromium/third_party/blink/renderer/core/html/forms/select_type.h
index e6eb23d62d9..e49dad8e0ba 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/select_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/select_type.h
@@ -19,14 +19,14 @@ class SelectType : public GarbageCollected<SelectType> {
// of |select|.
static SelectType* Create(HTMLSelectElement& select);
void WillBeDestroyed();
- virtual void Trace(Visitor* visitor);
+ virtual void Trace(Visitor* visitor) const;
// Returns true if the event is handled.
virtual bool DefaultEventHandler(const Event& event) = 0;
virtual void DidSelectOption(HTMLOptionElement* element,
HTMLSelectElement::SelectOptionFlags flags,
- bool should_update_popup);
+ bool should_update_popup) = 0;
virtual void OptionRemoved(HTMLOptionElement& option);
virtual void DidBlur() = 0;
@@ -46,6 +46,9 @@ class SelectType : public GarbageCollected<SelectType> {
virtual const ComputedStyle* OptionStyle() const;
virtual void MaximumOptionWidthMightBeChanged() const;
+ virtual HTMLOptionElement* SpatialNavigationFocusedOption();
+ virtual HTMLOptionElement* ActiveSelectionEnd() const;
+ virtual void ScrollToSelection();
virtual void ScrollToOption(HTMLOptionElement* option);
virtual void SelectAll();
virtual void SaveListboxActiveSelection();
@@ -55,6 +58,8 @@ class SelectType : public GarbageCollected<SelectType> {
// This is for ListBoxes.
virtual void ClearLastOnChangeSelection();
+ virtual void CreateShadowSubtree(ShadowRoot& root);
+ virtual Element& InnerElement() const;
virtual void ShowPopup();
virtual void HidePopup();
virtual void PopupDidHide();
diff --git a/chromium/third_party/blink/renderer/core/html/forms/slider_thumb_element.h b/chromium/third_party/blink/renderer/core/html/forms/slider_thumb_element.h
index cc4dd4d78f1..8ad31ff0604 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/slider_thumb_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/slider_thumb_element.h
@@ -59,6 +59,7 @@ class SliderThumbElement final : public HTMLDivElement {
HTMLInputElement* HostInput() const;
void SetPositionFromPoint(const LayoutPoint&);
void StopDragging();
+ bool IsSliderThumbElement() const override { return true; }
private:
LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.cc b/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.cc
index bb7179bb155..6172e243b67 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.cc
@@ -221,7 +221,7 @@ bool SpinButtonElement::ShouldRespondToMouseEvents() {
spin_button_owner_->ShouldSpinButtonRespondToMouseEvents();
}
-void SpinButtonElement::Trace(Visitor* visitor) {
+void SpinButtonElement::Trace(Visitor* visitor) const {
visitor->Trace(spin_button_owner_);
HTMLDivElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h b/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h
index 65f3284f0c7..b725e5f0608 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h
@@ -74,7 +74,7 @@ class CORE_EXPORT SpinButtonElement final : public HTMLDivElement,
void ForwardEvent(Event&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DetachLayoutTree(bool performing_reattach) override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/step_range.cc b/chromium/third_party/blink/renderer/core/html/forms/step_range.cc
index b4bcb5d9ebc..833df98498d 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/step_range.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/step_range.cc
@@ -21,6 +21,7 @@
#include "third_party/blink/renderer/core/html/forms/step_range.h"
#include <float.h>
+#include "base/notreached.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
diff --git a/chromium/third_party/blink/renderer/core/html/forms/submit_event.cc b/chromium/third_party/blink/renderer/core/html/forms/submit_event.cc
index 04c84a91404..0ec3ad14202 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/submit_event.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/submit_event.cc
@@ -20,7 +20,7 @@ SubmitEvent* SubmitEvent::Create(const AtomicString& type,
return MakeGarbageCollected<SubmitEvent>(type, event_init);
}
-void SubmitEvent::Trace(Visitor* visitor) {
+void SubmitEvent::Trace(Visitor* visitor) const {
visitor->Trace(submitter_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/submit_event.h b/chromium/third_party/blink/renderer/core/html/forms/submit_event.h
index 2e242d3a791..29552813e42 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/submit_event.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/submit_event.h
@@ -20,7 +20,7 @@ class SubmitEvent : public Event {
const SubmitEventInit* event_init);
SubmitEvent(const AtomicString& type, const SubmitEventInit* event_init);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
HTMLElement* submitter() const { return submitter_.Get(); }
const AtomicString& InterfaceName() const override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/text_control_element.cc b/chromium/third_party/blink/renderer/core/html/forms/text_control_element.cc
index 69211bb4443..076f2215ccc 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/text_control_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/text_control_element.cc
@@ -1048,7 +1048,7 @@ const String& TextControlElement::SuggestedValue() const {
return suggested_value_;
}
-void TextControlElement::Trace(Visitor* visitor) {
+void TextControlElement::Trace(Visitor* visitor) const {
visitor->Trace(inner_editor_);
HTMLFormControlElementWithState::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/text_control_element.h b/chromium/third_party/blink/renderer/core/html/forms/text_control_element.h
index 740cab80101..fce400feef1 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/text_control_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/text_control_element.h
@@ -151,7 +151,7 @@ class CORE_EXPORT TextControlElement : public HTMLFormControlElementWithState {
virtual void SetSuggestedValue(const String& value);
const String& SuggestedValue() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
ETextOverflow ValueForTextOverflow() const;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
index 07164ddc329..c82f3dc9f98 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
@@ -108,7 +108,7 @@ TextFieldInputType::TextFieldInputType(HTMLInputElement& element)
TextFieldInputType::~TextFieldInputType() = default;
-void TextFieldInputType::Trace(Visitor* visitor) {
+void TextFieldInputType::Trace(Visitor* visitor) const {
InputTypeView::Trace(visitor);
InputType::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.h
index 0e7994ca51a..8040fb31b77 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.h
@@ -45,7 +45,7 @@ class TextFieldInputType : public InputType,
USING_GARBAGE_COLLECTED_MIXIN(TextFieldInputType);
public:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
using InputType::GetElement;
String RawValue() const override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/validity_state.h b/chromium/third_party/blink/renderer/core/html/forms/validity_state.h
index df9283cd474..73453e61f04 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/validity_state.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/validity_state.h
@@ -36,7 +36,7 @@ class ValidityState final : public ScriptWrappable {
public:
explicit ValidityState(ListedElement* control) : control_(control) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(control_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc b/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc
index 3c913396405..981526ac0d3 100644
--- a/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc
@@ -418,6 +418,11 @@ base::Optional<WebImpression> HTMLAnchorElement::GetImpressionForNavigation()
expiry = base::TimeDelta::FromMilliseconds(expiry_milliseconds);
}
+ UseCounter::Count(GetExecutionContext(),
+ mojom::blink::WebFeature::kConversionAPIAll);
+ UseCounter::Count(GetExecutionContext(),
+ mojom::blink::WebFeature::kImpressionRegistration);
+
return WebImpression{conversion_destination, reporting_origin,
impression_data, expiry};
}
@@ -437,7 +442,7 @@ void HTMLAnchorElement::SendPings(const KURL& destination_url) const {
ping_value.Contains('\t')) &&
ping_value.Contains('<')) {
Deprecation::CountDeprecation(
- GetDocument(), WebFeature::kCanRequestURLHTTPContainingNewline);
+ GetExecutionContext(), WebFeature::kCanRequestURLHTTPContainingNewline);
return;
}
@@ -531,7 +536,7 @@ void HTMLAnchorElement::HandleClick(Event& event) {
// If hrefTranslate is enabled and set restrict processing it
// to same frame or navigations with noopener set.
- if (RuntimeEnabledFeatures::HrefTranslateEnabled(&GetDocument()) &&
+ if (RuntimeEnabledFeatures::HrefTranslateEnabled(GetExecutionContext()) &&
FastHasAttribute(html_names::kHreftranslateAttr) &&
(target_frame == frame || frame_request.GetWindowFeatures().noopener)) {
frame_request.SetHrefTranslate(
@@ -541,8 +546,9 @@ void HTMLAnchorElement::HandleClick(Event& event) {
}
// Only attach impressions for main frame navigations.
- if (RuntimeEnabledFeatures::ConversionMeasurementEnabled() && target_frame &&
- target_frame->IsMainFrame() && request.HasUserGesture() &&
+ if (RuntimeEnabledFeatures::ConversionMeasurementEnabled(
+ GetExecutionContext()) &&
+ target_frame && target_frame->IsMainFrame() && request.HasUserGesture() &&
HasImpression()) {
base::Optional<WebImpression> impression = GetImpressionForNavigation();
if (impression)
@@ -593,7 +599,7 @@ Node::InsertionNotificationRequest HTMLAnchorElement::InsertedInto(
return request;
}
-void HTMLAnchorElement::Trace(Visitor* visitor) {
+void HTMLAnchorElement::Trace(Visitor* visitor) const {
visitor->Trace(rel_list_);
HTMLElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_anchor_element.h b/chromium/third_party/blink/renderer/core/html/html_anchor_element.h
index a76f6ce870c..7685ce72caa 100644
--- a/chromium/third_party/blink/renderer/core/html/html_anchor_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_anchor_element.h
@@ -103,7 +103,7 @@ class CORE_EXPORT HTMLAnchorElement : public HTMLElement, public DOMURLUtils {
void SendPings(const KURL& destination_url) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
void ParseAttribute(const AttributeModificationParams&) override;
diff --git a/chromium/third_party/blink/renderer/core/html/html_attribute_names.json5 b/chromium/third_party/blink/renderer/core/html/html_attribute_names.json5
index f73ebeab331..7c7b7942aa3 100644
--- a/chromium/third_party/blink/renderer/core/html/html_attribute_names.json5
+++ b/chromium/third_party/blink/renderer/core/html/html_attribute_names.json5
@@ -233,7 +233,6 @@
"onportalactivate",
"onprogress",
"onratechange",
- "onrendersubtreeactivation",
"onreset",
"onresize",
"onscroll",
@@ -283,6 +282,7 @@
"rel",
"reportingorigin",
"required",
+ "resources",
"rev",
"reversed",
"role",
@@ -330,6 +330,7 @@
"version",
"vlink",
"vspace",
+ "virtualkeyboardpolicy",
"webkitdirectory",
"width",
"wrap",
diff --git a/chromium/third_party/blink/renderer/core/html/html_body_element.cc b/chromium/third_party/blink/renderer/core/html/html_body_element.cc
index f7bd4b515e7..3c45bacd725 100644
--- a/chromium/third_party/blink/renderer/core/html/html_body_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_body_element.cc
@@ -66,8 +66,8 @@ void HTMLBodyElement::CollectStyleForPresentationAttribute(
if (!url.IsEmpty()) {
CSSImageValue* image_value = MakeGarbageCollected<CSSImageValue>(
url, GetDocument().CompleteURL(url),
- Referrer(GetDocument().OutgoingReferrer(),
- GetDocument().GetReferrerPolicy()),
+ Referrer(GetExecutionContext()->OutgoingReferrer(),
+ GetExecutionContext()->GetReferrerPolicy()),
OriginClean::kTrue, false /* is_ad_related */);
image_value->SetInitiator(localName());
style->SetProperty(
@@ -215,7 +215,7 @@ void HTMLBodyElement::ParseAttribute(
GetDocument().SetWindowAttributeEventListener(
event_type_names::kLanguagechange,
CreateAttributeEventListener(GetDocument().GetFrame(), name, value));
- } else if (RuntimeEnabledFeatures::PortalsEnabled(&GetDocument()) &&
+ } else if (RuntimeEnabledFeatures::PortalsEnabled(GetExecutionContext()) &&
name == html_names::kOnportalactivateAttr) {
GetDocument().SetWindowAttributeEventListener(
event_type_names::kPortalactivate,
diff --git a/chromium/third_party/blink/renderer/core/html/html_collection.cc b/chromium/third_party/blink/renderer/core/html/html_collection.cc
index 384f50b80a4..d839a92aa47 100644
--- a/chromium/third_party/blink/renderer/core/html/html_collection.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_collection.cc
@@ -544,7 +544,7 @@ void HTMLCollection::NamedItems(const AtomicString& name,
HTMLCollection::NamedItemCache::NamedItemCache() = default;
-void HTMLCollection::Trace(Visitor* visitor) {
+void HTMLCollection::Trace(Visitor* visitor) const {
visitor->Trace(named_item_cache_);
visitor->Trace(collection_items_cache_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/html_collection.h b/chromium/third_party/blink/renderer/core/html/html_collection.h
index 3f12118654e..c4ad29a2e2d 100644
--- a/chromium/third_party/blink/renderer/core/html/html_collection.h
+++ b/chromium/third_party/blink/renderer/core/html/html_collection.h
@@ -114,7 +114,7 @@ class CORE_EXPORT HTMLCollection : public ScriptWrappable,
Iterator begin() const { return Iterator(this); }
Iterator end() const { return Iterator::CreateEnd(this); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
class NamedItemCache final : public GarbageCollected<NamedItemCache> {
@@ -142,7 +142,7 @@ class CORE_EXPORT HTMLCollection : public ScriptWrappable,
AddElementToMap(name_cache_, name, element);
}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(id_cache_);
visitor->Trace(name_cache_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_content_element.cc b/chromium/third_party/blink/renderer/core/html/html_content_element.cc
index 2f120a42fc5..2834d6c1063 100644
--- a/chromium/third_party/blink/renderer/core/html/html_content_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_content_element.cc
@@ -48,7 +48,7 @@ HTMLContentElement::HTMLContentElement(Document& document)
HTMLContentElement::~HTMLContentElement() = default;
-void HTMLContentElement::Trace(Visitor* visitor) {
+void HTMLContentElement::Trace(Visitor* visitor) const {
V0InsertionPoint::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_content_element.h b/chromium/third_party/blink/renderer/core/html/html_content_element.h
index 83db8015a5f..e57deb6040c 100644
--- a/chromium/third_party/blink/renderer/core/html/html_content_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_content_element.h
@@ -53,7 +53,7 @@ class CORE_EXPORT HTMLContentElement final : public V0InsertionPoint {
const CSSSelectorList& SelectorList() const;
bool IsSelectValid() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void ParseAttribute(const AttributeModificationParams&) override;
diff --git a/chromium/third_party/blink/renderer/core/html/html_document.cc b/chromium/third_party/blink/renderer/core/html/html_document.cc
index fa3d053df00..c3dd77c6550 100644
--- a/chromium/third_party/blink/renderer/core/html/html_document.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_document.cc
@@ -74,10 +74,14 @@ HTMLDocument::HTMLDocument(const DocumentInit& initializer,
HTMLDocument::~HTMLDocument() = default;
+HTMLDocument* HTMLDocument::CreateForTest() {
+ return MakeGarbageCollected<HTMLDocument>(DocumentInit::Create().ForTest());
+}
+
Document* HTMLDocument::CloneDocumentWithoutChildren() const {
return MakeGarbageCollected<HTMLDocument>(
DocumentInit::Create()
- .WithContextDocument(ContextDocument())
+ .WithExecutionContext(GetExecutionContext())
.WithOwnerDocument(const_cast<HTMLDocument*>(this))
.WithURL(Url())
.WithRegistrationContext(RegistrationContext()));
diff --git a/chromium/third_party/blink/renderer/core/html/html_document.h b/chromium/third_party/blink/renderer/core/html/html_document.h
index fa4c536df01..daf28cad782 100644
--- a/chromium/third_party/blink/renderer/core/html/html_document.h
+++ b/chromium/third_party/blink/renderer/core/html/html_document.h
@@ -35,10 +35,12 @@ class CORE_EXPORT HTMLDocument : public Document {
public:
explicit HTMLDocument(
- const DocumentInit& = DocumentInit::Create(),
+ const DocumentInit&,
DocumentClassFlags extended_document_classes = kDefaultDocumentClass);
~HTMLDocument() override;
+ static HTMLDocument* CreateForTest();
+
void AddNamedItem(const AtomicString& name);
void RemoveNamedItem(const AtomicString& name);
bool HasNamedItem(const AtomicString& name);
diff --git a/chromium/third_party/blink/renderer/core/html/html_element.cc b/chromium/third_party/blink/renderer/core/html/html_element.cc
index 8e246cb080b..c090f12f9fa 100644
--- a/chromium/third_party/blink/renderer/core/html/html_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_element.cc
@@ -502,8 +502,6 @@ AttributeTriggers* HTMLElement::TriggersForAttributeName(
nullptr},
{html_names::kOnratechangeAttr, kNoWebFeature,
event_type_names::kRatechange, nullptr},
- {html_names::kOnrendersubtreeactivationAttr, kNoWebFeature,
- event_type_names::kRendersubtreeactivation, nullptr},
{html_names::kOnresetAttr, kNoWebFeature, event_type_names::kReset,
nullptr},
{html_names::kOnresizeAttr, kNoWebFeature, event_type_names::kResize,
diff --git a/chromium/third_party/blink/renderer/core/html/html_element.idl b/chromium/third_party/blink/renderer/core/html/html_element.idl
index 9a806233e18..4f751fec935 100644
--- a/chromium/third_party/blink/renderer/core/html/html_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/html_element.idl
@@ -47,6 +47,11 @@
[ImplementedAs=isContentEditableForBinding] readonly attribute boolean isContentEditable;
[CEReactions, Reflect, ReflectOnly=("none","text","tel","url","email","numeric","decimal","search")] attribute DOMString inputMode;
+ // Explainers:
+ // https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/VirtualKeyboardPolicy/explainer.md
+ // https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/VirtualKeyboardAPI/explainer.md
+ [RuntimeEnabled=VirtualKeyboard, CEReactions, Reflect, ReflectOnly=("auto","manual")] attribute DOMString virtualKeyboardPolicy;
+
// CSSOM View Module
// https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlelement-interface
[Affects=Nothing, PerWorldBindings, ImplementedAs=unclosedOffsetParent] readonly attribute Element? offsetParent;
diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_element.cc b/chromium/third_party/blink/renderer/core/html/html_frame_element.cc
index a55bde6e05b..1770a962b27 100644
--- a/chromium/third_party/blink/renderer/core/html/html_frame_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_frame_element.cc
@@ -75,8 +75,7 @@ void HTMLFrameElement::ParseAttribute(
}
}
-ParsedFeaturePolicy HTMLFrameElement::ConstructContainerPolicy(
- Vector<String>*) const {
+ParsedFeaturePolicy HTMLFrameElement::ConstructContainerPolicy() const {
// Frame elements are not allowed to enable the fullscreen feature. Add an
// empty allowlist for the fullscreen feature so that the framed content is
// unable to use the API, regardless of origin.
diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_element.h b/chromium/third_party/blink/renderer/core/html/html_frame_element.h
index 30f604c98a7..2ea9ed35660 100644
--- a/chromium/third_party/blink/renderer/core/html/html_frame_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_frame_element.h
@@ -41,8 +41,7 @@ class CORE_EXPORT HTMLFrameElement final : public HTMLFrameElementBase {
bool NoResize() const;
- ParsedFeaturePolicy ConstructContainerPolicy(
- Vector<String>* /* messages */) const override;
+ ParsedFeaturePolicy ConstructContainerPolicy() const override;
mojom::blink::FrameOwnerElementType OwnerType() const final {
return mojom::blink::FrameOwnerElementType::kFrame;
diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_element_base.cc b/chromium/third_party/blink/renderer/core/html/html_frame_element_base.cc
index ac51562aefa..cd96dbb9677 100644
--- a/chromium/third_party/blink/renderer/core/html/html_frame_element_base.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_frame_element_base.cc
@@ -67,7 +67,7 @@ bool HTMLFrameElementBase::IsURLAllowed() const {
// frame. NB: This check can be invoked without any JS on the stack for some
// parser operations. In such case, we use the origin of the frame element's
// containing document as the caller context.
- v8::Isolate* isolate = GetDocument().GetIsolate();
+ v8::Isolate* isolate = GetExecutionContext()->GetIsolate();
LocalDOMWindow* accessing_window = isolate->InContext()
? CurrentDOMWindow(isolate)
: GetDocument().domWindow();
@@ -96,15 +96,12 @@ void HTMLFrameElementBase::OpenURL(bool replace_current_item) {
// URL at this point, *and* the base URL is a data URL, assume |url_| was
// relative and give a warning.
if (!url.IsValid() && GetDocument().BaseURL().ProtocolIsData()) {
- if (LocalDOMWindow* window = GetDocument().ExecutingWindow()) {
- if (LocalFrame* frame = window->GetFrame()) {
- frame->Console().AddMessage(MakeGarbageCollected<ConsoleMessage>(
+ GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kRendering,
mojom::ConsoleMessageLevel::kWarning,
"Invalid relative frame source URL (" + url_ +
") within data URL."));
- }
- }
}
LoadOrRedirectSubframe(url, frame_name_, replace_current_item);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_frame_element_test.cc
index 8545ba9e64f..f44e9d6c371 100644
--- a/chromium/third_party/blink/renderer/core/html/html_frame_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_frame_element_test.cc
@@ -21,6 +21,7 @@ TEST_F(HTMLFrameElementTest, DefaultContainerPolicy) {
const KURL document_url("http://example.com");
DocumentInit init =
DocumentInit::Create()
+ .ForTest()
.WithInitiatorOrigin(SecurityOrigin::Create(document_url))
.WithURL(document_url);
auto* document = MakeGarbageCollected<Document>(init);
diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc b/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc
index 08ae305ad65..c1c4dc67f9c 100644
--- a/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc
@@ -279,13 +279,13 @@ void HTMLFrameOwnerElement::SetSandboxFlags(
frame_policy_.sandbox_flags = flags;
// Recalculate the container policy in case the allow-same-origin flag has
// changed.
- frame_policy_.container_policy = ConstructContainerPolicy(nullptr);
+ frame_policy_.container_policy = ConstructContainerPolicy();
// Don't notify about updates if ContentFrame() is null, for example when
// the subframe hasn't been created yet.
if (ContentFrame()) {
- GetDocument().GetFrame()->Client()->DidChangeFramePolicy(ContentFrame(),
- frame_policy_);
+ GetDocument().GetFrame()->GetLocalFrameHostRemote().DidChangeFramePolicy(
+ ContentFrame()->GetFrameToken(), frame_policy_);
}
}
@@ -294,8 +294,8 @@ void HTMLFrameOwnerElement::SetDisallowDocumentAccesss(bool disallowed) {
// Don't notify about updates if ContentFrame() is null, for example when
// the subframe hasn't been created yet.
if (ContentFrame()) {
- GetDocument().GetFrame()->Client()->DidChangeFramePolicy(ContentFrame(),
- frame_policy_);
+ GetDocument().GetFrame()->GetLocalFrameHostRemote().DidChangeFramePolicy(
+ ContentFrame()->GetFrameToken(), frame_policy_);
}
}
@@ -311,18 +311,18 @@ void HTMLFrameOwnerElement::DisposePluginSoon(WebPluginContainerImpl* plugin) {
plugin->Dispose();
}
-void HTMLFrameOwnerElement::UpdateContainerPolicy(Vector<String>* messages) {
- frame_policy_.container_policy = ConstructContainerPolicy(messages);
+void HTMLFrameOwnerElement::UpdateContainerPolicy() {
+ frame_policy_.container_policy = ConstructContainerPolicy();
// Don't notify about updates if ContentFrame() is null, for example when
// the subframe hasn't been created yet.
if (ContentFrame()) {
- GetDocument().GetFrame()->Client()->DidChangeFramePolicy(ContentFrame(),
- frame_policy_);
+ GetDocument().GetFrame()->GetLocalFrameHostRemote().DidChangeFramePolicy(
+ ContentFrame()->GetFrameToken(), frame_policy_);
}
}
void HTMLFrameOwnerElement::UpdateRequiredPolicy() {
- const auto* frame = GetDocument().GetFrame();
+ auto* frame = GetDocument().GetFrame();
DocumentPolicy::FeatureState new_required_policy =
frame
? DocumentPolicy::MergeFeatureState(
@@ -334,13 +334,14 @@ void HTMLFrameOwnerElement::UpdateRequiredPolicy() {
frame_policy_.required_document_policy.clear();
for (auto i = new_required_policy.begin(), last = new_required_policy.end();
i != last;) {
- if (!DisabledByOriginTrial(i->first, &GetDocument()))
+ if (!DisabledByOriginTrial(i->first, GetExecutionContext()))
frame_policy_.required_document_policy.insert(*i);
++i;
}
if (ContentFrame()) {
- frame->Client()->DidChangeFramePolicy(ContentFrame(), frame_policy_);
+ frame->GetLocalFrameHostRemote().DidChangeFramePolicy(
+ ContentFrame()->GetFrameToken(), frame_policy_);
}
}
@@ -473,13 +474,10 @@ bool HTMLFrameOwnerElement::LoadOrRedirectSubframe(
// Update the |should_lazy_load_children_| value according to the "loading"
// attribute immediately, so that it still gets respected even if the "src"
// attribute gets parsed in ParseAttribute() before the "loading" attribute
- // does. Note that when the *feature policy* for "lazyload" is disabled, the
- // attribute value loading="eager" is ignored (i.e., interpreted as
- // "auto" instead).
+ // does.
if (should_lazy_load_children_ &&
EqualIgnoringASCIICase(FastGetAttribute(html_names::kLoadingAttr),
- "eager") &&
- !GetDocument().IsLazyLoadPolicyEnforced()) {
+ "eager")) {
should_lazy_load_children_ = false;
}
@@ -511,7 +509,7 @@ bool HTMLFrameOwnerElement::LoadOrRedirectSubframe(
return false;
if (GetDocument().GetFrame()->GetPage()->SubframeCount() >=
- Page::kMaxNumberOfFrames)
+ Page::MaxNumberOfFrames())
return false;
LocalFrame* child_frame =
@@ -535,13 +533,8 @@ bool HTMLFrameOwnerElement::LoadOrRedirectSubframe(
if (IsPlugin())
request.SetSkipServiceWorker(true);
- // When the feature policy "loading-frame-default-eager" is disabled in
- // the document, loading attribute value "auto" (or unset/invalid values) will
- // also be interpreted as "lazy".
const auto& loading_attr = FastGetAttribute(html_names::kLoadingAttr);
- bool loading_lazy_set = EqualIgnoringASCIICase(loading_attr, "lazy") ||
- (IsLoadingFrameDefaultEagerEnforced() &&
- !EqualIgnoringASCIICase(loading_attr, "eager"));
+ bool loading_lazy_set = EqualIgnoringASCIICase(loading_attr, "lazy");
if (!lazy_load_frame_observer_ &&
IsFrameLazyLoadable(GetDocument(), url, loading_lazy_set,
@@ -585,11 +578,7 @@ bool HTMLFrameOwnerElement::ShouldLazyLoadChildren() const {
void HTMLFrameOwnerElement::ParseAttribute(
const AttributeModificationParams& params) {
if (params.name == html_names::kLoadingAttr) {
- // Note that when the *feature policy* for "lazyload" is disabled, the
- // attribute value loading="eager" is ignored (i.e., interpreted as
- // "auto" instead).
- if (EqualIgnoringASCIICase(params.new_value, "eager") &&
- !GetDocument().IsLazyLoadPolicyEnforced()) {
+ if (EqualIgnoringASCIICase(params.new_value, "eager")) {
UseCounter::Count(GetDocument(),
WebFeature::kLazyLoadFrameLoadingAttributeEager);
should_lazy_load_children_ = false;
@@ -606,21 +595,25 @@ void HTMLFrameOwnerElement::ParseAttribute(
}
}
-void HTMLFrameOwnerElement::FrameCrossOriginToParentFrameChanged() {
- if (base::FeatureList::IsEnabled(
- blink::features::kCompositeCrossOriginIframes)) {
- SetNeedsCompositingUpdate();
- }
-}
-
void HTMLFrameOwnerElement::SetEmbeddingToken(
const base::UnguessableToken& embedding_token) {
- DCHECK(content_frame_);
- DCHECK(content_frame_->IsRemoteFrame());
+ DCHECK(ContentFrame());
embedding_token_ = embedding_token;
}
-void HTMLFrameOwnerElement::Trace(Visitor* visitor) {
+const base::Optional<base::UnguessableToken>&
+HTMLFrameOwnerElement::GetEmbeddingToken() const {
+ return embedding_token_;
+}
+
+bool HTMLFrameOwnerElement::IsAdRelated() const {
+ if (!content_frame_)
+ return false;
+
+ return content_frame_->IsAdSubframe();
+}
+
+void HTMLFrameOwnerElement::Trace(Visitor* visitor) const {
visitor->Trace(content_frame_);
visitor->Trace(embedded_content_view_);
visitor->Trace(lazy_load_frame_observer_);
@@ -628,10 +621,4 @@ void HTMLFrameOwnerElement::Trace(Visitor* visitor) {
FrameOwner::Trace(visitor);
}
-bool HTMLFrameOwnerElement::IsLoadingFrameDefaultEagerEnforced() const {
- return RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() &&
- !GetDocument().IsFeatureEnabled(
- mojom::blink::FeaturePolicyFeature::kLoadingFrameDefaultEager);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.h b/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.h
index 17b942a129d..c893f03da2d 100644
--- a/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.h
@@ -76,8 +76,6 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement,
return embedded_content_view_;
}
- void FrameCrossOriginToParentFrameChanged();
-
class PluginDisposeSuspendScope {
STACK_ALLOCATED();
@@ -131,11 +129,11 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement,
void ParseAttribute(const AttributeModificationParams&) override;
void SetEmbeddingToken(const base::UnguessableToken& token);
- const base::Optional<base::UnguessableToken>& GetEmbeddingToken() const {
- return embedding_token_;
- }
+ const base::Optional<base::UnguessableToken>& GetEmbeddingToken() const;
- void Trace(Visitor*) override;
+ bool IsAdRelated() const override;
+
+ void Trace(Visitor*) const override;
protected:
HTMLFrameOwnerElement(const QualifiedName& tag_name, Document&);
@@ -166,12 +164,11 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement,
// Return a feature policy container policy for this frame, based on the
// frame attributes and the effective origin specified in the frame
// attributes.
- virtual ParsedFeaturePolicy ConstructContainerPolicy(
- Vector<String>* /* messages */) const = 0;
+ virtual ParsedFeaturePolicy ConstructContainerPolicy() const = 0;
// Update the container policy and notify the frame loader client of any
// changes.
- void UpdateContainerPolicy(Vector<String>* messages = nullptr);
+ void UpdateContainerPolicy();
// Return a document policy required policy for this frame, based on the
// frame attributes.
@@ -202,8 +199,6 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement,
return network::mojom::ReferrerPolicy::kDefault;
}
- bool IsLoadingFrameDefaultEagerEnforced() const;
-
Member<Frame> content_frame_;
Member<EmbeddedContentView> embedded_content_view_;
FramePolicy frame_policy_;
diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_set_element.cc b/chromium/third_party/blink/renderer/core/html/html_frame_set_element.cc
index 5239ea86169..755fd9c497e 100644
--- a/chromium/third_party/blink/renderer/core/html/html_frame_set_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_frame_set_element.cc
@@ -202,7 +202,7 @@ void HTMLFrameSetElement::ParseAttribute(
GetDocument().SetWindowAttributeEventListener(
event_type_names::kLanguagechange,
CreateAttributeEventListener(GetDocument().GetFrame(), name, value));
- } else if (RuntimeEnabledFeatures::PortalsEnabled(&GetDocument()) &&
+ } else if (RuntimeEnabledFeatures::PortalsEnabled(GetExecutionContext()) &&
name == html_names::kOnportalactivateAttr) {
GetDocument().SetWindowAttributeEventListener(
event_type_names::kPortalactivate,
diff --git a/chromium/third_party/blink/renderer/core/html/html_html_element.cc b/chromium/third_party/blink/renderer/core/html/html_html_element.cc
index 34c9578ef53..929a82ab6a6 100644
--- a/chromium/third_party/blink/renderer/core/html/html_html_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_html_element.cc
@@ -79,10 +79,11 @@ void HTMLHtmlElement::MaybeSetupApplicationCache() {
const AtomicString& manifest = FastGetAttribute(html_names::kManifestAttr);
if (RuntimeEnabledFeatures::RestrictAppCacheToSecureContextsEnabled() &&
- !GetDocument().IsSecureContext()) {
+ !GetExecutionContext()->IsSecureContext()) {
if (!manifest.IsEmpty()) {
Deprecation::CountDeprecation(
- GetDocument(), WebFeature::kApplicationCacheAPIInsecureOrigin);
+ GetExecutionContext(),
+ WebFeature::kApplicationCacheAPIInsecureOrigin);
}
return;
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_iframe_element.cc b/chromium/third_party/blink/renderer/core/html/html_iframe_element.cc
index 742e867f733..960f6e5235f 100644
--- a/chromium/third_party/blink/renderer/core/html/html_iframe_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_iframe_element.cc
@@ -58,7 +58,7 @@ HTMLIFrameElement::HTMLIFrameElement(Document& document)
sandbox_(MakeGarbageCollected<HTMLIFrameElementSandbox>(this)),
referrer_policy_(network::mojom::ReferrerPolicy::kDefault) {}
-void HTMLIFrameElement::Trace(Visitor* visitor) {
+void HTMLIFrameElement::Trace(Visitor* visitor) const {
visitor->Trace(sandbox_);
visitor->Trace(policy_);
HTMLFrameElementBase::Trace(visitor);
@@ -196,17 +196,9 @@ void HTMLIFrameElement::ParseAttribute(
current_flags & ~sandbox_to_set;
}
SetSandboxFlags(sandbox_to_set);
- if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) {
- Vector<String> messages;
- UpdateContainerPolicy(&messages);
- if (!messages.IsEmpty()) {
- for (const String& message : messages) {
- GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
- mojom::ConsoleMessageSource::kOther,
- mojom::ConsoleMessageLevel::kWarning, message));
- }
- }
- }
+ if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled())
+ UpdateContainerPolicy();
+
UseCounter::Count(GetDocument(), WebFeature::kSandboxViaIFrame);
} else if (name == html_names::kReferrerpolicyAttr) {
referrer_policy_ = network::mojom::ReferrerPolicy::kDefault;
@@ -256,19 +248,15 @@ void HTMLIFrameElement::ParseAttribute(
} else if (name == html_names::kAllowAttr) {
if (allow_ != value) {
allow_ = value;
- Vector<String> messages;
- UpdateContainerPolicy(&messages);
- if (!messages.IsEmpty()) {
- for (const String& message : messages) {
- GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
- mojom::ConsoleMessageSource::kOther,
- mojom::ConsoleMessageLevel::kWarning, message));
- }
- }
+ UpdateContainerPolicy();
if (!value.IsEmpty()) {
UseCounter::Count(GetDocument(),
WebFeature::kFeaturePolicyAllowAttribute);
}
+ if (value.Contains(',')) {
+ UseCounter::Count(GetDocument(),
+ WebFeature::kCommaSeparatorInAllowAttribute);
+ }
}
} else if (name == html_names::kDisallowdocumentaccessAttr &&
RuntimeEnabledFeatures::DisallowDocumentAccessEnabled()) {
@@ -311,7 +299,7 @@ void HTMLIFrameElement::ParseAttribute(
DocumentPolicy::FeatureState HTMLIFrameElement::ConstructRequiredPolicy()
const {
- if (!RuntimeEnabledFeatures::DocumentPolicyEnabled(&GetDocument()))
+ if (!RuntimeEnabledFeatures::DocumentPolicyEnabled(GetExecutionContext()))
return {};
if (!required_policy_.IsEmpty()) {
@@ -348,29 +336,30 @@ DocumentPolicy::FeatureState HTMLIFrameElement::ConstructRequiredPolicy()
return new_required_policy.feature_state;
}
-ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy(
- Vector<String>* messages) const {
+ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy() const {
scoped_refptr<const SecurityOrigin> src_origin = GetOriginForFeaturePolicy();
scoped_refptr<const SecurityOrigin> self_origin =
GetDocument().GetSecurityOrigin();
+ PolicyParserMessageBuffer logger;
+
// Start with the allow attribute
ParsedFeaturePolicy container_policy = FeaturePolicyParser::ParseAttribute(
- allow_, self_origin, src_origin, messages, &GetDocument());
+ allow_, self_origin, src_origin, logger, GetExecutionContext());
// Next, process sandbox flags. These all only take effect if a corresponding
// policy does *not* exist in the allow attribute's value.
if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) {
// If the frame is sandboxed at all, then warn if feature policy attributes
// will override the sandbox attributes.
- if (messages && (sandbox_flags_converted_to_feature_policies_ &
- network::mojom::blink::WebSandboxFlags::kNavigation) !=
- network::mojom::blink::WebSandboxFlags::kNone) {
+ if ((sandbox_flags_converted_to_feature_policies_ &
+ network::mojom::blink::WebSandboxFlags::kNavigation) !=
+ network::mojom::blink::WebSandboxFlags::kNone) {
for (const auto& pair : SandboxFlagsWithFeaturePolicies()) {
if ((sandbox_flags_converted_to_feature_policies_ & pair.first) !=
network::mojom::blink::WebSandboxFlags::kNone &&
IsFeatureDeclared(pair.second, container_policy)) {
- messages->push_back(String::Format(
+ logger.Warn(String::Format(
"Allow and Sandbox attributes both mention '%s'. Allow will take "
"precedence.",
GetNameForFeature(pair.second).Utf8().c_str()));
@@ -390,8 +379,8 @@ ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy(
if (AllowFullscreen()) {
bool policy_changed = AllowFeatureEverywhereIfNotPresent(
mojom::blink::FeaturePolicyFeature::kFullscreen, container_policy);
- if (!policy_changed && messages) {
- messages->push_back(
+ if (!policy_changed) {
+ logger.Warn(
"Allow attribute will take precedence over 'allowfullscreen'.");
}
}
@@ -400,8 +389,8 @@ ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy(
if (AllowPaymentRequest()) {
bool policy_changed = AllowFeatureEverywhereIfNotPresent(
mojom::blink::FeaturePolicyFeature::kPayment, container_policy);
- if (!policy_changed && messages) {
- messages->push_back(
+ if (!policy_changed) {
+ logger.Warn(
"Allow attribute will take precedence over 'allowpaymentrequest'.");
}
}
@@ -411,6 +400,14 @@ ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy(
if (policy_)
policy_->UpdateContainerPolicy(container_policy, src_origin);
+ for (const auto& message : logger.GetMessages()) {
+ GetDocument().AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kOther, message.level,
+ message.content),
+ /* discard_duplicates */ true);
+ }
+
return container_policy;
}
@@ -504,13 +501,14 @@ HTMLIFrameElement::ConstructTrustTokenParams() const {
network::mojom::blink::TrustTokenOperationType::kSigning;
if (operation_requires_feature_policy &&
- (!GetDocument().IsFeatureEnabled(
+ (!GetExecutionContext()->IsFeatureEnabled(
mojom::blink::FeaturePolicyFeature::kTrustTokenRedemption))) {
- GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
- mojom::blink::ConsoleMessageSource::kOther,
- mojom::blink::ConsoleMessageLevel::kError,
- "Trust Tokens: Attempted redemption or signing without the "
- "trust-token-redemption Feature Policy feature present."));
+ GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kOther,
+ mojom::blink::ConsoleMessageLevel::kError,
+ "Trust Tokens: Attempted redemption or signing without the "
+ "trust-token-redemption Feature Policy feature present."));
return nullptr;
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_iframe_element.h b/chromium/third_party/blink/renderer/core/html/html_iframe_element.h
index f5c1ee044bc..b9a0f527fbe 100644
--- a/chromium/third_party/blink/renderer/core/html/html_iframe_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_iframe_element.h
@@ -43,7 +43,7 @@ class CORE_EXPORT HTMLIFrameElement final
USING_GARBAGE_COLLECTED_MIXIN(HTMLIFrameElement);
public:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
explicit HTMLIFrameElement(Document&);
~HTMLIFrameElement() override;
@@ -55,8 +55,7 @@ class CORE_EXPORT HTMLIFrameElement final
// Returns attributes that should be checked against Trusted Types
const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
- ParsedFeaturePolicy ConstructContainerPolicy(
- Vector<String>* /* messages */) const override;
+ ParsedFeaturePolicy ConstructContainerPolicy() const override;
DocumentPolicy::FeatureState ConstructRequiredPolicy() const override;
mojom::blink::FrameOwnerElementType OwnerType() const final {
diff --git a/chromium/third_party/blink/renderer/core/html/html_iframe_element.idl b/chromium/third_party/blink/renderer/core/html/html_iframe_element.idl
index a2ec716d1ee..c087b4f1292 100644
--- a/chromium/third_party/blink/renderer/core/html/html_iframe_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/html_iframe_element.idl
@@ -47,7 +47,7 @@
// Feature Policy
[CEReactions, Reflect] attribute DOMString allow;
// https://w3c.github.io/webappsec-feature-policy/#the-policy-object
- [RuntimeEnabled=FeaturePolicyJavaScriptInterface] readonly attribute FeaturePolicy featurePolicy;
+ readonly attribute FeaturePolicy featurePolicy;
// Document Policy
[RuntimeEnabled=DocumentPolicy, CEReactions, Reflect] attribute DOMString policy;
diff --git a/chromium/third_party/blink/renderer/core/html/html_iframe_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_iframe_element_test.cc
index 379168d4327..61171ac195f 100644
--- a/chromium/third_party/blink/renderer/core/html/html_iframe_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_iframe_element_test.cc
@@ -276,7 +276,7 @@ TEST_F(HTMLIFrameElementTest, SameOriginSandboxAttributeContainerPolicy) {
// iframe element.
TEST_F(HTMLIFrameElementTest, ConstructEmptyContainerPolicy) {
ParsedFeaturePolicy container_policy =
- frame_element_->ConstructContainerPolicy(nullptr);
+ frame_element_->ConstructContainerPolicy();
EXPECT_EQ(0UL, container_policy.size());
}
@@ -285,7 +285,7 @@ TEST_F(HTMLIFrameElementTest, ConstructEmptyContainerPolicy) {
TEST_F(HTMLIFrameElementTest, ConstructContainerPolicy) {
frame_element_->setAttribute(html_names::kAllowAttr, "payment; usb");
ParsedFeaturePolicy container_policy =
- frame_element_->ConstructContainerPolicy(nullptr);
+ frame_element_->ConstructContainerPolicy();
EXPECT_EQ(2UL, container_policy.size());
EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kPayment,
container_policy[0].feature);
@@ -306,7 +306,7 @@ TEST_F(HTMLIFrameElementTest, ConstructContainerPolicyWithAllowFullscreen) {
frame_element_->SetBooleanAttribute(html_names::kAllowfullscreenAttr, true);
ParsedFeaturePolicy container_policy =
- frame_element_->ConstructContainerPolicy(nullptr);
+ frame_element_->ConstructContainerPolicy();
EXPECT_EQ(1UL, container_policy.size());
EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
container_policy[0].feature);
@@ -321,7 +321,7 @@ TEST_F(HTMLIFrameElementTest, ConstructContainerPolicyWithAllowPaymentRequest) {
true);
ParsedFeaturePolicy container_policy =
- frame_element_->ConstructContainerPolicy(nullptr);
+ frame_element_->ConstructContainerPolicy();
EXPECT_EQ(2UL, container_policy.size());
EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kUsb,
container_policy[0].feature);
@@ -346,7 +346,7 @@ TEST_F(HTMLIFrameElementTest, ConstructContainerPolicyWithAllowAttributes) {
true);
ParsedFeaturePolicy container_policy =
- frame_element_->ConstructContainerPolicy(nullptr);
+ frame_element_->ConstructContainerPolicy();
EXPECT_EQ(3UL, container_policy.size());
EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kPayment,
container_policy[0].feature);
@@ -385,4 +385,41 @@ TEST_F(HTMLIFrameElementSimTest, PolicyAttributeParsingError) {
}
}
+TEST_F(HTMLIFrameElementSimTest, AllowAttributeParsingError) {
+ SimRequest main_resource("https://example.com", "text/html");
+ LoadURL("https://example.com");
+ main_resource.Complete(R"(
+ <iframe
+ allow="bad-feature-name"
+ allowfullscreen
+ allowpayment
+ sandbox=""></iframe>
+ )");
+
+ EXPECT_EQ(ConsoleMessages().size(), 1u)
+ << "Allow attribute parsing should only generate console message once, "
+ "even though there might be multiple call to "
+ "FeaturePolicyParser::ParseAttribute.";
+ EXPECT_TRUE(ConsoleMessages().front().StartsWith("Unrecognized feature"))
+ << "Expect feature policy parser raising error for unrecognized feature "
+ "but got: "
+ << ConsoleMessages().front();
+}
+
+TEST_F(HTMLIFrameElementSimTest, CommaSeparatorIsCounted) {
+ EXPECT_FALSE(
+ GetDocument().Loader()->GetUseCounterHelper().HasRecordedMeasurement(
+ WebFeature::kCommaSeparatorInAllowAttribute));
+ SimRequest main_resource("https://example.com", "text/html");
+ LoadURL("https://example.com");
+ main_resource.Complete(R"(
+ <iframe
+ allow="fullscreen, geolocation"></iframe>
+ )");
+
+ EXPECT_TRUE(
+ GetDocument().Loader()->GetUseCounterHelper().HasRecordedMeasurement(
+ WebFeature::kCommaSeparatorInAllowAttribute));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/html_image_element.cc b/chromium/third_party/blink/renderer/core/html/html_image_element.cc
index c54d6c04fa7..7ed7811b592 100644
--- a/chromium/third_party/blink/renderer/core/html/html_image_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_image_element.cc
@@ -80,7 +80,7 @@ class HTMLImageElement::ViewportChangeListener final
element_->NotifyViewportChanged();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(element_);
MediaQueryListListener::Trace(visitor);
}
@@ -103,8 +103,8 @@ HTMLImageElement::HTMLImageElement(Document& document, bool created_by_parser)
element_created_by_parser_(created_by_parser),
is_fallback_image_(false),
is_default_overridden_intrinsic_size_(
- !document.IsImageDocument() &&
- !document.IsFeatureEnabled(
+ !document.IsImageDocument() && GetExecutionContext() &&
+ !GetExecutionContext()->IsFeatureEnabled(
mojom::blink::DocumentPolicyFeature::kUnsizedMedia)),
is_legacy_format_or_unoptimized_image_(false),
referrer_policy_(network::mojom::ReferrerPolicy::kDefault) {
@@ -113,7 +113,7 @@ HTMLImageElement::HTMLImageElement(Document& document, bool created_by_parser)
HTMLImageElement::~HTMLImageElement() = default;
-void HTMLImageElement::Trace(Visitor* visitor) {
+void HTMLImageElement::Trace(Visitor* visitor) const {
visitor->Trace(image_loader_);
visitor->Trace(listener_);
visitor->Trace(form_);
@@ -287,11 +287,11 @@ void HTMLImageElement::ParseAttribute(
UseCounter::Count(GetDocument(), WebFeature::kImageDecodingAttribute);
decoding_mode_ = ParseImageDecodingMode(params.new_value);
} else if (name == html_names::kLoadingAttr &&
- EqualIgnoringASCIICase(params.new_value, "eager") &&
- !GetDocument().IsLazyLoadPolicyEnforced()) {
+ EqualIgnoringASCIICase(params.new_value, "eager")) {
GetImageLoader().LoadDeferredImage(referrer_policy_);
} else if (name == html_names::kImportanceAttr &&
- RuntimeEnabledFeatures::PriorityHintsEnabled(&GetDocument())) {
+ RuntimeEnabledFeatures::PriorityHintsEnabled(
+ GetExecutionContext())) {
// We only need to keep track of usage here, as the communication of the
// |importance| attribute to the loading pipeline takes place in
// ImageLoader.
@@ -355,7 +355,7 @@ ImageCandidate HTMLImageElement::FindBestFitImageFromPictureParent() {
continue;
if (!source->FastGetAttribute(html_names::kSrcAttr).IsNull()) {
- Deprecation::CountDeprecation(GetDocument(),
+ Deprecation::CountDeprecation(GetExecutionContext(),
WebFeature::kPictureSourceSrc);
}
String srcset = source->FastGetAttribute(html_names::kSrcsetAttr);
@@ -520,20 +520,20 @@ LayoutSize HTMLImageElement::DensityCorrectedIntrinsicDimensions() const {
return LayoutSize(LayoutReplaced::kDefaultWidth,
LayoutReplaced::kDefaultHeight);
}
- ImageResourceContent* image_resource = GetImageLoader().GetContent();
- if (!image_resource || !image_resource->HasImage())
+ ImageResourceContent* image_content = GetImageLoader().GetContent();
+ if (!image_content || !image_content->HasImage())
return LayoutSize();
float pixel_density = image_device_pixel_ratio_;
- if (image_resource->HasDevicePixelRatioHeaderValue() &&
- image_resource->DevicePixelRatioHeaderValue() > 0)
- pixel_density = 1 / image_resource->DevicePixelRatioHeaderValue();
+ if (image_content->HasDevicePixelRatioHeaderValue() &&
+ image_content->DevicePixelRatioHeaderValue() > 0)
+ pixel_density = 1 / image_content->DevicePixelRatioHeaderValue();
RespectImageOrientationEnum respect_image_orientation =
LayoutObject::ShouldRespectImageOrientation(GetLayoutObject());
LayoutSize natural_size(
- image_resource->IntrinsicSize(respect_image_orientation));
+ image_content->IntrinsicSize(respect_image_orientation));
natural_size.Scale(pixel_density);
return natural_size;
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_image_element.h b/chromium/third_party/blink/renderer/core/html/html_image_element.h
index 92800d28051..630301ef4f8 100644
--- a/chromium/third_party/blink/renderer/core/html/html_image_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_image_element.h
@@ -81,7 +81,7 @@ class CORE_EXPORT HTMLImageElement final
HTMLImageElement(Document&, const CreateElementFlags);
explicit HTMLImageElement(Document&, bool created_by_parser = false);
~HTMLImageElement() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
unsigned width();
unsigned height();
diff --git a/chromium/third_party/blink/renderer/core/html/html_image_fallback_helper.cc b/chromium/third_party/blink/renderer/core/html/html_image_fallback_helper.cc
index 9d89a0001b7..905e78f76a3 100644
--- a/chromium/third_party/blink/renderer/core/html/html_image_fallback_helper.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_image_fallback_helper.cc
@@ -21,15 +21,14 @@
namespace blink {
-static bool NoImageSourceSpecified(const Element& element) {
- return element.FastGetAttribute(html_names::kSrcAttr).IsEmpty();
-}
-
static bool ElementRepresentsNothing(const Element& element) {
const auto& html_element = To<HTMLElement>(element);
+ // We source fallback content/alternative text from more than just the 'alt'
+ // attribute, so consider the element to represent text in those cases as
+ // well.
bool alt_is_set = !html_element.AltText().IsNull();
bool alt_is_empty = alt_is_set && html_element.AltText().IsEmpty();
- bool src_is_set = !NoImageSourceSpecified(element);
+ bool src_is_set = !element.getAttribute(html_names::kSrcAttr).IsEmpty();
if (src_is_set && alt_is_empty)
return true;
return !src_is_set && (!alt_is_set || alt_is_empty);
@@ -170,7 +169,8 @@ void HTMLImageFallbackHelper::CustomStyleForAltText(Element& element,
bool image_has_intrinsic_dimensions =
new_style.Width().IsSpecifiedOrIntrinsic() &&
new_style.Height().IsSpecifiedOrIntrinsic();
- bool image_has_no_alt_attribute = To<HTMLElement>(element).AltText().IsNull();
+ bool image_has_no_alt_attribute =
+ element.getAttribute(html_names::kAltAttr).IsEmpty();
bool treat_as_replaced =
image_has_intrinsic_dimensions &&
(element.GetDocument().InQuirksMode() || image_has_no_alt_attribute);
diff --git a/chromium/third_party/blink/renderer/core/html/html_link_element.cc b/chromium/third_party/blink/renderer/core/html/html_link_element.cc
index f5efe07788b..fc9633c5f75 100644
--- a/chromium/third_party/blink/renderer/core/html/html_link_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_link_element.cc
@@ -41,6 +41,7 @@
#include "third_party/blink/renderer/core/html/cross_origin_attribute.h"
#include "third_party/blink/renderer/core/html/imports/link_import.h"
#include "third_party/blink/renderer/core/html/link_manifest.h"
+#include "third_party/blink/renderer/core/html/link_web_bundle.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/loader/link_loader.h"
@@ -61,6 +62,9 @@ HTMLLinkElement::HTMLLinkElement(Document& document,
referrer_policy_(network::mojom::ReferrerPolicy::kDefault),
sizes_(MakeGarbageCollected<DOMTokenList>(*this, html_names::kSizesAttr)),
rel_list_(MakeGarbageCollected<RelList>(this)),
+ resources_(
+ MakeGarbageCollected<DOMTokenList>(*this,
+ html_names::kResourcesAttr)),
created_by_parser_(flags.IsCreatedByParser()) {}
HTMLLinkElement::~HTMLLinkElement() = default;
@@ -72,23 +76,22 @@ void HTMLLinkElement::ParseAttribute(
if (name == html_names::kRelAttr) {
rel_attribute_ = LinkRelAttribute(value);
if (rel_attribute_.IsImport()) {
- if (RuntimeEnabledFeatures::HTMLImportsEnabled(&GetDocument())) {
- Deprecation::CountDeprecation(&GetDocument(), WebFeature::kHTMLImports);
+ if (RuntimeEnabledFeatures::HTMLImportsEnabled(GetExecutionContext())) {
+ Deprecation::CountDeprecation(GetExecutionContext(),
+ WebFeature::kHTMLImports);
} else {
// Show a warning that HTML Imports (<link rel=import>) were detected,
// but HTML Imports have been disabled. Without this, the failure would
// be silent.
- if (LocalDOMWindow* window = GetDocument().ExecutingWindow()) {
- if (LocalFrame* frame = window->GetFrame()) {
- frame->Console().AddMessage(MakeGarbageCollected<ConsoleMessage>(
- mojom::ConsoleMessageSource::kRendering,
- mojom::ConsoleMessageLevel::kWarning,
- "HTML Imports is deprecated and has now been removed as of "
- "M80. See "
- "https://www.chromestatus.com/features/5144752345317376 "
- "and https://developers.google.com/web/updates/2019/07/"
- "web-components-time-to-upgrade for more details."));
- }
+ if (auto* context = GetExecutionContext()) {
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kRendering,
+ mojom::blink::ConsoleMessageLevel::kWarning,
+ "HTML Imports is deprecated and has now been removed as of "
+ "M80. See "
+ "https://www.chromestatus.com/features/5144752345317376 "
+ "and https://developers.google.com/web/updates/2019/07/"
+ "web-components-time-to-upgrade for more details."));
}
}
}
@@ -138,15 +141,45 @@ void HTMLLinkElement::ParseAttribute(
} else if (name == html_names::kIntegrityAttr) {
integrity_ = value;
} else if (name == html_names::kImportanceAttr &&
- RuntimeEnabledFeatures::PriorityHintsEnabled(&GetDocument())) {
+ RuntimeEnabledFeatures::PriorityHintsEnabled(
+ GetExecutionContext())) {
UseCounter::Count(GetDocument(), WebFeature::kPriorityHints);
importance_ = value;
+ } else if (name == html_names::kResourcesAttr &&
+ RuntimeEnabledFeatures::SubresourceWebBundlesEnabled(
+ GetExecutionContext())) {
+ resources_->DidUpdateAttributeValue(params.old_value, value);
+
+ // Parse the attribute value as a space-separated list of urls
+ SpaceSplitString urls(value);
+ valid_resource_urls_.clear();
+ valid_resource_urls_.ReserveCapacityForSize(
+ SafeCast<wtf_size_t>(urls.size()));
+ for (wtf_size_t i = 0; i < urls.size(); ++i) {
+ KURL url = LinkWebBundle::ParseResourceUrl(urls[i]);
+ if (url.IsValid()) {
+ valid_resource_urls_.insert(std::move(url));
+ }
+ }
+ Process();
} else if (name == html_names::kDisabledAttr) {
UseCounter::Count(GetDocument(), WebFeature::kHTMLLinkElementDisabled);
if (params.reason == AttributeModificationReason::kByParser)
UseCounter::Count(GetDocument(), WebFeature::kHTMLLinkElementDisabledByParser);
- if (LinkStyle* link = GetLinkStyle())
+ // TODO(crbug.com/1087043): Remove this if() condition once the feature has
+ // landed and no compat issues are reported.
+ if (RuntimeEnabledFeatures::LinkDisabledNewSpecBehaviorEnabled(
+ GetExecutionContext())) {
+ LinkStyle* link = GetLinkStyle();
+ if (!link) {
+ link = MakeGarbageCollected<LinkStyle>(this);
+ link_ = link;
+ }
link->SetDisabledState(!value.IsNull());
+ } else {
+ if (LinkStyle* link = GetLinkStyle())
+ link->SetDisabledState(!value.IsNull());
+ }
} else {
if (name == html_names::kTitleAttr) {
if (LinkStyle* link = GetLinkStyle())
@@ -208,9 +241,16 @@ LinkResource* HTMLLinkElement::LinkResourceToProcess() {
if (!link_) {
if (rel_attribute_.IsImport()) {
// Only create an import link when HTML imports are enabled.
- if (!RuntimeEnabledFeatures::HTMLImportsEnabled(&GetDocument()))
+ if (!RuntimeEnabledFeatures::HTMLImportsEnabled(GetExecutionContext()))
return nullptr;
link_ = MakeGarbageCollected<LinkImport>(this);
+ } else if (rel_attribute_.IsWebBundle()) {
+ // Only create a webbundle link when SubresourceWebBundles are enabled.
+ if (!RuntimeEnabledFeatures::SubresourceWebBundlesEnabled(
+ GetExecutionContext())) {
+ return nullptr;
+ }
+ link_ = MakeGarbageCollected<LinkWebBundle>(this);
} else if (rel_attribute_.IsManifest()) {
link_ = MakeGarbageCollected<LinkManifest>(this);
} else {
@@ -438,11 +478,16 @@ DOMTokenList* HTMLLinkElement::sizes() const {
return sizes_.Get();
}
-void HTMLLinkElement::Trace(Visitor* visitor) {
+DOMTokenList* HTMLLinkElement::resources() const {
+ return resources_.Get();
+}
+
+void HTMLLinkElement::Trace(Visitor* visitor) const {
visitor->Trace(link_);
visitor->Trace(sizes_);
visitor->Trace(link_loader_);
visitor->Trace(rel_list_);
+ visitor->Trace(resources_);
HTMLElement::Trace(visitor);
LinkLoaderClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_link_element.h b/chromium/third_party/blink/renderer/core/html/html_link_element.h
index 9ba0c4ea32c..39a5e8c136c 100644
--- a/chromium/third_party/blink/renderer/core/html/html_link_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_link_element.h
@@ -38,6 +38,7 @@
#include "third_party/blink/renderer/core/html/rel_list.h"
#include "third_party/blink/renderer/core/loader/link_loader_client.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
namespace blink {
@@ -97,6 +98,13 @@ class CORE_EXPORT HTMLLinkElement final : public HTMLElement,
DOMTokenList* sizes() const;
+ // IDL method.
+ DOMTokenList* resources() const;
+
+ const HashSet<KURL>& ValidResourceUrls() const {
+ return valid_resource_urls_;
+ }
+
void ScheduleEvent();
// From LinkLoaderClient
@@ -110,14 +118,21 @@ class CORE_EXPORT HTMLLinkElement final : public HTMLElement,
FetchParameters::DeferOption,
ResourceClient*);
bool IsAlternate() const {
- return GetLinkStyle()->IsUnset() && rel_attribute_.IsAlternate();
+ // TODO(crbug.com/1087043): Remove this if() condition once the feature has
+ // landed and no compat issues are reported.
+ bool not_explicitly_enabled =
+ !GetLinkStyle()->IsExplicitlyEnabled() ||
+ !RuntimeEnabledFeatures::LinkDisabledNewSpecBehaviorEnabled(
+ GetExecutionContext());
+ return GetLinkStyle()->IsUnset() && rel_attribute_.IsAlternate() &&
+ not_explicitly_enabled;
}
bool ShouldProcessStyle() {
return LinkResourceToProcess() && GetLinkStyle();
}
bool IsCreatedByParser() const { return created_by_parser_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
LinkStyle* GetLinkStyle() const;
@@ -168,6 +183,8 @@ class CORE_EXPORT HTMLLinkElement final : public HTMLElement,
Member<RelList> rel_list_;
LinkRelAttribute rel_attribute_;
String scope_;
+ Member<DOMTokenList> resources_;
+ HashSet<KURL> valid_resource_urls_;
bool created_by_parser_;
};
diff --git a/chromium/third_party/blink/renderer/core/html/html_link_element.idl b/chromium/third_party/blink/renderer/core/html/html_link_element.idl
index f8908901496..776b99b9007 100644
--- a/chromium/third_party/blink/renderer/core/html/html_link_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/html_link_element.idl
@@ -58,4 +58,9 @@
// Subresource Integrity
// https://w3c.github.io/webappsec-subresource-integrity/#HTMLLinkElement
[Reflect] attribute DOMString integrity;
+
+ // Subresource loading with Web Bundles
+ // https://github.com/WICG/webpackage/blob/master/explainers/subresource-loading.md
+ // crbug.com/1082020
+ [RuntimeEnabled=SubresourceWebBundles, PutForwards=value] readonly attribute DOMTokenList resources;
};
diff --git a/chromium/third_party/blink/renderer/core/html/html_link_element_sizes_attribute_test.cc b/chromium/third_party/blink/renderer/core/html/html_link_element_sizes_attribute_test.cc
index d4b821683cc..96454f83140 100644
--- a/chromium/third_party/blink/renderer/core/html/html_link_element_sizes_attribute_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_link_element_sizes_attribute_test.cc
@@ -16,7 +16,7 @@ class HTMLLinkElementSizesAttributeTest : public testing::Test {};
TEST(HTMLLinkElementSizesAttributeTest,
setSizesPropertyValue_updatesAttribute) {
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* link =
MakeGarbageCollected<HTMLLinkElement>(*document, CreateElementFlags());
DOMTokenList* sizes = link->sizes();
@@ -28,7 +28,7 @@ TEST(HTMLLinkElementSizesAttributeTest,
TEST(HTMLLinkElementSizesAttributeTest,
setSizesAttribute_updatesSizesPropertyValue) {
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* link =
MakeGarbageCollected<HTMLLinkElement>(*document, CreateElementFlags());
DOMTokenList* sizes = link->sizes();
diff --git a/chromium/third_party/blink/renderer/core/html/html_marquee_element.cc b/chromium/third_party/blink/renderer/core/html/html_marquee_element.cc
index d12321171a9..9fc8c4e546a 100644
--- a/chromium/third_party/blink/renderer/core/html/html_marquee_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_marquee_element.cc
@@ -88,7 +88,7 @@ class HTMLMarqueeElement::RequestAnimationFrameCallback final
marquee_->ContinueAnimation();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(marquee_);
FrameRequestCallbackCollection::FrameCallback::Trace(visitor);
}
@@ -108,7 +108,7 @@ class HTMLMarqueeElement::AnimationFinished final : public NativeEventListener {
marquee_->start();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(marquee_);
NativeEventListener::Trace(visitor);
}
@@ -486,7 +486,7 @@ AtomicString HTMLMarqueeElement::CreateTransform(double value) const {
String::NumberToStringECMAScript(value) + "px)";
}
-void HTMLMarqueeElement::Trace(Visitor* visitor) {
+void HTMLMarqueeElement::Trace(Visitor* visitor) const {
visitor->Trace(mover_);
visitor->Trace(player_);
HTMLElement::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/html_marquee_element.h b/chromium/third_party/blink/renderer/core/html/html_marquee_element.h
index a9461edb73b..87013d57fb6 100644
--- a/chromium/third_party/blink/renderer/core/html/html_marquee_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_marquee_element.h
@@ -33,7 +33,7 @@ class HTMLMarqueeElement final : public HTMLElement {
DEFINE_WRAPPERTYPEINFO();
public:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
explicit HTMLMarqueeElement(Document&);
diff --git a/chromium/third_party/blink/renderer/core/html/html_meta_element.cc b/chromium/third_party/blink/renderer/core/html/html_meta_element.cc
index 853f518aeb3..3c332ec87a0 100644
--- a/chromium/third_party/blink/renderer/core/html/html_meta_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_meta_element.cc
@@ -574,9 +574,19 @@ void HTMLMetaElement::ProcessContent() {
if (EqualIgnoringASCIICase(name_value, "viewport")) {
ProcessViewportContentAttribute(content_value,
ViewportDescription::kViewportMeta);
- } else if (EqualIgnoringASCIICase(name_value, "referrer")) {
+ } else if (EqualIgnoringASCIICase(name_value, "referrer") &&
+ GetExecutionContext()) {
UseCounter::Count(&GetDocument(),
WebFeature::kHTMLMetaElementReferrerPolicy);
+ if (!IsDescendantOf(GetDocument().head())) {
+ UseCounter::Count(&GetDocument(),
+ WebFeature::kHTMLMetaElementReferrerPolicyOutsideHead);
+ }
+ if (content_value.Contains(',')) {
+ UseCounter::Count(
+ &GetDocument(),
+ WebFeature::kHTMLMetaElementReferrerPolicyMultipleTokens);
+ }
GetExecutionContext()->ParseAndSetReferrerPolicy(
content_value, true /* support legacy keywords */);
} else if (EqualIgnoringASCIICase(name_value, "handheldfriendly") &&
diff --git a/chromium/third_party/blink/renderer/core/html/html_meter_element.cc b/chromium/third_party/blink/renderer/core/html/html_meter_element.cc
index ada15e6ea4b..079257257b0 100644
--- a/chromium/third_party/blink/renderer/core/html/html_meter_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_meter_element.cc
@@ -223,7 +223,7 @@ bool HTMLMeterElement::CanContainRangeEndPoint() const {
return GetComputedStyle() && !GetComputedStyle()->HasEffectiveAppearance();
}
-void HTMLMeterElement::Trace(Visitor* visitor) {
+void HTMLMeterElement::Trace(Visitor* visitor) const {
visitor->Trace(value_);
HTMLElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_meter_element.h b/chromium/third_party/blink/renderer/core/html/html_meter_element.h
index 3a6e50e713f..620f2cbf7fc 100644
--- a/chromium/third_party/blink/renderer/core/html/html_meter_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_meter_element.h
@@ -63,7 +63,7 @@ class CORE_EXPORT HTMLMeterElement final : public HTMLElement {
bool CanContainRangeEndPoint() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~HTMLMeterElement() override;
diff --git a/chromium/third_party/blink/renderer/core/html/html_no_script_element.cc b/chromium/third_party/blink/renderer/core/html/html_no_script_element.cc
index 64ecf0c1c11..e2d87dc9e51 100644
--- a/chromium/third_party/blink/renderer/core/html/html_no_script_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_no_script_element.cc
@@ -42,7 +42,7 @@ HTMLNoScriptElement::HTMLNoScriptElement(Document& document)
bool HTMLNoScriptElement::LayoutObjectIsNeeded(
const ComputedStyle& style) const {
- if (GetDocument().CanExecuteScripts(kNotAboutToExecuteScript))
+ if (GetExecutionContext()->CanExecuteScripts(kNotAboutToExecuteScript))
return false;
return Element::LayoutObjectIsNeeded(style);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_object_element.cc b/chromium/third_party/blink/renderer/core/html/html_object_element.cc
index 6a2465ce913..2f992e08868 100644
--- a/chromium/third_party/blink/renderer/core/html/html_object_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_object_element.cc
@@ -58,7 +58,7 @@ HTMLObjectElement::HTMLObjectElement(Document& document,
inline HTMLObjectElement::~HTMLObjectElement() = default;
-void HTMLObjectElement::Trace(Visitor* visitor) {
+void HTMLObjectElement::Trace(Visitor* visitor) const {
ListedElement::Trace(visitor);
HTMLPlugInElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_object_element.h b/chromium/third_party/blink/renderer/core/html/html_object_element.h
index 6c14c233483..bbc9e3683ad 100644
--- a/chromium/third_party/blink/renderer/core/html/html_object_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_object_element.h
@@ -46,7 +46,7 @@ class CORE_EXPORT HTMLObjectElement final : public HTMLPlugInElement,
public:
HTMLObjectElement(Document&, const CreateElementFlags);
~HTMLObjectElement() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Returns attributes that should be checked against Trusted Types
const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
diff --git a/chromium/third_party/blink/renderer/core/html/html_plugin_element.cc b/chromium/third_party/blink/renderer/core/html/html_plugin_element.cc
index f1211b41033..bf2a8b47037 100644
--- a/chromium/third_party/blink/renderer/core/html/html_plugin_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_plugin_element.cc
@@ -128,8 +128,8 @@ HTMLPlugInElement::HTMLPlugInElement(
should_prefer_plug_ins_for_images_(prefer_plug_ins_for_images_option ==
kShouldPreferPlugInsForImages) {
SetHasCustomStyleCallbacks();
- if (doc.GetScheduler()) {
- doc.GetScheduler()->RegisterStickyFeature(
+ if (auto* context = doc.GetExecutionContext()) {
+ context->GetScheduler()->RegisterStickyFeature(
SchedulingPolicy::Feature::kContainsPlugins,
{SchedulingPolicy::RecordMetricsForBackForwardCache()});
}
@@ -140,7 +140,7 @@ HTMLPlugInElement::~HTMLPlugInElement() {
DCHECK(!is_delaying_load_event_);
}
-void HTMLPlugInElement::Trace(Visitor* visitor) {
+void HTMLPlugInElement::Trace(Visitor* visitor) const {
visitor->Trace(image_loader_);
visitor->Trace(persisted_plugin_);
HTMLFrameOwnerElement::Trace(visitor);
@@ -272,8 +272,7 @@ bool HTMLPlugInElement::ShouldAccelerate() const {
return plugin && plugin->CcLayer();
}
-ParsedFeaturePolicy HTMLPlugInElement::ConstructContainerPolicy(
- Vector<String>*) const {
+ParsedFeaturePolicy HTMLPlugInElement::ConstructContainerPolicy() const {
// Plugin elements (<object> and <embed>) are not allowed to enable the
// fullscreen feature. Add an empty allowlist for the fullscreen feature so
// that the nested browsing context is unable to use the API, regardless of
@@ -725,7 +724,7 @@ bool HTMLPlugInElement::AllowedToLoadObject(const KURL& url,
// is specified.
return (!mime_type.IsEmpty() && url.IsEmpty()) ||
!MixedContentChecker::ShouldBlockFetch(
- frame, mojom::RequestContextType::OBJECT,
+ frame, mojom::RequestContextType::OBJECT, url,
ResourceRequest::RedirectStatus::kNoRedirect, url,
/* devtools_id= */ base::nullopt);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_plugin_element.h b/chromium/third_party/blink/renderer/core/html/html_plugin_element.h
index 56ffb6e89a6..58cd78b33b7 100644
--- a/chromium/third_party/blink/renderer/core/html/html_plugin_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_plugin_element.h
@@ -66,7 +66,7 @@ class CORE_EXPORT HTMLPlugInElement
public:
~HTMLPlugInElement() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool IsPlugin() const final { return true; }
@@ -99,8 +99,7 @@ class CORE_EXPORT HTMLPlugInElement
bool ShouldAccelerate() const;
- ParsedFeaturePolicy ConstructContainerPolicy(
- Vector<String>* /* messages */) const override;
+ ParsedFeaturePolicy ConstructContainerPolicy() const override;
bool IsImageType() const;
HTMLImageLoader* ImageLoader() const { return image_loader_.Get(); }
diff --git a/chromium/third_party/blink/renderer/core/html/html_plugin_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_plugin_element_test.cc
index 985076f427b..0e8b8147533 100644
--- a/chromium/third_party/blink/renderer/core/html/html_plugin_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_plugin_element_test.cc
@@ -25,10 +25,6 @@ class TestPluginLocalFrameClient : public EmptyLocalFrameClient {
int plugin_created_count() const { return plugin_created_count_; }
private:
- std::unique_ptr<WebURLLoaderFactory> CreateURLLoaderFactory() override {
- return Platform::Current()->CreateDefaultURLLoaderFactory();
- }
-
WebPluginContainerImpl* CreatePlugin(HTMLPlugInElement& element,
const KURL& url,
const Vector<String>& param_names,
diff --git a/chromium/third_party/blink/renderer/core/html/html_progress_element.cc b/chromium/third_party/blink/renderer/core/html/html_progress_element.cc
index 054bc294414..3c9c804cead 100644
--- a/chromium/third_party/blink/renderer/core/html/html_progress_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_progress_element.cc
@@ -147,7 +147,7 @@ bool HTMLProgressElement::ShouldAppearIndeterminate() const {
return !IsDeterminate();
}
-void HTMLProgressElement::Trace(Visitor* visitor) {
+void HTMLProgressElement::Trace(Visitor* visitor) const {
visitor->Trace(value_);
HTMLElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_progress_element.h b/chromium/third_party/blink/renderer/core/html/html_progress_element.h
index 1473489db2a..61bce3bfc06 100644
--- a/chromium/third_party/blink/renderer/core/html/html_progress_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_progress_element.h
@@ -48,7 +48,7 @@ class CORE_EXPORT HTMLProgressElement final : public HTMLElement {
bool CanContainRangeEndPoint() const override { return false; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~HTMLProgressElement() override;
diff --git a/chromium/third_party/blink/renderer/core/html/html_script_element.cc b/chromium/third_party/blink/renderer/core/html/html_script_element.cc
index fd8290a81c4..756865b88ef 100644
--- a/chromium/third_party/blink/renderer/core/html/html_script_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_script_element.cc
@@ -47,8 +47,7 @@ HTMLScriptElement::HTMLScriptElement(Document& document,
const CreateElementFlags flags)
: HTMLElement(html_names::kScriptTag, document),
children_changed_by_api_(false),
- loader_(InitializeScriptLoader(flags.IsCreatedByParser(),
- flags.WasAlreadyStarted())) {}
+ loader_(InitializeScriptLoader(flags)) {}
const AttrNameToTrustedType& HTMLScriptElement::GetCheckedAttributeTypes()
const {
@@ -94,7 +93,8 @@ void HTMLScriptElement::ParseAttribute(
} else if (params.name == html_names::kAsyncAttr) {
loader_->HandleAsyncAttribute();
} else if (params.name == html_names::kImportanceAttr &&
- RuntimeEnabledFeatures::PriorityHintsEnabled(&GetDocument())) {
+ RuntimeEnabledFeatures::PriorityHintsEnabled(
+ GetExecutionContext())) {
// The only thing we need to do for the the importance attribute/Priority
// Hints is count usage upon parsing. Processing the value happens when the
// element loads.
@@ -270,7 +270,7 @@ bool HTMLScriptElement::AllowInlineScriptForCSP(
const AtomicString& nonce,
const WTF::OrdinalNumber& context_line,
const String& script_content) {
- return GetDocument().GetContentSecurityPolicyForWorld()->AllowInline(
+ return GetExecutionContext()->GetContentSecurityPolicyForWorld()->AllowInline(
ContentSecurityPolicy::InlineType::kScript, this, script_content, nonce,
GetDocument().Url(), context_line);
}
@@ -309,7 +309,7 @@ Element& HTMLScriptElement::CloneWithoutAttributesAndChildren(
return *factory.CreateElement(TagQName(), flags, IsValue());
}
-void HTMLScriptElement::Trace(Visitor* visitor) {
+void HTMLScriptElement::Trace(Visitor* visitor) const {
visitor->Trace(loader_);
HTMLElement::Trace(visitor);
ScriptElementBase::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/html_script_element.h b/chromium/third_party/blink/renderer/core/html/html_script_element.h
index 6315197c09a..ccafa59fc93 100644
--- a/chromium/third_party/blink/renderer/core/html/html_script_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_script_element.h
@@ -64,7 +64,7 @@ class CORE_EXPORT HTMLScriptElement final : public HTMLElement,
Document& GetDocument() const override;
ExecutionContext* GetExecutionContext() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void FinishParsingChildren() override;
diff --git a/chromium/third_party/blink/renderer/core/html/html_script_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_script_element_test.cc
index 2ea58d2feea..c9c61cdd214 100644
--- a/chromium/third_party/blink/renderer/core/html/html_script_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_script_element_test.cc
@@ -22,7 +22,7 @@ class HTMLScriptElementTest : public testing::Test {
HTMLScriptElement* MakeScript() {
HTMLScriptElement* script = To<HTMLScriptElement>(
document().body()->AppendChild(MakeGarbageCollected<HTMLScriptElement>(
- document(), CreateElementFlags::ByParser())));
+ document(), CreateElementFlags::ByParser(&document()))));
EXPECT_TRUE(script);
return script;
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_slot_element.cc b/chromium/third_party/blink/renderer/core/html/html_slot_element.cc
index c0d3b990d97..d5231b5b194 100644
--- a/chromium/third_party/blink/renderer/core/html/html_slot_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_slot_element.cc
@@ -746,7 +746,7 @@ bool HTMLSlotElement::HasAssignedNodesSlow() const {
return assignment.FindHostChildBySlotName(GetName());
}
-void HTMLSlotElement::Trace(Visitor* visitor) {
+void HTMLSlotElement::Trace(Visitor* visitor) const {
visitor->Trace(assigned_nodes_);
visitor->Trace(flat_tree_children_);
visitor->Trace(assigned_nodes_candidates_);
diff --git a/chromium/third_party/blink/renderer/core/html/html_slot_element.h b/chromium/third_party/blink/renderer/core/html/html_slot_element.h
index dab5c1f8416..2e0b527ac04 100644
--- a/chromium/third_party/blink/renderer/core/html/html_slot_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_slot_element.h
@@ -118,7 +118,7 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement {
void ClearAssignedNodesCandidates();
void RemoveAssignedNodeCandidate(Node&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
InsertionNotificationRequest InsertedInto(ContainerNode&) final;
diff --git a/chromium/third_party/blink/renderer/core/html/html_source_element.cc b/chromium/third_party/blink/renderer/core/html/html_source_element.cc
index c65bd23aebe..b3e2f46957b 100644
--- a/chromium/third_party/blink/renderer/core/html/html_source_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_source_element.cc
@@ -49,7 +49,7 @@ class HTMLSourceElement::Listener final : public MediaQueryListListener {
}
void ClearElement() { element_ = nullptr; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(element_);
MediaQueryListListener::Trace(visitor);
}
@@ -184,7 +184,7 @@ void HTMLSourceElement::NotifyMediaQueryChanged() {
picture->SourceOrMediaChanged();
}
-void HTMLSourceElement::Trace(Visitor* visitor) {
+void HTMLSourceElement::Trace(Visitor* visitor) const {
visitor->Trace(media_query_list_);
visitor->Trace(listener_);
HTMLElement::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/html_source_element.h b/chromium/third_party/blink/renderer/core/html/html_source_element.h
index 578e2eef779..2c461edcaf6 100644
--- a/chromium/third_party/blink/renderer/core/html/html_source_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_source_element.h
@@ -53,7 +53,7 @@ class HTMLSourceElement final : public HTMLElement {
void RemoveMediaQueryListListener();
void AddMediaQueryListListener();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DispatchPendingEvent();
diff --git a/chromium/third_party/blink/renderer/core/html/html_style_element.cc b/chromium/third_party/blink/renderer/core/html/html_style_element.cc
index e49545b4d73..1fb65d80835 100644
--- a/chromium/third_party/blink/renderer/core/html/html_style_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_style_element.cc
@@ -148,7 +148,7 @@ void HTMLStyleElement::setDisabled(bool set_disabled) {
style_sheet->setDisabled(set_disabled);
}
-void HTMLStyleElement::Trace(Visitor* visitor) {
+void HTMLStyleElement::Trace(Visitor* visitor) const {
StyleElement::Trace(visitor);
HTMLElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_style_element.h b/chromium/third_party/blink/renderer/core/html/html_style_element.h
index e9c77140b26..56c3e51316e 100644
--- a/chromium/third_party/blink/renderer/core/html/html_style_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_style_element.h
@@ -44,7 +44,7 @@ class CORE_EXPORT HTMLStyleElement final : public HTMLElement,
bool disabled() const;
void setDisabled(bool);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Always call this asynchronously because this can cause synchronous
diff --git a/chromium/third_party/blink/renderer/core/html/html_table_element.cc b/chromium/third_party/blink/renderer/core/html/html_table_element.cc
index b7693232ba2..7fbf2d4e948 100644
--- a/chromium/third_party/blink/renderer/core/html/html_table_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_table_element.cc
@@ -329,8 +329,8 @@ void HTMLTableElement::CollectStyleForPresentationAttribute(
WebFeature::kHTMLTableElementPresentationAttributeBackground);
CSSImageValue* image_value = MakeGarbageCollected<CSSImageValue>(
AtomicString(url), GetDocument().CompleteURL(url),
- Referrer(GetDocument().OutgoingReferrer(),
- GetDocument().GetReferrerPolicy()),
+ Referrer(GetExecutionContext()->OutgoingReferrer(),
+ GetExecutionContext()->GetReferrerPolicy()),
OriginClean::kTrue, false /* is_ad_related */);
style->SetProperty(
CSSPropertyValue(GetCSSPropertyBackgroundImage(), *image_value));
@@ -633,7 +633,7 @@ const AtomicString& HTMLTableElement::Summary() const {
return FastGetAttribute(html_names::kSummaryAttr);
}
-void HTMLTableElement::Trace(Visitor* visitor) {
+void HTMLTableElement::Trace(Visitor* visitor) const {
visitor->Trace(shared_cell_style_);
HTMLElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_table_element.h b/chromium/third_party/blink/renderer/core/html/html_table_element.h
index d3f59e00204..7cfaf43a8a5 100644
--- a/chromium/third_party/blink/renderer/core/html/html_table_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_table_element.h
@@ -73,7 +73,7 @@ class CORE_EXPORT HTMLTableElement final : public HTMLElement {
bool HasNonInBodyInsertionMode() const override { return true; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~HTMLTableElement() override;
diff --git a/chromium/third_party/blink/renderer/core/html/html_table_part_element.cc b/chromium/third_party/blink/renderer/core/html/html_table_part_element.cc
index 5d04bf78b73..8b7d3c33156 100644
--- a/chromium/third_party/blink/renderer/core/html/html_table_part_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_table_part_element.cc
@@ -62,8 +62,8 @@ void HTMLTablePartElement::CollectStyleForPresentationAttribute(
WebFeature::kHTMLTableElementPresentationAttributeBackground);
CSSImageValue* image_value = MakeGarbageCollected<CSSImageValue>(
AtomicString(url), GetDocument().CompleteURL(url),
- Referrer(GetDocument().OutgoingReferrer(),
- GetDocument().GetReferrerPolicy()),
+ Referrer(GetExecutionContext()->OutgoingReferrer(),
+ GetExecutionContext()->GetReferrerPolicy()),
OriginClean::kTrue, false /* is_ad_related */);
style->SetProperty(
CSSPropertyValue(GetCSSPropertyBackgroundImage(), *image_value));
diff --git a/chromium/third_party/blink/renderer/core/html/html_table_row_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_table_row_element_test.cc
index 8ccf5d44f08..84b43028542 100644
--- a/chromium/third_party/blink/renderer/core/html/html_table_row_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_table_row_element_test.cc
@@ -16,14 +16,14 @@ namespace blink {
// https://html.spec.whatwg.org/C/#dom-tr-rowindex
TEST(HTMLTableRowElementTest, rowIndex_notInTable) {
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* row = MakeGarbageCollected<HTMLTableRowElement>(*document);
EXPECT_EQ(-1, row->rowIndex())
<< "rows not in tables should have row index -1";
}
TEST(HTMLTableRowElementTest, rowIndex_directChildOfTable) {
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* table = MakeGarbageCollected<HTMLTableElement>(*document);
auto* row = MakeGarbageCollected<HTMLTableRowElement>(*document);
table->AppendChild(row);
@@ -32,7 +32,7 @@ TEST(HTMLTableRowElementTest, rowIndex_directChildOfTable) {
}
TEST(HTMLTableRowElementTest, rowIndex_inUnrelatedElementInTable) {
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* table = MakeGarbageCollected<HTMLTableElement>(*document);
// Almost any element will do; what's pertinent is that this is not
// THEAD, TBODY or TFOOT.
diff --git a/chromium/third_party/blink/renderer/core/html/html_template_element.cc b/chromium/third_party/blink/renderer/core/html/html_template_element.cc
index 25d817119e2..2cbed912ebc 100644
--- a/chromium/third_party/blink/renderer/core/html/html_template_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_template_element.cc
@@ -46,7 +46,7 @@ HTMLTemplateElement::HTMLTemplateElement(Document& document)
HTMLTemplateElement::~HTMLTemplateElement() = default;
DocumentFragment* HTMLTemplateElement::ContentInternal() const {
- if (!content_)
+ if (!content_ && GetExecutionContext())
content_ = MakeGarbageCollected<TemplateContentDocumentFragment>(
GetDocument().EnsureTemplateDocument(),
const_cast<HTMLTemplateElement*>(this));
@@ -66,7 +66,7 @@ DocumentFragment* HTMLTemplateElement::DeclarativeShadowContent() const {
void HTMLTemplateElement::CloneNonAttributePropertiesFrom(
const Element& source,
CloneChildrenFlag flag) {
- if (flag == CloneChildrenFlag::kSkip)
+ if (flag == CloneChildrenFlag::kSkip || !GetExecutionContext())
return;
DCHECK_NE(flag, CloneChildrenFlag::kCloneWithShadows);
auto& html_template_element = To<HTMLTemplateElement>(source);
@@ -76,12 +76,12 @@ void HTMLTemplateElement::CloneNonAttributePropertiesFrom(
void HTMLTemplateElement::DidMoveToNewDocument(Document& old_document) {
HTMLElement::DidMoveToNewDocument(old_document);
- if (!content_)
+ if (!content_ || !GetExecutionContext())
return;
GetDocument().EnsureTemplateDocument().AdoptIfNeeded(*content_);
}
-void HTMLTemplateElement::Trace(Visitor* visitor) {
+void HTMLTemplateElement::Trace(Visitor* visitor) const {
visitor->Trace(content_);
HTMLElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_template_element.h b/chromium/third_party/blink/renderer/core/html/html_template_element.h
index 6cfc5b166af..5db37948794 100644
--- a/chromium/third_party/blink/renderer/core/html/html_template_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_template_element.h
@@ -53,7 +53,7 @@ class CORE_EXPORT HTMLTemplateElement final : public HTMLElement {
bool HasNonInBodyInsertionMode() const override { return true; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
DocumentFragment* content() const;
diff --git a/chromium/third_party/blink/renderer/core/html/html_view_source_document.cc b/chromium/third_party/blink/renderer/core/html/html_view_source_document.cc
index c737b7b2675..c1f2ebb0e2c 100644
--- a/chromium/third_party/blink/renderer/core/html/html_view_source_document.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_view_source_document.cc
@@ -335,7 +335,7 @@ int HTMLViewSourceDocument::AddSrcset(const String& source,
return end;
}
-void HTMLViewSourceDocument::Trace(Visitor* visitor) {
+void HTMLViewSourceDocument::Trace(Visitor* visitor) const {
visitor->Trace(current_);
visitor->Trace(tbody_);
visitor->Trace(td_);
diff --git a/chromium/third_party/blink/renderer/core/html/html_view_source_document.h b/chromium/third_party/blink/renderer/core/html/html_view_source_document.h
index 87bf8b54dc8..7076c6186eb 100644
--- a/chromium/third_party/blink/renderer/core/html/html_view_source_document.h
+++ b/chromium/third_party/blink/renderer/core/html/html_view_source_document.h
@@ -40,7 +40,7 @@ class CORE_EXPORT HTMLViewSourceDocument final : public HTMLDocument {
void AddSource(const String&, HTMLToken&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
DocumentParser* CreateParser() override;
diff --git a/chromium/third_party/blink/renderer/core/html/image_document.cc b/chromium/third_party/blink/renderer/core/html/image_document.cc
index 3ae208645a9..f33f26ed020 100644
--- a/chromium/third_party/blink/renderer/core/html/image_document.cc
+++ b/chromium/third_party/blink/renderer/core/html/image_document.cc
@@ -69,7 +69,7 @@ class ImageEventListener : public NativeEventListener {
void Invoke(ExecutionContext*, Event*) override;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(doc_);
NativeEventListener::Trace(visitor);
}
@@ -99,7 +99,7 @@ class ImageDocumentParser : public RawDataDocumentParser {
return To<ImageDocument>(RawDataDocumentParser::GetDocument());
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(image_resource_);
RawDataDocumentParser::Trace(visitor);
}
@@ -562,7 +562,7 @@ bool ImageDocument::ShouldShrinkToFit() const {
return GetFrame()->IsMainFrame() && !is_wrap_content_web_view;
}
-void ImageDocument::Trace(Visitor* visitor) {
+void ImageDocument::Trace(Visitor* visitor) const {
visitor->Trace(div_element_);
visitor->Trace(image_element_);
HTMLDocument::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/image_document.h b/chromium/third_party/blink/renderer/core/html/image_document.h
index a9aa1335792..fec132d0867 100644
--- a/chromium/third_party/blink/renderer/core/html/image_document.h
+++ b/chromium/third_party/blink/renderer/core/html/image_document.h
@@ -52,7 +52,7 @@ class CORE_EXPORT ImageDocument final : public HTMLDocument {
void UpdateTitle();
bool ShouldShrinkToFit() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
DocumentParser* CreateParser() override;
diff --git a/chromium/third_party/blink/renderer/core/html/image_document_test.cc b/chromium/third_party/blink/renderer/core/html/image_document_test.cc
index 1e7cc5c37bc..0c08423a3c8 100644
--- a/chromium/third_party/blink/renderer/core/html/image_document_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/image_document_test.cc
@@ -19,6 +19,7 @@
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
namespace blink {
@@ -83,8 +84,6 @@ class ImageDocumentTest : public testing::Test {
void CreateDocumentWithoutLoadingImage(int view_width, int view_height);
void CreateDocument(int view_width, int view_height);
- DocumentParser* StartLoadingImage();
- void LoadImage();
ImageDocument& GetDocument() const;
@@ -93,10 +92,14 @@ class ImageDocumentTest : public testing::Test {
void SetPageZoom(float);
void SetWindowToViewportScalingFactor(float);
+ void SetForceZeroLayoutHeight(bool);
private:
Persistent<WindowToViewportScalingChromeClient> chrome_client_;
std::unique_ptr<DummyPageHolder> dummy_page_holder_;
+ float page_zoom_factor_ = 0.0f;
+ float viewport_scaling_factor_ = 0.0f;
+ base::Optional<bool> force_zero_layout_height_;
};
void ImageDocumentTest::CreateDocumentWithoutLoadingImage(int view_width,
@@ -109,19 +112,29 @@ void ImageDocumentTest::CreateDocumentWithoutLoadingImage(int view_width,
dummy_page_holder_ = std::make_unique<DummyPageHolder>(
IntSize(view_width, view_height), &page_clients);
- LocalFrame& frame = dummy_page_holder_->GetFrame();
- frame.GetDocument()->Shutdown();
- DocumentInit init =
- DocumentInit::Create()
- .WithDocumentLoader(frame.Loader().GetDocumentLoader())
- .WithTypeFrom("image/jpeg");
- frame.DomWindow()->InstallNewDocument(init);
- frame.GetDocument()->SetURL(KURL("http://www.example.com/image.jpg"));
+ if (page_zoom_factor_)
+ dummy_page_holder_->GetFrame().SetPageZoomFactor(page_zoom_factor_);
+ if (viewport_scaling_factor_)
+ chrome_client_->SetScalingFactor(viewport_scaling_factor_);
+ if (force_zero_layout_height_.has_value()) {
+ dummy_page_holder_->GetPage().GetSettings().SetForceZeroLayoutHeight(
+ force_zero_layout_height_.value());
+ }
+
+ auto params = std::make_unique<WebNavigationParams>();
+ params->url = KURL("http://www.example.com/image.jpg");
+
+ const Vector<unsigned char>& data = JpegImage();
+ WebNavigationParams::FillStaticResponse(
+ params.get(), "image/jpeg", "UTF-8",
+ base::make_span(reinterpret_cast<const char*>(data.data()), data.size()));
+ dummy_page_holder_->GetFrame().Loader().CommitNavigation(std::move(params),
+ nullptr);
}
void ImageDocumentTest::CreateDocument(int view_width, int view_height) {
CreateDocumentWithoutLoadingImage(view_width, view_height);
- LoadImage();
+ blink::test::RunPendingTasks();
}
ImageDocument& ImageDocumentTest::GetDocument() const {
@@ -130,25 +143,23 @@ ImageDocument& ImageDocumentTest::GetDocument() const {
return *image_document;
}
-DocumentParser* ImageDocumentTest::StartLoadingImage() {
- DocumentParser* parser = GetDocument().ImplicitOpen(
- ParserSynchronizationPolicy::kForceSynchronousParsing);
- const Vector<unsigned char>& data = JpegImage();
- parser->AppendBytes(reinterpret_cast<const char*>(data.data()), data.size());
- return parser;
-}
-
-void ImageDocumentTest::LoadImage() {
- DocumentParser* parser = StartLoadingImage();
- parser->Finish();
-}
-
void ImageDocumentTest::SetPageZoom(float factor) {
- dummy_page_holder_->GetFrame().SetPageZoomFactor(factor);
+ page_zoom_factor_ = factor;
+ if (dummy_page_holder_)
+ dummy_page_holder_->GetFrame().SetPageZoomFactor(factor);
}
void ImageDocumentTest::SetWindowToViewportScalingFactor(float factor) {
- chrome_client_->SetScalingFactor(factor);
+ viewport_scaling_factor_ = factor;
+ if (chrome_client_)
+ chrome_client_->SetScalingFactor(factor);
+}
+
+void ImageDocumentTest::SetForceZeroLayoutHeight(bool force) {
+ force_zero_layout_height_ = force;
+ if (dummy_page_holder_) {
+ dummy_page_holder_->GetPage().GetSettings().SetForceZeroLayoutHeight(force);
+ }
}
TEST_F(ImageDocumentTest, ImageLoad) {
@@ -175,9 +186,8 @@ TEST_F(ImageDocumentTest, RestoreImageOnClick) {
}
TEST_F(ImageDocumentTest, InitialZoomDoesNotAffectScreenFit) {
- CreateDocumentWithoutLoadingImage(20, 10);
SetPageZoom(2.f);
- LoadImage();
+ CreateDocument(20, 10);
EXPECT_EQ(10, ImageWidth());
EXPECT_EQ(10, ImageHeight());
GetDocument().ImageClicked(4, 4);
@@ -198,17 +208,15 @@ TEST_F(ImageDocumentTest, ZoomingDoesNotChangeRelativeSize) {
}
TEST_F(ImageDocumentTest, ImageScalesDownWithDsf) {
- CreateDocumentWithoutLoadingImage(20, 30);
SetWindowToViewportScalingFactor(2.f);
- LoadImage();
+ CreateDocument(20, 30);
EXPECT_EQ(10, ImageWidth());
EXPECT_EQ(10, ImageHeight());
}
TEST_F(ImageDocumentTest, ImageNotCenteredWithForceZeroLayoutHeight) {
- CreateDocumentWithoutLoadingImage(80, 70);
- GetDocument().GetPage()->GetSettings().SetForceZeroLayoutHeight(true);
- LoadImage();
+ SetForceZeroLayoutHeight(true);
+ CreateDocument(80, 70);
EXPECT_FALSE(GetDocument().ShouldShrinkToFit());
EXPECT_EQ(0, GetDocument().ImageElement()->OffsetLeft());
EXPECT_EQ(0, GetDocument().ImageElement()->OffsetTop());
@@ -217,9 +225,8 @@ TEST_F(ImageDocumentTest, ImageNotCenteredWithForceZeroLayoutHeight) {
}
TEST_F(ImageDocumentTest, ImageCenteredWithoutForceZeroLayoutHeight) {
- CreateDocumentWithoutLoadingImage(80, 70);
- GetDocument().GetPage()->GetSettings().SetForceZeroLayoutHeight(false);
- LoadImage();
+ SetForceZeroLayoutHeight(false);
+ CreateDocument(80, 70);
EXPECT_TRUE(GetDocument().ShouldShrinkToFit());
EXPECT_EQ(15, GetDocument().ImageElement()->OffsetLeft());
EXPECT_EQ(10, GetDocument().ImageElement()->OffsetTop());
@@ -234,9 +241,8 @@ TEST_F(ImageDocumentTest, DomInteractive) {
TEST_F(ImageDocumentTest, ImageSrcChangedBeforeFinish) {
CreateDocumentWithoutLoadingImage(80, 70);
- DocumentParser* parser = StartLoadingImage();
GetDocument().ImageElement()->removeAttribute(html_names::kSrcAttr);
- parser->Finish();
+ blink::test::RunPendingTasks();
}
#if defined(OS_ANDROID)
@@ -246,9 +252,8 @@ TEST_F(ImageDocumentTest, ImageSrcChangedBeforeFinish) {
#endif
TEST_F(ImageDocumentTest, MAYBE(ImageCenteredAtDeviceScaleFactor)) {
- CreateDocumentWithoutLoadingImage(30, 30);
SetWindowToViewportScalingFactor(1.5f);
- LoadImage();
+ CreateDocument(30, 30);
EXPECT_TRUE(GetDocument().ShouldShrinkToFit());
GetDocument().ImageClicked(15, 27);
diff --git a/chromium/third_party/blink/renderer/core/html/imports/README.md b/chromium/third_party/blink/renderer/core/html/imports/README.md
index c31bf6d9d1d..35836d4c89a 100644
--- a/chromium/third_party/blink/renderer/core/html/imports/README.md
+++ b/chromium/third_party/blink/renderer/core/html/imports/README.md
@@ -13,7 +13,7 @@ HTML Imports form a tree:
* The root of the tree is `HTMLImportTreeRoot`.
* The `HTMLImportTreeRoot` is owned by `HTMLImportsController`, which is owned
- by the master document as a `DocumentSupplement`.
+ by the tree_root document as a `DocumentSupplement`.
* The non-root nodes are `HTMLImportChild`. They are all owned by
`HTMLImporTreeRoot`. `LinkStyle` is wired into `HTMLImportChild` by
implementing `HTMLImportChildClient` interface.
diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import.h b/chromium/third_party/blink/renderer/core/html/imports/html_import.h
index cc874f35d79..69741e2ea50 100644
--- a/chromium/third_party/blink/renderer/core/html/imports/html_import.h
+++ b/chromium/third_party/blink/renderer/core/html/imports/html_import.h
@@ -66,7 +66,7 @@ class HTMLImport : public GarbageCollected<HTMLImport>,
virtual void StateWillChange() {}
virtual void StateDidChange();
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
// Stating from most conservative state.
diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_child.cc b/chromium/third_party/blink/renderer/core/html/imports/html_import_child.cc
index 301cb4a5ee8..ac7aad3cf3d 100644
--- a/chromium/third_party/blink/renderer/core/html/imports/html_import_child.cc
+++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_child.cc
@@ -174,7 +174,7 @@ void HTMLImportChild::Normalize() {
}
}
-void HTMLImportChild::Trace(Visitor* visitor) {
+void HTMLImportChild::Trace(Visitor* visitor) const {
visitor->Trace(custom_element_microtask_step_);
visitor->Trace(loader_);
visitor->Trace(client_);
diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_child.h b/chromium/third_party/blink/renderer/core/html/imports/html_import_child.h
index e8265e3ea31..7ba5533b9e5 100644
--- a/chromium/third_party/blink/renderer/core/html/imports/html_import_child.h
+++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_child.h
@@ -70,7 +70,7 @@ class HTMLImportChild final : public HTMLImport {
HTMLImportLoader* Loader() const final;
void StateWillChange() final;
void StateDidChange() final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void DidFinishLoading();
void DidFinishUpgradingCustomElements();
diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_child_client.h b/chromium/third_party/blink/renderer/core/html/imports/html_import_child_client.h
index 04525f82465..1b37fbb7828 100644
--- a/chromium/third_party/blink/renderer/core/html/imports/html_import_child_client.h
+++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_child_client.h
@@ -45,7 +45,7 @@ class HTMLImportChildClient : public GarbageCollectedMixin {
virtual void ImportChildWasDisposed(HTMLImportChild*) = 0;
virtual bool IsSync() const = 0;
virtual HTMLLinkElement* Link() = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.cc b/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.cc
index a921505e787..b23f609a9a5 100644
--- a/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.cc
+++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.cc
@@ -96,16 +96,21 @@ HTMLImportLoader::State HTMLImportLoader::StartWritingAndParsing(
const ResourceResponse& response) {
DCHECK(controller_);
DCHECK(!imports_.IsEmpty());
- Document* master = controller_->Master();
+ Document* tree_root = controller_->TreeRoot();
document_ = MakeGarbageCollected<HTMLDocument>(
DocumentInit::Create()
.WithImportsController(controller_)
- .WithContextDocument(master->ContextDocument())
- .WithRegistrationContext(master->RegistrationContext())
- .WithContentSecurityPolicy(master->GetContentSecurityPolicy())
+ .WithExecutionContext(tree_root->GetExecutionContext())
+ .WithRegistrationContext(tree_root->RegistrationContext())
.WithURL(response.CurrentRequestUrl()));
- document_->OpenForNavigation(kAllowAsynchronousParsing, response.MimeType(),
- "UTF-8");
+ // imports expect to be able to log CSP errors, which requires binding the CSP
+ // to a CSP delegate.
+ document_->BindContentSecurityPolicy();
+ document_->OpenForNavigation(
+ RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()
+ ? kAllowDeferredParsing
+ : kAllowAsynchronousParsing,
+ response.MimeType(), "UTF-8");
DocumentParser* parser = document_->Parser();
DCHECK(parser);
@@ -204,7 +209,7 @@ V0CustomElementSyncMicrotaskQueue* HTMLImportLoader::MicrotaskQueue() const {
return microtask_queue_;
}
-void HTMLImportLoader::Trace(Visitor* visitor) {
+void HTMLImportLoader::Trace(Visitor* visitor) const {
visitor->Trace(controller_);
visitor->Trace(imports_);
visitor->Trace(document_);
diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.h b/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.h
index cbae34ab7f2..70d6505f3a6 100644
--- a/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.h
+++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.h
@@ -87,7 +87,7 @@ class HTMLImportLoader final : public GarbageCollected<HTMLImportLoader>,
V0CustomElementSyncMicrotaskQueue* MicrotaskQueue() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// RawResourceClient overrides:
diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.cc b/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.cc
index d88f5f79f8d..f21358abc74 100644
--- a/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.cc
+++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.cc
@@ -77,7 +77,7 @@ void HTMLImportTreeRoot::RecalcTimerFired(TimerBase*) {
HTMLImport::RecalcTreeState(this);
}
-void HTMLImportTreeRoot::Trace(Visitor* visitor) {
+void HTMLImportTreeRoot::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(imports_);
HTMLImport::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.h b/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.h
index 5bfb3fe17c2..02a484bcae1 100644
--- a/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.h
+++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.h
@@ -33,7 +33,7 @@ class HTMLImportTreeRoot final : public HTMLImport, public NameClient {
HTMLImportChild* Add(HTMLImportChild*);
HTMLImportChild* Find(const KURL&) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override {
return "HTMLImportTreeRoot";
}
diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.cc b/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.cc
index 4e9573b0311..84e47deda9b 100644
--- a/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.cc
+++ b/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.cc
@@ -42,8 +42,8 @@
namespace blink {
-HTMLImportsController::HTMLImportsController(Document& master)
- : root_(MakeGarbageCollected<HTMLImportTreeRoot>(&master)) {}
+HTMLImportsController::HTMLImportsController(Document& tree_root)
+ : root_(MakeGarbageCollected<HTMLImportTreeRoot>(&tree_root)) {}
void HTMLImportsController::Dispose() {
// TODO(tkent): We copy loaders_ before iteration to avoid crashes.
@@ -117,7 +117,7 @@ HTMLImportChild* HTMLImportsController::Load(const Document& parent_document,
}
scoped_refptr<const SecurityOrigin> security_origin =
- Master()->GetSecurityOrigin();
+ TreeRoot()->GetSecurityOrigin();
ResourceFetcher* fetcher = parent->GetDocument()->Fetcher();
if (parent->GetDocument()->ImportsController()) {
@@ -137,7 +137,7 @@ HTMLImportChild* HTMLImportsController::Load(const Document& parent_document,
return child;
}
-Document* HTMLImportsController::Master() const {
+Document* HTMLImportsController::TreeRoot() const {
return root_ ? root_->GetDocument() : nullptr;
}
@@ -159,7 +159,7 @@ HTMLImportLoader* HTMLImportsController::LoaderFor(
return nullptr;
}
-void HTMLImportsController::Trace(Visitor* visitor) {
+void HTMLImportsController::Trace(Visitor* visitor) const {
visitor->Trace(root_);
visitor->Trace(loaders_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.h b/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.h
index ddb6933ec8b..7421c2a0573 100644
--- a/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.h
+++ b/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.h
@@ -60,13 +60,13 @@ class HTMLImportsController final
HTMLImportChildClient*,
FetchParameters&);
- Document* Master() const;
+ Document* TreeRoot() const;
wtf_size_t LoaderCount() const { return loaders_.size(); }
HTMLImportLoader* LoaderAt(wtf_size_t i) const { return loaders_[i]; }
HTMLImportLoader* LoaderFor(const Document&) const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void Dispose();
diff --git a/chromium/third_party/blink/renderer/core/html/imports/link_import.cc b/chromium/third_party/blink/renderer/core/html/imports/link_import.cc
index 01ca5ecdf25..85aa9e01c88 100644
--- a/chromium/third_party/blink/renderer/core/html/imports/link_import.cc
+++ b/chromium/third_party/blink/renderer/core/html/imports/link_import.cc
@@ -128,7 +128,7 @@ void LinkImport::OwnerRemoved() {
GetDocument().GetStyleEngine().HtmlImportAddedOrRemoved();
}
-void LinkImport::Trace(Visitor* visitor) {
+void LinkImport::Trace(Visitor* visitor) const {
visitor->Trace(child_);
HTMLImportChildClient::Trace(visitor);
LinkResource::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/imports/link_import.h b/chromium/third_party/blink/renderer/core/html/imports/link_import.h
index b6f1b8fcbc2..050903e0239 100644
--- a/chromium/third_party/blink/renderer/core/html/imports/link_import.h
+++ b/chromium/third_party/blink/renderer/core/html/imports/link_import.h
@@ -55,7 +55,7 @@ class LinkImport final : public LinkResource, public HTMLImportChildClient {
void Process() final;
LinkResourceType GetType() const final { return kImport; }
bool HasLoaded() const final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void OwnerInserted() final;
void OwnerRemoved() final;
diff --git a/chromium/third_party/blink/renderer/core/html/keywords.json5 b/chromium/third_party/blink/renderer/core/html/keywords.json5
index 411fc0bb7da..d1d3bae265f 100644
--- a/chromium/third_party/blink/renderer/core/html/keywords.json5
+++ b/chromium/third_party/blink/renderer/core/html/keywords.json5
@@ -90,5 +90,10 @@
"col",
"rowgroup",
"colgroup",
+
+ // This mode corresponds to virtualkeyboardpolicy
+ // https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/VirtualKeyboardPolicy/explainer.md
+ "auto",
+ "manual",
],
}
diff --git a/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc b/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc
index 24d34305f41..086f8f27796 100644
--- a/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc
+++ b/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc
@@ -382,7 +382,7 @@ void LazyLoadFrameObserver::RecordInitialDeferralAction(
}
}
-void LazyLoadFrameObserver::Trace(Visitor* visitor) {
+void LazyLoadFrameObserver::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(lazy_load_intersection_observer_);
visitor->Trace(visibility_metrics_observer_);
diff --git a/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.h b/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.h
index d79cf667b74..bdc66dc4e7a 100644
--- a/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.h
+++ b/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.h
@@ -53,7 +53,7 @@ class LazyLoadFrameObserver final
void LoadImmediately();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
struct LazyLoadRequestInfo;
diff --git a/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc
index 67c244fa972..90f6f81c3db 100644
--- a/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc
+++ b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc
@@ -335,7 +335,7 @@ bool LazyLoadImageObserver::IsFullyLoadableFirstKImageAndDecrementCount() {
return false;
}
-void LazyLoadImageObserver::Trace(Visitor* visitor) {
+void LazyLoadImageObserver::Trace(Visitor* visitor) const {
visitor->Trace(lazy_load_intersection_observer_);
visitor->Trace(visibility_metrics_observer_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h
index 5b89cd988cd..5d236775714 100644
--- a/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h
+++ b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h
@@ -49,7 +49,7 @@ class LazyLoadImageObserver final
bool IsFullyLoadableFirstKImageAndDecrementCount();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void LoadIfNearViewport(const HeapVector<Member<IntersectionObserverEntry>>&);
diff --git a/chromium/third_party/blink/renderer/core/html/link_rel_attribute.cc b/chromium/third_party/blink/renderer/core/html/link_rel_attribute.cc
index c4d5fddf615..acdd00411e8 100644
--- a/chromium/third_party/blink/renderer/core/html/link_rel_attribute.cc
+++ b/chromium/third_party/blink/renderer/core/html/link_rel_attribute.cc
@@ -50,7 +50,8 @@ LinkRelAttribute::LinkRelAttribute()
is_module_preload_(false),
is_service_worker_(false),
is_canonical_(false),
- is_monetization_(false) {}
+ is_monetization_(false),
+ is_web_bundle_(false) {}
LinkRelAttribute::LinkRelAttribute(const String& rel) : LinkRelAttribute() {
if (rel.IsEmpty())
@@ -102,6 +103,8 @@ LinkRelAttribute::LinkRelAttribute(const String& rel) : LinkRelAttribute() {
is_canonical_ = true;
} else if (EqualIgnoringASCIICase(link_type, "monetization")) {
is_monetization_ = true;
+ } else if (EqualIgnoringASCIICase(link_type, "webbundle")) {
+ is_web_bundle_ = true;
}
// Adding or removing a value here requires you to update
// RelList::supportedTokens()
diff --git a/chromium/third_party/blink/renderer/core/html/link_rel_attribute.h b/chromium/third_party/blink/renderer/core/html/link_rel_attribute.h
index 309cbcb0078..37f6ebf2532 100644
--- a/chromium/third_party/blink/renderer/core/html/link_rel_attribute.h
+++ b/chromium/third_party/blink/renderer/core/html/link_rel_attribute.h
@@ -61,6 +61,7 @@ class CORE_EXPORT LinkRelAttribute {
bool IsServiceWorker() const { return is_service_worker_; }
bool IsCanonical() const { return is_canonical_; }
bool IsMonetization() const { return is_monetization_; }
+ bool IsWebBundle() const { return is_web_bundle_; }
private:
mojom::blink::FaviconIconType icon_type_;
@@ -78,6 +79,7 @@ class CORE_EXPORT LinkRelAttribute {
bool is_service_worker_ : 1;
bool is_canonical_ : 1;
bool is_monetization_ : 1;
+ bool is_web_bundle_ : 1;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/link_rel_attribute_test.cc b/chromium/third_party/blink/renderer/core/html/link_rel_attribute_test.cc
index c4a142ff0fa..5b6c3ba1ac4 100644
--- a/chromium/third_party/blink/renderer/core/html/link_rel_attribute_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/link_rel_attribute_test.cc
@@ -43,7 +43,8 @@ static inline void TestLinkRelAttribute(const String& value,
bool is_link_prerender,
bool is_import = false,
bool is_preconnect = false,
- bool is_canonical = false) {
+ bool is_canonical = false,
+ bool is_web_bundle = false) {
SCOPED_TRACE(value.Utf8());
LinkRelAttribute link_rel_attribute(value);
ASSERT_EQ(is_style_sheet, link_rel_attribute.IsStyleSheet());
@@ -54,6 +55,7 @@ static inline void TestLinkRelAttribute(const String& value,
ASSERT_EQ(is_import, link_rel_attribute.IsImport());
ASSERT_EQ(is_preconnect, link_rel_attribute.IsPreconnect());
ASSERT_EQ(is_canonical, link_rel_attribute.IsCanonical());
+ ASSERT_EQ(is_web_bundle, link_rel_attribute.IsWebBundle());
}
TEST(LinkRelAttributeTest, Constructor) {
@@ -140,6 +142,12 @@ TEST(LinkRelAttributeTest, Constructor) {
TestLinkRelAttribute("caNONiCAL", false,
mojom::blink::FaviconIconType::kInvalid, false, false,
false, false, false, true);
+ TestLinkRelAttribute("webbundle", false,
+ mojom::blink::FaviconIconType::kInvalid, false, false,
+ false, false, false, false, true);
+ TestLinkRelAttribute("wEbBundle", false,
+ mojom::blink::FaviconIconType::kInvalid, false, false,
+ false, false, false, false, true);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/link_resource.cc b/chromium/third_party/blink/renderer/core/html/link_resource.cc
index c3b07b6bdaa..e7dd14f524e 100644
--- a/chromium/third_party/blink/renderer/core/html/link_resource.cc
+++ b/chromium/third_party/blink/renderer/core/html/link_resource.cc
@@ -47,7 +47,7 @@ bool LinkResource::ShouldLoadResource() const {
}
LocalFrame* LinkResource::LoadingFrame() const {
- return owner_->GetDocument().MasterDocument().GetFrame();
+ return owner_->GetDocument().TreeRootDocument().GetFrame();
}
Document& LinkResource::GetDocument() {
@@ -69,7 +69,7 @@ ExecutionContext* LinkResource::GetExecutionContext() {
return owner_->GetExecutionContext();
}
-void LinkResource::Trace(Visitor* visitor) {
+void LinkResource::Trace(Visitor* visitor) const {
visitor->Trace(owner_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/link_resource.h b/chromium/third_party/blink/renderer/core/html/link_resource.h
index c149a9dbee6..060124acb0e 100644
--- a/chromium/third_party/blink/renderer/core/html/link_resource.h
+++ b/chromium/third_party/blink/renderer/core/html/link_resource.h
@@ -59,7 +59,7 @@ class CORE_EXPORT LinkResource : public GarbageCollected<LinkResource> {
virtual void OwnerInserted() {}
virtual bool HasLoaded() const = 0;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
protected:
void Load();
diff --git a/chromium/third_party/blink/renderer/core/html/link_style.cc b/chromium/third_party/blink/renderer/core/html/link_style.cc
index ba9e774f8b2..5036ac1f0cb 100644
--- a/chromium/third_party/blink/renderer/core/html/link_style.cc
+++ b/chromium/third_party/blink/renderer/core/html/link_style.cc
@@ -202,6 +202,10 @@ void LinkStyle::RemovePendingSheet() {
void LinkStyle::SetDisabledState(bool disabled) {
LinkStyle::DisabledState old_disabled_state = disabled_state_;
disabled_state_ = disabled ? kDisabled : kEnabledViaScript;
+ // Whenever the disabled attribute is removed, set the link element's
+ // explicitly enabled attribute to true.
+ if (!disabled)
+ explicitly_enabled_ = true;
if (old_disabled_state == disabled_state_)
return;
@@ -231,8 +235,19 @@ void LinkStyle::SetDisabledState(bool disabled) {
}
if (sheet_) {
- sheet_->setDisabled(disabled);
- return;
+ // TODO(crbug.com/1087043): Remove this if() condition once the feature has
+ // landed and no compat issues are reported.
+ if (RuntimeEnabledFeatures::LinkDisabledNewSpecBehaviorEnabled(
+ GetExecutionContext())) {
+ DCHECK(disabled)
+ << "If link is being enabled, sheet_ shouldn't exist yet";
+ ClearSheet();
+ GetDocument().GetStyleEngine().SetNeedsActiveStyleUpdate(
+ owner_->GetTreeScope());
+ return;
+ } else {
+ sheet_->setDisabled(disabled);
+ }
}
if (disabled_state_ == kEnabledViaScript && owner_->ShouldProcessStyle())
@@ -324,7 +339,7 @@ void LinkStyle::Process() {
if (!GetDocument().GetSecurityOrigin()->CanDisplay(params.href))
return;
if (!GetDocument().GetContentSecurityPolicy()->AllowImageFromSource(
- params.href))
+ params.href, params.href, RedirectStatus::kNoRedirect))
return;
if (GetDocument().GetFrame())
GetDocument().GetFrame()->UpdateFaviconURL();
@@ -364,7 +379,7 @@ void LinkStyle::OwnerRemoved() {
ClearSheet();
}
-void LinkStyle::Trace(Visitor* visitor) {
+void LinkStyle::Trace(Visitor* visitor) const {
visitor->Trace(sheet_);
LinkResource::Trace(visitor);
ResourceClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/link_style.h b/chromium/third_party/blink/renderer/core/html/link_style.h
index 5c56f2dd233..2b4df40e3fd 100644
--- a/chromium/third_party/blink/renderer/core/html/link_style.h
+++ b/chromium/third_party/blink/renderer/core/html/link_style.h
@@ -36,7 +36,7 @@ class LinkStyle final : public LinkResource, ResourceClient {
void Process() override;
void OwnerRemoved() override;
bool HasLoaded() const override { return loaded_sheet_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void StartLoadingDynamicSheet();
void NotifyLoadedSheetAndAllCriticalSubresources(
@@ -54,6 +54,8 @@ class LinkStyle final : public LinkResource, ResourceClient {
}
bool IsUnset() const { return disabled_state_ == kUnset; }
+ bool IsExplicitlyEnabled() const { return explicitly_enabled_; }
+
CSSStyleSheet* Sheet() const { return sheet_.Get(); }
private:
@@ -76,6 +78,7 @@ class LinkStyle final : public LinkResource, ResourceClient {
DisabledState disabled_state_;
PendingSheetType pending_sheet_type_;
StyleEngineContext style_engine_context_;
+ bool explicitly_enabled_;
bool loading_;
bool fired_load_;
bool loaded_sheet_;
diff --git a/chromium/third_party/blink/renderer/core/html/link_web_bundle.cc b/chromium/third_party/blink/renderer/core/html/link_web_bundle.cc
new file mode 100644
index 00000000000..630a103ca50
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/link_web_bundle.cc
@@ -0,0 +1,49 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/html/link_web_bundle.h"
+
+namespace blink {
+
+LinkWebBundle::LinkWebBundle(HTMLLinkElement* owner) : LinkResource(owner) {}
+
+void LinkWebBundle::Process() {
+ // TODO(crbug.com/1082020): Implement this.
+}
+
+LinkResource::LinkResourceType LinkWebBundle::GetType() const {
+ return kOther;
+}
+
+bool LinkWebBundle::HasLoaded() const {
+ return false;
+}
+
+void LinkWebBundle::OwnerRemoved() {}
+
+// static
+KURL LinkWebBundle::ParseResourceUrl(const AtomicString& str) {
+ // The implementation is almost copy and paste from ParseExchangeURL() defined
+ // in services/data_decoder/web_bundle_parser.cc, replacing GURL with KURL.
+
+ // TODO(hayato): Consider to support a relative URL.
+ KURL url(str);
+ if (!url.IsValid())
+ return KURL();
+
+ // Exchange URL must not have a fragment or credentials.
+ if (url.HasFragmentIdentifier() || !url.User().IsEmpty() ||
+ !url.Pass().IsEmpty())
+ return KURL();
+
+ // For now, we allow only http: and https: schemes in Web Bundle URLs.
+ // TODO(crbug.com/966753): Revisit this once
+ // https://github.com/WICG/webpackage/issues/468 is resolved.
+ if (!url.ProtocolIsInHTTPFamily())
+ return KURL();
+
+ return url;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/link_web_bundle.h b/chromium/third_party/blink/renderer/core/html/link_web_bundle.h
new file mode 100644
index 00000000000..9d786eddf40
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/link_web_bundle.h
@@ -0,0 +1,37 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_LINK_WEB_BUNDLE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_LINK_WEB_BUNDLE_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/html/link_resource.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+
+namespace blink {
+
+// LinkWebBundle is used in the Subresource loading with Web Bundles feature.
+// See crbug.com/1082020 for details.
+// A <link rel="webbundle" ...> element creates LinkWebBundle.
+class CORE_EXPORT LinkWebBundle final : public LinkResource {
+ public:
+ explicit LinkWebBundle(HTMLLinkElement* owner);
+ ~LinkWebBundle() override = default;
+
+ void Process() override;
+ LinkResourceType GetType() const override;
+ bool HasLoaded() const override;
+ void OwnerRemoved() override;
+
+ // Parse the given |str| as a url. If |str| doesn't meet the criteria which
+ // WebBundles specification requires, this returns invalid empty KURL as an
+ // error.
+ // See
+ // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#name-parsing-the-index-section
+ static KURL ParseResourceUrl(const AtomicString& str);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_LINK_WEB_BUNDLE_H_
diff --git a/chromium/third_party/blink/renderer/core/html/link_web_bundle_test.cc b/chromium/third_party/blink/renderer/core/html/link_web_bundle_test.cc
new file mode 100644
index 00000000000..2d22d4bd180
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/link_web_bundle_test.cc
@@ -0,0 +1,85 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/html/link_web_bundle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/dom_token_list.h"
+#include "third_party/blink/renderer/core/html/html_link_element.h"
+
+namespace blink {
+
+namespace {
+
+void TestParseResourceUrl(const AtomicString& url, bool is_valid) {
+ ASSERT_EQ(LinkWebBundle::ParseResourceUrl(url).IsValid(), is_valid);
+}
+
+} // namespace
+
+TEST(LinkWebBundleTest, ParseResourceUrl) {
+ TestParseResourceUrl("https://test.example.com/", true);
+ TestParseResourceUrl("http://test.example.com/", true);
+ TestParseResourceUrl("https://user@test.example.com/", false);
+ TestParseResourceUrl("https://user:password@test.example.com/", false);
+ TestParseResourceUrl("https://test.example.com/#fragment", false);
+ TestParseResourceUrl("ftp://test.example.com/", false);
+ TestParseResourceUrl("file:///test.html", false);
+}
+
+TEST(LinkWebBundleTest, ResourcesAttribute) {
+ auto* document = Document::CreateForTest();
+ auto* link =
+ MakeGarbageCollected<HTMLLinkElement>(*document, CreateElementFlags());
+ DOMTokenList* resources = link->resources();
+ EXPECT_EQ(g_null_atom, resources->value());
+
+ link->setAttribute(html_names::kRelAttr, "webbundle");
+
+ // Valid url
+ link->setAttribute(html_names::kResourcesAttr, "https://test.example.com");
+ EXPECT_EQ("https://test.example.com", resources->value());
+ EXPECT_EQ(1u, link->ValidResourceUrls().size());
+ EXPECT_TRUE(
+ link->ValidResourceUrls().Contains(KURL("https://test.example.com")));
+
+ // Invalid urls
+ link->setAttribute(html_names::kResourcesAttr,
+ "https://user:test.example.com");
+ EXPECT_EQ("https://user:test.example.com", resources->value());
+ EXPECT_TRUE(link->ValidResourceUrls().IsEmpty());
+
+ link->setAttribute(html_names::kResourcesAttr,
+ "https://:pass@test.example.com");
+ EXPECT_TRUE(link->ValidResourceUrls().IsEmpty());
+
+ link->setAttribute(html_names::kResourcesAttr,
+ "https://test.example.com/#fragment");
+ EXPECT_TRUE(link->ValidResourceUrls().IsEmpty());
+
+ // Spece-separated valid urls
+ link->setAttribute(html_names::kResourcesAttr,
+ "https://test1.example.com https://test2.example.com");
+ EXPECT_EQ(2u, link->ValidResourceUrls().size());
+ EXPECT_TRUE(
+ link->ValidResourceUrls().Contains(KURL("https://test1.example.com")));
+ EXPECT_TRUE(
+ link->ValidResourceUrls().Contains(KURL("https://test2.example.com")));
+
+ // Space-separated valid and invalid urls
+ link->setAttribute(html_names::kResourcesAttr,
+ "https://test1.example.com https://user:test.example.com "
+ "https://test2.example.com");
+ EXPECT_EQ(
+ "https://test1.example.com https://user:test.example.com "
+ "https://test2.example.com",
+ resources->value());
+ EXPECT_EQ(2u, link->ValidResourceUrls().size());
+ EXPECT_TRUE(
+ link->ValidResourceUrls().Contains(KURL("https://test1.example.com")));
+ EXPECT_TRUE(
+ link->ValidResourceUrls().Contains(KURL("https://test2.example.com")));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.cc b/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.cc
index f435e762221..b2a180e58a8 100644
--- a/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.cc
@@ -89,7 +89,8 @@ bool AutoplayPolicy::IsDocumentAllowedToPlay(const Document& document) {
return false;
bool feature_policy_enabled =
- document.IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kAutoplay);
+ document.GetExecutionContext()->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kAutoplay);
for (Frame* frame = document.GetFrame(); frame;
frame = frame->Tree().Parent()) {
@@ -343,6 +344,7 @@ void AutoplayPolicy::OnIntersectionChangedForAutoplay(
if (ShouldAutoplay()) {
element_->paused_ = false;
+ element_->SetShowPosterFlag(false);
element_->ScheduleEvent(event_type_names::kPlay);
element_->ScheduleNotifyPlaying();
@@ -361,11 +363,12 @@ void AutoplayPolicy::MaybeSetAutoplayInitiated() {
autoplay_initiated_ = true;
- const Document& document = element_->GetDocument();
bool feature_policy_enabled =
- document.IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kAutoplay);
+ element_->GetExecutionContext() &&
+ element_->GetExecutionContext()->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kAutoplay);
- for (Frame* frame = document.GetFrame(); frame;
+ for (Frame* frame = element_->GetDocument().GetFrame(); frame;
frame = frame->Tree().Parent()) {
if (frame->HasStickyUserActivation() ||
frame->HadStickyUserActivationBeforeNavigation()) {
@@ -385,7 +388,7 @@ bool AutoplayPolicy::ShouldAutoplay() {
return element_->can_autoplay_ && element_->paused_ && element_->Autoplay();
}
-void AutoplayPolicy::Trace(Visitor* visitor) {
+void AutoplayPolicy::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(autoplay_intersection_observer_);
visitor->Trace(autoplay_uma_helper_);
diff --git a/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.h b/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.h
index 683f8e176d7..f28bf5b8bba 100644
--- a/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.h
+++ b/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.h
@@ -111,7 +111,7 @@ class CORE_EXPORT AutoplayPolicy final
// avoid false positives.
void EnsureAutoplayInitiatedSet();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
friend class AutoplayUmaHelper;
diff --git a/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc b/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc
index 44d1e8e0e39..78163e2cc42 100644
--- a/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc
@@ -297,7 +297,7 @@ bool AutoplayUmaHelper::ShouldListenToContextDestroyed() const {
muted_video_offscreen_duration_intersection_observer_;
}
-void AutoplayUmaHelper::Trace(Visitor* visitor) {
+void AutoplayUmaHelper::Trace(Visitor* visitor) const {
NativeEventListener::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
visitor->Trace(element_);
diff --git a/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h b/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h
index 80c709bc43b..fddf6ab258c 100644
--- a/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h
+++ b/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h
@@ -59,7 +59,7 @@ class CORE_EXPORT AutoplayUmaHelper : public NativeEventListener,
void Invoke(ExecutionContext*, Event*) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class MockAutoplayUmaHelper;
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_media_element.cc b/chromium/third_party/blink/renderer/core/html/media/html_media_element.cc
index 2cce1250ded..1bcde9e6393 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_media_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -259,7 +259,7 @@ class AudioSourceProviderClientLockScope {
STACK_ALLOCATED();
public:
- AudioSourceProviderClientLockScope(HTMLMediaElement& element)
+ explicit AudioSourceProviderClientLockScope(HTMLMediaElement& element)
: client_(element.AudioSourceNode()) {
if (client_)
client_->lock();
@@ -384,6 +384,11 @@ bool IsValidPlaybackRate(double rate) {
return rate == 0.0 || (rate >= kMinRate && rate <= kMaxRate);
}
+std::ostream& operator<<(std::ostream& stream,
+ HTMLMediaElement const& media_element) {
+ return stream << static_cast<void const*>(&media_element);
+}
+
} // anonymous namespace
MIMETypeRegistry::SupportsType HTMLMediaElement::GetSupportsType(
@@ -492,7 +497,6 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tag_name,
this,
&HTMLMediaElement::DeferredLoadTimerFired),
cc_layer_(nullptr),
- display_mode_(kUnknown),
official_playback_position_(0),
official_playback_position_needs_update_(true),
fragment_end_time_(std::numeric_limits<double>::quiet_NaN()),
@@ -505,6 +509,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tag_name,
paused_(true),
seeking_(false),
paused_by_context_paused_(false),
+ show_poster_flag_(true),
sent_stalled_event_(false),
ignore_preload_none_(false),
text_tracks_visible_(false),
@@ -520,7 +525,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tag_name,
media_controls_(nullptr),
controls_list_(MakeGarbageCollected<HTMLMediaElementControlsList>(this)),
lazy_load_intersection_observer_(nullptr) {
- DVLOG(1) << "HTMLMediaElement(" << (void*)this << ")";
+ DVLOG(1) << "HTMLMediaElement(" << *this << ")";
LocalFrame* frame = document.GetFrame();
if (frame) {
@@ -535,7 +540,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tag_name,
}
HTMLMediaElement::~HTMLMediaElement() {
- DVLOG(1) << "~HTMLMediaElement(" << (void*)this << ")";
+ DVLOG(1) << "~HTMLMediaElement(" << *this << ")";
}
void HTMLMediaElement::Dispose() {
@@ -550,7 +555,7 @@ void HTMLMediaElement::Dispose() {
}
void HTMLMediaElement::DidMoveToNewDocument(Document& old_document) {
- DVLOG(3) << "didMoveToNewDocument(" << (void*)this << ")";
+ DVLOG(3) << "didMoveToNewDocument(" << *this << ")";
load_timer_.MoveToNewTaskRunner(
GetDocument().GetTaskRunner(TaskType::kInternalMedia));
@@ -617,7 +622,7 @@ void HTMLMediaElement::ParseAttribute(
const AttributeModificationParams& params) {
const QualifiedName& name = params.name;
if (name == html_names::kSrcAttr) {
- DVLOG(2) << "parseAttribute(" << (void*)this
+ DVLOG(2) << "parseAttribute(" << *this
<< ", kSrcAttr, old=" << params.old_value
<< ", new=" << params.new_value << ")";
// Trigger a reload, as long as the 'src' attribute is present.
@@ -697,7 +702,7 @@ LayoutObject* HTMLMediaElement::CreateLayoutObject(const ComputedStyle&,
Node::InsertionNotificationRequest HTMLMediaElement::InsertedInto(
ContainerNode& insertion_point) {
- DVLOG(3) << "insertedInto(" << (void*)this << ", " << insertion_point << ")";
+ DVLOG(3) << "insertedInto(" << *this << ", " << insertion_point << ")";
HTMLElement::InsertedInto(insertion_point);
if (insertion_point.isConnected()) {
@@ -717,7 +722,7 @@ void HTMLMediaElement::DidNotifySubtreeInsertionsToDocument() {
}
void HTMLMediaElement::RemovedFrom(ContainerNode& insertion_point) {
- DVLOG(3) << "removedFrom(" << (void*)this << ", " << insertion_point << ")";
+ DVLOG(3) << "removedFrom(" << *this << ", " << insertion_point << ")";
removed_from_document_timer_.StartOneShot(base::TimeDelta(), FROM_HERE);
@@ -727,17 +732,16 @@ void HTMLMediaElement::RemovedFrom(ContainerNode& insertion_point) {
void HTMLMediaElement::AttachLayoutTree(AttachContext& context) {
HTMLElement::AttachLayoutTree(context);
- if (GetLayoutObject())
- GetLayoutObject()->UpdateFromElement();
+ UpdateLayoutObject();
}
void HTMLMediaElement::DidRecalcStyle(const StyleRecalcChange change) {
- if (!change.ReattachLayoutTree() && GetLayoutObject())
- GetLayoutObject()->UpdateFromElement();
+ if (!change.ReattachLayoutTree())
+ UpdateLayoutObject();
}
void HTMLMediaElement::ScheduleTextTrackResourceLoad() {
- DVLOG(3) << "scheduleTextTrackResourceLoad(" << (void*)this << ")";
+ DVLOG(3) << "scheduleTextTrackResourceLoad(" << *this << ")";
pending_action_flags_ |= kLoadTextTrackResource;
@@ -789,7 +793,7 @@ void HTMLMediaElement::SetSrc(const AtomicString& url) {
}
void HTMLMediaElement::SetSrcObject(MediaStreamDescriptor* src_object) {
- DVLOG(1) << "setSrcObject(" << (void*)this << ")";
+ DVLOG(1) << "setSrcObject(" << *this << ")";
src_object_ = src_object;
InvokeLoadAlgorithm();
}
@@ -816,14 +820,14 @@ String HTMLMediaElement::canPlayType(const String& mime_type) const {
break;
}
- DVLOG(2) << "canPlayType(" << (void*)this << ", " << mime_type << ") -> "
+ DVLOG(2) << "canPlayType(" << *this << ", " << mime_type << ") -> "
<< can_play;
return can_play;
}
void HTMLMediaElement::load() {
- DVLOG(1) << "load(" << (void*)this << ")";
+ DVLOG(1) << "load(" << *this << ")";
autoplay_policy_->TryUnlockingUserGesture();
@@ -831,12 +835,14 @@ void HTMLMediaElement::load() {
InvokeLoadAlgorithm();
}
+// Implements the "media element load algorithm" as defined by
+// https://html.spec.whatwg.org/multipage/media.html#media-element-load-algorithm
// TODO(srirama.m): Currently ignore_preload_none_ is reset before calling
// invokeLoadAlgorithm() in all places except load(). Move it inside here
// once microtask is implemented for "Await a stable state" step
// in resource selection algorithm.
void HTMLMediaElement::InvokeLoadAlgorithm() {
- DVLOG(3) << "invokeLoadAlgorithm(" << (void*)this << ")";
+ DVLOG(3) << "invokeLoadAlgorithm(" << *this << ")";
// Perform the cleanup required for the resource load algorithm to run.
StopPeriodicTimers();
@@ -847,7 +853,6 @@ void HTMLMediaElement::InvokeLoadAlgorithm() {
pending_action_flags_ &= ~kLoadMediaResource;
sent_stalled_event_ = false;
have_fired_loaded_data_ = false;
- display_mode_ = kUnknown;
autoplay_policy_->StopAutoplayMutedWhenVisible();
@@ -967,13 +972,13 @@ void HTMLMediaElement::InvokeLoadAlgorithm() {
}
void HTMLMediaElement::InvokeResourceSelectionAlgorithm() {
- DVLOG(3) << "invokeResourceSelectionAlgorithm(" << (void*)this << ")";
+ DVLOG(3) << "invokeResourceSelectionAlgorithm(" << *this << ")";
// The resource selection algorithm
// 1 - Set the networkState to NETWORK_NO_SOURCE
SetNetworkState(kNetworkNoSource);
// 2 - Set the element's show poster flag to true
- // TODO(srirama.m): Introduce show poster flag and update it as per spec
+ SetShowPosterFlag(true);
played_time_ranges_ = MakeGarbageCollected<TimeRanges>();
@@ -1013,7 +1018,7 @@ void HTMLMediaElement::LoadInternal() {
}
void HTMLMediaElement::SelectMediaResource() {
- DVLOG(3) << "selectMediaResource(" << (void*)this << ")";
+ DVLOG(3) << "selectMediaResource(" << *this << ")";
enum Mode { kObject, kAttribute, kChildren, kNothing };
Mode mode = kNothing;
@@ -1053,9 +1058,9 @@ void HTMLMediaElement::SelectMediaResource() {
UseCounter::Count(GetDocument(),
WebFeature::kHTMLMediaElementEmptyLoadWithFutureData);
}
- UpdateDisplayState();
+ UpdateLayoutObject();
- DVLOG(3) << "selectMediaResource(" << (void*)this << "), nothing to load";
+ DVLOG(3) << "selectMediaResource(" << *this << "), nothing to load";
return;
}
@@ -1070,18 +1075,17 @@ void HTMLMediaElement::SelectMediaResource() {
switch (mode) {
case kObject:
LoadSourceFromObject();
- DVLOG(3) << "selectMediaResource(" << (void*)this
+ DVLOG(3) << "selectMediaResource(" << *this
<< ", using 'srcObject' attribute";
break;
case kAttribute:
LoadSourceFromAttribute();
- DVLOG(3) << "selectMediaResource(" << (void*)this
+ DVLOG(3) << "selectMediaResource(" << *this
<< "), using 'src' attribute url";
break;
case kChildren:
LoadNextSourceChild();
- DVLOG(3) << "selectMediaResource(" << (void*)this
- << "), using source element";
+ DVLOG(3) << "selectMediaResource(" << *this << "), using source element";
break;
default:
NOTREACHED();
@@ -1104,7 +1108,7 @@ void HTMLMediaElement::LoadSourceFromAttribute() {
// If the src attribute's value is the empty string ... jump down to the
// failed step below
if (src_value.IsEmpty()) {
- DVLOG(3) << "LoadSourceFromAttribute(" << (void*)this << "), empty 'src'";
+ DVLOG(3) << "LoadSourceFromAttribute(" << *this << "), empty 'src'";
MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError,
BuildElementErrorMessage("Empty src attribute"));
return;
@@ -1145,8 +1149,8 @@ void HTMLMediaElement::LoadResource(const WebMediaPlayerSource& source,
if (source.IsURL()) {
url = source.GetAsURL();
DCHECK(IsSafeToLoadURL(url, kComplain));
- DVLOG(3) << "loadResource(" << (void*)this << ", "
- << UrlForLoggingMedia(url) << ", " << content_type << ")";
+ DVLOG(3) << "loadResource(" << *this << ", " << UrlForLoggingMedia(url)
+ << ", " << content_type << ")";
}
LocalFrame* frame = GetDocument().GetFrame();
@@ -1176,15 +1180,11 @@ void HTMLMediaElement::LoadResource(const WebMediaPlayerSource& source,
// until proved otherwise.
RemotePlaybackCompatibilityChanged(current_src_, false);
- DVLOG(3) << "loadResource(" << (void*)this << ") - current_src_ -> "
+ DVLOG(3) << "loadResource(" << *this << ") - current_src_ -> "
<< UrlForLoggingMedia(current_src_);
StartProgressEventTimer();
- // Reset display mode to force a recalculation of what to show because we are
- // resetting the player.
- SetDisplayMode(kUnknown);
-
SetPlayerPreload();
DCHECK(!media_source_);
@@ -1222,7 +1222,7 @@ void HTMLMediaElement::LoadResource(const WebMediaPlayerSource& source,
// including MediaSource blob URLs.
if (!source.IsMediaStream() && !url.ProtocolIs("blob") &&
EffectivePreloadType() == WebMediaPlayer::kPreloadNone) {
- DVLOG(3) << "loadResource(" << (void*)this
+ DVLOG(3) << "loadResource(" << *this
<< ") : Delaying load because preload == 'none'";
DeferLoad();
} else {
@@ -1235,13 +1235,6 @@ void HTMLMediaElement::LoadResource(const WebMediaPlayerSource& source,
? "Unable to load URL due to content type"
: "Unable to attach MediaSource"));
}
-
- // If there is no poster to display, allow the media engine to render video
- // frames as soon as they are available.
- UpdateDisplayState();
-
- if (GetLayoutObject())
- GetLayoutObject()->UpdateFromElement();
}
void HTMLMediaElement::StartPlayerLoad() {
@@ -1324,6 +1317,8 @@ void HTMLMediaElement::StartPlayerLoad() {
web_media_player_->SetLatencyHint(latencyHint());
+ web_media_player_->SetPreservesPitch(preservesPitch());
+
OnLoadStarted();
}
@@ -1482,8 +1477,8 @@ void HTMLMediaElement::DisableAutomaticTextTrackSelection() {
bool HTMLMediaElement::IsSafeToLoadURL(const KURL& url,
InvalidURLAction action_if_invalid) {
if (!url.IsValid()) {
- DVLOG(3) << "isSafeToLoadURL(" << (void*)this << ", "
- << UrlForLoggingMedia(url) << ") -> FALSE because url is invalid";
+ DVLOG(3) << "isSafeToLoadURL(" << *this << ", " << UrlForLoggingMedia(url)
+ << ") -> FALSE because url is invalid";
return false;
}
@@ -1495,15 +1490,13 @@ bool HTMLMediaElement::IsSafeToLoadURL(const KURL& url,
mojom::ConsoleMessageLevel::kError,
"Not allowed to load local resource: " + url.ElidedString()));
}
- DVLOG(3) << "isSafeToLoadURL(" << (void*)this << ", "
- << UrlForLoggingMedia(url)
+ DVLOG(3) << "isSafeToLoadURL(" << *this << ", " << UrlForLoggingMedia(url)
<< ") -> FALSE rejected by SecurityOrigin";
return false;
}
if (!GetDocument().GetContentSecurityPolicy()->AllowMediaFromSource(url)) {
- DVLOG(3) << "isSafeToLoadURL(" << (void*)this << ", "
- << UrlForLoggingMedia(url)
+ DVLOG(3) << "isSafeToLoadURL(" << *this << ", " << UrlForLoggingMedia(url)
<< ") -> rejected by Content Security Policy";
return false;
}
@@ -1533,27 +1526,27 @@ void HTMLMediaElement::StartProgressEventTimer() {
}
void HTMLMediaElement::WaitForSourceChange() {
- DVLOG(3) << "waitForSourceChange(" << (void*)this << ")";
+ DVLOG(3) << "waitForSourceChange(" << *this << ")";
StopPeriodicTimers();
load_state_ = kWaitingForSource;
- // 6.17 - Waiting: Set the element's networkState attribute to the
+ // 17 - Waiting: Set the element's networkState attribute to the
// NETWORK_NO_SOURCE value
SetNetworkState(kNetworkNoSource);
- // 6.18 - Set the element's delaying-the-load-event flag to false. This stops
+ // 18 - Set the element's show poster flag to true.
+ SetShowPosterFlag(true);
+
+ // 19 - Set the element's delaying-the-load-event flag to false. This stops
// delaying the load event.
SetShouldDelayLoadEvent(false);
- UpdateDisplayState();
-
- if (GetLayoutObject())
- GetLayoutObject()->UpdateFromElement();
+ UpdateLayoutObject();
}
void HTMLMediaElement::NoneSupported(const String& input_message) {
- DVLOG(3) << "NoneSupported(" << (void*)this << ", message='" << input_message
+ DVLOG(3) << "NoneSupported(" << *this << ", message='" << input_message
<< "')";
StopPeriodicTimers();
@@ -1579,7 +1572,7 @@ void HTMLMediaElement::NoneSupported(const String& input_message) {
SetNetworkState(kNetworkNoSource);
// 4 - Set the element's show poster flag to true.
- UpdateDisplayState();
+ SetShowPosterFlag(true);
// 5 - Fire a simple event named error at the media element.
ScheduleEvent(event_type_names::kError);
@@ -1593,13 +1586,12 @@ void HTMLMediaElement::NoneSupported(const String& input_message) {
// delaying the load event.
SetShouldDelayLoadEvent(false);
- if (GetLayoutObject())
- GetLayoutObject()->UpdateFromElement();
+ UpdateLayoutObject();
}
void HTMLMediaElement::MediaEngineError(MediaError* err) {
DCHECK_GE(ready_state_, kHaveMetadata);
- DVLOG(3) << "mediaEngineError(" << (void*)this << ", "
+ DVLOG(3) << "mediaEngineError(" << *this << ", "
<< static_cast<int>(err->code()) << ")";
// 1 - The user agent should cancel the fetching process.
@@ -1625,7 +1617,7 @@ void HTMLMediaElement::MediaEngineError(MediaError* err) {
}
void HTMLMediaElement::CancelPendingEventsAndCallbacks() {
- DVLOG(3) << "cancelPendingEventsAndCallbacks(" << (void*)this << ")";
+ DVLOG(3) << "cancelPendingEventsAndCallbacks(" << *this << ")";
async_event_queue_->CancelAllEvents();
for (HTMLSourceElement* source =
@@ -1640,8 +1632,8 @@ void HTMLMediaElement::NetworkStateChanged() {
void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error,
const String& input_message) {
- DVLOG(3) << "MediaLoadingFailed(" << (void*)this << ", "
- << static_cast<int>(error) << ", message='" << input_message << "')";
+ DVLOG(3) << "MediaLoadingFailed(" << *this << ", " << int{error}
+ << ", message='" << input_message << "')";
bool should_be_opaque = MediaShouldBeOpaque();
if (should_be_opaque)
@@ -1662,7 +1654,7 @@ void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error,
if (current_source_node_) {
current_source_node_->ScheduleErrorEvent();
} else {
- DVLOG(3) << "mediaLoadingFailed(" << (void*)this
+ DVLOG(3) << "mediaLoadingFailed(" << *this
<< ") - error event not sent, <source> was removed";
}
@@ -1675,11 +1667,11 @@ void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error,
ForgetResourceSpecificTracks();
if (HavePotentialSourceChild()) {
- DVLOG(3) << "mediaLoadingFailed(" << (void*)this
+ DVLOG(3) << "mediaLoadingFailed(" << *this
<< ") - scheduling next <source>";
ScheduleNextSourceChild();
} else {
- DVLOG(3) << "mediaLoadingFailed(" << (void*)this
+ DVLOG(3) << "mediaLoadingFailed(" << *this
<< ") - no more <source> elements, waiting";
WaitForSourceChange();
}
@@ -1708,13 +1700,12 @@ void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error,
}
}
- UpdateDisplayState();
+ UpdateLayoutObject();
}
void HTMLMediaElement::SetNetworkState(WebMediaPlayer::NetworkState state) {
- DVLOG(3) << "setNetworkState(" << (void*)this << ", "
- << static_cast<int>(state) << ") - current state is "
- << static_cast<int>(network_state_);
+ DVLOG(3) << "setNetworkState(" << *this << ", " << static_cast<int>(state)
+ << ") - current state is " << int{network_state_};
if (state == WebMediaPlayer::kNetworkStateEmpty) {
// Just update the cached state and leave, we can't do anything.
@@ -1762,7 +1753,7 @@ void HTMLMediaElement::ChangeNetworkStateFromLoadingToIdle() {
SetNetworkState(kNetworkIdle);
} else {
// TODO(dalecurtis): Replace c-style casts in follow up patch.
- DVLOG(1) << __func__ << "(" << (void*)this
+ DVLOG(1) << __func__ << "(" << *this
<< ") - Deferred network state change to idle for opaque media";
}
}
@@ -1772,8 +1763,8 @@ void HTMLMediaElement::ReadyStateChanged() {
}
void HTMLMediaElement::SetReadyState(ReadyState state) {
- DVLOG(3) << "setReadyState(" << (void*)this << ", " << static_cast<int>(state)
- << ") - current state is " << static_cast<int>(ready_state_);
+ DVLOG(3) << "setReadyState(" << *this << ", " << int{state}
+ << ") - current state is " << int{ready_state_};
// Set "wasPotentiallyPlaying" BEFORE updating ready_state_,
// potentiallyPlaying() uses it
@@ -1818,6 +1809,7 @@ void HTMLMediaElement::SetReadyState(ReadyState state) {
frame,
HasVideo() ? mojom::blink::RequestContextType::VIDEO
: mojom::blink::RequestContextType::AUDIO,
+ current_src_,
// Strictly speaking, this check is an approximation; a request could
// have have redirected back to its original URL, for example.
// However, the redirect status is only used to prevent leaking
@@ -1903,12 +1895,9 @@ void HTMLMediaElement::SetReadyState(ReadyState state) {
jumped = true;
}
- if (GetLayoutObject())
- GetLayoutObject()->UpdateFromElement();
+ UpdateLayoutObject();
}
- bool should_update_display_state = false;
-
bool is_potentially_playing = PotentiallyPlaying();
if (ready_state_ >= kHaveCurrentData && old_state < kHaveCurrentData &&
!have_fired_loaded_data_) {
@@ -1918,7 +1907,6 @@ void HTMLMediaElement::SetReadyState(ReadyState state) {
SetOfficialPlaybackPosition(CurrentPlaybackPosition());
have_fired_loaded_data_ = true;
- should_update_display_state = true;
ScheduleEvent(event_type_names::kLoadeddata);
SetShouldDelayLoadEvent(false);
@@ -1930,7 +1918,6 @@ void HTMLMediaElement::SetReadyState(ReadyState state) {
ScheduleEvent(event_type_names::kCanplay);
if (is_potentially_playing)
ScheduleNotifyPlaying();
- should_update_display_state = true;
}
if (ready_state_ == kHaveEnoughData && old_state < kHaveEnoughData &&
@@ -1943,23 +1930,35 @@ void HTMLMediaElement::SetReadyState(ReadyState state) {
if (autoplay_policy_->RequestAutoplayByAttribute()) {
paused_ = false;
+ SetShowPosterFlag(false);
ScheduleEvent(event_type_names::kPlay);
ScheduleNotifyPlaying();
can_autoplay_ = false;
}
ScheduleEvent(event_type_names::kCanplaythrough);
-
- should_update_display_state = true;
}
- if (should_update_display_state)
- UpdateDisplayState();
-
UpdatePlayState();
GetCueTimeline().UpdateActiveCues(currentTime());
}
+void HTMLMediaElement::SetShowPosterFlag(bool value) {
+ DVLOG(3) << "SetShowPosterFlag(" << *this << ", " << value
+ << ") - current state is " << show_poster_flag_;
+
+ if (value == show_poster_flag_)
+ return;
+
+ show_poster_flag_ = value;
+ UpdateLayoutObject();
+}
+
+void HTMLMediaElement::UpdateLayoutObject() {
+ if (GetLayoutObject())
+ GetLayoutObject()->UpdateFromElement();
+}
+
void HTMLMediaElement::ProgressEventTimerFired(TimerBase*) {
if (network_state_ != kNetworkLoading)
return;
@@ -1977,8 +1976,7 @@ void HTMLMediaElement::ProgressEventTimerFired(TimerBase*) {
ScheduleEvent(event_type_names::kProgress);
previous_progress_time_ = base::ElapsedTimer();
sent_stalled_event_ = false;
- if (GetLayoutObject())
- GetLayoutObject()->UpdateFromElement();
+ UpdateLayoutObject();
} else if (!media_source_ &&
previous_progress_time_->Elapsed() >
kStalledNotificationInterval &&
@@ -1996,8 +1994,7 @@ void HTMLMediaElement::ProgressEventTimerFired(TimerBase*) {
}
void HTMLMediaElement::AddPlayedRange(double start, double end) {
- DVLOG(3) << "addPlayedRange(" << (void*)this << ", " << start << ", " << end
- << ")";
+ DVLOG(3) << "addPlayedRange(" << *this << ", " << start << ", " << end << ")";
if (!played_time_ranges_)
played_time_ranges_ = MakeGarbageCollected<TimeRanges>();
played_time_ranges_->Add(start, end);
@@ -2057,13 +2054,16 @@ bool HTMLMediaElement::SupportsLoop() const {
}
void HTMLMediaElement::SetIgnorePreloadNone() {
- DVLOG(3) << "setIgnorePreloadNone(" << (void*)this << ")";
+ DVLOG(3) << "setIgnorePreloadNone(" << *this << ")";
ignore_preload_none_ = true;
SetPlayerPreload();
}
void HTMLMediaElement::Seek(double time) {
- DVLOG(2) << "seek(" << (void*)this << ", " << time << ")";
+ DVLOG(2) << "seek(" << *this << ", " << time << ")";
+
+ // 1 - Set the media element's show poster flag to false.
+ SetShowPosterFlag(false);
// 2 - If the media element's readyState is HAVE_NOTHING, abort these steps.
// FIXME: remove web_media_player_ check once we figure out how
@@ -2105,7 +2105,7 @@ void HTMLMediaElement::Seek(double time) {
// will never be cleared and we will never fire a 'seeked' event.
double media_time = GetWebMediaPlayer()->MediaTimeForTimeValue(time);
if (time != media_time) {
- DVLOG(3) << "seek(" << (void*)this << ", " << time
+ DVLOG(3) << "seek(" << *this << ", " << time
<< ") - media timeline equivalent is " << media_time;
time = media_time;
}
@@ -2134,13 +2134,14 @@ void HTMLMediaElement::Seek(double time) {
// 11 - Set the current playback position to the given new playback position.
GetWebMediaPlayer()->Seek(time);
+ GetWebMediaPlayer()->OnTimeUpdate();
// 14-17 are handled, if necessary, when the engine signals a readystate
// change or otherwise satisfies seek completion and signals a time change.
}
void HTMLMediaElement::FinishSeek() {
- DVLOG(3) << "finishSeek(" << (void*)this << ")";
+ DVLOG(3) << "finishSeek(" << *this << ")";
// 14 - Set the seeking IDL attribute to false.
seeking_ = false;
@@ -2154,8 +2155,6 @@ void HTMLMediaElement::FinishSeek() {
// 17 - Queue a task to fire a simple event named seeked at the element.
ScheduleEvent(event_type_names::kSeeked);
-
- SetDisplayMode(kVideo);
}
HTMLMediaElement::ReadyState HTMLMediaElement::getReadyState() const {
@@ -2244,7 +2243,7 @@ void HTMLMediaElement::SetOfficialPlaybackPosition(double position) const {
std::isnan(duration()) ? position : std::min(duration(), position);
if (official_playback_position_ != position) {
- DVLOG(3) << "setOfficialPlaybackPosition(" << (void*)this
+ DVLOG(3) << "setOfficialPlaybackPosition(" << *this
<< ") position:" << position
<< " truncated to duration:" << official_playback_position_;
}
@@ -2269,7 +2268,7 @@ double HTMLMediaElement::currentTime() const {
return default_playback_start_position_;
if (seeking_) {
- DVLOG(3) << "currentTime(" << (void*)this << ") - seeking, returning "
+ DVLOG(3) << "currentTime(" << *this << ") - seeking, returning "
<< last_seek_time_;
return last_seek_time_;
}
@@ -2321,7 +2320,7 @@ double HTMLMediaElement::playbackRate() const {
void HTMLMediaElement::setPlaybackRate(double rate,
ExceptionState& exception_state) {
- DVLOG(3) << "setPlaybackRate(" << (void*)this << ", " << rate << ")";
+ DVLOG(3) << "setPlaybackRate(" << *this << ", " << rate << ")";
if (GetLoadType() == WebMediaPlayer::kLoadTypeMediaStream)
return;
@@ -2357,8 +2356,13 @@ void HTMLMediaElement::UpdatePlaybackRate() {
// FIXME: remove web_media_player_ check once we figure out how
// web_media_player_ is going out of sync with readystate.
// web_media_player_ is cleared but readystate is not set to kHaveNothing.
- if (web_media_player_ && PotentiallyPlaying())
- GetWebMediaPlayer()->SetRate(playbackRate());
+ if (!web_media_player_)
+ return;
+
+ if (PotentiallyPlaying())
+ web_media_player_->SetRate(playbackRate());
+
+ web_media_player_->OnTimeUpdate();
}
bool HTMLMediaElement::ended() const {
@@ -2379,7 +2383,7 @@ String HTMLMediaElement::preload() const {
}
void HTMLMediaElement::setPreload(const AtomicString& preload) {
- DVLOG(2) << "setPreload(" << (void*)this << ", " << preload << ")";
+ DVLOG(2) << "setPreload(" << *this << ", " << preload << ")";
if (GetLoadType() == WebMediaPlayer::kLoadTypeMediaStream)
return;
setAttribute(html_names::kPreloadAttr, preload);
@@ -2475,7 +2479,7 @@ ScriptPromise HTMLMediaElement::playForBindings(ScriptState* script_state) {
}
base::Optional<DOMExceptionCode> HTMLMediaElement::Play() {
- DVLOG(2) << "play(" << (void*)this << ")";
+ DVLOG(2) << "play(" << *this << ")";
base::Optional<DOMExceptionCode> exception_code =
autoplay_policy_->RequestPlay();
@@ -2503,7 +2507,7 @@ base::Optional<DOMExceptionCode> HTMLMediaElement::Play() {
}
void HTMLMediaElement::PlayInternal() {
- DVLOG(3) << "playInternal(" << (void*)this << ")";
+ DVLOG(3) << "playInternal(" << *this << ")";
// Playback aborts any lazy loading.
if (lazy_load_intersection_observer_) {
@@ -2523,6 +2527,7 @@ void HTMLMediaElement::PlayInternal() {
if (paused_) {
paused_ = false;
+ SetShowPosterFlag(false);
ScheduleEvent(event_type_names::kPlay);
if (ready_state_ <= kHaveCurrentData)
@@ -2542,14 +2547,14 @@ void HTMLMediaElement::PlayInternal() {
}
void HTMLMediaElement::pause() {
- DVLOG(2) << "pause(" << (void*)this << ")";
+ DVLOG(2) << "pause(" << *this << ")";
autoplay_policy_->StopAutoplayMutedWhenVisible();
PauseInternal();
}
void HTMLMediaElement::PauseInternal() {
- DVLOG(3) << "pauseInternal(" << (void*)this << ")";
+ DVLOG(3) << "pauseInternal(" << *this << ")";
if (network_state_ == kNetworkEmpty)
InvokeResourceSelectionAlgorithm();
@@ -2573,6 +2578,17 @@ void HTMLMediaElement::PauseInternal() {
UpdatePlayState();
}
+bool HTMLMediaElement::preservesPitch() const {
+ return preserves_pitch_;
+}
+
+void HTMLMediaElement::setPreservesPitch(bool preserves_pitch) {
+ preserves_pitch_ = preserves_pitch;
+
+ if (GetWebMediaPlayer())
+ GetWebMediaPlayer()->SetPreservesPitch(preserves_pitch_);
+}
+
double HTMLMediaElement::latencyHint() const {
// Parse error will fallback to std::numeric_limits<double>::quiet_NaN()
double seconds = GetFloatingPointAttribute(html_names::kLatencyhintAttr);
@@ -2611,7 +2627,7 @@ bool HTMLMediaElement::Loop() const {
}
void HTMLMediaElement::SetLoop(bool b) {
- DVLOG(3) << "setLoop(" << (void*)this << ", " << BoolString(b) << ")";
+ DVLOG(3) << "setLoop(" << *this << ", " << BoolString(b) << ")";
SetBooleanAttribute(html_names::kLoopAttr, b);
}
@@ -2636,8 +2652,8 @@ bool HTMLMediaElement::ShouldShowControls(
return true;
}
- LocalFrame* frame = GetDocument().GetFrame();
- if (frame && !GetDocument().CanExecuteScripts(kNotAboutToExecuteScript)) {
+ ExecutionContext* context = GetExecutionContext();
+ if (context && !context->CanExecuteScripts(kNotAboutToExecuteScript)) {
if (record_metrics == RecordMetricsBehavior::kDoRecord)
RecordShowControlsUsage(this, MediaControlsShow::kNoScript);
return true;
@@ -2661,7 +2677,7 @@ double HTMLMediaElement::volume() const {
}
void HTMLMediaElement::setVolume(double vol, ExceptionState& exception_state) {
- DVLOG(2) << "setVolume(" << (void*)this << ", " << vol << ")";
+ DVLOG(2) << "setVolume(" << *this << ", " << vol << ")";
if (volume_ == vol)
return;
@@ -2707,7 +2723,7 @@ bool HTMLMediaElement::muted() const {
}
void HTMLMediaElement::setMuted(bool muted) {
- DVLOG(2) << "setMuted(" << (void*)this << ", " << BoolString(muted) << ")";
+ DVLOG(2) << "setMuted(" << *this << ", " << BoolString(muted) << ")";
if (muted_ == muted)
return;
@@ -2778,6 +2794,9 @@ void HTMLMediaElement::PlaybackProgressTimerFired(TimerBase*) {
}
void HTMLMediaElement::ScheduleTimeupdateEvent(bool periodic_event) {
+ if (web_media_player_)
+ web_media_player_->OnTimeUpdate();
+
// Per spec, consult current playback position to check for changing time.
double media_time = CurrentPlaybackPosition();
bool media_time_has_progressed =
@@ -2812,7 +2831,7 @@ AudioTrackList& HTMLMediaElement::audioTracks() {
}
void HTMLMediaElement::AudioTrackChanged(AudioTrack* track) {
- DVLOG(3) << "audioTrackChanged(" << (void*)this
+ DVLOG(3) << "audioTrackChanged(" << *this
<< ") trackId= " << String(track->id())
<< " enabled=" << BoolString(track->enabled());
DCHECK(MediaTracksEnabledInternally());
@@ -2844,9 +2863,9 @@ WebMediaPlayer::TrackId HTMLMediaElement::AddAudioTrack(
const WebString& language,
bool enabled) {
AtomicString kind_string = AudioKindToString(kind);
- DVLOG(3) << "addAudioTrack(" << (void*)this << ", '" << (String)id << "', ' "
- << (AtomicString)kind_string << "', '" << (String)label << "', '"
- << (String)language << "', " << BoolString(enabled) << ")";
+ DVLOG(3) << "addAudioTrack(" << *this << ", '" << String(id) << "', ' "
+ << kind_string << "', '" << String(label) << "', '"
+ << String(language) << "', " << BoolString(enabled) << ")";
auto* audio_track = MakeGarbageCollected<AudioTrack>(id, kind_string, label,
language, enabled);
@@ -2856,7 +2875,7 @@ WebMediaPlayer::TrackId HTMLMediaElement::AddAudioTrack(
}
void HTMLMediaElement::RemoveAudioTrack(WebMediaPlayer::TrackId track_id) {
- DVLOG(3) << "removeAudioTrack(" << (void*)this << ")";
+ DVLOG(3) << "removeAudioTrack(" << *this << ")";
audioTracks().Remove(track_id);
}
@@ -2866,8 +2885,7 @@ VideoTrackList& HTMLMediaElement::videoTracks() {
}
void HTMLMediaElement::SelectedVideoTrackChanged(VideoTrack* track) {
- DVLOG(3) << "selectedVideoTrackChanged(" << (void*)this
- << ") selectedTrackId="
+ DVLOG(3) << "selectedVideoTrackChanged(" << *this << ") selectedTrackId="
<< (track->selected() ? String(track->id()) : "none");
DCHECK(MediaTracksEnabledInternally());
@@ -2891,9 +2909,9 @@ WebMediaPlayer::TrackId HTMLMediaElement::AddVideoTrack(
const WebString& language,
bool selected) {
AtomicString kind_string = VideoKindToString(kind);
- DVLOG(3) << "addVideoTrack(" << (void*)this << ", '" << (String)id << "', '"
- << (AtomicString)kind_string << "', '" << (String)label << "', '"
- << (String)language << "', " << BoolString(selected) << ")";
+ DVLOG(3) << "addVideoTrack(" << *this << ", '" << String(id) << "', '"
+ << kind_string << "', '" << String(label) << "', '"
+ << String(language) << "', " << BoolString(selected) << ")";
// If another track was selected (potentially by the user), leave it selected.
if (selected && videoTracks().selectedIndex() != -1)
@@ -2907,7 +2925,7 @@ WebMediaPlayer::TrackId HTMLMediaElement::AddVideoTrack(
}
void HTMLMediaElement::RemoveVideoTrack(WebMediaPlayer::TrackId track_id) {
- DVLOG(3) << "removeVideoTrack(" << (void*)this << ")";
+ DVLOG(3) << "removeVideoTrack(" << *this << ")";
videoTracks().Remove(track_id);
}
@@ -3045,7 +3063,7 @@ void HTMLMediaElement::DidAddTrackElement(HTMLTrackElement* track_element) {
void HTMLMediaElement::DidRemoveTrackElement(HTMLTrackElement* track_element) {
KURL url = track_element->GetNonEmptyURLAttribute(html_names::kSrcAttr);
- DVLOG(3) << "didRemoveTrackElement(" << (void*)this << ") - 'src' is "
+ DVLOG(3) << "didRemoveTrackElement(" << *this << ") - 'src' is "
<< UrlForLoggingMedia(url);
TextTrack* text_track = track_element->track();
@@ -3113,12 +3131,11 @@ KURL HTMLMediaElement::SelectNextSourceChild(
// <source> elements.
bool should_log = action_if_invalid != kDoNothing;
if (should_log)
- DVLOG(3) << "selectNextSourceChild(" << (void*)this << ")";
+ DVLOG(3) << "selectNextSourceChild(" << *this << ")";
if (!next_child_node_to_consider_) {
if (should_log) {
- DVLOG(3) << "selectNextSourceChild(" << (void*)this
- << ") -> 0x0000, \"\"";
+ DVLOG(3) << "selectNextSourceChild(" << *this << ") -> 0x0000, \"\"";
}
return KURL();
}
@@ -3150,7 +3167,7 @@ KURL HTMLMediaElement::SelectNextSourceChild(
const AtomicString& src_value =
source->FastGetAttribute(html_names::kSrcAttr);
if (should_log) {
- DVLOG(3) << "selectNextSourceChild(" << (void*)this << ") - 'src' is "
+ DVLOG(3) << "selectNextSourceChild(" << *this << ") - 'src' is "
<< UrlForLoggingMedia(media_url);
}
if (src_value.IsEmpty())
@@ -3175,7 +3192,7 @@ KURL HTMLMediaElement::SelectNextSourceChild(
type = MimeTypeFromDataURL(media_url);
if (!type.IsEmpty()) {
if (should_log) {
- DVLOG(3) << "selectNextSourceChild(" << (void*)this << ") - 'type' is '"
+ DVLOG(3) << "selectNextSourceChild(" << *this << ") - 'type' is '"
<< type << "'";
}
if (!GetSupportsType(ContentType(type)))
@@ -3201,7 +3218,7 @@ KURL HTMLMediaElement::SelectNextSourceChild(
}
if (should_log) {
- DVLOG(3) << "selectNextSourceChild(" << (void*)this << ") -> "
+ DVLOG(3) << "selectNextSourceChild(" << *this << ") -> "
<< current_source_node_.Get() << ", "
<< (can_use_source_element ? UrlForLoggingMedia(media_url) : "");
}
@@ -3210,10 +3227,10 @@ KURL HTMLMediaElement::SelectNextSourceChild(
}
void HTMLMediaElement::SourceWasAdded(HTMLSourceElement* source) {
- DVLOG(3) << "sourceWasAdded(" << (void*)this << ", " << source << ")";
+ DVLOG(3) << "sourceWasAdded(" << *this << ", " << source << ")";
KURL url = source->GetNonEmptyURLAttribute(html_names::kSrcAttr);
- DVLOG(3) << "sourceWasAdded(" << (void*)this << ") - 'src' is "
+ DVLOG(3) << "sourceWasAdded(" << *this << ") - 'src' is "
<< UrlForLoggingMedia(url);
// We should only consider a <source> element when there is not src attribute
@@ -3233,7 +3250,7 @@ void HTMLMediaElement::SourceWasAdded(HTMLSourceElement* source) {
}
if (current_source_node_ && source == current_source_node_->nextSibling()) {
- DVLOG(3) << "sourceWasAdded(" << (void*)this
+ DVLOG(3) << "sourceWasAdded(" << *this
<< ") - <source> inserted immediately after current source";
// Ignore current |next_child_node_to_consider_| and consider |source|.
next_child_node_to_consider_ = source;
@@ -3265,10 +3282,10 @@ void HTMLMediaElement::SourceWasAdded(HTMLSourceElement* source) {
}
void HTMLMediaElement::SourceWasRemoved(HTMLSourceElement* source) {
- DVLOG(3) << "sourceWasRemoved(" << (void*)this << ", " << source << ")";
+ DVLOG(3) << "sourceWasRemoved(" << *this << ", " << source << ")";
KURL url = source->GetNonEmptyURLAttribute(html_names::kSrcAttr);
- DVLOG(3) << "sourceWasRemoved(" << (void*)this << ") - 'src' is "
+ DVLOG(3) << "sourceWasRemoved(" << *this << ") - 'src' is "
<< UrlForLoggingMedia(url);
if (source != current_source_node_ && source != next_child_node_to_consider_)
@@ -3277,7 +3294,7 @@ void HTMLMediaElement::SourceWasRemoved(HTMLSourceElement* source) {
if (source == next_child_node_to_consider_) {
if (current_source_node_)
next_child_node_to_consider_ = current_source_node_->nextSibling();
- DVLOG(3) << "sourceWasRemoved(" << (void*)this
+ DVLOG(3) << "sourceWasRemoved(" << *this
<< ") - next_child_node_to_consider_ set to "
<< next_child_node_to_consider_.Get();
} else if (source == current_source_node_) {
@@ -3287,13 +3304,13 @@ void HTMLMediaElement::SourceWasRemoved(HTMLSourceElement* source) {
// element is already inserted in a video or audio element will have no
// effect.
current_source_node_ = nullptr;
- DVLOG(3) << "SourceWasRemoved(" << (void*)this
+ DVLOG(3) << "SourceWasRemoved(" << *this
<< ") - current_source_node_ set to 0";
}
}
void HTMLMediaElement::TimeChanged() {
- DVLOG(3) << "timeChanged(" << (void*)this << ")";
+ DVLOG(3) << "timeChanged(" << *this << ")";
GetCueTimeline().UpdateActiveCues(currentTime());
@@ -3335,7 +3352,7 @@ void HTMLMediaElement::TimeChanged() {
}
void HTMLMediaElement::DurationChanged() {
- DVLOG(3) << "durationChanged(" << (void*)this << ")";
+ DVLOG(3) << "durationChanged(" << *this << ")";
// durationChanged() is triggered by media player.
CHECK(web_media_player_);
@@ -3348,20 +3365,22 @@ void HTMLMediaElement::DurationChanged() {
}
void HTMLMediaElement::DurationChanged(double duration, bool request_seek) {
- DVLOG(3) << "durationChanged(" << (void*)this << ", " << duration << ", "
+ DVLOG(3) << "durationChanged(" << *this << ", " << duration << ", "
<< BoolString(request_seek) << ")";
// Abort if duration unchanged.
if (duration_ == duration)
return;
- DVLOG(3) << "durationChanged(" << (void*)this << ") : " << duration_ << " -> "
+ DVLOG(3) << "durationChanged(" << *this << ") : " << duration_ << " -> "
<< duration;
duration_ = duration;
ScheduleEvent(event_type_names::kDurationchange);
- if (GetLayoutObject())
- GetLayoutObject()->UpdateFromElement();
+ if (web_media_player_)
+ web_media_player_->OnTimeUpdate();
+
+ UpdateLayoutObject();
if (request_seek)
Seek(duration);
@@ -3406,20 +3425,19 @@ void HTMLMediaElement::Repaint() {
if (cc_layer_)
cc_layer_->SetNeedsDisplay();
- UpdateDisplayState();
+ UpdateLayoutObject();
if (GetLayoutObject())
GetLayoutObject()->SetShouldDoFullPaintInvalidation();
}
void HTMLMediaElement::SizeChanged() {
- DVLOG(3) << "sizeChanged(" << (void*)this << ")";
+ DVLOG(3) << "sizeChanged(" << *this << ")";
DCHECK(HasVideo()); // "resize" makes no sense in absence of video.
if (ready_state_ > kHaveNothing && IsHTMLVideoElement())
ScheduleEvent(event_type_names::kResize);
- if (GetLayoutObject())
- GetLayoutObject()->UpdateFromElement();
+ UpdateLayoutObject();
}
WebTimeRanges HTMLMediaElement::BufferedInternal() const {
@@ -3510,7 +3528,7 @@ void HTMLMediaElement::UpdatePlayState() {
bool is_playing = GetWebMediaPlayer() && !GetWebMediaPlayer()->Paused();
bool should_be_playing = PotentiallyPlaying();
- DVLOG(3) << "updatePlayState(" << (void*)this
+ DVLOG(3) << "updatePlayState(" << *this
<< ") - shouldBePlaying = " << BoolString(should_be_playing)
<< ", isPlaying = " << BoolString(is_playing);
@@ -3518,8 +3536,6 @@ void HTMLMediaElement::UpdatePlayState() {
was_always_muted_ = false;
if (should_be_playing) {
- SetDisplayMode(kVideo);
-
if (!is_playing) {
// Set rate, muted before calling play in case they were set before the
// media engine was setup. The media engine should just stash the rate
@@ -3543,8 +3559,10 @@ void HTMLMediaElement::UpdatePlayState() {
AddPlayedRange(last_seek_time_, time);
}
- if (GetLayoutObject())
- GetLayoutObject()->UpdateFromElement();
+ UpdateLayoutObject();
+
+ if (web_media_player_)
+ web_media_player_->OnTimeUpdate();
}
void HTMLMediaElement::StopPeriodicTimers() {
@@ -3621,8 +3639,7 @@ void HTMLMediaElement::ContextDestroyed() {
paused_ = true;
seeking_ = false;
- if (GetLayoutObject())
- GetLayoutObject()->UpdateFromElement();
+ UpdateLayoutObject();
StopPeriodicTimers();
removed_from_document_timer_.Stop();
@@ -3631,7 +3648,7 @@ void HTMLMediaElement::ContextDestroyed() {
bool HTMLMediaElement::HasPendingActivity() const {
const auto result = HasPendingActivityInternal();
// TODO(dalecurtis): Replace c-style casts in followup patch.
- DVLOG(3) << "HasPendingActivity(" << (void*)this << ") = " << result;
+ DVLOG(3) << "HasPendingActivity(" << *this << ") = " << result;
return result;
}
@@ -3778,14 +3795,14 @@ TextTrackContainer& HTMLMediaElement::EnsureTextTrackContainer() {
}
void HTMLMediaElement::UpdateTextTrackDisplay() {
- DVLOG(3) << "updateTextTrackDisplay(" << (void*)this << ")";
+ DVLOG(3) << "updateTextTrackDisplay(" << *this << ")";
EnsureTextTrackContainer().UpdateDisplay(
*this, TextTrackContainer::kDidNotStartExposingControls);
}
void HTMLMediaElement::MediaControlsDidBecomeVisible() {
- DVLOG(3) << "mediaControlsDidBecomeVisible(" << (void*)this << ")";
+ DVLOG(3) << "mediaControlsDidBecomeVisible(" << *this << ")";
// When the user agent starts exposing a user interface for a video element,
// the user agent should run the rules for updating the text track rendering
@@ -3862,7 +3879,7 @@ void HTMLMediaElement::SetShouldDelayLoadEvent(bool should_delay) {
if (should_delay_load_event_ == should_delay)
return;
- DVLOG(3) << "setShouldDelayLoadEvent(" << (void*)this << ", "
+ DVLOG(3) << "setShouldDelayLoadEvent(" << *this << ", "
<< BoolString(should_delay) << ")";
should_delay_load_event_ = should_delay;
@@ -3927,7 +3944,7 @@ CueTimeline& HTMLMediaElement::GetCueTimeline() {
void HTMLMediaElement::ConfigureTextTrackDisplay() {
DCHECK(text_tracks_);
- DVLOG(3) << "configureTextTrackDisplay(" << (void*)this << ")";
+ DVLOG(3) << "configureTextTrackDisplay(" << *this << ")";
if (processing_preference_change_)
return;
@@ -4001,7 +4018,7 @@ bool HTMLMediaElement::IsInteractiveContent() const {
return FastHasAttribute(html_names::kControlsAttr);
}
-void HTMLMediaElement::Trace(Visitor* visitor) {
+void HTMLMediaElement::Trace(Visitor* visitor) const {
visitor->Trace(audio_source_node_);
visitor->Trace(played_time_ranges_);
visitor->Trace(async_event_queue_);
@@ -4220,11 +4237,11 @@ void HTMLMediaElement::AudioClientImpl::SetFormat(uint32_t number_of_channels,
client_->SetFormat(number_of_channels, sample_rate);
}
-void HTMLMediaElement::AudioClientImpl::Trace(Visitor* visitor) {
+void HTMLMediaElement::AudioClientImpl::Trace(Visitor* visitor) const {
visitor->Trace(client_);
}
-void HTMLMediaElement::AudioSourceProviderImpl::Trace(Visitor* visitor) {
+void HTMLMediaElement::AudioSourceProviderImpl::Trace(Visitor* visitor) const {
visitor->Trace(client_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_media_element.h b/chromium/third_party/blink/renderer/core/html/media/html_media_element.h
index 85851eb1cbc..f351646fcbc 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_media_element.h
+++ b/chromium/third_party/blink/renderer/core/html/media/html_media_element.h
@@ -108,7 +108,7 @@ class CORE_EXPORT HTMLMediaElement
// for the given document.
static void OnMediaControlsEnabledChange(Document*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
WebMediaPlayer* GetWebMediaPlayer() const { return web_media_player_.get(); }
@@ -205,6 +205,8 @@ class CORE_EXPORT HTMLMediaElement
void pause();
double latencyHint() const;
void setLatencyHint(double);
+ bool preservesPitch() const;
+ void setPreservesPitch(bool);
void FlingingStarted();
void FlingingStopped();
@@ -332,6 +334,8 @@ class CORE_EXPORT HTMLMediaElement
void SetCcLayerForTesting(cc::Layer* layer) { SetCcLayer(layer); }
+ bool IsShowPosterFlagSet() const { return show_poster_flag_; }
+
protected:
// Assert the correct order of the children in shadow dom when DCHECK is on.
static void AssertShadowRootChildren(ShadowRoot&);
@@ -359,13 +363,11 @@ class CORE_EXPORT HTMLMediaElement
void DidMoveToNewDocument(Document& old_document) override;
virtual KURL PosterImageURL() const { return KURL(); }
- enum DisplayMode { kUnknown, kPoster, kVideo };
- DisplayMode GetDisplayMode() const { return display_mode_; }
- virtual void SetDisplayMode(DisplayMode mode) { display_mode_ = mode; }
-
// Called after the creation of |web_media_player_|.
virtual void OnWebMediaPlayerCreated() {}
+ void UpdateLayoutObject();
+
private:
// Friend class for testing.
friend class ContextMenuControllerTest;
@@ -394,11 +396,12 @@ class CORE_EXPORT HTMLMediaElement
void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;
void ContextDestroyed() override;
- virtual void UpdateDisplayState() {}
virtual void OnPlay() {}
virtual void OnLoadStarted() {}
virtual void OnLoadFinished() {}
+ void SetShowPosterFlag(bool value);
+
void SetReadyState(ReadyState);
void SetNetworkState(WebMediaPlayer::NetworkState);
@@ -624,8 +627,6 @@ class CORE_EXPORT HTMLMediaElement
std::unique_ptr<WebMediaPlayer> web_media_player_;
cc::Layer* cc_layer_;
- DisplayMode display_mode_;
-
Member<MediaSource> media_source_;
// Stores "official playback position", updated periodically from "current
@@ -648,6 +649,7 @@ class CORE_EXPORT HTMLMediaElement
bool paused_ : 1;
bool seeking_ : 1;
bool paused_by_context_paused_ : 1;
+ bool show_poster_flag_ : 1;
// data has not been loaded since sending a "stalled" event
bool sent_stalled_event_ : 1;
@@ -662,6 +664,10 @@ class CORE_EXPORT HTMLMediaElement
bool was_always_muted_ : 1;
+ // Whether or not |web_media_player_| should apply pitch adjustments at
+ // playback raters other than 1.0.
+ bool preserves_pitch_ = true;
+
Member<AudioTrackList> audio_tracks_;
Member<VideoTrackList> video_tracks_;
Member<TextTrackList> text_tracks_;
@@ -693,7 +699,7 @@ class CORE_EXPORT HTMLMediaElement
// WebAudioSourceProviderClient
void SetFormat(uint32_t number_of_channels, float sample_rate) override;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<AudioSourceProviderClient> client_;
@@ -715,7 +721,7 @@ class CORE_EXPORT HTMLMediaElement
void SetClient(AudioSourceProviderClient*) override;
void ProvideInput(AudioBus*, uint32_t frames_to_process) override;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
scoped_refptr<WebAudioSourceProviderImpl> web_audio_source_provider_;
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_media_element.idl b/chromium/third_party/blink/renderer/core/html/media/html_media_element.idl
index 3e38825ead2..4bc7fd9ccc6 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_media_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/media/html_media_element.idl
@@ -76,6 +76,8 @@ enum CanPlayTypeResult { "" /* empty string */, "maybe", "probably" };
void pause();
[RuntimeEnabled=MediaLatencyHint, CEReactions]
attribute double latencyHint;
+ [RuntimeEnabled=MediaPreservesPitch]
+ attribute boolean preservesPitch;
// controls
[CEReactions, Reflect] attribute boolean controls;
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc b/chromium/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc
index faeb17ce9f1..6c87cdee963 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc
@@ -37,8 +37,10 @@ static constexpr base::TimeDelta kFakeMediaPlayerAutoIncrementTimeDelta =
// exception of the mocked methods).
class FakeWebMediaPlayer final : public EmptyWebMediaPlayer {
public:
- FakeWebMediaPlayer(WebMediaPlayerClient* client, Document* document)
- : client_(client), document_(document) {}
+ FakeWebMediaPlayer(WebMediaPlayerClient* client,
+ ExecutionContext* context,
+ double duration)
+ : client_(client), context_(context), duration_(duration) {}
MOCK_METHOD1(SetIsEffectivelyFullscreen,
void(blink::WebFullscreenVideoStatus));
@@ -48,7 +50,7 @@ class FakeWebMediaPlayer final : public EmptyWebMediaPlayer {
}
// Establish a large so tests can attempt seeking.
- double Duration() const override { return 1000000; }
+ double Duration() const override { return duration_; }
WebTimeRanges Seekable() const override {
WebTimeRange single_range[] = {WebTimeRange(0, Duration())};
@@ -64,6 +66,7 @@ class FakeWebMediaPlayer final : public EmptyWebMediaPlayer {
}
void Pause() override { playing_ = false; }
bool Paused() const override { return !playing_; }
+ bool IsEnded() const override { return current_time_ == duration_; }
void FinishSeek() {
ASSERT_GE(last_seek_time_, 0);
@@ -71,6 +74,8 @@ class FakeWebMediaPlayer final : public EmptyWebMediaPlayer {
last_seek_time_ = -1;
client_->TimeChanged();
+ if (playing_)
+ ScheduleTimeIncrement();
}
void SetAutoIncrementCurrentTime(bool auto_increment) {
@@ -86,7 +91,7 @@ class FakeWebMediaPlayer final : public EmptyWebMediaPlayer {
return;
}
- document_->GetTaskRunner(TaskType::kInternalMediaRealTime)
+ context_->GetTaskRunner(TaskType::kInternalMediaRealTime)
->PostDelayedTask(FROM_HERE,
base::BindOnce(&FakeWebMediaPlayer::AutoTimeIncrement,
base::Unretained(this)),
@@ -101,19 +106,27 @@ class FakeWebMediaPlayer final : public EmptyWebMediaPlayer {
scheduled_time_increment_ = false;
current_time_ += kFakeMediaPlayerAutoIncrementTimeDelta.InSecondsF();
- ScheduleTimeIncrement();
+
+ // Notify the client if we've reached the end of the set duration
+ if (current_time_ >= duration_) {
+ current_time_ = duration_;
+ client_->TimeChanged();
+ } else {
+ ScheduleTimeIncrement();
+ }
// Run V8 Microtasks (update OfficialPlaybackPosition)
- Microtask::PerformCheckpoint(document_->GetIsolate());
+ Microtask::PerformCheckpoint(context_->GetIsolate());
}
WebMediaPlayerClient* client_;
- WeakPersistent<Document> document_;
+ WeakPersistent<ExecutionContext> context_;
mutable double current_time_ = 0;
bool playing_ = false;
bool auto_increment_current_time_ = false;
bool scheduled_time_increment_ = false;
double last_seek_time_ = -1;
+ const double duration_;
};
class MediaStubLocalFrameClient : public EmptyLocalFrameClient {
@@ -122,8 +135,16 @@ class MediaStubLocalFrameClient : public EmptyLocalFrameClient {
HTMLMediaElement& element,
const WebMediaPlayerSource&,
WebMediaPlayerClient* client) override {
- return std::make_unique<FakeWebMediaPlayer>(client, &element.GetDocument());
+ return std::make_unique<FakeWebMediaPlayer>(
+ client, element.GetExecutionContext(), media_duration_);
+ }
+
+ void SetMediaDuration(double media_duration) {
+ media_duration_ = media_duration;
}
+
+ private:
+ double media_duration_ = 1000000;
};
using testing::_;
@@ -140,19 +161,33 @@ class HTMLMediaElementEventListenersTest : public PageTestBase {
}
void DestroyDocument() { PageTestBase::TearDown(); }
+
HTMLVideoElement* Video() {
return To<HTMLVideoElement>(GetDocument().QuerySelector("video"));
}
+
FakeWebMediaPlayer* WebMediaPlayer() {
return static_cast<FakeWebMediaPlayer*>(Video()->GetWebMediaPlayer());
}
+
+ MediaStubLocalFrameClient* LocalFrameClient() {
+ return static_cast<MediaStubLocalFrameClient*>(GetFrame().Client());
+ }
+
+ void SetMediaDuration(double duration) {
+ LocalFrameClient()->SetMediaDuration(duration);
+ }
+
MediaControls* Controls() { return Video()->GetMediaControls(); }
+
void SimulateReadyState(HTMLMediaElement::ReadyState state) {
Video()->SetReadyState(state);
}
+
void SimulateNetworkState(HTMLMediaElement::NetworkState state) {
Video()->SetNetworkState(state);
}
+
MediaCustomControlsFullscreenDetector* FullscreenDetector() {
return Video()->custom_controls_fullscreen_detector_;
}
@@ -406,4 +441,76 @@ TEST_F(HTMLMediaElementWithMockSchedulerTest, PeriodicTimeupdateAfterSeek) {
platform()->RunUntilIdle();
}
+TEST_F(HTMLMediaElementWithMockSchedulerTest, ShowPosterFlag_FalseAfterLoop) {
+ testing::InSequence dummy;
+
+ // Adjust the duration of the media to something we can reasonably loop
+ SetMediaDuration(10.0);
+
+ // Create a looping video with a source
+ GetDocument().body()->setInnerHTML(
+ "<video loop src=\"http://example.com\"></video>");
+ platform()->RunUntilIdle();
+ EXPECT_NE(WebMediaPlayer(), nullptr);
+ EXPECT_EQ(WebMediaPlayer()->Duration(), 10.0);
+ EXPECT_TRUE(Video()->Loop());
+
+ SimulateNetworkState(HTMLMediaElement::kNetworkIdle);
+ SimulateReadyState(HTMLMediaElement::kHaveEnoughData);
+
+ // Simulate advancing playback time to enable periodic timeupdates.
+ WebMediaPlayer()->SetAutoIncrementCurrentTime(true);
+ Video()->Play();
+
+ // Ensure the 'seeking' and 'seeked' events are fired, so we know a loop
+ // occurred
+ auto* seeking_handler = MakeGarbageCollected<MockEventListener>();
+ EXPECT_CALL(*seeking_handler, Invoke(_, _)).Times(1);
+ Video()->addEventListener(event_type_names::kSeeking, seeking_handler);
+ platform()->RunForPeriodSeconds(15);
+ testing::Mock::VerifyAndClearExpectations(seeking_handler);
+
+ auto* seeked_handler = MakeGarbageCollected<MockEventListener>();
+ EXPECT_CALL(*seeked_handler, Invoke(_, _)).Times(1);
+ Video()->addEventListener(event_type_names::kSeeked, seeked_handler);
+ WebMediaPlayer()->FinishSeek();
+ platform()->RunUntilIdle();
+ testing::Mock::VerifyAndClearExpectations(seeked_handler);
+
+ // ShowPosterFlag should be false after looping
+ EXPECT_FALSE(Video()->IsShowPosterFlagSet());
+}
+
+TEST_F(HTMLMediaElementWithMockSchedulerTest, ShowPosterFlag_FalseAfterEnded) {
+ testing::InSequence dummy;
+
+ // Adjust the duration of the media to something we can reach the end of
+ SetMediaDuration(10.0);
+
+ // Create a video with a source
+ GetDocument().body()->setInnerHTML(
+ "<video src=\"http://example.com\"></video>");
+ platform()->RunUntilIdle();
+ EXPECT_NE(WebMediaPlayer(), nullptr);
+ EXPECT_EQ(WebMediaPlayer()->Duration(), 10.0);
+
+ SimulateNetworkState(HTMLMediaElement::kNetworkIdle);
+ SimulateReadyState(HTMLMediaElement::kHaveEnoughData);
+
+ // Simulate advancing playback time to enable periodic timeupdates.
+ WebMediaPlayer()->SetAutoIncrementCurrentTime(true);
+ Video()->Play();
+
+ // Ensure the 'ended' event is fired
+ auto* ended_handler = MakeGarbageCollected<MockEventListener>();
+ Video()->addEventListener(event_type_names::kEnded, ended_handler);
+
+ EXPECT_CALL(*ended_handler, Invoke(_, _)).Times(1);
+ platform()->RunForPeriodSeconds(15);
+ testing::Mock::VerifyAndClearExpectations(ended_handler);
+
+ // ShowPosterFlag should be false even after ending
+ EXPECT_FALSE(Video()->IsShowPosterFlagSet());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_media_element_test.cc b/chromium/third_party/blink/renderer/core/html/media/html_media_element_test.cc
index 3fd83d9af3f..25bd257294c 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_media_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/html_media_element_test.cc
@@ -38,6 +38,8 @@ namespace {
class MockWebMediaPlayer : public EmptyWebMediaPlayer {
public:
+ MOCK_METHOD0(OnTimeUpdate, void());
+ MOCK_CONST_METHOD0(Seekable, WebTimeRanges());
MOCK_CONST_METHOD0(HasAudio, bool());
MOCK_CONST_METHOD0(HasVideo, bool());
MOCK_CONST_METHOD0(Duration, double());
@@ -88,6 +90,8 @@ class HTMLMediaElementTest : public testing::TestWithParam<MediaTestParam> {
// Most tests do not care about this call, nor its return value. Those that
// do will clear this expectation and set custom expectations/returns.
+ EXPECT_CALL(*mock_media_player, Seekable())
+ .WillRepeatedly(Return(WebTimeRanges()));
EXPECT_CALL(*mock_media_player, HasAudio()).WillRepeatedly(Return(true));
EXPECT_CALL(*mock_media_player, HasVideo()).WillRepeatedly(Return(true));
EXPECT_CALL(*mock_media_player, Duration()).WillRepeatedly(Return(1.0));
@@ -128,6 +132,8 @@ class HTMLMediaElementTest : public testing::TestWithParam<MediaTestParam> {
bool CouldPlayIfEnoughData() { return Media()->CouldPlayIfEnoughData(); }
+ bool PotentiallyPlaying() { return Media()->PotentiallyPlaying(); }
+
bool ShouldDelayLoadEvent() { return Media()->should_delay_load_event_; }
void SetReadyState(HTMLMediaElement::ReadyState state) {
@@ -606,4 +612,177 @@ TEST_P(HTMLMediaElementTest, NoPendingActivityEvenIfBeforeMetadata) {
EXPECT_TRUE(MediaShouldBeOpaque());
}
+TEST_P(HTMLMediaElementTest, OnTimeUpdate_DurationChange) {
+ // Prepare the player.
+ Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp));
+ test::RunPendingTasks();
+
+ // Change from no duration to 1s will trigger OnTimeUpdate().
+ EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate());
+ Media()->DurationChanged(1, false);
+ testing::Mock::VerifyAndClearExpectations(MockMediaPlayer());
+
+ // Change from 1s to 2s will trigger OnTimeUpdate().
+ EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate());
+ Media()->DurationChanged(2, false);
+ testing::Mock::VerifyAndClearExpectations(MockMediaPlayer());
+
+ // No duration change -> no OnTimeUpdate().
+ Media()->DurationChanged(2, false);
+}
+
+TEST_P(HTMLMediaElementTest, OnTimeUpdate_PlayPauseSetRate) {
+ // Prepare the player.
+ Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp));
+ test::RunPendingTasks();
+
+ EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate());
+ Media()->Play();
+ testing::Mock::VerifyAndClearExpectations(MockMediaPlayer());
+
+ EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate());
+ Media()->setPlaybackRate(0.5);
+ testing::Mock::VerifyAndClearExpectations(MockMediaPlayer());
+
+ EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate()).Times(testing::AtLeast(1));
+ Media()->pause();
+ testing::Mock::VerifyAndClearExpectations(MockMediaPlayer());
+
+ EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate());
+ Media()->setPlaybackRate(1.5);
+ testing::Mock::VerifyAndClearExpectations(MockMediaPlayer());
+
+ EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate());
+ Media()->Play();
+}
+
+TEST_P(HTMLMediaElementTest, OnTimeUpdate_ReadyState) {
+ // Prepare the player.
+ Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp));
+ test::RunPendingTasks();
+
+ // The ready state affects the progress of media time, so the player should
+ // be kept informed.
+ EXPECT_CALL(*MockMediaPlayer(), GetSrcAfterRedirects)
+ .WillRepeatedly(Return(GURL()));
+ EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate());
+ SetReadyState(HTMLMediaElement::kHaveCurrentData);
+ testing::Mock::VerifyAndClearExpectations(MockMediaPlayer());
+
+ EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate());
+ SetReadyState(HTMLMediaElement::kHaveFutureData);
+}
+
+TEST_P(HTMLMediaElementTest, OnTimeUpdate_Seeking) {
+ // Prepare the player and seekable ranges -- setCurrentTime()'s prerequisites.
+ WebTimeRanges seekable;
+ seekable.Add(0, 3);
+ EXPECT_CALL(*MockMediaPlayer(), Seekable).WillRepeatedly(Return(seekable));
+ EXPECT_CALL(*MockMediaPlayer(), GetSrcAfterRedirects)
+ .WillRepeatedly(Return(GURL()));
+ EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate());
+ Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp));
+ test::RunPendingTasks();
+ SetReadyState(HTMLMediaElement::kHaveCurrentData);
+
+ EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate());
+ Media()->setCurrentTime(1);
+ testing::Mock::VerifyAndClearExpectations(MockMediaPlayer());
+
+ EXPECT_CALL(*MockMediaPlayer(), Seekable).WillRepeatedly(Return(seekable));
+ EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate());
+ Media()->setCurrentTime(2);
+}
+
+TEST_P(HTMLMediaElementTest, ShowPosterFlag_InitiallyTrue) {
+ // ShowPosterFlag should be true upon initialization
+ EXPECT_TRUE(Media()->IsShowPosterFlagSet());
+
+ Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp));
+ test::RunPendingTasks();
+
+ EXPECT_TRUE(Media()->IsShowPosterFlagSet());
+
+ SetReadyState(HTMLMediaElement::kHaveEnoughData);
+ test::RunPendingTasks();
+
+ // ShowPosterFlag should still be true once video is ready to play
+ EXPECT_TRUE(Media()->IsShowPosterFlagSet());
+}
+
+TEST_P(HTMLMediaElementTest, ShowPosterFlag_FalseAfterPlay) {
+ Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp));
+ test::RunPendingTasks();
+
+ SetReadyState(HTMLMediaElement::kHaveEnoughData);
+ test::RunPendingTasks();
+
+ Media()->Play();
+ test::RunPendingTasks();
+
+ // ShowPosterFlag should be false once video is playing
+ ASSERT_FALSE(Media()->paused());
+ EXPECT_FALSE(Media()->IsShowPosterFlagSet());
+}
+
+TEST_P(HTMLMediaElementTest, ShowPosterFlag_FalseAfterSeek) {
+ Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp));
+ test::RunPendingTasks();
+
+ SetReadyState(HTMLMediaElement::kHaveEnoughData);
+ test::RunPendingTasks();
+
+ ASSERT_NE(Media()->duration(), 0.0);
+ Media()->setCurrentTime(Media()->duration() / 2);
+ test::RunPendingTasks();
+
+ EXPECT_FALSE(Media()->IsShowPosterFlagSet());
+}
+
+TEST_P(HTMLMediaElementTest, ShowPosterFlag_FalseAfterAutoPlay) {
+ Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp));
+ test::RunPendingTasks();
+
+ Media()->SetBooleanAttribute(html_names::kAutoplayAttr, true);
+ test::RunPendingTasks();
+
+ SetReadyState(HTMLMediaElement::kHaveEnoughData);
+ test::RunPendingTasks();
+
+ ASSERT_TRUE(WasAutoplayInitiated());
+ ASSERT_FALSE(Media()->paused());
+ EXPECT_FALSE(Media()->IsShowPosterFlagSet());
+}
+
+TEST_P(HTMLMediaElementTest, ShowPosterFlag_FalseAfterPlayBeforeReady) {
+ Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp));
+
+ // Initially we have nothing, we're not playing, trying to play, and the 'show
+ // poster' flag is set
+ EXPECT_EQ(Media()->getReadyState(), HTMLMediaElement::kHaveNothing);
+ EXPECT_TRUE(Media()->paused());
+ EXPECT_FALSE(PotentiallyPlaying());
+ EXPECT_TRUE(Media()->IsShowPosterFlagSet());
+
+ // Attempt to begin playback
+ Media()->Play();
+ test::RunPendingTasks();
+
+ // We still have no data, but we're not paused, and the 'show poster' flag is
+ // not set
+ EXPECT_EQ(Media()->getReadyState(), HTMLMediaElement::kHaveNothing);
+ EXPECT_FALSE(Media()->paused());
+ EXPECT_FALSE(PotentiallyPlaying());
+ EXPECT_FALSE(Media()->IsShowPosterFlagSet());
+
+ // Pretend we have data to begin playback
+ SetReadyState(HTMLMediaElement::kHaveFutureData);
+
+ // We should have data, be playing, and the show poster flag should be unset
+ EXPECT_EQ(Media()->getReadyState(), HTMLMediaElement::kHaveFutureData);
+ EXPECT_FALSE(Media()->paused());
+ EXPECT_TRUE(PotentiallyPlaying());
+ EXPECT_FALSE(Media()->IsShowPosterFlagSet());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_video_element.cc b/chromium/third_party/blink/renderer/core/html/media/html_video_element.cc
index 4805e7e2afd..28327caae48 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_video_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/html_video_element.cc
@@ -86,8 +86,8 @@ HTMLVideoElement::HTMLVideoElement(Document& document)
in_overlay_fullscreen_video_(false),
is_effectively_fullscreen_(false),
is_default_overridden_intrinsic_size_(
- !document.IsMediaDocument() &&
- !document.IsFeatureEnabled(
+ !document.IsMediaDocument() && GetExecutionContext() &&
+ !GetExecutionContext()->IsFeatureEnabled(
mojom::blink::DocumentPolicyFeature::kUnsizedMedia)),
video_has_played_(false),
mostly_filling_viewport_(false) {
@@ -105,7 +105,7 @@ HTMLVideoElement::HTMLVideoElement(Document& document)
UpdateStateIfNeeded();
}
-void HTMLVideoElement::Trace(Visitor* visitor) {
+void HTMLVideoElement::Trace(Visitor* visitor) const {
visitor->Trace(image_loader_);
visitor->Trace(custom_controls_fullscreen_detector_);
visitor->Trace(wake_lock_);
@@ -151,17 +151,25 @@ LayoutObject* HTMLVideoElement::CreateLayoutObject(const ComputedStyle&,
void HTMLVideoElement::AttachLayoutTree(AttachContext& context) {
HTMLMediaElement::AttachLayoutTree(context);
+ UpdatePosterImage();
+}
+
+void HTMLVideoElement::UpdatePosterImage() {
+ ImageResourceContent* image_content = nullptr;
- UpdateDisplayState();
- if (ShouldDisplayPosterImage()) {
+ // Load the poster if set, |VideoLayout| will decide whether to draw it.
+ if (!PosterImageURL().IsEmpty()) {
if (!image_loader_)
image_loader_ = MakeGarbageCollected<HTMLImageLoader>(this);
image_loader_->UpdateFromElement();
- if (GetLayoutObject()) {
- ToLayoutImage(GetLayoutObject())
- ->ImageResource()
- ->SetImageResource(image_loader_->GetContent());
- }
+ image_content = image_loader_->GetContent();
+ }
+
+ if (GetLayoutObject()) {
+ ToLayoutImage(GetLayoutObject())
+ ->ImageResource()
+ ->SetImageResource(image_content);
+ UpdateLayoutObject();
}
}
@@ -187,25 +195,8 @@ bool HTMLVideoElement::IsPresentationAttribute(
void HTMLVideoElement::ParseAttribute(
const AttributeModificationParams& params) {
if (params.name == html_names::kPosterAttr) {
- // In case the poster attribute is set after playback, don't update the
- // display state, post playback the correct state will be picked up.
- if (GetDisplayMode() < kVideo || !HasAvailableVideoFrame()) {
- // Force a poster recalc by setting display_mode_ to kUnknown directly
- // before calling UpdateDisplayState.
- HTMLMediaElement::SetDisplayMode(kUnknown);
- UpdateDisplayState();
- }
- if (!PosterImageURL().IsEmpty()) {
- if (!image_loader_)
- image_loader_ = MakeGarbageCollected<HTMLImageLoader>(this);
- image_loader_->UpdateFromElement(ImageLoader::kUpdateIgnorePreviousError);
- } else {
- if (GetLayoutObject()) {
- ToLayoutImage(GetLayoutObject())
- ->ImageResource()
- ->SetImageResource(nullptr);
- }
- }
+ UpdatePosterImage();
+
// Notify the player when the poster image URL changes.
if (GetWebMediaPlayer())
GetWebMediaPlayer()->SetPoster(PosterImageURL());
@@ -264,25 +255,6 @@ const AtomicString HTMLVideoElement::ImageSourceURL() const {
return default_poster_url_;
}
-void HTMLVideoElement::SetDisplayMode(DisplayMode mode) {
- DisplayMode old_mode = GetDisplayMode();
- KURL poster = PosterImageURL();
-
- if (!poster.IsEmpty()) {
- // We have a poster path, but only show it until the user triggers display
- // by playing or seeking and the media engine has something to display.
- // Don't show the poster if there is a seek operation or the video has
- // restarted because of loop attribute
- if (mode == kVideo && old_mode == kPoster && !HasAvailableVideoFrame())
- return;
- }
-
- HTMLMediaElement::SetDisplayMode(mode);
-
- if (GetLayoutObject() && GetDisplayMode() != old_mode)
- GetLayoutObject()->UpdateFromElement();
-}
-
void HTMLVideoElement::UpdatePictureInPictureAvailability() {
if (!web_media_player_)
return;
@@ -349,13 +321,6 @@ bool HTMLVideoElement::IsPersistent() const {
return is_persistent_;
}
-void HTMLVideoElement::UpdateDisplayState() {
- if (PosterImageURL().IsEmpty() || HasAvailableVideoFrame())
- SetDisplayMode(kVideo);
- else if (GetDisplayMode() < kPoster)
- SetDisplayMode(kPoster);
-}
-
void HTMLVideoElement::OnPlay() {
if (!video_has_played_) {
video_has_played_ = true;
@@ -598,7 +563,6 @@ KURL HTMLVideoElement::PosterImageURL() const {
scoped_refptr<Image> HTMLVideoElement::GetSourceImageForCanvas(
SourceImageStatus* status,
- AccelerationHint,
const FloatSize&) {
if (!HasAvailableVideoFrame()) {
*status = kInvalidSourceImageStatus;
@@ -607,8 +571,6 @@ scoped_refptr<Image> HTMLVideoElement::GetSourceImageForCanvas(
IntSize intrinsic_size(videoWidth(), videoHeight());
// TODO(fserb): this should not be default software.
- // FIXME: Not sure if we should we be doing anything with the AccelerationHint
- // argument here? Currently we use unacceleration mode.
std::unique_ptr<CanvasResourceProvider> resource_provider =
CanvasResourceProvider::CreateBitmapProvider(
intrinsic_size, kLow_SkFilterQuality, CanvasColorParams());
@@ -654,7 +616,7 @@ ScriptPromise HTMLVideoElement::CreateImageBitmap(
"The provided element has not retrieved data.");
return ScriptPromise();
}
- if (getReadyState() <= HTMLMediaElement::kHaveMetadata) {
+ if (!HasAvailableVideoFrame()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
"The provided element's player has no current data.");
@@ -771,6 +733,10 @@ void HTMLVideoElement::SetIsDominantVisibleContent(bool is_dominant) {
auto* player = GetWebMediaPlayer();
if (player)
player->BecameDominantVisibleContent(mostly_filling_viewport_);
+
+ auto* local_frame_view = GetDocument().View();
+ if (local_frame_view)
+ local_frame_view->NotifyVideoIsDominantVisibleStatus(this, is_dominant);
}
}
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_video_element.h b/chromium/third_party/blink/renderer/core/html/media/html_video_element.h
index d8ce1f17a1a..f5375948ea1 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_video_element.h
+++ b/chromium/third_party/blink/renderer/core/html/media/html_video_element.h
@@ -53,12 +53,13 @@ class CORE_EXPORT HTMLVideoElement final
public ImageBitmapSource,
public Supplementable<HTMLVideoElement> {
DEFINE_WRAPPERTYPEINFO();
+ USING_GARBAGE_COLLECTED_MIXIN(HTMLVideoElement);
public:
static const int kNoAlreadyUploadedFrame = -1;
- HTMLVideoElement(Document&);
- void Trace(Visitor*) override;
+ explicit HTMLVideoElement(Document&);
+ void Trace(Visitor*) const override;
bool HasPendingActivity() const final;
@@ -149,15 +150,12 @@ class CORE_EXPORT HTMLVideoElement final
int already_uploaded_id,
WebMediaPlayer::VideoFrameUploadMetadata* out_metadata);
- bool ShouldDisplayPosterImage() const { return GetDisplayMode() == kPoster; }
-
bool HasAvailableVideoFrame() const;
KURL PosterImageURL() const override;
// CanvasImageSource implementation
scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*,
- AccelerationHint,
const FloatSize&) override;
bool IsVideoElement() const override { return true; }
bool WouldTaintOrigin() const override;
@@ -201,13 +199,6 @@ class CORE_EXPORT HTMLVideoElement final
void SetIsEffectivelyFullscreen(blink::WebFullscreenVideoStatus);
void SetIsDominantVisibleContent(bool is_dominant);
- void SetImageForTest(ImageResourceContent* content) {
- if (!image_loader_)
- image_loader_ = MakeGarbageCollected<HTMLImageLoader>(this);
- image_loader_->SetImageForTest(content);
- SetDisplayMode(kPoster);
- }
-
VideoWakeLock* wake_lock_for_tests() const { return wake_lock_; }
protected:
@@ -231,6 +222,7 @@ class CORE_EXPORT HTMLVideoElement final
bool LayoutObjectIsNeeded(const ComputedStyle&) const override;
LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
void AttachLayoutTree(AttachContext&) override;
+ void UpdatePosterImage();
void ParseAttribute(const AttributeModificationParams&) override;
bool IsPresentationAttribute(const QualifiedName&) const override;
void CollectStyleForPresentationAttribute(
@@ -240,12 +232,10 @@ class CORE_EXPORT HTMLVideoElement final
bool IsURLAttribute(const Attribute&) const override;
const AtomicString ImageSourceURL() const override;
- void UpdateDisplayState() override;
void OnPlay() final;
void OnLoadStarted() final;
void OnLoadFinished() final;
void DidMoveToNewDocument(Document& old_document) override;
- void SetDisplayMode(DisplayMode) override;
void UpdatePictureInPictureAvailability();
diff --git a/chromium/third_party/blink/renderer/core/html/media/media_controls.cc b/chromium/third_party/blink/renderer/core/html/media/media_controls.cc
index 4f735e0d753..ce1bfe739d4 100644
--- a/chromium/third_party/blink/renderer/core/html/media/media_controls.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/media_controls.cc
@@ -48,7 +48,7 @@ HTMLMediaElement& MediaControls::MediaElement() const {
return *media_element_;
}
-void MediaControls::Trace(Visitor* visitor) {
+void MediaControls::Trace(Visitor* visitor) const {
visitor->Trace(media_element_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/media/media_controls.h b/chromium/third_party/blink/renderer/core/html/media/media_controls.h
index 57c9b42217f..955dcbe5dba 100644
--- a/chromium/third_party/blink/renderer/core/html/media/media_controls.h
+++ b/chromium/third_party/blink/renderer/core/html/media/media_controls.h
@@ -77,7 +77,7 @@ class CORE_EXPORT MediaControls : public GarbageCollectedMixin {
virtual HTMLDivElement* PanelElement() = 0;
virtual void OnMediaControlsEnabledChange() = 0;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<HTMLMediaElement> media_element_;
diff --git a/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc b/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc
index 9955b98391a..ebc5ca05433 100644
--- a/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc
@@ -231,7 +231,7 @@ bool MediaCustomControlsFullscreenDetector::IsVideoOrParentFullscreen() {
return fullscreen_element->contains(&VideoElement());
}
-void MediaCustomControlsFullscreenDetector::Trace(Visitor* visitor) {
+void MediaCustomControlsFullscreenDetector::Trace(Visitor* visitor) const {
NativeEventListener::Trace(visitor);
visitor->Trace(video_element_);
visitor->Trace(viewport_intersection_observer_);
diff --git a/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.h b/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.h
index fcd75bfd8a9..570ce9c03b5 100644
--- a/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.h
+++ b/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.h
@@ -34,7 +34,7 @@ class CORE_EXPORT MediaCustomControlsFullscreenDetector final
// EventListener implementation.
void Invoke(ExecutionContext*, Event*) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void TriggerObservation();
private:
diff --git a/chromium/third_party/blink/renderer/core/html/media/media_element_parser_helpers.cc b/chromium/third_party/blink/renderer/core/html/media/media_element_parser_helpers.cc
index eb358a1d903..b358da2044d 100644
--- a/chromium/third_party/blink/renderer/core/html/media/media_element_parser_helpers.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/media_element_parser_helpers.cc
@@ -18,7 +18,7 @@ void CheckUnsizedMediaViolation(const LayoutObject* layout_object,
bool is_unsized = !style.LogicalWidth().IsSpecified() &&
!style.LogicalHeight().IsSpecified();
if (is_unsized) {
- layout_object->GetDocument().IsFeatureEnabled(
+ layout_object->GetDocument().GetExecutionContext()->IsFeatureEnabled(
mojom::blink::DocumentPolicyFeature::kUnsizedMedia,
send_report ? ReportOptions::kReportOnFailure
: ReportOptions::kDoNotReport);
diff --git a/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc b/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc
index 0024ef5fbc4..8fa88c6d7e9 100644
--- a/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc
@@ -154,7 +154,7 @@ void MediaRemotingInterstitial::OnPosterImageChanged() {
GetVideoElement().FastGetAttribute(html_names::kPosterAttr));
}
-void MediaRemotingInterstitial::Trace(Visitor* visitor) {
+void MediaRemotingInterstitial::Trace(Visitor* visitor) const {
visitor->Trace(video_element_);
visitor->Trace(background_image_);
visitor->Trace(cast_icon_);
diff --git a/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h b/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h
index 6457522a778..8ccf4baa726 100644
--- a/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h
+++ b/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h
@@ -47,7 +47,7 @@ class MediaRemotingInterstitial final : public HTMLDivElement {
HTMLVideoElement& GetVideoElement() const { return *video_element_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Node override.
diff --git a/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc b/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc
index 40baab9412a..5627a70f441 100644
--- a/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc
@@ -47,7 +47,7 @@ class PictureInPictureInterstitial::VideoElementResizeObserverDelegate final
interstitial_->NotifyElementSizeChanged(*entries[0]->contentRect());
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(interstitial_);
ResizeObserver::Delegate::Trace(visitor);
}
@@ -173,7 +173,7 @@ void PictureInPictureInterstitial::OnPosterImageChanged() {
GetVideoElement().FastGetAttribute(html_names::kPosterAttr));
}
-void PictureInPictureInterstitial::Trace(Visitor* visitor) {
+void PictureInPictureInterstitial::Trace(Visitor* visitor) const {
visitor->Trace(resize_observer_);
visitor->Trace(video_element_);
visitor->Trace(background_image_);
diff --git a/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.h b/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.h
index deaaff75a85..85aae77812d 100644
--- a/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.h
+++ b/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.h
@@ -40,7 +40,7 @@ class PictureInPictureInterstitial final : public HTMLDivElement {
void RemovedFrom(ContainerNode&) override;
// Element:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class VideoElementResizeObserverDelegate;
diff --git a/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.cc b/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.cc
index 71f3d3c57b8..bb1cd102a2c 100644
--- a/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.cc
@@ -16,7 +16,7 @@ RemotePlaybackController* RemotePlaybackController::From(
return Supplement<HTMLMediaElement>::From<RemotePlaybackController>(element);
}
-void RemotePlaybackController::Trace(Visitor* visitor) {
+void RemotePlaybackController::Trace(Visitor* visitor) const {
Supplement<HTMLMediaElement>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.h b/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.h
index 5bd208eb656..64eb54916ed 100644
--- a/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.h
+++ b/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.h
@@ -30,7 +30,7 @@ class CORE_EXPORT RemotePlaybackController
virtual void AvailabilityChangedForTesting(bool screen_is_available) = 0;
virtual void StateChangedForTesting(bool is_connected) = 0;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit RemotePlaybackController(HTMLMediaElement&);
diff --git a/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.cc b/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.cc
index d0998e37e35..a27ed684da0 100644
--- a/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.cc
@@ -19,7 +19,7 @@ VideoFrameCallbackRequester* VideoFrameCallbackRequester::From(
element);
}
-void VideoFrameCallbackRequester::Trace(Visitor* visitor) {
+void VideoFrameCallbackRequester::Trace(Visitor* visitor) const {
Supplement<HTMLVideoElement>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.h b/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.h
index 7f4dff1cb39..b5743ddcebb 100644
--- a/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.h
+++ b/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.h
@@ -27,7 +27,7 @@ class CORE_EXPORT VideoFrameCallbackRequester
virtual ~VideoFrameCallbackRequester() = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
virtual void OnWebMediaPlayerCreated() = 0;
virtual void OnRequestVideoFrameCallback() = 0;
diff --git a/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.cc b/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.cc
index 5ec06cd93ab..c90cede4b1f 100644
--- a/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.cc
@@ -64,7 +64,7 @@ void VideoWakeLock::OnVisibilityChanged(
Update();
}
-void VideoWakeLock::Trace(Visitor* visitor) {
+void VideoWakeLock::Trace(Visitor* visitor) const {
NativeEventListener::Trace(visitor);
PageVisibilityObserver::Trace(visitor);
ExecutionContextLifecycleStateObserver::Trace(visitor);
@@ -117,6 +117,9 @@ bool VideoWakeLock::ShouldBeActive() const {
bool page_visible = GetPage() && GetPage()->IsPageVisible();
bool in_picture_in_picture =
PictureInPictureController::IsElementInPictureInPicture(&VideoElement());
+ bool context_is_running =
+ VideoElement().GetExecutionContext() &&
+ !VideoElement().GetExecutionContext()->IsContextPaused();
// The visibility requirements are met if one of the following is true:
// - it's in Picture-in-Picture;
@@ -135,8 +138,7 @@ bool VideoWakeLock::ShouldBeActive() const {
return playing_ && visibility_requirements_met &&
remote_playback_state_ !=
mojom::blink::PresentationConnectionState::CONNECTED &&
- !(VideoElement().GetDocument().IsContextPaused() ||
- VideoElement().GetDocument().IsContextDestroyed());
+ context_is_running;
}
void VideoWakeLock::EnsureWakeLockService() {
diff --git a/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.h b/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.h
index b042b0ca13c..c4e686b2620 100644
--- a/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.h
+++ b/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.h
@@ -40,7 +40,7 @@ class CORE_EXPORT VideoWakeLock final
void ElementDidMoveToNewDocument();
- void Trace(Visitor*) final;
+ void Trace(Visitor*) const final;
// EventListener implementation.
void Invoke(ExecutionContext*, Event*) final;
diff --git a/chromium/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc b/chromium/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc
index 407b93e81fb..62f79d46479 100644
--- a/chromium/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc
@@ -102,7 +102,7 @@ class VideoWakeLockTest : public PageTestBase {
nullptr, MakeGarbageCollected<VideoWakeLockFrameClient>(
std::make_unique<VideoWakeLockMediaPlayer>()));
- GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting(
+ GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting(
mojom::blink::PictureInPictureService::Name_,
WTF::BindRepeating(&VideoWakeLockPictureInPictureService::Bind,
WTF::Unretained(&pip_service_)));
@@ -117,7 +117,7 @@ class VideoWakeLockTest : public PageTestBase {
}
void TearDown() override {
- GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting(
+ GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting(
mojom::blink::PictureInPictureService::Name_, {});
PageTestBase::TearDown();
@@ -165,9 +165,7 @@ class VideoWakeLockTest : public PageTestBase {
mojom::FrameLifecycleState::kRunning);
}
- void SimulateContextDestroyed() {
- GetFrame().DomWindow()->NotifyContextDestroyed();
- }
+ void SimulateContextDestroyed() { GetFrame().DomWindow()->FrameDestroyed(); }
void SimulateNetworkState(HTMLMediaElement::NetworkState network_state) {
video_->SetNetworkState(network_state);
diff --git a/chromium/third_party/blink/renderer/core/html/parser/BUILD.gn b/chromium/third_party/blink/renderer/core/html/parser/BUILD.gn
index 43eb9f797d7..24c6c997ae8 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/html/parser/BUILD.gn
@@ -47,8 +47,6 @@ blink_core_sources("parser") {
"html_preload_scanner.h",
"html_resource_preloader.cc",
"html_resource_preloader.h",
- "html_source_tracker.cc",
- "html_source_tracker.h",
"html_srcset_parser.cc",
"html_srcset_parser.h",
"html_stack_item.h",
@@ -76,12 +74,14 @@ blink_core_sources("parser") {
"text_document_parser.h",
"text_resource_decoder.cc",
"text_resource_decoder.h",
+ "text_resource_decoder_builder.cc",
+ "text_resource_decoder_builder.h",
]
# Optimizing the HTML parser for speed yields significant gains in performance
# in parser-heavy scenarios. See https://crbug.com/787512.
- # Windows builds already override the default optimization in core.gni.
- if (!is_debug && !is_win) {
+ # All other platforms already override this in core.gni.
+ if (!is_debug && is_android) {
configs -= [ "//build/config/compiler:default_optimization" ]
configs += [ "//build/config/compiler:optimize_max" ]
}
diff --git a/chromium/third_party/blink/renderer/core/html/parser/atomic_html_token.h b/chromium/third_party/blink/renderer/core/html/parser/atomic_html_token.h
index 6c1dcaa54c6..a70363c9e9c 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/atomic_html_token.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/atomic_html_token.h
@@ -29,6 +29,7 @@
#include <memory>
#include "base/macros.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/core/dom/attribute.h"
#include "third_party/blink/renderer/core/html/parser/compact_html_token.h"
#include "third_party/blink/renderer/core/html/parser/html_token.h"
diff --git a/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.h b/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.h
index de2b5d96511..34278f1e6df 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.h
@@ -37,7 +37,6 @@
#include "third_party/blink/renderer/core/html/parser/compact_html_token.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_options.h"
#include "third_party/blink/renderer/core/html/parser/html_preload_scanner.h"
-#include "third_party/blink/renderer/core/html/parser/html_source_tracker.h"
#include "third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
#include "third_party/blink/renderer/core/page/viewport_description.h"
@@ -108,7 +107,6 @@ class BackgroundHTMLParser {
void UpdateDocument(const String& decoded_data);
BackgroundHTMLInputStream input_;
- HTMLSourceTracker source_tracker_;
std::unique_ptr<HTMLToken> token_;
std::unique_ptr<HTMLTokenizer> tokenizer_;
HTMLTreeBuilderSimulator tree_builder_simulator_;
diff --git a/chromium/third_party/blink/renderer/core/html/parser/compact_html_token.cc b/chromium/third_party/blink/renderer/core/html/parser/compact_html_token.cc
index 8291327ed58..b2d884a105b 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/compact_html_token.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/compact_html_token.cc
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/core/html/parser/compact_html_token.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/core/dom/qualified_name.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.cc b/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.cc
index dc384962258..b7644d32558 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.cc
@@ -115,8 +115,13 @@ static inline void Insert(HTMLConstructionSiteTask& task) {
// 3. If the adjusted insertion location is inside a template element, let it
// instead be inside the template element's template contents, after its last
// child (if any).
- if (auto* template_element = DynamicTo<HTMLTemplateElement>(*task.parent))
+ if (auto* template_element = DynamicTo<HTMLTemplateElement>(*task.parent)) {
task.parent = template_element->TemplateContentForHTMLConstructionSite();
+ // If the Document was detached in the middle of parsing, The template
+ // element won't be able to initialize its contents, so bail out.
+ if (!task.parent)
+ return;
+ }
// https://html.spec.whatwg.org/C/#insert-a-foreign-element
// 3.1, (3) Push (pop) an element queue
@@ -390,7 +395,7 @@ HTMLConstructionSite::~HTMLConstructionSite() {
DCHECK(pending_text_.IsEmpty());
}
-void HTMLConstructionSite::Trace(Visitor* visitor) {
+void HTMLConstructionSite::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(attachment_root_);
visitor->Trace(head_);
@@ -745,6 +750,9 @@ void HTMLConstructionSite::InsertFormattingElement(AtomicHTMLToken* token) {
void HTMLConstructionSite::InsertScriptElement(AtomicHTMLToken* token) {
CreateElementFlags flags;
+ bool should_be_parser_inserted =
+ parser_content_policy_ !=
+ kAllowScriptingContentAndDoNotMarkAlreadyStarted;
flags
// http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#already-started
// http://html5.org/specs/dom-parsing.html#dom-range-createcontextualfragment
@@ -752,8 +760,8 @@ void HTMLConstructionSite::InsertScriptElement(AtomicHTMLToken* token) {
// parser-inserted and already-started and later unmark them. However, we
// short circuit that logic to avoid the subtree traversal to find script
// elements since scripts can never see those flags or effects thereof.
- .SetCreatedByParser(parser_content_policy_ !=
- kAllowScriptingContentAndDoNotMarkAlreadyStarted)
+ .SetCreatedByParser(should_be_parser_inserted,
+ should_be_parser_inserted ? document_ : nullptr)
.SetAlreadyStarted(is_parsing_fragment_ && flags.IsCreatedByParser());
HTMLScriptElement* element = nullptr;
if (const auto* is_attribute = token->GetAttributeItem(html_names::kIsAttr)) {
@@ -799,8 +807,12 @@ void HTMLConstructionSite::InsertTextNode(const StringView& string,
// handled in Insert().
if (auto* template_element =
DynamicTo<HTMLTemplateElement>(*dummy_task.parent)) {
- dummy_task.parent =
- template_element->TemplateContentForHTMLConstructionSite();
+ // If the Document was detached in the middle of parsing, the template
+ // element won't be able to initialize its contents.
+ if (auto* content =
+ template_element->TemplateContentForHTMLConstructionSite()) {
+ dummy_task.parent = content;
+ }
}
// Unclear when parent != case occurs. Somehow we insert text into two
@@ -857,8 +869,8 @@ void HTMLConstructionSite::TakeAllChildren(
}
CreateElementFlags HTMLConstructionSite::GetCreateElementFlags() const {
- return is_parsing_fragment_ ? CreateElementFlags::ByFragmentParser()
- : CreateElementFlags::ByParser();
+ return is_parsing_fragment_ ? CreateElementFlags::ByFragmentParser(document_)
+ : CreateElementFlags::ByParser(document_);
}
Document& HTMLConstructionSite::OwnerDocumentForCurrentNode() {
@@ -867,8 +879,13 @@ Document& HTMLConstructionSite::OwnerDocumentForCurrentNode() {
// used in those places. The spec needs to be updated to reflect this
// behavior, and when that happens, a link to the spec should be placed here.
if (auto* template_element = DynamicTo<HTMLTemplateElement>(*CurrentNode())) {
- return template_element->TemplateContentForHTMLConstructionSite()
- ->GetDocument();
+ // If the Document was detached in the middle of parsing, The template
+ // element won't be able to initialize its contents. Fallback to the
+ // current node's document in that case..
+ if (auto* content =
+ template_element->TemplateContentForHTMLConstructionSite()) {
+ return content->GetDocument();
+ }
}
return CurrentNode()->GetDocument();
}
@@ -884,7 +901,7 @@ CustomElementDefinition* HTMLConstructionSite::LookUpCustomElementDefinition(
return nullptr;
// "2. If document does not have a browsing context, return null."
- LocalDOMWindow* window = document.ExecutingWindow();
+ LocalDOMWindow* window = document.domWindow();
if (!window)
return nullptr;
@@ -950,7 +967,8 @@ Element* HTMLConstructionSite::CreateElement(
// only partially construct themselves when created by the parser, but since
// this is a custom element, we need a fully-constructed element here.
element = definition->CreateElement(
- document, tag_name, GetCreateElementFlags().SetCreatedByParser(false));
+ document, tag_name,
+ GetCreateElementFlags().SetCreatedByParser(false, nullptr));
// "8. Append each attribute in the given token to element." We don't use
// setAttributes here because the custom element constructor may have
@@ -1145,7 +1163,7 @@ void HTMLConstructionSite::FosterParent(Node* node) {
QueueTask(task);
}
-void HTMLConstructionSite::PendingText::Trace(Visitor* visitor) {
+void HTMLConstructionSite::PendingText::Trace(Visitor* visitor) const {
visitor->Trace(parent);
visitor->Trace(next_child);
}
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.h b/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.h
index 6e40ad8438f..a1d6a3c6b37 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.h
@@ -53,7 +53,7 @@ struct HTMLConstructionSiteTask {
explicit HTMLConstructionSiteTask(Operation op)
: operation(op), self_closing(false) {}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(parent);
visitor->Trace(next_child);
visitor->Trace(child);
@@ -112,7 +112,7 @@ class HTMLConstructionSite final {
Document&,
ParserContentPolicy);
~HTMLConstructionSite();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void InitFragmentParsing(DocumentFragment*, Element* context_element);
@@ -328,7 +328,7 @@ class HTMLConstructionSite final {
return string_builder.IsEmpty();
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
Member<ContainerNode> parent;
Member<Node> next_child;
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.cc b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.cc
index eb81ef312c7..35b5fd38340 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.cc
@@ -80,6 +80,96 @@ size_t GetDiscardedTokenCountForTesting() {
return g_discarded_token_count_for_testing;
}
+// This sets the maximum number of tokens which the foreground HTML parser
+// should try to process in one go. Lower values generally mean faster first
+// paints, larger values delay first paint, but make sure it's closer to the
+// final page. This value gives a good speedup, but may need to be tuned
+// further.
+constexpr int kMaxTokenizationBudget = 500;
+
+// This class encapsulates the internal state needed for synchronous foreground
+// HTML parsing (e.g. if HTMLDocumentParser::PumpTokenizer yields, this class
+// tracks what should be done after the pump completes.)
+class HTMLDocumentParserState
+ : public GarbageCollected<HTMLDocumentParserState> {
+ public:
+ enum class DeferredParserState {
+ // Indicates that a tokenizer pump has either completed or hasn't been
+ // scheduled.
+ kNotScheduled,
+ // Indicates that a tokenizer pump is scheduled and hasn't completed yet.
+ kScheduled,
+ };
+
+ enum class MetaCSPTokenState {
+ // If we've seen a meta CSP token in an upcoming HTML chunk, then we need to
+ // defer any preloads until we've added the CSP token to the document and
+ // applied the Content Security Policy.
+ kSeen = 0,
+ // Indicates that there is no meta CSP token in the upcoming chunk.
+ kNotSeen = 1,
+ // Indicates that we've added the CSP token to the document and we can now
+ // fetch preloads.
+ kProcessed = 2,
+ // Indicates that it's too late to apply a Content-Security policy (because
+ // we've exited the header section.)
+ kUnenforceable = 3,
+ };
+
+ explicit HTMLDocumentParserState(ParserSynchronizationPolicy mode)
+ : state_(DeferredParserState::kNotScheduled),
+ meta_csp_state_(MetaCSPTokenState::kNotSeen),
+ mode_(mode),
+ end_if_delayed_(false),
+ should_complete_(false) {}
+
+ void Trace(Visitor* v) const {}
+
+ void SetState(DeferredParserState state) { state_ = state; }
+ DeferredParserState GetState() const { return state_; }
+ bool IsScheduled() const { return state_ == DeferredParserState::kScheduled; }
+ const char* GetStateAsString() const {
+ switch (state_) {
+ case DeferredParserState::kNotScheduled:
+ return "not_scheduled";
+ case DeferredParserState::kScheduled:
+ return "scheduled";
+ }
+ }
+
+ void SetEndIfDelayed(bool value) { end_if_delayed_ = value; }
+ void SetShouldComplete(bool value) { should_complete_ = value; }
+ bool ShouldEndIfDelayed() const { return end_if_delayed_; }
+ bool ShouldComplete() const { return should_complete_; }
+ bool IsSynchronous() const {
+ return mode_ == ParserSynchronizationPolicy::kForceSynchronousParsing;
+ }
+ ParserSynchronizationPolicy GetMode() const { return mode_; }
+
+ void SetSeenCSPMetaTag(const bool seen) {
+ if (meta_csp_state_ == MetaCSPTokenState::kUnenforceable)
+ return;
+ if (seen)
+ meta_csp_state_ = MetaCSPTokenState::kSeen;
+ else
+ meta_csp_state_ = MetaCSPTokenState::kNotSeen;
+ }
+
+ void SetExitedHeader() {
+ meta_csp_state_ = MetaCSPTokenState::kUnenforceable;
+ }
+ bool HaveExitedHeader() const {
+ return meta_csp_state_ == MetaCSPTokenState::kUnenforceable;
+ }
+
+ private:
+ DeferredParserState state_;
+ MetaCSPTokenState meta_csp_state_;
+ ParserSynchronizationPolicy mode_;
+ bool end_if_delayed_;
+ bool should_complete_;
+};
+
// This is a direct transcription of step 4 from:
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
static HTMLTokenizer::State TokenizerStateForContextElement(
@@ -169,20 +259,24 @@ HTMLDocumentParser::HTMLDocumentParser(Document& document,
: ScriptableDocumentParser(document, content_policy),
options_(&document),
reentry_permit_(HTMLParserReentryPermit::Create()),
- token_(sync_policy == kForceSynchronousParsing
+ token_(sync_policy != kAllowAsynchronousParsing
? std::make_unique<HTMLToken>()
: nullptr),
- tokenizer_(sync_policy == kForceSynchronousParsing
+ tokenizer_(sync_policy != kAllowAsynchronousParsing
? std::make_unique<HTMLTokenizer>(options_)
: nullptr),
- loading_task_runner_(document.GetTaskRunner(TaskType::kNetworking)),
+ loading_task_runner_(sync_policy == kForceSynchronousParsing
+ ? nullptr
+ : document.GetTaskRunner(TaskType::kNetworking)),
parser_scheduler_(sync_policy == kAllowAsynchronousParsing
? MakeGarbageCollected<HTMLParserScheduler>(
this,
loading_task_runner_.get())
: nullptr),
+ task_runner_state_(
+ MakeGarbageCollected<HTMLDocumentParserState>(sync_policy)),
pending_csp_meta_token_(nullptr),
- should_use_threading_(sync_policy == kAllowAsynchronousParsing),
+ can_parse_asynchronously_(sync_policy == kAllowAsynchronousParsing),
end_was_delayed_(false),
have_background_parser_(false),
pump_session_nesting_level_(0),
@@ -190,10 +284,19 @@ HTMLDocumentParser::HTMLDocumentParser(Document& document,
is_parsing_at_line_number_(false),
tried_loading_link_headers_(false),
added_pending_parser_blocking_stylesheet_(false),
- is_waiting_for_stylesheets_(false) {
- DCHECK(ShouldUseThreading() || (token_ && tokenizer_));
- // Threading is not allowed in prefetch mode.
- DCHECK(!document.IsPrefetchOnly() || !ShouldUseThreading());
+ is_waiting_for_stylesheets_(false),
+ scheduler_(sync_policy == kAllowDeferredParsing
+ ? Thread::Current()->Scheduler()
+ : nullptr) {
+ DCHECK(CanParseAsynchronously() || (token_ && tokenizer_));
+ // Asynchronous parsing is not allowed in prefetch mode.
+ DCHECK(!document.IsPrefetchOnly() || !CanParseAsynchronously());
+
+ // It is permissible to request the background HTML parser whilst also using
+ // --enable-blink-features=ForceSynchronousHTMLParsing, but it's usually
+ // unintentional. To help flush out these cases, trigger a DCHECK.
+ DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled() ||
+ !CanParseAsynchronously());
// Report metrics for async document parsing only. The document
// must be main frame to meet UKM requirements, and must have a high
@@ -231,11 +334,12 @@ void HTMLDocumentParser::Dispose() {
StopBackgroundParser();
}
-void HTMLDocumentParser::Trace(Visitor* visitor) {
+void HTMLDocumentParser::Trace(Visitor* visitor) const {
visitor->Trace(tree_builder_);
visitor->Trace(parser_scheduler_);
visitor->Trace(script_runner_);
visitor->Trace(preloader_);
+ visitor->Trace(task_runner_state_);
ScriptableDocumentParser::Trace(visitor);
HTMLParserScriptRunnerHost::Trace(visitor);
}
@@ -269,6 +373,8 @@ void HTMLDocumentParser::StopParsing() {
parser_scheduler_->Detach();
parser_scheduler_.Clear();
}
+ task_runner_state_->SetState(
+ HTMLDocumentParserState::DeferredParserState::kNotScheduled);
if (have_background_parser_)
StopBackgroundParser();
}
@@ -276,6 +382,8 @@ void HTMLDocumentParser::StopParsing() {
// This kicks off "Once the user agent stops parsing" as described by:
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the-end
void HTMLDocumentParser::PrepareToStopParsing() {
+ TRACE_EVENT1("blink", "HTMLDocumentParser::PrepareToStopParsing", "parser",
+ (void*)this);
// FIXME: It may not be correct to disable this for the background parser.
// That means hasInsertionPoint() may not be correct in some cases.
DCHECK(!HasInsertionPoint() || have_background_parser_);
@@ -283,6 +391,7 @@ void HTMLDocumentParser::PrepareToStopParsing() {
// NOTE: This pump should only ever emit buffered character tokens.
if (tokenizer_ && !GetDocument()->IsPrefetchOnly()) {
DCHECK(!have_background_parser_);
+ task_runner_state_->SetShouldComplete(true);
PumpTokenizerIfPossible();
}
@@ -310,12 +419,44 @@ bool HTMLDocumentParser::IsParsingFragment() const {
return tree_builder_->IsParsingFragment();
}
+void HTMLDocumentParser::DeferredPumpTokenizerIfPossible() {
+ // This method is called asynchronously, continues building the HTML document.
+ // This function should only be called when
+ // --enable-blink-features=ForceSynchronousHTMLParsing is available.
+ DCHECK(RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled());
+ TRACE_EVENT2("blink", "HTMLDocumentParser::DeferredPumpTokenizerIfPossible",
+ "parser", (void*)this, "state",
+ task_runner_state_->GetStateAsString());
+
+ if (IsDetached())
+ return;
+
+ if (task_runner_state_->IsScheduled()) {
+ HTMLDocumentParser::PumpTokenizerIfPossible();
+ }
+}
+
void HTMLDocumentParser::PumpTokenizerIfPossible() {
+ // This method is called synchronously, builds the HTML document up to
+ // the current budget, and optionally completes.
+ TRACE_EVENT1("blink", "HTMLDocumentParser::PumpTokenizerIfPossible", "parser",
+ (void*)this);
+
+ bool yielded = false;
+ const bool should_call_delay_end = task_runner_state_->ShouldEndIfDelayed();
CheckIfBlockingStylesheetAdded();
- if (IsStopped() || IsPaused())
- return;
+ if (!IsStopped() && !IsPaused()) {
+ yielded = PumpTokenizer();
+ }
- PumpTokenizer();
+ if (!yielded) {
+ // If we did not exceed the budget or parsed everything there was to
+ // parse, check if we should complete the document.
+ if (should_call_delay_end) {
+ EndIfDelayed();
+ }
+ task_runner_state_->SetShouldComplete(false);
+ }
}
bool HTMLDocumentParser::IsScheduledForUnpause() const {
@@ -324,8 +465,9 @@ bool HTMLDocumentParser::IsScheduledForUnpause() const {
// Used by HTMLParserScheduler
void HTMLDocumentParser::ResumeParsingAfterYield() {
- DCHECK(ShouldUseThreading());
+ DCHECK(CanParseAsynchronously());
DCHECK(have_background_parser_);
+ DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled());
ScopedYieldTimer(&yield_timer_, metrics_reporter_.get());
@@ -337,6 +479,8 @@ void HTMLDocumentParser::ResumeParsingAfterYield() {
}
void HTMLDocumentParser::RunScriptsForPausedTreeBuilder() {
+ TRACE_EVENT1("blink", "HTMLDocumentParser::RunScriptsForPausedTreeBuilder",
+ "parser", (void*)this);
DCHECK(ScriptingContentIsAllowed(GetParserContentPolicy()));
TextPosition script_start_position = TextPosition::BelowRangePosition();
@@ -363,6 +507,7 @@ bool HTMLDocumentParser::CanTakeNextToken() {
void HTMLDocumentParser::EnqueueTokenizedChunk(
std::unique_ptr<TokenizedChunk> chunk) {
+ DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled());
TRACE_EVENT0("blink", "HTMLDocumentParser::EnqueueTokenizedChunk");
DCHECK(chunk);
@@ -441,11 +586,13 @@ void HTMLDocumentParser::EnqueueTokenizedChunk(
void HTMLDocumentParser::DidReceiveEncodingDataFromBackgroundParser(
const DocumentEncodingData& data) {
+ DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled());
GetDocument()->SetEncodingData(data);
}
void HTMLDocumentParser::ValidateSpeculations(
std::unique_ptr<TokenizedChunk> chunk) {
+ DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled());
DCHECK(chunk);
// TODO(kouhei): We should simplify codepath here by disallowing
// ValidateSpeculations
@@ -494,6 +641,7 @@ void HTMLDocumentParser::DiscardSpeculationsAndResumeFrom(
std::unique_ptr<TokenizedChunk> last_chunk_before_script,
std::unique_ptr<HTMLToken> token,
std::unique_ptr<HTMLTokenizer> tokenizer) {
+ DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled());
// Clear back ref.
background_parser_->ClearParser();
@@ -539,10 +687,11 @@ size_t HTMLDocumentParser::ProcessTokenizedChunkFromBackgroundParser(
SECURITY_DCHECK(pump_speculations_session_nesting_level_ == 1);
SECURITY_DCHECK(!InPumpSession());
+ DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled());
DCHECK(!IsParsingFragment());
DCHECK(!IsPaused());
DCHECK(!IsStopped());
- DCHECK(ShouldUseThreading());
+ DCHECK(CanParseAsynchronously());
DCHECK(!tokenizer_);
DCHECK(!token_);
DCHECK(!last_chunk_before_pause_);
@@ -619,6 +768,7 @@ void HTMLDocumentParser::PumpPendingSpeculations() {
DCHECK(!IsStopped());
DCHECK(!IsScheduledForUnpause());
DCHECK(!InPumpSession());
+ DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled());
// FIXME: Here should never be reached when there is a blocking script,
// but it happens in unknown scenarios. See https://crbug.com/440901
@@ -666,7 +816,7 @@ void HTMLDocumentParser::PumpPendingSpeculations() {
}
void HTMLDocumentParser::ForcePlaintextForTextDocument() {
- if (ShouldUseThreading()) {
+ if (CanParseAsynchronously()) {
// This method is called before any data is appended, so we have to start
// the background parser ourselves.
if (!have_background_parser_)
@@ -679,7 +829,14 @@ void HTMLDocumentParser::ForcePlaintextForTextDocument() {
tokenizer_->SetState(HTMLTokenizer::kPLAINTEXTState);
}
-void HTMLDocumentParser::PumpTokenizer() {
+bool HTMLDocumentParser::PumpTokenizer() {
+ // If we're in kForceSynchronousParsing, always run until all available input
+ // is consumed.
+ bool should_run_until_completion = task_runner_state_->ShouldComplete() ||
+ task_runner_state_->IsSynchronous();
+ TRACE_EVENT2("blink", "HTMLDocumentParser::PumpTokenizer", "should_complete",
+ should_run_until_completion, "parser", (void*)this);
+
DCHECK(!GetDocument()->IsPrefetchOnly());
DCHECK(!IsStopped());
DCHECK(tokenizer_);
@@ -694,20 +851,35 @@ void HTMLDocumentParser::PumpTokenizer() {
// DidWriteHTML instead of WillWriteHTML.
probe::ParseHTML probe(GetDocument(), this);
- while (CanTakeNextToken()) {
+ bool should_yield = false;
+ int budget = kMaxTokenizationBudget;
+
+ while (CanTakeNextToken() && !should_yield) {
{
RUNTIME_CALL_TIMER_SCOPE(
V8PerIsolateData::MainThreadIsolate(),
RuntimeCallStats::CounterId::kHTMLTokenizerNextToken);
if (!tokenizer_->NextToken(input_.Current(), Token()))
break;
+ budget--;
}
ConstructTreeFromHTMLToken();
+ if (!should_run_until_completion && !IsPaused()) {
+ DCHECK_EQ(task_runner_state_->GetMode(), kAllowDeferredParsing);
+ should_yield = budget <= 0;
+ should_yield |= scheduler_->ShouldYieldForHighPriorityWork();
+ should_yield &= task_runner_state_->HaveExitedHeader();
+ } else {
+ should_yield = false;
+ }
DCHECK(IsStopped() || Token().IsUninitialized());
}
+ task_runner_state_->SetState(
+ HTMLDocumentParserState::DeferredParserState::kNotScheduled);
+
if (IsStopped())
- return;
+ return false;
// There should only be PendingText left since the tree-builder always flushes
// the task queue before returning. In case that ever changes, crash.
@@ -726,12 +898,35 @@ void HTMLDocumentParser::PumpTokenizer() {
ScanAndPreload(preload_scanner_.get());
}
}
+
+ CHECK(!(should_yield && (task_runner_state_->ShouldComplete() ||
+ task_runner_state_->IsSynchronous())));
+ if (should_yield) {
+ TRACE_EVENT0("blink", "HTMLDocumentParser::ScheduleTokenizerPump");
+ DCHECK(RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled());
+ DCHECK(!should_run_until_completion);
+ loading_task_runner_->PostTask(
+ FROM_HERE,
+ WTF::Bind(&HTMLDocumentParser::DeferredPumpTokenizerIfPossible,
+ WrapPersistent(this)));
+ task_runner_state_->SetState(
+ HTMLDocumentParserState::DeferredParserState::kScheduled);
+ }
+ return should_yield;
}
void HTMLDocumentParser::ConstructTreeFromHTMLToken() {
DCHECK(!GetDocument()->IsPrefetchOnly());
+
AtomicHTMLToken atomic_token(Token());
+ // Check whether we've exited the header.
+ if (!task_runner_state_->HaveExitedHeader()) {
+ if (GetDocument()->body()) {
+ task_runner_state_->SetExitedHeader();
+ }
+ }
+
// We clear the token_ in case ConstructTreeFromAtomicToken
// synchronously re-enters the parser. We don't clear the token immedately
// for kCharacter tokens because the AtomicHTMLToken avoids copying the
@@ -761,6 +956,7 @@ void HTMLDocumentParser::ConstructTreeFromHTMLToken() {
void HTMLDocumentParser::ConstructTreeFromCompactHTMLToken(
const CompactHTMLToken& compact_token) {
DCHECK(!GetDocument()->IsPrefetchOnly());
+ DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled());
AtomicHTMLToken token(compact_token);
tree_builder_->ConstructTree(&token);
CheckIfBlockingStylesheetAdded();
@@ -779,8 +975,8 @@ void HTMLDocumentParser::insert(const String& source) {
if (IsStopped())
return;
- TRACE_EVENT1("blink", "HTMLDocumentParser::insert", "source_length",
- source.length());
+ TRACE_EVENT2("blink", "HTMLDocumentParser::insert", "source_length",
+ source.length(), "parser", (void*)this);
if (!tokenizer_) {
DCHECK(!InPumpSession());
@@ -792,6 +988,12 @@ void HTMLDocumentParser::insert(const String& source) {
SegmentedString excluded_line_number_source(source);
excluded_line_number_source.SetExcludeLineNumbers();
input_.InsertAtCurrentInsertionPoint(excluded_line_number_source);
+
+ // Pump the the tokenizer to build the document from the given insert point.
+ // Should process everything available and not defer anything.
+ task_runner_state_->SetShouldComplete(true);
+ // Call EndIfDelayed manually at the end to maintain preload behaviour.
+ task_runner_state_->SetEndIfDelayed(false);
PumpTokenizerIfPossible();
if (IsPaused()) {
@@ -802,16 +1004,18 @@ void HTMLDocumentParser::insert(const String& source) {
CreatePreloadScanner(TokenPreloadScanner::ScannerType::kInsertion);
}
insertion_preload_scanner_->AppendToEnd(source);
- ScanAndPreload(insertion_preload_scanner_.get());
+ if (preloader_) {
+ ScanAndPreload(insertion_preload_scanner_.get());
+ }
}
-
EndIfDelayed();
}
void HTMLDocumentParser::StartBackgroundParser() {
TRACE_EVENT0("blink,loading", "HTMLDocumentParser::StartBackgroundParser");
+ DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled());
DCHECK(!IsStopped());
- DCHECK(ShouldUseThreading());
+ DCHECK(CanParseAsynchronously());
DCHECK(!have_background_parser_);
DCHECK(GetDocument());
have_background_parser_ = true;
@@ -839,7 +1043,8 @@ void HTMLDocumentParser::StartBackgroundParser() {
// the status of the Priority Hints Origin Trial, and has no way of figuring
// this out on its own. See https://crbug.com/821464.
bool priority_hints_origin_trial_enabled =
- RuntimeEnabledFeatures::PriorityHintsEnabled(GetDocument());
+ RuntimeEnabledFeatures::PriorityHintsEnabled(
+ GetDocument()->GetExecutionContext());
background_parser_->Init(
GetDocument()->Url(),
@@ -849,8 +1054,9 @@ void HTMLDocumentParser::StartBackgroundParser() {
}
void HTMLDocumentParser::StopBackgroundParser() {
- DCHECK(ShouldUseThreading());
+ DCHECK(CanParseAsynchronously());
DCHECK(have_background_parser_);
+ DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled());
have_background_parser_ = false;
@@ -860,44 +1066,54 @@ void HTMLDocumentParser::StopBackgroundParser() {
}
void HTMLDocumentParser::Append(const String& input_source) {
+ TRACE_EVENT2("blink", "HTMLDocumentParser::append", "size",
+ input_source.length(), "parser", (void*)this);
+
if (IsStopped())
return;
// We should never reach this point if we're using a parser thread, as
// appendBytes() will directly ship the data to the thread.
- DCHECK(!ShouldUseThreading());
+ DCHECK(!CanParseAsynchronously());
- TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"),
- "HTMLDocumentParser::append", "size", input_source.length());
const SegmentedString source(input_source);
+ if (!preload_scanner_ && GetDocument()->Url().IsValid() &&
+ (!task_runner_state_->IsSynchronous() ||
+ GetDocument()->IsPrefetchOnly() || IsPaused())) {
+ // If we're operating with synchronous, budgeted foreground HTML parsing
+ // or using the background parser, need to create a preload scanner to
+ // make sure that parser-blocking Javascript requests are dispatched in
+ // plenty of time, which prevents unnecessary delays.
+ // When parsing without a budget (e.g. for HTML fragment parsing), it's
+ // additional overhead to scan the string unless the parser's already
+ // paused whilst executing a script.
+ preload_scanner_ =
+ CreatePreloadScanner(TokenPreloadScanner::ScannerType::kMainDocument);
+ }
+
if (GetDocument()->IsPrefetchOnly()) {
// Do not prefetch if there is an appcache.
if (GetDocument()->Loader()->GetResponse().AppCacheID() != 0)
return;
- if (!preload_scanner_) {
- preload_scanner_ =
- CreatePreloadScanner(TokenPreloadScanner::ScannerType::kMainDocument);
- }
-
preload_scanner_->AppendToEnd(source);
ScanAndPreload(preload_scanner_.get());
// Return after the preload scanner, do not actually parse the document.
return;
}
-
if (preload_scanner_) {
if (input_.Current().IsEmpty() && !IsPaused()) {
- // We have parsed until the end of the current input and so are now moving
- // ahead of the preload scanner. Clear the scanner so we know to scan
- // starting from the current input point if we block again.
+ // We have parsed until the end of the current input and so are now
+ // moving ahead of the preload scanner. Clear the scanner so we know to
+ // scan starting from the current input point if we block again.
preload_scanner_.reset();
} else {
preload_scanner_->AppendToEnd(source);
- if (IsPaused())
+ if (IsPaused() && preloader_) {
ScanAndPreload(preload_scanner_.get());
+ }
}
}
@@ -910,9 +1126,9 @@ void HTMLDocumentParser::Append(const String& input_source) {
return;
}
+ // Schedule a tokenizer pump to process this new data.
+ task_runner_state_->SetEndIfDelayed(true);
PumpTokenizerIfPossible();
-
- EndIfDelayed();
}
void HTMLDocumentParser::end() {
@@ -942,9 +1158,16 @@ void HTMLDocumentParser::AttemptToRunDeferredScriptsAndEnd() {
end();
}
+bool HTMLDocumentParser::ShouldDelayEnd() const {
+ return InPumpSession() || IsPaused() || IsExecutingScript() ||
+ task_runner_state_->IsScheduled();
+}
+
void HTMLDocumentParser::AttemptToEnd() {
// finish() indicates we will not receive any more data. If we are waiting on
// an external script to load, we can't finish parsing quite yet.
+ TRACE_EVENT1("blink", "HTMLDocumentParser::AttemptToEnd", "parser",
+ (void*)this);
if (ShouldDelayEnd()) {
end_was_delayed_ = true;
@@ -954,6 +1177,9 @@ void HTMLDocumentParser::AttemptToEnd() {
}
void HTMLDocumentParser::EndIfDelayed() {
+ TRACE_EVENT1("blink", "HTMLDocumentParser::EndIfDelayed", "parser",
+ (void*)this);
+ task_runner_state_->SetEndIfDelayed(false);
// If we've already been detached, don't bother ending.
if (IsDetached())
return;
@@ -975,8 +1201,8 @@ void HTMLDocumentParser::Finish() {
return;
// Empty documents never got an append() call, and thus have never started a
- // background parser. In those cases, we ignore shouldUseThreading() and fall
- // through to the non-threading case.
+ // background parser. In those cases, we ignore CanParseAsynchronously() and
+ // fall through to the synchronous case.
if (have_background_parser_) {
if (!input_.HaveSeenEndOfFile())
input_.CloseWithoutMarkingEndOfFile();
@@ -1000,6 +1226,13 @@ void HTMLDocumentParser::Finish() {
if (!input_.HaveSeenEndOfFile())
input_.MarkEndOfFile();
+ if (task_runner_state_->IsScheduled() && !GetDocument()->IsPrefetchOnly()) {
+ // If there's any deferred work remaining, synchronously pump the tokenizer
+ // one last time to make sure that everything's added to the document.
+ task_runner_state_->SetShouldComplete(true);
+ PumpTokenizerIfPossible();
+ }
+
AttemptToEnd();
}
@@ -1010,8 +1243,11 @@ bool HTMLDocumentParser::IsExecutingScript() const {
}
bool HTMLDocumentParser::IsParsingAtLineNumber() const {
- return is_parsing_at_line_number_ &&
- ScriptableDocumentParser::IsParsingAtLineNumber();
+ if (CanParseAsynchronously()) {
+ return is_parsing_at_line_number_ &&
+ ScriptableDocumentParser::IsParsingAtLineNumber();
+ }
+ return ScriptableDocumentParser::IsParsingAtLineNumber();
}
OrdinalNumber HTMLDocumentParser::LineNumber() const {
@@ -1055,6 +1291,18 @@ bool HTMLDocumentParser::IsWaitingForScripts() const {
}
void HTMLDocumentParser::ResumeParsingAfterPause() {
+ // This function runs after a parser-blocking script has completed. There are
+ // four possible cases:
+ // 1) Parsing with kForceSynchronousParsing, where there is no background
+ // parser and a tokenizer_'s defined.
+ // 2) Parsing with kAllowAsynchronousParsing, without a background parser. In
+ // this case, the document is usually being completed or parsing has
+ // otherwise stopped.
+ // 3) Parsing with kAllowAsynchronousParsing with a background parser. In this
+ // case, need to add any pending speculations to the document.
+ // 4) Parsing with kAllowDeferredParsing, with a tokenizer_.
+ TRACE_EVENT1("blink", "HTMLDocumentParser::ResumeParsingAfterPause", "parser",
+ (void*)this);
DCHECK(!IsExecutingScript());
DCHECK(!IsPaused());
@@ -1062,7 +1310,7 @@ void HTMLDocumentParser::ResumeParsingAfterPause() {
if (IsStopped() || IsPaused())
return;
- if (have_background_parser_) {
+ if (have_background_parser_) { // Case 3)
// If we paused in the middle of processing a token chunk,
// deal with that before starting to pump.
if (last_chunk_before_pause_) {
@@ -1079,24 +1327,39 @@ void HTMLDocumentParser::ResumeParsingAfterPause() {
insertion_preload_scanner_.reset();
if (tokenizer_) {
+ // Case 1) or 4): kForceSynchronousParsing, kAllowDeferredParsing.
+ // kForceSynchronousParsing must pump the tokenizer synchronously.
+ // kDeferredParsing could (theoretically) defer the tokenizer pump.
+ // TODO(Richard.Townsend@arm.com) investigate this.
+ task_runner_state_->SetEndIfDelayed(true);
+ task_runner_state_->SetShouldComplete(true);
PumpTokenizerIfPossible();
+ } else {
+ // Case 2): kAllowAsynchronousParsing, no background parser available
+ // (indicating possible Document shutdown).
+ EndIfDelayed();
}
- EndIfDelayed();
}
void HTMLDocumentParser::AppendCurrentInputStreamToPreloadScannerAndScan() {
+ TRACE_EVENT1(
+ "blink",
+ "HTMLDocumentParser::AppendCurrentInputStreamToPreloadScannerAndScan",
+ "parser", (void*)this);
DCHECK(preload_scanner_);
+ DCHECK(preloader_);
preload_scanner_->AppendToEnd(input_.Current());
ScanAndPreload(preload_scanner_.get());
}
void HTMLDocumentParser::NotifyScriptLoaded(PendingScript* pending_script) {
+ TRACE_EVENT1("blink", "HTMLDocumentParser::NotifyScriptLoaded", "parser",
+ (void*)this);
DCHECK(script_runner_);
DCHECK(!IsExecutingScript());
scheduler::CooperativeSchedulingManager::AllowedStackScope
- whitelisted_stack_scope(
- scheduler::CooperativeSchedulingManager::Instance());
+ allowed_stack_scope(scheduler::CooperativeSchedulingManager::Instance());
if (IsStopped()) {
return;
@@ -1113,6 +1376,8 @@ void HTMLDocumentParser::NotifyScriptLoaded(PendingScript* pending_script) {
}
void HTMLDocumentParser::ExecuteScriptsWaitingForResources() {
+ TRACE_EVENT0("blink",
+ "HTMLDocumentParser::ExecuteScriptsWaitingForResources");
if (IsStopped())
return;
@@ -1168,18 +1433,21 @@ void HTMLDocumentParser::ParseDocumentFragment(
}
void HTMLDocumentParser::AppendBytes(const char* data, size_t length) {
+ TRACE_EVENT2("blink", "HTMLDocumentParser::appendBytes", "size",
+ (unsigned)length, "parser", (void*)this);
+
+ DCHECK(Thread::MainThread()->IsCurrentThread());
+
if (!length || IsStopped())
return;
- if (ShouldUseThreading()) {
+ if (CanParseAsynchronously()) {
if (!have_background_parser_)
StartBackgroundParser();
std::unique_ptr<Vector<char>> buffer =
std::make_unique<Vector<char>>(length);
memcpy(buffer->data(), data, length);
- TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"),
- "HTMLDocumentParser::appendBytes", "size", (unsigned)length);
loading_task_runner_->PostTask(
FROM_HERE,
@@ -1192,15 +1460,16 @@ void HTMLDocumentParser::AppendBytes(const char* data, size_t length) {
}
void HTMLDocumentParser::Flush() {
+ TRACE_EVENT1("blink", "HTMLDocumentParser::Flush", "parser", (void*)this);
// If we've got no decoder, we never received any data.
if (IsDetached() || NeedsDecoder())
return;
- if (ShouldUseThreading()) {
+ if (CanParseAsynchronously()) {
// In some cases, flush() is called without any invocation of appendBytes.
// Fallback to synchronous parsing in that case.
if (!have_background_parser_) {
- should_use_threading_ = false;
+ can_parse_asynchronously_ = false;
token_ = std::make_unique<HTMLToken>();
tokenizer_ = std::make_unique<HTMLTokenizer>(options_);
DecodedDataDocumentParser::Flush();
@@ -1257,20 +1526,26 @@ std::unique_ptr<HTMLPreloadScanner> HTMLDocumentParser::CreatePreloadScanner(
}
void HTMLDocumentParser::ScanAndPreload(HTMLPreloadScanner* scanner) {
- if (!preloader_)
- return;
-
+ TRACE_EVENT0("blink", "HTMLDocumentParser::ScanAndPreload");
+ DCHECK(preloader_);
bool seen_csp_meta_tag = false;
PreloadRequestStream requests = scanner->Scan(
GetDocument()->ValidBaseElementURL(), nullptr, seen_csp_meta_tag);
- preloader_->TakeAndPreload(requests);
+ task_runner_state_->SetSeenCSPMetaTag(seen_csp_meta_tag);
+ for (auto& request : requests) {
+ queued_preloads_.push_back(std::move(request));
+ }
+ FetchQueuedPreloads();
}
void HTMLDocumentParser::FetchQueuedPreloads() {
DCHECK(preloader_);
+ TRACE_EVENT0("blink", "HTMLDocumentParser::FetchQueuedPreloads");
- if (pending_csp_meta_token_ || !GetDocument()->documentElement())
- return;
+ if (CanParseAsynchronously()) {
+ if (pending_csp_meta_token_ || !GetDocument()->documentElement())
+ return;
+ }
if (!queued_preloads_.IsEmpty())
preloader_->TakeAndPreload(queued_preloads_);
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.h b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.h
index ac73abc6eeb..42d58d5e4b6 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.h
@@ -29,6 +29,7 @@
#include <memory>
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/parser_content_policy.h"
#include "third_party/blink/renderer/core/dom/scriptable_document_parser.h"
@@ -37,7 +38,6 @@
#include "third_party/blink/renderer/core/html/parser/html_parser_options.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_reentry_permit.h"
#include "third_party/blink/renderer/core/html/parser/html_preload_scanner.h"
-#include "third_party/blink/renderer/core/html/parser/html_source_tracker.h"
#include "third_party/blink/renderer/core/html/parser/html_token.h"
#include "third_party/blink/renderer/core/html/parser/html_tokenizer.h"
#include "third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.h"
@@ -46,6 +46,7 @@
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
#include "third_party/blink/renderer/core/page/viewport_description.h"
#include "third_party/blink/renderer/core/script/html_parser_script_runner_host.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/deque.h"
#include "third_party/blink/renderer/platform/wtf/text/text_position.h"
@@ -64,6 +65,7 @@ class HTMLParserScriptRunner;
class HTMLPreloadScanner;
class HTMLResourcePreloader;
class HTMLTreeBuilder;
+class HTMLDocumentParserState;
// TODO(https://crbug.com/1049898): These are only exposed to make it possible
// to delete an expired histogram. The test should be rewritten to test at a
@@ -82,7 +84,7 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser,
Element* context_element,
ParserContentPolicy);
~HTMLDocumentParser() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// TODO(alexclarke): Remove when background parser goes away.
void Dispose();
@@ -169,7 +171,7 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser,
void NotifyScriptLoaded(PendingScript*) final;
HTMLInputStream& InputStream() final { return input_; }
bool HasPreloadScanner() const final {
- return preload_scanner_.get() && !ShouldUseThreading();
+ return preload_scanner_.get() && !CanParseAsynchronously();
}
void AppendCurrentInputStreamToPreloadScannerAndScan() final;
@@ -186,8 +188,9 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser,
void PumpPendingSpeculations();
bool CanTakeNextToken();
- void PumpTokenizer();
+ bool PumpTokenizer();
void PumpTokenizerIfPossible();
+ void DeferredPumpTokenizerIfPossible();
void ConstructTreeFromHTMLToken();
void ConstructTreeFromCompactHTMLToken(const CompactHTMLToken&);
@@ -199,15 +202,12 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser,
void AttemptToRunDeferredScriptsAndEnd();
void end();
- bool ShouldUseThreading() const { return should_use_threading_; }
+ bool CanParseAsynchronously() const { return can_parse_asynchronously_; }
bool IsParsingFragment() const;
bool IsScheduledForUnpause() const;
bool InPumpSession() const { return pump_session_nesting_level_ > 0; }
- bool ShouldDelayEnd() const {
- return InPumpSession() || IsPaused() || IsScheduledForUnpause() ||
- IsExecutingScript();
- }
+ bool ShouldDelayEnd() const;
std::unique_ptr<HTMLPreloadScanner> CreatePreloadScanner(
TokenPreloadScanner::ScannerType);
@@ -234,7 +234,6 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser,
scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_;
Member<HTMLParserScheduler> parser_scheduler_;
- HTMLSourceTracker source_tracker_;
TextPosition text_position_;
// FIXME: last_chunk_before_pause_, tokenizer_, token_, and input_ should be
@@ -247,6 +246,7 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser,
// finalizer.
base::WeakPtr<BackgroundHTMLParser> background_parser_;
Member<HTMLResourcePreloader> preloader_;
+ Member<HTMLDocumentParserState> task_runner_state_;
PreloadRequestStream queued_preloads_;
// Metrics gathering and reporting
@@ -262,9 +262,7 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser,
// would require keeping track of token positions of preload requests.
CompactHTMLToken* pending_csp_meta_token_;
- TaskHandle resume_parsing_task_handle_;
-
- bool should_use_threading_;
+ bool can_parse_asynchronously_;
bool end_was_delayed_;
bool have_background_parser_;
unsigned pump_session_nesting_level_;
@@ -273,6 +271,7 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser,
bool tried_loading_link_headers_;
bool added_pending_parser_blocking_stylesheet_;
bool is_waiting_for_stylesheets_;
+ ThreadScheduler* scheduler_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_test.cc b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_test.cc
index d74f07df6a4..9ebeb085475 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_test.cc
@@ -8,8 +8,8 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
+#include "third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.h"
#include "third_party/blink/renderer/core/loader/prerenderer_client.h"
-#include "third_party/blink/renderer/core/loader/text_resource_decoder_builder.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.cc b/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.cc
index a4a13996c81..61383ee77b1 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.cc
@@ -123,7 +123,7 @@ bool HTMLElementStack::ElementRecord::IsAbove(ElementRecord* other) const {
return false;
}
-void HTMLElementStack::ElementRecord::Trace(Visitor* visitor) {
+void HTMLElementStack::ElementRecord::Trace(Visitor* visitor) const {
visitor->Trace(item_);
visitor->Trace(next_);
}
@@ -541,7 +541,7 @@ HTMLElementStack::FurthestBlockForFormattingElement(
return nullptr;
}
-void HTMLElementStack::Trace(Visitor* visitor) {
+void HTMLElementStack::Trace(Visitor* visitor) const {
visitor->Trace(top_);
visitor->Trace(root_node_);
visitor->Trace(head_element_);
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.h b/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.h
index a433c82874c..8380d7c87ab 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.h
@@ -60,7 +60,7 @@ class HTMLElementStack {
ElementRecord* Next() const { return next_.Get(); }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
friend class HTMLElementStack;
@@ -164,7 +164,7 @@ class HTMLElementStack {
ContainerNode* RootNode() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
#ifndef NDEBUG
void Show();
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_entity_parser.cc b/chromium/third_party/blink/renderer/core/html/parser/html_entity_parser.cc
index 2855991a54b..231cd4c52dc 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_entity_parser.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_entity_parser.cc
@@ -27,6 +27,7 @@
#include "third_party/blink/renderer/core/html/parser/html_entity_parser.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/core/html/parser/html_entity_search.h"
#include "third_party/blink/renderer/core/html/parser/html_entity_table.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h b/chromium/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h
index f9c4f2a13cb..bb2f43f327a 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h
@@ -75,7 +75,7 @@ class HTMLFormattingElementList {
return !item_ ? !!element : item_->GetElement() != element;
}
- void Trace(Visitor* visitor) { visitor->Trace(item_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(item_); }
private:
Member<HTMLStackItem> item_;
@@ -120,7 +120,7 @@ class HTMLFormattingElementList {
const Entry& at(wtf_size_t i) const { return entries_[i]; }
Entry& at(wtf_size_t i) { return entries_[i]; }
- void Trace(Visitor* visitor) { visitor->Trace(entries_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(entries_); }
#ifndef NDEBUG
void Show();
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.cc b/chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.cc
index 85a7b67b3c4..f66bbf0c583 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.cc
@@ -27,6 +27,7 @@
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
+#include "third_party/blink/renderer/platform/wtf/text/character_visitor.h"
#include "third_party/blink/renderer/platform/wtf/text/parsing_utilities.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
#include "third_party/blink/renderer/platform/wtf/text/string_to_number.h"
@@ -36,47 +37,37 @@
namespace blink {
-template <typename CharType>
-static String StripLeadingAndTrailingHTMLSpaces(String string,
- const CharType* characters,
- unsigned length) {
- unsigned num_leading_spaces = 0;
- unsigned num_trailing_spaces = 0;
-
- for (; num_leading_spaces < length; ++num_leading_spaces) {
- if (IsNotHTMLSpace<CharType>(characters[num_leading_spaces]))
- break;
- }
+String StripLeadingAndTrailingHTMLSpaces(const String& string) {
+ unsigned length = string.length();
- if (num_leading_spaces == length)
+ if (!length)
return string.IsNull() ? string : g_empty_atom.GetString();
- for (; num_trailing_spaces < length; ++num_trailing_spaces) {
- if (IsNotHTMLSpace<CharType>(characters[length - num_trailing_spaces - 1]))
- break;
- }
-
- DCHECK_LT(num_leading_spaces + num_trailing_spaces, length);
+ return WTF::VisitCharacters(string, [&](const auto* chars, unsigned length) {
+ unsigned num_leading_spaces = 0;
+ unsigned num_trailing_spaces = 0;
- if (!(num_leading_spaces | num_trailing_spaces))
- return string;
+ for (; num_leading_spaces < length; ++num_leading_spaces) {
+ if (IsNotHTMLSpace(chars[num_leading_spaces]))
+ break;
+ }
- return string.Substring(num_leading_spaces,
- length - (num_leading_spaces + num_trailing_spaces));
-}
+ if (num_leading_spaces == length)
+ return string.IsNull() ? string : g_empty_atom.GetString();
-String StripLeadingAndTrailingHTMLSpaces(const String& string) {
- unsigned length = string.length();
+ for (; num_trailing_spaces < length; ++num_trailing_spaces) {
+ if (IsNotHTMLSpace(chars[length - num_trailing_spaces - 1]))
+ break;
+ }
- if (!length)
- return string.IsNull() ? string : g_empty_atom.GetString();
+ DCHECK_LT(num_leading_spaces + num_trailing_spaces, length);
- if (string.Is8Bit())
- return StripLeadingAndTrailingHTMLSpaces<LChar>(
- string, string.Characters8(), length);
+ if (!(num_leading_spaces | num_trailing_spaces))
+ return string;
- return StripLeadingAndTrailingHTMLSpaces<UChar>(string, string.Characters16(),
- length);
+ return string.Substring(num_leading_spaces, length - (num_leading_spaces +
+ num_trailing_spaces));
+ });
}
String SerializeForNumberType(const Decimal& number) {
@@ -159,22 +150,6 @@ template <typename CharacterType>
static bool ParseHTMLIntegerInternal(const CharacterType* position,
const CharacterType* end,
int& value) {
- // Step 4
- SkipWhile<CharacterType, IsHTMLSpace<CharacterType>>(position, end);
-
- // Step 5
- if (position == end)
- return false;
- DCHECK_LT(position, end);
-
- bool ok;
- WTF::NumberParsingOptions options(
- WTF::NumberParsingOptions::kAcceptTrailingGarbage |
- WTF::NumberParsingOptions::kAcceptLeadingPlus);
- int wtf_value = CharactersToInt(position, end - position, options, &ok);
- if (ok)
- value = wtf_value;
- return ok;
}
// http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-integers
@@ -182,46 +157,31 @@ bool ParseHTMLInteger(const String& input, int& value) {
// Step 1
// Step 2
unsigned length = input.length();
- if (!length || input.Is8Bit()) {
- const LChar* start = input.Characters8();
- return ParseHTMLIntegerInternal(start, start + length, value);
- }
+ if (length == 0)
+ return false;
- const UChar* start = input.Characters16();
- return ParseHTMLIntegerInternal(start, start + length, value);
-}
-
-template <typename CharacterType>
-static WTF::NumberParsingResult ParseHTMLNonNegativeIntegerInternal(
- const CharacterType* position,
- const CharacterType* end,
- unsigned& value) {
- // This function is an implementation of the following algorithm:
- // https://html.spec.whatwg.org/C/#rules-for-parsing-non-negative-integers
- // However, in order to support integers >= 2^31, we fold [1] into this.
- // 'Step N' in the following comments refers to [1].
- //
- // [1]
- // https://html.spec.whatwg.org/C/#rules-for-parsing-integers
-
- // Step 4: Skip whitespace.
- SkipWhile<CharacterType, IsHTMLSpace<CharacterType>>(position, end);
-
- // Step 5: If position is past the end of input, return an error.
- if (position == end)
- return WTF::NumberParsingResult::kError;
- DCHECK_LT(position, end);
-
- WTF::NumberParsingResult result;
- WTF::NumberParsingOptions options(
- WTF::NumberParsingOptions::kAcceptTrailingGarbage |
- WTF::NumberParsingOptions::kAcceptLeadingPlus |
- WTF::NumberParsingOptions::kAcceptMinusZeroForUnsigned);
- unsigned wtf_value =
- CharactersToUInt(position, end - position, options, &result);
- if (result == WTF::NumberParsingResult::kSuccess)
- value = wtf_value;
- return result;
+ return WTF::VisitCharacters(
+ input, [&](const auto* position, unsigned length) {
+ using CharacterType = std::decay_t<decltype(*position)>;
+ const auto* end = position + length;
+
+ // Step 4
+ SkipWhile<CharacterType, IsHTMLSpace<CharacterType>>(position, end);
+
+ // Step 5
+ if (position == end)
+ return false;
+ DCHECK_LT(position, end);
+
+ bool ok;
+ WTF::NumberParsingOptions options(
+ WTF::NumberParsingOptions::kAcceptTrailingGarbage |
+ WTF::NumberParsingOptions::kAcceptLeadingPlus);
+ int wtf_value = CharactersToInt(position, end - position, options, &ok);
+ if (ok)
+ value = wtf_value;
+ return ok;
+ });
}
static WTF::NumberParsingResult ParseHTMLNonNegativeIntegerInternal(
@@ -230,13 +190,39 @@ static WTF::NumberParsingResult ParseHTMLNonNegativeIntegerInternal(
unsigned length = input.length();
if (length == 0)
return WTF::NumberParsingResult::kError;
- if (input.Is8Bit()) {
- const LChar* start = input.Characters8();
- return ParseHTMLNonNegativeIntegerInternal(start, start + length, value);
- }
- const UChar* start = input.Characters16();
- return ParseHTMLNonNegativeIntegerInternal(start, start + length, value);
+ return WTF::VisitCharacters(
+ input, [&](const auto* position, unsigned length) {
+ using CharacterType = std::decay_t<decltype(*position)>;
+ const auto* end = position + length;
+
+ // This function is an implementation of the following algorithm:
+ // https://html.spec.whatwg.org/C/#rules-for-parsing-non-negative-integers
+ // However, in order to support integers >= 2^31, we fold [1] into this.
+ // 'Step N' in the following comments refers to [1].
+ //
+ // [1]
+ // https://html.spec.whatwg.org/C/#rules-for-parsing-integers
+
+ // Step 4: Skip whitespace.
+ SkipWhile<CharacterType, IsHTMLSpace<CharacterType>>(position, end);
+
+ // Step 5: If position is past the end of input, return an error.
+ if (position == end)
+ return WTF::NumberParsingResult::kError;
+ DCHECK_LT(position, end);
+
+ WTF::NumberParsingResult result;
+ WTF::NumberParsingOptions options(
+ WTF::NumberParsingOptions::kAcceptTrailingGarbage |
+ WTF::NumberParsingOptions::kAcceptLeadingPlus |
+ WTF::NumberParsingOptions::kAcceptMinusZeroForUnsigned);
+ unsigned wtf_value =
+ CharactersToUInt(position, end - position, options, &result);
+ if (result == WTF::NumberParsingResult::kSuccess)
+ value = wtf_value;
+ return result;
+ });
}
// https://html.spec.whatwg.org/C/#rules-for-parsing-non-negative-integers
@@ -281,32 +267,38 @@ static Vector<double> ParseHTMLListOfFloatingPointNumbersInternal(
const CharacterType* position,
const CharacterType* end) {
Vector<double> numbers;
- SkipWhile<CharacterType, IsSpaceOrDelimiter>(position, end);
-
- while (position < end) {
- SkipWhile<CharacterType, IsNotSpaceDelimiterOrNumberStart>(position, end);
-
- const CharacterType* unparsed_number_start = position;
- SkipUntil<CharacterType, IsSpaceOrDelimiter>(position, end);
-
- size_t parsed_length = 0;
- double number = CharactersToDouble(
- unparsed_number_start, position - unparsed_number_start, parsed_length);
- numbers.push_back(CheckDoubleValue(number, parsed_length != 0, 0));
-
- SkipWhile<CharacterType, IsSpaceOrDelimiter>(position, end);
- }
return numbers;
}
// https://html.spec.whatwg.org/C/#rules-for-parsing-a-list-of-floating-point-numbers
Vector<double> ParseHTMLListOfFloatingPointNumbers(const String& input) {
+ Vector<double> numbers;
unsigned length = input.length();
- if (!length || input.Is8Bit())
- return ParseHTMLListOfFloatingPointNumbersInternal(
- input.Characters8(), input.Characters8() + length);
- return ParseHTMLListOfFloatingPointNumbersInternal(
- input.Characters16(), input.Characters16() + length);
+ if (!length)
+ return numbers;
+
+ WTF::VisitCharacters(input, [&](const auto* position, unsigned length) {
+ using CharacterType = std::decay_t<decltype(*position)>;
+ const auto* end = position + length;
+
+ SkipWhile<CharacterType, IsSpaceOrDelimiter>(position, end);
+
+ while (position < end) {
+ SkipWhile<CharacterType, IsNotSpaceDelimiterOrNumberStart>(position, end);
+
+ const CharacterType* unparsed_number_start = position;
+ SkipUntil<CharacterType, IsSpaceOrDelimiter>(position, end);
+
+ size_t parsed_length = 0;
+ double number =
+ CharactersToDouble(unparsed_number_start,
+ position - unparsed_number_start, parsed_length);
+ numbers.push_back(CheckDoubleValue(number, parsed_length != 0, 0));
+
+ SkipWhile<CharacterType, IsSpaceOrDelimiter>(position, end);
+ }
+ });
+ return numbers;
}
static const char kCharsetString[] = "charset";
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_parser_options.cc b/chromium/third_party/blink/renderer/core/html/parser/html_parser_options.cc
index a5c4119348f..1ca1e1b3152 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_parser_options.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_parser_options.cc
@@ -26,20 +26,22 @@
#include "third_party/blink/renderer/core/html/parser/html_parser_options.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
HTMLParserOptions::HTMLParserOptions(Document* document) {
- if (!document || !document->GetFrame())
+ auto* window = document ? document->domWindow() : nullptr;
+ if (!window)
return;
scripting_flag = (document->GetSettings()->GetParserScriptingFlagPolicy() ==
ParserScriptingFlagPolicy::kEnabled) ||
- document->CanExecuteScripts(kNotAboutToExecuteScript);
+ window->CanExecuteScripts(kNotAboutToExecuteScript);
priority_hints_origin_trial_enabled =
- RuntimeEnabledFeatures::PriorityHintsEnabled(document);
+ RuntimeEnabledFeatures::PriorityHintsEnabled(window);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.cc b/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.cc
index 1559a1624ba..871214fd6b1 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.cc
@@ -51,7 +51,7 @@ HTMLParserScheduler::HTMLParserScheduler(
HTMLParserScheduler::~HTMLParserScheduler() = default;
-void HTMLParserScheduler::Trace(Visitor* visitor) {
+void HTMLParserScheduler::Trace(Visitor* visitor) const {
visitor->Trace(parser_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.h b/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.h
index 87d35d4a9f8..a477674e510 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.h
@@ -66,7 +66,7 @@ class HTMLParserScheduler final : public GarbageCollected<HTMLParserScheduler> {
void Detach(); // Clear active tasks if any.
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
bool ShouldYield(const SpeculationsPumpSession&, bool starting_script) const;
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
index f80ec1268db..4a020714905 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
@@ -295,13 +295,6 @@ class TokenPreloadScanner::StartTagScanner {
request->SetCharset(Charset());
request->SetDefer(defer_);
- LoadingAttrValue effective_loading_attr_value = loading_attr_value_;
- // If the 'lazyload' feature policy is enforced, the attribute value
- // loading='eager' is considered as 'auto'.
- if (effective_loading_attr_value == LoadingAttrValue::kEager &&
- document_parameters.lazyload_policy_enforced) {
- effective_loading_attr_value = LoadingAttrValue::kAuto;
- }
if (type == ResourceType::kImage && Match(tag_impl_, html_names::kImgTag) &&
IsLazyLoadImageDeferable(document_parameters)) {
return nullptr;
@@ -559,14 +552,7 @@ class TokenPreloadScanner::StartTagScanner {
return false;
}
- // If the 'lazyload' feature policy is enforced, the attribute value
- // loading='eager' is considered as 'auto'.
- LoadingAttrValue effective_loading_attr_value = loading_attr_value_;
- if (effective_loading_attr_value == LoadingAttrValue::kEager &&
- document_parameters.lazyload_policy_enforced) {
- effective_loading_attr_value = LoadingAttrValue::kAuto;
- }
- switch (effective_loading_attr_value) {
+ switch (loading_attr_value_) {
case LoadingAttrValue::kEager:
return false;
case LoadingAttrValue::kLazy:
@@ -1114,7 +1100,6 @@ CachedDocumentParameters::CachedDocumentParameters(Document* document) {
referrer_policy = document->GetReferrerPolicy();
integrity_features =
SubresourceIntegrityHelper::GetFeatures(document->GetExecutionContext());
- lazyload_policy_enforced = document->IsLazyLoadPolicyEnforced();
if (document->Loader() && document->Loader()->GetFrame()) {
lazy_load_image_setting =
document->Loader()->GetFrame()->GetLazyLoadImageSetting();
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.h b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.h
index 429b1495788..7a2549801d1 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.h
@@ -67,7 +67,6 @@ struct CORE_EXPORT CachedDocumentParameters {
bool viewport_meta_enabled;
network::mojom::ReferrerPolicy referrer_policy;
SubresourceIntegrity::IntegrityFeatures integrity_features;
- bool lazyload_policy_enforced;
LocalFrame::LazyLoadImageSetting lazy_load_image_setting;
WeakPersistent<LazyLoadImageObserver> lazy_load_image_observer;
};
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
index a19d93de8d2..7c164f761b5 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
@@ -11,6 +11,7 @@
#include "third_party/blink/public/platform/web_runtime_features.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/renderer/core/css/media_values_cached.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/cross_origin_attribute.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_options.h"
@@ -256,7 +257,7 @@ class HTMLPreloadScannerTest : public PageTestBase {
kViewportEnabled);
GetDocument().GetSettings()->SetDoHtmlPreloadScanning(preload_state ==
kPreloadEnabled);
- GetDocument().SetReferrerPolicy(document_referrer_policy);
+ GetFrame().DomWindow()->SetReferrerPolicy(document_referrer_policy);
scanner_ = std::make_unique<HTMLPreloadScanner>(
options, document_url,
std::make_unique<CachedDocumentParameters>(&GetDocument()),
@@ -1225,7 +1226,6 @@ TEST_F(HTMLPreloadScannerTest, LazyLoadImage_DisabledForSmallImages) {
ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest
scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test(
false);
- GetDocument().GetSettings()->SetLazyLoadEnabled(true);
RunSetUp(kViewportEnabled);
LazyLoadImageTestCase test_cases[] = {
{"<img src='foo.jpg'>", true},
@@ -1245,7 +1245,6 @@ TEST_F(HTMLPreloadScannerTest, LazyLoadImage_DisabledForSmallImages) {
TEST_F(HTMLPreloadScannerTest, LazyLoadImage_FeatureDisabledWithAttribute) {
ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(false);
- GetDocument().GetSettings()->SetLazyLoadEnabled(true);
RunSetUp(kViewportEnabled);
LazyLoadImageTestCase test_cases[] = {
{"<img src='foo.jpg' loading='auto'>", false},
@@ -1264,7 +1263,6 @@ TEST_F(HTMLPreloadScannerTest,
ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest
scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test(
false);
- GetDocument().GetSettings()->SetLazyLoadEnabled(true);
RunSetUp(kViewportEnabled);
LazyLoadImageTestCase test_cases[] = {
{"<img src='foo.jpg' loading='auto'>", true},
@@ -1282,7 +1280,6 @@ TEST_F(HTMLPreloadScannerTest,
TEST_F(HTMLPreloadScannerTest,
LazyLoadImage_FeatureExplicitEnabledWithAttribute) {
ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true);
- GetDocument().GetSettings()->SetLazyLoadEnabled(true);
RunSetUp(kViewportEnabled);
LazyLoadImageTestCase test_cases[] = {
{"<img src='foo.jpg' loading='auto'>", false},
@@ -1302,7 +1299,6 @@ TEST_F(HTMLPreloadScannerTest,
ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest
scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test(
false);
- GetDocument().GetSettings()->SetLazyLoadEnabled(true);
RunSetUp(kViewportEnabled);
PreloadScannerTestCase test_cases[] = {
{"http://example.test", "<img src='foo.jpg' height='20px' width='20px'>",
@@ -1340,7 +1336,6 @@ TEST_F(HTMLPreloadScannerTest,
LazyLoadImage_FeatureExplicitPreloadForLargeImages) {
// Large images should not be preloaded, when loading is lazy.
ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true);
- GetDocument().GetSettings()->SetLazyLoadEnabled(true);
RunSetUp(kViewportEnabled);
PreloadScannerTestCase test_cases[] = {
{"http://example.test",
@@ -1366,30 +1361,27 @@ TEST_F(HTMLPreloadScannerTest,
Test(test_case);
}
+// TODO(domfarolino): Before merging, can we just delete this test, since we no
+// longer have metadata fetching?
TEST_F(HTMLPreloadScannerTest, LazyLoadImage_DisableMetadataFetch) {
- GetDocument().GetSettings()->SetLazyLoadEnabled(true);
struct TestCase {
bool automatic_lazy_image_loading_enabled;
const char* loading_attr_value;
bool expected_is_preload;
- // If preload happens, whether it is a fetch of placeholder or full image.
- bool expected_is_placeholder_fetch;
};
const TestCase test_cases[] = {
- // The lazyload eligible cases should not trigger any preload when
- // metadata fetch feature disabled, and trigger placeholder fetch if
- // metadata fetch feature is active.
- {false, "lazy", false, false},
- {true, "lazy", false, false},
- {true, "auto", false, false},
+ // The lazyload eligible cases should not trigger a preload.
+ {false, "lazy", false},
+ {true, "lazy", false},
+ {true, "auto", false},
// Lazyload ineligible case.
- {false, "auto", true, false},
+ {false, "auto", true},
// Full image should be fetched when loading='eager' irrespective of
- // automatic lazyload or metadata fetch feature states.
- {false, "eager", true, false},
- {true, "eager", true, false},
+ // automatic lazyload feature state.
+ {false, "eager", true},
+ {true, "eager", true},
};
for (const auto& test_case : test_cases) {
ScopedAutomaticLazyImageLoadingForTest
@@ -1402,8 +1394,7 @@ TEST_F(HTMLPreloadScannerTest, LazyLoadImage_DisableMetadataFetch) {
const std::string img_html = base::StringPrintf(
"<img src='foo.jpg' loading='%s'>", test_case.loading_attr_value);
if (test_case.expected_is_preload) {
- LazyLoadImageTestCase test_preload = {
- img_html.c_str(), test_case.expected_is_placeholder_fetch};
+ LazyLoadImageTestCase test_preload = {img_html.c_str(), false};
Test(test_preload);
} else {
PreloadScannerTestCase test_no_preload = {
@@ -1421,7 +1412,6 @@ TEST_F(HTMLPreloadScannerTest,
ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest
scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test(
false);
- GetDocument().GetSettings()->SetLazyLoadEnabled(true);
GetDocument().GetSettings()->SetLazyImageFirstKFullyLoadUnknown(1);
RunSetUp(kViewportEnabled);
@@ -1438,7 +1428,6 @@ TEST_F(HTMLPreloadScannerTest, LazyLoadImage_FirstKImagesAppliesForAutomatic) {
ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest
scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test(
false);
- GetDocument().GetSettings()->SetLazyLoadEnabled(true);
GetDocument().GetSettings()->SetLazyImageFirstKFullyLoadUnknown(1);
RunSetUp(kViewportEnabled);
@@ -1456,7 +1445,6 @@ TEST_F(HTMLPreloadScannerTest,
ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest
scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test(
false);
- GetDocument().GetSettings()->SetLazyLoadEnabled(true);
GetDocument().GetSettings()->SetLazyImageFirstKFullyLoadUnknown(1);
RunSetUp(kViewportEnabled);
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc b/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc
index 4a95b4a9b2f..0dca6283357 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc
@@ -45,7 +45,7 @@ namespace blink {
HTMLResourcePreloader::HTMLResourcePreloader(Document& document)
: document_(document) {}
-void HTMLResourcePreloader::Trace(Visitor* visitor) {
+void HTMLResourcePreloader::Trace(Visitor* visitor) const {
visitor->Trace(document_);
}
@@ -122,8 +122,7 @@ bool HTMLResourcePreloader::AllowPreloadRequest(PreloadRequest* preload) const {
case ResourceType::kCSSStyleSheet:
return true;
case ResourceType::kFont:
- return base::FeatureList::IsEnabled(
- features::kLightweightNoStatePrefetch_FetchFonts);
+ return false;
case ResourceType::kScript:
// We might skip all script.
if (GetFieldTrialParamByFeatureAsBool(
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.h b/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.h
index 263ead7891e..ef89b2a67b9 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.h
@@ -46,7 +46,7 @@ class CORE_EXPORT HTMLResourcePreloader
public:
explicit HTMLResourcePreloader(Document&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
protected:
void Preload(std::unique_ptr<PreloadRequest>) override;
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_source_tracker.cc b/chromium/third_party/blink/renderer/core/html/parser/html_source_tracker.cc
deleted file mode 100644
index 692440aa063..00000000000
--- a/chromium/third_party/blink/renderer/core/html/parser/html_source_tracker.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2010 Adam Barth. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/core/html/parser/html_source_tracker.h"
-
-#include "third_party/blink/renderer/core/html/parser/html_tokenizer.h"
-#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
-
-namespace blink {
-
-HTMLSourceTracker::HTMLSourceTracker() : is_started_(false) {}
-
-void HTMLSourceTracker::Start(SegmentedString& current_input,
- HTMLTokenizer* tokenizer,
- HTMLToken& token) {
- if (token.GetType() == HTMLToken::kUninitialized && !is_started_) {
- previous_source_.Clear();
- if (NeedToCheckTokenizerBuffer(tokenizer) &&
- tokenizer->NumberOfBufferedCharacters())
- previous_source_ = tokenizer->BufferedCharacters();
- } else {
- previous_source_.Append(current_source_);
- }
-
- is_started_ = true;
- current_source_ = current_input;
- token.SetBaseOffset(current_source_.NumberOfCharactersConsumed() -
- previous_source_.length());
-}
-
-void HTMLSourceTracker::end(SegmentedString& current_input,
- HTMLTokenizer* tokenizer,
- HTMLToken& token) {
- is_started_ = false;
-
- cached_source_for_token_ = String();
-
- // FIXME: This work should really be done by the HTMLTokenizer.
- wtf_size_t number_of_buffered_characters = 0u;
- if (NeedToCheckTokenizerBuffer(tokenizer)) {
- number_of_buffered_characters = tokenizer->NumberOfBufferedCharacters();
- }
- token.end(current_input.NumberOfCharactersConsumed() -
- number_of_buffered_characters);
-}
-
-String HTMLSourceTracker::SourceForToken(const HTMLToken& token) {
- if (!cached_source_for_token_.IsEmpty())
- return cached_source_for_token_;
-
- wtf_size_t length;
- if (token.GetType() == HTMLToken::kEndOfFile) {
- // Consume the remainder of the input, omitting the null character we use to
- // mark the end of the file.
- length = previous_source_.length() + current_source_.length() - 1;
- } else {
- DCHECK(!token.StartIndex());
- length = static_cast<wtf_size_t>(token.EndIndex() - token.StartIndex());
- }
-
- StringBuilder source;
- source.ReserveCapacity(length);
-
- size_t i = 0;
- for (; i < length && !previous_source_.IsEmpty(); ++i) {
- source.Append(previous_source_.CurrentChar());
- previous_source_.Advance();
- }
- for (; i < length; ++i) {
- DCHECK(!current_source_.IsEmpty());
- source.Append(current_source_.CurrentChar());
- current_source_.Advance();
- }
-
- cached_source_for_token_ = source.ToString();
- return cached_source_for_token_;
-}
-
-bool HTMLSourceTracker::NeedToCheckTokenizerBuffer(HTMLTokenizer* tokenizer) {
- HTMLTokenizer::State state = tokenizer->GetState();
- // The temporary buffer must not be used unconditionally, because in some
- // states (e.g. ScriptDataDoubleEscapedStartState), data is appended to
- // both the temporary buffer and the token itself.
- return state == HTMLTokenizer::kDataState ||
- HTMLTokenizer::IsEndTagBufferingState(state);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_source_tracker.h b/chromium/third_party/blink/renderer/core/html/parser/html_source_tracker.h
deleted file mode 100644
index 1e87b08935e..00000000000
--- a/chromium/third_party/blink/renderer/core/html/parser/html_source_tracker.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2010 Adam Barth. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PARSER_HTML_SOURCE_TRACKER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PARSER_HTML_SOURCE_TRACKER_H_
-
-#include "base/macros.h"
-#include "third_party/blink/renderer/core/html/parser/html_token.h"
-#include "third_party/blink/renderer/platform/text/segmented_string.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class HTMLTokenizer;
-
-class HTMLSourceTracker {
- DISALLOW_NEW();
-
- public:
- HTMLSourceTracker();
-
- // FIXME: Once we move "end" into HTMLTokenizer, rename "start" to
- // something that makes it obvious that this method can be called multiple
- // times.
- void Start(SegmentedString&, HTMLTokenizer*, HTMLToken&);
- void end(SegmentedString&, HTMLTokenizer*, HTMLToken&);
-
- String SourceForToken(const HTMLToken&);
-
- private:
- bool NeedToCheckTokenizerBuffer(HTMLTokenizer*);
-
- SegmentedString previous_source_;
- SegmentedString current_source_;
-
- String cached_source_for_token_;
-
- bool is_started_;
-
- DISALLOW_COPY_AND_ASSIGN(HTMLSourceTracker);
-};
-
-} // namespace blink
-
-#endif
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc b/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc
index 7d3025bbee5..bdbda40d96d 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc
@@ -46,6 +46,7 @@
#include "third_party/blink/renderer/platform/json/json_values.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
+#include "third_party/blink/renderer/platform/wtf/text/character_visitor.h"
#include "third_party/blink/renderer/platform/wtf/text/parsing_utilities.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/string_to_number.h"
@@ -275,12 +276,10 @@ static bool ParseDescriptors(const String& attribute,
DescriptorParsingResult& result,
Document* document) {
// FIXME: See if StringView can't be extended to replace DescriptorToken here.
- if (attribute.Is8Bit()) {
- return ParseDescriptors(attribute.Characters8(), descriptors, result,
- document);
- }
- return ParseDescriptors(attribute.Characters16(), descriptors, result,
- document);
+ return WTF::VisitCharacters(
+ attribute, [&](const auto* chars, unsigned length) {
+ return ParseDescriptors(chars, descriptors, result, document);
+ });
}
// http://picture.responsiveimages.org/#parse-srcset-attr
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_stack_item.h b/chromium/third_party/blink/renderer/core/html/parser/html_stack_item.h
index 3d7bc5aa4b3..9fcf4500e50 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_stack_item.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_stack_item.h
@@ -205,7 +205,7 @@ class HTMLStackItem final : public GarbageCollected<HTMLStackItem> {
tag_name == html_names::kWbrTag || tag_name == html_names::kXmpTag;
}
- void Trace(Visitor* visitor) { visitor->Trace(node_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(node_); }
private:
Member<ContainerNode> node_;
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.cc b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.cc
index c6551c6cfea..2c24eee68fa 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.cc
@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/core/dom/document_fragment.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/forms/html_form_control_element.h"
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
@@ -57,6 +58,7 @@
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
+#include "third_party/blink/renderer/platform/wtf/text/character_visitor.h"
namespace blink {
@@ -165,10 +167,9 @@ class HTMLTreeBuilder::CharacterTokenBuffer {
}
void GiveRemainingTo(StringBuilder& recipient) {
- if (characters_->Is8Bit())
- recipient.Append(characters_->Characters8() + current_, end_ - current_);
- else
- recipient.Append(characters_->Characters16() + current_, end_ - current_);
+ WTF::VisitCharacters(*characters_, [&](const auto* chars, unsigned length) {
+ recipient.Append(chars + current_, end_ - current_);
+ });
current_ = end_;
}
@@ -277,12 +278,12 @@ void HTMLTreeBuilder::FragmentParsingContext::Init(DocumentFragment* fragment,
context_element, HTMLStackItem::kItemForContextElement);
}
-void HTMLTreeBuilder::FragmentParsingContext::Trace(Visitor* visitor) {
+void HTMLTreeBuilder::FragmentParsingContext::Trace(Visitor* visitor) const {
visitor->Trace(fragment_);
visitor->Trace(context_element_stack_item_);
}
-void HTMLTreeBuilder::Trace(Visitor* visitor) {
+void HTMLTreeBuilder::Trace(Visitor* visitor) const {
visitor->Trace(fragment_context_);
visitor->Trace(tree_);
visitor->Trace(parser_);
@@ -896,7 +897,8 @@ void HTMLTreeBuilder::ProcessTemplateStartTag(AtomicHTMLToken* token) {
DeclarativeShadowRootType declarative_shadow_root_type(
DeclarativeShadowRootType::kNone);
- if (RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled()) {
+ if (RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled(
+ tree_.CurrentNode()->GetExecutionContext())) {
if (Attribute* type_attribute =
token->GetAttributeItem(html_names::kShadowrootAttr)) {
String shadow_mode = type_attribute->Value();
@@ -942,7 +944,8 @@ bool HTMLTreeBuilder::ProcessTemplateEndTag(AtomicHTMLToken* token) {
tree_.ActiveFormattingElements()->ClearToLastMarker();
template_insertion_modes_.pop_back();
ResetInsertionModeAppropriately();
- if (RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled() &&
+ if (RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled(
+ shadow_host_stack_item->GetNode()->GetExecutionContext()) &&
template_stack_item) {
DCHECK(template_stack_item->IsElementNode());
HTMLTemplateElement* template_element =
@@ -951,29 +954,32 @@ bool HTMLTreeBuilder::ProcessTemplateEndTag(AtomicHTMLToken* token) {
// attribute with the name "shadowroot" whose value was an ASCII
// case-insensitive match for the strings "open" or "closed", then stop this
// algorithm.
- // 10. If the adjusted current node is the topmost element in the stack of
- // open elements, then stop this algorithm.
- if (template_element->IsDeclarativeShadowRoot() &&
- shadow_host_stack_item->GetNode() != tree_.OpenElements()->RootNode()) {
- DCHECK(shadow_host_stack_item);
- DCHECK(shadow_host_stack_item->IsElementNode());
- UseCounter::Count(shadow_host_stack_item->GetElement()->GetDocument(),
- WebFeature::kDeclarativeShadowRoot);
- bool delegates_focus = template_stack_item->GetAttributeItem(
- html_names::kShadowrootdelegatesfocusAttr);
- // TODO(crbug.com/1063157): Add an attribute for imperative slot
- // assignment.
- bool manual_slotting = false;
- shadow_host_stack_item->GetElement()->AttachDeclarativeShadowRoot(
- template_element,
- template_element->GetDeclarativeShadowRootType() ==
- DeclarativeShadowRootType::kOpen
- ? ShadowRootType::kOpen
- : ShadowRootType::kClosed,
- delegates_focus ? FocusDelegation::kDelegateFocus
- : FocusDelegation::kNone,
- manual_slotting ? SlotAssignmentMode::kManual
- : SlotAssignmentMode::kAuto);
+ if (template_element->IsDeclarativeShadowRoot()) {
+ if (shadow_host_stack_item->GetNode() ==
+ tree_.OpenElements()->RootNode()) {
+ // 10. If the adjusted current node is the topmost element in the stack
+ // of open elements, then stop this algorithm.
+ template_element->SetDeclarativeShadowRootType(
+ DeclarativeShadowRootType::kNone);
+ } else {
+ DCHECK(shadow_host_stack_item);
+ DCHECK(shadow_host_stack_item->IsElementNode());
+ bool delegates_focus = template_stack_item->GetAttributeItem(
+ html_names::kShadowrootdelegatesfocusAttr);
+ // TODO(crbug.com/1063157): Add an attribute for imperative slot
+ // assignment.
+ bool manual_slotting = false;
+ shadow_host_stack_item->GetElement()->AttachDeclarativeShadowRoot(
+ template_element,
+ template_element->GetDeclarativeShadowRootType() ==
+ DeclarativeShadowRootType::kOpen
+ ? ShadowRootType::kOpen
+ : ShadowRootType::kClosed,
+ delegates_focus ? FocusDelegation::kDelegateFocus
+ : FocusDelegation::kNone,
+ manual_slotting ? SlotAssignmentMode::kManual
+ : SlotAssignmentMode::kAuto);
+ }
}
}
return true;
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.h b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.h
index 64dc15e3319..74c358cbc32 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.h
@@ -61,7 +61,7 @@ class HTMLTreeBuilder final : public GarbageCollected<HTMLTreeBuilder> {
ParserContentPolicy,
const HTMLParserOptions&);
~HTMLTreeBuilder();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
const HTMLElementStack* OpenElements() const { return tree_.OpenElements(); }
@@ -216,7 +216,7 @@ class HTMLTreeBuilder final : public GarbageCollected<HTMLTreeBuilder> {
return context_element_stack_item_.Get();
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<DocumentFragment> fragment_;
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.cc b/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.cc
index 15f8c4960d0..4d1bd538e0e 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.cc
@@ -26,10 +26,10 @@
#include "third_party/blink/renderer/core/html/parser/html_view_source_parser.h"
#include <memory>
-#include "third_party/blink/renderer/core/dom/dom_implementation.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_options.h"
#include "third_party/blink/renderer/core/html/parser/html_token.h"
+#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
namespace blink {
@@ -38,18 +38,18 @@ HTMLViewSourceParser::HTMLViewSourceParser(HTMLViewSourceDocument& document,
: DecodedDataDocumentParser(document),
tokenizer_(
std::make_unique<HTMLTokenizer>(HTMLParserOptions(&document))) {
- if (mime_type != "text/html" && !DOMImplementation::IsXMLMIMEType(mime_type))
+ if (mime_type != "text/html" && !MIMETypeRegistry::IsXMLMIMEType(mime_type))
tokenizer_->SetState(HTMLTokenizer::kPLAINTEXTState);
}
void HTMLViewSourceParser::PumpTokenizer() {
while (true) {
- source_tracker_.Start(input_.Current(), tokenizer_.get(), token_);
+ StartTracker(input_.Current(), tokenizer_.get(), token_);
if (!tokenizer_->NextToken(input_.Current(), token_))
return;
- source_tracker_.end(input_.Current(), tokenizer_.get(), token_);
+ EndTracker(input_.Current(), tokenizer_.get(), token_);
- GetDocument()->AddSource(source_tracker_.SourceForToken(token_), token_);
+ GetDocument()->AddSource(SourceForToken(token_), token_);
// FIXME: The tokenizer should do this work for us.
if (token_.GetType() == HTMLToken::kStartTag)
@@ -75,4 +75,80 @@ void HTMLViewSourceParser::Finish() {
}
}
+void HTMLViewSourceParser::StartTracker(SegmentedString& current_input,
+ HTMLTokenizer* tokenizer,
+ HTMLToken& token) {
+ if (token.GetType() == HTMLToken::kUninitialized && !tracker_is_started_) {
+ previous_source_.Clear();
+ if (NeedToCheckTokenizerBuffer(tokenizer) &&
+ tokenizer->NumberOfBufferedCharacters())
+ previous_source_ = tokenizer->BufferedCharacters();
+ } else {
+ previous_source_.Append(current_source_);
+ }
+
+ tracker_is_started_ = true;
+ current_source_ = current_input;
+ token.SetBaseOffset(current_source_.NumberOfCharactersConsumed() -
+ previous_source_.length());
+}
+
+void HTMLViewSourceParser::EndTracker(SegmentedString& current_input,
+ HTMLTokenizer* tokenizer,
+ HTMLToken& token) {
+ tracker_is_started_ = false;
+
+ cached_source_for_token_ = String();
+
+ // FIXME: This work should really be done by the HTMLTokenizer.
+ wtf_size_t number_of_buffered_characters = 0u;
+ if (NeedToCheckTokenizerBuffer(tokenizer)) {
+ number_of_buffered_characters = tokenizer->NumberOfBufferedCharacters();
+ }
+ token.end(current_input.NumberOfCharactersConsumed() -
+ number_of_buffered_characters);
+}
+
+String HTMLViewSourceParser::SourceForToken(const HTMLToken& token) {
+ if (!cached_source_for_token_.IsEmpty())
+ return cached_source_for_token_;
+
+ wtf_size_t length;
+ if (token.GetType() == HTMLToken::kEndOfFile) {
+ // Consume the remainder of the input, omitting the null character we use to
+ // mark the end of the file.
+ length = previous_source_.length() + current_source_.length() - 1;
+ } else {
+ DCHECK(!token.StartIndex());
+ length = static_cast<wtf_size_t>(token.EndIndex() - token.StartIndex());
+ }
+
+ StringBuilder source;
+ source.ReserveCapacity(length);
+
+ size_t i = 0;
+ for (; i < length && !previous_source_.IsEmpty(); ++i) {
+ source.Append(previous_source_.CurrentChar());
+ previous_source_.Advance();
+ }
+ for (; i < length; ++i) {
+ DCHECK(!current_source_.IsEmpty());
+ source.Append(current_source_.CurrentChar());
+ current_source_.Advance();
+ }
+
+ cached_source_for_token_ = source.ToString();
+ return cached_source_for_token_;
+}
+
+bool HTMLViewSourceParser::NeedToCheckTokenizerBuffer(
+ HTMLTokenizer* tokenizer) {
+ HTMLTokenizer::State state = tokenizer->GetState();
+ // The temporary buffer must not be used unconditionally, because in some
+ // states (e.g. ScriptDataDoubleEscapedStartState), data is appended to
+ // both the temporary buffer and the token itself.
+ return state == HTMLTokenizer::kDataState ||
+ HTMLTokenizer::IsEndTagBufferingState(state);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.h b/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.h
index dc695308840..81febb2e076 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.h
@@ -31,7 +31,6 @@
#include "third_party/blink/renderer/core/dom/decoded_data_document_parser.h"
#include "third_party/blink/renderer/core/html/html_view_source_document.h"
#include "third_party/blink/renderer/core/html/parser/html_input_stream.h"
-#include "third_party/blink/renderer/core/html/parser/html_source_tracker.h"
#include "third_party/blink/renderer/core/html/parser/html_tokenizer.h"
namespace blink {
@@ -56,10 +55,20 @@ class CORE_EXPORT HTMLViewSourceParser final
void PumpTokenizer();
void UpdateTokenizerState();
+ void StartTracker(SegmentedString&, HTMLTokenizer*, HTMLToken&);
+ void EndTracker(SegmentedString&, HTMLTokenizer*, HTMLToken&);
+ String SourceForToken(const HTMLToken&);
+ bool NeedToCheckTokenizerBuffer(HTMLTokenizer*);
+
HTMLInputStream input_;
HTMLToken token_;
- HTMLSourceTracker source_tracker_;
std::unique_ptr<HTMLTokenizer> tokenizer_;
+ bool tracker_is_started_;
+
+ SegmentedString previous_source_;
+ SegmentedString current_source_;
+
+ String cached_source_for_token_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser_test.cc b/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser_test.cc
index 3bd21514f75..3b3a5594446 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser_test.cc
@@ -17,7 +17,7 @@ namespace blink {
TEST(HTMLViewSourceParserTest, DetachThenFinish_ShouldNotCrash) {
String mime_type("text/html");
auto* document = MakeGarbageCollected<HTMLViewSourceDocument>(
- DocumentInit::Create().WithTypeFrom(mime_type));
+ DocumentInit::Create().ForTest().WithTypeFrom(mime_type));
auto* parser =
MakeGarbageCollected<HTMLViewSourceParser>(*document, mime_type);
// A client may detach the parser from the document.
diff --git a/chromium/third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h b/chromium/third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h
index e57d7071bc6..5283f13dd8e 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h
@@ -5,6 +5,7 @@ namespace blink {
enum ParserSynchronizationPolicy {
kAllowAsynchronousParsing,
+ kAllowDeferredParsing,
kForceSynchronousParsing,
};
}
diff --git a/chromium/third_party/blink/renderer/core/loader/text_resource_decoder_builder.cc b/chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.cc
index fb2d66ec459..88a0b4e5b6f 100644
--- a/chromium/third_party/blink/renderer/core/loader/text_resource_decoder_builder.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.cc
@@ -28,13 +28,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/core/loader/text_resource_decoder_builder.h"
+#include "third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.h"
#include <memory>
#include "base/stl_util.h"
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/dom/dom_implementation.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
@@ -95,7 +94,7 @@ TextResourceDecoderOptions::ContentType DetermineContentType(
return TextResourceDecoderOptions::kCSSContent;
if (EqualIgnoringASCIICase(mime_type, "text/html"))
return TextResourceDecoderOptions::kHTMLContent;
- if (DOMImplementation::IsXMLMIMEType(mime_type))
+ if (MIMETypeRegistry::IsXMLMIMEType(mime_type))
return TextResourceDecoderOptions::kXMLContent;
return TextResourceDecoderOptions::kPlainTextContent;
}
@@ -134,7 +133,7 @@ std::unique_ptr<TextResourceDecoder> BuildTextResourceDecoderFor(
frame->GetSettings()->GetDefaultTextEncodingName());
// Disable autodetection for XML/JSON to honor the default encoding (UTF-8)
// for unlabelled documents.
- if (DOMImplementation::IsXMLMIMEType(mime_type)) {
+ if (MIMETypeRegistry::IsXMLMIMEType(mime_type)) {
decoder =
std::make_unique<TextResourceDecoder>(TextResourceDecoderOptions(
TextResourceDecoderOptions::kXMLContent, default_encoding));
diff --git a/chromium/third_party/blink/renderer/core/loader/text_resource_decoder_builder.h b/chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.h
index 90725de3b4c..5166dd59878 100644
--- a/chromium/third_party/blink/renderer/core/loader/text_resource_decoder_builder.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.h
@@ -28,8 +28,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_TEXT_RESOURCE_DECODER_BUILDER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_TEXT_RESOURCE_DECODER_BUILDER_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PARSER_TEXT_RESOURCE_DECODER_BUILDER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PARSER_TEXT_RESOURCE_DECODER_BUILDER_H_
#include <memory>
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
@@ -46,4 +46,4 @@ CORE_EXPORT std::unique_ptr<TextResourceDecoder> BuildTextResourceDecoderFor(
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_TEXT_RESOURCE_DECODER_BUILDER_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PARSER_TEXT_RESOURCE_DECODER_BUILDER_H_
diff --git a/chromium/third_party/blink/renderer/core/loader/text_resource_decoder_builder_test.cc b/chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder_test.cc
index 95db7795fde..aa529b353c1 100644
--- a/chromium/third_party/blink/renderer/core/loader/text_resource_decoder_builder_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder_test.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/renderer/core/loader/text_resource_decoder_builder.h"
+#include "third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.h"
#include <memory>
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/third_party/blink/renderer/core/html/plugin_document.cc b/chromium/third_party/blink/renderer/core/html/plugin_document.cc
index 5ff78584883..17d92892f3f 100644
--- a/chromium/third_party/blink/renderer/core/html/plugin_document.cc
+++ b/chromium/third_party/blink/renderer/core/html/plugin_document.cc
@@ -57,7 +57,7 @@ class PluginDocumentParser : public RawDataDocumentParser {
embed_element_(nullptr),
background_color_(background_color) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(embed_element_);
RawDataDocumentParser::Trace(visitor);
}
@@ -185,8 +185,8 @@ PluginDocument::PluginDocument(const DocumentInit& initializer)
background_color_(initializer.GetPluginBackgroundColor()) {
SetCompatibilityMode(kQuirksMode);
LockCompatibilityMode();
- if (GetScheduler()) {
- GetScheduler()->RegisterStickyFeature(
+ if (GetExecutionContext()) {
+ GetExecutionContext()->GetScheduler()->RegisterStickyFeature(
SchedulingPolicy::Feature::kContainsPlugins,
{SchedulingPolicy::RecordMetricsForBackForwardCache()});
}
@@ -206,7 +206,7 @@ void PluginDocument::Shutdown() {
HTMLDocument::Shutdown();
}
-void PluginDocument::Trace(Visitor* visitor) {
+void PluginDocument::Trace(Visitor* visitor) const {
visitor->Trace(plugin_node_);
HTMLDocument::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/plugin_document.h b/chromium/third_party/blink/renderer/core/html/plugin_document.h
index d2faa0e365e..0b536cdcf1c 100644
--- a/chromium/third_party/blink/renderer/core/html/plugin_document.h
+++ b/chromium/third_party/blink/renderer/core/html/plugin_document.h
@@ -47,7 +47,7 @@ class CORE_EXPORT PluginDocument final : public HTMLDocument {
void Shutdown() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class BeforeUnloadEventListener;
diff --git a/chromium/third_party/blink/renderer/core/html/portal/document_portals.cc b/chromium/third_party/blink/renderer/core/html/portal/document_portals.cc
index bf53d46e18b..ba600abe02e 100644
--- a/chromium/third_party/blink/renderer/core/html/portal/document_portals.cc
+++ b/chromium/third_party/blink/renderer/core/html/portal/document_portals.cc
@@ -4,7 +4,9 @@
#include "third_party/blink/renderer/core/html/portal/document_portals.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/portal/portal_contents.h"
+#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
namespace blink {
@@ -28,15 +30,26 @@ DocumentPortals::DocumentPortals(Document& document)
void DocumentPortals::RegisterPortalContents(PortalContents* portal) {
portals_.push_back(portal);
+ auto* frame = GetSupplementable()->GetFrame();
+ if (!frame)
+ return;
+ if (auto* page = frame->GetPage())
+ page->IncrementSubframeCount();
}
void DocumentPortals::DeregisterPortalContents(PortalContents* portal) {
wtf_size_t index = portals_.Find(portal);
- if (index != WTF::kNotFound)
+ if (index != WTF::kNotFound) {
portals_.EraseAt(index);
+ auto* frame = GetSupplementable()->GetFrame();
+ if (!frame)
+ return;
+ if (auto* page = frame->GetPage())
+ page->DecrementSubframeCount();
+ }
}
-void DocumentPortals::Trace(Visitor* visitor) {
+void DocumentPortals::Trace(Visitor* visitor) const {
Supplement<Document>::Trace(visitor);
visitor->Trace(portals_);
visitor->Trace(activating_portal_);
diff --git a/chromium/third_party/blink/renderer/core/html/portal/document_portals.h b/chromium/third_party/blink/renderer/core/html/portal/document_portals.h
index 96b264aeb60..88fd72a4b09 100644
--- a/chromium/third_party/blink/renderer/core/html/portal/document_portals.h
+++ b/chromium/third_party/blink/renderer/core/html/portal/document_portals.h
@@ -52,7 +52,7 @@ class DocumentPortals final : public GarbageCollected<DocumentPortals>,
explicit DocumentPortals(Document&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<PortalContents>> portals_;
diff --git a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc
index 6d3bc25c35c..536e983949d 100644
--- a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc
@@ -41,6 +41,8 @@
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h"
#include "third_party/blink/renderer/platform/weborigin/referrer.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
@@ -54,7 +56,11 @@ HTMLPortalElement::HTMLPortalElement(
mojo::PendingAssociatedRemote<mojom::blink::Portal> remote_portal,
mojo::PendingAssociatedReceiver<mojom::blink::PortalClient>
portal_client_receiver)
- : HTMLFrameOwnerElement(html_names::kPortalTag, document) {
+ : HTMLFrameOwnerElement(html_names::kPortalTag, document),
+ feature_handle_for_scheduler_(
+ document.GetExecutionContext()->GetScheduler()->RegisterFeature(
+ SchedulingPolicy::Feature::kPortal,
+ {SchedulingPolicy::RecordMetricsForBackForwardCache()})) {
if (remote_portal) {
was_just_adopted_ = true;
DCHECK(CanHaveGuestContents())
@@ -64,13 +70,12 @@ HTMLPortalElement::HTMLPortalElement(
*this, portal_token, std::move(remote_portal),
std::move(portal_client_receiver));
}
-
UseCounter::Count(document, WebFeature::kHTMLPortalElement);
}
HTMLPortalElement::~HTMLPortalElement() {}
-void HTMLPortalElement::Trace(Visitor* visitor) {
+void HTMLPortalElement::Trace(Visitor* visitor) const {
HTMLFrameOwnerElement::Trace(visitor);
visitor->Trace(portal_);
}
@@ -97,31 +102,53 @@ void HTMLPortalElement::PortalContentsWillBeDestroyed(PortalContents* portal) {
portal_ = nullptr;
}
-bool HTMLPortalElement::CheckPortalsEnabledOrWarn() const {
- Document& document = GetDocument();
- if (RuntimeEnabledFeatures::PortalsEnabled(&document))
+bool HTMLPortalElement::IsCurrentlyWithinFrameLimit() const {
+ auto* frame = GetDocument().GetFrame();
+ if (!frame)
+ return false;
+ auto* page = frame->GetPage();
+ if (!page)
+ return false;
+ return page->SubframeCount() < Page::MaxNumberOfFrames();
+}
+
+bool HTMLPortalElement::CheckWithinFrameLimitOrWarn() const {
+ if (IsCurrentlyWithinFrameLimit())
return true;
- // TODO(jbroman): Consider linking to origin trial info if applicable.
+ Document& document = GetDocument();
document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::blink::ConsoleMessageSource::kRendering,
mojom::blink::ConsoleMessageLevel::kWarning,
+ "An operation was prevented due to too many frames and portals present "
+ "on the page."));
+ return false;
+}
+
+bool HTMLPortalElement::CheckPortalsEnabledOrWarn() const {
+ ExecutionContext* context = GetExecutionContext();
+ if (RuntimeEnabledFeatures::PortalsEnabled(context))
+ return true;
+
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kRendering,
+ mojom::blink::ConsoleMessageLevel::kWarning,
"An operation was prevented because a <portal> was moved to a document "
- "where it is not enabled."));
+ "where it is not enabled. See "
+ "https://www.chromium.org/blink/origin-trials/portals."));
return false;
}
bool HTMLPortalElement::CheckPortalsEnabledOrThrow(
ExceptionState& exception_state) const {
- Document& document = GetDocument();
- if (RuntimeEnabledFeatures::PortalsEnabled(&document))
+ if (RuntimeEnabledFeatures::PortalsEnabled(GetExecutionContext()))
return true;
- // TODO(jbroman): Consider linking to origin trial info if applicable.
exception_state.ThrowDOMException(
DOMExceptionCode::kNotSupportedError,
"An operation was prevented because a <portal> was moved to a document "
- "where it is not enabled.");
+ "where it is not enabled. See "
+ "https://www.chromium.org/blink/origin-trials/portals.");
return false;
}
@@ -141,6 +168,13 @@ HTMLPortalElement::GetGuestContentsEligibility() const {
if (!is_top_level)
return GuestContentsEligibility::kNotTopLevel;
+ // TODO(crbug.com/1051639): We need to find a long term solution to when/how
+ // portals should work in sandboxed documents.
+ if (GetDocument().GetSandboxFlags() !=
+ network::mojom::blink::WebSandboxFlags::kNone) {
+ return GuestContentsEligibility::kSandboxed;
+ }
+
if (!GetDocument().Url().ProtocolIsInHTTPFamily())
return GuestContentsEligibility::kNotHTTPFamily;
@@ -151,10 +185,16 @@ void HTMLPortalElement::Navigate() {
if (!CheckPortalsEnabledOrWarn())
return;
- if (portal_) {
- portal_->Navigate(GetNonEmptyURLAttribute(html_names::kSrcAttr),
- ReferrerPolicyAttribute());
- }
+ if (!CheckWithinFrameLimitOrWarn())
+ return;
+
+ auto url = GetNonEmptyURLAttribute(html_names::kSrcAttr);
+
+ if (url.PotentiallyDanglingMarkup())
+ return;
+
+ if (portal_)
+ portal_->Navigate(url, ReferrerPolicyAttribute());
}
namespace {
@@ -238,6 +278,13 @@ ScriptPromise HTMLPortalElement::activate(ScriptState* script_state,
"Cannot activate a portal that is inside another portal.");
return ScriptPromise();
}
+ if (GetDocument().BeforeUnloadStarted()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Cannot activate portal while document is in beforeunload or has "
+ "started unloading.");
+ return ScriptPromise();
+ }
BlinkTransferableMessage data =
ActivateDataAsMessage(script_state, options, exception_state);
@@ -317,6 +364,9 @@ Node::InsertionNotificationRequest HTMLPortalElement::InsertedInto(
if (!CheckPortalsEnabledOrWarn())
return result;
+ if (!CheckWithinFrameLimitOrWarn())
+ return result;
+
if (!SubframeLoadingDisabler::CanLoadFrame(*this))
return result;
@@ -331,6 +381,13 @@ Node::InsertionNotificationRequest HTMLPortalElement::InsertedInto(
"Cannot use <portal> in a nested browsing context."));
return result;
+ case GuestContentsEligibility::kSandboxed:
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kRendering,
+ mojom::ConsoleMessageLevel::kWarning,
+ "Cannot use <portal> in a sandboxed browsing context."));
+ return result;
+
case GuestContentsEligibility::kNotHTTPFamily:
GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kRendering,
diff --git a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h
index 1ec5984927d..5e9e05dec04 100644
--- a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h
+++ b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h
@@ -14,6 +14,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
+#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -43,7 +44,7 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement {
bool IsHTMLPortalElement() const final { return true; }
// ScriptWrappable overrides.
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// idl implementation.
ScriptPromise activate(ScriptState*, PortalActivateOptions*, ExceptionState&);
@@ -86,6 +87,15 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement {
bool CheckPortalsEnabledOrWarn() const;
bool CheckPortalsEnabledOrThrow(ExceptionState&) const;
+ // Checks if, when inserted, we were beyond the frame limit. If so, we will
+ // disable navigating the portal and insertion (and will display a warning in
+ // the console).
+ bool CheckWithinFrameLimitOrWarn() const;
+
+ // Checks that the number of frames and portals on the page are within the
+ // limit.
+ bool IsCurrentlyWithinFrameLimit() const;
+
enum class GuestContentsEligibility {
// Can have a guest contents.
kEligible,
@@ -93,6 +103,9 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement {
// Ineligible as it is not top-level.
kNotTopLevel,
+ // Ineligible as it is sandboxed.
+ kSandboxed,
+
// Ineligible as the host's protocol is not in the HTTP family.
kNotHTTPFamily,
@@ -120,7 +133,7 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement {
// HTMLFrameOwnerElement overrides
void DisconnectContentFrame() override;
- ParsedFeaturePolicy ConstructContainerPolicy(Vector<String>*) const override {
+ ParsedFeaturePolicy ConstructContainerPolicy() const override {
return ParsedFeaturePolicy();
}
void AttachLayoutTree(AttachContext& context) override;
@@ -133,6 +146,11 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement {
// Temporarily set to keep this element alive after adoption.
bool was_just_adopted_ = false;
+
+ // Disable BackForwardCache when using the portal feature, because we do not
+ // handle the state inside the portal after putting the page in cache.
+ FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle
+ feature_handle_for_scheduler_;
};
// Type casting. Custom since adoption could lead to an HTMLPortalElement ending
diff --git a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element_test.cc b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element_test.cc
index c7904de4aaf..92e22391e3f 100644
--- a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element_test.cc
@@ -35,7 +35,8 @@ TEST_F(HTMLPortalElementTest, PortalsDisabledInDocument) {
Document& document = GetDocument();
auto* portal = MakeGarbageCollected<HTMLPortalElement>(document);
ScopedPortalsForTest disable_portals(false);
- ASSERT_FALSE(RuntimeEnabledFeatures::PortalsEnabled(&document));
+ ASSERT_FALSE(
+ RuntimeEnabledFeatures::PortalsEnabled(document.GetExecutionContext()));
DummyExceptionStateForTesting exception_state;
ScriptState* script_state = ToScriptStateForMainWorld(&GetFrame());
diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.cc b/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.cc
index 2e685353655..3aebb0c255e 100644
--- a/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.cc
+++ b/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.cc
@@ -105,7 +105,7 @@ ScriptValue PortalActivateEvent::data(ScriptState* script_state) {
return ScriptValue(isolate, value);
}
-void PortalActivateEvent::Trace(Visitor* visitor) {
+void PortalActivateEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
visitor->Trace(document_);
visitor->Trace(adopted_portal_);
@@ -121,7 +121,8 @@ const AtomicString& PortalActivateEvent::InterfaceName() const {
HTMLPortalElement* PortalActivateEvent::adoptPredecessor(
ExceptionState& exception_state) {
- if (!RuntimeEnabledFeatures::PortalsEnabled(document_)) {
+ if (!RuntimeEnabledFeatures::PortalsEnabled(
+ document_ ? document_->GetExecutionContext() : nullptr)) {
exception_state.ThrowDOMException(
DOMExceptionCode::kNotSupportedError,
"Portals is not enabled in this document.");
diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.h b/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.h
index 41d3a4e0c41..d72fc5f19f8 100644
--- a/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.h
+++ b/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.h
@@ -64,7 +64,7 @@ class CORE_EXPORT PortalActivateEvent : public Event {
~PortalActivateEvent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Event overrides
const AtomicString& InterfaceName() const override;
diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_contents.cc b/chromium/third_party/blink/renderer/core/html/portal/portal_contents.cc
index 80f1404bc48..b077af9abca 100644
--- a/chromium/third_party/blink/renderer/core/html/portal/portal_contents.cc
+++ b/chromium/third_party/blink/renderer/core/html/portal/portal_contents.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/html/portal/portal_contents.h"
#include "base/compiler_specific.h"
+#include "base/time/time.h"
#include "third_party/blink/public/mojom/portal/portal.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/referrer.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
@@ -15,6 +16,8 @@
#include "third_party/blink/renderer/core/html/portal/html_portal_element.h"
#include "third_party/blink/renderer/core/html/portal/portal_post_message_helper.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/core/loader/document_load_timing.h"
+#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -60,7 +63,7 @@ ScriptPromise PortalContents::Activate(ScriptState* script_state,
// This object (and thus the Mojo connection it owns) remains alive while the
// renderer awaits the response.
remote_portal_->Activate(
- std::move(data),
+ std::move(data), base::TimeTicks::Now(),
WTF::Bind(&PortalContents::OnActivateResponse, WrapPersistent(this)));
// Dissociate from the element. The element is expected to do the same.
@@ -72,7 +75,7 @@ ScriptPromise PortalContents::Activate(ScriptState* script_state,
void PortalContents::OnActivateResponse(
mojom::blink::PortalActivateResult result) {
auto reject = [&](DOMExceptionCode code, const char* message) {
- if (GetDocument().IsContextDestroyed())
+ if (!GetDocument().GetExecutionContext())
return;
ScriptState* script_state = activate_resolver_->GetScriptState();
@@ -91,8 +94,8 @@ void PortalContents::OnActivateResponse(
bool should_destroy_contents = false;
switch (result) {
case mojom::blink::PortalActivateResult::kPredecessorWasAdopted:
- if (!GetDocument().IsContextDestroyed())
- GetDocument().GetPage()->SetInsidePortal(true);
+ if (auto* page = GetDocument().GetPage())
+ page->SetInsidePortal(true);
FALLTHROUGH;
case mojom::blink::PortalActivateResult::kPredecessorWillUnload:
activate_resolver_->Resolve();
@@ -154,10 +157,11 @@ void PortalContents::Navigate(
return;
}
+ ExecutionContext* context = GetDocument().GetExecutionContext();
if (referrer_policy_to_use == network::mojom::ReferrerPolicy::kDefault)
- referrer_policy_to_use = GetDocument().GetReferrerPolicy();
+ referrer_policy_to_use = context->GetReferrerPolicy();
Referrer referrer = SecurityPolicy::GenerateReferrer(
- referrer_policy_to_use, url, GetDocument().OutgoingReferrer());
+ referrer_policy_to_use, url, context->OutgoingReferrer());
auto mojo_referrer = mojom::blink::Referrer::New(
KURL(NullURL(), referrer.referrer), referrer.referrer_policy);
@@ -214,7 +218,7 @@ void PortalContents::DispatchLoadEvent() {
GetDocument().CheckCompleted();
}
-void PortalContents::Trace(Visitor* visitor) {
+void PortalContents::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(portal_element_);
visitor->Trace(activate_resolver_);
diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_contents.h b/chromium/third_party/blink/renderer/core/html/portal/portal_contents.h
index 82270a20191..2c63c8111a2 100644
--- a/chromium/third_party/blink/renderer/core/html/portal/portal_contents.h
+++ b/chromium/third_party/blink/renderer/core/html/portal/portal_contents.h
@@ -90,7 +90,7 @@ class PortalContents : public GarbageCollected<PortalContents>,
const scoped_refptr<const SecurityOrigin>& target_origin) override;
void DispatchLoadEvent() override;
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
private:
// Returns the document which controls the lifetime of this portal (usually,
diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_host.cc b/chromium/third_party/blink/renderer/core/html/portal/portal_host.cc
index 5758bd24cfb..10cbf0b3ddc 100644
--- a/chromium/third_party/blink/renderer/core/html/portal/portal_host.cc
+++ b/chromium/third_party/blink/renderer/core/html/portal/portal_host.cc
@@ -24,7 +24,7 @@ namespace blink {
PortalHost::PortalHost(LocalDOMWindow& window)
: Supplement<LocalDOMWindow>(window) {}
-void PortalHost::Trace(Visitor* visitor) {
+void PortalHost::Trace(Visitor* visitor) const {
EventTargetWithInlineData::Trace(visitor);
Supplement<LocalDOMWindow>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_host.h b/chromium/third_party/blink/renderer/core/html/portal/portal_host.h
index 49966b02916..ce127eb0872 100644
--- a/chromium/third_party/blink/renderer/core/html/portal/portal_host.h
+++ b/chromium/third_party/blink/renderer/core/html/portal/portal_host.h
@@ -28,7 +28,7 @@ class CORE_EXPORT PortalHost : public EventTargetWithInlineData,
public:
explicit PortalHost(LocalDOMWindow& window);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
static const char kSupplementName[];
static PortalHost& From(LocalDOMWindow& window);
diff --git a/chromium/third_party/blink/renderer/core/html/rel_list.cc b/chromium/third_party/blink/renderer/core/html/rel_list.cc
index dc257118aa5..abe48f3c1c2 100644
--- a/chromium/third_party/blink/renderer/core/html/rel_list.cc
+++ b/chromium/third_party/blink/renderer/core/html/rel_list.cc
@@ -50,10 +50,20 @@ bool RelList::ValidateTokenValue(const AtomicString& token_value,
return true;
}
if (RuntimeEnabledFeatures::SignedExchangeSubresourcePrefetchEnabled(
- &GetElement().GetDocument()) &&
+ GetElement().GetExecutionContext()) &&
token_value == "allowed-alt-sxg") {
return true;
}
+ if (RuntimeEnabledFeatures::SubresourceWebBundlesEnabled(
+ GetElement().GetExecutionContext()) &&
+ token_value == "webbundle") {
+ return true;
+ }
+ if (RuntimeEnabledFeatures::MediaFeedsEnabled(
+ GetElement().GetExecutionContext()) ||
+ token_value == "media-feed") {
+ return true;
+ }
} else if ((GetElement().HasTagName(html_names::kATag) ||
GetElement().HasTagName(html_names::kAreaTag)) &&
SupportedTokensAnchorAndArea().Contains(token_value)) {
diff --git a/chromium/third_party/blink/renderer/core/html/resources/controls_refresh.css b/chromium/third_party/blink/renderer/core/html/resources/controls_refresh.css
index ccf1422fad5..d8de47f45ad 100644
--- a/chromium/third_party/blink/renderer/core/html/resources/controls_refresh.css
+++ b/chromium/third_party/blink/renderer/core/html/resources/controls_refresh.css
@@ -146,7 +146,7 @@ input[type="date" i]::-webkit-calendar-picker-indicator,
input[type="datetime-local" i]::-webkit-calendar-picker-indicator,
input[type="month" i]::-webkit-calendar-picker-indicator,
input[type="week" i]::-webkit-calendar-picker-indicator {
- background-image: -webkit-image-set(url(images/calendar_icon.svg) 1x);
+ background-image: -internal-light-dark(-webkit-image-set(url(images/calendar_icon.svg) 1x), -webkit-image-set(url(images/calendar_icon_white.svg) 1x));
background-origin: content-box;
background-repeat: no-repeat;
background-size: contain;
diff --git a/chromium/third_party/blink/renderer/core/html/resources/forced_colors.css b/chromium/third_party/blink/renderer/core/html/resources/forced_colors.css
index 8752b6d2fd4..47b2e5f7355 100644
--- a/chromium/third_party/blink/renderer/core/html/resources/forced_colors.css
+++ b/chromium/third_party/blink/renderer/core/html/resources/forced_colors.css
@@ -14,9 +14,8 @@
@namespace "http://www.w3.org/1999/xhtml"
*/
-@media forced-colors {
- body {
- background-color: Canvas;
+@media ua-forced-colors {
+ html {
color: CanvasText;
fill: currentColor;
}
@@ -38,6 +37,10 @@
border-color: CanvasText;
}
+ mark {
+ -internal-forced-background-color-rgb: yellow;
+ }
+
::placeholder {
color: GrayText;
}
@@ -73,11 +76,13 @@
background-color: ButtonFace;
border-color: GrayText;
color: GrayText;
+ -internal-forced-background-color-rgb: ButtonFace;
}
input::-webkit-calendar-picker-indicator {
background-color: ButtonFace;
color: ButtonText;
+ -internal-forced-background-color-rgb: ButtonFace;
}
input::-webkit-datetime-edit-ampm-field:focus,
@@ -91,6 +96,7 @@
input::-webkit-datetime-edit-year-field:focus {
background-color: Highlight;
color: HighlightText;
+ -internal-forced-background-color-rgb: Highlight;
outline: none;
}
@@ -114,6 +120,7 @@
border-color: ButtonText;
background: ButtonFace;
color: ButtonText;
+ -internal-forced-background-color-rgb: ButtonFace;
}
button:hover,
@@ -164,6 +171,7 @@
background-color: Highlight !important;
color: Canvas !important;
forced-color-adjust: none;
+ -internal-forced-background-color-rgb: Highlight;
}
/* option both disabled and selected */
@@ -176,12 +184,14 @@
background-color: GrayText !important;
color: Canvas !important;
forced-color-adjust: none;
+ -internal-forced-background-color-rgb: GrayText;
}
select:-internal-list-box option:hover {
background-color: Highlight !important;
color: Canvas;
forced-color-adjust: none;
+ -internal-forced-background-color-rgb: Highlight;
}
select {
@@ -207,12 +217,14 @@
meter::-webkit-meter-bar {
background: ButtonFace;
border-color: CanvasText;
+ -internal-forced-background-color-rgb: ButtonFace;
}
meter::-webkit-meter-even-less-good-value,
meter::-webkit-meter-optimum-value,
meter::-webkit-meter-suboptimum-value {
background: Highlight;
+ -internal-forced-background-color-rgb: Highlight;
}
input:-internal-autofill-previewed,
diff --git a/chromium/third_party/blink/renderer/core/html/resources/images/calendar_icon_white.svg b/chromium/third_party/blink/renderer/core/html/resources/images/calendar_icon_white.svg
new file mode 100644
index 00000000000..3f4b476a17c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/resources/images/calendar_icon_white.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="15" viewBox="0 0 24 24"><path fill="#ffffff" d="M20 3h-1V1h-2v2H7V1H5v2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 18H4V8h16v13z"/><path fill="none" d="M0 0h24v24H0z"/></svg> \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/core/html/shadow/details_marker_control.cc b/chromium/third_party/blink/renderer/core/html/shadow/details_marker_control.cc
index 2e54345f6f7..a77981b2d28 100644
--- a/chromium/third_party/blink/renderer/core/html/shadow/details_marker_control.cc
+++ b/chromium/third_party/blink/renderer/core/html/shadow/details_marker_control.cc
@@ -31,13 +31,14 @@
#include "third_party/blink/renderer/core/html/shadow/details_marker_control.h"
#include "third_party/blink/renderer/core/html/html_summary_element.h"
+#include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h"
#include "third_party/blink/renderer/core/layout/layout_details_marker.h"
namespace blink {
DetailsMarkerControl::DetailsMarkerControl(Document& document)
: HTMLDivElement(document) {
- SetShadowPseudoId(AtomicString("-webkit-details-marker"));
+ SetShadowPseudoId(shadow_element_names::WebKitDetailsMarker());
}
LayoutObject* DetailsMarkerControl::CreateLayoutObject(const ComputedStyle&,
diff --git a/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.cc b/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.cc
index ae955ffa21f..9c5d9509379 100644
--- a/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.cc
+++ b/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.cc
@@ -104,6 +104,11 @@ const AtomicString& TextFieldContainer() {
return name;
}
+const AtomicString& WebKitDetailsMarker() {
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("-webkit-details-marker"));
+ return name;
+}
+
const AtomicString& FileUploadButton() {
DEFINE_STATIC_LOCAL(AtomicString, name, ("file-upload-button"));
return name;
diff --git a/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.h b/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.h
index 128f3ebd3de..fb459eff76c 100644
--- a/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.h
+++ b/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.h
@@ -40,6 +40,7 @@ namespace shadow_element_names {
const AtomicString& DetailsContent();
const AtomicString& DetailsSummary();
+// An ID attribute value for a details marker.
const AtomicString& DetailsMarker();
const AtomicString& DateTimeEdit();
CORE_EXPORT const AtomicString& SpinButton();
@@ -52,6 +53,8 @@ const AtomicString& PasswordRevealButton();
CORE_EXPORT const AtomicString& SliderThumb();
const AtomicString& SliderTrack();
const AtomicString& TextFieldContainer();
+// Pseudo element name ::-webkit-details-marker
+const AtomicString& WebKitDetailsMarker();
const AtomicString& FileUploadButton();
const AtomicString& OptGroupLabel();
diff --git a/chromium/third_party/blink/renderer/core/html/subresource_redirect_test.cc b/chromium/third_party/blink/renderer/core/html/subresource_redirect_test.cc
index e7f15117ddf..9a3422d7473 100644
--- a/chromium/third_party/blink/renderer/core/html/subresource_redirect_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/subresource_redirect_test.cc
@@ -66,9 +66,6 @@ class SubresourceRedirectSimTest
// This test verifies subresource redirect previews state based on different
// states of SaveData, LazyLoad, SubresourceRedirect features.
TEST_P(SubresourceRedirectSimTest, CSSBackgroundImage) {
- WebView().GetPage()->GetSettings().SetLazyLoadEnabled(
- is_lazyload_image_enabled());
-
SimRequest image_resource("https://example.com/img.png", "image/png");
LoadMainResource(String::Format(R"HTML(
<style>
diff --git a/chromium/third_party/blink/renderer/core/html/track/audio_track.cc b/chromium/third_party/blink/renderer/core/html/track/audio_track.cc
index 53484fa1333..9193f154912 100644
--- a/chromium/third_party/blink/renderer/core/html/track/audio_track.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/audio_track.cc
@@ -22,7 +22,7 @@ AudioTrack::AudioTrack(const String& id,
AudioTrack::~AudioTrack() = default;
-void AudioTrack::Trace(Visitor* visitor) {
+void AudioTrack::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
TrackBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/track/audio_track.h b/chromium/third_party/blink/renderer/core/html/track/audio_track.h
index c267eef9f57..0ca1b445933 100644
--- a/chromium/third_party/blink/renderer/core/html/track/audio_track.h
+++ b/chromium/third_party/blink/renderer/core/html/track/audio_track.h
@@ -23,7 +23,7 @@ class CORE_EXPORT AudioTrack final : public ScriptWrappable, public TrackBase {
const AtomicString& language,
bool enabled);
~AudioTrack() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool enabled() const { return enabled_; }
void setEnabled(bool);
diff --git a/chromium/third_party/blink/renderer/core/html/track/audio_track_list.h b/chromium/third_party/blink/renderer/core/html/track/audio_track_list.h
index 9e831d41179..fac6f1b337e 100644
--- a/chromium/third_party/blink/renderer/core/html/track/audio_track_list.h
+++ b/chromium/third_party/blink/renderer/core/html/track/audio_track_list.h
@@ -22,7 +22,7 @@ class CORE_EXPORT AudioTrackList final : public TrackListBase<AudioTrack> {
// EventTarget
const AtomicString& InterfaceName() const override;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
TrackListBase<AudioTrack>::Trace(visitor);
}
};
diff --git a/chromium/third_party/blink/renderer/core/html/track/cue_timeline.cc b/chromium/third_party/blink/renderer/core/html/track/cue_timeline.cc
index 590529d72a9..ae436e34f84 100644
--- a/chromium/third_party/blink/renderer/core/html/track/cue_timeline.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/cue_timeline.cc
@@ -362,7 +362,7 @@ void CueTimeline::EndIgnoringUpdateRequests() {
UpdateActiveCues(MediaElement().currentTime());
}
-void CueTimeline::Trace(Visitor* visitor) {
+void CueTimeline::Trace(Visitor* visitor) const {
visitor->Trace(media_element_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/track/cue_timeline.h b/chromium/third_party/blink/renderer/core/html/track/cue_timeline.h
index cbfc68db7e8..76b59798188 100644
--- a/chromium/third_party/blink/renderer/core/html/track/cue_timeline.h
+++ b/chromium/third_party/blink/renderer/core/html/track/cue_timeline.h
@@ -47,7 +47,7 @@ class CueTimeline final : public GarbageCollected<CueTimeline> {
const CueList& CurrentlyActiveCues() const { return currently_active_cues_; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
HTMLMediaElement& MediaElement() const { return *media_element_; }
diff --git a/chromium/third_party/blink/renderer/core/html/track/html_track_element.cc b/chromium/third_party/blink/renderer/core/html/track/html_track_element.cc
index 67d538e5186..e461bbbad6e 100644
--- a/chromium/third_party/blink/renderer/core/html/track/html_track_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/html_track_element.cc
@@ -338,7 +338,7 @@ HTMLMediaElement* HTMLTrackElement::MediaElement() const {
return DynamicTo<HTMLMediaElement>(parentElement());
}
-void HTMLTrackElement::Trace(Visitor* visitor) {
+void HTMLTrackElement::Trace(Visitor* visitor) const {
visitor->Trace(track_);
visitor->Trace(loader_);
HTMLElement::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/track/html_track_element.h b/chromium/third_party/blink/renderer/core/html/track/html_track_element.h
index 4e66620f818..b7473220e0b 100644
--- a/chromium/third_party/blink/renderer/core/html/track/html_track_element.h
+++ b/chromium/third_party/blink/renderer/core/html/track/html_track_element.h
@@ -53,7 +53,7 @@ class HTMLTrackElement final : public HTMLElement,
TextTrack* track();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~HTMLTrackElement() override;
diff --git a/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.cc b/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.cc
index 560607a0243..e932189035f 100644
--- a/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.cc
@@ -63,7 +63,7 @@ wtf_size_t LoadableTextTrack::TrackElementIndex() const {
return index;
}
-void LoadableTextTrack::Trace(Visitor* visitor) {
+void LoadableTextTrack::Trace(Visitor* visitor) const {
visitor->Trace(track_element_);
TextTrack::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.h b/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.h
index 87b69cdf8b0..1de1ed23456 100644
--- a/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.h
+++ b/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.h
@@ -49,7 +49,7 @@ class LoadableTextTrack final : public TextTrack {
bool IsDefault() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<HTMLTrackElement> track_element_;
diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track.cc b/chromium/third_party/blink/renderer/core/html/track/text_track.cc
index 703706b3b98..7e1f5852d6a 100644
--- a/chromium/third_party/blink/renderer/core/html/track/text_track.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/text_track.cc
@@ -376,7 +376,7 @@ Node* TextTrack::Owner() const {
return MediaElement();
}
-void TextTrack::Trace(Visitor* visitor) {
+void TextTrack::Trace(Visitor* visitor) const {
visitor->Trace(cues_);
visitor->Trace(active_cues_);
visitor->Trace(track_list_);
diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track.h b/chromium/third_party/blink/renderer/core/html/track/text_track.h
index e4459809417..f34193f77da 100644
--- a/chromium/third_party/blink/renderer/core/html/track/text_track.h
+++ b/chromium/third_party/blink/renderer/core/html/track/text_track.h
@@ -127,7 +127,7 @@ class CORE_EXPORT TextTrack : public EventTargetWithInlineData,
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const HeapVector<Member<CSSStyleSheet>>& GetCSSStyleSheets() const {
return style_sheets_;
diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_container.cc b/chromium/third_party/blink/renderer/core/html/track/text_track_container.cc
index fccd0224a16..e2bb51a8bc5 100644
--- a/chromium/third_party/blink/renderer/core/html/track/text_track_container.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/text_track_container.cc
@@ -55,7 +55,7 @@ class VideoElementResizeDelegate final : public ResizeObserver::Delegate {
entries[0]->target()->GetLayoutObject());
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(text_track_container_);
ResizeObserver::Delegate::Trace(visitor);
}
@@ -75,7 +75,7 @@ TextTrackContainer::TextTrackContainer(HTMLMediaElement& media_element)
ObserveSizeChanges(*media_element_);
}
-void TextTrackContainer::Trace(Visitor* visitor) {
+void TextTrackContainer::Trace(Visitor* visitor) const {
visitor->Trace(media_element_);
visitor->Trace(video_size_observer_);
HTMLDivElement::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_container.h b/chromium/third_party/blink/renderer/core/html/track/text_track_container.h
index 190f247449a..f5b110c0b10 100644
--- a/chromium/third_party/blink/renderer/core/html/track/text_track_container.h
+++ b/chromium/third_party/blink/renderer/core/html/track/text_track_container.h
@@ -55,7 +55,7 @@ class TextTrackContainer final : public HTMLDivElement {
void UpdateDisplay(HTMLMediaElement&, ExposingControls);
void UpdateDefaultFontSize(LayoutObject*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool IsTextTrackContainer() const override { return true; }
diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_cue.cc b/chromium/third_party/blink/renderer/core/html/track/text_track_cue.cc
index 08b901b75bd..d67cc93ba80 100644
--- a/chromium/third_party/blink/renderer/core/html/track/text_track_cue.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/text_track_cue.cc
@@ -132,7 +132,7 @@ const AtomicString& TextTrackCue::InterfaceName() const {
return event_target_names::kTextTrackCue;
}
-void TextTrackCue::Trace(Visitor* visitor) {
+void TextTrackCue::Trace(Visitor* visitor) const {
visitor->Trace(track_);
EventTargetWithInlineData::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_cue.h b/chromium/third_party/blink/renderer/core/html/track/text_track_cue.h
index 176febe7577..93acd32ef60 100644
--- a/chromium/third_party/blink/renderer/core/html/track/text_track_cue.h
+++ b/chromium/third_party/blink/renderer/core/html/track/text_track_cue.h
@@ -97,7 +97,7 @@ class TextTrackCue : public EventTargetWithInlineData {
DEFINE_ATTRIBUTE_EVENT_LISTENER(enter, kEnter)
DEFINE_ATTRIBUTE_EVENT_LISTENER(exit, kExit)
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
TextTrackCue(double start, double end);
diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.cc b/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.cc
index 44bd640bd32..30b9b17dccf 100644
--- a/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.cc
@@ -139,7 +139,7 @@ void TextTrackCueList::ValidateCueIndexes() {
first_invalid_index_ = list_.size();
}
-void TextTrackCueList::Trace(Visitor* visitor) {
+void TextTrackCueList::Trace(Visitor* visitor) const {
visitor->Trace(list_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.h b/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.h
index 505136faed1..51266a732db 100644
--- a/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.h
+++ b/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.h
@@ -55,7 +55,7 @@ class TextTrackCueList final : public ScriptWrappable {
}
void ValidateCueIndexes();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
wtf_size_t FindInsertionIndex(const TextTrackCue*) const;
diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_list.cc b/chromium/third_party/blink/renderer/core/html/track/text_track_list.cc
index c5cfc997620..7393444b2ce 100644
--- a/chromium/third_party/blink/renderer/core/html/track/text_track_list.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/text_track_list.cc
@@ -296,7 +296,7 @@ HTMLMediaElement* TextTrackList::Owner() const {
return owner_;
}
-void TextTrackList::Trace(Visitor* visitor) {
+void TextTrackList::Trace(Visitor* visitor) const {
visitor->Trace(owner_);
visitor->Trace(add_track_tracks_);
visitor->Trace(element_tracks_);
diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_list.h b/chromium/third_party/blink/renderer/core/html/track/text_track_list.h
index fd1483dafc9..0d04e60d169 100644
--- a/chromium/third_party/blink/renderer/core/html/track/text_track_list.h
+++ b/chromium/third_party/blink/renderer/core/html/track/text_track_list.h
@@ -70,7 +70,7 @@ class CORE_EXPORT TextTrackList final : public EventTargetWithInlineData {
bool HasShowingTracks();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void ScheduleTrackEvent(const AtomicString& event_name, TextTrack*);
diff --git a/chromium/third_party/blink/renderer/core/html/track/track_base.cc b/chromium/third_party/blink/renderer/core/html/track/track_base.cc
index 06186ff6f78..cffda8b41ef 100644
--- a/chromium/third_party/blink/renderer/core/html/track/track_base.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/track_base.cc
@@ -48,7 +48,7 @@ TrackBase::TrackBase(WebMediaPlayer::TrackType type,
TrackBase::~TrackBase() = default;
-void TrackBase::Trace(Visitor* visitor) {
+void TrackBase::Trace(Visitor* visitor) const {
Supplementable<TrackBase>::Trace(visitor);
visitor->Trace(media_element_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/track/track_base.h b/chromium/third_party/blink/renderer/core/html/track/track_base.h
index d752883ecb6..055fe6e79db 100644
--- a/chromium/third_party/blink/renderer/core/html/track/track_base.h
+++ b/chromium/third_party/blink/renderer/core/html/track/track_base.h
@@ -53,7 +53,7 @@ class CORE_EXPORT TrackBase : public Supplementable<TrackBase> {
}
HTMLMediaElement* MediaElement() const { return media_element_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
TrackBase(WebMediaPlayer::TrackType,
diff --git a/chromium/third_party/blink/renderer/core/html/track/track_event.cc b/chromium/third_party/blink/renderer/core/html/track/track_event.cc
index 24d0448c33c..e875488aeb0 100644
--- a/chromium/third_party/blink/renderer/core/html/track/track_event.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/track_event.cc
@@ -79,7 +79,7 @@ void TrackEvent::track(VideoTrackOrAudioTrackOrTextTrack& return_value) {
}
}
-void TrackEvent::Trace(Visitor* visitor) {
+void TrackEvent::Trace(Visitor* visitor) const {
visitor->Trace(track_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/track/track_event.h b/chromium/third_party/blink/renderer/core/html/track/track_event.h
index 6810fe194e2..af6a98f9352 100644
--- a/chromium/third_party/blink/renderer/core/html/track/track_event.h
+++ b/chromium/third_party/blink/renderer/core/html/track/track_event.h
@@ -59,7 +59,7 @@ class CORE_EXPORT TrackEvent final : public Event {
void track(VideoTrackOrAudioTrackOrTextTrack&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<TrackBase> track_;
diff --git a/chromium/third_party/blink/renderer/core/html/track/track_list_base.h b/chromium/third_party/blink/renderer/core/html/track/track_list_base.h
index 27b4c3b8e0a..4827214252c 100644
--- a/chromium/third_party/blink/renderer/core/html/track/track_list_base.h
+++ b/chromium/third_party/blink/renderer/core/html/track/track_list_base.h
@@ -77,7 +77,7 @@ class TrackListBase : public EventTargetWithInlineData {
ScheduleEvent(Event::Create(event_type_names::kChange));
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(tracks_);
visitor->Trace(media_element_);
EventTargetWithInlineData::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/track/video_track.cc b/chromium/third_party/blink/renderer/core/html/track/video_track.cc
index ee63e7767c8..9fc8cc67b13 100644
--- a/chromium/third_party/blink/renderer/core/html/track/video_track.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/video_track.cc
@@ -18,7 +18,7 @@ VideoTrack::VideoTrack(const String& id,
VideoTrack::~VideoTrack() = default;
-void VideoTrack::Trace(Visitor* visitor) {
+void VideoTrack::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
TrackBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/track/video_track.h b/chromium/third_party/blink/renderer/core/html/track/video_track.h
index a59fd126a47..69b051fba1b 100644
--- a/chromium/third_party/blink/renderer/core/html/track/video_track.h
+++ b/chromium/third_party/blink/renderer/core/html/track/video_track.h
@@ -23,7 +23,7 @@ class CORE_EXPORT VideoTrack final : public ScriptWrappable, public TrackBase {
const AtomicString& language,
bool selected);
~VideoTrack() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool selected() const { return selected_; }
void setSelected(bool);
diff --git a/chromium/third_party/blink/renderer/core/html/track/video_track_list.h b/chromium/third_party/blink/renderer/core/html/track/video_track_list.h
index 4fee375ea84..4cf6a0fdf95 100644
--- a/chromium/third_party/blink/renderer/core/html/track/video_track_list.h
+++ b/chromium/third_party/blink/renderer/core/html/track/video_track_list.h
@@ -24,7 +24,7 @@ class CORE_EXPORT VideoTrackList final : public TrackListBase<VideoTrack> {
void TrackSelected(WebMediaPlayer::TrackId selected_track_id);
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
TrackListBase<VideoTrack>::Trace(visitor);
}
};
diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc
index 401575bfb08..42277379f7f 100644
--- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc
@@ -145,7 +145,7 @@ VTTCueBackgroundBox::VTTCueBackgroundBox(Document& document)
SetShadowPseudoId(TextTrackCue::CueShadowPseudoId());
}
-void VTTCueBackgroundBox::Trace(Visitor* visitor) {
+void VTTCueBackgroundBox::Trace(Visitor* visitor) const {
visitor->Trace(track_);
HTMLDivElement::Trace(visitor);
}
@@ -1114,7 +1114,7 @@ Document& VTTCue::GetDocument() const {
return cue_background_box_->GetDocument();
}
-void VTTCue::Trace(Visitor* visitor) {
+void VTTCue::Trace(Visitor* visitor) const {
visitor->Trace(region_);
visitor->Trace(vtt_node_tree_);
visitor->Trace(cue_background_box_);
diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h
index 0152de94d5d..c8aec42a505 100644
--- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h
+++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h
@@ -80,7 +80,7 @@ class VTTCueBackgroundBox final : public HTMLDivElement {
explicit VTTCueBackgroundBox(Document&);
bool IsVTTCueBackgroundBox() const override { return true; }
void SetTrack(TextTrack*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const TextTrack* GetTrack() const { return track_; }
@@ -172,7 +172,7 @@ class VTTCue final : public TextTrackCue {
String ToString() const override;
#endif
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Document& GetDocument() const;
diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc
index ba0aef82404..d57e3602443 100644
--- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc
@@ -86,32 +86,32 @@ HTMLElement* VTTElement::CreateEquivalentHTMLElement(Document& document) {
case kVTTNodeTypeClass:
case kVTTNodeTypeLanguage:
case kVTTNodeTypeVoice:
- html_element = document.CreateRawElement(html_names::kSpanTag,
- CreateElementFlags::ByParser());
+ html_element =
+ document.CreateRawElement(html_names::kSpanTag, CreateElementFlags());
html_element->setAttribute(html_names::kTitleAttr,
getAttribute(VoiceAttributeName()));
html_element->setAttribute(html_names::kLangAttr,
getAttribute(LangAttributeName()));
break;
case kVTTNodeTypeItalic:
- html_element = document.CreateRawElement(html_names::kITag,
- CreateElementFlags::ByParser());
+ html_element =
+ document.CreateRawElement(html_names::kITag, CreateElementFlags());
break;
case kVTTNodeTypeBold:
- html_element = document.CreateRawElement(html_names::kBTag,
- CreateElementFlags::ByParser());
+ html_element =
+ document.CreateRawElement(html_names::kBTag, CreateElementFlags());
break;
case kVTTNodeTypeUnderline:
- html_element = document.CreateRawElement(html_names::kUTag,
- CreateElementFlags::ByParser());
+ html_element =
+ document.CreateRawElement(html_names::kUTag, CreateElementFlags());
break;
case kVTTNodeTypeRuby:
- html_element = document.CreateRawElement(html_names::kRubyTag,
- CreateElementFlags::ByParser());
+ html_element =
+ document.CreateRawElement(html_names::kRubyTag, CreateElementFlags());
break;
case kVTTNodeTypeRubyText:
- html_element = document.CreateRawElement(html_names::kRtTag,
- CreateElementFlags::ByParser());
+ html_element =
+ document.CreateRawElement(html_names::kRtTag, CreateElementFlags());
break;
default:
NOTREACHED();
@@ -137,7 +137,7 @@ void VTTElement::SetTrack(TextTrack* track) {
track_ = track;
}
-void VTTElement::Trace(Visitor* visitor) {
+void VTTElement::Trace(Visitor* visitor) const {
visitor->Trace(track_);
Element::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.h b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.h
index 9d26b2e9165..f95165e7cdf 100644
--- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.h
+++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.h
@@ -82,7 +82,7 @@ class VTTElement final : public Element {
const TextTrack* GetTrack() const { return track_; }
void SetTrack(TextTrack*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<TextTrack> track_;
diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc
index 3d878c164b5..0b6e9b6b8b6 100644
--- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc
@@ -669,7 +669,7 @@ void VTTTreeBuilder::ConstructTreeFromToken(Document& document) {
}
}
-void VTTParser::Trace(Visitor* visitor) {
+void VTTParser::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(current_region_);
visitor->Trace(client_);
diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.h b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.h
index 92355c84d39..b214f9303f6 100644
--- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.h
+++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.h
@@ -54,7 +54,7 @@ class VTTParserClient : public GarbageCollectedMixin {
virtual void NewCuesParsed() = 0;
virtual void FileFailedToParse() = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
// Implementation of the WebVTT parser algorithm.
@@ -114,7 +114,7 @@ class VTTParser final : public GarbageCollected<VTTParser> {
// Transfers ownership of last parsed style sheets to caller.
void GetNewStyleSheets(HeapVector<Member<CSSStyleSheet>>&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<Document> document_;
diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.cc b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.cc
index a7395d16272..d551daa9dea 100644
--- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.cc
@@ -419,7 +419,7 @@ void VTTRegion::ScrollTimerFired(TimerBase*) {
DisplayLastVTTCueBox();
}
-void VTTRegion::Trace(Visitor* visitor) {
+void VTTRegion::Trace(Visitor* visitor) const {
visitor->Trace(cue_container_);
visitor->Trace(region_display_tree_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.h b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.h
index 0adac94f793..87dadf7ad56 100644
--- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.h
+++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.h
@@ -88,7 +88,7 @@ class VTTRegion final : public ScriptWrappable {
void DisplayLastVTTCueBox();
void WillRemoveVTTCueBox(VTTCueBox*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void PrepareRegionDisplayTree();
diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_tokenizer.cc b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_tokenizer.cc
index 3483fa68061..9cee192afca 100644
--- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_tokenizer.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_tokenizer.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/html/track/vtt/vtt_tokenizer.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/core/html/parser/html_entity_parser.h"
#include "third_party/blink/renderer/core/html/parser/markup_tokenizer_inlines.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
diff --git a/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing.cc b/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing.cc
index 0724901f6f1..5f67023e60f 100644
--- a/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing.cc
+++ b/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing.cc
@@ -6,6 +6,7 @@
#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
#include "services/network/public/mojom/trust_tokens.mojom-shared.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_trust_token.h"
+#include "third_party/blink/renderer/core/fetch/trust_token_to_mojom.h"
#include "third_party/blink/renderer/platform/json/json_values.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -133,6 +134,14 @@ network::mojom::blink::TrustTokenParamsPtr TrustTokenParamsFromJson(
}
}
+ // |additionalSigningData| is optional.
+ if (JSONValue* additional_signing_data =
+ object->Get("additionalSigningData")) {
+ if (!additional_signing_data->AsString(
+ &ret->possibly_unsafe_additional_signing_data))
+ return nullptr;
+ }
+
return ret;
}
diff --git a/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing_test.cc b/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing_test.cc
index 75934f207ff..85721c02335 100644
--- a/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing_test.cc
@@ -229,5 +229,15 @@ TEST(TrustTokenAttributeParsing, TypeUnsafeAdditionalSignedHeader) {
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
+// Test that the parser requires that additionalSigningData be a string.
+TEST(TrustTokenAttributeParsing, TypeUnsafeAdditionalSigningData) {
+ auto json = ParseJSON(R"(
+ { "type": "token-request",
+ "additionalSigningData": 15 }
+ )");
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
} // namespace internal
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
index 4a4ab8e271a..b1cdb231862 100644
--- a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
+++ b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
@@ -45,7 +45,6 @@ constexpr const char* kImageBitmapOptionResizeQualityMedium = "medium";
constexpr const char* kImageBitmapOptionResizeQualityPixelated = "pixelated";
constexpr const char* kPreserveImageBitmapColorSpaceConversion = "preserve";
constexpr const char* kSRGBImageBitmapColorSpaceConversion = "srgb";
-constexpr const char* kLinearRGBImageBitmapColorSpaceConversion = "linear-rgb";
constexpr const char* kP3ImageBitmapColorSpaceConversion = "p3";
constexpr const char* kRec2020ImageBitmapColorSpaceConversion = "rec2020";
@@ -102,12 +101,7 @@ ImageBitmap::ParsedOptions ParseOptions(const ImageBitmapOptions* options,
options->colorSpaceConversion() != kImageBitmapOptionNone &&
options->colorSpaceConversion() != kImageBitmapOptionDefault) {
parsed_options.color_params.SetCanvasPixelFormat(CanvasPixelFormat::kF16);
- if (options->colorSpaceConversion() ==
- kLinearRGBImageBitmapColorSpaceConversion) {
- parsed_options.color_params.SetCanvasColorSpace(
- CanvasColorSpace::kLinearRGB);
- } else if (options->colorSpaceConversion() ==
- kP3ImageBitmapColorSpaceConversion) {
+ if (options->colorSpaceConversion() == kP3ImageBitmapColorSpaceConversion) {
parsed_options.color_params.SetCanvasColorSpace(CanvasColorSpace::kP3);
} else if (options->colorSpaceConversion() ==
kRec2020ImageBitmapColorSpaceConversion) {
@@ -243,8 +237,7 @@ std::unique_ptr<CanvasResourceProvider> CreateProvider(
->UsageForMailbox(source_image->GetMailboxHolder().mailbox);
auto resource_provider = CanvasResourceProvider::CreateSharedImageProvider(
size, context_provider, kLow_SkFilterQuality, color_params,
- source_image->IsOriginTopLeft(),
- CanvasResourceProvider::RasterMode::kGPU, usage_flags);
+ source_image->IsOriginTopLeft(), RasterMode::kGPU, usage_flags);
if (resource_provider)
return resource_provider;
@@ -329,6 +322,8 @@ scoped_refptr<StaticBitmapImage> GetImageWithAlphaDisposition(
? kPremul_SkAlphaType
: kUnpremul_SkAlphaType;
sk_sp<SkImage> skia_image = image->PaintImageForCurrentFrame().GetSkImage();
+ if (!skia_image)
+ return nullptr;
if (skia_image->alphaType() == alpha_type)
return std::move(image);
@@ -389,7 +384,7 @@ scoped_refptr<StaticBitmapImage> ScaleImage(
SkRect::MakeWH(sk_image->width(), sk_image->height()),
SkRect::MakeWH(parsed_options.resize_width,
parsed_options.resize_height),
- &paint, cc::PaintCanvas::kStrict_SrcRectConstraint);
+ &paint, SkCanvas::kStrict_SrcRectConstraint);
return resource_provider->Snapshot(image->CurrentFrameOrientation());
}
}
@@ -508,7 +503,7 @@ static scoped_refptr<StaticBitmapImage> CropImageAndApplyColorSpaceConversion(
SkRect::MakeXYWH(src_rect.X(), src_rect.Y(), src_rect.Width(),
src_rect.Height()),
SkRect::MakeWH(src_rect.Width(), src_rect.Height()), &paint,
- cc::PaintCanvas::kStrict_SrcRectConstraint);
+ SkCanvas::kStrict_SrcRectConstraint);
result = resource_provider->Snapshot(image->CurrentFrameOrientation());
} else {
result = UnacceleratedStaticBitmapImage::Create(
@@ -553,6 +548,8 @@ static scoped_refptr<StaticBitmapImage> CropImageAndApplyColorSpaceConversion(
parsed_options.premultiply_alpha
? kPremultiplyAlpha
: kUnpremultiplyAlpha);
+ if (!result)
+ return nullptr;
// convert pixel format if needed
result =
@@ -686,8 +683,8 @@ ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas,
base::Optional<IntRect> crop_rect,
const ImageBitmapOptions* options) {
SourceImageStatus status;
- scoped_refptr<Image> image_input = canvas->GetSourceImageForCanvas(
- &status, kPreferAcceleration, FloatSize());
+ scoped_refptr<Image> image_input =
+ canvas->GetSourceImageForCanvas(&status, FloatSize());
if (status != kNormalSourceImageStatus)
return;
DCHECK(IsA<StaticBitmapImage>(image_input.get()));
@@ -713,7 +710,7 @@ ImageBitmap::ImageBitmap(OffscreenCanvas* offscreen_canvas,
const ImageBitmapOptions* options) {
SourceImageStatus status;
scoped_refptr<Image> raw_input = offscreen_canvas->GetSourceImageForCanvas(
- &status, kPreferNoAcceleration, FloatSize(offscreen_canvas->Size()));
+ &status, FloatSize(offscreen_canvas->Size()));
DCHECK(IsA<StaticBitmapImage>(raw_input.get()));
scoped_refptr<StaticBitmapImage> input =
static_cast<StaticBitmapImage*>(raw_input.get());
@@ -1107,7 +1104,6 @@ ScriptPromise ImageBitmap::CreateImageBitmap(ScriptState* script_state,
scoped_refptr<Image> ImageBitmap::GetSourceImageForCanvas(
SourceImageStatus* status,
- AccelerationHint,
const FloatSize&) {
*status = kNormalSourceImageStatus;
if (!image_)
diff --git a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.h b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.h
index 93f42fea5ab..17428bd8ab9 100644
--- a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.h
+++ b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.h
@@ -105,7 +105,6 @@ class CORE_EXPORT ImageBitmap final : public ScriptWrappable,
// CanvasImageSource implementation
scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*,
- AccelerationHint,
const FloatSize&) override;
bool WouldTaintOrigin() const override { return !image_->OriginClean(); }
FloatSize ElementSize(const FloatSize&,
diff --git a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc
index 2aa8f6f36e0..32c39108707 100644
--- a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc
+++ b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc
@@ -226,7 +226,7 @@ void ImageBitmapFactories::DidFinishLoading(ImageBitmapLoader* loader) {
pending_loaders_.erase(loader);
}
-void ImageBitmapFactories::Trace(Visitor* visitor) {
+void ImageBitmapFactories::Trace(Visitor* visitor) const {
visitor->Trace(pending_loaders_);
Supplement<ExecutionContext>::Trace(visitor);
}
@@ -367,7 +367,7 @@ void ImageBitmapFactories::ImageBitmapLoader::ResolvePromiseOnOriginalThread(
factory_->DidFinishLoading(this);
}
-void ImageBitmapFactories::ImageBitmapLoader::Trace(Visitor* visitor) {
+void ImageBitmapFactories::ImageBitmapLoader::Trace(Visitor* visitor) const {
ExecutionContextLifecycleObserver::Trace(visitor);
visitor->Trace(factory_);
visitor->Trace(resolver_);
diff --git a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h
index e9dc2d79c5e..1babc40e543 100644
--- a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h
+++ b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h
@@ -57,7 +57,7 @@ class Blob;
class ExecutionContext;
class ImageBitmapSource;
-class ImageBitmapFactories final
+class CORE_EXPORT ImageBitmapFactories final
: public GarbageCollected<ImageBitmapFactories>,
public Supplement<ExecutionContext>,
public NameClient {
@@ -78,10 +78,15 @@ class ImageBitmapFactories final
int sh,
const ImageBitmapOptions*,
ExceptionState&);
+ static ScriptPromise CreateImageBitmap(ScriptState*,
+ ImageBitmapSource*,
+ base::Optional<IntRect> crop_rect,
+ const ImageBitmapOptions*,
+ ExceptionState&);
virtual ~ImageBitmapFactories() = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override {
return "ImageBitmapLoader";
}
@@ -109,7 +114,7 @@ class ImageBitmapFactories final
void LoadBlobAsync(Blob*);
ScriptPromise Promise() { return resolver_->Promise(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
~ImageBitmapLoader() override;
@@ -144,11 +149,6 @@ class ImageBitmapFactories final
};
static ImageBitmapFactories& From(ExecutionContext&);
- static ScriptPromise CreateImageBitmap(ScriptState*,
- ImageBitmapSource*,
- base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions*,
- ExceptionState&);
static ScriptPromise CreateImageBitmapFromBlob(
ScriptState*,
ImageBitmapSource*,
diff --git a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl
index f15b66ff774..e88342cb8e2 100644
--- a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl
+++ b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl
@@ -7,7 +7,7 @@
enum ImageOrientation { "none", "flipY" };
enum ImageBitmapPixelFormat { "default", "uint8" };
enum PremultiplyAlpha { "none", "premultiply", "default" };
-enum ColorSpaceConversion { "none", "default", "srgb", "linear-rgb", "rec2020", "p3" };
+enum ColorSpaceConversion { "none", "default" };
enum ResizeQuality { "pixelated", "low", "medium", "high" };
dictionary ImageBitmapOptions {
ImageOrientation imageOrientation = "none";
diff --git a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_test.cc b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_test.cc
index e087195e860..1d8a213157d 100644
--- a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_test.cc
+++ b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_test.cc
@@ -113,10 +113,10 @@ TEST_F(ImageBitmapTest, ImageResourceConsistency) {
SkImageInfo::MakeN32Premul(5, 5, src_rgb_color_space);
sk_sp<SkSurface> surface(SkSurface::MakeRaster(raster_image_info));
sk_sp<SkImage> image = surface->makeImageSnapshot();
- ImageResourceContent* original_image_resource =
+ ImageResourceContent* original_image_content =
ImageResourceContent::CreateLoaded(
UnacceleratedStaticBitmapImage::Create(image).get());
- image_element->SetImageForTest(original_image_resource);
+ image_element->SetImageForTest(original_image_content);
base::Optional<IntRect> crop_rect =
IntRect(0, 0, image_->width(), image_->height());
@@ -180,10 +180,10 @@ TEST_F(ImageBitmapTest, ImageBitmapSourceChanged) {
SkImageInfo::MakeN32Premul(5, 5, src_rgb_color_space);
sk_sp<SkSurface> raster_surface(SkSurface::MakeRaster(raster_image_info));
sk_sp<SkImage> raster_image = raster_surface->makeImageSnapshot();
- ImageResourceContent* original_image_resource =
+ ImageResourceContent* original_image_content =
ImageResourceContent::CreateLoaded(
UnacceleratedStaticBitmapImage::Create(raster_image).get());
- image->SetImageForTest(original_image_resource);
+ image->SetImageForTest(original_image_content);
const ImageBitmapOptions* default_options = ImageBitmapOptions::Create();
base::Optional<IntRect> crop_rect =
@@ -193,18 +193,18 @@ TEST_F(ImageBitmapTest, ImageBitmapSourceChanged) {
ASSERT_TRUE(image_bitmap);
ASSERT_EQ(
image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage(),
- original_image_resource->GetImage()
+ original_image_content->GetImage()
->PaintImageForCurrentFrame()
.GetSkImage());
- ImageResourceContent* new_image_resource = ImageResourceContent::CreateLoaded(
+ ImageResourceContent* new_image_content = ImageResourceContent::CreateLoaded(
UnacceleratedStaticBitmapImage::Create(image2_).get());
- image->SetImageForTest(new_image_resource);
+ image->SetImageForTest(new_image_content);
{
ASSERT_EQ(
image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage(),
- original_image_resource->GetImage()
+ original_image_content->GetImage()
->PaintImageForCurrentFrame()
.GetSkImage());
SkImage* image1 = image_bitmap->BitmapImage()
@@ -212,7 +212,7 @@ TEST_F(ImageBitmapTest, ImageBitmapSourceChanged) {
.GetSkImage()
.get();
ASSERT_NE(image1, nullptr);
- SkImage* image2 = original_image_resource->GetImage()
+ SkImage* image2 = original_image_content->GetImage()
->PaintImageForCurrentFrame()
.GetSkImage()
.get();
@@ -223,7 +223,7 @@ TEST_F(ImageBitmapTest, ImageBitmapSourceChanged) {
{
ASSERT_NE(
image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage(),
- new_image_resource->GetImage()
+ new_image_content->GetImage()
->PaintImageForCurrentFrame()
.GetSkImage());
SkImage* image1 = image_bitmap->BitmapImage()
@@ -231,7 +231,7 @@ TEST_F(ImageBitmapTest, ImageBitmapSourceChanged) {
.GetSkImage()
.get();
ASSERT_NE(image1, nullptr);
- SkImage* image2 = new_image_resource->GetImage()
+ SkImage* image2 = new_image_content->GetImage()
->PaintImageForCurrentFrame()
.GetSkImage()
.get();
@@ -256,8 +256,7 @@ TEST_F(ImageBitmapTest, AvoidGPUReadback) {
CanvasColorParams color_params;
auto resource_provider = CanvasResourceProvider::CreateSharedImageProvider(
IntSize(100, 100), context_provider_wrapper, kLow_SkFilterQuality,
- color_params, true /*is_origin_top_left*/,
- CanvasResourceProvider::RasterMode::kGPU,
+ color_params, true /*is_origin_top_left*/, RasterMode::kGPU,
0u /*shared_image_usage_flags*/);
scoped_refptr<StaticBitmapImage> bitmap = resource_provider->Snapshot();
@@ -274,8 +273,7 @@ TEST_F(ImageBitmapTest, AvoidGPUReadback) {
std::list<String> image_orientations = {"none", "flipY"};
std::list<String> premultiply_alphas = {"none", "premultiply", "default"};
- std::list<String> color_space_conversions = {
- "none", "default", "preserve", "srgb", "linear-rgb", "rec2020", "p3"};
+ std::list<String> color_space_conversions = {"none", "default"};
std::list<int> resize_widths = {25, 50, 75};
std::list<int> resize_heights = {25, 50, 75};
std::list<String> resize_qualities = {"pixelated", "low", "medium", "high"};
@@ -309,276 +307,6 @@ TEST_F(ImageBitmapTest, AvoidGPUReadback) {
}
}
-TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionHTMLImageElement) {
- auto dummy = std::make_unique<DummyPageHolder>(IntSize(800, 600));
- auto* image_element =
- MakeGarbageCollected<HTMLImageElement>(dummy->GetDocument());
-
- SkPaint p;
- p.setColor(SK_ColorRED);
- sk_sp<SkColorSpace> colorspin =
- ColorCorrectionTestUtils::ColorSpinSkColorSpace();
-
- SkImageInfo image_info = SkImageInfo::MakeN32Premul(10, 10, colorspin);
- sk_sp<SkSurface> surface(SkSurface::MakeRaster(image_info));
- surface->getCanvas()->drawCircle(5, 5, 5, p);
- sk_sp<SkImage> source_image = surface->makeImageSnapshot();
- SkPixmap source_pixmap;
- source_image->peekPixels(&source_pixmap);
-
- ImageResourceContent* original_image_resource =
- ImageResourceContent::CreateLoaded(
- UnacceleratedStaticBitmapImage::Create(source_image).get());
- image_element->SetImageForTest(original_image_resource);
-
- base::Optional<IntRect> crop_rect =
- IntRect(0, 0, source_image->width(), source_image->height());
-
- for (int conversion_iterator = kColorSpaceConversion_Default;
- conversion_iterator <= kColorSpaceConversion_Last;
- conversion_iterator++) {
- ImageBitmapOptions* options = ImageBitmapOptions::Create();
- options->setColorSpaceConversion(
- ColorCorrectionTestUtils::ColorSpaceConversionToString(
- static_cast<ColorSpaceConversion>(conversion_iterator)));
- auto* image_bitmap =
- MakeGarbageCollected<ImageBitmap>(image_element, crop_rect, options);
- ASSERT_TRUE(image_bitmap);
- sk_sp<SkImage> converted_image =
- image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage();
- SkPixmap converted_pixmap;
- converted_image->peekPixels(&converted_pixmap);
- unsigned num_pixels = source_image->width() * source_image->height();
-
- if (conversion_iterator == kColorSpaceConversion_Preserve) {
- EXPECT_TRUE(
- SkColorSpace::Equals(colorspin.get(), converted_image->colorSpace()));
- ColorCorrectionTestUtils::CompareColorCorrectedPixels(
- converted_pixmap.addr(), source_pixmap.addr(), num_pixels,
- kPixelFormat_8888, kAlphaMultiplied, kUnpremulRoundTripTolerance);
- } else {
- sk_sp<SkColorSpace> color_space =
- ColorCorrectionTestUtils::ColorSpaceConversionToSkColorSpace(
- static_cast<ColorSpaceConversion>(conversion_iterator));
- EXPECT_TRUE(SkColorSpace::Equals(color_space.get(),
- converted_image->colorSpace()));
-
- SkImageInfo expected_image_info =
- source_pixmap.info().makeColorSpace(color_space);
- if (color_space->gammaIsLinear()) {
- expected_image_info =
- expected_image_info.makeColorType(kRGBA_F16_SkColorType);
- }
- SkBitmap expected_bitmap;
- EXPECT_TRUE(expected_bitmap.tryAllocPixels(expected_image_info));
- source_image->readPixels(expected_bitmap.pixmap(), 0, 0);
-
- ColorCorrectionTestUtils::CompareColorCorrectedPixels(
- converted_pixmap.addr(), expected_bitmap.pixmap().addr(), num_pixels,
- color_space->gammaIsLinear() ? kPixelFormat_hhhh : kPixelFormat_8888,
- kAlphaMultiplied, kUnpremulRoundTripTolerance);
- }
- }
-}
-
-TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageBitmap) {
- SkPaint p;
- p.setColor(SK_ColorRED);
- sk_sp<SkColorSpace> colorspin =
- ColorCorrectionTestUtils::ColorSpinSkColorSpace();
-
- SkImageInfo image_info = SkImageInfo::MakeN32Premul(10, 10, colorspin);
- sk_sp<SkSurface> surface(SkSurface::MakeRaster(image_info));
- surface->getCanvas()->drawCircle(5, 5, 5, p);
- sk_sp<SkImage> source_image = surface->makeImageSnapshot();
- SkPixmap source_pixmap;
- source_image->peekPixels(&source_pixmap);
-
- base::Optional<IntRect> crop_rect =
- IntRect(0, 0, source_image->width(), source_image->height());
- ImageBitmapOptions* options = ImageBitmapOptions::Create();
- options->setColorSpaceConversion(
- ColorCorrectionTestUtils::ColorSpaceConversionToString(
- kColorSpaceConversion_Preserve));
- auto* source_image_bitmap = MakeGarbageCollected<ImageBitmap>(
- UnacceleratedStaticBitmapImage::Create(source_image), crop_rect, options);
- ASSERT_TRUE(source_image_bitmap);
-
- for (int conversion_iterator = kColorSpaceConversion_Default;
- conversion_iterator <= kColorSpaceConversion_Last;
- conversion_iterator++) {
- options->setColorSpaceConversion(
- ColorCorrectionTestUtils::ColorSpaceConversionToString(
- static_cast<ColorSpaceConversion>(conversion_iterator)));
- auto* image_bitmap = MakeGarbageCollected<ImageBitmap>(source_image_bitmap,
- crop_rect, options);
- ASSERT_TRUE(image_bitmap);
- sk_sp<SkImage> converted_image =
- image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage();
- SkPixmap converted_pixmap;
- converted_image->peekPixels(&converted_pixmap);
- unsigned num_pixels = source_image->width() * source_image->height();
-
- if (conversion_iterator == kColorSpaceConversion_Preserve) {
- EXPECT_TRUE(
- SkColorSpace::Equals(colorspin.get(), converted_image->colorSpace()));
- ColorCorrectionTestUtils::CompareColorCorrectedPixels(
- converted_pixmap.addr(), source_pixmap.addr(), num_pixels,
- kPixelFormat_8888, kAlphaMultiplied, kUnpremulRoundTripTolerance);
- } else {
- sk_sp<SkColorSpace> color_space =
- ColorCorrectionTestUtils::ColorSpaceConversionToSkColorSpace(
- static_cast<ColorSpaceConversion>(conversion_iterator));
- EXPECT_TRUE(SkColorSpace::Equals(color_space.get(),
- converted_image->colorSpace()));
-
- SkImageInfo expected_image_info =
- source_pixmap.info().makeColorSpace(color_space);
- if (color_space->gammaIsLinear()) {
- expected_image_info =
- expected_image_info.makeColorType(kRGBA_F16_SkColorType);
- }
- SkBitmap expected_bitmap;
- EXPECT_TRUE(expected_bitmap.tryAllocPixels(expected_image_info));
- source_image->readPixels(expected_bitmap.pixmap(), 0, 0);
-
- ColorCorrectionTestUtils::CompareColorCorrectedPixels(
- converted_pixmap.addr(), expected_bitmap.pixmap().addr(), num_pixels,
- color_space->gammaIsLinear() ? kPixelFormat_hhhh : kPixelFormat_8888,
- kAlphaMultiplied, kUnpremulRoundTripTolerance);
- }
- }
-}
-
-TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionStaticBitmapImage) {
- SkPaint p;
- p.setColor(SK_ColorRED);
- sk_sp<SkColorSpace> colorspin =
- ColorCorrectionTestUtils::ColorSpinSkColorSpace();
-
- SkImageInfo image_info = SkImageInfo::MakeN32Premul(10, 10, colorspin);
- sk_sp<SkSurface> surface(SkSurface::MakeRaster(image_info));
- surface->getCanvas()->drawCircle(5, 5, 5, p);
- sk_sp<SkImage> source_image = surface->makeImageSnapshot();
- SkPixmap source_pixmap;
- source_image->peekPixels(&source_pixmap);
-
- base::Optional<IntRect> crop_rect =
- IntRect(0, 0, source_image->width(), source_image->height());
-
- for (int conversion_iterator = kColorSpaceConversion_Default;
- conversion_iterator <= kColorSpaceConversion_Last;
- conversion_iterator++) {
- ImageBitmapOptions* options = ImageBitmapOptions::Create();
- options->setColorSpaceConversion(
- ColorCorrectionTestUtils::ColorSpaceConversionToString(
- static_cast<ColorSpaceConversion>(conversion_iterator)));
- auto* image_bitmap = MakeGarbageCollected<ImageBitmap>(
- UnacceleratedStaticBitmapImage::Create(source_image), crop_rect,
- options);
- ASSERT_TRUE(image_bitmap);
- sk_sp<SkImage> converted_image =
- image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage();
- SkPixmap converted_pixmap;
- converted_image->peekPixels(&converted_pixmap);
- unsigned num_pixels = source_image->width() * source_image->height();
-
- if (conversion_iterator == kColorSpaceConversion_Preserve) {
- EXPECT_TRUE(
- SkColorSpace::Equals(colorspin.get(), converted_image->colorSpace()));
- ColorCorrectionTestUtils::CompareColorCorrectedPixels(
- converted_pixmap.addr(), source_pixmap.addr(), num_pixels,
- kPixelFormat_8888, kAlphaMultiplied, kUnpremulRoundTripTolerance);
- } else {
- sk_sp<SkColorSpace> color_space =
- ColorCorrectionTestUtils::ColorSpaceConversionToSkColorSpace(
- static_cast<ColorSpaceConversion>(conversion_iterator));
- EXPECT_TRUE(SkColorSpace::Equals(color_space.get(),
- converted_image->colorSpace()));
-
- SkImageInfo expected_image_info =
- source_pixmap.info().makeColorSpace(color_space);
- if (color_space->gammaIsLinear()) {
- expected_image_info =
- expected_image_info.makeColorType(kRGBA_F16_SkColorType);
- }
- SkBitmap expected_bitmap;
- EXPECT_TRUE(expected_bitmap.tryAllocPixels(expected_image_info));
- source_image->readPixels(expected_bitmap.pixmap(), 0, 0);
-
- ColorCorrectionTestUtils::CompareColorCorrectedPixels(
- converted_pixmap.addr(), expected_bitmap.pixmap().addr(), num_pixels,
- color_space->gammaIsLinear() ? kPixelFormat_hhhh : kPixelFormat_8888,
- kAlphaMultiplied, kUnpremulRoundTripTolerance);
- }
- }
-}
-
-TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageData) {
- unsigned char data_buffer[4] = {32, 96, 160, 128};
- NotShared<DOMUint8ClampedArray> data(
- DOMUint8ClampedArray::Create(data_buffer, 4));
- ImageDataColorSettings* color_settings = ImageDataColorSettings::Create();
- ImageData* image_data =
- ImageData::Create(IntSize(1, 1), data, color_settings);
-
- SkImageInfo image_info =
- SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kUnpremul_SkAlphaType,
- SkColorSpace::MakeSRGB());
- SkBitmap source_bitmap;
- EXPECT_TRUE(source_bitmap.tryAllocPixels(image_info));
- SkPixmap source_pixmap;
- source_pixmap = source_bitmap.pixmap();
- memcpy(source_pixmap.writable_addr(), image_data->BufferBase()->Data(), 4);
-
- base::Optional<IntRect> crop_rect = IntRect(0, 0, 1, 1);
-
- for (int conversion_iterator = kColorSpaceConversion_Default;
- conversion_iterator <= kColorSpaceConversion_Last;
- conversion_iterator++) {
- ImageBitmapOptions* options = ImageBitmapOptions::Create();
- options->setColorSpaceConversion(
- ColorCorrectionTestUtils::ColorSpaceConversionToString(
- static_cast<ColorSpaceConversion>(conversion_iterator)));
- auto* image_bitmap =
- MakeGarbageCollected<ImageBitmap>(image_data, crop_rect, options);
- ASSERT_TRUE(image_bitmap);
- sk_sp<SkImage> converted_image =
- image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage();
- SkPixmap converted_pixmap;
- converted_image->peekPixels(&converted_pixmap);
- unsigned num_pixels = converted_image->width() * converted_image->height();
-
- if (conversion_iterator == kColorSpaceConversion_Preserve) {
- // crbug.com/886999
- // EXPECT_TRUE(SkColorSpace::Equals(SkColorSpace::MakeSRGB().get(),
- // converted_image->colorSpace()));
- SkBitmap expected_bitmap;
- EXPECT_TRUE(expected_bitmap.tryAllocPixels(converted_pixmap.info()));
- source_pixmap.readPixels(expected_bitmap.pixmap(), 0, 0);
-
- ColorCorrectionTestUtils::CompareColorCorrectedPixels(
- converted_pixmap.addr(), expected_bitmap.pixmap().addr(), num_pixels,
- kPixelFormat_8888, kAlphaMultiplied, kUnpremulRoundTripTolerance);
- } else {
- sk_sp<SkColorSpace> color_space =
- ColorCorrectionTestUtils::ColorSpaceConversionToSkColorSpace(
- static_cast<ColorSpaceConversion>(conversion_iterator));
- // crbug.com/886999
- // EXPECT_TRUE(SkColorSpace::Equals(color_space.get(),
- // converted_image->colorSpace()));
- SkBitmap expected_bitmap;
- EXPECT_TRUE(expected_bitmap.tryAllocPixels(converted_pixmap.info()));
- source_pixmap.readPixels(expected_bitmap.pixmap(), 0, 0);
-
- ColorCorrectionTestUtils::CompareColorCorrectedPixels(
- converted_pixmap.addr(), expected_bitmap.pixmap().addr(), num_pixels,
- color_space->gammaIsLinear() ? kPixelFormat_hhhh : kPixelFormat_8888,
- kAlphaMultiplied, kUnpremulRoundTripTolerance);
- }
- }
-}
-
TEST_F(ImageBitmapTest, ImageBitmapPixelFormat) {
SkImageInfo info = SkImageInfo::MakeS32(10, 10, kPremul_SkAlphaType);
sk_sp<SkSurface> surface(SkSurface::MakeRaster(info));
@@ -611,8 +339,8 @@ TEST_F(ImageBitmapTest, ImageBitmapPixelFormat) {
// internal SkImage back storage.
ASSERT_EQ(sk_image_internal, sk_image_internal_8888);
- sk_sp<SkColorSpace> p3_color_space =
- SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, SkNamedGamut::kDCIP3);
+ sk_sp<SkColorSpace> p3_color_space = SkColorSpace::MakeRGB(
+ SkNamedTransferFn::kLinear, SkNamedGamut::kDisplayP3);
SkImageInfo info_f16 = SkImageInfo::Make(10, 10, kRGBA_F16_SkColorType,
kPremul_SkAlphaType, p3_color_space);
sk_sp<SkSurface> surface_f16(SkSurface::MakeRaster(info_f16));
@@ -643,7 +371,8 @@ TEST_F(ImageBitmapTest, ImageBitmapPixelFormat) {
// This test is failing on asan-clang-phone because memory allocation is
// declined. See <http://crbug.com/782286>.
-#if defined(OS_ANDROID)
+// See <http://crbug.com/1090252>, test is flaky in fuchsia.
+#if defined(OS_ANDROID) || defined(OS_FUCHSIA)
#define MAYBE_CreateImageBitmapFromTooBigImageDataDoesNotCrash \
DISABLED_CreateImageBitmapFromTooBigImageDataDoesNotCrash
#else
@@ -659,9 +388,7 @@ TEST_F(ImageBitmapTest,
ImageData::CreateForTest(IntSize(v8::TypedArray::kMaxLength / 16, 1));
DCHECK(image_data);
ImageBitmapOptions* options = ImageBitmapOptions::Create();
- options->setColorSpaceConversion(
- ColorCorrectionTestUtils::ColorSpaceConversionToString(
- kColorSpaceConversion_Default));
+ options->setColorSpaceConversion("default");
auto* image_bitmap = MakeGarbageCollected<ImageBitmap>(
image_data, IntRect(IntPoint(0, 0), image_data->Size()), options);
DCHECK(image_bitmap);
diff --git a/chromium/third_party/blink/renderer/core/input/BUILD.gn b/chromium/third_party/blink/renderer/core/input/BUILD.gn
index 72733c9db2a..d489e89adfd 100644
--- a/chromium/third_party/blink/renderer/core/input/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/input/BUILD.gn
@@ -38,7 +38,7 @@ blink_core_sources("input") {
"touch_list.h",
]
- public_deps = [ "//ui/base/cursor" ]
+ public_deps = [ "//ui/base/cursor:cursor_base" ]
deps = [
"//skia",
diff --git a/chromium/third_party/blink/renderer/core/input/event_handler.cc b/chromium/third_party/blink/renderer/core/input/event_handler.cc
index 0ef3d79c15d..c22b03bac57 100644
--- a/chromium/third_party/blink/renderer/core/input/event_handler.cc
+++ b/chromium/third_party/blink/renderer/core/input/event_handler.cc
@@ -245,7 +245,7 @@ EventHandler::EventHandler(LocalFrame& frame)
this,
&EventHandler::ActiveIntervalTimerFired) {}
-void EventHandler::Trace(Visitor* visitor) {
+void EventHandler::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(selection_controller_);
visitor->Trace(capturing_mouse_events_element_);
@@ -597,7 +597,7 @@ base::Optional<ui::Cursor> EventHandler::SelectCursor(
IntRect visible_rect = page->GetVisualViewport().VisibleContentRect();
if (!visible_rect.Contains(cursor_rect)) {
Deprecation::CountDeprecation(
- &node->GetDocument(),
+ node->GetExecutionContext(),
WebFeature::kCustomCursorIntersectsViewport);
continue;
}
@@ -843,10 +843,8 @@ WebInputEventResult EventHandler::HandleMousePressEvent(
frame_, HitTestLocation(document_point),
HitTestRequest::kReadOnly | HitTestRequest::kRetargetForInert);
InputDeviceCapabilities* source_capabilities =
- frame_->GetDocument()
- ->domWindow()
- ->GetInputDeviceCapabilities()
- ->FiresTouchEvents(mouse_event.FromTouch());
+ frame_->DomWindow()->GetInputDeviceCapabilities()->FiresTouchEvents(
+ mouse_event.FromTouch());
if (event_result == WebInputEventResult::kNotHandled) {
event_result = mouse_event_manager_->HandleMouseFocus(hit_test_result,
@@ -1346,13 +1344,8 @@ void EventHandler::MarkHoverStateDirty() {
Element* EventHandler::EffectiveMouseEventTargetElement(
Element* target_element) {
Element* new_element_under_mouse = target_element;
- if (RuntimeEnabledFeatures::UnifiedPointerCaptureInBlinkEnabled()) {
- if (pointer_event_manager_->GetMouseCaptureTarget())
- new_element_under_mouse = pointer_event_manager_->GetMouseCaptureTarget();
- } else {
- if (capturing_mouse_events_element_)
- new_element_under_mouse = capturing_mouse_events_element_.Get();
- }
+ if (pointer_event_manager_->GetMouseCaptureTarget())
+ new_element_under_mouse = pointer_event_manager_->GetMouseCaptureTarget();
return new_element_under_mouse;
}
@@ -1621,8 +1614,6 @@ void EventHandler::CacheTouchAdjustmentResult(uint32_t id,
bool EventHandler::GestureCorrespondsToAdjustedTouch(
const WebGestureEvent& event) {
- if (!RuntimeEnabledFeatures::UnifiedTouchAdjustmentEnabled())
- return false;
// Gesture events start with a GestureTapDown. If GestureTapDown's unique id
// matches stored adjusted touchstart event id, then we can use the stored
// result for following gesture event.
@@ -2423,8 +2414,7 @@ MouseEventWithHitTestResults EventHandler::GetMouseEventTarget(
frame_, FloatPoint(event.PositionInRootFrame()));
// TODO(eirage): This does not handle chorded buttons yet.
- if (RuntimeEnabledFeatures::UnifiedPointerCaptureInBlinkEnabled() &&
- event.GetType() != WebInputEvent::Type::kMouseDown) {
+ if (event.GetType() != WebInputEvent::Type::kMouseDown) {
HitTestResult result(request, HitTestLocation(document_point));
Element* capture_target;
@@ -2462,11 +2452,9 @@ MouseEventWithHitTestResults EventHandler::GetMouseEventTarget(
void EventHandler::ReleaseMouseCaptureFromLocalRoot() {
CaptureMouseEventsToWidget(false);
- if (RuntimeEnabledFeatures::UnifiedPointerCaptureInBlinkEnabled()) {
- frame_->LocalFrameRoot()
- .GetEventHandler()
- .ReleaseMouseCaptureFromCurrentFrame();
- }
+ frame_->LocalFrameRoot()
+ .GetEventHandler()
+ .ReleaseMouseCaptureFromCurrentFrame();
}
void EventHandler::ReleaseMouseCaptureFromCurrentFrame() {
diff --git a/chromium/third_party/blink/renderer/core/input/event_handler.h b/chromium/third_party/blink/renderer/core/input/event_handler.h
index 42d4cd476e6..bbf6f3b2d98 100644
--- a/chromium/third_party/blink/renderer/core/input/event_handler.h
+++ b/chromium/third_party/blink/renderer/core/input/event_handler.h
@@ -80,7 +80,7 @@ class WebMouseWheelEvent;
class CORE_EXPORT EventHandler final : public GarbageCollected<EventHandler> {
public:
explicit EventHandler(LocalFrame&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void Clear();
diff --git a/chromium/third_party/blink/renderer/core/input/event_handler_test.cc b/chromium/third_party/blink/renderer/core/input/event_handler_test.cc
index 84ebb36b142..2ea3f66226f 100644
--- a/chromium/third_party/blink/renderer/core/input/event_handler_test.cc
+++ b/chromium/third_party/blink/renderer/core/input/event_handler_test.cc
@@ -1191,7 +1191,7 @@ TEST_F(EventHandlerSimTest, MouseUpOffScrollbarGeneratesScrollEnd) {
)HTML");
Compositor().BeginFrame();
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 0u);
// PageTestBase sizes the page to 800x600. Click on the scrollbar
// track, move off, then release the mouse and verify that GestureScrollEnd
@@ -1213,13 +1213,13 @@ TEST_F(EventHandlerSimTest, MouseUpOffScrollbarGeneratesScrollEnd) {
// Mouse down on the scrollbar track should have generated GSB/GSU.
if (scrollbar_theme_allows_hit_test) {
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 2u);
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData()[0].type,
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 2u);
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents()[0]->Event().GetType(),
WebInputEvent::Type::kGestureScrollBegin);
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData()[1].type,
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents()[1]->Event().GetType(),
WebInputEvent::Type::kGestureScrollUpdate);
} else {
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 0u);
}
const gfx::PointF middle_of_page(100, 100);
@@ -1233,9 +1233,9 @@ TEST_F(EventHandlerSimTest, MouseUpOffScrollbarGeneratesScrollEnd) {
// Mouse move should not have generated any gestures.
if (scrollbar_theme_allows_hit_test) {
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 2u);
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 2u);
} else {
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 0u);
}
WebMouseEvent mouse_up(WebInputEvent::Type::kMouseUp, middle_of_page,
@@ -1246,11 +1246,11 @@ TEST_F(EventHandlerSimTest, MouseUpOffScrollbarGeneratesScrollEnd) {
// Mouse up must generate GestureScrollEnd.
if (scrollbar_theme_allows_hit_test) {
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 3u);
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData()[2].type,
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 3u);
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents()[2]->Event().GetType(),
WebInputEvent::Type::kGestureScrollEnd);
} else {
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 0u);
}
}
@@ -1266,7 +1266,7 @@ TEST_F(EventHandlerSimTest, MouseUpOnlyOnScrollbar) {
Compositor().BeginFrame();
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 0u);
// Mouse down on the page, the move the mouse to the scrollbar and release.
// Validate that we don't inject a ScrollEnd (since no ScrollBegin was
@@ -1281,7 +1281,7 @@ TEST_F(EventHandlerSimTest, MouseUpOnlyOnScrollbar) {
GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(mouse_down);
// Mouse down on the page should not generate scroll gestures.
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 0u);
const gfx::PointF scrollbar_forward_track(795, 560);
WebMouseEvent mouse_move(WebInputEvent::Type::kMouseMove,
@@ -1293,7 +1293,7 @@ TEST_F(EventHandlerSimTest, MouseUpOnlyOnScrollbar) {
mouse_move, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
// Mouse move should not have generated any gestures.
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 0u);
WebMouseEvent mouse_up(WebInputEvent::Type::kMouseUp, scrollbar_forward_track,
scrollbar_forward_track,
@@ -1303,7 +1303,7 @@ TEST_F(EventHandlerSimTest, MouseUpOnlyOnScrollbar) {
GetDocument().GetFrame()->GetEventHandler().HandleMouseReleaseEvent(mouse_up);
// Mouse up should not have generated any gestures.
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 0u);
}
TEST_F(EventHandlerSimTest, RightClickNoGestures) {
@@ -1318,7 +1318,7 @@ TEST_F(EventHandlerSimTest, RightClickNoGestures) {
Compositor().BeginFrame();
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 0u);
// PageTestBase sizes the page to 800x600. Right click on the scrollbar
// track, and release the mouse and verify that no gesture events are
@@ -1332,7 +1332,7 @@ TEST_F(EventHandlerSimTest, RightClickNoGestures) {
mouse_down.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(mouse_down);
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 0u);
WebMouseEvent mouse_up(WebInputEvent::Type::kMouseUp, scrollbar_forward_track,
scrollbar_forward_track,
@@ -1341,7 +1341,7 @@ TEST_F(EventHandlerSimTest, RightClickNoGestures) {
mouse_up.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMouseReleaseEvent(mouse_up);
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 0u);
}
// https://crbug.com/976557 tracks the fix for re-enabling this test on Mac.
@@ -1391,7 +1391,7 @@ TEST_F(EventHandlerSimTest, MAYBE_GestureTapWithScrollSnaps) {
Compositor().BeginFrame();
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 0u);
// Only run this test if scrollbars are hit-testable (they are not on
// Android).
@@ -1408,42 +1408,24 @@ TEST_F(EventHandlerSimTest, MAYBE_GestureTapWithScrollSnaps) {
TapEventBuilder tap(scrollbar_forward_track, 1);
GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(tap);
- EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 3u);
-
- const Vector<frame_test_helpers::InjectedScrollGestureData>& data =
- WebWidgetClient().GetInjectedScrollGestureData();
- const frame_test_helpers::InjectedScrollGestureData gsb_data = data[0];
- const frame_test_helpers::InjectedScrollGestureData gsu_data = data[1];
- const frame_test_helpers::InjectedScrollGestureData gse_data = data[2];
- EXPECT_EQ(gsb_data.type, WebInputEvent::Type::kGestureScrollBegin);
- EXPECT_EQ(gsu_data.type, WebInputEvent::Type::kGestureScrollUpdate);
- EXPECT_EQ(gse_data.type, WebInputEvent::Type::kGestureScrollEnd);
-
- // Inject the gesture sequence based on the injected data.
- WebGestureEvent gsb{WebInputEvent::Type::kGestureScrollBegin,
- WebInputEvent::kNoModifiers,
- WebInputEvent::GetStaticTimeStampForTests()};
- gsb.SetFrameScale(1);
- gsb.SetSourceDevice(WebGestureDevice::kScrollbar);
- gsb.data.scroll_begin.delta_x_hint = -gsb_data.delta.x();
- gsb.data.scroll_begin.delta_y_hint = -gsb_data.delta.y();
- gsb.data.scroll_begin.scrollable_area_element_id =
- gsb_data.scrollable_area_element_id.GetStableId();
+ EXPECT_EQ(WebWidgetClient().GetInjectedScrollEvents().size(), 3u);
+
+ const Vector<std::unique_ptr<blink::WebCoalescedInputEvent>>& data =
+ WebWidgetClient().GetInjectedScrollEvents();
+ EXPECT_EQ(data[0]->Event().GetType(),
+ WebInputEvent::Type::kGestureScrollBegin);
+ EXPECT_EQ(data[1]->Event().GetType(),
+ WebInputEvent::Type::kGestureScrollUpdate);
+ EXPECT_EQ(data[2]->Event().GetType(), WebInputEvent::Type::kGestureScrollEnd);
+ const WebGestureEvent& gsb =
+ static_cast<const WebGestureEvent&>(data[0]->Event());
+ const WebGestureEvent& gsu =
+ static_cast<const WebGestureEvent&>(data[1]->Event());
+ const WebGestureEvent& gse =
+ static_cast<const WebGestureEvent&>(data[2]->Event());
+
GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(gsb);
- WebGestureEvent gsu{WebInputEvent::Type::kGestureScrollUpdate,
- WebInputEvent::kNoModifiers,
- WebInputEvent::GetStaticTimeStampForTests()};
- gsu.SetSourceDevice(WebGestureDevice::kScrollbar);
- gsu.SetFrameScale(1);
- gsu.data.scroll_update.delta_x = -gsu_data.delta.x();
- gsu.data.scroll_update.delta_y = -gsu_data.delta.y();
- gsu.data.scroll_update.delta_units = gsu_data.granularity;
GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(gsu);
- WebGestureEvent gse{WebInputEvent::Type::kGestureScrollEnd,
- WebInputEvent::kNoModifiers,
- WebInputEvent::GetStaticTimeStampForTests()};
- gse.SetSourceDevice(WebGestureDevice::kScrollbar);
- gse.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(gse);
// Ensure that there is an active animation on the scrollable area event
diff --git a/chromium/third_party/blink/renderer/core/input/event_handling_util.cc b/chromium/third_party/blink/renderer/core/input/event_handling_util.cc
index 0e8fe61b1b0..0cf92a19d6c 100644
--- a/chromium/third_party/blink/renderer/core/input/event_handling_util.cc
+++ b/chromium/third_party/blink/renderer/core/input/event_handling_util.cc
@@ -187,12 +187,6 @@ LocalFrame* GetTargetSubframe(
const MouseEventWithHitTestResults& hit_test_result,
Node* capturing_node,
bool* is_remote_frame) {
- if (!RuntimeEnabledFeatures::UnifiedPointerCaptureInBlinkEnabled() &&
- capturing_node) {
- return event_handling_util::SubframeForTargetNode(capturing_node,
- is_remote_frame);
- }
-
if (!hit_test_result.IsOverEmbeddedContentView())
return nullptr;
diff --git a/chromium/third_party/blink/renderer/core/input/event_handling_util.h b/chromium/third_party/blink/renderer/core/input/event_handling_util.h
index b3c987f0c6e..aec6a7e2fc9 100644
--- a/chromium/third_party/blink/renderer/core/input/event_handling_util.h
+++ b/chromium/third_party/blink/renderer/core/input/event_handling_util.h
@@ -66,7 +66,7 @@ class PointerEventTarget {
DISALLOW_NEW();
public:
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(target_element);
visitor->Trace(target_frame);
}
diff --git a/chromium/third_party/blink/renderer/core/input/gesture_manager.cc b/chromium/third_party/blink/renderer/core/input/gesture_manager.cc
index e07a04bad9e..03cfd6c8231 100644
--- a/chromium/third_party/blink/renderer/core/input/gesture_manager.cc
+++ b/chromium/third_party/blink/renderer/core/input/gesture_manager.cc
@@ -55,7 +55,7 @@ void GestureManager::Clear() {
long_tap_should_invoke_context_menu_ = false;
}
-void GestureManager::Trace(Visitor* visitor) {
+void GestureManager::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(scroll_manager_);
visitor->Trace(mouse_event_manager_);
@@ -237,10 +237,9 @@ WebInputEventResult GestureManager::HandleGestureTap(
selection_controller_->InitializeSelectionState();
if (mouse_down_event_result == WebInputEventResult::kNotHandled) {
mouse_down_event_result = mouse_event_manager_->HandleMouseFocus(
- current_hit_test, frame_->GetDocument()
- ->domWindow()
- ->GetInputDeviceCapabilities()
- ->FiresTouchEvents(true));
+ current_hit_test,
+ frame_->DomWindow()->GetInputDeviceCapabilities()->FiresTouchEvents(
+ true));
}
if (mouse_down_event_result == WebInputEventResult::kNotHandled) {
mouse_down_event_result = mouse_event_manager_->HandleMousePressEvent(
diff --git a/chromium/third_party/blink/renderer/core/input/gesture_manager.h b/chromium/third_party/blink/renderer/core/input/gesture_manager.h
index 0d5980cf2c5..0862b3a008e 100644
--- a/chromium/third_party/blink/renderer/core/input/gesture_manager.h
+++ b/chromium/third_party/blink/renderer/core/input/gesture_manager.h
@@ -30,7 +30,7 @@ class CORE_EXPORT GestureManager final
MouseEventManager&,
PointerEventManager&,
SelectionController&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void Clear();
diff --git a/chromium/third_party/blink/renderer/core/input/ime_on_focus_test.cc b/chromium/third_party/blink/renderer/core/input/ime_on_focus_test.cc
index 7f1b17bd74f..8881f08d2f1 100644
--- a/chromium/third_party/blink/renderer/core/input/ime_on_focus_test.cc
+++ b/chromium/third_party/blink/renderer/core/input/ime_on_focus_test.cc
@@ -14,6 +14,7 @@
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
+#include "ui/base/ime/mojom/text_input_state.mojom-blink.h"
using blink::frame_test_helpers::LoadFrame;
using blink::test::RunPendingTasks;
@@ -27,8 +28,10 @@ class ImeRequestTrackingWebWidgetClient
ImeRequestTrackingWebWidgetClient() : virtual_keyboard_request_count_(0) {}
// WebWidgetClient methods
- void ShowVirtualKeyboardOnElementFocus() override {
- ++virtual_keyboard_request_count_;
+ void TextInputStateChanged(
+ ui::mojom::blink::TextInputStatePtr state) override {
+ if (state->show_ime_if_needed)
+ ++virtual_keyboard_request_count_;
}
// Local methds
@@ -118,8 +121,15 @@ void ImeOnFocusTest::RunImeOnFocusTest(
if (!focus_element.IsNull())
Focus(focus_element);
- EXPECT_EQ(expected_virtual_keyboard_request_count,
- client.VirtualKeyboardRequestCount());
+ RunPendingTasks();
+ if (expected_virtual_keyboard_request_count == 0) {
+ EXPECT_EQ(0, client.VirtualKeyboardRequestCount());
+ } else {
+ // Some builds (Aura, android) request the virtual keyboard on
+ // gesture tap.
+ EXPECT_LE(expected_virtual_keyboard_request_count,
+ client.VirtualKeyboardRequestCount());
+ }
web_view_helper_.Reset();
}
diff --git a/chromium/third_party/blink/renderer/core/input/input_device_capabilities.h b/chromium/third_party/blink/renderer/core/input/input_device_capabilities.h
index 922d56b2008..951ca624543 100644
--- a/chromium/third_party/blink/renderer/core/input/input_device_capabilities.h
+++ b/chromium/third_party/blink/renderer/core/input/input_device_capabilities.h
@@ -51,7 +51,7 @@ class InputDeviceCapabilitiesConstants final
// |firesTouchEvents| set to value of |firesTouch|.
InputDeviceCapabilities* FiresTouchEvents(bool fires_touch);
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(fires_touch_events_);
visitor->Trace(doesnt_fire_touch_events_);
}
diff --git a/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.cc b/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.cc
index 67f5c368ab5..060e68d7df7 100644
--- a/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.cc
+++ b/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.cc
@@ -147,7 +147,7 @@ KeyboardEventManager::KeyboardEventManager(LocalFrame& frame,
ScrollManager& scroll_manager)
: frame_(frame), scroll_manager_(scroll_manager) {}
-void KeyboardEventManager::Trace(Visitor* visitor) {
+void KeyboardEventManager::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(scroll_manager_);
}
diff --git a/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.h b/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.h
index 7ffe289af7c..c6f39b3fc56 100644
--- a/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.h
+++ b/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.h
@@ -35,7 +35,7 @@ class CORE_EXPORT KeyboardEventManager final
#endif
KeyboardEventManager(LocalFrame&, ScrollManager&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
bool HandleAccessKey(const WebKeyboardEvent&);
WebInputEventResult KeyEvent(const WebKeyboardEvent&);
diff --git a/chromium/third_party/blink/renderer/core/input/mouse_event_manager.cc b/chromium/third_party/blink/renderer/core/input/mouse_event_manager.cc
index 33b4179ed74..bd80336590c 100644
--- a/chromium/third_party/blink/renderer/core/input/mouse_event_manager.cc
+++ b/chromium/third_party/blink/renderer/core/input/mouse_event_manager.cc
@@ -187,7 +187,7 @@ void MouseEventManager::Clear() {
MouseEventManager::~MouseEventManager() = default;
-void MouseEventManager::Trace(Visitor* visitor) {
+void MouseEventManager::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(scroll_manager_);
visitor->Trace(element_under_mouse_);
@@ -700,7 +700,7 @@ WebInputEventResult MouseEventManager::HandleMousePressEvent(
mouse_down_ = event.Event();
if (RuntimeEnabledFeatures::TextFragmentIdentifiersEnabled(
- frame_->GetDocument())) {
+ frame_->DomWindow())) {
if (frame_->View())
frame_->View()->DismissFragmentAnchor();
}
diff --git a/chromium/third_party/blink/renderer/core/input/mouse_event_manager.h b/chromium/third_party/blink/renderer/core/input/mouse_event_manager.h
index b237c0660b9..1caede75f48 100644
--- a/chromium/third_party/blink/renderer/core/input/mouse_event_manager.h
+++ b/chromium/third_party/blink/renderer/core/input/mouse_event_manager.h
@@ -39,7 +39,7 @@ class CORE_EXPORT MouseEventManager final
public:
MouseEventManager(LocalFrame&, ScrollManager&);
virtual ~MouseEventManager();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
WebInputEventResult DispatchMouseEvent(EventTarget*,
const AtomicString&,
diff --git a/chromium/third_party/blink/renderer/core/input/mouse_wheel_event_manager.cc b/chromium/third_party/blink/renderer/core/input/mouse_wheel_event_manager.cc
index 8b5976c1893..3f55af52b6a 100644
--- a/chromium/third_party/blink/renderer/core/input/mouse_wheel_event_manager.cc
+++ b/chromium/third_party/blink/renderer/core/input/mouse_wheel_event_manager.cc
@@ -15,6 +15,8 @@
#include "third_party/blink/renderer/core/layout/hit_test_request.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/page/page.h"
+#include "third_party/blink/renderer/core/page/pointer_lock_controller.h"
#include "third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h"
#include "third_party/blink/renderer/core/page/scrolling/scroll_state.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
@@ -43,7 +45,7 @@ MouseWheelEventManager::MouseWheelEventManager(LocalFrame& frame,
ScrollManager& scroll_manager)
: frame_(frame), wheel_target_(nullptr), scroll_manager_(scroll_manager) {}
-void MouseWheelEventManager::Trace(Visitor* visitor) {
+void MouseWheelEventManager::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(wheel_target_);
visitor->Trace(scroll_manager_);
@@ -85,12 +87,18 @@ WebInputEventResult MouseWheelEventManager::HandleWheelEvent(
bool has_phase_info = event.phase != WebMouseWheelEvent::kPhaseNone ||
event.momentum_phase != WebMouseWheelEvent::kPhaseNone;
- // Find and save the wheel_target_, this target will be used for the rest
- // of the current scrolling sequence. In the absence of phase info, send the
- // event to the target under the cursor.
- if (event.phase == WebMouseWheelEvent::kPhaseBegan || !wheel_target_ ||
- !has_phase_info) {
- wheel_target_ = FindTargetNode(event, doc, view);
+ Element* pointer_locked_element =
+ PointerLockController::GetPointerLockedElement(frame_);
+ if (pointer_locked_element) {
+ wheel_target_ = pointer_locked_element;
+ } else {
+ // Find and save the wheel_target_, this target will be used for the rest
+ // of the current scrolling sequence. In the absence of phase info, send the
+ // event to the target under the cursor.
+ if (event.phase == WebMouseWheelEvent::kPhaseBegan || !wheel_target_ ||
+ !has_phase_info) {
+ wheel_target_ = FindTargetNode(event, doc, view);
+ }
}
LocalFrame* subframe =
diff --git a/chromium/third_party/blink/renderer/core/input/mouse_wheel_event_manager.h b/chromium/third_party/blink/renderer/core/input/mouse_wheel_event_manager.h
index 57b361ca4b4..1156ec8345a 100644
--- a/chromium/third_party/blink/renderer/core/input/mouse_wheel_event_manager.h
+++ b/chromium/third_party/blink/renderer/core/input/mouse_wheel_event_manager.h
@@ -23,7 +23,7 @@ class MouseWheelEventManager final
: public GarbageCollected<MouseWheelEventManager> {
public:
explicit MouseWheelEventManager(LocalFrame&, ScrollManager&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void Clear();
diff --git a/chromium/third_party/blink/renderer/core/input/pointer_event_manager.cc b/chromium/third_party/blink/renderer/core/input/pointer_event_manager.cc
index 6c62af01ad2..99b37de3d6a 100644
--- a/chromium/third_party/blink/renderer/core/input/pointer_event_manager.cc
+++ b/chromium/third_party/blink/renderer/core/input/pointer_event_manager.cc
@@ -61,14 +61,6 @@ const AtomicString& MouseEventNameForPointerEventInputType(
}
}
-Element* GetPointerLockedElement(LocalFrame* frame) {
- if (Page* p = frame->GetPage()) {
- if (!p->GetPointerLockController().LockPending())
- return p->GetPointerLockController().GetElement();
- }
- return nullptr;
-}
-
} // namespace
PointerEventManager::PointerEventManager(LocalFrame& frame,
@@ -104,7 +96,7 @@ void PointerEventManager::Clear() {
dispatching_pointer_id_ = 0;
}
-void PointerEventManager::Trace(Visitor* visitor) {
+void PointerEventManager::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(element_under_pointer_);
visitor->Trace(pointer_capture_target_);
@@ -342,8 +334,7 @@ bool PointerEventManager::ShouldAdjustPointerEvent(
!frame_->GetSettings()->GetTouchAdjustmentEnabled())
return false;
- return RuntimeEnabledFeatures::UnifiedTouchAdjustmentEnabled() &&
- pointer_event.pointer_type ==
+ return pointer_event.pointer_type ==
WebPointerProperties::PointerType::kTouch &&
pointer_event.GetType() == WebInputEvent::Type::kPointerDown &&
pointer_event_factory_.IsPrimary(pointer_event);
@@ -550,7 +541,8 @@ WebInputEventResult PointerEventManager::HandlePointerEvent(
// not quite possible as we haven't merged the locked event
// dispatch with this path.
Node* target;
- Element* pointer_locked_element = GetPointerLockedElement(frame_);
+ Element* pointer_locked_element =
+ PointerLockController::GetPointerLockedElement(frame_);
if (pointer_locked_element &&
event.pointer_type == WebPointerProperties::PointerType::kMouse) {
// The locked element could be in another frame. So we need to delegate
@@ -851,17 +843,15 @@ WebInputEventResult PointerEventManager::SendMousePointerEvent(
// If pointerup releases the capture we also send boundary events
// rightaway when the pointer that supports hover. Perform a hit
// test to find the new target.
- if (RuntimeEnabledFeatures::UnifiedPointerCaptureInBlinkEnabled()) {
- if (pointer_capture_target_.find(pointer_event->pointerId()) !=
- pointer_capture_target_.end()) {
- HitTestRequest::HitTestRequestType hit_type =
- HitTestRequest::kRelease | HitTestRequest::kRetargetForInert;
- HitTestRequest request(hit_type);
- MouseEventWithHitTestResults mev =
- event_handling_util::PerformMouseEventHitTest(frame_, request,
- mouse_event);
- target = mev.InnerElement();
- }
+ if (pointer_capture_target_.find(pointer_event->pointerId()) !=
+ pointer_capture_target_.end()) {
+ HitTestRequest::HitTestRequestType hit_type =
+ HitTestRequest::kRelease | HitTestRequest::kRetargetForInert;
+ HitTestRequest request(hit_type);
+ MouseEventWithHitTestResults mev =
+ event_handling_util::PerformMouseEventHitTest(frame_, request,
+ mouse_event);
+ target = mev.InnerElement();
}
ProcessCaptureAndPositionOfPointerEvent(pointer_event, target,
canvas_region_id, &mouse_event);
diff --git a/chromium/third_party/blink/renderer/core/input/pointer_event_manager.h b/chromium/third_party/blink/renderer/core/input/pointer_event_manager.h
index 95816c902f1..39a4fa157bc 100644
--- a/chromium/third_party/blink/renderer/core/input/pointer_event_manager.h
+++ b/chromium/third_party/blink/renderer/core/input/pointer_event_manager.h
@@ -28,7 +28,7 @@ class CORE_EXPORT PointerEventManager final
: public GarbageCollected<PointerEventManager> {
public:
PointerEventManager(LocalFrame&, MouseEventManager&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// This is the unified path for handling all input device events. This may
// cause firing DOM pointerevents, mouseevent, and touch events accordingly.
@@ -112,7 +112,7 @@ class CORE_EXPORT PointerEventManager final
DISALLOW_NEW();
public:
- void Trace(Visitor* visitor) { visitor->Trace(target); }
+ void Trace(Visitor* visitor) const { visitor->Trace(target); }
Member<Element> target;
EventTargetAttributes() : target(nullptr) {}
EventTargetAttributes(Element* target) : target(target) {}
diff --git a/chromium/third_party/blink/renderer/core/input/scroll_manager.cc b/chromium/third_party/blink/renderer/core/input/scroll_manager.cc
index a862630dd4a..03664998f5d 100644
--- a/chromium/third_party/blink/renderer/core/input/scroll_manager.cc
+++ b/chromium/third_party/blink/renderer/core/input/scroll_manager.cc
@@ -78,7 +78,7 @@ void ScrollManager::Clear() {
ClearGestureScrollState();
}
-void ScrollManager::Trace(Visitor* visitor) {
+void ScrollManager::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(scroll_gesture_handling_node_);
visitor->Trace(previous_gesture_scrolled_node_);
@@ -445,6 +445,11 @@ void ScrollManager::RecordScrollRelatedMetrics(const WebGestureDevice device) {
WebInputEventResult ScrollManager::HandleGestureScrollBegin(
const WebGestureEvent& gesture_event) {
TRACE_EVENT0("input", "ScrollManager::handleGestureScrollBegin");
+ DCHECK(!RuntimeEnabledFeatures::ScrollUnificationEnabled());
+ if (RuntimeEnabledFeatures::ScrollUnificationEnabled()) {
+ return WebInputEventResult::kNotHandled;
+ }
+
Document* document = frame_->GetDocument();
if (!document->GetLayoutView())
@@ -538,6 +543,11 @@ WebInputEventResult ScrollManager::HandleGestureScrollUpdate(
TRACE_EVENT0("input", "ScrollManager::handleGestureScrollUpdate");
DCHECK_EQ(gesture_event.GetType(), WebInputEvent::Type::kGestureScrollUpdate);
+ DCHECK(!RuntimeEnabledFeatures::ScrollUnificationEnabled());
+ if (RuntimeEnabledFeatures::ScrollUnificationEnabled()) {
+ return WebInputEventResult::kNotHandled;
+ }
+
Node* node = scroll_gesture_handling_node_.Get();
if (!node || !node->GetLayoutObject()) {
TRACE_EVENT_INSTANT0("input", "Lost scroll_gesture_handling_node",
@@ -672,6 +682,12 @@ void ScrollManager::HandleDeferredGestureScrollEnd(
WebInputEventResult ScrollManager::HandleGestureScrollEnd(
const WebGestureEvent& gesture_event) {
TRACE_EVENT0("input", "ScrollManager::handleGestureScrollEnd");
+
+ DCHECK(!RuntimeEnabledFeatures::ScrollUnificationEnabled());
+ if (RuntimeEnabledFeatures::ScrollUnificationEnabled()) {
+ return WebInputEventResult::kNotHandled;
+ }
+
GetPage()->GetBrowserControls().ScrollEnd();
Node* node = scroll_gesture_handling_node_;
diff --git a/chromium/third_party/blink/renderer/core/input/scroll_manager.h b/chromium/third_party/blink/renderer/core/input/scroll_manager.h
index 12fd76d1222..5be484963ee 100644
--- a/chromium/third_party/blink/renderer/core/input/scroll_manager.h
+++ b/chromium/third_party/blink/renderer/core/input/scroll_manager.h
@@ -43,7 +43,7 @@ class CORE_EXPORT ScrollManager : public GarbageCollected<ScrollManager>,
public:
explicit ScrollManager(LocalFrame&);
virtual ~ScrollManager() = default;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void Clear();
diff --git a/chromium/third_party/blink/renderer/core/input/touch.cc b/chromium/third_party/blink/renderer/core/input/touch.cc
index 7213f1c835e..d590511cd92 100644
--- a/chromium/third_party/blink/renderer/core/input/touch.cc
+++ b/chromium/third_party/blink/renderer/core/input/touch.cc
@@ -117,7 +117,7 @@ Touch* Touch::CloneWithNewTarget(EventTarget* event_target) const {
rotation_angle_, force_, region_, absolute_location_);
}
-void Touch::Trace(Visitor* visitor) {
+void Touch::Trace(Visitor* visitor) const {
visitor->Trace(target_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/input/touch.h b/chromium/third_party/blink/renderer/core/input/touch.h
index 2673b89c6f2..2e768a89d1b 100644
--- a/chromium/third_party/blink/renderer/core/input/touch.h
+++ b/chromium/third_party/blink/renderer/core/input/touch.h
@@ -105,7 +105,7 @@ class CORE_EXPORT Touch final : public ScriptWrappable {
const FloatPoint& ScreenLocation() const { return screen_pos_; }
Touch* CloneWithNewTarget(EventTarget*) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<EventTarget> target_;
diff --git a/chromium/third_party/blink/renderer/core/input/touch_action_test.cc b/chromium/third_party/blink/renderer/core/input/touch_action_test.cc
index 7a766694ae2..adf81670d5a 100644
--- a/chromium/third_party/blink/renderer/core/input/touch_action_test.cc
+++ b/chromium/third_party/blink/renderer/core/input/touch_action_test.cc
@@ -390,9 +390,11 @@ void TouchActionTest::SendTouchEvent(WebView* web_view,
10.0f, 10.0f);
if (type == WebInputEvent::Type::kPointerCancel)
event.dispatch_type = WebInputEvent::DispatchType::kEventNonBlocking;
+ else
+ event.touch_start_or_first_touch_move = true;
- web_view->MainFrameWidget()->HandleInputEvent(
- WebCoalescedInputEvent(event, ui::LatencyInfo()));
+ web_view->MainFrameWidget()->ProcessInputEventSynchronously(
+ WebCoalescedInputEvent(event, ui::LatencyInfo()), base::DoNothing());
web_view->MainFrameWidget()->DispatchBufferedTouchEvents();
RunPendingTasks();
}
diff --git a/chromium/third_party/blink/renderer/core/input/touch_event_manager.cc b/chromium/third_party/blink/renderer/core/input/touch_event_manager.cc
index 8032b530bed..3965ed3f6e6 100644
--- a/chromium/third_party/blink/renderer/core/input/touch_event_manager.cc
+++ b/chromium/third_party/blink/renderer/core/input/touch_event_manager.cc
@@ -159,7 +159,7 @@ void TouchEventManager::Clear() {
current_touch_action_ = TouchAction::kAuto;
}
-void TouchEventManager::Trace(Visitor* visitor) {
+void TouchEventManager::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(touch_sequence_document_);
visitor->Trace(touch_attribute_map_);
diff --git a/chromium/third_party/blink/renderer/core/input/touch_event_manager.h b/chromium/third_party/blink/renderer/core/input/touch_event_manager.h
index 2d4a92c797e..26a1c2c53b3 100644
--- a/chromium/third_party/blink/renderer/core/input/touch_event_manager.h
+++ b/chromium/third_party/blink/renderer/core/input/touch_event_manager.h
@@ -31,7 +31,7 @@ class CORE_EXPORT TouchEventManager final
public:
explicit TouchEventManager(LocalFrame&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void HandleTouchPoint(const WebPointerEvent&,
const Vector<WebPointerEvent>&,
@@ -51,7 +51,7 @@ class CORE_EXPORT TouchEventManager final
class TouchPointAttributes final
: public GarbageCollected<TouchPointAttributes> {
public:
- void Trace(Visitor* visitor) { visitor->Trace(target_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(target_); }
TouchPointAttributes() = default;
explicit TouchPointAttributes(WebPointerEvent event)
diff --git a/chromium/third_party/blink/renderer/core/input/touch_list.cc b/chromium/third_party/blink/renderer/core/input/touch_list.cc
index 68b6002a8b5..153fdc151c9 100644
--- a/chromium/third_party/blink/renderer/core/input/touch_list.cc
+++ b/chromium/third_party/blink/renderer/core/input/touch_list.cc
@@ -37,7 +37,7 @@ const Touch* TouchList::item(unsigned index) const {
return const_cast<TouchList*>(this)->item(index);
}
-void TouchList::Trace(Visitor* visitor) {
+void TouchList::Trace(Visitor* visitor) const {
visitor->Trace(values_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/input/touch_list.h b/chromium/third_party/blink/renderer/core/input/touch_list.h
index 602c47f46ca..e7477421615 100644
--- a/chromium/third_party/blink/renderer/core/input/touch_list.h
+++ b/chromium/third_party/blink/renderer/core/input/touch_list.h
@@ -60,7 +60,7 @@ class CORE_EXPORT TouchList final : public ScriptWrappable {
void Append(Touch* touch) { values_.push_back(touch); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<Touch>> values_;
diff --git a/chromium/third_party/blink/renderer/core/inspector/BUILD.gn b/chromium/third_party/blink/renderer/core/inspector/BUILD.gn
index e8a912f1766..313029140b9 100644
--- a/chromium/third_party/blink/renderer/core/inspector/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/inspector/BUILD.gn
@@ -62,6 +62,8 @@ blink_core_sources("inspector") {
"inspector_io_agent.h",
"inspector_issue.cc",
"inspector_issue.h",
+ "inspector_issue_reporter.cc",
+ "inspector_issue_reporter.h",
"inspector_issue_storage.cc",
"inspector_issue_storage.h",
"inspector_layer_tree_agent.cc",
diff --git a/chromium/third_party/blink/renderer/core/inspector/DEPS b/chromium/third_party/blink/renderer/core/inspector/DEPS
index 56e80d50889..e9d24456e6a 100644
--- a/chromium/third_party/blink/renderer/core/inspector/DEPS
+++ b/chromium/third_party/blink/renderer/core/inspector/DEPS
@@ -5,7 +5,9 @@ include_rules = [
"+base/sampling_heap_profiler/poisson_allocation_sampler.h",
"+base/sampling_heap_profiler/sampling_heap_profiler.h",
# for base::GetUniqueIdForProcess
+ "+base/process/process.h",
"+base/process/process_handle.h",
+ "+base/process/process_metrics.h",
"+cc/trees/transform_node.h",
"+third_party/inspector_protocol/crdtp",
"+third_party/icu/source/common/unicode/locid.h",
diff --git a/chromium/third_party/blink/renderer/core/inspector/console_message.cc b/chromium/third_party/blink/renderer/core/inspector/console_message.cc
index 52ac9e3ea56..d7e43482073 100644
--- a/chromium/third_party/blink/renderer/core/inspector/console_message.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/console_message.cc
@@ -123,7 +123,7 @@ void ConsoleMessage::SetNodes(LocalFrame* frame, Vector<DOMNodeId> nodes) {
nodes_ = std::move(nodes);
}
-void ConsoleMessage::Trace(Visitor* visitor) {
+void ConsoleMessage::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/console_message.h b/chromium/third_party/blink/renderer/core/inspector/console_message.h
index e0cbd48922c..0bb189144c5 100644
--- a/chromium/third_party/blink/renderer/core/inspector/console_message.h
+++ b/chromium/third_party/blink/renderer/core/inspector/console_message.h
@@ -57,7 +57,7 @@ class CORE_EXPORT ConsoleMessage final
Vector<DOMNodeId>& Nodes();
void SetNodes(LocalFrame*, Vector<DOMNodeId> nodes);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
mojom::ConsoleMessageSource source_;
diff --git a/chromium/third_party/blink/renderer/core/inspector/console_message_storage.cc b/chromium/third_party/blink/renderer/core/inspector/console_message_storage.cc
index 12f61d2d6b9..4278aa80384 100644
--- a/chromium/third_party/blink/renderer/core/inspector/console_message_storage.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/console_message_storage.cc
@@ -99,7 +99,7 @@ int ConsoleMessageStorage::ExpiredCount() const {
return expired_count_;
}
-void ConsoleMessageStorage::Trace(Visitor* visitor) {
+void ConsoleMessageStorage::Trace(Visitor* visitor) const {
visitor->Trace(messages_);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/console_message_storage.h b/chromium/third_party/blink/renderer/core/inspector/console_message_storage.h
index 9a4e903043f..1ea2efe53a4 100644
--- a/chromium/third_party/blink/renderer/core/inspector/console_message_storage.h
+++ b/chromium/third_party/blink/renderer/core/inspector/console_message_storage.h
@@ -31,7 +31,7 @@ class CORE_EXPORT ConsoleMessageStorage
ConsoleMessage* at(wtf_size_t index) const;
int ExpiredCount() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
int expired_count_;
diff --git a/chromium/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc b/chromium/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc
index ef5ac5bd4ee..320cacee920 100644
--- a/chromium/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc
@@ -106,7 +106,7 @@ DevToolsEmulator::DevToolsEmulator(WebViewImpl* web_view)
web_view->GetPage()->GetSettings().GetCookieEnabled()),
document_cookie_disabled_(false) {}
-void DevToolsEmulator::Trace(Visitor* visitor) {}
+void DevToolsEmulator::Trace(Visitor* visitor) const {}
void DevToolsEmulator::SetTextAutosizingEnabled(bool enabled) {
embedder_text_autosizing_enabled_ = enabled;
diff --git a/chromium/third_party/blink/renderer/core/inspector/dev_tools_emulator.h b/chromium/third_party/blink/renderer/core/inspector/dev_tools_emulator.h
index 67aeaa49857..e208016b899 100644
--- a/chromium/third_party/blink/renderer/core/inspector/dev_tools_emulator.h
+++ b/chromium/third_party/blink/renderer/core/inspector/dev_tools_emulator.h
@@ -28,7 +28,7 @@ class CORE_EXPORT DevToolsEmulator final
: public GarbageCollected<DevToolsEmulator> {
public:
explicit DevToolsEmulator(WebViewImpl*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// Settings overrides.
void SetTextAutosizingEnabled(bool);
diff --git a/chromium/third_party/blink/renderer/core/inspector/dev_tools_host.cc b/chromium/third_party/blink/renderer/core/inspector/dev_tools_host.cc
index 5a0c2c3eb6c..e045e807404 100644
--- a/chromium/third_party/blink/renderer/core/inspector/dev_tools_host.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/dev_tools_host.cc
@@ -69,7 +69,7 @@ class FrontendMenuProvider final : public ContextMenuProvider {
DCHECK(!devtools_host_);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(devtools_host_);
ContextMenuProvider::Trace(visitor);
}
@@ -109,7 +109,7 @@ DevToolsHost::DevToolsHost(InspectorFrontendClient* client,
DevToolsHost::~DevToolsHost() = default;
-void DevToolsHost::Trace(Visitor* visitor) {
+void DevToolsHost::Trace(Visitor* visitor) const {
visitor->Trace(client_);
visitor->Trace(frontend_frame_);
visitor->Trace(menu_provider_);
diff --git a/chromium/third_party/blink/renderer/core/inspector/dev_tools_host.h b/chromium/third_party/blink/renderer/core/inspector/dev_tools_host.h
index f139c8ac9b9..ac3e6010e27 100644
--- a/chromium/third_party/blink/renderer/core/inspector/dev_tools_host.h
+++ b/chromium/third_party/blink/renderer/core/inspector/dev_tools_host.h
@@ -49,7 +49,7 @@ class CORE_EXPORT DevToolsHost final : public ScriptWrappable {
DevToolsHost(InspectorFrontendClient*, LocalFrame* frontend_frame);
~DevToolsHost() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void DisconnectClient();
float zoomFactor();
diff --git a/chromium/third_party/blink/renderer/core/inspector/devtools_agent.cc b/chromium/third_party/blink/renderer/core/inspector/devtools_agent.cc
index 32d3f155bf3..f5c138ac929 100644
--- a/chromium/third_party/blink/renderer/core/inspector/devtools_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/devtools_agent.cc
@@ -143,9 +143,12 @@ DevToolsAgent::DevToolsAgent(
inspector_task_runner_(std::move(inspector_task_runner)),
io_task_runner_(std::move(io_task_runner)) {}
-DevToolsAgent::~DevToolsAgent() {}
+DevToolsAgent::~DevToolsAgent() = default;
-void DevToolsAgent::Trace(Visitor* visitor) {
+void DevToolsAgent::Trace(Visitor* visitor) const {
+ visitor->Trace(associated_receiver_);
+ visitor->Trace(host_remote_);
+ visitor->Trace(associated_host_remote_);
visitor->Trace(inspected_frames_);
visitor->Trace(probe_sink_);
visitor->Trace(sessions_);
@@ -164,7 +167,7 @@ void DevToolsAgent::BindReceiverForWorker(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
DCHECK(!associated_receiver_.is_bound());
- host_remote_.Bind(std::move(host_remote));
+ host_remote_.Bind(std::move(host_remote), std::move(task_runner));
host_remote_.set_disconnect_handler(
WTF::Bind(&DevToolsAgent::CleanupConnection, WrapWeakPersistent(this)));
@@ -178,8 +181,8 @@ void DevToolsAgent::BindReceiver(
mojo::PendingAssociatedReceiver<mojom::blink::DevToolsAgent> receiver,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
DCHECK(!associated_receiver_.is_bound());
- associated_receiver_.Bind(std::move(receiver), std::move(task_runner));
- associated_host_remote_.Bind(std::move(host_remote));
+ associated_receiver_.Bind(std::move(receiver), task_runner);
+ associated_host_remote_.Bind(std::move(host_remote), task_runner);
associated_host_remote_.set_disconnect_handler(
WTF::Bind(&DevToolsAgent::CleanupConnection, WrapWeakPersistent(this)));
}
@@ -197,7 +200,8 @@ void DevToolsAgent::AttachDevToolsSessionImpl(
DevToolsSession* session = MakeGarbageCollected<DevToolsSession>(
this, std::move(host), std::move(session_receiver),
std::move(io_session_receiver), std::move(reattach_session_state),
- client_expects_binary_responses, session_id);
+ client_expects_binary_responses, session_id,
+ inspector_task_runner_->isolate_task_runner());
sessions_.insert(session);
client_->DebuggerTaskFinished();
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/devtools_agent.h b/chromium/third_party/blink/renderer/core/inspector/devtools_agent.h
index 3d387e9f73e..2a1708b0663 100644
--- a/chromium/third_party/blink/renderer/core/inspector/devtools_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/devtools_agent.h
@@ -9,13 +9,13 @@
#include "base/single_thread_task_runner.h"
#include "base/unguessable_token.h"
-#include "mojo/public/cpp/bindings/associated_receiver.h"
-#include "mojo/public/cpp/bindings/associated_remote.h"
-#include "mojo/public/cpp/bindings/receiver.h"
-#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/devtools/devtools_agent.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
@@ -34,7 +34,7 @@ class CORE_EXPORT DevToolsAgent : public GarbageCollected<DevToolsAgent>,
public:
class Client {
public:
- virtual ~Client() {}
+ virtual ~Client() = default;
virtual void AttachSession(DevToolsSession*, bool restore) = 0;
virtual void DetachSession(DevToolsSession*) = 0;
virtual void InspectElement(const gfx::Point&) = 0;
@@ -73,7 +73,7 @@ class CORE_EXPORT DevToolsAgent : public GarbageCollected<DevToolsAgent>,
mojo::PendingAssociatedRemote<mojom::blink::DevToolsAgentHost>,
mojo::PendingAssociatedReceiver<mojom::blink::DevToolsAgent>,
scoped_refptr<base::SingleThreadTaskRunner>);
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
friend class DevToolsSession;
@@ -123,11 +123,19 @@ class CORE_EXPORT DevToolsAgent : public GarbageCollected<DevToolsAgent>,
base::OnceClosure callback);
Client* client_;
- mojo::AssociatedReceiver<mojom::blink::DevToolsAgent> associated_receiver_{
- this};
- mojo::Remote<mojom::blink::DevToolsAgentHost> host_remote_;
- mojo::AssociatedRemote<mojom::blink::DevToolsAgentHost>
- associated_host_remote_;
+ // DevToolsAgent is not tied to ExecutionContext
+ HeapMojoAssociatedReceiver<mojom::blink::DevToolsAgent,
+ DevToolsAgent,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ associated_receiver_{this, nullptr};
+ // DevToolsAgent is not tied to ExecutionContext
+ HeapMojoRemote<mojom::blink::DevToolsAgentHost,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ host_remote_{nullptr};
+ // DevToolsAgent is not tied to ExecutionContext
+ HeapMojoAssociatedRemote<mojom::blink::DevToolsAgentHost,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ associated_host_remote_{nullptr};
Member<InspectedFrames> inspected_frames_;
Member<CoreProbeSink> probe_sink_;
HeapHashSet<Member<DevToolsSession>> sessions_;
diff --git a/chromium/third_party/blink/renderer/core/inspector/devtools_session.cc b/chromium/third_party/blink/renderer/core/inspector/devtools_session.cc
index 4ee6a0ea568..0608c4defc6 100644
--- a/chromium/third_party/blink/renderer/core/inspector/devtools_session.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/devtools_session.cc
@@ -64,7 +64,7 @@ class DevToolsSession::IOSession : public mojom::blink::DevToolsSession {
WTF::Passed(std::move(receiver))));
}
- ~IOSession() override {}
+ ~IOSession() override = default;
void BindInterface(
mojo::PendingReceiver<mojom::blink::DevToolsSession> receiver) {
@@ -117,20 +117,22 @@ DevToolsSession::DevToolsSession(
mojo::PendingReceiver<mojom::blink::DevToolsSession> io_receiver,
mojom::blink::DevToolsSessionStatePtr reattach_session_state,
bool client_expects_binary_responses,
- const String& session_id)
+ const String& session_id,
+ scoped_refptr<base::SequencedTaskRunner> mojo_task_runner)
: agent_(agent),
- receiver_(this, std::move(main_receiver)),
inspector_backend_dispatcher_(new protocol::UberDispatcher(this)),
session_state_(std::move(reattach_session_state)),
client_expects_binary_responses_(client_expects_binary_responses),
v8_session_state_(kV8StateKey),
v8_session_state_cbor_(&v8_session_state_, /*default_value=*/{}),
session_id_(session_id) {
+ receiver_.Bind(std::move(main_receiver), mojo_task_runner);
+
io_session_ = new IOSession(
agent_->io_task_runner_, agent_->inspector_task_runner_,
WrapCrossThreadWeakPersistent(this), std::move(io_receiver));
- host_remote_.Bind(std::move(host_remote));
+ host_remote_.Bind(std::move(host_remote), mojo_task_runner);
host_remote_.set_disconnect_handler(
WTF::Bind(&DevToolsSession::Detach, WrapWeakPersistent(this)));
@@ -157,7 +159,7 @@ void DevToolsSession::ConnectToV8(v8_inspector::V8Inspector* inspector,
}
bool DevToolsSession::IsDetached() {
- return !host_remote_.is_bound();
+ return !io_session_;
}
void DevToolsSession::Append(InspectorAgent* agent) {
@@ -348,7 +350,9 @@ void DevToolsSession::FlushProtocolNotifications() {
notification_queue_.clear();
}
-void DevToolsSession::Trace(Visitor* visitor) {
+void DevToolsSession::Trace(Visitor* visitor) const {
+ visitor->Trace(receiver_);
+ visitor->Trace(host_remote_);
visitor->Trace(agent_);
visitor->Trace(agents_);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/devtools_session.h b/chromium/third_party/blink/renderer/core/inspector/devtools_session.h
index 74e91538ed6..1a7018daea0 100644
--- a/chromium/third_party/blink/renderer/core/inspector/devtools_session.h
+++ b/chromium/third_party/blink/renderer/core/inspector/devtools_session.h
@@ -8,8 +8,6 @@
#include <memory>
#include "base/callback.h"
#include "base/macros.h"
-#include "mojo/public/cpp/bindings/associated_receiver.h"
-#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -18,6 +16,9 @@
#include "third_party/blink/renderer/core/inspector/inspector_session_state.h"
#include "third_party/blink/renderer/core/inspector/protocol/Forward.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -45,7 +46,8 @@ class CORE_EXPORT DevToolsSession : public GarbageCollected<DevToolsSession>,
mojo::PendingReceiver<mojom::blink::DevToolsSession> io_receiver,
mojom::blink::DevToolsSessionStatePtr reattach_session_state,
bool client_expects_binary_responses,
- const String& session_id);
+ const String& session_id,
+ scoped_refptr<base::SequencedTaskRunner> mojo_task_runner);
~DevToolsSession() override;
void ConnectToV8(v8_inspector::V8Inspector*, int context_group_id);
@@ -53,7 +55,7 @@ class CORE_EXPORT DevToolsSession : public GarbageCollected<DevToolsSession>,
void Append(InspectorAgent*);
void Detach();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// protocol::FrontendChannel implementation.
void FlushProtocolNotifications() override;
@@ -102,8 +104,15 @@ class CORE_EXPORT DevToolsSession : public GarbageCollected<DevToolsSession>,
std::vector<uint8_t> message) const;
Member<DevToolsAgent> agent_;
- mojo::AssociatedReceiver<mojom::blink::DevToolsSession> receiver_;
- mojo::AssociatedRemote<mojom::blink::DevToolsSessionHost> host_remote_;
+ // DevToolsSession is not tied to ExecutionContext
+ HeapMojoAssociatedReceiver<mojom::blink::DevToolsSession,
+ DevToolsSession,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ receiver_{this, nullptr};
+ // DevToolsSession is not tied to ExecutionContext
+ HeapMojoAssociatedRemote<mojom::blink::DevToolsSessionHost,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ host_remote_{nullptr};
IOSession* io_session_;
std::unique_ptr<v8_inspector::V8InspectorSession> v8_session_;
std::unique_ptr<protocol::UberDispatcher> inspector_backend_dispatcher_;
diff --git a/chromium/third_party/blink/renderer/core/inspector/dom_editor.cc b/chromium/third_party/blink/renderer/core/inspector/dom_editor.cc
index a7951fa37b2..c75fe54d5d8 100644
--- a/chromium/third_party/blink/renderer/core/inspector/dom_editor.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/dom_editor.cc
@@ -70,7 +70,7 @@ class DOMEditor::RemoveChildAction final : public InspectorHistory::Action {
return !exception_state.HadException();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(parent_node_);
visitor->Trace(node_);
visitor->Trace(anchor_node_);
@@ -121,7 +121,7 @@ class DOMEditor::InsertBeforeAction final : public InspectorHistory::Action {
return !exception_state.HadException();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(parent_node_);
visitor->Trace(node_);
visitor->Trace(anchor_node_);
@@ -159,7 +159,7 @@ class DOMEditor::RemoveAttributeAction final : public InspectorHistory::Action {
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(element_);
InspectorHistory::Action::Trace(visitor);
}
@@ -203,7 +203,7 @@ class DOMEditor::SetAttributeAction final : public InspectorHistory::Action {
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(element_);
InspectorHistory::Action::Trace(visitor);
}
@@ -251,7 +251,7 @@ class DOMEditor::SetOuterHTMLAction final : public InspectorHistory::Action {
Node* NewNode() { return new_node_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(node_);
visitor->Trace(next_sibling_);
visitor->Trace(new_node_);
@@ -294,7 +294,7 @@ class DOMEditor::ReplaceWholeTextAction final
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(text_node_);
InspectorHistory::Action::Trace(visitor);
}
@@ -331,7 +331,7 @@ class DOMEditor::ReplaceChildNodeAction final
return !exception_state.HadException();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(parent_node_);
visitor->Trace(new_node_);
visitor->Trace(old_node_);
@@ -365,7 +365,7 @@ class DOMEditor::SetNodeValueAction final : public InspectorHistory::Action {
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(node_);
InspectorHistory::Action::Trace(visitor);
}
@@ -505,7 +505,7 @@ Response DOMEditor::ReplaceWholeText(Text* text_node, const String& text) {
return ToResponse(exception_state);
}
-void DOMEditor::Trace(Visitor* visitor) {
+void DOMEditor::Trace(Visitor* visitor) const {
visitor->Trace(history_);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/dom_editor.h b/chromium/third_party/blink/renderer/core/inspector/dom_editor.h
index 0331991dcbb..f6e3e328529 100644
--- a/chromium/third_party/blink/renderer/core/inspector/dom_editor.h
+++ b/chromium/third_party/blink/renderer/core/inspector/dom_editor.h
@@ -49,7 +49,7 @@ class DOMEditor final : public GarbageCollected<DOMEditor> {
public:
explicit DOMEditor(InspectorHistory*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
bool InsertBefore(ContainerNode* parent_node,
Node*,
diff --git a/chromium/third_party/blink/renderer/core/inspector/dom_patch_support.cc b/chromium/third_party/blink/renderer/core/inspector/dom_patch_support.cc
index 7dc75ee684b..0011fea59a6 100644
--- a/chromium/third_party/blink/renderer/core/inspector/dom_patch_support.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/dom_patch_support.cc
@@ -61,8 +61,8 @@ DOMPatchSupport::DOMPatchSupport(DOMEditor* dom_editor, Document& document)
void DOMPatchSupport::PatchDocument(const String& markup) {
Document* new_document = nullptr;
- DocumentInit init =
- DocumentInit::Create().WithContextDocument(&GetDocument());
+ DocumentInit init = DocumentInit::Create().WithExecutionContext(
+ GetDocument().GetExecutionContext());
if (IsA<HTMLDocument>(GetDocument()))
new_document = MakeGarbageCollected<HTMLDocument>(init);
else if (GetDocument().IsSVGDocument())
@@ -533,7 +533,7 @@ void DOMPatchSupport::MarkNodeAsUsed(Digest* digest) {
}
}
-void DOMPatchSupport::Digest::Trace(Visitor* visitor) {
+void DOMPatchSupport::Digest::Trace(Visitor* visitor) const {
visitor->Trace(node_);
visitor->Trace(children_);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/dom_patch_support.h b/chromium/third_party/blink/renderer/core/inspector/dom_patch_support.h
index e8b2c51187d..5e9383c96e3 100644
--- a/chromium/third_party/blink/renderer/core/inspector/dom_patch_support.h
+++ b/chromium/third_party/blink/renderer/core/inspector/dom_patch_support.h
@@ -58,7 +58,7 @@ class DOMPatchSupport final {
class Digest final : public GarbageCollected<Digest> {
public:
explicit Digest(Node* node) : node_(node) {}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
String sha1_;
String attrs_sha1_;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspect_tool_common.css b/chromium/third_party/blink/renderer/core/inspector/inspect_tool_common.css
deleted file mode 100644
index da932de9de4..00000000000
--- a/chromium/third_party/blink/renderer/core/inspector/inspect_tool_common.css
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2019 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-body {
- margin: 0;
- padding: 0;
- font-size: 13px;
- color: #222;
-}
-
-body.platform-linux {
- font-family: Roboto, Ubuntu, Arial, sans-serif;
-}
-
-body.platform-mac {
- color: rgb(48, 57, 66);
- font-family: '.SFNSDisplay-Regular', 'Helvetica Neue', 'Lucida Grande', sans-serif;
-}
-
-body.platform-windows {
- font-family: 'Segoe UI', Tahoma, sans-serif;
-}
-
-.fill {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
-}
-
-#canvas {
- pointer-events: none;
-}
-
-.hidden {
- display: none !important;
-}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspect_tool_common.js b/chromium/third_party/blink/renderer/core/inspector/inspect_tool_common.js
deleted file mode 100644
index 2c3001c6469..00000000000
--- a/chromium/third_party/blink/renderer/core/inspector/inspect_tool_common.js
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-window.viewportSize = {width: 800, height: 600};
-window.deviceScaleFactor = 1;
-window.emulationScaleFactor = 1;
-window.pageScaleFactor = 1;
-window.pageZoomFactor = 1;
-window.scrollX = 0;
-window.scrollY = 0;
-
-function reset(resetData) {
- window.viewportSize = resetData.viewportSize;
- window.deviceScaleFactor = resetData.deviceScaleFactor;
- window.pageScaleFactor = resetData.pageScaleFactor;
- window.pageZoomFactor = resetData.pageZoomFactor;
- window.emulationScaleFactor = resetData.emulationScaleFactor;
- window.scrollX = Math.round(resetData.scrollX);
- window.scrollY = Math.round(resetData.scrollY);
-
- window.canvas = document.getElementById('canvas');
- if (window.canvas) {
- window.canvas.width = deviceScaleFactor * viewportSize.width;
- window.canvas.height = deviceScaleFactor * viewportSize.height;
- window.canvas.style.width = viewportSize.width + 'px';
- window.canvas.style.height = viewportSize.height + 'px';
-
- window.context = canvas.getContext('2d');
- window.context.scale(deviceScaleFactor, deviceScaleFactor);
-
- window.canvasWidth = viewportSize.width;
- window.canvasHeight = viewportSize.height;
- }
-
- doReset();
-}
-
-function doReset() { }
-
-function setPlatform(platform) {
- window.platform = platform;
- document.body.classList.add('platform-' + platform);
-}
-
-function dispatch(message) {
- const functionName = message.shift();
- window[functionName].apply(null, message);
-}
-
-function log(text) {
- let element = document.getElementById('log');
- if (!element) {
- element = document.body.createChild();
- element.id = 'log';
- }
- element.createChild('div').textContent = text;
-}
-
-function eventHasCtrlOrMeta(event) {
- return window.platform == 'mac' ? (event.metaKey && !event.ctrlKey) : (event.ctrlKey && !event.metaKey);
-}
-
-Element.prototype.createChild = function(tagName, className) {
- const element = createElement(tagName, className);
- element.addEventListener('click', function(e) { e.stopPropagation(); }, false);
- this.appendChild(element);
- return element;
-}
-
-Element.prototype.createTextChild = function(text) {
- const element = document.createTextNode(text);
- this.appendChild(element);
- return element;
-}
-
-Element.prototype.removeChildren = function()
-{
- if (this.firstChild)
- this.textContent = '';
-}
-
-function createElement(tagName, className)
-{
- const element = document.createElement(tagName);
- if (className)
- element.className = className;
- return element;
-}
-
-String.prototype.trimEnd = function(maxLength)
-{
- if (this.length <= maxLength)
- return String(this);
- return this.substr(0, maxLength - 1) + '\u2026';
-}
-
-/**
- * @param {number} num
- * @param {number} min
- * @param {number} max
- * @return {number}
- */
-Number.constrain = function(num, min, max) {
- if (num < min)
- num = min;
- else if (num > max)
- num = max;
- return num;
-};
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspect_tool_distances.html b/chromium/third_party/blink/renderer/core/inspector/inspect_tool_distances.html
deleted file mode 100644
index 645d6c2e61a..00000000000
--- a/chromium/third_party/blink/renderer/core/inspector/inspect_tool_distances.html
+++ /dev/null
@@ -1,103 +0,0 @@
-<!--
- Copyright 2019 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file.
--->
-<!DOCTYPE html>
-<html>
-<head>
-<script>
-
-/**
- * @param {!Object} data
- */
-function drawDistances(data)
-{
- const info = data['distanceInfo'];
- if (!info)
- return;
- const rect = quadToRect(getVisualQuad(info));
- const context = window.context;
- context.save();
- context.strokeStyle = '#ccc';
- for (const box of info['boxes'])
- context.strokeRect(box[0], box[1], box[2], box[3]);
- context.strokeStyle = '#f00';
- context.lineWidth = 1;
- context.rect(rect.x - 0.5, rect.y - 0.5, rect.w + 1, rect.h + 1);
- context.stroke();
- context.restore();
-}
-
-/**
- * @param {!Object} data
- * @return {!Array<number>}
- */
-function getVisualQuad(data) {
- const style = data['style'];
- if (shouldUseVisualBorder(style))
- return data['border'];
- else if (ShouldUseVisualPadding(style))
- return data['padding'];
- return data['content'];
-
- /**
- * @param {!Object} style
- * @return {boolean}
- */
- function shouldUseVisualBorder(style) {
- const sides = ['top', 'right', 'bottom', 'left'];
- for (const side of sides) {
- const border_width = style[`border-${side}-width`];
- const border_style = style[`border-${side}-style`];
- const border_color = style[`border-${side}-color`];
- if (border_width != '0px' && border_style != 'none' &&
- !border_color.endsWith('00'))
- return true;
- }
- const outline_width = style['outline-width'];
- const outline_style = style['outline-style'];
- const outline_color = style['outline-color'];
- if (outline_width != '0px' && outline_style != 'none' &&
- !outline_color.endsWith('00'))
- return true;
- const box_shadow = style['box-shadow'];
- if (box_shadow != 'none')
- return true;
- return false;
- }
-
- /**
- * @param {!Object} style
- * @return {boolean}
- */
- function ShouldUseVisualPadding(style) {
- const bg_color = style['background-color'];
- const bg_image = style['background-image'];
- if (!bg_color.startsWith('#FFFFFF') && !bg_color.endsWith('00'))
- return true;
- if (bg_image != 'none')
- return true;
- return false;
- }
-}
-
-/**
- * @param {!Array<number>} quad
- * @return {!Object}
- */
-function quadToRect(quad) {
- return {
- x: quad[0],
- y: quad[1],
- w: quad[4] - quad[0],
- h: quad[5] - quad[1]
- }
-}
-
-</script>
-</head>
-<body class="fill">
- <canvas id="canvas" class="fill"></canvas>
-</body>
-</html>
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspect_tool_highlight.html b/chromium/third_party/blink/renderer/core/inspector/inspect_tool_highlight.html
deleted file mode 100644
index b5c7dbdb50f..00000000000
--- a/chromium/third_party/blink/renderer/core/inspector/inspect_tool_highlight.html
+++ /dev/null
@@ -1,1112 +0,0 @@
-<!--
- Copyright (C) 2012 Google Inc. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--->
-<!DOCTYPE html>
-<html>
-<head>
-<script src="inspect_tool_common.js"></script>
-<link rel="stylesheet" href="inspect_tool_common.css">
-<style>
-body {
- --arrow-width: 15px;
- --arrow-height: 8px;
- --shadow-up: 5px;
- --shadow-down: -5px;
- --shadow-direction: var(--shadow-up);
- --arrow-up: polygon(0 0, 100% 0, 50% 100%);
- --arrow-down: polygon(50% 0, 0 100%, 100% 100%);
- --arrow: var(--arrow-up);
-}
-
-.px {
- color: rgb(128, 128, 128);
-}
-
-#element-title {
- position: absolute;
- z-index: 10;
-}
-
-/* Material */
-
-.tooltip-content {
- position: absolute;
- z-index: 10;
- -webkit-user-select: none;
-}
-
-.tooltip-content {
- background-color: white;
- padding: 5px 8px;
- border: 1px solid white;
- border-radius: 3px;
- box-sizing: border-box;
- min-width: 100px;
- max-width: min(300px, 100% - 4px);
- z-index: 1;
- background-clip: padding-box;
- will-change: transform;
- text-rendering: optimizeLegibility;
- pointer-events: none;
- filter: drop-shadow(0 2px 4px rgba(0,0,0,0.35));
-}
-
-.tooltip-content::after {
- content: "";
- background: white;
- width: var(--arrow-width);
- height: var(--arrow-height);
- clip-path: var(--arrow);
- position: absolute;
- top: var(--arrow-top);
- left: var(--arrow-left);
- visibility: var(--arrow-visibility);
-}
-
-.element-info-section {
- margin-top: 12px;
- margin-bottom: 6px;
-}
-
-.section-name {
- color: #333;
- font-weight: 500;
- font-size: 10px;
- text-transform: uppercase;
- letter-spacing: .05em;
- line-height: 12px;
-}
-
-.element-info {
- display: flex;
- flex-direction: column;
-}
-
-.element-info-header {
- display: flex;
- align-items: baseline;
-}
-
-.element-info-body {
- display: flex;
- flex-direction: column;
- padding-top: 2px;
- margin-top: 2px;
-}
-
-.element-info-row {
- display: flex;
- line-height: 19px;
-}
-
-.separator-container {
- display: flex;
- align-items: center;
- flex: auto;
- margin-left: 7px;
-}
-
-.separator {
- border-top: 1px solid #ddd;
- width: 100%;
-}
-
-.element-info-name {
- flex-shrink: 0;
- color: #666;
-}
-
-.element-info-gap {
- flex: auto;
-}
-
-.element-info-value-color {
- display: flex;
- color: rgb(48, 57, 66);
- margin-left: 10px;
- align-items: baseline;
-}
-
-.element-info-value-contrast {
- display: flex;
- align-items: center;
- text-align: right;
- color: rgb(48, 57, 66);
- margin-left: 10px;
-}
-
-.element-info-value-contrast .a11y-icon {
- margin-left: 8px;
-}
-
-.element-info-value-icon {
- display: flex;
- align-items: center;
-}
-
-.element-info-value-text {
- text-align: right;
- color: rgb(48, 57, 66);
- margin-left: 10px;
- align-items: baseline;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.color-swatch {
- display: flex;
- margin-right: 2px;
- width: 10px;
- height: 10px;
- background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
- line-height: 10px;
-}
-
-.color-swatch-inner {
- flex: auto;
- border: 1px solid rgba(128, 128, 128, 0.6);
-}
-
-.element-description {
- flex: 1 1;
- font-weight: bold;
- word-wrap: break-word;
- word-break: break-all;
-}
-
-.dimensions {
- color: hsl(0, 0%, 45%);
- text-align: right;
- margin-left: 10px;
-}
-
-.material-node-width {
- margin-right: 2px;
-}
-
-.material-node-height {
- margin-left: 2px;
-}
-
-.material-tag-name {
- /* Keep this in sync with inspectorSyntaxHighlight.css (--dom-tag-name-color) */
- color: rgb(136, 18, 128);
-}
-
-.material-class-name, .material-node-id {
- /* Keep this in sync with inspectorSyntaxHighlight.css (.webkit-html-attribute-value) */
- color: rgb(26, 26, 166);
-}
-
-.contrast-text {
- width: 16px;
- height: 16px;
- text-align: center;
- line-height: 16px;
- margin-right: 8px;
- border: 1px solid rgba(0, 0, 0, 0.1);
- padding: 0 1px;
-}
-
-.a11y-icon {
- width: 16px;
- height: 16px;
- background-repeat: no-repeat;
- display: inline-block;
-}
-
-.a11y-icon-not-ok {
- background-image: url('data:image/svg+xml,<svg fill="none" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"><path d="m9 1.5c-4.14 0-7.5 3.36-7.5 7.5s3.36 7.5 7.5 7.5 7.5-3.36 7.5-7.5-3.36-7.5-7.5-7.5zm0 13.5c-3.315 0-6-2.685-6-6 0-1.3875.4725-2.6625 1.2675-3.675l8.4075 8.4075c-1.0125.795-2.2875 1.2675-3.675 1.2675zm4.7325-2.325-8.4075-8.4075c1.0125-.795 2.2875-1.2675 3.675-1.2675 3.315 0 6 2.685 6 6 0 1.3875-.4725 2.6625-1.2675 3.675z" fill="%239e9e9e"/></svg>');
-}
-
-.a11y-icon-warning {
- background-image: url('data:image/svg+xml,<svg fill="none" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"><path d="m8.25 11.25h1.5v1.5h-1.5zm0-6h1.5v4.5h-1.5zm.7425-3.75c-4.14 0-7.4925 3.36-7.4925 7.5s3.3525 7.5 7.4925 7.5c4.1475 0 7.5075-3.36 7.5075-7.5s-3.36-7.5-7.5075-7.5zm.0075 13.5c-3.315 0-6-2.685-6-6s2.685-6 6-6 6 2.685 6 6-2.685 6-6 6z" fill="%23e37400"/></svg>');
-}
-
-.a11y-icon-ok {
- background-image: url('data:image/svg+xml,<svg fill="none" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"><path d="m9 1.5c-4.14 0-7.5 3.36-7.5 7.5s3.36 7.5 7.5 7.5 7.5-3.36 7.5-7.5-3.36-7.5-7.5-7.5zm0 13.5c-3.3075 0-6-2.6925-6-6s2.6925-6 6-6 6 2.6925 6 6-2.6925 6-6 6zm-1.5-4.35-1.95-1.95-1.05 1.05 3 3 6-6-1.05-1.05z" fill="%230ca40c"/></svg>');
-}
-
-@media (forced-colors: active) {
- :root, body {
- background-color: transparent;
- forced-color-adjust: none;
- }
- .tooltip-content {
- border-color: Highlight;
- background-color: Canvas;
- color: Text;
- forced-color-adjust: none;
- }
- .tooltip-content::after {
- background-color: Highlight;
- }
- .color-swatch-inner,
- .contrast-text,
- .separator {
- border-color: Highlight;
- }
- .dimensions,
- .element-info-name,
- .element-info-value-color,
- .element-info-value-contrast,
- .element-info-value-icon,
- .element-info-value-text,
- .material-tag-name,
- .material-class-name,
- .material-node-id {
- color: CanvasText;
- }
-}
-</style>
-
-
-<script>
-const lightGridColor = "rgba(0,0,0,0.2)";
-const darkGridColor = "rgba(0,0,0,0.7)";
-const transparentColor = "rgba(0, 0, 0, 0)";
-const gridBackgroundColor = "rgba(255, 255, 255, 0.8)";
-
-function _drawAxis(context, rulerAtRight, rulerAtBottom)
-{
- if (window._gridPainted)
- return;
- window._gridPainted = true;
-
- context.save();
-
- var pageFactor = pageZoomFactor * pageScaleFactor * emulationScaleFactor;
- var scrollX = window.scrollX * pageScaleFactor;
- var scrollY = window.scrollY * pageScaleFactor;
- function zoom(x)
- {
- return Math.round(x * pageFactor);
- }
- function unzoom(x)
- {
- return Math.round(x / pageFactor);
- }
-
- var width = canvasWidth / pageFactor;
- var height = canvasHeight / pageFactor;
-
- const gridSubStep = 5;
- const gridStep = 50;
-
- {
- // Draw X grid background
- context.save();
- context.fillStyle = gridBackgroundColor;
- if (rulerAtBottom)
- context.fillRect(0, zoom(height) - 15, zoom(width), zoom(height));
- else
- context.fillRect(0, 0, zoom(width), 15);
-
- // Clip out backgrounds intersection
- context.globalCompositeOperation = "destination-out";
- context.fillStyle = "red";
- if (rulerAtRight)
- context.fillRect(zoom(width) - 15, 0, zoom(width), zoom(height));
- else
- context.fillRect(0, 0, 15, zoom(height));
- context.restore();
-
- // Draw Y grid background
- context.fillStyle = gridBackgroundColor;
- if (rulerAtRight)
- context.fillRect(zoom(width) - 15, 0, zoom(width), zoom(height));
- else
- context.fillRect(0, 0, 15, zoom(height));
- }
-
- context.lineWidth = 1;
- context.strokeStyle = darkGridColor;
- context.fillStyle = darkGridColor;
- {
- // Draw labels.
- context.save();
- context.translate(-scrollX, 0.5 - scrollY);
- var maxY = height + unzoom(scrollY);
- for (var y = 2 * gridStep; y < maxY; y += 2 * gridStep) {
- context.save();
- context.translate(scrollX, zoom(y));
- context.rotate(-Math.PI / 2);
- context.fillText(y, 2, rulerAtRight ? zoom(width) - 7 : 13);
- context.restore();
- }
- context.translate(0.5, -0.5);
- var maxX = width + unzoom(scrollX);
- for (var x = 2 * gridStep; x < maxX; x += 2 * gridStep) {
- context.save();
- context.fillText(x, zoom(x) + 2, rulerAtBottom ? scrollY + zoom(height) - 7 : scrollY + 13);
- context.restore();
- }
- context.restore();
- }
-
- {
- // Draw vertical grid
- context.save();
- if (rulerAtRight) {
- context.translate(zoom(width), 0);
- context.scale(-1, 1);
- }
- context.translate(-scrollX, 0.5 - scrollY);
- var maxY = height + unzoom(scrollY);
- for (var y = gridStep; y < maxY; y += gridStep) {
- context.beginPath();
- context.moveTo(scrollX, zoom(y));
- var markLength = (y % (gridStep * 2)) ? 5 : 8;
- context.lineTo(scrollX + markLength, zoom(y));
- context.stroke();
- }
- context.strokeStyle = lightGridColor;
- for (var y = gridSubStep; y < maxY; y += gridSubStep) {
- if (!(y % gridStep))
- continue;
- context.beginPath();
- context.moveTo(scrollX, zoom(y));
- context.lineTo(scrollX + gridSubStep, zoom(y));
- context.stroke();
- }
- context.restore();
- }
-
- {
- // Draw horizontal grid
- context.save();
- if (rulerAtBottom) {
- context.translate(0, zoom(height));
- context.scale(1, -1);
- }
- context.translate(0.5 - scrollX, -scrollY);
- var maxX = width + unzoom(scrollX);
- for (var x = gridStep; x < maxX; x += gridStep) {
- context.beginPath();
- context.moveTo(zoom(x), scrollY);
- var markLength = (x % (gridStep * 2)) ? 5 : 8;
- context.lineTo(zoom(x), scrollY + markLength);
- context.stroke();
- }
- context.strokeStyle = lightGridColor;
- for (var x = gridSubStep; x < maxX; x += gridSubStep) {
- if (!(x % gridStep))
- continue;
- context.beginPath();
- context.moveTo(zoom(x), scrollY);
- context.lineTo(zoom(x), scrollY + gridSubStep);
- context.stroke();
- }
- context.restore();
- }
-
- context.restore();
-}
-
-function doReset()
-{
- document.getElementById("tooltip-container").removeChildren();
- window._gridPainted = false;
-}
-
-/**
- * @param {!String} hexa
- * @return {!Array<number>}
- */
-function parseHexa(hexa) {
- return hexa.match(/#(\w\w)(\w\w)(\w\w)(\w\w)/).slice(1).map(c => parseInt(c, 16) / 255);
-}
-
-/**
- * TODO(alexrudenko): import this and other color helpers from DevTools
- * @param {!Array<number>} rgba
- * @return {!Array<number>}
- */
-function rgbaToHsla(rgba) {
- const [r, g, b] = rgba;
- const max = Math.max(r, g, b);
- const min = Math.min(r, g, b);
- const diff = max - min;
- const sum = max + min;
-
- let h;
- if (min === max) {
- h = 0;
- } else if (r === max) {
- h = ((1 / 6 * (g - b) / diff) + 1) % 1;
- } else if (g === max) {
- h = (1 / 6 * (b - r) / diff) + 1 / 3;
- } else {
- h = (1 / 6 * (r - g) / diff) + 2 / 3;
- }
-
- const l = 0.5 * sum;
-
- let s;
- if (l === 0) {
- s = 0;
- } else if (l === 1) {
- s = 0;
- } else if (l <= 0.5) {
- s = diff / sum;
- } else {
- s = diff / (2 - sum);
- }
-
- return [h, s, l, rgba[3]];
-}
-
-/**
- * @param {!String} hexa
- * @param {!String} colorFormat
- * @return {!String}
- */
-function formatColor(hexa, colorFormat) {
- if (colorFormat === 'rgb') {
- const [r, g, b, a] = parseHexa(hexa);
- // rgb(r g b [ / a])
- return `rgb(${(r * 255).toFixed()} ${(g * 255).toFixed()} ${(b * 255).toFixed()}${a === 1 ? '' : ' / ' + Math.round(a * 100) / 100})`;
- }
-
- if (colorFormat === 'hsl') {
- const [h, s, l, a] = rgbaToHsla(parseHexa(hexa));
- // hsl(hdeg s l [ / a])
- return `hsl(${Math.round(h * 360)}deg ${Math.round(s * 100)} ${Math.round(l * 100)}${a === 1 ? '' : ' / ' + Math.round(a * 100) / 100})`;
- }
-
- if (hexa.endsWith("FF")) {
- // short hex if no alpha
- return hexa.substr(0, 7);
- }
-
- return hexa;
-}
-
-/**
-* Calculate the contrast ratio between a foreground and a background color.
-* Returns the ratio to 1, for example for two colors with a contrast ratio of 21:1,
-* this function will return 21.
-* See http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
-* @param {!Array<number>} fgRGBA
-* @param {!Array<number>} bgRGBA
-* @return {number}
-*/
-function contrastRatio(fgRGBA, bgRGBA) {
- // If we have a semi-transparent background color over an unknown
- // background, draw the line for the "worst case" scenario: where
- // the unknown background is the same color as the text.
- bgRGBA = blendColors(bgRGBA, fgRGBA);
- const fgLuminance = luminance(blendColors(fgRGBA, bgRGBA));
- const bgLuminance = luminance(bgRGBA);
- const result = (Math.max(fgLuminance, bgLuminance) + 0.05) / (Math.min(fgLuminance, bgLuminance) + 0.05);
- return result.toFixed(2);
-
- /**
- * Calculate the luminance of this color using the WCAG algorithm.
- * See http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
- * @param {!Array<number>} rgba
- * @return {number}
- */
- function luminance(rgba) {
- const rSRGB = rgba[0];
- const gSRGB = rgba[1];
- const bSRGB = rgba[2];
-
- const r = rSRGB <= 0.03928 ? rSRGB / 12.92 : Math.pow(((rSRGB + 0.055) / 1.055), 2.4);
- const g = gSRGB <= 0.03928 ? gSRGB / 12.92 : Math.pow(((gSRGB + 0.055) / 1.055), 2.4);
- const b = bSRGB <= 0.03928 ? bSRGB / 12.92 : Math.pow(((bSRGB + 0.055) / 1.055), 2.4);
-
- return 0.2126 * r + 0.7152 * g + 0.0722 * b;
- }
-
- /**
- * Combine the two given color according to alpha blending.
- * @param {!Array<number>} fgRGBA
- * @param {!Array<number>} bgRGBA
- * @return {!Array<number>}
- */
- function blendColors(fgRGBA, bgRGBA) {
- const alpha = fgRGBA[3];
- return [
- ((1 - alpha) * bgRGBA[0]) + (alpha * fgRGBA[0]),
- ((1 - alpha) * bgRGBA[1]) + (alpha * fgRGBA[1]),
- ((1 - alpha) * bgRGBA[2]) + (alpha * fgRGBA[2]),
- alpha + (bgRGBA[3] * (1 - alpha))
- ];
- }
-}
-
-function computeIsLargeFont(contrast) {
- const boldWeights = new Set(['bold', 'bolder', '600', '700', '800', '900']);
-
- const fontSizePx = parseFloat(contrast.fontSize.replace('px', ''));
- const isBold = boldWeights.has(contrast.fontWeight);
-
- const fontSizePt = fontSizePx * 72 / 96;
- if (isBold)
- return fontSizePt >= 14;
- else
- return fontSizePt >= 18;
-}
-
-function _createElementDescription(elementInfo, colorFormat)
-{
- const elementInfoElement = createElement("div", "element-info");
- const elementInfoHeaderElement = elementInfoElement.createChild("div", "element-info-header");
- const descriptionElement = elementInfoHeaderElement.createChild("div", "element-description monospace");
- const tagNameElement = descriptionElement.createChild("span", "material-tag-name");
- tagNameElement.textContent = elementInfo.tagName;
- const nodeIdElement = descriptionElement.createChild("span", "material-node-id");
- const maxLength = 80;
- nodeIdElement.textContent = elementInfo.idValue ? "#" + elementInfo.idValue.trimEnd(maxLength) : "";
- nodeIdElement.classList.toggle("hidden", !elementInfo.idValue);
-
- const classNameElement = descriptionElement.createChild("span", "material-class-name");
- if (nodeIdElement.textContent.length < maxLength)
- classNameElement.textContent = (elementInfo.className || "").trimEnd(maxLength - nodeIdElement.textContent.length);
- classNameElement.classList.toggle("hidden", !elementInfo.className);
- const dimensionsElement = elementInfoHeaderElement.createChild("div", "dimensions");
- dimensionsElement.createChild("span", "material-node-width").textContent = Math.round(elementInfo.nodeWidth * 100) / 100;
- dimensionsElement.createTextChild("\u00d7");
- dimensionsElement.createChild("span", "material-node-height").textContent = Math.round(elementInfo.nodeHeight * 100) / 100;
-
- const style = elementInfo.style || {};
- let elementInfoBodyElement;
-
- if (elementInfo.isLockedAncestor)
- addTextRow("Showing the locked ancestor", "");
-
- const color = style["color"];
- if (color && color !== "#00000000")
- addColorRow("Color", color, colorFormat);
-
- const fontFamily = style["font-family"];
- const fontSize = style["font-size"];
- if (fontFamily && fontSize !== "0px")
- addTextRow("Font", `${fontSize} ${fontFamily}`);
-
- const bgcolor = style["background-color"];
- if (bgcolor && bgcolor !== "#00000000")
- addColorRow("Background", bgcolor, colorFormat);
-
- const margin = style["margin"];
- if (margin && margin !== "0px")
- addTextRow("Margin", margin);
-
- const padding = style["padding"];
- if (padding && padding !== "0px")
- addTextRow("Padding", padding);
-
- const cbgColor = elementInfo.contrast ? elementInfo.contrast.backgroundColor : null;
- const hasContrastInfo = color && color !== "#00000000" && cbgColor && cbgColor !== "#00000000";
-
- if (elementInfo.showAccessibilityInfo) {
- addSection("Accessibility");
-
- if (hasContrastInfo)
- addContrastRow(style["color"], elementInfo.contrast);
-
- addTextRow("Name", elementInfo.accessibleName);
- addTextRow("Role", elementInfo.accessibleRole);
- addIconRow("Keyboard-focusable", elementInfo.isKeyboardFocusable ? "a11y-icon a11y-icon-ok" : "a11y-icon a11y-icon-not-ok");
- }
-
- function ensureElementInfoBody() {
- if (!elementInfoBodyElement)
- elementInfoBodyElement = elementInfoElement.createChild("div", "element-info-body")
- }
-
- function addSection(name) {
- ensureElementInfoBody();
- const rowElement = elementInfoBodyElement.createChild("div", "element-info-row element-info-section");
- const nameElement = rowElement.createChild("div", "section-name");
- nameElement.textContent = name;
- const separatorElement = rowElement
- .createChild("div", "separator-container")
- .createChild("div", "separator");
- }
-
- function addRow(name, rowClassName, valueClassName) {
- ensureElementInfoBody();
- const rowElement = elementInfoBodyElement.createChild("div", "element-info-row");
- if (rowClassName)
- rowElement.classList.add(rowClassName);
- const nameElement = rowElement.createChild("div", "element-info-name");
- nameElement.textContent = name;
- rowElement.createChild("div", "element-info-gap");
- return rowElement.createChild("div", valueClassName || "");
- }
-
- function addIconRow(name, value) {
- addRow(name, "", "element-info-value-icon").createChild('div', value);
- }
-
- function addTextRow(name, value) {
- addRow(name, "", "element-info-value-text").createTextChild(value);
- }
-
- function addColorRow(name, color, colorFormat) {
- const valueElement = addRow(name, "", "element-info-value-color");
- const swatch = valueElement.createChild("div", "color-swatch");
- const inner = swatch.createChild("div", "color-swatch-inner");
- inner.style.backgroundColor = color;
- valueElement.createTextChild(formatColor(color, colorFormat));
- }
-
- function addContrastRow(fgColor, contrast) {
- const ratio = contrastRatio(parseHexa(fgColor), parseHexa(contrast.backgroundColor));
- const threshold = computeIsLargeFont(contrast) ? 3.0 : 4.5;
- const valueElement = addRow("Contrast", "", "element-info-value-contrast");
- const sampleText = valueElement.createChild("div", "contrast-text");
- sampleText.style.color = fgColor;
- sampleText.style.backgroundColor = contrast.backgroundColor;
- sampleText.textContent = "Aa";
- const valueSpan = valueElement.createChild("span");
- valueSpan.textContent = Math.round(ratio * 100) / 100;
- valueElement.createChild("div", ratio < threshold ? "a11y-icon a11y-icon-warning" : "a11y-icon a11y-icon-ok");
- }
-
- return elementInfoElement;
-}
-
-function _drawElementTitle(elementInfo, bounds, colorFormat)
-{
- const tooltipContainer = document.getElementById("tooltip-container");
- tooltipContainer.removeChildren();
- _createMaterialTooltip(tooltipContainer, bounds, _createElementDescription(elementInfo, colorFormat), true);
-}
-
-function _createMaterialTooltip(parentElement, bounds, contentElement, withArrow)
-{
- const tooltipContainer = parentElement.createChild("div");
- const tooltipContent = tooltipContainer.createChild("div", "tooltip-content");
- tooltipContent.appendChild(contentElement);
-
- const titleWidth = tooltipContent.offsetWidth;
- const titleHeight = tooltipContent.offsetHeight;
- const arrowHalfWidth = 8;
- const pageMargin = 2;
- const arrowWidth = arrowHalfWidth * 2;
- const arrowInset = arrowHalfWidth + 2;
-
- const containerMinX = pageMargin + arrowInset;
- const containerMaxX = canvasWidth - pageMargin - arrowInset - arrowWidth;
-
- // Left align arrow to the tooltip but ensure it is pointing to the element.
- // Center align arrow if the inspected element bounds are too narrow.
- const boundsAreTooNarrow = bounds.maxX - bounds.minX < arrowWidth + 2 * arrowInset;
- let arrowX;
- if (boundsAreTooNarrow) {
- arrowX = (bounds.minX + bounds.maxX) * 0.5 - arrowHalfWidth;
- } else {
- const xFromLeftBound = bounds.minX + arrowInset;
- const xFromRightBound = bounds.maxX - arrowInset - arrowWidth;
- if (xFromLeftBound > containerMinX && xFromLeftBound < containerMaxX)
- arrowX = xFromLeftBound;
- else
- arrowX = Number.constrain(containerMinX, xFromLeftBound, xFromRightBound);
- }
- // Hide arrow if element is completely off the sides of the page.
- const arrowHidden = !withArrow || arrowX < containerMinX || arrowX > containerMaxX;
-
- let boxX = arrowX - arrowInset;
- boxX = Number.constrain(boxX, pageMargin, canvasWidth - titleWidth - pageMargin);
-
- let boxY = bounds.minY - arrowHalfWidth - titleHeight;
- let onTop = true;
- if (boxY < 0) {
- boxY = Math.min(canvasHeight - titleHeight, bounds.maxY + arrowHalfWidth);
- onTop = false;
- } else if (bounds.minY > canvasHeight) {
- boxY = canvasHeight - arrowHalfWidth - titleHeight;
- }
-
- // If tooltip intersects with the bounds, hide it.
- // Allow bounds to contain the box though for the large elements like <body>.
- const includes = boxX >= bounds.minX && boxX + titleWidth <= bounds.maxX &&
- boxY >= bounds.minY && boxY + titleHeight <= bounds.maxY;
- const overlaps = boxX < bounds.maxX && boxX + titleWidth > bounds.minX &&
- boxY < bounds.maxY && boxY + titleHeight > bounds.minY;
- if (overlaps && !includes) {
- tooltipContent.style.display = 'none';
- return;
- }
-
- tooltipContent.style.top = boxY + "px";
- tooltipContent.style.left = boxX + "px";
- tooltipContent.style.setProperty('--arrow-visibility', (arrowHidden || includes) ? 'hidden' : 'visible');
- if (arrowHidden)
- return;
-
- tooltipContent.style.setProperty('--arrow', onTop ? 'var(--arrow-up)' : 'var(--arrow-down)');
- tooltipContent.style.setProperty('--shadow-direction', onTop ? 'var(--shadow-up)' : 'var(--shadow-down)');
- tooltipContent.style.setProperty('--arrow-top', (onTop ? titleHeight : -arrowHalfWidth) + 'px');
- tooltipContent.style.setProperty('--arrow-left', (arrowX - boxX) + 'px');
-}
-
-function _drawRulers(context, bounds, rulerAtRight, rulerAtBottom, color, dash)
-{
- context.save();
- var width = canvasWidth;
- var height = canvasHeight;
- context.strokeStyle = color || "rgba(128, 128, 128, 0.3)";
- context.lineWidth = 1;
- context.translate(0.5, 0.5);
- if (dash) {
- context.setLineDash([3, 3]);
- }
-
- if (rulerAtRight) {
- for (var y in bounds.rightmostXForY) {
- context.beginPath();
- context.moveTo(width, y);
- context.lineTo(bounds.rightmostXForY[y], y);
- context.stroke();
- }
- } else {
- for (var y in bounds.leftmostXForY) {
- context.beginPath();
- context.moveTo(0, y);
- context.lineTo(bounds.leftmostXForY[y], y);
- context.stroke();
- }
- }
-
- if (rulerAtBottom) {
- for (var x in bounds.bottommostYForX) {
- context.beginPath();
- context.moveTo(x, height);
- context.lineTo(x, bounds.topmostYForX[x]);
- context.stroke();
- }
- } else {
- for (var x in bounds.topmostYForX) {
- context.beginPath();
- context.moveTo(x, 0);
- context.lineTo(x, bounds.topmostYForX[x]);
- context.stroke();
- }
- }
-
- context.restore();
-}
-
-function buildPath(commands, bounds) {
- var commandsIndex = 0;
-
- function extractPoints(count)
- {
- var points = [];
-
- for (var i = 0; i < count; ++i) {
- var x = Math.round(commands[commandsIndex++] * emulationScaleFactor);
- bounds.maxX = Math.max(bounds.maxX, x);
- bounds.minX = Math.min(bounds.minX, x);
-
- var y = Math.round(commands[commandsIndex++] * emulationScaleFactor);
- bounds.maxY = Math.max(bounds.maxY, y);
- bounds.minY = Math.min(bounds.minY, y);
-
- bounds.leftmostXForY[y] = Math.min(bounds.leftmostXForY[y] || Number.MAX_VALUE, x);
- bounds.rightmostXForY[y] = Math.max(bounds.rightmostXForY[y] || Number.MIN_VALUE, x);
- bounds.topmostYForX[x] = Math.min(bounds.topmostYForX[x] || Number.MAX_VALUE, y);
- bounds.bottommostYForX[x] = Math.max(bounds.bottommostYForX[x] || Number.MIN_VALUE, y);
- points.push(x, y);
- }
- return points;
- }
-
- var commandsLength = commands.length;
- var path = new Path2D();
- while (commandsIndex < commandsLength) {
- switch (commands[commandsIndex++]) {
- case "M":
- path.moveTo.apply(path, extractPoints(1));
- break;
- case "L":
- path.lineTo.apply(path, extractPoints(1));
- break;
- case "C":
- path.bezierCurveTo.apply(path, extractPoints(3));
- break;
- case "Q":
- path.quadraticCurveTo.apply(path, extractPoints(2));
- break;
- case "Z":
- path.closePath();
- break;
- }
- }
- path.closePath();
- return path;
-}
-
-function drawPath(context, commands, fillColor, outlineColor, bounds)
-{
- context.save();
- const path = buildPath(commands, bounds);
- if (fillColor) {
- context.fillStyle = fillColor;
- context.fill(path);
- }
- if (outlineColor) {
- context.lineWidth = 2;
- context.strokeStyle = outlineColor;
- context.stroke(path);
- }
- context.restore();
- return path;
-}
-
-function emptyBounds()
-{
- var bounds = {
- minX: Number.MAX_VALUE,
- minY: Number.MAX_VALUE,
- maxX: Number.MIN_VALUE,
- maxY: Number.MIN_VALUE,
- leftmostXForY: {},
- rightmostXForY: {},
- topmostYForX: {},
- bottommostYForX: {}
- };
- return bounds;
-}
-
-function _drawLayoutGridHighlight(highlight, context)
-{
- // Draw Grid border
- if (highlight.gridHighlightConfig.gridBorderColor) {
- context.save();
- context.translate(0.5, 0.5);
- context.lineWidth = 0;
- if (highlight.gridHighlightConfig.gridBorderDash) {
- context.setLineDash([3, 3]);
- }
- context.strokeStyle = highlight.gridHighlightConfig.gridBorderColor;
- context.stroke(buildPath(highlight.gridBorder, emptyBounds()));
- context.restore();
- }
-
- // Draw Cell Border
- if (highlight.gridHighlightConfig.cellBorderColor) {
- const rowBounds = emptyBounds();
- const columnBounds = emptyBounds();
- const rowPath = buildPath(highlight.rows, rowBounds);
- const columnPath = buildPath(highlight.columns, columnBounds);
- context.save();
- context.translate(0.5, 0.5);
- if (highlight.gridHighlightConfig.cellBorderDash) {
- context.setLineDash([3, 3]);
- }
- context.lineWidth = 0;
- context.strokeStyle = highlight.gridHighlightConfig.cellBorderColor;
-
- context.save();
- context.clip(columnPath);
- context.stroke(rowPath);
- context.restore();
-
- context.save();
- context.clip(rowPath);
- context.stroke(columnPath);
- context.restore();
-
- context.restore();
-
- if (highlight.gridHighlightConfig.showGridExtensionLines) {
- // Extend row gap lines left/up.
- _drawRulers(context, rowBounds, /* rulerAtRight */ false, /* rulerAtBottom */ false, highlight.gridHighlightConfig.cellBorderColor, highlight.gridHighlightConfig.cellBorderDash);
- // Extend row gap right/down.
- _drawRulers(context, rowBounds, /* rulerAtRight */ true, /* rulerAtBottom */ true, highlight.gridHighlightConfig.cellBorderColor, highlight.gridHighlightConfig.cellBorderDash);
- // Extend column lines left/up.
- _drawRulers(context, columnBounds, /* rulerAtRight */ false, /* rulerAtBottom */ false, highlight.gridHighlightConfig.cellBorderColor, highlight.gridHighlightConfig.cellBorderDash);
- // Extend column right/down.
- _drawRulers(context, columnBounds, /* rulerAtRight */ true, /* rulerAtBottom */ true, highlight.gridHighlightConfig.cellBorderColor, highlight.gridHighlightConfig.cellBorderDash);
- }
- }
-
- // Row Gaps
- if (highlight.gridHighlightConfig.rowGapColor) {
- context.save();
- context.translate(0.5, 0.5);
- context.lineWidth = 0;
- context.fillStyle = highlight.gridHighlightConfig.rowGapColor;
- let bounds = emptyBounds();
- const path = buildPath(highlight.rowGaps, bounds);
- if (highlight.gridHighlightConfig.rowHatchColor) {
- hatchFillPath(context, path, bounds, 10, highlight.gridHighlightConfig.rowHatchColor, /* flipDirection */ true);
- }
- context.fill(path);
- context.restore();
- }
-
- // Column Gaps
- if (highlight.gridHighlightConfig.columnGapColor) {
- context.save();
- context.translate(0.5, 0.5);
- context.lineWidth = 0;
- context.fillStyle = highlight.gridHighlightConfig.columnGapColor;
- let bounds = emptyBounds();
- const path = buildPath(highlight.columnGaps, bounds);
- if (highlight.gridHighlightConfig.columnHatchColor) {
- hatchFillPath(context, path, bounds, 10, highlight.gridHighlightConfig.columnHatchColor);
- }
- context.fill(path);
- context.restore();
- }
-}
-
-/**
- * Draw line hatching at a 45 degree angle for a given
- * path.
- * __________
- * |\ \ \ |
- * | \ \ \|
- * | \ \ |
- * |\ \ \ |
- * **********
- *
- * @param {CanvasRenderingContext2D} context
- * @param {Path2D} path
- * @param {Object} bounds
- * @param {delta} delta - vertical gap between hatching lines in pixels
- * @param {string} color
- * @param {boolean=} flipDirection - lines are drawn from top right to bottom left
- *
- */
-function hatchFillPath(context, path, bounds, delta, color, flipDirection) {
- const dx = bounds.maxX - bounds.minX;
- const dy = bounds.maxY - bounds.minY;
- context.rect(bounds.minX, bounds.minY, dx, dy);
- context.save();
- context.clip(path);
- context.setLineDash([5, 3]);
- const majorAxis = Math.max(dx, dy);
- context.strokeStyle = color;
- if (flipDirection) {
- for (let i = -majorAxis; i < majorAxis; i += delta) {
- context.beginPath();
- context.moveTo(bounds.maxX - i , bounds.minY);
- context.lineTo(bounds.maxX - dy - i, bounds.maxY);
- context.stroke();
- }
- } else {
- for (let i = -majorAxis; i < majorAxis; i += delta) {
- context.beginPath();
- context.moveTo(i + bounds.minX, bounds.minY);
- context.lineTo(dy + i + bounds.minX, bounds.maxY);
- context.stroke();
- }
- }
- context.restore();
-}
-
-function clipLayoutGridCells(highlight, context) {
- // It may seem simpler to, before drawing the desired path, call context.clip()
- // with the rows and then with the columns. However, the 2nd context.clip() call
- // would try to find the intersection of the rows and columns, which is way too
- // expensive if the grid is huge, e.g. a 1000x1000 grid has 1M cells.
- // Therefore, it's better to draw the path first, set the globalCompositeOperation
- // so that the existing canvas content is kept where it overlaps with new content,
- // and then draw the rows and columns.
- if (highlight.gridInfo) {
- for (const grid of highlight.gridInfo) {
- if (!grid.isPrimaryGrid)
- continue;
- context.save();
- context.globalCompositeOperation = "destination-in";
- drawPath(context, grid.rows, "red", null, emptyBounds());
- drawPath(context, grid.columns, "red", null, emptyBounds());
- context.restore();
- }
- }
-}
-
-function drawHighlight(highlight, context)
-{
- context = context || window.context;
- context.save();
-
- var bounds = emptyBounds();
-
- for (var paths = highlight.paths.slice(); paths.length;) {
- var path = paths.pop();
- context.save();
- drawPath(context, path.path, path.fillColor, path.outlineColor, bounds);
- if (paths.length) {
- context.globalCompositeOperation = "destination-out";
- drawPath(context, paths[paths.length - 1].path, "red", null, bounds);
- }
- // Clip content quad using the data grid cells info to create white stripes.
- if (path.name === "content")
- clipLayoutGridCells(highlight, context);
- context.restore();
- }
- context.restore();
-
- context.save();
-
- var rulerAtRight = highlight.paths.length && highlight.showRulers && bounds.minX < 20 && bounds.maxX + 20 < canvasWidth;
- var rulerAtBottom = highlight.paths.length && highlight.showRulers && bounds.minY < 20 && bounds.maxY + 20 < canvasHeight;
-
- if (highlight.showRulers)
- _drawAxis(context, rulerAtRight, rulerAtBottom);
-
- if (highlight.paths.length) {
- if (highlight.showExtensionLines)
- _drawRulers(context, bounds, rulerAtRight, rulerAtBottom);
-
- if (highlight.elementInfo)
- _drawElementTitle(highlight.elementInfo, bounds, highlight.colorFormat);
- }
- if (highlight.gridInfo) {
- for (var grid of highlight.gridInfo)
- _drawLayoutGridHighlight(grid, context);
- }
- context.restore();
-
- return { bounds: bounds };
-}
-
-function test() {
- document.body.classList.add("platform-mac");
- reset(window);
- drawHighlight(
- {"paths":[{"path":["M",122,133.796875,"L",822,133.796875,"L",822,208.796875,"L",122,208.796875,"Z"], "fillColor":"rgba(111, 168, 220, 0.658823529411765)","name":"content"},
- {"path":["M",122,113.796875,"L",822,113.796875,"L",822,228.796875,"L",122,228.796875,"Z"],"fillColor":"rgba(246, 178, 107, 0.66)","name":"margin"}],"showRulers":false,"showExtensionLines":false,
- "elementInfo":{"tagName":"button","className":"class.name", "idValue":"download-hero","nodeWidth":"700","nodeHeight":"75","style":{"color":"#FFFFFFFF","font-family":"\"Product Sans\", \"Open Sans\", Roboto, Arial, \"Product Sans\", \"Open Sans\", Roboto, Arial","font-size":"20px","line-height":"25px","padding":"0px","margin":"20px 0px","background-color":"#00000000"},"contrast":{"fontSize":"20px","fontWeight":"400","backgroundColor":"#F9B826BF"},"isKeyboardFocusable":false,"accessibleName":"name","accessibleRole":"role","showAccessibilityInfo":true}, showExtensionLines: true, showRulers: true, colorFormat: "hsl"});
-}
-
-</script>
-</head>
-<body class="fill">
- <canvas id="canvas" class="fill"></canvas>
- <div id="tooltip-container"></div>
-</body>
-</html>
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspect_tool_paused.html b/chromium/third_party/blink/renderer/core/inspector/inspect_tool_paused.html
deleted file mode 100644
index 22f5375dc0f..00000000000
--- a/chromium/third_party/blink/renderer/core/inspector/inspect_tool_paused.html
+++ /dev/null
@@ -1,108 +0,0 @@
-<!--
- Copyright 2019 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file.
--->
-<!DOCTYPE html>
-<html>
-<head>
-<script src="inspect_tool_common.js"></script>
-<link rel="stylesheet" href="inspect_tool_common.css">
-<style>
-body {
- background-color: rgba(0, 0, 0, 0.31);
-}
-
-.controls-line {
- display: flex;
- justify-content: center;
- margin: 10px 0;
-}
-
-.message-box {
- padding: 2px 4px;
- display: flex;
- align-items: center;
- cursor: default;
- overflow: hidden;
-}
-
-#paused-in-debugger {
- white-space: nowrap;
- text-overflow: ellipsis;
- overflow: hidden;
-}
-
-.controls-line > * {
- background-color: rgb(255, 255, 194);
- border: 1px solid rgb(202, 202, 202);
- height: 22px;
- box-sizing: border-box;
-}
-
-.controls-line .button {
- width: 26px;
- margin-left: -1px;
- margin-right: 0;
- padding: 0;
- flex-shrink: 0;
- flex-grow: 0;
- cursor: pointer;
-}
-
-.controls-line .button .glyph {
- width: 100%;
- height: 100%;
- background-color: rgba(0, 0, 0, 0.75);
- opacity: 0.8;
- -webkit-mask-repeat: no-repeat;
- -webkit-mask-position: center;
- position: relative;
-}
-
-.controls-line .button:active .glyph {
- top: 1px;
- left: 1px;
-}
-
-#resume-button .glyph {
- -webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAKCAYAAABv7tTEAAAAAXNSR0IArs4c6QAAAFJJREFUKM+10bEJgGAMBeEPbR3BLRzEVdzEVRzELRzBVohVwEJ+iODBlQfhBeJhsmHU4C0KnFjQV6J0x1SNAhdWDJUoPTB3PvLLeaUhypM3n3sD/qc7lDrdpIEAAAAASUVORK5CYII=);
- -webkit-mask-size: 13px 10px;
- background-color: rgb(66, 129, 235);
-}
-
-#step-over-button .glyph {
- -webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAKCAYAAAC5Sw6hAAAAAXNSR0IArs4c6QAAAOFJREFUKM+N0j8rhXEUB/DPcxW35CqhvIBrtqibkklhV8qkTHe4ZbdblcXgPVhuMdqUTUl5A2KRRCF5LGc4PT1P7qnfcr5/zu/8KdTHLFaxjHnc4RZXKI0QYxjgLQTVd42l/0wmg5iFX3iq5H6w22RS4DyRH7CB8cAXcBTGJT6xUmd0mEwuMdFQcA3fwXvGTAan8BrgPabTL9fRRyfx91PRMwyjGwcJ2EyCfsrfpPw2Pipz24NT/MZciiQYVshzOKnZ5Hturxt3k2MnCpS4SPkeHpPR8Sh3tYgttBoW9II2/AHiaEqvD2Fc0wAAAABJRU5ErkJggg==);
- -webkit-mask-size: 18px 10px;
-}
-
-</style>
-<script>
-
-function drawPausedInDebuggerMessage(message) {
- document.getElementById("paused-in-debugger").textContent = message;
-}
-
-window.addEventListener("DOMContentLoaded", () => {
- document.getElementById("resume-button").addEventListener("click", () => InspectorOverlayHost.send("resume"));
- document.getElementById("step-over-button").addEventListener("click", () => InspectorOverlayHost.send("stepOver"));
-});
-
-document.addEventListener("keydown", event => {
- if (event.key == "F8" || eventHasCtrlOrMeta(event) && event.keyCode == 220 /* backslash */)
- InspectorOverlayHost.send("resume");
- else if (event.key == "F10" || eventHasCtrlOrMeta(event) && event.keyCode == 222 /* single quote */)
- InspectorOverlayHost.send("stepOver");
-});
-
-</script>
-</head>
-
-<body class="fill">
- <div class="controls-line">
- <div class="message-box"><div id="paused-in-debugger"></div></div>
- <div class="button" id="resume-button" title="Resume script execution (F8)."><div class="glyph"></div></div>
- <div class="button" id="step-over-button" title="Step over next function call (F10)."><div class="glyph"></div></div>
- </div>
-</body>
-</html>
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspect_tool_screenshot.html b/chromium/third_party/blink/renderer/core/inspector/inspect_tool_screenshot.html
deleted file mode 100644
index 8517bfb950b..00000000000
--- a/chromium/third_party/blink/renderer/core/inspector/inspect_tool_screenshot.html
+++ /dev/null
@@ -1,102 +0,0 @@
-<!--
- Copyright 2019 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file.
--->
-<!DOCTYPE html>
-<html>
-<head>
-<script src="inspect_tool_common.js"></script>
-<link rel="stylesheet" href="inspect_tool_common.css">
-<style>
-body {
- cursor: crosshair;
-}
-#zone {
- background-color: #0003;
- border: 1px solid #fffd;
- display: none;
- position: absolute;
-}
-</style>
-<script>
-
-let anchor = null;
-let position = null;
-
-function currentRect() {
- return {
- x: Math.min(anchor.x, position.x),
- y: Math.min(anchor.y, position.y),
- width: Math.abs(anchor.x - position.x),
- height: Math.abs(anchor.y - position.y)
- };
-}
-
-function updateZone()
-{
- const zone = document.getElementById('zone');
- if (!position || !anchor) {
- zone.style.display = 'none';
- return;
- }
- zone.style.display = 'block';
- const rect = currentRect();
- zone.style.left = rect.x + 'px';
- zone.style.top = rect.y + 'px';
- zone.style.width = rect.width + 'px';
- zone.style.height = rect.height + 'px';
-}
-
-function cancel() {
- anchor = null;
- position = null;
-}
-
-function loaded() {
- document.documentElement.addEventListener('mousedown', event => {
- anchor = { x: event.pageX, y: event.pageY };
- position = anchor;
- updateZone();
- event.stopPropagation();
- event.preventDefault();
- }, true);
-
- document.documentElement.addEventListener('mouseup', event => {
- if (anchor && position) {
- const rect = currentRect();
- if (rect.width >= 5 && rect.height >= 5)
- InspectorOverlayHost.send(JSON.stringify(rect));
- }
- cancel();
- updateZone();
- event.stopPropagation();
- event.preventDefault();
- }, true);
-
- document.documentElement.addEventListener('mousemove', event => {
- if (anchor && event.buttons === 1)
- position = { x: event.pageX, y: event.pageY };
- else
- anchor = null;
- updateZone();
- event.stopPropagation();
- event.preventDefault();
- }, true);
-
- document.documentElement.addEventListener('keydown', event => {
- if (anchor && event.key === 'Escape') {
- cancel();
- updateZone();
- event.stopPropagation();
- event.preventDefault();
- }
- }, true);
-}
-
-</script>
-</head>
-<body class="fill" onload="loaded()">
- <div id="zone"></div>
-</body>
-</html>
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspect_tool_viewport_size.html b/chromium/third_party/blink/renderer/core/inspector/inspect_tool_viewport_size.html
deleted file mode 100644
index bb0f3731a83..00000000000
--- a/chromium/third_party/blink/renderer/core/inspector/inspect_tool_viewport_size.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!--
- Copyright 2019 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file.
--->
-<!DOCTYPE html>
-<html>
-<head>
-<script>
-
-const darkGridColor = "rgba(0,0,0,0.7)";
-const gridBackgroundColor = "rgba(255, 255, 255, 0.8)";
-
-function drawViewSize()
-{
- const text = `${viewportSize.width}px \u00D7 ${viewportSize.height}px`;
- context.save();
- context.font = `14px ${window.getComputedStyle(document.body).fontFamily}`;
- const textWidth = context.measureText(text).width;
- context.fillStyle = gridBackgroundColor;
- context.fillRect(canvasWidth - textWidth - 12, 0, canvasWidth, 25);
- context.fillStyle = darkGridColor;
- context.fillText(text, canvasWidth - textWidth - 6, 18);
- context.restore();
-}
-
-</script>
-</head>
-<body class="fill">
- <canvas id="canvas" class="fill"></canvas>
-</body>
-</html>
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspect_tools.cc b/chromium/third_party/blink/renderer/core/inspector/inspect_tools.cc
index 502c7676fca..f3eecc89caa 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspect_tools.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspect_tools.cc
@@ -9,7 +9,7 @@
#include "third_party/blink/public/common/input/web_keyboard_event.h"
#include "third_party/blink/public/common/input/web_pointer_event.h"
#include "third_party/blink/public/platform/web_input_event_result.h"
-#include "third_party/blink/public/resources/grit/blink_resources.h"
+#include "third_party/blink/public/resources/grit/inspector_overlay_resources_map.h"
#include "third_party/blink/renderer/core/css/css_color_value.h"
#include "third_party/blink/renderer/core/css/css_computed_style_declaration.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
@@ -115,7 +115,7 @@ SearchingForNodeTool::SearchingForNodeTool(InspectorDOMAgent* dom_agent,
InspectorOverlayAgent::ToHighlightConfig(highlight_config.get());
}
-void SearchingForNodeTool::Trace(Visitor* visitor) {
+void SearchingForNodeTool::Trace(Visitor* visitor) const {
InspectTool::Trace(visitor);
visitor->Trace(dom_agent_);
visitor->Trace(hovered_node_);
@@ -286,7 +286,7 @@ NodeHighlightTool::NodeHighlightTool(
} else {
node_ = node;
}
- contrast_info_ = FetchContrast(node);
+ contrast_info_ = FetchContrast(node_);
}
bool NodeHighlightTool::ForwardEventsToOverlay() {
@@ -311,11 +311,10 @@ void NodeHighlightTool::DrawNode() {
highlight_config_->show_info &&
node_->GetLayoutObject() &&
node_->GetDocument().GetFrame();
- InspectorHighlight highlight(node_.Get(), *highlight_config_, contrast_info_,
- append_element_info, false, is_locked_ancestor_);
- std::unique_ptr<protocol::DictionaryValue> highlight_json =
- highlight.AsProtocolValue();
- overlay_->EvaluateInOverlay("drawHighlight", std::move(highlight_json));
+ overlay_->EvaluateInOverlay(
+ "drawHighlight",
+ GetNodeInspectorHighlightAsJson(append_element_info,
+ false /* append_distance_info */));
}
void NodeHighlightTool::DrawMatchingSelector() {
@@ -343,15 +342,25 @@ void NodeHighlightTool::DrawMatchingSelector() {
}
}
-void NodeHighlightTool::Trace(Visitor* visitor) {
+void NodeHighlightTool::Trace(Visitor* visitor) const {
InspectTool::Trace(visitor);
visitor->Trace(node_);
}
+std::unique_ptr<protocol::DictionaryValue>
+NodeHighlightTool::GetNodeInspectorHighlightAsJson(
+ bool append_element_info,
+ bool append_distance_info) const {
+ InspectorHighlight highlight(node_.Get(), *highlight_config_, contrast_info_,
+ append_element_info, append_distance_info,
+ is_locked_ancestor_);
+ return highlight.AsProtocolValue();
+}
+
// NearbyDistanceTool ----------------------------------------------------------
int NearbyDistanceTool::GetDataResourceId() {
- return IDR_INSPECT_TOOL_DISTANCES_HTML;
+ return IDR_INSPECT_TOOL_DISTANCES_JS;
}
bool NearbyDistanceTool::HandleMouseDown(const WebMouseEvent& event,
@@ -409,7 +418,7 @@ void NearbyDistanceTool::Draw(float scale) {
overlay_->EvaluateInOverlay("drawDistances", highlight.AsProtocolValue());
}
-void NearbyDistanceTool::Trace(Visitor* visitor) {
+void NearbyDistanceTool::Trace(Visitor* visitor) const {
InspectTool::Trace(visitor);
visitor->Trace(hovered_node_);
}
@@ -421,7 +430,7 @@ void ShowViewSizeTool::Draw(float scale) {
}
int ShowViewSizeTool::GetDataResourceId() {
- return IDR_INSPECT_TOOL_VIEWPORT_SIZE_HTML;
+ return IDR_INSPECT_TOOL_VIEWPORT_SIZE_JS;
}
bool ShowViewSizeTool::ForwardEventsToOverlay() {
@@ -438,7 +447,7 @@ void ScreenshotTool::DoInit() {
}
int ScreenshotTool::GetDataResourceId() {
- return IDR_INSPECT_TOOL_SCREENSHOT_HTML;
+ return IDR_INSPECT_TOOL_SCREENSHOT_JS;
}
void ScreenshotTool::Dispatch(const String& message) {
@@ -521,7 +530,7 @@ void ScreenshotTool::Dispatch(const String& message) {
// PausedInDebuggerTool --------------------------------------------------------
int PausedInDebuggerTool::GetDataResourceId() {
- return IDR_INSPECT_TOOL_PAUSED_HTML;
+ return IDR_INSPECT_TOOL_PAUSED_JS;
}
void PausedInDebuggerTool::Draw(float scale) {
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspect_tools.h b/chromium/third_party/blink/renderer/core/inspector/inspect_tools.h
index 3d19e9ada1b..4d096c5547b 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspect_tools.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspect_tools.h
@@ -34,7 +34,7 @@ class SearchingForNodeTool : public InspectTool {
bool HandlePointerEvent(const WebPointerEvent&) override;
void Draw(float scale) override;
void NodeHighlightRequested(Node*);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
Member<InspectorDOMAgent> dom_agent_;
bool ua_shadow_;
@@ -73,6 +73,10 @@ class NodeHighlightTool : public InspectTool {
String selector_list,
std::unique_ptr<InspectorHighlightConfig> highlight_config);
+ std::unique_ptr<protocol::DictionaryValue> GetNodeInspectorHighlightAsJson(
+ bool append_element_info,
+ bool append_distance_info) const;
+
private:
bool ForwardEventsToOverlay() override;
bool HideOnMouseMove() override;
@@ -80,7 +84,7 @@ class NodeHighlightTool : public InspectTool {
void Draw(float scale) override;
void DrawNode();
void DrawMatchingSelector();
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
bool is_locked_ancestor_ = false;
Member<Node> node_;
@@ -103,7 +107,7 @@ class NearbyDistanceTool : public InspectTool {
bool HandleMouseMove(const WebMouseEvent& event) override;
bool HandleMouseUp(const WebMouseEvent& event) override;
void Draw(float scale) override;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
Member<Node> hovered_node_;
DISALLOW_COPY_AND_ASSIGN(NearbyDistanceTool);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspected_frames.cc b/chromium/third_party/blink/renderer/core/inspector/inspected_frames.cc
index c795f484df2..5616a748c25 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspected_frames.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspected_frames.cc
@@ -68,7 +68,7 @@ bool InspectedFrames::Iterator::operator!=(const Iterator& other) {
return !(*this == other);
}
-void InspectedFrames::Trace(Visitor* visitor) {
+void InspectedFrames::Trace(Visitor* visitor) const {
visitor->Trace(root_);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspected_frames.h b/chromium/third_party/blink/renderer/core/inspector/inspected_frames.h
index b35d35a3b75..763bc91531b 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspected_frames.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspected_frames.h
@@ -44,7 +44,7 @@ class CORE_EXPORT InspectedFrames final
Iterator begin();
Iterator end();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
Member<LocalFrame> root_;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc
index 734a3349e14..1a052a4e082 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc
@@ -447,7 +447,7 @@ String InspectorAnimationAgent::CreateCSSId(blink::Animation& animation) {
css_agent_->FindEffectiveDeclaration(*property, styles);
// Ignore inline styles.
if (!style || !style->ParentStyleSheet() || !style->parentRule() ||
- style->parentRule()->type() != CSSRule::kStyleRule)
+ style->parentRule()->GetType() != CSSRule::kStyleRule)
continue;
digestor.UpdateUtf8(property->GetPropertyNameString());
digestor.UpdateUtf8(css_agent_->StyleSheetId(style->ParentStyleSheet()));
@@ -527,7 +527,7 @@ double InspectorAnimationAgent::NormalizedStartTime(
return std::round(time_ms * 1000) / 1000;
}
-void InspectorAnimationAgent::Trace(Visitor* visitor) {
+void InspectorAnimationAgent::Trace(Visitor* visitor) const {
visitor->Trace(inspected_frames_);
visitor->Trace(css_agent_);
visitor->Trace(id_to_animation_);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_animation_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_animation_agent.h
index 1f1a11309b5..4cf66c2b5d0 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_animation_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_animation_agent.h
@@ -65,7 +65,7 @@ class CORE_EXPORT InspectorAnimationAgent final
protocol::Response AssertAnimation(const String& id,
blink::Animation*& result);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
using AnimationType = protocol::Animation::Animation::TypeEnum;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.cc
index 500adaefe95..0ad663e5356 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.cc
@@ -223,7 +223,7 @@ InspectorApplicationCacheAgent::BuildObjectForApplicationCacheResource(
return value;
}
-void InspectorApplicationCacheAgent::Trace(Visitor* visitor) {
+void InspectorApplicationCacheAgent::Trace(Visitor* visitor) const {
visitor->Trace(inspected_frames_);
InspectorBaseAgent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.h
index c8961f23dc4..73e63e2dc1e 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.h
@@ -42,7 +42,7 @@ class CORE_EXPORT InspectorApplicationCacheAgent final
public:
explicit InspectorApplicationCacheAgent(InspectedFrames*);
~InspectorApplicationCacheAgent() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// InspectorBaseAgent
void Restore() override;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_audits_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_audits_agent.cc
index de81a8e3df5..f6f7705fba6 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_audits_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_audits_agent.cc
@@ -66,7 +66,7 @@ bool EncodeAsImage(char* body,
} // namespace
-void InspectorAuditsAgent::Trace(Visitor* visitor) {
+void InspectorAuditsAgent::Trace(Visitor* visitor) const {
visitor->Trace(network_agent_);
visitor->Trace(inspector_issue_storage_);
InspectorBaseAgent::Trace(visitor);
@@ -187,6 +187,8 @@ blink::protocol::String InspectorIssueCodeValue(
return protocol::Audits::InspectorIssueCodeEnum::SameSiteCookieIssue;
case mojom::blink::InspectorIssueCode::kMixedContentIssue:
return protocol::Audits::InspectorIssueCodeEnum::MixedContentIssue;
+ case mojom::blink::InspectorIssueCode::kBlockedByResponseIssue:
+ return protocol::Audits::InspectorIssueCodeEnum::BlockedByResponseIssue;
}
}
@@ -194,11 +196,11 @@ protocol::String BuildCookieExclusionReason(
mojom::blink::SameSiteCookieExclusionReason exclusion_reason) {
switch (exclusion_reason) {
case blink::mojom::blink::SameSiteCookieExclusionReason::
- ExcludeSameSiteUnspecifiedTreatedAsLax:
+ kExcludeSameSiteUnspecifiedTreatedAsLax:
return protocol::Audits::SameSiteCookieExclusionReasonEnum::
ExcludeSameSiteUnspecifiedTreatedAsLax;
case blink::mojom::blink::SameSiteCookieExclusionReason::
- ExcludeSameSiteNoneInsecure:
+ kExcludeSameSiteNoneInsecure:
return protocol::Audits::SameSiteCookieExclusionReasonEnum::
ExcludeSameSiteNoneInsecure;
}
@@ -220,35 +222,35 @@ protocol::String BuildCookieWarningReason(
mojom::blink::SameSiteCookieWarningReason warning_reason) {
switch (warning_reason) {
case blink::mojom::blink::SameSiteCookieWarningReason::
- WarnSameSiteUnspecifiedCrossSiteContext:
+ kWarnSameSiteUnspecifiedCrossSiteContext:
return protocol::Audits::SameSiteCookieWarningReasonEnum::
WarnSameSiteUnspecifiedCrossSiteContext;
case blink::mojom::blink::SameSiteCookieWarningReason::
- WarnSameSiteNoneInsecure:
+ kWarnSameSiteNoneInsecure:
return protocol::Audits::SameSiteCookieWarningReasonEnum::
WarnSameSiteNoneInsecure;
case blink::mojom::blink::SameSiteCookieWarningReason::
- WarnSameSiteUnspecifiedLaxAllowUnsafe:
+ kWarnSameSiteUnspecifiedLaxAllowUnsafe:
return protocol::Audits::SameSiteCookieWarningReasonEnum::
WarnSameSiteUnspecifiedLaxAllowUnsafe;
case blink::mojom::blink::SameSiteCookieWarningReason::
- WarnSameSiteStrictLaxDowngradeStrict:
+ kWarnSameSiteStrictLaxDowngradeStrict:
return protocol::Audits::SameSiteCookieWarningReasonEnum::
WarnSameSiteStrictLaxDowngradeStrict;
case blink::mojom::blink::SameSiteCookieWarningReason::
- WarnSameSiteStrictCrossDowngradeStrict:
+ kWarnSameSiteStrictCrossDowngradeStrict:
return protocol::Audits::SameSiteCookieWarningReasonEnum::
WarnSameSiteStrictCrossDowngradeStrict;
case blink::mojom::blink::SameSiteCookieWarningReason::
- WarnSameSiteStrictCrossDowngradeLax:
+ kWarnSameSiteStrictCrossDowngradeLax:
return protocol::Audits::SameSiteCookieWarningReasonEnum::
WarnSameSiteStrictCrossDowngradeLax;
case blink::mojom::blink::SameSiteCookieWarningReason::
- WarnSameSiteLaxCrossDowngradeStrict:
+ kWarnSameSiteLaxCrossDowngradeStrict:
return protocol::Audits::SameSiteCookieWarningReasonEnum::
WarnSameSiteLaxCrossDowngradeStrict;
case blink::mojom::blink::SameSiteCookieWarningReason::
- WarnSameSiteLaxCrossDowngradeLax:
+ kWarnSameSiteLaxCrossDowngradeLax:
return protocol::Audits::SameSiteCookieWarningReasonEnum::
WarnSameSiteLaxCrossDowngradeLax;
}
@@ -267,9 +269,9 @@ std::unique_ptr<std::vector<blink::protocol::String>> BuildCookieWarningReasons(
protocol::String BuildCookieOperation(
mojom::blink::SameSiteCookieOperation operation) {
switch (operation) {
- case blink::mojom::blink::SameSiteCookieOperation::SetCookie:
+ case blink::mojom::blink::SameSiteCookieOperation::kSetCookie:
return protocol::Audits::SameSiteCookieOperationEnum::SetCookie;
- case blink::mojom::blink::SameSiteCookieOperation::ReadCookie:
+ case blink::mojom::blink::SameSiteCookieOperation::kReadCookie:
return protocol::Audits::SameSiteCookieOperationEnum::ReadCookie;
}
}
@@ -277,14 +279,16 @@ protocol::String BuildCookieOperation(
protocol::String BuildMixedContentResolutionStatus(
mojom::blink::MixedContentResolutionStatus resolution_type) {
switch (resolution_type) {
- case blink::mojom::blink::MixedContentResolutionStatus::MixedContentBlocked:
+ case blink::mojom::blink::MixedContentResolutionStatus::
+ kMixedContentBlocked:
return protocol::Audits::MixedContentResolutionStatusEnum::
MixedContentBlocked;
case blink::mojom::blink::MixedContentResolutionStatus::
- MixedContentAutomaticallyUpgraded:
+ kMixedContentAutomaticallyUpgraded:
return protocol::Audits::MixedContentResolutionStatusEnum::
MixedContentAutomaticallyUpgraded;
- case blink::mojom::blink::MixedContentResolutionStatus::MixedContentWarning:
+ case blink::mojom::blink::MixedContentResolutionStatus::
+ kMixedContentWarning:
return protocol::Audits::MixedContentResolutionStatusEnum::
MixedContentWarning;
}
@@ -364,19 +368,41 @@ protocol::String BuildMixedContentResourceType(
}
}
+protocol::String BuildBlockedByResponseReason(
+ network::mojom::blink::BlockedByResponseReason reason) {
+ switch (reason) {
+ case network::mojom::blink::BlockedByResponseReason::
+ kCoepFrameResourceNeedsCoepHeader:
+ return protocol::Audits::BlockedByResponseReasonEnum::
+ CoepFrameResourceNeedsCoepHeader;
+ case network::mojom::blink::BlockedByResponseReason::
+ kCoopSandboxedIFrameCannotNavigateToCoopPage:
+ return protocol::Audits::BlockedByResponseReasonEnum::
+ CoopSandboxedIFrameCannotNavigateToCoopPage;
+ case network::mojom::blink::BlockedByResponseReason::kCorpNotSameOrigin:
+ return protocol::Audits::BlockedByResponseReasonEnum::CorpNotSameOrigin;
+ case network::mojom::blink::BlockedByResponseReason::
+ kCorpNotSameOriginAfterDefaultedToSameOriginByCoep:
+ return protocol::Audits::BlockedByResponseReasonEnum::
+ CorpNotSameOriginAfterDefaultedToSameOriginByCoep;
+ case network::mojom::blink::BlockedByResponseReason::kCorpNotSameSite:
+ return protocol::Audits::BlockedByResponseReasonEnum::CorpNotSameSite;
+ }
+}
+
} // namespace
void InspectorAuditsAgent::InspectorIssueAdded(InspectorIssue* issue) {
auto issueDetails = protocol::Audits::InspectorIssueDetails::create();
- if (const auto* d = issue->Details()->sameSiteCookieIssueDetails.get()) {
+ if (const auto* d = issue->Details()->samesite_cookie_issue_details.get()) {
auto sameSiteCookieDetails =
std::move(protocol::Audits::SameSiteCookieIssueDetails::create()
.setCookie(BuildAffectedCookie(d->cookie))
.setCookieExclusionReasons(
- BuildCookieExclusionReasons(d->exclusionReason))
+ BuildCookieExclusionReasons(d->exclusion_reason))
.setCookieWarningReasons(
- BuildCookieWarningReasons(d->warningReason))
+ BuildCookieWarningReasons(d->warning_reason))
.setOperation(BuildCookieOperation(d->operation)));
if (d->site_for_cookies) {
@@ -409,6 +435,20 @@ void InspectorAuditsAgent::InspectorIssueAdded(InspectorIssue* issue) {
issueDetails.setMixedContentIssueDetails(std::move(mixedContentDetails));
}
+ if (const auto* d =
+ issue->Details()->blocked_by_response_issue_details.get()) {
+ auto blockedByResponseDetails =
+ protocol::Audits::BlockedByResponseIssueDetails::create()
+ .setRequest(BuildAffectedRequest(d->request))
+ .setReason(BuildBlockedByResponseReason(d->reason))
+ .build();
+ if (d->frame) {
+ blockedByResponseDetails->setFrame(BuildAffectedFrame(d->frame));
+ }
+ issueDetails.setBlockedByResponseIssueDetails(
+ std::move(blockedByResponseDetails));
+ }
+
auto inspector_issue = protocol::Audits::InspectorIssue::create()
.setCode(InspectorIssueCodeValue(issue->Code()))
.setDetails(issueDetails.build())
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_audits_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_audits_agent.h
index d03ee4bc9ee..586a3919e36 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_audits_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_audits_agent.h
@@ -21,7 +21,7 @@ class CORE_EXPORT InspectorAuditsAgent final
explicit InspectorAuditsAgent(InspectorNetworkAgent*, InspectorIssueStorage*);
~InspectorAuditsAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void InspectorIssueAdded(InspectorIssue*);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_base_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_base_agent.h
index fb5e6fb135e..6b7b8bbc4a3 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_base_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_base_agent.h
@@ -47,7 +47,7 @@ class CORE_EXPORT InspectorAgent : public GarbageCollected<InspectorAgent> {
public:
InspectorAgent() = default;
virtual ~InspectorAgent() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
virtual void Restore() {}
virtual void DidCommitLoadForLocalFrame(LocalFrame*) {}
@@ -86,7 +86,7 @@ class InspectorBaseAgent : public InspectorAgent,
instrumenting_agents_ = nullptr;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(instrumenting_agents_);
InspectorAgent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_css_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
index ef7c1ca3a0a..334d2a89370 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
@@ -62,6 +62,7 @@
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
#include "third_party/blink/renderer/core/dom/node.h"
+#include "third_party/blink/renderer/core/dom/pseudo_element.h"
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
@@ -419,7 +420,7 @@ class InspectorCSSAgent::SetStyleSheetTextAction final
text_ = other->text_;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(style_sheet_);
InspectorCSSAgent::StyleSheetAction::Trace(visitor);
}
@@ -517,7 +518,7 @@ class InspectorCSSAgent::ModifyRuleAction final
return nullptr;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(style_sheet_);
visitor->Trace(css_rule_);
InspectorCSSAgent::StyleSheetAction::Trace(visitor);
@@ -572,7 +573,7 @@ class InspectorCSSAgent::SetElementStyleAction final
return style_sheet_->SetText(text_, exception_state);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(style_sheet_);
InspectorCSSAgent::StyleSheetAction::Trace(visitor);
}
@@ -635,7 +636,7 @@ class InspectorCSSAgent::AddRuleAction final
return result;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(style_sheet_);
visitor->Trace(css_rule_);
InspectorCSSAgent::StyleSheetAction::Trace(visitor);
@@ -918,8 +919,8 @@ Response InspectorCSSAgent::getMediaQueries(
const CSSRuleVector& flat_rules = style_sheet->FlatRules();
for (unsigned i = 0; i < flat_rules.size(); ++i) {
CSSRule* rule = flat_rules.at(i).Get();
- if (rule->type() == CSSRule::kMediaRule ||
- rule->type() == CSSRule::kImportRule)
+ if (rule->GetType() == CSSRule::kMediaRule ||
+ rule->GetType() == CSSRule::kImportRule)
CollectMediaQueriesFromRule(rule, medias->get());
}
}
@@ -959,6 +960,13 @@ Response InspectorCSSAgent::getMatchedStylesForNode(
if (!owner_document->IsActive())
return Response::ServerError("Document is not active");
+ // The source text of mutable stylesheets needs to be updated
+ // to sync the latest changes.
+ for (InspectorStyleSheet* stylesheet :
+ css_style_sheet_to_inspector_style_sheet_.Values()) {
+ stylesheet->SyncTextIfNeeded();
+ }
+
// FIXME: It's really gross for the inspector to reach in and access
// StyleResolver directly here. We need to provide the Inspector better APIs
// to get this information without grabbing at internal style classes!
@@ -988,8 +996,15 @@ Response InspectorCSSAgent::getMatchedStylesForNode(
for (PseudoId pseudo_id = kFirstPublicPseudoId;
pseudo_id < kAfterLastInternalPseudoId;
pseudo_id = static_cast<PseudoId>(pseudo_id + 1)) {
+ if (!PseudoElement::IsWebExposed(pseudo_id, element))
+ continue;
+ // If the pseudo-element doesn't exist, exclude UA rules to avoid cluttering
+ // all elements.
+ unsigned rules_to_include = element->GetPseudoElement(pseudo_id)
+ ? StyleResolver::kAllCSSRules
+ : StyleResolver::kAllButUACSSRules;
RuleIndexList* matched_rules = style_resolver.PseudoCSSRulesForElement(
- element, pseudo_id, StyleResolver::kAllCSSRules);
+ element, pseudo_id, rules_to_include);
if (matched_rules && matched_rules->size()) {
pseudo_id_matches->fromJust()->emplace_back(
protocol::CSS::PseudoElementMatches::create()
@@ -1680,6 +1695,8 @@ Response InspectorCSSAgent::forcePseudoState(
void InspectorCSSAgent::IncrementFocusedCountForAncestors(Element* element) {
for (Node& ancestor : FlatTreeTraversal::AncestorsOf(*element)) {
+ if (!IsA<Element>(ancestor))
+ continue;
int node_id = dom_agent_->BoundNodeId(&ancestor);
if (!node_id)
continue;
@@ -1693,6 +1710,8 @@ void InspectorCSSAgent::IncrementFocusedCountForAncestors(Element* element) {
void InspectorCSSAgent::DecrementFocusedCountForAncestors(Element* element) {
for (Node& ancestor : FlatTreeTraversal::AncestorsOf(*element)) {
+ if (!IsA<Element>(ancestor))
+ continue;
int node_id = dom_agent_->BoundNodeId(&ancestor);
if (!node_id)
continue;
@@ -2207,6 +2226,15 @@ void InspectorCSSAgent::DidModifyDOMAttr(Element* element) {
it->value->DidModifyElementAttribute();
}
+void InspectorCSSAgent::DidMutateStyleSheet(CSSStyleSheet* css_style_sheet) {
+ InspectorStyleSheet* style_sheet =
+ css_style_sheet_to_inspector_style_sheet_.at(css_style_sheet);
+ if (!style_sheet)
+ return;
+ style_sheet->MarkForSync();
+ StyleSheetChanged(style_sheet);
+}
+
void InspectorCSSAgent::StyleSheetChanged(
InspectorStyleSheetBase* style_sheet) {
if (g_frontend_operation_counter)
@@ -2534,7 +2562,7 @@ Response InspectorCSSAgent::takeCoverageDelta(
HeapHashMap<Member<const StyleRule>, Member<CSSStyleRule>> rule_to_css_rule;
const CSSRuleVector& css_rules = style_sheet->FlatRules();
for (auto css_rule : css_rules) {
- if (css_rule->type() != CSSRule::kStyleRule)
+ if (css_rule->GetType() != CSSRule::kStyleRule)
continue;
CSSStyleRule* css_style_rule = AsCSSStyleRule(css_rule);
rule_to_css_rule.Set(css_style_rule->GetStyleRule(), css_style_rule);
@@ -2551,7 +2579,7 @@ Response InspectorCSSAgent::takeCoverageDelta(
return Response::Success();
}
-void InspectorCSSAgent::Trace(Visitor* visitor) {
+void InspectorCSSAgent::Trace(Visitor* visitor) const {
visitor->Trace(dom_agent_);
visitor->Trace(inspected_frames_);
visitor->Trace(network_agent_);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_css_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_css_agent.h
index 449b85ea315..d8be0cfa4b2 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_css_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_css_agent.h
@@ -109,7 +109,7 @@ class CORE_EXPORT InspectorCSSAgent final
InspectorResourceContentLoader*,
InspectorResourceContainer*);
~InspectorCSSAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void ForcePseudoState(Element*, CSSSelector::PseudoType, bool* result);
void DidCommitLoadForLocalFrame(LocalFrame*) override;
@@ -125,6 +125,7 @@ class CORE_EXPORT InspectorCSSAgent final
const FontCustomPlatformData*);
void SetCoverageEnabled(bool);
void WillChangeStyleElement(Element*);
+ void DidMutateStyleSheet(CSSStyleSheet* css_style_sheet);
void enable(std::unique_ptr<EnableCallback>) override;
protocol::Response disable() override;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
index bcf226243cf..403cf2e9703 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
@@ -110,7 +110,7 @@ class InspectorRevalidateDOMTask final
void ScheduleStyleAttrRevalidationFor(Element*);
void Reset() { timer_.Stop(); }
void OnTimer(TimerBase*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<InspectorDOMAgent> dom_agent_;
@@ -143,7 +143,7 @@ void InspectorRevalidateDOMTask::OnTimer(TimerBase*) {
style_attr_invalidated_elements_.clear();
}
-void InspectorRevalidateDOMTask::Trace(Visitor* visitor) {
+void InspectorRevalidateDOMTask::Trace(Visitor* visitor) const {
visitor->Trace(dom_agent_);
visitor->Trace(style_attr_invalidated_elements_);
}
@@ -1673,18 +1673,14 @@ std::unique_ptr<protocol::Array<protocol::DOM::Node>>
InspectorDOMAgent::BuildArrayForPseudoElements(Element* element,
NodeToIdMap* nodes_map) {
protocol::Array<protocol::DOM::Node> pseudo_elements;
- if (element->GetPseudoElement(kPseudoIdBefore)) {
- pseudo_elements.emplace_back(BuildObjectForNode(
- element->GetPseudoElement(kPseudoIdBefore), 0, false, nodes_map));
- }
- if (element->GetPseudoElement(kPseudoIdAfter)) {
- pseudo_elements.emplace_back(BuildObjectForNode(
- element->GetPseudoElement(kPseudoIdAfter), 0, false, nodes_map));
- }
- if (element->GetPseudoElement(kPseudoIdMarker) &&
- RuntimeEnabledFeatures::CSSMarkerPseudoElementEnabled()) {
- pseudo_elements.emplace_back(BuildObjectForNode(
- element->GetPseudoElement(kPseudoIdMarker), 0, false, nodes_map));
+ for (PseudoId pseudo_id :
+ {kPseudoIdBefore, kPseudoIdAfter, kPseudoIdMarker}) {
+ if (!PseudoElement::IsWebExposed(pseudo_id, element))
+ continue;
+ if (PseudoElement* pseudo_element = element->GetPseudoElement(pseudo_id)) {
+ pseudo_elements.emplace_back(
+ BuildObjectForNode(pseudo_element, 0, false, nodes_map));
+ }
}
if (pseudo_elements.empty())
return nullptr;
@@ -2096,13 +2092,11 @@ void InspectorDOMAgent::FrameOwnerContentUpdated(
}
void InspectorDOMAgent::PseudoElementCreated(PseudoElement* pseudo_element) {
- if (pseudo_element->IsMarkerPseudoElement() &&
- !RuntimeEnabledFeatures::CSSMarkerPseudoElementEnabled()) {
- return;
- }
Element* parent = pseudo_element->ParentOrShadowHostElement();
if (!parent)
return;
+ if (!PseudoElement::IsWebExposed(pseudo_element->GetPseudoId(), parent))
+ return;
int parent_id = document_node_to_id_map_->at(parent);
if (!parent_id)
return;
@@ -2379,7 +2373,7 @@ Response InspectorDOMAgent::getFileInfo(const String& object_id, String* path) {
return Response::Success();
}
-void InspectorDOMAgent::Trace(Visitor* visitor) {
+void InspectorDOMAgent::Trace(Visitor* visitor) const {
visitor->Trace(dom_listener_);
visitor->Trace(inspected_frames_);
visitor->Trace(document_node_to_id_map_);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_dom_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_dom_agent.h
index 689a068d888..c7534309ced 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_dom_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_dom_agent.h
@@ -87,7 +87,7 @@ class CORE_EXPORT InspectorDOMAgent final
: source_location_(std::move(source_location)) {}
SourceLocation& GetSourceLocation() { return *source_location_; }
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
private:
std::unique_ptr<SourceLocation> source_location_;
@@ -103,7 +103,7 @@ class CORE_EXPORT InspectorDOMAgent final
InspectedFrames*,
v8_inspector::V8InspectorSession*);
~InspectorDOMAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Restore() override;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_dom_debugger_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_dom_debugger_agent.cc
index 1889e2eede6..4f7c2427461 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_dom_debugger_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_dom_debugger_agent.cc
@@ -214,7 +214,7 @@ InspectorDOMDebuggerAgent::InspectorDOMDebuggerAgent(
InspectorDOMDebuggerAgent::~InspectorDOMDebuggerAgent() = default;
-void InspectorDOMDebuggerAgent::Trace(Visitor* visitor) {
+void InspectorDOMDebuggerAgent::Trace(Visitor* visitor) const {
visitor->Trace(dom_agent_);
visitor->Trace(dom_breakpoints_);
InspectorBaseAgent::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_dom_debugger_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_dom_debugger_agent.h
index 96708618d24..7ea3296e52e 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_dom_debugger_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_dom_debugger_agent.h
@@ -67,7 +67,7 @@ class CORE_EXPORT InspectorDOMDebuggerAgent final
InspectorDOMAgent*,
v8_inspector::V8InspectorSession*);
~InspectorDOMDebuggerAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// DOMDebugger API for frontend
protocol::Response setDOMBreakpoint(int node_id, const String& type) override;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc
index 42755c8a650..eceeb3435d6 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc
@@ -317,13 +317,14 @@ protocol::Response InspectorDOMSnapshotAgent::captureSnapshot(
protocol::Array<protocol::DOMSnapshot::DocumentSnapshot>>();
css_property_filter_ = std::make_unique<CSSPropertyFilter>();
- // Look up the CSSPropertyIDs for each entry in |computed_styles|.
- for (String& entry : *computed_styles) {
- CSSPropertyID property_id = cssPropertyID(main_window, entry);
- if (property_id == CSSPropertyID::kInvalid)
- continue;
- css_property_filter_->emplace_back(std::move(entry),
- std::move(property_id));
+ // Resolve all property names to CSSProperty references.
+ for (String& property_name : *computed_styles) {
+ const CSSPropertyID id =
+ unresolvedCSSPropertyID(main_window, property_name);
+ if (id == CSSPropertyID::kInvalid || id == CSSPropertyID::kVariable)
+ return Response::InvalidParams("invalid CSS property");
+ const auto& property = CSSProperty::Get(resolveCSSPropertyID(id));
+ css_property_filter_->push_back(&property);
}
if (include_paint_order.fromMaybe(false)) {
@@ -350,6 +351,8 @@ protocol::Response InspectorDOMSnapshotAgent::captureSnapshot(
string_table_.clear();
document_order_map_.clear();
documents_.reset();
+ css_value_cache_.clear();
+ style_cache_.clear();
return Response::Success();
}
@@ -396,7 +399,7 @@ void InspectorDOMSnapshotAgent::VisitDocument(Document* document) {
// order was calculated, since layout trees were already updated during
// TraversePaintLayerTree().
if (!paint_order_map_)
- document->UpdateStyleAndLayout(DocumentUpdateReason::kInspector);
+ document->UpdateStyleAndLayoutTreeForSubtree(document);
DocumentType* doc_type = document->doctype();
@@ -643,7 +646,7 @@ int InspectorDOMSnapshotAgent::BuildLayoutTreeNode(LayoutObject* layout_object,
}
}
- if (layout_object->Style() && layout_object->Style()->IsStackingContext())
+ if (layout_object->IsStackingContext())
SetRare(layout_tree_snapshot->getStackingContexts(), layout_index);
if (paint_order_map_) {
@@ -690,12 +693,37 @@ int InspectorDOMSnapshotAgent::BuildLayoutTreeNode(LayoutObject* layout_object,
std::unique_ptr<protocol::Array<int>>
InspectorDOMSnapshotAgent::BuildStylesForNode(Node* node) {
- auto* computed_style_info =
- MakeGarbageCollected<CSSComputedStyleDeclaration>(node, true);
+ DCHECK(
+ !node->GetDocument().NeedsLayoutTreeUpdateForNodeIncludingDisplayLocked(
+ *node, true /* ignore_adjacent_style */));
auto result = std::make_unique<protocol::Array<int>>();
- for (const auto& pair : *css_property_filter_) {
- String value = computed_style_info->GetPropertyValue(pair.second);
- result->emplace_back(AddString(value));
+ auto* layout_object = node->GetLayoutObject();
+ if (!layout_object)
+ return result;
+ const ComputedStyle* style = node->EnsureComputedStyle(kPseudoIdNone);
+ if (!style)
+ return result;
+ auto cached_style = style_cache_.find(style);
+ if (cached_style != style_cache_.end())
+ return std::make_unique<protocol::Array<int>>(*cached_style->value);
+ style_cache_.insert(style, result.get());
+ result->reserve(css_property_filter_->size());
+ for (const auto* property : *css_property_filter_) {
+ const CSSValue* value = property->CSSValueFromComputedStyle(
+ *style, layout_object, /* allow_visited_style= */ true);
+ if (!value) {
+ result->emplace_back(-1);
+ continue;
+ }
+ int index;
+ auto it = css_value_cache_.find(value);
+ if (it == css_value_cache_.end()) {
+ index = AddString(value->CssText());
+ css_value_cache_.insert(value, index);
+ } else {
+ index = it->value;
+ }
+ result->emplace_back(index);
}
return result;
}
@@ -714,7 +742,7 @@ void InspectorDOMSnapshotAgent::TraversePaintLayerTree(
PaintOrderMap* paint_order_map) {
// Update layout before traversal of document so that we inspect a
// current and consistent state of all trees.
- document->UpdateStyleAndLayout(DocumentUpdateReason::kInspector);
+ document->UpdateStyleAndLayoutTreeForSubtree(document);
PaintLayer* root_layer = document->GetLayoutView()->Layer();
// LayoutView requires a PaintLayer.
@@ -744,10 +772,11 @@ void InspectorDOMSnapshotAgent::VisitPaintLayer(
VisitPaintLayer(child_layer, paint_order_map);
}
-void InspectorDOMSnapshotAgent::Trace(Visitor* visitor) {
+void InspectorDOMSnapshotAgent::Trace(Visitor* visitor) const {
visitor->Trace(inspected_frames_);
visitor->Trace(dom_debugger_agent_);
visitor->Trace(document_order_map_);
+ visitor->Trace(css_value_cache_);
InspectorBaseAgent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h
index d5ef9a5cee7..5904b12782f 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h
@@ -17,6 +17,7 @@
namespace blink {
class CharacterData;
+class ComputedStyle;
class Document;
class Element;
class InspectedFrames;
@@ -28,7 +29,7 @@ class CORE_EXPORT InspectorDOMSnapshotAgent final
public:
InspectorDOMSnapshotAgent(InspectedFrames*, InspectorDOMDebuggerAgent*);
~InspectorDOMSnapshotAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Restore() override;
@@ -91,7 +92,7 @@ class CORE_EXPORT InspectorDOMSnapshotAgent final
static void TraversePaintLayerTree(Document*, PaintOrderMap* paint_order_map);
static void VisitPaintLayer(PaintLayer*, PaintOrderMap* paint_order_map);
- using CSSPropertyFilter = Vector<std::pair<String, CSSPropertyID>>;
+ using CSSPropertyFilter = Vector<const CSSProperty*>;
using OriginUrlMap = WTF::HashMap<DOMNodeId, String>;
// State of current snapshot.
@@ -104,6 +105,10 @@ class CORE_EXPORT InspectorDOMSnapshotAgent final
std::unique_ptr<protocol::Array<String>> strings_;
WTF::HashMap<String, int> string_table_;
+ HeapHashMap<Member<const CSSValue>, int> css_value_cache_;
+ HashMap<scoped_refptr<const ComputedStyle>, protocol::Array<int>*>
+ style_cache_;
+
std::unique_ptr<protocol::Array<protocol::DOMSnapshot::DocumentSnapshot>>
documents_;
std::unique_ptr<protocol::DOMSnapshot::DocumentSnapshot> document_;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc
index 843b8c340dd..4443df33c06 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc
@@ -664,7 +664,7 @@ Response InspectorEmulationAgent::AssertPage() {
return Response::Success();
}
-void InspectorEmulationAgent::Trace(Visitor* visitor) {
+void InspectorEmulationAgent::Trace(Visitor* visitor) const {
visitor->Trace(web_local_frame_);
InspectorBaseAgent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_emulation_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_emulation_agent.h
index e87627062f5..54dddfad8f2 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_emulation_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_emulation_agent.h
@@ -100,7 +100,7 @@ class CORE_EXPORT InspectorEmulationAgent final
protocol::Response disable() override;
void Restore() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
WebViewImpl* GetWebViewImpl();
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_highlight.cc
index e0b532a2b7b..c8895d62420 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_highlight.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -154,6 +154,28 @@ Path QuadToPath(const FloatQuad& quad) {
return quad_path;
}
+Path RowQuadToPath(const FloatQuad& quad, bool drawEndLine) {
+ Path quad_path;
+ quad_path.MoveTo(quad.P1());
+ quad_path.AddLineTo(quad.P2());
+ if (drawEndLine) {
+ quad_path.MoveTo(quad.P3());
+ quad_path.AddLineTo(quad.P4());
+ }
+ return quad_path;
+}
+
+Path ColumnQuadToPath(const FloatQuad& quad, bool drawEndLine) {
+ Path quad_path;
+ quad_path.MoveTo(quad.P1());
+ quad_path.AddLineTo(quad.P4());
+ if (drawEndLine) {
+ quad_path.MoveTo(quad.P3());
+ quad_path.AddLineTo(quad.P2());
+ }
+ return quad_path;
+}
+
FloatPoint FramePointToViewport(const LocalFrameView* view,
FloatPoint point_in_frame) {
FloatPoint point_in_root_frame = view->ConvertToRootFrame(point_in_frame);
@@ -309,11 +331,11 @@ std::unique_ptr<protocol::DictionaryValue> BuildElementInfo(Element* element) {
element_info->setString("nodeWidth", String::Number(bounding_box->width()));
element_info->setString("nodeHeight", String::Number(bounding_box->height()));
- element_info->setBoolean("showAccessibilityInfo", true);
element_info->setBoolean("isKeyboardFocusable",
element->IsKeyboardFocusable());
element_info->setString("accessibleName", element->computedName());
element_info->setString("accessibleRole", element->computedRole());
+
return element_info;
}
@@ -340,6 +362,10 @@ std::unique_ptr<protocol::DictionaryValue> BuildGridHighlightConfigInfo(
grid_config_info->setBoolean("cellBorderDash", grid_config.cell_border_dash);
grid_config_info->setBoolean("showGridExtensionLines",
grid_config.show_grid_extension_lines);
+ grid_config_info->setBoolean("showPositiveLineNumbers",
+ grid_config.show_positive_line_numbers);
+ grid_config_info->setBoolean("showNegativeLineNumbers",
+ grid_config.show_negative_line_numbers);
if (grid_config.grid_color != Color::kTransparent) {
grid_config_info->setString("gridBorderColor",
@@ -368,6 +394,73 @@ std::unique_ptr<protocol::DictionaryValue> BuildGridHighlightConfigInfo(
return grid_config_info;
}
+std::unique_ptr<protocol::ListValue> BuildGridPositiveLineNumberOffsets(
+ LayoutGrid* layout_grid,
+ const Vector<LayoutUnit>& trackPositions,
+ const LayoutUnit& grid_gap,
+ GridTrackSizingDirection direction,
+ float scale) {
+ std::unique_ptr<protocol::ListValue> number_offsets =
+ protocol::ListValue::create();
+
+ // Find index of the first explicit Grid Line.
+ size_t firstExplicitIndex =
+ layout_grid->ExplicitGridStartForDirection(direction);
+
+ LayoutUnit firstOffset = trackPositions.front();
+
+ // Go line by line, calculating the offset to fall in the middel of gaps
+ // if needed.
+ for (size_t i = firstExplicitIndex; i < trackPositions.size(); ++i) {
+ float gapOffset = grid_gap / 2;
+ // No need for a gap offset if there is no gap, or the first line is
+ // explicit, or this is the last line.
+ if (grid_gap == 0 || i == 0 || i == trackPositions.size() - 1) {
+ gapOffset = 0;
+ }
+
+ number_offsets->pushValue(protocol::FundamentalValue::create(
+ (trackPositions.at(i) - gapOffset - firstOffset) * scale));
+ }
+
+ return number_offsets;
+}
+
+std::unique_ptr<protocol::ListValue> BuildGridNegativeLineNumberOffsets(
+ LayoutGrid* layout_grid,
+ const Vector<LayoutUnit>& trackPositions,
+ const LayoutUnit& grid_gap,
+ GridTrackSizingDirection direction,
+ float scale) {
+ std::unique_ptr<protocol::ListValue> number_offsets =
+ protocol::ListValue::create();
+
+ // This is the number of tracks from the start of the grid, to the end of the
+ // explicit grid (including any leading implicit tracks).
+ size_t explicit_grid_end_track_count =
+ layout_grid->ExplicitGridEndForDirection(direction);
+
+ LayoutUnit firstOffset = trackPositions.front();
+
+ // Always start negative numbers at the first line.
+ number_offsets->pushValue(protocol::FundamentalValue::create(0));
+
+ // Then go line by line, calculating the offset to fall in the middle of gaps
+ // if needed.
+ for (size_t i = 1; i <= explicit_grid_end_track_count; i++) {
+ float gapOffset = grid_gap / 2;
+ if (grid_gap == 0 || (i == explicit_grid_end_track_count &&
+ i == trackPositions.size() - 1)) {
+ gapOffset = 0;
+ }
+
+ number_offsets->pushValue(protocol::FundamentalValue::create(
+ (trackPositions.at(i) - gapOffset - firstOffset) * scale));
+ }
+
+ return number_offsets;
+}
+
std::unique_ptr<protocol::DictionaryValue> BuildGridInfo(
LocalFrameView* containing_view,
LayoutGrid* layout_grid,
@@ -398,7 +491,8 @@ std::unique_ptr<protocol::DictionaryValue> BuildGridInfo(
PhysicalRect row(position, size);
FloatQuad row_quad = layout_grid->LocalRectToAbsoluteQuad(row);
FrameQuadToViewport(containing_view, row_quad);
- row_builder.AppendPath(QuadToPath(row_quad), scale);
+ row_builder.AppendPath(
+ RowQuadToPath(row_quad, i == rows.size() - 1 || row_gap > 0), scale);
// Row Gaps
if (i != rows.size() - 1) {
PhysicalOffset gap_position(row_left, rows.at(i) - row_gap);
@@ -424,7 +518,10 @@ std::unique_ptr<protocol::DictionaryValue> BuildGridInfo(
PhysicalRect column(position, size);
FloatQuad column_quad = layout_grid->LocalRectToAbsoluteQuad(column);
FrameQuadToViewport(containing_view, column_quad);
- column_builder.AppendPath(QuadToPath(column_quad), scale);
+ column_builder.AppendPath(
+ ColumnQuadToPath(column_quad,
+ i == columns.size() - 1 || column_gap > 0),
+ scale);
// Column Gaps
if (i != columns.size() - 1) {
PhysicalOffset gap_position(columns.at(i) - column_gap, column_top);
@@ -438,6 +535,30 @@ std::unique_ptr<protocol::DictionaryValue> BuildGridInfo(
grid_info->setValue("columns", column_builder.Release());
grid_info->setValue("columnGaps", column_gap_builder.Release());
+ // Positive Row and column Line offsets
+ if (highlight_config.grid_highlight_config &&
+ highlight_config.grid_highlight_config->show_positive_line_numbers) {
+ grid_info->setValue("positiveRowLineNumberOffsets",
+ BuildGridPositiveLineNumberOffsets(
+ layout_grid, rows, row_gap, kForRows, scale));
+ grid_info->setValue(
+ "positiveColumnLineNumberOffsets",
+ BuildGridPositiveLineNumberOffsets(layout_grid, columns, column_gap,
+ kForColumns, scale));
+ }
+
+ // Negative Row and column Line offsets
+ if (highlight_config.grid_highlight_config &&
+ highlight_config.grid_highlight_config->show_negative_line_numbers) {
+ grid_info->setValue("negativeRowLineNumberOffsets",
+ BuildGridNegativeLineNumberOffsets(
+ layout_grid, rows, row_gap, kForRows, scale));
+ grid_info->setValue(
+ "negativeColumnLineNumberOffsets",
+ BuildGridNegativeLineNumberOffsets(layout_grid, columns, column_gap,
+ kForColumns, scale));
+ }
+
// Grid border
PathBuilder grid_border_builder;
PhysicalOffset grid_position(row_left, column_top);
@@ -532,19 +653,23 @@ InspectorHighlightConfig::InspectorHighlightConfig()
show_styles(false),
show_rulers(false),
show_extension_lines(false),
+ show_accessibility_info(true),
color_format(ColorFormat::HEX) {}
InspectorHighlight::InspectorHighlight(float scale)
: highlight_paths_(protocol::ListValue::create()),
show_rulers_(false),
show_extension_lines_(false),
+ show_accessibility_info_(true),
scale_(scale),
color_format_(ColorFormat::HEX) {}
InspectorGridHighlightConfig::InspectorGridHighlightConfig()
: show_grid_extension_lines(false),
grid_border_dash(false),
- cell_border_dash(false) {}
+ cell_border_dash(false),
+ show_positive_line_numbers(false),
+ show_negative_line_numbers(false) {}
InspectorHighlight::InspectorHighlight(
Node* node,
@@ -556,6 +681,7 @@ InspectorHighlight::InspectorHighlight(
: highlight_paths_(protocol::ListValue::create()),
show_rulers_(highlight_config.show_rulers),
show_extension_lines_(highlight_config.show_extension_lines),
+ show_accessibility_info_(highlight_config.show_accessibility_info),
scale_(1.f),
color_format_(highlight_config.color_format) {
DCHECK(!DisplayLockUtilities::NearestLockedExclusiveAncestor(*node));
@@ -577,6 +703,10 @@ InspectorHighlight::InspectorHighlight(
if (element_info_ && is_locked_ancestor)
element_info_->setString("isLockedAncestor", "true");
+ if (element_info_) {
+ element_info_->setBoolean("showAccessibilityInfo",
+ show_accessibility_info_);
+ }
if (append_distance_info)
AppendDistanceInfo(node);
}
@@ -770,14 +900,6 @@ void InspectorHighlight::AppendNodeHighlight(
ToLayoutGrid(layout_object),
highlight_config, scale_, true));
}
- LayoutObject* parent = layout_object->Parent();
- if (!parent || !parent->IsLayoutGrid())
- return;
- if (!BuildNodeQuads(parent->GetNode(), &content, &padding, &border, &margin))
- return;
- grid_info_->pushValue(BuildGridInfo(node->GetDocument().View(),
- ToLayoutGrid(parent), highlight_config,
- scale_, false));
}
std::unique_ptr<protocol::DictionaryValue> InspectorHighlight::AsProtocolValue()
@@ -787,6 +909,7 @@ std::unique_ptr<protocol::DictionaryValue> InspectorHighlight::AsProtocolValue()
object->setValue("paths", highlight_paths_->clone());
object->setBoolean("showRulers", show_rulers_);
object->setBoolean("showExtensionLines", show_extension_lines_);
+ object->setBoolean("showAccessibilityInfo", show_accessibility_info_);
switch (color_format_) {
case ColorFormat::RGB:
object->setString("colorFormat", "rgb");
@@ -1067,6 +1190,8 @@ InspectorGridHighlightConfig InspectorHighlight::DefaultGridConfig() {
config.row_hatch_color = Color(255, 255, 255, 0);
config.column_hatch_color = Color(128, 128, 128, 0);
config.show_grid_extension_lines = true;
+ config.show_positive_line_numbers = true;
+ config.show_negative_line_numbers = true;
config.grid_border_dash = false;
config.cell_border_dash = true;
return config;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_highlight.h b/chromium/third_party/blink/renderer/core/inspector/inspector_highlight.h
index 9625b3941cd..05afd1bf3ab 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_highlight.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_highlight.h
@@ -34,6 +34,8 @@ struct CORE_EXPORT InspectorGridHighlightConfig {
bool show_grid_extension_lines;
bool grid_border_dash;
bool cell_border_dash;
+ bool show_positive_line_numbers;
+ bool show_negative_line_numbers;
};
struct CORE_EXPORT InspectorHighlightConfig {
@@ -56,6 +58,7 @@ struct CORE_EXPORT InspectorHighlightConfig {
bool show_styles;
bool show_rulers;
bool show_extension_lines;
+ bool show_accessibility_info;
String selector_list;
ColorFormat color_format;
@@ -128,6 +131,7 @@ class CORE_EXPORT InspectorHighlight {
std::unique_ptr<protocol::ListValue> grid_info_;
bool show_rulers_;
bool show_extension_lines_;
+ bool show_accessibility_info_;
float scale_;
ColorFormat color_format_;
};
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_history.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_history.cc
index 8aededb9a81..8eee391fb20 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_history.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_history.cc
@@ -56,7 +56,7 @@ InspectorHistory::Action::Action(const String& name) : name_(name) {}
InspectorHistory::Action::~Action() = default;
-void InspectorHistory::Action::Trace(Visitor* visitor) {}
+void InspectorHistory::Action::Trace(Visitor* visitor) const {}
String InspectorHistory::Action::ToString() {
return name_;
@@ -143,7 +143,7 @@ void InspectorHistory::Reset() {
history_.clear();
}
-void InspectorHistory::Trace(Visitor* visitor) {
+void InspectorHistory::Trace(Visitor* visitor) const {
visitor->Trace(history_);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_history.h b/chromium/third_party/blink/renderer/core/inspector/inspector_history.h
index ef5900cd5c5..5a37f8446b2 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_history.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_history.h
@@ -47,7 +47,7 @@ class InspectorHistory final : public GarbageCollected<InspectorHistory> {
public:
explicit Action(const String& name);
virtual ~Action();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
virtual String ToString();
virtual String MergeId();
@@ -67,7 +67,7 @@ class InspectorHistory final : public GarbageCollected<InspectorHistory> {
};
InspectorHistory();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
bool Perform(Action*, ExceptionState&);
void AppendPerformedAction(Action*);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_issue.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_issue.cc
index 3ae80a29047..7677f50d66c 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_issue.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_issue.cc
@@ -37,6 +37,6 @@ const mojom::blink::InspectorIssueDetailsPtr& InspectorIssue::Details() const {
return details_;
}
-void InspectorIssue::Trace(blink::Visitor* visitor) {}
+void InspectorIssue::Trace(blink::Visitor* visitor) const {}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_issue.h b/chromium/third_party/blink/renderer/core/inspector/inspector_issue.h
index 3dc9037fa4d..2c44a93822e 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_issue.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_issue.h
@@ -27,7 +27,7 @@ class CORE_EXPORT InspectorIssue final
mojom::blink::InspectorIssueCode Code() const;
const mojom::blink::InspectorIssueDetailsPtr& Details() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
mojom::blink::InspectorIssueCode code_;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_issue_reporter.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_issue_reporter.cc
new file mode 100644
index 00000000000..0e281fb1cd7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_issue_reporter.cc
@@ -0,0 +1,61 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/inspector/inspector_issue_reporter.h"
+
+#include "base/optional.h"
+#include "base/unguessable_token.h"
+#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom-blink.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/inspector/identifiers_factory.h"
+#include "third_party/blink/renderer/core/inspector/inspector_issue_storage.h"
+#include "third_party/blink/renderer/platform/heap/visitor.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
+
+namespace blink {
+
+InspectorIssueReporter::InspectorIssueReporter(InspectorIssueStorage* storage)
+ : storage_(storage) {}
+
+InspectorIssueReporter::~InspectorIssueReporter() = default;
+
+void InspectorIssueReporter::Trace(Visitor* visitor) const {
+ visitor->Trace(storage_);
+}
+
+void InspectorIssueReporter::DidFailLoading(
+ CoreProbeSink* sink,
+ uint64_t identifier,
+ DocumentLoader* loader,
+ const ResourceError& error,
+ const base::UnguessableToken& token) {
+ if (!storage_)
+ return;
+ base::Optional<network::mojom::BlockedByResponseReason>
+ blocked_by_response_reason = error.GetBlockedByResponseReason();
+ if (!blocked_by_response_reason)
+ return;
+ auto blocked_by_response_details =
+ mojom::blink::BlockedByResponseIssueDetails::New();
+ blocked_by_response_details->reason = *blocked_by_response_reason;
+ auto affected_request = mojom::blink::AffectedRequest::New();
+ affected_request->request_id =
+ IdentifiersFactory::RequestId(loader, identifier);
+ affected_request->url = error.FailingURL();
+ blocked_by_response_details->request = std::move(affected_request);
+
+ auto affected_frame = mojom::blink::AffectedFrame::New();
+ affected_frame->frame_id = IdentifiersFactory::IdFromToken(token);
+ blocked_by_response_details->frame = std::move(affected_frame);
+
+ auto details = mojom::blink::InspectorIssueDetails::New();
+ details->blocked_by_response_issue_details =
+ std::move(blocked_by_response_details);
+
+ storage_->AddInspectorIssue(
+ sink, mojom::blink::InspectorIssueInfo::New(
+ mojom::blink::InspectorIssueCode::kBlockedByResponseIssue,
+ std::move(details)));
+}
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_issue_reporter.h b/chromium/third_party/blink/renderer/core/inspector/inspector_issue_reporter.h
new file mode 100644
index 00000000000..09f849ee7a6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_issue_reporter.h
@@ -0,0 +1,47 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_ISSUE_REPORTER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_ISSUE_REPORTER_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+
+namespace base {
+class UnguessableToken;
+}
+
+namespace blink {
+class CoreProbeSink;
+class DocumentLoader;
+class ResourceError;
+class InspectorIssueStorage;
+
+// This class is always present on the local frame and can be used to
+// subscribe to core probes for issue reporting (which is on independent of
+// whether a DevToolsSession is attached).
+class CORE_EXPORT InspectorIssueReporter final
+ : public GarbageCollected<InspectorIssueReporter> {
+ public:
+ explicit InspectorIssueReporter(InspectorIssueStorage* storage);
+ virtual ~InspectorIssueReporter();
+ InspectorIssueReporter(const InspectorIssueReporter&) = delete;
+ InspectorIssueReporter& operator=(const InspectorIssueReporter&) = delete;
+
+ // Core Probes.
+ void DidFailLoading(CoreProbeSink* sink,
+ uint64_t identifier,
+ DocumentLoader* loader,
+ const ResourceError& error,
+ const base::UnguessableToken& token);
+
+ void Trace(Visitor*) const;
+
+ private:
+ WeakMember<InspectorIssueStorage> storage_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_ISSUE_REPORTER_H_
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_issue_storage.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_issue_storage.cc
index 803b7775cfd..b11773c54f9 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_issue_storage.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_issue_storage.cc
@@ -13,10 +13,10 @@ static const unsigned kMaxIssueCount = 1000;
InspectorIssueStorage::InspectorIssueStorage() = default;
-void InspectorIssueStorage::AddInspectorIssue(ExecutionContext* context,
+void InspectorIssueStorage::AddInspectorIssue(CoreProbeSink* sink,
InspectorIssue* issue) {
DCHECK(issues_.size() <= kMaxIssueCount);
- probe::InspectorIssueAdded(context, issue);
+ probe::InspectorIssueAdded(sink, issue);
if (issues_.size() == kMaxIssueCount) {
issues_.pop_front();
}
@@ -24,9 +24,16 @@ void InspectorIssueStorage::AddInspectorIssue(ExecutionContext* context,
}
void InspectorIssueStorage::AddInspectorIssue(
+ CoreProbeSink* sink,
+ mojom::blink::InspectorIssueInfoPtr info) {
+ AddInspectorIssue(sink, InspectorIssue::Create(std::move(info)));
+}
+
+void InspectorIssueStorage::AddInspectorIssue(
ExecutionContext* context,
mojom::blink::InspectorIssueInfoPtr info) {
- AddInspectorIssue(context, InspectorIssue::Create(std::move(info)));
+ AddInspectorIssue(probe::ToCoreProbeSink(context),
+ InspectorIssue::Create(std::move(info)));
}
void InspectorIssueStorage::Clear() {
@@ -41,7 +48,7 @@ InspectorIssue* InspectorIssueStorage::at(wtf_size_t index) const {
return issues_[index].Get();
}
-void InspectorIssueStorage::Trace(Visitor* visitor) {
+void InspectorIssueStorage::Trace(Visitor* visitor) const {
visitor->Trace(issues_);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_issue_storage.h b/chromium/third_party/blink/renderer/core/inspector/inspector_issue_storage.h
index 3a99f74185c..83f06bc02ee 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_issue_storage.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_issue_storage.h
@@ -13,6 +13,7 @@
namespace blink {
+class CoreProbeSink;
class InspectorIssue;
class ExecutionContext;
@@ -21,14 +22,15 @@ class CORE_EXPORT InspectorIssueStorage
public:
InspectorIssueStorage();
- void AddInspectorIssue(ExecutionContext*, InspectorIssue*);
+ void AddInspectorIssue(CoreProbeSink*, InspectorIssue*);
+ void AddInspectorIssue(CoreProbeSink*, mojom::blink::InspectorIssueInfoPtr);
void AddInspectorIssue(ExecutionContext*,
mojom::blink::InspectorIssueInfoPtr);
void Clear();
wtf_size_t size() const;
InspectorIssue* at(wtf_size_t index) const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
HeapDeque<Member<InspectorIssue>> issues_;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.cc
index 684f6121ecf..85ef5c7f021 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.cc
@@ -261,7 +261,7 @@ InspectorLayerTreeAgent::InspectorLayerTreeAgent(
InspectorLayerTreeAgent::~InspectorLayerTreeAgent() = default;
-void InspectorLayerTreeAgent::Trace(Visitor* visitor) {
+void InspectorLayerTreeAgent::Trace(Visitor* visitor) const {
visitor->Trace(inspected_frames_);
InspectorBaseAgent::Trace(visitor);
}
@@ -314,16 +314,13 @@ InspectorLayerTreeAgent::BuildLayerTree() {
auto layers = std::make_unique<protocol::Array<protocol::LayerTree::Layer>>();
auto* root_frame = inspected_frames_->Root();
- auto* layer_for_scrolling =
- root_frame->View()->LayoutViewport()->LayerForScrolling();
- int scrolling_layer_id = layer_for_scrolling ? layer_for_scrolling->id() : 0;
bool have_blocking_wheel_event_handlers =
root_frame->GetChromeClient().EventListenerProperties(
root_frame, cc::EventListenerClass::kMouseWheel) ==
cc::EventListenerProperties::kBlocking;
GatherLayers(root_layer, layers, have_blocking_wheel_event_handlers,
- scrolling_layer_id);
+ root_layer->layer_tree_host()->OuterViewportScrollElementId());
return layers;
}
@@ -331,18 +328,18 @@ void InspectorLayerTreeAgent::GatherLayers(
const cc::Layer* layer,
std::unique_ptr<Array<protocol::LayerTree::Layer>>& layers,
bool has_wheel_event_handlers,
- int scrolling_layer_id) {
+ CompositorElementId outer_viewport_scroll_element_id) {
if (client_->IsInspectorLayer(layer))
return;
if (layer->layer_tree_host()->is_hud_layer(layer))
return;
- int layer_id = layer->id();
layers->emplace_back(BuildObjectForLayer(
RootLayer(), layer,
- has_wheel_event_handlers && layer_id == scrolling_layer_id));
+ has_wheel_event_handlers &&
+ layer->element_id() == outer_viewport_scroll_element_id));
for (auto child : layer->children()) {
GatherLayers(child.get(), layers, has_wheel_event_handlers,
- scrolling_layer_id);
+ outer_viewport_scroll_element_id);
}
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.h
index 1f06545f9f9..6dd56908ea4 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.h
@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/inspector/inspector_base_agent.h"
#include "third_party/blink/renderer/core/inspector/protocol/LayerTree.h"
+#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -58,7 +59,7 @@ class CORE_EXPORT InspectorLayerTreeAgent final
InspectorLayerTreeAgent(InspectedFrames*, Client*);
~InspectorLayerTreeAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Restore() override;
@@ -112,7 +113,7 @@ class CORE_EXPORT InspectorLayerTreeAgent final
const cc::Layer*,
std::unique_ptr<protocol::Array<protocol::LayerTree::Layer>>&,
bool has_wheel_event_handlers,
- int scrolling_root_layer_id);
+ CompositorElementId outer_viewport_scroll_element_id);
Member<InspectedFrames> inspected_frames_;
Client* client_;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_log_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_log_agent.cc
index e3429abb2e7..3b03deff05f 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_log_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_log_agent.cc
@@ -83,7 +83,7 @@ InspectorLogAgent::InspectorLogAgent(
InspectorLogAgent::~InspectorLogAgent() = default;
-void InspectorLogAgent::Trace(Visitor* visitor) {
+void InspectorLogAgent::Trace(Visitor* visitor) const {
visitor->Trace(storage_);
visitor->Trace(performance_monitor_);
InspectorBaseAgent::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_log_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_log_agent.h
index 6dbe8f26f0b..ddd07d22006 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_log_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_log_agent.h
@@ -30,7 +30,7 @@ class CORE_EXPORT InspectorLogAgent
PerformanceMonitor*,
v8_inspector::V8InspectorSession*);
~InspectorLogAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Restore() override;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_media_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_media_agent.cc
index 40e9ae5054b..c4a8459ad6d 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_media_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_media_agent.cc
@@ -161,7 +161,7 @@ void InspectorMediaAgent::PlayersCreated(const Vector<WebString>& player_ids) {
GetFrontend()->playersCreated(std::move(protocol_players));
}
-void InspectorMediaAgent::Trace(Visitor* visitor) {
+void InspectorMediaAgent::Trace(Visitor* visitor) const {
visitor->Trace(local_frame_);
InspectorBaseAgent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_media_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_media_agent.h
index b65460cf07f..babbe58fc16 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_media_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_media_agent.h
@@ -40,7 +40,7 @@ class CORE_EXPORT InspectorMediaAgent final
void PlayersCreated(const Vector<WebString>&);
// blink-gc methods.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void RegisterAgent();
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc
index a172dc6d697..c5bd2660e57 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc
@@ -41,7 +41,7 @@ static Vector<T> Iter2Vector(const Iterable& iterable) {
}
// Garbage collection method.
-void MediaInspectorContextImpl::Trace(Visitor* visitor) {
+void MediaInspectorContextImpl::Trace(Visitor* visitor) const {
Supplement<LocalDOMWindow>::Trace(visitor);
visitor->Trace(players_);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_media_context_impl.h b/chromium/third_party/blink/renderer/core/inspector/inspector_media_context_impl.h
index 04cb0d2c7cc..15af500bd2c 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_media_context_impl.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_media_context_impl.h
@@ -16,7 +16,7 @@ namespace blink {
class LocalDOMWindow;
struct MediaPlayer final : public GarbageCollected<MediaPlayer> {
- void Trace(Visitor*) {}
+ void Trace(Visitor*) const {}
WebString player_id;
Vector<InspectorPlayerError> errors;
@@ -50,7 +50,7 @@ class CORE_EXPORT MediaInspectorContextImpl final
const InspectorPlayerProperties&) override;
// GarbageCollected methods.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
Vector<WebString> AllPlayerIds();
const MediaPlayer& MediaPlayerFromId(const WebString&);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_memory_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_memory_agent.cc
index b7bbd98f175..31a71d333e7 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_memory_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_memory_agent.cc
@@ -81,7 +81,7 @@ Response InspectorMemoryAgent::forciblyPurgeJavaScriptMemory() {
return Response::Success();
}
-void InspectorMemoryAgent::Trace(Visitor* visitor) {
+void InspectorMemoryAgent::Trace(Visitor* visitor) const {
visitor->Trace(frames_);
InspectorBaseAgent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_memory_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_memory_agent.h
index bd83b92b80c..451a5cf7876 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_memory_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_memory_agent.h
@@ -45,7 +45,7 @@ class CORE_EXPORT InspectorMemoryAgent final
public:
explicit InspectorMemoryAgent(InspectedFrames*);
~InspectorMemoryAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Restore() override;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_network_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
index fd21ad09a6e..b00c8d5f0e0 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -81,9 +81,11 @@
#include "third_party/blink/renderer/platform/network/http_header_map.h"
#include "third_party/blink/renderer/platform/network/network_state_notifier.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/text/base64.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
@@ -384,6 +386,19 @@ String BuildBlockedReason(ResourceRequestBlockedReason reason) {
return protocol::Network::BlockedReasonEnum::Other;
}
+String BuildServiceWorkerResponseSource(const ResourceResponse& response) {
+ switch (response.GetServiceWorkerResponseSource()) {
+ case network::mojom::FetchResponseSource::kCacheStorage:
+ return protocol::Network::ServiceWorkerResponseSourceEnum::CacheStorage;
+ case network::mojom::FetchResponseSource::kHttpCache:
+ return protocol::Network::ServiceWorkerResponseSourceEnum::HttpCache;
+ case network::mojom::FetchResponseSource::kNetwork:
+ return protocol::Network::ServiceWorkerResponseSourceEnum::Network;
+ case network::mojom::FetchResponseSource::kUnspecified:
+ return protocol::Network::ServiceWorkerResponseSourceEnum::FallbackCode;
+ }
+}
+
WebConnectionType ToWebConnectionType(const String& connection_type) {
if (connection_type == protocol::Network::ConnectionTypeEnum::None)
return kWebConnectionTypeNone;
@@ -458,6 +473,22 @@ std::unique_ptr<protocol::Network::WebSocketFrame> WebSocketMessageToProtocol(
.build();
}
+void SetNetworkStateOverride(bool offline,
+ double latency,
+ double download_throughput,
+ double upload_throughput,
+ WebConnectionType type) {
+ // TODO(dgozman): networkStateNotifier is per-process. It would be nice to
+ // have per-frame override instead.
+ if (offline || latency || download_throughput || upload_throughput) {
+ GetNetworkStateNotifier().SetNetworkConnectionInfoOverride(
+ !offline, type, base::nullopt, latency,
+ download_throughput / (1024 * 1024 / 8));
+ } else {
+ GetNetworkStateNotifier().ClearOverride();
+ }
+}
+
} // namespace
void InspectorNetworkAgent::Restore() {
@@ -479,6 +510,10 @@ static std::unique_ptr<protocol::Network::ResourceTiming> BuildObjectForTiming(
.setSslEnd(timing.CalculateMillisecondDelta(timing.SslEnd()))
.setWorkerStart(timing.CalculateMillisecondDelta(timing.WorkerStart()))
.setWorkerReady(timing.CalculateMillisecondDelta(timing.WorkerReady()))
+ .setWorkerFetchStart(
+ timing.CalculateMillisecondDelta(timing.WorkerFetchStart()))
+ .setWorkerRespondWithSettled(
+ timing.CalculateMillisecondDelta(timing.WorkerRespondWithSettled()))
.setSendStart(timing.CalculateMillisecondDelta(timing.SendStart()))
.setSendEnd(timing.CalculateMillisecondDelta(timing.SendEnd()))
.setReceiveHeadersEnd(
@@ -612,6 +647,18 @@ BuildObjectForResourceResponse(const ResourceResponse& response,
response_object->setFromDiskCache(response.WasCached());
response_object->setFromServiceWorker(response.WasFetchedViaServiceWorker());
+ if (response.WasFetchedViaServiceWorker()) {
+ response_object->setServiceWorkerResponseSource(
+ BuildServiceWorkerResponseSource(response));
+ }
+ if (!response.ResponseTime().is_null()) {
+ response_object->setResponseTime(
+ response.ResponseTime().ToJsTimeIgnoringNull());
+ }
+ if (!response.CacheStorageCacheName().IsEmpty()) {
+ response_object->setCacheStorageCacheName(response.CacheStorageCacheName());
+ }
+
response_object->setFromPrefetchCache(response.WasInPrefetchCache());
if (response.GetResourceLoadTiming())
response_object->setTiming(
@@ -715,7 +762,7 @@ BuildObjectForResourceResponse(const ResourceResponse& response,
InspectorNetworkAgent::~InspectorNetworkAgent() = default;
-void InspectorNetworkAgent::Trace(Visitor* visitor) {
+void InspectorNetworkAgent::Trace(Visitor* visitor) const {
visitor->Trace(inspected_frames_);
visitor->Trace(worker_global_scope_);
visitor->Trace(resources_data_);
@@ -889,7 +936,15 @@ void InspectorNetworkAgent::WillSendNavigationRequest(
// This method was pulled out of PrepareRequest(), because we want to be able
// to create DevTools issues before the PrepareRequest() call. We need these
// IDs to be set, to properly create a DevTools issue.
-void InspectorNetworkAgent::SetDevToolsIds(ResourceRequest& request) {
+void InspectorNetworkAgent::SetDevToolsIds(
+ ResourceRequest& request,
+ const FetchInitiatorInfo& initiator_info) {
+ // Network instrumentation ignores the requests initiated internally (these
+ // are unexpected to the user and usually do not hit the remote server).
+ // Ignore them and do not set the devtools id, so that other systems like
+ // network interceptor in the browser do not mistakenly report it.
+ if (initiator_info.name == fetch_initiator_type_names::kInternal)
+ return;
request.SetDevToolsToken(devtools_token_);
// The loader parameter is for generating a browser generated ID for a browser
@@ -1047,7 +1102,7 @@ void InspectorNetworkAgent::DidReceiveData(uint64_t identifier,
if (data) {
NetworkResourcesData::ResourceData const* resource_data =
resources_data_->Data(request_id);
- if (resource_data &&
+ if (resource_data && !resource_data->HasContent() &&
(!resource_data->CachedResource() ||
resource_data->CachedResource()->GetDataBufferingPolicy() ==
kDoNotBufferData ||
@@ -1096,7 +1151,7 @@ void InspectorNetworkAgent::DidFinishLoading(
pending_encoded_data_length);
}
- if (resource_data &&
+ if (resource_data && !resource_data->HasContent() &&
(!resource_data->CachedResource() ||
resource_data->CachedResource()->GetDataBufferingPolicy() ==
kDoNotBufferData ||
@@ -1126,9 +1181,12 @@ void InspectorNetworkAgent::DidReceiveCorsRedirectResponse(
WebURLLoaderClient::kUnknownEncodedDataLength, 0, false);
}
-void InspectorNetworkAgent::DidFailLoading(uint64_t identifier,
- DocumentLoader* loader,
- const ResourceError& error) {
+void InspectorNetworkAgent::DidFailLoading(
+ CoreProbeSink* sink,
+ uint64_t identifier,
+ DocumentLoader* loader,
+ const ResourceError& error,
+ const base::UnguessableToken& devtools_frame_or_worker_token) {
String request_id = IdentifiersFactory::RequestId(loader, identifier);
bool canceled = error.IsCancellation();
base::Optional<ResourceRequestBlockedReason> resource_request_blocked_reason =
@@ -1556,24 +1614,31 @@ Response InspectorNetworkAgent::emulateNetworkConditions(
double download_throughput,
double upload_throughput,
Maybe<String> connection_type) {
- if (!IsMainThread())
- return Response::ServerError("Not supported");
-
WebConnectionType type = kWebConnectionTypeUnknown;
if (connection_type.isJust()) {
type = ToWebConnectionType(connection_type.fromJust());
if (type == kWebConnectionTypeUnknown)
return Response::ServerError("Unknown connection type");
}
- // TODO(dgozman): networkStateNotifier is per-process. It would be nice to
- // have per-frame override instead.
- if (offline || latency || download_throughput || upload_throughput) {
- GetNetworkStateNotifier().SetNetworkConnectionInfoOverride(
- !offline, type, base::nullopt, latency,
- download_throughput / (1024 * 1024 / 8));
- } else {
- GetNetworkStateNotifier().ClearOverride();
+
+ if (worker_global_scope_) {
+ if (worker_global_scope_->IsServiceWorkerGlobalScope() ||
+ worker_global_scope_->IsSharedWorkerGlobalScope()) {
+ // In service workers and shared workers, we don't inspect the main thread
+ // so we must post a task there to make it possible to use
+ // NetworkStateNotifier.
+ PostCrossThreadTask(
+ *Thread::MainThread()->GetTaskRunner(), FROM_HERE,
+ CrossThreadBindOnce(SetNetworkStateOverride, offline, latency,
+ download_throughput, upload_throughput, type));
+ return Response::Success();
+ }
+ return Response::ServerError("Not supported");
}
+
+ SetNetworkStateOverride(offline, latency, download_throughput,
+ upload_throughput, type);
+
return Response::Success();
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_network_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_network_agent.h
index e6c46fe40a8..23a29621b3c 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_network_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_network_agent.h
@@ -81,7 +81,7 @@ class CORE_EXPORT InspectorNetworkAgent final
WorkerGlobalScope*,
v8_inspector::V8InspectorSession*);
~InspectorNetworkAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Restore() override;
@@ -136,9 +136,12 @@ class CORE_EXPORT InspectorNetworkAgent final
DocumentLoader*,
const ResourceResponse&,
Resource*);
- void DidFailLoading(uint64_t identifier,
- DocumentLoader*,
- const ResourceError&);
+ void DidFailLoading(
+ CoreProbeSink* sink,
+ uint64_t identifier,
+ DocumentLoader*,
+ const ResourceError&,
+ const base::UnguessableToken& devtools_frame_or_worker_token);
void DidCommitLoad(LocalFrame*, DocumentLoader*);
void ScriptImported(uint64_t identifier, const String& source_string);
void DidReceiveScriptResponse(uint64_t identifier);
@@ -192,7 +195,7 @@ class CORE_EXPORT InspectorNetworkAgent final
const char* payload,
size_t payload_length);
void DidReceiveWebSocketMessageError(uint64_t identifier, const String&);
- void SetDevToolsIds(ResourceRequest& request);
+ void SetDevToolsIds(ResourceRequest& request, const FetchInitiatorInfo&);
// Called from frontend
protocol::Response enable(Maybe<int> total_buffer_size,
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
index ffe39fd95a3..b7cf4bb6507 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
@@ -38,7 +38,7 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_data.h"
-#include "third_party/blink/public/resources/grit/blink_resources.h"
+#include "third_party/blink/public/resources/grit/inspector_overlay_resources_map.h"
#include "third_party/blink/public/web/web_widget_client.h"
#include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
@@ -120,7 +120,7 @@ void InspectTool::Init(InspectorOverlayAgent* overlay,
}
int InspectTool::GetDataResourceId() {
- return IDR_INSPECT_TOOL_HIGHLIGHT_HTML;
+ return IDR_INSPECT_TOOL_HIGHLIGHT_JS;
}
bool InspectTool::HandleInputEvent(LocalFrameView* frame_view,
@@ -204,7 +204,7 @@ bool InspectTool::HideOnHideHighlight() {
return false;
}
-void InspectTool::Trace(Visitor* visitor) {
+void InspectTool::Trace(Visitor* visitor) const {
visitor->Trace(overlay_);
}
@@ -223,15 +223,16 @@ Hinge::Hinge(FloatQuad quad,
int Hinge::GetDataResourceId() {
// TODO (soxia): In the future, we should make the hinge working properly
// with tools using different resources.
- return IDR_INSPECT_TOOL_HIGHLIGHT_HTML;
+ return IDR_INSPECT_TOOL_HIGHLIGHT_JS;
}
-void Hinge::Trace(Visitor* visitor) {
+void Hinge::Trace(Visitor* visitor) const {
visitor->Trace(overlay_);
}
void Hinge::Draw(float scale) {
- InspectorHighlight highlight(scale);
+ // scaling is applied at the drawHighlight code.
+ InspectorHighlight highlight(1.f);
highlight.AppendQuad(quad_, content_color_, outline_color_);
overlay_->EvaluateInOverlay("drawHighlight", highlight.AsProtocolValue());
}
@@ -321,7 +322,7 @@ class InspectorOverlayAgent::InspectorOverlayChromeClient final
InspectorOverlayAgent& overlay)
: client_(&client), overlay_(&overlay) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(client_);
visitor->Trace(overlay_);
EmptyChromeClient::Trace(visitor);
@@ -379,7 +380,7 @@ InspectorOverlayAgent::~InspectorOverlayAgent() {
DCHECK(!overlay_page_);
}
-void InspectorOverlayAgent::Trace(Visitor* visitor) {
+void InspectorOverlayAgent::Trace(Visitor* visitor) const {
visitor->Trace(frame_impl_);
visitor->Trace(inspected_frames_);
visitor->Trace(overlay_page_);
@@ -728,40 +729,30 @@ Response InspectorOverlayAgent::getHighlightObjectForTest(
Maybe<bool> include_distance,
Maybe<bool> include_style,
Maybe<String> colorFormat,
+ Maybe<bool> show_accessibility_info,
std::unique_ptr<protocol::DictionaryValue>* result) {
Node* node = nullptr;
Response response = dom_agent_->AssertNode(node_id, node);
if (!response.IsSuccess())
return response;
- bool is_locked_ancestor = false;
-
- // If |node| is in a display locked subtree, highlight the highest locked
- // ancestor element instead.
- if (Node* locked_ancestor =
- DisplayLockUtilities::HighestLockedExclusiveAncestor(*node)) {
- node = locked_ancestor;
- is_locked_ancestor = true;
- }
-
- InspectorHighlightConfig config = InspectorHighlight::DefaultConfig();
- config.show_styles = include_style.fromMaybe(false);
+ auto config = std::make_unique<InspectorHighlightConfig>(
+ InspectorHighlight::DefaultConfig());
+ config->show_styles = include_style.fromMaybe(false);
+ config->show_accessibility_info = show_accessibility_info.fromMaybe(true);
String format = colorFormat.fromMaybe("hex");
-
namespace ColorFormatEnum = protocol::Overlay::ColorFormatEnum;
if (format == ColorFormatEnum::Hsl) {
- config.color_format = ColorFormat::HSL;
+ config->color_format = ColorFormat::HSL;
} else if (format == ColorFormatEnum::Rgb) {
- config.color_format = ColorFormat::RGB;
+ config->color_format = ColorFormat::RGB;
} else {
- config.color_format = ColorFormat::HEX;
+ config->color_format = ColorFormat::HEX;
}
- InspectorHighlight highlight(node, config, InspectorHighlightContrastInfo(),
- true /* append_element_info */,
- include_distance.fromMaybe(false),
- is_locked_ancestor);
- *result = highlight.AsProtocolValue();
+ NodeHighlightTool tool(node, "" /* selector_list */, std::move(config));
+ *result = tool.GetNodeInspectorHighlightAsJson(
+ true /* append_element_info */, include_distance.fromMaybe(false));
return Response::Success();
}
@@ -902,6 +893,18 @@ void InspectorOverlayAgent::PaintOverlayPage() {
if (!view || !frame)
return;
+ auto now = base::Time::Now();
+ if (!backend_node_id_changed_ &&
+ now - last_paint_time_ < base::TimeDelta::FromMilliseconds(100)) {
+ OverlayMainFrame()->View()->UpdateAllLifecyclePhases(
+ DocumentUpdateReason::kInspector);
+ return;
+ }
+ if (backend_node_id_changed_) {
+ backend_node_id_changed_ = false;
+ }
+ last_paint_time_ = now;
+
LocalFrame* overlay_frame = OverlayMainFrame();
// To make overlay render the same size text with any emulation scale,
// compensate the emulation scale using page scale.
@@ -975,6 +978,8 @@ void InspectorOverlayAgent::LoadFrameForTool(int data_resource_id) {
overlay_settings.GetGenericFontFamilySettings().UpdateStandard(
settings.GetGenericFontFamilySettings().Standard());
+ overlay_settings.GetGenericFontFamilySettings().UpdateFixed(
+ settings.GetGenericFontFamilySettings().Fixed());
overlay_settings.GetGenericFontFamilySettings().UpdateSerif(
settings.GetGenericFontFamilySettings().Serif());
overlay_settings.GetGenericFontFamilySettings().UpdateSansSerif(
@@ -1003,13 +1008,13 @@ void InspectorOverlayAgent::LoadFrameForTool(int data_resource_id) {
frame->View()->SetBaseBackgroundColor(Color::kTransparent);
scoped_refptr<SharedBuffer> data = SharedBuffer::Create();
+
data->Append("<style>", static_cast<size_t>(7));
- data->Append(UncompressResourceAsBinary(IDR_INSPECT_TOOL_COMMON_CSS));
+ data->Append(UncompressResourceAsBinary(IDR_INSPECT_COMMON_CSS));
data->Append("</style>", static_cast<size_t>(8));
data->Append("<script>", static_cast<size_t>(8));
- data->Append(UncompressResourceAsBinary(IDR_INSPECT_TOOL_COMMON_JS));
- data->Append("</script>", static_cast<size_t>(9));
data->Append(UncompressResourceAsBinary(frame_resource_name_));
+ data->Append("</script>", static_cast<size_t>(9));
frame->ForceSynchronousDocumentInstall("text/html", data);
@@ -1032,6 +1037,8 @@ void InspectorOverlayAgent::LoadFrameForTool(int data_resource_id) {
EvaluateInOverlay("setPlatform", "mac");
#elif defined(OS_POSIX)
EvaluateInOverlay("setPlatform", "linux");
+#else
+ EvaluateInOverlay("setPlatform", "other");
#endif
}
@@ -1180,6 +1187,7 @@ void InspectorOverlayAgent::Inspect(Node* inspected_node) {
DOMNodeId backend_node_id = DOMNodeIds::IdForNode(node);
if (!enabled_.Get()) {
backend_node_id_to_inspect_ = backend_node_id;
+ backend_node_id_changed_ = true;
return;
}
@@ -1264,7 +1272,7 @@ void InspectorOverlayAgent::EnsureEnableFrameOverlay() {
void InspectorOverlayAgent::SetInspectTool(InspectTool* inspect_tool) {
LocalFrameView* view = frame_impl_->GetFrameView();
LocalFrame* frame = GetFrame();
- if (!view || !frame)
+ if (!view || !frame || !enabled_.Get())
return;
if (inspect_tool_)
@@ -1315,6 +1323,10 @@ InspectorOverlayAgent::ToGridHighlightConfig(
}
std::unique_ptr<InspectorGridHighlightConfig> highlight_config =
std::make_unique<InspectorGridHighlightConfig>();
+ highlight_config->show_positive_line_numbers =
+ config->getShowPositiveLineNumbers(false);
+ highlight_config->show_negative_line_numbers =
+ config->getShowNegativeLineNumbers(false);
highlight_config->show_grid_extension_lines =
config->getShowGridExtensionLines(false);
highlight_config->grid_border_dash = config->getGridBorderDash(false);
@@ -1341,6 +1353,8 @@ InspectorOverlayAgent::ToHighlightConfig(
std::unique_ptr<InspectorHighlightConfig> highlight_config =
std::make_unique<InspectorHighlightConfig>();
highlight_config->show_info = config->getShowInfo(false);
+ highlight_config->show_accessibility_info =
+ config->getShowAccessibilityInfo(true);
highlight_config->show_styles = config->getShowStyles(false);
highlight_config->show_rulers = config->getShowRulers(false);
highlight_config->show_extension_lines = config->getShowExtensionLines(false);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
index 4a2b9d455c9..1ad15a271a7 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
@@ -93,7 +93,7 @@ class CORE_EXPORT InspectTool : public GarbageCollected<InspectTool> {
virtual bool ForwardEventsToOverlay();
virtual void Draw(float scale) {}
virtual void Dispatch(const String& message) {}
- virtual void Trace(Visitor* visitor);
+ virtual void Trace(Visitor* visitor) const;
virtual void Dispose() {}
virtual bool HideOnHideHighlight();
virtual bool HideOnMouseMove();
@@ -114,7 +114,7 @@ class CORE_EXPORT Hinge final : public GarbageCollected<Hinge> {
~Hinge() = default;
static int GetDataResourceId();
void Draw(float scale);
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
private:
FloatQuad quad_;
@@ -139,7 +139,7 @@ class CORE_EXPORT InspectorOverlayAgent final
v8_inspector::V8InspectorSession*,
InspectorDOMAgent*);
~InspectorOverlayAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// protocol::Dispatcher::OverlayCommandHandler implementation.
protocol::Response enable() override;
@@ -184,6 +184,7 @@ class CORE_EXPORT InspectorOverlayAgent final
protocol::Maybe<bool> include_distance,
protocol::Maybe<bool> include_style,
protocol::Maybe<String> color_format,
+ protocol::Maybe<bool> show_accessibility_info,
std::unique_ptr<protocol::DictionaryValue>* highlight) override;
protocol::Response setShowHinge(
protocol::Maybe<protocol::Overlay::HingeConfig> hinge_config) override;
@@ -269,6 +270,9 @@ class CORE_EXPORT InspectorOverlayAgent final
InspectorAgentState::String paused_in_debugger_message_;
InspectorAgentState::String inspect_mode_;
InspectorAgentState::Bytes inspect_mode_protocol_config_;
+ base::Time last_paint_time_;
+ bool backend_node_id_changed_;
+
DISALLOW_COPY_AND_ASSIGN(InspectorOverlayAgent);
};
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_host.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_host.cc
index 26942927dbd..01740b9106b 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_host.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_host.cc
@@ -42,7 +42,7 @@ void InspectorOverlayHost::ClearDelegate() {
delegate_.Clear();
}
-void InspectorOverlayHost::Trace(Visitor* visitor) {
+void InspectorOverlayHost::Trace(Visitor* visitor) const {
visitor->Trace(delegate_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_host.h b/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_host.h
index 96e86efc9d8..2438f24bfe2 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_host.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_overlay_host.h
@@ -45,7 +45,7 @@ class CORE_EXPORT InspectorOverlayHost final : public ScriptWrappable {
};
explicit InspectorOverlayHost(Delegate*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void send(const String& message);
void ClearDelegate();
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
index 4f79e404321..55f708ddcef 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
@@ -40,7 +40,6 @@
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/document_timing.h"
-#include "third_party/blink/renderer/core/dom/dom_implementation.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -235,7 +234,7 @@ static std::unique_ptr<TextResourceDecoder> CreateResourceTextDecoder(
TextResourceDecoderOptions::kPlainTextContent,
WTF::TextEncoding(text_encoding_name)));
}
- if (DOMImplementation::IsXMLMIMEType(mime_type)) {
+ if (MIMETypeRegistry::IsXMLMIMEType(mime_type)) {
TextResourceDecoderOptions options(TextResourceDecoderOptions::kXMLContent);
options.SetUseLenientXMLDecoding();
return std::make_unique<TextResourceDecoder>(options);
@@ -249,7 +248,7 @@ static std::unique_ptr<TextResourceDecoder> CreateResourceTextDecoder(
return std::make_unique<TextResourceDecoder>(TextResourceDecoderOptions(
TextResourceDecoderOptions::kPlainTextContent, UTF8Encoding()));
}
- if (DOMImplementation::IsTextMIMEType(mime_type)) {
+ if (MIMETypeRegistry::IsPlainTextMIMEType(mime_type)) {
return std::make_unique<TextResourceDecoder>(TextResourceDecoderOptions(
TextResourceDecoderOptions::kPlainTextContent,
WTF::TextEncoding("ISO-8859-1")));
@@ -1428,7 +1427,7 @@ Response InspectorPageAgent::generateTestReport(const String& message,
return Response::Success();
}
-void InspectorPageAgent::Trace(Visitor* visitor) {
+void InspectorPageAgent::Trace(Visitor* visitor) const {
visitor->Trace(inspected_frames_);
visitor->Trace(inspector_resource_content_loader_);
visitor->Trace(isolated_worlds_);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_page_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_page_agent.h
index 33272e49144..840d25c725e 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_page_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_page_agent.h
@@ -218,7 +218,7 @@ class CORE_EXPORT InspectorPageAgent final
void Restore() override;
bool ScreencastEnabled();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void GetResourceContentAfterResourcesContentLoaded(
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_performance_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_performance_agent.cc
index cff050c6895..9693f872c5c 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_performance_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_performance_agent.cc
@@ -6,8 +6,11 @@
#include <utility>
+#include "base/process/process.h"
+#include "base/process/process_metrics.h"
#include "base/stl_util.h"
#include "base/time/time_override.h"
+#include "build/build_config.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/inspector/inspected_frames.h"
@@ -36,6 +39,23 @@ static constexpr const char* kInstanceCounterNames[] = {
#undef INSTANCE_COUNTER_NAME
};
+std::unique_ptr<base::ProcessMetrics> GetCurrentProcessMetrics() {
+ base::ProcessHandle handle = base::Process::Current().Handle();
+#if defined(OS_MACOSX)
+ // Port provider can be null if querying the current process.
+ return base::ProcessMetrics::CreateProcessMetrics(handle, nullptr);
+#else
+ return base::ProcessMetrics::CreateProcessMetrics(handle);
+#endif
+}
+
+base::TimeDelta GetCurrentProcessTime() {
+ std::unique_ptr<base::ProcessMetrics> process_metrics =
+ GetCurrentProcessMetrics();
+ base::TimeDelta process_time = process_metrics->GetCumulativeCPUUsage();
+ return process_time;
+}
+
} // namespace
InspectorPerformanceAgent::InspectorPerformanceAgent(
@@ -221,6 +241,9 @@ Response InspectorPerformanceAgent::getMetrics(
base::TimeDelta thread_time = GetThreadTimeNow() - thread_time_origin_;
AppendMetric(result.get(), "ThreadTime", thread_time.InSecondsF());
+ base::TimeDelta process_time = GetCurrentProcessTime();
+ AppendMetric(result.get(), "ProcessTime", process_time.InSecondsF());
+
v8::HeapStatistics heap_statistics;
V8PerIsolateData::MainThreadIsolate()->GetHeapStatistics(&heap_statistics);
AppendMetric(result.get(), "JSHeapUsedSize",
@@ -387,7 +410,7 @@ void InspectorPerformanceAgent::DidProcessTask(base::TimeTicks start_time,
task_start_ticks_ = base::TimeTicks();
}
-void InspectorPerformanceAgent::Trace(Visitor* visitor) {
+void InspectorPerformanceAgent::Trace(Visitor* visitor) const {
visitor->Trace(inspected_frames_);
InspectorBaseAgent<protocol::Performance::Metainfo>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_performance_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_performance_agent.h
index e8d399c752b..0fa45182c9e 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_performance_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_performance_agent.h
@@ -31,7 +31,7 @@ class CORE_EXPORT InspectorPerformanceAgent final
: public InspectorBaseAgent<protocol::Performance::Metainfo>,
public base::sequence_manager::TaskTimeObserver {
public:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
explicit InspectorPerformanceAgent(InspectedFrames*);
~InspectorPerformanceAgent() override;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_resource_container.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_resource_container.cc
index c96317ac005..192aeee9104 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_resource_container.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_resource_container.cc
@@ -14,7 +14,7 @@ InspectorResourceContainer::InspectorResourceContainer(
InspectorResourceContainer::~InspectorResourceContainer() = default;
-void InspectorResourceContainer::Trace(Visitor* visitor) {
+void InspectorResourceContainer::Trace(Visitor* visitor) const {
visitor->Trace(inspected_frames_);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_resource_container.h b/chromium/third_party/blink/renderer/core/inspector/inspector_resource_container.h
index 5c11d438396..fe4dc8dc3de 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_resource_container.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_resource_container.h
@@ -24,7 +24,7 @@ class CORE_EXPORT InspectorResourceContainer final
public:
explicit InspectorResourceContainer(InspectedFrames*);
~InspectorResourceContainer();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void DidCommitLoadForLocalFrame(LocalFrame*);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.cc
index 10a6e6b3c17..790445bfa39 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.cc
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/css/style_sheet_contents.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/html/html_link_element.h"
#include "third_party/blink/renderer/core/inspector/inspected_frames.h"
#include "third_party/blink/renderer/core/inspector/inspector_css_agent.h"
#include "third_party/blink/renderer/core/inspector/inspector_page_agent.h"
@@ -36,7 +37,7 @@ class InspectorResourceContentLoader::ResourceClient final
explicit ResourceClient(InspectorResourceContentLoader* loader)
: loader_(loader) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(loader_);
RawResourceClient::Trace(visitor);
}
@@ -137,6 +138,37 @@ void InspectorResourceContentLoader::Start() {
if (resource_client->GetResource())
pending_resource_clients_.insert(resource_client);
}
+
+ // Fetch app manifest if available.
+ // TODO (alexrudenko): This code duplicates the code in manifest_manager.cc
+ // and manifest_fetcher.cc. Move it to a shared place.
+ HTMLLinkElement* link_element = document->LinkManifest();
+ if (link_element) {
+ auto link = link_element->Href();
+ auto use_credentials = EqualIgnoringASCIICase(
+ link_element->FastGetAttribute(html_names::kCrossoriginAttr),
+ "use-credentials");
+ ResourceRequest manifest_request(link);
+ manifest_request.SetMode(network::mojom::RequestMode::kCors);
+ // See https://w3c.github.io/manifest/. Use "include" when use_credentials
+ // is true, and "omit" otherwise.
+ manifest_request.SetCredentialsMode(
+ use_credentials ? network::mojom::CredentialsMode::kInclude
+ : network::mojom::CredentialsMode::kOmit);
+ manifest_request.SetRequestContext(
+ mojom::blink::RequestContextType::MANIFEST);
+ ResourceLoaderOptions manifest_options;
+ manifest_options.initiator_info.name =
+ fetch_initiator_type_names::kInternal;
+ FetchParameters manifest_params(std::move(manifest_request),
+ manifest_options);
+ ResourceClient* manifest_client =
+ MakeGarbageCollected<ResourceClient>(this);
+ resources_.push_back(
+ RawResource::Fetch(manifest_params, fetcher, manifest_client));
+ if (manifest_client->GetResource())
+ pending_resource_clients_.insert(manifest_client);
+ }
}
all_requests_started_ = true;
@@ -165,7 +197,7 @@ InspectorResourceContentLoader::~InspectorResourceContentLoader() {
DCHECK(resources_.IsEmpty());
}
-void InspectorResourceContentLoader::Trace(Visitor* visitor) {
+void InspectorResourceContentLoader::Trace(Visitor* visitor) const {
visitor->Trace(inspected_frame_);
visitor->Trace(pending_resource_clients_);
visitor->Trace(resources_);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.h b/chromium/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.h
index 746406d0152..04b8ecec5ba 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.h
@@ -25,7 +25,7 @@ class CORE_EXPORT InspectorResourceContentLoader final
explicit InspectorResourceContentLoader(LocalFrame*);
~InspectorResourceContentLoader();
void Dispose();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
int CreateClientId();
void EnsureResourcesContentLoaded(int client_id, base::OnceClosure callback);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
index ce12579c49d..3bcf63ceb9e 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
@@ -534,7 +534,7 @@ void CollectFlatRules(RuleList rule_list, CSSRuleVector* result) {
// The result->append()'ed types should be exactly the same as in
// flattenSourceData().
- switch (rule->type()) {
+ switch (rule->GetType()) {
case CSSRule::kStyleRule:
case CSSRule::kImportRule:
case CSSRule::kCharsetRule:
@@ -661,6 +661,8 @@ void Diff(const Vector<String>& list_a,
delete[] backtrack;
}
+// Warning: it does not always produce valid CSS.
+// Use the rule's cssText method if you need to expose CSS externally.
String CanonicalCSSText(CSSRule* rule) {
auto* style_rule = DynamicTo<CSSStyleRule>(rule);
if (!style_rule)
@@ -898,7 +900,7 @@ String InspectorStyle::ShorthandValue(const String& shorthand_property) {
return builder.ToString();
}
-void InspectorStyle::Trace(Visitor* visitor) {
+void InspectorStyle::Trace(Visitor* visitor) const {
visitor->Trace(style_);
visitor->Trace(parent_style_sheet_);
visitor->Trace(source_data_);
@@ -929,6 +931,10 @@ const LineEndings* InspectorStyleSheetBase::GetLineEndings() {
return line_endings_.get();
}
+void InspectorStyleSheetBase::ResetLineEndings() {
+ line_endings_ = std::make_unique<LineEndings>();
+}
+
bool InspectorStyleSheetBase::LineNumberAndColumnToOffset(
unsigned line_number,
unsigned column_number,
@@ -961,19 +967,12 @@ InspectorStyleSheet::InspectorStyleSheet(
page_style_sheet_(page_style_sheet),
origin_(origin),
document_url_(document_url) {
- String text;
- bool success = InspectorStyleSheetText(&text);
- if (!success)
- success = InlineStyleSheetText(&text);
- if (!success)
- success = ResourceStyleSheetText(&text);
- if (success)
- InnerSetText(text, false);
+ UpdateText();
}
InspectorStyleSheet::~InspectorStyleSheet() = default;
-void InspectorStyleSheet::Trace(Visitor* visitor) {
+void InspectorStyleSheet::Trace(Visitor* visitor) const {
visitor->Trace(resource_container_);
visitor->Trace(network_agent_);
visitor->Trace(page_style_sheet_);
@@ -996,8 +995,8 @@ String InspectorStyleSheet::FinalURL() {
bool InspectorStyleSheet::SetText(const String& text,
ExceptionState& exception_state) {
- InnerSetText(text, true);
page_style_sheet_->SetText(text, CSSImportRules::kAllow);
+ InnerSetText(text, true);
OnStyleSheetTextChanged();
return true;
}
@@ -1024,7 +1023,7 @@ CSSStyleRule* InspectorStyleSheet::SetRuleSelector(
CSSRule* rule = RuleForSourceData(source_data);
if (!rule || !rule->parentStyleSheet() ||
- rule->type() != CSSRule::kStyleRule) {
+ rule->GetType() != CSSRule::kStyleRule) {
exception_state.ThrowDOMException(
DOMExceptionCode::kNotFoundError,
"Source range didn't match existing style source range");
@@ -1063,7 +1062,7 @@ CSSKeyframeRule* InspectorStyleSheet::SetKeyframeKey(
CSSRule* rule = RuleForSourceData(source_data);
if (!rule || !rule->parentStyleSheet() ||
- rule->type() != CSSRule::kKeyframeRule) {
+ rule->GetType() != CSSRule::kKeyframeRule) {
exception_state.ThrowDOMException(
DOMExceptionCode::kNotFoundError,
"Source range didn't match existing style source range");
@@ -1112,8 +1111,10 @@ CSSRule* InspectorStyleSheet::SetStyleText(const SourceRange& range,
style = style_rule->style();
else
style = To<CSSKeyframeRule>(rule)->style();
- style->setCSSText(page_style_sheet_->OwnerDocument()->GetExecutionContext(),
- text, exception_state);
+
+ ExecutionContext* execution_context =
+ page_style_sheet_->OwnerDocument()->GetExecutionContext();
+ style->setCSSText(execution_context, text, exception_state);
ReplaceText(source_data->rule_body_range, text, new_range, old_text);
OnStyleSheetTextChanged();
@@ -1143,7 +1144,7 @@ CSSMediaRule* InspectorStyleSheet::SetMediaRuleText(
CSSRule* rule = RuleForSourceData(source_data);
if (!rule || !rule->parentStyleSheet() ||
- rule->type() != CSSRule::kMediaRule) {
+ rule->GetType() != CSSRule::kMediaRule) {
exception_state.ThrowDOMException(
DOMExceptionCode::kNotFoundError,
"Source range didn't match existing style source range");
@@ -1257,7 +1258,7 @@ CSSStyleRule* InspectorStyleSheet::InsertCSSOMRuleBySourceRange(
exception_state);
CSSRule* rule = RuleForSourceData(containing_rule_source_data);
- if (!rule || rule->type() != CSSRule::kMediaRule) {
+ if (!rule || rule->GetType() != CSSRule::kMediaRule) {
exception_state.ThrowDOMException(DOMExceptionCode::kNotFoundError,
"Cannot insert rule in non-media rule.");
return nullptr;
@@ -1340,7 +1341,7 @@ bool InspectorStyleSheet::DeleteRule(const SourceRange& range,
}
CSSRule* parent_rule = rule->parentRule();
if (parent_rule) {
- if (parent_rule->type() != CSSRule::kMediaRule) {
+ if (parent_rule->GetType() != CSSRule::kMediaRule) {
exception_state.ThrowDOMException(
DOMExceptionCode::kNotFoundError,
"Cannot remove rule from non-media rule.");
@@ -1398,8 +1399,7 @@ void InspectorStyleSheet::ReplaceText(const SourceRange& range,
InnerSetText(sheet_text, true);
}
-void InspectorStyleSheet::InnerSetText(const String& text,
- bool mark_as_locally_modified) {
+void InspectorStyleSheet::ParseText(const String& text) {
CSSRuleSourceDataList* rule_tree =
MakeGarbageCollected<CSSRuleSourceDataList>();
auto* style_sheet = MakeGarbageCollected<StyleSheetContents>(
@@ -1415,8 +1415,12 @@ void InspectorStyleSheet::InnerSetText(const String& text,
source_data_sheet =
MakeGarbageCollected<CSSStyleSheet>(style_sheet, import_rule);
} else {
- source_data_sheet = MakeGarbageCollected<CSSStyleSheet>(
- style_sheet, *page_style_sheet_->ownerNode());
+ if (page_style_sheet_->ownerNode()) {
+ source_data_sheet = MakeGarbageCollected<CSSStyleSheet>(
+ style_sheet, *page_style_sheet_->ownerNode());
+ } else {
+ source_data_sheet = MakeGarbageCollected<CSSStyleSheet>(style_sheet);
+ }
}
parsed_flat_rules_.clear();
@@ -1424,6 +1428,50 @@ void InspectorStyleSheet::InnerSetText(const String& text,
source_data_ = MakeGarbageCollected<CSSRuleSourceDataList>();
FlattenSourceData(*rule_tree, source_data_.Get());
+}
+
+// The stylesheet text might be out of sync with `page_style_sheet_` rules.
+// This method checks if a rule is present in the source text using
+// `SourceDataForRule` and produces a new text with all rules merged into the
+// original text. For example, if the source text is
+//
+// /* comment */ .rule1 {} .rule3 {}
+//
+// and the page_style_sheet_ contains
+//
+// .rule0 {} .rule1 {} .rule2 {} .rule3 {} .rule4 {}
+//
+// The result should be
+//
+// .rule0 {} /* comment */ .rule1 {} .rule2 {} .rule3 {} .rule4 {}
+//
+// Note that page_style_sheet_ does not maintain comments and original
+// formatting.
+String InspectorStyleSheet::MergeCSSOMRulesWithText(const String& text) {
+ String merged_text = text;
+ unsigned original_insert_pos = 0;
+ unsigned inserted_count = 0;
+ for (unsigned i = 0; i < page_style_sheet_->length(); i++) {
+ CSSRuleSourceData* source_data =
+ SourceDataForRule(page_style_sheet_->item(i));
+ if (source_data) {
+ original_insert_pos = source_data->rule_body_range.end + 1;
+ continue;
+ }
+ String rule_text = page_style_sheet_->item(i)->cssText();
+ merged_text.replace(original_insert_pos + inserted_count, 0, rule_text);
+ inserted_count += rule_text.length();
+ }
+ rule_to_source_data_.clear();
+ source_data_to_rule_.clear();
+ cssom_flat_rules_.clear();
+ return merged_text;
+}
+
+void InspectorStyleSheet::InnerSetText(const String& text,
+ bool mark_as_locally_modified) {
+ ParseText(text);
+
text_ = text;
if (mark_as_locally_modified) {
@@ -1489,6 +1537,7 @@ InspectorStyleSheet::BuildObjectForStyleSheetInfo() {
.setTitle(style_sheet->title())
.setFrameId(frame ? IdentifiersFactory::FrameId(frame) : "")
.setIsInline(style_sheet->IsInline() && !StartsAtZero())
+ .setIsMutable(style_sheet->Contents()->IsMutable())
.setStartLine(start.line_.ZeroBasedInt())
.setStartColumn(start.column_.ZeroBasedInt())
.setLength(text_length)
@@ -1873,7 +1922,8 @@ bool InspectorStyleSheet::ResourceStyleSheetText(String* result) {
return false;
KURL url(page_style_sheet_->href());
- if (resource_container_->LoadStyleSheetContent(url, result))
+ if (page_style_sheet_->href() &&
+ resource_container_->LoadStyleSheetContent(url, result))
return true;
bool base64_encoded;
@@ -1894,17 +1944,80 @@ Element* InspectorStyleSheet::OwnerStyleElement() {
return owner_element;
}
-bool InspectorStyleSheet::InlineStyleSheetText(String* result) {
- Element* owner_element = OwnerStyleElement();
- if (!owner_element)
+String InspectorStyleSheet::CollectStyleSheetRules() {
+ StringBuilder builder;
+ for (unsigned i = 0; i < page_style_sheet_->length(); i++) {
+ builder.Append(page_style_sheet_->item(i)->cssText());
+ builder.Append('\n');
+ }
+ return builder.ToString();
+}
+
+bool InspectorStyleSheet::CSSOMStyleSheetText(String* result) {
+ if (origin_ != protocol::CSS::StyleSheetOriginEnum::Regular) {
return false;
- if (resource_container_->LoadStyleElementContent(
- DOMNodeIds::IdForNode(owner_element), result))
- return true;
- *result = owner_element->textContent();
+ }
+ *result = CollectStyleSheetRules();
return true;
}
+void InspectorStyleSheet::Reset() {
+ ResetLineEndings();
+ if (source_data_)
+ source_data_->clear();
+ cssom_flat_rules_.clear();
+ parsed_flat_rules_.clear();
+ rule_to_source_data_.clear();
+ source_data_to_rule_.clear();
+}
+
+void InspectorStyleSheet::SyncTextIfNeeded() {
+ if (!marked_for_sync_)
+ return;
+ Reset();
+ UpdateText();
+ marked_for_sync_ = false;
+}
+
+void InspectorStyleSheet::UpdateText() {
+ String text;
+ bool success = InspectorStyleSheetText(&text);
+ if (!success)
+ success = InlineStyleSheetText(&text);
+ if (!success)
+ success = ResourceStyleSheetText(&text);
+ if (!success)
+ success = CSSOMStyleSheetText(&text);
+ if (success)
+ InnerSetText(text, false);
+}
+
+bool InspectorStyleSheet::IsMutable() const {
+ return page_style_sheet_->Contents()->IsMutable();
+}
+
+bool InspectorStyleSheet::InlineStyleSheetText(String* out) {
+ Element* owner_element = OwnerStyleElement();
+ bool result = false;
+ if (!owner_element)
+ return result;
+
+ result = resource_container_->LoadStyleElementContent(
+ DOMNodeIds::IdForNode(owner_element), out);
+
+ if (!result) {
+ *out = owner_element->textContent();
+ result = true;
+ }
+
+ if (result && IsMutable()) {
+ ParseText(*out);
+ *out = MergeCSSOMRulesWithText(*out);
+ }
+
+ return result;
+}
+
bool InspectorStyleSheet::InspectorStyleSheetText(String* result) {
if (origin_ != protocol::CSS::StyleSheetOriginEnum::Inspector)
return false;
@@ -1991,7 +2104,7 @@ const String& InspectorStyleSheetForInlineStyle::ElementStyleText() {
return element_->getAttribute("style").GetString();
}
-void InspectorStyleSheetForInlineStyle::Trace(Visitor* visitor) {
+void InspectorStyleSheetForInlineStyle::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(inspector_style_);
InspectorStyleSheetBase::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.h b/chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.h
index 3f7fd47c06b..999d00e295c 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.h
@@ -67,7 +67,7 @@ class InspectorStyle final : public GarbageCollected<InspectorStyle> {
bool StyleText(String* result);
bool TextForRange(const SourceRange&, String* result);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void PopulateAllProperties(Vector<CSSPropertySourceData>& result);
@@ -89,7 +89,7 @@ class InspectorStyleSheetBase
virtual void StyleSheetChanged(InspectorStyleSheetBase*) = 0;
};
virtual ~InspectorStyleSheetBase() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
String Id() { return id_; }
@@ -113,6 +113,7 @@ class InspectorStyleSheetBase
Listener* GetListener() { return listener_; }
void OnStyleSheetTextChanged();
const LineEndings* GetLineEndings();
+ void ResetLineEndings();
virtual InspectorStyle* GetInspectorStyle(CSSStyleDeclaration*) = 0;
@@ -133,11 +134,14 @@ class InspectorStyleSheet : public InspectorStyleSheetBase {
InspectorStyleSheetBase::Listener*,
InspectorResourceContainer*);
~InspectorStyleSheet() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
String FinalURL();
bool SetText(const String&, ExceptionState&) override;
bool GetText(String* result) override;
+ void MarkForSync() { marked_for_sync_ = true; }
+ void SyncTextIfNeeded();
+
CSSStyleRule* SetRuleSelector(const SourceRange&,
const String& selector,
SourceRange* new_range,
@@ -212,6 +216,8 @@ class InspectorStyleSheet : public InspectorStyleSheetBase {
bool ResourceStyleSheetText(String* result);
bool InlineStyleSheetText(String* result);
bool InspectorStyleSheetText(String* result);
+ String CollectStyleSheetRules();
+ bool CSSOMStyleSheetText(String* result);
std::unique_ptr<protocol::Array<protocol::CSS::Value>> SelectorsFromSource(
CSSRuleSourceData*,
const String&);
@@ -219,11 +225,17 @@ class InspectorStyleSheet : public InspectorStyleSheetBase {
bool HasSourceURL();
bool StartsAtZero();
+ bool IsMutable() const;
+ void Reset();
+ void UpdateText();
+
void ReplaceText(const SourceRange&,
const String& text,
SourceRange* new_range,
String* old_text);
void InnerSetText(const String& new_text, bool mark_as_locally_modified);
+ void ParseText(const String& text);
+ String MergeCSSOMRulesWithText(const String& text);
Element* OwnerStyleElement();
Member<InspectorResourceContainer> resource_container_;
@@ -243,6 +255,8 @@ class InspectorStyleSheet : public InspectorStyleSheetBase {
IndexMap rule_to_source_data_;
IndexMap source_data_to_rule_;
String source_url_;
+ // True means that CSSOM rules are to be synced with the original source text.
+ bool marked_for_sync_;
};
class InspectorStyleSheetForInlineStyle final : public InspectorStyleSheetBase {
@@ -254,7 +268,7 @@ class InspectorStyleSheetForInlineStyle final : public InspectorStyleSheetBase {
CSSStyleDeclaration* InlineStyle();
CSSRuleSourceData* RuleSourceData();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const Document* GetDocument() override;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_task_runner.h b/chromium/third_party/blink/renderer/core/inspector/inspector_task_runner.h
index 212f2427c5b..011339ad2d9 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_task_runner.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_task_runner.h
@@ -52,6 +52,10 @@ class CORE_EXPORT InspectorTaskRunner final
// execution.
void AppendTaskDontInterrupt(Task) LOCKS_EXCLUDED(mutex_);
+ scoped_refptr<base::SingleThreadTaskRunner> isolate_task_runner() {
+ return isolate_task_runner_;
+ }
+
private:
friend ThreadSafeRefCounted<InspectorTaskRunner>;
explicit InspectorTaskRunner(
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_trace_events.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
index 88dad8dce93..bed4c015d5f 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
@@ -177,9 +177,12 @@ void InspectorTraceEvents::DidFinishLoading(uint64_t identifier,
decoded_body_length));
}
-void InspectorTraceEvents::DidFailLoading(uint64_t identifier,
- DocumentLoader* loader,
- const ResourceError&) {
+void InspectorTraceEvents::DidFailLoading(
+ CoreProbeSink* sink,
+ uint64_t identifier,
+ DocumentLoader* loader,
+ const ResourceError&,
+ const base::UnguessableToken& devtools_frame_or_worker_token) {
TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceFinish",
TRACE_EVENT_SCOPE_THREAD, "data",
inspector_resource_finish_event::Data(
@@ -392,43 +395,47 @@ const char* CompileOptionsString(v8::ScriptCompiler::CompileOptions options) {
const char* NotStreamedReasonString(ScriptStreamer::NotStreamingReason reason) {
switch (reason) {
- case ScriptStreamer::kNotHTTP:
+ case ScriptStreamer::NotStreamingReason::kNotHTTP:
return "not http/https protocol";
- case ScriptStreamer::kRevalidate:
+ case ScriptStreamer::NotStreamingReason::kRevalidate:
return "revalidation event";
- case ScriptStreamer::kContextNotValid:
+ case ScriptStreamer::NotStreamingReason::kContextNotValid:
return "script context not valid";
- case ScriptStreamer::kEncodingNotSupported:
+ case ScriptStreamer::NotStreamingReason::kEncodingNotSupported:
return "encoding not supported";
- case ScriptStreamer::kThreadBusy:
+ case ScriptStreamer::NotStreamingReason::kThreadBusy:
return "script streamer thread busy";
- case ScriptStreamer::kV8CannotStream:
+ case ScriptStreamer::NotStreamingReason::kV8CannotStream:
return "V8 cannot stream script";
- case ScriptStreamer::kScriptTooSmall:
+ case ScriptStreamer::NotStreamingReason::kScriptTooSmall:
return "script too small";
- case ScriptStreamer::kNoResourceBuffer:
+ case ScriptStreamer::NotStreamingReason::kNoResourceBuffer:
return "resource no longer alive";
- case ScriptStreamer::kHasCodeCache:
+ case ScriptStreamer::NotStreamingReason::kHasCodeCache:
return "script has code-cache available";
- case ScriptStreamer::kStreamerNotReadyOnGetSource:
+ case ScriptStreamer::NotStreamingReason::kStreamerNotReadyOnGetSource:
return "streamer not ready";
- case ScriptStreamer::kInlineScript:
+ case ScriptStreamer::NotStreamingReason::kInlineScript:
return "inline script";
- case ScriptStreamer::kDidntTryToStartStreaming:
- return "start streaming not called";
- case ScriptStreamer::kErrorOccurred:
+ case ScriptStreamer::NotStreamingReason::kErrorOccurred:
return "an error occurred";
- case ScriptStreamer::kStreamingDisabled:
+ case ScriptStreamer::NotStreamingReason::kStreamingDisabled:
return "already disabled streaming";
- case ScriptStreamer::kSecondScriptResourceUse:
+ case ScriptStreamer::NotStreamingReason::kSecondScriptResourceUse:
return "already used streamed data";
- case ScriptStreamer::kWorkerTopLevelScript:
+ case ScriptStreamer::NotStreamingReason::kWorkerTopLevelScript:
return "worker top-level scripts are not streamable";
- case ScriptStreamer::kModuleScript:
+ case ScriptStreamer::NotStreamingReason::kModuleScript:
return "module script";
- case ScriptStreamer::kAlreadyLoaded:
- case ScriptStreamer::kCount:
- case ScriptStreamer::kInvalid:
+ case ScriptStreamer::NotStreamingReason::kNoDataPipe:
+ return "no data pipe received";
+ case ScriptStreamer::NotStreamingReason::kDisabledByFeatureList:
+ return "streaming disabled from the feature list";
+ case ScriptStreamer::NotStreamingReason::kLoadingCancelled:
+ return "loading was cancelled";
+ case ScriptStreamer::NotStreamingReason::kDidntTryToStartStreaming:
+ case ScriptStreamer::NotStreamingReason::kAlreadyLoaded:
+ case ScriptStreamer::NotStreamingReason::kInvalid:
NOTREACHED();
}
NOTREACHED();
@@ -835,6 +842,30 @@ std::unique_ptr<TracedValue> inspector_receive_response_event::Data(
value->SetDouble("encodedDataLength", response.EncodedDataLength());
value->SetBoolean("fromCache", response.WasCached());
value->SetBoolean("fromServiceWorker", response.WasFetchedViaServiceWorker());
+
+ if (response.WasFetchedViaServiceWorker()) {
+ switch (response.GetServiceWorkerResponseSource()) {
+ case network::mojom::FetchResponseSource::kCacheStorage:
+ value->SetString("serviceWorkerResponseSource", "cacheStorage");
+ break;
+ case network::mojom::FetchResponseSource::kHttpCache:
+ value->SetString("serviceWorkerResponseSource", "httpCache");
+ break;
+ case network::mojom::FetchResponseSource::kNetwork:
+ value->SetString("serviceWorkerResponseSource", "network");
+ break;
+ case network::mojom::FetchResponseSource::kUnspecified:
+ value->SetString("serviceWorkerResponseSource", "fallbackCode");
+ }
+ }
+
+ if (!response.ResponseTime().is_null()) {
+ value->SetDouble("responseTime", response.ResponseTime().ToJsTime());
+ }
+ if (!response.CacheStorageCacheName().IsEmpty()) {
+ value->SetString("cacheStorageCacheName", response.CacheStorageCacheName());
+ }
+
if (response.GetResourceLoadTiming()) {
value->BeginDictionary("timing");
RecordTiming(*response.GetResourceLoadTiming(), value.get());
@@ -1209,8 +1240,8 @@ std::unique_ptr<TracedValue> inspector_paint_image_event::Data(
const FloatRect& dest_rect) {
auto value = std::make_unique<TracedValue>();
SetGeneratingNodeInfo(value.get(), &layout_image, "nodeId");
- if (const ImageResourceContent* resource = layout_image.CachedImage())
- value->SetString("url", resource->Url().GetString());
+ if (const ImageResourceContent* content = layout_image.CachedImage())
+ value->SetString("url", content->Url().GetString());
value->SetInteger("x", dest_rect.X());
value->SetInteger("y", dest_rect.Y());
@@ -1227,8 +1258,8 @@ std::unique_ptr<TracedValue> inspector_paint_image_event::Data(
const StyleImage& style_image) {
auto value = std::make_unique<TracedValue>();
SetGeneratingNodeInfo(value.get(), &owning_layout_object, "nodeId");
- if (const ImageResourceContent* resource = style_image.CachedImage())
- value->SetString("url", resource->Url().GetString());
+ if (const ImageResourceContent* content = style_image.CachedImage())
+ value->SetString("url", content->Url().GetString());
return value;
}
@@ -1240,8 +1271,8 @@ std::unique_ptr<TracedValue> inspector_paint_image_event::Data(
auto value = std::make_unique<TracedValue>();
if (node)
SetNodeInfo(value.get(), node, "nodeId", nullptr);
- if (const ImageResourceContent* resource = style_image.CachedImage())
- value->SetString("url", resource->Url().GetString());
+ if (const ImageResourceContent* content = style_image.CachedImage())
+ value->SetString("url", content->Url().GetString());
value->SetInteger("x", dest_rect.X());
value->SetInteger("y", dest_rect.Y());
@@ -1255,10 +1286,10 @@ std::unique_ptr<TracedValue> inspector_paint_image_event::Data(
std::unique_ptr<TracedValue> inspector_paint_image_event::Data(
const LayoutObject* owning_layout_object,
- const ImageResourceContent& image_resource) {
+ const ImageResourceContent& image_content) {
auto value = std::make_unique<TracedValue>();
SetGeneratingNodeInfo(value.get(), owning_layout_object, "nodeId");
- value->SetString("url", image_resource.Url().GetString());
+ value->SetString("url", image_content.Url().GetString());
return value;
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_trace_events.h b/chromium/third_party/blink/renderer/core/inspector/inspector_trace_events.h
index 589e587e905..4246f36fdbd 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_trace_events.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_trace_events.h
@@ -11,6 +11,7 @@
#include "base/optional.h"
#include "third_party/blink/renderer/bindings/core/v8/script_streamer.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/core_probe_sink.h"
#include "third_party/blink/renderer/core/css/css_selector.h"
#include "third_party/blink/renderer/core/loader/frame_loader_types.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -109,9 +110,12 @@ class CORE_EXPORT InspectorTraceEvents
int64_t encoded_data_length,
int64_t decoded_body_length,
bool should_report_corb_blocking);
- void DidFailLoading(uint64_t identifier,
- DocumentLoader*,
- const ResourceError&);
+ void DidFailLoading(
+ CoreProbeSink* sink,
+ uint64_t identifier,
+ DocumentLoader*,
+ const ResourceError&,
+ const base::UnguessableToken& devtools_frame_or_worker_token);
void MarkResourceAsCached(DocumentLoader* loader, uint64_t identifier);
void Will(const probe::ExecuteScript&);
@@ -127,7 +131,7 @@ class CORE_EXPORT InspectorTraceEvents
void FrameStartedLoading(LocalFrame*);
- void Trace(Visitor*) {}
+ void Trace(Visitor*) const {}
private:
DISALLOW_COPY_AND_ASSIGN(InspectorTraceEvents);
diff --git a/chromium/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc b/chromium/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
index e39da971aaf..86f58b0d198 100644
--- a/chromium/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
@@ -386,7 +386,7 @@ int LegacyDOMSnapshotAgent::VisitLayoutTreeNode(LayoutObject* layout_object,
if (style_index != -1)
layout_tree_node->setStyleIndex(style_index);
- if (layout_object->Style() && layout_object->Style()->IsStackingContext())
+ if (layout_object->Style() && layout_object->IsStackingContext())
layout_tree_node->setIsStackingContext(true);
if (paint_order_map_) {
diff --git a/chromium/third_party/blink/renderer/core/inspector/main_thread_debugger.cc b/chromium/third_party/blink/renderer/core/inspector/main_thread_debugger.cc
index a7d3ab1ff45..bfe349178ce 100644
--- a/chromium/third_party/blink/renderer/core/inspector/main_thread_debugger.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/main_thread_debugger.cc
@@ -310,7 +310,7 @@ void MainThreadDebugger::endEnsureAllContextsInGroup(int context_group_id) {
bool MainThreadDebugger::canExecuteScripts(int context_group_id) {
LocalFrame* frame = WeakIdentifierMap<LocalFrame>::Lookup(context_group_id);
- return frame->GetDocument()->CanExecuteScripts(kNotAboutToExecuteScript);
+ return frame->DomWindow()->CanExecuteScripts(kNotAboutToExecuteScript);
}
void MainThreadDebugger::runIfWaitingForDebugger(int context_group_id) {
diff --git a/chromium/third_party/blink/renderer/core/inspector/network_resources_data.cc b/chromium/third_party/blink/renderer/core/inspector/network_resources_data.cc
index fbbb16aa534..99b030ac6be 100644
--- a/chromium/third_party/blink/renderer/core/inspector/network_resources_data.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/network_resources_data.cc
@@ -75,7 +75,7 @@ NetworkResourcesData::ResourceData::ResourceData(
pending_encoded_data_length_(0),
cached_resource_(nullptr) {}
-void NetworkResourcesData::ResourceData::Trace(Visitor* visitor) {
+void NetworkResourcesData::ResourceData::Trace(Visitor* visitor) const {
visitor->Trace(network_resources_data_);
visitor->Trace(xhr_replay_data_);
visitor->template RegisterWeakCallbackMethod<
@@ -121,6 +121,8 @@ size_t NetworkResourcesData::ResourceData::EvictContent() {
void NetworkResourcesData::ResourceData::SetResource(
const Resource* cached_resource) {
cached_resource_ = cached_resource;
+ if (cached_resource && cached_resource->GetType() == ResourceType::kFont)
+ ToFontResource(cached_resource)->AddClearDataObserver(this);
}
void NetworkResourcesData::ResourceData::ProcessCustomWeakness(
@@ -148,6 +150,17 @@ void NetworkResourcesData::ResourceData::ProcessCustomWeakness(
cached_resource_ = nullptr;
}
+void NetworkResourcesData::ResourceData::FontResourceDataWillBeCleared() {
+ if (cached_resource_->ResourceBuffer()) {
+ // Save the cached resource before its data becomes unavailable.
+ network_resources_data_->MaybeAddResourceData(
+ RequestId(), cached_resource_->ResourceBuffer());
+ }
+ // There is no point tracking the resource anymore.
+ cached_resource_ = nullptr;
+ network_resources_data_->MaybeDecodeDataToContent(RequestId());
+}
+
uint64_t NetworkResourcesData::ResourceData::DataLength() const {
uint64_t data_length = 0;
if (data_buffer_)
@@ -189,7 +202,7 @@ NetworkResourcesData::NetworkResourcesData(size_t total_buffer_size,
NetworkResourcesData::~NetworkResourcesData() = default;
-void NetworkResourcesData::Trace(Visitor* visitor) {
+void NetworkResourcesData::Trace(Visitor* visitor) const {
visitor->Trace(request_id_to_resource_data_map_);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/network_resources_data.h b/chromium/third_party/blink/renderer/core/inspector/network_resources_data.h
index 2346a511a4f..11811d94430 100644
--- a/chromium/third_party/blink/renderer/core/inspector/network_resources_data.h
+++ b/chromium/third_party/blink/renderer/core/inspector/network_resources_data.h
@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
#include "third_party/blink/renderer/core/inspector/inspector_page_agent.h"
+#include "third_party/blink/renderer/core/loader/resource/font_resource.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/network/http_header_map.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -44,7 +45,6 @@ namespace blink {
class EncodedFormData;
class ExecutionContext;
-class Resource;
class ResourceResponse;
class TextResourceDecoder;
@@ -65,7 +65,9 @@ class XHRReplayData final : public GarbageCollected<XHRReplayData> {
const HTTPHeaderMap& Headers() const { return headers_; }
bool IncludeCredentials() const { return include_credentials_; }
- virtual void Trace(Visitor* visitor) { visitor->Trace(execution_context_); }
+ virtual void Trace(Visitor* visitor) const {
+ visitor->Trace(execution_context_);
+ }
private:
WeakMember<ExecutionContext> execution_context_;
@@ -79,7 +81,9 @@ class XHRReplayData final : public GarbageCollected<XHRReplayData> {
class NetworkResourcesData final
: public GarbageCollected<NetworkResourcesData> {
public:
- class ResourceData final : public GarbageCollected<ResourceData> {
+ class ResourceData final : public GarbageCollected<ResourceData>,
+ public FontResourceClearDataObserver {
+ USING_GARBAGE_COLLECTED_MIXIN(ResourceData);
friend class NetworkResourcesData;
public:
@@ -160,7 +164,11 @@ class NetworkResourcesData final
post_data_ = post_data;
}
EncodedFormData* PostData() const { return post_data_.get(); }
- void Trace(Visitor*);
+
+ // FontResourceClearDataObserver implementation.
+ void FontResourceDataWillBeCleared() override;
+
+ void Trace(Visitor*) const override;
private:
bool HasData() const { return data_buffer_.get(); }
@@ -233,7 +241,7 @@ class NetworkResourcesData final
int64_t GetAndClearPendingEncodedDataLength(const String& request_id);
void AddPendingEncodedDataLength(const String& request_id,
size_t encoded_data_length);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
ResourceData* ResourceDataForRequestId(const String& request_id) const;
diff --git a/chromium/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc b/chromium/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc
index e9e2fe1c23e..bfbc89b6495 100644
--- a/chromium/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc
@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/core/inspector/devtools_session.h"
#include "third_party/blink/renderer/core/inspector/inspector_audits_agent.h"
#include "third_party/blink/renderer/core/inspector/inspector_emulation_agent.h"
+#include "third_party/blink/renderer/core/inspector/inspector_issue_reporter.h"
#include "third_party/blink/renderer/core/inspector/inspector_log_agent.h"
#include "third_party/blink/renderer/core/inspector/inspector_network_agent.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
@@ -74,6 +75,9 @@ WorkerInspectorController::WorkerInspectorController(
thread_(thread),
inspected_frames_(nullptr),
probe_sink_(MakeGarbageCollected<CoreProbeSink>()) {
+ probe_sink_->AddInspectorIssueReporter(
+ MakeGarbageCollected<InspectorIssueReporter>(
+ thread->GetInspectorIssueStorage()));
probe_sink_->AddInspectorTraceEvents(
MakeGarbageCollected<InspectorTraceEvents>());
worker_devtools_token_ = devtools_params->devtools_worker_token;
@@ -183,7 +187,7 @@ void WorkerInspectorController::EmitTraceEvent() {
worker_thread_id_));
}
-void WorkerInspectorController::Trace(Visitor* visitor) {
+void WorkerInspectorController::Trace(Visitor* visitor) const {
visitor->Trace(agent_);
visitor->Trace(inspected_frames_);
visitor->Trace(probe_sink_);
diff --git a/chromium/third_party/blink/renderer/core/inspector/worker_inspector_controller.h b/chromium/third_party/blink/renderer/core/inspector/worker_inspector_controller.h
index 21585d1f3f5..f6372dc9af3 100644
--- a/chromium/third_party/blink/renderer/core/inspector/worker_inspector_controller.h
+++ b/chromium/third_party/blink/renderer/core/inspector/worker_inspector_controller.h
@@ -70,7 +70,7 @@ class WorkerInspectorController final
scoped_refptr<InspectorTaskRunner>,
std::unique_ptr<WorkerDevToolsParams>);
~WorkerInspectorController() override;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
CoreProbeSink* GetProbeSink() const { return probe_sink_.Get(); }
DevToolsAgent* GetDevToolsAgent() const { return agent_.Get(); }
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.cc b/chromium/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.cc
index 7560f2a741c..701e1408643 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.cc
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.cc
@@ -83,7 +83,7 @@ void ElementIntersectionObserverData::InvalidateCachedRects() {
entry.value->InvalidateCachedRects();
}
-void ElementIntersectionObserverData::Trace(Visitor* visitor) {
+void ElementIntersectionObserverData::Trace(Visitor* visitor) const {
visitor->Trace(observations_);
visitor->Trace(observers_);
}
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h b/chromium/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h
index 641603fbca3..92682df732a 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h
@@ -46,7 +46,7 @@ class CORE_EXPORT ElementIntersectionObserverData final
// algorithm is invalid and must be recomputed.
void InvalidateCachedRects();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override {
return "ElementIntersectionObserverData";
}
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
index eef6e1da665..b54140b258b 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
@@ -51,34 +51,72 @@ LayoutUnit ComputeMargin(const Length& length,
}
// Expand rect by the given margin values.
-void ApplyRootMargin(PhysicalRect& rect,
- const Vector<Length>& margin,
- float zoom) {
+void ApplyMargin(
+ PhysicalRect& expand_rect,
+ const Vector<Length>& margin,
+ float zoom,
+ const base::Optional<PhysicalRect>& resolution_rect = base::nullopt) {
if (margin.IsEmpty())
return;
// TODO(szager): Make sure the spec is clear that left/right margins are
// resolved against width and not height.
+ const PhysicalRect& rect = resolution_rect.value_or(expand_rect);
LayoutRectOutsets outsets(ComputeMargin(margin[0], rect.Height(), zoom),
ComputeMargin(margin[1], rect.Width(), zoom),
ComputeMargin(margin[2], rect.Height(), zoom),
ComputeMargin(margin[3], rect.Width(), zoom));
- rect.Expand(outsets);
+ expand_rect.Expand(outsets);
+}
+
+// Returns the root intersect rect for the given root object, with the given
+// margins applied, in the coordinate system of the root object.
+//
+// https://w3c.github.io/IntersectionObserver/#intersectionobserver-root-intersection-rectangle
+PhysicalRect InitializeRootRect(const LayoutObject* root,
+ const Vector<Length>& margin) {
+ DCHECK(margin.IsEmpty() || margin.size() == 4);
+ PhysicalRect result;
+ auto* layout_view = DynamicTo<LayoutView>(root);
+ if (layout_view && root->GetDocument().IsInMainFrame()) {
+ // The main frame is a bit special as the scrolling viewport can differ in
+ // size from the LayoutView itself. There's two situations this occurs in:
+ // 1) The ForceZeroLayoutHeight quirk setting is used in Android WebView for
+ // compatibility and sets the initial-containing-block's (a.k.a.
+ // LayoutView) height to 0. Thus, we can't use its size for intersection
+ // testing. Use the FrameView geometry instead.
+ // 2) An element wider than the ICB can cause us to resize the FrameView so
+ // we can zoom out to fit the entire element width.
+ result = layout_view->OverflowClipRect(PhysicalOffset());
+ } else if (root->IsBox() && root->HasOverflowClip()) {
+ result = ToLayoutBox(root)->PhysicalContentBoxRect();
+ } else {
+ result = PhysicalRect(ToLayoutBoxModelObject(root)->BorderBoundingBox());
+ }
+ ApplyMargin(result, margin, root->StyleRef().EffectiveZoom());
+ return result;
}
// Return the bounding box of target in target's own coordinate system
-PhysicalRect InitializeTargetRect(const LayoutObject* target, unsigned flags) {
+PhysicalRect InitializeTargetRect(const LayoutObject* target,
+ unsigned flags,
+ const Vector<Length>& margin,
+ const LayoutObject* root) {
+ PhysicalRect result;
if ((flags & IntersectionGeometry::kShouldUseReplacedContentRect) &&
target->IsLayoutEmbeddedContent()) {
- return ToLayoutEmbeddedContent(target)->ReplacedContentRect();
- }
- if (target->IsBox())
- return PhysicalRect(ToLayoutBoxModelObject(target)->BorderBoundingBox());
- if (target->IsLayoutInline()) {
- return target->AbsoluteToLocalRect(
+ result = ToLayoutEmbeddedContent(target)->ReplacedContentRect();
+ } else if (target->IsBox()) {
+ result = PhysicalRect(ToLayoutBoxModelObject(target)->BorderBoundingBox());
+ } else if (target->IsLayoutInline()) {
+ result = target->AbsoluteToLocalRect(
PhysicalRect::EnclosingRect(target->AbsoluteBoundingBoxFloatRect()));
+ } else {
+ result = ToLayoutText(target)->PhysicalLinesBoundingBox();
}
- return ToLayoutText(target)->PhysicalLinesBoundingBox();
+ ApplyMargin(result, margin, root->StyleRef().EffectiveZoom(),
+ InitializeRootRect(root, {} /* margin */));
+ return result;
}
// Return the local frame root for a given object
@@ -93,7 +131,6 @@ LayoutView* LocalRootView(const LayoutObject& object) {
//
// https://w3c.github.io/IntersectionObserver/v2/#calculate-visibility-algo
bool ComputeIsVisible(const LayoutObject* target, const PhysicalRect& rect) {
- DCHECK(RuntimeEnabledFeatures::IntersectionObserverV2Enabled());
if (target->GetDocument().GetFrame()->LocalFrameRoot().GetOcclusionState() !=
FrameOcclusionState::kGuaranteedNotOccluded) {
return false;
@@ -114,34 +151,6 @@ bool ComputeIsVisible(const LayoutObject* target, const PhysicalRect& rect) {
return false;
}
-// Returns the root intersect rect for the given root object, with the given
-// margins applied, in the coordinate system of the root object.
-//
-// https://w3c.github.io/IntersectionObserver/#intersectionobserver-root-intersection-rectangle
-PhysicalRect InitializeRootRect(const LayoutObject* root,
- const Vector<Length>& margin) {
- DCHECK(margin.IsEmpty() || margin.size() == 4);
- PhysicalRect result;
- auto* layout_view = DynamicTo<LayoutView>(root);
- if (layout_view && root->GetDocument().IsInMainFrame()) {
- // The main frame is a bit special as the scrolling viewport can differ in
- // size from the LayoutView itself. There's two situations this occurs in:
- // 1) The ForceZeroLayoutHeight quirk setting is used in Android WebView for
- // compatibility and sets the initial-containing-block's (a.k.a.
- // LayoutView) height to 0. Thus, we can't use its size for intersection
- // testing. Use the FrameView geometry instead.
- // 2) An element wider than the ICB can cause us to resize the FrameView so
- // we can zoom out to fit the entire element width.
- result = layout_view->OverflowClipRect(PhysicalOffset());
- } else if (root->IsBox() && root->HasOverflowClip()) {
- result = ToLayoutBox(root)->PhysicalContentBoxRect();
- } else {
- result = PhysicalRect(ToLayoutBoxModelObject(root)->BorderBoundingBox());
- }
- ApplyRootMargin(result, margin, root->StyleRef().EffectiveZoom());
- return result;
-}
-
// Validates the given target element and returns its LayoutObject
LayoutObject* GetTargetLayoutObject(const Element& target_element) {
if (!target_element.isConnected())
@@ -224,11 +233,15 @@ IntersectionGeometry::IntersectionGeometry(const Node* root_node,
const Element& target_element,
const Vector<Length>& root_margin,
const Vector<float>& thresholds,
+ const Vector<Length>& target_margin,
unsigned flags,
CachedRects* cached_rects)
: flags_(flags & kConstructorFlagsMask),
intersection_ratio_(0),
threshold_index_(0) {
+ // Only one of root_margin or target_margin can be specified.
+ DCHECK(root_margin.IsEmpty() || target_margin.IsEmpty());
+
if (cached_rects)
cached_rects->valid = false;
if (!root_node)
@@ -241,13 +254,15 @@ IntersectionGeometry::IntersectionGeometry(const Node* root_node,
if (!root)
return;
RootGeometry root_geometry(root, root_margin);
- ComputeGeometry(root_geometry, root, target, thresholds, cached_rects);
+ ComputeGeometry(root_geometry, root, target, thresholds, target_margin,
+ cached_rects);
}
IntersectionGeometry::IntersectionGeometry(const RootGeometry& root_geometry,
const Node& explicit_root,
const Element& target_element,
const Vector<float>& thresholds,
+ const Vector<Length>& target_margin,
unsigned flags,
CachedRects* cached_rects)
: flags_(flags & kConstructorFlagsMask),
@@ -262,13 +277,15 @@ IntersectionGeometry::IntersectionGeometry(const RootGeometry& root_geometry,
&explicit_root, target, !ShouldUseCachedRects());
if (!root)
return;
- ComputeGeometry(root_geometry, root, target, thresholds, cached_rects);
+ ComputeGeometry(root_geometry, root, target, thresholds, target_margin,
+ cached_rects);
}
void IntersectionGeometry::ComputeGeometry(const RootGeometry& root_geometry,
const LayoutObject* root,
const LayoutObject* target,
const Vector<float>& thresholds,
+ const Vector<Length>& target_margin,
CachedRects* cached_rects) {
DCHECK(cached_rects || !ShouldUseCachedRects());
// Initially:
@@ -284,7 +301,7 @@ void IntersectionGeometry::ComputeGeometry(const RootGeometry& root_geometry,
unclipped_intersection_rect_ =
cached_rects->unscrolled_unclipped_intersection_rect;
} else {
- target_rect_ = InitializeTargetRect(target, flags_);
+ target_rect_ = InitializeTargetRect(target, flags_, target_margin, root);
// We have to map/clip target_rect_ up to the root, so we begin with the
// intersection rect in target's coordinate system. After ClipToRoot, it
// will be in root's coordinate system.
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_geometry.h b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_geometry.h
index be2d8bc20dc..59a41662cb3 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_geometry.h
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_geometry.h
@@ -76,6 +76,7 @@ class CORE_EXPORT IntersectionGeometry {
const Element& target,
const Vector<Length>& root_margin,
const Vector<float>& thresholds,
+ const Vector<Length>& target_margin,
unsigned flags,
CachedRects* cached_rects = nullptr);
@@ -83,6 +84,7 @@ class CORE_EXPORT IntersectionGeometry {
const Node& explicit_root,
const Element& target,
const Vector<float>& thresholds,
+ const Vector<Length>& target_margin,
unsigned flags,
CachedRects* cached_rects = nullptr);
@@ -127,6 +129,7 @@ class CORE_EXPORT IntersectionGeometry {
const LayoutObject* root,
const LayoutObject* target,
const Vector<float>& thresholds,
+ const Vector<Length>& target_margin,
CachedRects* cached_rects);
// Map intersection_rect from the coordinate system of the target to the
// coordinate system of the root, applying intervening clips.
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
index 1e58a306d96..d8e49a84860 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
@@ -48,9 +48,9 @@ void IntersectionObservation::ComputeIntersection(
return;
DCHECK(observer_->root());
unsigned geometry_flags = GetIntersectionGeometryFlags(compute_flags);
- IntersectionGeometry geometry(root_geometry, *observer_->root(), *Target(),
- observer_->thresholds(), geometry_flags,
- cached_rects_.get());
+ IntersectionGeometry geometry(
+ root_geometry, *observer_->root(), *Target(), observer_->thresholds(),
+ observer_->TargetMargin(), geometry_flags, cached_rects_.get());
ProcessIntersectionGeometry(geometry);
}
@@ -58,9 +58,9 @@ void IntersectionObservation::ComputeIntersection(unsigned compute_flags) {
if (!ShouldCompute(compute_flags))
return;
unsigned geometry_flags = GetIntersectionGeometryFlags(compute_flags);
- IntersectionGeometry geometry(observer_->root(), *Target(),
- observer_->RootMargin(),
- observer_->thresholds(), geometry_flags);
+ IntersectionGeometry geometry(
+ observer_->root(), *Target(), observer_->RootMargin(),
+ observer_->thresholds(), observer_->TargetMargin(), geometry_flags);
ProcessIntersectionGeometry(geometry);
}
@@ -93,7 +93,7 @@ void IntersectionObservation::InvalidateCachedRects() {
cached_rects_->valid = false;
}
-void IntersectionObservation::Trace(Visitor* visitor) {
+void IntersectionObservation::Trace(Visitor* visitor) const {
visitor->Trace(observer_);
visitor->Trace(entries_);
visitor->Trace(target_);
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observation.h b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observation.h
index 9aeabf8de67..0d1c721ff3c 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observation.h
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observation.h
@@ -58,7 +58,7 @@ class CORE_EXPORT IntersectionObservation final
void Disconnect();
void InvalidateCachedRects();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
bool CanUseCachedRectsForTesting() const { return CanUseCachedRects(); }
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc
index ad5235457b6..52eecf359b6 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc
@@ -60,7 +60,7 @@ class IntersectionObserverDelegateImpl final
ExecutionContext* GetExecutionContext() const override { return context_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
IntersectionObserverDelegate::Trace(visitor);
visitor->Trace(context_);
}
@@ -72,9 +72,9 @@ class IntersectionObserverDelegateImpl final
DISALLOW_COPY_AND_ASSIGN(IntersectionObserverDelegateImpl);
};
-void ParseRootMargin(String root_margin_parameter,
- Vector<Length>& root_margin,
- ExceptionState& exception_state) {
+void ParseMargin(String margin_parameter,
+ Vector<Length>& margin,
+ ExceptionState& exception_state) {
// TODO(szager): Make sure this exact syntax and behavior is spec-ed
// somewhere.
@@ -84,12 +84,12 @@ void ParseRootMargin(String root_margin_parameter,
// "1px 2px" = top/bottom left/right
// "1px 2px 3px" = top left/right bottom
// "1px 2px 3px 4px" = top left right bottom
- CSSTokenizer tokenizer(root_margin_parameter);
+ CSSTokenizer tokenizer(margin_parameter);
const auto tokens = tokenizer.TokenizeToEOF();
CSSParserTokenRange token_range(tokens);
while (token_range.Peek().GetType() != kEOFToken &&
!exception_state.HadException()) {
- if (root_margin.size() == 4) {
+ if (margin.size() == 4) {
exception_state.ThrowDOMException(
DOMExceptionCode::kSyntaxError,
"Extra text found at the end of rootMargin.");
@@ -98,16 +98,16 @@ void ParseRootMargin(String root_margin_parameter,
const CSSParserToken& token = token_range.ConsumeIncludingWhitespace();
switch (token.GetType()) {
case kPercentageToken:
- root_margin.push_back(Length::Percent(token.NumericValue()));
+ margin.push_back(Length::Percent(token.NumericValue()));
break;
case kDimensionToken:
switch (token.GetUnitType()) {
case CSSPrimitiveValue::UnitType::kPixels:
- root_margin.push_back(
+ margin.push_back(
Length::Fixed(static_cast<int>(floor(token.NumericValue()))));
break;
case CSSPrimitiveValue::UnitType::kPercentage:
- root_margin.push_back(Length::Percent(token.NumericValue()));
+ margin.push_back(Length::Percent(token.NumericValue()));
break;
default:
exception_state.ThrowDOMException(
@@ -169,24 +169,22 @@ IntersectionObserver* IntersectionObserver::Create(
DOMHighResTimeStamp delay = 0;
bool track_visibility = false;
- if (RuntimeEnabledFeatures::IntersectionObserverV2Enabled()) {
- delay = observer_init->delay();
- track_visibility = observer_init->trackVisibility();
- if (track_visibility && delay < 100) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kNotSupportedError,
- "To enable the 'trackVisibility' option, you must also use a "
- "'delay' option with a value of at least 100. Visibility is more "
- "expensive to compute than the basic intersection; enabling this "
- "option may negatively affect your page's performance. Please make "
- "sure you *really* need visibility tracking before enabling the "
- "'trackVisibility' option.");
- return nullptr;
- }
+ delay = observer_init->delay();
+ track_visibility = observer_init->trackVisibility();
+ if (track_visibility && delay < 100) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotSupportedError,
+ "To enable the 'trackVisibility' option, you must also use a "
+ "'delay' option with a value of at least 100. Visibility is more "
+ "expensive to compute than the basic intersection; enabling this "
+ "option may negatively affect your page's performance. Please make "
+ "sure you *really* need visibility tracking before enabling the "
+ "'trackVisibility' option.");
+ return nullptr;
}
- Vector<Length> root_margin;
- ParseRootMargin(observer_init->rootMargin(), root_margin, exception_state);
+ Vector<Length> margin;
+ ParseMargin(observer_init->rootMargin(), margin, exception_state);
if (exception_state.HadException())
return nullptr;
@@ -196,8 +194,8 @@ IntersectionObserver* IntersectionObserver::Create(
return nullptr;
return MakeGarbageCollected<IntersectionObserver>(
- delegate, root, root_margin, thresholds, kFractionOfTarget, delay,
- track_visibility, false);
+ delegate, root, margin, thresholds, kFractionOfTarget, delay,
+ track_visibility, false, kApplyMarginToRoot);
}
IntersectionObserver* IntersectionObserver::Create(
@@ -216,7 +214,7 @@ IntersectionObserver* IntersectionObserver::Create(
}
IntersectionObserver* IntersectionObserver::Create(
- const Vector<Length>& root_margin,
+ const Vector<Length>& margin,
const Vector<float>& thresholds,
Document* document,
EventCallback callback,
@@ -225,57 +223,59 @@ IntersectionObserver* IntersectionObserver::Create(
DOMHighResTimeStamp delay,
bool track_visibility,
bool always_report_root_bounds,
+ MarginTarget margin_target,
ExceptionState& exception_state) {
IntersectionObserverDelegateImpl* intersection_observer_delegate =
MakeGarbageCollected<IntersectionObserverDelegateImpl>(
document->GetExecutionContext(), std::move(callback), behavior);
return MakeGarbageCollected<IntersectionObserver>(
- *intersection_observer_delegate, nullptr, root_margin, thresholds,
- semantics, delay, track_visibility, always_report_root_bounds);
+ *intersection_observer_delegate, nullptr, margin, thresholds, semantics,
+ delay, track_visibility, always_report_root_bounds, margin_target);
}
IntersectionObserver::IntersectionObserver(
IntersectionObserverDelegate& delegate,
Node* root,
- const Vector<Length>& root_margin,
+ const Vector<Length>& margin,
const Vector<float>& thresholds,
ThresholdInterpretation semantics,
DOMHighResTimeStamp delay,
bool track_visibility,
- bool always_report_root_bounds)
+ bool always_report_root_bounds,
+ MarginTarget margin_target)
: ExecutionContextClient(delegate.GetExecutionContext()),
delegate_(&delegate),
root_(root),
thresholds_(thresholds),
delay_(delay),
- root_margin_(4, Length::Fixed(0)),
+ margin_(4, Length::Fixed(0)),
+ margin_target_(margin_target),
root_is_implicit_(root ? 0 : 1),
track_visibility_(track_visibility),
track_fraction_of_root_(semantics == kFractionOfRoot),
always_report_root_bounds_(always_report_root_bounds),
needs_delivery_(0),
can_use_cached_rects_(0) {
- switch (root_margin.size()) {
+ switch (margin.size()) {
case 0:
break;
case 1:
- root_margin_[0] = root_margin_[1] = root_margin_[2] = root_margin_[3] =
- root_margin[0];
+ margin_[0] = margin_[1] = margin_[2] = margin_[3] = margin[0];
break;
case 2:
- root_margin_[0] = root_margin_[2] = root_margin[0];
- root_margin_[1] = root_margin_[3] = root_margin[1];
+ margin_[0] = margin_[2] = margin[0];
+ margin_[1] = margin_[3] = margin[1];
break;
case 3:
- root_margin_[0] = root_margin[0];
- root_margin_[1] = root_margin_[3] = root_margin[1];
- root_margin_[2] = root_margin[2];
+ margin_[0] = margin[0];
+ margin_[1] = margin_[3] = margin[1];
+ margin_[2] = margin[2];
break;
case 4:
- root_margin_[0] = root_margin[0];
- root_margin_[1] = root_margin[1];
- root_margin_[2] = root_margin[2];
- root_margin_[3] = root_margin[3];
+ margin_[0] = margin[0];
+ margin_[1] = margin[1];
+ margin_[2] = margin[2];
+ margin_[3] = margin[3];
break;
default:
NOTREACHED();
@@ -398,13 +398,19 @@ static void AppendLength(StringBuilder& string_builder, const Length& length) {
String IntersectionObserver::rootMargin() const {
StringBuilder string_builder;
- AppendLength(string_builder, root_margin_[0]);
- string_builder.Append(' ');
- AppendLength(string_builder, root_margin_[1]);
- string_builder.Append(' ');
- AppendLength(string_builder, root_margin_[2]);
- string_builder.Append(' ');
- AppendLength(string_builder, root_margin_[3]);
+ const auto& margin = RootMargin();
+ if (margin.IsEmpty()) {
+ string_builder.Append("0px 0px 0px 0px");
+ } else {
+ DCHECK_EQ(margin.size(), 4u);
+ AppendLength(string_builder, margin[0]);
+ string_builder.Append(' ');
+ AppendLength(string_builder, margin[1]);
+ string_builder.Append(' ');
+ AppendLength(string_builder, margin[2]);
+ string_builder.Append(' ');
+ AppendLength(string_builder, margin[3]);
+ }
return string_builder.ToString();
}
@@ -425,7 +431,7 @@ bool IntersectionObserver::ComputeIntersections(unsigned flags) {
IntersectionGeometry::RootGeometry root_geometry(
IntersectionGeometry::GetRootLayoutObjectForTarget(root(), nullptr,
false),
- root_margin_);
+ RootMargin());
HeapVector<Member<IntersectionObservation>> observations_to_process;
// TODO(szager): Is this copy necessary?
CopyToVector(observations_, observations_to_process);
@@ -466,7 +472,7 @@ bool IntersectionObserver::HasPendingActivity() const {
return !observations_.IsEmpty();
}
-void IntersectionObserver::Trace(Visitor* visitor) {
+void IntersectionObserver::Trace(Visitor* visitor) const {
visitor->template RegisterWeakCallbackMethod<
IntersectionObserver, &IntersectionObserver::ProcessCustomWeakness>(this);
visitor->Trace(delegate_);
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.h b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.h
index f1747a98120..162c3308cfb 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.h
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.h
@@ -71,6 +71,18 @@ class CORE_EXPORT IntersectionObserver final
kPostTaskToDeliver
};
+ // Used to specify whether the margins apply to the root element or the source
+ // element. The effect of the root element margins is that intermediate
+ // scrollers clip content by its bounding box without considering margins.
+ // That is, margins only apply to the last scroller (root). The effect of
+ // source element margins is that the margins apply to the first / deepest
+ // clipper, but do not apply to any other clippers. Note that in a case of a
+ // single clipper, the two approaches are equivalent.
+ //
+ // Note that the percentage margin is resolved against the root rect, even
+ // when the margin is applied to the target.
+ enum MarginTarget { kApplyMarginToRoot, kApplyMarginToTarget };
+
static IntersectionObserver* Create(const IntersectionObserverInit*,
IntersectionObserverDelegate&,
ExceptionState& = ASSERT_NO_EXCEPTION);
@@ -85,7 +97,7 @@ class CORE_EXPORT IntersectionObserver final
// interpreted according to the given |semantics|. |delay| specifies the
// minimum period between change notifications.
static IntersectionObserver* Create(
- const Vector<Length>& root_margin,
+ const Vector<Length>& margin,
const Vector<float>& thresholds,
Document* document,
EventCallback callback,
@@ -94,18 +106,20 @@ class CORE_EXPORT IntersectionObserver final
DOMHighResTimeStamp delay = 0,
bool track_visbility = false,
bool always_report_root_bounds = false,
+ MarginTarget margin_target = kApplyMarginToRoot,
ExceptionState& = ASSERT_NO_EXCEPTION);
static void ResumeSuspendedObservers();
explicit IntersectionObserver(IntersectionObserverDelegate&,
Node*,
- const Vector<Length>& root_margin,
+ const Vector<Length>& margin,
const Vector<float>& thresholds,
ThresholdInterpretation semantics,
DOMHighResTimeStamp delay,
bool track_visibility,
- bool always_report_root_bounds);
+ bool always_report_root_bounds,
+ MarginTarget margin_target);
// API methods.
void observe(Element*, ExceptionState& = ASSERT_NO_EXCEPTION);
@@ -137,11 +151,12 @@ class CORE_EXPORT IntersectionObserver final
DOMHighResTimeStamp GetTimeStamp() const;
DOMHighResTimeStamp GetEffectiveDelay() const;
- const Vector<Length>& RootMargin() const { return root_margin_; }
- const Length& TopMargin() const { return root_margin_[0]; }
- const Length& RightMargin() const { return root_margin_[1]; }
- const Length& BottomMargin() const { return root_margin_[2]; }
- const Length& LeftMargin() const { return root_margin_[3]; }
+ Vector<Length> RootMargin() const {
+ return margin_target_ == kApplyMarginToRoot ? margin_ : Vector<Length>();
+ }
+ Vector<Length> TargetMargin() const {
+ return margin_target_ == kApplyMarginToTarget ? margin_ : Vector<Length>();
+ }
bool ComputeIntersections(unsigned flags);
@@ -158,7 +173,7 @@ class CORE_EXPORT IntersectionObserver final
// ScriptWrappable override:
bool HasPendingActivity() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Enable/disable throttling of visibility checking, so we don't have to add
// sleep() calls to tests to wait for notifications to show up.
@@ -175,7 +190,8 @@ class CORE_EXPORT IntersectionObserver final
HeapLinkedHashSet<WeakMember<IntersectionObservation>> observations_;
Vector<float> thresholds_;
DOMHighResTimeStamp delay_;
- Vector<Length> root_margin_;
+ Vector<Length> margin_;
+ MarginTarget margin_target_;
unsigned root_is_implicit_ : 1;
unsigned track_visibility_ : 1;
unsigned track_fraction_of_root_ : 1;
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.idl b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.idl
index f55852bbbd8..d3253b6a06d 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.idl
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.idl
@@ -15,8 +15,8 @@ callback IntersectionObserverCallback = void (sequence<IntersectionObserverEntry
readonly attribute DOMString rootMargin;
// https://github.com/WICG/IntersectionObserver/issues/114
readonly attribute FrozenArray<double> thresholds;
- [RuntimeEnabled=IntersectionObserverV2] readonly attribute DOMHighResTimeStamp delay;
- [RuntimeEnabled=IntersectionObserverV2] readonly attribute boolean trackVisibility;
+ readonly attribute DOMHighResTimeStamp delay;
+ readonly attribute boolean trackVisibility;
[RaisesException] void observe(Element target);
[RaisesException] void unobserve(Element target);
[RaisesException] void disconnect();
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc
index dcdc40da1a6..df930776cdb 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc
@@ -141,7 +141,7 @@ void IntersectionObserverController::RemoveTrackedObservation(
tracked_implicit_root_observations_.erase(&observation);
}
-void IntersectionObserverController::Trace(Visitor* visitor) {
+void IntersectionObserverController::Trace(Visitor* visitor) const {
visitor->Trace(tracked_explicit_root_observers_);
visitor->Trace(tracked_implicit_root_observations_);
visitor->Trace(pending_intersection_observers_);
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h
index 171462f83d5..e3cb65fd4fa 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h
@@ -50,7 +50,7 @@ class IntersectionObserverController
bool NeedsOcclusionTracking() const { return needs_occlusion_tracking_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override {
return "IntersectionObserverController";
}
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_delegate.h b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_delegate.h
index cd6ccf12097..51565d53f71 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_delegate.h
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_delegate.h
@@ -27,7 +27,7 @@ class IntersectionObserverDelegate
virtual void Deliver(const HeapVector<Member<IntersectionObserverEntry>>&,
IntersectionObserver&) = 0;
virtual ExecutionContext* GetExecutionContext() const = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
const char* NameInHeapSnapshot() const override {
return "IntersectionObserverDelegate";
}
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.cc b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.cc
index b552a61a1bb..66d0e700ab2 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.cc
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.cc
@@ -30,7 +30,7 @@ DOMRectReadOnly* IntersectionObserverEntry::intersectionRect() const {
FloatRect(geometry_.IntersectionRect()));
}
-void IntersectionObserverEntry::Trace(Visitor* visitor) {
+void IntersectionObserverEntry::Trace(Visitor* visitor) const {
visitor->Trace(target_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h
index 7c4883a1d50..5e29cab2d73 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h
@@ -36,7 +36,7 @@ class CORE_EXPORT IntersectionObserverEntry final : public ScriptWrappable {
// blink-internal interface
const IntersectionGeometry& GetGeometry() const { return geometry_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
IntersectionGeometry geometry_;
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.idl b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.idl
index 475284d1e29..6b2f66daf81 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.idl
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.idl
@@ -13,7 +13,7 @@
readonly attribute DOMRectReadOnly boundingClientRect;
readonly attribute DOMRectReadOnly intersectionRect;
readonly attribute boolean isIntersecting;
- [RuntimeEnabled=IntersectionObserverV2] readonly attribute boolean isVisible;
+ readonly attribute boolean isVisible;
readonly attribute double intersectionRatio;
readonly attribute Element target;
};
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_init.idl b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_init.idl
index e83f13dc56b..128e58d4331 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_init.idl
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_init.idl
@@ -8,6 +8,6 @@ dictionary IntersectionObserverInit {
(Element or Document)? root = null;
DOMString rootMargin = "0px";
(double or sequence<double>) threshold = 0;
- [RuntimeEnabled=IntersectionObserverV2] DOMHighResTimeStamp delay = 0;
- [RuntimeEnabled=IntersectionObserverV2] boolean trackVisibility = false;
+ DOMHighResTimeStamp delay = 0;
+ boolean trackVisibility = false;
};
diff --git a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc
index 0928877b684..7388410bd99 100644
--- a/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc
+++ b/chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc
@@ -64,7 +64,7 @@ class TestIntersectionObserverDelegate : public IntersectionObserverDelegate {
return geometry.IntersectionRect();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
IntersectionObserverDelegate::Trace(visitor);
visitor->Trace(document_);
visitor->Trace(entries_);
@@ -80,11 +80,9 @@ class TestIntersectionObserverDelegate : public IntersectionObserverDelegate {
class IntersectionObserverTest : public SimTest {};
-class IntersectionObserverV2Test : public IntersectionObserverTest,
- public ScopedIntersectionObserverV2ForTest {
+class IntersectionObserverV2Test : public IntersectionObserverTest {
public:
- IntersectionObserverV2Test()
- : IntersectionObserverTest(), ScopedIntersectionObserverV2ForTest(true) {
+ IntersectionObserverV2Test() {
IntersectionObserver::SetThrottleDelayEnabledForTesting(false);
}
@@ -237,7 +235,8 @@ TEST_F(IntersectionObserverTest, ReportsFractionOfTargetOrRoot) {
MakeGarbageCollected<IntersectionObserver>(
*target_observer_delegate, nullptr, Vector<Length>(),
Vector<float>{kExpectedFractionOfTarget / 2},
- IntersectionObserver::kFractionOfTarget, 0, false, false);
+ IntersectionObserver::kFractionOfTarget, 0, false, false,
+ IntersectionObserver::kApplyMarginToRoot);
DummyExceptionStateForTesting exception_state;
target_observer->observe(target, exception_state);
ASSERT_FALSE(exception_state.HadException());
@@ -248,7 +247,8 @@ TEST_F(IntersectionObserverTest, ReportsFractionOfTargetOrRoot) {
MakeGarbageCollected<IntersectionObserver>(
*root_observer_delegate, nullptr, Vector<Length>(),
Vector<float>{kExpectedFractionOfRoot / 2},
- IntersectionObserver::kFractionOfRoot, 0, false, false);
+ IntersectionObserver::kFractionOfRoot, 0, false, false,
+ IntersectionObserver::kApplyMarginToRoot);
root_observer->observe(target, exception_state);
ASSERT_FALSE(exception_state.HadException());
@@ -950,4 +950,111 @@ TEST_F(IntersectionObserverV2Test, BasicTransform) {
EXPECT_FALSE(observer_delegate->LastEntry()->isVisible());
}
+TEST_F(IntersectionObserverTest, ApplyMarginToTarget) {
+ WebView().MainFrameWidget()->Resize(WebSize(200, 200));
+ SimRequest main_resource("https://example.com/", "text/html");
+ LoadURL("https://example.com/");
+ main_resource.Complete(R"HTML(
+ <style>
+ #scroller { height: 100px; overflow: scroll; }
+ #target { width: 50px; height: 50px; }
+ .spacer { height: 105px; }
+ </style>
+ <div id=scroller>
+ <div class=spacer></div>
+ <div id=target></div>
+ </div>
+ )HTML");
+
+ Element* target = GetDocument().getElementById("target");
+ ASSERT_TRUE(target);
+
+ TestIntersectionObserverDelegate* root_margin_delegate =
+ MakeGarbageCollected<TestIntersectionObserverDelegate>(GetDocument());
+ IntersectionObserver* root_margin_observer =
+ MakeGarbageCollected<IntersectionObserver>(
+ *root_margin_delegate, nullptr, Vector<Length>{Length::Fixed(10)},
+ Vector<float>{std::numeric_limits<float>::min()},
+ IntersectionObserver::kFractionOfTarget, 0, false, false,
+ IntersectionObserver::kApplyMarginToRoot);
+
+ DummyExceptionStateForTesting exception_state;
+ root_margin_observer->observe(target, exception_state);
+ ASSERT_FALSE(exception_state.HadException());
+
+ TestIntersectionObserverDelegate* target_margin_delegate =
+ MakeGarbageCollected<TestIntersectionObserverDelegate>(GetDocument());
+ // Same parameters as above except that margin is applied to target.
+ IntersectionObserver* target_margin_observer =
+ MakeGarbageCollected<IntersectionObserver>(
+ *target_margin_delegate, nullptr, Vector<Length>{Length::Fixed(10)},
+ Vector<float>{std::numeric_limits<float>::min()},
+ IntersectionObserver::kFractionOfTarget, 0, false, false,
+ IntersectionObserver::kApplyMarginToTarget);
+
+ target_margin_observer->observe(target, exception_state);
+ ASSERT_FALSE(exception_state.HadException());
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+ ASSERT_FALSE(Compositor().NeedsBeginFrame());
+
+ EXPECT_EQ(root_margin_delegate->CallCount(), 1);
+ EXPECT_EQ(root_margin_delegate->EntryCount(), 1);
+ // Since the inner scroller clips content, the root margin has no effect and
+ // target is not intersecting.
+ EXPECT_FALSE(root_margin_delegate->LastEntry()->isIntersecting());
+
+ EXPECT_EQ(target_margin_delegate->CallCount(), 1);
+ EXPECT_EQ(target_margin_delegate->EntryCount(), 1);
+ // Since the margin is applied to the target, the inner scroller clips an
+ // expanded rect, which ends up being visible in the root. Hence, it is
+ // intersecting.
+ EXPECT_TRUE(target_margin_delegate->LastEntry()->isIntersecting());
+}
+
+TEST_F(IntersectionObserverTest, TargetMarginPercentResolvesAgainstRoot) {
+ WebView().MainFrameWidget()->Resize(WebSize(200, 500));
+ SimRequest main_resource("https://example.com/", "text/html");
+ LoadURL("https://example.com/");
+ main_resource.Complete(R"HTML(
+ <style>
+ #scroller { height: 100px; overflow: scroll; }
+ #target { width: 50px; height: 50px; }
+ .spacer { height: 145px; }
+ </style>
+ <div id=scroller>
+ <div class=spacer></div>
+ <div id=target></div>
+ </div>
+ )HTML");
+
+ Element* target = GetDocument().getElementById("target");
+ ASSERT_TRUE(target);
+
+ TestIntersectionObserverDelegate* target_margin_delegate =
+ MakeGarbageCollected<TestIntersectionObserverDelegate>(GetDocument());
+ // 10% margin on a target would be 5px if it resolved against target, which is
+ // not enough to intersect. It would be 10px if it resolved against the
+ // scroller, which is also not enough. However, it would be 50px if it
+ // resolved against root, which would make it intersecting.
+ IntersectionObserver* target_margin_observer =
+ MakeGarbageCollected<IntersectionObserver>(
+ *target_margin_delegate, nullptr, Vector<Length>{Length::Percent(10)},
+ Vector<float>{std::numeric_limits<float>::min()},
+ IntersectionObserver::kFractionOfTarget, 0, false, false,
+ IntersectionObserver::kApplyMarginToTarget);
+
+ DummyExceptionStateForTesting exception_state;
+ target_margin_observer->observe(target, exception_state);
+ ASSERT_FALSE(exception_state.HadException());
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+ ASSERT_FALSE(Compositor().NeedsBeginFrame());
+
+ EXPECT_EQ(target_margin_delegate->CallCount(), 1);
+ EXPECT_EQ(target_margin_delegate->EntryCount(), 1);
+ EXPECT_TRUE(target_margin_delegate->LastEntry()->isIntersecting());
+}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/BUILD.gn b/chromium/third_party/blink/renderer/core/layout/BUILD.gn
index 0f7341938a0..fdc18664d57 100644
--- a/chromium/third_party/blink/renderer/core/layout/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/layout/BUILD.gn
@@ -63,6 +63,8 @@ blink_core_sources("layout") {
"geometry/physical_size.h",
"geometry/transform_state.cc",
"geometry/transform_state.h",
+ "geometry/writing_mode_converter.cc",
+ "geometry/writing_mode_converter.h",
"grid.cc",
"grid.h",
"grid_baseline_alignment.cc",
@@ -145,6 +147,8 @@ blink_core_sources("layout") {
"layout_list_item.h",
"layout_list_marker.cc",
"layout_list_marker.h",
+ "layout_list_marker_image.cc",
+ "layout_list_marker_image.h",
"layout_media.cc",
"layout_media.h",
"layout_multi_column_flow_thread.cc",
@@ -262,6 +266,8 @@ blink_core_sources("layout") {
"line/trailing_objects.cc",
"line/trailing_objects.h",
"line/word_measurement.h",
+ "list_marker.cc",
+ "list_marker.h",
"list_marker_text.cc",
"list_marker_text.h",
"map_coordinates_flags.h",
@@ -324,6 +330,14 @@ blink_core_sources("layout") {
"ng/geometry/ng_margin_strut.cc",
"ng/geometry/ng_margin_strut.h",
"ng/geometry/ng_static_position.h",
+ "ng/grid/layout_ng_grid.cc",
+ "ng/grid/layout_ng_grid.h",
+ "ng/grid/ng_grid_child_iterator.cc",
+ "ng/grid/ng_grid_child_iterator.h",
+ "ng/grid/ng_grid_layout_algorithm.cc",
+ "ng/grid/ng_grid_layout_algorithm.h",
+ "ng/grid/ng_grid_track_collection.cc",
+ "ng/grid/ng_grid_track_collection.h",
"ng/inline/empty_offset_mapping_builder.h",
"ng/inline/layout_ng_text.h",
"ng/inline/layout_ng_text_fragment.h",
@@ -377,6 +391,8 @@ blink_core_sources("layout") {
"ng/inline/ng_line_truncator.h",
"ng/inline/ng_line_utils.cc",
"ng/inline/ng_line_utils.h",
+ "ng/inline/ng_logical_line_item.cc",
+ "ng/inline/ng_logical_line_item.h",
"ng/inline/ng_offset_mapping.cc",
"ng/inline/ng_offset_mapping.h",
"ng/inline/ng_offset_mapping_builder.cc",
@@ -385,6 +401,8 @@ blink_core_sources("layout") {
"ng/inline/ng_physical_line_box_fragment.h",
"ng/inline/ng_physical_text_fragment.cc",
"ng/inline/ng_physical_text_fragment.h",
+ "ng/inline/ng_ruby_utils.cc",
+ "ng/inline/ng_ruby_utils.h",
"ng/inline/ng_text_fragment.cc",
"ng/inline/ng_text_fragment.h",
"ng/inline/ng_text_fragment_builder.cc",
@@ -399,8 +417,6 @@ blink_core_sources("layout") {
"ng/layout_ng_block_flow_mixin.h",
"ng/layout_ng_fieldset.cc",
"ng/layout_ng_fieldset.h",
- "ng/layout_ng_grid.cc",
- "ng/layout_ng_grid.h",
"ng/layout_ng_mixin.cc",
"ng/layout_ng_mixin.h",
"ng/layout_ng_progress.cc",
@@ -418,12 +434,8 @@ blink_core_sources("layout") {
"ng/list/layout_ng_inside_list_marker.h",
"ng/list/layout_ng_list_item.cc",
"ng/list/layout_ng_list_item.h",
- "ng/list/layout_ng_list_marker_image.cc",
- "ng/list/layout_ng_list_marker_image.h",
"ng/list/layout_ng_outside_list_marker.cc",
"ng/list/layout_ng_outside_list_marker.h",
- "ng/list/list_marker.cc",
- "ng/list/list_marker.h",
"ng/list/ng_unpositioned_list_marker.cc",
"ng/list/ng_unpositioned_list_marker.h",
"ng/mathml/layout_ng_mathml_block.cc",
@@ -440,6 +452,7 @@ blink_core_sources("layout") {
"ng/mathml/ng_math_space_layout_algorithm.h",
"ng/mathml/ng_math_under_over_layout_algorithm.cc",
"ng/mathml/ng_math_under_over_layout_algorithm.h",
+ "ng/mathml/ng_mathml_paint_info.h",
"ng/ng_absolute_utils.cc",
"ng/ng_absolute_utils.h",
"ng/ng_block_break_token.cc",
@@ -478,8 +491,6 @@ blink_core_sources("layout") {
"ng/ng_fragment_child_iterator.h",
"ng/ng_fragmentation_utils.cc",
"ng/ng_fragmentation_utils.h",
- "ng/ng_grid_layout_algorithm.cc",
- "ng/ng_grid_layout_algorithm.h",
"ng/ng_ink_overflow.cc",
"ng/ng_ink_overflow.h",
"ng/ng_layout_algorithm.h",
@@ -535,6 +546,10 @@ blink_core_sources("layout") {
"ng/table/layout_ng_table_section.cc",
"ng/table/layout_ng_table_section.h",
"ng/table/layout_ng_table_section_interface.h",
+ "ng/table/ng_table_layout_algorithm_helpers.cc",
+ "ng/table/ng_table_layout_algorithm_helpers.h",
+ "ng/table/ng_table_layout_algorithm_types.cc",
+ "ng/table/ng_table_layout_algorithm_types.h",
"order_iterator.cc",
"order_iterator.h",
"overflow_model.h",
diff --git a/chromium/third_party/blink/renderer/core/layout/api/line_layout_item.h b/chromium/third_party/blink/renderer/core/layout/api/line_layout_item.h
index f3c8d5a489e..54d5aeab8c3 100644
--- a/chromium/third_party/blink/renderer/core/layout/api/line_layout_item.h
+++ b/chromium/third_party/blink/renderer/core/layout/api/line_layout_item.h
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_object_inlines.h"
#include "third_party/blink/renderer/core/layout/layout_text.h"
+#include "third_party/blink/renderer/core/layout/layout_text_fragment.h"
#include "third_party/blink/renderer/core/paint/object_paint_invalidator.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
@@ -64,6 +65,14 @@ class LineLayoutItem {
Node* NonPseudoNode() const { return layout_object_->NonPseudoNode(); }
+ Node* GetNodeForOwnerNodeId() const {
+ LayoutTextFragment* layout_text_fragment =
+ ToLayoutTextFragmentOrNull(layout_object_);
+ if (layout_text_fragment)
+ return layout_text_fragment->AssociatedTextNode();
+ return layout_object_->GetNode();
+ }
+
LineLayoutItem Parent() const {
return LineLayoutItem(layout_object_->Parent());
}
diff --git a/chromium/third_party/blink/renderer/core/layout/api/line_layout_list_marker.h b/chromium/third_party/blink/renderer/core/layout/api/line_layout_list_marker.h
index f5cc4ed4fcd..30e6869bb0a 100644
--- a/chromium/third_party/blink/renderer/core/layout/api/line_layout_list_marker.h
+++ b/chromium/third_party/blink/renderer/core/layout/api/line_layout_list_marker.h
@@ -5,22 +5,22 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_API_LINE_LAYOUT_LIST_MARKER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_API_LINE_LAYOUT_LIST_MARKER_H_
-#include "third_party/blink/renderer/core/layout/api/line_layout_box.h"
-#include "third_party/blink/renderer/core/layout/layout_list_marker.h"
+#include "third_party/blink/renderer/core/layout/api/line_layout_item.h"
namespace blink {
-class LineLayoutListMarker : public LineLayoutBox {
+class LineLayoutListMarker : public LineLayoutItem {
public:
- explicit LineLayoutListMarker(LayoutListMarker* layout_list_marker)
- : LineLayoutBox(layout_list_marker) {}
+ explicit LineLayoutListMarker(LayoutObject* object) : LineLayoutItem(object) {
+ SECURITY_DCHECK(!object || object->IsListMarker());
+ }
explicit LineLayoutListMarker(const LineLayoutItem& item)
- : LineLayoutBox(item) {
+ : LineLayoutItem(item) {
SECURITY_DCHECK(!item || item.IsListMarker());
}
- explicit LineLayoutListMarker(std::nullptr_t) : LineLayoutBox(nullptr) {}
+ explicit LineLayoutListMarker(std::nullptr_t) : LineLayoutItem(nullptr) {}
LineLayoutListMarker() = default;
diff --git a/chromium/third_party/blink/renderer/core/layout/api/selection_state.cc b/chromium/third_party/blink/renderer/core/layout/api/selection_state.cc
index 86c66c603dc..e2ba364136e 100644
--- a/chromium/third_party/blink/renderer/core/layout/api/selection_state.cc
+++ b/chromium/third_party/blink/renderer/core/layout/api/selection_state.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/layout/api/selection_state.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/layout/counter_node.cc b/chromium/third_party/blink/renderer/core/layout/counter_node.cc
index 4e6b3ceb3b9..d51138fcb02 100644
--- a/chromium/third_party/blink/renderer/core/layout/counter_node.cc
+++ b/chromium/third_party/blink/renderer/core/layout/counter_node.cc
@@ -30,8 +30,8 @@
namespace blink {
-CounterNode::CounterNode(LayoutObject& o, bool has_reset_type, int value)
- : has_reset_type_(has_reset_type),
+CounterNode::CounterNode(LayoutObject& o, unsigned type_mask, int value)
+ : type_mask_(type_mask),
value_(value),
count_in_parent_(0),
owner_(o),
@@ -93,9 +93,9 @@ CounterNode::~CounterNode() {
}
scoped_refptr<CounterNode> CounterNode::Create(LayoutObject& owner,
- bool has_reset_type,
+ unsigned type_mask,
int value) {
- return base::AdoptRef(new CounterNode(owner, has_reset_type, value));
+ return base::AdoptRef(new CounterNode(owner, type_mask, value));
}
CounterNode* CounterNode::NextInPreOrderAfterChildren(
@@ -146,6 +146,14 @@ int CounterNode::ComputeCountInParent() const {
// According to the spec, if an increment would overflow or underflow the
// counter, we are allowed to ignore the increment.
// https://drafts.csswg.org/css-lists-3/#valdef-counter-reset-custom-ident-integer
+
+ // If we have a set type, then we override parent value altogether, so the
+ // result is just our value.
+ if (HasSetType())
+ return value_;
+
+ // If we act as a reset, then we don't add anything on top of the parent count
+ // (and we don't override it as we would with a set type).
int increment = ActsAsReset() ? 0 : value_;
if (previous_sibling_) {
return base::CheckAdd(previous_sibling_->count_in_parent_, increment)
@@ -218,6 +226,31 @@ void CounterNode::ResetLayoutObjects() {
}
}
+// static
+CounterNode* CounterNode::AncestorNodeAcrossStyleContainment(
+ const LayoutObject& starting_object,
+ const AtomicString& identifier) {
+ bool crossed_style_containment = false;
+ for (auto* ancestor = starting_object.Parent(); ancestor;
+ ancestor = ancestor->Parent()) {
+ crossed_style_containment |= ancestor->ShouldApplyStyleContainment();
+ if (!crossed_style_containment)
+ continue;
+ if (CounterMap* node_map = LayoutCounter::GetCounterMap(ancestor)) {
+ if (CounterNode* node = node_map->at(identifier))
+ return node;
+ }
+ }
+ return nullptr;
+}
+
+CounterNode* CounterNode::ParentCrossingStyleContainment(
+ const AtomicString& identifier) const {
+ if (parent_)
+ return parent_;
+ return AncestorNodeAcrossStyleContainment(Owner(), identifier);
+}
+
void CounterNode::ResetThisAndDescendantsLayoutObjects() {
CounterNode* node = this;
do {
@@ -251,7 +284,7 @@ void CounterNode::InsertAfter(CounterNode* new_child,
if (ref_child && ref_child->parent_ != this)
return;
- if (new_child->has_reset_type_) {
+ if (new_child->HasResetType()) {
while (last_child_ != ref_child)
LayoutCounter::DestroyCounterNode(last_child_->Owner(), identifier);
}
@@ -278,7 +311,7 @@ void CounterNode::InsertAfter(CounterNode* new_child,
last_child_ = new_child;
}
- if (!new_child->first_child_ || new_child->has_reset_type_) {
+ if (!new_child->first_child_ || new_child->HasResetType()) {
new_child->count_in_parent_ = new_child->ComputeCountInParent();
new_child->ResetThisAndDescendantsLayoutObjects();
if (next)
diff --git a/chromium/third_party/blink/renderer/core/layout/counter_node.h b/chromium/third_party/blink/renderer/core/layout/counter_node.h
index 5388c8bf27b..1ba00809897 100644
--- a/chromium/third_party/blink/renderer/core/layout/counter_node.h
+++ b/chromium/third_party/blink/renderer/core/layout/counter_node.h
@@ -47,12 +47,15 @@ class CounterNode : public RefCounted<CounterNode> {
USING_FAST_MALLOC(CounterNode);
public:
+ enum Type { kIncrementType = 1 << 0, kResetType = 1 << 1, kSetType = 1 << 2 };
+
static scoped_refptr<CounterNode> Create(LayoutObject&,
- bool is_reset,
+ unsigned type_mask,
int value);
~CounterNode();
- bool ActsAsReset() const { return has_reset_type_ || !parent_; }
- bool HasResetType() const { return has_reset_type_; }
+ bool ActsAsReset() const { return HasResetType() || !parent_; }
+ bool HasResetType() const { return type_mask_ & kResetType; }
+ bool HasSetType() const { return type_mask_ & kSetType; }
int Value() const { return value_; }
int CountInParent() const { return count_in_parent_; }
LayoutObject& Owner() const { return owner_; }
@@ -62,6 +65,21 @@ class CounterNode : public RefCounted<CounterNode> {
// Invalidates the text in the layoutObjects of this counter, if any.
void ResetLayoutObjects();
+ // This finds a closest ancestor style containment boundary, crosses it, and
+ // then returns the closest ancestor CounterNode available (for the given
+ // `identifier`). Note that the element that specifies contain: style is
+ // itself considered to be across the boundary from its subtree.
+ static CounterNode* AncestorNodeAcrossStyleContainment(
+ const LayoutObject&,
+ const AtomicString& identifier);
+
+ // Returns the parent of this CounterNode. If the node is the root, then it
+ // instead tries to find a node with the same identifier across the style
+ // containment boundary so that it can continue navigating up to the root of
+ // the document. This is used for reporting content: counters().
+ CounterNode* ParentCrossingStyleContainment(
+ const AtomicString& identifier) const;
+
CounterNode* Parent() const { return parent_; }
CounterNode* PreviousSibling() const { return previous_sibling_; }
CounterNode* NextSibling() const { return next_sibling_; }
@@ -88,14 +106,14 @@ class CounterNode : public RefCounted<CounterNode> {
const AtomicString& identifier);
private:
- CounterNode(LayoutObject&, bool is_reset, int value);
+ CounterNode(LayoutObject&, unsigned type_mask, int value);
int ComputeCountInParent() const;
// Invalidates the text in the layoutObject of this counter, if any,
// and in the layoutObjects of all descendants of this counter, if any.
void ResetThisAndDescendantsLayoutObjects();
void Recount();
- bool has_reset_type_;
+ unsigned type_mask_;
int value_;
int count_in_parent_;
LayoutObject& owner_;
diff --git a/chromium/third_party/blink/renderer/core/layout/custom_scrollbar.cc b/chromium/third_party/blink/renderer/core/layout/custom_scrollbar.cc
index 5136d0d40a3..fee43efde47 100644
--- a/chromium/third_party/blink/renderer/core/layout/custom_scrollbar.cc
+++ b/chromium/third_party/blink/renderer/core/layout/custom_scrollbar.cc
@@ -46,70 +46,42 @@ CustomScrollbar::CustomScrollbar(ScrollableArea* scrollable_area,
nullptr,
CustomScrollbarTheme::GetCustomScrollbarTheme()) {
DCHECK(style_source);
-
- // FIXME: We need to do this because CustomScrollbar::styleChanged is called
- // as soon as the scrollbar is created.
-
- // Update the scrollbar size.
- IntRect rect(0, 0, 0, 0);
- UpdateScrollbarPart(kScrollbarBGPart);
- if (LayoutCustomScrollbarPart* part = parts_.at(kScrollbarBGPart)) {
- part->UpdateLayout();
- rect.SetSize(FlooredIntSize(part->Size()));
- } else if (Orientation() == kHorizontalScrollbar) {
- rect.SetWidth(Width());
- } else {
- rect.SetHeight(Height());
- }
-
- SetFrameRect(rect);
}
CustomScrollbar::~CustomScrollbar() {
- if (parts_.IsEmpty())
- return;
-
- // When a scrollbar is detached from its parent (causing all parts removal)
- // and ready to be destroyed, its destruction can be delayed because of
- // RefPtr maintained in other classes such as EventHandler
- // (m_lastScrollbarUnderMouse).
- // Meanwhile, we can have a call to updateScrollbarPart which recreates the
- // scrollbar part. So, we need to destroy these parts since we don't want them
- // to call on a destroyed scrollbar. See webkit bug 68009.
- UpdateScrollbarParts(true);
+ DCHECK(!scrollable_area_);
+ DCHECK(parts_.IsEmpty());
}
int CustomScrollbar::HypotheticalScrollbarThickness(
+ const ScrollableArea* scrollable_area,
ScrollbarOrientation orientation,
- const LayoutBox& enclosing_box,
- const LayoutObject& style_source) {
- scoped_refptr<const ComputedStyle> part_style =
- style_source.GetUncachedPseudoElementStyle(
- PseudoElementStyleRequest(kPseudoIdScrollbar, nullptr,
- kScrollbarBGPart),
- style_source.Style());
- if (orientation == kHorizontalScrollbar) {
- return LayoutCustomScrollbarPart::ComputeScrollbarHeight(
- enclosing_box.ClientHeight().ToInt(), part_style.get());
- }
- return LayoutCustomScrollbarPart::ComputeScrollbarWidth(
- enclosing_box.ClientWidth().ToInt(), part_style.get());
+ Element* style_source) {
+ // Create a temporary scrollbar so that we can match style rules like
+ // ::-webkit-scrollbar:horizontal according to the scrollbar's orientation.
+ auto* scrollbar = MakeGarbageCollected<CustomScrollbar>(
+ const_cast<ScrollableArea*>(scrollable_area), orientation, style_source);
+ scrollbar->UpdateScrollbarPart(kScrollbarBGPart);
+ auto* part = scrollbar->GetPart(kScrollbarBGPart);
+ int thickness = part ? part->ComputeThickness() : 0;
+ scrollbar->DisconnectFromScrollableArea();
+ return thickness;
}
-void CustomScrollbar::Trace(Visitor* visitor) {
+void CustomScrollbar::Trace(Visitor* visitor) const {
Scrollbar::Trace(visitor);
}
void CustomScrollbar::DisconnectFromScrollableArea() {
- UpdateScrollbarParts(true);
+ DestroyScrollbarParts();
Scrollbar::DisconnectFromScrollableArea();
}
-void CustomScrollbar::SetEnabled(bool e) {
- bool was_enabled = Enabled();
- Scrollbar::SetEnabled(e);
- if (was_enabled != e)
- UpdateScrollbarParts();
+void CustomScrollbar::SetEnabled(bool enabled) {
+ if (Enabled() == enabled)
+ return;
+ Scrollbar::SetEnabled(enabled);
+ UpdateScrollbarParts();
}
void CustomScrollbar::StyleChanged() {
@@ -117,6 +89,11 @@ void CustomScrollbar::StyleChanged() {
}
void CustomScrollbar::SetHoveredPart(ScrollbarPart part) {
+ // This can be called from EventHandler after the scrollbar has been
+ // disconnected from the scrollable area.
+ if (!scrollable_area_)
+ return;
+
if (part == hovered_part_)
return;
@@ -128,10 +105,17 @@ void CustomScrollbar::SetHoveredPart(ScrollbarPart part) {
UpdateScrollbarPart(kScrollbarBGPart);
UpdateScrollbarPart(kTrackBGPart);
+
+ PositionScrollbarParts();
}
void CustomScrollbar::SetPressedPart(ScrollbarPart part,
WebInputEvent::Type type) {
+ // This can be called from EventHandler after the scrollbar has been
+ // disconnected from the scrollable area.
+ if (!scrollable_area_)
+ return;
+
ScrollbarPart old_part = pressed_part_;
Scrollbar::SetPressedPart(part, type);
@@ -140,6 +124,8 @@ void CustomScrollbar::SetPressedPart(ScrollbarPart part,
UpdateScrollbarPart(kScrollbarBGPart);
UpdateScrollbarPart(kTrackBGPart);
+
+ PositionScrollbarParts();
}
scoped_refptr<const ComputedStyle>
@@ -156,39 +142,33 @@ CustomScrollbar::GetScrollbarPseudoElementStyle(ScrollbarPart part_type,
return source_style->AddCachedPseudoElementStyle(std::move(part_style));
}
-void CustomScrollbar::UpdateScrollbarParts(bool destroy) {
- UpdateScrollbarPart(kScrollbarBGPart, destroy);
- UpdateScrollbarPart(kBackButtonStartPart, destroy);
- UpdateScrollbarPart(kForwardButtonStartPart, destroy);
- UpdateScrollbarPart(kBackTrackPart, destroy);
- UpdateScrollbarPart(kThumbPart, destroy);
- UpdateScrollbarPart(kForwardTrackPart, destroy);
- UpdateScrollbarPart(kBackButtonEndPart, destroy);
- UpdateScrollbarPart(kForwardButtonEndPart, destroy);
- UpdateScrollbarPart(kTrackBGPart, destroy);
-
- if (destroy)
- return;
+void CustomScrollbar::DestroyScrollbarParts() {
+ for (auto& part : parts_)
+ part.value->Destroy();
+ parts_.clear();
+}
+
+void CustomScrollbar::UpdateScrollbarParts() {
+ for (auto part :
+ {kScrollbarBGPart, kBackButtonStartPart, kForwardButtonStartPart,
+ kBackTrackPart, kThumbPart, kForwardTrackPart, kBackButtonEndPart,
+ kForwardButtonEndPart, kTrackBGPart})
+ UpdateScrollbarPart(part);
// See if the scrollbar's thickness changed. If so, we need to mark our
// owning object as needing a layout.
bool is_horizontal = Orientation() == kHorizontalScrollbar;
int old_thickness = is_horizontal ? Height() : Width();
int new_thickness = 0;
- LayoutCustomScrollbarPart* part = parts_.at(kScrollbarBGPart);
- if (part) {
- part->UpdateLayout();
- new_thickness =
- (is_horizontal ? part->Size().Height() : part->Size().Width()).ToInt();
- }
+ if (auto* part = parts_.at(kScrollbarBGPart))
+ new_thickness = part->ComputeThickness();
if (new_thickness != old_thickness) {
SetFrameRect(
IntRect(Location(), IntSize(is_horizontal ? Width() : new_thickness,
is_horizontal ? new_thickness : Height())));
if (LayoutBox* box = GetScrollableArea()->GetLayoutBox()) {
- auto* layout_block = DynamicTo<LayoutBlock>(box);
- if (layout_block)
+ if (auto* layout_block = DynamicTo<LayoutBlock>(box))
layout_block->NotifyScrollbarThicknessChanged();
box->SetChildNeedsLayout();
// LayoutNG may attempt to reuse line-box fragments. It will do this even
@@ -197,9 +177,19 @@ void CustomScrollbar::UpdateScrollbarParts(bool destroy) {
// this is similar to border or padding changing, (which marks the box as
// self needs layout).
box->SetNeedsLayout(layout_invalidation_reason::kScrollbarChanged);
- if (scrollable_area_)
- scrollable_area_->SetScrollCornerNeedsPaintInvalidation();
+ scrollable_area_->SetScrollCornerNeedsPaintInvalidation();
}
+ return;
+ }
+
+ // If we didn't return above, it means that there is no change or the change
+ // doesn't affect layout of the box. Update position to reflect the change if
+ // any.
+ if (LayoutBox* box = GetScrollableArea()->GetLayoutBox()) {
+ // It's not ready to position scrollbar parts if the containing box has not
+ // been inserted into the layout tree.
+ if (box->IsLayoutView() || box->Parent())
+ PositionScrollbarParts();
}
}
@@ -227,18 +217,16 @@ static PseudoId PseudoForScrollbarPart(ScrollbarPart part) {
return kPseudoIdScrollbar;
}
-void CustomScrollbar::UpdateScrollbarPart(ScrollbarPart part_type,
- bool destroy) {
+void CustomScrollbar::UpdateScrollbarPart(ScrollbarPart part_type) {
+ DCHECK(scrollable_area_);
if (part_type == kNoPart)
return;
scoped_refptr<const ComputedStyle> part_style =
- !destroy ? GetScrollbarPseudoElementStyle(
- part_type, PseudoForScrollbarPart(part_type))
- : scoped_refptr<const ComputedStyle>(nullptr);
-
+ GetScrollbarPseudoElementStyle(part_type,
+ PseudoForScrollbarPart(part_type));
bool need_layout_object =
- !destroy && part_style && part_style->Display() != EDisplay::kNone;
+ part_style && part_style->Display() != EDisplay::kNone;
if (need_layout_object &&
// display:block overrides OS settings.
@@ -270,8 +258,7 @@ void CustomScrollbar::UpdateScrollbarPart(ScrollbarPart part_type,
parts_.erase(part_type);
part_layout_object->Destroy();
part_layout_object = nullptr;
- if (!destroy)
- SetNeedsPaintInvalidation(part_type);
+ SetNeedsPaintInvalidation(part_type);
}
if (part_layout_object)
@@ -283,52 +270,40 @@ IntRect CustomScrollbar::ButtonRect(ScrollbarPart part_type) const {
if (!part_layout_object)
return IntRect();
- part_layout_object->UpdateLayout();
-
bool is_horizontal = Orientation() == kHorizontalScrollbar;
- if (part_type == kBackButtonStartPart)
- return IntRect(
- Location(),
- IntSize(
- is_horizontal ? part_layout_object->PixelSnappedWidth() : Width(),
- is_horizontal ? Height()
- : part_layout_object->PixelSnappedHeight()));
- if (part_type == kForwardButtonEndPart) {
- return IntRect(
- is_horizontal ? X() + Width() - part_layout_object->PixelSnappedWidth()
- : X(),
- is_horizontal
- ? Y()
- : Y() + Height() - part_layout_object->PixelSnappedHeight(),
- is_horizontal ? part_layout_object->PixelSnappedWidth() : Width(),
- is_horizontal ? Height() : part_layout_object->PixelSnappedHeight());
- }
+ int button_length = part_layout_object->ComputeLength();
+ IntRect button_rect(Location(), is_horizontal
+ ? IntSize(button_length, Height())
+ : IntSize(Width(), button_length));
- if (part_type == kForwardButtonStartPart) {
- IntRect previous_button = ButtonRect(kBackButtonStartPart);
- return IntRect(
- is_horizontal ? X() + previous_button.Width() : X(),
- is_horizontal ? Y() : Y() + previous_button.Height(),
- is_horizontal ? part_layout_object->PixelSnappedWidth() : Width(),
- is_horizontal ? Height() : part_layout_object->PixelSnappedHeight());
+ switch (part_type) {
+ case kBackButtonStartPart:
+ break;
+ case kForwardButtonEndPart:
+ button_rect.Move(is_horizontal ? Width() - button_length : 0,
+ is_horizontal ? 0 : Height() - button_length);
+ break;
+ case kForwardButtonStartPart: {
+ IntRect previous_button = ButtonRect(kBackButtonStartPart);
+ button_rect.Move(is_horizontal ? previous_button.Width() : 0,
+ is_horizontal ? 0 : previous_button.Height());
+ break;
+ }
+ case kBackButtonEndPart: {
+ IntRect next_button = ButtonRect(kForwardButtonEndPart);
+ button_rect.Move(
+ is_horizontal ? Width() - next_button.Width() - button_length : 0,
+ is_horizontal ? 0 : Height() - next_button.Height() - button_length);
+ break;
+ }
+ default:
+ NOTREACHED();
}
-
- IntRect following_button = ButtonRect(kForwardButtonEndPart);
- return IntRect(
- is_horizontal ? X() + Width() - following_button.Width() -
- part_layout_object->PixelSnappedWidth()
- : X(),
- is_horizontal ? Y()
- : Y() + Height() - following_button.Height() -
- part_layout_object->PixelSnappedHeight(),
- is_horizontal ? part_layout_object->PixelSnappedWidth() : Width(),
- is_horizontal ? Height() : part_layout_object->PixelSnappedHeight());
+ return button_rect;
}
IntRect CustomScrollbar::TrackRect(int start_length, int end_length) const {
- LayoutCustomScrollbarPart* part = parts_.at(kTrackBGPart);
- if (part)
- part->UpdateLayout();
+ const LayoutCustomScrollbarPart* part = GetPart(kTrackBGPart);
if (Orientation() == kHorizontalScrollbar) {
int margin_left = part ? part->MarginLeft().ToInt() : 0;
@@ -351,12 +326,10 @@ IntRect CustomScrollbar::TrackRect(int start_length, int end_length) const {
IntRect CustomScrollbar::TrackPieceRectWithMargins(
ScrollbarPart part_type,
const IntRect& old_rect) const {
- LayoutCustomScrollbarPart* part_layout_object = parts_.at(part_type);
+ const LayoutCustomScrollbarPart* part_layout_object = GetPart(part_type);
if (!part_layout_object)
return old_rect;
- part_layout_object->UpdateLayout();
-
IntRect rect = old_rect;
if (Orientation() == kHorizontalScrollbar) {
rect.SetX((rect.X() + part_layout_object->MarginLeft()).ToInt());
@@ -370,24 +343,80 @@ IntRect CustomScrollbar::TrackPieceRectWithMargins(
}
int CustomScrollbar::MinimumThumbLength() const {
- LayoutCustomScrollbarPart* part_layout_object = parts_.at(kThumbPart);
- if (!part_layout_object)
- return 0;
- part_layout_object->UpdateLayout();
- return (Orientation() == kHorizontalScrollbar
- ? part_layout_object->Size().Width()
- : part_layout_object->Size().Height())
- .ToInt();
+ if (const auto* part_layout_object = GetPart(kThumbPart))
+ return part_layout_object->ComputeLength();
+ return 0;
+}
+
+void CustomScrollbar::OffsetDidChange(mojom::blink::ScrollType scroll_type) {
+ Scrollbar::OffsetDidChange(scroll_type);
+ PositionScrollbarParts();
+}
+
+void CustomScrollbar::PositionScrollbarParts() {
+ DCHECK_NE(
+ scrollable_area_->GetLayoutBox()->GetDocument().Lifecycle().GetState(),
+ DocumentLifecycle::kInPaint);
+
+ // Update frame rect of parts.
+ IntRect track_rect = GetTheme().TrackRect(*this);
+ IntRect start_track_rect;
+ IntRect thumb_rect;
+ IntRect end_track_rect;
+ GetTheme().SplitTrack(*this, track_rect, start_track_rect, thumb_rect,
+ end_track_rect);
+ for (auto& part : parts_) {
+ IntRect part_rect;
+ switch (part.key) {
+ case kBackButtonStartPart:
+ case kForwardButtonStartPart:
+ case kBackButtonEndPart:
+ case kForwardButtonEndPart:
+ part_rect = ButtonRect(part.key);
+ break;
+ case kBackTrackPart:
+ part_rect = start_track_rect;
+ break;
+ case kForwardTrackPart:
+ part_rect = end_track_rect;
+ break;
+ case kThumbPart:
+ part_rect = thumb_rect;
+ break;
+ case kTrackBGPart:
+ part_rect = track_rect;
+ break;
+ case kScrollbarBGPart:
+ part_rect = FrameRect();
+ break;
+ default:
+ NOTREACHED();
+ }
+ part.value->ClearNeedsLayoutWithoutPaintInvalidation();
+ // The part's paint offset is relative to the box.
+ // TODO(crbug.com/1020913): This should be part of PaintPropertyTreeBuilder
+ // when we support subpixel layout of overflow controls.
+ part.value->GetMutableForPainting().FirstFragment().SetPaintOffset(
+ PhysicalOffset(part_rect.Location()));
+ // The part's frame_rect is relative to the scrollbar.
+ part_rect.MoveBy(-Location());
+ part.value->SetFrameRect(LayoutRect(part_rect));
+ }
}
void CustomScrollbar::InvalidateDisplayItemClientsOfScrollbarParts() {
for (auto& part : parts_) {
ObjectPaintInvalidator(*part.value)
- .InvalidateDisplayItemClientsIncludingNonCompositingDescendants(
- PaintInvalidationReason::kScrollControl);
+ .SlowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(
+ *part.value, PaintInvalidationReason::kScrollControl);
}
}
+void CustomScrollbar::ClearPaintFlags() {
+ for (auto& part : parts_)
+ part.value->ClearPaintFlags();
+}
+
void CustomScrollbar::SetVisualRect(const IntRect& rect) {
Scrollbar::SetVisualRect(rect);
for (auto& part : parts_)
diff --git a/chromium/third_party/blink/renderer/core/layout/custom_scrollbar.h b/chromium/third_party/blink/renderer/core/layout/custom_scrollbar.h
index 734cb2d7931..aeebaa58c8d 100644
--- a/chromium/third_party/blink/renderer/core/layout/custom_scrollbar.h
+++ b/chromium/third_party/blink/renderer/core/layout/custom_scrollbar.h
@@ -36,23 +36,21 @@ namespace blink {
class ComputedStyle;
class Element;
-class LayoutBox;
class LayoutCustomScrollbarPart;
-class LayoutObject;
// Custom scrollbars are created when a box has -webkit-scrollbar* pseudo
// styles. The parts of a custom scrollbar are layout objects of class
// LayoutCustomScrollbarPart.
-class CustomScrollbar final : public Scrollbar {
+class CORE_EXPORT CustomScrollbar final : public Scrollbar {
public:
- CustomScrollbar(ScrollableArea*, ScrollbarOrientation, Element*);
+ CustomScrollbar(ScrollableArea*, ScrollbarOrientation, Element* style_source);
~CustomScrollbar() override;
- // Return the thickness that a custom scrollbar would have, without actually
- // constructing the scrollbar.
- static int HypotheticalScrollbarThickness(ScrollbarOrientation,
- const LayoutBox& enclosing_box,
- const LayoutObject& style_source);
+ // Return the thickness that a custom scrollbar would have, before actually
+ // constructing the real scrollbar.
+ static int HypotheticalScrollbarThickness(const ScrollableArea*,
+ ScrollbarOrientation,
+ Element* style_source);
IntRect ButtonRect(ScrollbarPart) const;
IntRect TrackRect(int start_length, int end_length) const;
@@ -62,6 +60,10 @@ class CustomScrollbar final : public Scrollbar {
bool IsOverlayScrollbar() const override { return false; }
+ void OffsetDidChange(mojom::blink::ScrollType) override;
+
+ void PositionScrollbarParts();
+
LayoutCustomScrollbarPart* GetPart(ScrollbarPart part_type) {
return parts_.at(part_type);
}
@@ -70,10 +72,10 @@ class CustomScrollbar final : public Scrollbar {
}
void InvalidateDisplayItemClientsOfScrollbarParts();
-
+ void ClearPaintFlags();
void SetVisualRect(const IntRect&) final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class Scrollbar;
@@ -88,14 +90,15 @@ class CustomScrollbar final : public Scrollbar {
bool IsCustomScrollbar() const override { return true; }
- void UpdateScrollbarParts(bool destroy = false);
-
+ void DestroyScrollbarParts();
+ void UpdateScrollbarParts();
scoped_refptr<const ComputedStyle> GetScrollbarPseudoElementStyle(
ScrollbarPart,
PseudoId);
- void UpdateScrollbarPart(ScrollbarPart, bool destroy = false);
+ void UpdateScrollbarPart(ScrollbarPart);
- HashMap<unsigned, LayoutCustomScrollbarPart*> parts_;
+ HashMap<ScrollbarPart, LayoutCustomScrollbarPart*> parts_;
+ bool needs_position_scrollbar_parts_ = true;
};
template <>
diff --git a/chromium/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc
index 91792d6bfff..341c36230e5 100644
--- a/chromium/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc
@@ -82,7 +82,8 @@ FlexItem::FlexItem(const FlexLayoutAlgorithm* algorithm,
base::Optional<MinMaxSizes> min_max_cross_sizes,
LayoutUnit main_axis_border_padding,
LayoutUnit cross_axis_border_padding,
- NGPhysicalBoxStrut physical_margins)
+ NGPhysicalBoxStrut physical_margins,
+ NGBoxStrut scrollbars)
: algorithm(algorithm),
line_number(0),
box(box),
@@ -95,6 +96,7 @@ FlexItem::FlexItem(const FlexLayoutAlgorithm* algorithm,
main_axis_border_padding(main_axis_border_padding),
cross_axis_border_padding(cross_axis_border_padding),
physical_margins(physical_margins),
+ scrollbars(scrollbars),
frozen(false),
needs_relayout_for_stretch(false),
ng_input_node(/* LayoutBox* */ nullptr) {
@@ -588,16 +590,17 @@ LayoutUnit FlexLayoutAlgorithm::GapBetweenItems(
return LayoutUnit();
DCHECK_GE(percent_resolution_sizes.inline_size, 0);
if (IsColumnFlow(style)) {
- if (LIKELY(style.RowGap().IsNormal()))
- return LayoutUnit();
- return MinimumValueForLength(
- style.RowGap().GetLength(),
- percent_resolution_sizes.block_size.ClampNegativeToZero());
- }
- if (LIKELY(style.ColumnGap().IsNormal()))
+ if (const base::Optional<Length>& row_gap = style.RowGap()) {
+ return MinimumValueForLength(
+ *row_gap, percent_resolution_sizes.block_size.ClampNegativeToZero());
+ }
return LayoutUnit();
- return MinimumValueForLength(style.ColumnGap().GetLength(),
- percent_resolution_sizes.inline_size);
+ }
+ if (const base::Optional<Length>& column_gap = style.ColumnGap()) {
+ return MinimumValueForLength(*column_gap,
+ percent_resolution_sizes.inline_size);
+ }
+ return LayoutUnit();
}
// static
@@ -608,16 +611,17 @@ LayoutUnit FlexLayoutAlgorithm::GapBetweenLines(
return LayoutUnit();
DCHECK_GE(percent_resolution_sizes.inline_size, 0);
if (!IsColumnFlow(style)) {
- if (LIKELY(style.RowGap().IsNormal()))
- return LayoutUnit();
- return MinimumValueForLength(
- style.RowGap().GetLength(),
- percent_resolution_sizes.block_size.ClampNegativeToZero());
- }
- if (LIKELY(style.ColumnGap().IsNormal()))
+ if (const base::Optional<Length>& row_gap = style.RowGap()) {
+ return MinimumValueForLength(
+ *row_gap, percent_resolution_sizes.block_size.ClampNegativeToZero());
+ }
return LayoutUnit();
- return MinimumValueForLength(style.ColumnGap().GetLength(),
- percent_resolution_sizes.inline_size);
+ }
+ if (const base::Optional<Length>& column_gap = style.ColumnGap()) {
+ return MinimumValueForLength(*column_gap,
+ percent_resolution_sizes.inline_size);
+ }
+ return LayoutUnit();
}
FlexLayoutAlgorithm::FlexLayoutAlgorithm(const ComputedStyle* style,
@@ -633,13 +637,13 @@ FlexLayoutAlgorithm::FlexLayoutAlgorithm(const ComputedStyle* style,
DCHECK_GE(gap_between_lines_, 0);
const auto& row_gap = style->RowGap();
const auto& column_gap = style->ColumnGap();
- if (!row_gap.IsNormal() || !column_gap.IsNormal()) {
+ if (row_gap || column_gap) {
UseCounter::Count(document, WebFeature::kFlexGapSpecified);
if (gap_between_items_ || gap_between_lines_)
UseCounter::Count(document, WebFeature::kFlexGapPositive);
}
- if (!row_gap.IsNormal() && row_gap.GetLength().IsPercentOrCalc()) {
+ if (row_gap && row_gap->IsPercentOrCalc()) {
UseCounter::Count(document, WebFeature::kFlexRowGapPercent);
if (percent_resolution_sizes.block_size == LayoutUnit(-1))
UseCounter::Count(document, WebFeature::kFlexRowGapPercentIndefinite);
@@ -749,7 +753,8 @@ bool FlexLayoutAlgorithm::ShouldApplyMinSizeAutoForChild(
IsHorizontalFlow() != child.StyleRef().IsHorizontalWritingMode();
bool intrinsic_in_childs_block_axis =
main_axis_is_childs_block_axis &&
- (min.IsMinContent() || min.IsMaxContent() || min.IsFitContent());
+ (min.IsMinContent() || min.IsMaxContent() || min.IsMinIntrinsic() ||
+ min.IsFitContent());
if (!min.IsAuto() && !intrinsic_in_childs_block_axis)
return false;
diff --git a/chromium/third_party/blink/renderer/core/layout/flexible_box_algorithm.h b/chromium/third_party/blink/renderer/core/layout/flexible_box_algorithm.h
index 6e0a4c255e4..3da8d3ca1fb 100644
--- a/chromium/third_party/blink/renderer/core/layout/flexible_box_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/flexible_box_algorithm.h
@@ -126,7 +126,8 @@ class FlexItem {
base::Optional<MinMaxSizes> min_max_cross_sizes,
LayoutUnit main_axis_border_padding,
LayoutUnit cross_axis_border_padding,
- NGPhysicalBoxStrut physical_margins);
+ NGPhysicalBoxStrut physical_margins,
+ NGBoxStrut scrollbars);
LayoutUnit HypotheticalMainAxisMarginBoxSize() const {
return hypothetical_main_content_size + main_axis_border_padding +
@@ -197,6 +198,7 @@ class FlexItem {
const LayoutUnit main_axis_border_padding;
const LayoutUnit cross_axis_border_padding;
NGPhysicalBoxStrut physical_margins;
+ const NGBoxStrut scrollbars;
LayoutUnit flexed_content_size;
diff --git a/chromium/third_party/blink/renderer/core/layout/floating_objects.h b/chromium/third_party/blink/renderer/core/layout/floating_objects.h
index 11edc377a8d..92a4784eda5 100644
--- a/chromium/third_party/blink/renderer/core/layout/floating_objects.h
+++ b/chromium/third_party/blink/renderer/core/layout/floating_objects.h
@@ -143,8 +143,7 @@ class FloatingObject {
is_lowest_non_overhanging_float_in_child;
}
- // FIXME: Callers of these methods are dangerous and should be whitelisted
- // explicitly or removed.
+ // FIXME: Callers of these methods are dangerous and should be removed.
RootInlineBox* OriginatingLine() const { return originating_line_; }
void SetOriginatingLine(RootInlineBox* line) { originating_line_ = line; }
diff --git a/chromium/third_party/blink/renderer/core/layout/force_legacy_layout_test.cc b/chromium/third_party/blink/renderer/core/layout/force_legacy_layout_test.cc
index e4c5ff110ff..5503864c2e2 100644
--- a/chromium/third_party/blink/renderer/core/layout/force_legacy_layout_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/force_legacy_layout_test.cc
@@ -10,11 +10,6 @@
namespace blink {
namespace {
-bool ForcesLegacyLayout(const Element& element) {
- return element.ShouldForceLegacyLayout() &&
- !element.GetLayoutObject()->IsLayoutNGMixin();
-}
-
bool UsesNGLayout(const Element& element) {
return !element.ShouldForceLegacyLayout() &&
element.GetLayoutObject()->IsLayoutNGMixin();
@@ -23,9 +18,11 @@ bool UsesNGLayout(const Element& element) {
} // anonymous namespace
class ForceLegacyLayoutTest : public RenderingTest {
- public:
+ protected:
ForceLegacyLayoutTest()
: RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()) {}
+
+ bool EditingNGEnabled() { return RuntimeEnabledFeatures::EditingNGEnabled(); }
};
TEST_F(ForceLegacyLayoutTest, ForceLegacyBfcRecalcAncestorStyle) {
@@ -74,19 +71,19 @@ TEST_F(ForceLegacyLayoutTest, ForceLegacyBfcRecalcAncestorStyle) {
EXPECT_TRUE(UsesNGLayout(*bfc));
EXPECT_TRUE(UsesNGLayout(*container));
EXPECT_TRUE(UsesNGLayout(*middle));
- EXPECT_TRUE(ForcesLegacyLayout(*inner));
- EXPECT_TRUE(ForcesLegacyLayout(*child));
+ EXPECT_EQ(UsesNGLayout(*inner), EditingNGEnabled());
+ EXPECT_EQ(UsesNGLayout(*child), EditingNGEnabled());
// Remove overflow:hidden, so that the contenteditable element no longer
// establishes a formatting context.
inner->removeAttribute(html_names::kStyleAttr);
UpdateAllLifecyclePhasesForTest();
EXPECT_TRUE(UsesNGLayout(*body));
- EXPECT_TRUE(ForcesLegacyLayout(*bfc));
- EXPECT_TRUE(ForcesLegacyLayout(*container));
- EXPECT_TRUE(ForcesLegacyLayout(*middle));
- EXPECT_TRUE(ForcesLegacyLayout(*inner));
- EXPECT_TRUE(ForcesLegacyLayout(*child));
+ EXPECT_EQ(UsesNGLayout(*bfc), EditingNGEnabled());
+ EXPECT_EQ(UsesNGLayout(*container), EditingNGEnabled());
+ EXPECT_EQ(UsesNGLayout(*middle), EditingNGEnabled());
+ EXPECT_EQ(UsesNGLayout(*inner), EditingNGEnabled());
+ EXPECT_EQ(UsesNGLayout(*child), EditingNGEnabled());
// Change a non-inherited property. Legacy layout is triggered by #inner, but
// should be propagated all the way up to #container (which is the node that
@@ -95,21 +92,21 @@ TEST_F(ForceLegacyLayoutTest, ForceLegacyBfcRecalcAncestorStyle) {
middle->setAttribute(html_names::kStyleAttr, "background-color:blue;");
UpdateAllLifecyclePhasesForTest();
EXPECT_TRUE(UsesNGLayout(*body));
- EXPECT_TRUE(ForcesLegacyLayout(*bfc));
- EXPECT_TRUE(ForcesLegacyLayout(*container));
- EXPECT_TRUE(ForcesLegacyLayout(*middle));
- EXPECT_TRUE(ForcesLegacyLayout(*inner));
- EXPECT_TRUE(ForcesLegacyLayout(*child));
+ EXPECT_EQ(UsesNGLayout(*bfc), EditingNGEnabled());
+ EXPECT_EQ(UsesNGLayout(*container), EditingNGEnabled());
+ EXPECT_EQ(UsesNGLayout(*middle), EditingNGEnabled());
+ EXPECT_EQ(UsesNGLayout(*inner), EditingNGEnabled());
+ EXPECT_EQ(UsesNGLayout(*child), EditingNGEnabled());
// Change a property that requires re-attachment.
container->setAttribute(html_names::kStyleAttr, "display:block;");
UpdateAllLifecyclePhasesForTest();
EXPECT_TRUE(UsesNGLayout(*body));
- EXPECT_TRUE(ForcesLegacyLayout(*bfc));
- EXPECT_TRUE(ForcesLegacyLayout(*container));
- EXPECT_TRUE(ForcesLegacyLayout(*middle));
- EXPECT_TRUE(ForcesLegacyLayout(*inner));
- EXPECT_TRUE(ForcesLegacyLayout(*child));
+ EXPECT_EQ(UsesNGLayout(*bfc), EditingNGEnabled());
+ EXPECT_EQ(UsesNGLayout(*container), EditingNGEnabled());
+ EXPECT_EQ(UsesNGLayout(*middle), EditingNGEnabled());
+ EXPECT_EQ(UsesNGLayout(*inner), EditingNGEnabled());
+ EXPECT_EQ(UsesNGLayout(*child), EditingNGEnabled());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/geometry/logical_offset.cc b/chromium/third_party/blink/renderer/core/layout/geometry/logical_offset.cc
index 5d3cbbb6de6..90ed61b1a34 100644
--- a/chromium/third_party/blink/renderer/core/layout/geometry/logical_offset.cc
+++ b/chromium/third_party/blink/renderer/core/layout/geometry/logical_offset.cc
@@ -7,44 +7,24 @@
#include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_offset.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_size.h"
+#include "third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
-PhysicalOffset LogicalOffset::ConvertToPhysical(WritingMode mode,
+PhysicalOffset LogicalOffset::ConvertToPhysical(
+ WritingDirectionMode writing_direction,
+ PhysicalSize outer_size,
+ PhysicalSize inner_size) const {
+ return WritingModeConverter(writing_direction, outer_size)
+ .ToPhysical(*this, inner_size);
+}
+
+PhysicalOffset LogicalOffset::ConvertToPhysical(WritingMode writing_mode,
TextDirection direction,
PhysicalSize outer_size,
PhysicalSize inner_size) const {
- switch (mode) {
- case WritingMode::kHorizontalTb:
- if (direction == TextDirection::kLtr)
- return PhysicalOffset(inline_offset, block_offset);
- return PhysicalOffset(outer_size.width - inline_offset - inner_size.width,
- block_offset);
- case WritingMode::kVerticalRl:
- case WritingMode::kSidewaysRl:
- if (direction == TextDirection::kLtr) {
- return PhysicalOffset(
- outer_size.width - block_offset - inner_size.width, inline_offset);
- }
- return PhysicalOffset(
- outer_size.width - block_offset - inner_size.width,
- outer_size.height - inline_offset - inner_size.height);
- case WritingMode::kVerticalLr:
- if (direction == TextDirection::kLtr)
- return PhysicalOffset(block_offset, inline_offset);
- return PhysicalOffset(
- block_offset, outer_size.height - inline_offset - inner_size.height);
- case WritingMode::kSidewaysLr:
- if (direction == TextDirection::kLtr) {
- return PhysicalOffset(block_offset, outer_size.height - inline_offset -
- inner_size.height);
- }
- return PhysicalOffset(block_offset, inline_offset);
- default:
- NOTREACHED();
- return PhysicalOffset();
- }
+ return ConvertToPhysical({writing_mode, direction}, outer_size, inner_size);
}
String LogicalOffset::ToString() const {
diff --git a/chromium/third_party/blink/renderer/core/layout/geometry/logical_offset.h b/chromium/third_party/blink/renderer/core/layout/geometry/logical_offset.h
index ae0a241fc25..aa737fd1110 100644
--- a/chromium/third_party/blink/renderer/core/layout/geometry/logical_offset.h
+++ b/chromium/third_party/blink/renderer/core/layout/geometry/logical_offset.h
@@ -7,8 +7,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
-#include "third_party/blink/renderer/platform/text/text_direction.h"
-#include "third_party/blink/renderer/platform/text/writing_mode.h"
+#include "third_party/blink/renderer/platform/text/writing_direction_mode.h"
namespace blink {
@@ -38,8 +37,11 @@ struct CORE_EXPORT LogicalOffset {
// the same point.
// @param outer_size the size of the rect (typically a fragment).
// @param inner_size the size of the inner rect (typically a child fragment).
- PhysicalOffset ConvertToPhysical(WritingMode,
- TextDirection,
+ PhysicalOffset ConvertToPhysical(WritingDirectionMode writing_direction,
+ PhysicalSize outer_size,
+ PhysicalSize inner_size) const;
+ PhysicalOffset ConvertToPhysical(WritingMode writing_mode,
+ TextDirection direction,
PhysicalSize outer_size,
PhysicalSize inner_size) const;
diff --git a/chromium/third_party/blink/renderer/core/layout/geometry/logical_offset_test.cc b/chromium/third_party/blink/renderer/core/layout/geometry/logical_offset_test.cc
deleted file mode 100644
index 4ee80cf8c75..00000000000
--- a/chromium/third_party/blink/renderer/core/layout/geometry/logical_offset_test.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/layout/geometry/logical_offset.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/core/layout/geometry/physical_offset.h"
-#include "third_party/blink/renderer/core/layout/geometry/physical_size.h"
-#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
-
-namespace blink {
-
-namespace {
-
-TEST(GeometryUnitsTest, ConvertLogicalOffsetToPhysicalOffset) {
- LogicalOffset logical_offset(20, 30);
- PhysicalSize outer_size(300, 400);
- PhysicalSize inner_size(5, 65);
- PhysicalOffset offset;
-
- offset = logical_offset.ConvertToPhysical(
- WritingMode::kHorizontalTb, TextDirection::kLtr, outer_size, inner_size);
- EXPECT_EQ(20, offset.left);
- EXPECT_EQ(30, offset.top);
-
- offset = logical_offset.ConvertToPhysical(
- WritingMode::kHorizontalTb, TextDirection::kRtl, outer_size, inner_size);
- EXPECT_EQ(275, offset.left);
- EXPECT_EQ(30, offset.top);
-
- offset = logical_offset.ConvertToPhysical(
- WritingMode::kVerticalRl, TextDirection::kLtr, outer_size, inner_size);
- EXPECT_EQ(265, offset.left);
- EXPECT_EQ(20, offset.top);
-
- offset = logical_offset.ConvertToPhysical(
- WritingMode::kVerticalRl, TextDirection::kRtl, outer_size, inner_size);
- EXPECT_EQ(265, offset.left);
- EXPECT_EQ(315, offset.top);
-
- offset = logical_offset.ConvertToPhysical(
- WritingMode::kSidewaysRl, TextDirection::kLtr, outer_size, inner_size);
- EXPECT_EQ(265, offset.left);
- EXPECT_EQ(20, offset.top);
-
- offset = logical_offset.ConvertToPhysical(
- WritingMode::kSidewaysRl, TextDirection::kRtl, outer_size, inner_size);
- EXPECT_EQ(265, offset.left);
- EXPECT_EQ(315, offset.top);
-
- offset = logical_offset.ConvertToPhysical(
- WritingMode::kVerticalLr, TextDirection::kLtr, outer_size, inner_size);
- EXPECT_EQ(30, offset.left);
- EXPECT_EQ(20, offset.top);
-
- offset = logical_offset.ConvertToPhysical(
- WritingMode::kVerticalLr, TextDirection::kRtl, outer_size, inner_size);
- EXPECT_EQ(30, offset.left);
- EXPECT_EQ(315, offset.top);
-
- offset = logical_offset.ConvertToPhysical(
- WritingMode::kSidewaysLr, TextDirection::kLtr, outer_size, inner_size);
- EXPECT_EQ(30, offset.left);
- EXPECT_EQ(315, offset.top);
-
- offset = logical_offset.ConvertToPhysical(
- WritingMode::kSidewaysLr, TextDirection::kRtl, outer_size, inner_size);
- EXPECT_EQ(30, offset.left);
- EXPECT_EQ(20, offset.top);
-}
-
-} // namespace
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/geometry/logical_rect.cc b/chromium/third_party/blink/renderer/core/layout/geometry/logical_rect.cc
index 93912b47183..9bd744cbcc9 100644
--- a/chromium/third_party/blink/renderer/core/layout/geometry/logical_rect.cc
+++ b/chromium/third_party/blink/renderer/core/layout/geometry/logical_rect.cc
@@ -38,25 +38,6 @@ void LogicalRect::Unite(const LogicalRect& other) {
size = new_end_offset - offset;
}
-PhysicalRect LogicalRect::ConvertToPhysical(
- WritingMode writing_mode,
- const PhysicalSize& outer_size) const {
- if (IsHorizontalWritingMode(writing_mode)) {
- return {offset.inline_offset, offset.block_offset, size.inline_size,
- size.block_size};
- }
-
- // Vertical, clock-wise rotation.
- if (writing_mode != WritingMode::kSidewaysLr) {
- return {outer_size.width - BlockEndOffset(), offset.inline_offset,
- size.block_size, size.inline_size};
- }
-
- // Vertical, counter-clock-wise rotation.
- return {offset.block_offset, outer_size.height - InlineEndOffset(),
- size.block_size, size.inline_size};
-}
-
String LogicalRect::ToString() const {
return String::Format("%s,%s %sx%s",
offset.inline_offset.ToString().Ascii().c_str(),
diff --git a/chromium/third_party/blink/renderer/core/layout/geometry/logical_rect.h b/chromium/third_party/blink/renderer/core/layout/geometry/logical_rect.h
index 43d65daef54..b6196671e85 100644
--- a/chromium/third_party/blink/renderer/core/layout/geometry/logical_rect.h
+++ b/chromium/third_party/blink/renderer/core/layout/geometry/logical_rect.h
@@ -13,8 +13,6 @@
namespace blink {
class LayoutRect;
-struct PhysicalRect;
-struct PhysicalSize;
// LogicalRect is the position and size of a rect (typically a fragment)
// relative to the parent in the logical coordinate system.
@@ -68,10 +66,6 @@ struct CORE_EXPORT LogicalRect {
void Unite(const LogicalRect&);
- // Convert logical coordinate to local physical coordinate.
- PhysicalRect ConvertToPhysical(WritingMode writing_mode,
- const PhysicalSize& outer_size) const;
-
String ToString() const;
};
diff --git a/chromium/third_party/blink/renderer/core/layout/geometry/physical_offset.cc b/chromium/third_party/blink/renderer/core/layout/geometry/physical_offset.cc
index d2c6d1634f1..a151caea379 100644
--- a/chromium/third_party/blink/renderer/core/layout/geometry/physical_offset.cc
+++ b/chromium/third_party/blink/renderer/core/layout/geometry/physical_offset.cc
@@ -6,39 +6,26 @@
#include "third_party/blink/renderer/core/layout/geometry/logical_offset.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_size.h"
+#include "third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h"
#include "third_party/blink/renderer/platform/geometry/layout_point.h"
#include "third_party/blink/renderer/platform/geometry/layout_size.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
-LogicalOffset PhysicalOffset::ConvertToLogical(WritingMode mode,
+LogicalOffset PhysicalOffset::ConvertToLogical(
+ WritingDirectionMode writing_direction,
+ PhysicalSize outer_size,
+ PhysicalSize inner_size) const {
+ return WritingModeConverter(writing_direction, outer_size)
+ .ToLogical(*this, inner_size);
+}
+
+LogicalOffset PhysicalOffset::ConvertToLogical(WritingMode writing_mode,
TextDirection direction,
PhysicalSize outer_size,
PhysicalSize inner_size) const {
- switch (mode) {
- case WritingMode::kHorizontalTb:
- if (direction == TextDirection::kLtr)
- return LogicalOffset(left, top);
- return LogicalOffset(outer_size.width - left - inner_size.width, top);
- case WritingMode::kVerticalRl:
- case WritingMode::kSidewaysRl:
- if (direction == TextDirection::kLtr)
- return LogicalOffset(top, outer_size.width - left - inner_size.width);
- return LogicalOffset(outer_size.height - top - inner_size.height,
- outer_size.width - left - inner_size.width);
- case WritingMode::kVerticalLr:
- if (direction == TextDirection::kLtr)
- return LogicalOffset(top, left);
- return LogicalOffset(outer_size.height - top - inner_size.height, left);
- case WritingMode::kSidewaysLr:
- if (direction == TextDirection::kLtr)
- return LogicalOffset(outer_size.height - top - inner_size.height, left);
- return LogicalOffset(top, left);
- default:
- NOTREACHED();
- return LogicalOffset();
- }
+ return ConvertToLogical({writing_mode, direction}, outer_size, inner_size);
}
String PhysicalOffset::ToString() const {
diff --git a/chromium/third_party/blink/renderer/core/layout/geometry/physical_offset.h b/chromium/third_party/blink/renderer/core/layout/geometry/physical_offset.h
index 20ddb662d16..a2e93b6e48e 100644
--- a/chromium/third_party/blink/renderer/core/layout/geometry/physical_offset.h
+++ b/chromium/third_party/blink/renderer/core/layout/geometry/physical_offset.h
@@ -9,8 +9,7 @@
#include "third_party/blink/renderer/platform/geometry/layout_point.h"
#include "third_party/blink/renderer/platform/geometry/layout_size.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
-#include "third_party/blink/renderer/platform/text/text_direction.h"
-#include "third_party/blink/renderer/platform/text/writing_mode.h"
+#include "third_party/blink/renderer/platform/text/writing_direction_mode.h"
namespace blink {
@@ -38,8 +37,11 @@ struct CORE_EXPORT PhysicalOffset {
// https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical
// @param outer_size the size of the rect (typically a fragment).
// @param inner_size the size of the inner rect (typically a child fragment).
- LogicalOffset ConvertToLogical(WritingMode,
- TextDirection,
+ LogicalOffset ConvertToLogical(WritingDirectionMode writing_direction,
+ PhysicalSize outer_size,
+ PhysicalSize inner_size) const;
+ LogicalOffset ConvertToLogical(WritingMode writing_mode,
+ TextDirection direction,
PhysicalSize outer_size,
PhysicalSize inner_size) const;
@@ -116,6 +118,11 @@ struct CORE_EXPORT PhysicalOffset {
LayoutUnit::FromFloatRound(size.Height())};
}
+ void Scale(float s) {
+ left *= s;
+ top *= s;
+ }
+
constexpr explicit operator FloatPoint() const { return {left, top}; }
constexpr explicit operator FloatSize() const { return {left, top}; }
diff --git a/chromium/third_party/blink/renderer/core/layout/geometry/physical_offset_test.cc b/chromium/third_party/blink/renderer/core/layout/geometry/physical_offset_test.cc
deleted file mode 100644
index 767cab1a2b9..00000000000
--- a/chromium/third_party/blink/renderer/core/layout/geometry/physical_offset_test.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/layout/geometry/physical_offset.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/core/layout/geometry/logical_offset.h"
-#include "third_party/blink/renderer/core/layout/geometry/physical_size.h"
-#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
-
-namespace blink {
-
-namespace {
-
-TEST(GeometryUnitsTest, ConvertPhysicalOffsetToLogicalOffset) {
- PhysicalOffset physical_offset(20, 30);
- PhysicalSize outer_size(300, 400);
- PhysicalSize inner_size(5, 65);
- LogicalOffset offset;
-
- offset = physical_offset.ConvertToLogical(
- WritingMode::kHorizontalTb, TextDirection::kLtr, outer_size, inner_size);
- EXPECT_EQ(20, offset.inline_offset);
- EXPECT_EQ(30, offset.block_offset);
-
- offset = physical_offset.ConvertToLogical(
- WritingMode::kHorizontalTb, TextDirection::kRtl, outer_size, inner_size);
- EXPECT_EQ(275, offset.inline_offset);
- EXPECT_EQ(30, offset.block_offset);
-
- offset = physical_offset.ConvertToLogical(
- WritingMode::kVerticalRl, TextDirection::kLtr, outer_size, inner_size);
- EXPECT_EQ(30, offset.inline_offset);
- EXPECT_EQ(275, offset.block_offset);
-
- offset = physical_offset.ConvertToLogical(
- WritingMode::kVerticalRl, TextDirection::kRtl, outer_size, inner_size);
- EXPECT_EQ(305, offset.inline_offset);
- EXPECT_EQ(275, offset.block_offset);
-
- offset = physical_offset.ConvertToLogical(
- WritingMode::kSidewaysRl, TextDirection::kLtr, outer_size, inner_size);
- EXPECT_EQ(30, offset.inline_offset);
- EXPECT_EQ(275, offset.block_offset);
-
- offset = physical_offset.ConvertToLogical(
- WritingMode::kSidewaysRl, TextDirection::kRtl, outer_size, inner_size);
- EXPECT_EQ(305, offset.inline_offset);
- EXPECT_EQ(275, offset.block_offset);
-
- offset = physical_offset.ConvertToLogical(
- WritingMode::kVerticalLr, TextDirection::kLtr, outer_size, inner_size);
- EXPECT_EQ(30, offset.inline_offset);
- EXPECT_EQ(20, offset.block_offset);
-
- offset = physical_offset.ConvertToLogical(
- WritingMode::kVerticalLr, TextDirection::kRtl, outer_size, inner_size);
- EXPECT_EQ(305, offset.inline_offset);
- EXPECT_EQ(20, offset.block_offset);
-
- offset = physical_offset.ConvertToLogical(
- WritingMode::kSidewaysLr, TextDirection::kLtr, outer_size, inner_size);
- EXPECT_EQ(305, offset.inline_offset);
- EXPECT_EQ(20, offset.block_offset);
-
- offset = physical_offset.ConvertToLogical(
- WritingMode::kSidewaysLr, TextDirection::kRtl, outer_size, inner_size);
- EXPECT_EQ(30, offset.inline_offset);
- EXPECT_EQ(20, offset.block_offset);
-}
-
-} // namespace
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/geometry/physical_rect.cc b/chromium/third_party/blink/renderer/core/layout/geometry/physical_rect.cc
index 56d55e143a2..706ae77c154 100644
--- a/chromium/third_party/blink/renderer/core/layout/geometry/physical_rect.cc
+++ b/chromium/third_party/blink/renderer/core/layout/geometry/physical_rect.cc
@@ -13,15 +13,6 @@
namespace blink {
-LogicalRect PhysicalRect::ConvertToLogical(WritingMode mode,
- TextDirection direction,
- PhysicalSize outer_size,
- PhysicalSize inner_size) const {
- return LogicalRect(
- offset.ConvertToLogical(mode, direction, outer_size, inner_size),
- size.ConvertToLogical(mode));
-}
-
bool PhysicalRect::Contains(const PhysicalRect& other) const {
return offset.left <= other.offset.left && offset.top <= other.offset.top &&
Right() >= other.Right() && Bottom() >= other.Bottom();
diff --git a/chromium/third_party/blink/renderer/core/layout/geometry/physical_rect.h b/chromium/third_party/blink/renderer/core/layout/geometry/physical_rect.h
index 8c8a236c58c..238d9e39add 100644
--- a/chromium/third_party/blink/renderer/core/layout/geometry/physical_rect.h
+++ b/chromium/third_party/blink/renderer/core/layout/geometry/physical_rect.h
@@ -22,7 +22,6 @@ class TextStream;
namespace blink {
class ComputedStyle;
-struct LogicalRect;
struct NGPhysicalBoxStrut;
// PhysicalRect is the position and size of a rect (typically a fragment)
@@ -50,15 +49,6 @@ struct CORE_EXPORT PhysicalRect {
PhysicalOffset offset;
PhysicalSize size;
- // Converts a physical offset to a logical offset. See:
- // https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical
- // @param outer_size the size of the rect (typically a fragment).
- // @param inner_size the size of the inner rect (typically a child fragment).
- LogicalRect ConvertToLogical(WritingMode,
- TextDirection,
- PhysicalSize outer_size,
- PhysicalSize inner_size) const;
-
constexpr bool IsEmpty() const { return size.IsEmpty(); }
constexpr LayoutUnit X() const { return offset.left; }
diff --git a/chromium/third_party/blink/renderer/core/layout/geometry/writing_mode_converter.cc b/chromium/third_party/blink/renderer/core/layout/geometry/writing_mode_converter.cc
new file mode 100644
index 00000000000..4de9df959bf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/geometry/writing_mode_converter.cc
@@ -0,0 +1,90 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h"
+
+namespace blink {
+
+LogicalOffset WritingModeConverter::SlowToLogical(
+ const PhysicalOffset& offset,
+ const PhysicalSize& inner_size) const {
+ switch (GetWritingMode()) {
+ case WritingMode::kHorizontalTb:
+ DCHECK(!IsLtr()); // LTR is in the fast code path.
+ return LogicalOffset(outer_size_.width - offset.left - inner_size.width,
+ offset.top);
+ case WritingMode::kVerticalRl:
+ case WritingMode::kSidewaysRl:
+ if (IsLtr()) {
+ return LogicalOffset(
+ offset.top, outer_size_.width - offset.left - inner_size.width);
+ }
+ return LogicalOffset(outer_size_.height - offset.top - inner_size.height,
+ outer_size_.width - offset.left - inner_size.width);
+ case WritingMode::kVerticalLr:
+ if (IsLtr())
+ return LogicalOffset(offset.top, offset.left);
+ return LogicalOffset(outer_size_.height - offset.top - inner_size.height,
+ offset.left);
+ case WritingMode::kSidewaysLr:
+ if (IsLtr()) {
+ return LogicalOffset(
+ outer_size_.height - offset.top - inner_size.height, offset.left);
+ }
+ return LogicalOffset(offset.top, offset.left);
+ }
+ NOTREACHED();
+ return LogicalOffset();
+}
+
+PhysicalOffset WritingModeConverter::SlowToPhysical(
+ const LogicalOffset& offset,
+ const PhysicalSize& inner_size) const {
+ switch (GetWritingMode()) {
+ case WritingMode::kHorizontalTb:
+ DCHECK(!IsLtr()); // LTR is in the fast code path.
+ return PhysicalOffset(
+ outer_size_.width - offset.inline_offset - inner_size.width,
+ offset.block_offset);
+ case WritingMode::kVerticalRl:
+ case WritingMode::kSidewaysRl:
+ if (IsLtr()) {
+ return PhysicalOffset(
+ outer_size_.width - offset.block_offset - inner_size.width,
+ offset.inline_offset);
+ }
+ return PhysicalOffset(
+ outer_size_.width - offset.block_offset - inner_size.width,
+ outer_size_.height - offset.inline_offset - inner_size.height);
+ case WritingMode::kVerticalLr:
+ if (IsLtr())
+ return PhysicalOffset(offset.block_offset, offset.inline_offset);
+ return PhysicalOffset(
+ offset.block_offset,
+ outer_size_.height - offset.inline_offset - inner_size.height);
+ case WritingMode::kSidewaysLr:
+ if (IsLtr()) {
+ return PhysicalOffset(
+ offset.block_offset,
+ outer_size_.height - offset.inline_offset - inner_size.height);
+ }
+ return PhysicalOffset(offset.block_offset, offset.inline_offset);
+ }
+ NOTREACHED();
+ return PhysicalOffset();
+}
+
+LogicalRect WritingModeConverter::SlowToLogical(
+ const PhysicalRect& rect) const {
+ return LogicalRect(SlowToLogical(rect.offset, rect.size),
+ ToLogical(rect.size));
+}
+
+PhysicalRect WritingModeConverter::SlowToPhysical(
+ const LogicalRect& rect) const {
+ const PhysicalSize size = ToPhysical(rect.size);
+ return PhysicalRect(SlowToPhysical(rect.offset, size), size);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h b/chromium/third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h
new file mode 100644
index 00000000000..54a1f8a7a1e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h
@@ -0,0 +1,124 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_GEOMETRY_WRITING_MODE_CONVERTER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_GEOMETRY_WRITING_MODE_CONVERTER_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/layout/geometry/logical_rect.h"
+#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
+#include "third_party/blink/renderer/platform/text/writing_direction_mode.h"
+
+namespace blink {
+
+// This class represents CSS property values to convert between logical and
+// physical coordinate systems. See:
+// https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical
+class CORE_EXPORT WritingModeConverter {
+ STACK_ALLOCATED();
+
+ public:
+ // @param writing_direction |WritingMode| and |TextDirection|.
+ // @param outer_size the size of the rect (typically a fragment). Some
+ // combinations of |WritingMode| and |TextDirection| require the size of the
+ // container to make the offset relative to the right or the bottom edges.
+ WritingModeConverter(WritingDirectionMode writing_direction,
+ const PhysicalSize& outer_size)
+ : writing_direction_(writing_direction), outer_size_(outer_size) {}
+
+ // Construct without |outer_size|. Caller should call |SetOuterSize| before
+ // conversions.
+ explicit WritingModeConverter(WritingDirectionMode writing_direction)
+ : writing_direction_(writing_direction) {}
+
+ // Conversion properties and utilities.
+ WritingDirectionMode GetWritingDirection() const {
+ return writing_direction_;
+ }
+ WritingMode GetWritingMode() const {
+ return writing_direction_.GetWritingMode();
+ }
+ TextDirection Direction() const { return writing_direction_.Direction(); }
+ bool IsLtr() const { return writing_direction_.IsLtr(); }
+
+ void SetOuterSize(const PhysicalSize& outer_size) {
+ outer_size_ = outer_size;
+ }
+
+ // |LogicalOffset| and |PhysicalOffset| conversions.
+ // PhysicalOffset will be the physical top left point of the rectangle
+ // described by offset + inner_size. Setting inner_size to 0,0 will return
+ // the same point.
+ // @param inner_size the size of the inner rect (typically a child fragment).
+ LogicalOffset ToLogical(const PhysicalOffset& offset,
+ const PhysicalSize& inner_size) const;
+ PhysicalOffset ToPhysical(const LogicalOffset& offset,
+ const PhysicalSize& inner_size) const;
+
+ // |LogicalSize| and |PhysicalSize| conversions.
+ LogicalSize ToLogical(const PhysicalSize& size) const;
+ PhysicalSize ToPhysical(const LogicalSize& size) const;
+
+ // |LogicalRect| and |PhysicalRect| conversions.
+ LogicalRect ToLogical(const PhysicalRect& rect) const;
+ PhysicalRect ToPhysical(const LogicalRect& rect) const;
+
+ private:
+ LogicalOffset SlowToLogical(const PhysicalOffset& offset,
+ const PhysicalSize& inner_size) const;
+ PhysicalOffset SlowToPhysical(const LogicalOffset& offset,
+ const PhysicalSize& inner_size) const;
+
+ LogicalRect SlowToLogical(const PhysicalRect& rect) const;
+ PhysicalRect SlowToPhysical(const LogicalRect& rect) const;
+
+ WritingDirectionMode writing_direction_;
+ PhysicalSize outer_size_;
+};
+
+inline LogicalOffset WritingModeConverter::ToLogical(
+ const PhysicalOffset& offset,
+ const PhysicalSize& inner_size) const {
+ if (writing_direction_.IsHorizontalLtr())
+ return LogicalOffset(offset.left, offset.top);
+ return SlowToLogical(offset, inner_size);
+}
+
+inline PhysicalOffset WritingModeConverter::ToPhysical(
+ const LogicalOffset& offset,
+ const PhysicalSize& inner_size) const {
+ if (writing_direction_.IsHorizontalLtr())
+ return PhysicalOffset(offset.inline_offset, offset.block_offset);
+ return SlowToPhysical(offset, inner_size);
+}
+
+inline LogicalSize WritingModeConverter::ToLogical(
+ const PhysicalSize& size) const {
+ return size.ConvertToLogical(GetWritingMode());
+}
+
+inline PhysicalSize WritingModeConverter::ToPhysical(
+ const LogicalSize& size) const {
+ return ToPhysicalSize(size, GetWritingMode());
+}
+
+inline LogicalRect WritingModeConverter::ToLogical(
+ const PhysicalRect& rect) const {
+ if (writing_direction_.IsHorizontalLtr())
+ return LogicalRect(rect.X(), rect.Y(), rect.Width(), rect.Height());
+ return SlowToLogical(rect);
+}
+
+inline PhysicalRect WritingModeConverter::ToPhysical(
+ const LogicalRect& rect) const {
+ if (writing_direction_.IsHorizontalLtr()) {
+ return PhysicalRect(rect.offset.inline_offset, rect.offset.block_offset,
+ rect.size.inline_size, rect.size.block_size);
+ }
+ return SlowToPhysical(rect);
+}
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_GEOMETRY_WRITING_MODE_CONVERTER_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/geometry/writing_mode_converter_test.cc b/chromium/third_party/blink/renderer/core/layout/geometry/writing_mode_converter_test.cc
new file mode 100644
index 00000000000..9ff283d175d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/geometry/writing_mode_converter_test.cc
@@ -0,0 +1,130 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
+
+namespace blink {
+
+namespace {
+
+TEST(WritingModeConverterTest, ConvertLogicalOffsetToPhysicalOffset) {
+ LogicalOffset logical_offset(20, 30);
+ PhysicalSize outer_size(300, 400);
+ PhysicalSize inner_size(5, 65);
+ PhysicalOffset offset;
+
+ offset = WritingModeConverter(
+ {WritingMode::kHorizontalTb, TextDirection::kLtr}, outer_size)
+ .ToPhysical(logical_offset, inner_size);
+ EXPECT_EQ(PhysicalOffset(20, 30), offset);
+
+ offset = WritingModeConverter(
+ {WritingMode::kHorizontalTb, TextDirection::kRtl}, outer_size)
+ .ToPhysical(logical_offset, inner_size);
+ EXPECT_EQ(PhysicalOffset(275, 30), offset);
+
+ offset = WritingModeConverter({WritingMode::kVerticalRl, TextDirection::kLtr},
+ outer_size)
+ .ToPhysical(logical_offset, inner_size);
+ EXPECT_EQ(PhysicalOffset(265, 20), offset);
+
+ offset = WritingModeConverter({WritingMode::kVerticalRl, TextDirection::kRtl},
+ outer_size)
+ .ToPhysical(logical_offset, inner_size);
+ EXPECT_EQ(PhysicalOffset(265, 315), offset);
+
+ offset = WritingModeConverter({WritingMode::kSidewaysRl, TextDirection::kLtr},
+ outer_size)
+ .ToPhysical(logical_offset, inner_size);
+ EXPECT_EQ(PhysicalOffset(265, 20), offset);
+
+ offset = WritingModeConverter({WritingMode::kSidewaysRl, TextDirection::kRtl},
+ outer_size)
+ .ToPhysical(logical_offset, inner_size);
+ EXPECT_EQ(PhysicalOffset(265, 315), offset);
+
+ offset = WritingModeConverter({WritingMode::kVerticalLr, TextDirection::kLtr},
+ outer_size)
+ .ToPhysical(logical_offset, inner_size);
+ EXPECT_EQ(PhysicalOffset(30, 20), offset);
+
+ offset = WritingModeConverter({WritingMode::kVerticalLr, TextDirection::kRtl},
+ outer_size)
+ .ToPhysical(logical_offset, inner_size);
+ EXPECT_EQ(PhysicalOffset(30, 315), offset);
+
+ offset = WritingModeConverter({WritingMode::kSidewaysLr, TextDirection::kLtr},
+ outer_size)
+ .ToPhysical(logical_offset, inner_size);
+ EXPECT_EQ(PhysicalOffset(30, 315), offset);
+
+ offset = WritingModeConverter({WritingMode::kSidewaysLr, TextDirection::kRtl},
+ outer_size)
+ .ToPhysical(logical_offset, inner_size);
+ EXPECT_EQ(PhysicalOffset(30, 20), offset);
+}
+
+TEST(WritingModeConverterTest, ConvertPhysicalOffsetToLogicalOffset) {
+ PhysicalOffset physical_offset(20, 30);
+ PhysicalSize outer_size(300, 400);
+ PhysicalSize inner_size(5, 65);
+ LogicalOffset offset;
+
+ offset = WritingModeConverter(
+ {WritingMode::kHorizontalTb, TextDirection::kLtr}, outer_size)
+ .ToLogical(physical_offset, inner_size);
+ EXPECT_EQ(LogicalOffset(20, 30), offset);
+
+ offset = WritingModeConverter(
+ {WritingMode::kHorizontalTb, TextDirection::kRtl}, outer_size)
+ .ToLogical(physical_offset, inner_size);
+ EXPECT_EQ(LogicalOffset(275, 30), offset);
+
+ offset = WritingModeConverter({WritingMode::kVerticalRl, TextDirection::kLtr},
+ outer_size)
+ .ToLogical(physical_offset, inner_size);
+ EXPECT_EQ(LogicalOffset(30, 275), offset);
+
+ offset = WritingModeConverter({WritingMode::kVerticalRl, TextDirection::kRtl},
+ outer_size)
+ .ToLogical(physical_offset, inner_size);
+ EXPECT_EQ(LogicalOffset(305, 275), offset);
+
+ offset = WritingModeConverter({WritingMode::kSidewaysRl, TextDirection::kLtr},
+ outer_size)
+ .ToLogical(physical_offset, inner_size);
+ EXPECT_EQ(LogicalOffset(30, 275), offset);
+
+ offset = WritingModeConverter({WritingMode::kSidewaysRl, TextDirection::kRtl},
+ outer_size)
+ .ToLogical(physical_offset, inner_size);
+ EXPECT_EQ(LogicalOffset(305, 275), offset);
+
+ offset = WritingModeConverter({WritingMode::kVerticalLr, TextDirection::kLtr},
+ outer_size)
+ .ToLogical(physical_offset, inner_size);
+ EXPECT_EQ(LogicalOffset(30, 20), offset);
+
+ offset = WritingModeConverter({WritingMode::kVerticalLr, TextDirection::kRtl},
+ outer_size)
+ .ToLogical(physical_offset, inner_size);
+ EXPECT_EQ(LogicalOffset(305, 20), offset);
+
+ offset = WritingModeConverter({WritingMode::kSidewaysLr, TextDirection::kLtr},
+ outer_size)
+ .ToLogical(physical_offset, inner_size);
+ EXPECT_EQ(LogicalOffset(305, 20), offset);
+
+ offset = WritingModeConverter({WritingMode::kSidewaysLr, TextDirection::kRtl},
+ outer_size)
+ .ToLogical(physical_offset, inner_size);
+ EXPECT_EQ(LogicalOffset(30, 20), offset);
+}
+
+} // namespace
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/grid.cc b/chromium/third_party/blink/renderer/core/layout/grid.cc
index d86bcfc238c..64bac6a4b0f 100644
--- a/chromium/third_party/blink/renderer/core/layout/grid.cc
+++ b/chromium/third_party/blink/renderer/core/layout/grid.cc
@@ -28,13 +28,13 @@ std::unique_ptr<Grid> Grid::Create(const LayoutGrid* layout_grid) {
Grid::Grid(const LayoutGrid* grid) : order_iterator_(grid) {}
-void Grid::SetSmallestTracksStart(int row_start, int column_start) {
- smallest_row_start_ = row_start;
- smallest_column_start_ = column_start;
+void Grid::SetExplicitGridStart(size_t row_start, size_t column_start) {
+ explicit_row_start_ = row_start;
+ explicit_column_start_ = column_start;
}
-int Grid::SmallestTrackStart(GridTrackSizingDirection direction) const {
- return direction == kForRows ? smallest_row_start_ : smallest_column_start_;
+size_t Grid::ExplicitGridStart(GridTrackSizingDirection direction) const {
+ return direction == kForRows ? explicit_row_start_ : explicit_column_start_;
}
GridArea Grid::GridItemArea(const LayoutBox& item) const {
@@ -119,8 +119,8 @@ void Grid::SetNeedsItemsPlacement(bool needs_items_placement) {
ClearGridDataStructure();
grid_item_area_.clear();
grid_items_indexes_map_.clear();
- smallest_row_start_ = 0;
- smallest_column_start_ = 0;
+ explicit_row_start_ = 0;
+ explicit_column_start_ = 0;
auto_repeat_columns_ = 0;
auto_repeat_rows_ = 0;
auto_repeat_empty_columns_ = nullptr;
diff --git a/chromium/third_party/blink/renderer/core/layout/grid.h b/chromium/third_party/blink/renderer/core/layout/grid.h
index 528bed93c14..2831f8a8bf4 100644
--- a/chromium/third_party/blink/renderer/core/layout/grid.h
+++ b/chromium/third_party/blink/renderer/core/layout/grid.h
@@ -57,8 +57,8 @@ class CORE_EXPORT Grid {
size_t GridItemPaintOrder(const LayoutBox&) const;
void SetGridItemPaintOrder(const LayoutBox&, size_t order);
- int SmallestTrackStart(GridTrackSizingDirection) const;
- void SetSmallestTracksStart(int row_start, int column_start);
+ size_t ExplicitGridStart(GridTrackSizingDirection) const;
+ void SetExplicitGridStart(size_t row_start, size_t column_start);
size_t AutoRepeatTracks(GridTrackSizingDirection) const;
void SetAutoRepeatTracks(size_t auto_repeat_rows, size_t auto_repeat_columns);
@@ -124,8 +124,8 @@ class CORE_EXPORT Grid {
OrderIterator order_iterator_;
- int smallest_column_start_{0};
- int smallest_row_start_{0};
+ size_t explicit_column_start_{0};
+ size_t explicit_row_start_{0};
size_t auto_repeat_columns_{0};
size_t auto_repeat_rows_{0};
diff --git a/chromium/third_party/blink/renderer/core/layout/grid_test.cc b/chromium/third_party/blink/renderer/core/layout/grid_test.cc
index e9779901a9d..2ce29e71b0f 100644
--- a/chromium/third_party/blink/renderer/core/layout/grid_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/grid_test.cc
@@ -36,8 +36,8 @@ TEST_F(GridTest, EmptyGrid) {
EXPECT_FALSE(grid->HasGridItems());
- EXPECT_EQ(0, grid->SmallestTrackStart(kForRows));
- EXPECT_EQ(0, grid->SmallestTrackStart(kForColumns));
+ EXPECT_EQ(0u, grid->ExplicitGridStart(kForRows));
+ EXPECT_EQ(0u, grid->ExplicitGridStart(kForColumns));
EXPECT_EQ(0u, grid->AutoRepeatTracks(kForRows));
EXPECT_EQ(0u, grid->AutoRepeatTracks(kForColumns));
@@ -65,8 +65,8 @@ TEST_F(GridTest, SingleChild) {
EXPECT_TRUE(grid->HasGridItems());
- EXPECT_EQ(0, grid->SmallestTrackStart(kForRows));
- EXPECT_EQ(0, grid->SmallestTrackStart(kForColumns));
+ EXPECT_EQ(0u, grid->ExplicitGridStart(kForRows));
+ EXPECT_EQ(0u, grid->ExplicitGridStart(kForColumns));
auto area = grid->GridItemArea(*child);
EXPECT_EQ(0u, area.columns.StartLine());
@@ -166,8 +166,8 @@ TEST_F(GridTest, IntrinsicGrid) {
EXPECT_TRUE(grid->HasGridItems());
- EXPECT_EQ(-2, grid->SmallestTrackStart(kForRows));
- EXPECT_EQ(0, grid->SmallestTrackStart(kForColumns));
+ EXPECT_EQ(2u, grid->ExplicitGridStart(kForRows));
+ EXPECT_EQ(0u, grid->ExplicitGridStart(kForColumns));
auto area = grid->GridItemArea(*child1);
EXPECT_EQ(0u, area.columns.StartLine());
@@ -291,8 +291,8 @@ TEST_F(GridTest, ExplicitlyPositionedChild) {
EXPECT_TRUE(grid->HasGridItems());
- EXPECT_EQ(0, grid->SmallestTrackStart(kForRows));
- EXPECT_EQ(0, grid->SmallestTrackStart(kForColumns));
+ EXPECT_EQ(0u, grid->ExplicitGridStart(kForRows));
+ EXPECT_EQ(0u, grid->ExplicitGridStart(kForColumns));
auto area = grid->GridItemArea(*child);
EXPECT_EQ(1u, area.columns.StartLine());
diff --git a/chromium/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc
index 16d8d1e7d2c..fc0baf9c2a4 100644
--- a/chromium/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc
@@ -798,7 +798,9 @@ LayoutUnit IndefiniteSizeStrategy::MaxContentForChild(LayoutBox& child) const {
DCHECK(GridLayoutUtils::IsOrthogonalChild(*GetLayoutGrid(), child));
return child.LogicalHeight() +
- GridLayoutUtils::MarginLogicalHeightForChild(*GetLayoutGrid(), child);
+ GridLayoutUtils::MarginLogicalHeightForChild(*GetLayoutGrid(), child) +
+ algorithm_.BaselineOffsetForChild(child,
+ GridAxisForDirection(Direction()));
}
bool IndefiniteSizeStrategy::IsComputingSizeContainment() const {
@@ -875,7 +877,7 @@ const GridTrackSize& GridTrackSizingAlgorithm::RawGridTrackSize(
size_t explicit_tracks_count = track_styles.size() + auto_repeat_tracks_count;
int untranslated_index_as_int =
- translated_index + grid_.SmallestTrackStart(direction);
+ translated_index - grid_.ExplicitGridStart(direction);
size_t auto_track_styles_size = auto_track_styles.size();
if (untranslated_index_as_int < 0) {
int index =
@@ -946,8 +948,20 @@ GridTrackSize GridTrackSizingAlgorithm::CalculateGridTrackSize(
// values are treated as <auto>.
if (IsRelativeSizedTrackAsAuto(track_size, direction)) {
if (direction == kForRows) {
- UseCounter::Count(layout_grid_->GetDocument(),
- WebFeature::kGridRowTrackPercentIndefiniteHeight);
+ // We avoid counting the cases in which it doesn't matter if we resolve
+ // the percentages row tracks against the intrinsic height of the grid
+ // container or we treat them as auto. Basically if we have just one row,
+ // it has 100% size and the max-block-size is none.
+ if ((grid_.NumTracks(direction) != 1) || !min_track_breadth.IsLength() ||
+ !min_track_breadth.length().IsPercent() ||
+ (min_track_breadth.length().Percent() != 100.0f) ||
+ !max_track_breadth.IsLength() ||
+ !max_track_breadth.length().IsPercent() ||
+ (max_track_breadth.length().Percent() != 100.0f) ||
+ !layout_grid_->StyleRef().LogicalMaxHeight().IsNone()) {
+ UseCounter::Count(layout_grid_->GetDocument(),
+ WebFeature::kGridRowTrackPercentIndefiniteHeight);
+ }
}
if (min_track_breadth.HasPercentage())
min_track_breadth = Length::Auto();
diff --git a/chromium/third_party/blink/renderer/core/layout/hit_test_cache.cc b/chromium/third_party/blink/renderer/core/layout/hit_test_cache.cc
index 5a46d3b68cb..9a007761a6a 100644
--- a/chromium/third_party/blink/renderer/core/layout/hit_test_cache.cc
+++ b/chromium/third_party/blink/renderer/core/layout/hit_test_cache.cc
@@ -40,7 +40,7 @@ bool HitTestCache::LookupCachedResult(const HitTestLocation& location,
return result;
}
-void HitTestCacheEntry::Trace(Visitor* visitor) {
+void HitTestCacheEntry::Trace(Visitor* visitor) const {
visitor->Trace(result);
}
@@ -85,7 +85,7 @@ void HitTestCache::Clear() {
items_.clear();
}
-void HitTestCache::Trace(Visitor* visitor) {
+void HitTestCache::Trace(Visitor* visitor) const {
visitor->Trace(items_);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/hit_test_cache.h b/chromium/third_party/blink/renderer/core/layout/hit_test_cache.h
index 985e58c1840..b4d0fce618b 100644
--- a/chromium/third_party/blink/renderer/core/layout/hit_test_cache.h
+++ b/chromium/third_party/blink/renderer/core/layout/hit_test_cache.h
@@ -37,7 +37,7 @@ namespace blink {
struct HitTestCacheEntry {
DISALLOW_NEW();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
HitTestLocation location;
HitTestResult result;
@@ -61,7 +61,7 @@ class CORE_EXPORT HitTestCache final : public GarbageCollected<HitTestCache> {
const HitTestResult&,
uint64_t dom_tree_version);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// The below UMA values reference a validity region. This code has not
diff --git a/chromium/third_party/blink/renderer/core/layout/hit_test_canvas_result.cc b/chromium/third_party/blink/renderer/core/layout/hit_test_canvas_result.cc
index 79e9b485d94..4568de680e0 100644
--- a/chromium/third_party/blink/renderer/core/layout/hit_test_canvas_result.cc
+++ b/chromium/third_party/blink/renderer/core/layout/hit_test_canvas_result.cc
@@ -17,7 +17,7 @@ Element* HitTestCanvasResult::GetControl() const {
return control_.Get();
}
-void HitTestCanvasResult::Trace(Visitor* visitor) {
+void HitTestCanvasResult::Trace(Visitor* visitor) const {
visitor->Trace(control_);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/hit_test_canvas_result.h b/chromium/third_party/blink/renderer/core/layout/hit_test_canvas_result.h
index 4dcc8d19cdb..773f1cdff2f 100644
--- a/chromium/third_party/blink/renderer/core/layout/hit_test_canvas_result.h
+++ b/chromium/third_party/blink/renderer/core/layout/hit_test_canvas_result.h
@@ -17,7 +17,7 @@ class CORE_EXPORT HitTestCanvasResult final
String GetId() const;
Element* GetControl() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
String id_;
diff --git a/chromium/third_party/blink/renderer/core/layout/hit_test_result.cc b/chromium/third_party/blink/renderer/core/layout/hit_test_result.cc
index 68ac6dfdaa8..1359aa6bdd5 100644
--- a/chromium/third_party/blink/renderer/core/layout/hit_test_result.cc
+++ b/chromium/third_party/blink/renderer/core/layout/hit_test_result.cc
@@ -128,7 +128,7 @@ void HitTestResult::PopulateFromCachedResult(const HitTestResult& other) {
: nullptr;
}
-void HitTestResult::Trace(Visitor* visitor) {
+void HitTestResult::Trace(Visitor* visitor) const {
visitor->Trace(inner_node_);
visitor->Trace(inert_node_);
visitor->Trace(inner_element_);
diff --git a/chromium/third_party/blink/renderer/core/layout/hit_test_result.h b/chromium/third_party/blink/renderer/core/layout/hit_test_result.h
index d40ba852d00..3db892ee822 100644
--- a/chromium/third_party/blink/renderer/core/layout/hit_test_result.h
+++ b/chromium/third_party/blink/renderer/core/layout/hit_test_result.h
@@ -67,7 +67,7 @@ class CORE_EXPORT HitTestResult {
HitTestResult(const HitTestResult&);
~HitTestResult();
HitTestResult& operator=(const HitTestResult&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
bool EqualForCacheability(const HitTestResult&) const;
void CacheValues(const HitTestResult& other);
diff --git a/chromium/third_party/blink/renderer/core/layout/intrinsic_sizing_info.h b/chromium/third_party/blink/renderer/core/layout/intrinsic_sizing_info.h
index 3c75bfad4a4..8fcac461125 100644
--- a/chromium/third_party/blink/renderer/core/layout/intrinsic_sizing_info.h
+++ b/chromium/third_party/blink/renderer/core/layout/intrinsic_sizing_info.h
@@ -15,6 +15,9 @@ struct IntrinsicSizingInfo {
IntrinsicSizingInfo() : has_width(true), has_height(true) {}
+ // Both size and aspect_ratio use logical coordinates.
+ // Because they are using float instead of LayoutUnit, we can't use
+ // LogicalSize here.
FloatSize size;
FloatSize aspect_ratio;
bool has_width;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_block.cc b/chromium/third_party/blink/renderer/core/layout/layout_block.cc
index 4e97d89ff2f..ce16a5a2801 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_block.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_block.cc
@@ -442,6 +442,8 @@ void LayoutBlock::AddVisualOverflowFromChildren() {
if (PrePaintBlockedByDisplayLock(DisplayLockLifecycleTarget::kChildren))
return;
+ DCHECK(!NeedsLayout());
+
if (ChildrenInline())
To<LayoutBlockFlow>(this)->AddVisualOverflowFromInlineChildren();
else
@@ -459,6 +461,8 @@ void LayoutBlock::AddLayoutOverflowFromChildren() {
}
void LayoutBlock::ComputeVisualOverflow(bool) {
+ DCHECK(!SelfNeedsLayout());
+
LayoutRect previous_visual_overflow_rect = VisualOverflowRect();
ClearVisualOverflow();
AddVisualOverflowFromChildren();
@@ -499,6 +503,18 @@ void LayoutBlock::ComputeLayoutOverflow(LayoutUnit old_client_after_edge,
LayoutUnit(1));
AddLayoutOverflow(rect_to_apply);
SetLayoutClientAfterEdge(old_client_after_edge);
+
+ if (PaddingEnd() && !ChildrenInline()) {
+ EOverflow overflow = StyleRef().OverflowInlineDirection();
+ if (overflow == EOverflow::kAuto) {
+ UseCounter::Count(GetDocument(),
+ WebFeature::kInlineOverflowAutoWithInlineEndPadding);
+ } else if (overflow == EOverflow::kScroll) {
+ UseCounter::Count(
+ GetDocument(),
+ WebFeature::kInlineOverflowScrollWithInlineEndPadding);
+ }
+ }
}
}
@@ -959,6 +975,7 @@ void LayoutBlock::InsertPositionedObject(LayoutBox* o) {
if (container_map_it->value == this) {
DCHECK(HasPositionedObjects());
DCHECK(PositionedObjects()->Contains(o));
+ PositionedObjects()->AppendOrMoveToLast(o);
return;
}
RemovePositionedObject(o);
@@ -1667,7 +1684,8 @@ void LayoutBlock::ComputeChildPreferredLogicalWidths(
const Length& computed_inline_size = child.StyleRef().LogicalWidth();
if (computed_inline_size.IsMaxContent())
min_preferred_logical_width = max_preferred_logical_width;
- else if (computed_inline_size.IsMinContent())
+ else if (computed_inline_size.IsMinContent() ||
+ computed_inline_size.IsMinIntrinsic())
max_preferred_logical_width = min_preferred_logical_width;
}
}
@@ -1684,9 +1702,15 @@ LayoutUnit LayoutBlock::EmptyLineBaseline(
LineDirectionMode line_direction) const {
if (!HasLineIfEmpty())
return LayoutUnit(-1);
+ const auto baseline_offset = BaselineForEmptyLine(line_direction);
+ return baseline_offset ? *baseline_offset : LayoutUnit(-1);
+}
+
+base::Optional<LayoutUnit> LayoutBlock::BaselineForEmptyLine(
+ LineDirectionMode line_direction) const {
const SimpleFontData* font_data = FirstLineStyle()->GetFont().PrimaryFont();
if (!font_data)
- return LayoutUnit(-1);
+ return base::nullopt;
const auto& font_metrics = font_data->GetFontMetrics();
const LayoutUnit line_height =
LineHeight(true, line_direction, kPositionOfInteriorLineBoxes);
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_block.h b/chromium/third_party/blink/renderer/core/layout/layout_block.h
index 68f16211d48..c729be28a63 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_block.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_block.h
@@ -401,6 +401,12 @@ class CORE_EXPORT LayoutBlock : public LayoutBox {
void UpdateAfterLayout() override;
MinMaxSizes PreferredLogicalWidths() const override;
+ virtual bool HasLineIfEmpty() const;
+ // Returns baseline offset if we can get |SimpleFontData| from primary font.
+ // Or returns no value if we can't get font data.
+ base::Optional<LayoutUnit> BaselineForEmptyLine(
+ LineDirectionMode line_direction) const;
+
protected:
virtual void AdjustInlineDirectionLineBounds(
unsigned /* expansionOpportunityCount */,
@@ -435,8 +441,6 @@ class CORE_EXPORT LayoutBlock : public LayoutBox {
// this object even if overflow is non-visible.
virtual bool AllowsOverflowClip() const;
- virtual bool HasLineIfEmpty() const;
-
bool SimplifiedLayout();
virtual void SimplifiedNormalFlowLayout();
@@ -477,6 +481,9 @@ class CORE_EXPORT LayoutBlock : public LayoutBox {
hit_test_action == kHitTestChildBlockBackground;
}
+ // Returns baseline offset of this block if is empty editable or having
+ // CSS property "--internal-empty-line-height"fabricated", otherwise
+ // returns |LayoutUnit(-1)|.
LayoutUnit EmptyLineBaseline(LineDirectionMode line_direction) const;
private:
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_block_flow.cc b/chromium/third_party/blink/renderer/core/layout/layout_block_flow.cc
index 6214dce7169..ee76ca597cd 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_block_flow.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_block_flow.cc
@@ -255,16 +255,15 @@ class BlockChildrenLayoutInfo {
bool IsAtFirstInFlowChild() const { return is_at_first_in_flow_child_; }
void ClearIsAtFirstInFlowChild() { is_at_first_in_flow_child_ = false; }
- // The page name of the previous sibling. Consecutive siblings with the same
- // name are allowed on the same page, but if they differ, we need a page
- // break.
- const AtomicString& ChildPageName() const { return child_page_name_; }
- void SetChildPageName(const AtomicString& name) { child_page_name_ = name; }
+ const AtomicString& PreviousEndPage() const { return previous_end_page_; }
+ void SetPreviousEndPage(const AtomicString& name) {
+ previous_end_page_ = name;
+ }
private:
MultiColumnLayoutState multi_column_layout_state_;
MarginInfo margin_info_;
- AtomicString child_page_name_;
+ AtomicString previous_end_page_;
LayoutUnit previous_float_logical_bottom_;
EBreakBetween previous_break_after_value_;
bool is_at_first_in_flow_child_;
@@ -595,6 +594,9 @@ void LayoutBlockFlow::ResetLayout() {
// [1] https://drafts.csswg.org/css-break/#possible-breaks
SetBreakBefore(LayoutBlock::BreakBefore());
SetBreakAfter(LayoutBlock::BreakAfter());
+
+ SetPropagatedStartPageName(AtomicString());
+ SetPropagatedEndPageName(AtomicString());
}
}
@@ -839,12 +841,49 @@ bool LayoutBlockFlow::PositionAndLayoutOnceIfNeeded(
void LayoutBlockFlow::InsertForcedBreakBeforeChildIfNeeded(
LayoutBox& child,
BlockChildrenLayoutInfo& layout_info) {
+ LayoutState* layout_state = View()->GetLayoutState();
+
+ // If the child has a start/end page name, that's the current name. Otherwise
+ // we'll use the input page name of this block (the name specified by this
+ // block, or by an ancestor). Adjacent siblings with the same page name may be
+ // placed on the same page. Otherwise, if there's a mismatch between the
+ // previous end page name and the current start page name, we need a break,
+ // except before the first in-flow child, since there's no valid class A
+ // breakpoint there.
+ const AtomicString child_start_page = child.StartPageName();
+ const AtomicString child_end_page = child.EndPageName();
+ const AtomicString& current_start_page =
+ child_start_page ? child_start_page : layout_state->InputPageName();
+ const AtomicString& current_end_page =
+ child_end_page ? child_end_page : layout_state->InputPageName();
+ bool page_name_has_changed =
+ current_start_page != layout_info.PreviousEndPage();
+
+ // Page name changes are detected above by comparing the previous end page
+ // name and the current start page name. We're now storing the current *end*
+ // page name, for the next sibling to use in its comparison. This means that
+ // we're not paying any attention to any page name changes within the current
+ // child. That's fine, though. We're done with this child, and we've already
+ // inserted any named page breaks that were needed inside the child. Note that
+ // all of that will be discarded and re-laid out, if it turns out that we need
+ // a break before this child as well. This is how block fragmentation works;
+ // if we insert a break in front of something that we've laid out, we need
+ // another deep layout pass of all subsequent content, since pagination struts
+ // (or the whereabouts of the fragmentation boundary relative to the child)
+ // may change.
+ layout_info.SetPreviousEndPage(current_end_page);
+
if (layout_info.IsAtFirstInFlowChild()) {
// There's no class A break point before the first child (only *between*
// siblings), so steal its break value and join it with what we already have
// here.
SetBreakBefore(
JoinFragmentainerBreakValues(BreakBefore(), child.BreakBefore()));
+
+ // Similarly, since there's no valid class A breakpoint here, if the first
+ // child has a start page name associated, it will be propagated upwards.
+ SetPropagatedStartPageName(child_start_page);
+
return;
}
@@ -854,21 +893,7 @@ void LayoutBlockFlow::InsertForcedBreakBeforeChildIfNeeded(
EBreakBetween class_a_break_point_value =
child.ClassABreakPointValue(layout_info.PreviousBreakAfterValue());
- bool is_named_page_break;
- if (layout_info.ChildPageName()) {
- // Adjacent siblings with the same page name may be put on the same
- // page. Otherwise, we need a break.
- is_named_page_break =
- layout_info.ChildPageName() != child.StyleRef().Page();
- } else {
- // If the previous sibling (if any) didn't specify a page name, see if one
- // is specified on an ancestor. If the child specifies a page name, and it
- // doesn't match what's specified further up (if anything), we need a break.
- is_named_page_break =
- child.StyleRef().Page() &&
- child.StyleRef().Page() != View()->GetLayoutState()->PageName();
- }
- if (is_named_page_break)
+ if (page_name_has_changed && IsBreakBetweenControllable(EBreakBetween::kPage))
class_a_break_point_value = EBreakBetween::kPage;
if (IsForcedFragmentainerBreakValue(class_a_break_point_value)) {
@@ -879,14 +904,13 @@ void LayoutBlockFlow::InsertForcedBreakBeforeChildIfNeeded(
SetLogicalHeight(new_logical_top);
LayoutUnit pagination_strut = new_logical_top - old_logical_top;
child.SetPaginationStrut(pagination_strut);
- if (is_named_page_break) {
+ if (page_name_has_changed) {
// This was a forced break because of named pages. We now need to store
// the page number where this happened, so that we can apply the right
// descriptors (size, margins, page-orientation, etc.) when printing the
// page.
- layout_info.SetChildPageName(child.StyleRef().Page());
if (NamedPagesMapper* mapper = View()->GetNamedPagesMapper()) {
- mapper->AddNamedPage(child.StyleRef().Page(),
+ mapper->AddNamedPage(current_start_page,
CurrentPageNumber(new_logical_top));
}
}
@@ -2266,13 +2290,18 @@ void LayoutBlockFlow::HandleAfterSideOfBlock(LayoutBox* last_child,
// Update our bottom collapsed margin info.
SetCollapsedBottomMargin(margin_info);
- // There's no class A break point right after the last child, only *between*
- // siblings. So propagate the break-after value, and keep looking for a class
- // A break point (at the next in-flow block-level object), where we'll join
- // this break-after value with the break-before value there.
- if (View()->GetLayoutState()->IsPaginated() && last_child)
+ if (View()->GetLayoutState()->IsPaginated() && last_child) {
+ // There's no class A break point right after the last child, only *between*
+ // siblings. So propagate the break-after value, and keep looking for a
+ // class A break point (at the next in-flow block-level object), where we'll
+ // join this break-after value with the break-before value there.
SetBreakAfter(
JoinFragmentainerBreakValues(BreakAfter(), last_child->BreakAfter()));
+
+ // Similarly, since there's no valid class A breakpoint here, if the last
+ // child has a end page name associated, it will be propagated upwards.
+ SetPropagatedEndPageName(last_child->EndPageName());
+ }
}
void LayoutBlockFlow::SetMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg) {
@@ -2356,9 +2385,12 @@ EBreakBetween LayoutBlockFlow::BreakAfter() const {
}
void LayoutBlockFlow::AddVisualOverflowFromFloats() {
- if (!floating_objects_)
+ if (PrePaintBlockedByDisplayLock(DisplayLockLifecycleTarget::kChildren) ||
+ !floating_objects_)
return;
+ DCHECK(!NeedsLayout());
+
for (auto& floating_object : floating_objects_->Set()) {
if (floating_object->IsDescendant()) {
AddVisualOverflowFromChild(
@@ -2371,7 +2403,10 @@ void LayoutBlockFlow::AddVisualOverflowFromFloats() {
void LayoutBlockFlow::AddVisualOverflowFromFloats(
const NGPhysicalContainerFragment& fragment) {
+ DCHECK(!NeedsLayout());
+ DCHECK(!PrePaintBlockedByDisplayLock(DisplayLockLifecycleTarget::kChildren));
DCHECK(fragment.HasFloatingDescendantsForPaint());
+
for (const NGLink& child : fragment.Children()) {
if (child->HasSelfPaintingLayer())
continue;
@@ -2391,7 +2426,8 @@ void LayoutBlockFlow::AddVisualOverflowFromFloats(
}
void LayoutBlockFlow::AddLayoutOverflowFromFloats() {
- if (!floating_objects_)
+ if (LayoutBlockedByDisplayLock(DisplayLockLifecycleTarget::kChildren) ||
+ !floating_objects_)
return;
for (auto& floating_object : floating_objects_->Set()) {
@@ -2416,6 +2452,8 @@ const NGFragmentItems* LayoutBlockFlow::FragmentItems() const {
void LayoutBlockFlow::ComputeVisualOverflow(
bool recompute_floats) {
+ DCHECK(!SelfNeedsLayout());
+
LayoutRect previous_visual_overflow_rect = VisualOverflowRect();
ClearVisualOverflow();
AddVisualOverflowFromChildren();
@@ -2427,6 +2465,7 @@ void LayoutBlockFlow::ComputeVisualOverflow(
(recompute_floats || CreatesNewFormattingContext() ||
HasSelfPaintingLayer()))
AddVisualOverflowFromFloats();
+
if (VisualOverflowRect() != previous_visual_overflow_rect) {
InvalidateIntersectionObserverCachedRects();
SetShouldCheckForPaintInvalidation();
@@ -3059,8 +3098,7 @@ void LayoutBlockFlow::RemoveChild(LayoutObject* old_child) {
// If we are an empty anonymous block in the continuation chain,
// we need to remove ourself and fix the continuation chain.
- if (!BeingDestroyed() && IsAnonymousBlockContinuation() &&
- !old_child->IsListMarker()) {
+ if (!BeingDestroyed() && IsAnonymousBlockContinuation()) {
LayoutObject* containing_block_ignoring_anonymous = ContainingBlock();
while (containing_block_ignoring_anonymous &&
containing_block_ignoring_anonymous->IsAnonymous())
@@ -4070,14 +4108,14 @@ bool LayoutBlockFlow::HitTestFloats(HitTestResult& result,
return false;
}
-PhysicalOffset LayoutBlockFlow::AccumulateInFlowPositionOffsets() const {
+PhysicalOffset LayoutBlockFlow::AccumulateRelativePositionOffsets() const {
if (!IsAnonymousBlock() || !IsInFlowPositioned())
return PhysicalOffset();
PhysicalOffset offset;
for (const LayoutObject* p = InlineElementContinuation();
p && p->IsLayoutInline(); p = p->Parent()) {
if (p->IsInFlowPositioned())
- offset += ToLayoutInline(p)->OffsetForInFlowPosition();
+ offset += ToLayoutInline(p)->RelativePositionOffset();
}
return offset;
}
@@ -4247,6 +4285,44 @@ void LayoutBlockFlow::SetFirstForcedBreakOffset(LayoutUnit block_offset) {
rare_data_->first_forced_break_offset_ = block_offset;
}
+const AtomicString LayoutBlockFlow::StartPageName() const {
+ if (const AtomicString& propagated_name = PropagatedStartPageName())
+ return propagated_name;
+ return StyleRef().Page();
+}
+
+const AtomicString LayoutBlockFlow::EndPageName() const {
+ if (const AtomicString& propagated_name = PropagatedEndPageName())
+ return propagated_name;
+ return StyleRef().Page();
+}
+
+const AtomicString LayoutBlockFlow::PropagatedStartPageName() const {
+ if (!rare_data_)
+ return AtomicString();
+ return rare_data_->propagated_start_page_name_;
+}
+
+void LayoutBlockFlow::SetPropagatedStartPageName(const AtomicString& name) {
+ if (name.IsEmpty() && !rare_data_)
+ return;
+ LayoutBlockFlowRareData& rare_data = EnsureRareData();
+ rare_data.propagated_start_page_name_ = name;
+}
+
+const AtomicString LayoutBlockFlow::PropagatedEndPageName() const {
+ if (!rare_data_)
+ return AtomicString();
+ return rare_data_->propagated_end_page_name_;
+}
+
+void LayoutBlockFlow::SetPropagatedEndPageName(const AtomicString& name) {
+ if (name.IsEmpty() && !rare_data_)
+ return;
+ LayoutBlockFlowRareData& rare_data = EnsureRareData();
+ rare_data.propagated_end_page_name_ = name;
+}
+
void LayoutBlockFlow::PositionSpannerDescendant(
LayoutMultiColumnSpannerPlaceholder& child) {
LayoutBox& spanner = *child.LayoutObjectInFlowThread();
@@ -4263,6 +4339,7 @@ bool LayoutBlockFlow::CreatesNewFormattingContext() const {
IsDocumentElement() || IsGridItem() || IsWritingModeRoot() ||
IsMathItem() || StyleRef().Display() == EDisplay::kFlowRoot ||
ShouldApplyPaintContainment() || ShouldApplyLayoutContainment() ||
+ StyleRef().IsDeprecatedWebkitBoxWithVerticalLineClamp() ||
StyleRef().SpecifiesColumns() ||
StyleRef().GetColumnSpan() == EColumnSpan::kAll) {
// The specs require this object to establish a new formatting context.
@@ -4468,7 +4545,7 @@ void LayoutBlockFlow::RecalcFloatingDescendantsVisualOverflow(
const NGPhysicalContainerFragment& fragment) {
DCHECK(fragment.HasFloatingDescendantsForPaint());
- for (const NGLink& child : fragment.Children()) {
+ for (const NGLink& child : fragment.PostLayoutChildren()) {
if (child->IsFloating()) {
child->GetMutableLayoutObject()
->RecalcNormalFlowChildVisualOverflowIfNeeded();
@@ -4574,13 +4651,8 @@ PositionWithAffinity LayoutBlockFlow::PositionForPoint(
}
}
- bool move_caret_to_boundary =
- GetDocument()
- .GetFrame()
- ->GetEditor()
- .Behavior()
- .ShouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
-
+ const bool move_caret_to_boundary =
+ ShouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
if (!move_caret_to_boundary && !closest_box && last_root_box_with_children) {
// y coordinate is below last root line box, pretend we hit it
closest_box =
@@ -4644,6 +4716,15 @@ PositionWithAffinity LayoutBlockFlow::PositionForPoint(
return CreatePositionWithAffinity(0);
}
+bool LayoutBlockFlow::ShouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom()
+ const {
+ return GetDocument()
+ .GetFrame()
+ ->GetEditor()
+ .Behavior()
+ .ShouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
+}
+
#if DCHECK_IS_ON()
void LayoutBlockFlow::ShowLineTreeAndMark(const InlineBox* marked_box1,
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_block_flow.h b/chromium/third_party/blink/renderer/core/layout/layout_block_flow.h
index e7f1a334a53..b36394a18dd 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_block_flow.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_block_flow.h
@@ -356,6 +356,9 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
}
void SetFirstForcedBreakOffset(LayoutUnit);
+ const AtomicString StartPageName() const final;
+ const AtomicString EndPageName() const final;
+
void PositionSpannerDescendant(LayoutMultiColumnSpannerPlaceholder& child);
bool CreatesNewFormattingContext() const override;
@@ -433,6 +436,7 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override;
PositionWithAffinity PositionForPoint(const LayoutObject& offset_parent,
const PhysicalOffset& offset) const;
+ bool ShouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom() const;
LayoutUnit LowestFloatLogicalBottom(EClear = EClear::kBoth) const;
@@ -535,7 +539,7 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
const PhysicalOffset& accumulated_offset,
HitTestAction) override;
- PhysicalOffset AccumulateInFlowPositionOffsets() const override;
+ PhysicalOffset AccumulateRelativePositionOffsets() const override;
private:
void ResetLayout();
@@ -669,6 +673,16 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
return rare_data_ && rare_data_->did_break_at_line_to_avoid_widow_;
}
+ // Start page name propagated from the first child, if there are children, and
+ // the first child has a start page name associated with it.
+ const AtomicString PropagatedStartPageName() const;
+ void SetPropagatedStartPageName(const AtomicString&);
+
+ // End page name propagated from the last child, if there are children, and
+ // the last child has a end page name associated with it.
+ const AtomicString PropagatedEndPageName() const;
+ void SetPropagatedEndPageName(const AtomicString&);
+
public:
struct FloatWithRect {
DISALLOW_NEW();
@@ -753,7 +767,7 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
return (-block->MarginAfter()).ClampNegativeToZero();
}
- void Trace(Visitor*) {}
+ void Trace(Visitor*) const {}
MarginValues margins_;
LayoutUnit pagination_strut_propagated_from_child_;
@@ -768,6 +782,14 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
// |offset_mapping_| here.
std::unique_ptr<NGOffsetMapping> offset_mapping_;
+ // Name of the start page for this object, if propagated from a descendant;
+ // see https://drafts.csswg.org/css-page-3/#start-page-value
+ AtomicString propagated_start_page_name_;
+
+ // Name of the end page for this object, if propagated from a descendant;
+ // see https://drafts.csswg.org/css-page-3/#end-page-value
+ AtomicString propagated_end_page_name_;
+
unsigned break_before_ : 4;
unsigned break_after_ : 4;
int line_break_to_avoid_widow_;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_block_flow_line.cc b/chromium/third_party/blink/renderer/core/layout/layout_block_flow_line.cc
index dc9f0999a5f..a928cded339 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_block_flow_line.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_block_flow_line.cc
@@ -1901,7 +1901,7 @@ void LayoutBlockFlow::ComputeInlinePreferredLogicalWidths(
}
// Ignore spaces after a list marker.
- if (child->IsListMarkerIncludingNGOutside())
+ if (child->IsBoxListMarkerIncludingNG())
strip_front_spaces = true;
} else {
min_logical_width = std::max(min_logical_width, inline_min);
@@ -2385,12 +2385,8 @@ bool LayoutBlockFlow::GeneratesLineBoxesForInlineChild(LayoutObject* inline_obj)
}
void LayoutBlockFlow::AddVisualOverflowFromInlineChildren() {
- LayoutUnit end_padding = HasOverflowClip() ? PaddingEnd() : LayoutUnit();
- // FIXME: Need to find another way to do this, since scrollbars could show
- // when we don't want them to.
- if (HasOverflowClip() && !end_padding && GetNode() &&
- IsRootEditableElement(*GetNode()) && StyleRef().IsLeftToRightDirection())
- end_padding = LayoutUnit(1);
+ DCHECK(!NeedsLayout());
+ DCHECK(!PrePaintBlockedByDisplayLock(DisplayLockLifecycleTarget::kChildren));
if (const NGPaintFragment* paint_fragment = PaintFragment()) {
for (const NGPaintFragment* child : paint_fragment->Children()) {
@@ -2454,12 +2450,46 @@ void LayoutBlockFlow::AddVisualOverflowFromInlineChildren() {
}
void LayoutBlockFlow::AddLayoutOverflowFromInlineChildren() {
+ DCHECK(!LayoutBlockedByDisplayLock(DisplayLockLifecycleTarget::kChildren));
+
LayoutUnit end_padding = HasOverflowClip() ? PaddingEnd() : LayoutUnit();
// FIXME: Need to find another way to do this, since scrollbars could show
// when we don't want them to.
+ // The test[1] verifies this.
+ // [1] editing/input/editable-container-with-word-wrap-normal.html
if (HasOverflowClip() && !end_padding && GetNode() &&
- IsRootEditableElement(*GetNode()) && StyleRef().IsLeftToRightDirection())
+ IsRootEditableElement(*GetNode()) &&
+ StyleRef().IsLeftToRightDirection()) {
+ if (const NGPhysicalBoxFragment* fragment = CurrentFragment()) {
+ if (const NGFragmentItems* items = fragment->Items()) {
+ for (NGInlineCursor cursor(*items); cursor;
+ cursor.MoveToNextSkippingChildren()) {
+ if (!cursor.Current().IsLineBox())
+ continue;
+ const NGFragmentItem& child = *cursor.CurrentItem();
+ LogicalRect logical_rect =
+ fragment->ConvertChildToLogical(child.RectInContainerBlock());
+ logical_rect.size.inline_size += 1;
+ AddLayoutOverflow(
+ fragment->ConvertChildToPhysical(logical_rect).ToLayoutRect());
+ }
+ return;
+ }
+ // Note: Paint fragment for this block isn't set yet.
+ for (const NGLink& child : fragment->Children()) {
+ if (!child->IsLineBox())
+ continue;
+ LogicalRect logical_rect = fragment->ConvertChildToLogical(
+ PhysicalRect(child.Offset(), child->Size()));
+ logical_rect.size.inline_size += 1;
+ AddLayoutOverflow(
+ fragment->ConvertChildToPhysical(logical_rect).ToLayoutRect());
+ }
+ return;
+ }
end_padding = LayoutUnit(1);
+ }
+
for (RootInlineBox* curr = FirstRootBox(); curr; curr = curr->NextRootBox())
AddLayoutOverflow(curr->PaddedLayoutOverflowRect(end_padding));
}
@@ -2772,8 +2802,12 @@ void LayoutBlockFlow::SetShouldDoFullPaintInvalidationForFirstLine() {
// Mark all descendants of the first line if first-line style.
for (NGInlineCursor descendants = first_line.CursorForDescendants();
descendants; descendants.MoveToNext()) {
- LayoutObject* layout_object =
- descendants.Current()->GetMutableLayoutObject();
+ const NGFragmentItem* item = descendants.Current().Item();
+ if (UNLIKELY(item->IsLayoutObjectDestroyedOrMoved())) {
+ descendants.MoveToNextSkippingChildren();
+ continue;
+ }
+ LayoutObject* layout_object = item->GetMutableLayoutObject();
DCHECK(layout_object);
layout_object->StyleRef().ClearCachedPseudoElementStyles();
layout_object->SetShouldDoFullPaintInvalidation();
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_box.cc b/chromium/third_party/blink/renderer/core/layout/layout_box.cc
index c0cc36526af..54f13b0b9d5 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_box.cc
@@ -248,7 +248,7 @@ LayoutBoxRareData::LayoutBoxRareData()
snap_container_(nullptr),
snap_areas_(nullptr) {}
-void LayoutBoxRareData::Trace(Visitor* visitor) {
+void LayoutBoxRareData::Trace(Visitor* visitor) const {
visitor->Trace(layout_child_);
}
@@ -266,14 +266,8 @@ LayoutBox::LayoutBox(ContainerNode* node)
LayoutBox::~LayoutBox() = default;
PaintLayerType LayoutBox::LayerTypeRequired() const {
- // hasAutoZIndex only returns true if the element is positioned or a flex-item
- // since position:static elements that are not flex-items get their z-index
- // coerced to auto.
- if (IsPositioned() || CreatesGroup() || HasTransformRelatedProperty() ||
- HasHiddenBackface() || HasReflection() ||
+ if (IsStacked() || HasHiddenBackface() ||
(StyleRef().SpecifiesColumns() && !CanTraversePhysicalFragments()) ||
- StyleRef().IsStackingContext() ||
- StyleRef().ShouldCompositeForCurrentAnimations() ||
IsEffectiveRootScroller())
return kNormalPaintLayer;
@@ -386,6 +380,16 @@ void LayoutBox::StyleWillChange(StyleDifference diff,
// recalculation.
SetNeedsLayoutAndIntrinsicWidthsRecalc(
layout_invalidation_reason::kStyleChange);
+
+ if (IsInLayoutNGInlineFormattingContext() &&
+ RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled() &&
+ FirstInlineFragmentItemIndex()) {
+ // Out of flow are not part of |NGFragmentItems|, and that further
+ // changes including destruction cannot be tracked. Mark it is moved
+ // out from this IFC.
+ NGFragmentItems::LayoutObjectWillBeMoved(*this);
+ ClearFirstInlineFragmentItemIndex();
+ }
} else {
MarkContainerChainForLayout();
}
@@ -492,8 +496,11 @@ void LayoutBox::StyleDidChange(StyleDifference diff,
// The overflow clip paint property depends on border sizes through
// overflowClipRect(), and border radii, so we update properties on
// border size or radii change.
+ //
+ // For some controls, it depends on paddings.
if (!old_style->BorderSizeEquals(new_style) ||
- !old_style->RadiiEqual(new_style)) {
+ !old_style->RadiiEqual(new_style) ||
+ (HasControlClip() && !old_style->PaddingEqual(new_style))) {
SetNeedsPaintPropertyUpdate();
if (Layer())
Layer()->SetNeedsCompositingInputsUpdate();
@@ -1000,6 +1007,7 @@ LayoutUnit LayoutBox::ConstrainLogicalHeightByMinMax(
const Length& logical_max_height = StyleRef().LogicalMaxHeight();
if (!logical_max_height.IsNone() && !logical_max_height.IsMinContent() &&
!logical_max_height.IsMaxContent() &&
+ !logical_max_height.IsMinIntrinsic() &&
!logical_max_height.IsFitContent()) {
LayoutUnit max_h = ComputeLogicalHeightUsing(kMaxSize, logical_max_height,
intrinsic_content_height);
@@ -1008,7 +1016,7 @@ LayoutUnit LayoutBox::ConstrainLogicalHeightByMinMax(
}
Length logical_min_height = StyleRef().LogicalMinHeight();
if (logical_min_height.IsMinContent() || logical_min_height.IsMaxContent() ||
- logical_min_height.IsFitContent())
+ logical_min_height.IsMinIntrinsic() || logical_min_height.IsFitContent())
logical_min_height = Length::Auto();
return std::max(logical_height,
ComputeLogicalHeightUsing(kMinSize, logical_min_height,
@@ -1066,9 +1074,18 @@ void LayoutBox::SetLocationAndUpdateOverflowControlsIfNeeded(
IntSize old_pixel_snapped_border_rect_size =
PixelSnappedBorderBoxRect().Size();
SetLocation(location);
+ // TODO(crbug.com/1020913): This is problematic because this function may be
+ // called after layout of this LayoutBox. Changing scroll container size here
+ // will cause inconsistent layout. Also we should be careful not to set
+ // this LayoutBox NeedsLayout. This will be unnecessary when we support
+ // subpixel layout of scrollable area and overflow controls.
if (PixelSnappedBorderBoxRect().Size() !=
old_pixel_snapped_border_rect_size) {
+ bool needed_layout = NeedsLayout();
+ PaintLayerScrollableArea::FreezeScrollbarsScope freeze_scrollbar;
Layer()->UpdateSizeAndScrollingAfterLayout();
+ // The above call should not schedule new NeedsLayout.
+ DCHECK(needed_layout || !NeedsLayout());
}
}
@@ -1079,6 +1096,11 @@ FloatQuad LayoutBox::AbsoluteContentQuad(MapCoordinatesFlags flags) const {
PhysicalRect LayoutBox::PhysicalBackgroundRect(
BackgroundRectType rect_type) const {
+ // If the background transfers to view, the used background of this object
+ // is transparent.
+ if (rect_type == kBackgroundKnownOpaqueRect && BackgroundTransfersToView())
+ return PhysicalRect();
+
EFillBox background_box = EFillBox::kText;
// Find the largest background rect of the given opaqueness.
if (const FillLayer* current = &(StyleRef().BackgroundLayers())) {
@@ -1419,9 +1441,14 @@ bool LayoutBox::MapVisualRectToContainer(
transform.PostTranslate(offset.Width(), offset.Height());
}
+ bool has_perspective = container_object && container_object->HasLayer() &&
+ container_object->StyleRef().HasPerspective();
+ if (has_perspective && RuntimeEnabledFeatures::TransformInteropEnabled() &&
+ container_object != NonAnonymousAncestor())
+ has_perspective = false;
+
// d) Perspective applied by container.
- if (container_object && container_object->HasLayer() &&
- container_object->StyleRef().HasPerspective()) {
+ if (has_perspective) {
// Perspective on the container affects us, so we have to factor it in here.
DCHECK(container_object->HasLayer());
FloatPoint perspective_origin =
@@ -1919,11 +1946,6 @@ bool LayoutBox::GetBackgroundPaintedExtent(PhysicalRect& painted_extent) const {
bool LayoutBox::BackgroundIsKnownToBeOpaqueInRect(
const PhysicalRect& local_rect) const {
- // If the background transfers to view, the used background of this object
- // is transparent.
- if (BackgroundTransfersToView())
- return false;
-
// If the element has appearance, it might be painted by theme.
// We cannot be sure if theme paints the background opaque.
// In this case it is safe to not assume opaqueness.
@@ -1943,6 +1965,20 @@ bool LayoutBox::BackgroundIsKnownToBeOpaqueInRect(
.Contains(local_rect);
}
+// TODO(wangxianzhu): The current rules are very basic. May use more complex
+// rules if they can improve LCD text.
+bool LayoutBox::TextIsKnownToBeOnOpaqueBackground() const {
+ // Text may overflow the background area.
+ if (!ShouldClipOverflow())
+ return false;
+ // Same as BackgroundIsKnownToBeOpaqueInRect() about appearance.
+ if (StyleRef().HasEffectiveAppearance())
+ return false;
+
+ PhysicalRect rect = OverflowClipRect(PhysicalOffset());
+ return PhysicalBackgroundRect(kBackgroundKnownOpaqueRect).Contains(rect);
+}
+
static bool IsCandidateForOpaquenessTest(const LayoutBox& child_box) {
const ComputedStyle& child_style = child_box.StyleRef();
if (child_style.GetPosition() != EPosition::kStatic &&
@@ -1961,7 +1997,7 @@ static bool IsCandidateForOpaquenessTest(const LayoutBox& child_box) {
if (child_layer->GetCompositingState() != kNotComposited)
return false;
// FIXME: Deal with z-index.
- if (child_style.IsStackingContext())
+ if (child_box.IsStackingContext())
return false;
if (child_layer->HasTransformRelatedProperty() ||
child_layer->IsTransparent() ||
@@ -2179,6 +2215,19 @@ void LayoutBox::InvalidatePaint(const PaintInvalidatorContext& context) const {
BoxPaintInvalidator(*this, context).InvalidatePaint();
}
+void LayoutBox::ClearPaintFlags() {
+ LayoutObject::ClearPaintFlags();
+
+ if (auto* scrollable_area = GetScrollableArea()) {
+ if (auto* scrollbar =
+ DynamicTo<CustomScrollbar>(scrollable_area->HorizontalScrollbar()))
+ scrollbar->ClearPaintFlags();
+ if (auto* scrollbar =
+ DynamicTo<CustomScrollbar>(scrollable_area->VerticalScrollbar()))
+ scrollbar->ClearPaintFlags();
+ }
+}
+
PhysicalRect LayoutBox::OverflowClipRect(
const PhysicalOffset& location,
OverlayScrollbarClipBehavior overlay_scrollbar_clip_behavior) const {
@@ -2641,7 +2690,7 @@ const NGLayoutResult* LayoutBox::GetCachedLayoutResult() const {
const NGLayoutResult* result = layout_results_[0].get();
if (result->IsSingleUse())
return nullptr;
- DCHECK(result->PhysicalFragment().IsAlive());
+ DCHECK(result->PhysicalFragment().IsAlive() || BeingDestroyed());
DCHECK_EQ(layout_results_.size(), 1u);
return result;
}
@@ -2758,7 +2807,8 @@ scoped_refptr<const NGLayoutResult> LayoutBox::CachedLayoutResult(
// Update our temporary cache status, if the size cache check indicated we
// might need simplified layout.
- if (size_cache_status == NGLayoutCacheStatus::kNeedsSimplifiedLayout)
+ if (size_cache_status == NGLayoutCacheStatus::kNeedsSimplifiedLayout &&
+ cache_status == NGLayoutCacheStatus::kHit)
cache_status = NGLayoutCacheStatus::kNeedsSimplifiedLayout;
LayoutUnit bfc_line_offset = new_space.BfcOffset().line_offset;
@@ -3073,6 +3123,14 @@ bool LayoutBox::NeedsForcedBreakBefore(
return IsForcedFragmentainerBreakValue(break_value);
}
+const AtomicString LayoutBox::StartPageName() const {
+ return StyleRef().Page();
+}
+
+const AtomicString LayoutBox::EndPageName() const {
+ return StyleRef().Page();
+}
+
PhysicalRect LayoutBox::LocalVisualRectIgnoringVisibility() const {
return PhysicalSelfVisualOverflowRect();
}
@@ -3274,7 +3332,7 @@ static float GetMaxWidthListMarker(const LayoutBox* layout_object) {
LayoutBox* list_item = ToLayoutBox(child);
for (LayoutObject* item_child = list_item->SlowFirstChild(); item_child;
item_child = item_child->NextSibling()) {
- if (!item_child->IsListMarker())
+ if (!item_child->IsListMarkerForNormalContent())
continue;
LayoutBox* item_marker = ToLayoutBox(item_child);
// Make sure to compute the autosized width.
@@ -3455,7 +3513,8 @@ LayoutUnit LayoutBox::ComputeIntrinsicLogicalWidthUsing(
MinMaxSizes sizes = IntrinsicLogicalWidths();
- if (logical_width_length.IsMinContent())
+ if (logical_width_length.IsMinContent() ||
+ logical_width_length.IsMinIntrinsic())
return sizes.min_size;
if (logical_width_length.IsMaxContent())
@@ -3970,6 +4029,7 @@ LayoutUnit LayoutBox::ComputeIntrinsicLogicalContentHeightUsing(
// If that happens, this code will have to change.
if (logical_height_length.IsMinContent() ||
logical_height_length.IsMaxContent() ||
+ logical_height_length.IsMinIntrinsic() ||
logical_height_length.IsFitContent()) {
if (IsAtomicInlineLevel() && !IsFlexibleBoxIncludingNG() && !IsLayoutGrid())
return IntrinsicSize().Height();
@@ -4213,7 +4273,8 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalWidthUsing(
case Length::kFixed:
return AdjustContentBoxLogicalWidthForBoxSizing(logical_width.Value());
case Length::kMinContent:
- case Length::kMaxContent: {
+ case Length::kMaxContent:
+ case Length::kMinIntrinsic: {
// MinContent/MaxContent don't need the availableLogicalWidth argument.
LayoutUnit available_logical_width;
return ComputeIntrinsicLogicalWidthUsing(logical_width,
@@ -4275,7 +4336,7 @@ bool LayoutBox::LogicalHeightComputesAsNone(SizeType size_type) const {
// Note that the values 'min-content', 'max-content' and 'fit-content' should
// behave as the initial value if specified in the block direction.
if (logical_height.IsMinContent() || logical_height.IsMaxContent() ||
- logical_height.IsFitContent())
+ logical_height.IsMinIntrinsic() || logical_height.IsFitContent())
return true;
Length initial_logical_height =
@@ -4471,11 +4532,14 @@ LayoutUnit LayoutBox::AvailableLogicalHeightUsing(
} else if (HasOverrideLogicalHeight() &&
IsOverrideLogicalHeightDefinite()) {
return OverrideContentLogicalHeight();
- } else if (const auto* previous_result = GetCachedLayoutResult()) {
- const NGConstraintSpace& space =
- previous_result->GetConstraintSpaceForCaching();
- if (space.IsFixedBlockSize() && !space.IsFixedBlockSizeIndefinite())
- return space.AvailableSize().block_size;
+ } else if (!GetBoxLayoutExtraInput()) {
+ // TODO(ikilpatrick): Remove this post M86.
+ if (const auto* previous_result = GetCachedLayoutResult()) {
+ const NGConstraintSpace& space =
+ previous_result->GetConstraintSpaceForCaching();
+ if (space.IsFixedBlockSize() && !space.IsFixedBlockSizeIndefinite())
+ return space.AvailableSize().block_size;
+ }
}
}
@@ -5275,6 +5339,7 @@ void LayoutBox::ComputePositionedLogicalHeight(
const Length& logical_max_height = style_to_use.LogicalMaxHeight();
if (!logical_max_height.IsNone() && !logical_max_height.IsMinContent() &&
!logical_max_height.IsMaxContent() &&
+ !logical_max_height.IsMinIntrinsic() &&
!logical_max_height.IsFitContent()) {
LogicalExtentComputedValues max_values;
@@ -5294,7 +5359,7 @@ void LayoutBox::ComputePositionedLogicalHeight(
// Calculate constraint equation values for 'min-height' case.
Length logical_min_height = style_to_use.LogicalMinHeight();
if (logical_min_height.IsMinContent() || logical_min_height.IsMaxContent() ||
- logical_min_height.IsFitContent())
+ logical_min_height.IsMinIntrinsic() || logical_min_height.IsFitContent())
logical_min_height = Length::Auto();
if (!logical_min_height.IsZero() || logical_min_height.IsFillAvailable()) {
LogicalExtentComputedValues min_values;
@@ -5752,18 +5817,6 @@ bool LayoutBox::ShouldBeConsideredAsReplaced() const {
return IsA<HTMLImageElement>(element);
}
-bool LayoutBox::HasNonCompositedScrollbars() const {
- if (PaintLayerScrollableArea* scrollable_area = GetScrollableArea()) {
- if (scrollable_area->HasHorizontalScrollbar() &&
- !scrollable_area->LayerForHorizontalScrollbar())
- return true;
- if (scrollable_area->HasVerticalScrollbar() &&
- !scrollable_area->LayerForVerticalScrollbar())
- return true;
- }
- return false;
-}
-
void LayoutBox::UpdateFragmentationInfoForChild(LayoutBox& child) {
LayoutState* layout_state = View()->GetLayoutState();
DCHECK(layout_state->IsPaginated());
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_box.h b/chromium/third_party/blink/renderer/core/layout/layout_box.h
index 963867ebfdd..5921913da3a 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_box.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_box.h
@@ -69,7 +69,7 @@ struct LayoutBoxRareData final : public GarbageCollected<LayoutBoxRareData> {
public:
LayoutBoxRareData();
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
// For spanners, the spanner placeholder that lays us out within the multicol
// container.
@@ -220,6 +220,7 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
bool BackgroundIsKnownToBeOpaqueInRect(
const PhysicalRect& local_rect) const override;
+ bool TextIsKnownToBeOnOpaqueBackground() const override;
virtual bool BackgroundShouldAlwaysBeClipped() const { return false; }
@@ -307,10 +308,12 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
LayoutUnit MinimumLogicalHeightForEmptyLine() const {
return BorderAndPaddingLogicalHeight() + ScrollbarLogicalHeight() +
- LineHeight(
- true,
- IsHorizontalWritingMode() ? kHorizontalLine : kVerticalLine,
- kPositionOfInteriorLineBoxes);
+ LogicalHeightForEmptyLine();
+ }
+ LayoutUnit LogicalHeightForEmptyLine() const {
+ return LineHeight(
+ true, IsHorizontalWritingMode() ? kHorizontalLine : kVerticalLine,
+ kPositionOfInteriorLineBoxes);
}
void SetLogicalLeft(LayoutUnit left) {
@@ -1055,6 +1058,14 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
// value of the previous in-flow sibling.
bool NeedsForcedBreakBefore(EBreakBetween previous_break_after_value) const;
+ // Get the name of the start page name for this object; see
+ // https://drafts.csswg.org/css-page-3/#start-page-value
+ virtual const AtomicString StartPageName() const;
+
+ // Get the name of the end page name for this object; see
+ // https://drafts.csswg.org/css-page-3/#end-page-value
+ virtual const AtomicString EndPageName() const;
+
bool MapToVisualRectInAncestorSpaceInternal(
const LayoutBoxModelObject* ancestor,
TransformState&,
@@ -1547,9 +1558,8 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
// Returns true if the box intersects the viewport visible to the user.
bool IntersectsVisibleViewport() const;
- bool HasNonCompositedScrollbars() const final;
-
void EnsureIsReadyForPaintInvalidation() override;
+ void ClearPaintFlags() override;
bool HasControlClip() const;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_box_model_object.cc b/chromium/third_party/blink/renderer/core/layout/layout_box_model_object.cc
index 42a4f5d5b50..efb9bb50267 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_box_model_object.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_box_model_object.cc
@@ -122,11 +122,6 @@ LayoutBoxModelObject::ComputeBackgroundPaintLocationIfComposited() const {
return kBackgroundPaintInScrollingContents;
}
- // TODO(flackr): When we correctly clip the scrolling contents layer we can
- // paint locally equivalent backgrounds into it. https://crbug.com/645957
- if (HasClip())
- return kBackgroundPaintInGraphicsLayer;
-
// Inset box shadow is painted in the scrolling area above the background, and
// it doesn't scroll, so the background can only be painted in the main layer.
if (HasInsetBoxShadow(StyleRef()))
@@ -245,8 +240,8 @@ void LayoutBoxModelObject::StyleWillChange(StyleDifference diff,
// invalidate the current compositing container chain which may have painted
// cached subsequences containing this object or descendant objects.
if (Style() &&
- (StyleRef().IsStacked() != new_style.IsStacked() ||
- StyleRef().IsStackingContext() != new_style.IsStackingContext()) &&
+ (IsStacked() != IsStacked(new_style) ||
+ IsStackingContext() != IsStackingContext(new_style)) &&
// ObjectPaintInvalidator requires this.
IsRooted()) {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
@@ -599,7 +594,7 @@ void LayoutBoxModelObject::AddOutlineRectsForDescendant(
Vector<PhysicalRect>& rects,
const PhysicalOffset& additional_offset,
NGOutlineType include_block_overflows) const {
- if (descendant.IsText() || descendant.IsListMarker())
+ if (descendant.IsText() || descendant.IsListMarkerForNormalContent())
return;
if (descendant.HasLayer()) {
@@ -755,6 +750,12 @@ bool LayoutBoxModelObject::HasAutoHeightOrContainingBlockWithAutoHeight(
this_box->HasOverrideContainingBlockContentLogicalHeight()) {
return this_box->OverrideContainingBlockContentLogicalHeight() ==
LayoutUnit(-1);
+ } else if (this_box && this_box->GetCachedLayoutResult() &&
+ !this_box->GetBoxLayoutExtraInput()) {
+ return this_box->GetCachedLayoutResult()
+ ->GetConstraintSpaceForCaching()
+ .AvailableSize()
+ .block_size == LayoutUnit(-1);
}
return !cb->HasDefiniteLogicalHeight();
}
@@ -765,7 +766,7 @@ bool LayoutBoxModelObject::HasAutoHeightOrContainingBlockWithAutoHeight(
PhysicalOffset LayoutBoxModelObject::RelativePositionOffset() const {
DCHECK(IsRelPositioned());
- PhysicalOffset offset = AccumulateInFlowPositionOffsets();
+ PhysicalOffset offset = AccumulateRelativePositionOffsets();
LayoutBlock* containing_block = ContainingBlock();
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_box_model_object.h b/chromium/third_party/blink/renderer/core/layout/layout_box_model_object.h
index 2e33f628434..15236cff8dc 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_box_model_object.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_box_model_object.h
@@ -416,6 +416,9 @@ class CORE_EXPORT LayoutBoxModelObject : public LayoutObject {
virtual bool BackgroundIsKnownToBeOpaqueInRect(const PhysicalRect&) const {
return false;
}
+ // Returns true if all text in the paint-order subtree will be painted on
+ // opaque background.
+ virtual bool TextIsKnownToBeOnOpaqueBackground() const { return false; }
// This object's background is transferred to its LayoutView if:
// 1. it's the document element, or
@@ -470,7 +473,7 @@ class CORE_EXPORT LayoutBoxModelObject : public LayoutObject {
// See continuation above for more details.
void SetContinuation(LayoutBoxModelObject*);
- virtual PhysicalOffset AccumulateInFlowPositionOffsets() const {
+ virtual PhysicalOffset AccumulateRelativePositionOffsets() const {
return PhysicalOffset();
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_box_model_object_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_box_model_object_test.cc
index a34bab16c6e..5bfeb9b92a9 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_box_model_object_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_box_model_object_test.cc
@@ -1070,16 +1070,16 @@ TEST_F(LayoutBoxModelObjectTest, InvalidatePaintLayerOnStackedChange) {
auto* parent = target->Parent();
auto* original_compositing_container =
target->Layer()->CompositingContainer();
- EXPECT_FALSE(target->StyleRef().IsStackingContext());
- EXPECT_TRUE(target->StyleRef().IsStacked());
- EXPECT_FALSE(parent->StyleRef().IsStacked());
+ EXPECT_FALSE(target->IsStackingContext());
+ EXPECT_TRUE(target->IsStacked());
+ EXPECT_FALSE(parent->IsStacked());
EXPECT_NE(parent, original_compositing_container->GetLayoutObject());
target_element->setAttribute(html_names::kClassAttr, "non-stacked");
GetDocument().View()->UpdateLifecycleToLayoutClean(
DocumentUpdateReason::kTest);
- EXPECT_FALSE(target->StyleRef().IsStacked());
+ EXPECT_FALSE(target->IsStacked());
EXPECT_TRUE(target->Layer()->SelfNeedsRepaint());
EXPECT_TRUE(original_compositing_container->DescendantNeedsRepaint());
auto* new_compositing_container = target->Layer()->CompositingContainer();
@@ -1090,7 +1090,7 @@ TEST_F(LayoutBoxModelObjectTest, InvalidatePaintLayerOnStackedChange) {
GetDocument().View()->UpdateLifecycleToLayoutClean(
DocumentUpdateReason::kTest);
- EXPECT_TRUE(target->StyleRef().IsStacked());
+ EXPECT_TRUE(target->IsStacked());
EXPECT_TRUE(target->Layer()->SelfNeedsRepaint());
EXPECT_TRUE(new_compositing_container->DescendantNeedsRepaint());
EXPECT_EQ(original_compositing_container,
@@ -1327,7 +1327,7 @@ TEST_F(LayoutBoxModelObjectTest, UpdateStackingContextForOption) {
auto* option_element = GetDocument().getElementById("opt");
auto* option_layout = option_element->GetLayoutObject();
ASSERT_TRUE(option_layout);
- EXPECT_TRUE(option_layout->StyleRef().IsStackingContext());
+ EXPECT_TRUE(option_layout->IsStackingContext());
EXPECT_TRUE(option_layout->StyleRef().HasCurrentOpacityAnimation());
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_box_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_box_test.cc
index 99bcb9ca795..91b31b8f6f9 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_box_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_box_test.cc
@@ -1436,4 +1436,31 @@ TEST_P(LayoutBoxTest, HasNonCollapsedBorderDecoration) {
EXPECT_TRUE(div->HasNonCollapsedBorderDecoration());
}
+TEST_P(LayoutBoxTest,
+ ThickScrollbarSubpixelSizeMarginNoDirtyLayoutAfterLayout) {
+ // |target| creates horizontal scrollbar during layout because the contents
+ // overflow horizontally, which causes vertical overflow because the
+ // horizontal scrollbar reduces available height. For now we suppress
+ // creation of the vertical scrollbar because otherwise we would need another
+ // layout. The subpixel margin and size cause change of pixel snapped border
+ // size after layout which requires repositioning of the overflow controls.
+ // This test ensures there is no left-over dirty layout.
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ ::-webkit-scrollbar {
+ width: 100px;
+ height: 100px;
+ background: blue;
+ }
+ </style>
+ <div id="target"
+ style="width: 150.3px; height: 150.3px; margin: 10.4px;
+ font-size: 30px; overflow: auto">
+ <div style="width: 200px; height: 80px"></div>
+ </div>
+ )HTML");
+
+ DCHECK(!GetLayoutObjectByElementId("target")->NeedsLayout());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_counter.cc b/chromium/third_party/blink/renderer/core/layout/layout_counter.cc
index d3a3e1359e0..07e09e99039 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_counter.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_counter.cc
@@ -43,15 +43,16 @@
namespace blink {
-typedef HashMap<AtomicString, scoped_refptr<CounterNode>> CounterMap;
typedef HashMap<const LayoutObject*, std::unique_ptr<CounterMap>> CounterMaps;
-static CounterNode* MakeCounterNodeIfNeeded(LayoutObject&,
- const AtomicString& identifier,
- bool always_create_counter);
+namespace {
+
+CounterNode* MakeCounterNodeIfNeeded(LayoutObject&,
+ const AtomicString& identifier,
+ bool always_create_counter);
// See class definition as to why we have this map.
-static CounterMaps& GetCounterMaps() {
+CounterMaps& GetCounterMaps() {
DEFINE_STATIC_LOCAL(CounterMaps, static_counter_maps, ());
return static_counter_maps;
}
@@ -67,15 +68,19 @@ Element* AncestorStyleContainmentObject(const Element& element) {
return nullptr;
}
+int ValueForText(CounterNode* node) {
+ return node->ActsAsReset() ? node->Value() : node->CountInParent();
+}
+
// This function processes the DOM tree including pseudo elements as defined in
// CSS 2.1. This method will always return either a previous element within the
// same contain: style scope or nullptr.
-static Element* PreviousInPreOrderRespectingContainment(
- const Element& element) {
+Element* PreviousInPreOrderRespectingContainment(const Element& element) {
Element* previous = ElementTraversal::PreviousIncludingPseudo(element);
Element* style_contain_ancestor = AncestorStyleContainmentObject(element);
while (true) {
+ // Find the candidate previous element.
while (previous && !previous->GetLayoutObject() &&
!previous->HasDisplayContentsStyle())
previous = ElementTraversal::PreviousIncludingPseudo(*previous);
@@ -83,18 +88,27 @@ static Element* PreviousInPreOrderRespectingContainment(
return nullptr;
Element* previous_style_contain_ancestor =
AncestorStyleContainmentObject(*previous);
+ // If the candidate's containment ancestor is the same as elements, then
+ // that's a valid candidate.
if (previous_style_contain_ancestor == style_contain_ancestor)
return previous;
+
+ // Otherwise, if previous does not have a containment ancestor, it means
+ // that we have already escaped `element`'s containment ancestor, so return
+ // nullptr.
if (!previous_style_contain_ancestor)
return nullptr;
+
+ // If, however, the candidate does have a containment ancestor, it could be
+ // that we entered a new sub-containment. Try again starting from the
+ // contain ancestor.
previous = previous_style_contain_ancestor;
}
}
// This function processes the DOM including pseudo elements as defined in
// CSS 2.1. This method avoids crossing contain: style boundaries.
-static Element* PreviousSiblingOrParentRespectingContainment(
- const Element& element) {
+Element* PreviousSiblingOrParentRespectingContainment(const Element& element) {
Element* previous = ElementTraversal::PseudoAwarePreviousSibling(element);
// Skip display:none elements.
while (previous && !previous->GetLayoutObject() &&
@@ -105,23 +119,22 @@ static Element* PreviousSiblingOrParentRespectingContainment(
previous = element.parentElement();
if (previous) {
if (const ComputedStyle* style = previous->GetComputedStyle()) {
- if (style->Contain() & kContainsStyle)
+ if (style->ContainsStyle())
return nullptr;
}
}
return previous;
}
-static inline bool AreElementsSiblings(const Element& first,
- const Element& second) {
+inline bool AreElementsSiblings(const Element& first, const Element& second) {
return first.parentElement() == second.parentElement();
}
// This function processes the the DOM tree including pseudo elements as defined
// in CSS 2.1.
-static LayoutObject* NextInPreOrder(const LayoutObject& object,
- const Element* stay_within,
- bool skip_descendants = false) {
+LayoutObject* NextInPreOrder(const LayoutObject& object,
+ const Element* stay_within,
+ bool skip_descendants = false) {
auto* self = To<Element>(object.GetNode());
DCHECK(self);
Element* next =
@@ -137,10 +150,10 @@ static LayoutObject* NextInPreOrder(const LayoutObject& object,
return next ? next->GetLayoutObject() : nullptr;
}
-static bool PlanCounter(LayoutObject& object,
- const AtomicString& identifier,
- bool& is_reset,
- int& value) {
+bool PlanCounter(LayoutObject& object,
+ const AtomicString& identifier,
+ unsigned& type_mask,
+ int& value) {
// Real text nodes don't have their own style so they can't have counters.
// We can't even look at their styles or we'll see extra resets and
// increments!
@@ -167,10 +180,13 @@ static bool PlanCounter(LayoutObject& object,
return false; // Counters are forbidden from all other pseudo elements.
}
+ type_mask = 0;
const CounterDirectives directives = style.GetCounterDirectives(identifier);
if (directives.IsDefined()) {
value = directives.CombinedValue();
- is_reset = directives.IsReset();
+ type_mask |= directives.IsIncrement() ? CounterNode::kIncrementType : 0;
+ type_mask |= directives.IsReset() ? CounterNode::kResetType : 0;
+ type_mask |= directives.IsSet() ? CounterNode::kSetType : 0;
return true;
}
@@ -179,22 +195,22 @@ static bool PlanCounter(LayoutObject& object,
if (ListItemOrdinal* ordinal = ListItemOrdinal::Get(*e)) {
if (const auto& explicit_value = ordinal->ExplicitValue()) {
value = explicit_value.value();
- is_reset = true;
+ type_mask = CounterNode::kResetType;
return true;
}
value = 1;
- is_reset = false;
+ type_mask = CounterNode::kIncrementType;
return true;
}
if (auto* olist = DynamicTo<HTMLOListElement>(*e)) {
value = olist->StartConsideringItemCount();
- is_reset = true;
+ type_mask = CounterNode::kResetType;
return true;
}
if (IsA<HTMLUListElement>(*e) || IsA<HTMLMenuElement>(*e) ||
IsA<HTMLDirectoryElement>(*e)) {
value = 0;
- is_reset = true;
+ type_mask = CounterNode::kResetType;
return true;
}
}
@@ -218,11 +234,11 @@ static bool PlanCounter(LayoutObject& object,
// references that are in the scope of the counter or nested counter defined
// by that reset node.
// - Non-reset CounterNodes cannot have descendants.
-static bool FindPlaceForCounter(LayoutObject& counter_owner,
- const AtomicString& identifier,
- bool is_reset,
- scoped_refptr<CounterNode>& parent,
- scoped_refptr<CounterNode>& previous_sibling) {
+bool FindPlaceForCounter(LayoutObject& counter_owner,
+ const AtomicString& identifier,
+ bool is_reset,
+ scoped_refptr<CounterNode>& parent,
+ scoped_refptr<CounterNode>& previous_sibling) {
// We cannot stop searching for counters with the same identifier before we
// also check this layout object, because it may affect the positioning in the
// tree of our counter.
@@ -364,13 +380,13 @@ static bool FindPlaceForCounter(LayoutObject& counter_owner,
return false;
}
-static inline Element* ParentElement(LayoutObject& object) {
+inline Element* ParentElement(LayoutObject& object) {
return To<Element>(object.GetNode())->parentElement();
}
-static CounterNode* MakeCounterNodeIfNeeded(LayoutObject& object,
- const AtomicString& identifier,
- bool always_create_counter) {
+CounterNode* MakeCounterNodeIfNeeded(LayoutObject& object,
+ const AtomicString& identifier,
+ bool always_create_counter) {
if (object.HasCounterNodeMap()) {
if (CounterMap* node_map = GetCounterMaps().at(&object)) {
if (CounterNode* node = node_map->at(identifier))
@@ -378,18 +394,18 @@ static CounterNode* MakeCounterNodeIfNeeded(LayoutObject& object,
}
}
- bool is_reset = false;
+ unsigned type_mask = 0;
int value = 0;
- if (!PlanCounter(object, identifier, is_reset, value) &&
+ if (!PlanCounter(object, identifier, type_mask, value) &&
!always_create_counter)
return nullptr;
scoped_refptr<CounterNode> new_parent = nullptr;
scoped_refptr<CounterNode> new_previous_sibling = nullptr;
scoped_refptr<CounterNode> new_node =
- CounterNode::Create(object, is_reset, value);
+ CounterNode::Create(object, type_mask, value);
- if (is_reset) {
+ if (type_mask & CounterNode::kResetType) {
// Find the place where we would've inserted the new node if it was a
// non-reset node. We have to move every non-reset sibling after the
// insertion point to a child of the new node.
@@ -407,7 +423,8 @@ static CounterNode* MakeCounterNodeIfNeeded(LayoutObject& object,
}
}
- if (FindPlaceForCounter(object, identifier, is_reset, new_parent,
+ if (FindPlaceForCounter(object, identifier,
+ type_mask & CounterNode::kResetType, new_parent,
new_previous_sibling))
new_parent->InsertAfter(new_node.get(), new_previous_sibling.get(),
identifier);
@@ -420,8 +437,13 @@ static CounterNode* MakeCounterNodeIfNeeded(LayoutObject& object,
object.SetHasCounterNodeMap(true);
}
node_map->Set(identifier, new_node);
- if (new_node->Parent())
+ // If the new node has a parent, that means any descendant would have been
+ // updated by `CounterNode::MoveNonResetSiblingsToChildOf()` above, so we
+ // don't need to update descendants. Likewise, if the object has style
+ // containment, any descendant should not become parented across the boundary.
+ if (new_node->Parent() || object.ShouldApplyStyleContainment())
return new_node.get();
+
// Checking if some nodes that were previously counter tree root nodes
// should become children of this node now.
CounterMaps& maps = GetCounterMaps();
@@ -432,13 +454,20 @@ static CounterNode* MakeCounterNodeIfNeeded(LayoutObject& object,
current_layout_object;
current_layout_object = NextInPreOrder(*current_layout_object,
stay_within, skip_descendants)) {
- skip_descendants = false;
+ // We'll update the current object and we might recurse into the
+ // descendants. However, if the object has style containment then we do not
+ // cross the boundary which begins right after the object. In other words we
+ // skip the descendants of this object.
+ skip_descendants = current_layout_object->ShouldApplyStyleContainment();
if (!current_layout_object->HasCounterNodeMap())
continue;
CounterNode* current_counter =
maps.at(current_layout_object)->at(identifier);
if (!current_counter)
continue;
+ // At this point we found a counter to reparent. So we don't need to descend
+ // into the layout tree further, since any further counters we find would be
+ // at most parented to `current_counter` we just found.
skip_descendants = true;
if (current_counter->Parent())
continue;
@@ -450,6 +479,8 @@ static CounterNode* MakeCounterNodeIfNeeded(LayoutObject& object,
return new_node.get();
}
+} // namespace
+
LayoutCounter::LayoutCounter(PseudoElement& pseudo,
const CounterContent& counter)
: LayoutText(nullptr, StringImpl::empty_),
@@ -473,8 +504,18 @@ void LayoutCounter::WillBeDestroyed() {
}
scoped_refptr<StringImpl> LayoutCounter::OriginalText() const {
- if (!counter_node_) {
- LayoutObject* container = Parent();
+ // Child will be the base of our text that we report. First, we need to find
+ // an appropriate child.
+ CounterNode* child = nullptr;
+
+ // Find a container on which to create the counter if one needs creating.
+ LayoutObject* container = Parent();
+ bool should_create_counter = counter_.Separator().IsNull();
+ // Optimization: the only reason we need a proper container is if we might not
+ // need to create a counter (in which case, we navigate container's
+ // ancestors), or if we don't have a counter_node_ (in which case we need to
+ // find the container to place the counter on).
+ if (!should_create_counter || !counter_node_) {
while (true) {
if (!container)
return nullptr;
@@ -488,23 +529,74 @@ scoped_refptr<StringImpl> LayoutCounter::OriginalText() const {
break;
container = container->Parent();
}
- MakeCounterNodeIfNeeded(*container, counter_.Identifier(), true)
- ->AddLayoutObject(const_cast<LayoutCounter*>(this));
- DCHECK(counter_node_);
}
- CounterNode* child = counter_node_;
- int value = child->ActsAsReset() ? child->Value() : child->CountInParent();
- String text = list_marker_text::GetText(counter_.ListStyle(), value);
+ // Now that we have a container, check if the counter directives are
+ // defined between us and the first style containment element, meaning that
+ // the counter would be created for our scope even if there is no content
+ // request. If not, and if the separator is not null, meaning the request was
+ // for something like counters(n, "."), then we first have to check our
+ // ancestors across the style containment boundary. If the ancestors have the
+ // value for our identifier, then we don't need a counter here and it is
+ // instead omitted. See counter-scoping-001.html WPT and crbug.com/882383#c11
+ // for more context.
+ if (!should_create_counter) {
+ for (auto* scope_ancestor = container; scope_ancestor;
+ scope_ancestor = scope_ancestor->Parent()) {
+ auto& style = scope_ancestor->StyleRef();
+ if (style.ContainsStyle())
+ break;
+ const CounterDirectives directives =
+ style.GetCounterDirectives(counter_.Identifier());
+ if (directives.IsDefined()) {
+ should_create_counter = true;
+ break;
+ }
+ }
+ }
+ if (!should_create_counter) {
+ // If we have an ancestor across the the containment boundary, then use it
+ // as the child, without needing to create a counter on `this`. If we don't
+ // have such an ancestor, we need to create a `counter_node_` on `this`.
+ if (auto* node = CounterNode::AncestorNodeAcrossStyleContainment(
+ *this, counter_.Identifier())) {
+ child = node;
+ } else {
+ should_create_counter = true;
+ }
+ }
+
+ if (should_create_counter) {
+ if (!counter_node_) {
+ MakeCounterNodeIfNeeded(*container, counter_.Identifier(), true)
+ ->AddLayoutObject(const_cast<LayoutCounter*>(this));
+ DCHECK(counter_node_);
+ }
+ child = counter_node_;
+ }
+
+ // In all cases we should end up with a `child` which is the base of our
+ // navigation.
+ DCHECK(child);
+
+ int value = ValueForText(child);
+ String text = list_marker_text::GetText(counter_.ListStyle(), value);
+ // If the separator exists, we need to append all of the parent values as well,
+ // including the ones that cross the style containment boundary.
if (!counter_.Separator().IsNull()) {
if (!child->ActsAsReset())
- child = child->Parent();
- while (CounterNode* parent = child->Parent()) {
+ child = child->ParentCrossingStyleContainment(counter_.Identifier());
+ bool next_result_uses_parent_value = !child->Parent();
+ while (CounterNode* parent =
+ child->ParentCrossingStyleContainment(counter_.Identifier())) {
text = list_marker_text::GetText(counter_.ListStyle(),
- child->CountInParent()) +
+ next_result_uses_parent_value
+ ? ValueForText(parent)
+ : child->CountInParent()) +
counter_.Separator() + text;
child = parent;
+ next_result_uses_parent_value = !child->Parent();
}
}
@@ -637,6 +729,8 @@ static void UpdateCounters(LayoutObject& layout_object) {
void LayoutCounter::LayoutObjectSubtreeAttached(LayoutObject* layout_object) {
DCHECK(layout_object->View());
+ // Only update counters if we have LayoutCounter which is created when we have
+ // a content: field with a counter requirement.
if (!layout_object->View()->HasLayoutCounters())
return;
Node* node = layout_object->GetNode();
@@ -646,9 +740,21 @@ void LayoutCounter::LayoutObjectSubtreeAttached(LayoutObject* layout_object) {
node = layout_object->GeneratingNode();
if (node && node->NeedsReattachLayoutTree())
return; // No need to update if the parent is not attached yet
+
+ // Update the descendants.
for (LayoutObject* descendant = layout_object; descendant;
descendant = descendant->NextInPreOrder(layout_object))
UpdateCounters(*descendant);
+
+ bool crossed_boundary = false;
+ // Since we skipped counter updates if there were no counters, we might need
+ // to update parent counters that lie beyond the style containment boundary.
+ for (LayoutObject* parent = layout_object->Parent(); parent;
+ parent = parent->Parent()) {
+ crossed_boundary |= parent->ShouldApplyStyleContainment();
+ if (crossed_boundary)
+ UpdateCounters(*parent);
+ }
}
void LayoutCounter::LayoutObjectStyleChanged(LayoutObject& layout_object,
@@ -713,12 +819,19 @@ void LayoutCounter::LayoutObjectStyleChanged(LayoutObject& layout_object,
}
}
+// static
+CounterMap* LayoutCounter::GetCounterMap(LayoutObject* object) {
+ if (object->HasCounterNodeMap())
+ return GetCounterMaps().at(object);
+ return nullptr;
+}
+
} // namespace blink
#if DCHECK_IS_ON()
-void showCounterLayoutObjectTree(const blink::LayoutObject* layout_object,
- const char* counter_name) {
+void showCounterLayoutTree(const blink::LayoutObject* layout_object,
+ const char* counter_name) {
if (!layout_object)
return;
const blink::LayoutObject* root = layout_object;
@@ -732,15 +845,19 @@ void showCounterLayoutObjectTree(const blink::LayoutObject* layout_object,
for (const blink::LayoutObject* parent = current; parent && parent != root;
parent = parent->Parent())
fprintf(stderr, " ");
- fprintf(
- stderr, "%p N:%p P:%p PS:%p NS:%p C:%p\n", current, current->GetNode(),
- current->Parent(), current->PreviousSibling(), current->NextSibling(),
- current->HasCounterNodeMap()
- ? counter_name ? blink::GetCounterMaps().at(current)->at(identifier)
- : (blink::CounterNode*)1
- : (blink::CounterNode*)nullptr);
+ fprintf(stderr, "%p %s", current, current->DebugName().Utf8().c_str());
+ auto* counter_node =
+ current->HasCounterNodeMap() && current
+ ? blink::GetCounterMaps().at(current)->at(identifier)
+ : nullptr;
+ if (counter_node) {
+ fprintf(stderr, " counter:%p parent:%p value:%d countInParent:%d\n",
+ counter_node, counter_node->Parent(), counter_node->Value(),
+ counter_node->CountInParent());
+ } else {
+ fprintf(stderr, "\n");
+ }
}
- fflush(stderr);
}
#endif // DCHECK_IS_ON()
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_counter.h b/chromium/third_party/blink/renderer/core/layout/layout_counter.h
index 6766dae45fe..41f35c77b7a 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_counter.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_counter.h
@@ -30,6 +30,8 @@ namespace blink {
class CounterNode;
class PseudoElement;
+using CounterMap = HashMap<AtomicString, scoped_refptr<CounterNode>>;
+
// LayoutCounter is used to represent the text of a counter.
// See http://www.w3.org/TR/CSS21/generate.html#counters
//
@@ -65,6 +67,8 @@ class LayoutCounter final : public LayoutText {
const ComputedStyle* old_style,
const ComputedStyle& new_style);
+ static CounterMap* GetCounterMap(LayoutObject*);
+
void UpdateCounter();
const char* GetName() const override { return "LayoutCounter"; }
@@ -95,8 +99,7 @@ DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutCounter, IsCounter());
#if DCHECK_IS_ON()
// Outside the blink namespace for ease of invocation from gdb.
-void showCounterLayoutTree(const blink::LayoutObject*,
- const char* counterName = nullptr);
+void showCounterLayoutTree(const blink::LayoutObject*, const char* counterName);
#endif
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_COUNTER_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.cc b/chromium/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.cc
index 2b76e6100ae..c1717f47d23 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.cc
@@ -39,7 +39,7 @@ LayoutCustomScrollbarPart::LayoutCustomScrollbarPart(
ScrollableArea* scrollable_area,
CustomScrollbar* scrollbar,
ScrollbarPart part)
- : LayoutBlock(nullptr),
+ : LayoutReplaced(nullptr, LayoutSize()),
scrollable_area_(scrollable_area),
scrollbar_(scrollbar),
part_(part) {
@@ -91,148 +91,102 @@ LayoutCustomScrollbarPart* LayoutCustomScrollbarPart::CreateAnonymous(
return layout_object;
}
-void LayoutCustomScrollbarPart::UpdateLayout() {
- // We don't worry about positioning ourselves. We're just determining our
- // minimum width/height.
- SetLocation(LayoutPoint());
- if (scrollbar_->Orientation() == kHorizontalScrollbar)
- LayoutHorizontalPart();
- else
- LayoutVerticalPart();
-
- ClearNeedsLayout();
+// TODO(crbug.com/1020913): Support subpixel layout of scrollbars and remove
+// ToInt() in the following functions.
+static int ComputeSize(SizeType size_type,
+ const Length& length,
+ int container_size) {
+ if (!length.IsIntrinsicOrAuto() || (size_type == kMinSize && length.IsAuto()))
+ return MinimumValueForLength(length, LayoutUnit(container_size)).ToInt();
+ return CustomScrollbarTheme::GetCustomScrollbarTheme()->ScrollbarThickness();
}
-void LayoutCustomScrollbarPart::LayoutHorizontalPart() {
- if (part_ == kScrollbarBGPart) {
- SetWidth(LayoutUnit(scrollbar_->Width()));
- UpdateScrollbarHeight();
- } else {
- UpdateScrollbarWidth();
- SetHeight(LayoutUnit(scrollbar_->Height()));
- }
-}
+static int ComputeWidth(int container_width, const ComputedStyle& style) {
+ if (style.Display() == EDisplay::kNone)
+ return 0;
-void LayoutCustomScrollbarPart::LayoutVerticalPart() {
- if (part_ == kScrollbarBGPart) {
- UpdateScrollbarWidth();
- SetHeight(LayoutUnit(scrollbar_->Height()));
- } else {
- SetWidth(LayoutUnit(scrollbar_->Width()));
- UpdateScrollbarHeight();
- }
+ int w = ComputeSize(kMainOrPreferredSize, style.Width(), container_width);
+ int min_width = ComputeSize(kMinSize, style.MinWidth(), container_width);
+ int max_width = w;
+ if (!style.MaxWidth().IsNone())
+ max_width = ComputeSize(kMaxSize, style.MaxWidth(), container_width);
+ return std::max(min_width, std::min(max_width, w));
}
-static int CalcScrollbarThicknessUsing(SizeType size_type,
- const Length& length,
- int containing_length,
- ScrollbarTheme* theme) {
- if (!length.IsIntrinsicOrAuto() || (size_type == kMinSize && length.IsAuto()))
- return MinimumValueForLength(length, LayoutUnit(containing_length)).ToInt();
- return theme->ScrollbarThickness();
+static int ComputeHeight(int container_height, const ComputedStyle& style) {
+ if (style.Display() == EDisplay::kNone)
+ return 0;
+
+ int h = ComputeSize(kMainOrPreferredSize, style.Height(), container_height);
+ int min_height = ComputeSize(kMinSize, style.MinHeight(), container_height);
+ int max_height = h;
+ if (!style.MaxHeight().IsNone())
+ max_height = ComputeSize(kMaxSize, style.MaxHeight(), container_height);
+ return std::max(min_height, std::min(max_height, h));
}
-int LayoutCustomScrollbarPart::ComputeScrollbarWidth(
- int visible_size,
- const ComputedStyle* style) {
- CustomScrollbarTheme* theme = CustomScrollbarTheme::GetCustomScrollbarTheme();
- int w = CalcScrollbarThicknessUsing(kMainOrPreferredSize, style->Width(),
- visible_size, theme);
- int min_width = CalcScrollbarThicknessUsing(kMinSize, style->MinWidth(),
- visible_size, theme);
- int max_width = w;
- if (!style->MaxWidth().IsNone()) {
- max_width = CalcScrollbarThicknessUsing(kMaxSize, style->MaxWidth(),
- visible_size, theme);
- }
+int LayoutCustomScrollbarPart::ComputeThickness() const {
+ DCHECK_EQ(kScrollbarBGPart, part_);
- return std::max(min_width, std::min(max_width, w));
+ // Use 0 for container width/height, so percentage size will be ignored.
+ // We have never supported that.
+ if (scrollbar_->Orientation() == kHorizontalScrollbar)
+ return ComputeHeight(0, StyleRef());
+ return ComputeWidth(0, StyleRef());
}
-int LayoutCustomScrollbarPart::ComputeScrollbarHeight(
- int visible_size,
- const ComputedStyle* style) {
- CustomScrollbarTheme* theme = CustomScrollbarTheme::GetCustomScrollbarTheme();
- int h = CalcScrollbarThicknessUsing(kMainOrPreferredSize, style->Height(),
- visible_size, theme);
- int min_height = CalcScrollbarThicknessUsing(kMinSize, style->MinHeight(),
- visible_size, theme);
- int max_height = h;
- if (!style->MaxHeight().IsNone()) {
- max_height = CalcScrollbarThicknessUsing(kMaxSize, style->MaxHeight(),
- visible_size, theme);
- }
- return std::max(min_height, std::min(max_height, h));
+int LayoutCustomScrollbarPart::ComputeLength() const {
+ DCHECK_NE(kScrollbarBGPart, part_);
+
+ IntRect visible_content_rect =
+ scrollbar_->GetScrollableArea()->VisibleContentRect(kIncludeScrollbars);
+ if (scrollbar_->Orientation() == kHorizontalScrollbar)
+ return ComputeWidth(visible_content_rect.Width(), StyleRef());
+ return ComputeHeight(visible_content_rect.Height(), StyleRef());
}
-void LayoutCustomScrollbarPart::UpdateScrollbarWidth() {
- LayoutBox* box = scrollbar_->GetScrollableArea()->GetLayoutBox();
- if (!box)
- return;
- // FIXME: We are querying layout information but nothing guarantees that it's
- // up to date, especially since we are called at style change.
- // FIXME: Querying the style's border information doesn't work on table cells
- // with collapsing borders.
- int visible_size = box->Size().Width() - box->StyleRef().BorderLeftWidth() -
- box->StyleRef().BorderRightWidth();
- SetWidth(LayoutUnit(ComputeScrollbarWidth(visible_size, Style())));
+static LayoutUnit ComputeMargin(const Length& style_margin) {
+ // TODO(crbug.com/1020913): Support subpixel layout of scrollbars and remove
+ // Round() below.
+ return LayoutUnit(MinimumValueForLength(style_margin, LayoutUnit()).Round());
+}
- // Buttons and track pieces can all have margins along the axis of the
- // scrollbar. Values are rounded because scrollbar parts need to be rendered
- // at device pixel boundaries.
- SetMarginLeft(LayoutUnit(
- MinimumValueForLength(StyleRef().MarginLeft(), LayoutUnit(visible_size))
- .Round()));
- SetMarginRight(LayoutUnit(
- MinimumValueForLength(StyleRef().MarginRight(), LayoutUnit(visible_size))
- .Round()));
+LayoutUnit LayoutCustomScrollbarPart::MarginTop() const {
+ if (scrollbar_->Orientation() == kHorizontalScrollbar)
+ return LayoutUnit();
+ return ComputeMargin(StyleRef().MarginTop());
}
-void LayoutCustomScrollbarPart::UpdateScrollbarHeight() {
- LayoutBox* box = scrollbar_->GetScrollableArea()->GetLayoutBox();
- if (!box)
- return;
- // FIXME: We are querying layout information but nothing guarantees that it's
- // up to date, especially since we are called at style change.
- // FIXME: Querying the style's border information doesn't work on table cells
- // with collapsing borders.
- int visible_size = box->Size().Height() - box->StyleRef().BorderTopWidth() -
- box->StyleRef().BorderBottomWidth();
- SetHeight(LayoutUnit(ComputeScrollbarHeight(visible_size, Style())));
+LayoutUnit LayoutCustomScrollbarPart::MarginBottom() const {
+ if (scrollbar_->Orientation() == kHorizontalScrollbar)
+ return LayoutUnit();
+ return ComputeMargin(StyleRef().MarginBottom());
+}
- // Buttons and track pieces can all have margins along the axis of the
- // scrollbar. Values are rounded because scrollbar parts need to be rendered
- // at device pixel boundaries.
- SetMarginTop(LayoutUnit(
- MinimumValueForLength(StyleRef().MarginTop(), LayoutUnit(visible_size))
- .Round()));
- SetMarginBottom(LayoutUnit(
- MinimumValueForLength(StyleRef().MarginBottom(), LayoutUnit(visible_size))
- .Round()));
+LayoutUnit LayoutCustomScrollbarPart::MarginLeft() const {
+ if (scrollbar_->Orientation() == kVerticalScrollbar)
+ return LayoutUnit();
+ return ComputeMargin(StyleRef().MarginLeft());
}
-MinMaxSizes LayoutCustomScrollbarPart::PreferredLogicalWidths() const {
- return MinMaxSizes();
+LayoutUnit LayoutCustomScrollbarPart::MarginRight() const {
+ if (scrollbar_->Orientation() == kVerticalScrollbar)
+ return LayoutUnit();
+ return ComputeMargin(StyleRef().MarginRight());
}
-void LayoutCustomScrollbarPart::StyleWillChange(
- StyleDifference diff,
- const ComputedStyle& new_style) {
- LayoutBlock::StyleWillChange(diff, new_style);
+void LayoutCustomScrollbarPart::UpdateFromStyle() {
+ LayoutReplaced::UpdateFromStyle();
SetInline(false);
+ ClearPositionedState();
+ SetFloating(false);
}
void LayoutCustomScrollbarPart::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
- LayoutBlock::StyleDidChange(diff, old_style);
- // See adjustStyleBeforeSet() above.
- DCHECK(!IsOrthogonalWritingModeRoot());
- SetInline(false);
- ClearPositionedState();
- SetFloating(false);
+ LayoutReplaced::StyleDidChange(diff, old_style);
if (old_style && (diff.NeedsPaintInvalidation() || diff.NeedsLayout()))
SetNeedsPaintInvalidation();
-
RecordPercentLengthStats();
}
@@ -250,11 +204,11 @@ void LayoutCustomScrollbarPart::RecordPercentLengthStats() const {
// "==" below tests both direct percent length and percent used in calculated
// length.
if (scrollbar_->Orientation() == width_orientation) {
- if (ComputeScrollbarWidth(0, Style()) ==
- ComputeScrollbarWidth(LayoutUnit::NearlyMax().ToInt(), Style()))
+ if (ComputeWidth(0, StyleRef()) ==
+ ComputeWidth(LayoutUnit::NearlyMax().ToInt(), StyleRef()))
return;
- } else if (ComputeScrollbarHeight(0, Style()) ==
- ComputeScrollbarHeight(LayoutUnit::NearlyMax().ToInt(), Style())) {
+ } else if (ComputeHeight(0, StyleRef()) ==
+ ComputeHeight(LayoutUnit::NearlyMax().ToInt(), StyleRef())) {
return;
}
@@ -264,7 +218,7 @@ void LayoutCustomScrollbarPart::RecordPercentLengthStats() const {
void LayoutCustomScrollbarPart::ImageChanged(WrappedImagePtr image,
CanDeferInvalidation defer) {
SetNeedsPaintInvalidation();
- LayoutBlock::ImageChanged(image, defer);
+ LayoutReplaced::ImageChanged(image, defer);
}
void LayoutCustomScrollbarPart::SetNeedsPaintInvalidation() {
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.h b/chromium/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.h
index 0832faddd20..9795e0f0b19 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.h
@@ -26,7 +26,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_CUSTOM_SCROLLBAR_PART_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_CUSTOM_SCROLLBAR_PART_H_
-#include "third_party/blink/renderer/core/layout/layout_block.h"
+#include "third_party/blink/renderer/core/layout/layout_replaced.h"
#include "third_party/blink/renderer/core/scroll/scroll_types.h"
namespace blink {
@@ -34,7 +34,7 @@ namespace blink {
class CustomScrollbar;
class ScrollableArea;
-class LayoutCustomScrollbarPart final : public LayoutBlock {
+class CORE_EXPORT LayoutCustomScrollbarPart final : public LayoutReplaced {
public:
static LayoutCustomScrollbarPart* CreateAnonymous(Document*,
ScrollableArea*,
@@ -45,45 +45,46 @@ class LayoutCustomScrollbarPart final : public LayoutBlock {
PaintLayerType LayerTypeRequired() const override { return kNoPaintLayer; }
- void UpdateLayout() override;
+ // Computes thickness of the scrollbar (which defines thickness of all parts).
+ // For kScrollbarBGPart only. This can be called during style update.
+ // Percentage size will be ignored.
+ int ComputeThickness() const;
- static int ComputeScrollbarWidth(int visible_size, const ComputedStyle*);
- static int ComputeScrollbarHeight(int visible_size, const ComputedStyle*);
+ // Computes size of the part in the direction of the scrollbar orientation.
+ // This doesn't apply to kScrollbarBGPart because its length is not determined
+ // by the style of the part of itself. For kThumbPart this returns the
+ // minimum length of the thumb. The length may depend on the size of the
+ // containing box, so this function can only be called after the size is
+ // available.
+ int ComputeLength() const;
- // Scrollbar parts needs to be rendered at device pixel boundaries.
- LayoutUnit MarginTop() const override {
- DCHECK(IsIntegerValue(LayoutBlock::MarginTop()));
- return LayoutBlock::MarginTop();
- }
- LayoutUnit MarginBottom() const override {
- DCHECK(IsIntegerValue(LayoutBlock::MarginBottom()));
- return LayoutBlock::MarginBottom();
- }
- LayoutUnit MarginLeft() const override {
- DCHECK(IsIntegerValue(LayoutBlock::MarginLeft()));
- return LayoutBlock::MarginLeft();
- }
- LayoutUnit MarginRight() const override {
- DCHECK(IsIntegerValue(LayoutBlock::MarginRight()));
- return LayoutBlock::MarginRight();
- }
+ LayoutUnit MarginTop() const override;
+ LayoutUnit MarginBottom() const override;
+ LayoutUnit MarginLeft() const override;
+ LayoutUnit MarginRight() const override;
bool IsOfType(LayoutObjectType type) const override {
return type == kLayoutObjectLayoutCustomScrollbarPart ||
- LayoutBlock::IsOfType(type);
+ LayoutReplaced::IsOfType(type);
}
ScrollableArea* GetScrollableArea() const { return scrollable_area_; }
- protected:
- void StyleWillChange(StyleDifference,
- const ComputedStyle& new_style) override;
+ private:
+ LayoutCustomScrollbarPart(ScrollableArea*, CustomScrollbar*, ScrollbarPart);
+
+ void UpdateFromStyle() override;
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
void ImageChanged(WrappedImagePtr, CanDeferInvalidation) override;
- private:
- LayoutCustomScrollbarPart(ScrollableArea*, CustomScrollbar*, ScrollbarPart);
+ // A scrollbar part's Location() and PhysicalLocation() are relative to the
+ // scrollbar (instead of relative to any LayoutBox ancestor), and both are
+ // in physical coordinates.
+ LayoutBox* LocationContainer() const override { return nullptr; }
- MinMaxSizes PreferredLogicalWidths() const override;
+ // A scrollbar part is not in the layout tree and is not laid out like other
+ // layout objects. CustomScrollbar will call scrollbar parts' SetFrameRect()
+ // from its SetFrameRect() when needed.
+ void UpdateLayout() override { NOTREACHED(); }
// Have all padding getters return 0. The important point here is to avoid
// resolving percents against the containing block, since scroll bar corners
@@ -95,20 +96,13 @@ class LayoutCustomScrollbarPart final : public LayoutBlock {
LayoutUnit PaddingLeft() const override { return LayoutUnit(); }
LayoutUnit PaddingRight() const override { return LayoutUnit(); }
- void LayoutHorizontalPart();
- void LayoutVerticalPart();
-
- void UpdateScrollbarWidth();
- void UpdateScrollbarHeight();
-
void SetNeedsPaintInvalidation();
- bool AllowsOverflowClip() const override { return false; }
-
void RecordPercentLengthStats() const;
UntracedMember<ScrollableArea> scrollable_area_;
UntracedMember<CustomScrollbar> scrollbar_;
+
ScrollbarPart part_;
};
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_embedded_content.cc b/chromium/third_party/blink/renderer/core/layout/layout_embedded_content.cc
index 41b92eaa2eb..20d3666cc78 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_embedded_content.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_embedded_content.cc
@@ -92,6 +92,14 @@ FrameView* LayoutEmbeddedContent::ChildFrameView() const {
return DynamicTo<FrameView>(GetEmbeddedContentView());
}
+LayoutView* LayoutEmbeddedContent::ChildLayoutView() const {
+ if (HTMLFrameOwnerElement* owner_element = GetFrameOwnerElement()) {
+ if (Document* content_document = owner_element->contentDocument())
+ return content_document->GetLayoutView();
+ }
+ return nullptr;
+}
+
WebPluginContainerImpl* LayoutEmbeddedContent::Plugin() const {
EmbeddedContentView* embedded_content_view = GetEmbeddedContentView();
if (embedded_content_view && embedded_content_view->IsPluginView())
@@ -106,44 +114,30 @@ EmbeddedContentView* LayoutEmbeddedContent::GetEmbeddedContentView() const {
}
PaintLayerType LayoutEmbeddedContent::LayerTypeRequired() const {
- if (RequiresAcceleratedCompositing())
+ if (AdditionalCompositingReasons())
return kNormalPaintLayer;
PaintLayerType type = LayoutReplaced::LayerTypeRequired();
if (type != kNoPaintLayer)
return type;
- return kForcedPaintLayer;
-}
-bool LayoutEmbeddedContent::RequiresAcceleratedCompositing() const {
- // There are two general cases in which we can return true. First, if this is
- // a plugin LayoutObject and the plugin has a layer, then we need a layer.
- // Second, if this is a LayoutObject with a contentDocument and that document
- // needs a layer, then we need a layer.
- WebPluginContainerImpl* plugin_view = Plugin();
- if (plugin_view && plugin_view->CcLayer())
- return true;
-
- auto* element = GetFrameOwnerElement();
- if (!element)
- return false;
-
- if (Frame* content_frame = element->ContentFrame()) {
- if (content_frame->IsRemoteFrame())
- return true;
- if (base::FeatureList::IsEnabled(
- blink::features::kCompositeCrossOriginIframes) &&
- content_frame->IsCrossOriginToParentFrame()) {
- return true;
+ // We can't check layout_view->Layer()->GetCompositingReasons() here because
+ // we're only in style update, so haven't run compositing update yet.
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ if (LayoutView* child_layout_view = ChildLayoutView()) {
+ if (child_layout_view->AdditionalCompositingReasons())
+ return kNormalPaintLayer;
}
}
- if (Document* content_document = element->contentDocument()) {
- auto* layout_view = content_document->GetLayoutView();
- if (layout_view)
- return layout_view->UsesCompositing();
- }
+ return kForcedPaintLayer;
+}
+bool LayoutEmbeddedContent::ContentDocumentIsCompositing() const {
+ if (PaintLayerCompositor* inner_compositor =
+ PaintLayerCompositor::FrameContentsCompositor(*this)) {
+ return inner_compositor->StaleInCompositingMode();
+ }
return false;
}
@@ -253,8 +247,15 @@ bool LayoutEmbeddedContent::NodeAtPoint(
}
CompositingReasons LayoutEmbeddedContent::AdditionalCompositingReasons() const {
- if (RequiresAcceleratedCompositing())
- return CompositingReason::kIFrame;
+ WebPluginContainerImpl* plugin_view = Plugin();
+ if (plugin_view && plugin_view->CcLayer())
+ return CompositingReason::kPlugin;
+ if (auto* element = GetFrameOwnerElement()) {
+ if (Frame* content_frame = element->ContentFrame()) {
+ if (content_frame->IsRemoteFrame())
+ return CompositingReason::kIFrame;
+ }
+ }
return CompositingReason::kNone;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_embedded_content.h b/chromium/third_party/blink/renderer/core/layout/layout_embedded_content.h
index ce5d1ef6a97..223f1a6d66e 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_embedded_content.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_embedded_content.h
@@ -44,7 +44,7 @@ class CORE_EXPORT LayoutEmbeddedContent : public LayoutReplaced {
explicit LayoutEmbeddedContent(HTMLFrameOwnerElement*);
~LayoutEmbeddedContent() override;
- bool RequiresAcceleratedCompositing() const;
+ bool ContentDocumentIsCompositing() const;
bool NodeAtPoint(HitTestResult&,
const HitTestLocation&,
@@ -59,6 +59,7 @@ class CORE_EXPORT LayoutEmbeddedContent : public LayoutReplaced {
// to LayoutObject::GetFrameView which returns the LocalFrameView associated
// with the root Document Frame.
FrameView* ChildFrameView() const;
+ LayoutView* ChildLayoutView() const;
WebPluginContainerImpl* Plugin() const;
EmbeddedContentView* GetEmbeddedContentView() const;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.cc b/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.cc
index dc65bd18f88..913e46224b8 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.cc
@@ -107,12 +107,6 @@ void LayoutEmbeddedObject::UpdateLayout() {
ClearNeedsLayout();
}
-CompositingReasons LayoutEmbeddedObject::AdditionalCompositingReasons() const {
- if (RequiresAcceleratedCompositing())
- return CompositingReason::kPlugin;
- return CompositingReason::kNone;
-}
-
void LayoutEmbeddedObject::ComputeIntrinsicSizingInfo(
IntrinsicSizingInfo& intrinsic_sizing_info) const {
DCHECK(!ShouldApplySizeContainment());
@@ -122,6 +116,13 @@ void LayoutEmbeddedObject::ComputeIntrinsicSizingInfo(
// doesn't know about them.
intrinsic_sizing_info.size.Scale(StyleRef().EffectiveZoom());
+ // Handle an overridden aspect ratio
+ if (const base::Optional<IntSize>& aspect_ratio =
+ StyleRef().AspectRatio()) {
+ intrinsic_sizing_info.aspect_ratio.SetWidth(aspect_ratio->Width());
+ intrinsic_sizing_info.aspect_ratio.SetHeight(aspect_ratio->Height());
+ }
+
if (!IsHorizontalWritingMode())
intrinsic_sizing_info.Transpose();
return;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.h b/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.h
index 8aa0c87086b..8cc0293e75b 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.h
@@ -62,8 +62,6 @@ class LayoutEmbeddedObject final : public LayoutEmbeddedContent {
void ComputeIntrinsicSizingInfo(IntrinsicSizingInfo&) const override;
bool NeedsPreferredWidthsRecalculation() const override;
- CompositingReasons AdditionalCompositingReasons() const override;
-
PluginAvailability plugin_availability_ = kPluginAvailable;
String unavailable_plugin_replacement_text_;
};
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_flexible_box.cc b/chromium/third_party/blink/renderer/core/layout/layout_flexible_box.cc
index 379e91b8265..1f75974198c 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_flexible_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_flexible_box.cc
@@ -41,6 +41,7 @@
#include "third_party/blink/renderer/core/layout/min_max_sizes.h"
#include "third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
#include "third_party/blink/renderer/core/layout/text_autosizer.h"
#include "third_party/blink/renderer/core/paint/block_painter.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
@@ -656,7 +657,7 @@ LayoutUnit LayoutFlexibleBox::ComputeMainAxisExtentForChild(
// our logical width is auto, we can just use our cached value. So let's do
// that here. (Compare code in LayoutBlock::computePreferredLogicalWidths)
if (child.StyleRef().LogicalWidth().IsAuto() && !HasAspectRatio(child)) {
- if (size.IsMinContent())
+ if (size.IsMinContent() || size.IsMinIntrinsic())
return child.PreferredLogicalWidths().min_size - border_and_padding;
if (size.IsMaxContent())
return child.PreferredLogicalWidths().max_size - border_and_padding;
@@ -958,9 +959,8 @@ void LayoutFlexibleBox::LayoutFlexItems(bool relayout_children,
PaintLayerScrollableArea::PreventRelayoutScope prevent_relayout_scope(
layout_scope);
- // Set up our master list of flex items. All of the rest of the algorithm
- // should work off this list of a subset.
- // TODO(cbiesinger): That second part is not yet true.
+ // Set up our list of flex items. All of the rest of the algorithm should
+ // work off this list of a subset.
ChildLayoutType layout_type =
relayout_children ? kForceLayout : kLayoutIfNeeded;
const LayoutUnit line_break_length = MainAxisContentExtent(LayoutUnit::Max());
@@ -1257,7 +1257,7 @@ void LayoutFlexibleBox::ConstructAndAppendFlexItem(
algorithm->emplace_back(
&child, child.StyleRef(), child_inner_flex_base_size, sizes,
/* min_max_cross_sizes */ base::nullopt, main_axis_border_padding,
- cross_axis_border_padding, physical_margins);
+ cross_axis_border_padding, physical_margins, /* unused */ NGBoxStrut());
}
void LayoutFlexibleBox::SetOverrideMainAxisContentSizeForChild(FlexItem& item) {
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_grid.cc b/chromium/third_party/blink/renderer/core/layout/layout_grid.cc
index 6e500101073..3d4fee9109d 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_grid.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_grid.cc
@@ -378,8 +378,8 @@ void LayoutGrid::UpdateBlockLayout(bool relayout_children) {
LayoutGridItems();
track_sizing_algorithm_.Reset();
- if (NumTracks(kForRows, *grid_) > 1u && !StyleRef().RowGap().IsNormal() &&
- StyleRef().RowGap().GetLength().IsPercentOrCalc()) {
+ if (NumTracks(kForRows, *grid_) > 1u && StyleRef().RowGap() &&
+ StyleRef().RowGap()->IsPercentOrCalc()) {
UseCounter::Count(GetDocument(), WebFeature::kGridRowGapPercent);
if (!CachedHasDefiniteLogicalHeight()) {
UseCounter::Count(GetDocument(),
@@ -406,31 +406,31 @@ void LayoutGrid::UpdateBlockLayout(bool relayout_children) {
LayoutUnit LayoutGrid::GridGap(
GridTrackSizingDirection direction,
base::Optional<LayoutUnit> available_size) const {
- const GapLength& gap =
+ const base::Optional<Length>& gap =
direction == kForColumns ? StyleRef().ColumnGap() : StyleRef().RowGap();
- if (gap.IsNormal())
+ if (!gap)
return LayoutUnit();
- return ValueForLength(gap.GetLength(), available_size.value_or(LayoutUnit()));
+ return ValueForLength(*gap, available_size.value_or(LayoutUnit()));
}
LayoutUnit LayoutGrid::GridGap(GridTrackSizingDirection direction) const {
LayoutUnit available_size;
bool is_row_axis = direction == kForColumns;
- const GapLength& gap =
+ const base::Optional<Length>& gap =
is_row_axis ? StyleRef().ColumnGap() : StyleRef().RowGap();
- if (gap.IsNormal())
+ if (!gap)
return LayoutUnit();
- if (gap.GetLength().IsPercentOrCalc()) {
+ if (gap->IsPercentOrCalc()) {
available_size =
is_row_axis ? AvailableLogicalWidth() : ContentLogicalHeight();
}
// TODO(rego): Maybe we could cache the computed percentage as a performance
// improvement.
- return ValueForLength(gap.GetLength(), available_size);
+ return ValueForLength(*gap, available_size);
}
LayoutUnit LayoutGrid::GuttersSize(
@@ -766,7 +766,7 @@ LayoutGrid::ComputeEmptyTracksForAutoRepeat(
is_row_axis ? StyleRef().GridAutoRepeatColumnsInsertionPoint()
: StyleRef().GridAutoRepeatRowsInsertionPoint();
size_t first_auto_repeat_track =
- insertion_point + std::abs(grid.SmallestTrackStart(direction));
+ insertion_point + grid.ExplicitGridStart(direction);
size_t last_auto_repeat_track =
first_auto_repeat_track + grid.AutoRepeatTracks(direction);
@@ -862,9 +862,9 @@ void LayoutGrid::PlaceItemsOnGrid(
GridArea area = grid.GridItemArea(*child);
if (!area.rows.IsIndefinite())
- area.rows.Translate(abs(grid.SmallestTrackStart(kForRows)));
+ area.rows.Translate(grid.ExplicitGridStart(kForRows));
if (!area.columns.IsIndefinite())
- area.columns.Translate(abs(grid.SmallestTrackStart(kForColumns)));
+ area.columns.Translate(grid.ExplicitGridStart(kForColumns));
if (area.rows.IsIndefinite() || area.columns.IsIndefinite()) {
grid.SetGridItemArea(*child, area);
@@ -954,7 +954,8 @@ void LayoutGrid::PerformGridItemsPreLayout(
// TODO (jfernandez): Can we avoid it ?
if (IsBaselineAlignmentForChild(*child)) {
if (child->HasRelativeLogicalWidth() ||
- child->HasRelativeLogicalHeight()) {
+ child->HasRelativeLogicalHeight() ||
+ child->StyleRef().LogicalHeight().IsAuto()) {
UpdateGridAreaLogicalSize(
*child, algorithm.EstimatedGridAreaBreadthForChild(*child));
}
@@ -965,8 +966,8 @@ void LayoutGrid::PerformGridItemsPreLayout(
void LayoutGrid::PopulateExplicitGridAndOrderIterator(Grid& grid) const {
OrderIteratorPopulator populator(grid.GetOrderIterator());
- int smallest_row_start = 0;
- int smallest_column_start = 0;
+ size_t explicit_row_start = 0;
+ size_t explicit_column_start = 0;
size_t auto_repeat_rows = grid.AutoRepeatTracks(kForRows);
size_t auto_repeat_columns = grid.AutoRepeatTracks(kForColumns);
@@ -991,8 +992,8 @@ void LayoutGrid::PopulateExplicitGridAndOrderIterator(Grid& grid) const {
// |positions| is 0 if we need to run the auto-placement algorithm.
if (!row_positions.IsIndefinite()) {
- smallest_row_start =
- std::min(smallest_row_start, row_positions.UntranslatedStartLine());
+ explicit_row_start = std::max<int>(
+ explicit_row_start, -row_positions.UntranslatedStartLine());
maximum_row_index =
std::max<int>(maximum_row_index, row_positions.UntranslatedEndLine());
} else {
@@ -1004,8 +1005,8 @@ void LayoutGrid::PopulateExplicitGridAndOrderIterator(Grid& grid) const {
}
if (!column_positions.IsIndefinite()) {
- smallest_column_start = std::min(
- smallest_column_start, column_positions.UntranslatedStartLine());
+ explicit_column_start = std::max<int>(
+ explicit_column_start, -column_positions.UntranslatedStartLine());
maximum_column_index = std::max<int>(
maximum_column_index, column_positions.UntranslatedEndLine());
} else {
@@ -1017,9 +1018,9 @@ void LayoutGrid::PopulateExplicitGridAndOrderIterator(Grid& grid) const {
}
}
- grid.SetSmallestTracksStart(smallest_row_start, smallest_column_start);
- grid.EnsureGridSize(maximum_row_index + abs(smallest_row_start),
- maximum_column_index + abs(smallest_column_start));
+ grid.SetExplicitGridStart(explicit_row_start, explicit_column_start);
+ grid.EnsureGridSize(maximum_row_index + explicit_row_start,
+ maximum_column_index + explicit_column_start);
}
std::unique_ptr<GridArea>
@@ -2053,10 +2054,10 @@ LayoutUnit LayoutGrid::GridAreaBreadthForOutOfFlowChild(
if (span.IsIndefinite())
return is_row_axis ? ClientLogicalWidth() : ClientLogicalHeight();
- int smallest_start = abs(grid_->SmallestTrackStart(direction));
- int start_line = span.UntranslatedStartLine() + smallest_start;
- int end_line = span.UntranslatedEndLine() + smallest_start;
- int last_line = NumTracks(direction, *grid_);
+ size_t explicit_start = grid_->ExplicitGridStart(direction);
+ size_t start_line = span.UntranslatedStartLine() + explicit_start;
+ size_t end_line = span.UntranslatedEndLine() + explicit_start;
+ size_t last_line = NumTracks(direction, *grid_);
GridPosition start_position = direction == kForColumns
? child.StyleRef().GridColumnStart()
: child.StyleRef().GridRowStart();
@@ -2482,6 +2483,19 @@ size_t LayoutGrid::NumTracks(GridTrackSizingDirection direction,
StyleRef(), grid.AutoRepeatTracks(kForColumns));
}
+size_t LayoutGrid::ExplicitGridEndForDirection(
+ GridTrackSizingDirection direction) const {
+ size_t leading = ExplicitGridStartForDirection(direction);
+
+ if (direction == kForRows) {
+ return leading + GridPositionsResolver::ExplicitGridRowCount(
+ StyleRef(), grid_->AutoRepeatTracks(direction));
+ }
+
+ return leading + GridPositionsResolver::ExplicitGridColumnCount(
+ StyleRef(), grid_->AutoRepeatTracks(direction));
+}
+
LayoutUnit LayoutGrid::GridItemOffset(
GridTrackSizingDirection direction) const {
return direction == kForRows ? offset_between_rows_.distribution_offset
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_grid.h b/chromium/third_party/blink/renderer/core/layout/layout_grid.h
index 9b9bb6b31d7..6599f9236bc 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_grid.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_grid.h
@@ -87,6 +87,11 @@ class LayoutGrid final : public LayoutBlock {
return grid_->AutoRepeatTracks(direction);
}
+ size_t ExplicitGridStartForDirection(
+ GridTrackSizingDirection direction) const {
+ return grid_->ExplicitGridStart(direction);
+ }
+
LayoutUnit TranslateOutOfFlowRTLCoordinate(const LayoutBox&,
LayoutUnit) const;
@@ -113,6 +118,8 @@ class LayoutGrid final : public LayoutBlock {
StyleContentAlignmentData ContentAlignment(GridTrackSizingDirection) const;
+ size_t ExplicitGridEndForDirection(GridTrackSizingDirection) const;
+
// Exposed for testing *ONLY*.
Grid* InternalGrid() const { return grid_.get(); }
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_image.cc b/chromium/third_party/blink/renderer/core/layout/layout_image.cc
index 6f2a3ae49ac..eff5e034b5c 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_image.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_image.cc
@@ -116,7 +116,7 @@ void LayoutImage::ImageChanged(WrappedImagePtr new_image,
// If error occurred, image marker should be replaced by a LayoutText.
// NotifyOfSubtreeChange to make list item updating its marker content.
- if (IsLayoutNGListMarkerImage() && image_resource_->ErrorOccurred())
+ if (IsListMarkerImage() && image_resource_->ErrorOccurred())
NotifyOfSubtreeChange();
// Per the spec, we let the server-sent header override srcset/other sources
@@ -363,6 +363,13 @@ void LayoutImage::ComputeIntrinsicSizingInfo(
if (StyleRef().GetObjectFit() != EObjectFit::kScaleDown)
intrinsic_sizing_info.size.Scale(ImageDevicePixelRatio());
+ // Handle an overridden aspect ratio
+ if (const base::Optional<IntSize>& aspect_ratio =
+ StyleRef().AspectRatio()) {
+ intrinsic_sizing_info.aspect_ratio.SetWidth(aspect_ratio->Width());
+ intrinsic_sizing_info.aspect_ratio.SetHeight(aspect_ratio->Height());
+ }
+
if (!IsHorizontalWritingMode())
intrinsic_sizing_info.Transpose();
return;
@@ -373,7 +380,7 @@ void LayoutImage::ComputeIntrinsicSizingInfo(
// Our intrinsicSize is empty if we're laying out generated images with
// relative width/height. Figure out the right intrinsic size to use.
if (intrinsic_sizing_info.size.IsEmpty() &&
- !image_resource_->HasIntrinsicSize() && !IsLayoutNGListMarkerImage()) {
+ !image_resource_->HasIntrinsicSize() && !IsListMarkerImage()) {
if (HasOverrideContainingBlockContentLogicalWidth() &&
HasOverrideContainingBlockContentLogicalHeight()) {
intrinsic_sizing_info.size.SetWidth(
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_image_resource.h b/chromium/third_party/blink/renderer/core/layout/layout_image_resource.h
index 808a0958044..286f9912e18 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_image_resource.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_image_resource.h
@@ -70,7 +70,7 @@ class CORE_EXPORT LayoutImageResource
const LayoutSize&) const;
virtual WrappedImagePtr ImagePtr() const { return cached_image_.Get(); }
- virtual void Trace(Visitor* visitor) { visitor->Trace(cached_image_); }
+ virtual void Trace(Visitor* visitor) const { visitor->Trace(cached_image_); }
protected:
// Device scale factor for the associated LayoutObject.
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_image_resource_style_image.cc b/chromium/third_party/blink/renderer/core/layout/layout_image_resource_style_image.cc
index ed8c3dfe576..db5476d73ee 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_image_resource_style_image.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_image_resource_style_image.cc
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/core/layout/layout_image_resource_style_image.h"
+#include "third_party/blink/renderer/core/layout/layout_list_marker_image.h"
#include "third_party/blink/renderer/core/layout/layout_replaced.h"
#include "third_party/blink/renderer/core/style/style_fetched_image.h"
@@ -70,9 +71,12 @@ scoped_refptr<Image> LayoutImageResourceStyleImage::GetImage(
FloatSize LayoutImageResourceStyleImage::ImageSize(float multiplier) const {
// TODO(davve): Find out the correct default object size in this context.
- return ImageSizeWithDefaultSize(multiplier,
- LayoutSize(LayoutReplaced::kDefaultWidth,
- LayoutReplaced::kDefaultHeight));
+ LayoutSize default_size =
+ layout_object_->IsListMarkerImage()
+ ? ToLayoutListMarkerImage(layout_object_)->DefaultSize()
+ : LayoutSize(LayoutReplaced::kDefaultWidth,
+ LayoutReplaced::kDefaultHeight);
+ return ImageSizeWithDefaultSize(multiplier, default_size);
}
FloatSize LayoutImageResourceStyleImage::ImageSizeWithDefaultSize(
@@ -82,7 +86,7 @@ FloatSize LayoutImageResourceStyleImage::ImageSizeWithDefaultSize(
layout_object_->GetDocument(), multiplier, default_size,
LayoutObject::ShouldRespectImageOrientation(layout_object_));
}
-void LayoutImageResourceStyleImage::Trace(Visitor* visitor) {
+void LayoutImageResourceStyleImage::Trace(Visitor* visitor) const {
visitor->Trace(style_image_);
LayoutImageResource::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_image_resource_style_image.h b/chromium/third_party/blink/renderer/core/layout/layout_image_resource_style_image.h
index 108d42d137f..b1b08dd182c 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_image_resource_style_image.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_image_resource_style_image.h
@@ -55,7 +55,7 @@ class LayoutImageResourceStyleImage final : public LayoutImageResource {
const LayoutSize&) const override;
WrappedImagePtr ImagePtr() const override { return style_image_->Data(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<StyleImage> style_image_;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_inline.cc b/chromium/third_party/blink/renderer/core/layout/layout_inline.cc
index d55ad530de2..3e25c8e4e67 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_inline.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -470,8 +470,16 @@ LayoutRect LayoutInline::LocalCaretRect(
LayoutRect caret_rect =
LocalCaretRectForEmptyElement(BorderAndPaddingWidth(), LayoutUnit());
- if (InlineBox* first_box = FirstLineBox())
+ if (InlineBox* first_box = FirstLineBox()) {
caret_rect.MoveBy(first_box->Location());
+ } else if (IsInLayoutNGInlineFormattingContext()) {
+ NGInlineCursor cursor;
+ cursor.MoveTo(*this);
+ if (cursor) {
+ caret_rect.MoveBy(
+ cursor.Current().OffsetInContainerBlock().ToLayoutPoint());
+ }
+ }
return caret_rect;
}
@@ -1786,27 +1794,25 @@ void LayoutInline::InvalidateDisplayItemClients(
PaintInvalidationReason invalidation_reason) const {
ObjectPaintInvalidator paint_invalidator(*this);
- if (RuntimeEnabledFeatures::LayoutNGBlockFragmentationEnabled() &&
- !RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
- auto fragments = NGPaintFragment::InlineFragmentsFor(this);
- if (fragments.IsInLayoutNGInlineFormattingContext()) {
- for (NGPaintFragment* fragment : fragments) {
- paint_invalidator.InvalidateDisplayItemClient(*fragment,
- invalidation_reason);
- }
- return;
- }
- }
-
if (IsInLayoutNGInlineFormattingContext()) {
if (!ShouldCreateBoxFragment())
return;
- NGInlineCursor cursor;
- for (cursor.MoveTo(*this); cursor; cursor.MoveToNextForSameLayoutObject()) {
- DCHECK_EQ(cursor.Current().GetLayoutObject(), this);
- paint_invalidator.InvalidateDisplayItemClient(
- *cursor.Current().GetDisplayItemClient(), invalidation_reason);
+ if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ NGInlineCursor cursor;
+ for (cursor.MoveTo(*this); cursor;
+ cursor.MoveToNextForSameLayoutObject()) {
+ DCHECK_EQ(cursor.Current().GetLayoutObject(), this);
+ paint_invalidator.InvalidateDisplayItemClient(
+ *cursor.Current().GetDisplayItemClient(), invalidation_reason);
+ }
+ return;
}
+#if DCHECK_IS_ON()
+ NGInlineCursor cursor;
+ for (cursor.MoveTo(*this); cursor; cursor.MoveToNextForSameLayoutObject())
+ DCHECK_EQ(cursor.Current().GetDisplayItemClient(), this);
+#endif
+ paint_invalidator.InvalidateDisplayItemClient(*this, invalidation_reason);
return;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_inline_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_inline_test.cc
index f2af84a79e1..c6c6352c2d8 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_inline_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_inline_test.cc
@@ -111,14 +111,6 @@ TEST_F(LayoutInlineTest, RegionHitTest) {
ToLayoutInline(GetLayoutObjectByElementId("lotsOfBoxes"));
ASSERT_TRUE(lots_of_boxes);
- if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
- NGInlineCursor cursor;
- cursor.MoveTo(*lots_of_boxes);
- ASSERT_TRUE(cursor);
- EXPECT_EQ(lots_of_boxes, cursor.Current().GetLayoutObject());
- return;
- }
-
HitTestRequest hit_request(HitTestRequest::kTouchEvent |
HitTestRequest::kListBased);
@@ -149,9 +141,10 @@ TEST_F(LayoutInlineTest, RegionHitTest) {
}
const auto* div = To<LayoutBlockFlow>(lots_of_boxes->Parent());
- for (const NGPaintFragment* line : div->PaintFragment()->Children()) {
- DCHECK(line->PhysicalFragment().IsLineBox());
- NGInlineCursor line_cursor(*line);
+ NGInlineCursor cursor(*div);
+ for (cursor.MoveToFirstLine(); cursor; cursor.MoveToNextLine()) {
+ DCHECK(cursor.Current().IsLineBox());
+ NGInlineCursor line_cursor = cursor.CursorForDescendants();
bool hit_outcome = lots_of_boxes->HitTestCulledInline(
hit_result, location, hit_offset, &line_cursor);
EXPECT_FALSE(hit_outcome);
@@ -287,6 +280,34 @@ TEST_P(ParameterizedLayoutInlineTest, MultilineRelativePositionedHitTest) {
}
}
+TEST_P(ParameterizedLayoutInlineTest, HitTestCulledInlinePreWrap) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ html, body { margin: 0; }
+ body {
+ width: 250px;
+ }
+ span {
+ white-space: pre-wrap;
+ font: 30px serif;
+ }
+ </style>
+ <div id="container">
+ <span id="span">The quick brown fox jumps over the lazy dog.</span>
+ </div>
+ )HTML");
+ HitTestRequest hit_request(HitTestRequest::kReadOnly);
+ PhysicalOffset hit_location(100, 15);
+ HitTestLocation location(hit_location);
+ HitTestResult hit_result(hit_request, location);
+ LayoutObject* container = GetLayoutObjectByElementId("container");
+ container->HitTestAllPhases(hit_result, location, PhysicalOffset());
+
+ Element* span = GetElementById("span");
+ Node* text_node = span->firstChild();
+ EXPECT_EQ(hit_result.InnerNode(), text_node);
+}
+
TEST_P(ParameterizedLayoutInlineTest, VisualRectInDocument) {
LoadAhem();
SetBodyInnerHTML(R"HTML(
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_inside_list_marker.cc b/chromium/third_party/blink/renderer/core/layout/layout_inside_list_marker.cc
index ada7d6b11d0..d18bce73b67 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_inside_list_marker.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_inside_list_marker.cc
@@ -7,7 +7,7 @@
namespace blink {
LayoutInsideListMarker::LayoutInsideListMarker(Element* element)
- : LayoutListMarker(element) {}
+ : LayoutInline(element) {}
LayoutInsideListMarker::~LayoutInsideListMarker() = default;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_inside_list_marker.h b/chromium/third_party/blink/renderer/core/layout/layout_inside_list_marker.h
index 22426dfdec1..b5a8d26fa23 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_inside_list_marker.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_inside_list_marker.h
@@ -6,27 +6,34 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_INSIDE_LIST_MARKER_H_
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/layout/layout_list_marker.h"
+#include "third_party/blink/renderer/core/layout/layout_inline.h"
+#include "third_party/blink/renderer/core/layout/list_marker.h"
namespace blink {
-// Used to layout the list item's inside marker.
+// Used to layout a list item's inside marker with non-normal 'content'.
// The LayoutInsideListMarker always has to be a child of a LayoutListItem.
-class CORE_EXPORT LayoutInsideListMarker final : public LayoutListMarker {
+class CORE_EXPORT LayoutInsideListMarker final : public LayoutInline {
public:
explicit LayoutInsideListMarker(Element*);
~LayoutInsideListMarker() override;
const char* GetName() const override { return "LayoutInsideListMarker"; }
+ const ListMarker& Marker() const { return list_marker_; }
+ ListMarker& Marker() { return list_marker_; }
+
private:
bool IsOfType(LayoutObjectType type) const override {
return type == kLayoutObjectInsideListMarker ||
- LayoutListMarker::IsOfType(type);
+ LayoutInline::IsOfType(type);
}
+
+ ListMarker list_marker_;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutInsideListMarker, IsInsideListMarker());
+DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutInsideListMarker,
+ IsInsideListMarkerForCustomContent());
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_list_item.cc b/chromium/third_party/blink/renderer/core/layout/layout_list_item.cc
index df0dd904451..c519fb4b27c 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_list_item.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_list_item.cc
@@ -279,8 +279,7 @@ bool LayoutListItem::UpdateMarkerLocation() {
}
}
- if (!marker_parent ||
- (marker_parent != line_box_parent && NormalChildNeedsLayout())) {
+ if (!marker_parent || marker_parent != line_box_parent) {
marker->Remove();
line_box_parent->AddChild(marker, FirstNonMarkerChild(line_box_parent));
// TODO(rhogan): line_box_parent and marker_parent may be deleted by
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_list_item.h b/chromium/third_party/blink/renderer/core/layout/layout_list_item.h
index b324ba8020a..df62f2b0a49 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_list_item.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_list_item.h
@@ -44,9 +44,8 @@ class LayoutListItem final : public LayoutBlockFlow {
Element* list_item = To<Element>(GetNode());
if (LayoutObject* marker =
list_item->PseudoElementLayoutObject(kPseudoIdMarker)) {
- if (marker->IsListMarker())
+ if (marker->IsListMarkerForNormalContent())
return ToLayoutListMarker(marker);
- NOTREACHED();
}
return nullptr;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_list_marker.cc b/chromium/third_party/blink/renderer/core/layout/layout_list_marker.cc
index 0425425e887..eb35e4a09d2 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_list_marker.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_list_marker.cc
@@ -28,19 +28,13 @@
#include "third_party/blink/renderer/core/layout/api/line_layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/layout_analyzer.h"
#include "third_party/blink/renderer/core/layout/layout_list_item.h"
+#include "third_party/blink/renderer/core/layout/list_marker.h"
#include "third_party/blink/renderer/core/layout/list_marker_text.h"
#include "third_party/blink/renderer/core/paint/list_marker_painter.h"
#include "third_party/blink/renderer/platform/fonts/font.h"
namespace blink {
-const int kCMarkerPaddingPx = 7;
-
-// TODO(glebl): Move to core/html/resources/html.css after
-// Blink starts to support ::marker crbug.com/457718
-// Recommended UA margin for list markers.
-const int kCUAMarkerMarginEm = 1;
-
LayoutListMarker::LayoutListMarker(Element* element) : LayoutBox(element) {
DCHECK(ListItem());
SetInline(true);
@@ -183,24 +177,24 @@ void LayoutListMarker::UpdateContent() {
return;
switch (GetListStyleCategory()) {
- case ListStyleCategory::kNone:
+ case ListMarker::ListStyleCategory::kNone:
break;
- case ListStyleCategory::kSymbol:
+ case ListMarker::ListStyleCategory::kSymbol:
text_ = list_marker_text::GetText(StyleRef().ListStyleType(),
0); // value is ignored for these types
break;
- case ListStyleCategory::kLanguage:
+ case ListMarker::ListStyleCategory::kLanguage:
text_ = list_marker_text::GetText(StyleRef().ListStyleType(),
ListItem()->Value());
break;
- case ListStyleCategory::kStaticString:
+ case ListMarker::ListStyleCategory::kStaticString:
text_ = StyleRef().ListStyleStringValue();
break;
}
}
String LayoutListMarker::TextAlternative() const {
- if (GetListStyleCategory() == ListStyleCategory::kStaticString)
+ if (GetListStyleCategory() == ListMarker::ListStyleCategory::kStaticString)
return text_;
UChar suffix =
list_marker_text::Suffix(StyleRef().ListStyleType(), ListItem()->Value());
@@ -208,13 +202,14 @@ String LayoutListMarker::TextAlternative() const {
return text_ + suffix + ' ';
}
-LayoutUnit LayoutListMarker::GetWidthOfText(ListStyleCategory category) const {
+LayoutUnit LayoutListMarker::GetWidthOfText(
+ ListMarker::ListStyleCategory category) const {
// TODO(crbug.com/1012289): this code doesn't support bidi algorithm.
if (text_.IsEmpty())
return LayoutUnit();
const Font& font = StyleRef().GetFont();
LayoutUnit item_width = LayoutUnit(font.Width(TextRun(text_)));
- if (category == ListStyleCategory::kStaticString) {
+ if (category == ListMarker::ListStyleCategory::kStaticString) {
// Don't add a suffix.
return item_width;
}
@@ -239,15 +234,15 @@ MinMaxSizes LayoutListMarker::ComputeIntrinsicLogicalWidths() const {
sizes = StyleRef().IsHorizontalWritingMode() ? image_size.Width()
: image_size.Height();
} else {
- ListStyleCategory category = GetListStyleCategory();
+ ListMarker::ListStyleCategory category = GetListStyleCategory();
switch (category) {
- case ListStyleCategory::kNone:
+ case ListMarker::ListStyleCategory::kNone:
break;
- case ListStyleCategory::kSymbol:
- sizes = WidthOfSymbol(StyleRef());
+ case ListMarker::ListStyleCategory::kSymbol:
+ sizes = ListMarker::WidthOfSymbol(StyleRef());
break;
- case ListStyleCategory::kLanguage:
- case ListStyleCategory::kStaticString:
+ case ListMarker::ListStyleCategory::kLanguage:
+ case ListMarker::ListStyleCategory::kStaticString:
sizes = GetWidthOfText(category);
break;
}
@@ -261,82 +256,22 @@ MinMaxSizes LayoutListMarker::PreferredLogicalWidths() const {
return IntrinsicLogicalWidths();
}
-LayoutUnit LayoutListMarker::WidthOfSymbol(const ComputedStyle& style) {
- const Font& font = style.GetFont();
- const SimpleFontData* font_data = font.PrimaryFont();
- DCHECK(font_data);
- if (!font_data)
- return LayoutUnit();
- return LayoutUnit((font_data->GetFontMetrics().Ascent() * 2 / 3 + 1) / 2 + 2);
-}
-
void LayoutListMarker::UpdateMargins(LayoutUnit marker_inline_size) {
LayoutUnit margin_start;
LayoutUnit margin_end;
const ComputedStyle& style = StyleRef();
- if (IsInsideListMarker()) {
+ if (IsInside()) {
std::tie(margin_start, margin_end) =
- InlineMarginsForInside(style, IsImage());
+ ListMarker::InlineMarginsForInside(style, IsImage());
} else {
- std::tie(margin_start, margin_end) =
- InlineMarginsForOutside(style, IsImage(), marker_inline_size);
+ std::tie(margin_start, margin_end) = ListMarker::InlineMarginsForOutside(
+ style, IsImage(), marker_inline_size);
}
SetMarginStart(margin_start);
SetMarginEnd(margin_end);
}
-std::pair<LayoutUnit, LayoutUnit> LayoutListMarker::InlineMarginsForInside(
- const ComputedStyle& style,
- bool is_image) {
- if (!style.ContentBehavesAsNormal())
- return {};
- if (is_image)
- return {LayoutUnit(), LayoutUnit(kCMarkerPaddingPx)};
- switch (GetListStyleCategory(style.ListStyleType())) {
- case ListStyleCategory::kSymbol:
- return {LayoutUnit(-1),
- LayoutUnit(kCUAMarkerMarginEm * style.ComputedFontSize())};
- default:
- break;
- }
- return {};
-}
-
-std::pair<LayoutUnit, LayoutUnit> LayoutListMarker::InlineMarginsForOutside(
- const ComputedStyle& style,
- bool is_image,
- LayoutUnit marker_inline_size) {
- LayoutUnit margin_start;
- LayoutUnit margin_end;
- if (!style.ContentBehavesAsNormal()) {
- margin_start = -marker_inline_size;
- } else if (is_image) {
- margin_start = -marker_inline_size - kCMarkerPaddingPx;
- margin_end = LayoutUnit(kCMarkerPaddingPx);
- } else {
- switch (GetListStyleCategory(style.ListStyleType())) {
- case ListStyleCategory::kNone:
- break;
- case ListStyleCategory::kSymbol: {
- const SimpleFontData* font_data = style.GetFont().PrimaryFont();
- DCHECK(font_data);
- if (!font_data)
- return {};
- const FontMetrics& font_metrics = font_data->GetFontMetrics();
- int offset = font_metrics.Ascent() * 2 / 3;
- margin_start = LayoutUnit(-offset - kCMarkerPaddingPx - 1);
- margin_end = offset + kCMarkerPaddingPx + 1 - marker_inline_size;
- break;
- }
- default:
- margin_start = -marker_inline_size;
- }
- }
- DCHECK_EQ(margin_start + margin_end, -marker_inline_size);
- return {margin_start, margin_end};
-}
-
LayoutUnit LayoutListMarker::LineHeight(
bool first_line,
LineDirectionMode direction,
@@ -360,79 +295,16 @@ LayoutUnit LayoutListMarker::BaselinePosition(
line_position_mode);
}
-LayoutListMarker::ListStyleCategory LayoutListMarker::GetListStyleCategory()
- const {
- return GetListStyleCategory(StyleRef().ListStyleType());
+ListMarker::ListStyleCategory LayoutListMarker::GetListStyleCategory() const {
+ return ListMarker::GetListStyleCategory(StyleRef().ListStyleType());
}
-LayoutListMarker::ListStyleCategory LayoutListMarker::GetListStyleCategory(
- EListStyleType type) {
- switch (type) {
- case EListStyleType::kNone:
- return ListStyleCategory::kNone;
- case EListStyleType::kString:
- return ListStyleCategory::kStaticString;
- case EListStyleType::kDisc:
- case EListStyleType::kCircle:
- case EListStyleType::kSquare:
- return ListStyleCategory::kSymbol;
- case EListStyleType::kArabicIndic:
- case EListStyleType::kArmenian:
- case EListStyleType::kBengali:
- case EListStyleType::kCambodian:
- case EListStyleType::kCjkIdeographic:
- case EListStyleType::kCjkEarthlyBranch:
- case EListStyleType::kCjkHeavenlyStem:
- case EListStyleType::kDecimalLeadingZero:
- case EListStyleType::kDecimal:
- case EListStyleType::kDevanagari:
- case EListStyleType::kEthiopicHalehame:
- case EListStyleType::kEthiopicHalehameAm:
- case EListStyleType::kEthiopicHalehameTiEr:
- case EListStyleType::kEthiopicHalehameTiEt:
- case EListStyleType::kGeorgian:
- case EListStyleType::kGujarati:
- case EListStyleType::kGurmukhi:
- case EListStyleType::kHangul:
- case EListStyleType::kHangulConsonant:
- case EListStyleType::kHebrew:
- case EListStyleType::kHiragana:
- case EListStyleType::kHiraganaIroha:
- case EListStyleType::kKannada:
- case EListStyleType::kKatakana:
- case EListStyleType::kKatakanaIroha:
- case EListStyleType::kKhmer:
- case EListStyleType::kKoreanHangulFormal:
- case EListStyleType::kKoreanHanjaFormal:
- case EListStyleType::kKoreanHanjaInformal:
- case EListStyleType::kLao:
- case EListStyleType::kLowerAlpha:
- case EListStyleType::kLowerArmenian:
- case EListStyleType::kLowerGreek:
- case EListStyleType::kLowerLatin:
- case EListStyleType::kLowerRoman:
- case EListStyleType::kMalayalam:
- case EListStyleType::kMongolian:
- case EListStyleType::kMyanmar:
- case EListStyleType::kOriya:
- case EListStyleType::kPersian:
- case EListStyleType::kSimpChineseFormal:
- case EListStyleType::kSimpChineseInformal:
- case EListStyleType::kTelugu:
- case EListStyleType::kThai:
- case EListStyleType::kTibetan:
- case EListStyleType::kTradChineseFormal:
- case EListStyleType::kTradChineseInformal:
- case EListStyleType::kUpperAlpha:
- case EListStyleType::kUpperArmenian:
- case EListStyleType::kUpperLatin:
- case EListStyleType::kUpperRoman:
- case EListStyleType::kUrdu:
- return ListStyleCategory::kLanguage;
- default:
- NOTREACHED();
- return ListStyleCategory::kLanguage;
- }
+bool LayoutListMarker::IsInside() const {
+ const LayoutListItem* list_item = ListItem();
+ const ComputedStyle& parent_style = list_item->StyleRef();
+ return parent_style.ListStylePosition() == EListStylePosition::kInside ||
+ (IsA<HTMLLIElement>(list_item->GetNode()) &&
+ !parent_style.IsInsideListElement());
}
LayoutRect LayoutListMarker::GetRelativeMarkerRect() const {
@@ -440,14 +312,14 @@ LayoutRect LayoutListMarker::GetRelativeMarkerRect() const {
return LayoutRect(LayoutPoint(), ImageBulletSize());
LayoutRect relative_rect;
- ListStyleCategory category = GetListStyleCategory();
+ ListMarker::ListStyleCategory category = GetListStyleCategory();
switch (category) {
- case ListStyleCategory::kNone:
+ case ListMarker::ListStyleCategory::kNone:
return LayoutRect();
- case ListStyleCategory::kSymbol:
- return RelativeSymbolMarkerRect(StyleRef(), Size().Width());
- case ListStyleCategory::kLanguage:
- case ListStyleCategory::kStaticString: {
+ case ListMarker::ListStyleCategory::kSymbol:
+ return ListMarker::RelativeSymbolMarkerRect(StyleRef(), Size().Width());
+ case ListMarker::ListStyleCategory::kLanguage:
+ case ListMarker::ListStyleCategory::kStaticString: {
const SimpleFontData* font_data = StyleRef().GetFont().PrimaryFont();
DCHECK(font_data);
if (!font_data)
@@ -467,27 +339,4 @@ LayoutRect LayoutListMarker::GetRelativeMarkerRect() const {
return relative_rect;
}
-LayoutRect LayoutListMarker::RelativeSymbolMarkerRect(
- const ComputedStyle& style,
- LayoutUnit width) {
- LayoutRect relative_rect;
- const SimpleFontData* font_data = style.GetFont().PrimaryFont();
- DCHECK(font_data);
- if (!font_data)
- return LayoutRect();
-
- // TODO(wkorman): Review and clean up/document the calculations below.
- // http://crbug.com/543193
- const FontMetrics& font_metrics = font_data->GetFontMetrics();
- int ascent = font_metrics.Ascent();
- int bullet_width = (ascent * 2 / 3 + 1) / 2;
- relative_rect = LayoutRect(1, 3 * (ascent - ascent * 2 / 3) / 2, bullet_width,
- bullet_width);
- if (!style.IsHorizontalWritingMode()) {
- relative_rect = relative_rect.TransposedRect();
- relative_rect.SetX(width - relative_rect.X() - relative_rect.Width());
- }
- return relative_rect;
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_list_marker.h b/chromium/third_party/blink/renderer/core/layout/layout_list_marker.h
index 1fee564ee6e..5d65fd3b0fa 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_list_marker.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_list_marker.h
@@ -26,13 +26,15 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
+#include "third_party/blink/renderer/core/layout/list_marker.h"
namespace blink {
class LayoutListItem;
-// This class holds code shared among legacy classes for list markers.
-class CORE_EXPORT LayoutListMarker : public LayoutBox {
+// Used to layout a list item's marker with 'content: normal'.
+// The LayoutListMarker always has to be a child of a LayoutListItem.
+class CORE_EXPORT LayoutListMarker final : public LayoutBox {
public:
explicit LayoutListMarker(Element*);
~LayoutListMarker() override;
@@ -43,35 +45,21 @@ class CORE_EXPORT LayoutListMarker : public LayoutBox {
// Marker text with suffix, e.g. "1. ", for use in accessibility.
String TextAlternative() const;
- // A reduced set of list style categories allowing for more concise expression
- // of list style specific logic.
- enum class ListStyleCategory { kNone, kSymbol, kLanguage, kStaticString };
+ ListMarker::ListStyleCategory GetListStyleCategory() const;
- // Returns the list's style as one of a reduced high level categorical set of
- // styles.
- ListStyleCategory GetListStyleCategory() const;
- static ListStyleCategory GetListStyleCategory(EListStyleType);
+ bool IsInside() const;
void UpdateMarginsAndContent();
- // Compute inline margins for 'list-style-position: inside' and 'outside'.
- static std::pair<LayoutUnit, LayoutUnit> InlineMarginsForInside(
- const ComputedStyle&,
- bool is_image);
- static std::pair<LayoutUnit, LayoutUnit> InlineMarginsForOutside(
- const ComputedStyle&,
- bool is_image,
- LayoutUnit marker_inline_size);
-
LayoutRect GetRelativeMarkerRect() const;
- static LayoutRect RelativeSymbolMarkerRect(const ComputedStyle&, LayoutUnit);
- static LayoutUnit WidthOfSymbol(const ComputedStyle&);
bool IsImage() const override;
const StyleImage* GetImage() const { return image_.Get(); }
const LayoutListItem* ListItem() const;
LayoutSize ImageBulletSize() const;
+ const char* GetName() const override { return "LayoutListMarker"; }
+
LayoutUnit LineOffset() const { return line_offset_; }
protected:
@@ -81,6 +69,10 @@ class CORE_EXPORT LayoutListMarker : public LayoutBox {
MinMaxSizes ComputeIntrinsicLogicalWidths() const override;
MinMaxSizes PreferredLogicalWidths() const override;
+ bool IsOfType(LayoutObjectType type) const override {
+ return type == kLayoutObjectListMarker || LayoutBox::IsOfType(type);
+ }
+
void Paint(const PaintInfo&) const override;
void UpdateLayout() override;
@@ -101,7 +93,7 @@ class CORE_EXPORT LayoutListMarker : public LayoutBox {
bool IsText() const { return !IsImage(); }
- LayoutUnit GetWidthOfText(ListStyleCategory) const;
+ LayoutUnit GetWidthOfText(ListMarker::ListStyleCategory) const;
void UpdateMargins(LayoutUnit marker_inline_size);
void UpdateContent();
@@ -114,7 +106,8 @@ class CORE_EXPORT LayoutListMarker : public LayoutBox {
LayoutUnit line_offset_;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutListMarker, IsListMarker());
+DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutListMarker,
+ IsListMarkerForNormalContent());
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.cc b/chromium/third_party/blink/renderer/core/layout/layout_list_marker_image.cc
index 0ff22412114..ae1b5fb8774 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_list_marker_image.cc
@@ -1,8 +1,8 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.h"
+#include "third_party/blink/renderer/core/layout/layout_list_marker_image.h"
#include "third_party/blink/renderer/core/layout/intrinsic_sizing_info.h"
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
@@ -10,35 +10,37 @@
namespace blink {
-LayoutNGListMarkerImage::LayoutNGListMarkerImage(Element* element)
+LayoutListMarkerImage::LayoutListMarkerImage(Element* element)
: LayoutImage(element) {}
-LayoutNGListMarkerImage* LayoutNGListMarkerImage::CreateAnonymous(
+LayoutListMarkerImage* LayoutListMarkerImage::CreateAnonymous(
Document* document) {
- LayoutNGListMarkerImage* object = new LayoutNGListMarkerImage(nullptr);
+ LayoutListMarkerImage* object = new LayoutListMarkerImage(nullptr);
object->SetDocumentForAnonymous(document);
return object;
}
-bool LayoutNGListMarkerImage::IsOfType(LayoutObjectType type) const {
- return type == kLayoutObjectNGListMarkerImage || LayoutImage::IsOfType(type);
+bool LayoutListMarkerImage::IsOfType(LayoutObjectType type) const {
+ return type == kLayoutObjectListMarkerImage || LayoutImage::IsOfType(type);
}
-// Because ImageResource() is always LayoutImageResourceStyleImage. So we could
-// use StyleImage::ImageSize to determine the concrete object size with
-// default object size(ascent/2 x ascent/2).
-void LayoutNGListMarkerImage::ComputeIntrinsicSizingInfoByDefaultSize(
- IntrinsicSizingInfo& intrinsic_sizing_info) const {
+LayoutSize LayoutListMarkerImage::DefaultSize() const {
const SimpleFontData* font_data = Style()->GetFont().PrimaryFont();
DCHECK(font_data);
if (!font_data)
- return;
-
+ return LayoutSize(kDefaultWidth, kDefaultHeight);
LayoutUnit bullet_width =
font_data->GetFontMetrics().Ascent() / LayoutUnit(2);
- LayoutSize default_object_size(bullet_width, bullet_width);
+ return LayoutSize(bullet_width, bullet_width);
+}
+
+// Because ImageResource() is always LayoutImageResourceStyleImage. So we could
+// use StyleImage::ImageSize to determine the concrete object size with
+// default object size(ascent/2 x ascent/2).
+void LayoutListMarkerImage::ComputeIntrinsicSizingInfoByDefaultSize(
+ IntrinsicSizingInfo& intrinsic_sizing_info) const {
FloatSize concrete_size = ImageResource()->ImageSizeWithDefaultSize(
- Style()->EffectiveZoom(), default_object_size);
+ Style()->EffectiveZoom(), DefaultSize());
concrete_size.Scale(ImageDevicePixelRatio());
LayoutSize image_size(RoundedLayoutSize(concrete_size));
@@ -48,7 +50,7 @@ void LayoutNGListMarkerImage::ComputeIntrinsicSizingInfoByDefaultSize(
intrinsic_sizing_info.has_height = true;
}
-void LayoutNGListMarkerImage::ComputeIntrinsicSizingInfo(
+void LayoutListMarkerImage::ComputeIntrinsicSizingInfo(
IntrinsicSizingInfo& intrinsic_sizing_info) const {
LayoutImage::ComputeIntrinsicSizingInfo(intrinsic_sizing_info);
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_list_marker_image.h b/chromium/third_party/blink/renderer/core/layout/layout_list_marker_image.h
new file mode 100644
index 00000000000..878cde826a1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/layout_list_marker_image.h
@@ -0,0 +1,36 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_LIST_MARKER_IMAGE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_LIST_MARKER_IMAGE_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/layout/layout_image.h"
+
+namespace blink {
+
+class Document;
+
+class CORE_EXPORT LayoutListMarkerImage final : public LayoutImage {
+ public:
+ explicit LayoutListMarkerImage(Element*);
+ static LayoutListMarkerImage* CreateAnonymous(Document*);
+
+ bool IsLayoutNGObject() const override {
+ return IsLayoutNGObjectForListMarkerImage();
+ }
+ LayoutSize DefaultSize() const;
+
+ private:
+ bool IsOfType(LayoutObjectType) const override;
+
+ void ComputeIntrinsicSizingInfoByDefaultSize(IntrinsicSizingInfo&) const;
+ void ComputeIntrinsicSizingInfo(IntrinsicSizingInfo&) const final;
+};
+
+DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutListMarkerImage, IsListMarkerImage());
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_LIST_MARKER_IMAGE_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.cc b/chromium/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.cc
index 19754331b32..fee52b9ac31 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.cc
@@ -108,7 +108,7 @@ static inline bool CanContainSpannerInParentFragmentationContext(
if (!block_flow)
return false;
return !block_flow->CreatesNewFormattingContext() &&
- !block_flow->StyleRef().CanContainFixedPositionObjects(false) &&
+ !block_flow->CanContainFixedPositionObjects() &&
block_flow->GetPaginationBreakability() != LayoutBox::kForbidBreaks &&
!IsMultiColumnContainer(*block_flow);
}
@@ -778,11 +778,11 @@ void LayoutMultiColumnFlowThread::CalculateColumnCountAndWidth(
LayoutUnit LayoutMultiColumnFlowThread::ColumnGap(const ComputedStyle& style,
LayoutUnit available_width) {
- if (style.ColumnGap().IsNormal()) {
- // "1em" is recommended as the normal gap setting. Matches <p> margins.
- return LayoutUnit(style.GetFontDescription().ComputedSize());
- }
- return ValueForLength(style.ColumnGap().GetLength(), available_width);
+ if (const base::Optional<Length>& column_gap = style.ColumnGap())
+ return ValueForLength(*column_gap, available_width);
+
+ // "1em" is recommended as the normal gap setting. Matches <p> margins.
+ return LayoutUnit(style.GetFontDescription().ComputedSize());
}
void LayoutMultiColumnFlowThread::CreateAndInsertMultiColumnSet(
@@ -1165,6 +1165,7 @@ void LayoutMultiColumnFlowThread::FlowThreadDescendantWillBeRemoved(
}
static inline bool NeedsToReinsertIntoFlowThread(
+ const LayoutBox& box,
const ComputedStyle& old_style,
const ComputedStyle& new_style) {
// If we've become (or are about to become) a container for absolutely
@@ -1172,13 +1173,14 @@ static inline bool NeedsToReinsertIntoFlowThread(
// re-evaluate the need for column sets. There may be out-of-flow descendants
// further down that become part of the flow thread, or cease to be part of
// the flow thread, because of this change.
- if (old_style.CanContainFixedPositionObjects(false) !=
- new_style.CanContainFixedPositionObjects(false))
+ if (box.ComputeIsFixedContainer(&old_style) !=
+ box.ComputeIsFixedContainer(&new_style))
return true;
return old_style.GetPosition() != new_style.GetPosition();
}
-static inline bool NeedsToRemoveFromFlowThread(const ComputedStyle& old_style,
+static inline bool NeedsToRemoveFromFlowThread(const LayoutBox& box,
+ const ComputedStyle& old_style,
const ComputedStyle& new_style) {
// This function is called BEFORE computed style update. If an in-flow
// descendant goes out-of-flow, we may have to remove column sets and spanner
@@ -1192,7 +1194,7 @@ static inline bool NeedsToRemoveFromFlowThread(const ComputedStyle& old_style,
// been updated.
return (new_style.HasOutOfFlowPosition() &&
!old_style.HasOutOfFlowPosition()) ||
- NeedsToReinsertIntoFlowThread(old_style, new_style);
+ NeedsToReinsertIntoFlowThread(box, old_style, new_style);
}
static inline bool NeedsToInsertIntoFlowThread(
@@ -1218,7 +1220,7 @@ static inline bool NeedsToInsertIntoFlowThread(
if (containing_flow_thread == flow_thread)
return true;
}
- return NeedsToReinsertIntoFlowThread(old_style, new_style);
+ return NeedsToReinsertIntoFlowThread(*flow_thread, old_style, new_style);
}
void LayoutMultiColumnFlowThread::FlowThreadDescendantStyleWillChange(
@@ -1226,7 +1228,8 @@ void LayoutMultiColumnFlowThread::FlowThreadDescendantStyleWillChange(
StyleDifference diff,
const ComputedStyle& new_style) {
toggle_spanners_if_needed_ = false;
- if (NeedsToRemoveFromFlowThread(descendant->StyleRef(), new_style)) {
+ if (NeedsToRemoveFromFlowThread(*descendant, descendant->StyleRef(),
+ new_style)) {
FlowThreadDescendantWillBeRemoved(descendant);
return;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_multi_column_set.cc b/chromium/third_party/blink/renderer/core/layout/layout_multi_column_set.cc
index 05575c71fc9..5c1b83304f1 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_multi_column_set.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_multi_column_set.cc
@@ -488,13 +488,13 @@ PositionWithAffinity LayoutMultiColumnSet::PositionForPoint(
LayoutUnit LayoutMultiColumnSet::ColumnGap() const {
LayoutBlockFlow* parent_block = MultiColumnBlockFlow();
- if (parent_block->StyleRef().ColumnGap().IsNormal()) {
- // "1em" is recommended as the normal gap setting. Matches <p> margins.
- return LayoutUnit(
- parent_block->StyleRef().GetFontDescription().ComputedPixelSize());
- }
- return ValueForLength(parent_block->StyleRef().ColumnGap().GetLength(),
- AvailableLogicalWidth());
+ if (const base::Optional<Length>& column_gap =
+ parent_block->StyleRef().ColumnGap())
+ return ValueForLength(*column_gap, AvailableLogicalWidth());
+
+ // "1em" is recommended as the normal gap setting. Matches <p> margins.
+ return LayoutUnit(
+ parent_block->StyleRef().GetFontDescription().ComputedPixelSize());
}
unsigned LayoutMultiColumnSet::ActualColumnCount() const {
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_object.cc b/chromium/third_party/blink/renderer/core/layout/layout_object.cc
index 688121f8ab6..3827e90b420 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_object.cc
@@ -80,10 +80,6 @@
#include "third_party/blink/renderer/core/layout/layout_list_marker.h"
#include "third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h"
#include "third_party/blink/renderer/core/layout/layout_object_factory.h"
-#include "third_party/blink/renderer/core/layout/layout_table_caption.h"
-#include "third_party/blink/renderer/core/layout/layout_table_cell.h"
-#include "third_party/blink/renderer/core/layout/layout_table_col.h"
-#include "third_party/blink/renderer/core/layout/layout_table_row.h"
#include "third_party/blink/renderer/core/layout/layout_text_fragment.h"
#include "third_party/blink/renderer/core/layout/layout_theme.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
@@ -245,24 +241,16 @@ LayoutObject* LayoutObject::CreateObject(Element* element,
return LayoutObjectFactory::CreateBlockFlow(*element, style, legacy);
case EDisplay::kTable:
case EDisplay::kInlineTable:
- UseCounter::Count(element->GetDocument(),
- WebFeature::kLegacyLayoutByTable);
- return new LayoutTable(element);
+ return LayoutObjectFactory::CreateTable(*element, style, legacy);
case EDisplay::kTableRowGroup:
case EDisplay::kTableHeaderGroup:
case EDisplay::kTableFooterGroup:
- UseCounter::Count(element->GetDocument(),
- WebFeature::kLegacyLayoutByTable);
- return new LayoutTableSection(element);
+ return LayoutObjectFactory::CreateTableSection(*element, style, legacy);
case EDisplay::kTableRow:
- UseCounter::Count(element->GetDocument(),
- WebFeature::kLegacyLayoutByTable);
- return new LayoutTableRow(element);
+ return LayoutObjectFactory::CreateTableRow(*element, style, legacy);
case EDisplay::kTableColumnGroup:
case EDisplay::kTableColumn:
- UseCounter::Count(element->GetDocument(),
- WebFeature::kLegacyLayoutByTable);
- return new LayoutTableCol(element);
+ return LayoutObjectFactory::CreateTableColumn(*element, style, legacy);
case EDisplay::kTableCell:
return LayoutObjectFactory::CreateTableCell(*element, style, legacy);
case EDisplay::kTableCaption:
@@ -431,7 +419,7 @@ void LayoutObject::AddChild(LayoutObject* new_child,
!after_child->IsBeforeContent()) {
table = after_child;
} else {
- table = LayoutTable::CreateAnonymousWithParent(this);
+ table = LayoutObjectFactory::CreateAnonymousTableWithParent(*this);
children->InsertChildNode(this, table, before_child);
}
table->AddChild(new_child);
@@ -845,7 +833,6 @@ LayoutBox* LayoutObject::EnclosingBox() const {
}
LayoutBlockFlow* LayoutObject::RootInlineFormattingContext() const {
- DCHECK(IsInline());
for (LayoutObject* parent = Parent(); parent; parent = parent->Parent()) {
if (auto* block_flow = DynamicTo<LayoutBlockFlow>(parent)) {
// Skip |LayoutFlowThread| because it is skipped when finding the first
@@ -859,7 +846,6 @@ LayoutBlockFlow* LayoutObject::RootInlineFormattingContext() const {
}
LayoutBlockFlow* LayoutObject::FragmentItemsContainer() const {
- DCHECK(IsInline());
for (LayoutObject* parent = Parent(); parent; parent = parent->Parent()) {
if (auto* block_flow = DynamicTo<LayoutBlockFlow>(parent))
return block_flow;
@@ -937,7 +923,10 @@ static inline bool ObjectIsRelayoutBoundary(const LayoutObject* object) {
// Positioned objects always have self-painting layers and are safe to use as
// relayout boundaries.
bool is_svg_root = object->IsSVGRoot();
- if (!object->IsPositioned() && !is_svg_root)
+ bool has_self_painting_layer =
+ object->HasLayer() &&
+ ToLayoutBoxModelObject(object)->HasSelfPaintingLayer();
+ if (!has_self_painting_layer && !is_svg_root)
return false;
// LayoutInline can't be relayout roots since LayoutBlockFlow is responsible
@@ -989,11 +978,12 @@ static inline bool ObjectIsRelayoutBoundary(const LayoutObject* object) {
// In LayoutNG, if box has any OOF descendants, they are propagated to
// parent. Therefore, we must mark parent chain for layout.
- if (layout_box->GetCachedLayoutResult() &&
- layout_box->GetCachedLayoutResult()
- ->PhysicalFragment()
- .HasOutOfFlowPositionedDescendants())
- return false;
+ if (const NGLayoutResult* layouot_result =
+ layout_box->GetCachedLayoutResult()) {
+ if (layouot_result->PhysicalFragment()
+ .HasOutOfFlowPositionedDescendants())
+ return false;
+ }
}
if (object->IsTextControl())
@@ -1290,11 +1280,6 @@ inline void LayoutObject::InvalidateContainerIntrinsicLogicalWidths() {
LayoutObject* LayoutObject::ContainerForAbsolutePosition(
AncestorSkipInfo* skip_info) const {
return FindAncestorByPredicate(this, skip_info, [](LayoutObject* candidate) {
- if (!candidate->StyleRef().CanContainAbsolutePositionObjects() &&
- candidate->ShouldApplyLayoutContainment()) {
- UseCounter::Count(candidate->GetDocument(),
- WebFeature::kCSSContainLayoutPositionedDescendants);
- }
return candidate->CanContainAbsolutePositionObjects();
});
}
@@ -1303,12 +1288,6 @@ LayoutObject* LayoutObject::ContainerForFixedPosition(
AncestorSkipInfo* skip_info) const {
DCHECK(!IsText());
return FindAncestorByPredicate(this, skip_info, [](LayoutObject* candidate) {
- if (!candidate->StyleRef().CanContainFixedPositionObjects(
- candidate->IsDocumentElement()) &&
- candidate->ShouldApplyLayoutContainment()) {
- UseCounter::Count(candidate->GetDocument(),
- WebFeature::kCSSContainLayoutPositionedDescendants);
- }
return candidate->CanContainFixedPositionObjects();
});
}
@@ -1358,6 +1337,13 @@ LayoutBlock* LayoutObject::ContainingBlock(AncestorSkipInfo* skip_info) const {
return DynamicTo<LayoutBlock>(object);
}
+LayoutObject* LayoutObject::NonAnonymousAncestor() const {
+ LayoutObject* ancestor = Parent();
+ while (ancestor && ancestor->IsAnonymous())
+ ancestor = ancestor->Parent();
+ return ancestor;
+}
+
LayoutBlock* LayoutObject::FindNonAnonymousContainingBlock(
LayoutObject* container,
AncestorSkipInfo* skip_info) {
@@ -1397,6 +1383,11 @@ bool LayoutObject::ComputeIsFixedContainer(const ComputedStyle* style) const {
if (IsA<LayoutView>(this) || IsSVGForeignObject() || IsTextControl())
return true;
// https://www.w3.org/TR/css-transforms-1/#containing-block-for-all-descendants
+
+ if (RuntimeEnabledFeatures::TransformInteropEnabled() &&
+ style->TransformStyle3D() == ETransformStyle3D::kPreserve3d)
+ return true;
+
if (style->HasTransformRelatedProperty()) {
if (!IsInline() || IsAtomicInlineLevel())
return true;
@@ -2051,10 +2042,18 @@ StyleDifference LayoutObject::AdjustStyleDifference(
(IsText() && !IsBR() && ToLayoutText(this)->HasInlineFragments()) ||
(IsSVG() && StyleRef().SvgStyle().IsFillColorCurrentColor()) ||
(IsSVG() && StyleRef().SvgStyle().IsStrokeColorCurrentColor()) ||
- IsListMarker() || IsDetailsMarker() || IsMathML())
+ IsListMarkerForNormalContent() || IsDetailsMarker() || IsMathML())
diff.SetNeedsPaintInvalidation();
}
+ // TODO(1088373): Pixel_WebGLHighToLowPower fails without this. This isn't the
+ // right way to ensure GPU switching. Investigate and do it in the right way.
+ if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled() &&
+ !diff.NeedsPaintInvalidation() && IsLayoutView() && Style() &&
+ !Style()->GetFont().IsFallbackValid()) {
+ diff.SetNeedsPaintInvalidation();
+ }
+
// The answer to layerTypeRequired() for plugins, iframes, and canvas can
// change without the actual style changing, since it depends on whether we
// decide to composite these elements. When the/ layer status of one of these
@@ -2383,8 +2382,9 @@ void LayoutObject::StyleWillChange(StyleDifference diff,
bool visibility_changed = style_->Visibility() != new_style.Visibility();
// If our z-index changes value or our visibility changes,
// we need to dirty our stacking context's z-order list.
- if (visibility_changed || style_->ZIndex() != new_style.ZIndex() ||
- style_->IsStackingContext() != new_style.IsStackingContext()) {
+ if (visibility_changed ||
+ style_->EffectiveZIndex() != new_style.EffectiveZIndex() ||
+ IsStackingContext(*style_) != IsStackingContext(new_style)) {
GetDocument().SetAnnotatedRegionsDirty(true);
if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache()) {
if (GetNode())
@@ -2540,6 +2540,20 @@ void LayoutObject::StyleDidChange(StyleDifference diff,
}
}
+ if (HasHiddenBackface()) {
+ bool preserve_3d =
+ (Parent() && Parent()->StyleRef().UsedTransformStyle3D() ==
+ ETransformStyle3D::kPreserve3d);
+ if (style_->HasTransform() || preserve_3d) {
+ UseCounter::Count(GetDocument(),
+ WebFeature::kHiddenBackfaceWithPossible3D);
+ }
+ if (preserve_3d) {
+ UseCounter::Count(GetDocument(),
+ WebFeature::kHiddenBackfaceWithPreserve3D);
+ }
+ }
+
// First assume the outline will be affected. It may be updated when we know
// it's not affected.
bool has_outline = style_->HasOutline();
@@ -2980,8 +2994,13 @@ void LayoutObject::GetTransformFromContainer(
transform.PostTranslate(offset_in_container.left.ToFloat(),
offset_in_container.top.ToFloat());
- if (container_object && container_object->HasLayer() &&
- container_object->StyleRef().HasPerspective()) {
+ bool has_perspective = container_object && container_object->HasLayer() &&
+ container_object->StyleRef().HasPerspective();
+ if (has_perspective && RuntimeEnabledFeatures::TransformInteropEnabled() &&
+ container_object != NonAnonymousAncestor())
+ has_perspective = false;
+
+ if (has_perspective) {
// Perspective on the container affects us, so we have to factor it in here.
DCHECK(container_object->HasLayer());
FloatPoint perspective_origin =
@@ -3468,9 +3487,26 @@ void LayoutObject::DestroyAndCleanupAnonymousWrappers() {
if (destroy_root_parent->IsLayoutFlowThread())
break;
- if (destroy_root->PreviousSibling() || destroy_root->NextSibling())
- break; // Need to keep the anonymous parent, since it won't become empty
- // by the removal of this LayoutObject.
+ // We need to keep the anonymous parent, if it won't become empty by the
+ // removal of this LayoutObject.
+ if (destroy_root->PreviousSibling())
+ break;
+ if (const LayoutObject* sibling = destroy_root->NextSibling()) {
+ if (destroy_root->GetNode()) {
+ // When there are inline continuations, there may be multiple layout
+ // objects generated from the same node, and those are special. They
+ // will be removed as part of destroying |this|, in
+ // LayoutInline::WillBeDestroyed(). So if that's all we have left, we
+ // need to realize now that the anonymous containing block will become
+ // empty. So we have to destroy it.
+ while (sibling && sibling->GetNode() == destroy_root->GetNode())
+ sibling = sibling->NextSibling();
+ }
+ if (sibling)
+ break;
+ DCHECK(destroy_root->IsLayoutInline());
+ DCHECK(ToLayoutInline(destroy_root)->Continuation());
+ }
}
destroy_root->Destroy();
@@ -3709,7 +3745,7 @@ bool LayoutObject::WillRenderImage() {
return false;
// We will not render a new image when ExecutionContext is paused
- if (GetDocument().IsContextPaused())
+ if (GetDocument().GetExecutionContext()->IsContextPaused())
return false;
// Suspend animations when the page is not visible.
@@ -3728,6 +3764,18 @@ bool LayoutObject::GetImageAnimationPolicy(ImageAnimationPolicy& policy) {
return true;
}
+bool LayoutObject::IsInsideListMarker() const {
+ return (IsListMarkerForNormalContent() &&
+ ToLayoutListMarker(this)->IsInside()) ||
+ IsInsideListMarkerForCustomContent();
+}
+
+bool LayoutObject::IsOutsideListMarker() const {
+ return (IsListMarkerForNormalContent() &&
+ !ToLayoutListMarker(this)->IsInside()) ||
+ IsOutsideListMarkerForCustomContent();
+}
+
int LayoutObject::CaretMinOffset() const {
return 0;
}
@@ -4093,6 +4141,20 @@ bool LayoutObject::PaintInvalidationStateIsDirty() const {
}
#endif
+void LayoutObject::ClearPaintFlags() {
+ DCHECK_EQ(GetDocument().Lifecycle().GetState(),
+ DocumentLifecycle::kInPrePaint);
+ ClearPaintInvalidationFlags();
+ bitfields_.SetNeedsPaintPropertyUpdate(false);
+ bitfields_.SetEffectiveAllowedTouchActionChanged(false);
+
+ if (!PrePaintBlockedByDisplayLock(DisplayLockLifecycleTarget::kChildren)) {
+ bitfields_.SetDescendantNeedsPaintPropertyUpdate(false);
+ bitfields_.SetDescendantEffectiveAllowedTouchActionChanged(false);
+ bitfields_.ResetSubtreePaintPropertyUpdateReasons();
+ }
+}
+
bool LayoutObject::IsAllowedToModifyLayoutTreeStructure(Document& document) {
return document.Lifecycle().StateAllowsLayoutTreeMutations();
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_object.h b/chromium/third_party/blink/renderer/core/layout/layout_object.h
index f1d44dd67ce..5d1593e4471 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_object.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_object.h
@@ -551,6 +551,28 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
ShouldApplySizeContainment();
}
+ inline bool IsStackingContext() const {
+ return IsStackingContext(StyleRef());
+ }
+ inline bool IsStackingContext(const ComputedStyle& style) const {
+ // This is an inlined version of the following:
+ // `IsStackingContextWithoutContainment() ||
+ // ShouldApplyLayoutContainment() ||
+ // ShouldApplyPaintContainment()`
+ // The reason it is inlined is that the containment checks share
+ // common logic, which is extracted here to avoid repeated computation.
+ return style.IsStackingContextWithoutContainment() ||
+ ((style.ContainsLayout() || style.ContainsPaint()) &&
+ (!IsInline() || IsAtomicInlineLevel()) && !IsRubyText() &&
+ (!IsTablePart() || IsLayoutBlockFlow()));
+ }
+
+ inline bool IsStacked() const { return IsStacked(StyleRef()); }
+ inline bool IsStacked(const ComputedStyle& style) const {
+ return style.GetPosition() != EPosition::kStatic ||
+ IsStackingContext(style);
+ }
+
void NotifyPriorityScrollAnchorStatusChanged();
private:
@@ -652,7 +674,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
}
bool IsFrame() const { return IsOfType(kLayoutObjectFrame); }
bool IsFrameSet() const { return IsOfType(kLayoutObjectFrameSet); }
- bool IsInsideListMarker() const {
+ bool IsInsideListMarkerForCustomContent() const {
return IsOfType(kLayoutObjectInsideListMarker);
}
bool IsLayoutNGBlockFlow() const {
@@ -666,9 +688,6 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
bool IsLayoutNGInsideListMarker() const {
return IsOfType(kLayoutObjectNGInsideListMarker);
}
- bool IsLayoutNGListMarkerImage() const {
- return IsOfType(kLayoutObjectNGListMarkerImage);
- }
bool IsLayoutNGOutsideListMarker() const {
return IsOfType(kLayoutObjectNGOutsideListMarker);
}
@@ -681,10 +700,16 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
return IsOfType(kLayoutObjectLayoutNGTableCol);
}
bool IsListItem() const { return IsOfType(kLayoutObjectListItem); }
+ bool IsListMarkerForNormalContent() const {
+ return IsOfType(kLayoutObjectListMarker);
+ }
+ bool IsListMarkerImage() const {
+ return IsOfType(kLayoutObjectListMarkerImage);
+ }
bool IsMathML() const { return IsOfType(kLayoutObjectMathML); }
bool IsMathMLRoot() const { return IsOfType(kLayoutObjectMathMLRoot); }
bool IsMedia() const { return IsOfType(kLayoutObjectMedia); }
- bool IsOutsideListMarker() const {
+ bool IsOutsideListMarkerForCustomContent() const {
return IsOfType(kLayoutObjectOutsideListMarker);
}
bool IsProgress() const { return IsOfType(kLayoutObjectProgress); }
@@ -938,8 +963,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
(StyleRef().Display() == EDisplay::kBlock ||
StyleRef().Display() == EDisplay::kWebkitBox) &&
StyleRef().StyleType() == kPseudoIdNone && IsLayoutBlock() &&
- !IsListMarker() && !IsLayoutFlowThread() &&
- !IsLayoutMultiColumnSet();
+ !IsLayoutFlowThread() && !IsLayoutMultiColumnSet();
}
// If node has been split into continuations, it returns the first layout
// object generated for the node.
@@ -1155,6 +1179,8 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
bool ShouldClipOverflow() const { return bitfields_.ShouldClipOverflow(); }
bool HasClipRelatedProperty() const;
+ // Not returning StyleRef().HasTransformRelatedProperty() because some objects
+ // ignore the transform-related styles (e.g. LayoutInline, LayoutSVGBlock).
bool HasTransformRelatedProperty() const {
return bitfields_.HasTransformRelatedProperty();
}
@@ -1170,8 +1196,8 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// Returns |true| if any property that renders using filter operations is
// used (including, but not limited to, 'filter' and 'box-reflect').
- // Not calling style()->hasFilterInducingProperty because some objects force
- // to ignore reflection style (e.g. LayoutInline).
+ // Not calling StyleRef().HasFilterInducingProperty() because some objects
+ // ignore reflection style (e.g. LayoutInline, LayoutSVGBlock).
bool HasFilterInducingProperty() const {
return StyleRef().HasNonInitialFilter() || HasReflection();
}
@@ -1354,8 +1380,6 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// Returns true if style would make this object a fixed container.
// This value gets cached by bitfields_.can_contain_fixed_position_objects_.
- // TODO(pdr): Should this function be unified with
- // ComputedStyle::CanContainFixedPositionObjects?
bool ComputeIsFixedContainer(const ComputedStyle* style) const;
virtual LayoutObject* HoverAncestor() const { return Parent(); }
@@ -1640,6 +1664,10 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
LayoutObject* container,
AncestorSkipInfo* = nullptr);
+ // Returns the nearest anceestor in the layout tree that is not anonymous,
+ // or null if there is none.
+ LayoutObject* NonAnonymousAncestor() const;
+
const LayoutBlock* InclusiveContainingBlock() const;
bool CanContainAbsolutePositionObjects() const {
@@ -1963,6 +1991,8 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
!IsLayoutNGOutsideListMarker() && !IsOutsideListMarker();
}
+ // Not returning StyleRef().BoxReflect() because some objects ignore the
+ // reflection style (e.g. LayoutInline, LayoutSVGBlock).
bool HasReflection() const { return bitfields_.HasReflection(); }
// The current selection state for an object. For blocks, the state refers to
@@ -2034,17 +2064,40 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
return IsListItem() || IsLayoutNGListItem();
}
- // There are 3 types of list marker. LayoutNG creates different types for
- // inside and outside; outside is derived from LayoutBlockFlow, and inside
- // from LayoutInline. Legacy is derived from LayoutBox.
+ // There 5 different types of list markers:
+ // * LayoutListMarker (LayoutBox): for both outside and inside markers with
+ // 'content: normal', in legacy layout.
+ // * LayoutInsideListMarker (LayoutInline): for non-normal inside markers in
+ // legacy layout.
+ // * LayoutOutsideListMarker (LayoutBlockFlow): for non-normal outside markers
+ // in legacy layout.
+ // * LayoutNGInsideListMarker (LayoutInline): for inside markers in LayoutNG.
+ // * LayoutNGOutsideListMarker (LayoutNGBlockFlowMixin<LayoutBlockFlow>):
+ // for outside markers in LayoutNG.
+
+ // Legacy marker with inside position, normal or not.
+ bool IsInsideListMarker() const;
+ // Legacy marker with outside position, normal or not.
+ bool IsOutsideListMarker() const;
+ // Any kind of legacy list marker.
bool IsListMarker() const {
- return IsOutsideListMarker() || IsInsideListMarker();
+ return IsListMarkerForNormalContent() ||
+ IsInsideListMarkerForCustomContent() ||
+ IsOutsideListMarkerForCustomContent();
+ }
+ // Any kind of LayoutBox list marker.
+ bool IsBoxListMarkerIncludingNG() const {
+ return IsListMarkerForNormalContent() ||
+ IsOutsideListMarkerForCustomContent() ||
+ IsLayoutNGOutsideListMarker();
}
- bool IsListMarkerIncludingNGOutside() const {
- return IsListMarker() || IsLayoutNGOutsideListMarker();
+ // Any kind of LayoutNG list marker.
+ bool IsLayoutNGListMarker() const {
+ return IsLayoutNGInsideListMarker() || IsLayoutNGOutsideListMarker();
}
- bool IsListMarkerIncludingNGOutsideAndInside() const {
- return IsListMarkerIncludingNGOutside() || IsLayoutNGInsideListMarker();
+ // Any kind of list marker.
+ bool IsListMarkerIncludingAll() const {
+ return IsListMarker() || IsLayoutNGListMarker();
}
virtual bool IsCombineText() const { return false; }
@@ -2103,9 +2156,8 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
TransformationMatrix&) const;
bool CreatesGroup() const {
- return StyleRef().HasOpacity() || HasMask() || HasClipPath() ||
- HasFilterInducingProperty() || HasNonInitialBackdropFilter() ||
- StyleRef().HasBlendMode();
+ // See |HasReflection()| for why |StyleRef().BoxReflect()| is not used.
+ return StyleRef().HasGroupingProperty(HasReflection());
}
Vector<PhysicalRect> OutlineRects(const PhysicalOffset& additional_offset,
@@ -2236,8 +2288,6 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// setNeedsRepaint before calling this function.
virtual void InvalidateDisplayItemClients(PaintInvalidationReason) const;
- virtual bool HasNonCompositedScrollbars() const { return false; }
-
// Called before setting style for existing/new anonymous child. Override to
// set custom styles for the child. For new anonymous child, |child| is null.
virtual void UpdateAnonymousChildStyle(const LayoutObject* child,
@@ -2306,21 +2356,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
public:
// Convenience mutator that clears paint invalidation flags and this object
// and its descendants' needs-paint-property-update flags.
- void ClearPaintFlags() {
- DCHECK_EQ(layout_object_.GetDocument().Lifecycle().GetState(),
- DocumentLifecycle::kInPrePaint);
- layout_object_.ClearPaintInvalidationFlags();
- layout_object_.bitfields_.SetNeedsPaintPropertyUpdate(false);
- layout_object_.bitfields_.SetEffectiveAllowedTouchActionChanged(false);
-
- if (!layout_object_.PrePaintBlockedByDisplayLock(
- DisplayLockLifecycleTarget::kChildren)) {
- layout_object_.bitfields_.SetDescendantNeedsPaintPropertyUpdate(false);
- layout_object_.bitfields_
- .SetDescendantEffectiveAllowedTouchActionChanged(false);
- layout_object_.bitfields_.ResetSubtreePaintPropertyUpdateReasons();
- }
- }
+ void ClearPaintFlags() { layout_object_.ClearPaintFlags(); }
void SetShouldCheckForPaintInvalidation() {
// This method is only intended to be called when visiting this object
// during pre-paint, and as such it should only mark itself, and not the
@@ -2579,6 +2615,20 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
return element->GetDisplayLockContext();
}
+ void SetDocumentForAnonymous(Document* document) {
+ DCHECK(IsAnonymous());
+ node_ = document;
+ }
+
+ bool IsLayoutNGObjectForListMarkerImage() const {
+ DCHECK(IsListMarkerImage());
+ return bitfields_.IsLayoutNGObjectForListMarkerImage();
+ }
+ void SetIsLayoutNGObjectForListMarkerImage(bool b) {
+ DCHECK(IsListMarkerImage());
+ bitfields_.SetIsLayoutNGObjectForListMarkerImage(b);
+ }
+
protected:
enum LayoutObjectType {
kLayoutObjectBr,
@@ -2594,6 +2644,8 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
kLayoutObjectLayoutTableCol,
kLayoutObjectLayoutNGTableCol,
kLayoutObjectListItem,
+ kLayoutObjectListMarker,
+ kLayoutObjectListMarkerImage,
kLayoutObjectMathML,
kLayoutObjectMathMLRoot,
kLayoutObjectMedia,
@@ -2605,7 +2657,6 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
kLayoutObjectNGListItem,
kLayoutObjectNGInsideListMarker,
kLayoutObjectNGOutsideListMarker,
- kLayoutObjectNGListMarkerImage,
kLayoutObjectNGProgress,
kLayoutObjectNGText,
kLayoutObjectOutsideListMarker,
@@ -2721,11 +2772,6 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
virtual void InsertedIntoTree();
virtual void WillBeRemovedFromTree();
- void SetDocumentForAnonymous(Document* document) {
- DCHECK(IsAnonymous());
- node_ = document;
- }
-
#if DCHECK_IS_ON()
virtual bool PaintInvalidationStateIsDirty() const;
#endif
@@ -2735,6 +2781,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
DCHECK(!NeedsLayout() ||
LayoutBlockedByDisplayLock(DisplayLockLifecycleTarget::kChildren));
}
+ virtual void ClearPaintFlags();
void SetIsBackgroundAttachmentFixedObject(bool);
@@ -3153,8 +3200,9 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// control clips or contain: paint.
ADD_BOOLEAN_BITFIELD(should_clip_overflow_, ShouldClipOverflow);
- // This boolean is the cached value from
- // ComputedStyle::hasTransformRelatedProperty.
+ // The cached value from ComputedStyle::HasTransformRelatedProperty for
+ // objects that do not ignore transform-related styles (e.g. not
+ // LayoutInline, LayoutSVGBlock).
ADD_BOOLEAN_BITFIELD(has_transform_related_property_,
HasTransformRelatedProperty);
ADD_BOOLEAN_BITFIELD(has_reflection_, HasReflection);
@@ -3265,6 +3313,10 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// True at start of |Destroy()| before calling |WillBeDestroyed()|.
ADD_BOOLEAN_BITFIELD(being_destroyed_, BeingDestroyed);
+ // From LayoutListMarkerImage
+ ADD_BOOLEAN_BITFIELD(is_layout_ng_object_for_list_marker_image,
+ IsLayoutNGObjectForListMarkerImage);
+
private:
// This is the cached 'position' value of this object
// (see ComputedStyle::position).
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_object_factory.cc b/chromium/third_party/blink/renderer/core/layout/layout_object_factory.cc
index eb9bd180d32..2e79c23ae79 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_object_factory.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_object_factory.cc
@@ -15,25 +15,34 @@
#include "third_party/blink/renderer/core/layout/layout_inside_list_marker.h"
#include "third_party/blink/renderer/core/layout/layout_list_item.h"
#include "third_party/blink/renderer/core/layout/layout_outside_list_marker.h"
+#include "third_party/blink/renderer/core/layout/layout_table.h"
#include "third_party/blink/renderer/core/layout/layout_table_caption.h"
#include "third_party/blink/renderer/core/layout/layout_table_cell.h"
+#include "third_party/blink/renderer/core/layout/layout_table_col.h"
+#include "third_party/blink/renderer/core/layout/layout_table_row.h"
+#include "third_party/blink/renderer/core/layout/layout_table_section.h"
#include "third_party/blink/renderer/core/layout/layout_text.h"
#include "third_party/blink/renderer/core/layout/layout_text_fragment.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.h"
+#include "third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.h"
#include "third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h"
#include "third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h"
#include "third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.h"
-#include "third_party/blink/renderer/core/layout/ng/layout_ng_grid.h"
#include "third_party/blink/renderer/core/layout/ng/layout_ng_progress.h"
#include "third_party/blink/renderer/core/layout/ng/layout_ng_ruby_as_block.h"
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.h"
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h"
#include "third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.h"
+#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h"
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.h"
+#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h"
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell_legacy.h"
+#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.h"
+#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h"
+#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -141,10 +150,20 @@ LayoutObject* LayoutObjectFactory::CreateListMarker(Node& node,
(IsA<HTMLLIElement>(parent) && !parent_style->IsInsideListElement());
if (is_inside) {
return CreateObject<LayoutObject, LayoutNGInsideListMarker,
- LayoutInsideListMarker>(node, style, legacy);
+ LayoutListMarker>(node, style, legacy);
}
return CreateObject<LayoutObject, LayoutNGOutsideListMarker,
- LayoutOutsideListMarker>(node, style, legacy);
+ LayoutListMarker>(node, style, legacy);
+}
+
+LayoutBlock* LayoutObjectFactory::CreateTable(Node& node,
+ const ComputedStyle& style,
+ LegacyLayout legacy) {
+ bool disable_ng_for_type = !RuntimeEnabledFeatures::LayoutNGTableEnabled();
+ if (disable_ng_for_type)
+ UseCounter::Count(node.GetDocument(), WebFeature::kLegacyLayoutByTable);
+ return CreateObject<LayoutBlock, LayoutNGTable, LayoutTable>(
+ node, style, legacy, disable_ng_for_type);
}
LayoutTableCaption* LayoutObjectFactory::CreateTableCaption(
@@ -155,12 +174,47 @@ LayoutTableCaption* LayoutObjectFactory::CreateTableCaption(
legacy);
}
-LayoutTableCell* LayoutObjectFactory::CreateTableCell(
+LayoutBlockFlow* LayoutObjectFactory::CreateTableCell(
Node& node,
const ComputedStyle& style,
LegacyLayout legacy) {
- return CreateObject<LayoutTableCell, LayoutNGTableCellLegacy>(node, style,
- legacy);
+ if (RuntimeEnabledFeatures::LayoutNGTableEnabled()) {
+ return CreateObject<LayoutBlockFlow, LayoutNGTableCell, LayoutTableCell>(
+ node, style, legacy);
+ } else {
+ return CreateObject<LayoutBlockFlow, LayoutNGTableCellLegacy,
+ LayoutTableCell>(node, style, legacy);
+ }
+}
+
+LayoutBox* LayoutObjectFactory::CreateTableColumn(Node& node,
+ const ComputedStyle& style,
+ LegacyLayout legacy) {
+ bool disable_ng_for_type = !RuntimeEnabledFeatures::LayoutNGTableEnabled();
+ if (disable_ng_for_type)
+ UseCounter::Count(node.GetDocument(), WebFeature::kLegacyLayoutByTable);
+ return CreateObject<LayoutBox, LayoutNGTableColumn, LayoutTableCol>(
+ node, style, legacy, disable_ng_for_type);
+}
+
+LayoutBox* LayoutObjectFactory::CreateTableRow(Node& node,
+ const ComputedStyle& style,
+ LegacyLayout legacy) {
+ bool disable_ng_for_type = !RuntimeEnabledFeatures::LayoutNGTableEnabled();
+ if (disable_ng_for_type)
+ UseCounter::Count(node.GetDocument(), WebFeature::kLegacyLayoutByTable);
+ return CreateObject<LayoutBox, LayoutNGTableRow, LayoutTableRow>(
+ node, style, legacy, disable_ng_for_type);
+}
+
+LayoutBox* LayoutObjectFactory::CreateTableSection(Node& node,
+ const ComputedStyle& style,
+ LegacyLayout legacy) {
+ bool disable_ng_for_type = !RuntimeEnabledFeatures::LayoutNGTableEnabled();
+ if (disable_ng_for_type)
+ UseCounter::Count(node.GetDocument(), WebFeature::kLegacyLayoutByTable);
+ return CreateObject<LayoutBox, LayoutNGTableSection, LayoutTableSection>(
+ node, style, legacy, disable_ng_for_type);
}
LayoutBlock* LayoutObjectFactory::CreateFieldset(Node& node,
@@ -229,4 +283,62 @@ LayoutRubyAsBlock* LayoutObjectFactory::CreateRubyAsBlock(
legacy);
}
+LayoutBox* LayoutObjectFactory::CreateAnonymousTableWithParent(
+ const LayoutObject& parent) {
+ scoped_refptr<ComputedStyle> new_style =
+ ComputedStyle::CreateAnonymousStyleWithDisplay(
+ parent.StyleRef(),
+ parent.IsLayoutInline() ? EDisplay::kInlineTable : EDisplay::kTable);
+ LegacyLayout legacy =
+ parent.ForceLegacyLayout() ? LegacyLayout::kForce : LegacyLayout::kAuto;
+
+ LayoutBlock* new_table =
+ CreateTable(parent.GetDocument(), *new_style, legacy);
+ new_table->SetDocumentForAnonymous(&parent.GetDocument());
+ new_table->SetStyle(std::move(new_style));
+ return new_table;
+}
+
+LayoutBox* LayoutObjectFactory::CreateAnonymousTableSectionWithParent(
+ const LayoutObject& parent) {
+ scoped_refptr<ComputedStyle> new_style =
+ ComputedStyle::CreateAnonymousStyleWithDisplay(parent.StyleRef(),
+ EDisplay::kTableRowGroup);
+ LegacyLayout legacy =
+ parent.ForceLegacyLayout() ? LegacyLayout::kForce : LegacyLayout::kAuto;
+
+ LayoutBox* new_section =
+ CreateTableSection(parent.GetDocument(), *new_style, legacy);
+ new_section->SetDocumentForAnonymous(&parent.GetDocument());
+ new_section->SetStyle(std::move(new_style));
+ return new_section;
+}
+
+LayoutBox* LayoutObjectFactory::CreateAnonymousTableRowWithParent(
+ const LayoutObject& parent) {
+ scoped_refptr<ComputedStyle> new_style =
+ ComputedStyle::CreateAnonymousStyleWithDisplay(parent.StyleRef(),
+ EDisplay::kTableRow);
+ LegacyLayout legacy =
+ parent.ForceLegacyLayout() ? LegacyLayout::kForce : LegacyLayout::kAuto;
+ LayoutBox* new_row = CreateTableRow(parent.GetDocument(), *new_style, legacy);
+ new_row->SetDocumentForAnonymous(&parent.GetDocument());
+ new_row->SetStyle(std::move(new_style));
+ return new_row;
+}
+
+LayoutBlockFlow* LayoutObjectFactory::CreateAnonymousTableCellWithParent(
+ const LayoutObject& parent) {
+ scoped_refptr<ComputedStyle> new_style =
+ ComputedStyle::CreateAnonymousStyleWithDisplay(parent.StyleRef(),
+ EDisplay::kTableCell);
+ LegacyLayout legacy =
+ parent.ForceLegacyLayout() ? LegacyLayout::kForce : LegacyLayout::kAuto;
+ LayoutBlockFlow* new_cell =
+ CreateTableCell(parent.GetDocument(), *new_style, legacy);
+ new_cell->SetDocumentForAnonymous(&parent.GetDocument());
+ new_cell->SetStyle(std::move(new_style));
+ return new_cell;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_object_factory.h b/chromium/third_party/blink/renderer/core/layout/layout_object_factory.h
index 1cc47ff245c..831a1beba07 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_object_factory.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_object_factory.h
@@ -15,11 +15,11 @@ class ComputedStyle;
class LayoutBlock;
class LayoutBlockFlow;
class LayoutObject;
+class LayoutBox;
enum class LegacyLayout;
class LayoutProgress;
class LayoutRubyAsBlock;
class LayoutTableCaption;
-class LayoutTableCell;
class LayoutText;
class LayoutTextFragment;
class Node;
@@ -50,12 +50,21 @@ class LayoutObjectFactory {
static LayoutObject* CreateListMarker(Node&,
const ComputedStyle&,
LegacyLayout);
+ static LayoutBlock* CreateTable(Node&, const ComputedStyle&, LegacyLayout);
static LayoutTableCaption* CreateTableCaption(Node&,
const ComputedStyle&,
LegacyLayout);
- static LayoutTableCell* CreateTableCell(Node&,
+ static LayoutBlockFlow* CreateTableCell(Node&,
const ComputedStyle&,
LegacyLayout);
+ static LayoutBox* CreateTableColumn(Node&,
+ const ComputedStyle&,
+ LegacyLayout);
+
+ static LayoutBox* CreateTableRow(Node&, const ComputedStyle&, LegacyLayout);
+ static LayoutBox* CreateTableSection(Node&,
+ const ComputedStyle&,
+ LegacyLayout);
static LayoutBlock* CreateFieldset(Node&, const ComputedStyle&, LegacyLayout);
static LayoutBlockFlow* CreateFileUploadControl(Node& node,
const ComputedStyle& style,
@@ -72,6 +81,19 @@ class LayoutObjectFactory {
static LayoutRubyAsBlock* CreateRubyAsBlock(Node* node,
const ComputedStyle& style,
LegacyLayout legacy);
+
+ // Anonoymous creation methods
+
+ static LayoutBox* CreateAnonymousTableWithParent(const LayoutObject& parent);
+
+ static LayoutBox* CreateAnonymousTableSectionWithParent(
+ const LayoutObject& parent);
+
+ static LayoutBox* CreateAnonymousTableRowWithParent(
+ const LayoutObject& parent);
+
+ static LayoutBlockFlow* CreateAnonymousTableCellWithParent(
+ const LayoutObject& parent);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_object_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_object_test.cc
index 5d06f5326ac..1b1799977a0 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_object_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_object_test.cc
@@ -86,13 +86,140 @@ TEST_F(LayoutObjectTest, DisplayInlineBlockCreateObject) {
EXPECT_TRUE(layout_object->IsInline());
}
+TEST_F(LayoutObjectTest, BackdropFilterAsGroupingProperty) {
+ ScopedTransformInteropForTest enabled(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <style> div { transform-style: preserve-3d; } </style>
+ <div id=target1 style="backdrop-filter: blur(2px)"></div>
+ <div id=target2 style="will-change: backdrop-filter"></div>
+ <div id=target3 style="position: relative"></div>
+ )HTML");
+ EXPECT_TRUE(GetLayoutObjectByElementId("target1")
+ ->StyleRef()
+ .HasGroupingPropertyForUsedTransformStyle3D());
+ EXPECT_TRUE(GetLayoutObjectByElementId("target2")
+ ->StyleRef()
+ .HasGroupingPropertyForUsedTransformStyle3D());
+ EXPECT_FALSE(GetLayoutObjectByElementId("target1")->StyleRef().Preserves3D());
+ EXPECT_FALSE(GetLayoutObjectByElementId("target2")->StyleRef().Preserves3D());
+
+ EXPECT_FALSE(GetLayoutObjectByElementId("target3")
+ ->StyleRef()
+ .HasGroupingPropertyForUsedTransformStyle3D());
+ EXPECT_TRUE(GetLayoutObjectByElementId("target3")->StyleRef().Preserves3D());
+}
+
+TEST_F(LayoutObjectTest, BlendModeAsGroupingProperty) {
+ ScopedTransformInteropForTest enabled(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <style> div { transform-style: preserve-3d; } </style>
+ <div id=target1 style="mix-blend-mode: multiply"></div>
+ <div id=target2 style="position: relative"></div>
+ )HTML");
+ EXPECT_TRUE(GetLayoutObjectByElementId("target1")
+ ->StyleRef()
+ .HasGroupingPropertyForUsedTransformStyle3D());
+ EXPECT_FALSE(GetLayoutObjectByElementId("target1")->StyleRef().Preserves3D());
+
+ EXPECT_FALSE(GetLayoutObjectByElementId("target2")
+ ->StyleRef()
+ .HasGroupingPropertyForUsedTransformStyle3D());
+ EXPECT_TRUE(GetLayoutObjectByElementId("target2")->StyleRef().Preserves3D());
+}
+
+TEST_F(LayoutObjectTest, CSSClipAsGroupingProperty) {
+ ScopedTransformInteropForTest enabled(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <style> div { transform-style: preserve-3d; } </style>
+ <div id=target1 style="clip: rect(1px, 2px, 3px, 4px)"></div>
+ <div id=target2 style="position: absolute; clip: rect(1px, 2px, 3px, 4px)">
+ </div>
+ <div id=target3 style="position: relative"></div>
+ )HTML");
+ EXPECT_FALSE(GetLayoutObjectByElementId("target1")
+ ->StyleRef()
+ .HasGroupingPropertyForUsedTransformStyle3D());
+ EXPECT_TRUE(GetLayoutObjectByElementId("target1")->StyleRef().Preserves3D());
+ EXPECT_TRUE(GetLayoutObjectByElementId("target2")
+ ->StyleRef()
+ .HasGroupingPropertyForUsedTransformStyle3D());
+ EXPECT_FALSE(GetLayoutObjectByElementId("target2")->StyleRef().Preserves3D());
+
+ EXPECT_FALSE(GetLayoutObjectByElementId("target3")
+ ->StyleRef()
+ .HasGroupingPropertyForUsedTransformStyle3D());
+ EXPECT_TRUE(GetLayoutObjectByElementId("target3")->StyleRef().Preserves3D());
+}
+
+TEST_F(LayoutObjectTest, ClipPathAsGroupingProperty) {
+ ScopedTransformInteropForTest enabled(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <style> div { transform-style: preserve-3d; } </style>
+ <div id=target1 style="clip-path: circle(40%)"></div>
+ <div id=target2 style="position: relative"></div>
+ )HTML");
+ EXPECT_TRUE(GetLayoutObjectByElementId("target1")
+ ->StyleRef()
+ .HasGroupingPropertyForUsedTransformStyle3D());
+ EXPECT_FALSE(GetLayoutObjectByElementId("target1")->StyleRef().Preserves3D());
+
+ EXPECT_FALSE(GetLayoutObjectByElementId("target2")
+ ->StyleRef()
+ .HasGroupingPropertyForUsedTransformStyle3D());
+ EXPECT_TRUE(GetLayoutObjectByElementId("target2")->StyleRef().Preserves3D());
+}
+
+TEST_F(LayoutObjectTest, IsolationAsGroupingProperty) {
+ ScopedTransformInteropForTest enabled(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <style> div { transform-style: preserve-3d; } </style>
+ <div id=target1 style="isolation: isolate"></div>
+ <div id=target2 style="position: relative"></div>
+ )HTML");
+ EXPECT_TRUE(GetLayoutObjectByElementId("target1")
+ ->StyleRef()
+ .HasGroupingPropertyForUsedTransformStyle3D());
+ EXPECT_FALSE(GetLayoutObjectByElementId("target1")->StyleRef().Preserves3D());
+
+ EXPECT_FALSE(GetLayoutObjectByElementId("target2")
+ ->StyleRef()
+ .HasGroupingPropertyForUsedTransformStyle3D());
+ EXPECT_TRUE(GetLayoutObjectByElementId("target2")->StyleRef().Preserves3D());
+}
+
+TEST_F(LayoutObjectTest, MaskAsGroupingProperty) {
+ ScopedTransformInteropForTest enabled(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <style> div { transform-style: preserve-3d; } </style>
+ <div id=target1 style="-webkit-mask:linear-gradient(black,transparent)">
+ </div>
+ <div id=target2 style="position: relative"></div>
+ )HTML");
+ EXPECT_TRUE(GetLayoutObjectByElementId("target1")
+ ->StyleRef()
+ .HasGroupingPropertyForUsedTransformStyle3D());
+ EXPECT_FALSE(GetLayoutObjectByElementId("target1")->StyleRef().Preserves3D());
+
+ EXPECT_FALSE(GetLayoutObjectByElementId("target2")
+ ->StyleRef()
+ .HasGroupingPropertyForUsedTransformStyle3D());
+ EXPECT_TRUE(GetLayoutObjectByElementId("target2")->StyleRef().Preserves3D());
+}
+
TEST_F(LayoutObjectTest, UseCountBackdropFilterAsGroupingProperty) {
SetBodyInnerHTML(R"HTML(
<style> div { transform-style: preserve-3d; } </style>
<div id=target style="backdrop-filter: blur(2px)"></div>
)HTML");
- EXPECT_FALSE(
- GetLayoutObjectByElementId("target")->StyleRef().HasGroupingProperty());
+ EXPECT_FALSE(GetLayoutObjectByElementId("target")
+ ->StyleRef()
+ .HasGroupingPropertyForUsedTransformStyle3D());
EXPECT_TRUE(GetDocument().IsUseCounted(
WebFeature::kAdditionalGroupingPropertiesForCompat));
}
@@ -169,6 +296,20 @@ TEST_F(
EXPECT_EQ(PhysicalOffset(2, 10), offset);
}
+TEST_F(LayoutObjectTest, ContainingBlockFixedPosUnderFlattened3DWithInterop) {
+ ScopedTransformInteropForTest enabled(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <div id=container style='transform-style: preserve-3d; opacity: 0.9'>
+ <div id=target style='position:fixed'></div>
+ </div>
+ )HTML");
+
+ LayoutObject* target = GetLayoutObjectByElementId("target");
+ LayoutObject* container = GetLayoutObjectByElementId("container");
+ EXPECT_EQ(container, target->Container());
+}
+
TEST_F(LayoutObjectTest, ContainingBlockFixedLayoutObjectInTransformedDiv) {
SetBodyInnerHTML(R"HTML(
<div style='transform:translateX(0px)'>
@@ -1117,4 +1258,69 @@ TEST_F(LayoutObjectTest, NeedsLayoutOverflowRecalc) {
EXPECT_FALSE(other->NeedsLayoutOverflowRecalc());
}
+TEST_F(LayoutObjectTest, ContainValueIsRelayoutBoundary) {
+ SetBodyInnerHTML(R"HTML(
+ <div id='target1' style='contain:layout'></div>
+ <div id='target2' style='contain:layout size'></div>
+ <div id='target3' style='contain:paint'></div>
+ <div id='target4' style='contain:size'></div>
+ <div id='target5' style='contain:content'></div>
+ <div id='target6' style='contain:strict'></div>
+ )HTML");
+ EXPECT_FALSE(GetLayoutObjectByElementId("target1")->IsRelayoutBoundary());
+ EXPECT_TRUE(GetLayoutObjectByElementId("target2")->IsRelayoutBoundary());
+ EXPECT_FALSE(GetLayoutObjectByElementId("target3")->IsRelayoutBoundary());
+ EXPECT_FALSE(GetLayoutObjectByElementId("target4")->IsRelayoutBoundary());
+ EXPECT_FALSE(GetLayoutObjectByElementId("target5")->IsRelayoutBoundary());
+ EXPECT_TRUE(GetLayoutObjectByElementId("target6")->IsRelayoutBoundary());
+}
+
+TEST_F(LayoutObjectTest, PerspectiveIsNotParent) {
+ ScopedTransformInteropForTest enabled(true);
+
+ GetDocument().SetBaseURLOverride(KURL("http://test.com"));
+ SetBodyInnerHTML(R"HTML(
+ <style>body { margin:0; }</style>
+ <div id='ancestor' style='perspective: 100px'>
+ <div>
+ <div id='child' style='width: 10px; height: 10px; transform: rotateY(45deg);
+ position: absolute'></div>
+ </div>
+ </div>
+ )HTML");
+
+ auto* ancestor =
+ ToLayoutBox(GetDocument().getElementById("ancestor")->GetLayoutObject());
+ auto* child =
+ ToLayoutBox(GetDocument().getElementById("child")->GetLayoutObject());
+
+ TransformationMatrix transform;
+ child->GetTransformFromContainer(ancestor, PhysicalOffset(), transform);
+ TransformationMatrix::DecomposedType decomposed;
+ EXPECT_TRUE(transform.Decompose(decomposed));
+ EXPECT_EQ(0, decomposed.perspective_z);
+}
+
+TEST_F(LayoutObjectTest, PerspectiveWithAnonymousTable) {
+ ScopedTransformInteropForTest enabled(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <style>body { margin:0; }</style>
+ <div id='ancestor' style='display: table; perspective: 100px; width: 100px; height: 100px;'>
+ <div id='child' style='display: table-cell; width: 100px; height: 100px; transform: rotateY(45deg);
+ position: absolute'></div>
+ </table>
+ )HTML");
+
+ LayoutObject* child = GetLayoutObjectByElementId("child");
+ LayoutBoxModelObject* ancestor =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("ancestor"));
+
+ TransformationMatrix transform;
+ child->GetTransformFromContainer(ancestor, PhysicalOffset(), transform);
+ TransformationMatrix::DecomposedType decomposed;
+ EXPECT_TRUE(transform.Decompose(decomposed));
+ EXPECT_EQ(-0.01, decomposed.perspective_z);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_outside_list_marker.cc b/chromium/third_party/blink/renderer/core/layout/layout_outside_list_marker.cc
index 41956979cb9..2d175ec302e 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_outside_list_marker.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_outside_list_marker.cc
@@ -7,7 +7,7 @@
namespace blink {
LayoutOutsideListMarker::LayoutOutsideListMarker(Element* element)
- : LayoutListMarker(element) {}
+ : LayoutBlockFlow(element) {}
LayoutOutsideListMarker::~LayoutOutsideListMarker() = default;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_outside_list_marker.h b/chromium/third_party/blink/renderer/core/layout/layout_outside_list_marker.h
index 20ff17c14a8..4893132849e 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_outside_list_marker.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_outside_list_marker.h
@@ -6,27 +6,34 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_OUTSIDE_LIST_MARKER_H_
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/layout/layout_list_marker.h"
+#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
+#include "third_party/blink/renderer/core/layout/list_marker.h"
namespace blink {
// Used to layout the list item's outside marker.
// The LayoutOutsideListMarker always has to be a child of a LayoutListItem.
-class CORE_EXPORT LayoutOutsideListMarker final : public LayoutListMarker {
+class CORE_EXPORT LayoutOutsideListMarker final : public LayoutBlockFlow {
public:
explicit LayoutOutsideListMarker(Element*);
~LayoutOutsideListMarker() override;
const char* GetName() const override { return "LayoutOutsideListMarker"; }
+ const ListMarker& Marker() const { return list_marker_; }
+ ListMarker& Marker() { return list_marker_; }
+
private:
bool IsOfType(LayoutObjectType type) const override {
return type == kLayoutObjectOutsideListMarker ||
- LayoutListMarker::IsOfType(type);
+ LayoutBlockFlow::IsOfType(type);
}
+
+ ListMarker list_marker_;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutOutsideListMarker, IsOutsideListMarker());
+DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutOutsideListMarker,
+ IsOutsideListMarkerForCustomContent());
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_quote.cc b/chromium/third_party/blink/renderer/core/layout/layout_quote.cc
index 19e6bc05abf..7d50dce6526 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_quote.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_quote.cc
@@ -238,8 +238,24 @@ const QuotesData* QuotesDataForLanguage(const AtomicString& lang) {
std::string lowercase_lang = lang.LowerASCII().Utf8();
Language key = {lowercase_lang.c_str(), 0, 0, 0, 0, nullptr};
Language* match = std::lower_bound(g_languages, languages_end, key);
- if (match == languages_end || strcmp(match->lang, key.lang))
- return nullptr;
+
+ if (match == languages_end)
+ --match;
+
+ if (strcmp(match->lang, key.lang)) {
+ // No exact match, try to find without subtags.
+ std::size_t hyphen_offset = lowercase_lang.find('-');
+ if (hyphen_offset == std::string::npos)
+ return nullptr;
+
+ std::string locale = lowercase_lang.substr(0, hyphen_offset);
+ while (match != g_languages && strcmp(match->lang, locale.c_str()) > 0) {
+ --match;
+ }
+
+ if (strcmp(match->lang, locale.c_str()))
+ return nullptr;
+ }
if (!match->data) {
auto data = QuotesData::Create(match->open1, match->close1, match->open2,
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_replaced.cc b/chromium/third_party/blink/renderer/core/layout/layout_replaced.cc
index e5b86b519aa..b8b149fb585 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_replaced.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_replaced.cc
@@ -148,7 +148,7 @@ bool LayoutReplaced::NeedsPreferredWidthsRecalculation() const {
return HasRelativeLogicalHeight() && StyleRef().LogicalWidth().IsAuto();
}
-static inline bool LayoutObjectHasAspectRatio(
+static inline bool LayoutObjectHasIntrinsicAspectRatio(
const LayoutObject* layout_object) {
DCHECK(layout_object);
return layout_object->IsImage() || layout_object->IsCanvas() ||
@@ -695,16 +695,21 @@ void LayoutReplaced::ComputeIntrinsicSizingInfo(
intrinsic_sizing_info.size = FloatSize(IntrinsicLogicalWidth().ToFloat(),
IntrinsicLogicalHeight().ToFloat());
+ if (const base::Optional<IntSize>& aspect_ratio = StyleRef().AspectRatio()) {
+ intrinsic_sizing_info.aspect_ratio.SetWidth(aspect_ratio->Width());
+ intrinsic_sizing_info.aspect_ratio.SetHeight(aspect_ratio->Height());
+ return;
+ }
+
// Figure out if we need to compute an intrinsic ratio.
- if (!LayoutObjectHasAspectRatio(this))
+ if (!LayoutObjectHasIntrinsicAspectRatio(this))
return;
if (!intrinsic_sizing_info.size.IsEmpty())
intrinsic_sizing_info.aspect_ratio = intrinsic_sizing_info.size;
auto* elem = DynamicTo<Element>(GetNode());
- if (RuntimeEnabledFeatures::AspectRatioFromWidthAndHeightEnabled() && elem &&
- IsA<HTMLImageElement>(elem) &&
+ if (elem && IsA<HTMLImageElement>(elem) &&
intrinsic_sizing_info.aspect_ratio.IsEmpty() &&
elem->FastHasAttribute(html_names::kWidthAttr) &&
elem->FastHasAttribute(html_names::kHeightAttr)) {
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_ruby_run.cc b/chromium/third_party/blink/renderer/core/layout/layout_ruby_run.cc
index 9b86bda50b0..99a16581dcd 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_ruby_run.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_ruby_run.cc
@@ -246,8 +246,10 @@ void LayoutRubyRun::UpdateLayout() {
last_line_ruby_text_bottom = root_box->LogicalBottomLayoutOverflow();
}
- if (StyleRef().IsFlippedLinesWritingMode() ==
- (StyleRef().GetRubyPosition() == RubyPosition::kAfter)) {
+ RubyPosition block_start_position = StyleRef().IsFlippedLinesWritingMode()
+ ? RubyPosition::kAfter
+ : RubyPosition::kBefore;
+ if (StyleRef().GetRubyPosition() == block_start_position) {
LayoutUnit first_line_top;
if (LayoutRubyBase* rb = RubyBase()) {
RootInlineBox* root_box = rb->FirstRootBox();
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_ruby_text.cc b/chromium/third_party/blink/renderer/core/layout/layout_ruby_text.cc
index 730b2a35e1c..7c304fdfed0 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_ruby_text.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_ruby_text.cc
@@ -42,6 +42,16 @@ bool LayoutRubyText::IsChildAllowed(LayoutObject* child,
return child->IsInline();
}
+void LayoutRubyText::StyleDidChange(StyleDifference diff,
+ const ComputedStyle* old_style) {
+ if (StyleRef().GetTextAlign() !=
+ ComputedStyleInitialValues::InitialTextAlign()) {
+ UseCounter::Count(GetDocument(),
+ WebFeature::kRubyTextWithNonDefaultTextAlign);
+ }
+ LayoutBlockFlow::StyleDidChange(diff, old_style);
+}
+
ETextAlign LayoutRubyText::TextAlignmentForLine(
bool ends_with_soft_break) const {
ETextAlign text_align = StyleRef().GetTextAlign();
@@ -60,9 +70,10 @@ void LayoutRubyText::AdjustInlineDirectionLineBounds(
LayoutUnit& logical_width) const {
ETextAlign text_align = StyleRef().GetTextAlign();
// FIXME: This check is bogus since user can set the initial value.
- if (text_align != ComputedStyleInitialValues::InitialTextAlign())
+ if (text_align != ComputedStyleInitialValues::InitialTextAlign()) {
return LayoutBlockFlow::AdjustInlineDirectionLineBounds(
expansion_opportunity_count, logical_left, logical_width);
+ }
int max_preferred_logical_width = PreferredLogicalWidths().max_size.ToInt();
if (max_preferred_logical_width >= logical_width)
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_ruby_text.h b/chromium/third_party/blink/renderer/core/layout/layout_ruby_text.h
index 3684bc00e6b..c2f43d613d7 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_ruby_text.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_ruby_text.h
@@ -48,6 +48,9 @@ class LayoutRubyText : public LayoutBlockFlow {
bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;
+ void StyleDidChange(StyleDifference diff,
+ const ComputedStyle* old_style) override;
+
bool CreatesNewFormattingContext() const final {
// Ruby text objects are pushed around after layout, to become flush with
// the associated ruby base. As such, we cannot let floats leak out from
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_shift_tracker.cc b/chromium/third_party/blink/renderer/core/layout/layout_shift_tracker.cc
index dc374a71017..161f755a135 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_shift_tracker.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_shift_tracker.cc
@@ -154,6 +154,11 @@ void LayoutShiftTracker::ObjectShifted(
if (source.IsSVG())
return;
+ if (Element* element = DynamicTo<Element>(source.GetNode())) {
+ if (element->IsSliderThumbElement())
+ return;
+ }
+
const auto root_state = PropertyTreeStateFor(*source.View());
FloatClipRect clip_rect =
@@ -563,7 +568,7 @@ void LayoutShiftTracker::SetLayoutShiftRects(const Vector<IntRect>& int_rects) {
}
}
-void LayoutShiftTracker::Trace(Visitor* visitor) {
+void LayoutShiftTracker::Trace(Visitor* visitor) const {
visitor->Trace(frame_view_);
}
@@ -620,7 +625,7 @@ void ReattachHook::NotifyAttach(const Node& node) {
fragment.SetVisualRect(visual_rect);
}
-void ReattachHook::Trace(Visitor* visitor) {
+void ReattachHook::Trace(Visitor* visitor) const {
visitor->Trace(visual_rects_);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_shift_tracker.h b/chromium/third_party/blink/renderer/core/layout/layout_shift_tracker.h
index fcff32159d9..79ad83d2a56 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_shift_tracker.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_shift_tracker.h
@@ -60,14 +60,14 @@ class CORE_EXPORT LayoutShiftTracker final
base::TimeTicks MostRecentInputTimestamp() {
return most_recent_input_timestamp_;
}
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
// Saves and restores visual rects on layout objects when a layout tree is
// rebuilt by Node::ReattachLayoutTree.
class ReattachHook : public GarbageCollected<ReattachHook> {
public:
ReattachHook() : scope_(nullptr) {}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
class Scope {
public:
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_state.cc b/chromium/third_party/blink/renderer/core/layout/layout_state.cc
index c7258a54f38..4ed2149ee86 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_state.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_state.cc
@@ -57,10 +57,10 @@ LayoutState::LayoutState(LayoutBox& layout_object,
height_offset_for_table_footers_ = next_->HeightOffsetForTableFooters();
layout_object.View()->PushLayoutState(*this);
- if (const AtomicString& named_page = layout_object.StyleRef().Page())
- page_name_ = named_page;
+ if (const AtomicString& page_name = layout_object.StyleRef().Page())
+ input_page_name_ = page_name;
else
- page_name_ = next_->page_name_;
+ input_page_name_ = next_->input_page_name_;
if (layout_object.IsLayoutFlowThread()) {
// Entering a new pagination context.
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_state.h b/chromium/third_party/blink/renderer/core/layout/layout_state.h
index 190e5ba2450..0e0572b125a 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_state.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_state.h
@@ -91,7 +91,11 @@ class LayoutState {
height_offset_for_table_footers_ = offset;
}
- const AtomicString& PageName() const { return page_name_; }
+ // The input page name is the name specified by the element itself, if any. If
+ // the element doesn't specify one, but an ancestor does, return that.
+ // Otherwise it's an empty string. This is the page name that will be used on
+ // all descendants if none of them override it.
+ const AtomicString& InputPageName() const { return input_page_name_; }
const LayoutSize& PaginationOffset() const { return pagination_offset_; }
bool ContainingBlockLogicalWidthChanged() const {
@@ -131,7 +135,7 @@ class LayoutState {
// paginated layout.
LayoutUnit height_offset_for_table_footers_;
- AtomicString page_name_;
+ AtomicString input_page_name_;
LayoutObject& layout_object_;
DISALLOW_COPY_AND_ASSIGN(LayoutState);
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_table.cc b/chromium/third_party/blink/renderer/core/layout/layout_table.cc
index 2b41ff4843e..4d25549e08d 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table.cc
@@ -32,6 +32,7 @@
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_analyzer.h"
+#include "third_party/blink/renderer/core/layout/layout_object_factory.h"
#include "third_party/blink/renderer/core/layout/layout_table_caption.h"
#include "third_party/blink/renderer/core/layout/layout_table_cell.h"
#include "third_party/blink/renderer/core/layout/layout_table_col.h"
@@ -231,8 +232,8 @@ void LayoutTable::AddChild(LayoutObject* child, LayoutObject* before_child) {
NeedsTableSection(before_child))
before_child = nullptr;
- LayoutTableSection* section =
- LayoutTableSection::CreateAnonymousWithParent(this);
+ LayoutBox* section =
+ LayoutObjectFactory::CreateAnonymousTableSectionWithParent(*this);
AddChild(section, before_child);
section->AddChild(child);
}
@@ -315,7 +316,7 @@ void LayoutTable::UpdateLogicalWidth() {
// might not even get there.
UpdateCachedIntrinsicLogicalWidthsIfNeeded();
- if (IsFlexItemIncludingDeprecatedAndNG() || IsGridItem()) {
+ if (IsGridItem()) {
// TODO(jfernandez): Investigate whether the grid layout algorithm provides
// all the logic needed and that we're not skipping anything essential due
// to the early return here.
@@ -388,6 +389,9 @@ void LayoutTable::UpdateLogicalWidth() {
std::min(available_content_logical_width, max_width).Floor()));
}
+ if (HasOverrideLogicalWidth())
+ SetLogicalWidth(std::max(LogicalWidth(), OverrideLogicalWidth()));
+
// Ensure we aren't bigger than our max-width style.
const Length& style_max_logical_width = StyleRef().LogicalMaxWidth();
if ((style_max_logical_width.IsSpecified() &&
@@ -565,6 +569,7 @@ LayoutUnit LayoutTable::LogicalHeightFromStyle() const {
!logical_max_height_length.IsNegative() &&
!logical_max_height_length.IsMinContent() &&
!logical_max_height_length.IsMaxContent() &&
+ !logical_max_height_length.IsMinIntrinsic() &&
!logical_max_height_length.IsFitContent())) {
LayoutUnit computed_max_logical_height =
ConvertStyleLogicalHeightToComputedHeight(logical_max_height_length);
@@ -575,6 +580,7 @@ LayoutUnit LayoutTable::LogicalHeightFromStyle() const {
Length logical_min_height_length = StyleRef().LogicalMinHeight();
if (logical_min_height_length.IsMinContent() ||
logical_min_height_length.IsMaxContent() ||
+ logical_min_height_length.IsMinIntrinsic() ||
logical_min_height_length.IsFitContent())
logical_min_height_length = Length::Auto();
@@ -1657,16 +1663,9 @@ bool LayoutTable::NodeAtPoint(HitTestResult& result,
return false;
}
-LayoutTable* LayoutTable::CreateAnonymousWithParent(
- const LayoutObject* parent) {
- scoped_refptr<ComputedStyle> new_style =
- ComputedStyle::CreateAnonymousStyleWithDisplay(
- parent->StyleRef(),
- parent->IsLayoutInline() ? EDisplay::kInlineTable : EDisplay::kTable);
- LayoutTable* new_table = new LayoutTable(nullptr);
- new_table->SetDocumentForAnonymous(&parent->GetDocument());
- new_table->SetStyle(std::move(new_style));
- return new_table;
+LayoutBox* LayoutTable::CreateAnonymousBoxWithSameTypeAs(
+ const LayoutObject* parent) const {
+ return LayoutObjectFactory::CreateAnonymousTableWithParent(*parent);
}
void LayoutTable::EnsureIsReadyForPaintInvalidation() {
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_table.h b/chromium/third_party/blink/renderer/core/layout/layout_table.h
index 53978ca750e..2bc9a2f65b5 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table.h
@@ -48,11 +48,11 @@ enum TableHeightChangingValue { kTableHeightNotChanging, kTableHeightChanging };
// LayoutTable is the LayoutObject associated with
// display: table or inline-table.
//
-// LayoutTable is the master coordinator for determining the overall table
-// structure. The reason is that LayoutTableSection children have a local
-// view over what their structure is but don't account for other
-// LayoutTableSection. Thus LayoutTable helps keep consistency across
-// LayoutTableSection. See e.g. |m_effectiveColumns| below.
+// LayoutTable is the coordinator for determining the overall table structure.
+// The reason is that LayoutTableSection children have a local view over what
+// their structure is but don't account for other LayoutTableSection. Thus
+// LayoutTable helps keep consistency across LayoutTableSection. See e.g.
+// |m_effectiveColumns| below.
//
// LayoutTable expects only 3 types of children:
// - zero or more LayoutTableCol
@@ -378,11 +378,8 @@ class CORE_EXPORT LayoutTable final : public LayoutBlock,
RecalcSections();
}
- static LayoutTable* CreateAnonymousWithParent(const LayoutObject*);
LayoutBox* CreateAnonymousBoxWithSameTypeAs(
- const LayoutObject* parent) const override {
- return CreateAnonymousWithParent(parent);
- }
+ const LayoutObject* parent) const override;
void AddCaption(const LayoutTableCaption*);
void RemoveCaption(const LayoutTableCaption*);
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_table_cell.cc b/chromium/third_party/blink/renderer/core/layout/layout_table_cell.cc
index 7d041319196..5e51751b0b4 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table_cell.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table_cell.cc
@@ -1154,23 +1154,16 @@ LayoutTableCell* LayoutTableCell::CreateAnonymous(
Document* document,
scoped_refptr<ComputedStyle> style,
LegacyLayout legacy) {
- LayoutTableCell* layout_object =
+ LayoutBlockFlow* layout_object =
LayoutObjectFactory::CreateTableCell(*document, *style, legacy);
layout_object->SetDocumentForAnonymous(document);
layout_object->SetStyle(std::move(style));
- return layout_object;
+ return To<LayoutTableCell>(layout_object);
}
-LayoutTableCell* LayoutTableCell::CreateAnonymousWithParent(
- const LayoutObject* parent) {
- scoped_refptr<ComputedStyle> new_style =
- ComputedStyle::CreateAnonymousStyleWithDisplay(parent->StyleRef(),
- EDisplay::kTableCell);
- LegacyLayout legacy =
- parent->ForceLegacyLayout() ? LegacyLayout::kForce : LegacyLayout::kAuto;
- LayoutTableCell* new_cell = LayoutTableCell::CreateAnonymous(
- &parent->GetDocument(), std::move(new_style), legacy);
- return new_cell;
+LayoutBox* LayoutTableCell::CreateAnonymousBoxWithSameTypeAs(
+ const LayoutObject* parent) const {
+ return LayoutObjectFactory::CreateAnonymousTableCellWithParent(*parent);
}
bool LayoutTableCell::BackgroundIsKnownToBeOpaqueInRect(
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_table_cell.h b/chromium/third_party/blink/renderer/core/layout/layout_table_cell.h
index b2f2dd196e5..9a5454b5177 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table_cell.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table_cell.h
@@ -241,11 +241,9 @@ class CORE_EXPORT LayoutTableCell : public LayoutBlockFlow,
static LayoutTableCell* CreateAnonymous(Document*,
scoped_refptr<ComputedStyle>,
LegacyLayout);
- static LayoutTableCell* CreateAnonymousWithParent(const LayoutObject*);
+
LayoutBox* CreateAnonymousBoxWithSameTypeAs(
- const LayoutObject* parent) const override {
- return CreateAnonymousWithParent(parent);
- }
+ const LayoutObject* parent) const override;
// The table's style determines cell order and cell adjacency in the table.
// Collapsed borders also use in table's inline and block directions.
@@ -378,7 +376,9 @@ class CORE_EXPORT LayoutTableCell : public LayoutBlockFlow,
protected:
bool IsOfType(LayoutObjectType type) const override {
- return type == kLayoutObjectTableCell || LayoutBlockFlow::IsOfType(type);
+ return type == kLayoutObjectTableCell ||
+ type == kLayoutObjectTableCellLegacy ||
+ LayoutBlockFlow::IsOfType(type);
}
private:
@@ -551,7 +551,7 @@ inline LayoutTableCell* LayoutTableRow::LastCell() const {
template <>
struct DowncastTraits<LayoutTableCell> {
static bool AllowFrom(const LayoutObject& object) {
- return object.IsTableCell();
+ return object.IsTableCellLegacy();
}
};
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_table_cell_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_table_cell_test.cc
index 0826849fc2e..8ebdfc8baf1 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table_cell_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table_cell_test.cc
@@ -30,8 +30,12 @@
namespace blink {
-class LayoutTableCellDeathTest : public RenderingTest {
+class LayoutTableCellDeathTest : public RenderingTest,
+ public ScopedLayoutNGTableForTest {
protected:
+ // These tests test Legacy behavior only.
+ LayoutTableCellDeathTest() : ScopedLayoutNGTableForTest(false) {}
+
void SetUp() override {
RenderingTest::SetUp();
auto style = ComputedStyle::Create();
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_table_row.cc b/chromium/third_party/blink/renderer/core/layout/layout_table_row.cc
index 8dbea5af6e8..5cb289c9343 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table_row.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table_row.cc
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_analyzer.h"
+#include "third_party/blink/renderer/core/layout/layout_object_factory.h"
#include "third_party/blink/renderer/core/layout/layout_state.h"
#include "third_party/blink/renderer/core/layout/layout_table_cell.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
@@ -154,7 +155,8 @@ void LayoutTableRow::AddChild(LayoutObject* child, LayoutObject* before_child) {
return;
}
- LayoutTableCell* cell = LayoutTableCell::CreateAnonymousWithParent(this);
+ LayoutBlockFlow* cell =
+ LayoutObjectFactory::CreateAnonymousTableCellWithParent(*this);
AddChild(cell, before_child);
cell->AddChild(child);
return;
@@ -284,15 +286,9 @@ LayoutTableRow* LayoutTableRow::CreateAnonymous(Document* document) {
return layout_object;
}
-LayoutTableRow* LayoutTableRow::CreateAnonymousWithParent(
- const LayoutObject* parent) {
- LayoutTableRow* new_row =
- LayoutTableRow::CreateAnonymous(&parent->GetDocument());
- scoped_refptr<ComputedStyle> new_style =
- ComputedStyle::CreateAnonymousStyleWithDisplay(parent->StyleRef(),
- EDisplay::kTableRow);
- new_row->SetStyle(std::move(new_style));
- return new_row;
+LayoutBox* LayoutTableRow::CreateAnonymousBoxWithSameTypeAs(
+ const LayoutObject* parent) const {
+ return LayoutObjectFactory::CreateAnonymousTableRowWithParent(*parent);
}
void LayoutTableRow::ComputeLayoutOverflow() {
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_table_row.h b/chromium/third_party/blink/renderer/core/layout/layout_table_row.h
index 82feffcf220..eba5cbb37c0 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table_row.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table_row.h
@@ -84,11 +84,8 @@ class CORE_EXPORT LayoutTableRow final : public LayoutTableBoxComponent,
}
static LayoutTableRow* CreateAnonymous(Document*);
- static LayoutTableRow* CreateAnonymousWithParent(const LayoutObject*);
LayoutBox* CreateAnonymousBoxWithSameTypeAs(
- const LayoutObject* parent) const override {
- return CreateAnonymousWithParent(parent);
- }
+ const LayoutObject* parent) const override;
void SetRowIndex(unsigned row_index) {
CHECK_LE(row_index, kMaxRowIndex);
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_table_section.cc b/chromium/third_party/blink/renderer/core/layout/layout_table_section.cc
index c67288cb774..9ad149a9ea2 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table_section.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table_section.cc
@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_analyzer.h"
+#include "third_party/blink/renderer/core/layout/layout_object_factory.h"
#include "third_party/blink/renderer/core/layout/layout_table_cell.h"
#include "third_party/blink/renderer/core/layout/layout_table_col.h"
#include "third_party/blink/renderer/core/layout/layout_table_row.h"
@@ -173,7 +174,8 @@ void LayoutTableSection::AddChild(LayoutObject* child,
return;
}
- LayoutObject* row = LayoutTableRow::CreateAnonymousWithParent(this);
+ LayoutObject* row =
+ LayoutObjectFactory::CreateAnonymousTableRowWithParent(*this);
AddChild(row, before_child);
row->AddChild(child);
return;
@@ -1868,15 +1870,9 @@ bool LayoutTableSection::NodeAtPoint(HitTestResult& result,
return false;
}
-LayoutTableSection* LayoutTableSection::CreateAnonymousWithParent(
- const LayoutObject* parent) {
- scoped_refptr<ComputedStyle> new_style =
- ComputedStyle::CreateAnonymousStyleWithDisplay(parent->StyleRef(),
- EDisplay::kTableRowGroup);
- LayoutTableSection* new_section = new LayoutTableSection(nullptr);
- new_section->SetDocumentForAnonymous(&parent->GetDocument());
- new_section->SetStyle(std::move(new_style));
- return new_section;
+LayoutBox* LayoutTableSection::CreateAnonymousBoxWithSameTypeAs(
+ const LayoutObject* parent) const {
+ return LayoutObjectFactory::CreateAnonymousTableSectionWithParent(*parent);
}
void LayoutTableSection::SetLogicalPositionForCell(
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_table_section.h b/chromium/third_party/blink/renderer/core/layout/layout_table_section.h
index 2e3495ce6e3..4731fd7b088 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table_section.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table_section.h
@@ -232,11 +232,8 @@ class CORE_EXPORT LayoutTableSection final
// information.
int DistributeExtraLogicalHeightToRows(int extra_logical_height);
- static LayoutTableSection* CreateAnonymousWithParent(const LayoutObject*);
LayoutBox* CreateAnonymousBoxWithSameTypeAs(
- const LayoutObject* parent) const override {
- return CreateAnonymousWithParent(parent);
- }
+ const LayoutObject* parent) const override;
void Paint(const PaintInfo&) const override;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_text.cc b/chromium/third_party/blink/renderer/core/layout/layout_text.cc
index 6e6add82e13..b418493f056 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text.cc
@@ -1757,69 +1757,71 @@ void LayoutText::SetTextWithOffset(scoped_refptr<StringImpl> text,
int delta = new_len - old_len;
unsigned end = len ? offset + len - 1 : offset;
- RootInlineBox* first_root_box = nullptr;
- RootInlineBox* last_root_box = nullptr;
-
bool dirtied_lines = false;
- // Dirty all text boxes that include characters in between offset and
- // offset+len.
- for (InlineTextBox* curr : TextBoxes()) {
- // FIXME: This shouldn't rely on the end of a dirty line box. See
- // https://bugs.webkit.org/show_bug.cgi?id=97264
- // Text run is entirely before the affected range.
- if (curr->end() < offset)
- continue;
+ if (!IsInLayoutNGInlineFormattingContext()) {
+ RootInlineBox* first_root_box = nullptr;
+ RootInlineBox* last_root_box = nullptr;
+
+ // Dirty all text boxes that include characters in between offset and
+ // offset+len.
+ for (InlineTextBox* curr : TextBoxes()) {
+ // FIXME: This shouldn't rely on the end of a dirty line box. See
+ // https://bugs.webkit.org/show_bug.cgi?id=97264
+ // Text run is entirely before the affected range.
+ if (curr->end() < offset)
+ continue;
- // Text run is entirely after the affected range.
- if (curr->Start() > end) {
- curr->OffsetRun(delta);
- RootInlineBox* root = &curr->Root();
- if (!first_root_box) {
- first_root_box = root;
- // The affected area was in between two runs. Go ahead and mark the root
- // box of the run after the affected area as dirty.
- first_root_box->MarkDirty();
+ // Text run is entirely after the affected range.
+ if (curr->Start() > end) {
+ curr->OffsetRun(delta);
+ RootInlineBox* root = &curr->Root();
+ if (!first_root_box) {
+ first_root_box = root;
+ // The affected area was in between two runs. Go ahead and mark the
+ // root box of the run after the affected area as dirty.
+ first_root_box->MarkDirty();
+ dirtied_lines = true;
+ }
+ last_root_box = root;
+ } else if (curr->end() >= offset && curr->end() <= end) {
+ // Text run overlaps with the left end of the affected range.
+ curr->DirtyLineBoxes();
+ dirtied_lines = true;
+ } else if (curr->Start() <= offset && curr->end() >= end) {
+ // Text run subsumes the affected range.
+ curr->DirtyLineBoxes();
+ dirtied_lines = true;
+ } else if (curr->Start() <= end && curr->end() >= end) {
+ // Text run overlaps with right end of the affected range.
+ curr->DirtyLineBoxes();
dirtied_lines = true;
}
- last_root_box = root;
- } else if (curr->end() >= offset && curr->end() <= end) {
- // Text run overlaps with the left end of the affected range.
- curr->DirtyLineBoxes();
- dirtied_lines = true;
- } else if (curr->Start() <= offset && curr->end() >= end) {
- // Text run subsumes the affected range.
- curr->DirtyLineBoxes();
- dirtied_lines = true;
- } else if (curr->Start() <= end && curr->end() >= end) {
- // Text run overlaps with right end of the affected range.
- curr->DirtyLineBoxes();
- dirtied_lines = true;
}
- }
- // Now we have to walk all of the clean lines and adjust their cached line
- // break information to reflect our updated offsets.
- if (last_root_box)
- last_root_box = last_root_box->NextRootBox();
- if (first_root_box) {
- RootInlineBox* prev = first_root_box->PrevRootBox();
- if (prev)
- first_root_box = prev;
- } else if (LastTextBox()) {
- DCHECK(!last_root_box);
- first_root_box = &LastTextBox()->Root();
- first_root_box->MarkDirty();
- dirtied_lines = true;
- }
- for (RootInlineBox* curr = first_root_box; curr && curr != last_root_box;
- curr = curr->NextRootBox()) {
- if (curr->LineBreakObj().IsEqual(this) && curr->LineBreakPos() > end)
- curr->SetLineBreakPos(clampTo<int>(curr->LineBreakPos() + delta));
+ // Now we have to walk all of the clean lines and adjust their cached line
+ // break information to reflect our updated offsets.
+ if (last_root_box)
+ last_root_box = last_root_box->NextRootBox();
+ if (first_root_box) {
+ RootInlineBox* prev = first_root_box->PrevRootBox();
+ if (prev)
+ first_root_box = prev;
+ } else if (LastTextBox()) {
+ DCHECK(!last_root_box);
+ first_root_box = &LastTextBox()->Root();
+ first_root_box->MarkDirty();
+ dirtied_lines = true;
+ }
+ for (RootInlineBox* curr = first_root_box; curr && curr != last_root_box;
+ curr = curr->NextRootBox()) {
+ if (curr->LineBreakObj().IsEqual(this) && curr->LineBreakPos() > end)
+ curr->SetLineBreakPos(clampTo<int>(curr->LineBreakPos() + delta));
+ }
}
// If the text node is empty, dirty the line where new text will be inserted.
- if (!FirstTextBox() && Parent()) {
+ if (!HasInlineFragments() && Parent()) {
Parent()->DirtyLinesFromChangedChild(this);
dirtied_lines = true;
}
@@ -2492,24 +2494,22 @@ void LayoutText::InvalidateDisplayItemClients(
PaintInvalidationReason invalidation_reason) const {
ObjectPaintInvalidator paint_invalidator(*this);
- if (RuntimeEnabledFeatures::LayoutNGBlockFragmentationEnabled() &&
- !RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
- auto fragments = NGPaintFragment::InlineFragmentsFor(this);
- if (fragments.IsInLayoutNGInlineFormattingContext()) {
- for (NGPaintFragment* fragment : fragments) {
- paint_invalidator.InvalidateDisplayItemClient(*fragment,
- invalidation_reason);
+ if (IsInLayoutNGInlineFormattingContext()) {
+ if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ NGInlineCursor cursor;
+ for (cursor.MoveTo(*this); cursor;
+ cursor.MoveToNextForSameLayoutObject()) {
+ paint_invalidator.InvalidateDisplayItemClient(
+ *cursor.Current().GetDisplayItemClient(), invalidation_reason);
}
return;
}
- }
-
- if (IsInLayoutNGInlineFormattingContext()) {
+#if DCHECK_IS_ON()
NGInlineCursor cursor;
- for (cursor.MoveTo(*this); cursor; cursor.MoveToNextForSameLayoutObject()) {
- paint_invalidator.InvalidateDisplayItemClient(
- *cursor.Current().GetDisplayItemClient(), invalidation_reason);
- }
+ for (cursor.MoveTo(*this); cursor; cursor.MoveToNextForSameLayoutObject())
+ DCHECK_EQ(cursor.Current().GetDisplayItemClient(), this);
+#endif
+ paint_invalidator.InvalidateDisplayItemClient(*this, invalidation_reason);
return;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_text_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_text_test.cc
index ec907acd7fa..62de1f9355e 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text_test.cc
@@ -66,6 +66,30 @@ class LayoutTextTest : public RenderingTest {
target ? target->GetLayoutObject() : FindFirstLayoutText();
return layout_object->LocalSelectionVisualRect();
}
+
+ std::string GetSnapCode(const LayoutText& layout_text,
+ const std::string& caret_text) {
+ return GetSnapCode(layout_text, caret_text.find('|'));
+ }
+
+ std::string GetSnapCode(const char* id, const std::string& caret_text) {
+ return GetSnapCode(*GetLayoutTextById(id), caret_text);
+ }
+
+ std::string GetSnapCode(const std::string& caret_text) {
+ return GetSnapCode(*GetBasicText(), caret_text);
+ }
+
+ std::string GetSnapCode(const LayoutText& layout_text, unsigned offset) {
+ std::string result(3, '_');
+ // Note:: |IsBeforeNonCollapsedCharacter()| and |ContainsCaretOffset()|
+ // accept out-of-bound offset but |IsAfterNonCollapsedCharacter()| doesn't.
+ result[0] = layout_text.IsBeforeNonCollapsedCharacter(offset) ? 'B' : '-';
+ result[1] = layout_text.ContainsCaretOffset(offset) ? 'C' : '-';
+ if (offset <= layout_text.TextLength())
+ result[2] = layout_text.IsAfterNonCollapsedCharacter(offset) ? 'A' : '-';
+ return result;
+ }
};
const char kTacoText[] = "Los Compadres Taco Truck";
@@ -81,6 +105,15 @@ class ParameterizedLayoutTextTest : public testing::WithParamInterface<bool>,
bool LayoutNGEnabled() const {
return RuntimeEnabledFeatures::LayoutNGEnabled();
}
+
+ // TODO(yosin): Once we release EditingNG, this function is used for
+ // specifying legacy specific behavior.
+ const char* ValueWithLegacy(const char* ng_text,
+ const char* legacy_text,
+ const char* reason) {
+ DCHECK_NE(*reason, 0);
+ return LayoutNGEnabled() ? ng_text : legacy_text;
+ }
};
INSTANTIATE_TEST_SUITE_P(All, ParameterizedLayoutTextTest, testing::Bool());
@@ -315,52 +348,269 @@ TEST_P(ParameterizedLayoutTextTest, ResolvedTextLength) {
TEST_P(ParameterizedLayoutTextTest, ContainsCaretOffset) {
// This test records the behavior introduced in crrev.com/e3eb4e
SetBasicBody(" foo bar ");
- EXPECT_FALSE(GetBasicText()->ContainsCaretOffset(0)); // "| foo bar "
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(1)); // " |foo bar "
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(2)); // " f|oo bar "
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(3)); // " fo|o bar "
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(4)); // " foo| bar "
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(5)); // " foo | bar "
- EXPECT_FALSE(GetBasicText()->ContainsCaretOffset(6)); // " foo | bar "
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(7)); // " foo |bar "
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(8)); // " foo b|ar "
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(9)); // " foo ba|r "
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(10)); // " foo bar| "
- EXPECT_FALSE(GetBasicText()->ContainsCaretOffset(11)); // " foo bar |"
- EXPECT_FALSE(GetBasicText()->ContainsCaretOffset(12)); // out of range
+ // text_content = "foo bar"
+ // offset mapping unit:
+ // [0] = C DOM:0-1 TC:0-0
+ // [1] = I DOM:1-5 TC:0-4 "foo "
+ // [2] = C DOM:5-7 TC:4-4
+ // [3] = I DOM:7-10 TC:4-7 "bar"
+ // [4] = C DOM:10-11 TC:7-7
+ EXPECT_EQ("---", GetSnapCode("| foo bar "));
+ EXPECT_EQ("BC-", GetSnapCode(" |foo bar "));
+ EXPECT_EQ("BCA", GetSnapCode(" f|oo bar "));
+ EXPECT_EQ("BCA", GetSnapCode(" fo|o bar "));
+ EXPECT_EQ("BCA", GetSnapCode(" foo| bar "));
+ EXPECT_EQ("-CA", GetSnapCode(" foo | bar "));
+ EXPECT_EQ("---", GetSnapCode(" foo | bar "));
+ EXPECT_EQ("BC-", GetSnapCode(" foo |bar "));
+ EXPECT_EQ("BCA", GetSnapCode(" foo b|ar "));
+ EXPECT_EQ("BCA", GetSnapCode(" foo ba|r "));
+ EXPECT_EQ("-CA", GetSnapCode(" foo bar| "));
+ EXPECT_EQ("---", GetSnapCode(" foo bar |"));
+ EXPECT_EQ("--_", GetSnapCode(*GetBasicText(), 12)); // out of range
}
TEST_P(ParameterizedLayoutTextTest, ContainsCaretOffsetInPre) {
// These tests record the behavior introduced in crrev.com/e3eb4e
+ InsertStyleElement("#target {white-space: pre; }");
+
+ SetBasicBody("foo bar");
+ EXPECT_EQ("BC-", GetSnapCode("|foo bar"));
+ EXPECT_EQ("BCA", GetSnapCode("f|oo bar"));
+ EXPECT_EQ("BCA", GetSnapCode("fo|o bar"));
+ EXPECT_EQ("BCA", GetSnapCode("foo| bar"));
+ EXPECT_EQ("BCA", GetSnapCode("foo | bar"));
+ EXPECT_EQ("BCA", GetSnapCode("foo | bar"));
+ EXPECT_EQ("BCA", GetSnapCode("foo |bar"));
+ EXPECT_EQ("BCA", GetSnapCode("foo b|ar"));
+ EXPECT_EQ("BCA", GetSnapCode("foo ba|r"));
+ EXPECT_EQ("-CA", GetSnapCode("foo bar|"));
+
+ SetBasicBody("abc\n");
+ // text_content = "abc\n"
+ // offset mapping unit:
+ // [0] I DOM:0-4 TC:0-4 "abc\n"
+ EXPECT_EQ("BC-", GetSnapCode("|abc\n"));
+ EXPECT_EQ("BCA", GetSnapCode("a|bc\n"));
+ EXPECT_EQ("BCA", GetSnapCode("ab|c\n"));
+ EXPECT_EQ("BCA", GetSnapCode("abc|\n"));
+ EXPECT_EQ("--A", GetSnapCode("abc\n|"));
+
+ SetBasicBody("foo\nbar");
+ EXPECT_EQ("BC-", GetSnapCode("|foo\nbar"));
+ EXPECT_EQ("BCA", GetSnapCode("f|oo\nbar"));
+ EXPECT_EQ("BCA", GetSnapCode("fo|o\nbar"));
+ EXPECT_EQ("BCA", GetSnapCode("foo|\nbar"));
+ EXPECT_EQ("BCA", GetSnapCode("foo\n|bar"));
+ EXPECT_EQ("BCA", GetSnapCode("foo\nb|ar"));
+ EXPECT_EQ("BCA", GetSnapCode("foo\nba|r"));
+ EXPECT_EQ("-CA", GetSnapCode("foo\nbar|"));
+}
- SetBodyInnerHTML("<pre id='target'>foo bar</pre>");
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(0)); // "|foo bar"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(1)); // "f|oo bar"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(2)); // "fo|o bar"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(3)); // "foo| bar"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(4)); // "foo | bar"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(5)); // "foo | bar"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(6)); // "foo |bar"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(7)); // "foo b|ar"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(8)); // "foo ba|r"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(9)); // "foo bar|"
-
- SetBodyInnerHTML("<pre id='target'>foo\n</pre>");
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(0)); // "|foo\n"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(1)); // "f|oo\n"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(2)); // "fo|o\n"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(3)); // "foo|\n"
- EXPECT_FALSE(GetBasicText()->ContainsCaretOffset(4)); // "foo\n|"
-
- SetBodyInnerHTML("<pre id='target'>foo\nbar</pre>");
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(0)); // "|foo\nbar"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(1)); // "f|oo\nbar"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(2)); // "fo|o\nbar"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(3)); // "foo|\nbar"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(4)); // "foo\n|bar"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(5)); // "foo\nb|ar"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(6)); // "foo\nba|r"
- EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(7)); // "foo\nbar|"
+TEST_P(ParameterizedLayoutTextTest, ContainsCaretOffsetInPreLine) {
+ InsertStyleElement("#target {white-space: pre-line; }");
+
+ SetBasicBody("ab \n cd");
+ // text_content = "ab\ncd"
+ // offset mapping unit:
+ // [0] I DOM:0-2 TC:0-2 "ab"
+ // [1] C DOM:2-3 TC:2-2
+ // [2] I DOM:3-4 TC:2-3 "\n"
+ // [3] C DOM:4-5 TC:3-3
+ // [4] I DOM:5-7 TC:3-5 "cd"
+ EXPECT_EQ("BC-", GetSnapCode("|ab \n cd"));
+ EXPECT_EQ("BCA", GetSnapCode("a|b \n cd"));
+ EXPECT_EQ(ValueWithLegacy("-CA", "BCA", "before collapsed trailing space"),
+ GetSnapCode("ab| \n cd"));
+ EXPECT_EQ(ValueWithLegacy("BC-", "BCA", "after first trailing space"),
+ GetSnapCode("ab |\n cd"));
+ EXPECT_EQ(ValueWithLegacy("--A", "B-A", "before collapsed leading space"),
+ GetSnapCode("ab \n| cd"));
+ EXPECT_EQ(ValueWithLegacy("BC-", "BCA", "after collapsed leading space"),
+ GetSnapCode("ab \n |cd"));
+
+ SetBasicBody("ab \n cd");
+ // text_content = "ab\ncd"
+ // offset mapping unit:
+ // [0] I DOM:0-2 TC:0-2 "ab"
+ // [1] C DOM:2-4 TC:2-2
+ // [2] I DOM:4-5 TC:2-3 "\n"
+ // [3] C DOM:5-7 TC:3-3
+ // [4] I DOM:7-9 TC:3-5 "cd"
+ EXPECT_EQ("BC-", GetSnapCode("|ab \n cd"));
+ EXPECT_EQ("BCA", GetSnapCode("a|b \n cd"));
+ EXPECT_EQ(ValueWithLegacy("-CA", "BCA", "before collapsed trailing space"),
+ GetSnapCode("ab| \n cd"));
+ EXPECT_EQ(ValueWithLegacy("---", "-CA", "after first trailing space"),
+ GetSnapCode("ab | \n cd"));
+ EXPECT_EQ(ValueWithLegacy("BC-", "BCA", "after collapsed trailing space"),
+ GetSnapCode("ab |\n cd"));
+ EXPECT_EQ(ValueWithLegacy("--A", "B-A", "before collapsed leading space"),
+ GetSnapCode("ab \n| cd"));
+ EXPECT_EQ(ValueWithLegacy("---", "--A", "after collapsed leading space"),
+ GetSnapCode("ab \n | cd"));
+ EXPECT_EQ("BC-", GetSnapCode("ab \n |cd"));
+ EXPECT_EQ("BCA", GetSnapCode("ab \n c|d"));
+ EXPECT_EQ("-CA", GetSnapCode("ab \n cd|"));
+
+ SetBasicBody("a\n\nb");
+ EXPECT_EQ("BC-", GetSnapCode("|a\n\nb"));
+ EXPECT_EQ("BCA", GetSnapCode("a|\n\nb"));
+ EXPECT_EQ("BCA", GetSnapCode("a\n|\nb"));
+ EXPECT_EQ("BCA", GetSnapCode("a\n\n|b"));
+ EXPECT_EQ("-CA", GetSnapCode("a\n\nb|"));
+
+ SetBasicBody("a \n \n b");
+ // text_content = "a\n\nb"
+ // offset mapping unit:
+ // [0] = I DOM:0-1 TC:0-1 "a"
+ // [1] = C DOM:1-2 TC:1-1
+ // [2] = I DOM:2-3 TC:1-2 "\n"
+ // [3] = C DOM:3-4 TC:2-2
+ // [4] = I DOM:4-5 TC:2-3 "\n"
+ // [5] = C DOM:5-6 TC:3-3
+ // [6] = I DOM:6-7 TC:3-4 "b"
+ EXPECT_EQ("BC-", GetSnapCode("|a \n \n b"));
+ EXPECT_EQ(ValueWithLegacy("-CA", "BCA", "before collapsed trailing space"),
+ GetSnapCode("a| \n \n b"));
+ EXPECT_EQ(ValueWithLegacy("BC-", "BCA", "after first trailing space"),
+ GetSnapCode("a |\n \n b"));
+ EXPECT_EQ(ValueWithLegacy("--A", "B-A", "before leading collapsed space"),
+ GetSnapCode("a \n| \n b"));
+ EXPECT_EQ(ValueWithLegacy("BC-", "BCA", "after first trailing space"),
+ GetSnapCode("a \n |\n b"));
+ EXPECT_EQ(ValueWithLegacy("--A", "B-A", "before collapsed leading space"),
+ GetSnapCode("a \n \n| b"));
+ EXPECT_EQ(ValueWithLegacy("BC-", "BCA", "after collapsed leading space"),
+ GetSnapCode("a \n \n |b"));
+ EXPECT_EQ("-CA", GetSnapCode("a \n \n b|"));
+
+ SetBasicBody("a \n \n b");
+ // text_content = "a\n\nb"
+ // offset mapping unit:
+ // [0] = I DOM:0-1 TC:0-1 "a"
+ // [1] = C DOM:1-2 TC:1-1
+ // [2] = I DOM:2-3 TC:1-2 "\n"
+ // [3] = C DOM:3-5 TC:2-2
+ // [4] = I DOM:5-6 TC:2-3 "\n"
+ // [5] = C DOM:6-7 TC:3-3
+ // [6] = I DOM:7-8 TC:3-4 "b"
+ EXPECT_EQ("BC-", GetSnapCode("|a \n \n b"));
+ EXPECT_EQ(ValueWithLegacy("-CA", "BCA", "before collapsed trailing space"),
+ GetSnapCode("a| \n \n b"));
+ EXPECT_EQ(ValueWithLegacy("BC-", "BCA", "after first trailing space"),
+ GetSnapCode("a |\n \n b"));
+ EXPECT_EQ(ValueWithLegacy("--A", "B-A", "before collapsed leading space"),
+ GetSnapCode("a \n| \n b"));
+ EXPECT_EQ(ValueWithLegacy("---", "--A",
+ "after first trailing and in leading space"),
+ GetSnapCode("a \n | \n b"));
+ EXPECT_EQ("BC-", GetSnapCode("a \n |\n b"));
+ EXPECT_EQ(ValueWithLegacy("--A", "B-A", "before collapsed leading space"),
+ GetSnapCode("a \n \n| b"));
+ EXPECT_EQ(ValueWithLegacy("BC-", "BCA", "after collapsed leading space"),
+ GetSnapCode("a \n \n |b"));
+ EXPECT_EQ("-CA", GetSnapCode("a \n \n b|"));
+}
+
+TEST_P(ParameterizedLayoutTextTest, ContainsCaretOffsetWithTrailingSpace) {
+ SetBodyInnerHTML("<div id=target>ab<br>cd</div>");
+ const LayoutText& text_ab = *GetLayoutTextById("target");
+ const LayoutText& layout_br = *ToLayoutText(text_ab.NextSibling());
+ const LayoutText& text_cd = *ToLayoutText(layout_br.NextSibling());
+
+ EXPECT_EQ("BC-", GetSnapCode(text_ab, "|ab<br>"));
+ EXPECT_EQ("BCA", GetSnapCode(text_ab, "a|b<br>"));
+ EXPECT_EQ("-CA", GetSnapCode(text_ab, "ab|<br>"));
+ EXPECT_EQ("BC-", GetSnapCode(layout_br, 0));
+ EXPECT_EQ("--A", GetSnapCode(layout_br, 1));
+ EXPECT_EQ("BC-", GetSnapCode(text_cd, "|cd"));
+ EXPECT_EQ("BCA", GetSnapCode(text_cd, "c|d"));
+ EXPECT_EQ("-CA", GetSnapCode(text_cd, "cd|"));
+}
+
+TEST_P(ParameterizedLayoutTextTest, ContainsCaretOffsetWithTrailingSpace1) {
+ SetBodyInnerHTML("<div id=target>ab <br> cd</div>");
+ const LayoutText& text_ab = *GetLayoutTextById("target");
+ const LayoutText& layout_br = *ToLayoutText(text_ab.NextSibling());
+ const LayoutText& text_cd = *ToLayoutText(layout_br.NextSibling());
+
+ // text_content = "ab\ncd"
+ // offset mapping unit:
+ // [0] I DOM:0-2 TC:0-2 "ab"
+ // [1] C DOM:2-3 TC:2-2
+ // [2] I DOM:0-1 TC:2-3 "\n" <br>
+ // [3] C DOM:0-1 TC:3-3
+ // [4] I DOM:1-3 TC:3-5 "cd"
+ EXPECT_EQ("BC-", GetSnapCode(text_ab, "|ab <br>"));
+ EXPECT_EQ("BCA", GetSnapCode(text_ab, "a|b <br>"));
+ EXPECT_EQ(ValueWithLegacy("-CA", "BCA", "before after first trailing space"),
+ GetSnapCode(text_ab, "ab| <br>"));
+ EXPECT_EQ(ValueWithLegacy("---", "-CA", "after first trailing space"),
+ GetSnapCode(text_ab, "ab |<br>"));
+ EXPECT_EQ("BC-", GetSnapCode(layout_br, 0));
+ EXPECT_EQ("--A", GetSnapCode(layout_br, 1));
+ EXPECT_EQ("---", GetSnapCode(text_cd, "| cd"));
+ EXPECT_EQ("BC-", GetSnapCode(text_cd, " |cd"));
+ EXPECT_EQ("BCA", GetSnapCode(text_cd, " c|d"));
+ EXPECT_EQ("-CA", GetSnapCode(text_cd, " cd|"));
+}
+
+TEST_P(ParameterizedLayoutTextTest, ContainsCaretOffsetWithTrailingSpace2) {
+ SetBodyInnerHTML("<div id=target>ab <br> cd</div>");
+ const LayoutText& text_ab = *GetLayoutTextById("target");
+ const LayoutText& layout_br = *ToLayoutText(text_ab.NextSibling());
+ const LayoutText& text_cd = *ToLayoutText(layout_br.NextSibling());
+
+ // text_content = "ab\ncd"
+ // offset mapping unit:
+ // [0] I DOM:0-2 TC:0-2 "ab"
+ // [1] C DOM:2-4 TC:2-2
+ // [2] I DOM:0-1 TC:2-3 "\n" <br>
+ // [3] C DOM:0-2 TC:3-3
+ // [4] I DOM:2-4 TC:3-5 "cd"
+ EXPECT_EQ("BC-", GetSnapCode(text_ab, "|ab <br>"));
+ EXPECT_EQ("BCA", GetSnapCode(text_ab, "a|b <br>"));
+ EXPECT_EQ(ValueWithLegacy("-CA", "BCA", "after first trailing space"),
+ GetSnapCode(text_ab, "ab| <br>"));
+ EXPECT_EQ(ValueWithLegacy("---", "-CA", "after first trailing space"),
+ GetSnapCode(text_ab, "ab | <br>"));
+ EXPECT_EQ("---", GetSnapCode(text_ab, "ab |<br>"));
+ EXPECT_EQ(ValueWithLegacy("BC-", "---", "before <br>"),
+ GetSnapCode(layout_br, 0));
+ EXPECT_EQ(ValueWithLegacy("--A", "---", "after <br>"),
+ GetSnapCode(layout_br, 1));
+ EXPECT_EQ("---", GetSnapCode(text_cd, "| cd"));
+ EXPECT_EQ("---", GetSnapCode(text_cd, " | cd"));
+ EXPECT_EQ("BC-", GetSnapCode(text_cd, " |cd"));
+ EXPECT_EQ("BCA", GetSnapCode(text_cd, " c|d"));
+ EXPECT_EQ("-CA", GetSnapCode(text_cd, " cd|"));
+}
+
+TEST_P(ParameterizedLayoutTextTest, ContainsCaretOffsetWithTrailingSpace3) {
+ SetBodyInnerHTML("<div id=target>a<br> <br>b<br></div>");
+ const LayoutText& text_a = *GetLayoutTextById("target");
+ const LayoutText& layout_br1 = *ToLayoutText(text_a.NextSibling());
+ const LayoutText& text_space = *ToLayoutText(layout_br1.NextSibling());
+ EXPECT_EQ(1u, text_space.TextLength());
+ const LayoutText& layout_br2 = *ToLayoutText(text_space.NextSibling());
+ const LayoutText& text_b = *ToLayoutText(layout_br2.NextSibling());
+ // Note: the last <br> doesn't have layout object.
+
+ // text_content = "a\n \nb"
+ // offset mapping unit:
+ // [0] I DOM:0-1 TC:0-1 "a"
+ EXPECT_EQ("BC-", GetSnapCode(text_a, "|a<br>"));
+ EXPECT_EQ("-CA", GetSnapCode(text_a, "a|<br>"));
+ EXPECT_EQ("-CA", GetSnapCode(text_a, "a|<br>"));
+ EXPECT_EQ("BC-", GetSnapCode(layout_br1, 0));
+ EXPECT_EQ("--A", GetSnapCode(layout_br1, 1));
+ EXPECT_EQ("BC-", GetSnapCode(text_space, 0));
+ EXPECT_EQ("--A", GetSnapCode(text_space, 1));
+ EXPECT_EQ("BC-", GetSnapCode(layout_br2, 0));
+ EXPECT_EQ("-CA", GetSnapCode(layout_br2, 1));
+ EXPECT_EQ("BC-", GetSnapCode(text_b, "|b<br>"));
+ EXPECT_EQ("--A", GetSnapCode(text_b, "b|<br>"));
}
TEST_P(ParameterizedLayoutTextTest, GetTextBoxInfoWithCollapsedWhiteSpace) {
@@ -529,110 +779,152 @@ TEST_P(ParameterizedLayoutTextTest,
IsBeforeAfterNonCollapsedCharacterNoLineWrap) {
// Basic tests
SetBasicBody("foo");
- EXPECT_TRUE(GetBasicText()->IsBeforeNonCollapsedCharacter(0)); // "|foo"
- EXPECT_TRUE(GetBasicText()->IsAfterNonCollapsedCharacter(3)); // "foo|"
-
- // Return false at node end/start, respectively
- EXPECT_FALSE(GetBasicText()->IsBeforeNonCollapsedCharacter(3)); // "foo|"
- EXPECT_FALSE(GetBasicText()->IsAfterNonCollapsedCharacter(0)); // "|foo"
+ EXPECT_EQ("BC-", GetSnapCode("|foo"));
+ EXPECT_EQ("BCA", GetSnapCode("f|oo"));
+ EXPECT_EQ("BCA", GetSnapCode("fo|o"));
+ EXPECT_EQ("-CA", GetSnapCode("foo|"));
// Consecutive spaces are collapsed into one
SetBasicBody("f bar");
- EXPECT_TRUE(GetBasicText()->IsBeforeNonCollapsedCharacter(1)); // "f| bar"
- EXPECT_FALSE(GetBasicText()->IsBeforeNonCollapsedCharacter(2)); // "f | bar"
- EXPECT_FALSE(GetBasicText()->IsBeforeNonCollapsedCharacter(3)); // "f | bar"
- EXPECT_TRUE(GetBasicText()->IsAfterNonCollapsedCharacter(2)); // "f | bar"
- EXPECT_FALSE(GetBasicText()->IsAfterNonCollapsedCharacter(3)); // "f | bar"
- EXPECT_FALSE(GetBasicText()->IsAfterNonCollapsedCharacter(4)); // "f |bar"
+ EXPECT_EQ("BC-", GetSnapCode("|f bar"));
+ EXPECT_EQ("BCA", GetSnapCode("f| bar"));
+ EXPECT_EQ("-CA", GetSnapCode("f | bar"));
+ EXPECT_EQ("---", GetSnapCode("f | bar"));
+ EXPECT_EQ("BC-", GetSnapCode("f |bar"));
+ EXPECT_EQ("BCA", GetSnapCode("f b|ar"));
+ EXPECT_EQ("BCA", GetSnapCode("f ba|r"));
+ EXPECT_EQ("-CA", GetSnapCode("f bar|"));
// Leading spaces in a block are collapsed
SetBasicBody(" foo");
- EXPECT_FALSE(GetBasicText()->IsBeforeNonCollapsedCharacter(0)); // "| foo"
- EXPECT_FALSE(GetBasicText()->IsBeforeNonCollapsedCharacter(1)); // " | foo"
- EXPECT_FALSE(GetBasicText()->IsAfterNonCollapsedCharacter(1)); // " | foo"
- EXPECT_FALSE(GetBasicText()->IsAfterNonCollapsedCharacter(2)); // " |foo"
+ EXPECT_EQ("---", GetSnapCode("| foo"));
+ EXPECT_EQ("---", GetSnapCode(" | foo"));
+ EXPECT_EQ("BC-", GetSnapCode(" |foo"));
+ EXPECT_EQ("BCA", GetSnapCode(" f|oo"));
+ EXPECT_EQ("BCA", GetSnapCode(" fo|o"));
+ EXPECT_EQ("-CA", GetSnapCode(" foo|"));
// Trailing spaces in a block are collapsed
SetBasicBody("foo ");
- EXPECT_FALSE(GetBasicText()->IsBeforeNonCollapsedCharacter(3)); // "foo| "
- EXPECT_FALSE(GetBasicText()->IsBeforeNonCollapsedCharacter(4)); // "foo | "
- EXPECT_FALSE(GetBasicText()->IsAfterNonCollapsedCharacter(4)); // "foo | "
- EXPECT_FALSE(GetBasicText()->IsAfterNonCollapsedCharacter(5)); // "foo |"
+ EXPECT_EQ("BC-", GetSnapCode("|foo "));
+ EXPECT_EQ("BCA", GetSnapCode("f|oo "));
+ EXPECT_EQ("BCA", GetSnapCode("fo|o "));
+ EXPECT_EQ("-CA", GetSnapCode("foo| "));
+ EXPECT_EQ("---", GetSnapCode("foo | "));
+ EXPECT_EQ("---", GetSnapCode("foo |"));
// Non-collapsed space at node end
SetBasicBody("foo <span>bar</span>");
- EXPECT_TRUE(GetBasicText()->IsBeforeNonCollapsedCharacter(
- 3)); // "foo| <span>bar</span>"
- EXPECT_TRUE(GetBasicText()->IsAfterNonCollapsedCharacter(
- 4)); // "foo |<span>bar</span>"
+ EXPECT_EQ("BC-", GetSnapCode("|foo "));
+ EXPECT_EQ("BCA", GetSnapCode("f|oo "));
+ EXPECT_EQ("BCA", GetSnapCode("fo|o "));
+ EXPECT_EQ("BCA", GetSnapCode("foo| "));
+ EXPECT_EQ("-CA", GetSnapCode("foo |"));
// Non-collapsed space at node start
SetBasicBody("foo<span id=bar> bar</span>");
- EXPECT_TRUE(GetLayoutTextById("bar")->IsBeforeNonCollapsedCharacter(
- 0)); // "foo<span>| bar</span>"
- EXPECT_TRUE(GetLayoutTextById("bar")->IsAfterNonCollapsedCharacter(
- 1)); // "foo<span> |bar</span>"
+ EXPECT_EQ("BC-", GetSnapCode("bar", "| bar"));
+ EXPECT_EQ("BCA", GetSnapCode("bar", " |bar"));
+ EXPECT_EQ("BCA", GetSnapCode("bar", " b|ar"));
+ EXPECT_EQ("BCA", GetSnapCode("bar", " ba|r"));
+ EXPECT_EQ("-CA", GetSnapCode("bar", " bar|"));
// Consecutive spaces across nodes
SetBasicBody("foo <span id=bar> bar</span>");
- EXPECT_TRUE(GetBasicText()->IsBeforeNonCollapsedCharacter(
- 3)); // "foo| <span> bar</span>"
- EXPECT_TRUE(GetBasicText()->IsAfterNonCollapsedCharacter(
- 4)); // "foo |<span> bar</span>"
- EXPECT_FALSE(GetLayoutTextById("bar")->IsBeforeNonCollapsedCharacter(
- 0)); // foo <span>| bar</span>
- EXPECT_FALSE(GetLayoutTextById("bar")->IsAfterNonCollapsedCharacter(
- 1)); // foo <span> |bar</span>
+ // text_content = "foo bar"
+ // [0] I DOM:0-4 TC:0-4 "foo "
+ // [1] C DOM:0-1 TC:4-4 " bar"
+ // [2] I DOM:1-4 TC:4-7 " bar"
+ EXPECT_EQ("BC-", GetSnapCode("|foo "));
+ EXPECT_EQ("BCA", GetSnapCode("f|oo "));
+ EXPECT_EQ("BCA", GetSnapCode("fo|o "));
+ EXPECT_EQ("BCA", GetSnapCode("foo| "));
+ EXPECT_EQ("-CA", GetSnapCode("foo |"));
+ EXPECT_EQ("---", GetSnapCode("bar", "| bar"));
+ EXPECT_EQ("BC-", GetSnapCode("bar", " |bar"));
+ EXPECT_EQ("BCA", GetSnapCode("bar", " b|ar"));
+ EXPECT_EQ("BCA", GetSnapCode("bar", " ba|r"));
+ EXPECT_EQ("-CA", GetSnapCode("bar", " bar|"));
// Non-collapsed whitespace text node
SetBasicBody("foo<span id=space> </span>bar");
- EXPECT_TRUE(GetLayoutTextById("space")->IsBeforeNonCollapsedCharacter(0));
- EXPECT_TRUE(GetLayoutTextById("space")->IsAfterNonCollapsedCharacter(1));
+ EXPECT_EQ("BC-", GetSnapCode("space", "| "));
+ EXPECT_EQ("-CA", GetSnapCode("space", " |"));
// Collapsed whitespace text node
SetBasicBody("foo <span id=space> </span>bar");
- EXPECT_FALSE(GetLayoutTextById("space")->IsBeforeNonCollapsedCharacter(0));
- EXPECT_FALSE(GetLayoutTextById("space")->IsAfterNonCollapsedCharacter(1));
+ EXPECT_EQ("---", GetSnapCode("space", "| "));
+ EXPECT_EQ("---", GetSnapCode("space", " |"));
}
TEST_P(ParameterizedLayoutTextTest, IsBeforeAfterNonCollapsedLineWrapSpace) {
LoadAhem();
- // Line wrapping inside node
- SetAhemBody("xx xx", 2);
- EXPECT_TRUE(GetBasicText()->IsBeforeNonCollapsedCharacter(2)); // "xx| xx"
- EXPECT_TRUE(GetBasicText()->IsAfterNonCollapsedCharacter(3)); // "xx |xx"
+ // Note: Because we can place a caret before soft line wrap, "ab| cd",
+ // |GetSnapCode()| should return "BC-" for both NG and legacy.
- // Legacy layout fails in the remaining test cases
- if (!LayoutNGEnabled())
- return;
+ // Line wrapping inside node
+ SetAhemBody("ab cd", 2);
+ // text_content = "ab cd"
+ // [0] I DOM:0-3 TC:0-3 "ab "
+ // [1] C DOM:3-4 TC:3-3 " "
+ // [2] I DOM:4-6 TC:3-5 "cd"
+ EXPECT_EQ("BC-", GetSnapCode("|ab cd"));
+ EXPECT_EQ("BCA", GetSnapCode("a|b cd"));
+ EXPECT_EQ("BCA", GetSnapCode("ab| cd"));
+ EXPECT_EQ(ValueWithLegacy("-CA", "--A", "after soft line wrap"),
+ GetSnapCode("ab | cd"));
+ EXPECT_EQ("BC-", GetSnapCode("ab |cd"));
+ EXPECT_EQ("BCA", GetSnapCode("ab c|d"));
+ EXPECT_EQ("-CA", GetSnapCode("ab cd|"));
// Line wrapping at node start
- SetAhemBody("xx<span id=span> xx</span>", 2);
- EXPECT_TRUE(GetLayoutTextById("span")->IsBeforeNonCollapsedCharacter(
- 0)); // "xx<span>| xx</span>"
- EXPECT_TRUE(GetLayoutTextById("span")->IsAfterNonCollapsedCharacter(
- 1)); // "xx<span>| xx</span>"
+ // text_content = "xx"
+ // [0] I DOM:0-2 TC:0-2 "xx"
+ // [1] I DOM:0-1 TC:2-3 " "
+ // [2] C DOM:1-2 TC:3-3 " "
+ // [3] I DOM:2-3 TC:3-5 "xx"
+ SetAhemBody("ab<span id=span> cd</span>", 2);
+ EXPECT_EQ(ValueWithLegacy("BC-", "---", "before soft line wrap"),
+ GetSnapCode("span", "| cd"));
+ EXPECT_EQ(ValueWithLegacy("-CA", "---", "after soft line wrap"),
+ GetSnapCode("span", " | cd"));
+ EXPECT_EQ("BC-", GetSnapCode("span", " |cd"));
+ EXPECT_EQ("BCA", GetSnapCode("span", " c|d"));
+ EXPECT_EQ("-CA", GetSnapCode("span", " cd|"));
// Line wrapping at node end
- SetAhemBody("xx <span>xx</span>", 2);
- EXPECT_TRUE(GetBasicText()->IsBeforeNonCollapsedCharacter(
- 2)); // "xx| <span>xx</span>"
- EXPECT_TRUE(GetBasicText()->IsAfterNonCollapsedCharacter(
- 3)); // "xx |<span>xx</span>"
+ SetAhemBody("ab <span>cd</span>", 2);
+ // text_content = "ab cd"
+ // [0] I DOM:0-3 TC:0-3 "ab "
+ // [1] C DOM:3-4 TC:3-3 " "
+ // [2] I DOM:0-2 TC:3-5 "cd"
+ EXPECT_EQ("BC-", GetSnapCode("|ab "));
+ EXPECT_EQ("BCA", GetSnapCode("a|b "));
+ EXPECT_EQ(ValueWithLegacy("BCA", "-CA", "before soft line wrap"),
+ GetSnapCode("ab| "));
+ EXPECT_EQ(ValueWithLegacy("-CA", "---", "after soft line wrap"),
+ GetSnapCode("ab | "));
+ EXPECT_EQ("---", GetSnapCode("ab |"));
// Entire node as line wrapping
- SetAhemBody("xx<span id=space> </span>xx", 2);
- EXPECT_TRUE(GetLayoutTextById("space")->IsBeforeNonCollapsedCharacter(0));
- EXPECT_TRUE(GetLayoutTextById("space")->IsAfterNonCollapsedCharacter(1));
+ SetAhemBody("ab<span id=space> </span>cd", 2);
+ // text_content = "ab cd"
+ // [0] I DOM:0-2 TC:0-2 "ab"
+ // [1] I DOM:0-1 TC:2-3 " "
+ // [2] C DOM:1-2 TC:3-3 " "
+ // [3] I DOM:0-2 TC:3-5 "cd"
+ EXPECT_EQ(ValueWithLegacy("BC-", "---", "before soft line wrap"),
+ GetSnapCode("space", "| "));
+ EXPECT_EQ(ValueWithLegacy("-CA", "---", "after soft line wrap"),
+ GetSnapCode("space", " | "));
+ EXPECT_EQ("---", GetSnapCode("space", " |"));
}
TEST_P(ParameterizedLayoutTextTest, IsBeforeAfterNonCollapsedCharacterBR) {
SetBasicBody("<br>");
- EXPECT_TRUE(GetBasicText()->IsBeforeNonCollapsedCharacter(0));
- EXPECT_FALSE(GetBasicText()->IsBeforeNonCollapsedCharacter(1));
- EXPECT_FALSE(GetBasicText()->IsAfterNonCollapsedCharacter(0));
- EXPECT_TRUE(GetBasicText()->IsAfterNonCollapsedCharacter(1));
+ EXPECT_EQ("BC-", GetSnapCode(*GetBasicText(), 0));
+ EXPECT_EQ("--A", GetSnapCode(*GetBasicText(), 1));
}
TEST_P(ParameterizedLayoutTextTest, AbsoluteQuads) {
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_theme_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_theme_test.cc
index 7461a3457ca..f9a19671467 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_theme_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_theme_test.cc
@@ -88,7 +88,7 @@ TEST_F(LayoutThemeTest, SystemColorWithColorScheme) {
<style>
#dark {
color: buttonface;
- color-scheme: dark;
+ color-scheme: light dark;
}
</style>
<div id="dark"></div>
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_theme_win.cc b/chromium/third_party/blink/renderer/core/layout/layout_theme_win.cc
index ff108f6f396..e447ce6d5df 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_theme_win.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_theme_win.cc
@@ -22,10 +22,6 @@ LayoutTheme& LayoutTheme::NativeTheme() {
Color LayoutThemeWin::SystemColor(CSSValueID css_value_id,
WebColorScheme color_scheme) const {
- if (!RuntimeEnabledFeatures::UseWindowsSystemColorsEnabled()) {
- return LayoutThemeDefault::SystemColor(css_value_id, color_scheme);
- }
-
blink::WebThemeEngine::SystemThemeColor theme_color;
switch (css_value_id) {
case CSSValueID::kActivetext:
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_tree_as_text.cc b/chromium/third_party/blink/renderer/core/layout/layout_tree_as_text.cc
index 28cc1cbd7c3..4b2b012761b 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_tree_as_text.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_tree_as_text.cc
@@ -46,10 +46,11 @@
#include "third_party/blink/renderer/core/layout/layout_table_cell.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/line/inline_text_box.h"
+#include "third_party/blink/renderer/core/layout/list_marker.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment.h"
-#include "third_party/blink/renderer/core/layout/ng/list/list_marker.h"
+#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_image.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_inline.h"
@@ -282,7 +283,7 @@ void LayoutTreeAsText::WriteLayoutObject(WTF::TextStream& ts,
}
}
- if (o.IsListMarker()) {
+ if (o.IsListMarkerForNormalContent()) {
String text = ToLayoutListMarker(o).GetText();
if (!text.IsEmpty()) {
if (text.length() != 1) {
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_video.cc b/chromium/third_party/blink/renderer/core/layout/layout_video.cc
index 5a71ef5b8ce..53e0582f6a1 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_video.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_video.cc
@@ -43,7 +43,7 @@ LayoutSize LayoutVideo::DefaultSize() {
}
void LayoutVideo::IntrinsicSizeChanged() {
- if (VideoElement()->ShouldDisplayPosterImage())
+ if (VideoElement()->IsShowPosterFlagSet())
LayoutMedia::IntrinsicSizeChanged();
UpdateIntrinsicSize(/* is_in_layout */ false);
}
@@ -96,7 +96,7 @@ LayoutSize LayoutVideo::CalculateIntrinsicSize() {
return LayoutSize(size);
}
- if (video->ShouldDisplayPosterImage() && !cached_image_size_.IsEmpty() &&
+ if (video->IsShowPosterFlagSet() && !cached_image_size_.IsEmpty() &&
!ImageResource()->ErrorOccurred())
return cached_image_size_;
@@ -120,8 +120,13 @@ void LayoutVideo::ImageChanged(WrappedImagePtr new_image,
UpdateIntrinsicSize(/* is_in_layout */ false);
}
-bool LayoutVideo::ShouldDisplayVideo() const {
- return !VideoElement()->ShouldDisplayPosterImage();
+LayoutVideo::DisplayMode LayoutVideo::GetDisplayMode() const {
+ if (!VideoElement()->IsShowPosterFlagSet() ||
+ VideoElement()->PosterImageURL().IsEmpty()) {
+ return kVideo;
+ } else {
+ return kPoster;
+ }
}
void LayoutVideo::PaintReplaced(const PaintInfo& paint_info,
@@ -142,7 +147,6 @@ void LayoutVideo::UpdateFromElement() {
LayoutMedia::UpdateFromElement();
UpdatePlayer(/* is_in_layout */ false);
- // If the DisplayMode of the video changed, then we need to paint.
SetShouldDoFullPaintInvalidation();
}
@@ -174,7 +178,7 @@ LayoutUnit LayoutVideo::MinimumReplacedHeight() const {
}
PhysicalRect LayoutVideo::ReplacedContentRect() const {
- if (ShouldDisplayVideo()) {
+ if (GetDisplayMode() == kVideo) {
// Video codecs may need to restart from an I-frame when the output is
// resized. Round size in advance to avoid 1px snap difference.
return PreSnappedRectForPersistentSizing(ComputeObjectFit());
@@ -193,7 +197,7 @@ CompositingReasons LayoutVideo::AdditionalCompositingReasons() const {
if (element->IsFullscreen() && element->UsesOverlayFullscreenVideo())
return CompositingReason::kVideo;
- if (ShouldDisplayVideo() && SupportsAcceleratedRendering())
+ if (GetDisplayMode() == kVideo && SupportsAcceleratedRendering())
return CompositingReason::kVideo;
return CompositingReason::kNone;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_video.h b/chromium/third_party/blink/renderer/core/layout/layout_video.h
index ed6ce6aa006..9d1b0bba2b3 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_video.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_video.h
@@ -35,7 +35,7 @@ class HTMLVideoElement;
class LayoutVideo final : public LayoutMedia {
public:
- LayoutVideo(HTMLVideoElement*);
+ explicit LayoutVideo(HTMLVideoElement*);
~LayoutVideo() override;
static LayoutSize DefaultSize();
@@ -44,7 +44,9 @@ class LayoutVideo final : public LayoutMedia {
bool SupportsAcceleratedRendering() const;
- bool ShouldDisplayVideo() const;
+ enum DisplayMode { kPoster, kVideo };
+ DisplayMode GetDisplayMode() const;
+
HTMLVideoElement* VideoElement() const;
const char* GetName() const override { return "LayoutVideo"; }
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_view.cc b/chromium/third_party/blink/renderer/core/layout/layout_view.cc
index 67af94038fa..b002e563a62 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_view.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_view.cc
@@ -24,6 +24,7 @@
#include <inttypes.h>
#include "build/build_config.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_screen_info.h"
@@ -345,6 +346,15 @@ void LayoutView::UpdateLayout() {
LayoutBlockFlow::UpdateLayout();
+ if (named_pages_mapper_) {
+ // If a start page name got propagated all the way up to the root, that will
+ // be the name for the first page. Usually we insert names into the mapper
+ // as part of inserting forced breaks, but in this case there'll be no
+ // break, since we're at the first page.
+ if (const AtomicString first_page_name = StartPageName())
+ named_pages_mapper_->NameFirstPage(first_page_name);
+ }
+
#if DCHECK_IS_ON()
CheckLayoutState();
#endif
@@ -831,11 +841,9 @@ IntervalArena* LayoutView::GetIntervalArena() {
}
bool LayoutView::BackgroundIsKnownToBeOpaqueInRect(const PhysicalRect&) const {
- // FIXME: Remove this main frame check. Same concept applies to subframes too.
- if (!GetFrame()->IsMainFrame())
- return false;
-
- return frame_view_->HasOpaqueBackground();
+ // The base background color applies to the main frame only.
+ return GetFrame()->IsMainFrame() &&
+ !frame_view_->BaseBackgroundColor().HasAlpha();
}
FloatSize LayoutView::ViewportSizeForViewportUnits() const {
@@ -894,6 +902,18 @@ bool LayoutView::UpdateLogicalWidthAndColumnWidth() {
return relayout_children || ShouldUsePrintingLayout();
}
+CompositingReasons LayoutView::AdditionalCompositingReasons() const {
+ // TODO(lfg): Audit for portals
+ const LocalFrame& frame = frame_view_->GetFrame();
+ if (frame.OwnerLayoutObject() &&
+ base::FeatureList::IsEnabled(
+ blink::features::kCompositeCrossOriginIframes) &&
+ frame.IsCrossOriginToParentFrame()) {
+ return CompositingReason::kIFrame;
+ }
+ return CompositingReason::kNone;
+}
+
void LayoutView::UpdateCounters() {
if (!needs_counter_update_)
return;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_view.h b/chromium/third_party/blink/renderer/core/layout/layout_view.h
index 7a36102b35d..584e4fe9be3 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_view.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_view.h
@@ -181,6 +181,9 @@ class CORE_EXPORT LayoutView final : public LayoutBlockFlow {
LayoutState* GetLayoutState() const { return layout_state_; }
+ bool CanHaveAdditionalCompositingReasons() const override { return true; }
+ CompositingReasons AdditionalCompositingReasons() const override;
+
void UpdateHitTestResult(HitTestResult&,
const PhysicalOffset&) const override;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_view_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_view_test.cc
index e41c96484d1..ce2abaea5ea 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_view_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_view_test.cc
@@ -135,10 +135,6 @@ class LayoutViewHitTestTest : public testing::WithParamInterface<HitTestConfig>,
protected:
bool LayoutNG() { return RuntimeEnabledFeatures::LayoutNGEnabled(); }
bool IsAndroidOrWindowsEditingBehavior() {
- // TODO(crbug.com/971414): For now LayoutNG always uses Android/Windows
- // behavior for ShouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom().
- if (LayoutNG())
- return true;
return GetParam().editing_behavior == kEditingAndroidBehavior ||
GetParam().editing_behavior == kEditingWindowsBehavior;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/line/inline_box.cc b/chromium/third_party/blink/renderer/core/layout/line/inline_box.cc
index fbb94e4db67..0ebeb3d14e8 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/inline_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/line/inline_box.cc
@@ -102,8 +102,9 @@ IntRect InlineBox::PartialInvalidationVisualRect() const {
}
DOMNodeId InlineBox::OwnerNodeId() const {
- return GetLineLayoutItem().GetNode()
- ? DOMNodeIds::IdForNode(GetLineLayoutItem().GetNode())
+ return GetLineLayoutItem().GetNodeForOwnerNodeId()
+ ? DOMNodeIds::IdForNode(
+ GetLineLayoutItem().GetNodeForOwnerNodeId())
: kInvalidDOMNodeId;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc b/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc
index 909f16a6fed..d71e63106c9 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc
@@ -827,9 +827,12 @@ void InlineFlowBox::PlaceBoxesInBlockDirection(
// being part of the overall lineTop/lineBottom.
// Really this is a workaround hack for the fact that ruby should have
// been done as line layout and not done using inline-block.
- if (GetLineLayoutItem().StyleRef().IsFlippedLinesWritingMode() ==
- (curr->GetLineLayoutItem().StyleRef().GetRubyPosition() ==
- RubyPosition::kAfter))
+ RubyPosition block_start_position =
+ GetLineLayoutItem().StyleRef().IsFlippedLinesWritingMode()
+ ? RubyPosition::kAfter
+ : RubyPosition::kBefore;
+ if (curr->GetLineLayoutItem().StyleRef().GetRubyPosition() ==
+ block_start_position)
has_annotations_before = true;
else
has_annotations_after = true;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/list_marker.cc b/chromium/third_party/blink/renderer/core/layout/list_marker.cc
index b2533d42d7a..3aa26b4e03f 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/list/list_marker.cc
+++ b/chromium/third_party/blink/renderer/core/layout/list_marker.cc
@@ -2,36 +2,87 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/renderer/core/layout/ng/list/list_marker.h"
+#include "third_party/blink/renderer/core/layout/list_marker.h"
#include "third_party/blink/renderer/core/layout/layout_image_resource_style_image.h"
+#include "third_party/blink/renderer/core/layout/layout_inside_list_marker.h"
+#include "third_party/blink/renderer/core/layout/layout_list_item.h"
+#include "third_party/blink/renderer/core/layout/layout_list_marker_image.h"
+#include "third_party/blink/renderer/core/layout/layout_outside_list_marker.h"
#include "third_party/blink/renderer/core/layout/list_marker_text.h"
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.h"
-#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.h"
+#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h"
namespace blink {
+const int kCMarkerPaddingPx = 7;
+
+// TODO(glebl): Move to core/html/resources/html.css after
+// Blink starts to support ::marker crbug.com/457718
+// Recommended UA margin for list markers.
+const int kCUAMarkerMarginEm = 1;
+
ListMarker::ListMarker() : marker_text_type_(kNotText) {}
-const ListMarker* ListMarker::Get(const LayoutObject* object) {
- if (!object)
- return nullptr;
- if (object->IsLayoutNGOutsideListMarker())
- return &ToLayoutNGOutsideListMarker(object)->Marker();
- if (object->IsLayoutNGInsideListMarker())
- return &ToLayoutNGInsideListMarker(object)->Marker();
+const ListMarker* ListMarker::Get(const LayoutObject* marker) {
+ if (auto* outside_marker = ToLayoutOutsideListMarkerOrNull(marker))
+ return &outside_marker->Marker();
+ if (auto* inside_marker = ToLayoutInsideListMarkerOrNull(marker))
+ return &inside_marker->Marker();
+ if (auto* ng_outside_marker = ToLayoutNGOutsideListMarkerOrNull(marker))
+ return &ng_outside_marker->Marker();
+ if (auto* ng_inside_marker = ToLayoutNGInsideListMarkerOrNull(marker))
+ return &ng_inside_marker->Marker();
return nullptr;
}
-ListMarker* ListMarker::Get(LayoutObject* object) {
+ListMarker* ListMarker::Get(LayoutObject* marker) {
return const_cast<ListMarker*>(
- ListMarker::Get(static_cast<const LayoutObject*>(object)));
+ ListMarker::Get(static_cast<const LayoutObject*>(marker)));
+}
+
+LayoutObject* ListMarker::MarkerFromListItem(const LayoutObject* list_item) {
+ if (auto* legacy_list_item = ToLayoutListItemOrNull(list_item))
+ return legacy_list_item->Marker();
+ if (auto* ng_list_item = ToLayoutNGListItemOrNull(list_item))
+ return ng_list_item->Marker();
+ return nullptr;
+}
+
+LayoutObject* ListMarker::ListItem(const LayoutObject& marker) const {
+ DCHECK_EQ(Get(&marker), this);
+ LayoutObject* list_item = marker.GetNode()->parentNode()->GetLayoutObject();
+ DCHECK(list_item);
+ DCHECK(list_item->IsListItemIncludingNG());
+ return list_item;
+}
+
+LayoutBlockFlow* ListMarker::ListItemBlockFlow(
+ const LayoutObject& marker) const {
+ DCHECK_EQ(Get(&marker), this);
+ LayoutObject* list_item = ListItem(marker);
+ if (auto* legacy_list_item = ToLayoutListItemOrNull(list_item))
+ return legacy_list_item;
+ if (auto* ng_list_item = ToLayoutNGListItemOrNull(list_item))
+ return ng_list_item;
+ NOTREACHED();
+ return nullptr;
+}
+
+int ListMarker::ListItemValue(const LayoutObject& list_item) const {
+ if (auto* legacy_list_item = ToLayoutListItemOrNull(list_item))
+ return legacy_list_item->Value();
+ if (auto* ng_list_item = ToLayoutNGListItemOrNull(list_item))
+ return ng_list_item->Value();
+ NOTREACHED();
+ return 0;
}
// If the value of ListStyleType changed, we need to the marker text has been
// updated.
void ListMarker::ListStyleTypeChanged(LayoutObject& marker) {
+ DCHECK_EQ(Get(&marker), this);
if (marker_text_type_ == kNotText || marker_text_type_ == kUnresolved)
return;
@@ -41,6 +92,7 @@ void ListMarker::ListStyleTypeChanged(LayoutObject& marker) {
}
void ListMarker::OrdinalValueChanged(LayoutObject& marker) {
+ DCHECK_EQ(Get(&marker), this);
if (marker_text_type_ == kOrdinalValue) {
marker_text_type_ = kUnresolved;
marker.SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
@@ -49,6 +101,7 @@ void ListMarker::OrdinalValueChanged(LayoutObject& marker) {
}
void ListMarker::UpdateMarkerText(LayoutObject& marker, LayoutText* text) {
+ DCHECK_EQ(Get(&marker), this);
DCHECK(text);
DCHECK_EQ(marker_text_type_, kUnresolved);
StringBuilder marker_text_builder;
@@ -59,93 +112,39 @@ void ListMarker::UpdateMarkerText(LayoutObject& marker, LayoutText* text) {
}
void ListMarker::UpdateMarkerText(LayoutObject& marker) {
+ DCHECK_EQ(Get(&marker), this);
UpdateMarkerText(marker, ToLayoutText(marker.SlowFirstChild()));
}
-LayoutNGListItem* ListMarker::ListItem(const LayoutObject& marker) {
- return ToLayoutNGListItem(marker.GetNode()->parentNode()->GetLayoutObject());
-}
-
ListMarker::MarkerTextType ListMarker::MarkerText(
const LayoutObject& marker,
StringBuilder* text,
MarkerTextFormat format) const {
+ DCHECK_EQ(Get(&marker), this);
+ if (!marker.StyleRef().ContentBehavesAsNormal())
+ return kNotText;
if (IsMarkerImage(marker)) {
if (format == kWithSuffix)
text->Append(' ');
return kNotText;
}
- LayoutNGListItem* list_item = ListItem(marker);
+ LayoutObject* list_item = ListItem(marker);
const ComputedStyle& style = list_item->StyleRef();
- switch (style.ListStyleType()) {
- case EListStyleType::kNone:
+ switch (GetListStyleCategory(style.ListStyleType())) {
+ case ListStyleCategory::kNone:
return kNotText;
- case EListStyleType::kString: {
+ case ListStyleCategory::kStaticString:
text->Append(style.ListStyleStringValue());
return kStatic;
- }
- case EListStyleType::kDisc:
- case EListStyleType::kCircle:
- case EListStyleType::kSquare:
+ case ListStyleCategory::kSymbol:
// value is ignored for these types
text->Append(list_marker_text::GetText(style.ListStyleType(), 0));
if (format == kWithSuffix)
text->Append(' ');
return kSymbolValue;
- case EListStyleType::kArabicIndic:
- case EListStyleType::kArmenian:
- case EListStyleType::kBengali:
- case EListStyleType::kCambodian:
- case EListStyleType::kCjkIdeographic:
- case EListStyleType::kCjkEarthlyBranch:
- case EListStyleType::kCjkHeavenlyStem:
- case EListStyleType::kDecimalLeadingZero:
- case EListStyleType::kDecimal:
- case EListStyleType::kDevanagari:
- case EListStyleType::kEthiopicHalehame:
- case EListStyleType::kEthiopicHalehameAm:
- case EListStyleType::kEthiopicHalehameTiEr:
- case EListStyleType::kEthiopicHalehameTiEt:
- case EListStyleType::kGeorgian:
- case EListStyleType::kGujarati:
- case EListStyleType::kGurmukhi:
- case EListStyleType::kHangul:
- case EListStyleType::kHangulConsonant:
- case EListStyleType::kHebrew:
- case EListStyleType::kHiragana:
- case EListStyleType::kHiraganaIroha:
- case EListStyleType::kKannada:
- case EListStyleType::kKatakana:
- case EListStyleType::kKatakanaIroha:
- case EListStyleType::kKhmer:
- case EListStyleType::kKoreanHangulFormal:
- case EListStyleType::kKoreanHanjaFormal:
- case EListStyleType::kKoreanHanjaInformal:
- case EListStyleType::kLao:
- case EListStyleType::kLowerAlpha:
- case EListStyleType::kLowerArmenian:
- case EListStyleType::kLowerGreek:
- case EListStyleType::kLowerLatin:
- case EListStyleType::kLowerRoman:
- case EListStyleType::kMalayalam:
- case EListStyleType::kMongolian:
- case EListStyleType::kMyanmar:
- case EListStyleType::kOriya:
- case EListStyleType::kPersian:
- case EListStyleType::kSimpChineseFormal:
- case EListStyleType::kSimpChineseInformal:
- case EListStyleType::kTelugu:
- case EListStyleType::kThai:
- case EListStyleType::kTibetan:
- case EListStyleType::kTradChineseFormal:
- case EListStyleType::kTradChineseInformal:
- case EListStyleType::kUpperAlpha:
- case EListStyleType::kUpperArmenian:
- case EListStyleType::kUpperLatin:
- case EListStyleType::kUpperRoman:
- case EListStyleType::kUrdu: {
- int value = list_item->Value();
+ case ListStyleCategory::kLanguage: {
+ int value = ListItemValue(*list_item);
text->Append(list_marker_text::GetText(style.ListStyleType(), value));
if (format == kWithSuffix) {
text->Append(list_marker_text::Suffix(style.ListStyleType(), value));
@@ -159,26 +158,28 @@ ListMarker::MarkerTextType ListMarker::MarkerText(
}
String ListMarker::MarkerTextWithSuffix(const LayoutObject& marker) const {
+ DCHECK_EQ(Get(&marker), this);
StringBuilder text;
MarkerText(marker, &text, kWithSuffix);
return text.ToString();
}
String ListMarker::MarkerTextWithoutSuffix(const LayoutObject& marker) const {
+ DCHECK_EQ(Get(&marker), this);
StringBuilder text;
MarkerText(marker, &text, kWithoutSuffix);
return text.ToString();
}
String ListMarker::TextAlternative(const LayoutObject& marker) const {
+ DCHECK_EQ(Get(&marker), this);
// For accessibility, return the marker string in the logical order even in
// RTL, reflecting speech order.
return MarkerTextWithSuffix(marker);
}
void ListMarker::UpdateMarkerContentIfNeeded(LayoutObject& marker) {
- LayoutNGListItem* list_item = ListItem(marker);
-
+ DCHECK_EQ(Get(&marker), this);
if (!marker.StyleRef().ContentBehavesAsNormal()) {
marker_text_type_ = kNotText;
return;
@@ -188,8 +189,9 @@ void ListMarker::UpdateMarkerContentIfNeeded(LayoutObject& marker) {
LayoutObject* child = marker.SlowFirstChild();
DCHECK(!child || !child->NextSibling());
+ const ComputedStyle& style = ListItem(marker)->StyleRef();
if (IsMarkerImage(marker)) {
- StyleImage* list_style_image = list_item->StyleRef().ListStyleImage();
+ StyleImage* list_style_image = style.ListStyleImage();
if (child) {
// If the url of `list-style-image` changed, create a new LayoutImage.
if (!child->IsLayoutImage() ||
@@ -200,8 +202,10 @@ void ListMarker::UpdateMarkerContentIfNeeded(LayoutObject& marker) {
}
}
if (!child) {
- LayoutNGListMarkerImage* image =
- LayoutNGListMarkerImage::CreateAnonymous(&marker.GetDocument());
+ LayoutListMarkerImage* image =
+ LayoutListMarkerImage::CreateAnonymous(&marker.GetDocument());
+ if (marker.IsLayoutNGListMarker())
+ image->SetIsLayoutNGObjectForListMarkerImage(true);
scoped_refptr<ComputedStyle> image_style =
ComputedStyle::CreateAnonymousStyleWithDisplay(marker.StyleRef(),
EDisplay::kInline);
@@ -216,7 +220,7 @@ void ListMarker::UpdateMarkerContentIfNeeded(LayoutObject& marker) {
return;
}
- if (list_item->StyleRef().ListStyleType() == EListStyleType::kNone) {
+ if (style.ListStyleType() == EListStyleType::kNone) {
marker_text_type_ = kNotText;
return;
}
@@ -248,9 +252,168 @@ void ListMarker::UpdateMarkerContentIfNeeded(LayoutObject& marker) {
LayoutObject* ListMarker::SymbolMarkerLayoutText(
const LayoutObject& marker) const {
+ DCHECK_EQ(Get(&marker), this);
if (marker_text_type_ != kSymbolValue)
return nullptr;
return marker.SlowFirstChild();
}
+bool ListMarker::IsMarkerImage(const LayoutObject& marker) const {
+ DCHECK_EQ(Get(&marker), this);
+ return marker.StyleRef().ContentBehavesAsNormal() &&
+ ListItem(marker)->StyleRef().GeneratesMarkerImage();
+}
+
+LayoutUnit ListMarker::WidthOfSymbol(const ComputedStyle& style) {
+ const Font& font = style.GetFont();
+ const SimpleFontData* font_data = font.PrimaryFont();
+ DCHECK(font_data);
+ if (!font_data)
+ return LayoutUnit();
+ return LayoutUnit((font_data->GetFontMetrics().Ascent() * 2 / 3 + 1) / 2 + 2);
+}
+
+std::pair<LayoutUnit, LayoutUnit> ListMarker::InlineMarginsForInside(
+ const ComputedStyle& style,
+ bool is_image) {
+ if (!style.ContentBehavesAsNormal())
+ return {};
+ if (is_image)
+ return {LayoutUnit(), LayoutUnit(kCMarkerPaddingPx)};
+ switch (GetListStyleCategory(style.ListStyleType())) {
+ case ListStyleCategory::kSymbol:
+ return {LayoutUnit(-1),
+ LayoutUnit(kCUAMarkerMarginEm * style.ComputedFontSize())};
+ default:
+ break;
+ }
+ return {};
+}
+
+std::pair<LayoutUnit, LayoutUnit> ListMarker::InlineMarginsForOutside(
+ const ComputedStyle& style,
+ bool is_image,
+ LayoutUnit marker_inline_size) {
+ LayoutUnit margin_start;
+ LayoutUnit margin_end;
+ if (!style.ContentBehavesAsNormal()) {
+ margin_start = -marker_inline_size;
+ } else if (is_image) {
+ margin_start = -marker_inline_size - kCMarkerPaddingPx;
+ margin_end = LayoutUnit(kCMarkerPaddingPx);
+ } else {
+ switch (GetListStyleCategory(style.ListStyleType())) {
+ case ListStyleCategory::kNone:
+ break;
+ case ListStyleCategory::kSymbol: {
+ const SimpleFontData* font_data = style.GetFont().PrimaryFont();
+ DCHECK(font_data);
+ if (!font_data)
+ return {};
+ const FontMetrics& font_metrics = font_data->GetFontMetrics();
+ int offset = font_metrics.Ascent() * 2 / 3;
+ margin_start = LayoutUnit(-offset - kCMarkerPaddingPx - 1);
+ margin_end = offset + kCMarkerPaddingPx + 1 - marker_inline_size;
+ break;
+ }
+ default:
+ margin_start = -marker_inline_size;
+ }
+ }
+ DCHECK_EQ(margin_start + margin_end, -marker_inline_size);
+ return {margin_start, margin_end};
+}
+
+LayoutRect ListMarker::RelativeSymbolMarkerRect(const ComputedStyle& style,
+ LayoutUnit width) {
+ LayoutRect relative_rect;
+ const SimpleFontData* font_data = style.GetFont().PrimaryFont();
+ DCHECK(font_data);
+ if (!font_data)
+ return LayoutRect();
+
+ // TODO(wkorman): Review and clean up/document the calculations below.
+ // http://crbug.com/543193
+ const FontMetrics& font_metrics = font_data->GetFontMetrics();
+ int ascent = font_metrics.Ascent();
+ int bullet_width = (ascent * 2 / 3 + 1) / 2;
+ relative_rect = LayoutRect(1, 3 * (ascent - ascent * 2 / 3) / 2, bullet_width,
+ bullet_width);
+ if (!style.IsHorizontalWritingMode()) {
+ relative_rect = relative_rect.TransposedRect();
+ relative_rect.SetX(width - relative_rect.X() - relative_rect.Width());
+ }
+ return relative_rect;
+}
+
+ListMarker::ListStyleCategory ListMarker::GetListStyleCategory(
+ EListStyleType type) {
+ switch (type) {
+ case EListStyleType::kNone:
+ return ListStyleCategory::kNone;
+ case EListStyleType::kString:
+ return ListStyleCategory::kStaticString;
+ case EListStyleType::kDisc:
+ case EListStyleType::kCircle:
+ case EListStyleType::kSquare:
+ return ListStyleCategory::kSymbol;
+ case EListStyleType::kArabicIndic:
+ case EListStyleType::kArmenian:
+ case EListStyleType::kBengali:
+ case EListStyleType::kCambodian:
+ case EListStyleType::kCjkIdeographic:
+ case EListStyleType::kCjkEarthlyBranch:
+ case EListStyleType::kCjkHeavenlyStem:
+ case EListStyleType::kDecimalLeadingZero:
+ case EListStyleType::kDecimal:
+ case EListStyleType::kDevanagari:
+ case EListStyleType::kEthiopicHalehame:
+ case EListStyleType::kEthiopicHalehameAm:
+ case EListStyleType::kEthiopicHalehameTiEr:
+ case EListStyleType::kEthiopicHalehameTiEt:
+ case EListStyleType::kGeorgian:
+ case EListStyleType::kGujarati:
+ case EListStyleType::kGurmukhi:
+ case EListStyleType::kHangul:
+ case EListStyleType::kHangulConsonant:
+ case EListStyleType::kHebrew:
+ case EListStyleType::kHiragana:
+ case EListStyleType::kHiraganaIroha:
+ case EListStyleType::kKannada:
+ case EListStyleType::kKatakana:
+ case EListStyleType::kKatakanaIroha:
+ case EListStyleType::kKhmer:
+ case EListStyleType::kKoreanHangulFormal:
+ case EListStyleType::kKoreanHanjaFormal:
+ case EListStyleType::kKoreanHanjaInformal:
+ case EListStyleType::kLao:
+ case EListStyleType::kLowerAlpha:
+ case EListStyleType::kLowerArmenian:
+ case EListStyleType::kLowerGreek:
+ case EListStyleType::kLowerLatin:
+ case EListStyleType::kLowerRoman:
+ case EListStyleType::kMalayalam:
+ case EListStyleType::kMongolian:
+ case EListStyleType::kMyanmar:
+ case EListStyleType::kOriya:
+ case EListStyleType::kPersian:
+ case EListStyleType::kSimpChineseFormal:
+ case EListStyleType::kSimpChineseInformal:
+ case EListStyleType::kTelugu:
+ case EListStyleType::kThai:
+ case EListStyleType::kTibetan:
+ case EListStyleType::kTradChineseFormal:
+ case EListStyleType::kTradChineseInformal:
+ case EListStyleType::kUpperAlpha:
+ case EListStyleType::kUpperArmenian:
+ case EListStyleType::kUpperLatin:
+ case EListStyleType::kUpperRoman:
+ case EListStyleType::kUrdu:
+ return ListStyleCategory::kLanguage;
+ default:
+ NOTREACHED();
+ return ListStyleCategory::kLanguage;
+ }
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/list_marker.h b/chromium/third_party/blink/renderer/core/layout/list_marker.h
index 0ecf1844689..c90e7af1c1b 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/list/list_marker.h
+++ b/chromium/third_party/blink/renderer/core/layout/list_marker.h
@@ -2,17 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LIST_LIST_MARKER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LIST_LIST_MARKER_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LIST_MARKER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LIST_MARKER_H_
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
-#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
namespace blink {
-// This class holds code shared among LayoutNG classes for list markers.
+class LayoutListItem;
+class LayoutNGListItem;
+class LayoutText;
+
+// This class holds code shared among all classes for list markers, for both
+// legacy layout and LayoutNG.
class CORE_EXPORT ListMarker {
+ friend class LayoutListItem;
friend class LayoutNGListItem;
public:
@@ -21,7 +26,10 @@ class CORE_EXPORT ListMarker {
static const ListMarker* Get(const LayoutObject*);
static ListMarker* Get(LayoutObject*);
- static LayoutNGListItem* ListItem(const LayoutObject&);
+ static LayoutObject* MarkerFromListItem(const LayoutObject*);
+
+ LayoutObject* ListItem(const LayoutObject&) const;
+ LayoutBlockFlow* ListItemBlockFlow(const LayoutObject&) const;
String MarkerTextWithSuffix(const LayoutObject&) const;
String MarkerTextWithoutSuffix(const LayoutObject&) const;
@@ -29,20 +37,37 @@ class CORE_EXPORT ListMarker {
// Marker text with suffix, e.g. "1. ", for use in accessibility.
String TextAlternative(const LayoutObject&) const;
- static bool IsMarkerImage(const LayoutObject& marker) {
- return ListItem(marker)->StyleRef().GeneratesMarkerImage();
- }
+ bool IsMarkerImage(const LayoutObject&) const;
void UpdateMarkerTextIfNeeded(LayoutObject& marker) {
+ DCHECK_EQ(Get(&marker), this);
if (marker_text_type_ == kUnresolved)
UpdateMarkerText(marker);
}
void UpdateMarkerContentIfNeeded(LayoutObject&);
- void OrdinalValueChanged(LayoutObject&);
-
LayoutObject* SymbolMarkerLayoutText(const LayoutObject&) const;
+ // Compute inline margins for 'list-style-position: inside' and 'outside'.
+ static std::pair<LayoutUnit, LayoutUnit> InlineMarginsForInside(
+ const ComputedStyle&,
+ bool is_image);
+ static std::pair<LayoutUnit, LayoutUnit> InlineMarginsForOutside(
+ const ComputedStyle&,
+ bool is_image,
+ LayoutUnit marker_inline_size);
+
+ static LayoutRect RelativeSymbolMarkerRect(const ComputedStyle&, LayoutUnit);
+ static LayoutUnit WidthOfSymbol(const ComputedStyle&);
+
+ // A reduced set of list style categories allowing for more concise expression
+ // of list style specific logic.
+ enum class ListStyleCategory { kNone, kSymbol, kLanguage, kStaticString };
+
+ // Returns the list's style as one of a reduced high level categorical set of
+ // styles.
+ static ListStyleCategory GetListStyleCategory(EListStyleType);
+
private:
enum MarkerTextFormat { kWithSuffix, kWithoutSuffix };
enum MarkerTextType {
@@ -62,10 +87,13 @@ class CORE_EXPORT ListMarker {
void UpdateMarkerText(LayoutObject&, LayoutText*);
void ListStyleTypeChanged(LayoutObject&);
+ void OrdinalValueChanged(LayoutObject&);
+
+ int ListItemValue(const LayoutObject&) const;
unsigned marker_text_type_ : 3; // MarkerTextType
};
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LIST_LIST_MARKER_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LIST_MARKER_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/README.md b/chromium/third_party/blink/renderer/core/layout/ng/README.md
index 09c24da1f24..961a60cb9d3 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/README.md
+++ b/chromium/third_party/blink/renderer/core/layout/ng/README.md
@@ -113,7 +113,7 @@ Here is the instruction how to generate a new result.
`chromium\src>for %file in (*.log) do DynamoRIO\tools\bin64\drcov2lcov.exe -input %file -output %file.info -src_filter layout/ng -src_skip_filter _test`
* Merge all lcov files into one file
`chromium\src>node lcov-result-merger\bin\lcov-result-merger.js *.info output.info`
-* Generate the coverage html from the master lcov file
+* Generate the coverage html from the lcov file
`chromium\src>C:\Perl64\bin\perl.exe dynamorio.git\third_party\lcov\genhtml output.info -o output`
### Debugging, logging and testing ###
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc b/chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc
index 3a2d2beb0b1..43f6f426a4e 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc
@@ -353,12 +353,12 @@ CSSLayoutDefinition::Instance* CSSLayoutDefinition::CreateInstance() {
return MakeGarbageCollected<Instance>(this, instance.V8Value());
}
-void CSSLayoutDefinition::Instance::Trace(Visitor* visitor) {
+void CSSLayoutDefinition::Instance::Trace(Visitor* visitor) const {
visitor->Trace(definition_);
visitor->Trace(instance_);
}
-void CSSLayoutDefinition::Trace(Visitor* visitor) {
+void CSSLayoutDefinition::Trace(Visitor* visitor) const {
visitor->Trace(constructor_);
visitor->Trace(intrinsic_sizes_);
visitor->Trace(layout_);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.h b/chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.h
index d2bef60636a..5596cc1d38f 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.h
@@ -78,7 +78,7 @@ class CSSLayoutDefinition final : public GarbageCollected<CSSLayoutDefinition>,
IntrinsicSizesResultOptions**,
bool* child_depends_on_percentage_block_size);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void ReportException(ExceptionState*);
@@ -106,7 +106,7 @@ class CSSLayoutDefinition final : public GarbageCollected<CSSLayoutDefinition>,
ScriptState* GetScriptState() const { return script_state_; }
- virtual void Trace(Visitor* visitor);
+ virtual void Trace(Visitor* visitor) const;
const char* NameInHeapSnapshot() const override {
return "CSSLayoutDefinition";
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.cc b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.cc
index 7dd9c992f83..55bf4282702 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.cc
@@ -21,7 +21,7 @@ const NGLayoutInputNode& CustomIntrinsicSizes::GetLayoutNode() const {
return child_->GetLayoutNode();
}
-void CustomIntrinsicSizes::Trace(Visitor* visitor) {
+void CustomIntrinsicSizes::Trace(Visitor* visitor) const {
visitor->Trace(child_);
visitor->Trace(token_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.h b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.h
index 1bfa9cea738..7c81a6e61cb 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.h
@@ -37,7 +37,7 @@ class CustomIntrinsicSizes : public ScriptWrappable {
bool IsValid() const { return token_->IsValid(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<CustomLayoutChild> child_;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc
index a4ed4148eca..d7e43154fd7 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc
@@ -86,7 +86,7 @@ ScriptPromise CustomLayoutChild::layoutNextFragment(
return resolver->Promise();
}
-void CustomLayoutChild::Trace(Visitor* visitor) {
+void CustomLayoutChild::Trace(Visitor* visitor) const {
visitor->Trace(style_map_);
visitor->Trace(token_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h
index 7943adc0ac3..2b1a0a51a42 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h
@@ -46,7 +46,7 @@ class CustomLayoutChild : public ScriptWrappable {
void SetCustomLayoutToken(CustomLayoutToken* token) { token_ = token; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
NGLayoutInputNode node_;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.cc b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.cc
index 9ed31898a5c..28b8883540f 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.cc
@@ -47,7 +47,7 @@ ScriptValue CustomLayoutConstraints::data(ScriptState* script_state) const {
layout_worklet_world_v8_data_.NewLocal(script_state->GetIsolate()));
}
-void CustomLayoutConstraints::Trace(Visitor* visitor) {
+void CustomLayoutConstraints::Trace(Visitor* visitor) const {
visitor->Trace(layout_worklet_world_v8_data_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.h b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.h
index 6a496623aab..c3dfb58244b 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.h
@@ -32,7 +32,7 @@ class CustomLayoutConstraints : public ScriptWrappable {
base::Optional<double> fixedBlockSize() const;
ScriptValue data(ScriptState*) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
double fixed_inline_size_;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.cc b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.cc
index 1d724aa4f68..60cecbc6440 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.cc
@@ -53,7 +53,7 @@ ScriptValue CustomLayoutFragment::data(ScriptState* script_state) const {
layout_worklet_world_v8_data_.NewLocal(script_state->GetIsolate()));
}
-void CustomLayoutFragment::Trace(Visitor* visitor) {
+void CustomLayoutFragment::Trace(Visitor* visitor) const {
visitor->Trace(child_);
visitor->Trace(token_);
visitor->Trace(layout_worklet_world_v8_data_);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h
index c9b5dde905d..13fc70ef9e2 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h
@@ -61,7 +61,7 @@ class CustomLayoutFragment : public ScriptWrappable {
bool IsValid() const { return token_->IsValid(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<CustomLayoutChild> child_;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_scope.h b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_scope.h
index 3cc70061f06..8071f4c7a53 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_scope.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_scope.h
@@ -22,7 +22,7 @@ typedef Vector<CustomLayoutWorkTask, 4> CustomLayoutWorkQueue;
class CustomLayoutToken : public GarbageCollected<CustomLayoutToken> {
public:
CustomLayoutToken() : is_detached_(false) {}
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
bool IsValid() const;
private:
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc
index b24800c68ef..14ce056a557 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc
@@ -150,7 +150,8 @@ void CustomLayoutWorkTask::RunIntrinsicSizesTask(
DCHECK_EQ(type_, CustomLayoutWorkTask::TaskType::kIntrinsicSizes);
DCHECK(resolver_);
- MinMaxSizesInput input(child_percentage_resolution_block_size_for_min_max);
+ MinMaxSizesInput input(child_percentage_resolution_block_size_for_min_max,
+ MinMaxSizesType::kContent);
MinMaxSizesResult result =
ComputeMinAndMaxContentContribution(parent_style, child, input);
resolver_->Resolve(MakeGarbageCollected<CustomIntrinsicSizes>(
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/document_layout_definition.cc b/chromium/third_party/blink/renderer/core/layout/ng/custom/document_layout_definition.cc
index c68765b9107..40266002ee6 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/document_layout_definition.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/document_layout_definition.cc
@@ -33,7 +33,7 @@ bool DocumentLayoutDefinition::IsEqual(const CSSLayoutDefinition& other) {
other.ChildCustomInvalidationProperties();
}
-void DocumentLayoutDefinition::Trace(Visitor* visitor) {
+void DocumentLayoutDefinition::Trace(Visitor* visitor) const {
visitor->Trace(layout_definition_);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/document_layout_definition.h b/chromium/third_party/blink/renderer/core/layout/ng/custom/document_layout_definition.h
index 0c2d8bce246..2a2c1052afb 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/document_layout_definition.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/document_layout_definition.h
@@ -37,7 +37,7 @@ class DocumentLayoutDefinition final
return registered_definitions_count_;
}
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
bool IsEqual(const CSSLayoutDefinition&);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet.cc b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet.cc
index be7fd1d4847..7340fed04c8 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet.cc
@@ -45,7 +45,7 @@ LayoutWorkletGlobalScopeProxy* LayoutWorklet::Proxy() {
return LayoutWorkletGlobalScopeProxy::From(FindAvailableGlobalScope());
}
-void LayoutWorklet::Trace(Visitor* visitor) {
+void LayoutWorklet::Trace(Visitor* visitor) const {
visitor->Trace(document_definition_map_);
visitor->Trace(pending_layout_registry_);
Worklet::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet.h b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet.h
index 7f852c563e2..20475e9697b 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet.h
@@ -47,7 +47,7 @@ class CORE_EXPORT LayoutWorklet : public Worklet,
void AddPendingLayout(const AtomicString& name, Node*);
LayoutWorkletGlobalScopeProxy* Proxy();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
// TODO(ikilpatrick): Make selection of the global scope non-deterministic.
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.cc b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.cc
index 51bb52ea69d..317d8921237 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.cc
@@ -167,7 +167,7 @@ CSSLayoutDefinition* LayoutWorkletGlobalScope::FindDefinition(
return layout_definitions_.at(name);
}
-void LayoutWorkletGlobalScope::Trace(Visitor* visitor) {
+void LayoutWorkletGlobalScope::Trace(Visitor* visitor) const {
visitor->Trace(layout_definitions_);
visitor->Trace(pending_layout_registry_);
WorkletGlobalScope::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.h b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.h
index c02359b83b2..9bb6d62a34c 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.h
@@ -44,7 +44,7 @@ class CORE_EXPORT LayoutWorkletGlobalScope final : public WorkletGlobalScope {
CSSLayoutDefinition* FindDefinition(const AtomicString& name);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// https://drafts.css-houdini.org/css-layout-api/#layout-definitions
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.cc b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.cc
index 4a161756a61..76f95c12604 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.cc
@@ -92,7 +92,7 @@ CSSLayoutDefinition* LayoutWorkletGlobalScopeProxy::FindDefinition(
return global_scope_->FindDefinition(name);
}
-void LayoutWorkletGlobalScopeProxy::Trace(Visitor* visitor) {
+void LayoutWorkletGlobalScopeProxy::Trace(Visitor* visitor) const {
visitor->Trace(global_scope_);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.h b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.h
index de993758af3..97efbd1f814 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.h
@@ -46,7 +46,7 @@ class CORE_EXPORT LayoutWorkletGlobalScopeProxy
LayoutWorkletGlobalScope* global_scope() const { return global_scope_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
std::unique_ptr<MainThreadWorkletReportingProxy> reporting_proxy_;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc
index b2dbb2d6b09..05f5ff77648 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc
@@ -21,12 +21,7 @@ namespace blink {
NGCustomLayoutAlgorithm::NGCustomLayoutAlgorithm(
const NGLayoutAlgorithmParams& params)
- : NGLayoutAlgorithm(params),
- params_(params),
- border_padding_(params.fragment_geometry.border +
- params.fragment_geometry.padding),
- border_scrollbar_padding_(border_padding_ +
- params.fragment_geometry.scrollbar) {
+ : NGLayoutAlgorithm(params), params_(params) {
DCHECK(params.space.IsNewFormattingContext());
container_builder_.SetIsNewFormattingContext(
params.space.IsNewFormattingContext());
@@ -58,7 +53,7 @@ MinMaxSizesResult NGCustomLayoutAlgorithm::ComputeMinMaxSizes(
IntrinsicSizesResultOptions* intrinsic_sizes_result_options = nullptr;
if (!instance->IntrinsicSizes(
ConstraintSpace(), document, Node(),
- container_builder_.InitialBorderBoxSize(), border_scrollbar_padding_,
+ container_builder_.InitialBorderBoxSize(), BorderScrollbarPadding(),
input.percentage_resolution_block_size, &scope,
&intrinsic_sizes_result_options, &depends_on_percentage_block_size)) {
// TODO(ikilpatrick): Report this error to the developer.
@@ -104,7 +99,7 @@ scoped_refptr<const NGLayoutResult> NGCustomLayoutAlgorithm::Layout() {
scoped_refptr<SerializedScriptValue> fragment_result_data;
if (!instance->Layout(ConstraintSpace(), document, Node(),
container_builder_.InitialBorderBoxSize(),
- border_scrollbar_padding_, &scope,
+ BorderScrollbarPadding(), &scope,
fragment_result_options, &fragment_result_data)) {
// TODO(ikilpatrick): Report this error to the developer.
return FallbackLayout();
@@ -156,10 +151,10 @@ scoped_refptr<const NGLayoutResult> NGCustomLayoutAlgorithm::Layout() {
// Compute the final block-size.
LayoutUnit auto_block_size = std::max(
- border_padding_.BlockSum(),
+ BorderScrollbarPadding().BlockSum(),
LayoutUnit::FromDoubleRound(fragment_result_options->autoBlockSize()));
LayoutUnit block_size = ComputeBlockSizeForFragment(
- ConstraintSpace(), Style(), border_padding_, auto_block_size,
+ ConstraintSpace(), Style(), BorderPadding(), auto_block_size,
container_builder_.InitialBorderBoxSize().inline_size);
if (fragment_result_options->hasBaseline()) {
@@ -170,7 +165,7 @@ scoped_refptr<const NGLayoutResult> NGCustomLayoutAlgorithm::Layout() {
container_builder_.SetCustomLayoutData(std::move(fragment_result_data));
container_builder_.SetIntrinsicBlockSize(auto_block_size);
- container_builder_.SetBlockSize(block_size);
+ container_builder_.SetFragmentsTotalBlockSize(block_size);
NGOutOfFlowLayoutPart(
Node(), ConstraintSpace(),
@@ -190,8 +185,7 @@ void NGCustomLayoutAlgorithm::AddAnyOutOfFlowPositionedChildren(
DCHECK(child);
while (*child && child->IsOutOfFlowPositioned()) {
container_builder_.AddOutOfFlowChildCandidate(
- To<NGBlockNode>(*child), {border_scrollbar_padding_.inline_start,
- border_scrollbar_padding_.block_start});
+ To<NGBlockNode>(*child), BorderScrollbarPadding().StartOffset());
*child = child->NextSibling();
}
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.h
index 2ba330632c7..950ce9da4c2 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.h
@@ -29,8 +29,6 @@ class CORE_EXPORT NGCustomLayoutAlgorithm
scoped_refptr<const NGLayoutResult> FallbackLayout();
const NGLayoutAlgorithmParams& params_;
- const NGBoxStrut border_padding_;
- const NGBoxStrut border_scrollbar_padding_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/pending_layout_registry.cc b/chromium/third_party/blink/renderer/core/layout/ng/custom/pending_layout_registry.cc
index 644f324ac9c..8c9b1e0f2c8 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/pending_layout_registry.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/pending_layout_registry.cc
@@ -42,7 +42,7 @@ void PendingLayoutRegistry::AddPendingLayout(const AtomicString& name,
set->insert(node);
}
-void PendingLayoutRegistry::Trace(Visitor* visitor) {
+void PendingLayoutRegistry::Trace(Visitor* visitor) const {
visitor->Trace(pending_layouts_);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/pending_layout_registry.h b/chromium/third_party/blink/renderer/core/layout/ng/custom/pending_layout_registry.h
index 8afe379befd..f0c7eb34ce5 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/pending_layout_registry.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/pending_layout_registry.h
@@ -23,7 +23,7 @@ class PendingLayoutRegistry : public GarbageCollected<PendingLayoutRegistry> {
void NotifyLayoutReady(const AtomicString& name);
void AddPendingLayout(const AtomicString& name, Node*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// This is a map of Nodes which are waiting for a CSSLayoutDefinition to be
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc
index 6de92e5be92..8a38aba09cc 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc
@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_space_utils.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
+#include "third_party/blink/renderer/core/style/computed_style_constants.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -27,10 +28,6 @@ namespace blink {
NGFlexLayoutAlgorithm::NGFlexLayoutAlgorithm(
const NGLayoutAlgorithmParams& params)
: NGLayoutAlgorithm(params),
- border_padding_(params.fragment_geometry.border +
- params.fragment_geometry.padding),
- border_scrollbar_padding_(border_padding_ +
- params.fragment_geometry.scrollbar),
is_column_(Style().ResolvedIsColumnFlexDirection()),
is_horizontal_flow_(FlexLayoutAlgorithm::IsHorizontalFlow(Style())),
is_cross_size_definite_(IsContainerCrossSizeDefinite()) {
@@ -39,10 +36,8 @@ NGFlexLayoutAlgorithm::NGFlexLayoutAlgorithm(
container_builder_.SetInitialFragmentGeometry(params.fragment_geometry);
border_box_size_ = container_builder_.InitialBorderBoxSize();
- content_box_size_ =
- ShrinkAvailableSize(border_box_size_, border_scrollbar_padding_);
child_percentage_size_ = CalculateChildPercentageSize(
- ConstraintSpace(), Node(), content_box_size_);
+ ConstraintSpace(), Node(), ChildAvailableSize());
algorithm_.emplace(&Style(), MainAxisContentExtent(LayoutUnit::Max()),
child_percentage_size_, &Node().GetDocument());
@@ -57,20 +52,22 @@ bool NGFlexLayoutAlgorithm::MainAxisIsInlineAxis(
LayoutUnit NGFlexLayoutAlgorithm::MainAxisContentExtent(
LayoutUnit sum_hypothetical_main_size) const {
if (Style().ResolvedIsColumnFlexDirection()) {
- // Even though we only pass border_padding_ in the third parameter, the
+ // Even though we only pass border_padding in the third parameter, the
// return value includes scrollbar, so subtract scrollbar to get content
// size.
- // We add border_scrollbar_padding to the fourth parameter because
+ // We add |border_scrollbar_padding| to the fourth parameter because
// |content_size| needs to be the size of the border box. We've overloaded
// the term "content".
- return ComputeBlockSizeForFragment(ConstraintSpace(), Style(),
- border_padding_,
- sum_hypothetical_main_size +
- border_scrollbar_padding_.BlockSum(),
- border_box_size_.inline_size) -
- border_scrollbar_padding_.BlockSum();
+ const LayoutUnit border_scrollbar_padding =
+ BorderScrollbarPadding().BlockSum();
+ return ComputeBlockSizeForFragment(
+ ConstraintSpace(), Style(), BorderPadding(),
+ sum_hypothetical_main_size.ClampNegativeToZero() +
+ border_scrollbar_padding,
+ border_box_size_.inline_size) -
+ border_scrollbar_padding;
}
- return content_box_size_.inline_size;
+ return ChildAvailableSize().inline_size;
}
namespace {
@@ -103,15 +100,20 @@ AxisEdge CrossAxisStaticPositionEdge(const ComputedStyle& style,
const ComputedStyle& child_style) {
ItemPosition alignment =
FlexLayoutAlgorithm::AlignmentForChild(style, child_style);
- bool is_wrap_reverse = style.FlexWrap() == EFlexWrap::kWrapReverse;
+ // AlignmentForChild already accounted for wrap-reverse for kFlexStart and
+ // kFlexEnd, but not kStretch. kStretch is supposed to act like kFlexStart.
+ if (style.FlexWrap() == EFlexWrap::kWrapReverse &&
+ alignment == ItemPosition::kStretch) {
+ return AxisEdge::kEnd;
+ }
if (alignment == ItemPosition::kFlexEnd)
- return is_wrap_reverse ? AxisEdge::kStart : AxisEdge::kEnd;
+ return AxisEdge::kEnd;
if (alignment == ItemPosition::kCenter)
return AxisEdge::kCenter;
- return is_wrap_reverse ? AxisEdge::kEnd : AxisEdge::kStart;
+ return AxisEdge::kStart;
}
} // namespace
@@ -129,18 +131,17 @@ void NGFlexLayoutAlgorithm::HandleOutOfFlowPositioned(NGBlockNode child) {
InlineEdge inline_edge;
BlockEdge block_edge;
- LogicalOffset offset(border_scrollbar_padding_.inline_start,
- border_scrollbar_padding_.block_start);
+ LogicalOffset offset = BorderScrollbarPadding().StartOffset();
// Determine the static-position based off the axis-edge.
if (inline_axis_edge == AxisEdge::kStart) {
inline_edge = InlineEdge::kInlineStart;
} else if (inline_axis_edge == AxisEdge::kCenter) {
inline_edge = InlineEdge::kInlineCenter;
- offset.inline_offset += content_box_size_.inline_size / 2;
+ offset.inline_offset += ChildAvailableSize().inline_size / 2;
} else {
inline_edge = InlineEdge::kInlineEnd;
- offset.inline_offset += content_box_size_.inline_size;
+ offset.inline_offset += ChildAvailableSize().inline_size;
}
// We may not know the final block-size of the fragment yet. This will be
@@ -149,10 +150,10 @@ void NGFlexLayoutAlgorithm::HandleOutOfFlowPositioned(NGBlockNode child) {
block_edge = BlockEdge::kBlockStart;
} else if (block_axis_edge == AxisEdge::kCenter) {
block_edge = BlockEdge::kBlockCenter;
- offset.block_offset -= border_scrollbar_padding_.BlockSum() / 2;
+ offset.block_offset -= BorderScrollbarPadding().BlockSum() / 2;
} else {
block_edge = BlockEdge::kBlockEnd;
- offset.block_offset -= border_scrollbar_padding_.BlockSum();
+ offset.block_offset -= BorderScrollbarPadding().BlockSum();
}
container_builder_.AddOutOfFlowChildCandidate(child, offset, inline_edge,
@@ -329,16 +330,17 @@ double NGFlexLayoutAlgorithm::GetMainOverCrossAspectRatio(
return ratio;
}
-namespace {
-
-LayoutUnit CalculateFixedCrossSize(LayoutUnit available_size,
- const MinMaxSizes& cross_axis_min_max,
- LayoutUnit margin_sum) {
+LayoutUnit NGFlexLayoutAlgorithm::CalculateFixedCrossSize(
+ const MinMaxSizes& cross_axis_min_max,
+ const NGBoxStrut& margins) const {
+ if (!is_column_)
+ DCHECK_NE(ChildAvailableSize().block_size, kIndefiniteSize);
+ LayoutUnit available_size = is_column_ ? ChildAvailableSize().inline_size
+ : ChildAvailableSize().block_size;
+ LayoutUnit margin_sum = is_column_ ? margins.InlineSum() : margins.BlockSum();
return cross_axis_min_max.ClampSizeToMinAndMax(available_size - margin_sum);
}
-} // namespace
-
NGConstraintSpace NGFlexLayoutAlgorithm::BuildSpaceForIntrinsicBlockSize(
const NGBlockNode& flex_item,
const NGPhysicalBoxStrut& physical_margins = NGPhysicalBoxStrut(),
@@ -354,22 +356,19 @@ NGConstraintSpace NGFlexLayoutAlgorithm::BuildSpaceForIntrinsicBlockSize(
NGBoxStrut margins = physical_margins.ConvertToLogical(
ConstraintSpace().GetWritingMode(), Style().Direction());
- LogicalSize child_available_size = content_box_size_;
+ LogicalSize child_available_size = ChildAvailableSize();
if (ShouldItemShrinkToFit(flex_item)) {
space_builder.SetIsShrinkToFit(true);
} else if (cross_axis_min_max.min_size != kIndefiniteSize &&
WillChildCrossSizeBeContainerCrossSize(flex_item)) {
+ LayoutUnit cross_size =
+ CalculateFixedCrossSize(cross_axis_min_max, margins);
if (is_column_) {
space_builder.SetIsFixedInlineSize(true);
- child_available_size.inline_size =
- CalculateFixedCrossSize(child_available_size.inline_size,
- cross_axis_min_max, margins.InlineSum());
+ child_available_size.inline_size = cross_size;
} else {
space_builder.SetIsFixedBlockSize(true);
- DCHECK_NE(content_box_size_.block_size, kIndefiniteSize);
- child_available_size.block_size =
- CalculateFixedCrossSize(child_available_size.block_size,
- cross_axis_min_max, margins.BlockSum());
+ child_available_size.block_size = cross_size;
}
}
@@ -402,7 +401,7 @@ NGConstraintSpace NGFlexLayoutAlgorithm::BuildSpaceForFlexBasis(
// This space is only used for resolving lengths, not for layout. We only
// need the available and percentage sizes.
- space_builder.SetAvailableSize(content_box_size_);
+ space_builder.SetAvailableSize(ChildAvailableSize());
space_builder.SetPercentageResolutionSize(child_percentage_size_);
space_builder.SetReplacedPercentageResolutionSize(child_percentage_size_);
return space_builder.ToConstraintSpace();
@@ -439,20 +438,15 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() {
: physical_border_padding.HorizontalSum();
base::Optional<MinMaxSizesResult> min_max_sizes;
- auto MinMaxSizesFunc = [&]() -> MinMaxSizesResult {
+ auto MinMaxSizesFunc = [&](MinMaxSizesType type) -> MinMaxSizesResult {
if (!min_max_sizes) {
- NGConstraintSpace child_space = BuildSpaceForIntrinsicBlockSize(child);
- if (child_style.OverflowBlockDirection() == EOverflow::kAuto) {
- // Ensure this child has been laid out so its auto scrollbars are
- // included in its intrinsic sizes.
- child.Layout(child_space);
- }
// We want the child's intrinsic inline sizes in its writing mode, so
// pass child's writing mode as the first parameter, which is nominally
// |container_writing_mode|.
- min_max_sizes = child.ComputeMinMaxSizes(
- child_style.GetWritingMode(),
- MinMaxSizesInput(content_box_size_.block_size), &child_space);
+ NGConstraintSpace child_space = BuildSpaceForIntrinsicBlockSize(child);
+ MinMaxSizesInput input(ChildAvailableSize().block_size, type);
+ min_max_sizes = child.ComputeMinMaxSizes(child_style.GetWritingMode(),
+ input, &child_space);
}
return *min_max_sizes;
};
@@ -528,27 +522,25 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() {
// https://drafts.csswg.org/css-flexbox/#algo-main-item
const Length& cross_axis_length =
is_horizontal_flow_ ? child.Style().Height() : child.Style().Width();
- if (child.HasAspectRatio() &&
- (IsItemCrossAxisLengthDefinite(child, cross_axis_length))) {
+ // This check should use HasAspectRatio() instead of Style().
+ // AspectRatio(), but to avoid introducing a behavior change we only
+ // do this for the aspect-ratio property for now until FlexNG ships.
+ bool use_cross_axis_for_aspect_ratio =
+ child.Style().AspectRatio() &&
+ WillChildCrossSizeBeContainerCrossSize(child);
+ if (use_cross_axis_for_aspect_ratio ||
+ (child.HasAspectRatio() &&
+ (IsItemCrossAxisLengthDefinite(child, cross_axis_length)))) {
// This is Part B of 9.2.3
// https://drafts.csswg.org/css-flexbox/#algo-main-item It requires that
// the item has a definite cross size.
- //
- // But for determining the flex-basis of aspect ratio items, both legacy
- // and FF both ignore part of the flex spec that has a more lenient
- // definition of definite.
- // https://drafts.csswg.org/css-flexbox/#definite says "If a single-line
- // flex container has a definite cross size, the outer cross size of any
- // stretched flex items is the flex container's inner cross size
- // (clamped to the flex item's min and max cross size) and is considered
- // definite". But when this happens, neither legacy nor firefox use the
- // container's cross size to calculate the item's main size, they just
- // fall to block E. E.g. Legacy and FF show a 16x100 green square
- // instead of a 100x100 green square for
- // https://jsfiddle.net/dgrogan/djh5wu0x/1/. I think it should be
- // 100x100.
LayoutUnit cross_size;
- if (MainAxisIsInlineAxis(child)) {
+ if (use_cross_axis_for_aspect_ratio) {
+ NGBoxStrut margins = physical_child_margins.ConvertToLogical(
+ ConstraintSpace().GetWritingMode(), Style().Direction());
+ cross_size = CalculateFixedCrossSize(
+ min_max_sizes_in_cross_axis_direction, margins);
+ } else if (MainAxisIsInlineAxis(child)) {
cross_size = ResolveMainBlockLength(
flex_basis_space, child_style,
border_padding_in_child_writing_mode, cross_axis_length,
@@ -575,12 +567,14 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() {
// is not exactly correct.
// TODO(dgrogan): Replace with a variant of ComputeReplacedSize that
// ignores min-width, width, max-width.
- MinMaxSizesInput input(child_percentage_size_.block_size);
+ MinMaxSizesInput input(child_percentage_size_.block_size,
+ MinMaxSizesType::kContent);
flex_base_border_box =
ComputeMinAndMaxContentContribution(Style(), child, input)
.sizes.max_size;
} else {
- flex_base_border_box = MinMaxSizesFunc().sizes.max_size;
+ flex_base_border_box =
+ MinMaxSizesFunc(MinMaxSizesType::kContent).sizes.max_size;
}
} else {
// Parts C, D, and E for what are usually column flex containers.
@@ -627,14 +621,16 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() {
MinMaxSizes table_preferred_widths =
ComputeMinAndMaxContentContribution(
Style(), child,
- MinMaxSizesInput(child_percentage_size_.block_size))
+ MinMaxSizesInput(child_percentage_size_.block_size,
+ MinMaxSizesType::kIntrinsic))
.sizes;
min_max_sizes_in_main_axis_direction.min_size =
table_preferred_widths.min_size;
} else {
LayoutUnit content_size_suggestion;
if (MainAxisIsInlineAxis(child)) {
- content_size_suggestion = MinMaxSizesFunc().sizes.min_size;
+ content_size_suggestion =
+ MinMaxSizesFunc(MinMaxSizesType::kContent).sizes.min_size;
} else {
LayoutUnit intrinsic_block_size;
if (child.IsReplaced()) {
@@ -737,12 +733,13 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() {
DCHECK_GE(min_max_sizes_in_main_axis_direction.min_size, 0);
DCHECK_GE(min_max_sizes_in_main_axis_direction.max_size, 0);
+ NGBoxStrut scrollbars = ComputeScrollbarsForNonAnonymous(child);
algorithm_
->emplace_back(nullptr, child.Style(), flex_base_content_size,
min_max_sizes_in_main_axis_direction,
min_max_sizes_in_cross_axis_direction,
main_axis_border_padding, cross_axis_border_padding,
- physical_child_margins)
+ physical_child_margins, scrollbars)
.ng_input_node = child;
}
}
@@ -791,27 +788,49 @@ NGFlexLayoutAlgorithm::AdjustChildSizeForAspectRatioCrossAxisMinAndMax(
}
scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
+ if (auto result = LayoutInternal())
+ return result;
+
+ // We may have aborted layout due to a child changing scrollbars, relayout
+ // with the new scrollbar information.
+ return RelayoutIgnoringChildScrollbarChanges();
+}
+
+scoped_refptr<const NGLayoutResult>
+NGFlexLayoutAlgorithm::RelayoutIgnoringChildScrollbarChanges() {
+ DCHECK(!ignore_child_scrollbar_changes_);
+ // Freezing the scrollbars for the sub-tree shouldn't be strictly necessary,
+ // but we do this just in case we trigger an unstable layout.
+ PaintLayerScrollableArea::FreezeScrollbarsScope freeze_scrollbars;
+ NGLayoutAlgorithmParams params(
+ Node(), container_builder_.InitialFragmentGeometry(), ConstraintSpace(),
+ BreakToken(), /* early_break */ nullptr);
+ NGFlexLayoutAlgorithm algorithm(params);
+ algorithm.ignore_child_scrollbar_changes_ = true;
+ return algorithm.Layout();
+}
+
+scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::LayoutInternal() {
PaintLayerScrollableArea::DelayScrollOffsetClampScope delay_clamp_scope;
ConstructAndAppendFlexItems();
LayoutUnit main_axis_start_offset;
LayoutUnit main_axis_end_offset;
- LayoutUnit cross_axis_offset = border_scrollbar_padding_.block_start;
+ LayoutUnit cross_axis_offset = BorderScrollbarPadding().block_start;
if (is_column_) {
const bool is_column_reverse =
Style().ResolvedIsColumnReverseFlexDirection();
- main_axis_start_offset = is_column_reverse
- ? LayoutUnit()
- : border_scrollbar_padding_.block_start;
+ main_axis_start_offset =
+ is_column_reverse ? LayoutUnit() : BorderScrollbarPadding().block_start;
main_axis_end_offset =
- is_column_reverse ? LayoutUnit() : border_scrollbar_padding_.block_end;
- cross_axis_offset = border_scrollbar_padding_.inline_start;
+ is_column_reverse ? LayoutUnit() : BorderScrollbarPadding().block_end;
+ cross_axis_offset = BorderScrollbarPadding().inline_start;
} else if (Style().ResolvedIsRowReverseFlexDirection()) {
- main_axis_start_offset = border_scrollbar_padding_.inline_end;
- main_axis_end_offset = border_scrollbar_padding_.inline_start;
+ main_axis_start_offset = BorderScrollbarPadding().inline_end;
+ main_axis_end_offset = BorderScrollbarPadding().inline_start;
} else {
- main_axis_start_offset = border_scrollbar_padding_.inline_start;
- main_axis_end_offset = border_scrollbar_padding_.inline_end;
+ main_axis_start_offset = BorderScrollbarPadding().inline_start;
+ main_axis_end_offset = BorderScrollbarPadding().inline_end;
}
FlexLine* line;
while (
@@ -838,15 +857,14 @@ scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
NGBoxStrut margins = flex_item.physical_margins.ConvertToLogical(
ConstraintSpace().GetWritingMode(), Style().Direction());
if (is_column_) {
- available_size.inline_size = content_box_size_.inline_size;
+ available_size.inline_size = ChildAvailableSize().inline_size;
available_size.block_size =
flex_item.flexed_content_size + flex_item.main_axis_border_padding;
space_builder.SetIsFixedBlockSize(true);
if (WillChildCrossSizeBeContainerCrossSize(flex_item.ng_input_node)) {
space_builder.SetIsFixedInlineSize(true);
available_size.inline_size = CalculateFixedCrossSize(
- available_size.inline_size, flex_item.min_max_cross_sizes.value(),
- margins.InlineSum());
+ flex_item.min_max_cross_sizes.value(), margins);
}
// https://drafts.csswg.org/css-flexbox/#definite-sizes
// If the flex container has a definite main size, a flex item's
@@ -859,13 +877,12 @@ scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
} else {
available_size.inline_size =
flex_item.flexed_content_size + flex_item.main_axis_border_padding;
- available_size.block_size = content_box_size_.block_size;
+ available_size.block_size = ChildAvailableSize().block_size;
space_builder.SetIsFixedInlineSize(true);
if (WillChildCrossSizeBeContainerCrossSize(flex_item.ng_input_node)) {
space_builder.SetIsFixedBlockSize(true);
available_size.block_size = CalculateFixedCrossSize(
- available_size.block_size, flex_item.min_max_cross_sizes.value(),
- margins.BlockSum());
+ flex_item.min_max_cross_sizes.value(), margins);
} else if (DoesItemStretch(flex_item.ng_input_node)) {
// If we are in a row flexbox, and we don't have a fixed block-size
// (yet), use the "measure" cache slot. This will be the first
@@ -913,20 +930,28 @@ scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
cross_axis_offset);
}
- LayoutUnit intrinsic_block_size = algorithm_->IntrinsicContentBlockSize() +
- border_scrollbar_padding_.BlockSum();
+ LayoutUnit intrinsic_block_size = BorderScrollbarPadding().BlockSum();
+
+ if (algorithm_->FlexLines().IsEmpty() &&
+ To<LayoutBlock>(Node().GetLayoutBox())->HasLineIfEmpty()) {
+ intrinsic_block_size += Node().GetLayoutBox()->LogicalHeightForEmptyLine();
+ } else {
+ intrinsic_block_size += algorithm_->IntrinsicContentBlockSize();
+ }
intrinsic_block_size =
ClampIntrinsicBlockSize(ConstraintSpace(), Node(),
- border_scrollbar_padding_, intrinsic_block_size);
+ BorderScrollbarPadding(), intrinsic_block_size);
LayoutUnit block_size = ComputeBlockSizeForFragment(
- ConstraintSpace(), Style(), border_padding_, intrinsic_block_size,
+ ConstraintSpace(), Style(), BorderPadding(), intrinsic_block_size,
border_box_size_.inline_size);
container_builder_.SetIntrinsicBlockSize(intrinsic_block_size);
- container_builder_.SetBlockSize(block_size);
+ container_builder_.SetFragmentsTotalBlockSize(block_size);
- GiveLinesAndItemsFinalPositionAndSize();
+ bool success = GiveLinesAndItemsFinalPositionAndSize();
+ if (!success)
+ return nullptr;
NGOutOfFlowLayoutPart(
Node(), ConstraintSpace(),
@@ -973,16 +998,16 @@ void NGFlexLayoutAlgorithm::ApplyStretchAlignmentToChild(FlexItem& flex_item) {
flex_item.ng_input_node.Layout(child_space, /* break_token */ nullptr);
}
-void NGFlexLayoutAlgorithm::GiveLinesAndItemsFinalPositionAndSize() {
+bool NGFlexLayoutAlgorithm::GiveLinesAndItemsFinalPositionAndSize() {
Vector<FlexLine>& line_contexts = algorithm_->FlexLines();
const LayoutUnit cross_axis_start_edge =
line_contexts.IsEmpty() ? LayoutUnit()
: line_contexts[0].cross_axis_offset;
LayoutUnit final_content_main_size =
- container_builder_.InlineSize() - border_scrollbar_padding_.InlineSum();
- LayoutUnit final_content_cross_size =
- container_builder_.BlockSize() - border_scrollbar_padding_.BlockSum();
+ container_builder_.InlineSize() - BorderScrollbarPadding().InlineSum();
+ LayoutUnit final_content_cross_size = container_builder_.FragmentBlockSize() -
+ BorderScrollbarPadding().BlockSum();
if (is_column_)
std::swap(final_content_main_size, final_content_cross_size);
@@ -1003,11 +1028,12 @@ void NGFlexLayoutAlgorithm::GiveLinesAndItemsFinalPositionAndSize() {
if (Style().ResolvedIsColumnReverseFlexDirection()) {
algorithm_->LayoutColumnReverse(final_content_main_size,
- border_scrollbar_padding_.block_start);
+ BorderScrollbarPadding().block_start);
}
base::Optional<LayoutUnit> fallback_baseline;
+ bool success = true;
LayoutUnit overflow_block_size;
for (FlexLine& line_context : line_contexts) {
for (wtf_size_t child_number = 0;
@@ -1049,16 +1075,30 @@ void NGFlexLayoutAlgorithm::GiveLinesAndItemsFinalPositionAndSize() {
overflow_block_size =
std::max(overflow_block_size,
location.Y() + fragment.BlockSize() + margin_block_end);
+
+ // Detect if the flex-item had its scrollbar state change. If so we need
+ // to relayout as the input to the flex algorithm is incorrect.
+ if (!ignore_child_scrollbar_changes_) {
+ if (flex_item.scrollbars !=
+ ComputeScrollbarsForNonAnonymous(flex_item.ng_input_node))
+ success = false;
+ } else {
+ DCHECK_EQ(flex_item.scrollbars,
+ ComputeScrollbarsForNonAnonymous(flex_item.ng_input_node));
+ }
}
}
container_builder_.SetOverflowBlockSize(overflow_block_size +
- border_scrollbar_padding_.block_end);
+ BorderScrollbarPadding().block_end);
// Set the baseline to the fallback, if we didn't find any children with
// baseline alignment.
if (!container_builder_.Baseline() && fallback_baseline)
container_builder_.SetBaseline(*fallback_baseline);
+
+ // Signal if we need to relayout with new child scrollbar information.
+ return success;
}
void NGFlexLayoutAlgorithm::PropagateBaselineFromChild(
@@ -1090,7 +1130,7 @@ void NGFlexLayoutAlgorithm::PropagateBaselineFromChild(
MinMaxSizesResult NGFlexLayoutAlgorithm::ComputeMinMaxSizes(
const MinMaxSizesInput& child_input) const {
if (auto result = CalculateMinMaxSizesIgnoringChildren(
- Node(), border_scrollbar_padding_))
+ Node(), BorderScrollbarPadding()))
return *result;
MinMaxSizes sizes;
@@ -1136,7 +1176,7 @@ MinMaxSizesResult NGFlexLayoutAlgorithm::ComputeMinMaxSizes(
// Due to negative margins, it is possible that we calculated a negative
// intrinsic width. Make sure that we never return a negative width.
sizes.Encompass(LayoutUnit());
- sizes += border_scrollbar_padding_.InlineSum();
+ sizes += BorderScrollbarPadding().InlineSum();
return {sizes, depends_on_percentage_block_size};
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h
index e0e33c2bdc6..8bb19f7da46 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h
@@ -23,11 +23,13 @@ class CORE_EXPORT NGFlexLayoutAlgorithm
public:
NGFlexLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
- scoped_refptr<const NGLayoutResult> Layout() override;
-
MinMaxSizesResult ComputeMinMaxSizes(const MinMaxSizesInput&) const override;
+ scoped_refptr<const NGLayoutResult> Layout() override;
private:
+ scoped_refptr<const NGLayoutResult> RelayoutIgnoringChildScrollbarChanges();
+ scoped_refptr<const NGLayoutResult> LayoutInternal();
+
bool DoesItemCrossSizeComputeToAuto(const NGBlockNode& child) const;
bool IsItemFlexBasisDefinite(const NGBlockNode& child) const;
bool IsItemMainSizeDefinite(const NGBlockNode& child) const;
@@ -51,6 +53,9 @@ class CORE_EXPORT NGFlexLayoutAlgorithm
bool IsColumnContainerMainSizeDefinite() const;
bool IsContainerCrossSizeDefinite() const;
+ LayoutUnit CalculateFixedCrossSize(const MinMaxSizes& cross_axis_min_max,
+ const NGBoxStrut& margins) const;
+
NGConstraintSpace BuildSpaceForFlexBasis(const NGBlockNode& flex_item) const;
NGConstraintSpace BuildSpaceForIntrinsicBlockSize(
const NGBlockNode& flex_item,
@@ -58,7 +63,7 @@ class CORE_EXPORT NGFlexLayoutAlgorithm
const MinMaxSizes& cross_axis) const;
void ConstructAndAppendFlexItems();
void ApplyStretchAlignmentToChild(FlexItem& flex_item);
- void GiveLinesAndItemsFinalPositionAndSize();
+ bool GiveLinesAndItemsFinalPositionAndSize();
void LayoutColumnReverse(LayoutUnit main_axis_content_size);
// This is same method as FlexItem but we need that logic before FlexItem is
@@ -75,13 +80,11 @@ class CORE_EXPORT NGFlexLayoutAlgorithm
LayoutUnit block_offset,
base::Optional<LayoutUnit>* fallback_baseline);
- const NGBoxStrut border_padding_;
- const NGBoxStrut border_scrollbar_padding_;
const bool is_column_;
const bool is_horizontal_flow_;
const bool is_cross_size_definite_;
+ bool ignore_child_scrollbar_changes_ = false;
LogicalSize border_box_size_;
- LogicalSize content_box_size_;
LogicalSize child_percentage_size_;
base::Optional<FlexLayoutAlgorithm> algorithm_;
};
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_grid.cc b/chromium/third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.cc
index 672f1a4b32c..b4bdc582181 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_grid.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/renderer/core/layout/ng/layout_ng_grid.h"
+#include "third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_grid.h b/chromium/third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.h
index 060835974ba..d7601da5c03 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_grid.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LAYOUT_NG_GRID_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LAYOUT_NG_GRID_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_LAYOUT_NG_GRID_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_LAYOUT_NG_GRID_H_
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/layout_block.h"
@@ -28,4 +28,4 @@ class CORE_EXPORT LayoutNGGrid : public LayoutNGMixin<LayoutBlock> {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LAYOUT_NG_GRID_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_LAYOUT_NG_GRID_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.cc b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.cc
new file mode 100644
index 00000000000..d0791c16dea
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.cc
@@ -0,0 +1,37 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.h"
+
+namespace blink {
+
+NGGridChildIterator::NGGridChildIterator(const NGBlockNode node) {
+ Setup(node);
+}
+
+void NGGridChildIterator::Setup(const NGBlockNode node) {
+ const int initial_order = ComputedStyleInitialValues::InitialOrder();
+ bool needs_sort = false;
+
+ // Collect all our children, and order them by either their order property.
+ for (NGLayoutInputNode child = node.FirstChild(); child;
+ child = child.NextSibling()) {
+ int order = child.Style().Order();
+ needs_sort |= order != initial_order;
+ children_.emplace_back(To<NGBlockNode>(child), order);
+ }
+
+ // We only need to sort this vector if we encountered a non-initial order
+ // property.
+ if (needs_sort) {
+ std::stable_sort(children_.begin(), children_.end(),
+ [](const ChildWithOrder& c1, const ChildWithOrder& c2) {
+ return c1.order < c2.order;
+ });
+ }
+
+ iterator_ = children_.begin();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.h b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.h
new file mode 100644
index 00000000000..440e4a8180f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.h
@@ -0,0 +1,54 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_CHILD_ITERATOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_CHILD_ITERATOR_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+// A utility class which given the current grid node will iterate through its
+// children.
+//
+// TODO(layout-dev): Once LayoutNG supports NG-fragmentation this will need
+// to be updated to accept a break-token.
+//
+// This class does not handle modifications to its arguments after it has been
+// constructed.
+class CORE_EXPORT NGGridChildIterator {
+ STACK_ALLOCATED();
+
+ public:
+ explicit NGGridChildIterator(const NGBlockNode node);
+
+ // Returns the next block node which should be laid out.
+ NGBlockNode NextChild() {
+ if (iterator_ == children_.end())
+ return nullptr;
+
+ return (*iterator_++).child;
+ }
+
+ struct ChildWithOrder {
+ DISALLOW_NEW();
+ ChildWithOrder(NGBlockNode child, int order) : child(child), order(order) {}
+ NGBlockNode child;
+ int order;
+ };
+
+ protected:
+ virtual void Setup(const NGBlockNode node);
+ Vector<ChildWithOrder, 4> children_;
+ Vector<ChildWithOrder, 4>::const_iterator iterator_;
+};
+
+} // namespace blink
+
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(
+ blink::NGGridChildIterator::ChildWithOrder)
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_CHILD_ITERATOR_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator_test.cc
new file mode 100644
index 00000000000..d5468ce0775
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator_test.cc
@@ -0,0 +1,98 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_layout_test.h"
+
+namespace blink {
+namespace {
+
+TEST_F(NGLayoutTest, TestNGGridChildIterator) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="parent" style="display: grid">
+ <div id="child1">Child 1</div>
+ <div id="child2">Child 2</div>
+ <div id="child3">Child 3</div>
+ <div id="child4">Child 4</div>
+ </div>
+ )HTML");
+
+ NGBlockNode parent_block(ToLayoutBox(GetLayoutObjectByElementId("parent")));
+
+ int index = 0;
+ NGGridChildIterator iterator(parent_block);
+ for (NGBlockNode child = iterator.NextChild(); child;
+ child = iterator.NextChild()) {
+ StringBuilder cell_id;
+ cell_id.Append("child");
+ cell_id.Append(AtomicString::Number(++index));
+ NGBlockNode cell_block(ToLayoutBox(
+ GetLayoutObjectByElementId(cell_id.ToString().Ascii().c_str())));
+ EXPECT_EQ(child, cell_block);
+ }
+
+ EXPECT_EQ(index, 4);
+}
+
+TEST_F(NGLayoutTest, TestNGGridChildIteratorWithOrderReversed) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="parent" style="display: grid">
+ <div id="child1" style="order: 4">Child 1</div>
+ <div id="child2" style="order: 3">Child 2</div>
+ <div id="child3" style="order: 2">Child 3</div>
+ <div id="child4" style="order: 1">Child 4</div>
+ </div>
+ )HTML");
+
+ NGBlockNode parent_block(ToLayoutBox(GetLayoutObjectByElementId("parent")));
+
+ int index = 4;
+ NGGridChildIterator iterator(parent_block);
+ for (NGBlockNode child = iterator.NextChild(); child;
+ child = iterator.NextChild()) {
+ StringBuilder cell_id;
+ cell_id.Append("child");
+ cell_id.Append(AtomicString::Number(index));
+ NGBlockNode cell_block(ToLayoutBox(
+ GetLayoutObjectByElementId(cell_id.ToString().Ascii().c_str())));
+ EXPECT_EQ(child, cell_block);
+ --index;
+ }
+
+ EXPECT_EQ(index, 0);
+}
+
+TEST_F(NGLayoutTest, TestNGGridChildIteratorWithOrderMixed) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="parent" style="display: grid">
+ <div id="child1" style="order: 3">Child 1</div>
+ <div id="child2" style="order: 3">Child 2</div>
+ <div id="child3" style="order: -1">Child 3</div>
+ <div id="child4" style="order: 0">Child 4</div>
+ </div>
+ )HTML");
+
+ NGBlockNode parent_block(ToLayoutBox(GetLayoutObjectByElementId("parent")));
+ int expected_order[] = {3, 4, 1, 2};
+
+ int index = 0;
+ NGGridChildIterator iterator(parent_block);
+ for (NGBlockNode child = iterator.NextChild(); child;
+ child = iterator.NextChild()) {
+ StringBuilder cell_id;
+ cell_id.Append("child");
+ cell_id.Append(AtomicString::Number(expected_order[index]));
+ NGBlockNode cell_block(ToLayoutBox(
+ GetLayoutObjectByElementId(cell_id.ToString().Ascii().c_str())));
+ EXPECT_EQ(child, cell_block);
+ ++index;
+ }
+
+ EXPECT_EQ(index, 4);
+}
+
+} // namespace
+
+} // namespace blink
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
new file mode 100644
index 00000000000..63c63ee2c72
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc
@@ -0,0 +1,76 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h"
+
+#include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
+
+namespace blink {
+
+NGGridLayoutAlgorithm::NGGridLayoutAlgorithm(
+ const NGLayoutAlgorithmParams& params)
+ : NGLayoutAlgorithm(params),
+ state_(GridLayoutAlgorithmState::kMeasuringItems) {
+ DCHECK(params.space.IsNewFormattingContext());
+ DCHECK(!params.break_token);
+ container_builder_.SetIsNewFormattingContext(true);
+ container_builder_.SetInitialFragmentGeometry(params.fragment_geometry);
+
+ child_percentage_size_ = CalculateChildPercentageSize(
+ ConstraintSpace(), Node(), ChildAvailableSize());
+}
+
+scoped_refptr<const NGLayoutResult> NGGridLayoutAlgorithm::Layout() {
+ switch (state_) {
+ case GridLayoutAlgorithmState::kMeasuringItems:
+ ConstructAndAppendGridItems();
+ break;
+
+ default:
+ break;
+ }
+
+ return container_builder_.ToBoxFragment();
+}
+
+MinMaxSizesResult NGGridLayoutAlgorithm::ComputeMinMaxSizes(
+ const MinMaxSizesInput& input) const {
+ return {MinMaxSizes(), /* depends_on_percentage_block_size */ true};
+}
+
+void NGGridLayoutAlgorithm::ConstructAndAppendGridItems() {
+ NGGridChildIterator iterator(Node());
+ for (NGBlockNode child = iterator.NextChild(); child;
+ child = iterator.NextChild()) {
+ ConstructAndAppendGridItem(child);
+ }
+}
+
+void NGGridLayoutAlgorithm::ConstructAndAppendGridItem(
+ const NGBlockNode& node) {
+ GridItem item;
+ item.constraint_space = BuildSpaceForMeasure(node);
+ items_.emplace_back(item);
+}
+
+NGConstraintSpace NGGridLayoutAlgorithm::BuildSpaceForMeasure(
+ const NGBlockNode& grid_item) {
+ const ComputedStyle& child_style = grid_item.Style();
+
+ NGConstraintSpaceBuilder space_builder(ConstraintSpace(),
+ child_style.GetWritingMode(),
+ /* is_new_fc */ true);
+ space_builder.SetCacheSlot(NGCacheSlot::kMeasure);
+ space_builder.SetIsPaintedAtomically(true);
+
+ // TODO(kschmi) - do layout/measuring and handle non-fixed sizes here.
+ space_builder.SetAvailableSize(ChildAvailableSize());
+ space_builder.SetPercentageResolutionSize(child_percentage_size_);
+ space_builder.SetTextDirection(child_style.Direction());
+ return space_builder.ToConstraintSpace();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_grid_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h
index 65530019710..e0898325e1a 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_grid_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_GRID_LAYOUT_ALGORITHM_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_GRID_LAYOUT_ALGORITHM_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_LAYOUT_ALGORITHM_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_LAYOUT_ALGORITHM_H_
#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -21,8 +23,27 @@ class CORE_EXPORT NGGridLayoutAlgorithm
scoped_refptr<const NGLayoutResult> Layout() override;
MinMaxSizesResult ComputeMinMaxSizes(const MinMaxSizesInput&) const override;
+
+ private:
+ friend class NGGridLayoutAlgorithmTest;
+
+ void ConstructAndAppendGridItems();
+ void ConstructAndAppendGridItem(const NGBlockNode& node);
+ NGConstraintSpace BuildSpaceForMeasure(const NGBlockNode& grid_item);
+
+ enum class GridLayoutAlgorithmState {
+ kMeasuringItems,
+ };
+ GridLayoutAlgorithmState state_;
+
+ struct GridItem {
+ NGConstraintSpace constraint_space;
+ };
+ Vector<GridItem> items_;
+
+ LogicalSize child_percentage_size_;
};
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_GRID_LAYOUT_ALGORITHM_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_LAYOUT_ALGORITHM_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm_test.cc
new file mode 100644
index 00000000000..0f991d63a5d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm_test.cc
@@ -0,0 +1,106 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
+
+namespace blink {
+
+class NGGridLayoutAlgorithmTest
+ : public NGBaseLayoutAlgorithmTest,
+ private ScopedLayoutNGGridForTest,
+ private ScopedLayoutNGBlockFragmentationForTest {
+ protected:
+ NGGridLayoutAlgorithmTest()
+ : ScopedLayoutNGGridForTest(true),
+ ScopedLayoutNGBlockFragmentationForTest(true) {}
+ void SetUp() override {
+ NGBaseLayoutAlgorithmTest::SetUp();
+ style_ = ComputedStyle::Create();
+ }
+
+ // Helper methods to access private data on NGGridLayoutAlgorithm. This class
+ // is a friend of NGGridLayoutAlgorithm but the individual tests are not.
+ size_t GridItemSize(NGGridLayoutAlgorithm& algorithm) {
+ return algorithm.items_.size();
+ }
+
+ Vector<NGConstraintSpace> GridItemConstraintSpaces(
+ NGGridLayoutAlgorithm& algorithm) {
+ Vector<NGConstraintSpace> constraint_spaces;
+ for (auto& item : algorithm.items_) {
+ constraint_spaces.push_back(NGConstraintSpace(item.constraint_space));
+ }
+ return constraint_spaces;
+ }
+
+ scoped_refptr<ComputedStyle> style_;
+};
+
+TEST_F(NGGridLayoutAlgorithmTest, NGGridLayoutAlgorithmMeasuring) {
+ if (!RuntimeEnabledFeatures::LayoutNGGridEnabled())
+ return;
+
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #grid1 {
+ display: grid;
+ grid-template-columns: 100px 100px;
+ grid-template-rows: 100px 100px;
+ }
+ #cell1 {
+ grid-column: 1;
+ grid-row: 1;
+ width: 50px;
+ }
+ #cell2 {
+ grid-column: 2;
+ grid-row: 1;
+ width: 50px;
+ }
+ #cell3 {
+ grid-column: 1;
+ grid-row: 2;
+ width: 50px;
+ }
+ #cell4 {
+ grid-column: 2;
+ grid-row: 2;
+ width: 50px;
+ }
+ </style>
+ <div id="grid1">
+ <div id="cell1">Cell 1</div>
+ <div id="cell2">Cell 2</div>
+ <div id="cell3">Cell 3</div>
+ <div id="cell4">Cell 4</div>
+ </div>
+ )HTML");
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("grid1")));
+
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(100), LayoutUnit(100)), false, true);
+
+ NGFragmentGeometry fragment_geometry =
+ CalculateInitialFragmentGeometry(space, node);
+
+ NGGridLayoutAlgorithm algorithm({node, fragment_geometry, space});
+ EXPECT_EQ(GridItemSize(algorithm), 0U);
+ algorithm.Layout();
+ EXPECT_EQ(GridItemSize(algorithm), 4U);
+
+ Vector<NGConstraintSpace> constraint_spaces =
+ GridItemConstraintSpaces(algorithm);
+
+ EXPECT_EQ(GridItemSize(algorithm), constraint_spaces.size());
+ for (auto& constraint_space : constraint_spaces) {
+ EXPECT_EQ(constraint_space.AvailableSize().inline_size.ToInt(), 100);
+ }
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..26c190ad4a7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc
@@ -0,0 +1,510 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h"
+#include "base/check.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+
+namespace blink {
+
+constexpr wtf_size_t NGGridTrackCollectionBase::kInvalidRangeIndex;
+
+wtf_size_t NGGridTrackCollectionBase::RangeIndexFromTrackNumber(
+ wtf_size_t track_number) const {
+ wtf_size_t upper = RangeCount();
+ wtf_size_t lower = 0u;
+
+ // We can't look for a range in a collection with no ranges.
+ DCHECK_NE(upper, 0u);
+ // We don't expect a |track_number| outside of the bounds of the collection.
+ DCHECK_NE(track_number, kInvalidRangeIndex);
+ DCHECK_LT(track_number,
+ RangeTrackNumber(upper - 1u) + RangeTrackCount(upper - 1u));
+
+ // Do a binary search on the tracks.
+ wtf_size_t range = upper - lower;
+ while (range > 1) {
+ wtf_size_t center = lower + (range / 2u);
+
+ wtf_size_t center_track_number = RangeTrackNumber(center);
+ wtf_size_t center_track_count = RangeTrackCount(center);
+
+ if (center_track_number <= track_number &&
+ (track_number - center_track_number) < center_track_count) {
+ // We found the track.
+ return center;
+ } else if (center_track_number > track_number) {
+ // This track is too high.
+ upper = center;
+ range = upper - lower;
+ } else {
+ // This track is too low.
+ lower = center + 1u;
+ range = upper - lower;
+ }
+ }
+
+ return lower;
+}
+
+String NGGridTrackCollectionBase::ToString() const {
+ if (RangeCount() == kInvalidRangeIndex)
+ return "NGGridTrackCollection: Empty";
+
+ StringBuilder builder;
+ builder.Append("NGGridTrackCollection: [RangeCount: ");
+ builder.AppendNumber<wtf_size_t>(RangeCount());
+ builder.Append("], Ranges: ");
+ for (wtf_size_t range_index = 0; range_index < RangeCount(); ++range_index) {
+ builder.Append("[Start: ");
+ builder.AppendNumber<wtf_size_t>(RangeTrackNumber(range_index));
+ builder.Append(", Count: ");
+ builder.AppendNumber<wtf_size_t>(RangeTrackCount(range_index));
+ if (IsRangeCollapsed(range_index)) {
+ builder.Append(", Collapsed ");
+ }
+ builder.Append("]");
+ if (range_index + 1 < RangeCount())
+ builder.Append(", ");
+ }
+ return builder.ToString();
+}
+
+NGGridTrackCollectionBase::RangeRepeatIterator::RangeRepeatIterator(
+ const NGGridTrackCollectionBase* collection,
+ wtf_size_t range_index)
+ : collection_(collection) {
+ DCHECK(collection_);
+ range_count_ = collection_->RangeCount();
+ SetRangeIndex(range_index);
+}
+
+bool NGGridTrackCollectionBase::RangeRepeatIterator::MoveToNextRange() {
+ return SetRangeIndex(range_index_ + 1);
+}
+
+wtf_size_t NGGridTrackCollectionBase::RangeRepeatIterator::RepeatCount() const {
+ return range_track_count_;
+}
+
+wtf_size_t NGGridTrackCollectionBase::RangeRepeatIterator::RangeTrackStart()
+ const {
+ return range_track_start_;
+}
+
+wtf_size_t NGGridTrackCollectionBase::RangeRepeatIterator::RangeTrackEnd()
+ const {
+ if (range_index_ == kInvalidRangeIndex)
+ return kInvalidRangeIndex;
+ return range_track_start_ + range_track_count_ - 1;
+}
+
+bool NGGridTrackCollectionBase::RangeRepeatIterator::IsRangeCollapsed() const {
+ DCHECK(range_index_ != kInvalidRangeIndex);
+ DCHECK(collection_);
+ return collection_->IsRangeCollapsed(range_index_);
+}
+
+bool NGGridTrackCollectionBase::RangeRepeatIterator::SetRangeIndex(
+ wtf_size_t range_index) {
+ if (range_index < 0 || range_index >= range_count_) {
+ // Invalid index.
+ range_index_ = kInvalidRangeIndex;
+ range_track_start_ = kInvalidRangeIndex;
+ range_track_count_ = 0;
+ return false;
+ }
+
+ range_index_ = range_index;
+ range_track_start_ = collection_->RangeTrackNumber(range_index_);
+ range_track_count_ = collection_->RangeTrackCount(range_index_);
+ return true;
+}
+
+NGGridTrackRepeater::NGGridTrackRepeater(wtf_size_t track_index,
+ wtf_size_t repeat_size,
+ wtf_size_t repeat_count,
+ RepeatType repeat_type)
+ : track_index(track_index),
+ repeat_size(repeat_size),
+ repeat_count(repeat_count),
+ repeat_type(repeat_type) {}
+
+String NGGridTrackRepeater::ToString() const {
+ StringBuilder builder;
+ builder.Append("Repeater: [Index: ");
+ builder.AppendNumber<wtf_size_t>(track_index);
+ builder.Append("], [RepeatSize: ");
+ builder.AppendNumber<wtf_size_t>(repeat_size);
+ builder.Append("], [RepeatCount: ");
+ switch (repeat_type) {
+ case RepeatType::kCount:
+ builder.AppendNumber<wtf_size_t>(repeat_count);
+ builder.Append("]");
+ break;
+ case RepeatType::kAutoFill:
+ builder.Append("auto-fill]");
+ break;
+ case RepeatType::kAutoFit:
+ builder.Append("auto-fit]");
+ break;
+ }
+ return builder.ToString();
+}
+
+NGGridTrackList::NGGridTrackList() {
+ auto_repeater_index_ = NGGridTrackCollectionBase::kInvalidRangeIndex;
+ total_track_count_ = 0;
+}
+
+wtf_size_t NGGridTrackList::RepeatCount(wtf_size_t index,
+ wtf_size_t auto_value) const {
+ DCHECK_LT(index, RepeaterCount());
+ if (index == auto_repeater_index_)
+ return auto_value;
+ return repeaters_[index].repeat_count;
+}
+
+wtf_size_t NGGridTrackList::RepeatSize(wtf_size_t index) const {
+ DCHECK_LT(index, RepeaterCount());
+ return repeaters_[index].repeat_size;
+}
+
+NGGridTrackRepeater::RepeatType NGGridTrackList::RepeatType(
+ wtf_size_t index) const {
+ DCHECK_LT(index, RepeaterCount());
+ return repeaters_[index].repeat_type;
+}
+
+wtf_size_t NGGridTrackList::RepeaterCount() const {
+ return repeaters_.size();
+}
+
+wtf_size_t NGGridTrackList::TotalTrackCount() const {
+ return total_track_count_;
+}
+
+bool NGGridTrackList::AddRepeater(wtf_size_t track_index,
+ wtf_size_t track_count,
+ wtf_size_t repeat_count) {
+ return AddRepeater(track_index, track_count, repeat_count,
+ NGGridTrackRepeater::RepeatType::kCount);
+}
+
+bool NGGridTrackList::AddAutoRepeater(
+ wtf_size_t track_index,
+ wtf_size_t track_count,
+ NGGridTrackRepeater::RepeatType repeat_type) {
+ return AddRepeater(track_index, track_count, 1u, repeat_type);
+}
+
+bool NGGridTrackList::AddRepeater(wtf_size_t track_index,
+ wtf_size_t track_count,
+ wtf_size_t repeat_count,
+ NGGridTrackRepeater::RepeatType repeat_type) {
+ // Ensure valid track index.
+ DCHECK_NE(NGGridTrackCollectionBase::kInvalidRangeIndex, track_index);
+
+#if DCHECK_IS_ON()
+ // Ensure we do not skip or overlap tracks.
+ DCHECK(IsTrackContiguous(track_index));
+#endif
+
+ // If the repeater is auto, the repeat_count should be 1.
+ DCHECK(repeat_type == NGGridTrackRepeater::RepeatType::kCount ||
+ repeat_count == 1u);
+
+ // Ensure adding tracks will not overflow the total in this track list and
+ // that there is only one auto repeater per track list.
+ switch (repeat_type) {
+ case NGGridTrackRepeater::RepeatType::kCount:
+ if (track_count > AvailableTrackCount() / repeat_count)
+ return false;
+ total_track_count_ += track_count * repeat_count;
+ break;
+ case NGGridTrackRepeater::RepeatType::kAutoFill:
+ case NGGridTrackRepeater::RepeatType::kAutoFit: // Intentional Fallthrough.
+ if (HasAutoRepeater() || track_count > AvailableTrackCount())
+ return false;
+ total_track_count_ += track_count;
+ // Update auto repeater index and append repeater.
+ auto_repeater_index_ = repeaters_.size();
+ break;
+ }
+
+ repeaters_.emplace_back(track_index, track_count, repeat_count, repeat_type);
+
+ return true;
+}
+
+String NGGridTrackList::ToString() const {
+ StringBuilder builder;
+ builder.Append("TrackList: {");
+ for (wtf_size_t i = 0; i < repeaters_.size(); ++i) {
+ builder.Append(" ");
+ builder.Append(repeaters_[i].ToString());
+ if (i + 1 != repeaters_.size())
+ builder.Append(", ");
+ }
+ builder.Append(" } ");
+ return builder.ToString();
+}
+
+bool NGGridTrackList::HasAutoRepeater() {
+ return auto_repeater_index_ != NGGridTrackCollectionBase::kInvalidRangeIndex;
+}
+
+wtf_size_t NGGridTrackList::AvailableTrackCount() const {
+ return NGGridTrackCollectionBase::kMaxRangeIndex - total_track_count_;
+}
+
+#if DCHECK_IS_ON()
+bool NGGridTrackList::IsTrackContiguous(wtf_size_t track_index) const {
+ return repeaters_.IsEmpty() ||
+ (repeaters_.back().track_index + repeaters_.back().repeat_size ==
+ track_index);
+}
+#endif
+
+void NGGridBlockTrackCollection::SetSpecifiedTracks(
+ const NGGridTrackList& specified_tracks,
+ wtf_size_t auto_repeat_count,
+ const NGGridTrackList& implicit_tracks) {
+ // The implicit track list should have only one repeater, if any.
+ DCHECK_LE(implicit_tracks.RepeaterCount(), 1u);
+ specified_tracks_ = specified_tracks;
+ implicit_tracks_ = implicit_tracks;
+ auto_repeat_count_ = auto_repeat_count;
+
+ wtf_size_t repeater_count = specified_tracks_.RepeaterCount();
+ wtf_size_t total_track_count = 0;
+
+ for (wtf_size_t i = 0; i < repeater_count; ++i) {
+ wtf_size_t repeater_track_start = total_track_count + 1;
+ wtf_size_t repeater_track_count =
+ specified_tracks_.RepeatCount(i, auto_repeat_count_) *
+ specified_tracks_.RepeatSize(i);
+ if (repeater_track_count != 0) {
+ starting_tracks_.push_back(repeater_track_start);
+ ending_tracks_.push_back(repeater_track_start + repeater_track_count - 1);
+ }
+ total_track_count += repeater_track_count;
+ }
+}
+
+void NGGridBlockTrackCollection::EnsureTrackCoverage(wtf_size_t track_number,
+ wtf_size_t span_length) {
+ DCHECK_NE(kInvalidRangeIndex, track_number);
+ DCHECK_NE(kInvalidRangeIndex, span_length);
+ track_indices_need_sort_ = true;
+ starting_tracks_.push_back(track_number);
+ ending_tracks_.push_back(track_number + span_length - 1);
+}
+
+void NGGridBlockTrackCollection::FinalizeRanges() {
+ ranges_.clear();
+
+ // Sort start and ending tracks from low to high.
+ if (track_indices_need_sort_) {
+ std::stable_sort(starting_tracks_.begin(), starting_tracks_.end());
+ std::stable_sort(ending_tracks_.begin(), ending_tracks_.end());
+ }
+
+ wtf_size_t current_range_track_start = 1u;
+ if (starting_tracks_.size() > 0 && starting_tracks_[0] == 0)
+ current_range_track_start = 0;
+
+ // Indices into the starting and ending track vectors.
+ wtf_size_t starting_tracks_index = 0;
+ wtf_size_t ending_tracks_index = 0;
+
+ wtf_size_t repeater_index = kInvalidRangeIndex;
+ wtf_size_t repeater_track_start = kInvalidRangeIndex;
+ wtf_size_t next_repeater_track_start = 1u;
+ wtf_size_t current_repeater_track_count = 0;
+
+ wtf_size_t total_repeater_count = specified_tracks_.RepeaterCount();
+ wtf_size_t open_items_or_repeaters = 0;
+ bool is_in_auto_fit_range = false;
+
+ while (true) {
+ // Identify starting tracks index.
+ while (starting_tracks_index < starting_tracks_.size() &&
+ current_range_track_start >=
+ starting_tracks_[starting_tracks_index]) {
+ ++starting_tracks_index;
+ ++open_items_or_repeaters;
+ }
+
+ // Identify ending tracks index.
+ while (ending_tracks_index < ending_tracks_.size() &&
+ current_range_track_start > ending_tracks_[ending_tracks_index]) {
+ ++ending_tracks_index;
+ --open_items_or_repeaters;
+ DCHECK_GE(open_items_or_repeaters, 0u);
+ }
+
+ // Identify ending tracks index.
+ if (ending_tracks_index >= ending_tracks_.size()) {
+ DCHECK_EQ(open_items_or_repeaters, 0u);
+ break;
+ }
+
+ // Determine the next starting and ending track index.
+ wtf_size_t next_starting_track = kInvalidRangeIndex;
+ if (starting_tracks_index < starting_tracks_.size())
+ next_starting_track = starting_tracks_[starting_tracks_index];
+ wtf_size_t next_ending_track = ending_tracks_[ending_tracks_index];
+
+ // Move |next_repeater_track_start| to the start of the next repeater, if
+ // needed.
+ while (current_range_track_start == next_repeater_track_start) {
+ if (++repeater_index == total_repeater_count) {
+ repeater_index = kInvalidRangeIndex;
+ repeater_track_start = next_repeater_track_start;
+ is_in_auto_fit_range = false;
+ break;
+ }
+
+ is_in_auto_fit_range = specified_tracks_.RepeatType(repeater_index) ==
+ NGGridTrackRepeater::RepeatType::kAutoFit;
+ current_repeater_track_count =
+ specified_tracks_.RepeatCount(repeater_index, auto_repeat_count_) *
+ specified_tracks_.RepeatSize(repeater_index);
+ repeater_track_start = next_repeater_track_start;
+ next_repeater_track_start += current_repeater_track_count;
+ }
+
+ // Determine track number and count of the range.
+ Range range;
+ range.starting_track_number = current_range_track_start;
+ if (next_starting_track != kInvalidRangeIndex) {
+ range.track_count =
+ std::min(next_ending_track + 1u, next_starting_track) -
+ current_range_track_start;
+ } else {
+ range.track_count = next_ending_track + 1u - current_range_track_start;
+ }
+
+ // Compute repeater index and offset.
+ if (repeater_index == kInvalidRangeIndex) {
+ range.is_implicit_range = true;
+ if (implicit_tracks_.RepeaterCount() == 0) {
+ // No specified implicit tracks, use auto tracks.
+ range.repeater_index = kInvalidRangeIndex;
+ range.repeater_offset = 0;
+ } else {
+ // Use implicit tracks.
+ wtf_size_t implicit_repeat_size = ImplicitRepeatSize();
+ range.repeater_index = 0;
+ if (range.starting_track_number == 0) {
+ wtf_size_t offset_from_end =
+ (1 - range.starting_track_number) % implicit_repeat_size;
+ if (offset_from_end == implicit_repeat_size) {
+ range.repeater_offset = 0;
+ } else {
+ range.repeater_offset =
+ current_range_track_start - repeater_track_start;
+ }
+ }
+ }
+ } else {
+ range.is_implicit_range = false;
+ range.repeater_index = repeater_index;
+ range.repeater_offset = current_range_track_start - repeater_track_start;
+ }
+ range.is_collapsed = is_in_auto_fit_range && open_items_or_repeaters == 1u;
+
+ current_range_track_start += range.track_count;
+ ranges_.push_back(range);
+ }
+
+#if DCHECK_IS_ON()
+ while (repeater_index != kInvalidRangeIndex &&
+ repeater_index < total_repeater_count - 1u) {
+ ++repeater_index;
+ DCHECK_EQ(0u, specified_tracks_.RepeatSize(repeater_index));
+ }
+#endif
+ DCHECK_EQ(starting_tracks_index, starting_tracks_.size());
+ DCHECK_EQ(ending_tracks_index, starting_tracks_.size());
+ DCHECK(repeater_index == total_repeater_count - 1u ||
+ repeater_index == kInvalidRangeIndex);
+ starting_tracks_.clear();
+ ending_tracks_.clear();
+}
+
+const NGGridBlockTrackCollection::Range&
+NGGridBlockTrackCollection::RangeAtRangeIndex(wtf_size_t range_index) const {
+ DCHECK_NE(range_index, kInvalidRangeIndex);
+ DCHECK_LT(range_index, ranges_.size());
+ return ranges_[range_index];
+}
+const NGGridBlockTrackCollection::Range&
+NGGridBlockTrackCollection::RangeAtTrackNumber(wtf_size_t track_number) const {
+ wtf_size_t range_index = RangeIndexFromTrackNumber(track_number);
+ DCHECK_NE(range_index, kInvalidRangeIndex);
+ DCHECK_LT(range_index, ranges_.size());
+ return ranges_[range_index];
+}
+
+String NGGridBlockTrackCollection::ToString() const {
+ if (ranges_.IsEmpty()) {
+ StringBuilder builder;
+ builder.Append("NGGridTrackCollection: [SpecifiedTracks: ");
+ builder.Append(specified_tracks_.ToString());
+ if (HasImplicitTracks()) {
+ builder.Append("], [ImplicitTracks: ");
+ builder.Append(implicit_tracks_.ToString());
+ }
+
+ builder.Append("], [Starting: {");
+ for (wtf_size_t i = 0; i < starting_tracks_.size(); ++i) {
+ builder.AppendNumber<wtf_size_t>(starting_tracks_[i]);
+ if (i + 1 != starting_tracks_.size())
+ builder.Append(", ");
+ }
+ builder.Append("} ], [Ending: {");
+ for (wtf_size_t i = 0; i < ending_tracks_.size(); ++i) {
+ builder.AppendNumber<wtf_size_t>(ending_tracks_[i]);
+ if (i + 1 != ending_tracks_.size())
+ builder.Append(", ");
+ }
+ builder.Append("} ] ");
+ return builder.ToString();
+ } else {
+ return NGGridTrackCollectionBase::ToString();
+ }
+}
+bool NGGridBlockTrackCollection::HasImplicitTracks() const {
+ return implicit_tracks_.RepeaterCount() != 0;
+}
+wtf_size_t NGGridBlockTrackCollection::ImplicitRepeatSize() const {
+ DCHECK(HasImplicitTracks());
+ return implicit_tracks_.RepeatSize(0);
+}
+
+wtf_size_t NGGridBlockTrackCollection::RangeTrackNumber(
+ wtf_size_t range_index) const {
+ DCHECK_LT(range_index, RangeCount());
+ return ranges_[range_index].starting_track_number;
+}
+
+wtf_size_t NGGridBlockTrackCollection::RangeTrackCount(
+ wtf_size_t range_index) const {
+ DCHECK_LT(range_index, RangeCount());
+ return ranges_[range_index].track_count;
+}
+
+bool NGGridBlockTrackCollection::IsRangeCollapsed(
+ wtf_size_t range_index) const {
+ DCHECK_LT(range_index, RangeCount());
+ return ranges_[range_index].is_collapsed;
+}
+
+wtf_size_t NGGridBlockTrackCollection::RangeCount() const {
+ return ranges_.size();
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..ca66e0190f3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h
@@ -0,0 +1,207 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_TRACK_COLLECTION_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_TRACK_COLLECTION_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+// NGGridTrackCollectionBase provides an implementation for some shared
+// functionality on track range collections, specifically binary search on
+// the collection to get a range index given a track number.
+class CORE_EXPORT NGGridTrackCollectionBase {
+ public:
+ static constexpr wtf_size_t kInvalidRangeIndex = kNotFound;
+ static constexpr wtf_size_t kMaxRangeIndex = kNotFound - 1;
+
+ class CORE_EXPORT RangeRepeatIterator {
+ public:
+ RangeRepeatIterator(const NGGridTrackCollectionBase* collection,
+ wtf_size_t range_index);
+
+ // Moves iterator to next range, skipping over repeats in a range. Return
+ // true if the move was successful.
+ bool MoveToNextRange();
+ wtf_size_t RepeatCount() const;
+ // Returns the track number for the start of the range.
+ wtf_size_t RangeTrackStart() const;
+ // Returns the track number at the end of the range.
+ wtf_size_t RangeTrackEnd() const;
+
+ bool IsRangeCollapsed() const;
+
+ private:
+ bool SetRangeIndex(wtf_size_t range_index);
+ const NGGridTrackCollectionBase* collection_;
+ wtf_size_t range_index_;
+ wtf_size_t range_count_;
+
+ // First track number of a range.
+ wtf_size_t range_track_start_;
+ // Count of repeated tracks in a range.
+ wtf_size_t range_track_count_;
+ };
+
+ // Gets the range index for the range that contains the given track number.
+ wtf_size_t RangeIndexFromTrackNumber(wtf_size_t track_number) const;
+
+ String ToString() const;
+
+ protected:
+ // Returns the first track number of a range.
+ virtual wtf_size_t RangeTrackNumber(wtf_size_t range_index) const = 0;
+
+ // Returns the number of tracks in a range.
+ virtual wtf_size_t RangeTrackCount(wtf_size_t range_index) const = 0;
+
+ // Returns true if the range at the given index is collapsed.
+ virtual bool IsRangeCollapsed(wtf_size_t range_index) const = 0;
+
+ // Returns the number of track ranges in the collection.
+ virtual wtf_size_t RangeCount() const = 0;
+};
+
+// Stores tracks related data by compressing repeated tracks into a single node.
+struct NGGridTrackRepeater {
+ enum class RepeatType { kCount, kAutoFill, kAutoFit };
+ NGGridTrackRepeater(wtf_size_t track_index,
+ wtf_size_t repeat_size,
+ wtf_size_t repeat_count,
+ RepeatType repeat_type);
+ String ToString() const;
+ bool operator==(const NGGridTrackRepeater& rhs) const;
+ // Index of the first track being repeated.
+ wtf_size_t track_index;
+ // Amount of tracks to be repeated.
+ wtf_size_t repeat_size;
+ // Amount of times the group of tracks are repeated.
+ wtf_size_t repeat_count;
+ // Type of repetition.
+ RepeatType repeat_type;
+};
+
+class CORE_EXPORT NGGridTrackList {
+ public:
+ NGGridTrackList();
+ // Returns the repeat count of the repeater at |index|, or |auto_value|
+ // if the repeater is auto.
+ wtf_size_t RepeatCount(wtf_size_t index, wtf_size_t auto_value) const;
+ // Returns the number of tracks in the repeater at |index|.
+ wtf_size_t RepeatSize(wtf_size_t index) const;
+ // Returns the repeat type of the repeater at |index|.
+ NGGridTrackRepeater::RepeatType RepeatType(wtf_size_t index) const;
+ // Returns the count of repeaters.
+ wtf_size_t RepeaterCount() const;
+ // Returns the total count of all the tracks in this list.
+ wtf_size_t TotalTrackCount() const;
+
+ // Adds a non-auto repeater.
+ bool AddRepeater(wtf_size_t track_index,
+ wtf_size_t track_count,
+ wtf_size_t repeat_count);
+ // Adds an auto repeater.
+ bool AddAutoRepeater(wtf_size_t track_index,
+ wtf_size_t track_count,
+ NGGridTrackRepeater::RepeatType repeat_type);
+ // Returns true if this list contains an auto repeater.
+ bool HasAutoRepeater();
+
+ // Clears all data.
+ void Clear();
+
+ String ToString() const;
+
+ private:
+ bool AddRepeater(wtf_size_t track_index,
+ wtf_size_t track_count,
+ wtf_size_t repeat_count,
+ NGGridTrackRepeater::RepeatType repeat_type);
+ // Returns the amount of tracks available before overflow.
+ wtf_size_t AvailableTrackCount() const;
+
+#if DCHECK_IS_ON()
+ // Helper to check if |track_index| does not cause a gap or overlap with the
+ // tracks in this list. Ensures |track_index| is equal to 1 + the last track's
+ // index.
+ bool IsTrackContiguous(wtf_size_t track_index) const;
+#endif
+
+ Vector<NGGridTrackRepeater> repeaters_;
+ // The index of the automatic repeater, if there is one; |kInvalidRangeIndex|
+ // otherwise.
+ wtf_size_t auto_repeater_index_;
+ // Total count of tracks.
+ wtf_size_t total_track_count_;
+};
+
+class CORE_EXPORT NGGridBlockTrackCollection
+ : public NGGridTrackCollectionBase {
+ public:
+ struct Range {
+ wtf_size_t starting_track_number;
+ wtf_size_t track_count;
+ wtf_size_t repeater_index;
+ wtf_size_t repeater_offset;
+ bool is_collapsed;
+ bool is_implicit_range;
+ };
+
+ // Sets the specified, implicit tracks, along with a given auto repeat value.
+ void SetSpecifiedTracks(const NGGridTrackList& specified_tracks,
+ wtf_size_t auto_repeat_count,
+ const NGGridTrackList& implicit_tracks);
+ // Ensures that after FinalizeRanges is called, a range will start at the
+ // |track_number|, and a range will end at |track_number| + |span_length|
+ void EnsureTrackCoverage(wtf_size_t track_number, wtf_size_t span_length);
+
+ // Build the collection of ranges based on information provided by
+ // SetSpecifiedTracks and EnsureTrackCoverage.
+ void FinalizeRanges();
+ // Returns the range at the given range index.
+ const Range& RangeAtRangeIndex(wtf_size_t range_index) const;
+ // Returns the range at the given track.
+ const Range& RangeAtTrackNumber(wtf_size_t track_number) const;
+
+ String ToString() const;
+
+ protected:
+ // Returns the first track number of a range.
+ wtf_size_t RangeTrackNumber(wtf_size_t range_index) const override;
+
+ // Returns the number of tracks in a range.
+ wtf_size_t RangeTrackCount(wtf_size_t range_index) const override;
+
+ // Returns true if the range at |range_index| is collapsed.
+ bool IsRangeCollapsed(wtf_size_t range_index) const override;
+
+ // Returns the number of track ranges in the collection.
+ wtf_size_t RangeCount() const override;
+
+ private:
+ // Returns true if this collection had implicit tracks provided.
+ bool HasImplicitTracks() const;
+ // Returns the repeat size of the implicit tracks.
+ wtf_size_t ImplicitRepeatSize() const;
+
+ bool track_indices_need_sort_ = false;
+ wtf_size_t auto_repeat_count_ = 0;
+
+ // Stores the specified and implicit tracks specified by SetSpecifiedTracks.
+ NGGridTrackList specified_tracks_;
+ NGGridTrackList implicit_tracks_;
+
+ // Starting and ending tracks mark where ranges will start and end.
+ // Once the ranges have been built in FinalizeRanges, these are cleared.
+ Vector<wtf_size_t> starting_tracks_;
+ Vector<wtf_size_t> ending_tracks_;
+ Vector<Range> ranges_;
+};
+
+} // namespace blink
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::NGGridTrackRepeater)
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_TRACK_COLLECTION_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection_test.cc
new file mode 100644
index 00000000000..e194b80d014
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection_test.cc
@@ -0,0 +1,248 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <vector>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_layout_test.h"
+
+namespace blink {
+namespace {
+#define EXPECT_RANGE(expected_start, expected_count, iterator) \
+ EXPECT_EQ(expected_count, iterator.RepeatCount()); \
+ EXPECT_EQ(expected_start, iterator.RangeTrackStart()); \
+ EXPECT_EQ(expected_start + expected_count - 1, iterator.RangeTrackEnd()); \
+ EXPECT_FALSE(iterator.IsRangeCollapsed());
+#define EXPECT_COLLAPSED_RANGE(expected_start, expected_count, iterator) \
+ EXPECT_EQ(expected_start, iterator.RangeTrackStart()); \
+ EXPECT_EQ(expected_count, iterator.RepeatCount()); \
+ EXPECT_EQ(expected_start + expected_count - 1, iterator.RangeTrackEnd()); \
+ EXPECT_TRUE(iterator.IsRangeCollapsed());
+class NGGridTrackCollectionBaseTest : public NGGridTrackCollectionBase {
+ public:
+ struct TestTrackRange {
+ wtf_size_t track_number;
+ wtf_size_t track_count;
+ };
+ explicit NGGridTrackCollectionBaseTest(
+ const std::vector<wtf_size_t>& range_sizes) {
+ wtf_size_t track_number = 0;
+ for (wtf_size_t size : range_sizes) {
+ TestTrackRange range;
+ range.track_number = track_number;
+ range.track_count = size;
+ ranges_.push_back(range);
+ track_number += size;
+ }
+ }
+
+ protected:
+ wtf_size_t RangeTrackNumber(wtf_size_t range_index) const override {
+ return ranges_[range_index].track_number;
+ }
+ wtf_size_t RangeTrackCount(wtf_size_t range_index) const override {
+ return ranges_[range_index].track_count;
+ }
+ bool IsRangeCollapsed(wtf_size_t range_index) const override { return false; }
+
+ wtf_size_t RangeCount() const override { return ranges_.size(); }
+
+ private:
+ Vector<TestTrackRange> ranges_;
+};
+
+using NGGridTrackCollectionTest = NGLayoutTest;
+
+TEST_F(NGGridTrackCollectionTest, TestRangeIndexFromTrackNumber) {
+ // Small case.
+ NGGridTrackCollectionBaseTest track_collection({3, 10u, 5u});
+ EXPECT_EQ(0u, track_collection.RangeIndexFromTrackNumber(0u));
+ EXPECT_EQ(1u, track_collection.RangeIndexFromTrackNumber(4u));
+ EXPECT_EQ(2u, track_collection.RangeIndexFromTrackNumber(15u));
+
+ // Small case with large repeat count.
+ track_collection = NGGridTrackCollectionBaseTest({3000000u, 7u, 10u});
+ EXPECT_EQ(0u, track_collection.RangeIndexFromTrackNumber(600u));
+ EXPECT_EQ(1u, track_collection.RangeIndexFromTrackNumber(3000000u));
+ EXPECT_EQ(1u, track_collection.RangeIndexFromTrackNumber(3000004u));
+
+ // Larger case.
+ track_collection = NGGridTrackCollectionBaseTest({
+ 10u, // 0 - 9
+ 10u, // 10 - 19
+ 10u, // 20 - 29
+ 10u, // 30 - 39
+ 20u, // 40 - 59
+ 20u, // 60 - 79
+ 20u, // 80 - 99
+ 100u, // 100 - 199
+ });
+ EXPECT_EQ(0u, track_collection.RangeIndexFromTrackNumber(0u));
+ EXPECT_EQ(3u, track_collection.RangeIndexFromTrackNumber(35u));
+ EXPECT_EQ(4u, track_collection.RangeIndexFromTrackNumber(40u));
+ EXPECT_EQ(5u, track_collection.RangeIndexFromTrackNumber(79));
+ EXPECT_EQ(7u, track_collection.RangeIndexFromTrackNumber(105u));
+}
+
+TEST_F(NGGridTrackCollectionTest, TestRangeRepeatIteratorMoveNext) {
+ // [1-3] [4-13] [14 -18]
+ NGGridTrackCollectionBaseTest track_collection({3u, 10u, 5u});
+ EXPECT_EQ(0u, track_collection.RangeIndexFromTrackNumber(0u));
+
+ NGGridTrackCollectionBaseTest::RangeRepeatIterator iterator(&track_collection,
+ 0u);
+ EXPECT_RANGE(0u, 3u, iterator);
+
+ EXPECT_TRUE(iterator.MoveToNextRange());
+ EXPECT_RANGE(3u, 10u, iterator);
+
+ EXPECT_TRUE(iterator.MoveToNextRange());
+ EXPECT_RANGE(13u, 5u, iterator);
+
+ EXPECT_FALSE(iterator.MoveToNextRange());
+
+ NGGridTrackCollectionBaseTest empty_collection({});
+
+ NGGridTrackCollectionBaseTest::RangeRepeatIterator empty_iterator(
+ &empty_collection, 0u);
+ EXPECT_EQ(NGGridTrackCollectionBase::kInvalidRangeIndex,
+ empty_iterator.RangeTrackStart());
+ EXPECT_EQ(NGGridTrackCollectionBase::kInvalidRangeIndex,
+ empty_iterator.RangeTrackEnd());
+ EXPECT_EQ(0u, empty_iterator.RepeatCount());
+ EXPECT_FALSE(empty_iterator.MoveToNextRange());
+}
+
+TEST_F(NGGridTrackCollectionTest, TestNGGridTrackList) {
+ NGGridTrackList track_list;
+ ASSERT_EQ(0u, track_list.RepeaterCount());
+ EXPECT_FALSE(track_list.HasAutoRepeater());
+
+ EXPECT_TRUE(track_list.AddRepeater(0, 2, 4));
+ ASSERT_EQ(1u, track_list.RepeaterCount());
+ EXPECT_EQ(8u, track_list.TotalTrackCount());
+ EXPECT_EQ(4u, track_list.RepeatCount(0, 77));
+ EXPECT_EQ(2u, track_list.RepeatSize(0));
+ EXPECT_FALSE(track_list.HasAutoRepeater());
+
+ EXPECT_TRUE(track_list.AddAutoRepeater(
+ 2, 3, NGGridTrackRepeater::RepeatType::kAutoFill));
+ ASSERT_EQ(2u, track_list.RepeaterCount());
+ EXPECT_EQ(11u, track_list.TotalTrackCount());
+ EXPECT_EQ(77u, track_list.RepeatCount(1, 77));
+ EXPECT_EQ(3u, track_list.RepeatSize(1));
+ EXPECT_TRUE(track_list.HasAutoRepeater());
+
+ // Can't add more than one auto repeater to a list.
+ EXPECT_FALSE(track_list.AddAutoRepeater(
+ 5, 3, NGGridTrackRepeater::RepeatType::kAutoFill));
+
+ EXPECT_TRUE(track_list.AddRepeater(
+ 5, NGGridTrackCollectionBase::kMaxRangeIndex - 20, 1));
+ ASSERT_EQ(3u, track_list.RepeaterCount());
+ EXPECT_EQ(NGGridTrackCollectionBase::kMaxRangeIndex - 9,
+ track_list.TotalTrackCount());
+ EXPECT_EQ(1u, track_list.RepeatCount(2, 77));
+ EXPECT_EQ(NGGridTrackCollectionBase::kMaxRangeIndex - 20,
+ track_list.RepeatSize(2));
+
+ // Try to add a repeater that would overflow the total track count.
+ EXPECT_FALSE(track_list.AddRepeater(
+ NGGridTrackCollectionBase::kMaxRangeIndex - 15u, 3, 10));
+ ASSERT_EQ(3u, track_list.RepeaterCount());
+
+ // Try to add a repeater that would overflow the track size in a repeater.
+ EXPECT_FALSE(
+ track_list.AddRepeater(NGGridTrackCollectionBase::kMaxRangeIndex - 15u,
+ NGGridTrackCollectionBase::kMaxRangeIndex, 10));
+ ASSERT_EQ(3u, track_list.RepeaterCount());
+}
+
+TEST_F(NGGridTrackCollectionTest, TestNGGridBlockTrackCollection) {
+ NGGridTrackList specified_tracks;
+ ASSERT_TRUE(specified_tracks.AddRepeater(1, 2, 4));
+ ASSERT_TRUE(specified_tracks.AddAutoRepeater(
+ 3, 3, NGGridTrackRepeater::RepeatType::kAutoFill));
+ ASSERT_EQ(2u, specified_tracks.RepeaterCount());
+ NGGridBlockTrackCollection block_collection;
+ block_collection.SetSpecifiedTracks(specified_tracks, 3, NGGridTrackList());
+ block_collection.FinalizeRanges();
+
+ NGGridTrackCollectionBase::RangeRepeatIterator iterator(&block_collection,
+ 0u);
+ EXPECT_RANGE(1u, 8u, iterator);
+
+ EXPECT_TRUE(iterator.MoveToNextRange());
+ EXPECT_RANGE(9u, 9u, iterator);
+
+ EXPECT_FALSE(iterator.MoveToNextRange());
+}
+
+TEST_F(NGGridTrackCollectionTest, TestNGGridBlockTrackCollectionCollapsed) {
+ NGGridTrackList specified_tracks;
+ ASSERT_TRUE(specified_tracks.AddRepeater(1, 2, 4));
+ ASSERT_TRUE(specified_tracks.AddAutoRepeater(
+ 3, 3, NGGridTrackRepeater::RepeatType::kAutoFit));
+ ASSERT_TRUE(specified_tracks.AddRepeater(6, 3, 7));
+ ASSERT_EQ(3u, specified_tracks.RepeaterCount());
+ NGGridBlockTrackCollection block_collection;
+ block_collection.SetSpecifiedTracks(specified_tracks, 3, NGGridTrackList());
+ block_collection.FinalizeRanges();
+
+ NGGridTrackCollectionBase::RangeRepeatIterator iterator(&block_collection,
+ 0u);
+ EXPECT_RANGE(1u, 8u, iterator);
+
+ EXPECT_TRUE(iterator.MoveToNextRange());
+ EXPECT_COLLAPSED_RANGE(9u, 9u, iterator);
+
+ EXPECT_TRUE(iterator.MoveToNextRange());
+ EXPECT_RANGE(18u, 21u, iterator);
+
+ EXPECT_FALSE(iterator.MoveToNextRange());
+}
+
+TEST_F(NGGridTrackCollectionTest, TestNGGridBlockTrackCollectionImplicit) {
+ NGGridTrackList specified_tracks;
+ ASSERT_TRUE(specified_tracks.AddRepeater(1, 2, 4));
+ ASSERT_TRUE(specified_tracks.AddRepeater(3, 3, 3));
+ ASSERT_TRUE(specified_tracks.AddRepeater(6, 3, 7));
+ ASSERT_EQ(3u, specified_tracks.RepeaterCount());
+
+ NGGridTrackList implicit_tracks;
+ ASSERT_TRUE(implicit_tracks.AddRepeater(1, 8, 2));
+
+ NGGridBlockTrackCollection block_collection;
+ block_collection.SetSpecifiedTracks(specified_tracks, 3, implicit_tracks);
+ block_collection.EnsureTrackCoverage(3, 40);
+ block_collection.EnsureTrackCoverage(3, 40);
+ block_collection.FinalizeRanges();
+ NGGridTrackCollectionBase::RangeRepeatIterator iterator(&block_collection,
+ 0u);
+ EXPECT_RANGE(1u, 2u, iterator);
+ EXPECT_FALSE(block_collection.RangeAtTrackNumber(1u).is_implicit_range);
+
+ EXPECT_TRUE(iterator.MoveToNextRange());
+ EXPECT_RANGE(3u, 6u, iterator);
+ EXPECT_FALSE(block_collection.RangeAtTrackNumber(4).is_implicit_range);
+
+ EXPECT_TRUE(iterator.MoveToNextRange());
+ EXPECT_RANGE(9u, 9u, iterator);
+ EXPECT_FALSE(block_collection.RangeAtTrackNumber(7).is_implicit_range);
+
+ EXPECT_TRUE(iterator.MoveToNextRange());
+ EXPECT_RANGE(18u, 21u, iterator);
+ EXPECT_FALSE(block_collection.RangeAtTrackNumber(20).is_implicit_range);
+
+ EXPECT_TRUE(iterator.MoveToNextRange());
+ EXPECT_TRUE(block_collection.RangeAtTrackNumber(40).is_implicit_range);
+ EXPECT_RANGE(39u, 4u, iterator);
+
+ EXPECT_FALSE(iterator.MoveToNextRange());
+}
+
+} // namespace
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/README.md b/chromium/third_party/blink/renderer/core/layout/ng/inline/README.md
index 0ddc51ec99d..6c6a762b856 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/README.md
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/README.md
@@ -62,11 +62,12 @@ as in the following.
Inline layout is performed in the following phases:
-1. **Pre-layout** converts LayoutObject tree to a concatenated string
+1. **[Pre-layout]** converts LayoutObject tree to a concatenated string
and a list of [NGInlineItem].
-2. **Line breaking** breaks it into lines and
+2. **[Line breaking]** breaks it into lines and
produces a list of [NGInlineItemResult] for each line.
-3. **Line box construction** produces a fragment tree.
+3. **[Line box construction]** orders and positions items on a line.
+4. **[Generate fragments]** generates physical fragments.
This is similar to [CSS Text Processing Order of Operations],
but not exactly the same,
@@ -74,8 +75,8 @@ because the spec prioritizes the simple description than being accurate.
[CSS Text Processing Order of Operations]: https://drafts.csswg.org/css-text-3/#order
-### Pre-layout ###
-[Pre-layout]: #pre-layout
+### <a name="pre-layout">Pre-layout</a> ###
+[pre-layout]: #pre-layout
For inline layout there is a pre-layout pass that prepares the internal data
structures needed to perform line layout.
@@ -104,7 +105,8 @@ three separate steps or stages that are executed in order:
[text-transform]: https://drafts.csswg.org/css-text-3/#propdef-text-transform
-### Line Breaking ###
+### <a name="line-breaking">Line Breaking</a> ###
+[line breaking]: #line-breaking
[NGLineBreaker] takes a list of [NGInlineItem],
measure them, break into lines, and
@@ -134,53 +136,51 @@ This phase:
[CSS Calculating widths and margins]: https://drafts.csswg.org/css2/visudet.html#Computing_widths_and_margins
-### Line Box Construction ###
+### <a name="create-line">Line Box Construction</a> ###
+[line Box Construction]: #create-line
`NGInlineLayoutAlgorithm::CreateLine()` takes a list of [NGInlineItemResult] and
-produces [NGPhysicalLineBoxFragment] for each line.
-
-Lines are then wrapped in an anonymous [NGPhysicalBoxFragment]
-so that one [NGInlineNode] has one corresponding fragment.
+produces a list of [NGLogicalLineItem].
This phase consists of following sub-phases:
-1. Bidirectional reordering:
- Reorder the list of [NGInlineItemResult]
+1. Create a [NGLogicalLineItem] for each [NGInlineItemResult]
+ and determine the positions.
+
+ The inline size of each item was already determined by [NGLineBreaker],
+ but the inline position is recomputed
+ because [BiDi reordering](#bidi) may change them.
+
+ In block direction,
+ [NGLogicalLineItem] is placed as if the baseline is at 0.
+ This is adjusted later, possibly multiple times,
+ for [vertical-align] and the block offset of the parent inline box.
+
+ An open-tag item pushes a new stack entry of [NGInlineBoxState],
+ and a close-tag item pops a stack entry.
+ This stack is used to determine the size of the inline box,
+ for [vertical-align], and for a few other purposes.
+ Please see [Inline Box Tree] below.
+
+2. Process all pending operations in [Inline Box Tree].
+3. [Bidirectional reordering](#bidi):
+ Reorder the list of [NGLogicalLineItem]
according to [UAX#9 Reordering Resolved Levels].
See [Bidirectional text] below.
- After this point forward, the list of [NGInlineItemResult] is
+ After this point forward, the list of [NGLogicalLineItem] is
in _visual order_; which is from [line-left] to [line-right].
The block direction is still logical,
but the inline direction is physical.
+4. Applies [ellipsizing] if needed.
+5. Applies the CSS [text-align] property.
+6. Moves the baseline to the correct position
+ based on the height of the line box.
-2. Create a [NGPhysicalFragment] for each [NGInlineItemResult]
- in visual ([line-left] to [line-right]) order,
- and place them into [NGPhysicalLineBoxFragment].
-
- 1. A text item produces a [NGPhysicalTextFragment].
- 2. An open-tag item pushes a new stack entry of [NGInlineBoxState],
- and a close-tag item pops a stack entry.
- Performs operations that require the size of the inline box,
- or ancestor boxes.
- See [Inline Box Tree] below.
-
- The inline size of each item was already determined by [NGLineBreaker],
- but the inline position is recomputed
- because BiDi reordering may have changed it.
-
- In block direction, [NGPhysicalFragment] is placed
- as if the baseline is at 0.
- This is adjusted later, possibly multiple times.
- See [Inline Box Tree] and the post-process below.
-
-3. Post-process the constructed line box.
- This includes:
- 1. Process all pending operations in [Inline Box Tree].
- 2. Moves the baseline to the correct position
- based on the height of the line box.
- 3. Applies the CSS [text-align] property.
+Note: There is [a discussion](https://docs.google.com/document/d/1dxzIHl1dwBtgeKgWd2cKcog8AyydN5rduQvXthMOMD0/edit?usp=sharing)
+to merge [NGInlineItemResult] and [NGLogicalLineItem], but this hasn't been done yet.
+[ellipsizing]: https://drafts.csswg.org/css-ui-3/#overflow-ellipsis
[line-left]: https://drafts.csswg.org/css-writing-modes-3/#line-left
[line-right]: https://drafts.csswg.org/css-writing-modes-3/#line-right
[text-align]: https://drafts.csswg.org/css-text-3/#propdef-text-align
@@ -240,6 +240,20 @@ Once all children and their positions and sizes are finalized,
`NGInlineLayoutStateStack::CreateBoxFragments()`
creates [NGPhysicalBoxFragment] and add children to it.
+### <a name="generate-fragments">Generate Fragments</a> ###
+[generate fragments]: #generate-fragments
+
+When all [NGLogicalLineItem]s are ordered and positioned,
+they are converted to fragments.
+
+Without [NGFragmentItem] enabled,
+each [NGLogicalLineItem] produces a [NGPhysicalFragment],
+added to the [NGPhysicalLineBoxFragment].
+
+With [NGFragmentItem] enabled,
+each [NGLogicalLineItem] produces a [NGFragmentItem],
+added to the [NGFragmentItems] in the containing block of the inline formatting context.
+
## Miscellaneous topics ##
### Baseline ###
@@ -355,6 +369,8 @@ positions in the context. See [design doc](https://goo.gl/CJbxky) for details.
[NGBoxFragmentBuilder]: ../ng_box_fragment_builder.h
[NGConstraintSpace]: ../ng_constraint_space_builder.h
[NGConstraintSpaceBuilder]: ../ng_constraint_space_builder.h
+[NGFragmentItem]: ng_fragment_item.h
+[NGFragmentItems]: ng_fragment_items.h
[NGInlineBoxState]: ng_inline_box_state.h
[NGInlineItem]: ng_inline_item.h
[NGInlineItemResult]: ng_inline_item_result.h
@@ -362,6 +378,8 @@ positions in the context. See [design doc](https://goo.gl/CJbxky) for details.
[NGInlineLayoutAlgorithm]: ng_inline_layout_algorithm.h
[NGLayoutInputNode]: ../ng_layout_input_node.h
[NGLineBreaker]: ng_line_breaker.h
+[NGLogicalLineItem]: ng_logical_line_item.h
+[NGLogicalLineItems]: ng_logical_line_items.h
[NGOffsetMapping]: ng_offset_mapping.h
[NGPhysicalBoxFragment]: ../ng_physical_box_fragment.h
[NGPhysicalFragment]: ../ng_physical_fragment.h
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_test.cc
index da28e31bfcf..ed5a6e062c9 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_test.cc
@@ -142,6 +142,23 @@ TEST_F(LayoutNGTextTest, SetTextWithOffsetDeleteCollapseWhiteSpaceEnd) {
GetItemsAsString(*text.GetLayoutObject()));
}
+// web_tests/external/wpt/editing/run/delete.html?993-993
+// web_tests/external/wpt/editing/run/forwarddelete.html?1193-1193
+TEST_F(LayoutNGTextTest, SetTextWithOffsetDeleteNbspInPreWrap) {
+ if (!RuntimeEnabledFeatures::LayoutNGEnabled())
+ return;
+
+ InsertStyleElement("#target { white-space:pre-wrap; }");
+ SetBodyInnerHTML(u"<p id=target>&nbsp; abc</p>");
+ Text& text = To<Text>(*GetElementById("target")->firstChild());
+ text.deleteData(0, 1, ASSERT_NO_EXCEPTION);
+
+ EXPECT_EQ(
+ "*{' ', ShapeResult=0+1}\n"
+ "*{'abc', ShapeResult=2+3}\n",
+ GetItemsAsString(*text.GetLayoutObject()));
+}
+
TEST_F(LayoutNGTextTest, SetTextWithOffsetDeleteRTL) {
if (!RuntimeEnabledFeatures::LayoutNGEnabled())
return;
@@ -174,6 +191,38 @@ TEST_F(LayoutNGTextTest, SetTextWithOffsetDeleteRTL2) {
GetItemsAsString(*text.GetLayoutObject()));
}
+// editing/deleting/delete_ws_fixup.html
+TEST_F(LayoutNGTextTest, SetTextWithOffsetDeleteThenNonCollapse) {
+ if (!RuntimeEnabledFeatures::LayoutNGEnabled())
+ return;
+
+ SetBodyInnerHTML(u"<div id=target>abc def<b> </b>ghi</div>");
+ Text& text = To<Text>(*GetElementById("target")->firstChild());
+ text.deleteData(4, 3, ASSERT_NO_EXCEPTION); // remove "def"
+
+ EXPECT_EQ(
+ "*{'abc ', ShapeResult=0+4}\n"
+ "{''}\n"
+ "{'ghi', ShapeResult=4+3}\n",
+ GetItemsAsString(*text.GetLayoutObject()));
+}
+
+// editing/deleting/delete_ws_fixup.html
+TEST_F(LayoutNGTextTest, SetTextWithOffsetDeleteThenNonCollapse2) {
+ if (!RuntimeEnabledFeatures::LayoutNGEnabled())
+ return;
+
+ SetBodyInnerHTML(u"<div id=target>abc def<b> X </b>ghi</div>");
+ Text& text = To<Text>(*GetElementById("target")->firstChild());
+ text.deleteData(4, 3, ASSERT_NO_EXCEPTION); // remove "def"
+
+ EXPECT_EQ(
+ "*{'abc ', ShapeResult=0+4}\n"
+ "{'X ', ShapeResult=4+2}\n"
+ "{'ghi', ShapeResult=6+3}\n",
+ GetItemsAsString(*text.GetLayoutObject()));
+}
+
// http://crbug.com/1039143
TEST_F(LayoutNGTextTest, SetTextWithOffsetDeleteWithBidiControl) {
if (!RuntimeEnabledFeatures::LayoutNGEnabled())
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.cc
index 4098a6363f7..08a2a61198f 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.cc
@@ -15,17 +15,23 @@ NGBidiParagraph::~NGBidiParagraph() {
bool NGBidiParagraph::SetParagraph(const String& text,
const ComputedStyle& block_style) {
+ if (UNLIKELY(block_style.GetUnicodeBidi() == UnicodeBidi::kPlaintext))
+ return SetParagraph(text, base::nullopt);
+ return SetParagraph(text, block_style.Direction());
+}
+
+bool NGBidiParagraph::SetParagraph(
+ const String& text,
+ base::Optional<TextDirection> base_direction) {
DCHECK(!ubidi_);
ubidi_ = ubidi_open();
- bool use_heuristic_base_direction =
- block_style.GetUnicodeBidi() == UnicodeBidi::kPlaintext;
UBiDiLevel para_level;
- if (use_heuristic_base_direction) {
- para_level = UBIDI_DEFAULT_LTR;
- } else {
- base_direction_ = block_style.Direction();
+ if (base_direction) {
+ base_direction_ = *base_direction;
para_level = IsLtr(base_direction_) ? UBIDI_LTR : UBIDI_RTL;
+ } else {
+ para_level = UBIDI_DEFAULT_LTR;
}
ICUError error;
@@ -38,7 +44,7 @@ bool NGBidiParagraph::SetParagraph(const String& text,
return false;
}
- if (use_heuristic_base_direction)
+ if (!base_direction)
base_direction_ = DirectionFromLevel(ubidi_getParaLevel(ubidi_));
return true;
@@ -60,6 +66,17 @@ unsigned NGBidiParagraph::GetLogicalRun(unsigned start,
return end;
}
+void NGBidiParagraph::GetLogicalRuns(const String& text, Runs* runs) const {
+ DCHECK(runs->IsEmpty());
+ for (unsigned start = 0; start < text.length();) {
+ UBiDiLevel level;
+ unsigned end = GetLogicalRun(start, &level);
+ DCHECK_GT(end, start);
+ runs->emplace_back(start, end, level);
+ start = end;
+ }
+}
+
void NGBidiParagraph::IndicesInVisualOrder(
const Vector<UBiDiLevel, 32>& levels,
Vector<int32_t, 32>* indices_in_visual_order_out) {
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.h
index dc53a487dfa..fc40c73b1df 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.h
@@ -5,6 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_BIDI_PARAGRAPH_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_BIDI_PARAGRAPH_H_
+#include "base/optional.h"
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -23,7 +25,7 @@ class ComputedStyle;
// UAX#9 and create logical runs.
// http://unicode.org/reports/tr9/
// It can also create visual runs once lines breaks are determined.
-class NGBidiParagraph {
+class CORE_EXPORT NGBidiParagraph {
STACK_ALLOCATED();
public:
@@ -35,6 +37,8 @@ class NGBidiParagraph {
// Returns false on failure. Nothing other than the destructor should be
// called.
bool SetParagraph(const String&, const ComputedStyle&);
+ bool SetParagraph(const String&,
+ base::Optional<TextDirection> base_direction);
// @return the entire text is unidirectional.
bool IsUnidirectional() const {
@@ -52,6 +56,30 @@ class NGBidiParagraph {
// http://unicode.org/reports/tr9/#The_Paragraph_Level
static TextDirection BaseDirectionForString(const StringView&);
+ struct Run {
+ Run(unsigned start, unsigned end, UBiDiLevel level)
+ : start(start), end(end), level(level) {
+ DCHECK_GT(end, start);
+ }
+
+ unsigned Length() const { return end - start; }
+ TextDirection Direction() const { return DirectionFromLevel(level); }
+
+ bool operator==(const Run& other) const {
+ return start == other.start && end == other.end && level == other.level;
+ }
+
+ unsigned start;
+ unsigned end;
+ UBiDiLevel level;
+ };
+ using Runs = Vector<Run, 32>;
+
+ // Get a list of |Run| in the logical order (before bidi reorder.)
+ // |text| must be the same one as |SetParagraph|.
+ // This is higher-level API for |GetLogicalRun|.
+ void GetLogicalRuns(const String& text, Runs* runs) const;
+
// Returns the end offset of a logical run that starts from the |start|
// offset.
unsigned GetLogicalRun(unsigned start, UBiDiLevel*) const;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph_test.cc
new file mode 100644
index 00000000000..15e6591055e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph_test.cc
@@ -0,0 +1,40 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+using testing::ElementsAre;
+
+TEST(NGBidiParagraph, SetParagraphHeuristicLtr) {
+ String text(u"abc");
+ NGBidiParagraph bidi;
+ bidi.SetParagraph(text, base::nullopt);
+ EXPECT_EQ(bidi.BaseDirection(), TextDirection::kLtr);
+}
+
+TEST(NGBidiParagraph, SetParagraphHeuristicRtl) {
+ String text(u"\u05D0\u05D1\u05D2");
+ NGBidiParagraph bidi;
+ bidi.SetParagraph(text, base::nullopt);
+ EXPECT_EQ(bidi.BaseDirection(), TextDirection::kRtl);
+}
+
+TEST(NGBidiParagraph, GetLogicalRuns) {
+ String text(u"\u05D0\u05D1\u05D2 abc \u05D3\u05D4\u05D5");
+ NGBidiParagraph bidi;
+ bidi.SetParagraph(text, TextDirection::kRtl);
+ NGBidiParagraph::Runs runs;
+ bidi.GetLogicalRuns(text, &runs);
+ EXPECT_THAT(runs, ElementsAre(NGBidiParagraph::Run(0, 4, 1),
+ NGBidiParagraph::Run(4, 7, 2),
+ NGBidiParagraph::Run(7, 11, 1)));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc
index d5075dba7d6..5867968d822 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc
@@ -299,7 +299,12 @@ NGCaretPosition ComputeNGCaretPosition(const PositionWithAffinity& position) {
return NGCaretPosition();
const NGOffsetMapping* mapping = NGInlineNode::GetOffsetMapping(context);
- DCHECK(mapping);
+ if (!mapping) {
+ // TODO(yosin): We should find when we reach here[1].
+ // [1] http://crbug.com/1100481
+ NOTREACHED() << context;
+ return NGCaretPosition();
+ }
const base::Optional<unsigned> maybe_offset =
mapping->GetTextContentOffset(position.GetPosition());
if (!maybe_offset.has_value()) {
@@ -322,17 +327,17 @@ PositionWithAffinity NGCaretPosition::ToPositionInDOMTreeWithAffinity() const {
return PositionWithAffinity();
switch (position_type) {
case NGCaretPositionType::kBeforeBox:
- if (cursor.Current().GetNode())
- return PositionWithAffinity();
- return PositionWithAffinity(
- Position::BeforeNode(*cursor.Current().GetNode()),
- TextAffinity::kDownstream);
+ if (const Node* node = cursor.Current().GetNode()) {
+ return PositionWithAffinity(Position::BeforeNode(*node),
+ TextAffinity::kDownstream);
+ }
+ return PositionWithAffinity();
case NGCaretPositionType::kAfterBox:
- if (cursor.Current().GetNode())
- return PositionWithAffinity();
- return PositionWithAffinity(
- Position::AfterNode(*cursor.Current().GetNode()),
- TextAffinity::kUpstreamIfPossible);
+ if (const Node* node = cursor.Current().GetNode()) {
+ return PositionWithAffinity(Position::AfterNode(*node),
+ TextAffinity::kUpstreamIfPossible);
+ }
+ return PositionWithAffinity();
case NGCaretPositionType::kAtTextOffset:
// In case of ::first-letter, |cursor.Current().GetNode()| is null.
DCHECK(text_offset.has_value());
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_caret_rect.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_caret_rect.cc
index bccd83f3551..6bef0e6f0f6 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_caret_rect.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_caret_rect.cc
@@ -52,6 +52,26 @@ PhysicalRect ComputeLocalCaretRectByBoxSide(const NGInlineCursor& cursor,
return PhysicalRect(caret_location, caret_size);
}
+bool ShouldAlignCaretRight(ETextAlign text_align, TextDirection direction) {
+ switch (text_align) {
+ case ETextAlign::kRight:
+ case ETextAlign::kWebkitRight:
+ return true;
+ case ETextAlign::kLeft:
+ case ETextAlign::kWebkitLeft:
+ case ETextAlign::kCenter:
+ case ETextAlign::kWebkitCenter:
+ return false;
+ case ETextAlign::kJustify:
+ case ETextAlign::kStart:
+ return IsRtl(direction);
+ case ETextAlign::kEnd:
+ return IsLtr(direction);
+ }
+ NOTREACHED();
+ return false;
+}
+
PhysicalRect ComputeLocalCaretRectAtTextOffset(const NGInlineCursor& cursor,
unsigned offset) {
DCHECK(cursor.Current().IsText());
@@ -62,7 +82,8 @@ PhysicalRect ComputeLocalCaretRectAtTextOffset(const NGInlineCursor& cursor,
cursor.Current().GetLayoutObject()->GetDocument().View();
LayoutUnit caret_width = frame_view->CaretWidth();
- const bool is_horizontal = cursor.Current().Style().IsHorizontalWritingMode();
+ const ComputedStyle& style = cursor.Current().Style();
+ const bool is_horizontal = style.IsHorizontalWritingMode();
LayoutUnit caret_height = is_horizontal ? cursor.Current().Size().height
: cursor.Current().Size().width;
@@ -90,15 +111,33 @@ PhysicalRect ComputeLocalCaretRectAtTextOffset(const NGInlineCursor& cursor,
line_box.Current().OffsetInContainerBlock();
const PhysicalRect line_box_rect(line_box_offset, line_box.Current().Size());
+ const NGInlineBreakToken& break_token =
+ *line_box.Current().InlineBreakToken();
+ const bool is_last_line =
+ break_token.IsFinished() || break_token.IsForcedBreak();
+ const ComputedStyle& block_style = fragmentainer.Style();
+ bool should_align_caret_right =
+ ShouldAlignCaretRight(block_style.GetTextAlign(is_last_line),
+ block_style.Direction()) &&
+ (style.GetUnicodeBidi() != UnicodeBidi::kPlaintext ||
+ IsLtr(cursor.Current().ResolvedDirection()));
+
// For horizontal text, adjust the location in the x direction to ensure that
// it completely falls in the union of line box and containing block, and
// then round it to the nearest pixel.
if (is_horizontal) {
- const LayoutUnit min_x = std::min(LayoutUnit(), line_box_offset.left);
- caret_location.left = std::max(caret_location.left, min_x);
- const LayoutUnit max_x =
- std::max(fragmentainer.Size().width, line_box_rect.Right());
- caret_location.left = std::min(caret_location.left, max_x - caret_width);
+ if (should_align_caret_right) {
+ const LayoutUnit left_edge = std::min(LayoutUnit(), line_box_rect.X());
+ caret_location.left = std::max(caret_location.left, left_edge);
+ caret_location.left =
+ std::min(caret_location.left, line_box_rect.Right() - caret_width);
+ } else {
+ const LayoutUnit right_edge =
+ std::max(fragmentainer.Size().width, line_box_rect.Right());
+ caret_location.left =
+ std::min(caret_location.left, right_edge - caret_width);
+ caret_location.left = std::max(caret_location.left, line_box_rect.X());
+ }
caret_location.left = LayoutUnit(caret_location.left.Round());
return PhysicalRect(caret_location, caret_size);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
index 4aedb519e64..56af2e5c74d 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
@@ -15,6 +15,23 @@
namespace blink {
+namespace {
+
+struct SameSizeAsNGFragmentItem {
+ struct {
+ void* pointer;
+ NGTextOffset text_offset;
+ } type_data;
+ PhysicalRect rect;
+ void* pointers[2];
+ wtf_size_t sizes[2];
+ unsigned flags;
+};
+
+static_assert(sizeof(NGFragmentItem) == sizeof(SameSizeAsNGFragmentItem),
+ "NGFragmentItem should stay small");
+} // namespace
+
NGFragmentItem::NGFragmentItem(const NGPhysicalTextFragment& text)
: layout_object_(text.GetLayoutObject()),
text_({text.TextShapeResult(), text.TextOffset()}),
@@ -26,7 +43,6 @@ NGFragmentItem::NGFragmentItem(const NGPhysicalTextFragment& text)
text_direction_(static_cast<unsigned>(text.ResolvedDirection())),
ink_overflow_computed_(false),
is_dirty_(false),
- is_first_for_node_(true),
is_last_for_node_(true) {
#if DCHECK_IS_ON()
if (text_.shape_result) {
@@ -44,19 +60,22 @@ NGFragmentItem::NGFragmentItem(const NGPhysicalTextFragment& text)
DCHECK(!IsFormattingContextRoot());
}
-NGFragmentItem::NGFragmentItem(NGInlineItemResult&& item_result,
- const PhysicalSize& size)
- : layout_object_(item_result.item->GetLayoutObject()),
- text_({std::move(item_result.shape_result), item_result.TextOffset()}),
+NGFragmentItem::NGFragmentItem(
+ const NGInlineItem& inline_item,
+ scoped_refptr<const ShapeResultView> shape_result,
+ const NGTextOffset& text_offset,
+ const PhysicalSize& size,
+ bool is_hidden_for_paint)
+ : layout_object_(inline_item.GetLayoutObject()),
+ text_({std::move(shape_result), text_offset}),
rect_({PhysicalOffset(), size}),
type_(kText),
- sub_type_(static_cast<unsigned>(item_result.item->TextType())),
- style_variant_(static_cast<unsigned>(item_result.item->StyleVariant())),
- is_hidden_for_paint_(false), // TODO(kojii): not supported yet.
- text_direction_(static_cast<unsigned>(item_result.item->Direction())),
+ sub_type_(static_cast<unsigned>(inline_item.TextType())),
+ style_variant_(static_cast<unsigned>(inline_item.StyleVariant())),
+ is_hidden_for_paint_(is_hidden_for_paint),
+ text_direction_(static_cast<unsigned>(inline_item.Direction())),
ink_overflow_computed_(false),
is_dirty_(false),
- is_first_for_node_(true),
is_last_for_node_(true) {
#if DCHECK_IS_ON()
if (text_.shape_result) {
@@ -64,15 +83,40 @@ NGFragmentItem::NGFragmentItem(NGInlineItemResult&& item_result,
DCHECK_EQ(text_.shape_result->EndIndex(), EndOffset());
}
#endif
- // TODO(kojii): Generated text not supported yet.
DCHECK_NE(TextType(), NGTextType::kLayoutGenerated);
DCHECK(!IsFormattingContextRoot());
}
-NGFragmentItem::NGFragmentItem(const NGPhysicalLineBoxFragment& line,
- wtf_size_t item_count)
+NGFragmentItem::NGFragmentItem(
+ const NGInlineItem& inline_item,
+ scoped_refptr<const ShapeResultView> shape_result,
+ const String& text_content,
+ const PhysicalSize& size,
+ bool is_hidden_for_paint)
+ : layout_object_(inline_item.GetLayoutObject()),
+ generated_text_({std::move(shape_result), text_content}),
+ rect_({PhysicalOffset(), size}),
+ type_(kGeneratedText),
+ sub_type_(static_cast<unsigned>(inline_item.TextType())),
+ style_variant_(static_cast<unsigned>(inline_item.StyleVariant())),
+ is_hidden_for_paint_(is_hidden_for_paint),
+ text_direction_(static_cast<unsigned>(inline_item.Direction())),
+ ink_overflow_computed_(false),
+ is_dirty_(false),
+ is_last_for_node_(true) {
+#if DCHECK_IS_ON()
+ if (text_.shape_result) {
+ DCHECK_EQ(text_.shape_result->StartIndex(), StartOffset());
+ DCHECK_EQ(text_.shape_result->EndIndex(), EndOffset());
+ }
+#endif
+ DCHECK_EQ(TextType(), NGTextType::kLayoutGenerated);
+ DCHECK(!IsFormattingContextRoot());
+}
+
+NGFragmentItem::NGFragmentItem(const NGPhysicalLineBoxFragment& line)
: layout_object_(line.ContainerLayoutObject()),
- line_({&line, item_count}),
+ line_({&line, /* descendants_count */ 1}),
rect_({PhysicalOffset(), line.Size()}),
type_(kLine),
sub_type_(static_cast<unsigned>(line.LineBoxType())),
@@ -81,7 +125,6 @@ NGFragmentItem::NGFragmentItem(const NGPhysicalLineBoxFragment& line,
text_direction_(static_cast<unsigned>(line.BaseDirection())),
ink_overflow_computed_(false),
is_dirty_(false),
- is_first_for_node_(true),
is_last_for_node_(true) {
DCHECK(!IsFormattingContextRoot());
}
@@ -89,7 +132,7 @@ NGFragmentItem::NGFragmentItem(const NGPhysicalLineBoxFragment& line,
NGFragmentItem::NGFragmentItem(const NGPhysicalBoxFragment& box,
TextDirection resolved_direction)
: layout_object_(box.GetLayoutObject()),
- box_({&box, 1}),
+ box_({&box, /* descendants_count */ 1}),
rect_({PhysicalOffset(), box.Size()}),
type_(kBox),
style_variant_(static_cast<unsigned>(box.StyleVariant())),
@@ -97,65 +140,83 @@ NGFragmentItem::NGFragmentItem(const NGPhysicalBoxFragment& box,
text_direction_(static_cast<unsigned>(resolved_direction)),
ink_overflow_computed_(false),
is_dirty_(false),
- is_first_for_node_(true),
is_last_for_node_(true) {
DCHECK_EQ(IsFormattingContextRoot(), box.IsFormattingContextRoot());
}
-NGFragmentItem::NGFragmentItem(const NGInlineItem& inline_item,
- const PhysicalSize& size)
- : layout_object_(inline_item.GetLayoutObject()),
- box_({nullptr, 1}),
- rect_({PhysicalOffset(), size}),
- type_(kBox),
- style_variant_(static_cast<unsigned>(inline_item.StyleVariant())),
- is_hidden_for_paint_(false),
- text_direction_(static_cast<unsigned>(TextDirection::kLtr)),
- ink_overflow_computed_(false),
- is_dirty_(false),
- is_first_for_node_(true),
- is_last_for_node_(true) {
- DCHECK_EQ(inline_item.Type(), NGInlineItem::kOpenTag);
- DCHECK(layout_object_);
- DCHECK(layout_object_->IsLayoutInline());
- DCHECK(!IsFormattingContextRoot());
-}
+NGFragmentItem::NGFragmentItem(NGLogicalLineItem&& line_item,
+ WritingMode writing_mode) {
+ DCHECK(line_item.CanCreateFragmentItem());
-// static
-void NGFragmentItem::Create(NGLineBoxFragmentBuilder::ChildList* child_list,
- const String& text_content,
- WritingMode writing_mode) {
- for (auto& child : *child_list) {
- DCHECK(!child.fragment_item);
+ if (line_item.fragment) {
+ new (this) NGFragmentItem(*line_item.fragment);
+ return;
+ }
- if (child.fragment) {
- child.fragment_item = base::AdoptRef(new NGFragmentItem(*child.fragment));
- continue;
+ if (line_item.inline_item) {
+ if (UNLIKELY(line_item.text_content)) {
+ new (this) NGFragmentItem(
+ *line_item.inline_item, std::move(line_item.shape_result),
+ line_item.text_content,
+ ToPhysicalSize(line_item.MarginSize(), writing_mode),
+ line_item.is_hidden_for_paint);
+ return;
}
- if (child.item_result) {
- child.fragment_item = base::AdoptRef(new NGFragmentItem(
- std::move(*child.item_result),
- ToPhysicalSize({child.inline_size, child.rect.size.block_size},
- writing_mode)));
- continue;
- }
+ new (this)
+ NGFragmentItem(*line_item.inline_item,
+ std::move(line_item.shape_result), line_item.text_offset,
+ ToPhysicalSize(line_item.MarginSize(), writing_mode),
+ line_item.is_hidden_for_paint);
+ return;
+ }
- if (child.layout_result) {
- const NGPhysicalBoxFragment& fragment =
- To<NGPhysicalBoxFragment>(child.layout_result->PhysicalFragment());
- child.fragment_item = base::AdoptRef(
- new NGFragmentItem(fragment, child.ResolvedDirection()));
- continue;
- }
+ if (line_item.layout_result) {
+ const NGPhysicalBoxFragment& box_fragment =
+ To<NGPhysicalBoxFragment>(line_item.layout_result->PhysicalFragment());
+ new (this) NGFragmentItem(box_fragment, line_item.ResolvedDirection());
+ return;
+ }
- if (child.inline_item) {
- child.fragment_item = base::AdoptRef(new NGFragmentItem(
- *child.inline_item,
- ToPhysicalSize(child.rect.size,
- child.inline_item->Style()->GetWritingMode())));
- }
+ // CanCreateFragmentItem()
+ NOTREACHED();
+ CHECK(false);
+}
+
+NGFragmentItem::NGFragmentItem(const NGFragmentItem& source)
+ : layout_object_(source.layout_object_),
+ rect_(source.rect_),
+ fragment_id_(source.fragment_id_),
+ delta_to_next_for_same_layout_object_(
+ source.delta_to_next_for_same_layout_object_),
+ type_(source.type_),
+ sub_type_(source.sub_type_),
+ style_variant_(source.style_variant_),
+ is_hidden_for_paint_(source.is_hidden_for_paint_),
+ text_direction_(source.text_direction_),
+ ink_overflow_computed_(source.ink_overflow_computed_),
+ is_dirty_(source.is_dirty_),
+ is_last_for_node_(source.is_last_for_node_) {
+ switch (Type()) {
+ case kText:
+ new (&text_) TextItem(source.text_);
+ break;
+ case kGeneratedText:
+ new (&generated_text_) GeneratedTextItem(source.generated_text_);
+ break;
+ case kLine:
+ new (&line_) LineItem(source.line_);
+ break;
+ case kBox:
+ new (&box_) BoxItem(source.box_);
+ break;
}
+
+ // Copy |ink_overflow_| only for text items, because ink overflow for other
+ // items may be chnaged even in simplified layout or when reusing lines, and
+ // that they need to be re-computed anyway.
+ if (source.ink_overflow_ && ink_overflow_computed_ && IsText())
+ ink_overflow_ = std::make_unique<NGInkOverflow>(*source.ink_overflow_);
}
NGFragmentItem::~NGFragmentItem() {
@@ -179,8 +240,7 @@ bool NGFragmentItem::IsInlineBox() const {
if (Type() == kBox) {
if (const NGPhysicalBoxFragment* box = BoxFragment())
return box->IsInlineBox();
- DCHECK(GetLayoutObject()->IsLayoutInline());
- return true;
+ NOTREACHED();
}
return false;
}
@@ -336,7 +396,7 @@ TextDirection NGFragmentItem::ResolvedDirection() const {
return static_cast<TextDirection>(text_direction_);
}
-String NGFragmentItem::DebugName() const {
+String NGFragmentItem::ToString() const {
// TODO(yosin): Once |NGPaintFragment| is removed, we should get rid of
// following if-statements.
// For ease of rebasing, we use same |DebugName()| as |NGPaintFrgment|.
@@ -368,20 +428,6 @@ String NGFragmentItem::DebugName() const {
return "NGFragmentItem";
}
-IntRect NGFragmentItem::VisualRect() const {
- // TODO(kojii): Need to reconsider the storage of |VisualRect|, to integrate
- // better with |FragmentData| and to avoid dependency to |LayoutObject|.
- DCHECK(GetLayoutObject());
- return GetLayoutObject()->VisualRectForInlineBox();
-}
-
-IntRect NGFragmentItem::PartialInvalidationVisualRect() const {
- // TODO(yosin): Need to reconsider the storage of |VisualRect|, to integrate
- // better with |FragmentData| and to avoid dependency to |LayoutObject|.
- DCHECK(GetLayoutObject());
- return GetLayoutObject()->PartialInvalidationVisualRectForInlineBox();
-}
-
PhysicalRect NGFragmentItem::LocalVisualRectFor(
const LayoutObject& layout_object) {
DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
@@ -427,6 +473,14 @@ void NGFragmentItem::RecalcInkOverflow(
PhysicalRect* self_and_contents_rect_out) {
DCHECK_EQ(this, cursor->CurrentItem());
+ if (UNLIKELY(IsLayoutObjectDestroyedOrMoved())) {
+ // TODO(crbug.com/1099613): This should not happen, as long as it is really
+ // layout-clean. It looks like there are cases where the layout is dirty.
+ NOTREACHED();
+ cursor->MoveToNextSkippingChildren();
+ return;
+ }
+
if (IsText()) {
cursor->MoveToNext();
@@ -482,7 +536,7 @@ void NGFragmentItem::RecalcInkOverflow(
DCHECK(box_fragment->IsInlineBox());
self_rect = box_fragment->ComputeSelfInkOverflow();
} else {
- self_rect = LocalRect();
+ NOTREACHED();
}
*self_and_contents_rect_out = UnionRect(self_rect, contents_rect);
} else {
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
index 703564f3ebc..7823ff0bcef 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
@@ -21,16 +21,15 @@ namespace blink {
class NGFragmentItems;
class NGInlineBreakToken;
-class NGInlineItem;
class NGPhysicalTextFragment;
struct NGTextFragmentPaintInfo;
+struct NGLogicalLineItem;
// This class represents a text run or a box in an inline formatting context.
//
// This class consumes less memory than a full fragment, and can be stored in a
// flat list (NGFragmentItems) for easier and faster traversal.
-class CORE_EXPORT NGFragmentItem : public RefCounted<NGFragmentItem>,
- public DisplayItemClient {
+class CORE_EXPORT NGFragmentItem {
public:
// Represents regular text that exists in the DOM.
struct TextItem {
@@ -66,23 +65,21 @@ class CORE_EXPORT NGFragmentItem : public RefCounted<NGFragmentItem>,
enum ItemType { kText, kGeneratedText, kLine, kBox };
+ // Create appropriate type for |line_item|.
+ NGFragmentItem(NGLogicalLineItem&& line_item, WritingMode writing_mode);
// Create a text item.
// TODO(kojii): Should be able to create without once creating fragments.
explicit NGFragmentItem(const NGPhysicalTextFragment& text);
// Create a box item.
NGFragmentItem(const NGPhysicalBoxFragment& box,
TextDirection resolved_direction);
- // Create a culled box item.
- NGFragmentItem(const NGInlineItem& inline_item, const PhysicalSize& size);
// Create a line item.
- NGFragmentItem(const NGPhysicalLineBoxFragment& line, wtf_size_t item_count);
+ explicit NGFragmentItem(const NGPhysicalLineBoxFragment& line);
- // Create |NGFragmentItem| for all items in |child_list|.
- static void Create(NGLineBoxFragmentBuilder::ChildList* child_list,
- const String& text_content,
- WritingMode writing_mode);
+ // The copy constructor.
+ NGFragmentItem(const NGFragmentItem&);
- ~NGFragmentItem() final;
+ ~NGFragmentItem();
ItemType Type() const { return static_cast<ItemType>(type_); }
@@ -95,19 +92,33 @@ class CORE_EXPORT NGFragmentItem : public RefCounted<NGFragmentItem>,
bool IsHiddenForPaint() const { return is_hidden_for_paint_; }
bool IsListMarker() const;
- // Return true if this is the first fragment generated from a node.
- bool IsFirstForNode() const {
- DCHECK(Type() != kLine);
- return is_first_for_node_;
+ // A sequence number of fragments generated from a |LayoutObject|.
+ // For line boxes, please see |kInitialLineFragmentId|.
+ wtf_size_t FragmentId() const {
+ DCHECK_NE(Type(), kLine);
+ return fragment_id_;
}
+ void SetFragmentId(wtf_size_t id) const {
+ DCHECK_NE(Type(), kLine);
+ fragment_id_ = id;
+ }
+ // The initial framgent_id for line boxes.
+ // TODO(kojii): This is to avoid conflict with multicol because line boxes use
+ // its |LayoutBlockFlow| as their |DisplayItemClient|, but multicol also uses
+ // fragment id for |LayoutBlockFlow| today. The plan is to make |FragmentData|
+ // a |DisplayItemClient| instead.
+ // TODO(kojii): The fragment id for line boxes must be unique across NG block
+ // fragmentation. This is not implemented yet.
+ static constexpr wtf_size_t kInitialLineFragmentId = 0x80000000;
+
+ // Return true if this is the first fragment generated from a node.
+ bool IsFirstForNode() const { return !FragmentId(); }
// Return true if this is the last fragment generated from a node.
bool IsLastForNode() const {
DCHECK(Type() != kLine);
return is_last_for_node_;
}
-
- void SetIsFirstForNode(bool is_first) const { is_first_for_node_ = is_first; }
void SetIsLastForNode(bool is_last) const { is_last_for_node_ = is_last; }
NGStyleVariant StyleVariant() const {
@@ -129,11 +140,17 @@ class CORE_EXPORT NGFragmentItem : public RefCounted<NGFragmentItem>,
LayoutObject* GetMutableLayoutObject() const {
return const_cast<LayoutObject*>(layout_object_);
}
+ bool IsLayoutObjectDestroyedOrMoved() const { return !layout_object_; }
void LayoutObjectWillBeDestroyed() const;
void LayoutObjectWillBeMoved() const;
Node* GetNode() const { return layout_object_->GetNode(); }
Node* NodeForHitTest() const { return layout_object_->NodeForHitTest(); }
+ // Use |LayoutObject|+|FragmentId()| for |DisplayItem::Id|.
+ const DisplayItemClient* GetDisplayItemClient() const {
+ return GetLayoutObject();
+ }
+
wtf_size_t DeltaToNextForSameLayoutObject() const {
return delta_to_next_for_same_layout_object_;
}
@@ -161,8 +178,15 @@ class CORE_EXPORT NGFragmentItem : public RefCounted<NGFragmentItem>,
}
bool HasChildren() const { return DescendantsCount() > 1; }
void SetDescendantsCount(wtf_size_t count) {
- CHECK_EQ(Type(), kBox);
- box_.descendants_count = count;
+ if (Type() == kBox) {
+ box_.descendants_count = count;
+ return;
+ }
+ if (Type() == kLine) {
+ line_.descendants_count = count;
+ return;
+ }
+ NOTREACHED();
}
// Returns |NGPhysicalBoxFragment| if one is associated with this item.
@@ -202,11 +226,6 @@ class CORE_EXPORT NGFragmentItem : public RefCounted<NGFragmentItem>,
return NGLineBoxType::kNormalLineBox;
}
- // DisplayItemClient overrides
- String DebugName() const override;
- IntRect VisualRect() const override;
- IntRect PartialInvalidationVisualRect() const override;
-
static PhysicalRect LocalVisualRectFor(const LayoutObject& layout_object);
// Re-compute the ink overflow for the |cursor| until its end.
@@ -347,9 +366,24 @@ class CORE_EXPORT NGFragmentItem : public RefCounted<NGFragmentItem>,
// Returns true if this item is reusable.
bool CanReuse() const;
+ const NGFragmentItem* operator->() const { return this; }
+
+ // Get a description of |this| for the debug purposes.
+ String ToString() const;
+
private:
// Create a text item.
- NGFragmentItem(NGInlineItemResult&& item_result, const PhysicalSize& size);
+ NGFragmentItem(const NGInlineItem& inline_item,
+ scoped_refptr<const ShapeResultView> shape_result,
+ const NGTextOffset& text_offset,
+ const PhysicalSize& size,
+ bool is_hidden_for_paint);
+ // Create a generated text item.
+ NGFragmentItem(const NGInlineItem& inline_item,
+ scoped_refptr<const ShapeResultView> shape_result,
+ const String& text_content,
+ const PhysicalSize& size,
+ bool is_hidden_for_paint);
const LayoutBox* InkOverflowOwnerBox() const;
LayoutBox* MutableInkOverflowOwnerBox();
@@ -375,6 +409,8 @@ class CORE_EXPORT NGFragmentItem : public RefCounted<NGFragmentItem>,
std::unique_ptr<NGInkOverflow> ink_overflow_;
+ mutable wtf_size_t fragment_id_ = 0;
+
// Item index delta to the next item for the same |LayoutObject|.
mutable wtf_size_t delta_to_next_for_same_layout_object_ = 0;
@@ -392,7 +428,6 @@ class CORE_EXPORT NGFragmentItem : public RefCounted<NGFragmentItem>,
mutable unsigned is_dirty_ : 1;
- mutable unsigned is_first_for_node_ : 1;
mutable unsigned is_last_for_node_ : 1;
};
@@ -405,6 +440,9 @@ inline bool NGFragmentItem::CanReuse() const {
return false;
}
+CORE_EXPORT std::ostream& operator<<(std::ostream&, const NGFragmentItem*);
+CORE_EXPORT std::ostream& operator<<(std::ostream&, const NGFragmentItem&);
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_FRAGMENT_ITEM_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc
index 59d6f53c852..cfe1900729d 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc
@@ -12,14 +12,6 @@
namespace blink {
-namespace {
-
-inline bool ShouldSetFirstAndLastForNode() {
- return RuntimeEnabledFeatures::LayoutNGFragmentTraversalEnabled();
-}
-
-} // namespace
-
NGFragmentItems::NGFragmentItems(NGFragmentItemsBuilder* builder)
: text_content_(std::move(builder->text_content_)),
first_line_text_content_(std::move(builder->first_line_text_content_)),
@@ -28,16 +20,13 @@ NGFragmentItems::NGFragmentItems(NGFragmentItemsBuilder* builder)
for (unsigned i = 0; i < size_; ++i) {
// Call the move constructor to move without |AddRef|. Items in
// |NGFragmentItemsBuilder| are not used after |this| was constructed.
- DCHECK(source_items[i].item);
- new (&items_[i])
- scoped_refptr<const NGFragmentItem>(std::move(source_items[i].item));
- DCHECK(!source_items[i].item); // Ensure the source was moved.
+ new (&items_[i]) NGFragmentItem(std::move(source_items[i].item));
}
}
NGFragmentItems::~NGFragmentItems() {
for (unsigned i = 0; i < size_; ++i)
- items_[i]->Release();
+ items_[i].~NGFragmentItem();
}
bool NGFragmentItems::IsSubSpan(const Span& span) const {
@@ -47,63 +36,66 @@ bool NGFragmentItems::IsSubSpan(const Span& span) const {
void NGFragmentItems::FinalizeAfterLayout(
const Vector<scoped_refptr<const NGLayoutResult>, 1>& results) {
- HashMap<const LayoutObject*, const NGFragmentItem*> first_and_last;
+ struct LastItem {
+ const NGFragmentItem* item;
+ wtf_size_t fragment_id;
+ wtf_size_t item_index;
+ };
+ HashMap<const LayoutObject*, LastItem> last_items;
for (const auto& result : results) {
const auto& fragment =
To<NGPhysicalBoxFragment>(result->PhysicalFragment());
const NGFragmentItems* current = fragment.Items();
if (UNLIKELY(!current))
continue;
- HashMap<const LayoutObject*, wtf_size_t> last_fragment_map;
+
+ // TODO(layout-dev): Make this work for multiple box fragments (block
+ // fragmentation).
+ const bool create_index_cache = fragment.IsFirstForNode();
+
const Span items = current->Items();
wtf_size_t index = 0;
- for (const scoped_refptr<const NGFragmentItem>& item : items) {
+ for (const NGFragmentItem& item : items) {
++index;
- if (item->Type() == NGFragmentItem::kLine) {
- DCHECK_EQ(item->DeltaToNextForSameLayoutObject(), 0u);
- continue;
- }
- LayoutObject* const layout_object = item->GetMutableLayoutObject();
- if (UNLIKELY(layout_object->IsFloating())) {
- DCHECK_EQ(item->DeltaToNextForSameLayoutObject(), 0u);
+ if (item.Type() == NGFragmentItem::kLine) {
+ DCHECK_EQ(item.DeltaToNextForSameLayoutObject(), 0u);
continue;
}
+ LayoutObject* const layout_object = item.GetMutableLayoutObject();
DCHECK(!layout_object->IsOutOfFlowPositioned());
- DCHECK(layout_object->IsInLayoutNGInlineFormattingContext()) << *item;
- item->SetDeltaToNextForSameLayoutObject(0);
-
- if (ShouldSetFirstAndLastForNode()) {
- bool is_first_for_node =
- first_and_last.Set(layout_object, item.get()).is_new_entry;
- item->SetIsFirstForNode(is_first_for_node);
- item->SetIsLastForNode(false);
- }
-
- // TODO(layout-dev): Make this work for multiple box fragments (block
- // fragmentation).
- if (!fragment.IsFirstForNode())
+ DCHECK(layout_object->IsInLayoutNGInlineFormattingContext());
+
+ item.SetDeltaToNextForSameLayoutObject(0);
+ item.SetIsLastForNode(false);
+
+ const auto last_item_result =
+ last_items.insert(layout_object, LastItem{&item, 0, index});
+ if (last_item_result.is_new_entry) {
+ item.SetFragmentId(0);
+ if (create_index_cache) {
+ DCHECK_EQ(layout_object->FirstInlineFragmentItemIndex(), 0u);
+ layout_object->SetFirstInlineFragmentItemIndex(index);
+ }
continue;
+ }
- auto insert_result = last_fragment_map.insert(layout_object, index);
- if (insert_result.is_new_entry) {
- DCHECK_EQ(layout_object->FirstInlineFragmentItemIndex(), 0u);
- layout_object->SetFirstInlineFragmentItemIndex(index);
- continue;
+ LastItem* last = &last_item_result.stored_value->value;
+ const NGFragmentItem* last_item = last->item;
+ DCHECK_EQ(last_item->DeltaToNextForSameLayoutObject(), 0u);
+ if (create_index_cache) {
+ const wtf_size_t last_index = last->item_index;
+ DCHECK_GT(last_index, 0u);
+ DCHECK_LT(last_index, items.size());
+ DCHECK_LT(last_index, index);
+ last_item->SetDeltaToNextForSameLayoutObject(index - last_index);
}
- const wtf_size_t last_index = insert_result.stored_value->value;
- insert_result.stored_value->value = index;
- DCHECK_GT(last_index, 0u) << *item;
- DCHECK_LT(last_index, items.size());
- DCHECK_LT(last_index, index);
- DCHECK_EQ(items[last_index - 1]->DeltaToNextForSameLayoutObject(), 0u);
- items[last_index - 1]->SetDeltaToNextForSameLayoutObject(index -
- last_index);
+ item.SetFragmentId(++last->fragment_id);
+ last->item = &item;
+ last->item_index = index;
}
}
- if (!ShouldSetFirstAndLastForNode())
- return;
- for (const auto& iter : first_and_last)
- iter.value->SetIsLastForNode(true);
+ for (const auto& iter : last_items)
+ iter.value.item->SetIsLastForNode(true);
}
void NGFragmentItems::ClearAssociatedFragments(LayoutObject* container) {
@@ -113,7 +105,7 @@ void NGFragmentItems::ClearAssociatedFragments(LayoutObject* container) {
for (LayoutObject* child = container->SlowFirstChild(); child;
child = child->NextSibling()) {
if (UNLIKELY(!child->IsInLayoutNGInlineFormattingContext() ||
- child->IsFloatingOrOutOfFlowPositioned()))
+ child->IsOutOfFlowPositioned()))
continue;
child->ClearFirstInlineFragmentItemIndex();
@@ -183,7 +175,7 @@ bool NGFragmentItems::TryDirtyFirstLineFor(
DCHECK(layout_object.IsInLayoutNGInlineFormattingContext());
DCHECK(!layout_object.IsFloatingOrOutOfFlowPositioned());
if (wtf_size_t index = layout_object.FirstInlineFragmentItemIndex()) {
- const NGFragmentItem& item = *Items()[index - 1];
+ const NGFragmentItem& item = Items()[index - 1];
DCHECK_EQ(&layout_object, item.GetLayoutObject());
item.SetDirty();
return true;
@@ -251,32 +243,18 @@ void NGFragmentItems::DirtyLinesFromChangedChild(
void NGFragmentItems::DirtyLinesFromNeedsLayout(
const LayoutBlockFlow* container) const {
DCHECK_EQ(this, container->FragmentItems());
- for (LayoutObject* layout_object = container->FirstChild(); layout_object;) {
- if (layout_object->IsText()) {
- if (layout_object->SelfNeedsLayout()) {
- DirtyLinesFromChangedChild(layout_object);
- return;
- }
- } else if (auto* layout_inline = ToLayoutInlineOrNull(layout_object)) {
- if (layout_object->SelfNeedsLayout()) {
- DirtyLinesFromChangedChild(layout_object);
- return;
- }
- if (layout_object->NormalChildNeedsLayout() ||
- layout_object->PosChildNeedsLayout()) {
- if (LayoutObject* child = layout_inline->FirstChild()) {
- layout_object = child;
- continue;
- }
- }
- } else {
- if (layout_object->NeedsLayout()) {
- DirtyLinesFromChangedChild(layout_object);
- return;
- }
+ // Mark dirty for the first top-level child that has |NeedsLayout|.
+ //
+ // TODO(kojii): We could mark first descendant to increase reuse
+ // opportunities. Doing this complicates the logic, especially when culled
+ // inline is involved, and common case is to append to large IFC. Choose
+ // simpler logic and faster to check over more reuse opportunities.
+ for (LayoutObject* child = container->FirstChild(); child;
+ child = child->NextSibling()) {
+ if (child->NeedsLayout()) {
+ DirtyLinesFromChangedChild(child);
+ return;
}
-
- layout_object = layout_object->NextInPreOrderAfterChildren(container);
}
}
@@ -292,8 +270,8 @@ void NGFragmentItems::LayoutObjectWillBeMoved(
*container.GetPhysicalFragment(idx);
DCHECK(fragment.Items());
for (const auto& item : fragment.Items()->Items()) {
- if (item->GetLayoutObject() == &layout_object)
- item->LayoutObjectWillBeMoved();
+ if (item.GetLayoutObject() == &layout_object)
+ item.LayoutObjectWillBeMoved();
}
}
return;
@@ -319,8 +297,8 @@ void NGFragmentItems::LayoutObjectWillBeDestroyed(
*container.GetPhysicalFragment(idx);
DCHECK(fragment.Items());
for (const auto& item : fragment.Items()->Items()) {
- if (item->GetLayoutObject() == &layout_object)
- item->LayoutObjectWillBeDestroyed();
+ if (item.GetLayoutObject() == &layout_object)
+ item.LayoutObjectWillBeDestroyed();
}
}
return;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h
index eebdb5f616e..00025571a5a 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h
@@ -24,15 +24,21 @@ class CORE_EXPORT NGFragmentItems {
wtf_size_t Size() const { return size_; }
- using Span = base::span<const scoped_refptr<const NGFragmentItem>>;
+ using Span = base::span<const NGFragmentItem>;
Span Items() const { return base::make_span(ItemsData(), size_); }
+ bool Equals(const Span& span) const {
+ return ItemsData() == span.data() && Size() == span.size();
+ }
bool IsSubSpan(const Span& span) const;
const NGFragmentItem& front() const {
CHECK_GE(size_, 1u);
- return *items_[0];
+ return items_[0];
}
+ // Text content for `::first-line`. Available only if `::first-line` has
+ // different style than non-first-line style.
+ const String& FirstLineText() const { return first_line_text_content_; }
const String& Text(bool first_line) const {
return UNLIKELY(first_line) ? first_line_text_content_ : text_content_;
}
@@ -66,9 +72,7 @@ class CORE_EXPORT NGFragmentItems {
wtf_size_t ByteSize() const { return ByteSizeFor(Size()); }
private:
- const scoped_refptr<const NGFragmentItem>* ItemsData() const {
- return reinterpret_cast<const scoped_refptr<const NGFragmentItem>*>(items_);
- }
+ const NGFragmentItem* ItemsData() const { return items_; }
static bool CanReuseAll(NGInlineCursor* cursor);
bool TryDirtyFirstLineFor(const LayoutObject& layout_object) const;
@@ -86,7 +90,7 @@ class CORE_EXPORT NGFragmentItems {
static_assert(
sizeof(NGFragmentItem*) == sizeof(scoped_refptr<const NGFragmentItem>),
"scoped_refptr must be the size of a pointer for |ItemsData()| to work");
- NGFragmentItem* items_[];
+ NGFragmentItem items_[0];
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc
index 452e1c2f102..74f8d5d2feb 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h"
+#include "third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h"
@@ -11,7 +12,14 @@
namespace blink {
-NGFragmentItemsBuilder::NGFragmentItemsBuilder(const NGInlineNode& node) {
+NGFragmentItemsBuilder::NGFragmentItemsBuilder(
+ WritingDirectionMode writing_direction)
+ : node_(nullptr), writing_direction_(writing_direction) {}
+
+NGFragmentItemsBuilder::NGFragmentItemsBuilder(
+ const NGInlineNode& node,
+ WritingDirectionMode writing_direction)
+ : node_(node), writing_direction_(writing_direction) {
const NGInlineItemsData& items_data = node.ItemsData(false);
text_content_ = items_data.text_content;
const NGInlineItemsData& first_line = node.ItemsData(true);
@@ -30,11 +38,17 @@ NGFragmentItemsBuilder::NGFragmentItemsBuilder(const NGInlineNode& node) {
void NGFragmentItemsBuilder::SetCurrentLine(
const NGPhysicalLineBoxFragment& line,
- ChildList&& children) {
+ NGLogicalLineItems* current_line) {
#if DCHECK_IS_ON()
current_line_fragment_ = &line;
#endif
- current_line_ = std::move(children);
+ DCHECK(current_line);
+ DCHECK(!current_line_); // Check |AddLine| runs after |SetCurrentLine|.
+ current_line_ = current_line;
+}
+
+void NGFragmentItemsBuilder::ClearCurrentLineForTesting() {
+ current_line_ = nullptr;
}
void NGFragmentItemsBuilder::AddLine(const NGPhysicalLineBoxFragment& line,
@@ -43,79 +57,81 @@ void NGFragmentItemsBuilder::AddLine(const NGPhysicalLineBoxFragment& line,
#if DCHECK_IS_ON()
DCHECK_EQ(current_line_fragment_, &line);
#endif
+ DCHECK(current_line_);
// Reserve the capacity for (children + line box item).
const wtf_size_t size_before = items_.size();
- const wtf_size_t estimated_size = size_before + current_line_.size() + 1;
+ const wtf_size_t estimated_size = size_before + current_line_->size() + 1;
const wtf_size_t old_capacity = items_.capacity();
if (estimated_size > old_capacity)
items_.ReserveCapacity(std::max(estimated_size, old_capacity * 2));
// Add an empty item so that the start of the line can be set later.
const wtf_size_t line_start_index = items_.size();
- items_.emplace_back(offset);
+ items_.emplace_back(offset, line);
- AddItems(current_line_.begin(), current_line_.end());
+ AddItems(current_line_->begin(), current_line_->end());
// All children are added. Create an item for the start of the line.
+ NGFragmentItem& line_item = items_[line_start_index].item;
const wtf_size_t item_count = items_.size() - line_start_index;
- DCHECK(!items_[line_start_index].item);
- items_[line_start_index].item =
- base::MakeRefCounted<NGFragmentItem>(line, item_count);
+ DCHECK_EQ(line_item.DescendantsCount(), 1u);
+ line_item.SetDescendantsCount(item_count);
// Keep children's offsets relative to |line|. They will be adjusted later in
// |ConvertToPhysical()|.
- current_line_.clear();
+ // Clear the current line without releasing the buffer. It is likely to be
+ // reused again.
+ current_line_->Shrink(0);
#if DCHECK_IS_ON()
+ current_line_ = nullptr;
current_line_fragment_ = nullptr;
#endif
DCHECK_LE(items_.size(), estimated_size);
}
-void NGFragmentItemsBuilder::AddItems(Child* child_begin, Child* child_end) {
+void NGFragmentItemsBuilder::AddItems(NGLogicalLineItem* child_begin,
+ NGLogicalLineItem* child_end) {
DCHECK(!is_converted_to_physical_);
- for (Child* child_iter = child_begin; child_iter != child_end;) {
- Child& child = *child_iter;
+ const WritingMode writing_mode = GetWritingMode();
+ for (NGLogicalLineItem* child_iter = child_begin; child_iter != child_end;) {
+ NGLogicalLineItem& child = *child_iter;
// OOF children should have been added to their parent box fragments.
DCHECK(!child.out_of_flow_positioned_box);
- if (!child.fragment_item) {
+ if (!child.CanCreateFragmentItem()) {
++child_iter;
continue;
}
if (child.children_count <= 1) {
- items_.emplace_back(std::move(child.fragment_item), child.rect.offset);
+ items_.emplace_back(child.rect.offset, std::move(child), writing_mode);
++child_iter;
continue;
}
- DCHECK(child.fragment_item->IsContainer());
- DCHECK(!child.fragment_item->IsFloating());
// Children of inline boxes are flattened and added to |items_|, with the
// count of descendant items to preserve the tree structure.
//
// Add an empty item so that the start of the box can be set later.
- wtf_size_t box_start_index = items_.size();
- items_.emplace_back(child.rect.offset);
+ const wtf_size_t box_start_index = items_.size();
+ items_.emplace_back(child.rect.offset, std::move(child), writing_mode);
// Add all children, including their desendants, skipping this item.
CHECK_GE(child.children_count, 1u); // 0 will loop infinitely.
- Child* end_child_iter = child_iter + child.children_count;
+ NGLogicalLineItem* end_child_iter = child_iter + child.children_count;
CHECK_LE(end_child_iter - child_begin, child_end - child_begin);
AddItems(child_iter + 1, end_child_iter);
child_iter = end_child_iter;
// All children are added. Compute how many items are actually added. The
// number of items added maybe different from |child.children_count|.
- wtf_size_t item_count = items_.size() - box_start_index;
-
- // Create an item for the start of the box.
- child.fragment_item->SetDescendantsCount(item_count);
- DCHECK(!items_[box_start_index].item);
- items_[box_start_index].item = std::move(child.fragment_item);
+ const wtf_size_t item_count = items_.size() - box_start_index;
+ NGFragmentItem& box_item = items_[box_start_index].item;
+ DCHECK_EQ(box_item.DescendantsCount(), 1u);
+ box_item.SetDescendantsCount(item_count);
}
}
@@ -127,24 +143,28 @@ void NGFragmentItemsBuilder::AddListMarker(
// Resolved direction matters only for inline items, and outside list markers
// are not inline.
const TextDirection resolved_direction = TextDirection::kLtr;
- items_.emplace_back(
- base::MakeRefCounted<NGFragmentItem>(marker_fragment, resolved_direction),
- offset);
+ items_.emplace_back(offset, marker_fragment, resolved_direction);
}
NGFragmentItemsBuilder::AddPreviousItemsResult
NGFragmentItemsBuilder::AddPreviousItems(
const NGFragmentItems& items,
- WritingMode writing_mode,
- TextDirection direction,
const PhysicalSize& container_size,
NGBoxFragmentBuilder* container_builder,
- bool stop_at_dirty) {
- AddPreviousItemsResult result;
- if (stop_at_dirty) {
+ const NGFragmentItem* end_item) {
+ if (end_item) {
+ DCHECK(node_);
DCHECK(container_builder);
DCHECK(text_content_);
+
+ if (UNLIKELY(items.FirstLineText() && !first_line_text_content_)) {
+ // Don't reuse previous items if they have different `::first-line` style
+ // but |this| doesn't. Reaching here means that computed style doesn't
+ // change, but |NGFragmentItem| has wrong |NGStyleVariant|.
+ return AddPreviousItemsResult();
+ }
} else {
+ DCHECK(!container_builder);
DCHECK(!text_content_);
text_content_ = items.Text(false);
first_line_text_content_ = items.Text(true);
@@ -159,11 +179,13 @@ NGFragmentItemsBuilder::AddPreviousItems(
// This is needed because the container size may be different, in that case,
// the physical offsets are different when `writing-mode: vertial-rl`.
DCHECK(!is_converted_to_physical_);
- const WritingMode line_writing_mode = ToLineWritingMode(writing_mode);
+ const WritingModeConverter converter(GetWritingDirection(), container_size);
+ const WritingMode writing_mode = GetWritingMode();
+ WritingModeConverter line_converter(
+ {ToLineWritingMode(writing_mode), TextDirection::kLtr});
- const NGFragmentItem* const end_item =
- stop_at_dirty ? items.EndOfReusableItems() : nullptr;
- const NGFragmentItem* last_line_start_item = nullptr;
+ const NGInlineBreakToken* last_break_token = nullptr;
+ const NGInlineItemsData* items_data = nullptr;
LayoutUnit used_block_size;
for (NGInlineCursor cursor(items); cursor;) {
@@ -174,74 +196,88 @@ NGFragmentItemsBuilder::AddPreviousItems(
DCHECK(!item.IsDirty());
const LogicalOffset item_offset =
- item.OffsetInContainerBlock().ConvertToLogical(
- writing_mode, direction, container_size, item.Size());
- items_.emplace_back(&item, item_offset);
+ converter.ToLogical(item.OffsetInContainerBlock(), item.Size());
if (item.Type() == NGFragmentItem::kLine) {
+ DCHECK(item.LineBoxFragment());
+ if (end_item) {
+ // Check if this line has valid item_index and offset.
+ const NGPhysicalLineBoxFragment* line_fragment = item.LineBoxFragment();
+ const NGInlineBreakToken* break_token =
+ To<NGInlineBreakToken>(line_fragment->BreakToken());
+ DCHECK(!break_token->IsFinished());
+ const NGInlineItemsData* current_items_data;
+ if (UNLIKELY(break_token->UseFirstLineStyle()))
+ current_items_data = &node_.ItemsData(true);
+ else if (items_data)
+ current_items_data = items_data;
+ else
+ current_items_data = items_data = &node_.ItemsData(false);
+ if (UNLIKELY(!current_items_data->IsValidOffset(
+ break_token->ItemIndex(), break_token->TextOffset()))) {
+ NOTREACHED();
+ break;
+ }
+
+ last_break_token = break_token;
+ container_builder->AddChild(*line_fragment, item_offset);
+ used_block_size +=
+ item.Size().ConvertToLogical(writing_mode).block_size;
+ }
+
+ items_.emplace_back(item_offset, item);
const PhysicalRect line_box_bounds = item.RectInContainerBlock();
+ line_converter.SetOuterSize(line_box_bounds.size);
for (NGInlineCursor line = cursor.CursorForDescendants(); line;
line.MoveToNext()) {
const NGFragmentItem& line_child = *line.Current().Item();
DCHECK(line_child.CanReuse());
items_.emplace_back(
- &line_child,
- (line_child.OffsetInContainerBlock() - line_box_bounds.offset)
- .ConvertToLogical(line_writing_mode, TextDirection::kLtr,
- line_box_bounds.size, line_child.Size()));
+ line_converter.ToLogical(
+ line_child.OffsetInContainerBlock() - line_box_bounds.offset,
+ line_child.Size()),
+ line_child);
}
cursor.MoveToNextSkippingChildren();
- DCHECK(item.LineBoxFragment());
- if (stop_at_dirty) {
- container_builder->AddChild(*item.LineBoxFragment(), item_offset);
- last_line_start_item = &item;
- used_block_size +=
- item.Size().ConvertToLogical(writing_mode).block_size;
- }
continue;
}
DCHECK_NE(item.Type(), NGFragmentItem::kLine);
- DCHECK(!stop_at_dirty);
+ DCHECK(!end_item);
+ items_.emplace_back(item_offset, item);
cursor.MoveToNext();
}
+ DCHECK_LE(items_.size(), estimated_size);
- if (stop_at_dirty && last_line_start_item) {
- result.inline_break_token = last_line_start_item->InlineBreakToken();
- DCHECK(result.inline_break_token);
- DCHECK(!result.inline_break_token->IsFinished());
- result.used_block_size = used_block_size;
- result.succeeded = true;
+ if (end_item && last_break_token) {
+ DCHECK(!last_break_token->IsFinished());
+ return AddPreviousItemsResult{last_break_token, used_block_size, true};
}
-
- DCHECK_LE(items_.size(), estimated_size);
- return result;
+ return AddPreviousItemsResult();
}
const NGFragmentItemsBuilder::ItemWithOffsetList& NGFragmentItemsBuilder::Items(
- WritingMode writing_mode,
- TextDirection direction,
const PhysicalSize& outer_size) {
- ConvertToPhysical(writing_mode, direction, outer_size);
+ ConvertToPhysical(outer_size);
return items_;
}
// Convert internal logical offsets to physical. Items are kept with logical
// offset until outer box size is determined.
-void NGFragmentItemsBuilder::ConvertToPhysical(WritingMode writing_mode,
- TextDirection direction,
- const PhysicalSize& outer_size) {
+void NGFragmentItemsBuilder::ConvertToPhysical(const PhysicalSize& outer_size) {
if (is_converted_to_physical_)
return;
+ const WritingModeConverter converter(GetWritingDirection(), outer_size);
// Children of lines have line-relative offsets. Use line-writing mode to
- // convert their logical offsets.
- const WritingMode line_writing_mode = ToLineWritingMode(writing_mode);
+ // convert their logical offsets. Use `kLtr` because inline items are after
+ // bidi-reoder, and that their offset is visual, not logical.
+ WritingModeConverter line_converter(
+ {ToLineWritingMode(GetWritingMode()), TextDirection::kLtr});
for (ItemWithOffset* iter = items_.begin(); iter != items_.end(); ++iter) {
- NGFragmentItem* item = const_cast<NGFragmentItem*>(iter->item.get());
- item->SetOffset(iter->offset.ConvertToPhysical(writing_mode, direction,
- outer_size, item->Size()));
+ NGFragmentItem* item = &iter->item;
+ item->SetOffset(converter.ToPhysical(iter->offset, item->Size()));
// Transform children of lines separately from children of the block,
// because they may have different directions from the block. To do
@@ -251,16 +287,14 @@ void NGFragmentItemsBuilder::ConvertToPhysical(WritingMode writing_mode,
DCHECK(descendants_count);
if (descendants_count) {
const PhysicalRect line_box_bounds = item->RectInContainerBlock();
+ line_converter.SetOuterSize(line_box_bounds.size);
while (--descendants_count) {
++iter;
DCHECK_NE(iter, items_.end());
- item = const_cast<NGFragmentItem*>(iter->item.get());
- // Use `kLtr` because inline items are after bidi-reoder, and that
- // their offset is visual, not logical.
- item->SetOffset(iter->offset.ConvertToPhysical(
- line_writing_mode, TextDirection::kLtr,
- line_box_bounds.size, item->Size()) +
- line_box_bounds.offset);
+ item = &iter->item;
+ item->SetOffset(
+ line_converter.ToPhysical(iter->offset, item->Size()) +
+ line_box_bounds.offset);
}
}
}
@@ -278,12 +312,10 @@ base::Optional<LogicalOffset> NGFragmentItemsBuilder::LogicalOffsetFor(
return base::nullopt;
}
-void NGFragmentItemsBuilder::ToFragmentItems(WritingMode writing_mode,
- TextDirection direction,
- const PhysicalSize& outer_size,
+void NGFragmentItemsBuilder::ToFragmentItems(const PhysicalSize& outer_size,
void* data) {
DCHECK(text_content_);
- ConvertToPhysical(writing_mode, direction, outer_size);
+ ConvertToPhysical(outer_size);
new (data) NGFragmentItems(this);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h
index c161eed2aec..081a0286c6a 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h
@@ -7,7 +7,8 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h"
+#include "third_party/blink/renderer/platform/text/writing_direction_mode.h"
namespace blink {
@@ -22,8 +23,17 @@ class CORE_EXPORT NGFragmentItemsBuilder {
STACK_ALLOCATED();
public:
- NGFragmentItemsBuilder() = default;
- explicit NGFragmentItemsBuilder(const NGInlineNode& node);
+ explicit NGFragmentItemsBuilder(WritingDirectionMode writing_direction);
+ NGFragmentItemsBuilder(const NGInlineNode& node,
+ WritingDirectionMode writing_direction);
+
+ WritingDirectionMode GetWritingDirection() const {
+ return writing_direction_;
+ }
+ WritingMode GetWritingMode() const {
+ return writing_direction_.GetWritingMode();
+ }
+ TextDirection Direction() const { return writing_direction_.Direction(); }
wtf_size_t Size() const { return items_.size(); }
@@ -39,22 +49,20 @@ class CORE_EXPORT NGFragmentItemsBuilder {
: text_content_;
}
- // The caller should create a |ChildList| for a complete line and add to this
- // builder.
+ // The caller should create a |NGLogicalLineItems| for a complete line and add
+ // to this builder.
//
// Adding a line is a two-pass operation, because |NGInlineLayoutAlgorithm|
// creates and positions children within a line box, but its parent algorithm
// positions the line box. |SetCurrentLine| sets the children, and the next
// |AddLine| adds them.
//
- // TODO(kojii): Moving |ChildList| is not cheap because it has inline
- // capacity. Reconsider the ownership.
- using Child = NGLineBoxFragmentBuilder::Child;
- using ChildList = NGLineBoxFragmentBuilder::ChildList;
+ // The caller must keep |children| alive until |AddLine| completes.
void SetCurrentLine(const NGPhysicalLineBoxFragment& line,
- ChildList&& children);
+ NGLogicalLineItems* current_line);
void AddLine(const NGPhysicalLineBoxFragment& line,
const LogicalOffset& offset);
+ void ClearCurrentLineForTesting();
// Add a list marker to the current line.
void AddListMarker(const NGPhysicalBoxFragment& marker_fragment,
@@ -76,25 +84,22 @@ class CORE_EXPORT NGFragmentItemsBuilder {
// items and stops copying before the first dirty line.
AddPreviousItemsResult AddPreviousItems(
const NGFragmentItems& items,
- WritingMode writing_mode,
- TextDirection direction,
const PhysicalSize& container_size,
NGBoxFragmentBuilder* container_builder = nullptr,
- bool stop_at_dirty = false);
+ const NGFragmentItem* end_item = nullptr);
struct ItemWithOffset {
DISALLOW_NEW();
public:
- ItemWithOffset(scoped_refptr<const NGFragmentItem> item,
- const LogicalOffset& offset)
- : item(std::move(item)), offset(offset) {}
- explicit ItemWithOffset(const LogicalOffset& offset) : offset(offset) {}
+ template <class... Args>
+ explicit ItemWithOffset(const LogicalOffset& offset, Args&&... args)
+ : item(std::forward<Args>(args)...), offset(offset) {}
- const NGFragmentItem& operator*() const { return *item; }
- const NGFragmentItem* operator->() const { return item.get(); }
+ const NGFragmentItem& operator*() const { return item; }
+ const NGFragmentItem* operator->() const { return &item; }
- scoped_refptr<const NGFragmentItem> item;
+ NGFragmentItem item;
LogicalOffset offset;
};
@@ -110,30 +115,27 @@ class CORE_EXPORT NGFragmentItemsBuilder {
// containing block geometry for OOF-positioned nodes.
//
// Once this method has been called, new items cannot be added.
- const ItemWithOffsetList& Items(WritingMode,
- TextDirection,
- const PhysicalSize& outer_size);
+ const ItemWithOffsetList& Items(const PhysicalSize& outer_size);
// Build a |NGFragmentItems|. The builder cannot build twice because data set
// to this builder may be cleared.
- void ToFragmentItems(WritingMode,
- TextDirection,
- const PhysicalSize& outer_size,
- void* data);
+ void ToFragmentItems(const PhysicalSize& outer_size, void* data);
private:
- void AddItems(Child* child_begin, Child* child_end);
+ void AddItems(NGLogicalLineItem* child_begin, NGLogicalLineItem* child_end);
- void ConvertToPhysical(WritingMode writing_mode,
- TextDirection direction,
- const PhysicalSize& outer_size);
+ void ConvertToPhysical(const PhysicalSize& outer_size);
ItemWithOffsetList items_;
String text_content_;
String first_line_text_content_;
// Keeps children of a line until the offset is determined. See |AddLine|.
- ChildList current_line_;
+ NGLogicalLineItems* current_line_ = nullptr;
+
+ NGInlineNode node_;
+
+ WritingDirectionMode writing_direction_;
bool has_floating_descendants_for_paint_ = false;
bool is_converted_to_physical_ = false;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
index 33ba9243ca0..bb2d2a16de5 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
@@ -106,7 +106,7 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnBeginPlaceItems(
const ComputedStyle& line_style,
FontBaseline baseline_type,
bool line_height_quirk,
- NGLineBoxFragmentBuilder::ChildList* line_box) {
+ NGLogicalLineItems* line_box) {
if (stack_.IsEmpty()) {
// For the first line, push a box state for the line itself.
stack_.resize(1);
@@ -156,7 +156,7 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnOpenTag(
const NGInlineItem& item,
const NGInlineItemResult& item_result,
FontBaseline baseline_type,
- NGLineBoxFragmentBuilder::ChildList* line_box) {
+ NGLogicalLineItems* line_box) {
NGInlineBoxState* box =
OnOpenTag(item, item_result, baseline_type, *line_box);
box->needs_box_fragment = item.ShouldCreateBoxFragment();
@@ -169,7 +169,7 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnOpenTag(
const NGInlineItem& item,
const NGInlineItemResult& item_result,
FontBaseline baseline_type,
- const NGLineBoxFragmentBuilder::ChildList& line_box) {
+ const NGLogicalLineItems& line_box) {
DCHECK(item.Style());
const ComputedStyle& style = *item.Style();
stack_.resize(stack_.size() + 1);
@@ -186,7 +186,7 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnOpenTag(
}
NGInlineBoxState* NGInlineLayoutStateStack::OnCloseTag(
- NGLineBoxFragmentBuilder::ChildList* line_box,
+ NGLogicalLineItems* line_box,
NGInlineBoxState* box,
FontBaseline baseline_type,
bool has_end_edge) {
@@ -200,9 +200,8 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnCloseTag(
return &stack_.back();
}
-void NGInlineLayoutStateStack::OnEndPlaceItems(
- NGLineBoxFragmentBuilder::ChildList* line_box,
- FontBaseline baseline_type) {
+void NGInlineLayoutStateStack::OnEndPlaceItems(NGLogicalLineItems* line_box,
+ FontBaseline baseline_type) {
for (auto it = stack_.rbegin(); it != stack_.rend(); ++it) {
NGInlineBoxState* box = &(*it);
if (!box->has_end_edge && box->needs_box_fragment &&
@@ -215,17 +214,15 @@ void NGInlineLayoutStateStack::OnEndPlaceItems(
// that |ApplyBaselineShift()| can compute offset for both children and boxes.
// Copy the final offset to |box_data_list_|.
for (BoxData& box_data : box_data_list_) {
- const NGLineBoxFragmentBuilder::Child& placeholder =
- (*line_box)[box_data.fragment_start];
+ const NGLogicalLineItem& placeholder = (*line_box)[box_data.fragment_start];
DCHECK(placeholder.IsPlaceholder());
box_data.rect.offset = placeholder.rect.offset;
}
}
-void NGInlineLayoutStateStack::EndBoxState(
- NGInlineBoxState* box,
- NGLineBoxFragmentBuilder::ChildList* line_box,
- FontBaseline baseline_type) {
+void NGInlineLayoutStateStack::EndBoxState(NGInlineBoxState* box,
+ NGLogicalLineItems* line_box,
+ FontBaseline baseline_type) {
if (box->needs_box_fragment)
AddBoxData(box, line_box);
@@ -237,8 +234,6 @@ void NGInlineLayoutStateStack::EndBoxState(
return;
NGInlineBoxState& parent_box = *std::prev(box);
- // Propagate necessary data back to the parent box.
-
// Unite the metrics to the parent box.
if (position_pending == kPositionNotPending)
parent_box.metrics.Unite(box->metrics);
@@ -250,7 +245,7 @@ void NGInlineLayoutStateStack::EndBoxState(
// from placeholders.
void NGInlineLayoutStateStack::AddBoxFragmentPlaceholder(
NGInlineBoxState* box,
- NGLineBoxFragmentBuilder::ChildList* line_box,
+ NGLogicalLineItems* line_box,
FontBaseline baseline_type) {
DCHECK(box != stack_.begin() &&
box->item->Type() != NGInlineItem::kAtomicInline);
@@ -278,49 +273,37 @@ void NGInlineLayoutStateStack::AddBoxFragmentPlaceholder(
}
// Add a |BoxData|, for each close-tag that needs a box fragment.
-void NGInlineLayoutStateStack::AddBoxData(
- NGInlineBoxState* box,
- NGLineBoxFragmentBuilder::ChildList* line_box) {
- DCHECK(box->needs_box_fragment ||
- (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled() &&
- box->has_box_placeholder && box != stack_.begin() &&
- box->item->Type() != NGInlineItem::kAtomicInline));
+void NGInlineLayoutStateStack::AddBoxData(NGInlineBoxState* box,
+ NGLogicalLineItems* line_box) {
+ DCHECK(box->needs_box_fragment);
DCHECK(box->style);
const ComputedStyle& style = *box->style;
- NGLineBoxFragmentBuilder::Child& placeholder =
- (*line_box)[box->fragment_start];
+ NGLogicalLineItem& placeholder = (*line_box)[box->fragment_start];
DCHECK(placeholder.IsPlaceholder());
const unsigned fragment_end = line_box->size();
DCHECK(box->item);
BoxData& box_data = box_data_list_.emplace_back(
box->fragment_start, fragment_end, box->item, placeholder.Size());
- if (box->needs_box_fragment) {
- box_data.padding = box->padding;
- if (box->has_start_edge) {
- box_data.has_line_left_edge = true;
- box_data.margin_line_left = box->margin_inline_start;
- box_data.margin_border_padding_line_left = box->margin_inline_start +
- box->borders.inline_start +
- box->padding.inline_start;
- }
- if (box->has_end_edge) {
- box_data.has_line_right_edge = true;
- box_data.margin_line_right = box->margin_inline_end;
- box_data.margin_border_padding_line_right = box->margin_inline_end +
- box->borders.inline_end +
- box->padding.inline_end;
- }
- if (IsRtl(style.Direction())) {
- std::swap(box_data.has_line_left_edge, box_data.has_line_right_edge);
- std::swap(box_data.margin_line_left, box_data.margin_line_right);
- std::swap(box_data.margin_border_padding_line_left,
- box_data.margin_border_padding_line_right);
- }
- } else {
- DCHECK_EQ(box->margin_inline_start, 0);
- DCHECK_EQ(box->margin_inline_end, 0);
- DCHECK(box->padding.IsEmpty());
- DCHECK(box->borders.IsEmpty());
+ box_data.padding = box->padding;
+ if (box->has_start_edge) {
+ box_data.has_line_left_edge = true;
+ box_data.margin_line_left = box->margin_inline_start;
+ box_data.margin_border_padding_line_left = box->margin_inline_start +
+ box->borders.inline_start +
+ box->padding.inline_start;
+ }
+ if (box->has_end_edge) {
+ box_data.has_line_right_edge = true;
+ box_data.margin_line_right = box->margin_inline_end;
+ box_data.margin_border_padding_line_right = box->margin_inline_end +
+ box->borders.inline_end +
+ box->padding.inline_end;
+ }
+ if (IsRtl(style.Direction())) {
+ std::swap(box_data.has_line_left_edge, box_data.has_line_right_edge);
+ std::swap(box_data.margin_line_left, box_data.margin_line_right);
+ std::swap(box_data.margin_border_padding_line_left,
+ box_data.margin_border_padding_line_right);
}
DCHECK((*line_box)[box->fragment_start].IsPlaceholder());
@@ -356,8 +339,7 @@ void NGInlineLayoutStateStack::ChildInserted(unsigned index) {
}
}
-void NGInlineLayoutStateStack::PrepareForReorder(
- NGLineBoxFragmentBuilder::ChildList* line_box) {
+void NGInlineLayoutStateStack::PrepareForReorder(NGLogicalLineItems* line_box) {
// There's nothing to do if no boxes.
if (box_data_list_.IsEmpty())
return;
@@ -368,7 +350,7 @@ void NGInlineLayoutStateStack::PrepareForReorder(
box_data_index++;
DCHECK((*line_box)[box_data.fragment_start].IsPlaceholder());
for (unsigned i = box_data.fragment_start; i < box_data.fragment_end; i++) {
- NGLineBoxFragmentBuilder::Child& child = (*line_box)[i];
+ NGLogicalLineItem& child = (*line_box)[i];
unsigned child_box_data_index = child.box_data_index;
if (!child_box_data_index) {
child.box_data_index = box_data_index;
@@ -390,7 +372,7 @@ void NGInlineLayoutStateStack::PrepareForReorder(
}
void NGInlineLayoutStateStack::UpdateAfterReorder(
- NGLineBoxFragmentBuilder::ChildList* line_box) {
+ NGLogicalLineItems* line_box) {
// There's nothing to do if no boxes.
if (box_data_list_.IsEmpty())
return;
@@ -416,18 +398,18 @@ void NGInlineLayoutStateStack::UpdateAfterReorder(
DCHECK_GT(box_data.fragment_end, box_data.fragment_start);
}
// Check all |box_data_index| were migrated to BoxData.
- for (const NGLineBoxFragmentBuilder::Child& child : *line_box) {
+ for (const NGLogicalLineItem& child : *line_box) {
DCHECK_EQ(child.box_data_index, 0u);
}
#endif
}
unsigned NGInlineLayoutStateStack::UpdateBoxDataFragmentRange(
- NGLineBoxFragmentBuilder::ChildList* line_box,
+ NGLogicalLineItems* line_box,
unsigned index) {
// Find the first line box item that should create a box fragment.
for (; index < line_box->size(); index++) {
- NGLineBoxFragmentBuilder::Child* start = &(*line_box)[index];
+ NGLogicalLineItem* start = &(*line_box)[index];
const unsigned box_data_index = start->box_data_index;
if (!box_data_index)
continue;
@@ -444,7 +426,7 @@ unsigned NGInlineLayoutStateStack::UpdateBoxDataFragmentRange(
// Find the end line box item.
const unsigned start_index = index;
for (index++; index < line_box->size(); index++) {
- NGLineBoxFragmentBuilder::Child* end = &(*line_box)[index];
+ NGLogicalLineItem* end = &(*line_box)[index];
// If we found another box that maybe included in this box, update it
// first. Updating will change |end->box_data_index| so that we can
@@ -510,11 +492,11 @@ void NGInlineLayoutStateStack::BoxData::UpdateFragmentEdges(
}
LayoutUnit NGInlineLayoutStateStack::ComputeInlinePositions(
- NGLineBoxFragmentBuilder::ChildList* line_box,
+ NGLogicalLineItems* line_box,
LayoutUnit position) {
// At this point, children are in the visual order, and they have their
// origins at (0, 0). Accumulate inline offset from left to right.
- for (NGLineBoxFragmentBuilder::Child& child : *line_box) {
+ for (NGLogicalLineItem& child : *line_box) {
child.margin_line_left = child.rect.offset.inline_offset;
child.rect.offset.inline_offset += position;
// Box margins/boders/paddings will be processed later.
@@ -560,7 +542,7 @@ LayoutUnit NGInlineLayoutStateStack::ComputeInlinePositions(
// border/padding of this box and margin/border/padding of descendants
// boxes, while accumulating its margin/border/padding.
unsigned start = box_data.fragment_start;
- NGLineBoxFragmentBuilder::Child& start_child = (*line_box)[start];
+ NGLogicalLineItem& start_child = (*line_box)[start];
LayoutUnit line_left_offset =
start_child.rect.offset.inline_offset - start_child.margin_line_left;
LinePadding& start_padding = accumulated_padding[start];
@@ -569,7 +551,7 @@ LayoutUnit NGInlineLayoutStateStack::ComputeInlinePositions(
DCHECK_GT(box_data.fragment_end, start);
unsigned last = box_data.fragment_end - 1;
- NGLineBoxFragmentBuilder::Child& last_child = (*line_box)[last];
+ NGLogicalLineItem& last_child = (*line_box)[last];
LayoutUnit line_right_offset = last_child.rect.offset.inline_offset -
last_child.margin_line_left +
last_child.inline_size;
@@ -585,36 +567,19 @@ LayoutUnit NGInlineLayoutStateStack::ComputeInlinePositions(
}
void NGInlineLayoutStateStack::CreateBoxFragments(
- NGLineBoxFragmentBuilder::ChildList* line_box) {
+ NGLogicalLineItems* line_box) {
DCHECK(!box_data_list_.IsEmpty());
for (BoxData& box_data : box_data_list_) {
unsigned start = box_data.fragment_start;
unsigned end = box_data.fragment_end;
DCHECK_GT(end, start);
- NGLineBoxFragmentBuilder::Child* child = &(*line_box)[start];
- if (box_data.item->ShouldCreateBoxFragment()) {
- scoped_refptr<const NGLayoutResult> box_fragment =
- box_data.CreateBoxFragment(line_box);
- if (child->IsPlaceholder()) {
- child->layout_result = std::move(box_fragment);
- child->rect = box_data.rect;
- child->children_count = end - start;
- continue;
- }
-
- // |AddBoxFragmentPlaceholder| adds a placeholder at |fragment_start|, but
- // bidi reordering may move it. Insert in such case.
- line_box->InsertChild(start, std::move(box_fragment), box_data.rect,
- end - start + 1);
- ChildInserted(start + 1);
- continue;
- }
-
- DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
- DCHECK(box_data.item);
+ NGLogicalLineItem* child = &(*line_box)[start];
+ DCHECK(box_data.item->ShouldCreateBoxFragment());
+ scoped_refptr<const NGLayoutResult> box_fragment =
+ box_data.CreateBoxFragment(line_box);
if (child->IsPlaceholder()) {
- child->inline_item = box_data.item;
+ child->layout_result = std::move(box_fragment);
child->rect = box_data.rect;
child->children_count = end - start;
continue;
@@ -622,7 +587,7 @@ void NGInlineLayoutStateStack::CreateBoxFragments(
// |AddBoxFragmentPlaceholder| adds a placeholder at |fragment_start|, but
// bidi reordering may move it. Insert in such case.
- line_box->InsertChild(start, *box_data.item, box_data.rect,
+ line_box->InsertChild(start, std::move(box_fragment), box_data.rect,
end - start + 1);
ChildInserted(start + 1);
}
@@ -632,7 +597,7 @@ void NGInlineLayoutStateStack::CreateBoxFragments(
scoped_refptr<const NGLayoutResult>
NGInlineLayoutStateStack::BoxData::CreateBoxFragment(
- NGLineBoxFragmentBuilder::ChildList* line_box) {
+ NGLogicalLineItems* line_box) {
DCHECK(item);
DCHECK(item->Style());
const ComputedStyle& style = *item->Style();
@@ -646,7 +611,7 @@ NGInlineLayoutStateStack::BoxData::CreateBoxFragment(
// Because children are already in the visual order, use LTR for the
// fragment builder so that it should not transform the coordinates for RTL.
NGBoxFragmentBuilder box(item->GetLayoutObject(), &style,
- style.GetWritingMode(), TextDirection::kLtr);
+ {style.GetWritingMode(), TextDirection::kLtr});
box.SetInitialFragmentGeometry(fragment_geometry);
box.SetBoxType(NGPhysicalFragment::kInlineBox);
box.SetStyleVariant(item->StyleVariant());
@@ -657,7 +622,13 @@ NGInlineLayoutStateStack::BoxData::CreateBoxFragment(
box.SetBorderEdges({true, has_line_right_edge, true, has_line_left_edge});
for (unsigned i = fragment_start; i < fragment_end; i++) {
- NGLineBoxFragmentBuilder::Child& child = (*line_box)[i];
+ NGLogicalLineItem& child = (*line_box)[i];
+
+ // If |child| has a fragment created by previous |CreateBoxFragment|, skip
+ // children that were already added to |child|.
+ if (child.children_count)
+ i += child.children_count - 1;
+
if (child.out_of_flow_positioned_box) {
DCHECK(item->GetLayoutObject()->IsLayoutInline());
NGBlockNode oof_box(ToLayoutBox(child.out_of_flow_positioned_box));
@@ -705,10 +676,9 @@ NGInlineLayoutStateStack::BoxData::CreateBoxFragment(
}
NGInlineLayoutStateStack::PositionPending
-NGInlineLayoutStateStack::ApplyBaselineShift(
- NGInlineBoxState* box,
- NGLineBoxFragmentBuilder::ChildList* line_box,
- FontBaseline baseline_type) {
+NGInlineLayoutStateStack::ApplyBaselineShift(NGInlineBoxState* box,
+ NGLogicalLineItems* line_box,
+ FontBaseline baseline_type) {
// Some 'vertical-align' values require the size of their parents. Align all
// such descendant boxes that require the size of this box; they are queued in
// |pending_descendants|.
@@ -852,7 +822,7 @@ NGInlineLayoutStateStack::ApplyBaselineShift(
NGLineHeightMetrics NGInlineLayoutStateStack::MetricsForTopAndBottomAlign(
const NGInlineBoxState& box,
- const NGLineBoxFragmentBuilder::ChildList& line_box) const {
+ const NGLogicalLineItems& line_box) const {
DCHECK(!box.pending_descendants.IsEmpty());
// |metrics| is the bounds of "aligned subtree", that is, bounds of
@@ -871,8 +841,7 @@ NGLineHeightMetrics NGInlineLayoutStateStack::MetricsForTopAndBottomAlign(
continue;
// |block_offset| is the top position when the baseline is at 0.
- const NGLineBoxFragmentBuilder::Child& placeholder =
- line_box[box_data.fragment_start];
+ const NGLogicalLineItem& placeholder = line_box[box_data.fragment_start];
DCHECK(placeholder.IsPlaceholder());
LayoutUnit box_ascent = -placeholder.rect.offset.block_offset;
NGLineHeightMetrics box_metrics(box_ascent,
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
index 6dcee9c380a..6f58b80073a 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
@@ -16,8 +16,9 @@
namespace blink {
class NGInlineItem;
-struct NGInlineItemResult;
+class NGLogicalLineItems;
class ShapeResultView;
+struct NGInlineItemResult;
// Fragments that require the layout position/size of ancestor are packed in
// this struct.
@@ -114,31 +115,30 @@ class CORE_EXPORT NGInlineLayoutStateStack {
// Initialize the box state stack for a new line.
// @return The initial box state for the line.
- NGInlineBoxState* OnBeginPlaceItems(
- const ComputedStyle&,
- FontBaseline,
- bool line_height_quirk,
- NGLineBoxFragmentBuilder::ChildList* line_box);
+ NGInlineBoxState* OnBeginPlaceItems(const ComputedStyle&,
+ FontBaseline,
+ bool line_height_quirk,
+ NGLogicalLineItems* line_box);
// Push a box state stack.
NGInlineBoxState* OnOpenTag(const NGInlineItem&,
const NGInlineItemResult&,
FontBaseline baseline_type,
- const NGLineBoxFragmentBuilder::ChildList&);
+ const NGLogicalLineItems&);
// This variation adds a box placeholder to |line_box|.
NGInlineBoxState* OnOpenTag(const NGInlineItem&,
const NGInlineItemResult&,
FontBaseline baseline_type,
- NGLineBoxFragmentBuilder::ChildList* line_box);
+ NGLogicalLineItems* line_box);
// Pop a box state stack.
- NGInlineBoxState* OnCloseTag(NGLineBoxFragmentBuilder::ChildList*,
+ NGInlineBoxState* OnCloseTag(NGLogicalLineItems*,
NGInlineBoxState*,
FontBaseline,
bool has_end_edge = true);
// Compute all the pending positioning at the end of a line.
- void OnEndPlaceItems(NGLineBoxFragmentBuilder::ChildList*, FontBaseline);
+ void OnEndPlaceItems(NGLogicalLineItems*, FontBaseline);
bool HasBoxFragments() const { return !box_data_list_.IsEmpty(); }
@@ -148,12 +148,12 @@ class CORE_EXPORT NGInlineLayoutStateStack {
// This class keeps indexes to fragments in the line box, and that only
// appending is allowed. Call this function to move all such data to the line
// box, so that outside of this class can reorder fragments in the line box.
- void PrepareForReorder(NGLineBoxFragmentBuilder::ChildList*);
+ void PrepareForReorder(NGLogicalLineItems*);
// When reordering was complete, call this function to re-construct the box
// data from the line box. Callers must call |PrepareForReorder()| before
// reordering.
- void UpdateAfterReorder(NGLineBoxFragmentBuilder::ChildList*);
+ void UpdateAfterReorder(NGLogicalLineItems*);
// Update start/end of the first BoxData found at |index|.
//
@@ -161,19 +161,17 @@ class CORE_EXPORT NGInlineLayoutStateStack {
//
// Returns the index to process next. It should be given to the next call to
// this function.
- unsigned UpdateBoxDataFragmentRange(NGLineBoxFragmentBuilder::ChildList*,
- unsigned index);
+ unsigned UpdateBoxDataFragmentRange(NGLogicalLineItems*, unsigned index);
// Update edges of inline fragmented boxes.
void UpdateFragmentedBoxDataEdges();
// Compute inline positions of fragments and boxes.
- LayoutUnit ComputeInlinePositions(NGLineBoxFragmentBuilder::ChildList*,
- LayoutUnit position);
+ LayoutUnit ComputeInlinePositions(NGLogicalLineItems*, LayoutUnit position);
// Create box fragments. This function turns a flat list of children into
// a box tree.
- void CreateBoxFragments(NGLineBoxFragmentBuilder::ChildList*);
+ void CreateBoxFragments(NGLogicalLineItems*);
#if DCHECK_IS_ON()
void CheckSame(const NGInlineLayoutStateStack&) const;
@@ -182,14 +180,12 @@ class CORE_EXPORT NGInlineLayoutStateStack {
private:
// End of a box state, either explicitly by close tag, or implicitly at the
// end of a line.
- void EndBoxState(NGInlineBoxState*,
- NGLineBoxFragmentBuilder::ChildList*,
- FontBaseline);
+ void EndBoxState(NGInlineBoxState*, NGLogicalLineItems*, FontBaseline);
void AddBoxFragmentPlaceholder(NGInlineBoxState*,
- NGLineBoxFragmentBuilder::ChildList*,
+ NGLogicalLineItems*,
FontBaseline);
- void AddBoxData(NGInlineBoxState*, NGLineBoxFragmentBuilder::ChildList*);
+ void AddBoxData(NGInlineBoxState*, NGLogicalLineItems*);
enum PositionPending { kPositionNotPending, kPositionPending };
@@ -200,14 +196,14 @@ class CORE_EXPORT NGInlineLayoutStateStack {
// https://www.w3.org/TR/CSS22/visudet.html#propdef-vertical-align
// https://www.w3.org/TR/css-inline-3/#propdef-vertical-align
PositionPending ApplyBaselineShift(NGInlineBoxState*,
- NGLineBoxFragmentBuilder::ChildList*,
+ NGLogicalLineItems*,
FontBaseline);
// Compute the metrics for when 'vertical-align' is 'top' and 'bottom' from
// |pending_descendants|.
NGLineHeightMetrics MetricsForTopAndBottomAlign(
const NGInlineBoxState&,
- const NGLineBoxFragmentBuilder::ChildList&) const;
+ const NGLogicalLineItems&) const;
// Data for a box fragment. See AddBoxFragmentPlaceholder().
// This is a transient object only while building a line box.
@@ -253,8 +249,7 @@ class CORE_EXPORT NGInlineLayoutStateStack {
void UpdateFragmentEdges(Vector<BoxData, 4>& list);
- scoped_refptr<const NGLayoutResult> CreateBoxFragment(
- NGLineBoxFragmentBuilder::ChildList*);
+ scoped_refptr<const NGLayoutResult> CreateBoxFragment(NGLogicalLineItems*);
};
Vector<NGInlineBoxState, 4> stack_;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.cc
index 888119d970d..0f4293fd07c 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.cc
@@ -9,6 +9,7 @@ namespace blink {
namespace {
struct SameSizeAsNGInlineChildLayoutContext {
+ NGLogicalLineItems line_items_;
base::Optional<NGInlineLayoutStateStack> box_states_;
void* pointers[2];
unsigned number;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h
index 360714b2902..09210c5894f 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h"
namespace blink {
@@ -27,6 +28,10 @@ class NGInlineChildLayoutContext {
items_builder_ = builder;
}
+ // Returns an instance of |NGLogicalLineItems|. This is reused when laying out
+ // the next line.
+ NGLogicalLineItems* LogicalLineItems() { return &logical_line_items_; }
+
// Returns the NGInlineLayoutStateStack in this context.
bool HasBoxStates() const { return box_states_.has_value(); }
NGInlineLayoutStateStack* BoxStates() { return &*box_states_; }
@@ -50,6 +55,8 @@ class NGInlineChildLayoutContext {
// transit, allocating separately is easier.
NGFragmentItemsBuilder* items_builder_ = nullptr;
+ NGLogicalLineItems logical_line_items_;
+
base::Optional<NGInlineLayoutStateStack> box_states_;
// The items and its index this context is set up for.
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
index 88473e916fd..1da02bfd534 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
#include "third_party/blink/renderer/core/editing/position_with_affinity.h"
+#include "third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/layout_text.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h"
@@ -18,8 +19,11 @@ namespace blink {
inline void NGInlineCursor::MoveToItem(const ItemsSpan::iterator& iter) {
DCHECK(IsItemCursor());
DCHECK(iter >= items_.begin() && iter <= items_.end());
- current_.item_iter_ = iter;
- current_.item_ = iter == items_.end() ? nullptr : iter->get();
+ if (iter != items_.end()) {
+ current_.Set(iter);
+ return;
+ }
+ MakeNull();
}
void NGInlineCursor::SetRoot(const NGFragmentItems& fragment_items,
@@ -117,7 +121,7 @@ const LayoutBlockFlow* NGInlineCursor::GetLayoutBlockFlow() const {
return layout_object->RootInlineFormattingContext();
}
if (IsItemCursor()) {
- const NGFragmentItem& item = *fragment_items_->Items().front();
+ const NGFragmentItem& item = fragment_items_->front();
const LayoutObject* layout_object = item.GetLayoutObject();
if (item.Type() == NGFragmentItem::kLine)
return To<LayoutBlockFlow>(layout_object);
@@ -454,11 +458,18 @@ const DisplayItemClient* NGInlineCursorPosition::GetDisplayItemClient() const {
if (paint_fragment_)
return paint_fragment_;
if (item_)
- return item_;
+ return item_->GetDisplayItemClient();
NOTREACHED();
return nullptr;
}
+wtf_size_t NGInlineCursorPosition::FragmentId() const {
+ if (paint_fragment_)
+ return 0;
+ DCHECK(item_);
+ return item_->FragmentId();
+}
+
const NGInlineBreakToken* NGInlineCursorPosition::InlineBreakToken() const {
DCHECK(IsLineBox());
if (paint_fragment_) {
@@ -652,6 +663,20 @@ PhysicalOffset NGInlineCursorPosition::LineEndPoint() const {
pixel_size);
}
+LogicalRect NGInlineCursorPosition::ConvertChildToLogical(
+ const PhysicalRect& physical_rect) const {
+ return WritingModeConverter(
+ {Style().GetWritingMode(), ResolvedOrBaseDirection()}, Size())
+ .ToLogical(physical_rect);
+}
+
+PhysicalRect NGInlineCursorPosition::ConvertChildToPhysical(
+ const LogicalRect& logical_rect) const {
+ return WritingModeConverter(
+ {Style().GetWritingMode(), ResolvedOrBaseDirection()}, Size())
+ .ToPhysical(logical_rect);
+}
+
PositionWithAffinity NGInlineCursor::PositionForPointInInlineFormattingContext(
const PhysicalOffset& point,
const NGPhysicalBoxFragment& container) {
@@ -667,20 +692,26 @@ PositionWithAffinity NGInlineCursor::PositionForPointInInlineFormattingContext(
PhysicalSize(LayoutUnit(1), LayoutUnit(1)))
.block_offset;
- // Stores the closest line box child above |point| in the block direction.
+ // Stores the closest line box child after |point| in the block direction.
// Used if we can't find any child |point| falls in to resolve the position.
- NGInlineCursorPosition closest_line_before;
- LayoutUnit closest_line_before_block_offset = LayoutUnit::Min();
+ NGInlineCursorPosition closest_line_after;
+ LayoutUnit closest_line_after_block_offset = LayoutUnit::Min();
- // Stores the closest line box child below |point| in the block direction.
+ // Stores the closest line box child before |point| in the block direction.
// Used if we can't find any child |point| falls in to resolve the position.
- NGInlineCursorPosition closest_line_after;
- LayoutUnit closest_line_after_block_offset = LayoutUnit::Max();
+ NGInlineCursorPosition closest_line_before;
+ LayoutUnit closest_line_before_block_offset = LayoutUnit::Max();
while (*this) {
const NGFragmentItem* child_item = CurrentItem();
DCHECK(child_item);
if (child_item->Type() == NGFragmentItem::kLine) {
+ if (!CursorForDescendants().TryToMoveToFirstInlineLeafChild()) {
+ // editing/selection/last-empty-inline.html requires this to skip
+ // empty <span> with padding.
+ MoveToNextItemSkippingChildren();
+ continue;
+ }
// Try to resolve if |point| falls in a line box in block direction.
const LayoutUnit child_block_offset =
child_item->OffsetInContainerBlock()
@@ -688,9 +719,9 @@ PositionWithAffinity NGInlineCursor::PositionForPointInInlineFormattingContext(
child_item->Size())
.block_offset;
if (point_block_offset < child_block_offset) {
- if (child_block_offset < closest_line_after_block_offset) {
- closest_line_after_block_offset = child_block_offset;
- closest_line_after = Current();
+ if (child_block_offset < closest_line_before_block_offset) {
+ closest_line_before_block_offset = child_block_offset;
+ closest_line_before = Current();
}
MoveToNextItemSkippingChildren();
continue;
@@ -701,9 +732,9 @@ PositionWithAffinity NGInlineCursor::PositionForPointInInlineFormattingContext(
child_block_offset +
child_item->Size().ConvertToLogical(writing_mode).block_size;
if (point_block_offset >= child_block_end_offset) {
- if (child_block_end_offset > closest_line_before_block_offset) {
- closest_line_before_block_offset = child_block_end_offset;
- closest_line_before = Current();
+ if (child_block_end_offset > closest_line_after_block_offset) {
+ closest_line_after_block_offset = child_block_end_offset;
+ closest_line_after = Current();
}
MoveToNextItemSkippingChildren();
continue;
@@ -719,18 +750,47 @@ PositionWithAffinity NGInlineCursor::PositionForPointInInlineFormattingContext(
MoveToNextItem();
}
- if (closest_line_after) {
- MoveTo(closest_line_after);
- if (const PositionWithAffinity child_position =
- PositionForPointInInlineBox(point))
+ // At here, |point| is not inside any line in |this|:
+ // |closest_line_before|
+ // |point|
+ // |closest_line_after|
+ if (closest_line_before) {
+ MoveTo(closest_line_before);
+ // Note: |move_caret_to_boundary| is true for Mac and Unix.
+ const bool move_caret_to_boundary =
+ To<LayoutBlockFlow>(Current().GetLayoutObject())
+ ->ShouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
+ if (move_caret_to_boundary) {
+ // Tests[1-3] reach here.
+ // [1] editing/selection/click-in-margins-inside-editable-div.html
+ // [2] fast/writing-mode/flipped-blocks-hit-test-line-edges.html
+ // [3] All/LayoutViewHitTestTest.HitTestHorizontal/4
+ if (auto first_position = PositionForStartOfLine())
+ return PositionWithAffinity(first_position.GetPosition());
+ } else if (const PositionWithAffinity child_position =
+ PositionForPointInInlineBox(point))
return child_position;
}
- if (closest_line_before) {
- MoveTo(closest_line_before);
- if (const PositionWithAffinity child_position =
- PositionForPointInInlineBox(point))
+ if (closest_line_after) {
+ MoveTo(closest_line_after);
+ // Note: |move_caret_to_boundary| is true for Mac and Unix.
+ const bool move_caret_to_boundary =
+ To<LayoutBlockFlow>(Current().GetLayoutObject())
+ ->ShouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
+ if (move_caret_to_boundary) {
+ // Tests[1-3] reach here.
+ // [1] editing/selection/click-in-margins-inside-editable-div.html
+ // [2] fast/writing-mode/flipped-blocks-hit-test-line-edges.html
+ // [3] All/LayoutViewHitTestTest.HitTestHorizontal/4
+ if (auto last_position = PositionForEndOfLine())
+ return PositionWithAffinity(last_position.GetPosition());
+ } else if (const PositionWithAffinity child_position =
+ PositionForPointInInlineBox(point)) {
+ // Test[1] reaches here.
+ // [1] editing/selection/last-empty-inline.html
return child_position;
+ }
}
return PositionWithAffinity();
@@ -802,14 +862,14 @@ PositionWithAffinity NGInlineCursor::PositionForPointInInlineBox(
}
if (const PositionWithAffinity child_position =
- descendants.PositionForPointInChild(point, *child_item))
+ descendants.PositionForPointInChild(point))
return child_position;
}
if (closest_child_after) {
descendants.MoveTo(closest_child_after);
if (const PositionWithAffinity child_position =
- descendants.PositionForPointInChild(point, *closest_child_after))
+ descendants.PositionForPointInChild(point))
return child_position;
// TODO(yosin): we should do like "closest_child_before" once we have a
// case.
@@ -818,7 +878,7 @@ PositionWithAffinity NGInlineCursor::PositionForPointInInlineBox(
if (closest_child_before) {
descendants.MoveTo(closest_child_before);
if (const PositionWithAffinity child_position =
- descendants.PositionForPointInChild(point, *closest_child_before))
+ descendants.PositionForPointInChild(point))
return child_position;
if (closest_child_before->BoxFragment()) {
// LayoutViewHitTest.HitTestHorizontal "Top-right corner (outside) of div"
@@ -827,36 +887,22 @@ PositionWithAffinity NGInlineCursor::PositionForPointInInlineBox(
}
}
- if (container->Type() == NGFragmentItem::kLine) {
- // There are no inline items to hit in this line box, e.g. <span> with
- // size and border. We try in lines before |this| line in the block.
- // See editing/selection/last-empty-inline.html
- NGInlineCursor cursor;
- cursor.MoveTo(*this);
- const PhysicalOffset point_in_line =
- point - Current().OffsetInContainerBlock();
- for (;;) {
- cursor.MoveToPreviousLine();
- if (!cursor)
- break;
- const PhysicalOffset adjusted_point =
- point_in_line + cursor.Current().OffsetInContainerBlock();
- if (auto position = cursor.PositionForPointInInlineBox(adjusted_point))
- return position;
- }
- }
-
return PositionWithAffinity();
}
PositionWithAffinity NGInlineCursor::PositionForPointInChild(
- const PhysicalOffset& point,
- const NGFragmentItem& child_item) const {
- DCHECK_EQ(&child_item, CurrentItem());
+ const PhysicalOffset& point_in_container) const {
+ if (auto* paint_fragment = CurrentPaintFragment()) {
+ const PhysicalOffset point_in_child =
+ point_in_container - paint_fragment->OffsetInContainerBlock();
+ return paint_fragment->PositionForPoint(point_in_child);
+ }
+ DCHECK(CurrentItem());
+ const NGFragmentItem& child_item = *CurrentItem();
switch (child_item.Type()) {
case NGFragmentItem::kText:
return child_item.PositionForPointInText(
- point - child_item.OffsetInContainerBlock(), *this);
+ point_in_container - child_item.OffsetInContainerBlock(), *this);
case NGFragmentItem::kGeneratedText:
break;
case NGFragmentItem::kBox:
@@ -867,9 +913,9 @@ PositionWithAffinity NGInlineCursor::PositionForPointInChild(
// can utilize LayoutBlock::PositionForPoint() that resolves the
// position in block layout.
// TODO(xiaochengh): Don't fallback to legacy for NG block layout.
- if (box_fragment->IsBlockFlow() || box_fragment->IsLegacyLayoutRoot()) {
+ if (!box_fragment->IsInlineBox()) {
return child_item.GetLayoutObject()->PositionForPoint(
- point - child_item.OffsetInContainerBlock());
+ point_in_container - child_item.OffsetInContainerBlock());
}
} else {
// |LayoutInline| used to be culled.
@@ -883,6 +929,26 @@ PositionWithAffinity NGInlineCursor::PositionForPointInChild(
return PositionWithAffinity();
}
+PositionWithAffinity NGInlineCursor::PositionForStartOfLine() const {
+ DCHECK(Current().IsLineBox());
+ const PhysicalOffset point_in_line = Current().LineStartPoint();
+ if (IsItemCursor()) {
+ return PositionForPointInInlineBox(point_in_line +
+ Current().OffsetInContainerBlock());
+ }
+ return CurrentPaintFragment()->PositionForPoint(point_in_line);
+}
+
+PositionWithAffinity NGInlineCursor::PositionForEndOfLine() const {
+ DCHECK(Current().IsLineBox());
+ const PhysicalOffset point_in_line = Current().LineEndPoint();
+ if (IsItemCursor()) {
+ return PositionForPointInInlineBox(point_in_line +
+ Current().OffsetInContainerBlock());
+ }
+ return CurrentPaintFragment()->PositionForPoint(point_in_line);
+}
+
void NGInlineCursor::MoveTo(const NGInlineCursorPosition& position) {
CheckValid(position);
current_ = position;
@@ -913,7 +979,7 @@ NGInlineCursor::ItemsSpan::iterator NGInlineCursor::SlowFirstItemIteratorFor(
const LayoutObject& layout_object,
const ItemsSpan& items) {
for (ItemsSpan::iterator iter = items.begin(); iter != items.end(); ++iter) {
- if ((*iter)->GetLayoutObject() == &layout_object)
+ if (iter->GetLayoutObject() == &layout_object)
return iter;
}
return items.end();
@@ -992,7 +1058,7 @@ bool NGInlineCursor::IsAtFirst() const {
if (const NGPaintFragment* paint_fragment = Current().PaintFragment())
return paint_fragment == root_paint_fragment_->FirstChild();
if (const NGFragmentItem* item = Current().Item())
- return item == items_.front().get();
+ return item == &items_.front();
return false;
}
@@ -1022,7 +1088,7 @@ void NGInlineCursor::MoveToFirstLine() {
if (IsItemCursor()) {
auto iter = std::find_if(
items_.begin(), items_.end(),
- [](const auto& item) { return item->Type() == NGFragmentItem::kLine; });
+ [](const auto& item) { return item.Type() == NGFragmentItem::kLine; });
if (iter != items_.end()) {
MoveToItem(iter);
return;
@@ -1058,7 +1124,7 @@ void NGInlineCursor::MoveToLastLine() {
DCHECK(IsItemCursor());
auto iter = std::find_if(
items_.rbegin(), items_.rend(),
- [](const auto& item) { return item->Type() == NGFragmentItem::kLine; });
+ [](const auto& item) { return item.Type() == NGFragmentItem::kLine; });
if (iter != items_.rend())
MoveToItem(std::next(iter).base());
else
@@ -1198,6 +1264,15 @@ bool NGInlineCursor::TryToMoveToFirstChild() {
return true;
}
+bool NGInlineCursor::TryToMoveToFirstInlineLeafChild() {
+ while (IsNotNull()) {
+ if (Current().IsInlineLeaf())
+ return true;
+ MoveToNext();
+ }
+ return false;
+}
+
bool NGInlineCursor::TryToMoveToLastChild() {
if (!Current().HasChildren())
return false;
@@ -1226,7 +1301,7 @@ void NGInlineCursor::MoveToNextItem() {
return;
DCHECK(current_.item_iter_ != items_.end());
if (++current_.item_iter_ != items_.end()) {
- current_.item_ = current_.item_iter_->get();
+ current_.item_ = &*current_.item_iter_;
return;
}
MakeNull();
@@ -1250,7 +1325,7 @@ void NGInlineCursor::MoveToPreviousItem() {
if (current_.item_iter_ == items_.begin())
return MakeNull();
--current_.item_iter_;
- current_.item_ = current_.item_iter_->get();
+ current_.item_ = &*current_.item_iter_;
}
void NGInlineCursor::MoveToParentPaintFragment() {
@@ -1318,46 +1393,79 @@ void NGInlineCursor::MoveToPreviousSiblingPaintFragment() {
void NGInlineCursor::MoveTo(const LayoutObject& layout_object) {
DCHECK(layout_object.IsInLayoutNGInlineFormattingContext());
- DCHECK(!layout_object.IsFloatingOrOutOfFlowPositioned());
- // If this cursor is rootless, find the root of the inline formatting context.
- bool had_root = true;
- if (!HasRoot()) {
- had_root = false;
- const LayoutBlockFlow& root = *layout_object.RootInlineFormattingContext();
- DCHECK(&root);
- SetRoot(root);
+ DCHECK(!layout_object.IsOutOfFlowPositioned());
+
+ if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ // If this cursor is rootless, find the root of the inline formatting
+ // context.
if (!HasRoot()) {
- if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
- MakeNull();
+ const LayoutBlockFlow& root =
+ *layout_object.RootInlineFormattingContext();
+ DCHECK(&root);
+ SetRoot(root);
+ if (!HasRoot()) {
+ const auto fragments =
+ NGPaintFragment::InlineFragmentsFor(&layout_object);
+ if (!fragments.IsInLayoutNGInlineFormattingContext() ||
+ fragments.IsEmpty())
+ return MakeNull();
+ // external/wpt/css/css-scroll-anchoring/text-anchor-in-vertical-rl.html
+ // reaches here.
+ root_paint_fragment_ = fragments.front().Root();
+ }
+ DCHECK(HasRoot());
+ }
+
+ const auto fragments = NGPaintFragment::InlineFragmentsFor(&layout_object);
+ if (!fragments.IsEmpty()) {
+ // If |this| is IFC root, just move to the first fragment.
+ if (!root_paint_fragment_->Parent()) {
+ DCHECK(fragments.front().IsDescendantOfNotSelf(*root_paint_fragment_));
+ MoveTo(fragments.front());
return;
}
- const auto fragments =
- NGPaintFragment::InlineFragmentsFor(&layout_object);
- if (!fragments.IsInLayoutNGInlineFormattingContext() ||
- fragments.IsEmpty())
- return MakeNull();
- // external/wpt/css/css-scroll-anchoring/text-anchor-in-vertical-rl.html
- // reaches here.
- root_paint_fragment_ = fragments.front().Root();
+ // If |this| is limited, find the first fragment in the range.
+ for (const auto* fragment : fragments) {
+ if (fragment->IsDescendantOfNotSelf(*root_paint_fragment_)) {
+ MoveTo(*fragment);
+ return;
+ }
+ }
}
+ return MakeNull();
}
- if (fragment_items_) {
- wtf_size_t item_index = layout_object.FirstInlineFragmentItemIndex();
- if (!item_index) {
- DCHECK_EQ(SlowFirstItemIndexFor(layout_object, fragment_items_->Items()),
- fragment_items_->Size());
+
+ // If this cursor is rootless, find the root of the inline formatting context.
+ if (!HasRoot()) {
+ const LayoutBlockFlow* root = layout_object.RootInlineFormattingContext();
+ DCHECK(root);
+ const NGFragmentItems* fragment_items = root->FragmentItems();
+ if (UNLIKELY(!fragment_items)) {
MakeNull();
return;
}
- // |FirstInlineFragmentItemIndex| is 1-based. Convert to 0-based index.
- --item_index;
+ SetRoot(*fragment_items);
+ DCHECK(HasRoot());
+ }
+
+ wtf_size_t item_index = layout_object.FirstInlineFragmentItemIndex();
+ if (UNLIKELY(!item_index)) {
DCHECK_EQ(SlowFirstItemIndexFor(layout_object, fragment_items_->Items()),
- item_index);
+ fragment_items_->Size());
+ MakeNull();
+ return;
+ }
+
+ // |FirstInlineFragmentItemIndex| is 1-based. Convert to 0-based index.
+ --item_index;
+ DCHECK_EQ(SlowFirstItemIndexFor(layout_object, fragment_items_->Items()),
+ item_index);
- // Skip items before |items_|, in case |this| is part of IFC.
+ // Skip items before |items_|, in case |this| is part of IFC.
+ if (UNLIKELY(!fragment_items_->Equals(items_))) {
const wtf_size_t span_begin_item_index = SpanBeginItemIndex();
- while (item_index < span_begin_item_index) {
- const NGFragmentItem& item = *fragment_items_->Items()[item_index];
+ while (UNLIKELY(item_index < span_begin_item_index)) {
+ const NGFragmentItem& item = fragment_items_->Items()[item_index];
const wtf_size_t next_delta = item.DeltaToNextForSameLayoutObject();
if (!next_delta) {
MakeNull();
@@ -1365,21 +1473,15 @@ void NGInlineCursor::MoveTo(const LayoutObject& layout_object) {
}
item_index += next_delta;
}
- if (item_index >= span_begin_item_index + items_.size()) {
+ if (UNLIKELY(item_index >= span_begin_item_index + items_.size())) {
MakeNull();
return;
}
-
- const wtf_size_t span_index = item_index - span_begin_item_index;
- DCHECK_LT(span_index, items_.size());
- return MoveToItem(items_.begin() + span_index);
- }
- if (root_paint_fragment_) {
- const auto fragments = NGPaintFragment::InlineFragmentsFor(&layout_object);
- if (!fragments.IsInLayoutNGInlineFormattingContext() || fragments.IsEmpty())
- return MakeNull();
- return MoveTo(fragments.front());
+ item_index -= span_begin_item_index;
}
+
+ DCHECK_LT(item_index, items_.size());
+ current_.Set(items_.begin() + item_index);
}
void NGInlineCursor::MoveToIncludingCulledInline(
@@ -1412,18 +1514,34 @@ void NGInlineCursor::MoveToNextForSameLayoutObject() {
if (current_.paint_fragment_) {
if (auto* paint_fragment =
current_.paint_fragment_->NextForSameLayoutObject()) {
- // |paint_fragment| can be in another fragment tree rooted by
- // |root_paint_fragment_|, e.g. "multicol-span-all-restyle-002.html"
- root_paint_fragment_ = paint_fragment->Root();
- return MoveTo(*paint_fragment);
+ if (!root_paint_fragment_->Parent()) {
+ // |paint_fragment| can be in another fragment tree rooted by
+ // |root_paint_fragment_|, e.g. "multicol-span-all-restyle-002.html"
+ root_paint_fragment_ = paint_fragment->Root();
+ MoveTo(*paint_fragment);
+ return;
+ }
+ // If |this| is limited, make sure the result is in the range.
+ if (paint_fragment->IsDescendantOfNotSelf(*root_paint_fragment_)) {
+ MoveTo(*paint_fragment);
+ return;
+ }
}
return MakeNull();
}
if (current_.item_) {
const wtf_size_t delta = current_.item_->DeltaToNextForSameLayoutObject();
- if (delta == 0u)
- return MakeNull();
- return MoveToItem(current_.item_iter_ + delta);
+ if (delta) {
+ // Check the next item is in |items_| because |delta| can be beyond
+ // |end()| if |this| is limited.
+ const wtf_size_t delta_to_end = items_.end() - current_.item_iter_;
+ if (delta < delta_to_end) {
+ MoveToItem(current_.item_iter_ + delta);
+ return;
+ }
+ DCHECK(!fragment_items_->Equals(items_));
+ }
+ MakeNull();
}
}
@@ -1458,10 +1576,8 @@ NGInlineBackwardCursor::NGInlineBackwardCursor(const NGInlineCursor& cursor)
sibling.MoveToNextSkippingChildren())
sibling_item_iterators_.push_back(sibling.Current().item_iter_);
current_index_ = sibling_item_iterators_.size();
- if (current_index_) {
- current_.item_iter_ = sibling_item_iterators_[--current_index_];
- current_.item_ = current_.item_iter_->get();
- }
+ if (current_index_)
+ current_.Set(sibling_item_iterators_[--current_index_]);
return;
}
DCHECK(!cursor);
@@ -1486,8 +1602,7 @@ void NGInlineBackwardCursor::MoveToPreviousSibling() {
return;
}
if (current_.item_) {
- current_.item_iter_ = sibling_item_iterators_[--current_index_];
- current_.item_ = current_.item_iter_->get();
+ current_.Set(sibling_item_iterators_[--current_index_]);
return;
}
NOTREACHED();
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h
index 6e2b0d842c2..7bd011eb716 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h
@@ -10,6 +10,7 @@
#include "base/containers/span.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/editing/forward.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_text_offset.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -43,7 +44,7 @@ struct PhysicalSize;
// is faster than moving to |NGFragmentItem|.
class CORE_EXPORT NGInlineCursorPosition {
public:
- using ItemsSpan = base::span<const scoped_refptr<const NGFragmentItem>>;
+ using ItemsSpan = NGFragmentItems::Span;
const NGPaintFragment* PaintFragment() const { return paint_fragment_; }
const NGFragmentItem* Item() const { return item_; }
@@ -109,6 +110,7 @@ class CORE_EXPORT NGInlineCursorPosition {
LayoutObject* GetMutableLayoutObject() const;
const Node* GetNode() const;
const DisplayItemClient* GetDisplayItemClient() const;
+ wtf_size_t FragmentId() const;
// True if fragment at the current position can have children.
bool CanHaveChildren() const;
@@ -154,6 +156,10 @@ class CORE_EXPORT NGInlineCursorPosition {
// line.
TextDirection BaseDirection() const;
+ TextDirection ResolvedOrBaseDirection() const {
+ return IsLineBox() ? BaseDirection() : ResolvedDirection();
+ }
+
// True if the current position is text or atomic inline box.
// Note: Because of this function is used for caret rect, hit testing, etc,
// this function returns false for hidden for paint, text overflow ellipsis,
@@ -164,12 +170,25 @@ class CORE_EXPORT NGInlineCursorPosition {
// other than line.
bool HasSoftWrapToNextLine() const;
- // Returns a point at the visual start/end of the line.
+ // Returns a point at the visual start/end of the line. (0, 0) is left-top of
+ // the line.
// Encapsulates the handling of text direction and writing mode.
PhysicalOffset LineStartPoint() const;
PhysicalOffset LineEndPoint() const;
+ // LogicalRect/PhysicalRect conversions
+ // |logical_rect| and |physical_rect| are converted with |Size()| as
+ // "outer size".
+ LogicalRect ConvertChildToLogical(const PhysicalRect& physical_rect) const;
+ PhysicalRect ConvertChildToPhysical(const LogicalRect& logical_rect) const;
+
private:
+ void Set(const ItemsSpan::iterator& iter) {
+ DCHECK(!paint_fragment_);
+ item_iter_ = iter;
+ item_ = &*iter;
+ }
+
void Clear() {
paint_fragment_ = nullptr;
item_ = nullptr;
@@ -197,7 +216,7 @@ class CORE_EXPORT NGInlineCursor {
STACK_ALLOCATED();
public:
- using ItemsSpan = base::span<const scoped_refptr<const NGFragmentItem>>;
+ using ItemsSpan = NGFragmentItems::Span;
explicit NGInlineCursor(const LayoutBlockFlow& block_flow);
explicit NGInlineCursor(const NGFragmentItems& items);
@@ -296,6 +315,20 @@ class CORE_EXPORT NGInlineCursor {
PositionWithAffinity PositionForPointInInlineBox(
const PhysicalOffset& point) const;
+ // Returns |PositionWithAffinity| in current position at x-coordinate of
+ // |point_in_container| for horizontal writing mode, or y-coordinate of
+ // |point_in_container| for vertical writing mode.
+ // Note: Even if |point_in_container| is outside of an item of current
+ // position, this function returns boundary position of an item.
+ // Note: This function is used for locating caret at same x/y-coordinate as
+ // previous caret after line up/down.
+ PositionWithAffinity PositionForPointInChild(
+ const PhysicalOffset& point_in_container) const;
+
+ // Returns first/last position of |this| line. |this| should be line box.
+ PositionWithAffinity PositionForStartOfLine() const;
+ PositionWithAffinity PositionForEndOfLine() const;
+
//
// Functions to move the current position.
//
@@ -376,6 +409,9 @@ class CORE_EXPORT NGInlineCursor {
// Returns true if the current position moves to first child.
bool TryToMoveToFirstChild();
+ // Returns true if the current position moves to first inline leaf child.
+ bool TryToMoveToFirstInlineLeafChild();
+
// Returns true if the current position moves to last child.
bool TryToMoveToLastChild();
@@ -434,10 +470,6 @@ class CORE_EXPORT NGInlineCursor {
wtf_size_t SpanBeginItemIndex() const;
wtf_size_t SpanIndexFromItemIndex(unsigned index) const;
- PositionWithAffinity PositionForPointInChild(
- const PhysicalOffset& point,
- const NGFragmentItem& child_item) const;
-
NGInlineCursorPosition current_;
ItemsSpan items_;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor_test.cc
index 580588369e4..896d6a9e60c 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor_test.cc
@@ -628,6 +628,46 @@ TEST_P(NGInlineCursorTest, NextForSameLayoutObject) {
EXPECT_THAT(list, ElementsAre("abc", "", "def", "", "ghi"));
}
+// Test |NextForSameLayoutObject| with limit range set.
+TEST_P(NGInlineCursorTest, NextForSameLayoutObjectWithRange) {
+ // In this snippet, `<span>` wraps to 3 lines, and that there are 3 fragments
+ // for `<span>`.
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ div {
+ font-size: 10px;
+ width: 5ch;
+ }
+ span {
+ background: orange;
+ }
+ </style>
+ <div id="root">
+ <span id="span1">
+ 1111
+ 2222
+ 3333
+ </span>
+ </div>
+ )HTML");
+ LayoutBlockFlow* root =
+ To<LayoutBlockFlow>(GetLayoutObjectByElementId("root"));
+ NGInlineCursor cursor(*root);
+ cursor.MoveToFirstLine();
+ cursor.MoveToNextLine();
+ NGInlineCursor line2 = cursor.CursorForDescendants();
+
+ // Now |line2| is limited to the 2nd line. There should be only one framgnet
+ // for `<span>` if we search using `line2`.
+ LayoutObject* span1 = GetLayoutObjectByElementId("span1");
+ wtf_size_t count = 0;
+ for (line2.MoveTo(*span1); line2; line2.MoveToNextForSameLayoutObject()) {
+ DCHECK_EQ(line2.Current().GetLayoutObject(), span1);
+ ++count;
+ }
+ EXPECT_EQ(count, 1u);
+}
+
TEST_P(NGInlineCursorTest, Sibling) {
// TDOO(yosin): Remove <style> once NGFragmentItem don't do culled inline.
InsertStyleElement("a, b { background: gray; }");
@@ -698,6 +738,152 @@ TEST_P(NGInlineCursorTest, EmptyOutOfFlow) {
EXPECT_THAT(list, ElementsAre());
}
+TEST_P(NGInlineCursorTest, PositionForPointInChildHorizontalLTR) {
+ LoadAhem();
+ InsertStyleElement(
+ "p {"
+ "direction: ltr;"
+ "font: 10px/20px Ahem;"
+ "padding: 10px;"
+ "writing-mode: horizontal-tb;"
+ "}");
+ NGInlineCursor cursor = SetupCursor("<p id=root>ab</p>");
+ const auto& text = *To<Text>(GetElementById("root")->firstChild());
+ ASSERT_TRUE(cursor.Current().IsLineBox());
+ EXPECT_EQ(PhysicalRect(PhysicalOffset(10, 10), PhysicalSize(20, 20)),
+ cursor.Current().RectInContainerBlock());
+
+ cursor.MoveTo(*text.GetLayoutObject());
+ EXPECT_EQ(PhysicalRect(PhysicalOffset(10, 15), PhysicalSize(20, 10)),
+ cursor.Current().RectInContainerBlock());
+ const PhysicalOffset left_top = cursor.Current().OffsetInContainerBlock();
+
+ EXPECT_EQ(PositionWithAffinity(Position(text, 0)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(-5, 0)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 0)),
+ cursor.PositionForPointInChild(left_top));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 0)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(5, 0)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 1)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(10, 0)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 1)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(15, 0)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 2), TextAffinity::kUpstream),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(20, 0)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 2), TextAffinity::kUpstream),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(25, 0)));
+}
+
+TEST_P(NGInlineCursorTest, PositionForPointInChildHorizontalRTL) {
+ LoadAhem();
+ InsertStyleElement(
+ "p {"
+ "direction: rtl;"
+ "font: 10px/20px Ahem;"
+ "padding: 10px;"
+ "writing-mode: horizontal-tb;"
+ "}");
+ NGInlineCursor cursor = SetupCursor("<p id=root><bdo dir=rtl>AB</bdo></p>");
+ const auto& text =
+ *To<Text>(GetElementById("root")->firstChild()->firstChild());
+ ASSERT_TRUE(cursor.Current().IsLineBox());
+ EXPECT_EQ(PhysicalRect(PhysicalOffset(754, 10), PhysicalSize(20, 20)),
+ cursor.Current().RectInContainerBlock());
+
+ cursor.MoveTo(*text.GetLayoutObject());
+ EXPECT_EQ(PhysicalRect(PhysicalOffset(754, 15), PhysicalSize(20, 10)),
+ cursor.Current().RectInContainerBlock());
+ const PhysicalOffset left_top = cursor.Current().OffsetInContainerBlock();
+
+ EXPECT_EQ(PositionWithAffinity(Position(text, 2), TextAffinity::kUpstream),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(-5, 0)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 2), TextAffinity::kUpstream),
+ cursor.PositionForPointInChild(left_top));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 2), TextAffinity::kUpstream),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(5, 0)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 1)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(10, 0)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 1)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(15, 0)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 0)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(20, 0)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 0)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(25, 0)));
+}
+
+TEST_P(NGInlineCursorTest, PositionForPointInChildVerticalLTR) {
+ LoadAhem();
+ InsertStyleElement(
+ "p {"
+ "direction: ltr;"
+ "font: 10px/20px Ahem;"
+ "padding: 10px;"
+ "writing-mode: vertical-lr;"
+ "}");
+ NGInlineCursor cursor = SetupCursor("<p id=root>ab</p>");
+ const auto& text = *To<Text>(GetElementById("root")->firstChild());
+ ASSERT_TRUE(cursor.Current().IsLineBox());
+ EXPECT_EQ(PhysicalRect(PhysicalOffset(10, 10), PhysicalSize(20, 20)),
+ cursor.Current().RectInContainerBlock());
+
+ cursor.MoveTo(*text.GetLayoutObject());
+ EXPECT_EQ(PhysicalRect(PhysicalOffset(15, 10), PhysicalSize(10, 20)),
+ cursor.Current().RectInContainerBlock());
+ const PhysicalOffset left_top = cursor.Current().OffsetInContainerBlock();
+
+ EXPECT_EQ(PositionWithAffinity(Position(text, 0)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(0, -5)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 0)),
+ cursor.PositionForPointInChild(left_top));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 0)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(0, 5)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 1)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(0, 10)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 1)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(0, 15)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 2), TextAffinity::kUpstream),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(0, 20)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 2), TextAffinity::kUpstream),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(0, 25)));
+}
+
+TEST_P(NGInlineCursorTest, PositionForPointInChildVerticalRTL) {
+ LoadAhem();
+ InsertStyleElement(
+ "p {"
+ "direction: rtl;"
+ "font: 10px/20px Ahem;"
+ "padding: 10px;"
+ "writing-mode: vertical-rl;"
+ "}");
+ NGInlineCursor cursor = SetupCursor("<p id=root><bdo dir=rtl>AB</bdo></p>");
+ const auto& text =
+ *To<Text>(GetElementById("root")->firstChild()->firstChild());
+ ASSERT_TRUE(cursor.Current().IsLineBox());
+ EXPECT_EQ(PhysicalRect(PhysicalOffset(10, 10), PhysicalSize(20, 20)),
+ cursor.Current().RectInContainerBlock());
+
+ cursor.MoveTo(*text.GetLayoutObject());
+ EXPECT_EQ(PhysicalRect(PhysicalOffset(15, 10), PhysicalSize(10, 20)),
+ cursor.Current().RectInContainerBlock());
+ const PhysicalOffset left_top = cursor.Current().OffsetInContainerBlock();
+
+ EXPECT_EQ(PositionWithAffinity(Position(text, 2), TextAffinity::kUpstream),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(0, -5)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 2), TextAffinity::kUpstream),
+ cursor.PositionForPointInChild(left_top));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 2), TextAffinity::kUpstream),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(0, 5)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 1)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(0, 10)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 1)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(0, 15)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 0)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(0, 20)));
+ EXPECT_EQ(PositionWithAffinity(Position(text, 0)),
+ cursor.PositionForPointInChild(left_top + PhysicalOffset(0, 25)));
+}
+
TEST_P(NGInlineCursorTest, Previous) {
// TDOO(yosin): Remove <style> once NGFragmentItem don't do culled inline.
InsertStyleElement("b { background: gray; }");
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h
index 531527710c8..d7aa21969b1 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h
@@ -115,6 +115,8 @@ class CORE_EXPORT NGInlineItem {
unsigned EndOffset() const { return end_offset_; }
unsigned Length() const { return end_offset_ - start_offset_; }
+ bool IsValidOffset(unsigned offset) const;
+
TextDirection Direction() const { return DirectionFromLevel(BidiLevel()); }
UBiDiLevel BidiLevel() const { return static_cast<UBiDiLevel>(bidi_level_); }
// Resolved bidi level for the reordering algorithm. Certain items have
@@ -131,6 +133,9 @@ class CORE_EXPORT NGInlineItem {
bool IsImage() const {
return GetLayoutObject() && GetLayoutObject()->IsLayoutImage();
}
+ bool IsRubyRun() const {
+ return GetLayoutObject() && GetLayoutObject()->IsRubyRun();
+ }
void SetOffset(unsigned start, unsigned end) {
DCHECK_GE(end, start);
@@ -184,6 +189,10 @@ class CORE_EXPORT NGInlineItem {
(Type() == NGInlineItem::kControl && type == kCollapsible));
end_collapse_type_ = type;
}
+ bool IsCollapsibleSpaceOnly() const {
+ return Type() == NGInlineItem::kText &&
+ end_collapse_type_ == kCollapsible && Length() == 1u;
+ }
// True if this item was generated (not in DOM).
// NGInlineItemsBuilder may generate break opportunitites to express the
@@ -229,7 +238,7 @@ class CORE_EXPORT NGInlineItem {
unsigned end_offset,
UBiDiLevel);
- void AssertOffset(unsigned offset) const;
+ void AssertOffset(unsigned offset) const { DCHECK(IsValidOffset(offset)); }
void AssertEndOffset(unsigned offset) const;
String ToString() const;
@@ -257,9 +266,9 @@ class CORE_EXPORT NGInlineItem {
friend class NGInlineNodeDataEditor;
};
-inline void NGInlineItem::AssertOffset(unsigned offset) const {
- DCHECK((offset >= start_offset_ && offset < end_offset_) ||
- (offset == start_offset_ && start_offset_ == end_offset_));
+inline bool NGInlineItem::IsValidOffset(unsigned offset) const {
+ return (offset >= start_offset_ && offset < end_offset_) ||
+ (start_offset_ == end_offset_ && offset == start_offset_);
}
inline void NGInlineItem::AssertEndOffset(unsigned offset) const {
@@ -287,6 +296,10 @@ struct CORE_EXPORT NGInlineItemsData {
// The DOM to text content offset mapping of this inline node.
std::unique_ptr<NGOffsetMapping> offset_mapping;
+ bool IsValidOffset(unsigned index, unsigned offset) const {
+ return index < items.size() && items[index].IsValidOffset(offset);
+ }
+
void AssertOffset(unsigned index, unsigned offset) const {
items[index].AssertOffset(offset);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc
index 4fa2ff96298..592f46b652d 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc
@@ -10,20 +10,17 @@
namespace blink {
-NGInlineItemResult::NGInlineItemResult()
- : item(nullptr), item_index(0), start_offset(0), end_offset(0) {}
+NGInlineItemResult::NGInlineItemResult() : item(nullptr), item_index(0) {}
NGInlineItemResult::NGInlineItemResult(const NGInlineItem* item,
unsigned index,
- unsigned start,
- unsigned end,
+ const NGTextOffset& text_offset,
bool break_anywhere_if_overflow,
bool should_create_line_box,
bool has_unpositioned_floats)
: item(item),
item_index(index),
- start_offset(start),
- end_offset(end),
+ text_offset(text_offset),
break_anywhere_if_overflow(break_anywhere_if_overflow),
should_create_line_box(should_create_line_box),
has_unpositioned_floats(has_unpositioned_floats) {}
@@ -33,16 +30,31 @@ void NGLineInfo::SetLineStyle(const NGInlineNode& node,
bool use_first_line_style) {
use_first_line_style_ = use_first_line_style;
items_data_ = &items_data;
- line_style_ = node.GetLayoutBox()->Style(use_first_line_style_);
+ const LayoutBox* box = node.GetLayoutBox();
+ line_style_ = box->Style(use_first_line_style_);
needs_accurate_end_position_ = ComputeNeedsAccurateEndPosition();
+ is_ruby_base_ = box->IsRubyBase();
+ is_ruby_text_ = box->IsRubyText();
+}
+
+ETextAlign NGLineInfo::GetTextAlign(bool is_last_line) const {
+ // See LayoutRubyBase::TextAlignmentForLine().
+ if (is_ruby_base_)
+ return ETextAlign::kJustify;
+
+ // See LayoutRubyText::TextAlignmentForLine().
+ if (is_ruby_text_ && LineStyle().GetTextAlign() ==
+ ComputedStyleInitialValues::InitialTextAlign())
+ return ETextAlign::kJustify;
+
+ return LineStyle().GetTextAlign(is_last_line);
}
bool NGLineInfo::ComputeNeedsAccurateEndPosition() const {
// Some 'text-align' values need accurate end position. At this point, we
// don't know if this is the last line or not, and thus we don't know whether
// 'text-align' is used or 'text-align-last' is used.
- const ComputedStyle& line_style = LineStyle();
- switch (line_style.GetTextAlign()) {
+ switch (GetTextAlign()) {
case ETextAlign::kStart:
break;
case ETextAlign::kEnd:
@@ -61,7 +73,16 @@ bool NGLineInfo::ComputeNeedsAccurateEndPosition() const {
return true;
break;
}
- switch (line_style.TextAlignLast()) {
+ ETextAlignLast align_last = LineStyle().TextAlignLast();
+ if (is_ruby_base_) {
+ // See LayoutRubyBase::TextAlignmentForLine().
+ align_last = ETextAlignLast::kJustify;
+ } else if (is_ruby_text_ &&
+ align_last == ComputedStyleInitialValues::InitialTextAlignLast()) {
+ // See LayoutRubyText::TextAlignmentForLine().
+ align_last = ETextAlignLast::kJustify;
+ }
+ switch (align_last) {
case ETextAlignLast::kStart:
case ETextAlignLast::kAuto:
return false;
@@ -85,13 +106,13 @@ bool NGLineInfo::ComputeNeedsAccurateEndPosition() const {
void NGInlineItemResult::CheckConsistency(bool allow_null_shape_result) const {
DCHECK(item);
if (item->Type() == NGInlineItem::kText) {
- DCHECK_LT(start_offset, end_offset);
+ text_offset.AssertNotEmpty();
if (allow_null_shape_result && !shape_result)
return;
DCHECK(shape_result);
- DCHECK_EQ(end_offset - start_offset, shape_result->NumCharacters());
- DCHECK_EQ(start_offset, shape_result->StartIndex());
- DCHECK_EQ(end_offset, shape_result->EndIndex());
+ DCHECK_EQ(Length(), shape_result->NumCharacters());
+ DCHECK_EQ(StartOffset(), shape_result->StartIndex());
+ DCHECK_EQ(EndOffset(), shape_result->EndIndex());
}
}
#endif
@@ -105,7 +126,7 @@ unsigned NGLineInfo::InflowEndOffset() const {
if (item.Type() == NGInlineItem::kText ||
item.Type() == NGInlineItem::kControl ||
item.Type() == NGInlineItem::kAtomicInline)
- return item_result.end_offset;
+ return item_result.EndOffset();
}
return StartOffset();
}
@@ -133,7 +154,7 @@ bool NGLineInfo::ShouldHangTrailingSpaces() const {
}
void NGLineInfo::UpdateTextAlign() {
- text_align_ = line_style_->GetTextAlign(IsLastLine());
+ text_align_ = GetTextAlign(IsLastLine());
if (HasTrailingSpaces() && ShouldHangTrailingSpaces()) {
hang_width_ = ComputeTrailingSpaceWidth(&end_offset_for_justify_);
@@ -175,18 +196,18 @@ LayoutUnit NGLineInfo::ComputeTrailingSpaceWidth(
// The last text item may contain trailing spaces if this is a last line,
// has a forced break, or is 'white-space: pre'.
- unsigned end_offset = item_result.end_offset;
+ unsigned end_offset = item_result.EndOffset();
DCHECK(end_offset);
if (item.Type() == NGInlineItem::kText) {
const String& text = items_data_->text_content;
if (end_offset && text[end_offset - 1] == kSpaceCharacter) {
do {
--end_offset;
- } while (end_offset > item_result.start_offset &&
+ } while (end_offset > item_result.StartOffset() &&
text[end_offset - 1] == kSpaceCharacter);
// If all characters in this item_result are spaces, check next item.
- if (end_offset == item_result.start_offset) {
+ if (end_offset == item_result.StartOffset()) {
trailing_spaces_width += item_result.inline_size;
continue;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h
index 66adbd9e850..eb31318da41 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h
@@ -32,11 +32,10 @@ struct CORE_EXPORT NGInlineItemResult {
DISALLOW_NEW();
public:
- NGTextOffset TextOffset() const { return {start_offset, end_offset}; }
- unsigned Length() const {
- DCHECK_GT(end_offset, start_offset);
- return end_offset - start_offset;
- }
+ const NGTextOffset& TextOffset() const { return text_offset; }
+ unsigned StartOffset() const { return text_offset.start; }
+ unsigned EndOffset() const { return text_offset.end; }
+ unsigned Length() const { return text_offset.Length(); }
LayoutUnit HyphenInlineSize() const {
return hyphen_shape_result->SnappedWidth().ClampNegativeToZero();
@@ -52,12 +51,15 @@ struct CORE_EXPORT NGInlineItemResult {
unsigned item_index;
// The range of text content for this item.
- unsigned start_offset;
- unsigned end_offset;
+ NGTextOffset text_offset;
// Inline size of this item.
LayoutUnit inline_size;
+ // Pending inline-end overhang amount for RubyRun.
+ // This is committed if a following item meets conditions.
+ LayoutUnit pending_end_overhang;
+
// ShapeResult for text items. Maybe different from NGInlineItem if re-shape
// is needed in the line breaker.
scoped_refptr<const ShapeResultView> shape_result;
@@ -129,8 +131,7 @@ struct CORE_EXPORT NGInlineItemResult {
NGInlineItemResult();
NGInlineItemResult(const NGInlineItem*,
unsigned index,
- unsigned start,
- unsigned end,
+ const NGTextOffset& text_offset,
bool break_anywhere_if_overflow,
bool should_create_line_box,
bool has_unpositioned_floats);
@@ -253,6 +254,7 @@ class CORE_EXPORT NGLineInfo {
bool NeedsAccurateEndPosition() const { return needs_accurate_end_position_; }
private:
+ ETextAlign GetTextAlign(bool is_last_line = false) const;
bool ComputeNeedsAccurateEndPosition() const;
// The width of preserved trailing spaces.
@@ -283,6 +285,8 @@ class CORE_EXPORT NGLineInfo {
bool has_overflow_ = false;
bool has_trailing_spaces_ = false;
bool needs_accurate_end_position_ = false;
+ bool is_ruby_base_ = false;
+ bool is_ruby_text_ = false;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
index 6e66ff045ba..69eaf05758d 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
@@ -894,6 +894,7 @@ void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendAtomicInline(
RestoreTrailingCollapsibleSpaceIfRemoved();
Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter,
layout_object);
+ has_ruby_ = has_ruby_ || layout_object->IsRubyRun();
// When this atomic inline is inside of an inline box, the height of the
// inline box can be different from the height of the atomic inline. Ensure
@@ -980,7 +981,7 @@ void NGInlineItemsBuilderTemplate<
// Keep the item even if the length became zero. This is not needed for
// the layout purposes, but needed to maintain LayoutObject states. See
- // |AddEmptyTextItem()|.
+ // |AppendEmptyTextItem()|.
item->SetEndOffset(item->EndOffset() - 1);
item->SetEndCollapseType(NGInlineItem::kCollapsed);
@@ -1188,8 +1189,20 @@ void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::ExitInline(
break;
}
DCHECK_GT(i, current_box->item_index);
- if (!item.IsEmptyItem())
- break;
+ if (item.IsEmptyItem()) {
+ // float, abspos, collapsed space(<div>ab <span> </span>).
+ // See editing/caret/empty_inlines.html
+ // See also [1] for empty line box.
+ // [1] https://drafts.csswg.org/css2/visuren.html#phantom-line-box
+ continue;
+ }
+ if (item.IsCollapsibleSpaceOnly()) {
+ // Because we can't collapse trailing spaces until next node, we
+ // create box fragment for it: <div>ab<span> </span></div>
+ // See editing/selection/mixed-editability-10.html
+ continue;
+ }
+ break;
}
}
@@ -1226,6 +1239,11 @@ void NGInlineItemsBuilderTemplate<
// |SegmentText()| will analyze the text and reset |is_bidi_enabled_| if it
// doesn't contain any RTL characters.
data->is_bidi_enabled_ = MayBeBidiEnabled();
+ // Note: Even if |IsEmptyInline()| is true, |text_| isn't empty, e.g. it
+ // holds U+FFFC(ORC) for float or abspos.
+ data->has_line_even_if_empty_ =
+ IsEmptyInline() && block_flow_->HasLineIfEmpty();
+ data->has_ruby_ = has_ruby_;
data->is_empty_inline_ = IsEmptyInline();
data->is_block_level_ = IsBlockLevel();
data->changes_may_affect_earlier_lines_ = ChangesMayAffectEarlierLines();
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h
index a8e6d3f5907..5178c1ebc01 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h
@@ -44,10 +44,13 @@ class NGInlineItemsBuilderTemplate {
public:
// Create a builder that appends items to |items|.
- explicit NGInlineItemsBuilderTemplate(Vector<NGInlineItem>* items)
- : items_(items) {}
+ NGInlineItemsBuilderTemplate(LayoutBlockFlow* block_flow,
+ Vector<NGInlineItem>* items)
+ : block_flow_(block_flow), items_(items) {}
~NGInlineItemsBuilderTemplate();
+ LayoutBlockFlow* GetLayoutBlockFlow() const { return block_flow_; }
+
String ToString();
// Returns whether the items contain any Bidi controls.
@@ -146,6 +149,7 @@ class NGInlineItemsBuilderTemplate {
private:
static bool NeedsBoxInfo();
+ LayoutBlockFlow* const block_flow_;
Vector<NGInlineItem>* items_;
StringBuilder text_;
@@ -177,6 +181,7 @@ class NGInlineItemsBuilderTemplate {
Vector<BidiContext> bidi_context_;
bool has_bidi_controls_ = false;
+ bool has_ruby_ = false;
bool is_empty_inline_ = true;
bool is_block_level_ = true;
bool changes_may_affect_earlier_lines_ = false;
@@ -226,6 +231,8 @@ class NGInlineItemsBuilderTemplate {
const ComputedStyle&,
LayoutText*,
unsigned* start);
+
+ friend class NGInlineItemsBuilderTest;
};
template <>
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc
index 77aff76eecc..912b017a631 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h"
+#include "third_party/blink/renderer/core/layout/ng/layout_ng_ruby_run.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_test.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
@@ -28,6 +29,9 @@ class NGInlineItemsBuilderTest : public NGLayoutTest {
void SetUp() override {
NGLayoutTest::SetUp();
style_ = ComputedStyle::Create();
+ block_flow_ = LayoutBlockFlow::CreateAnonymous(&GetDocument(), style_,
+ LegacyLayout::kAuto);
+ anonymous_objects_.push_back(block_flow_);
}
void TearDown() override {
@@ -36,6 +40,8 @@ class NGInlineItemsBuilderTest : public NGLayoutTest {
NGLayoutTest::TearDown();
}
+ LayoutBlockFlow* GetLayoutBlockFlow() const { return block_flow_; }
+
void SetWhiteSpace(EWhiteSpace whitespace) {
style_->SetWhiteSpace(whitespace);
}
@@ -48,6 +54,10 @@ class NGInlineItemsBuilderTest : public NGLayoutTest {
return style;
}
+ bool HasRuby(const NGInlineItemsBuilder& builder) const {
+ return builder.has_ruby_;
+ }
+
void AppendText(const String& text, NGInlineItemsBuilder* builder) {
LayoutText* layout_text = LayoutText::CreateEmptyAnonymous(
GetDocument(), style_.get(), LegacyLayout::kAuto);
@@ -62,6 +72,14 @@ class NGInlineItemsBuilderTest : public NGLayoutTest {
builder->AppendAtomicInline(layout_block_flow);
}
+ void AppendRubyRun(NGInlineItemsBuilder* builder) {
+ LayoutNGRubyRun* ruby_run = new LayoutNGRubyRun();
+ ruby_run->SetDocumentForAnonymous(&GetDocument());
+ ruby_run->SetStyle(style_);
+ anonymous_objects_.push_back(ruby_run);
+ builder->AppendAtomicInline(ruby_run);
+ }
+
struct Input {
const String text;
EWhiteSpace whitespace = EWhiteSpace::kNormal;
@@ -71,7 +89,7 @@ class NGInlineItemsBuilderTest : public NGLayoutTest {
const String& TestAppend(Vector<Input> inputs) {
items_.clear();
Vector<LayoutText*> anonymous_objects;
- NGInlineItemsBuilder builder(&items_);
+ NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items_);
for (Input& input : inputs) {
if (!input.layout_text) {
input.layout_text = LayoutText::CreateEmptyAnonymous(
@@ -122,7 +140,7 @@ class NGInlineItemsBuilderTest : public NGLayoutTest {
fake_data.is_bidi_enabled_ = has_bidi_controls;
Vector<NGInlineItem> reuse_items;
- NGInlineItemsBuilder reuse_builder(&reuse_items);
+ NGInlineItemsBuilder reuse_builder(GetLayoutBlockFlow(), &reuse_items);
for (Input& input : inputs) {
// Collect items for this LayoutObject.
DCHECK(input.layout_text);
@@ -153,6 +171,7 @@ class NGInlineItemsBuilderTest : public NGLayoutTest {
EXPECT_EQ(text_, reuse_text);
}
+ LayoutBlockFlow* block_flow_ = nullptr;
Vector<NGInlineItem> items_;
String text_;
scoped_refptr<ComputedStyle> style_;
@@ -317,7 +336,7 @@ TEST_F(NGInlineItemsBuilderTest, CollapseEastAsianWidth) {
#endif
TEST_F(NGInlineItemsBuilderTest, OpaqueToSpaceCollapsing) {
- NGInlineItemsBuilder builder(&items_);
+ NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items_);
AppendText("Hello ", &builder);
builder.AppendOpaque(NGInlineItem::kBidiControl,
kFirstStrongIsolateCharacter);
@@ -329,7 +348,7 @@ TEST_F(NGInlineItemsBuilderTest, OpaqueToSpaceCollapsing) {
}
TEST_F(NGInlineItemsBuilderTest, CollapseAroundReplacedElement) {
- NGInlineItemsBuilder builder(&items_);
+ NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items_);
AppendText("Hello ", &builder);
AppendAtomicInline(&builder);
AppendText(" World", &builder);
@@ -337,7 +356,7 @@ TEST_F(NGInlineItemsBuilderTest, CollapseAroundReplacedElement) {
}
TEST_F(NGInlineItemsBuilderTest, CollapseNewlineAfterObject) {
- NGInlineItemsBuilder builder(&items_);
+ NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items_);
AppendAtomicInline(&builder);
AppendText("\n", &builder);
AppendAtomicInline(&builder);
@@ -389,7 +408,7 @@ TEST_F(NGInlineItemsBuilderTest, IgnorablePre) {
TEST_F(NGInlineItemsBuilderTest, Empty) {
Vector<NGInlineItem> items;
- NGInlineItemsBuilder builder(&items);
+ NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items);
scoped_refptr<ComputedStyle> block_style(ComputedStyle::Create());
builder.EnterBlock(block_style.get());
builder.ExitBlock();
@@ -431,7 +450,7 @@ TEST_F(NGInlineItemsBuilderTest, GenerateBreakOpportunityAfterLeadingSpaces) {
TEST_F(NGInlineItemsBuilderTest, BidiBlockOverride) {
Vector<NGInlineItem> items;
- NGInlineItemsBuilder builder(&items);
+ NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items);
scoped_refptr<ComputedStyle> block_style(ComputedStyle::Create());
block_style->SetUnicodeBidi(UnicodeBidi::kBidiOverride);
block_style->SetDirection(TextDirection::kRtl);
@@ -461,7 +480,7 @@ static LayoutInline* CreateLayoutInline(
TEST_F(NGInlineItemsBuilderTest, BidiIsolate) {
Vector<NGInlineItem> items;
- NGInlineItemsBuilder builder(&items);
+ NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items);
AppendText("Hello ", &builder);
LayoutInline* const isolate_rtl =
CreateLayoutInline(&GetDocument(), [](ComputedStyle* style) {
@@ -486,7 +505,7 @@ TEST_F(NGInlineItemsBuilderTest, BidiIsolate) {
TEST_F(NGInlineItemsBuilderTest, BidiIsolateOverride) {
Vector<NGInlineItem> items;
- NGInlineItemsBuilder builder(&items);
+ NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items);
AppendText("Hello ", &builder);
LayoutInline* const isolate_override_rtl =
CreateLayoutInline(&GetDocument(), [](ComputedStyle* style) {
@@ -509,4 +528,26 @@ TEST_F(NGInlineItemsBuilderTest, BidiIsolateOverride) {
isolate_override_rtl->Destroy();
}
+TEST_F(NGInlineItemsBuilderTest, HasRuby) {
+ Vector<NGInlineItem> items;
+ NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items);
+ EXPECT_FALSE(HasRuby(builder)) << "has_ruby_ should be false initially.";
+
+ AppendText("Hello ", &builder);
+ EXPECT_FALSE(HasRuby(builder))
+ << "Adding non-AtomicInline should not affect it.";
+
+ AppendAtomicInline(&builder);
+ EXPECT_FALSE(HasRuby(builder))
+ << "Adding non-ruby AtomicInline should not affect it.";
+
+ AppendRubyRun(&builder);
+ EXPECT_TRUE(HasRuby(builder))
+ << "Adding a ruby AtomicInline should set it to true.";
+
+ AppendAtomicInline(&builder);
+ EXPECT_TRUE(HasRuby(builder))
+ << "Adding non-ruby AtomicInline should not clear it.";
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
index 0ab10f3f371..81ead292e07 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -19,6 +19,7 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h"
#include "third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h"
@@ -63,12 +64,14 @@ NGInlineLayoutAlgorithm::NGInlineLayoutAlgorithm(
// lays out in visual order.
TextDirection::kLtr,
break_token),
+ line_box_(*context->LogicalLineItems()),
box_states_(nullptr),
context_(context),
baseline_type_(container_builder_.Style().GetFontBaseline()),
is_horizontal_writing_mode_(
blink::IsHorizontalWritingMode(space.GetWritingMode())) {
DCHECK(context);
+ DCHECK(&line_box_);
quirks_mode_ = inline_node.InLineHeightQuirksMode();
}
@@ -79,7 +82,7 @@ NGInlineLayoutAlgorithm::~NGInlineLayoutAlgorithm() = default;
NGInlineBoxState* NGInlineLayoutAlgorithm::HandleOpenTag(
const NGInlineItem& item,
const NGInlineItemResult& item_result,
- NGLineBoxFragmentBuilder::ChildList* line_box,
+ NGLogicalLineItems* line_box,
NGInlineLayoutStateStack* box_states) const {
NGInlineBoxState* box =
box_states->OnOpenTag(item, item_result, baseline_type_, line_box);
@@ -164,7 +167,7 @@ void NGInlineLayoutAlgorithm::RebuildBoxStates(
}
// Create box states for tags that are not closed yet.
- NGLineBoxFragmentBuilder::ChildList line_box;
+ NGLogicalLineItems line_box;
box_states->OnBeginPlaceItems(line_info.LineStyle(), baseline_type_,
quirks_mode_, &line_box);
for (const NGInlineItem* item : open_items) {
@@ -180,7 +183,7 @@ void NGInlineLayoutAlgorithm::CheckBoxStates(
const NGInlineBreakToken* break_token) const {
NGInlineLayoutStateStack rebuilt;
RebuildBoxStates(line_info, break_token, &rebuilt);
- NGLineBoxFragmentBuilder::ChildList line_box;
+ NGLogicalLineItems line_box;
rebuilt.OnBeginPlaceItems(line_info.LineStyle(), baseline_type_, quirks_mode_,
&line_box);
DCHECK(box_states_);
@@ -194,7 +197,8 @@ void NGInlineLayoutAlgorithm::CreateLine(
NGExclusionSpace* exclusion_space) {
// Needs MutableResults to move ShapeResult out of the NGLineInfo.
NGInlineItemResults* line_items = line_info->MutableResults();
- line_box_.resize(0);
+ // Clear the current line without releasing the buffer.
+ line_box_.Shrink(0);
// Apply justification before placing items, because it affects size/position
// of items, which are needed to compute inline static positions.
@@ -244,13 +248,16 @@ void NGInlineLayoutAlgorithm::CreateLine(
item.TextType() == NGTextType::kSymbolMarker);
if (UNLIKELY(item_result.hyphen_shape_result)) {
LayoutUnit hyphen_inline_size = item_result.HyphenInlineSize();
- line_box_.AddChild(&item_result, box->text_top,
+ line_box_.AddChild(item, std::move(item_result.shape_result),
+ item_result.TextOffset(), box->text_top,
item_result.inline_size - hyphen_inline_size,
box->text_height, item.BidiLevel());
PlaceHyphen(item_result, hyphen_inline_size, box);
} else {
- line_box_.AddChild(&item_result, box->text_top, item_result.inline_size,
- box->text_height, item.BidiLevel());
+ line_box_.AddChild(item, std::move(item_result.shape_result),
+ item_result.TextOffset(), box->text_top,
+ item_result.inline_size, box->text_height,
+ item.BidiLevel());
}
has_logical_text_items = true;
@@ -259,6 +266,7 @@ void NGInlineLayoutAlgorithm::CreateLine(
} else if (item.Type() == NGInlineItem::kControl) {
PlaceControlItem(item, *line_info, &item_result, box);
+ has_logical_text_items = true;
} else if (item.Type() == NGInlineItem::kOpenTag) {
box = HandleOpenTag(item, item_result, &line_box_, box_states_);
} else if (item.Type() == NGInlineItem::kCloseTag) {
@@ -319,13 +327,6 @@ void NGInlineLayoutAlgorithm::CreateLine(
line_info->AvailableWidth() - line_info->TextIndent() &&
node_.GetLayoutBlockFlow()->ShouldTruncateOverflowingText()) ||
ConstraintSpace().LinesUntilClamp() == 1)) {
- // TODO(kojii): |NGLineTruncator| does not support |Child|-based truncation
- // yet, so create |NGPhysicalTextFragment| first.
- if (has_logical_text_items) {
- line_box_.CreateTextFragments(ConstraintSpace().GetWritingMode(),
- line_info->ItemsData().text_content);
- has_logical_text_items = false;
- }
NGLineTruncator truncator(*line_info);
auto* input =
DynamicTo<HTMLInputElement>(node_.GetLayoutBlockFlow()->GetNode());
@@ -359,16 +360,18 @@ void NGInlineLayoutAlgorithm::CreateLine(
container_builder_.SetBfcLineOffset(bfc_line_offset);
const NGLineHeightMetrics& line_box_metrics =
- box_states_->LineBoxState().metrics;
+ UNLIKELY(Node().HasLineEvenIfEmpty())
+ ? NGLineHeightMetrics(line_info->LineStyle())
+ : box_states_->LineBoxState().metrics;
// Place out-of-flow positioned objects.
- // This adjusts the NGLineBoxFragmentBuilder::Child::offset member to contain
+ // This adjusts the NGLogicalLineItem::offset member to contain
// the static position of the OOF positioned children relative to the linebox.
if (has_out_of_flow_positioned_items)
PlaceOutOfFlowObjects(*line_info, line_box_metrics);
// Place floating objects.
- // This adjusts the NGLineBoxFragmentBuilder::Child::offset member to
+ // This adjusts the NGLogicalLineItem::offset member to
// contain the position of the float relative to the linebox.
// Additionally it will perform layout on any unpositioned floats which
// needed the line height to correctly determine their final position.
@@ -377,6 +380,14 @@ void NGInlineLayoutAlgorithm::CreateLine(
exclusion_space);
}
+ NGAnnotationMetrics annotation_metrics;
+ if (Node().HasRuby() &&
+ !RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ annotation_metrics = ComputeAnnotationOverflow(line_box_, line_box_metrics,
+ -line_box_metrics.ascent,
+ line_info->LineStyle());
+ }
+
// Create box fragments if needed. After this point forward, |line_box_| is a
// tree structure.
// The individual children don't move position within the |line_box_|, rather
@@ -389,11 +400,6 @@ void NGInlineLayoutAlgorithm::CreateLine(
context_->SetItemIndex(line_info->ItemsData().items,
line_info->EndItemIndex());
- if (UNLIKELY(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())) {
- NGFragmentItem::Create(&line_box_, line_info->ItemsData().text_content,
- ConstraintSpace().GetWritingMode());
- }
-
// Even if we have something in-flow, it may just be empty items that
// shouldn't trigger creation of a line. Exit now if that's the case.
if (line_info->IsEmptyLine()) {
@@ -410,12 +416,57 @@ void NGInlineLayoutAlgorithm::CreateLine(
// the line box to the line top.
line_box_.MoveInBlockDirection(line_box_metrics.ascent);
+ if (Node().HasRuby() &&
+ RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ annotation_metrics = ComputeAnnotationOverflow(
+ line_box_, line_box_metrics, LayoutUnit(), line_info->LineStyle());
+ }
+ LayoutUnit annotation_overflow_block_start;
+ LayoutUnit annotation_overflow_block_end;
+ LayoutUnit annotation_space_block_start;
+ LayoutUnit annotation_space_block_end;
+ if (!IsFlippedLinesWritingMode(line_info->LineStyle().GetWritingMode())) {
+ annotation_overflow_block_start = annotation_metrics.overflow_over;
+ annotation_overflow_block_end = annotation_metrics.overflow_under;
+ annotation_space_block_start = annotation_metrics.space_over;
+ annotation_space_block_end = annotation_metrics.space_under;
+ } else {
+ annotation_overflow_block_start = annotation_metrics.overflow_under;
+ annotation_overflow_block_end = annotation_metrics.overflow_over;
+ annotation_space_block_start = annotation_metrics.space_under;
+ annotation_space_block_end = annotation_metrics.space_over;
+ }
+
+ LayoutUnit block_offset_shift = annotation_overflow_block_start;
+ // If the previous line has block-end annotation overflow and this line has
+ // block-start annotation space, shift up the block offset of this line.
+ if (ConstraintSpace().BlockStartAnnotationSpace() < LayoutUnit() &&
+ annotation_space_block_start) {
+ const LayoutUnit overflow = -ConstraintSpace().BlockStartAnnotationSpace();
+ block_offset_shift = -std::min(annotation_space_block_start, overflow);
+ }
+
+ // If this line has block-start annotation overflow and the previous line has
+ // block-end annotation space, borrow the block-end space of the previous line
+ // and shift down the block offset by |overflow - space|.
+ if (annotation_overflow_block_start &&
+ ConstraintSpace().BlockStartAnnotationSpace() > LayoutUnit()) {
+ block_offset_shift = (annotation_overflow_block_start -
+ ConstraintSpace().BlockStartAnnotationSpace())
+ .ClampNegativeToZero();
+ }
+
if (line_info->UseFirstLineStyle())
container_builder_.SetStyleVariant(NGStyleVariant::kFirstLine);
container_builder_.SetBaseDirection(line_info->BaseDirection());
container_builder_.SetInlineSize(inline_size);
container_builder_.SetMetrics(line_box_metrics);
- container_builder_.SetBfcBlockOffset(line_info->BfcOffset().block_offset);
+ container_builder_.SetBfcBlockOffset(line_info->BfcOffset().block_offset +
+ block_offset_shift);
+ if (annotation_overflow_block_end)
+ container_builder_.SetAnnotationOverflow(annotation_overflow_block_end);
+ else if (annotation_space_block_end)
+ container_builder_.SetBlockEndAnnotationSpace(annotation_space_block_end);
}
void NGInlineLayoutAlgorithm::PlaceControlItem(const NGInlineItem& item,
@@ -457,11 +508,10 @@ void NGInlineLayoutAlgorithm::PlaceControlItem(const NGInlineItem& item,
if (UNLIKELY(quirks_mode_ && !box->HasMetrics()))
box->EnsureTextMetrics(*item.Style(), baseline_type_);
- NGTextFragmentBuilder text_builder(ConstraintSpace().GetWritingMode());
- text_builder.SetItem(line_info.ItemsData().text_content, item_result,
- box->text_height);
- line_box_.AddChild(text_builder.ToTextFragment(), box->text_top,
- item_result->inline_size, item.BidiLevel());
+ line_box_.AddChild(item, std::move(item_result->shape_result),
+ item_result->TextOffset(), box->text_top,
+ item_result->inline_size, box->text_height,
+ item.BidiLevel());
}
void NGInlineLayoutAlgorithm::PlaceHyphen(const NGInlineItemResult& item_result,
@@ -472,15 +522,10 @@ void NGInlineLayoutAlgorithm::PlaceHyphen(const NGInlineItemResult& item_result,
DCHECK(item_result.hyphen_shape_result);
DCHECK_EQ(hyphen_inline_size, item_result.HyphenInlineSize());
const NGInlineItem& item = *item_result.item;
- const WritingMode writing_mode = ConstraintSpace().GetWritingMode();
- NGTextFragmentBuilder builder(writing_mode);
- builder.SetText(
- item.GetLayoutObject(), item_result.hyphen_string, item.Style(),
- /* is_ellipsis_style */ false,
- ShapeResultView::Create(item_result.hyphen_shape_result.get()));
- DCHECK(!box->text_metrics.IsEmpty());
- line_box_.AddChild(builder.ToTextFragment(), box->text_top,
- hyphen_inline_size, item.BidiLevel());
+ line_box_.AddChild(
+ item, ShapeResultView::Create(item_result.hyphen_shape_result.get()),
+ item_result.hyphen_string, box->text_top, hyphen_inline_size,
+ box->text_height, item.BidiLevel());
}
NGInlineBoxState* NGInlineLayoutAlgorithm::PlaceAtomicInline(
@@ -568,7 +613,7 @@ void NGInlineLayoutAlgorithm::PlaceOutOfFlowObjects(
bool has_rtl_block_level_out_of_flow_objects = false;
bool is_ltr = IsLtr(line_info.BaseDirection());
- for (NGLineBoxFragmentBuilder::Child& child : line_box_) {
+ for (NGLogicalLineItem& child : line_box_) {
has_preceding_inline_level_content |= child.HasInFlowFragment();
const LayoutObject* box = child.out_of_flow_positioned_box;
@@ -608,7 +653,7 @@ void NGInlineLayoutAlgorithm::PlaceOutOfFlowObjects(
if (UNLIKELY(has_rtl_block_level_out_of_flow_objects)) {
has_preceding_inline_level_content = false;
- for (NGLineBoxFragmentBuilder::Child& child : base::Reversed(line_box_)) {
+ for (NGLogicalLineItem& child : base::Reversed(line_box_)) {
const LayoutObject* box = child.out_of_flow_positioned_box;
if (!box) {
has_preceding_inline_level_content |= child.HasInFlowFragment();
@@ -648,7 +693,7 @@ void NGInlineLayoutAlgorithm::PlaceFloatingObjects(
? ConstraintSpace().ExpectedBfcBlockOffset()
: line_info.BfcOffset().block_offset;
- for (NGLineBoxFragmentBuilder::Child& child : line_box_) {
+ for (NGLogicalLineItem& child : line_box_) {
// We need to position any floats which should be on the "next" line now.
// If this is an empty inline, all floats are positioned during the
// PositionLeadingFloats step.
@@ -697,22 +742,23 @@ void NGInlineLayoutAlgorithm::PlaceListMarker(const NGInlineItem& item,
// Justify the line. This changes the size of items by adding spacing.
// Returns false if justification failed and should fall back to start-aligned.
-bool NGInlineLayoutAlgorithm::ApplyJustify(LayoutUnit space,
- NGLineInfo* line_info) {
+base::Optional<LayoutUnit> NGInlineLayoutAlgorithm::ApplyJustify(
+ LayoutUnit space,
+ NGLineInfo* line_info) {
// Empty lines should align to start.
if (line_info->IsEmptyLine())
- return false;
+ return base::nullopt;
// Justify the end of visible text, ignoring preserved trailing spaces.
unsigned end_offset = line_info->EndOffsetForJustify();
// If this line overflows, fallback to 'text-align: start'.
if (space <= 0)
- return false;
+ return base::nullopt;
// Can't justify an empty string.
if (end_offset == line_info->StartOffset())
- return false;
+ return base::nullopt;
// Construct the line text to compute spacing for.
StringBuilder line_text_builder;
@@ -735,8 +781,32 @@ bool NGInlineLayoutAlgorithm::ApplyJustify(LayoutUnit space,
ShapeResultSpacing<String> spacing(line_text);
spacing.SetExpansion(space, line_info->BaseDirection(),
line_info->LineStyle().GetTextJustify());
- if (!spacing.HasExpansion())
- return false; // no expansion opportunities exist.
+ const LayoutObject* box = Node().GetLayoutBox();
+ if (!spacing.HasExpansion()) {
+ // See AdjustInlineDirectionLineBounds() of LayoutRubyBase and
+ // LayoutRubyText.
+ if (box && (box->IsRubyText() || box->IsRubyBase()))
+ return space / 2;
+ return base::nullopt;
+ }
+
+ LayoutUnit inset;
+ // See AdjustInlineDirectionLineBounds() of LayoutRubyBase and
+ // LayoutRubyText.
+ if (box && (box->IsRubyText() || box->IsRubyBase())) {
+ unsigned count = std::min(spacing.ExpansionOppotunityCount(),
+ static_cast<unsigned>(LayoutUnit::Max().Floor()));
+ // Inset the ruby base/text by half the inter-ideograph expansion amount.
+ inset = space / (count + 1);
+ // For ruby text, inset it by no more than a full-width ruby character on
+ // each side.
+ if (box->IsRubyText()) {
+ inset =
+ std::min(LayoutUnit(2 * line_info->LineStyle().FontSize()), inset);
+ }
+ spacing.SetExpansion(space - inset, line_info->BaseDirection(),
+ line_info->LineStyle().GetTextJustify());
+ }
for (NGInlineItemResult& item_result : *line_info->MutableResults()) {
if (item_result.has_only_trailing_spaces)
@@ -744,10 +814,9 @@ bool NGInlineLayoutAlgorithm::ApplyJustify(LayoutUnit space,
if (item_result.shape_result) {
scoped_refptr<ShapeResult> shape_result =
item_result.shape_result->CreateShapeResult();
- DCHECK_GE(item_result.start_offset, line_info->StartOffset());
- DCHECK_EQ(shape_result->NumCharacters(),
- item_result.end_offset - item_result.start_offset);
- shape_result->ApplySpacing(spacing, item_result.start_offset -
+ DCHECK_GE(item_result.StartOffset(), line_info->StartOffset());
+ DCHECK_EQ(shape_result->NumCharacters(), item_result.Length());
+ shape_result->ApplySpacing(spacing, item_result.StartOffset() -
line_info->StartOffset() -
shape_result->StartIndex());
item_result.inline_size = shape_result->SnappedWidth();
@@ -756,9 +825,9 @@ bool NGInlineLayoutAlgorithm::ApplyJustify(LayoutUnit space,
item_result.shape_result = ShapeResultView::Create(shape_result.get());
} else if (item_result.item->Type() == NGInlineItem::kAtomicInline) {
float offset = 0.f;
- DCHECK_LE(line_info->StartOffset(), item_result.start_offset);
+ DCHECK_LE(line_info->StartOffset(), item_result.StartOffset());
unsigned line_text_offset =
- item_result.start_offset - line_info->StartOffset();
+ item_result.StartOffset() - line_info->StartOffset();
DCHECK_EQ(kObjectReplacementCharacter, line_text[line_text_offset]);
float space = spacing.ComputeSpacing(line_text_offset, offset);
item_result.inline_size += space;
@@ -766,7 +835,7 @@ bool NGInlineLayoutAlgorithm::ApplyJustify(LayoutUnit space,
DCHECK_EQ(offset, 0.f);
}
}
- return true;
+ return inset / 2;
}
// Apply the 'text-align' property to |line_info|. Returns the amount to move
@@ -780,10 +849,9 @@ LayoutUnit NGInlineLayoutAlgorithm::ApplyTextAlign(NGLineInfo* line_info) {
ETextAlign text_align = line_info->TextAlign();
if (text_align == ETextAlign::kJustify) {
- // If justification succeeds, no offset is needed. Expansions are set to
- // each |NGInlineItemResult| in |line_info|.
- if (ApplyJustify(space, line_info))
- return LayoutUnit();
+ base::Optional<LayoutUnit> offset = ApplyJustify(space, line_info);
+ if (offset)
+ return *offset;
// If justification fails, fallback to 'text-align: start'.
text_align = ETextAlign::kStart;
@@ -826,7 +894,7 @@ LayoutUnit NGInlineLayoutAlgorithm::ComputeContentSize(
scoped_refptr<const NGLayoutResult> NGInlineLayoutAlgorithm::Layout() {
NGExclusionSpace initial_exclusion_space(ConstraintSpace().ExclusionSpace());
- bool is_empty_inline = Node().IsEmptyInline();
+ const bool is_empty_inline = Node().IsEmptyInline();
if (is_empty_inline) {
// Margins should collapse across "certain zero-height line boxes".
@@ -1018,7 +1086,7 @@ scoped_refptr<const NGLayoutResult> NGInlineLayoutAlgorithm::Layout() {
container_builder_.ToLineBoxFragment();
items_builder->SetCurrentLine(
To<NGPhysicalLineBoxFragment>(layout_result->PhysicalFragment()),
- std::move(line_box_));
+ &line_box_);
return layout_result;
}
@@ -1109,7 +1177,7 @@ void NGInlineLayoutAlgorithm::BidiReorder(TextDirection base_direction) {
Vector<UBiDiLevel, 32> levels;
levels.ReserveInitialCapacity(line_box_.size());
bool has_opaque_items = false;
- for (NGLineBoxFragmentBuilder::Child& item : line_box_) {
+ for (NGLogicalLineItem& item : line_box_) {
if (item.IsOpaqueToBidiReordering()) {
levels.push_back(kOpaqueBidiLevel);
has_opaque_items = true;
@@ -1136,13 +1204,13 @@ void NGInlineLayoutAlgorithm::BidiReorder(TextDirection base_direction) {
NGBidiParagraph::IndicesInVisualOrder(levels, &indices_in_visual_order);
// Reorder to the visual order.
- NGLineBoxFragmentBuilder::ChildList visual_items;
+ NGLogicalLineItems visual_items;
visual_items.ReserveInitialCapacity(line_box_.size());
for (unsigned logical_index : indices_in_visual_order) {
visual_items.AddChild(std::move(line_box_[logical_index]));
DCHECK(!line_box_[logical_index].HasInFlowFragment() ||
- // |item_result| will not be null by moving.
- line_box_[logical_index].item_result);
+ // |inline_item| will not be null by moving.
+ line_box_[logical_index].inline_item);
}
DCHECK_EQ(line_box_.size(), visual_items.size());
line_box_ = std::move(visual_items);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h
index 23722eca460..05b15a0147e 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h
@@ -7,7 +7,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h"
#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h"
@@ -74,7 +74,7 @@ class CORE_EXPORT NGInlineLayoutAlgorithm final
NGInlineBoxState* HandleOpenTag(const NGInlineItem&,
const NGInlineItemResult&,
- NGLineBoxFragmentBuilder::ChildList*,
+ NGLogicalLineItems*,
NGInlineLayoutStateStack*) const;
NGInlineBoxState* HandleCloseTag(const NGInlineItem&,
const NGInlineItemResult&,
@@ -105,13 +105,13 @@ class CORE_EXPORT NGInlineLayoutAlgorithm final
const NGLineInfo&);
LayoutUnit ApplyTextAlign(NGLineInfo*);
- bool ApplyJustify(LayoutUnit space, NGLineInfo*);
+ base::Optional<LayoutUnit> ApplyJustify(LayoutUnit space, NGLineInfo*);
LayoutUnit ComputeContentSize(const NGLineInfo&,
const NGExclusionSpace&,
LayoutUnit line_height);
- NGLineBoxFragmentBuilder::ChildList line_box_;
+ NGLogicalLineItems& line_box_;
NGInlineLayoutStateStack* box_states_;
NGInlineChildLayoutContext* context_;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
index 9bd25a79215..2157a1e6ee2 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
@@ -52,10 +52,11 @@ TEST_F(NGInlineLayoutAlgorithmTest, BreakToken) {
NGConstraintSpace constraint_space = builder.ToConstraintSpace();
NGInlineChildLayoutContext context;
- NGBoxFragmentBuilder container_builder(block_flow, block_flow->Style(),
- block_flow->Style()->GetWritingMode(),
- block_flow->Style()->Direction());
- NGFragmentItemsBuilder items_builder(inline_node);
+ NGBoxFragmentBuilder container_builder(
+ block_flow, block_flow->Style(),
+ block_flow->Style()->GetWritingDirection());
+ NGFragmentItemsBuilder items_builder(inline_node,
+ container_builder.GetWritingDirection());
if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
container_builder.SetItemsBuilder(&items_builder);
context.SetItemsBuilder(&items_builder);
@@ -66,12 +67,14 @@ TEST_F(NGInlineLayoutAlgorithmTest, BreakToken) {
EXPECT_FALSE(line1.BreakToken()->IsFinished());
// Perform 2nd layout with the break token from the 1st line.
+ items_builder.ClearCurrentLineForTesting();
scoped_refptr<const NGLayoutResult> layout_result2 =
inline_node.Layout(constraint_space, line1.BreakToken(), &context);
const auto& line2 = layout_result2->PhysicalFragment();
EXPECT_FALSE(line2.BreakToken()->IsFinished());
// Perform 3rd layout with the break token from the 2nd line.
+ items_builder.ClearCurrentLineForTesting();
scoped_refptr<const NGLayoutResult> layout_result3 =
inline_node.Layout(constraint_space, line2.BreakToken(), &context);
const auto& line3 = layout_result3->PhysicalFragment();
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
index 075cd9ebf3b..0518f8b6d7b 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
@@ -7,12 +7,13 @@
#include <algorithm>
#include <memory>
+#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
-#include "third_party/blink/renderer/core/layout/layout_list_marker.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_text.h"
+#include "third_party/blink/renderer/core/layout/list_marker.h"
#include "third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h"
@@ -94,14 +95,17 @@ class ReusingTextShaper final {
ShapeResult::CreateEmpty(*reusable_shape_results.front());
unsigned offset = start_offset;
for (const ShapeResult* reusable_shape_result : reusable_shape_results) {
- DCHECK_LE(offset, reusable_shape_result->StartIndex());
+ // In case of pre-wrap having break opportunity after leading space,
+ // |offset| can be greater than |reusable_shape_result->StartIndex()|.
+ // e.g. <div style="white-space:pre">&nbsp; abc</div>, deleteChar(0, 1)
+ // See xternal/wpt/editing/run/delete.html?993-993
if (offset < reusable_shape_result->StartIndex()) {
AppendShapeResult(
*Reshape(start_item, offset, reusable_shape_result->StartIndex()),
shape_result.get());
offset = shape_result->EndIndex();
}
- DCHECK_EQ(offset, reusable_shape_result->StartIndex());
+ DCHECK_LT(offset, reusable_shape_result->EndIndex());
DCHECK(shape_result->NumCharacters() == 0 ||
shape_result->EndIndex() == offset);
reusable_shape_result->CopyRange(
@@ -183,9 +187,9 @@ class ReusingTextShaper final {
// There are also performance considerations, since template saves the overhead
// for condition checking and branching.
template <typename ItemsBuilder>
-void CollectInlinesInternal(LayoutBlockFlow* block,
- ItemsBuilder* builder,
+void CollectInlinesInternal(ItemsBuilder* builder,
const NGInlineNodeData* previous_data) {
+ LayoutBlockFlow* const block = builder->GetLayoutBlockFlow();
builder->EnterBlock(block->Style());
LayoutObject* node = GetLayoutObjectForFirstChildNode(block);
@@ -215,7 +219,7 @@ void CollectInlinesInternal(LayoutBlockFlow* block,
builder->ClearInlineFragment(node);
} else if (node->IsAtomicInlineLevel()) {
- if (node->IsListMarkerIncludingNGOutside()) {
+ if (node->IsBoxListMarkerIncludingNG()) {
// LayoutNGListItem produces the 'outside' list marker as an inline
// block. This is an out-of-flow item whose position is computed
// automatically.
@@ -373,7 +377,7 @@ bool NGInlineNode::IsPrepareLayoutFinished() const {
return data && !data->text_content.IsNull();
}
-void NGInlineNode::PrepareLayoutIfNeeded() {
+void NGInlineNode::PrepareLayoutIfNeeded() const {
std::unique_ptr<NGInlineNodeData> previous_data;
LayoutBlockFlow* block_flow = GetLayoutBlockFlow();
if (IsPrepareLayoutFinished()) {
@@ -388,7 +392,7 @@ void NGInlineNode::PrepareLayoutIfNeeded() {
}
void NGInlineNode::PrepareLayout(
- std::unique_ptr<NGInlineNodeData> previous_data) {
+ std::unique_ptr<NGInlineNodeData> previous_data) const {
// Scan list of siblings collecting all in-flow non-atomic inlines. A single
// NGInlineNode represent a collection of adjacent non-atomic inlines.
NGInlineNodeData* data = MutableData();
@@ -516,16 +520,19 @@ class NGInlineNodeDataEditor final {
// Skip items in replaced range.
while (it->end_offset_ < end_offset)
++it;
- DCHECK_EQ(it->layout_object_, layout_text_);
// Inserted text
- if (inserted_text_length > 0) {
- const unsigned inserted_start_offset =
- items.IsEmpty() ? 0 : items.back().end_offset_;
- const unsigned inserted_end_offset =
- inserted_start_offset + inserted_text_length;
- items.push_back(NGInlineItem(*it, inserted_start_offset,
- inserted_end_offset, nullptr));
+ if (it->layout_object_ == layout_text_) {
+ if (inserted_text_length > 0) {
+ const unsigned inserted_start_offset =
+ items.IsEmpty() ? 0 : items.back().end_offset_;
+ const unsigned inserted_end_offset =
+ inserted_start_offset + inserted_text_length;
+ items.push_back(NGInlineItem(*it, inserted_start_offset,
+ inserted_end_offset, nullptr));
+ }
+ } else {
+ DCHECK_LE(inserted_text_length, 0);
}
// Copy part of item after replaced range.
@@ -571,7 +578,6 @@ class NGInlineNodeDataEditor final {
unsigned start_offset) const {
DCHECK_LE(item.start_offset_, start_offset);
DCHECK_LT(start_offset, item.end_offset_);
- DCHECK_EQ(item.layout_object_, layout_text_);
if (item.start_offset_ == start_offset)
return item;
const unsigned end_offset = item.end_offset_;
@@ -688,11 +694,11 @@ bool NGInlineNode::SetTextWithOffset(LayoutText* layout_text,
NGInlineNode node(editor.GetLayoutBlockFlow());
NGInlineNodeData* data = node.MutableData();
data->items.ReserveCapacity(previous_data->items.size());
- NGInlineItemsBuilder builder(&data->items);
+ NGInlineItemsBuilder builder(editor.GetLayoutBlockFlow(), &data->items);
// TODO(yosin): We should reuse before/after |layout_text| during collecting
// inline items.
layout_text->ClearInlineItems();
- CollectInlinesInternal(node.GetLayoutBlockFlow(), &builder, previous_data);
+ CollectInlinesInternal(&builder, previous_data);
builder.DidFinishCollectInlines(data);
// Relocates |ShapeResult| in |previous_data| after |offset|+|length|
editor.Run();
@@ -703,12 +709,12 @@ bool NGInlineNode::SetTextWithOffset(LayoutText* layout_text,
return true;
}
-const NGInlineNodeData& NGInlineNode::EnsureData() {
+const NGInlineNodeData& NGInlineNode::EnsureData() const {
PrepareLayoutIfNeeded();
return Data();
}
-const NGOffsetMapping* NGInlineNode::ComputeOffsetMappingIfNeeded() {
+const NGOffsetMapping* NGInlineNode::ComputeOffsetMappingIfNeeded() const {
DCHECK(!GetLayoutBlockFlow()->GetDocument().NeedsLayoutTreeUpdate());
NGInlineNodeData* data = MutableData();
@@ -732,10 +738,10 @@ void NGInlineNode::ComputeOffsetMapping(LayoutBlockFlow* layout_block_flow,
// |builder| not construct items and text content.
Vector<NGInlineItem> items;
items.ReserveCapacity(EstimateInlineItemsCount(*layout_block_flow));
- NGInlineItemsBuilderForOffsetMapping builder(&items);
+ NGInlineItemsBuilderForOffsetMapping builder(layout_block_flow, &items);
builder.GetOffsetMappingBuilder().ReserveCapacity(
EstimateOffsetMappingItemsCount(*layout_block_flow));
- CollectInlinesInternal(layout_block_flow, &builder, nullptr);
+ CollectInlinesInternal(&builder, nullptr);
// For non-NG object, we need the text, and also the inline items to resolve
// bidi levels. Otherwise |data| already has the text from the pre-layout
@@ -791,19 +797,19 @@ const NGOffsetMapping* NGInlineNode::GetOffsetMapping(
// parent LayoutInline where possible, and joining all text content in a single
// string to allow bidi resolution and shaping of the entire block.
void NGInlineNode::CollectInlines(NGInlineNodeData* data,
- NGInlineNodeData* previous_data) {
+ NGInlineNodeData* previous_data) const {
DCHECK(data->text_content.IsNull());
DCHECK(data->items.IsEmpty());
LayoutBlockFlow* block = GetLayoutBlockFlow();
block->WillCollectInlines();
data->items.ReserveCapacity(EstimateInlineItemsCount(*block));
- NGInlineItemsBuilder builder(&data->items);
- CollectInlinesInternal(block, &builder, previous_data);
+ NGInlineItemsBuilder builder(block, &data->items);
+ CollectInlinesInternal(&builder, previous_data);
builder.DidFinishCollectInlines(data);
}
-void NGInlineNode::SegmentText(NGInlineNodeData* data) {
+void NGInlineNode::SegmentText(NGInlineNodeData* data) const {
SegmentBidiRuns(data);
SegmentScriptRuns(data);
SegmentFontOrientation(data);
@@ -812,8 +818,8 @@ void NGInlineNode::SegmentText(NGInlineNodeData* data) {
}
// Segment NGInlineItem by script, Emoji, and orientation using RunSegmenter.
-void NGInlineNode::SegmentScriptRuns(NGInlineNodeData* data) {
- DCHECK_EQ(data->segments, nullptr);
+void NGInlineNode::SegmentScriptRuns(NGInlineNodeData* data) const {
+ DCHECK_EQ(data->segments.get(), nullptr);
String& text_content = data->text_content;
if (text_content.IsEmpty()) {
@@ -895,7 +901,7 @@ void NGInlineNode::SegmentScriptRuns(NGInlineNodeData* data) {
DCHECK_EQ(range.end, text_content.length());
}
-void NGInlineNode::SegmentFontOrientation(NGInlineNodeData* data) {
+void NGInlineNode::SegmentFontOrientation(NGInlineNodeData* data) const {
// Segment by orientation, only if vertical writing mode and items with
// 'text-orientation: mixed'.
if (GetLayoutBlockFlow()->IsHorizontalWritingMode())
@@ -937,7 +943,7 @@ void NGInlineNode::SegmentFontOrientation(NGInlineNodeData* data) {
// Segment bidi runs by resolving bidi embedding levels.
// http://unicode.org/reports/tr9/#Resolving_Embedding_Levels
-void NGInlineNode::SegmentBidiRuns(NGInlineNodeData* data) {
+void NGInlineNode::SegmentBidiRuns(NGInlineNodeData* data) const {
if (!data->is_bidi_enabled_) {
data->SetBaseDirection(TextDirection::kLtr);
return;
@@ -982,7 +988,8 @@ void NGInlineNode::SegmentBidiRuns(NGInlineNodeData* data) {
void NGInlineNode::ShapeText(NGInlineItemsData* data,
const String* previous_text,
- const Vector<NGInlineItem>* previous_items) {
+ const Vector<NGInlineItem>* previous_items) const {
+ TRACE_EVENT0("blink", "NGInlineNode::ShapeText");
const String& text_content = data->text_content;
Vector<NGInlineItem>* items = &data->items;
@@ -1009,7 +1016,7 @@ void NGInlineNode::ShapeText(NGInlineItemsData* data,
// Symbol marker is painted as graphics. Create a ShapeResult of space
// glyphs with the desired size to make it less special for line breaker.
if (UNLIKELY(start_item.IsSymbolMarker())) {
- LayoutUnit symbol_width = LayoutListMarker::WidthOfSymbol(start_style);
+ LayoutUnit symbol_width = ListMarker::WidthOfSymbol(start_style);
DCHECK_GT(symbol_width, 0);
start_item.shape_result_ = ShapeResult::CreateForSpaces(
&font, direction, start_item.StartOffset(), start_item.Length(),
@@ -1155,7 +1162,7 @@ void NGInlineNode::ShapeText(NGInlineItemsData* data,
}
// Create Vector<NGInlineItem> with :first-line rules applied if needed.
-void NGInlineNode::ShapeTextForFirstLineIfNeeded(NGInlineNodeData* data) {
+void NGInlineNode::ShapeTextForFirstLineIfNeeded(NGInlineNodeData* data) const {
// First check if the document has any :first-line rules.
DCHECK(!data->first_line_items_);
LayoutObject* layout_object = GetLayoutBox();
@@ -1200,7 +1207,7 @@ void NGInlineNode::ShapeTextForFirstLineIfNeeded(NGInlineNodeData* data) {
data->first_line_items_ = std::move(first_line_items);
}
-void NGInlineNode::AssociateItemsWithInlines(NGInlineNodeData* data) {
+void NGInlineNode::AssociateItemsWithInlines(NGInlineNodeData* data) const {
#if DCHECK_IS_ON()
HashSet<LayoutObject*> associated_objects;
#endif
@@ -1283,7 +1290,7 @@ void NGInlineNode::ClearAssociatedFragments(
scoped_refptr<const NGLayoutResult> NGInlineNode::Layout(
const NGConstraintSpace& constraint_space,
const NGBreakToken* break_token,
- NGInlineChildLayoutContext* context) {
+ NGInlineChildLayoutContext* context) const {
PrepareLayoutIfNeeded();
const auto* inline_break_token = To<NGInlineBreakToken>(break_token);
@@ -1292,16 +1299,20 @@ scoped_refptr<const NGLayoutResult> NGInlineNode::Layout(
auto layout_result = algorithm.Layout();
#if defined(OS_ANDROID)
- // Cached position data is crucial for line breaking performance and is
- // preserved across layouts to speed up subsequent layout passes due to
- // reflow, page zoom, window resize, etc. On Android though reflows are less
- // common, page zoom isn't used (instead uses pinch-zoom), and the window
- // typically can't be resized (apart from rotation). To reduce memory usage
- // discard the cached position data after layout.
- NGInlineNodeData* data = MutableData();
- for (auto& item : data->items) {
- if (item.shape_result_)
- item.shape_result_->DiscardPositionData();
+ if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ // Cached position data is crucial for line breaking performance and is
+ // preserved across layouts to speed up subsequent layout passes due to
+ // reflow, page zoom, window resize, etc. On Android though reflows are less
+ // common, page zoom isn't used (instead uses pinch-zoom), and the window
+ // typically can't be resized (apart from rotation). To reduce memory usage
+ // discard the cached position data after layout.
+ // TODO(crbug.com/1042604): FragmentItem should save memory enough to re-
+ // enable the position cache.
+ NGInlineNodeData* data = MutableData();
+ for (auto& item : data->items) {
+ if (item.shape_result_)
+ item.shape_result_->DiscardPositionData();
+ }
}
#endif // defined(OS_ANDROID)
@@ -1587,7 +1598,8 @@ static LayoutUnit ComputeContentSize(
const ComputedStyle& float_style = float_node.Style();
// Floats don't intrude into floats.
- MinMaxSizesInput float_input(input.percentage_resolution_block_size);
+ MinMaxSizesInput float_input(input.percentage_resolution_block_size,
+ MinMaxSizesType::kContent);
MinMaxSizesResult child_result =
ComputeMinAndMaxContentContribution(style, float_node, float_input);
LayoutUnit child_inline_margins =
@@ -1637,7 +1649,7 @@ static LayoutUnit ComputeContentSize(
MinMaxSizesResult NGInlineNode::ComputeMinMaxSizes(
WritingMode container_writing_mode,
const MinMaxSizesInput& input,
- const NGConstraintSpace* constraint_space) {
+ const NGConstraintSpace* constraint_space) const {
PrepareLayoutIfNeeded();
// Compute the max of inline sizes of all line boxes with 0 available inline
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h
index c14ef2b3644..af75b0b6a9f 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h
@@ -27,7 +27,8 @@ struct NGInlineItemsData;
// inline nodes and their descendants.
class CORE_EXPORT NGInlineNode : public NGLayoutInputNode {
public:
- NGInlineNode(LayoutBlockFlow*);
+ explicit NGInlineNode(LayoutBlockFlow*);
+ explicit NGInlineNode(std::nullptr_t) : NGLayoutInputNode(nullptr) {}
LayoutBlockFlow* GetLayoutBlockFlow() const {
return To<LayoutBlockFlow>(box_);
@@ -44,14 +45,15 @@ class CORE_EXPORT NGInlineNode : public NGLayoutInputNode {
scoped_refptr<const NGLayoutResult> Layout(
const NGConstraintSpace&,
const NGBreakToken*,
- NGInlineChildLayoutContext* context);
+ NGInlineChildLayoutContext* context) const;
// Computes the value of min-content and max-content for this anonymous block
// box. min-content is the inline size when lines wrap at every break
// opportunity, and max-content is when lines do not wrap at all.
- MinMaxSizesResult ComputeMinMaxSizes(WritingMode container_writing_mode,
- const MinMaxSizesInput&,
- const NGConstraintSpace* = nullptr);
+ MinMaxSizesResult ComputeMinMaxSizes(
+ WritingMode container_writing_mode,
+ const MinMaxSizesInput&,
+ const NGConstraintSpace* = nullptr) const;
// Instruct to re-compute |PrepareLayout| on the next layout.
void InvalidatePrepareLayoutForTest() {
@@ -98,7 +100,7 @@ class CORE_EXPORT NGInlineNode : public NGLayoutInputNode {
// Returns the DOM to text content offset mapping of this block. If it is not
// computed before, compute and store it in NGInlineNodeData.
// This funciton must be called with clean layout.
- const NGOffsetMapping* ComputeOffsetMappingIfNeeded();
+ const NGOffsetMapping* ComputeOffsetMappingIfNeeded() const;
// Get |NGOffsetMapping| for the |layout_block_flow|. |layout_block_flow|
// should be laid out. This function works for both new and legacy layout.
@@ -108,6 +110,9 @@ class CORE_EXPORT NGInlineNode : public NGLayoutInputNode {
bool IsBidiEnabled() const { return Data().is_bidi_enabled_; }
TextDirection BaseDirection() const { return Data().BaseDirection(); }
+ bool HasLineEvenIfEmpty() { return EnsureData().has_line_even_if_empty_; }
+ bool HasRuby() const { return Data().has_ruby_; }
+
bool IsEmptyInline() { return EnsureData().is_empty_inline_; }
bool IsBlockLevel() { return EnsureData().is_block_level_; }
@@ -127,7 +132,7 @@ class CORE_EXPORT NGInlineNode : public NGLayoutInputNode {
struct FloatingObject {
DISALLOW_NEW();
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
const ComputedStyle& float_style;
const ComputedStyle& style;
@@ -139,22 +144,22 @@ class CORE_EXPORT NGInlineNode : public NGLayoutInputNode {
// Prepare inline and text content for layout. Must be called before
// calling the Layout method.
- void PrepareLayoutIfNeeded();
- void PrepareLayout(std::unique_ptr<NGInlineNodeData> previous_data);
+ void PrepareLayoutIfNeeded() const;
+ void PrepareLayout(std::unique_ptr<NGInlineNodeData> previous_data) const;
void CollectInlines(NGInlineNodeData*,
- NGInlineNodeData* previous_data = nullptr);
- void SegmentText(NGInlineNodeData*);
- void SegmentScriptRuns(NGInlineNodeData*);
- void SegmentFontOrientation(NGInlineNodeData*);
- void SegmentBidiRuns(NGInlineNodeData*);
+ NGInlineNodeData* previous_data = nullptr) const;
+ void SegmentText(NGInlineNodeData*) const;
+ void SegmentScriptRuns(NGInlineNodeData*) const;
+ void SegmentFontOrientation(NGInlineNodeData*) const;
+ void SegmentBidiRuns(NGInlineNodeData*) const;
void ShapeText(NGInlineItemsData*,
const String* previous_text = nullptr,
- const Vector<NGInlineItem>* previous_items = nullptr);
- void ShapeTextForFirstLineIfNeeded(NGInlineNodeData*);
- void AssociateItemsWithInlines(NGInlineNodeData*);
+ const Vector<NGInlineItem>* previous_items = nullptr) const;
+ void ShapeTextForFirstLineIfNeeded(NGInlineNodeData*) const;
+ void AssociateItemsWithInlines(NGInlineNodeData*) const;
- NGInlineNodeData* MutableData() {
+ NGInlineNodeData* MutableData() const {
return To<LayoutBlockFlow>(box_)->GetNGInlineNodeData();
}
const NGInlineNodeData& Data() const {
@@ -167,7 +172,7 @@ class CORE_EXPORT NGInlineNode : public NGLayoutInputNode {
DCHECK(IsPrepareLayoutFinished());
return *To<LayoutBlockFlow>(box_)->GetNGInlineNodeData();
}
- const NGInlineNodeData& EnsureData();
+ const NGInlineNodeData& EnsureData() const;
static void ComputeOffsetMapping(LayoutBlockFlow* layout_block_flow,
NGInlineNodeData* data);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h
index 5dda66cc9f2..0636afc4b3d 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h
@@ -22,6 +22,8 @@ struct CORE_EXPORT NGInlineNodeData : NGInlineItemsData {
return static_cast<TextDirection>(base_direction_);
}
+ bool HasLineEvenIfEmpty() const { return has_line_even_if_empty_; }
+ bool HasRuby() const { return has_ruby_; }
bool IsEmptyInline() const { return is_empty_inline_; }
bool IsBlockLevel() const { return is_block_level_; }
@@ -56,6 +58,14 @@ struct CORE_EXPORT NGInlineNodeData : NGInlineItemsData {
unsigned is_bidi_enabled_ : 1;
unsigned base_direction_ : 1; // TextDirection
+ // True if there are no inline item items and the associated block is root
+ // editable element or having "-internal-empty-line-height:fabricated",
+ // e.g. <div contenteditable></div>, <input type=button value="">
+ unsigned has_line_even_if_empty_ : 1;
+
+ // The node contains <ruby>.
+ unsigned has_ruby_ : 1;
+
// We use this flag to determine if the inline node is empty, and will
// produce a single zero block-size line box. If the node has text, atomic
// inlines, open/close tags with margins/border/padding this will be false.
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
index 92ef98f42be..511fc704621 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
@@ -114,7 +114,8 @@ class NGInlineNodeTest : public NGLayoutTest {
.ComputeMinMaxSizes(
node.Style().GetWritingMode(),
MinMaxSizesInput(
- /* percentage_resolution_block_size */ LayoutUnit()))
+ /* percentage_resolution_block_size */ LayoutUnit(),
+ MinMaxSizesType::kContent))
.sizes;
}
@@ -140,13 +141,16 @@ class NGInlineNodeTest : public NGLayoutTest {
return end_offsets;
}
- void TestFirstLineIsDirty(LayoutBlockFlow* block_flow, bool expected) {
+ void TestAnyItrermsAreDirty(LayoutBlockFlow* block_flow, bool expected) {
const NGFragmentItems* items = block_flow->FragmentItems();
items->DirtyLinesFromNeedsLayout(block_flow);
- const NGFragmentItem* end_reusable_item = items->EndOfReusableItems();
- NGInlineCursor cursor(*items);
- cursor.MoveToFirstLine();
- EXPECT_EQ(cursor.Current().Item() == end_reusable_item, expected);
+ // Check |NGFragmentItem::IsDirty| directly without using
+ // |EndOfReusableItems|. This is different from the line cache logic, but
+ // some items may not be reusable even if |!IsDirty()|.
+ const bool is_any_items_dirty =
+ std::any_of(items->Items().begin(), items->Items().end(),
+ [](const NGFragmentItem& item) { return item.IsDirty(); });
+ EXPECT_EQ(is_any_items_dirty, expected);
}
scoped_refptr<const ComputedStyle> style_;
@@ -636,8 +640,8 @@ TEST_P(StyleChangeTest, NeedsCollectInlinesOnStyle) {
if (data.is_line_dirty &&
RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
- TestFirstLineIsDirty(To<LayoutBlockFlow>(container->GetLayoutObject()),
- *data.is_line_dirty);
+ TestAnyItrermsAreDirty(To<LayoutBlockFlow>(container->GetLayoutObject()),
+ *data.is_line_dirty);
}
ForceLayout(); // Ensure running layout does not crash.
@@ -1035,9 +1039,11 @@ TEST_F(NGInlineNodeTest, ClearFirstInlineFragmentOnSplitFlow) {
// Keep the text fragment to compare later.
Element* inner_span = GetElementById("inner_span");
Node* text = inner_span->firstChild();
- scoped_refptr<NGPaintFragment> text_fragment_before_split =
- text->GetLayoutObject()->FirstInlineFragment();
- EXPECT_NE(text_fragment_before_split.get(), nullptr);
+ NGInlineCursor before_split;
+ before_split.MoveTo(*text->GetLayoutObject());
+ EXPECT_TRUE(before_split);
+ scoped_refptr<const NGPaintFragment> text_fragment_before_split =
+ before_split.Current().PaintFragment();
// Append <div> to <span>. causing SplitFlow().
Element* outer_span = GetElementById("outer_span");
@@ -1053,23 +1059,32 @@ TEST_F(NGInlineNodeTest, ClearFirstInlineFragmentOnSplitFlow) {
// destroyed, and should not be accessible.
GetDocument().UpdateStyleAndLayoutTree();
EXPECT_FALSE(text->GetLayoutObject()->IsInLayoutNGInlineFormattingContext());
- scoped_refptr<NGPaintFragment> text_fragment_before_layout =
- text->GetLayoutObject()->FirstInlineFragment();
- EXPECT_EQ(text_fragment_before_layout, nullptr);
+ EXPECT_FALSE(text->GetLayoutObject()->HasInlineFragments());
// Update layout. There should be a different instance of the text fragment.
UpdateAllLifecyclePhasesForTest();
- scoped_refptr<NGPaintFragment> text_fragment_after_layout =
- text->GetLayoutObject()->FirstInlineFragment();
- EXPECT_NE(text_fragment_before_split, text_fragment_after_layout);
+ NGInlineCursor after_layout;
+ after_layout.MoveTo(*text->GetLayoutObject());
+ EXPECT_TRUE(after_layout);
+ if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ EXPECT_NE(text_fragment_before_split.get(),
+ after_layout.Current().PaintFragment());
+ }
// Check it is the one owned by the new root inline formatting context.
LayoutBlock* anonymous_block =
inner_span->GetLayoutObject()->ContainingBlock();
EXPECT_TRUE(anonymous_block->IsAnonymous());
- const NGPaintFragment* block_fragment = anonymous_block->PaintFragment();
- const NGPaintFragment* line_box_fragment = block_fragment->FirstChild();
- EXPECT_EQ(line_box_fragment->FirstChild(), text_fragment_after_layout);
+ NGInlineCursor anonymous_block_cursor(*To<LayoutBlockFlow>(anonymous_block));
+ anonymous_block_cursor.MoveToFirstLine();
+ anonymous_block_cursor.MoveToFirstChild();
+ EXPECT_TRUE(anonymous_block_cursor);
+ EXPECT_EQ(anonymous_block_cursor.Current().GetLayoutObject(),
+ text->GetLayoutObject());
+ if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ EXPECT_EQ(anonymous_block_cursor.Current().PaintFragment(),
+ after_layout.Current().PaintFragment());
+ }
}
TEST_F(NGInlineNodeTest, AddChildToSVGRoot) {
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc
index 3ec775afee2..2cb44b83e61 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_fragment.h"
@@ -40,90 +41,7 @@ void NGLineBoxFragmentBuilder::SetIsEmptyLineBox() {
line_box_type_ = NGPhysicalLineBoxFragment::kEmptyLineBox;
}
-void NGLineBoxFragmentBuilder::ChildList::CreateTextFragments(
- WritingMode writing_mode,
- const String& text_content) {
- NGTextFragmentBuilder text_builder(writing_mode);
- for (auto& child : *this) {
- if (NGInlineItemResult* item_result = child.item_result) {
- DCHECK(item_result->item);
- const NGInlineItem& item = *item_result->item;
- DCHECK(item.Type() == NGInlineItem::kText ||
- item.Type() == NGInlineItem::kControl);
- DCHECK(item.TextType() == NGTextType::kNormal ||
- item.TextType() == NGTextType::kSymbolMarker);
- text_builder.SetItem(text_content, item_result,
- child.rect.size.block_size);
- DCHECK(!child.fragment);
- child.fragment = text_builder.ToTextFragment();
- }
- }
-}
-
-NGLineBoxFragmentBuilder::Child*
-NGLineBoxFragmentBuilder::ChildList::FirstInFlowChild() {
- for (auto& child : *this) {
- if (child.HasInFlowFragment())
- return &child;
- }
- return nullptr;
-}
-
-NGLineBoxFragmentBuilder::Child*
-NGLineBoxFragmentBuilder::ChildList::LastInFlowChild() {
- for (auto it = rbegin(); it != rend(); it++) {
- auto& child = *it;
- if (child.HasInFlowFragment())
- return &child;
- }
- return nullptr;
-}
-
-void NGLineBoxFragmentBuilder::ChildList::WillInsertChild(
- unsigned insert_before) {
- unsigned index = 0;
- for (Child& child : children_) {
- if (index >= insert_before)
- break;
- if (child.children_count && index + child.children_count > insert_before)
- ++child.children_count;
- ++index;
- }
-}
-
-void NGLineBoxFragmentBuilder::ChildList::InsertChild(unsigned index) {
- WillInsertChild(index);
- children_.insert(index, Child());
-}
-
-void NGLineBoxFragmentBuilder::ChildList::MoveInInlineDirection(
- LayoutUnit delta) {
- for (auto& child : children_)
- child.rect.offset.inline_offset += delta;
-}
-
-void NGLineBoxFragmentBuilder::ChildList::MoveInInlineDirection(
- LayoutUnit delta,
- unsigned start,
- unsigned end) {
- for (unsigned index = start; index < end; index++)
- children_[index].rect.offset.inline_offset += delta;
-}
-
-void NGLineBoxFragmentBuilder::ChildList::MoveInBlockDirection(
- LayoutUnit delta) {
- for (auto& child : children_)
- child.rect.offset.block_offset += delta;
-}
-
-void NGLineBoxFragmentBuilder::ChildList::MoveInBlockDirection(LayoutUnit delta,
- unsigned start,
- unsigned end) {
- for (unsigned index = start; index < end; index++)
- children_[index].rect.offset.block_offset += delta;
-}
-
-void NGLineBoxFragmentBuilder::AddChildren(ChildList& children) {
+void NGLineBoxFragmentBuilder::AddChildren(NGLogicalLineItems& children) {
children_.ReserveCapacity(children.size());
for (auto& child : children) {
@@ -143,7 +61,8 @@ void NGLineBoxFragmentBuilder::AddChildren(ChildList& children) {
}
}
-void NGLineBoxFragmentBuilder::PropagateChildrenData(ChildList& children) {
+void NGLineBoxFragmentBuilder::PropagateChildrenData(
+ NGLogicalLineItems& children) {
for (unsigned index = 0; index < children.size(); ++index) {
auto& child = children[index];
if (child.layout_result) {
@@ -172,7 +91,7 @@ void NGLineBoxFragmentBuilder::PropagateChildrenData(ChildList& children) {
scoped_refptr<const NGLayoutResult>
NGLineBoxFragmentBuilder::ToLineBoxFragment() {
- writing_mode_ = ToLineWritingMode(writing_mode_);
+ writing_direction_.SetWritingMode(ToLineWritingMode(GetWritingMode()));
if (!break_token_)
break_token_ = NGInlineBreakToken::Create(node_);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h
index 8c3dc2cd273..47540975fc5 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h
@@ -21,7 +21,7 @@ namespace blink {
class ComputedStyle;
class NGInlineBreakToken;
-struct NGInlineItemResult;
+class NGLogicalLineItems;
class CORE_EXPORT NGLineBoxFragmentBuilder final
: public NGContainerFragmentBuilder {
@@ -31,13 +31,13 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
NGLineBoxFragmentBuilder(NGInlineNode node,
scoped_refptr<const ComputedStyle> style,
const NGConstraintSpace* space,
- WritingMode writing_mode,
- TextDirection)
- : NGContainerFragmentBuilder(node,
- style,
- space,
- writing_mode,
- TextDirection::kLtr),
+ WritingDirectionMode writing_direction)
+ : NGContainerFragmentBuilder(
+ node,
+ style,
+ space,
+ // Always use LTR because line items are in visual order.
+ {writing_direction.GetWritingMode(), TextDirection::kLtr}),
line_box_type_(NGPhysicalLineBoxFragment::kNormalLineBox),
base_direction_(TextDirection::kLtr) {}
@@ -71,248 +71,13 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
break_token_ = std::move(break_token);
}
- // A data struct to keep NGLayoutResult or fragment until the box tree
- // structures and child offsets are finalized.
- struct Child {
- DISALLOW_NEW();
-
- scoped_refptr<NGFragmentItem> fragment_item;
- scoped_refptr<const NGLayoutResult> layout_result;
- scoped_refptr<const NGPhysicalTextFragment> fragment;
- const NGInlineItem* inline_item = nullptr;
- // |NGInlineItemResult| to create a text fragment from.
- NGInlineItemResult* item_result = nullptr;
- LayoutObject* out_of_flow_positioned_box = nullptr;
- LayoutObject* unpositioned_float = nullptr;
- // The offset of the border box, initially in this child coordinate system.
- // |ComputeInlinePositions()| converts it to the offset within the line box.
- LogicalRect rect;
- // The offset of a positioned float wrt. the root BFC. This should only be
- // set for positioned floats.
- NGBfcOffset bfc_offset;
- // The inline size of the margin box.
- LayoutUnit inline_size;
- LayoutUnit margin_line_left;
- // The index of |box_data_list_|, used in |PrepareForReorder()| and
- // |UpdateAfterReorder()| to track children of boxes across BiDi reorder.
- unsigned box_data_index = 0;
- // For an inline box, shows the number of descendant |Child|ren, including
- // empty ones. Includes itself, so 1 means no descendants. 0 if not an
- // inline box. Available only after |CreateBoxFragments()|.
- unsigned children_count = 0;
- UBiDiLevel bidi_level = 0xff;
- // The current text direction for OOF positioned items.
- TextDirection container_direction = TextDirection::kLtr;
-
- // Empty constructor needed for |resize()|.
- Child() = default;
- // Create a placeholder. A placeholder does not have a fragment nor a bidi
- // level.
- Child(LayoutUnit block_offset, LayoutUnit block_size)
- : rect(LayoutUnit(), block_offset, LayoutUnit(), block_size) {}
- Child(const NGInlineItem& inline_item,
- const LogicalRect& rect,
- unsigned children_count)
- : inline_item(&inline_item),
- rect(rect),
- children_count(children_count) {}
- // Crete a bidi control. A bidi control does not have a fragment, but has
- // bidi level and affects bidi reordering.
- Child(UBiDiLevel bidi_level) : bidi_level(bidi_level) {}
- // Create an in-flow |NGLayoutResult|.
- Child(scoped_refptr<const NGLayoutResult> layout_result,
- const LogicalRect& rect,
- unsigned children_count,
- UBiDiLevel bidi_level)
- : layout_result(std::move(layout_result)),
- rect(rect),
- children_count(children_count),
- bidi_level(bidi_level) {}
- Child(scoped_refptr<const NGLayoutResult> layout_result,
- LogicalOffset offset,
- LayoutUnit inline_size,
- unsigned children_count,
- UBiDiLevel bidi_level)
- : layout_result(std::move(layout_result)),
- rect(offset, LogicalSize()),
- inline_size(inline_size),
- children_count(children_count),
- bidi_level(bidi_level) {}
- // Create an in-flow text fragment.
- Child(NGInlineItemResult* item_result,
- LayoutUnit block_offset,
- LayoutUnit inline_size,
- LayoutUnit text_height,
- UBiDiLevel bidi_level)
- : item_result(item_result),
- rect(LayoutUnit(), block_offset, LayoutUnit(), text_height),
- inline_size(inline_size),
- bidi_level(bidi_level) {}
- Child(scoped_refptr<const NGPhysicalTextFragment> fragment,
- LogicalOffset offset,
- LayoutUnit inline_size,
- UBiDiLevel bidi_level)
- : fragment(std::move(fragment)),
- rect(offset, LogicalSize()),
- inline_size(inline_size),
- bidi_level(bidi_level) {}
- Child(scoped_refptr<const NGPhysicalTextFragment> fragment,
- LayoutUnit block_offset,
- LayoutUnit inline_size,
- UBiDiLevel bidi_level)
- : fragment(std::move(fragment)),
- rect(LayoutUnit(), block_offset, LayoutUnit(), LayoutUnit()),
- inline_size(inline_size),
- bidi_level(bidi_level) {}
- // Create an out-of-flow positioned object.
- Child(LayoutObject* out_of_flow_positioned_box,
- UBiDiLevel bidi_level,
- TextDirection container_direction)
- : out_of_flow_positioned_box(out_of_flow_positioned_box),
- bidi_level(bidi_level),
- container_direction(container_direction) {}
- // Create an unpositioned float.
- Child(LayoutObject* unpositioned_float, UBiDiLevel bidi_level)
- : unpositioned_float(unpositioned_float), bidi_level(bidi_level) {}
- // Create a positioned float.
- Child(scoped_refptr<const NGLayoutResult> layout_result,
- NGBfcOffset bfc_offset,
- UBiDiLevel bidi_level)
- : layout_result(std::move(layout_result)),
- bfc_offset(bfc_offset),
- bidi_level(bidi_level) {}
-
- bool HasInFlowFragment() const {
- if (fragment_item)
- return true;
- if (fragment)
- return true;
- if (item_result)
- return true;
- if (layout_result && !layout_result->PhysicalFragment().IsFloating())
- return true;
-
- return false;
- }
- bool HasOutOfFlowFragment() const { return out_of_flow_positioned_box; }
- bool HasFragment() const {
- return HasInFlowFragment() || HasOutOfFlowFragment();
- }
- bool HasBidiLevel() const { return bidi_level != 0xff; }
- bool IsPlaceholder() const { return !HasFragment() && !HasBidiLevel(); }
- bool IsOpaqueToBidiReordering() const {
- if (IsPlaceholder())
- return true;
- // Skip all inline boxes. Fragments for inline boxes maybe created earlier
- // if they have no children.
- if (layout_result) {
- const LayoutObject* layout_object =
- layout_result->PhysicalFragment().GetLayoutObject();
- DCHECK(layout_object);
- if (layout_object->IsLayoutInline())
- return true;
- }
- return false;
- }
- const LogicalOffset& Offset() const { return rect.offset; }
- LayoutUnit InlineOffset() const { return rect.offset.inline_offset; }
- const LogicalSize& Size() const { return rect.size; }
- const NGPhysicalFragment* PhysicalFragment() const {
- if (layout_result)
- return &layout_result->PhysicalFragment();
- return fragment.get();
- }
- TextDirection ResolvedDirection() const {
- // Inline boxes are not leaves that they don't have directions.
- DCHECK(HasBidiLevel() || layout_result->PhysicalFragment().IsInlineBox());
- return HasBidiLevel() ? DirectionFromLevel(bidi_level)
- : TextDirection::kLtr;
- }
- };
-
- // A vector of Child.
- // Unlike the fragment builder, chlidren are mutable.
- // Callers can add to the fragment builder in a batch once finalized.
- class ChildList {
- STACK_ALLOCATED();
-
- public:
- ChildList() = default;
- void operator=(ChildList&& other) {
- children_ = std::move(other.children_);
- }
-
- Child& operator[](wtf_size_t i) { return children_[i]; }
- const Child& operator[](wtf_size_t i) const { return children_[i]; }
-
- wtf_size_t size() const { return children_.size(); }
- bool IsEmpty() const { return children_.IsEmpty(); }
- void ReserveInitialCapacity(unsigned capacity) {
- children_.ReserveInitialCapacity(capacity);
- }
- void clear() { children_.resize(0); }
- void resize(wtf_size_t size) { children_.resize(size); }
-
- using iterator = Vector<Child, 16>::iterator;
- iterator begin() { return children_.begin(); }
- iterator end() { return children_.end(); }
- using const_iterator = Vector<Child, 16>::const_iterator;
- const_iterator begin() const { return children_.begin(); }
- const_iterator end() const { return children_.end(); }
- using reverse_iterator = Vector<Child, 16>::reverse_iterator;
- reverse_iterator rbegin() { return children_.rbegin(); }
- reverse_iterator rend() { return children_.rend(); }
- using const_reverse_iterator = Vector<Child, 16>::const_reverse_iterator;
- const_reverse_iterator rbegin() const { return children_.rbegin(); }
- const_reverse_iterator rend() const { return children_.rend(); }
-
- Child* FirstInFlowChild();
- Child* LastInFlowChild();
-
- // Add a child. Accepts all constructor arguments for |Child|.
- template <class... Args>
- void AddChild(Args&&... args) {
- children_.emplace_back(std::forward<Args>(args)...);
- }
- void InsertChild(unsigned index);
- void InsertChild(unsigned index,
- scoped_refptr<const NGLayoutResult> layout_result,
- const LogicalRect& rect,
- unsigned children_count) {
- WillInsertChild(index);
- children_.insert(index, Child(std::move(layout_result), rect,
- children_count, /* bidi_level */ 0));
- }
- void InsertChild(unsigned index,
- const NGInlineItem& inline_item,
- const LogicalRect& rect,
- unsigned children_count) {
- WillInsertChild(index);
- children_.insert(index, Child(inline_item, rect, children_count));
- }
-
- void MoveInInlineDirection(LayoutUnit);
- void MoveInInlineDirection(LayoutUnit, unsigned start, unsigned end);
- void MoveInBlockDirection(LayoutUnit);
- void MoveInBlockDirection(LayoutUnit, unsigned start, unsigned end);
-
- // Create |NGPhysicalTextFragment| for all text children.
- void CreateTextFragments(WritingMode writing_mode,
- const String& text_content);
-
- private:
- void WillInsertChild(unsigned index);
-
- Vector<Child, 16> children_;
- };
-
// Add all items in ChildList. Skips null Child if any.
- void AddChildren(ChildList&);
+ void AddChildren(NGLogicalLineItems&);
// Propagate data in |ChildList| without adding them to this builder. When
// adding children as fragment items, they appear in the container, but there
// are some data that should be propagated through line box fragments.
- void PropagateChildrenData(ChildList&);
+ void PropagateChildrenData(NGLogicalLineItems&);
// Creates the fragment. Can only be called once.
scoped_refptr<const NGLayoutResult> ToLineBoxFragment();
@@ -331,7 +96,4 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
} // namespace blink
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
- blink::NGLineBoxFragmentBuilder::Child)
-
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_LINE_BOX_FRAGMENT_BUILDER_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
index 1964973a226..45a4869ac14 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
@@ -93,7 +94,7 @@ inline void ComputeCanBreakAfter(NGInlineItemResult* item_result,
bool auto_wrap,
const LazyLineBreakIterator& break_iterator) {
item_result->can_break_after =
- auto_wrap && break_iterator.IsBreakable(item_result->end_offset);
+ auto_wrap && break_iterator.IsBreakable(item_result->EndOffset());
}
inline void RemoveLastItem(NGLineInfo* line_info) {
@@ -235,8 +236,9 @@ inline NGInlineItemResult* NGLineBreaker::AddItem(const NGInlineItem& item,
DCHECK_LE(end_offset, item.EndOffset());
NGInlineItemResults* item_results = line_info->MutableResults();
return &item_results->emplace_back(
- &item, item_index_, offset_, end_offset, break_anywhere_if_overflow_,
- ShouldCreateLineBox(*item_results), HasUnpositionedFloats(*item_results));
+ &item, item_index_, NGTextOffset(offset_, end_offset),
+ break_anywhere_if_overflow_, ShouldCreateLineBox(*item_results),
+ HasUnpositionedFloats(*item_results));
}
inline NGInlineItemResult* NGLineBreaker::AddItem(const NGInlineItem& item,
@@ -350,7 +352,8 @@ void NGLineBreaker::NextLine(
// line boxes. These cases need to be reviewed.
bool should_create_line_box = ShouldCreateLineBox(item_results) ||
(has_list_marker_ && line_info->IsLastLine()) ||
- mode_ != NGLineBreakerMode::kContent;
+ mode_ != NGLineBreakerMode::kContent ||
+ node_.HasLineEvenIfEmpty();
if (!should_create_line_box)
line_info->SetIsEmptyLine();
@@ -443,7 +446,7 @@ void NGLineBreaker::BreakLine(
// determine the break opportunity.
NGInlineItemResult* item_result = AddItem(item, line_info);
item_result->can_break_after =
- break_iterator_.IsBreakable(item_result->end_offset);
+ break_iterator_.IsBreakable(item_result->EndOffset());
MoveToNextOf(item);
} else if (item.Type() == NGInlineItem::kListMarker) {
NGInlineItemResult* item_result = AddItem(item, line_info);
@@ -480,23 +483,23 @@ bool NGLineBreaker::ShouldForceCanBreakAfter(
DCHECK(auto_wrap_);
DCHECK_EQ(item_result.item->Type(), NGInlineItem::kText);
const String& text = Text();
- DCHECK_GE(text.length(), item_result.end_offset);
- if (text.length() <= item_result.end_offset ||
- text[item_result.end_offset] != kObjectReplacementCharacter)
+ DCHECK_GE(text.length(), item_result.EndOffset());
+ if (text.length() <= item_result.EndOffset() ||
+ text[item_result.EndOffset()] != kObjectReplacementCharacter)
return false;
// This kObjectReplacementCharacter can be any objects, such as a floating or
// an OOF object. Check if it's really an atomic inline.
const Vector<NGInlineItem>& items = Items();
for (const NGInlineItem* item = std::next(item_result.item);
item != items.end(); ++item) {
- DCHECK_EQ(item->StartOffset(), item_result.end_offset);
+ DCHECK_EQ(item->StartOffset(), item_result.EndOffset());
if (item->Type() == NGInlineItem::kAtomicInline) {
// Except when sticky images quirk was applied.
if (UNLIKELY(text[item->StartOffset()] == kNoBreakSpaceCharacter))
return false;
- return true;
+ return !item->IsRubyRun();
}
- if (item->EndOffset() > item_result.end_offset)
+ if (item->EndOffset() > item_result.EndOffset())
break;
}
return false;
@@ -556,6 +559,12 @@ void NGLineBreaker::HandleText(const NGInlineItem& item,
NGInlineItemResult* item_result = AddItem(item, line_info);
item_result->should_create_line_box = true;
+ // Try to commit |pending_end_overhang_| of a prior NGInlineItemResult.
+ // |pending_end_overhang_| doesn't work well with bidi reordering. It's
+ // difficult to compute overhang after bidi reordering because it affect
+ // line breaking.
+ if (maybe_have_end_overhang_)
+ position_ -= CommitPendingEndOverhang(line_info);
if (auto_wrap_) {
if (mode_ == NGLineBreakerMode::kMinContent &&
@@ -582,7 +591,7 @@ void NGLineBreaker::HandleText(const NGInlineItem& item,
// If the break is at the middle of a text item, we know no trailable
// items follow, only trailable spaces if any. This is very common that
// shortcut to handling trailing spaces.
- if (item_result->end_offset < item.EndOffset())
+ if (item_result->EndOffset() < item.EndOffset())
return HandleTrailingSpaces(item, shape_result, line_info);
// The break point found at the end of this text item. Continue looking
@@ -608,8 +617,8 @@ void NGLineBreaker::HandleText(const NGInlineItem& item,
// If this is all trailable spaces, this item is trailable, and next item
// maybe too. Don't go to |HandleOverflow()| yet.
- if (IsAllBreakableSpaces(Text(), item_result->start_offset,
- item_result->end_offset))
+ if (IsAllBreakableSpaces(Text(), item_result->StartOffset(),
+ item_result->EndOffset()))
return;
HandleOverflow(line_info);
@@ -618,8 +627,8 @@ void NGLineBreaker::HandleText(const NGInlineItem& item,
// Add until the end of the item if !auto_wrap. In most cases, it's the whole
// item.
- DCHECK_EQ(item_result->end_offset, item.EndOffset());
- if (item_result->start_offset == item.StartOffset()) {
+ DCHECK_EQ(item_result->EndOffset(), item.EndOffset());
+ if (item_result->StartOffset() == item.StartOffset()) {
item_result->inline_size =
shape_result.SnappedWidth().ClampNegativeToZero();
item_result->shape_result = ShapeResultView::Create(&shape_result);
@@ -627,9 +636,9 @@ void NGLineBreaker::HandleText(const NGInlineItem& item,
// <wbr> can wrap even if !auto_wrap. Spaces after that will be leading
// spaces and thus be collapsed.
DCHECK(trailing_whitespace_ == WhitespaceState::kLeading &&
- item_result->start_offset >= item.StartOffset());
+ item_result->StartOffset() >= item.StartOffset());
item_result->shape_result = ShapeResultView::Create(
- &shape_result, item_result->start_offset, item_result->end_offset);
+ &shape_result, item_result->StartOffset(), item_result->EndOffset());
item_result->inline_size =
item_result->shape_result->SnappedWidth().ClampNegativeToZero();
}
@@ -652,7 +661,7 @@ NGLineBreaker::BreakResult NGLineBreaker::BreakText(
(item.Type() == NGInlineItem::kControl &&
Text()[item.StartOffset()] == kTabulationCharacter));
DCHECK(&item_shape_result);
- item.AssertOffset(item_result->start_offset);
+ item.AssertOffset(item_result->StartOffset());
DCHECK_EQ(item_shape_result.StartIndex(), item.StartOffset());
DCHECK_EQ(item_shape_result.EndIndex(), item.EndOffset());
@@ -676,7 +685,7 @@ NGLineBreaker::BreakResult NGLineBreaker::BreakText(
// Use kStartShouldBeSafe if at the beginning of a line.
unsigned options = ShapingLineBreaker::kDefaultOptions;
- if (item_result->start_offset != line_info->StartOffset())
+ if (item_result->StartOffset() != line_info->StartOffset())
options |= ShapingLineBreaker::kDontReshapeStart;
// Reshaping between the last character and trailing spaces is needed only
@@ -702,7 +711,7 @@ NGLineBreaker::BreakResult NGLineBreaker::BreakText(
DCHECK_LE(try_count, 2u);
#endif
scoped_refptr<const ShapeResultView> shape_result = breaker.ShapeLine(
- item_result->start_offset, available_width.ClampNegativeToZero(),
+ item_result->StartOffset(), available_width.ClampNegativeToZero(),
options, &result);
// If this item overflows and 'break-word' is set, this line will be
@@ -710,14 +719,15 @@ NGLineBreaker::BreakResult NGLineBreaker::BreakText(
if (!shape_result) {
DCHECK(options & ShapingLineBreaker::kNoResultIfOverflow);
item_result->inline_size = available_width_with_hyphens + 1;
- item_result->end_offset = item.EndOffset();
+ item_result->text_offset.end = item.EndOffset();
+ item_result->text_offset.AssertNotEmpty();
return kOverflow;
}
DCHECK_EQ(shape_result->NumCharacters(),
- result.break_offset - item_result->start_offset);
+ result.break_offset - item_result->StartOffset());
// It is critical to move the offset forward, or NGLineBreaker may keep
// adding NGInlineItemResult until all the memory is consumed.
- CHECK_GT(result.break_offset, item_result->start_offset);
+ CHECK_GT(result.break_offset, item_result->StartOffset());
inline_size = shape_result->SnappedWidth().ClampNegativeToZero();
if (UNLIKELY(result.is_hyphenated)) {
@@ -741,7 +751,8 @@ NGLineBreaker::BreakResult NGLineBreaker::BreakText(
item_result->hyphen_string = String();
}
item_result->inline_size = inline_size;
- item_result->end_offset = result.break_offset;
+ item_result->text_offset.end = result.break_offset;
+ item_result->text_offset.AssertNotEmpty();
item_result->shape_result = std::move(shape_result);
break;
}
@@ -754,7 +765,7 @@ NGLineBreaker::BreakResult NGLineBreaker::BreakText(
// * If width > available_width: The first break opportunity does not fit.
// offset is the first break opportunity, either inside, at the end, or
// beyond the end.
- if (item_result->end_offset < item.EndOffset()) {
+ if (item_result->EndOffset() < item.EndOffset()) {
item_result->can_break_after = true;
if (UNLIKELY(break_iterator_.BreakType() ==
@@ -764,9 +775,9 @@ NGLineBreaker::BreakResult NGLineBreaker::BreakText(
trailing_whitespace_ = WhitespaceState::kNone;
}
} else {
- DCHECK_EQ(item_result->end_offset, item.EndOffset());
+ DCHECK_EQ(item_result->EndOffset(), item.EndOffset());
item_result->can_break_after =
- break_iterator_.IsBreakable(item_result->end_offset);
+ break_iterator_.IsBreakable(item_result->EndOffset());
if (!item_result->can_break_after && item.Type() == NGInlineItem::kText &&
ShouldForceCanBreakAfter(*item_result))
item_result->can_break_after = true;
@@ -783,7 +794,7 @@ NGLineBreaker::BreakResult NGLineBreaker::BreakText(
}
// Breaks the text item at the previous break opportunity from
-// |item_result->end_offset|. Returns false if there were no previous break
+// |item_result->text_offset.end|. Returns false if there were no previous break
// opportunities.
bool NGLineBreaker::BreakTextAtPreviousBreakOpportunity(
NGInlineItemResult* item_result) {
@@ -794,13 +805,14 @@ bool NGLineBreaker::BreakTextAtPreviousBreakOpportunity(
DCHECK(item.Style() && item.Style()->AutoWrap());
unsigned break_opportunity = break_iterator_.PreviousBreakOpportunity(
- item_result->end_offset - 1, item_result->start_offset);
- if (break_opportunity <= item_result->start_offset)
+ item_result->EndOffset() - 1, item_result->StartOffset());
+ if (break_opportunity <= item_result->StartOffset())
return false;
- item_result->end_offset = break_opportunity;
- item_result->shape_result =
- ShapeResultView::Create(item.TextShapeResult(), item_result->start_offset,
- item_result->end_offset);
+ item_result->text_offset.end = break_opportunity;
+ item_result->text_offset.AssertNotEmpty();
+ item_result->shape_result = ShapeResultView::Create(
+ item.TextShapeResult(), item_result->StartOffset(),
+ item_result->EndOffset());
item_result->inline_size =
item_result->shape_result->SnappedWidth().ClampNegativeToZero();
item_result->can_break_after = true;
@@ -832,7 +844,7 @@ bool NGLineBreaker::HandleTextForFastMinContent(NGInlineItemResult* item_result,
// If this is the first part of the text, it may form a word with the previous
// item. Fallback to |HandleText()|.
- unsigned start_offset = item_result->start_offset;
+ unsigned start_offset = item_result->StartOffset();
DCHECK_LT(start_offset, item.EndOffset());
if (start_offset != line_info->StartOffset() &&
start_offset == item.StartOffset())
@@ -895,7 +907,8 @@ bool NGLineBreaker::HandleTextForFastMinContent(NGInlineItemResult* item_result,
return false;
// Create an NGInlineItemResult that has the max of widths of all words.
- item_result->end_offset = last_end_offset;
+ item_result->text_offset.end = last_end_offset;
+ item_result->text_offset.AssertNotEmpty();
item_result->inline_size = LayoutUnit::FromFloatCeil(min_width);
item_result->can_break_after = true;
@@ -945,7 +958,7 @@ scoped_refptr<ShapeResultView> NGLineBreaker::TruncateLineEndResult(
const NGInlineItem& item = *item_result.item;
// Check given offsets require to truncate |item_result.shape_result|.
- const unsigned start_offset = item_result.start_offset;
+ const unsigned start_offset = item_result.StartOffset();
const ShapeResultView* source_result = item_result.shape_result.get();
DCHECK(source_result);
DCHECK_GE(start_offset, source_result->StartIndex());
@@ -978,7 +991,7 @@ void NGLineBreaker::UpdateShapeResult(const NGLineInfo& line_info,
NGInlineItemResult* item_result) {
DCHECK(item_result);
item_result->shape_result =
- TruncateLineEndResult(line_info, *item_result, item_result->end_offset);
+ TruncateLineEndResult(line_info, *item_result, item_result->EndOffset());
DCHECK(item_result->shape_result);
item_result->inline_size = item_result->shape_result->SnappedWidth();
}
@@ -1038,8 +1051,8 @@ void NGLineBreaker::HandleTrailingSpaces(const NGInlineItem& item,
NGInlineItemResult* item_result = AddItem(item, end, line_info);
item_result->has_only_trailing_spaces = true;
item_result->shape_result = ShapeResultView::Create(&shape_result);
- if (item_result->start_offset == item.StartOffset() &&
- item_result->end_offset == item.EndOffset())
+ if (item_result->StartOffset() == item.StartOffset() &&
+ item_result->EndOffset() == item.EndOffset())
item_result->inline_size = item_result->shape_result->SnappedWidth();
else
UpdateShapeResult(*line_info, item_result);
@@ -1079,7 +1092,7 @@ void NGLineBreaker::RemoveTrailingCollapsibleSpace(NGLineInfo* line_info) {
if (end_index < item_results.size()) {
const NGInlineItemResult& end_item_result = item_results[end_index];
unsigned end_item_index = end_item_result.item_index;
- unsigned end_offset = end_item_result.start_offset;
+ unsigned end_offset = end_item_result.StartOffset();
ResetRewindLoopDetector();
Rewind(end_index, line_info);
item_index_ = end_item_index;
@@ -1100,8 +1113,8 @@ void NGLineBreaker::RemoveTrailingCollapsibleSpace(NGLineInfo* line_info) {
position_ -= item_result->inline_size;
if (scoped_refptr<const ShapeResultView>& collapsed_shape_result =
trailing_collapsible_space_->collapsed_shape_result) {
- DCHECK_GE(item_result->end_offset, item_result->start_offset + 2);
- --item_result->end_offset;
+ --item_result->text_offset.end;
+ item_result->text_offset.AssertNotEmpty();
item_result->shape_result = collapsed_shape_result;
item_result->inline_size = item_result->shape_result->SnappedWidth();
position_ += item_result->inline_size;
@@ -1152,9 +1165,9 @@ void NGLineBreaker::ComputeTrailingCollapsibleSpace(NGLineInfo* line_info) {
if (item.EndCollapseType() == NGInlineItem::kOpaqueToCollapsing)
continue;
if (item.Type() == NGInlineItem::kText) {
- DCHECK_GT(item_result.end_offset, 0u);
+ DCHECK_GT(item_result.EndOffset(), 0u);
DCHECK(item.Style());
- if (!IsBreakableSpace(text[item_result.end_offset - 1]))
+ if (!IsBreakableSpace(text[item_result.EndOffset() - 1]))
break;
if (!item.Style()->CollapseWhiteSpace()) {
trailing_whitespace_ = WhitespaceState::kPreserved;
@@ -1169,10 +1182,10 @@ void NGLineBreaker::ComputeTrailingCollapsibleSpace(NGLineInfo* line_info) {
trailing_collapsible_space_->item_result != &item_result) {
trailing_collapsible_space_.emplace();
trailing_collapsible_space_->item_result = &item_result;
- if (item_result.end_offset - 1 > item_result.start_offset) {
+ if (item_result.EndOffset() - 1 > item_result.StartOffset()) {
trailing_collapsible_space_->collapsed_shape_result =
TruncateLineEndResult(*line_info, item_result,
- item_result.end_offset - 1);
+ item_result.EndOffset() - 1);
}
}
trailing_whitespace_ = WhitespaceState::kCollapsible;
@@ -1377,7 +1390,8 @@ void NGLineBreaker::HandleAtomicInline(
} else {
DCHECK(mode_ == NGLineBreakerMode::kMinContent || !max_size_cache_);
NGBlockNode child(ToLayoutBox(item.GetLayoutObject()));
- MinMaxSizesInput input(percentage_resolution_block_size_for_min_max);
+ MinMaxSizesInput input(percentage_resolution_block_size_for_min_max,
+ MinMaxSizesType::kContent);
MinMaxSizesResult result =
ComputeMinAndMaxContentContribution(node_.Style(), child, input);
if (mode_ == NGLineBreakerMode::kMinContent) {
@@ -1405,6 +1419,25 @@ void NGLineBreaker::HandleAtomicInline(
auto_wrap_ && !(sticky_images_quirk_ && item.IsImage());
position_ += item_result->inline_size;
+
+ if (item.IsRubyRun()) {
+ // Overrides can_break_after.
+ ComputeCanBreakAfter(item_result, auto_wrap_, break_iterator_);
+
+ NGAnnotationOverhang overhang = GetOverhang(*item_result);
+ if (overhang.end > LayoutUnit()) {
+ item_result->pending_end_overhang = overhang.end;
+ maybe_have_end_overhang_ = true;
+ }
+
+ if (CanApplyStartOverhang(*line_info, overhang.start)) {
+ DCHECK_EQ(item_result->margins.inline_start, LayoutUnit());
+ item_result->margins.inline_start = -overhang.start;
+ item_result->inline_size -= overhang.start;
+ position_ -= overhang.start;
+ }
+ }
+
trailing_whitespace_ = WhitespaceState::kNone;
MoveToNextOf(item);
}
@@ -1640,8 +1673,8 @@ void NGLineBreaker::HandleCloseTag(const NGInlineItem& item,
// iterator cannot compute this because it considers break opportunities are
// before a run of spaces.
const String& text = Text();
- if (item_result->end_offset < text.length() &&
- IsBreakableSpace(text[item_result->end_offset])) {
+ if (item_result->EndOffset() < text.length() &&
+ IsBreakableSpace(text[item_result->EndOffset()])) {
item_result->can_break_after = true;
return;
}
@@ -1720,7 +1753,7 @@ void NGLineBreaker::HandleOverflow(NGLineInfo* line_info) {
BreakText(item_result, item, *item.TextShapeResult(),
std::min(item_available_width, min_available_width),
item_available_width, line_info);
- DCHECK_LE(item_result->end_offset, item_result_before.end_offset);
+ DCHECK_LE(item_result->EndOffset(), item_result_before.EndOffset());
#if DCHECK_IS_ON()
item_result->CheckConsistency(true);
#endif
@@ -1728,8 +1761,8 @@ void NGLineBreaker::HandleOverflow(NGLineInfo* line_info) {
// If BreakText() changed this item small enough to fit, break here.
if (item_result->can_break_after &&
item_result->inline_size <= item_available_width &&
- item_result->end_offset < item_result_before.end_offset) {
- DCHECK_LT(item_result->end_offset, item.EndOffset());
+ item_result->EndOffset() < item_result_before.EndOffset()) {
+ DCHECK_LT(item_result->EndOffset(), item.EndOffset());
// If this is the last item, adjust it to accommodate the change.
const unsigned new_end = i + 1;
@@ -1739,7 +1772,7 @@ void NGLineBreaker::HandleOverflow(NGLineInfo* line_info) {
available_width + width_to_rewind + item_result->inline_size;
DCHECK_EQ(position_, line_info->ComputeWidth());
item_index_ = item_result->item_index;
- offset_ = item_result->end_offset;
+ offset_ = item_result->EndOffset();
items_data_.AssertOffset(item_index_, offset_);
HandleTrailingSpaces(item, line_info);
return;
@@ -1818,11 +1851,11 @@ void NGLineBreaker::RewindOverflow(unsigned new_end, NGLineInfo* line_info) {
const EWhiteSpace white_space = item.Style()->WhiteSpace();
if (ComputedStyle::AutoWrap(white_space) &&
white_space != EWhiteSpace::kBreakSpaces &&
- IsBreakableSpace(text[item_result.start_offset])) {
+ IsBreakableSpace(text[item_result.StartOffset()])) {
// If all characters are trailable spaces, check the next item.
if (item_result.shape_result &&
- IsAllBreakableSpaces(text, item_result.start_offset + 1,
- item_result.end_offset)) {
+ IsAllBreakableSpaces(text, item_result.StartOffset() + 1,
+ item_result.EndOffset())) {
continue;
}
// If this item starts with spaces followed by non-space characters,
@@ -1842,7 +1875,7 @@ void NGLineBreaker::RewindOverflow(unsigned new_end, NGLineInfo* line_info) {
// All control characters except newline are trailable if auto_wrap. We
// should not have rewound if there was a newline, so safe to assume all
// controls are trailable.
- DCHECK_NE(text[item_result.start_offset], kNewlineCharacter);
+ DCHECK_NE(text[item_result.StartOffset()], kNewlineCharacter);
DCHECK(item.Style());
EWhiteSpace white_space = item.Style()->WhiteSpace();
if (ComputedStyle::AutoWrap(white_space) &&
@@ -1953,8 +1986,9 @@ void NGLineBreaker::Rewind(unsigned new_end, NGLineInfo* line_info) {
// When rewinding all items, use |results[0].start_offset|.
const NGInlineItemResult& first_remove = item_results[new_end];
item_index_ = first_remove.item_index;
- offset_ = first_remove.start_offset;
+ offset_ = first_remove.StartOffset();
trailing_whitespace_ = WhitespaceState::kLeading;
+ maybe_have_end_overhang_ = false;
}
SetCurrentStyle(ComputeCurrentStyle(new_end, line_info));
@@ -2077,7 +2111,7 @@ void NGLineBreaker::MoveToNextOf(const NGInlineItem& item) {
}
void NGLineBreaker::MoveToNextOf(const NGInlineItemResult& item_result) {
- offset_ = item_result.end_offset;
+ offset_ = item_result.EndOffset();
item_index_ = item_result.item_index;
DCHECK(item_result.item);
if (offset_ == item_result.item->EndOffset())
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
index 05481028298..32b872488dc 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
@@ -261,6 +261,9 @@ class CORE_EXPORT NGLineBreaker {
// between images, and between text and images.
bool sticky_images_quirk_ = false;
+ // True if the resultant line contains a RubyRun with inline-end overhang.
+ bool maybe_have_end_overhang_ = false;
+
const NGInlineItemsData& items_data_;
// The text content of this node. This is same as |items_data_.text_content|
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc
index 38160e6e800..54b6f646a29 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc
@@ -22,8 +22,7 @@ String ToString(NGInlineItemResults line, NGInlineNode node) {
const String& text = node.ItemsData(false).text_content;
for (const auto& item_result : line) {
builder.Append(
- StringView(text, item_result.start_offset,
- item_result.end_offset - item_result.start_offset));
+ StringView(text, item_result.StartOffset(), item_result.Length()));
}
return builder.ToString();
}
@@ -535,11 +534,12 @@ TEST_F(NGLineBreakerTest, MinMaxWithTrailingSpaces) {
<div id=container>12345 6789 </div>
)HTML");
- auto sizes = node.ComputeMinMaxSizes(
- WritingMode::kHorizontalTb,
- MinMaxSizesInput(/* percentage_resolution_block_size */ (
- LayoutUnit())))
- .sizes;
+ auto sizes =
+ node.ComputeMinMaxSizes(
+ WritingMode::kHorizontalTb,
+ MinMaxSizesInput(/* percentage_resolution_block_size */
+ LayoutUnit(), MinMaxSizesType::kContent))
+ .sizes;
EXPECT_EQ(sizes.min_size, LayoutUnit(60));
EXPECT_EQ(sizes.max_size, LayoutUnit(110));
}
@@ -563,10 +563,38 @@ TEST_F(NGLineBreakerTest, TableCellWidthCalculationQuirkOutOfFlow) {
node.ComputeMinMaxSizes(
WritingMode::kHorizontalTb,
- MinMaxSizesInput(/* percentage_resolution_block_size */ LayoutUnit()));
+ MinMaxSizesInput(/* percentage_resolution_block_size */ LayoutUnit(),
+ MinMaxSizesType::kContent));
// Pass if |ComputeMinMaxSize| doesn't hit DCHECK failures.
}
+// crbug.com/1091359
+TEST_F(NGLineBreakerTest, RewindRubyRun) {
+ NGInlineNode node = CreateInlineNode(R"HTML(
+<div id="container">
+<style>
+* {
+ -webkit-text-security:square;
+ font-size:16px;
+}
+</style>
+<big style="word-wrap: break-word">a
+<ruby dir="rtl">
+<rt>
+B AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+<svg></svg>
+<b>
+</rt>
+</ruby>
+ )HTML");
+
+ node.ComputeMinMaxSizes(
+ WritingMode::kHorizontalTb,
+ MinMaxSizesInput(/* percentage_resolution_block_size */ LayoutUnit(),
+ MinMaxSizesType::kContent));
+ // This test passes if no CHECK failures.
+}
+
#undef MAYBE_OverflowAtomicInline
} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc
index 0306094c1f4..98b3cf7d46b 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc
@@ -6,6 +6,7 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/platform/fonts/font_baseline.h"
@@ -38,6 +39,7 @@ NGLineTruncator::NGLineTruncator(const NGLineInfo& line_info)
const ComputedStyle& NGLineTruncator::EllipsisStyle() const {
// The ellipsis is styled according to the line style.
// https://drafts.csswg.org/css-ui/#ellipsing-details
+ DCHECK(line_style_);
return *line_style_;
}
@@ -57,20 +59,16 @@ void NGLineTruncator::SetupEllipsis() {
}
LayoutUnit NGLineTruncator::PlaceEllipsisNextTo(
- NGLineBoxFragmentBuilder::ChildList* line_box,
- NGLineBoxFragmentBuilder::Child* ellipsized_child) {
+ NGLogicalLineItems* line_box,
+ NGLogicalLineItem* ellipsized_child) {
// Create the ellipsis, associating it with the ellipsized child.
DCHECK(ellipsized_child->HasInFlowFragment());
LayoutObject* ellipsized_layout_object =
- ellipsized_child->PhysicalFragment()->GetMutableLayoutObject();
+ ellipsized_child->GetMutableLayoutObject();
DCHECK(ellipsized_layout_object);
DCHECK(ellipsized_layout_object->IsInline());
DCHECK(ellipsized_layout_object->IsText() ||
ellipsized_layout_object->IsAtomicInlineLevel());
- NGTextFragmentBuilder builder(line_style_->GetWritingMode());
- builder.SetText(ellipsized_layout_object, ellipsis_text_, &EllipsisStyle(),
- true /* is_ellipsis_style */,
- std::move(ellipsis_shape_result_));
// Now the offset of the ellpisis is determined. Place the ellpisis into the
// line box.
@@ -78,17 +76,23 @@ LayoutUnit NGLineTruncator::PlaceEllipsisNextTo(
IsLtr(line_direction_)
? ellipsized_child->InlineOffset() + ellipsized_child->inline_size
: ellipsized_child->InlineOffset() - ellipsis_width_;
- LayoutUnit ellpisis_ascent;
+ NGLineHeightMetrics ellipsis_metrics;
DCHECK(ellipsis_font_data_);
if (ellipsis_font_data_) {
- FontBaseline baseline_type = line_style_->GetFontBaseline();
- NGLineHeightMetrics ellipsis_metrics(ellipsis_font_data_->GetFontMetrics(),
- baseline_type);
- ellpisis_ascent = ellipsis_metrics.ascent;
+ ellipsis_metrics = NGLineHeightMetrics(
+ ellipsis_font_data_->GetFontMetrics(), line_style_->GetFontBaseline());
}
- line_box->AddChild(builder.ToTextFragment(),
- LogicalOffset{ellipsis_inline_offset, -ellpisis_ascent},
- ellipsis_width_, 0);
+
+ DCHECK(ellipsis_text_);
+ DCHECK(ellipsis_shape_result_.get());
+ NGTextFragmentBuilder builder(line_style_->GetWritingMode());
+ builder.SetText(ellipsized_layout_object, ellipsis_text_, &EllipsisStyle(),
+ NGStyleVariant::kEllipsis, std::move(ellipsis_shape_result_),
+ {ellipsis_width_, ellipsis_metrics.LineHeight()});
+ line_box->AddChild(
+ builder.ToTextFragment(),
+ LogicalOffset{ellipsis_inline_offset, -ellipsis_metrics.ascent},
+ ellipsis_width_, 0);
return ellipsis_inline_offset;
}
@@ -97,12 +101,13 @@ wtf_size_t NGLineTruncator::AddTruncatedChild(
bool leave_one_character,
LayoutUnit position,
TextDirection edge,
- NGLineBoxFragmentBuilder::ChildList* line_box,
+ NGLogicalLineItems* line_box,
NGInlineLayoutStateStack* box_states) {
- NGLineBoxFragmentBuilder::ChildList& line = *line_box;
-
+ NGLogicalLineItems& line = *line_box;
+ const NGLogicalLineItem& source_item = line[source_index];
+ DCHECK(source_item.shape_result);
scoped_refptr<ShapeResult> shape_result =
- line[source_index].fragment->TextShapeResult()->CreateShapeResult();
+ source_item.shape_result->CreateShapeResult();
unsigned text_offset = shape_result->OffsetToFit(position, edge);
if (IsLtr(edge) ? IsLeftMostOffset(*shape_result, text_offset)
: IsRightMostOffset(*shape_result, text_offset)) {
@@ -116,51 +121,41 @@ wtf_size_t NGLineTruncator::AddTruncatedChild(
edge);
}
- const auto& fragment = line[source_index].fragment;
- const bool keep_start = edge == fragment->ResolvedDirection();
- scoped_refptr<const NGPhysicalTextFragment> truncated_fragment =
- keep_start ? fragment->TrimText(fragment->StartOffset(),
- fragment->StartOffset() + text_offset)
- : fragment->TrimText(fragment->StartOffset() + text_offset,
- fragment->EndOffset());
- wtf_size_t new_index = line.size();
- line.AddChild();
+ const wtf_size_t new_index = line.size();
+ line.AddChild(TruncateText(source_item, *shape_result, text_offset, edge));
box_states->ChildInserted(new_index);
- line[new_index] = line[source_index];
- line[new_index].inline_size = line_style_->IsHorizontalWritingMode()
- ? truncated_fragment->Size().width
- : truncated_fragment->Size().height;
- line[new_index].fragment = std::move(truncated_fragment);
return new_index;
}
-LayoutUnit NGLineTruncator::TruncateLine(
- LayoutUnit line_width,
- NGLineBoxFragmentBuilder::ChildList* line_box,
- NGInlineLayoutStateStack* box_states) {
+LayoutUnit NGLineTruncator::TruncateLine(LayoutUnit line_width,
+ NGLogicalLineItems* line_box,
+ NGInlineLayoutStateStack* box_states) {
+ DCHECK(std::all_of(line_box->begin(), line_box->end(),
+ [](const auto& item) { return !item.fragment; }));
+
// Shape the ellipsis and compute its inline size.
SetupEllipsis();
// Loop children from the logical last to the logical first to determine where
// to place the ellipsis. Children maybe truncated or moved as part of the
// process.
- NGLineBoxFragmentBuilder::Child* ellipsized_child = nullptr;
- scoped_refptr<const NGPhysicalTextFragment> truncated_fragment;
+ NGLogicalLineItem* ellipsized_child = nullptr;
+ base::Optional<NGLogicalLineItem> truncated_child;
if (IsLtr(line_direction_)) {
- NGLineBoxFragmentBuilder::Child* first_child = line_box->FirstInFlowChild();
+ NGLogicalLineItem* first_child = line_box->FirstInFlowChild();
for (auto it = line_box->rbegin(); it != line_box->rend(); it++) {
auto& child = *it;
if (EllipsizeChild(line_width, ellipsis_width_, &child == first_child,
- &child, &truncated_fragment)) {
+ &child, &truncated_child)) {
ellipsized_child = &child;
break;
}
}
} else {
- NGLineBoxFragmentBuilder::Child* first_child = line_box->LastInFlowChild();
+ NGLogicalLineItem* first_child = line_box->LastInFlowChild();
for (auto& child : *line_box) {
if (EllipsizeChild(line_width, ellipsis_width_, &child == first_child,
- &child, &truncated_fragment)) {
+ &child, &truncated_child)) {
ellipsized_child = &child;
break;
}
@@ -172,28 +167,23 @@ LayoutUnit NGLineTruncator::TruncateLine(
return line_width;
// Truncate the text fragment if needed.
- if (truncated_fragment) {
- DCHECK(ellipsized_child->fragment);
+ if (truncated_child) {
// In order to preserve layout information before truncated, hide the
// original fragment and insert a truncated one.
size_t child_index_to_truncate = ellipsized_child - line_box->begin();
- line_box->InsertChild(child_index_to_truncate + 1);
+ line_box->InsertChild(child_index_to_truncate + 1,
+ std::move(*truncated_child));
box_states->ChildInserted(child_index_to_truncate + 1);
- NGLineBoxFragmentBuilder::Child* child_to_truncate =
+ NGLogicalLineItem* child_to_truncate =
&(*line_box)[child_index_to_truncate];
ellipsized_child = std::next(child_to_truncate);
- *ellipsized_child = *child_to_truncate;
+
HideChild(child_to_truncate);
- LayoutUnit new_inline_size = line_style_->IsHorizontalWritingMode()
- ? truncated_fragment->Size().width
- : truncated_fragment->Size().height;
- DCHECK_LE(new_inline_size, ellipsized_child->inline_size);
+ DCHECK_LE(ellipsized_child->inline_size, child_to_truncate->inline_size);
if (UNLIKELY(IsRtl(line_direction_))) {
ellipsized_child->rect.offset.inline_offset +=
- ellipsized_child->inline_size - new_inline_size;
+ child_to_truncate->inline_size - ellipsized_child->inline_size;
}
- ellipsized_child->inline_size = new_inline_size;
- ellipsized_child->fragment = std::move(truncated_fragment);
}
// Create the ellipsis, associating it with the ellipsized child.
@@ -212,24 +202,27 @@ LayoutUnit NGLineTruncator::TruncateLine(
// Children with IsPlaceholder() can appear anywhere.
LayoutUnit NGLineTruncator::TruncateLineInTheMiddle(
LayoutUnit line_width,
- NGLineBoxFragmentBuilder::ChildList* line_box,
+ NGLogicalLineItems* line_box,
NGInlineLayoutStateStack* box_states) {
// Shape the ellipsis and compute its inline size.
SetupEllipsis();
- NGLineBoxFragmentBuilder::ChildList& line = *line_box;
+ NGLogicalLineItems& line = *line_box;
wtf_size_t initial_index_left = kNotFound;
wtf_size_t initial_index_right = kNotFound;
for (wtf_size_t i = 0; i < line_box->size(); ++i) {
auto& child = line[i];
- if (!child.fragment && child.IsPlaceholder())
+ if (child.IsPlaceholder())
continue;
- if (child.HasOutOfFlowFragment() || !child.fragment ||
- !child.fragment->TextShapeResult()) {
+ if (!child.shape_result) {
if (initial_index_right != kNotFound)
break;
continue;
}
+ // Skip pseudo elements like ::before.
+ if (!child.GetNode())
+ continue;
+
if (initial_index_left == kNotFound)
initial_index_left = i;
initial_index_right = i;
@@ -378,7 +371,7 @@ LayoutUnit NGLineTruncator::TruncateLineInTheMiddle(
// Hide this child from being painted. Leaves a hidden fragment so that layout
// queries such as |offsetWidth| work as if it is not truncated.
-void NGLineTruncator::HideChild(NGLineBoxFragmentBuilder::Child* child) {
+void NGLineTruncator::HideChild(NGLogicalLineItem* child) {
DCHECK(child->HasInFlowFragment());
if (const NGPhysicalTextFragment* text = child->fragment.get()) {
@@ -393,22 +386,15 @@ void NGLineTruncator::HideChild(NGLineBoxFragmentBuilder::Child* child) {
if (fragment.HasOutOfFlowPositionedDescendants())
return;
- // If this child has self painting layer, not producing fragments will not
- // suppress painting because layers are painted separately. Move it out of
- // the clipping area.
- if (fragment.HasSelfPaintingLayer()) {
- // |available_width_| may not be enough when the containing block has
- // paddings, because clipping is at the content box but ellipsizing is at
- // the padding box. Just move to the max because we don't know paddings,
- // and max should do what we need.
- child->rect.offset.inline_offset = LayoutUnit::NearlyMax();
- return;
- }
-
child->layout_result = fragment.CloneAsHiddenForPaint();
return;
}
+ if (child->inline_item) {
+ child->is_hidden_for_paint = true;
+ return;
+ }
+
NOTREACHED();
}
@@ -419,9 +405,9 @@ bool NGLineTruncator::EllipsizeChild(
LayoutUnit line_width,
LayoutUnit ellipsis_width,
bool is_first_child,
- NGLineBoxFragmentBuilder::Child* child,
- scoped_refptr<const NGPhysicalTextFragment>* truncated_fragment) {
- DCHECK(truncated_fragment && !*truncated_fragment);
+ NGLogicalLineItem* child,
+ base::Optional<NGLogicalLineItem>* truncated_child) {
+ DCHECK(truncated_child && !*truncated_child);
// Leave out-of-flow children as is.
if (!child->HasInFlowFragment())
@@ -429,8 +415,7 @@ bool NGLineTruncator::EllipsizeChild(
// Inline boxes should not be ellipsized. Usually they will be created in the
// later phase, but empty inline box are already created.
- if (child->layout_result &&
- child->layout_result->PhysicalFragment().IsInlineBox())
+ if (child->IsInlineBox())
return false;
// Can't place ellipsis if this child is completely outside of the box.
@@ -449,19 +434,20 @@ bool NGLineTruncator::EllipsizeChild(
}
// At least part of this child is in the box.
- // If not all of this child can fit, try to truncate.
+ // If |child| can fit in the space, truncate this line at the end of |child|.
space_for_child -= ellipsis_width;
- if (space_for_child < child->inline_size &&
- !TruncateChild(space_for_child, is_first_child, *child,
- truncated_fragment)) {
- // This child is partially in the box, but it should not be visible because
- // earlier sibling will be truncated and ellipsized.
- if (!is_first_child)
- HideChild(child);
- return false;
- }
+ if (space_for_child >= child->inline_size)
+ return true;
- return true;
+ // If not all of this child can fit, try to truncate.
+ if (TruncateChild(space_for_child, is_first_child, *child, truncated_child))
+ return true;
+
+ // This child is partially in the box, but it can't be truncated to fit. It
+ // should not be visible because earlier sibling will be truncated.
+ if (!is_first_child)
+ HideChild(child);
+ return false;
}
// Truncate the specified child. Returns true if truncated successfully, false
@@ -474,50 +460,53 @@ bool NGLineTruncator::EllipsizeChild(
bool NGLineTruncator::TruncateChild(
LayoutUnit space_for_child,
bool is_first_child,
- const NGLineBoxFragmentBuilder::Child& child,
- scoped_refptr<const NGPhysicalTextFragment>* truncated_fragment) {
- DCHECK(truncated_fragment && !*truncated_fragment);
+ const NGLogicalLineItem& child,
+ base::Optional<NGLogicalLineItem>* truncated_child) {
+ DCHECK(truncated_child && !*truncated_child);
+ DCHECK(!child.fragment);
// If the space is not enough, try the next child.
if (space_for_child <= 0 && !is_first_child)
return false;
// Only text fragments can be truncated.
- if (!child.fragment)
- return is_first_child;
- auto& fragment = To<NGPhysicalTextFragment>(*child.fragment);
-
- // No need to truncate empty results.
- if (!fragment.TextShapeResult())
+ if (!child.shape_result)
return is_first_child;
// TODO(layout-dev): Add support for OffsetToFit to ShapeResultView to avoid
// this copy.
- scoped_refptr<blink::ShapeResult> shape_result =
- fragment.TextShapeResult()->CreateShapeResult();
- if (!shape_result)
- return is_first_child;
-
+ scoped_refptr<ShapeResult> shape_result =
+ child.shape_result->CreateShapeResult();
+ DCHECK(shape_result);
+ const NGTextOffset original_offset = child.text_offset;
// Compute the offset to truncate.
- unsigned new_length = shape_result->OffsetToFit(
+ unsigned offset_to_fit = shape_result->OffsetToFit(
IsLtr(line_direction_) ? space_for_child
: shape_result->Width() - space_for_child,
line_direction_);
- DCHECK_LE(new_length, fragment.TextLength());
- if (!new_length || new_length == fragment.TextLength()) {
+ DCHECK_LE(offset_to_fit, original_offset.Length());
+ if (!offset_to_fit || offset_to_fit == original_offset.Length()) {
if (!is_first_child)
return false;
- new_length = !new_length ? 1 : new_length - 1;
+ offset_to_fit = !offset_to_fit ? 1 : offset_to_fit - 1;
}
-
- // Truncate the text fragment.
- *truncated_fragment =
- line_direction_ == shape_result->Direction()
- ? fragment.TrimText(fragment.StartOffset(),
- fragment.StartOffset() + new_length)
- : fragment.TrimText(fragment.StartOffset() + new_length,
- fragment.EndOffset());
+ *truncated_child =
+ TruncateText(child, *shape_result, offset_to_fit, line_direction_);
return true;
}
+NGLogicalLineItem NGLineTruncator::TruncateText(const NGLogicalLineItem& item,
+ const ShapeResult& shape_result,
+ unsigned offset_to_fit,
+ TextDirection direction) {
+ const NGTextOffset new_text_offset =
+ direction == shape_result.Direction()
+ ? NGTextOffset(item.StartOffset(), item.StartOffset() + offset_to_fit)
+ : NGTextOffset(item.StartOffset() + offset_to_fit, item.EndOffset());
+ scoped_refptr<ShapeResultView> new_shape_result = ShapeResultView::Create(
+ &shape_result, new_text_offset.start, new_text_offset.end);
+ DCHECK(item.inline_item);
+ return NGLogicalLineItem(item, std::move(new_shape_result), new_text_offset);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h
index c65fa3ce5a4..024e2d3cfec 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h
@@ -14,6 +14,8 @@ namespace blink {
class NGInlineLayoutStateStack;
class NGLineInfo;
+class NGLogicalLineItems;
+struct NGLogicalLineItem;
// A class to truncate lines and place ellipsis, invoked by the CSS
// 'text-overflow: ellipsis' property.
@@ -30,13 +32,12 @@ class CORE_EXPORT NGLineTruncator final {
// |line_box| should be after bidi reorder, but before box fragments are
// created.
LayoutUnit TruncateLine(LayoutUnit line_width,
- NGLineBoxFragmentBuilder::ChildList* line_box,
+ NGLogicalLineItems* line_box,
NGInlineLayoutStateStack* box_states);
- LayoutUnit TruncateLineInTheMiddle(
- LayoutUnit line_width,
- NGLineBoxFragmentBuilder::ChildList* line_box,
- NGInlineLayoutStateStack* box_states);
+ LayoutUnit TruncateLineInTheMiddle(LayoutUnit line_width,
+ NGLogicalLineItems* line_box,
+ NGInlineLayoutStateStack* box_states);
private:
const ComputedStyle& EllipsisStyle() const;
@@ -45,9 +46,8 @@ class CORE_EXPORT NGLineTruncator final {
void SetupEllipsis();
// Add a child for ellipsis next to |ellipsized_child|.
- LayoutUnit PlaceEllipsisNextTo(
- NGLineBoxFragmentBuilder::ChildList* line_box,
- NGLineBoxFragmentBuilder::Child* ellipsized_child);
+ LayoutUnit PlaceEllipsisNextTo(NGLogicalLineItems* line_box,
+ NGLogicalLineItem* ellipsized_child);
static constexpr wtf_size_t kDidNotAddChild = WTF::kNotFound;
// Add a child with truncated text of (*line_box)[source_index].
@@ -65,20 +65,25 @@ class CORE_EXPORT NGLineTruncator final {
bool leave_one_character,
LayoutUnit position,
TextDirection edge,
- NGLineBoxFragmentBuilder::ChildList* line_box,
+ NGLogicalLineItems* line_box,
NGInlineLayoutStateStack* box_states);
- bool EllipsizeChild(
- LayoutUnit line_width,
- LayoutUnit ellipsis_width,
- bool is_first_child,
- NGLineBoxFragmentBuilder::Child*,
- scoped_refptr<const NGPhysicalTextFragment>* truncated_fragment);
- bool TruncateChild(
- LayoutUnit space_for_this_child,
- bool is_first_child,
- const NGLineBoxFragmentBuilder::Child& child,
- scoped_refptr<const NGPhysicalTextFragment>* truncated_fragment);
- void HideChild(NGLineBoxFragmentBuilder::Child* child);
+ bool EllipsizeChild(LayoutUnit line_width,
+ LayoutUnit ellipsis_width,
+ bool is_first_child,
+ NGLogicalLineItem*,
+ base::Optional<NGLogicalLineItem>* truncated_child);
+ bool TruncateChild(LayoutUnit space_for_this_child,
+ bool is_first_child,
+ const NGLogicalLineItem& child,
+ base::Optional<NGLogicalLineItem>* truncated_child);
+ // Create |NGLogicalLineItem| by truncating text |item| at |offset_to_fit|.
+ // |direction| specifies which side of the text is trimmed; if |kLtr|, it
+ // keeps the left end and trims the right end.
+ NGLogicalLineItem TruncateText(const NGLogicalLineItem& item,
+ const ShapeResult& shape_result,
+ unsigned offset_to_fit,
+ TextDirection direction);
+ void HideChild(NGLogicalLineItem* child);
scoped_refptr<const ComputedStyle> line_style_;
LayoutUnit available_width_;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.cc
new file mode 100644
index 00000000000..246b6c54f1b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.cc
@@ -0,0 +1,121 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h"
+
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.h"
+
+namespace blink {
+
+const LayoutObject* NGLogicalLineItem::GetLayoutObject() const {
+ if (inline_item)
+ return inline_item->GetLayoutObject();
+ if (const NGPhysicalFragment* fragment = PhysicalFragment())
+ return fragment->GetLayoutObject();
+ return nullptr;
+}
+
+LayoutObject* NGLogicalLineItem::GetMutableLayoutObject() const {
+ if (inline_item)
+ return inline_item->GetLayoutObject();
+ if (const NGPhysicalFragment* fragment = PhysicalFragment())
+ return fragment->GetMutableLayoutObject();
+ return nullptr;
+}
+
+const Node* NGLogicalLineItem::GetNode() const {
+ if (const LayoutObject* layout_object = GetLayoutObject())
+ return layout_object->GetNode();
+ return nullptr;
+}
+
+const ComputedStyle* NGLogicalLineItem::Style() const {
+ if (const auto* fragment = PhysicalFragment())
+ return &fragment->Style();
+ if (inline_item)
+ return inline_item->Style();
+ return nullptr;
+}
+
+void NGLogicalLineItems::CreateTextFragments(WritingMode writing_mode,
+ const String& text_content) {
+ NGTextFragmentBuilder text_builder(writing_mode);
+ for (auto& child : *this) {
+ if (const NGInlineItem* inline_item = child.inline_item) {
+ if (UNLIKELY(child.text_content)) {
+ // Create a generated text fragmment.
+ text_builder.SetText(inline_item->GetLayoutObject(), child.text_content,
+ inline_item->Style(), inline_item->StyleVariant(),
+ std::move(child.shape_result), child.MarginSize());
+ } else {
+ // Create a regular text fragmment.
+ DCHECK((inline_item->Type() == NGInlineItem::kText &&
+ (inline_item->TextType() == NGTextType::kNormal ||
+ inline_item->TextType() == NGTextType::kSymbolMarker)) ||
+ inline_item->Type() == NGInlineItem::kControl);
+ text_builder.SetItem(text_content, *inline_item,
+ std::move(child.shape_result), child.text_offset,
+ child.MarginSize());
+ }
+ text_builder.SetIsHiddenForPaint(child.is_hidden_for_paint);
+ DCHECK(!child.fragment);
+ child.fragment = text_builder.ToTextFragment();
+ }
+ }
+}
+
+NGLogicalLineItem* NGLogicalLineItems::FirstInFlowChild() {
+ for (auto& child : *this) {
+ if (child.HasInFlowFragment())
+ return &child;
+ }
+ return nullptr;
+}
+
+NGLogicalLineItem* NGLogicalLineItems::LastInFlowChild() {
+ for (auto it = rbegin(); it != rend(); it++) {
+ auto& child = *it;
+ if (child.HasInFlowFragment())
+ return &child;
+ }
+ return nullptr;
+}
+
+void NGLogicalLineItems::WillInsertChild(unsigned insert_before) {
+ unsigned index = 0;
+ for (NGLogicalLineItem& child : children_) {
+ if (index >= insert_before)
+ break;
+ if (child.children_count && index + child.children_count > insert_before)
+ ++child.children_count;
+ ++index;
+ }
+}
+
+void NGLogicalLineItems::MoveInInlineDirection(LayoutUnit delta) {
+ for (auto& child : children_)
+ child.rect.offset.inline_offset += delta;
+}
+
+void NGLogicalLineItems::MoveInInlineDirection(LayoutUnit delta,
+ unsigned start,
+ unsigned end) {
+ for (unsigned index = start; index < end; index++)
+ children_[index].rect.offset.inline_offset += delta;
+}
+
+void NGLogicalLineItems::MoveInBlockDirection(LayoutUnit delta) {
+ for (auto& child : children_)
+ child.rect.offset.block_offset += delta;
+}
+
+void NGLogicalLineItems::MoveInBlockDirection(LayoutUnit delta,
+ unsigned start,
+ unsigned end) {
+ for (unsigned index = start; index < end; index++)
+ children_[index].rect.offset.block_offset += delta;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h
new file mode 100644
index 00000000000..92eaa4b0eaa
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h
@@ -0,0 +1,301 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_LOGICAL_LINE_ITEM_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_LOGICAL_LINE_ITEM_H_
+
+#include "third_party/blink/renderer/core/layout/geometry/logical_rect.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+class LayoutObject;
+
+// This class represents an item in a line, after line break, but still mutable
+// and in the logical coordinate system.
+struct NGLogicalLineItem {
+ DISALLOW_NEW();
+
+ // Empty constructor needed for |resize()|.
+ NGLogicalLineItem() = default;
+ // Create a placeholder. A placeholder does not have a fragment nor a bidi
+ // level.
+ NGLogicalLineItem(LayoutUnit block_offset, LayoutUnit block_size)
+ : rect(LayoutUnit(), block_offset, LayoutUnit(), block_size) {}
+ // Crete a bidi control. A bidi control does not have a fragment, but has
+ // bidi level and affects bidi reordering.
+ explicit NGLogicalLineItem(UBiDiLevel bidi_level) : bidi_level(bidi_level) {}
+ // Create an in-flow |NGLayoutResult|.
+ NGLogicalLineItem(scoped_refptr<const NGLayoutResult> layout_result,
+ const LogicalRect& rect,
+ unsigned children_count,
+ UBiDiLevel bidi_level)
+ : layout_result(std::move(layout_result)),
+ rect(rect),
+ children_count(children_count),
+ bidi_level(bidi_level) {}
+ NGLogicalLineItem(scoped_refptr<const NGLayoutResult> layout_result,
+ LogicalOffset offset,
+ LayoutUnit inline_size,
+ unsigned children_count,
+ UBiDiLevel bidi_level)
+ : layout_result(std::move(layout_result)),
+ rect(offset, LogicalSize()),
+ inline_size(inline_size),
+ children_count(children_count),
+ bidi_level(bidi_level) {}
+ // Create an in-flow text fragment.
+ NGLogicalLineItem(const NGInlineItem& inline_item,
+ scoped_refptr<const ShapeResultView> shape_result,
+ const NGTextOffset& text_offset,
+ LayoutUnit block_offset,
+ LayoutUnit inline_size,
+ LayoutUnit text_height,
+ UBiDiLevel bidi_level)
+ : inline_item(&inline_item),
+ shape_result(std::move(shape_result)),
+ text_offset(text_offset),
+ rect(LayoutUnit(), block_offset, LayoutUnit(), text_height),
+ inline_size(inline_size),
+ bidi_level(bidi_level) {}
+ NGLogicalLineItem(const NGInlineItem& inline_item,
+ scoped_refptr<const ShapeResultView> shape_result,
+ const String& text_content,
+ LayoutUnit block_offset,
+ LayoutUnit inline_size,
+ LayoutUnit text_height,
+ UBiDiLevel bidi_level)
+ : inline_item(&inline_item),
+ shape_result(std::move(shape_result)),
+ text_offset(
+ {this->shape_result->StartIndex(), this->shape_result->EndIndex()}),
+ text_content(text_content),
+ rect(LayoutUnit(), block_offset, LayoutUnit(), text_height),
+ inline_size(inline_size),
+ bidi_level(bidi_level) {}
+ NGLogicalLineItem(const NGLogicalLineItem& source_item,
+ scoped_refptr<const ShapeResultView> shape_result,
+ const NGTextOffset& text_offset)
+ : inline_item(source_item.inline_item),
+ shape_result(std::move(shape_result)),
+ text_offset(text_offset),
+ text_content(source_item.text_content),
+ rect(source_item.rect),
+ inline_size(this->shape_result->SnappedWidth()),
+ bidi_level(source_item.bidi_level) {}
+ NGLogicalLineItem(scoped_refptr<const NGPhysicalTextFragment> fragment,
+ LogicalOffset offset,
+ LayoutUnit inline_size,
+ UBiDiLevel bidi_level)
+ : fragment(std::move(fragment)),
+ rect(offset, LogicalSize()),
+ inline_size(inline_size),
+ bidi_level(bidi_level) {}
+ NGLogicalLineItem(scoped_refptr<const NGPhysicalTextFragment> fragment,
+ LayoutUnit block_offset,
+ LayoutUnit inline_size,
+ UBiDiLevel bidi_level)
+ : fragment(std::move(fragment)),
+ rect(LayoutUnit(), block_offset, LayoutUnit(), LayoutUnit()),
+ inline_size(inline_size),
+ bidi_level(bidi_level) {}
+ // Create an out-of-flow positioned object.
+ NGLogicalLineItem(LayoutObject* out_of_flow_positioned_box,
+ UBiDiLevel bidi_level,
+ TextDirection container_direction)
+ : out_of_flow_positioned_box(out_of_flow_positioned_box),
+ bidi_level(bidi_level),
+ container_direction(container_direction) {}
+ // Create an unpositioned float.
+ NGLogicalLineItem(LayoutObject* unpositioned_float, UBiDiLevel bidi_level)
+ : unpositioned_float(unpositioned_float), bidi_level(bidi_level) {}
+ // Create a positioned float.
+ NGLogicalLineItem(scoped_refptr<const NGLayoutResult> layout_result,
+ NGBfcOffset bfc_offset,
+ UBiDiLevel bidi_level)
+ : layout_result(std::move(layout_result)),
+ bfc_offset(bfc_offset),
+ bidi_level(bidi_level) {}
+
+ bool IsInlineBox() const {
+ return layout_result && layout_result->PhysicalFragment().IsInlineBox();
+ }
+ bool HasInFlowFragment() const {
+ return fragment || inline_item ||
+ (layout_result && !layout_result->PhysicalFragment().IsFloating());
+ }
+ bool HasInFlowOrFloatingFragment() const {
+ return fragment || inline_item || layout_result;
+ }
+ bool HasOutOfFlowFragment() const { return out_of_flow_positioned_box; }
+ bool HasFragment() const {
+ return HasInFlowOrFloatingFragment() || HasOutOfFlowFragment();
+ }
+ bool IsControl() const {
+ return inline_item && inline_item->Type() == NGInlineItem::kControl;
+ }
+ bool CanCreateFragmentItem() const { return HasInFlowOrFloatingFragment(); }
+ bool HasBidiLevel() const { return bidi_level != 0xff; }
+ bool IsPlaceholder() const { return !HasFragment() && !HasBidiLevel(); }
+ bool IsOpaqueToBidiReordering() const {
+ if (IsPlaceholder())
+ return true;
+ // Skip all inline boxes. Fragments for inline boxes maybe created earlier
+ // if they have no children.
+ if (layout_result) {
+ const LayoutObject* layout_object =
+ layout_result->PhysicalFragment().GetLayoutObject();
+ DCHECK(layout_object);
+ if (layout_object->IsLayoutInline())
+ return true;
+ }
+ return false;
+ }
+
+ const LogicalOffset& Offset() const { return rect.offset; }
+ LayoutUnit InlineOffset() const { return rect.offset.inline_offset; }
+ LayoutUnit BlockOffset() const { return rect.offset.block_offset; }
+ LayoutUnit BlockEndOffset() const { return rect.BlockEndOffset(); }
+ const LogicalSize& Size() const { return rect.size; }
+ LogicalSize MarginSize() const { return {inline_size, Size().block_size}; }
+
+ const NGPhysicalFragment* PhysicalFragment() const {
+ if (layout_result)
+ return &layout_result->PhysicalFragment();
+ return fragment.get();
+ }
+ const LayoutObject* GetLayoutObject() const;
+ LayoutObject* GetMutableLayoutObject() const;
+ const Node* GetNode() const;
+ const ComputedStyle* Style() const;
+
+ unsigned StartOffset() const { return text_offset.start; }
+ unsigned EndOffset() const { return text_offset.end; }
+
+ TextDirection ResolvedDirection() const {
+ // Inline boxes are not leaves that they don't have directions.
+ DCHECK(HasBidiLevel() || IsInlineBox());
+ return HasBidiLevel() ? DirectionFromLevel(bidi_level)
+ : TextDirection::kLtr;
+ }
+
+ scoped_refptr<const NGLayoutResult> layout_result;
+ scoped_refptr<const NGPhysicalTextFragment> fragment;
+
+ // Data to create a text fragment from.
+ const NGInlineItem* inline_item = nullptr;
+ scoped_refptr<const ShapeResultView> shape_result;
+ NGTextOffset text_offset;
+
+ // Data to create a generated text fragment.
+ String text_content;
+
+ LayoutObject* out_of_flow_positioned_box = nullptr;
+ LayoutObject* unpositioned_float = nullptr;
+ // The offset of the border box, initially in this child coordinate system.
+ // |ComputeInlinePositions()| converts it to the offset within the line box.
+ LogicalRect rect;
+ // The offset of a positioned float wrt. the root BFC. This should only be
+ // set for positioned floats.
+ NGBfcOffset bfc_offset;
+ // The inline size of the margin box.
+ LayoutUnit inline_size;
+ LayoutUnit margin_line_left;
+ // The index of |box_data_list_|, used in |PrepareForReorder()| and
+ // |UpdateAfterReorder()| to track children of boxes across BiDi reorder.
+ unsigned box_data_index = 0;
+ // For an inline box, shows the number of descendant |Child|ren, including
+ // empty ones. Includes itself, so 1 means no descendants. 0 if not an
+ // inline box. Available only after |CreateBoxFragments()|.
+ unsigned children_count = 0;
+ UBiDiLevel bidi_level = 0xff;
+ // The current text direction for OOF positioned items.
+ TextDirection container_direction = TextDirection::kLtr;
+
+ bool is_hidden_for_paint = false;
+};
+
+// A vector of Child.
+// Unlike the fragment builder, chlidren are mutable.
+// Callers can add to the fragment builder in a batch once finalized.
+class NGLogicalLineItems {
+ STACK_ALLOCATED();
+
+ public:
+ NGLogicalLineItems() = default;
+ void operator=(NGLogicalLineItems&& other) {
+ children_ = std::move(other.children_);
+ }
+
+ NGLogicalLineItem& operator[](wtf_size_t i) { return children_[i]; }
+ const NGLogicalLineItem& operator[](wtf_size_t i) const {
+ return children_[i];
+ }
+
+ wtf_size_t size() const { return children_.size(); }
+ bool IsEmpty() const { return children_.IsEmpty(); }
+ void ReserveInitialCapacity(unsigned capacity) {
+ children_.ReserveInitialCapacity(capacity);
+ }
+ void Shrink(wtf_size_t size) { children_.Shrink(size); }
+
+ using iterator = Vector<NGLogicalLineItem, 16>::iterator;
+ iterator begin() { return children_.begin(); }
+ iterator end() { return children_.end(); }
+ using const_iterator = Vector<NGLogicalLineItem, 16>::const_iterator;
+ const_iterator begin() const { return children_.begin(); }
+ const_iterator end() const { return children_.end(); }
+ using reverse_iterator = Vector<NGLogicalLineItem, 16>::reverse_iterator;
+ reverse_iterator rbegin() { return children_.rbegin(); }
+ reverse_iterator rend() { return children_.rend(); }
+ using const_reverse_iterator =
+ Vector<NGLogicalLineItem, 16>::const_reverse_iterator;
+ const_reverse_iterator rbegin() const { return children_.rbegin(); }
+ const_reverse_iterator rend() const { return children_.rend(); }
+
+ NGLogicalLineItem* FirstInFlowChild();
+ NGLogicalLineItem* LastInFlowChild();
+
+ // Add a child. Accepts all constructor arguments for |NGLogicalLineItem|.
+ template <class... Args>
+ void AddChild(Args&&... args) {
+ children_.emplace_back(std::forward<Args>(args)...);
+ }
+ void InsertChild(unsigned index, NGLogicalLineItem&& item) {
+ WillInsertChild(index);
+ children_.insert(index, item);
+ }
+ void InsertChild(unsigned index,
+ scoped_refptr<const NGLayoutResult> layout_result,
+ const LogicalRect& rect,
+ unsigned children_count) {
+ WillInsertChild(index);
+ children_.insert(
+ index, NGLogicalLineItem(std::move(layout_result), rect, children_count,
+ /* bidi_level */ 0));
+ }
+
+ void MoveInInlineDirection(LayoutUnit);
+ void MoveInInlineDirection(LayoutUnit, unsigned start, unsigned end);
+ void MoveInBlockDirection(LayoutUnit);
+ void MoveInBlockDirection(LayoutUnit, unsigned start, unsigned end);
+
+ // Create |NGPhysicalTextFragment| for all text children.
+ void CreateTextFragments(WritingMode writing_mode,
+ const String& text_content);
+
+ private:
+ void WillInsertChild(unsigned index);
+
+ Vector<NGLogicalLineItem, 16> children_;
+};
+
+} // namespace blink
+
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::NGLogicalLineItem)
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_LOGICAL_LINE_ITEM_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
index 5fb2fef7142..a199d2c241b 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
@@ -513,6 +513,35 @@ Position NGOffsetMapping::GetFirstPosition(unsigned offset) const {
return CreatePositionForOffsetMapping(node, dom_offset);
}
+const NGOffsetMappingUnit* NGOffsetMapping::GetFirstMappingUnit(
+ unsigned offset) const {
+ // Find the first unit where |unit.TextContentEnd() <= offset|
+ if (units_.IsEmpty() || units_.front().TextContentStart() > offset)
+ return nullptr;
+ const NGOffsetMappingUnit* result =
+ std::lower_bound(units_.begin(), units_.end(), offset,
+ [](const NGOffsetMappingUnit& unit, unsigned offset) {
+ return unit.TextContentEnd() < offset;
+ });
+ if (result == units_.end())
+ return nullptr;
+ const NGOffsetMappingUnit* next_unit = std::next(result);
+ if (next_unit != units_.end() && next_unit->TextContentStart() == offset) {
+ // For offset=2, returns [1] instead of [0].
+ // For offset=3, returns [3] instead of [2],
+ // in below example:
+ // text_content = "ab\ncd"
+ // offset mapping unit:
+ // [0] I DOM:0-2 TC:0-2 "ab"
+ // [1] C DOM:2-3 TC:2-2
+ // [2] I DOM:3-4 TC:2-3 "\n"
+ // [3] C DOM:4-5 TC:3-3
+ // [4] I DOM:5-7 TC:3-5 "cd"
+ return next_unit;
+ }
+ return result;
+}
+
const NGOffsetMappingUnit* NGOffsetMapping::GetLastMappingUnit(
unsigned offset) const {
// Find the last unit where |unit.TextContentStart() <= offset|
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h
index d5869ad6ea9..c4ee39eb926 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h
@@ -214,6 +214,10 @@ class CORE_EXPORT NGOffsetMapping {
base::span<const NGOffsetMappingUnit>
GetMappingUnitsForTextContentOffsetRange(unsigned start, unsigned end) const;
+ // Returns the first |NGOffsetMappingUnit| where |TextContentStart() >=
+ // offset| including unit for generated content.
+ const NGOffsetMappingUnit* GetFirstMappingUnit(unsigned offset) const;
+
// Returns the last |NGOffsetMappingUnit| where |TextContentStart() >= offset|
// including unit for generated content.
const NGOffsetMappingUnit* GetLastMappingUnit(unsigned offset) const;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc
index da14a44e464..d31c0787812 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc
@@ -46,12 +46,12 @@ bool operator!=(const NGOffsetMappingUnit& unit,
return !operator==(unit, other);
}
-void PrintTo(const NGOffsetMappingUnit& unit, std::ostream& ostream) {
+void PrintTo(const NGOffsetMappingUnit& unit, std::ostream* ostream) {
static const char* kTypeNames[] = {"Identity", "Collapsed", "Expanded"};
- ostream << "{" << kTypeNames[static_cast<unsigned>(unit.GetType())] << " "
- << unit.GetLayoutObject() << " dom=" << unit.DOMStart() << "-"
- << unit.DOMEnd() << " tc=" << unit.TextContentStart() << "-"
- << unit.TextContentEnd() << "}";
+ *ostream << "{" << kTypeNames[static_cast<unsigned>(unit.GetType())] << " "
+ << unit.GetLayoutObject() << " dom=" << unit.DOMStart() << "-"
+ << unit.DOMEnd() << " tc=" << unit.TextContentStart() << "-"
+ << unit.TextContentEnd() << "}";
}
bool operator==(const Vector<NGOffsetMappingUnit>& units1,
@@ -72,19 +72,19 @@ bool operator==(const Vector<NGOffsetMappingUnit>& units,
return units == ToVector(range);
}
-void PrintTo(const Vector<NGOffsetMappingUnit>& units, std::ostream& ostream) {
- ostream << "[";
+void PrintTo(const Vector<NGOffsetMappingUnit>& units, std::ostream* ostream) {
+ *ostream << "[";
const char* comma = "";
for (const auto& unit : units) {
- ostream << comma;
+ *ostream << comma;
PrintTo(unit, ostream);
comma = ", ";
}
- ostream << "]";
+ *ostream << "]";
}
void PrintTo(const base::span<const NGOffsetMappingUnit>& range,
- std::ostream& ostream) {
+ std::ostream* ostream) {
PrintTo(ToVector(range), ostream);
}
@@ -145,6 +145,17 @@ class NGOffsetMappingTest : public NGLayoutTest {
return result.ToString();
}
+ Vector<NGOffsetMappingUnit> GetFirstLast(const std::string& caret_text) {
+ const auto offset = caret_text.find('|');
+ return {*GetOffsetMapping().GetFirstMappingUnit(offset),
+ *GetOffsetMapping().GetLastMappingUnit(offset)};
+ }
+
+ Vector<NGOffsetMappingUnit> GetUnits(wtf_size_t index1, wtf_size_t index2) {
+ const auto& units = GetOffsetMapping().GetUnits();
+ return {units[index1], units[index2]};
+ }
+
String TestCollapsingWithCSSWhiteSpace(String text, String whitespace) {
StringBuilder html;
html.Append("<div id=t style=\"white-space:");
@@ -1081,6 +1092,10 @@ TEST_F(NGOffsetMappingTest, Table) {
ASSERT_EQ(1u, result.GetRanges().size());
TEST_RANGE(result.GetRanges(), foo_node, 0u, 3u);
+
+ EXPECT_EQ(GetUnits(1, 1), GetFirstLast("|foo"));
+ EXPECT_EQ(GetUnits(1, 1), GetFirstLast("f|oo"));
+ EXPECT_EQ(GetUnits(2, 2), GetFirstLast("foo|"));
}
TEST_F(NGOffsetMappingTest, GetMappingForInlineBlock) {
@@ -1134,6 +1149,35 @@ TEST_F(NGOffsetMappingTest, NoWrapSpaceAndCollapsibleSpace) {
1u, 5u, 5u);
TEST_UNIT(mapping.GetUnits()[2], NGOffsetMappingUnitType::kIdentity, bar, 1u,
4u, 5u, 8u);
+
+ EXPECT_EQ(GetUnits(0, 0), GetFirstLast("|foo Xbar"));
+ EXPECT_EQ(GetUnits(0, 0), GetFirstLast("foo| Xbar"));
+ EXPECT_EQ(GetUnits(0, 0), GetFirstLast("foo |Xbar"));
+ EXPECT_EQ(GetUnits(2, 2), GetFirstLast("foo X|bar"));
+}
+
+TEST_F(NGOffsetMappingTest, PreLine) {
+ InsertStyleElement("#t { white-space: pre-line; }");
+ SetupHtml("t", "<div id=t>ab \n cd</div>");
+ const LayoutObject& text_ab_n_cd = *layout_object_;
+ const NGOffsetMapping& result = GetOffsetMapping();
+
+ EXPECT_EQ("ab\ncd", result.GetText());
+
+ EXPECT_EQ((Vector<NGOffsetMappingUnit>{
+ NGOffsetMappingUnit(kIdentity, text_ab_n_cd, 0u, 2u, 0u, 2u),
+ NGOffsetMappingUnit(kCollapsed, text_ab_n_cd, 2u, 3u, 2u, 2u),
+ NGOffsetMappingUnit(kIdentity, text_ab_n_cd, 3u, 4u, 2u, 3u),
+ NGOffsetMappingUnit(kCollapsed, text_ab_n_cd, 4u, 5u, 3u, 3u),
+ NGOffsetMappingUnit(kIdentity, text_ab_n_cd, 5u, 7u, 3u, 5u)}),
+ result.GetUnits());
+
+ EXPECT_EQ(GetUnits(0, 0), GetFirstLast("|ab\ncd"));
+ EXPECT_EQ(GetUnits(0, 0), GetFirstLast("a|b\ncd"));
+ EXPECT_EQ(GetUnits(1, 2), GetFirstLast("ab|\ncd"));
+ EXPECT_EQ(GetUnits(3, 4), GetFirstLast("ab\n|cd"));
+ EXPECT_EQ(GetUnits(4, 4), GetFirstLast("ab\nc|d"));
+ EXPECT_EQ(GetUnits(4, 4), GetFirstLast("ab\ncd|"));
}
TEST_F(NGOffsetMappingTest, BiDiAroundForcedBreakInPreLine) {
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc
index ac726c4dea4..c61c09c99f9 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc
@@ -71,15 +71,21 @@ NGLineHeightMetrics NGPhysicalLineBoxFragment::BaselineMetrics() const {
namespace {
// Include the inline-size of the line-box in the overflow.
+// Do not update block offset and block size of |overflow|.
inline void AddInlineSizeToOverflow(const PhysicalRect& rect,
const WritingMode container_writing_mode,
PhysicalRect* overflow) {
PhysicalRect inline_rect;
inline_rect.offset = rect.offset;
- if (IsHorizontalWritingMode(container_writing_mode))
+ if (IsHorizontalWritingMode(container_writing_mode)) {
inline_rect.size.width = rect.size.width;
- else
+ inline_rect.offset.top = overflow->offset.top;
+ inline_rect.size.height = overflow->size.height;
+ } else {
inline_rect.size.height = rect.size.height;
+ inline_rect.offset.left = overflow->offset.left;
+ inline_rect.size.width = overflow->size.width;
+ }
overflow->UniteEvenIfEmpty(inline_rect);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc
index f7993f84dd7..4d256625f13 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc
@@ -52,7 +52,7 @@ NGPhysicalTextFragment::NGPhysicalTextFragment(
DCHECK_LE(text_offset_.end, source.EndOffset());
DCHECK(shape_result_ || IsFlowControl()) << *this;
base_or_resolved_direction_ = source.base_or_resolved_direction_;
- ink_overflow_computed_ = false;
+ ink_overflow_computed_or_mathml_paint_info_ = false;
}
NGPhysicalTextFragment::NGPhysicalTextFragment(NGTextFragmentBuilder* builder)
@@ -60,12 +60,12 @@ NGPhysicalTextFragment::NGPhysicalTextFragment(NGTextFragmentBuilder* builder)
kFragmentText,
static_cast<unsigned>(builder->text_type_)),
text_(builder->text_),
- text_offset_({builder->start_offset_, builder->end_offset_}),
+ text_offset_(builder->text_offset_),
shape_result_(std::move(builder->shape_result_)) {
DCHECK(shape_result_ || IsFlowControl()) << *this;
base_or_resolved_direction_ =
static_cast<unsigned>(builder->ResolvedDirection());
- ink_overflow_computed_ = false;
+ ink_overflow_computed_or_mathml_paint_info_ = false;
}
bool NGPhysicalTextFragment::IsGeneratedText() const {
@@ -78,10 +78,8 @@ LayoutUnit NGPhysicalTextFragment::InlinePositionForOffset(
unsigned offset,
LayoutUnit (*round_function)(float),
AdjustMidCluster adjust_mid_cluster) const {
- scoped_refptr<NGFragmentItem> item =
- base::MakeRefCounted<NGFragmentItem>(*this);
- return item->InlinePositionForOffset(Text(), offset, round_function,
- adjust_mid_cluster);
+ return NGFragmentItem(*this).InlinePositionForOffset(
+ Text(), offset, round_function, adjust_mid_cluster);
}
// TODO(yosin): We should move |NGFragmentItem::InlinePositionForOffset" to
@@ -125,17 +123,14 @@ LayoutUnit NGFragmentItem::InlinePositionForOffset(StringView text,
LayoutUnit NGPhysicalTextFragment::InlinePositionForOffset(
unsigned offset) const {
- scoped_refptr<NGFragmentItem> item =
- base::MakeRefCounted<NGFragmentItem>(*this);
- return item->InlinePositionForOffset(Text(), offset);
+ return NGFragmentItem(*this).InlinePositionForOffset(Text(), offset);
}
std::pair<LayoutUnit, LayoutUnit>
NGPhysicalTextFragment::LineLeftAndRightForOffsets(unsigned start_offset,
unsigned end_offset) const {
- scoped_refptr<NGFragmentItem> item =
- base::MakeRefCounted<NGFragmentItem>(*this);
- return item->LineLeftAndRightForOffsets(Text(), start_offset, end_offset);
+ return NGFragmentItem(*this).LineLeftAndRightForOffsets(Text(), start_offset,
+ end_offset);
}
// TODO(yosin): We should move |NGFragmentItem::InlinePositionForOffset" to
@@ -162,9 +157,7 @@ std::pair<LayoutUnit, LayoutUnit> NGFragmentItem::LineLeftAndRightForOffsets(
PhysicalRect NGPhysicalTextFragment::LocalRect(unsigned start_offset,
unsigned end_offset) const {
- scoped_refptr<NGFragmentItem> item =
- base::MakeRefCounted<NGFragmentItem>(*this);
- return item->LocalRect(Text(), start_offset, end_offset);
+ return NGFragmentItem(*this).LocalRect(Text(), start_offset, end_offset);
}
// TODO(yosin): We should move |NGFragmentItem::InlinePositionForOffset" to
@@ -194,7 +187,7 @@ PhysicalRect NGFragmentItem::LocalRect(StringView text,
}
PhysicalRect NGPhysicalTextFragment::SelfInkOverflow() const {
- if (!ink_overflow_computed_)
+ if (!ink_overflow_computed_or_mathml_paint_info_)
ComputeSelfInkOverflow();
if (ink_overflow_)
return ink_overflow_->self_ink_overflow;
@@ -202,7 +195,7 @@ PhysicalRect NGPhysicalTextFragment::SelfInkOverflow() const {
}
void NGPhysicalTextFragment::ComputeSelfInkOverflow() const {
- ink_overflow_computed_ = true;
+ ink_overflow_computed_or_mathml_paint_info_ = true;
if (UNLIKELY(!shape_result_)) {
ink_overflow_ = nullptr;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.cc
new file mode 100644
index 00000000000..dcb51cdf645
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.cc
@@ -0,0 +1,305 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.h"
+
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+
+namespace blink {
+
+// TODO(layout-dev): Using ScrollableOverflow() is same as legacy
+// LayoutRubyRun. However its result is not good with some fonts/platforms.
+// See crbug.com/1082087.
+LayoutUnit LastLineTextLogicalBottom(const NGPhysicalBoxFragment& container,
+ LayoutUnit default_value) {
+ const ComputedStyle& container_style = container.Style();
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ if (!container.Items())
+ return default_value;
+ NGInlineCursor cursor(*container.Items());
+ cursor.MoveToLastLine();
+ const auto* line_item = cursor.CurrentItem();
+ if (!line_item)
+ return default_value;
+ DCHECK_EQ(line_item->Type(), NGFragmentItem::kLine);
+ DCHECK(line_item->LineBoxFragment());
+ PhysicalRect line_rect =
+ line_item->LineBoxFragment()->ScrollableOverflowForLine(
+ container, container_style, *line_item, cursor);
+ return container.ConvertChildToLogical(line_rect).BlockEndOffset();
+ }
+
+ const NGPhysicalLineBoxFragment* last_line = nullptr;
+ PhysicalOffset last_line_offset;
+ for (const auto& child_link : container.PostLayoutChildren()) {
+ if (const auto* maybe_line =
+ DynamicTo<NGPhysicalLineBoxFragment>(*child_link)) {
+ last_line = maybe_line;
+ last_line_offset = child_link.offset;
+ }
+ }
+ if (!last_line)
+ return default_value;
+ PhysicalRect line_rect =
+ last_line->ScrollableOverflow(container, container_style);
+ line_rect.Move(last_line_offset);
+ return container.ConvertChildToLogical(line_rect).BlockEndOffset();
+}
+
+// TODO(layout-dev): Using ScrollableOverflow() is same as legacy
+// LayoutRubyRun. However its result is not good with some fonts/platforms.
+// See crbug.com/1082087.
+LayoutUnit FirstLineTextLogicalTop(const NGPhysicalBoxFragment& container,
+ LayoutUnit default_value) {
+ const ComputedStyle& container_style = container.Style();
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ if (!container.Items())
+ return default_value;
+ NGInlineCursor cursor(*container.Items());
+ cursor.MoveToFirstLine();
+ const auto* line_item = cursor.CurrentItem();
+ if (!line_item)
+ return default_value;
+ DCHECK_EQ(line_item->Type(), NGFragmentItem::kLine);
+ DCHECK(line_item->LineBoxFragment());
+ PhysicalRect line_rect =
+ line_item->LineBoxFragment()->ScrollableOverflowForLine(
+ container, container_style, *line_item, cursor);
+ return container.ConvertChildToLogical(line_rect).offset.block_offset;
+ }
+
+ for (const auto& child_link : container.PostLayoutChildren()) {
+ if (const auto* line = DynamicTo<NGPhysicalLineBoxFragment>(*child_link)) {
+ PhysicalRect line_rect =
+ line->ScrollableOverflow(container, container_style);
+ line_rect.Move(child_link.offset);
+ return container.ConvertChildToLogical(line_rect).offset.block_offset;
+ }
+ }
+ return default_value;
+}
+
+// See LayoutRubyRun::GetOverhang().
+NGAnnotationOverhang GetOverhang(const NGInlineItemResult& item) {
+ DCHECK(RuntimeEnabledFeatures::LayoutNGRubyEnabled());
+ NGAnnotationOverhang overhang;
+ if (!item.layout_result)
+ return overhang;
+
+ const auto& run_fragment =
+ To<NGPhysicalContainerFragment>(item.layout_result->PhysicalFragment());
+ LayoutUnit start_overhang = LayoutUnit::Max();
+ LayoutUnit end_overhang = LayoutUnit::Max();
+ bool found_line = false;
+ const ComputedStyle* ruby_text_style = nullptr;
+ for (const auto& child_link : run_fragment.PostLayoutChildren()) {
+ const NGPhysicalFragment& child_fragment = *child_link.get();
+ const LayoutObject* layout_object = child_fragment.GetLayoutObject();
+ if (!layout_object)
+ continue;
+ if (layout_object->IsRubyText()) {
+ ruby_text_style = layout_object->Style();
+ continue;
+ }
+ if (layout_object->IsRubyBase()) {
+ const ComputedStyle& base_style = child_fragment.Style();
+ const WritingMode writing_mode = base_style.GetWritingMode();
+ const LayoutUnit base_inline_size =
+ NGFragment(writing_mode, child_fragment).InlineSize();
+ // RubyBase's inline_size is always same as RubyRun's inline_size.
+ // Overhang values are offsets from RubyBase's inline edges to
+ // the outmost text.
+ for (const auto& base_child_link :
+ To<NGPhysicalContainerFragment>(child_fragment)
+ .PostLayoutChildren()) {
+ const LayoutUnit line_inline_size =
+ NGFragment(writing_mode, *base_child_link).InlineSize();
+ if (line_inline_size == LayoutUnit())
+ continue;
+ found_line = true;
+ const LayoutUnit start =
+ base_child_link.offset
+ .ConvertToLogical(writing_mode, base_style.Direction(),
+ child_fragment.Size(),
+ base_child_link.get()->Size())
+ .inline_offset;
+ const LayoutUnit end = base_inline_size - start - line_inline_size;
+ start_overhang = std::min(start_overhang, start);
+ end_overhang = std::min(end_overhang, end);
+ }
+ }
+ }
+
+ if (!found_line || !ruby_text_style)
+ return overhang;
+ DCHECK_NE(start_overhang, LayoutUnit::Max());
+ DCHECK_NE(end_overhang, LayoutUnit::Max());
+ // We allow overhang up to the half of ruby text font size.
+ const LayoutUnit half_width_of_ruby_font =
+ LayoutUnit(ruby_text_style->FontSize()) / 2;
+ overhang.start = std::min(start_overhang, half_width_of_ruby_font);
+ overhang.end = std::min(end_overhang, half_width_of_ruby_font);
+ return overhang;
+}
+
+// See LayoutRubyRun::GetOverhang().
+bool CanApplyStartOverhang(const NGLineInfo& line_info,
+ LayoutUnit& start_overhang) {
+ if (start_overhang <= LayoutUnit())
+ return false;
+ DCHECK(RuntimeEnabledFeatures::LayoutNGRubyEnabled());
+ const NGInlineItemResults& items = line_info.Results();
+ // Requires at least the current item and the previous item.
+ if (items.size() < 2)
+ return false;
+ // Find a previous item other than kOpenTag/kCloseTag.
+ // Searching items in the logical order doesn't work well with bidi
+ // reordering. However, it's difficult to compute overhang after bidi
+ // reordering because it affects line breaking.
+ wtf_size_t previous_index = items.size() - 2;
+ while ((items[previous_index].item->Type() == NGInlineItem::kOpenTag ||
+ items[previous_index].item->Type() == NGInlineItem::kCloseTag) &&
+ previous_index > 0)
+ --previous_index;
+ const NGInlineItemResult& previous_item = items[previous_index];
+ if (previous_item.item->Type() != NGInlineItem::kText)
+ return false;
+ const NGInlineItem& current_item = *items.back().item;
+ if (previous_item.item->Style()->FontSize() >
+ current_item.Style()->FontSize())
+ return false;
+ start_overhang = std::min(start_overhang, previous_item.inline_size);
+ return true;
+}
+
+// See LayoutRubyRun::GetOverhang().
+LayoutUnit CommitPendingEndOverhang(NGLineInfo* line_info) {
+ DCHECK(RuntimeEnabledFeatures::LayoutNGRubyEnabled());
+ DCHECK(line_info);
+ NGInlineItemResults* items = line_info->MutableResults();
+ if (items->size() < 2U)
+ return LayoutUnit();
+ const NGInlineItemResult& text_item = items->back();
+ DCHECK_EQ(text_item.item->Type(), NGInlineItem::kText);
+ wtf_size_t i = items->size() - 2;
+ while ((*items)[i].item->Type() != NGInlineItem::kAtomicInline) {
+ const auto type = (*items)[i].item->Type();
+ if (type != NGInlineItem::kOpenTag && type != NGInlineItem::kCloseTag)
+ return LayoutUnit();
+ if (i-- == 0)
+ return LayoutUnit();
+ }
+ NGInlineItemResult& atomic_inline_item = (*items)[i];
+ if (!atomic_inline_item.layout_result->PhysicalFragment().IsRubyRun())
+ return LayoutUnit();
+ if (atomic_inline_item.pending_end_overhang <= LayoutUnit())
+ return LayoutUnit();
+ if (atomic_inline_item.item->Style()->FontSize() <
+ text_item.item->Style()->FontSize())
+ return LayoutUnit();
+ // Ideally we should refer to inline_size of |text_item| instead of the width
+ // of the NGInlineItem's ShapeResult. However it's impossible to compute
+ // inline_size of |text_item| before calling BreakText(), and BreakText()
+ // requires precise |position_| which takes |end_overhang| into account.
+ LayoutUnit end_overhang =
+ std::min(atomic_inline_item.pending_end_overhang,
+ LayoutUnit(text_item.item->TextShapeResult()->Width()));
+ DCHECK_EQ(atomic_inline_item.margins.inline_end, LayoutUnit());
+ atomic_inline_item.margins.inline_end = -end_overhang;
+ atomic_inline_item.inline_size -= end_overhang;
+ atomic_inline_item.pending_end_overhang = LayoutUnit();
+ return end_overhang;
+}
+
+NGAnnotationMetrics ComputeAnnotationOverflow(
+ const NGLogicalLineItems& logical_line,
+ const NGLineHeightMetrics& line_box_metrics,
+ LayoutUnit line_over,
+ const ComputedStyle& line_style) {
+ DCHECK(RuntimeEnabledFeatures::LayoutNGRubyEnabled());
+ // Min/max position of content without line-height.
+ LayoutUnit content_over = line_over + line_box_metrics.ascent;
+ LayoutUnit content_under = content_over;
+
+ // Min/max position of annotations.
+ LayoutUnit annotation_over = content_over;
+ LayoutUnit annotation_under = content_over;
+
+ const LayoutUnit line_under = line_over + line_box_metrics.LineHeight();
+ bool has_over_emphasis = false;
+ bool has_under_emphasis = false;
+ for (const NGLogicalLineItem& item : logical_line) {
+ if (item.HasInFlowFragment()) {
+ if (!item.IsControl()) {
+ content_over = std::min(content_over, item.BlockOffset());
+ content_under = std::max(content_under, item.BlockEndOffset());
+ }
+ if (const auto* style = item.Style()) {
+ if (style->GetTextEmphasisMark() != TextEmphasisMark::kNone) {
+ if (style->GetTextEmphasisLineLogicalSide() == LineLogicalSide::kOver)
+ has_over_emphasis = true;
+ else
+ has_under_emphasis = true;
+ }
+ }
+ }
+
+ // Accumulate |AnnotationOverflow| from ruby runs. All ruby run items have
+ // |layout_result|.
+ const NGLayoutResult* layout_result = item.layout_result.get();
+ if (!layout_result)
+ continue;
+ LayoutUnit overflow = layout_result->AnnotationOverflow();
+ if (IsFlippedLinesWritingMode(line_style.GetWritingMode()))
+ overflow = -overflow;
+ if (overflow < LayoutUnit()) {
+ annotation_over =
+ std::min(annotation_over, item.rect.offset.block_offset + overflow);
+ } else if (overflow > LayoutUnit()) {
+ const LayoutUnit logical_bottom =
+ item.rect.offset.block_offset +
+ layout_result->PhysicalFragment()
+ .Size()
+ .ConvertToLogical(line_style.GetWritingMode())
+ .block_size;
+ annotation_under = std::max(annotation_under, logical_bottom + overflow);
+ }
+ }
+
+ // Probably this is an empty line. We should secure font-size space.
+ const LayoutUnit font_size(line_style.ComputedFontSize());
+ if (content_under - content_over < font_size) {
+ LayoutUnit half_leading = (line_box_metrics.LineHeight() - font_size) / 2;
+ half_leading = half_leading.ClampNegativeToZero();
+ content_over = line_over + half_leading;
+ content_under = line_under - half_leading;
+ }
+
+ // Don't provide annotation space if text-emphasis exists.
+ // TODO(layout-dev): If the text-emphasis is in [line_over, line_under],
+ // this line can provide annotation space.
+ if (has_over_emphasis)
+ content_over = line_over;
+ if (has_under_emphasis)
+ content_under = line_under;
+
+ const LayoutUnit overflow_over =
+ (line_over - annotation_over).ClampNegativeToZero();
+ const LayoutUnit overflow_under =
+ (annotation_under - line_under).ClampNegativeToZero();
+ return {overflow_over, overflow_under,
+ // With some fonts, text fragment sizes can exceed line-height.
+ // We need ClampNegativeToZero().
+ overflow_over ? LayoutUnit()
+ : (content_over - line_over).ClampNegativeToZero(),
+ overflow_under ? LayoutUnit()
+ : (line_under - content_under).ClampNegativeToZero()};
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.h
new file mode 100644
index 00000000000..9d3afe91ff3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.h
@@ -0,0 +1,85 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_RUBY_UTILS_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_RUBY_UTILS_H_
+
+#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
+
+namespace blink {
+
+class ComputedStyle;
+class NGLineInfo;
+class NGLogicalLineItems;
+class NGPhysicalBoxFragment;
+struct NGInlineItemResult;
+struct NGLineHeightMetrics;
+
+// Returns the logical bottom offset of the last line text, relative to
+// |container| origin. This is used to decide ruby annotation box position.
+//
+// See NGBlockLayoutAlgorithm::LayoutRubyText().
+LayoutUnit LastLineTextLogicalBottom(const NGPhysicalBoxFragment& container,
+ LayoutUnit default_value);
+
+// Returns the logical top offset of the first line text, relative to
+// |container| origin. This is used to decide ruby annotation box position.
+//
+// See NGBlockLayoutAlgorithm::LayoutRubyText().
+LayoutUnit FirstLineTextLogicalTop(const NGPhysicalBoxFragment& container,
+ LayoutUnit default_value);
+
+struct NGAnnotationOverhang {
+ LayoutUnit start;
+ LayoutUnit end;
+};
+
+// Returns overhang values of the specified NGInlineItemResult representing
+// LayoutNGRubyRun.
+//
+// This is used by NGLineBreaker.
+NGAnnotationOverhang GetOverhang(const NGInlineItemResult& item);
+
+// Returns true if |start_overhang| is applied to a previous item, and
+// clamp |start_overhang| to the width of the previous item.
+//
+// This is used by NGLineBreaker.
+bool CanApplyStartOverhang(const NGLineInfo& line_info,
+ LayoutUnit& start_overhang);
+
+// This should be called after NGInlineItemResult for a text is added in
+// NGLineBreaker::HandleText().
+//
+// This function may update a NGInlineItemResult representing RubyRun
+// in |line_info|
+LayoutUnit CommitPendingEndOverhang(NGLineInfo* line_info);
+
+// Stores ComputeAnnotationOverflow() results.
+//
+// |overflow_over| and |space_over| are exclusive. Only one of them can be
+// non-zero. |overflow_under| and |space_under| are exclusive too.
+// All fields never be negative.
+struct NGAnnotationMetrics {
+ // The amount of annotation overflow at the line-over side.
+ LayoutUnit overflow_over;
+ // The amount of annotation overflow at the line-under side.
+ LayoutUnit overflow_under;
+ // The amount of annotation space which the next line at the line-over
+ // side can consume.
+ LayoutUnit space_over;
+ // The amount of annotation space which the next line at the line-under
+ // side can consume.
+ LayoutUnit space_under;
+};
+
+// Compute over/under annotation overflow/space for the specified line.
+NGAnnotationMetrics ComputeAnnotationOverflow(
+ const NGLogicalLineItems& logical_line,
+ const NGLineHeightMetrics& line_box_metrics,
+ LayoutUnit line_over,
+ const ComputedStyle& line_style);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_RUBY_UTILS_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.cc
index bd872d67343..e6b086e8968 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.cc
@@ -17,51 +17,47 @@ NGTextFragmentBuilder::NGTextFragmentBuilder(
const NGPhysicalTextFragment& fragment)
: NGFragmentBuilder(fragment),
text_(fragment.text_),
- start_offset_(fragment.StartOffset()),
- end_offset_(fragment.EndOffset()),
+ text_offset_(fragment.TextOffset()),
shape_result_(fragment.TextShapeResult()),
text_type_(fragment.TextType()) {}
-void NGTextFragmentBuilder::SetItem(const String& text_content,
- NGInlineItemResult* item_result,
- LayoutUnit line_height) {
- DCHECK(item_result);
- const NGInlineItem* item = item_result->item;
- DCHECK(item);
- DCHECK_NE(item->TextType(), NGTextType::kLayoutGenerated)
+void NGTextFragmentBuilder::SetItem(
+ const String& text_content,
+ const NGInlineItem& item,
+ scoped_refptr<const ShapeResultView> shape_result,
+ const NGTextOffset& text_offset,
+ const LogicalSize& size) {
+ DCHECK_NE(item.TextType(), NGTextType::kLayoutGenerated)
<< "Please use SetText() instead.";
- DCHECK(item->Style());
+ DCHECK(item.Style());
- text_type_ = item->TextType();
+ text_type_ = item.TextType();
text_ = text_content;
- start_offset_ = item_result->start_offset;
- end_offset_ = item_result->end_offset;
- resolved_direction_ = item->Direction();
- SetStyle(item->Style(), item->StyleVariant());
- size_ = {item_result->inline_size, line_height};
- shape_result_ = std::move(item_result->shape_result);
- layout_object_ = item->GetLayoutObject();
+ text_offset_ = text_offset;
+ resolved_direction_ = item.Direction();
+ SetStyle(item.Style(), item.StyleVariant());
+ size_ = size;
+ shape_result_ = std::move(shape_result);
+ layout_object_ = item.GetLayoutObject();
}
void NGTextFragmentBuilder::SetText(
LayoutObject* layout_object,
const String& text,
scoped_refptr<const ComputedStyle> style,
- bool is_ellipsis_style,
- scoped_refptr<const ShapeResultView> shape_result) {
+ NGStyleVariant style_variant,
+ scoped_refptr<const ShapeResultView> shape_result,
+ const LogicalSize& size) {
DCHECK(layout_object);
DCHECK(style);
DCHECK(shape_result);
text_type_ = NGTextType::kLayoutGenerated;
text_ = text;
- start_offset_ = shape_result->StartIndex();
- end_offset_ = shape_result->EndIndex();
+ text_offset_ = {shape_result->StartIndex(), shape_result->EndIndex()};
resolved_direction_ = shape_result->Direction();
- SetStyle(style, is_ellipsis_style ? NGStyleVariant::kEllipsis
- : NGStyleVariant::kStandard);
- size_ = {shape_result->SnappedWidth(),
- NGLineHeightMetrics(*style).LineHeight()};
+ SetStyle(style, style_variant);
+ size_ = size;
shape_result_ = std::move(shape_result);
layout_object_ = layout_object;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.h
index 1d028144f27..7e90f264e2f 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.h
@@ -15,14 +15,13 @@ namespace blink {
class LayoutObject;
class ShapeResultView;
-struct NGInlineItemResult;
class CORE_EXPORT NGTextFragmentBuilder final : public NGFragmentBuilder {
STACK_ALLOCATED();
public:
- NGTextFragmentBuilder(WritingMode writing_mode)
- : NGFragmentBuilder(writing_mode, TextDirection::kLtr) {}
+ explicit NGTextFragmentBuilder(WritingMode writing_mode)
+ : NGFragmentBuilder({writing_mode, TextDirection::kLtr}) {}
NGTextFragmentBuilder(const NGPhysicalTextFragment& fragment);
@@ -30,23 +29,25 @@ class CORE_EXPORT NGTextFragmentBuilder final : public NGFragmentBuilder {
// NOTE: Takes ownership of the shape result within the item result.
void SetItem(const String& text_content,
- NGInlineItemResult*,
- LayoutUnit line_height);
+ const NGInlineItem& inline_item,
+ scoped_refptr<const ShapeResultView> shape_result,
+ const NGTextOffset& text_offset,
+ const LogicalSize& size);
// Set text for generated text, e.g. hyphen and ellipsis.
void SetText(LayoutObject*,
const String& text,
scoped_refptr<const ComputedStyle>,
- bool is_ellipsis_style,
- scoped_refptr<const ShapeResultView>);
+ NGStyleVariant style_variant,
+ scoped_refptr<const ShapeResultView>,
+ const LogicalSize& size);
// Creates the fragment. Can only be called once.
scoped_refptr<const NGPhysicalTextFragment> ToTextFragment();
private:
String text_;
- unsigned start_offset_;
- unsigned end_offset_;
+ NGTextOffset text_offset_;
scoped_refptr<const ShapeResultView> shape_result_;
NGTextType text_type_ = NGTextType::kNormal;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_offset.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_offset.h
index 0d6c7251095..8e196f9850f 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_offset.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_offset.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_TEXT_OFFSET_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_TEXT_OFFSET_H_
-#include "base/logging.h"
+#include "base/check_op.h"
#include "third_party/blink/renderer/core/core_export.h"
namespace blink {
@@ -23,6 +23,7 @@ struct CORE_EXPORT NGTextOffset {
}
void AssertValid() const { DCHECK_GE(end, start); }
+ void AssertNotEmpty() const { DCHECK_GT(end, start); }
unsigned start;
unsigned end;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc
index a7904987197..2d0f8c53b64 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/position_with_affinity.h"
#include "third_party/blink/renderer/core/layout/hit_test_location.h"
#include "third_party/blink/renderer/core/layout/layout_analyzer.h"
@@ -252,6 +253,33 @@ bool LayoutNGBlockFlowMixin<Base>::NodeAtPoint(
accumulated_offset, action);
}
+// Move specified position to start/end of non-editable region.
+// If it can be found, we prefer a visually equivalent position that is
+// editable.
+// See also LayoutObject::CreatePositionWithAffinity()
+// Example:
+// <editable><non-editable>|abc</non-editable></editable>
+// =>
+// <editable>|<non-editable>abc</non-editable></editable>
+static PositionWithAffinity AdjustForEditingBoundary(
+ const PositionWithAffinity& position_with_affinity) {
+ if (position_with_affinity.IsNull())
+ return position_with_affinity;
+ const Position& position = position_with_affinity.GetPosition();
+ const Node& node = *position.ComputeContainerNode();
+ if (HasEditableStyle(node))
+ return position_with_affinity;
+ const Position& forward =
+ MostForwardCaretPosition(position, kCanCrossEditingBoundary);
+ if (HasEditableStyle(*forward.ComputeContainerNode()))
+ return PositionWithAffinity(forward);
+ const Position& backward =
+ MostBackwardCaretPosition(position, kCanCrossEditingBoundary);
+ if (HasEditableStyle(*backward.ComputeContainerNode()))
+ return PositionWithAffinity(backward);
+ return position_with_affinity;
+}
+
template <typename Base>
PositionWithAffinity LayoutNGBlockFlowMixin<Base>::PositionForPoint(
const PhysicalOffset& point) const {
@@ -272,7 +300,7 @@ PositionWithAffinity LayoutNGBlockFlowMixin<Base>::PositionForPoint(
Base::OffsetForContents(point_in_contents);
if (const PositionWithAffinity position =
paint_fragment->PositionForPoint(point_in_contents))
- return position;
+ return AdjustForEditingBoundary(position);
} else if (const NGPhysicalBoxFragment* fragment = CurrentFragment()) {
if (const NGFragmentItems* items = fragment->Items()) {
// The given offset is relative to this |LayoutBlockFlow|. Convert to the
@@ -283,7 +311,7 @@ PositionWithAffinity LayoutNGBlockFlowMixin<Base>::PositionForPoint(
if (const PositionWithAffinity position =
cursor.PositionForPointInInlineFormattingContext(
point_in_contents, *fragment))
- return position;
+ return AdjustForEditingBoundary(position);
}
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
index 1c82b8a6480..32822417c99 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
@@ -92,7 +92,8 @@ MinMaxSizes LayoutNGMixin<Base>::ComputeIntrinsicLogicalWidths() const {
NGConstraintSpace space = ConstraintSpaceForMinMaxSizes();
MinMaxSizes sizes =
node.ComputeMinMaxSizes(node.Style().GetWritingMode(),
- MinMaxSizesInput(available_logical_height),
+ MinMaxSizesInput(available_logical_height,
+ MinMaxSizesType::kContent),
&space)
.sizes;
@@ -154,8 +155,7 @@ void LayoutNGMixin<Base>::UpdateOutOfFlowBlockLayout() {
NGBlockNode container_node(container);
NGBoxFragmentBuilder container_builder(
container_node, scoped_refptr<const ComputedStyle>(container_style),
- /* space */ nullptr, container_style->GetWritingMode(),
- container_style->Direction());
+ /* space */ nullptr, container_style->GetWritingDirection());
container_builder.SetIsNewFormattingContext(
container_node.CreatesNewFormattingContext());
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.h b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.h
index 5702a72422c..8d1e30248e4 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.h
@@ -7,7 +7,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
-#include "third_party/blink/renderer/core/layout/ng/list/list_marker.h"
+#include "third_party/blink/renderer/core/layout/list_marker.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc
index c3a6d3f0b9f..c45686e298d 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
-#include "third_party/blink/renderer/core/layout/ng/list/list_marker.h"
+#include "third_party/blink/renderer/core/layout/list_marker.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.h b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.h
deleted file mode 100644
index 86bdb5ec592..00000000000
--- a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LIST_LAYOUT_NG_LIST_MARKER_IMAGE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LIST_LAYOUT_NG_LIST_MARKER_IMAGE_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/layout/layout_image.h"
-
-namespace blink {
-
-class Document;
-
-class CORE_EXPORT LayoutNGListMarkerImage final : public LayoutImage {
- public:
- explicit LayoutNGListMarkerImage(Element*);
- static LayoutNGListMarkerImage* CreateAnonymous(Document*);
-
- bool IsLayoutNGObject() const override { return true; }
-
- private:
- bool IsOfType(LayoutObjectType) const override;
-
- void ComputeIntrinsicSizingInfoByDefaultSize(IntrinsicSizingInfo&) const;
- void ComputeIntrinsicSizingInfo(IntrinsicSizingInfo&) const final;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LIST_LAYOUT_NG_LIST_MARKER_IMAGE_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h
index 3b30f46349b..fa7cb43175a 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h
@@ -7,8 +7,8 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
+#include "third_party/blink/renderer/core/layout/list_marker.h"
#include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.h"
-#include "third_party/blink/renderer/core/layout/ng/list/list_marker.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.cc b/chromium/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.cc
index e0e08726a1f..491b22f50ba 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.cc
@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h"
-#include "third_party/blink/renderer/core/layout/layout_list_marker.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h"
@@ -36,7 +35,7 @@ bool NGUnpositionedListMarker::IsImage() const {
LayoutUnit NGUnpositionedListMarker::InlineOffset(
const LayoutUnit marker_inline_size) const {
DCHECK(marker_layout_object_);
- auto margins = LayoutListMarker::InlineMarginsForOutside(
+ auto margins = ListMarker::InlineMarginsForOutside(
marker_layout_object_->StyleRef(), IsImage(), marker_inline_size);
return margins.first;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.cc
index 831821243aa..01c72e4fa4c 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.cc
@@ -124,10 +124,7 @@ FractionStackParameters GetFractionStackParameters(const ComputedStyle& style) {
NGMathFractionLayoutAlgorithm::NGMathFractionLayoutAlgorithm(
const NGLayoutAlgorithmParams& params)
- : NGLayoutAlgorithm(params),
- border_scrollbar_padding_(params.fragment_geometry.border +
- params.fragment_geometry.padding +
- params.fragment_geometry.scrollbar) {
+ : NGLayoutAlgorithm(params) {
DCHECK(params.space.IsNewFormattingContext());
container_builder_.SetIsNewFormattingContext(
params.space.IsNewFormattingContext());
@@ -142,8 +139,7 @@ void NGMathFractionLayoutAlgorithm::GatherChildren(NGBlockNode* numerator,
NGBlockNode block_child = To<NGBlockNode>(child);
if (child.IsOutOfFlowPositioned()) {
container_builder_.AddOutOfFlowChildCandidate(
- block_child, {border_scrollbar_padding_.inline_start,
- border_scrollbar_padding_.block_start});
+ block_child, BorderScrollbarPadding().StartOffset());
continue;
}
if (!*numerator) {
@@ -169,17 +165,14 @@ scoped_refptr<const NGLayoutResult> NGMathFractionLayoutAlgorithm::Layout() {
NGBlockNode denominator = nullptr;
GatherChildren(&numerator, &denominator);
- const LogicalSize border_box_size = container_builder_.InitialBorderBoxSize();
- auto child_available_size =
- ShrinkAvailableSize(border_box_size, border_scrollbar_padding_);
auto numerator_space = CreateConstraintSpaceForMathChild(
- Node(), child_available_size, ConstraintSpace(), numerator);
+ Node(), ChildAvailableSize(), ConstraintSpace(), numerator);
scoped_refptr<const NGLayoutResult> numerator_layout_result =
numerator.Layout(numerator_space);
auto numerator_margins =
ComputeMarginsFor(numerator_space, numerator.Style(), ConstraintSpace());
auto denominator_space = CreateConstraintSpaceForMathChild(
- Node(), child_available_size, ConstraintSpace(), denominator);
+ Node(), ChildAvailableSize(), ConstraintSpace(), denominator);
scoped_refptr<const NGLayoutResult> denominator_layout_result =
denominator.Layout(denominator_space);
auto denominator_margins = ComputeMarginsFor(
@@ -238,8 +231,8 @@ scoped_refptr<const NGLayoutResult> NGMathFractionLayoutAlgorithm::Layout() {
LayoutUnit fraction_descent =
std::max(-numerator_shift + numerator_descent,
denominator_shift + denominator_descent);
- fraction_ascent += border_scrollbar_padding_.block_start;
- fraction_descent += border_scrollbar_padding_.block_end;
+ fraction_ascent += BorderScrollbarPadding().block_start;
+ fraction_descent += BorderScrollbarPadding().block_end;
LayoutUnit total_block_size = fraction_ascent + fraction_descent;
container_builder_.SetBaseline(fraction_ascent);
@@ -247,14 +240,13 @@ scoped_refptr<const NGLayoutResult> NGMathFractionLayoutAlgorithm::Layout() {
LogicalOffset numerator_offset;
LogicalOffset denominator_offset;
numerator_offset.inline_offset =
- border_scrollbar_padding_.inline_start + numerator_margins.inline_start +
- (child_available_size.inline_size -
+ BorderScrollbarPadding().inline_start + numerator_margins.inline_start +
+ (ChildAvailableSize().inline_size -
(numerator_fragment.InlineSize() + numerator_margins.InlineSum())) /
2;
denominator_offset.inline_offset =
- border_scrollbar_padding_.inline_start +
- denominator_margins.inline_start +
- (child_available_size.inline_size -
+ BorderScrollbarPadding().inline_start + denominator_margins.inline_start +
+ (ChildAvailableSize().inline_size -
(denominator_fragment.InlineSize() + denominator_margins.InlineSum())) /
2;
@@ -274,11 +266,11 @@ scoped_refptr<const NGLayoutResult> NGMathFractionLayoutAlgorithm::Layout() {
denominator.StoreMargins(ConstraintSpace(), denominator_margins);
LayoutUnit block_size = ComputeBlockSizeForFragment(
- ConstraintSpace(), Style(), border_scrollbar_padding_, total_block_size,
- border_box_size.inline_size);
+ ConstraintSpace(), Style(), BorderPadding(), total_block_size,
+ container_builder_.InitialBorderBoxSize().inline_size);
container_builder_.SetIntrinsicBlockSize(total_block_size);
- container_builder_.SetBlockSize(block_size);
+ container_builder_.SetFragmentsTotalBlockSize(block_size);
NGOutOfFlowLayoutPart(Node(), ConstraintSpace(), container_builder_.Borders(),
&container_builder_)
@@ -290,7 +282,7 @@ scoped_refptr<const NGLayoutResult> NGMathFractionLayoutAlgorithm::Layout() {
MinMaxSizesResult NGMathFractionLayoutAlgorithm::ComputeMinMaxSizes(
const MinMaxSizesInput& child_input) const {
if (auto result = CalculateMinMaxSizesIgnoringChildren(
- Node(), border_scrollbar_padding_))
+ Node(), BorderScrollbarPadding()))
return *result;
MinMaxSizes sizes;
@@ -310,7 +302,7 @@ MinMaxSizesResult NGMathFractionLayoutAlgorithm::ComputeMinMaxSizes(
child_result.depends_on_percentage_block_size;
}
- sizes += border_scrollbar_padding_.InlineSum();
+ sizes += BorderScrollbarPadding().InlineSum();
return {sizes, depends_on_percentage_block_size};
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.h
index 83640d5826a..05b8761c6f6 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.h
@@ -22,7 +22,6 @@ class CORE_EXPORT NGMathFractionLayoutAlgorithm
MinMaxSizesResult ComputeMinMaxSizes(const MinMaxSizesInput&) const final;
void GatherChildren(NGBlockNode* numerator, NGBlockNode* denominator);
- const NGBoxStrut border_scrollbar_padding_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.cc
index a4f4ef38039..851c08fc2fc 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.cc
@@ -29,11 +29,7 @@ inline LayoutUnit InlineOffsetForDisplayMathCentering(
NGMathRowLayoutAlgorithm::NGMathRowLayoutAlgorithm(
const NGLayoutAlgorithmParams& params)
- : NGLayoutAlgorithm(params),
- border_padding_(params.fragment_geometry.border +
- params.fragment_geometry.padding),
- border_scrollbar_padding_(border_padding_ +
- params.fragment_geometry.scrollbar) {
+ : NGLayoutAlgorithm(params) {
DCHECK(params.space.IsNewFormattingContext());
DCHECK(!ConstraintSpace().HasBlockFragmentation());
container_builder_.SetIsNewFormattingContext(
@@ -42,7 +38,7 @@ NGMathRowLayoutAlgorithm::NGMathRowLayoutAlgorithm(
}
void NGMathRowLayoutAlgorithm::LayoutRowItems(
- NGContainerFragmentBuilder::ChildrenVector* children,
+ ChildrenVector* children,
LayoutUnit* max_row_block_baseline,
LogicalSize* row_total_size) {
LayoutUnit inline_offset, max_row_ascent, max_row_descent;
@@ -53,13 +49,12 @@ void NGMathRowLayoutAlgorithm::LayoutRowItems(
// absolutely positioned".
// Issue: https://github.com/mathml-refresh/mathml/issues/16
container_builder_.AddOutOfFlowChildCandidate(
- To<NGBlockNode>(child), {border_scrollbar_padding_.inline_start,
- border_scrollbar_padding_.block_start});
+ To<NGBlockNode>(child), BorderScrollbarPadding().StartOffset());
continue;
}
const ComputedStyle& child_style = child.Style();
NGConstraintSpace child_space = CreateConstraintSpaceForMathChild(
- Node(), child_available_size_, ConstraintSpace(), child);
+ Node(), ChildAvailableSize(), ConstraintSpace(), child);
scoped_refptr<const NGLayoutResult> result =
To<NGBlockNode>(child).Layout(child_space, nullptr /* break token */);
const NGPhysicalContainerFragment& physical_fragment =
@@ -79,8 +74,9 @@ void NGMathRowLayoutAlgorithm::LayoutRowItems(
// TODO(rbuis): Operators can add lspace and rspace.
children->emplace_back(
+ To<NGBlockNode>(child), margins,
LogicalOffset{inline_offset, margins.block_start - ascent},
- &physical_fragment);
+ std::move(&physical_fragment));
inline_offset += fragment.InlineSize() + margins.inline_end;
@@ -103,10 +99,8 @@ scoped_refptr<const NGLayoutResult> NGMathRowLayoutAlgorithm::Layout() {
LayoutUnit max_row_block_baseline;
const LogicalSize border_box_size = container_builder_.InitialBorderBoxSize();
- child_available_size_ =
- ShrinkAvailableSize(border_box_size, border_scrollbar_padding_);
- NGContainerFragmentBuilder::ChildrenVector children;
+ ChildrenVector children;
LayoutRowItems(&children, &max_row_block_baseline, &max_row_size);
// Add children taking into account centering, baseline and
@@ -114,23 +108,24 @@ scoped_refptr<const NGLayoutResult> NGMathRowLayoutAlgorithm::Layout() {
LayoutUnit center_offset = InlineOffsetForDisplayMathCentering(
is_display_math, container_builder_.InlineSize(),
max_row_size.inline_size);
- LogicalOffset adjust_offset(
- border_scrollbar_padding_.inline_start + center_offset,
- border_scrollbar_padding_.block_start + max_row_block_baseline);
- for (auto& child : children) {
- child.offset += adjust_offset;
+
+ LogicalOffset adjust_offset = BorderScrollbarPadding().StartOffset();
+ adjust_offset += LogicalOffset{center_offset, max_row_block_baseline};
+ for (auto& child_data : children) {
+ child_data.offset += adjust_offset;
container_builder_.AddChild(
- To<NGPhysicalContainerFragment>(*child.fragment), child.offset);
+ To<NGPhysicalContainerFragment>(*child_data.fragment),
+ child_data.offset);
+ child_data.child.StoreMargins(ConstraintSpace(), child_data.margins);
}
- container_builder_.SetBaseline(border_scrollbar_padding_.block_start +
- max_row_block_baseline);
+ container_builder_.SetBaseline(adjust_offset.block_offset);
auto block_size = ComputeBlockSizeForFragment(
- ConstraintSpace(), Style(), border_padding_,
- max_row_size.block_size + border_scrollbar_padding_.BlockSum(),
+ ConstraintSpace(), Style(), BorderPadding(),
+ max_row_size.block_size + BorderScrollbarPadding().BlockSum(),
border_box_size.inline_size);
- container_builder_.SetBlockSize(block_size);
+ container_builder_.SetFragmentsTotalBlockSize(block_size);
NGOutOfFlowLayoutPart(
Node(), ConstraintSpace(),
@@ -144,7 +139,7 @@ scoped_refptr<const NGLayoutResult> NGMathRowLayoutAlgorithm::Layout() {
MinMaxSizesResult NGMathRowLayoutAlgorithm::ComputeMinMaxSizes(
const MinMaxSizesInput& child_input) const {
if (auto result = CalculateMinMaxSizesIgnoringChildren(
- Node(), border_scrollbar_padding_))
+ Node(), BorderScrollbarPadding()))
return *result;
MinMaxSizes sizes;
@@ -171,7 +166,7 @@ MinMaxSizesResult NGMathRowLayoutAlgorithm::ComputeMinMaxSizes(
sizes.Encompass(LayoutUnit());
DCHECK_LE(sizes.min_size, sizes.max_size);
- sizes += border_scrollbar_padding_.InlineSum();
+ sizes += BorderScrollbarPadding().InlineSum();
return {sizes, depends_on_percentage_block_size};
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h
index 1463e6256f6..478fc8167c0 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h
@@ -19,21 +19,34 @@ class CORE_EXPORT NGMathRowLayoutAlgorithm
NGBoxFragmentBuilder,
NGBlockBreakToken> {
public:
- NGMathRowLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
-
- protected:
- void LayoutRowItems(NGContainerFragmentBuilder::ChildrenVector*,
- LayoutUnit* max_row_block_baseline,
- LogicalSize* row_total_size);
+ explicit NGMathRowLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
+
+ struct ChildWithOffsetAndMargins {
+ DISALLOW_NEW();
+ ChildWithOffsetAndMargins(const NGBlockNode& child,
+ const NGBoxStrut& margins,
+ LogicalOffset offset,
+ scoped_refptr<const NGPhysicalFragment> fragment)
+ : child(child),
+ margins(margins),
+ offset(offset),
+ fragment(std::move(fragment)) {}
+
+ NGBlockNode child;
+ NGBoxStrut margins;
+ LogicalOffset offset;
+ scoped_refptr<const NGPhysicalFragment> fragment;
+ };
+ typedef Vector<ChildWithOffsetAndMargins, 4> ChildrenVector;
private:
scoped_refptr<const NGLayoutResult> Layout() final;
MinMaxSizesResult ComputeMinMaxSizes(const MinMaxSizesInput&) const final;
- LogicalSize child_available_size_;
- const NGBoxStrut border_padding_;
- const NGBoxStrut border_scrollbar_padding_;
+ void LayoutRowItems(ChildrenVector*,
+ LayoutUnit* max_row_block_baseline,
+ LogicalSize* row_total_size);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.cc
index afdfca8c5b8..31b2a7a4f77 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.cc
@@ -79,16 +79,11 @@ ScriptsVerticalParameters GetScriptsVerticalParameters(
NGMathScriptsLayoutAlgorithm::NGMathScriptsLayoutAlgorithm(
const NGLayoutAlgorithmParams& params)
- : NGLayoutAlgorithm(params),
- border_scrollbar_padding_(params.fragment_geometry.border +
- params.fragment_geometry.scrollbar +
- params.fragment_geometry.padding) {
+ : NGLayoutAlgorithm(params) {
DCHECK(params.space.IsNewFormattingContext());
container_builder_.SetIsNewFormattingContext(
params.space.IsNewFormattingContext());
container_builder_.SetInitialFragmentGeometry(params.fragment_geometry);
- child_available_size_ = ShrinkAvailableSize(
- container_builder_.InitialBorderBoxSize(), border_scrollbar_padding_);
}
void NGMathScriptsLayoutAlgorithm::GatherChildren(
@@ -103,8 +98,7 @@ void NGMathScriptsLayoutAlgorithm::GatherChildren(
if (child.IsOutOfFlowPositioned()) {
if (container_builder) {
container_builder->AddOutOfFlowChildCandidate(
- block_child, {border_scrollbar_padding_.inline_start,
- border_scrollbar_padding_.block_start});
+ block_child, BorderScrollbarPadding().StartOffset());
}
continue;
}
@@ -232,7 +226,7 @@ NGMathScriptsLayoutAlgorithm::ChildAndMetrics
NGMathScriptsLayoutAlgorithm::LayoutAndGetMetrics(NGBlockNode child) const {
ChildAndMetrics child_and_metrics;
auto constraint_space = CreateConstraintSpaceForMathChild(
- Node(), child_available_size_, ConstraintSpace(), child);
+ Node(), ChildAvailableSize(), ConstraintSpace(), child);
child_and_metrics.result =
child.Layout(constraint_space, nullptr /*break_token*/);
NGBoxFragment fragment(
@@ -265,14 +259,17 @@ scoped_refptr<const NGLayoutResult> NGMathScriptsLayoutAlgorithm::Layout() {
VerticalMetrics metrics =
GetVerticalMetrics(base_metrics, sub_metrics, sup_metrics);
+ const LogicalOffset content_start_offset =
+ BorderScrollbarPadding().StartOffset();
+
LayoutUnit ascent =
std::max(base_metrics.ascent, metrics.ascent + metrics.sup_shift) +
- border_scrollbar_padding_.block_start;
+ content_start_offset.block_offset;
LayoutUnit descent =
std::max(base_metrics.descent, metrics.descent + metrics.sub_shift);
// TODO(rbuis): take into account italic correction.
- LayoutUnit inline_offset = border_scrollbar_padding_.inline_start +
- base_metrics.margins.inline_start;
+ LayoutUnit inline_offset =
+ content_start_offset.inline_offset + base_metrics.margins.inline_start;
LogicalOffset base_offset(
inline_offset,
@@ -302,15 +299,14 @@ scoped_refptr<const NGLayoutResult> NGMathScriptsLayoutAlgorithm::Layout() {
container_builder_.SetBaseline(ascent);
LayoutUnit intrinsic_block_size =
- ascent + descent + border_scrollbar_padding_.block_end;
+ ascent + descent + BorderScrollbarPadding().block_end;
LayoutUnit block_size = ComputeBlockSizeForFragment(
- ConstraintSpace(), Style(), border_scrollbar_padding_,
- intrinsic_block_size,
+ ConstraintSpace(), Style(), BorderPadding(), intrinsic_block_size,
container_builder_.InitialBorderBoxSize().inline_size);
container_builder_.SetIntrinsicBlockSize(intrinsic_block_size);
- container_builder_.SetBlockSize(block_size);
+ container_builder_.SetFragmentsTotalBlockSize(block_size);
NGOutOfFlowLayoutPart(Node(), ConstraintSpace(), container_builder_.Borders(),
&container_builder_)
@@ -322,7 +318,7 @@ scoped_refptr<const NGLayoutResult> NGMathScriptsLayoutAlgorithm::Layout() {
MinMaxSizesResult NGMathScriptsLayoutAlgorithm::ComputeMinMaxSizes(
const MinMaxSizesInput& child_input) const {
if (auto result = CalculateMinMaxSizesIgnoringChildren(
- Node(), border_scrollbar_padding_))
+ Node(), BorderScrollbarPadding()))
return *result;
NGBlockNode base = nullptr;
@@ -384,7 +380,7 @@ MinMaxSizesResult NGMathScriptsLayoutAlgorithm::ComputeMinMaxSizes(
NOTREACHED();
break;
}
- sizes += border_scrollbar_padding_.InlineSum();
+ sizes += BorderScrollbarPadding().InlineSum();
return {sizes, depends_on_percentage_block_size};
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.h
index 8d8f34ea40c..ce65ecd1df9 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.h
@@ -57,9 +57,6 @@ class CORE_EXPORT NGMathScriptsLayoutAlgorithm
const ChildAndMetrics& sup_metrics) const;
scoped_refptr<const NGLayoutResult> Layout() final;
-
- LogicalSize child_available_size_;
- const NGBoxStrut border_scrollbar_padding_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.cc
index 6dad93301a8..51be5e7fb8b 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.cc
@@ -11,9 +11,7 @@ namespace blink {
NGMathSpaceLayoutAlgorithm::NGMathSpaceLayoutAlgorithm(
const NGLayoutAlgorithmParams& params)
- : NGLayoutAlgorithm(params),
- border_padding_(params.fragment_geometry.border +
- params.fragment_geometry.padding) {
+ : NGLayoutAlgorithm(params) {
DCHECK(params.fragment_geometry.scrollbar.IsEmpty());
container_builder_.SetIsNewFormattingContext(true);
container_builder_.SetInitialFragmentGeometry(params.fragment_geometry);
@@ -22,27 +20,28 @@ NGMathSpaceLayoutAlgorithm::NGMathSpaceLayoutAlgorithm(
scoped_refptr<const NGLayoutResult> NGMathSpaceLayoutAlgorithm::Layout() {
DCHECK(!BreakToken());
+ LayoutUnit intrinsic_block_size = BorderScrollbarPadding().BlockSum();
LayoutUnit block_size = ComputeBlockSizeForFragment(
- ConstraintSpace(), Style(), border_padding_, border_padding_.BlockSum(),
+ ConstraintSpace(), Style(), BorderPadding(), intrinsic_block_size,
container_builder_.InitialBorderBoxSize().inline_size);
- container_builder_.SetIntrinsicBlockSize(border_padding_.BlockSum());
- container_builder_.SetBlockSize(block_size);
+ container_builder_.SetIntrinsicBlockSize(intrinsic_block_size);
+ container_builder_.SetFragmentsTotalBlockSize(block_size);
container_builder_.SetBaseline(
- border_padding_.block_start +
+ BorderScrollbarPadding().block_start +
ValueForLength(Style().GetMathBaseline(), LayoutUnit()));
return container_builder_.ToBoxFragment();
}
MinMaxSizesResult NGMathSpaceLayoutAlgorithm::ComputeMinMaxSizes(
const MinMaxSizesInput&) const {
- if (auto result =
- CalculateMinMaxSizesIgnoringChildren(Node(), border_padding_))
+ if (auto result = CalculateMinMaxSizesIgnoringChildren(
+ Node(), BorderScrollbarPadding()))
return *result;
MinMaxSizes sizes;
- sizes += border_padding_.InlineSum();
+ sizes += BorderScrollbarPadding().InlineSum();
return {sizes, /* depends_on_percentage_block_size */ false};
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.h
index 838d058f895..5306bf446cf 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.h
@@ -21,8 +21,6 @@ class CORE_EXPORT NGMathSpaceLayoutAlgorithm
scoped_refptr<const NGLayoutResult> Layout() final;
MinMaxSizesResult ComputeMinMaxSizes(const MinMaxSizesInput&) const final;
-
- const NGBoxStrut border_padding_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.cc
index 1b419ddb83e..872196de21a 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.cc
@@ -75,10 +75,7 @@ UnderOverVerticalParameters GetUnderOverVerticalParameters(
NGMathUnderOverLayoutAlgorithm::NGMathUnderOverLayoutAlgorithm(
const NGLayoutAlgorithmParams& params)
- : NGLayoutAlgorithm(params),
- border_scrollbar_padding_(params.fragment_geometry.border +
- params.fragment_geometry.padding +
- params.fragment_geometry.scrollbar) {
+ : NGLayoutAlgorithm(params) {
DCHECK(params.space.IsNewFormattingContext());
container_builder_.SetIsNewFormattingContext(
params.space.IsNewFormattingContext());
@@ -94,8 +91,7 @@ void NGMathUnderOverLayoutAlgorithm::GatherChildren(NGBlockNode* base,
NGBlockNode block_child = To<NGBlockNode>(child);
if (child.IsOutOfFlowPositioned()) {
container_builder_.AddOutOfFlowChildCandidate(
- block_child, {border_scrollbar_padding_.inline_start,
- border_scrollbar_padding_.block_start});
+ block_child, BorderScrollbarPadding().StartOffset());
continue;
}
if (!*base) {
@@ -135,10 +131,11 @@ scoped_refptr<const NGLayoutResult> NGMathUnderOverLayoutAlgorithm::Layout() {
GatherChildren(&base, &over, &under);
const LogicalSize border_box_size = container_builder_.InitialBorderBoxSize();
- auto child_available_size =
- ShrinkAvailableSize(border_box_size, border_scrollbar_padding_);
- LayoutUnit block_offset = border_scrollbar_padding_.block_start;
+ const LogicalOffset content_start_offset =
+ BorderScrollbarPadding().StartOffset();
+
+ LayoutUnit block_offset = content_start_offset.block_offset;
UnderOverVerticalParameters parameters =
GetUnderOverVerticalParameters(Style());
// TODO(rbuis): handle stretchy operators.
@@ -148,7 +145,7 @@ scoped_refptr<const NGLayoutResult> NGMathUnderOverLayoutAlgorithm::Layout() {
// therefore centered relative to themselves).
if (over) {
auto over_space = CreateConstraintSpaceForMathChild(
- Node(), child_available_size, ConstraintSpace(), over);
+ Node(), ChildAvailableSize(), ConstraintSpace(), over);
scoped_refptr<const NGLayoutResult> over_layout_result =
over.Layout(over_space);
NGBoxStrut over_margins =
@@ -158,8 +155,8 @@ scoped_refptr<const NGLayoutResult> NGMathUnderOverLayoutAlgorithm::Layout() {
To<NGPhysicalBoxFragment>(over_layout_result->PhysicalFragment()));
block_offset += parameters.over_extra_ascender + over_margins.block_start;
LogicalOffset over_offset = {
- border_scrollbar_padding_.inline_start + over_margins.inline_start +
- (child_available_size.inline_size -
+ content_start_offset.inline_offset + over_margins.inline_start +
+ (ChildAvailableSize().inline_size -
(over_fragment.InlineSize() + over_margins.InlineSum())) /
2,
block_offset};
@@ -180,7 +177,7 @@ scoped_refptr<const NGLayoutResult> NGMathUnderOverLayoutAlgorithm::Layout() {
}
auto base_space = CreateConstraintSpaceForMathChild(
- Node(), child_available_size, ConstraintSpace(), base);
+ Node(), ChildAvailableSize(), ConstraintSpace(), base);
auto base_layout_result = base.Layout(base_space);
auto base_margins =
ComputeMarginsFor(base_space, base.Style(), ConstraintSpace());
@@ -191,8 +188,8 @@ scoped_refptr<const NGLayoutResult> NGMathUnderOverLayoutAlgorithm::Layout() {
block_offset += base_margins.block_start;
LogicalOffset base_offset = {
- border_scrollbar_padding_.inline_start + base_margins.inline_start +
- (child_available_size.inline_size -
+ content_start_offset.inline_offset + base_margins.inline_start +
+ (ChildAvailableSize().inline_size -
(base_fragment.InlineSize() + base_margins.InlineSum())) /
2,
block_offset};
@@ -203,7 +200,7 @@ scoped_refptr<const NGLayoutResult> NGMathUnderOverLayoutAlgorithm::Layout() {
if (under) {
auto under_space = CreateConstraintSpaceForMathChild(
- Node(), child_available_size, ConstraintSpace(), under);
+ Node(), ChildAvailableSize(), ConstraintSpace(), under);
scoped_refptr<const NGLayoutResult> under_layout_result =
under.Layout(under_space);
NGBoxStrut under_margins =
@@ -221,8 +218,8 @@ scoped_refptr<const NGLayoutResult> NGMathUnderOverLayoutAlgorithm::Layout() {
parameters.under_shift_min - under_ascent);
}
LogicalOffset under_offset = {
- border_scrollbar_padding_.inline_start + under_margins.inline_start +
- (child_available_size.inline_size -
+ content_start_offset.inline_offset + under_margins.inline_start +
+ (ChildAvailableSize().inline_size -
(under_fragment.InlineSize() + under_margins.InlineSum())) /
2,
block_offset};
@@ -238,14 +235,14 @@ scoped_refptr<const NGLayoutResult> NGMathUnderOverLayoutAlgorithm::Layout() {
base_fragment.Baseline().value_or(base_fragment.BlockSize());
container_builder_.SetBaseline(base_offset.block_offset + base_ascent);
- block_offset += border_scrollbar_padding_.block_end;
+ block_offset += BorderScrollbarPadding().block_end;
- LayoutUnit block_size = ComputeBlockSizeForFragment(
- ConstraintSpace(), Style(), border_scrollbar_padding_, block_offset,
- border_box_size.inline_size);
+ LayoutUnit block_size =
+ ComputeBlockSizeForFragment(ConstraintSpace(), Style(), BorderPadding(),
+ block_offset, border_box_size.inline_size);
container_builder_.SetIntrinsicBlockSize(block_offset);
- container_builder_.SetBlockSize(block_size);
+ container_builder_.SetFragmentsTotalBlockSize(block_size);
NGOutOfFlowLayoutPart(Node(), ConstraintSpace(), container_builder_.Borders(),
&container_builder_)
@@ -259,7 +256,7 @@ MinMaxSizesResult NGMathUnderOverLayoutAlgorithm::ComputeMinMaxSizes(
DCHECK(IsValidMathMLScript(Node()));
if (auto result = CalculateMinMaxSizesIgnoringChildren(
- Node(), border_scrollbar_padding_))
+ Node(), BorderScrollbarPadding()))
return *result;
MinMaxSizes sizes;
@@ -279,7 +276,7 @@ MinMaxSizesResult NGMathUnderOverLayoutAlgorithm::ComputeMinMaxSizes(
child_result.depends_on_percentage_block_size;
}
- sizes += border_scrollbar_padding_.InlineSum();
+ sizes += BorderScrollbarPadding().InlineSum();
return {sizes, depends_on_percentage_block_size};
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.h
index a324e1b6032..c5d7d931943 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.h
@@ -26,8 +26,6 @@ class CORE_EXPORT NGMathUnderOverLayoutAlgorithm
void GatherChildren(NGBlockNode* base,
NGBlockNode* second,
NGBlockNode* third);
-
- const NGBoxStrut border_scrollbar_padding_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_mathml_paint_info.h b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_mathml_paint_info.h
new file mode 100644
index 00000000000..157a3f09651
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_mathml_paint_info.h
@@ -0,0 +1,28 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATHML_PAINT_INFO_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATHML_PAINT_INFO_H_
+
+#include <unicode/uchar.h>
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
+
+namespace blink {
+
+class ShapeResultView;
+
+struct CORE_EXPORT NGMathMLPaintInfo {
+ USING_FAST_MALLOC(NGMathMLPaintInfo);
+
+ public:
+ scoped_refptr<const ShapeResultView> operator_shape_result_view;
+ LayoutUnit operator_inline_size;
+ LayoutUnit operator_ascent;
+ LayoutUnit operator_descent;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATHML_PAINT_INFO_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
index fd2180c4c50..f8acd6fe3ed 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
@@ -369,15 +369,21 @@ base::Optional<LayoutUnit> ComputeAbsoluteDialogYPosition(
return base::nullopt;
}
- auto* scrollable_area = dialog.GetDocument().View()->LayoutViewport();
+ auto& document = dialog.GetDocument();
+ auto* scrollable_area = document.View()->LayoutViewport();
LayoutUnit top =
LayoutUnit((dialog.Style()->GetPosition() == EPosition::kFixed)
? 0
: scrollable_area->ScrollOffsetInt().Height());
- int visible_height = dialog.GetDocument().View()->Height();
+ if (top)
+ UseCounter::Count(document, WebFeature::kDialogWithNonZeroScrollOffset);
+
+ int visible_height = document.View()->Height();
if (height < visible_height)
top += (visible_height - height) / 2;
+ else if (height > visible_height)
+ UseCounter::Count(document, WebFeature::kDialogHeightLargerThanViewport);
dialog_node->SetCentered(top);
return top;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc
index eea8efbb3da..dc210bf78e6 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc
@@ -27,13 +27,15 @@ NGBlockBreakToken::NGBlockBreakToken(
unsigned sequence_number,
const NGBreakTokenVector& child_break_tokens,
NGBreakAppeal break_appeal,
- bool has_seen_all_children)
+ bool has_seen_all_children,
+ bool is_at_block_end)
: NGBreakToken(kBlockBreakToken, kUnfinished, node),
consumed_block_size_(consumed_block_size),
sequence_number_(sequence_number),
num_children_(child_break_tokens.size()) {
break_appeal_ = break_appeal;
has_seen_all_children_ = has_seen_all_children;
+ is_at_block_end_ = is_at_block_end;
for (wtf_size_t i = 0; i < child_break_tokens.size(); ++i) {
child_break_tokens_[i] = child_break_tokens[i].get();
child_break_tokens_[i]->AddRef();
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h
index ee2bcc92fba..917d753b120 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h
@@ -30,7 +30,8 @@ class CORE_EXPORT NGBlockBreakToken final : public NGBreakToken {
unsigned sequence_number,
const NGBreakTokenVector& child_break_tokens,
NGBreakAppeal break_appeal,
- bool has_seen_all_children) {
+ bool has_seen_all_children,
+ bool is_at_block_end) {
// We store the children list inline in the break token as a flexible
// array. Therefore, we need to make sure to allocate enough space for
// that array here, which requires a manual allocation + placement new.
@@ -38,9 +39,10 @@ class CORE_EXPORT NGBlockBreakToken final : public NGBreakToken {
sizeof(NGBlockBreakToken) +
child_break_tokens.size() * sizeof(NGBreakToken*),
::WTF::GetStringWithTypeName<NGBlockBreakToken>());
- new (data) NGBlockBreakToken(PassKey(), node, consumed_block_size,
- sequence_number, child_break_tokens,
- break_appeal, has_seen_all_children);
+ new (data)
+ NGBlockBreakToken(PassKey(), node, consumed_block_size, sequence_number,
+ child_break_tokens, break_appeal,
+ has_seen_all_children, is_at_block_end);
return base::AdoptRef(static_cast<NGBlockBreakToken*>(data));
}
@@ -95,6 +97,30 @@ class CORE_EXPORT NGBlockBreakToken final : public NGBreakToken {
// have one (since all children are either finished, or have a break token).
bool HasSeenAllChildren() const { return has_seen_all_children_; }
+ // Return true if layout was past the block-end border edge of the node when
+ // it fragmented. This typically means that something is overflowing the node,
+ // and that establishes a parallel flow [1]. Subsequent content may be put
+ // into the same fragmentainer as a fragment whose break token is in this
+ // state, as long as it fits.
+ //
+ // [1] https://www.w3.org/TR/css-break-3/#parallel-flows
+ //
+ // <div style="columns:2; column-fill:auto; height:100px;">
+ // <div id="a" style="height:100px;">
+ // <div id="inner" style="height:200px;"></div>
+ // </div>
+ // <div id="b" style="margin-top:-30px; height:30px;"></div>
+ // </div>
+ //
+ // #a and #b will be in the first column, while #inner will be in both the
+ // first and second one. The important detail here is that we're at the end of
+ // #a exactly at the bottom of the first column - even if #a broke inside
+ // because of #child. This means that we have no space left as such, but we're
+ // not ready to proceed to the next column. Anything that can fit at the
+ // bottom of a column (either because it actually has 0 height, or e.g. a
+ // negative top margin) will be put into that column, not the next.
+ bool IsAtBlockEnd() const { return is_at_block_end_; }
+
// The break tokens for children of the layout node.
//
// Each child we have visited previously in the block-flow layout algorithm
@@ -125,7 +151,8 @@ class CORE_EXPORT NGBlockBreakToken final : public NGBreakToken {
unsigned sequence_number,
const NGBreakTokenVector& child_break_tokens,
NGBreakAppeal break_appeal,
- bool has_seen_all_children);
+ bool has_seen_all_children,
+ bool is_at_block_end);
explicit NGBlockBreakToken(PassKey, NGLayoutInputNode node);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator.h
index 3b7636ad530..d75eb17c8d5 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator.h
@@ -43,9 +43,6 @@ class CORE_EXPORT NGBlockChildIterator {
Entry NextChild(
const NGInlineBreakToken* previous_inline_break_token = nullptr);
- // Return true if there are no more children to process.
- bool IsAtEnd() const { return !child_; }
-
private:
NGLayoutInputNode child_;
const NGBlockBreakToken* break_token_;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator_test.cc
index 01b46282762..91a0e741387 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator_test.cc
@@ -59,19 +59,19 @@ TEST_F(NGBlockChildIteratorTest, BreakTokens) {
NGBreakTokenVector empty_tokens_list;
scoped_refptr<NGBreakToken> child_token1 = NGBlockBreakToken::Create(
node1, LayoutUnit(), 0, empty_tokens_list, kBreakAppealPerfect,
- /* has_seen_all_children */ false);
+ /* has_seen_all_children */ false, /* is_at_block_end */ false);
scoped_refptr<NGBreakToken> child_token2 = NGBlockBreakToken::Create(
node2, LayoutUnit(), 0, empty_tokens_list, kBreakAppealPerfect,
- /* has_seen_all_children */ false);
+ /* has_seen_all_children */ false, /* is_at_block_end */ false);
scoped_refptr<NGBreakToken> child_token3 = NGBlockBreakToken::Create(
node3, LayoutUnit(), 0, empty_tokens_list, kBreakAppealPerfect,
- /* has_seen_all_children */ false);
+ /* has_seen_all_children */ false, /* is_at_block_end */ false);
NGBreakTokenVector child_break_tokens;
child_break_tokens.push_back(child_token1);
scoped_refptr<NGBlockBreakToken> parent_token = NGBlockBreakToken::Create(
container, LayoutUnit(), 0, child_break_tokens, kBreakAppealPerfect,
- /* has_seen_all_children */ false);
+ /* has_seen_all_children */ false, /* is_at_block_end */ false);
NGBlockChildIterator iterator(node1, parent_token.get());
ASSERT_EQ(NGBlockChildIterator::Entry(node1, child_token1.get()),
@@ -87,7 +87,7 @@ TEST_F(NGBlockChildIteratorTest, BreakTokens) {
child_break_tokens.push_back(child_token2);
parent_token = NGBlockBreakToken::Create(
container, LayoutUnit(), 0, child_break_tokens, kBreakAppealPerfect,
- /* has_seen_all_children */ false);
+ /* has_seen_all_children */ false, /* is_at_block_end */ false);
iterator = NGBlockChildIterator(node1, parent_token.get());
ASSERT_EQ(NGBlockChildIterator::Entry(node1, child_token1.get()),
@@ -104,7 +104,7 @@ TEST_F(NGBlockChildIteratorTest, BreakTokens) {
child_break_tokens.push_back(child_token3);
parent_token = NGBlockBreakToken::Create(
container, LayoutUnit(), 0, child_break_tokens, kBreakAppealPerfect,
- /* has_seen_all_children */ false);
+ /* has_seen_all_children */ false, /* is_at_block_end */ false);
iterator = NGBlockChildIterator(node1, parent_token.get());
ASSERT_EQ(NGBlockChildIterator::Entry(node2, child_token2.get()),
@@ -120,7 +120,7 @@ TEST_F(NGBlockChildIteratorTest, BreakTokens) {
child_break_tokens.push_back(child_token3);
parent_token = NGBlockBreakToken::Create(
container, LayoutUnit(), 0, child_break_tokens, kBreakAppealPerfect,
- /* has_seen_all_children */ false);
+ /* has_seen_all_children */ false, /* is_at_block_end */ false);
iterator = NGBlockChildIterator(node1, parent_token.get());
ASSERT_EQ(NGBlockChildIterator::Entry(node1, child_token1.get()),
@@ -146,13 +146,13 @@ TEST_F(NGBlockChildIteratorTest, SeenAllChildren) {
NGBreakTokenVector empty_tokens_list;
scoped_refptr<NGBreakToken> child_token1 = NGBlockBreakToken::Create(
node1, LayoutUnit(), 0, empty_tokens_list, kBreakAppealPerfect,
- /* has_seen_all_children */ false);
+ /* has_seen_all_children */ false, /* is_at_block_end */ false);
NGBreakTokenVector child_break_tokens;
child_break_tokens.push_back(child_token1);
scoped_refptr<NGBlockBreakToken> parent_token = NGBlockBreakToken::Create(
container, LayoutUnit(), 0, child_break_tokens, kBreakAppealPerfect,
- /* has_seen_all_children */ true);
+ /* has_seen_all_children */ true, /* is_at_block_end */ false);
// We have a break token for #child1, but have seen all children. This happens
// e.g. when #child1 has overflow into a new fragmentainer, while #child2 was
@@ -167,7 +167,7 @@ TEST_F(NGBlockChildIteratorTest, SeenAllChildren) {
child_break_tokens.clear();
parent_token = NGBlockBreakToken::Create(
container, LayoutUnit(), 0, child_break_tokens, kBreakAppealPerfect,
- /* has_seen_all_children */ true);
+ /* has_seen_all_children */ true, /* is_at_block_end */ false);
// We have no break tokens, but have seen all children. This happens e.g. when
// we have a large container with fixed block-size, with empty space at the
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
index ab6b62882b8..d2a1a60c73d 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -14,6 +14,8 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.h"
+#include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h"
#include "third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_child_iterator.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_utils.h"
@@ -38,96 +40,24 @@
namespace blink {
namespace {
-// Returns the logical bottom offset of the last line text, relative to
-// |container| origin. This is used to decide ruby annotation box position.
-//
-// TODO(layout-dev): Using ScrollableOverflow() is same as legacy
-// LayoutRubyRun. However its result is not good with some fonts/platforms.
-LayoutUnit LastLineTextLogicalBottom(const NGPhysicalBoxFragment& container,
- LayoutUnit default_value) {
- const ComputedStyle& container_style = container.Style();
- if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
- if (!container.Items())
- return default_value;
- NGInlineCursor cursor(*container.Items());
- cursor.MoveToLastLine();
- const auto* line_item = cursor.CurrentItem();
- if (!line_item)
- return default_value;
- DCHECK_EQ(line_item->Type(), NGFragmentItem::kLine);
- DCHECK(line_item->LineBoxFragment());
- PhysicalRect line_rect =
- line_item->LineBoxFragment()->ScrollableOverflowForLine(
- container, container_style, *line_item, cursor);
- return line_rect
- .ConvertToLogical(container_style.GetWritingMode(),
- container_style.Direction(), container.Size(),
- cursor.Current().Size())
- .BlockEndOffset();
- }
-
- const NGPhysicalLineBoxFragment* last_line = nullptr;
- PhysicalOffset last_line_offset;
- for (const auto& child_link : container.PostLayoutChildren()) {
- if (const auto* maybe_line =
- DynamicTo<NGPhysicalLineBoxFragment>(*child_link)) {
- last_line = maybe_line;
- last_line_offset = child_link.offset;
- }
- }
- if (!last_line)
- return default_value;
- PhysicalRect line_rect =
- last_line->ScrollableOverflow(container, container_style);
- line_rect.Move(last_line_offset);
- return line_rect
- .ConvertToLogical(container_style.GetWritingMode(),
- container_style.Direction(), container.Size(),
- last_line->Size())
- .BlockEndOffset();
-}
-
-// Returns the logical top offset of the first line text, relative to
-// |container| origin. This is used to decide ruby annotation box position.
-//
-// TODO(layout-dev): Using ScrollableOverflow() is same as legacy
-// LayoutRubyRun. However its result is not good with some fonts/platforms.
-LayoutUnit FirstLineTextLogicalTop(const NGPhysicalBoxFragment& container,
- LayoutUnit default_value) {
- const ComputedStyle& container_style = container.Style();
- if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
- if (!container.Items())
- return default_value;
- NGInlineCursor cursor(*container.Items());
- cursor.MoveToFirstLine();
- const auto* line_item = cursor.CurrentItem();
- if (!line_item)
- return default_value;
- DCHECK_EQ(line_item->Type(), NGFragmentItem::kLine);
- DCHECK(line_item->LineBoxFragment());
- PhysicalRect line_rect =
- line_item->LineBoxFragment()->ScrollableOverflowForLine(
- container, container_style, *line_item, cursor);
- return line_rect
- .ConvertToLogical(container_style.GetWritingMode(),
- container_style.Direction(), container.Size(),
- cursor.Current().Size())
- .offset.block_offset;
- }
-
- for (const auto& child_link : container.PostLayoutChildren()) {
- if (const auto* line = DynamicTo<NGPhysicalLineBoxFragment>(*child_link)) {
- PhysicalRect line_rect =
- line->ScrollableOverflow(container, container_style);
- line_rect.Move(child_link.offset);
- return line_rect
- .ConvertToLogical(container_style.GetWritingMode(),
- container_style.Direction(), container.Size(),
- line->Size())
- .offset.block_offset;
- }
- }
- return default_value;
+bool HasLineEvenIfEmpty(LayoutBox* box) {
+ LayoutBlockFlow* const block_flow = DynamicTo<LayoutBlockFlow>(box);
+ if (!block_flow)
+ return false;
+ // Note: |block_flow->NeedsCollectInline()| is true after removing all
+ // children from block[1].
+ // [1] editing/inserting/insert_after_delete.html
+ LayoutObject* const child = GetLayoutObjectForFirstChildNode(block_flow);
+ if (!child) {
+ // Note: |block_flow->ChildrenInline()| can be both true or false:
+ // - true: just after construction, <div></div>
+ // - true: one of child is inline them remove all, <div>abc</div>
+ // - false: all children are block then remove all, <div><p></p></div>
+ return block_flow->HasLineIfEmpty();
+ }
+ if (!AreNGBlockFlowChildrenInline(block_flow))
+ return false;
+ return NGInlineNode(block_flow).HasLineEvenIfEmpty();
}
inline scoped_refptr<const NGLayoutResult> LayoutBlockChild(
@@ -268,16 +198,11 @@ inline bool IsEarlyBreakpoint(const NGEarlyBreak& breakpoint,
NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(
const NGLayoutAlgorithmParams& params)
: NGLayoutAlgorithm(params),
- border_padding_(params.fragment_geometry.border +
- params.fragment_geometry.padding),
- border_scrollbar_padding_(border_padding_ +
- params.fragment_geometry.scrollbar),
previous_result_(params.previous_result),
is_resuming_(IsResumingLayout(params.break_token)),
exclusion_space_(params.space.ExclusionSpace()),
lines_until_clamp_(params.space.LinesUntilClamp()),
early_break_(params.early_break) {
- AdjustForFragmentation(BreakToken(), &border_scrollbar_padding_);
container_builder_.SetIsNewFormattingContext(
params.space.IsNewFormattingContext());
container_builder_.SetInitialFragmentGeometry(params.fragment_geometry);
@@ -293,8 +218,8 @@ void NGBlockLayoutAlgorithm::SetBoxType(NGPhysicalFragment::NGBoxType type) {
MinMaxSizesResult NGBlockLayoutAlgorithm::ComputeMinMaxSizes(
const MinMaxSizesInput& input) const {
- if (auto result = CalculateMinMaxSizesIgnoringChildren(
- node_, border_scrollbar_padding_))
+ if (auto result =
+ CalculateMinMaxSizesIgnoringChildren(node_, BorderScrollbarPadding()))
return *result;
MinMaxSizes sizes;
@@ -336,7 +261,8 @@ MinMaxSizesResult NGBlockLayoutAlgorithm::ComputeMinMaxSizes(
float_right_inline_size = LayoutUnit();
}
- MinMaxSizesInput child_input(input.percentage_resolution_block_size);
+ MinMaxSizesInput child_input(input.percentage_resolution_block_size,
+ input.type);
if (child.IsInline() || child.IsAnonymousBlock()) {
child_input.float_left_inline_size = float_left_inline_size;
child_input.float_right_inline_size = float_right_inline_size;
@@ -434,7 +360,7 @@ MinMaxSizesResult NGBlockLayoutAlgorithm::ComputeMinMaxSizes(
DCHECK_GE(sizes.min_size, LayoutUnit());
DCHECK_LE(sizes.min_size, sizes.max_size) << Node().ToString();
- sizes += border_scrollbar_padding_.InlineSum();
+ sizes += BorderScrollbarPadding().InlineSum();
return {sizes, depends_on_percentage_block_size};
}
@@ -499,7 +425,8 @@ NOINLINE scoped_refptr<const NGLayoutResult>
NGBlockLayoutAlgorithm::LayoutWithItemsBuilder(
const NGInlineNode& first_child,
NGInlineChildLayoutContext* context) {
- NGFragmentItemsBuilder items_builder(first_child);
+ NGFragmentItemsBuilder items_builder(
+ first_child, container_builder_.GetWritingDirection());
container_builder_.SetItemsBuilder(&items_builder);
context->SetItemsBuilder(&items_builder);
scoped_refptr<const NGLayoutResult> result = Layout(context);
@@ -542,22 +469,14 @@ NGBlockLayoutAlgorithm::RelayoutIgnoringLineClamp() {
inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
NGInlineChildLayoutContext* inline_child_layout_context) {
- const LogicalSize border_box_size = container_builder_.InitialBorderBoxSize();
- child_available_size_ =
- ShrinkAvailableSize(border_box_size, border_scrollbar_padding_);
-
child_percentage_size_ = CalculateChildPercentageSize(
- ConstraintSpace(), Node(), child_available_size_);
+ ConstraintSpace(), Node(), ChildAvailableSize());
replaced_child_percentage_size_ = CalculateReplacedChildPercentageSize(
- ConstraintSpace(), Node(), child_available_size_,
- border_scrollbar_padding_, border_padding_);
+ ConstraintSpace(), Node(), ChildAvailableSize(), BorderScrollbarPadding(),
+ BorderPadding());
- // All of the above calculations with border_scrollbar_padding_ shouldn't
- // include the table cell's intrinsic padding. We can now add this.
- if (ConstraintSpace().IsTableCell()) {
- border_scrollbar_padding_ += ComputeIntrinsicPadding(
- ConstraintSpace(), Style(), container_builder_.Scrollbar());
- }
+ container_builder_.AdjustBorderScrollbarPaddingForFragmentation(BreakToken());
+ container_builder_.AdjustBorderScrollbarPaddingForTableCell();
DCHECK_EQ(!!inline_child_layout_context,
Node().IsInlineFormattingContextRoot());
@@ -581,14 +500,19 @@ inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
}
if (RuntimeEnabledFeatures::BlockFlowHandlesWebkitLineClampEnabled() &&
- Style().IsDeprecatedWebkitBoxWithVerticalLineClamp() &&
- !ignore_line_clamp_)
- lines_until_clamp_ = Style().LineClamp();
+ Style().IsDeprecatedWebkitBoxWithVerticalLineClamp()) {
+ if (!ignore_line_clamp_)
+ lines_until_clamp_ = Style().LineClamp();
+ } else if (Style().HasLineClamp()) {
+ UseCounter::Count(Node().GetDocument(),
+ WebFeature::kWebkitLineClampWithoutWebkitBox);
+ }
- LayoutUnit content_edge = border_scrollbar_padding_.block_start;
+ LayoutUnit content_edge = BorderScrollbarPadding().block_start;
NGPreviousInflowPosition previous_inflow_position = {
LayoutUnit(), ConstraintSpace().MarginStrut(),
+ is_resuming_ ? LayoutUnit() : container_builder_.Padding().block_start,
/* self_collapsing_child_had_clearance */ false};
// Do not collapse margins between parent and its child if:
@@ -601,11 +525,10 @@ inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
// D: We're forced to stop margin collapsing by a CSS property
//
// In all those cases we can and must resolve the BFC block offset now.
- if (border_scrollbar_padding_.block_start || is_resuming_ ||
+ if (content_edge || is_resuming_ ||
ConstraintSpace().IsNewFormattingContext()) {
bool discard_subsequent_margins =
- previous_inflow_position.margin_strut.discard_margins &&
- !border_scrollbar_padding_.block_start;
+ previous_inflow_position.margin_strut.discard_margins && !content_edge;
if (!ResolveBfcBlockOffset(&previous_inflow_position)) {
// There should be no preceding content that depends on the BFC block
// offset of a new formatting context block, and likewise when resuming
@@ -724,7 +647,7 @@ inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
}
container_builder_.AddBreakBeforeChild(child, kBreakAppealPerfect,
/* is_forced_break */ false);
- SetFragmentainerOutOfSpace(&previous_inflow_position);
+ ConsumeRemainingFragmentainerSpace(&previous_inflow_position);
break;
}
@@ -751,10 +674,13 @@ inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
return container_builder_.Abort(status);
}
if (ConstraintSpace().HasBlockFragmentation()) {
- if (container_builder_.DidBreak() &&
- IsFragmentainerOutOfSpace(
- previous_inflow_position.logical_block_offset))
+ // A child break in a parallel flow doesn't affect whether we should
+ // break here or not.
+ if (container_builder_.HasInflowChildBreakInside()) {
+ // But if the break happened in the same flow, we'll now just finish
+ // layout of the fragment. No more siblings should be processed.
break;
+ }
// We need to propagate the initial break-before value up our container
// chain, until we reach a container that's not a first child. If we get
@@ -783,7 +709,7 @@ inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
NGLayoutResult::kNeedsRelayoutWithNoForcedTruncateAtLineClamp);
}
- if (child_iterator.IsAtEnd()) {
+ if (!child_iterator.NextChild(previous_inline_break_token.get()).node) {
// We've gone through all the children. This doesn't necessarily mean that
// we're done fragmenting, as there may be parallel flows [1] (visible
// overflow) still needing more space than what the current fragmentainer
@@ -800,6 +726,37 @@ inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
// offset, as that could give us a negative content box size.
intrinsic_block_size_ = content_edge;
+ // Add line height for empty content editable or button with empty label, e.g.
+ // <div contenteditable></div>, <input type="button" value="">
+ if (container_builder_.HasSeenAllChildren() &&
+ HasLineEvenIfEmpty(Node().GetLayoutBox())) {
+ intrinsic_block_size_ +=
+ std::max(intrinsic_block_size_,
+ Node().GetLayoutBox()->LogicalHeightForEmptyLine());
+ // Test [1][2] require baseline offset for empty editable.
+ // [1] css3/flexbox/baseline-for-empty-line.html
+ // [2] inline-block/contenteditable-baseline.html
+ const LayoutBlock* const layout_block =
+ To<LayoutBlock>(Node().GetLayoutBox());
+ if (auto baseline_offset = layout_block->BaselineForEmptyLine(
+ layout_block->IsHorizontalWritingMode() ? kHorizontalLine
+ : kVerticalLine))
+ container_builder_.SetBaseline(*baseline_offset);
+ }
+
+ // Collapse annotation overflow and padding.
+ // logical_block_offset already contains block-end annotation overflow.
+ // However, if the container has non-zero block-end padding, the annotation
+ // can extend on the padding. So we decrease logical_block_offset by
+ // shareable part of the annotation overflow and the padding.
+ if (previous_inflow_position.block_end_annotation_space < LayoutUnit()) {
+ DCHECK(RuntimeEnabledFeatures::LayoutNGRubyEnabled());
+ const LayoutUnit annotation_overflow =
+ -previous_inflow_position.block_end_annotation_space;
+ previous_inflow_position.logical_block_offset -=
+ std::min(container_builder_.Padding().block_end, annotation_overflow);
+ }
+
// To save space of the stack when we recurse into children, the rest of this
// function is continued within |FinishLayout|. However it should be read as
// one function.
@@ -822,9 +779,10 @@ scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::FinishLayout(
// intrinsic block-size at the time of the clamp.
if (intrinsic_block_size_when_clamped_) {
DCHECK(container_builder_.BfcBlockOffset());
- intrinsic_block_size_ = *intrinsic_block_size_when_clamped_;
+ intrinsic_block_size_ = *intrinsic_block_size_when_clamped_ +
+ BorderScrollbarPadding().block_end;
end_margin_strut = NGMarginStrut();
- } else if (border_scrollbar_padding_.block_end ||
+ } else if (BorderScrollbarPadding().block_end ||
previous_inflow_position->self_collapsing_child_had_clearance ||
ConstraintSpace().IsNewFormattingContext()) {
// The end margin strut of an in-flow fragment contributes to the size of
@@ -833,16 +791,7 @@ scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::FinishLayout(
// - There was a self-collapsing child affected by clearance.
// - We are a new formatting context.
// Additionally this fragment produces no end margin strut.
- //
- // If we are a quirky container, we ignore any quirky margins and
- // just consider normal margins to extend our size. Other UAs
- // perform this calculation differently, e.g. by just ignoring the
- // *last* quirky margin.
- // TODO: revisit previous implementation to avoid changing behavior and
- // https://html.spec.whatwg.org/C/#margin-collapsing-quirks
- LayoutUnit margin_strut_sum = node_.IsQuirkyContainer()
- ? end_margin_strut.QuirkyContainerSum()
- : end_margin_strut.Sum();
+
if (!container_builder_.BfcBlockOffset()) {
// If we have collapsed through the block start and all children (if any),
// now is the time to determine the BFC block offset, because finally we
@@ -857,6 +806,22 @@ scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::FinishLayout(
}
DCHECK(container_builder_.BfcBlockOffset());
} else {
+ // If we are a quirky container, we ignore any quirky margins and just
+ // consider normal margins to extend our size. Other UAs perform this
+ // calculation differently, e.g. by just ignoring the *last* quirky
+ // margin.
+ LayoutUnit margin_strut_sum = node_.IsQuirkyContainer()
+ ? end_margin_strut.QuirkyContainerSum()
+ : end_margin_strut.Sum();
+
+ if (ConstraintSpace().HasKnownFragmentainerBlockSize()) {
+ LayoutUnit bfc_block_offset =
+ *container_builder_.BfcBlockOffset() +
+ previous_inflow_position->logical_block_offset;
+ margin_strut_sum = AdjustedMarginAfterFinalChildFragment(
+ ConstraintSpace(), bfc_block_offset, margin_strut_sum);
+ }
+
// The trailing margin strut will be part of our intrinsic block size, but
// only if there is something that separates the end margin strut from the
// input margin strut (typically child content, block start
@@ -870,7 +835,7 @@ scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::FinishLayout(
previous_inflow_position->logical_block_offset + margin_strut_sum);
}
- intrinsic_block_size_ += border_scrollbar_padding_.block_end;
+ intrinsic_block_size_ += BorderScrollbarPadding().block_end;
end_margin_strut = NGMarginStrut();
} else {
// Update our intrinsic block size to be just past the block-end border edge
@@ -884,15 +849,20 @@ scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::FinishLayout(
container_builder_.SetOverflowBlockSize(intrinsic_block_size_);
intrinsic_block_size_ = ClampIntrinsicBlockSize(
- ConstraintSpace(), Node(), border_scrollbar_padding_,
+ ConstraintSpace(), Node(), BorderScrollbarPadding(),
intrinsic_block_size_,
CalculateQuirkyBodyMarginBlockSum(end_margin_strut));
+ LayoutUnit previously_consumed_block_size;
+ if (UNLIKELY(BreakToken()))
+ previously_consumed_block_size = BreakToken()->ConsumedBlockSize();
+
// Recompute the block-axis size now that we know our content size.
border_box_size.block_size = ComputeBlockSizeForFragment(
- ConstraintSpace(), Style(), border_padding_, intrinsic_block_size_,
+ ConstraintSpace(), Style(), BorderPadding(),
+ previously_consumed_block_size + intrinsic_block_size_,
border_box_size.inline_size);
- container_builder_.SetBlockSize(border_box_size.block_size);
+ container_builder_.SetFragmentsTotalBlockSize(border_box_size.block_size);
// If our BFC block-offset is still unknown, we check:
// - If we have a non-zero block-size (margins don't collapse through us).
@@ -1005,14 +975,22 @@ bool NGBlockLayoutAlgorithm::TryReuseFragmentsFromCache(
To<NGPhysicalBoxFragment>(previous_result_->PhysicalFragment());
const NGFragmentItems* previous_items = previous_fragment.Items();
DCHECK(previous_items);
+
+ // Find reusable lines. Fail if no items are reusable.
previous_items->DirtyLinesFromNeedsLayout(inline_node.GetLayoutBlockFlow());
+ const NGFragmentItem* end_item = previous_items->EndOfReusableItems();
+ DCHECK(end_item);
+ if (!end_item || end_item == &previous_items->front())
+ return false;
const auto& children = container_builder_.Children();
const wtf_size_t children_before = children.size();
+ NGFragmentItemsBuilder* items_builder = container_builder_.ItemsBuilder();
const NGConstraintSpace& space = ConstraintSpace();
- const auto result = container_builder_.ItemsBuilder()->AddPreviousItems(
- *previous_items, space.GetWritingMode(), space.Direction(),
- previous_fragment.Size(), &container_builder_, /* stop_at_dirty */ true);
+ DCHECK_EQ(items_builder->GetWritingMode(), space.GetWritingMode());
+ DCHECK_EQ(items_builder->Direction(), space.Direction());
+ const auto result = items_builder->AddPreviousItems(
+ *previous_items, previous_fragment.Size(), &container_builder_, end_item);
if (UNLIKELY(!result.succeeded)) {
DCHECK_EQ(children.size(), children_before);
@@ -1038,7 +1016,7 @@ void NGBlockLayoutAlgorithm::HandleOutOfFlowPositioned(
const NGPreviousInflowPosition& previous_inflow_position,
NGBlockNode child) {
DCHECK(child.IsOutOfFlowPositioned());
- LogicalOffset static_offset = {border_scrollbar_padding_.inline_start,
+ LogicalOffset static_offset = {BorderScrollbarPadding().inline_start,
previous_inflow_position.logical_block_offset};
// We only include the margin strut in the OOF static-position if we know we
@@ -1064,12 +1042,12 @@ void NGBlockLayoutAlgorithm::HandleOutOfFlowPositioned(
NGBfcOffset origin_bfc_offset = {
ConstraintSpace().BfcOffset().line_offset +
- border_scrollbar_padding_.LineLeft(Style().Direction()),
+ BorderScrollbarPadding().LineLeft(Style().Direction()),
origin_bfc_block_offset};
static_offset.inline_offset += CalculateOutOfFlowStaticInlineLevelOffset(
Style(), origin_bfc_offset, exclusion_space_,
- child_available_size_.inline_size);
+ ChildAvailableSize().inline_size);
}
container_builder_.AddOutOfFlowChildCandidate(child, static_offset);
@@ -1083,27 +1061,17 @@ void NGBlockLayoutAlgorithm::HandleFloat(
DCHECK(!IsResumingLayout(child_break_token) ||
container_builder_.BfcBlockOffset());
- if (broke_before_float_) {
- // We have already broken before a float. This means that we cannot place
- // any more floats now, as a float isn't allowed to start before any
- // preceding float.
- DCHECK(!child_break_token);
- container_builder_.AddBreakBeforeChild(child, base::nullopt,
- /* is_forced_break */ false);
- return;
- }
-
// If we don't have a BFC block-offset yet, the "expected" BFC block-offset
// is used to optimistically place floats.
NGBfcOffset origin_bfc_offset = {
ConstraintSpace().BfcOffset().line_offset +
- border_scrollbar_padding_.LineLeft(ConstraintSpace().Direction()),
+ BorderScrollbarPadding().LineLeft(ConstraintSpace().Direction()),
container_builder_.BfcBlockOffset()
? NextBorderEdge(previous_inflow_position)
: ConstraintSpace().ExpectedBfcBlockOffset()};
NGUnpositionedFloat unpositioned_float(
- child, child_break_token, child_available_size_, child_percentage_size_,
+ child, child_break_token, ChildAvailableSize(), child_percentage_size_,
replaced_child_percentage_size_, origin_bfc_offset, ConstraintSpace(),
Style());
@@ -1127,39 +1095,27 @@ void NGBlockLayoutAlgorithm::HandleFloat(
// TODO(mstensho): Handle abortions caused by block fragmentation.
DCHECK_EQ(layout_result.Status(), NGLayoutResult::kSuccess);
- const auto& physical_fragment = layout_result.PhysicalFragment();
- if (const NGBreakToken* token = physical_fragment.BreakToken()) {
+ if (positioned_float.need_break_before) {
DCHECK(ConstraintSpace().HasBlockFragmentation());
- if (!child_break_token && token->BreakAppeal() != kBreakAppealPerfect) {
- LayoutUnit fragmentainer_block_offset =
- ConstraintSpace().FragmentainerOffsetAtBfc() +
- positioned_float.bfc_offset.block_offset;
- if (fragmentainer_block_offset > LayoutUnit()) {
- // The float broke inside, and not at an ideal breakpoint. Break before
- // the float instead. Note that we don't check if we're at a valid class
- // A or C breakpoint (we only check that we're not at the start of the
- // fragmentainer (in which case breaking typically wouldn't eliminate
- // the unappealing break inside the float)). While no other browsers do
- // this either, we should consider doing this in the future. For now,
- // don't let the float affect the appeal of breaking inside this
- // container.
- BreakBeforeChild(ConstraintSpace(), child, layout_result,
- fragmentainer_block_offset,
- /* appeal */ base::nullopt,
- /* is_forced_break */ false, &container_builder_);
-
- // Then carry on with layout of this container. The float constitutes a
- // parallel flow, and there may be siblings that could still fit in the
- // current fragmentainer.
- broke_before_float_ = true;
- return;
- }
- }
+ LayoutUnit fragmentainer_block_offset =
+ ConstraintSpace().FragmentainerOffsetAtBfc() +
+ positioned_float.bfc_offset.block_offset;
+ BreakBeforeChild(ConstraintSpace(), child, *positioned_float.layout_result,
+ fragmentainer_block_offset,
+ /* appeal */ base::nullopt,
+ /* is_forced_break */ false, &container_builder_);
+
+ // After breaking before the float, carry on with layout of this
+ // container. The float constitutes a parallel flow, and there may be
+ // siblings that could still fit in the current fragmentainer.
+ return;
}
// TODO(mstensho): There should be a class A breakpoint between a float and
// another float, and also between a float and an in-flow block.
+ const NGPhysicalFragment& physical_fragment =
+ positioned_float.layout_result->PhysicalFragment();
LayoutUnit float_inline_size =
NGFragment(ConstraintSpace().GetWritingMode(), physical_fragment)
.InlineSize();
@@ -1193,7 +1149,7 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::HandleNewFormattingContext(
LayoutUnit child_origin_line_offset =
ConstraintSpace().BfcOffset().line_offset +
- border_scrollbar_padding_.LineLeft(direction);
+ BorderScrollbarPadding().LineLeft(direction);
// If the child has a block-start margin, and the BFC block offset is still
// unresolved, and we have preceding adjoining floats, things get complicated
@@ -1379,7 +1335,7 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::HandleNewFormattingContext(
// The margins we store will be used by e.g. getComputedStyle().
// When calculating these values, ignore any floats that might have
// affected the child. This is what Edge does.
- ResolveInlineMargins(child_style, Style(), child_available_size_.inline_size,
+ ResolveInlineMargins(child_style, Style(), ChildAvailableSize().inline_size,
fragment.InlineSize(), &child_data.margins);
To<NGBlockNode>(child).StoreMargins(ConstraintSpace(), child_data.margins);
@@ -1411,8 +1367,8 @@ NGBlockLayoutAlgorithm::LayoutNewFormattingContext(
DCHECK(container_builder_.BfcBlockOffset());
LayoutOpportunityVector opportunities =
- exclusion_space_.AllLayoutOpportunities(
- origin_offset, child_available_size_.inline_size);
+ exclusion_space_.AllLayoutOpportunities(origin_offset,
+ ChildAvailableSize().inline_size);
// We should always have at least one opportunity.
DCHECK_GT(opportunities.size(), 0u);
@@ -1444,14 +1400,14 @@ NGBlockLayoutAlgorithm::LayoutNewFormattingContext(
bool can_expand_outside_opportunity =
opportunity.rect.start_offset.line_offset ==
origin_offset.line_offset &&
- opportunity.rect.InlineSize() == child_available_size_.inline_size;
+ opportunity.rect.InlineSize() == ChildAvailableSize().inline_size;
if (can_expand_outside_opportunity) {
// No floats have affected the available inline-size, adjust the
// available inline-size by the margins.
DCHECK_EQ(line_left_offset, origin_offset.line_offset);
DCHECK_EQ(line_right_offset,
- origin_offset.line_offset + child_available_size_.inline_size);
+ origin_offset.line_offset + ChildAvailableSize().inline_size);
line_left_offset += line_left_margin;
line_right_offset -= line_right_margin;
} else {
@@ -1463,7 +1419,7 @@ NGBlockLayoutAlgorithm::LayoutNewFormattingContext(
origin_offset.line_offset + line_left_margin.ClampNegativeToZero());
line_right_offset = std::min(line_right_offset,
origin_offset.line_offset +
- child_available_size_.inline_size -
+ ChildAvailableSize().inline_size -
line_right_margin.ClampNegativeToZero());
}
LayoutUnit opportunity_size =
@@ -1480,7 +1436,7 @@ NGBlockLayoutAlgorithm::LayoutNewFormattingContext(
NGConstraintSpace child_space = CreateConstraintSpaceForChild(
child, child_data,
- {child_available_inline_size, child_available_size_.block_size},
+ {child_available_inline_size, ChildAvailableSize().block_size},
/* is_new_fc */ true, opportunity.rect.start_offset.block_offset);
// All formatting context roots (like this child) should start with an empty
@@ -1616,8 +1572,9 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::HandleInflow(
ComputeChildData(*previous_inflow_position, child, child_break_token,
/* is_new_fc */ false);
NGConstraintSpace child_space = CreateConstraintSpaceForChild(
- child, child_data, child_available_size_, /* is_new_fc */ false,
- forced_bfc_block_offset, has_clearance_past_adjoining_floats);
+ child, child_data, ChildAvailableSize(), /* is_new_fc */ false,
+ forced_bfc_block_offset, has_clearance_past_adjoining_floats,
+ previous_inflow_position->block_end_annotation_space);
scoped_refptr<const NGLayoutResult> layout_result =
LayoutInflow(child_space, child_break_token, early_break_, &child,
inline_child_layout_context);
@@ -1795,7 +1752,7 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::FinishInflow(
self_collapsing_child_needs_relayout) &&
child_bfc_block_offset) {
NGConstraintSpace new_child_space = CreateConstraintSpaceForChild(
- child, *child_data, child_available_size_, /* is_new_fc */ false,
+ child, *child_data, ChildAvailableSize(), /* is_new_fc */ false,
child_bfc_block_offset);
layout_result =
LayoutInflow(new_child_space, child_break_token, early_break_, &child,
@@ -1810,7 +1767,7 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::FinishInflow(
child_bfc_block_offset = layout_result->BfcBlockOffset();
DCHECK(child_bfc_block_offset);
new_child_space = CreateConstraintSpaceForChild(
- child, *child_data, child_available_size_, /* is_new_fc */ false,
+ child, *child_data, ChildAvailableSize(), /* is_new_fc */ false,
child_bfc_block_offset);
layout_result =
LayoutInflow(new_child_space, child_break_token, early_break_, &child,
@@ -1892,7 +1849,7 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::FinishInflow(
// required by e.g. getComputedStyle()).
if (!child_data->margins_fully_resolved) {
ResolveInlineMargins(child.Style(), Style(),
- child_available_size_.inline_size,
+ ChildAvailableSize().inline_size,
fragment.InlineSize(), &child_data->margins);
child_data->margins_fully_resolved = true;
}
@@ -1914,7 +1871,10 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::FinishInflow(
if (UNLIKELY(ConstraintSpace().IsInColumnBfc())) {
if (NGBlockNode spanner_node = layout_result->ColumnSpanner()) {
container_builder_.SetColumnSpanner(spanner_node);
- if (!container_builder_.DidBreak()) {
+ // TODO(mstensho): DidBreakSelf() is always false here, so this check is
+ // wrong. Still, no failing tests! Please investigate.
+ // HasInflowChildBreakInside() ought to be a better choice.
+ if (!container_builder_.DidBreakSelf()) {
// If we still haven't found a descendant at which to resume column
// layout after the spanner, look for one now.
if (NGLayoutInputNode next = child.NextSibling()) {
@@ -1939,8 +1899,7 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::FinishInflow(
// If line-clamping occurred save the intrinsic block-size, as this
// becomes the final intrinsic block-size.
intrinsic_block_size_when_clamped_ =
- previous_inflow_position->logical_block_offset +
- border_scrollbar_padding_.block_end;
+ previous_inflow_position->logical_block_offset;
}
}
return NGLayoutResult::kSuccess;
@@ -1986,7 +1945,7 @@ NGInflowChildData NGBlockLayoutAlgorithm::ComputeChildData(
NGBfcOffset child_bfc_offset = {
ConstraintSpace().BfcOffset().line_offset +
- border_scrollbar_padding_.LineLeft(ConstraintSpace().Direction()) +
+ BorderScrollbarPadding().LineLeft(ConstraintSpace().Direction()) +
margins.LineLeft(ConstraintSpace().Direction()),
BfcBlockOffset() + logical_block_offset};
@@ -2065,7 +2024,15 @@ NGPreviousInflowPosition NGBlockLayoutAlgorithm::ComputeInflowPosition(
if (!container_builder_.BfcBlockOffset())
DCHECK_EQ(logical_block_offset, LayoutUnit());
} else {
- logical_block_offset = logical_offset.block_offset + fragment.BlockSize();
+ // We add AnnotationOverflow unconditionally here. Then, we cancel it if
+ // - The next line box has block-start annotation space, or
+ // - There are no following child boxes and this container has block-end
+ // padding.
+ //
+ // See NGInlineLayoutAlgorithm::CreateLine() and
+ // BlockLayoutAlgorithm::Layout().
+ logical_block_offset = logical_offset.block_offset + fragment.BlockSize() +
+ layout_result.AnnotationOverflow();
}
NGMarginStrut margin_strut = layout_result.EndMarginStrut();
@@ -2095,7 +2062,13 @@ NGPreviousInflowPosition NGBlockLayoutAlgorithm::ComputeInflowPosition(
(previous_inflow_position.self_collapsing_child_had_clearance &&
is_self_collapsing);
- return {logical_block_offset, margin_strut,
+ LayoutUnit annotation_space = layout_result.BlockEndAnnotationSpace();
+ if (layout_result.AnnotationOverflow() > LayoutUnit()) {
+ DCHECK(!annotation_space);
+ annotation_space = -layout_result.AnnotationOverflow();
+ }
+
+ return {logical_block_offset, margin_strut, annotation_space,
self_or_sibling_self_collapsing_child_had_clearance};
}
@@ -2123,21 +2096,8 @@ LayoutUnit NGBlockLayoutAlgorithm::FragmentainerSpaceAvailable() const {
*container_builder_.BfcBlockOffset();
}
-bool NGBlockLayoutAlgorithm::IsFragmentainerOutOfSpace(
- LayoutUnit block_offset) const {
- if (did_break_before_child_)
- return true;
- if (!ConstraintSpace().HasKnownFragmentainerBlockSize())
- return false;
- if (!container_builder_.BfcBlockOffset().has_value())
- return false;
- return block_offset >= FragmentainerSpaceAvailable();
-}
-
-void NGBlockLayoutAlgorithm::SetFragmentainerOutOfSpace(
+void NGBlockLayoutAlgorithm::ConsumeRemainingFragmentainerSpace(
NGPreviousInflowPosition* previous_inflow_position) {
- did_break_before_child_ = true;
-
if (ConstraintSpace().HasKnownFragmentainerBlockSize()) {
// The remaining part of the fragmentainer (the unusable space for child
// content, due to the break) should still be occupied by this container.
@@ -2148,7 +2108,8 @@ void NGBlockLayoutAlgorithm::SetFragmentainerOutOfSpace(
bool NGBlockLayoutAlgorithm::FinalizeForFragmentation() {
if (Node().IsInlineFormattingContextRoot() && !early_break_) {
- if (container_builder_.DidBreak() || first_overflowing_line_) {
+ if (container_builder_.HasInflowChildBreakInside() ||
+ first_overflowing_line_) {
if (first_overflowing_line_ &&
first_overflowing_line_ < container_builder_.LineCount()) {
int line_number;
@@ -2176,31 +2137,22 @@ bool NGBlockLayoutAlgorithm::FinalizeForFragmentation() {
}
}
- if (!ConstraintSpace().HasKnownFragmentainerBlockSize())
+ if (container_builder_.IsFragmentainerBoxType()) {
+ // We're building fragmentainers. Just copy the block-size from the
+ // constraint space. Calculating the size the regular way would cause some
+ // problems with overflow. For one, we don't want to produce a break token
+ // if there's no child content that requires it.
+ LayoutUnit consumed_block_size =
+ BreakToken() ? BreakToken()->ConsumedBlockSize() : LayoutUnit();
+ LayoutUnit block_size = ConstraintSpace().FragmentainerBlockSize();
+ container_builder_.SetFragmentBlockSize(block_size);
+ container_builder_.SetConsumedBlockSize(consumed_block_size + block_size);
return true;
+ }
- LayoutUnit consumed_block_size =
- BreakToken() ? BreakToken()->ConsumedBlockSize() : LayoutUnit();
- LayoutUnit space_left = FragmentainerSpaceAvailable();
- LayoutUnit block_size;
- if (container_builder_.BoxType() == NGPhysicalFragment::kColumnBox &&
- ConstraintSpace().HasKnownFragmentainerBlockSize()) {
- // We're building column fragments, and we know the column size. Just use
- // that. Calculating the size the regular way would cause some problems with
- // overflow. For one, we don't want to produce a break token if there's no
- // child content that requires it.
- block_size = ConstraintSpace().FragmentainerBlockSize();
- } else {
- block_size = ComputeBlockSizeForFragment(
- ConstraintSpace(), Style(), border_padding_,
- consumed_block_size + intrinsic_block_size_,
- container_builder_.InitialBorderBoxSize().inline_size);
-
- block_size -= consumed_block_size;
- DCHECK_GE(block_size, LayoutUnit())
- << "Adding and subtracting the consumed_block_size shouldn't leave the "
- "block_size for this fragment smaller than zero.";
-
+ LayoutUnit space_left = kIndefiniteSize;
+ if (ConstraintSpace().HasKnownFragmentainerBlockSize()) {
+ space_left = FragmentainerSpaceAvailable();
if (space_left <= LayoutUnit()) {
// The amount of space available may be zero, or even negative, if the
// border-start edge of this block starts exactly at, or even after the
@@ -2216,8 +2168,8 @@ bool NGBlockLayoutAlgorithm::FinalizeForFragmentation() {
}
}
- FinishFragmentation(ConstraintSpace(), BreakToken(), block_size,
- intrinsic_block_size_, space_left, &container_builder_);
+ FinishFragmentation(Node(), ConstraintSpace(), BreakToken(), BorderPadding(),
+ space_left, &container_builder_);
return true;
}
@@ -2250,7 +2202,7 @@ NGBreakStatus NGBlockLayoutAlgorithm::BreakBeforeChildIfNeeded(
BreakBeforeChild(ConstraintSpace(), child, layout_result,
fragmentainer_block_offset, kBreakAppealPerfect,
/* is_forced_break */ true, &container_builder_);
- SetFragmentainerOutOfSpace(previous_inflow_position);
+ ConsumeRemainingFragmentainerSpace(previous_inflow_position);
return NGBreakStatus::kBrokeBefore;
}
}
@@ -2340,7 +2292,7 @@ NGBreakStatus NGBlockLayoutAlgorithm::BreakBeforeChildIfNeeded(
&container_builder_))
return NGBreakStatus::kNeedsEarlierBreak;
- SetFragmentainerOutOfSpace(previous_inflow_position);
+ ConsumeRemainingFragmentainerSpace(previous_inflow_position);
return NGBreakStatus::kBrokeBefore;
}
@@ -2348,8 +2300,9 @@ void NGBlockLayoutAlgorithm::UpdateEarlyBreakBetweenLines() {
// We shouldn't be here if we already know where to break.
DCHECK(!early_break_);
- // If the child already broke, it's a little too late to look for breakpoints.
- DCHECK(!container_builder_.DidBreak());
+ // If something in this flow already broke, it's a little too late to look for
+ // breakpoints.
+ DCHECK(!container_builder_.HasInflowChildBreakInside());
int line_count = container_builder_.LineCount();
if (line_count < 2)
@@ -2412,7 +2365,7 @@ NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins(
NGConstraintSpaceBuilder builder(ConstraintSpace(),
child_style.GetWritingMode(),
/* is_new_fc */ false);
- builder.SetAvailableSize(child_available_size_);
+ builder.SetAvailableSize(ChildAvailableSize());
builder.SetPercentageResolutionSize(child_percentage_size_);
NGConstraintSpace space = builder.ToConstraintSpace();
@@ -2435,7 +2388,8 @@ NGConstraintSpace NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
const LogicalSize child_available_size,
bool is_new_fc,
const base::Optional<LayoutUnit> child_bfc_block_offset,
- bool has_clearance_past_adjoining_floats) {
+ bool has_clearance_past_adjoining_floats,
+ LayoutUnit block_start_annotation_space) {
const ComputedStyle& style = Style();
const ComputedStyle& child_style = child.Style();
WritingMode child_writing_mode =
@@ -2550,6 +2504,7 @@ NGConstraintSpace NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
// child establishes a new formatting context or not.
builder.SetDiscardingMarginStrut();
}
+ builder.SetBlockStartAnnotationSpace(block_start_annotation_space);
if (ConstraintSpace().HasBlockFragmentation()) {
LayoutUnit fragmentainer_offset_delta;
@@ -2746,7 +2701,7 @@ bool NGBlockLayoutAlgorithm::PositionOrPropagateListMarker(
}
list_marker.AddToBox(space, baseline_type, content,
- border_scrollbar_padding_, *marker_layout_result,
+ BorderScrollbarPadding(), *marker_layout_result,
*content_baseline, content_offset,
&container_builder_);
return true;
@@ -2797,7 +2752,7 @@ bool NGBlockLayoutAlgorithm::PositionListMarkerWithoutLineBoxes(
if (container_builder_.BfcBlockOffset()) {
intrinsic_block_size_ = std::max(marker_block_size, intrinsic_block_size_);
container_builder_.SetIntrinsicBlockSize(intrinsic_block_size_);
- container_builder_.SetBlockSize(
+ container_builder_.SetFragmentsTotalBlockSize(
std::max(marker_block_size, container_builder_.Size().block_size));
}
return true;
@@ -2824,17 +2779,19 @@ void NGBlockLayoutAlgorithm::LayoutRubyText(
NGConstraintSpaceBuilder builder(
ConstraintSpace(), ruby_text_child->Style().GetWritingMode(), true);
- builder.SetAvailableSize(child_available_size_);
+ builder.SetAvailableSize(ChildAvailableSize());
scoped_refptr<const NGLayoutResult> result =
To<NGBlockNode>(*ruby_text_child)
.Layout(builder.ToConstraintSpace(), break_token.get());
- LayoutUnit ruby_text_top;
+ LayoutUnit ruby_text_box_top;
const NGPhysicalBoxFragment& ruby_text_fragment =
To<NGPhysicalBoxFragment>(result->PhysicalFragment());
- if (Style().IsFlippedLinesWritingMode() ==
- (Style().GetRubyPosition() == RubyPosition::kAfter)) {
+ RubyPosition block_start_position = Style().IsFlippedLinesWritingMode()
+ ? RubyPosition::kAfter
+ : RubyPosition::kBefore;
+ if (Style().GetRubyPosition() == block_start_position) {
LayoutUnit last_line_ruby_text_bottom = LastLineTextLogicalBottom(
ruby_text_fragment, result->IntrinsicBlockSize());
@@ -2850,30 +2807,53 @@ void NGBlockLayoutAlgorithm::LayoutRubyText(
}
}
}
- ruby_text_top = first_line_top - last_line_ruby_text_bottom;
+ ruby_text_box_top = first_line_top - last_line_ruby_text_bottom;
+ const LayoutUnit ruby_text_top =
+ ruby_text_box_top +
+ FirstLineTextLogicalTop(ruby_text_fragment, LayoutUnit());
+ if (ruby_text_top < LayoutUnit())
+ container_builder_.SetAnnotationOverflow(ruby_text_top);
} else {
LayoutUnit first_line_ruby_text_top =
FirstLineTextLogicalTop(ruby_text_fragment, LayoutUnit());
// Find a fragment for RubyBase, and get the bottom of text in it.
LayoutUnit last_line_bottom;
+ LayoutUnit base_logical_bottom;
for (const auto& child : container_builder_.Children()) {
if (const auto* layout_object = child.fragment->GetLayoutObject()) {
if (layout_object->IsRubyBase()) {
- last_line_bottom = LastLineTextLogicalBottom(
- To<NGPhysicalBoxFragment>(*child.fragment),
+ LayoutUnit base_block_size =
child.fragment->Size()
.ConvertToLogical(Style().GetWritingMode())
- .block_size);
+ .block_size;
+ last_line_bottom = LastLineTextLogicalBottom(
+ To<NGPhysicalBoxFragment>(*child.fragment), base_block_size);
last_line_bottom += child.offset.block_offset;
+ base_logical_bottom = child.offset.block_offset + base_block_size;
break;
}
}
}
- ruby_text_top = last_line_bottom - first_line_ruby_text_top;
+ ruby_text_box_top = last_line_bottom - first_line_ruby_text_top;
+ LayoutUnit ruby_text_height =
+ ruby_text_fragment.Size()
+ .ConvertToLogical(Style().GetWritingMode())
+ .block_size;
+ ruby_text_height =
+ LastLineTextLogicalBottom(ruby_text_fragment, ruby_text_height);
+ LayoutUnit logical_bottom_overflow =
+ ruby_text_box_top + ruby_text_height - base_logical_bottom;
+ if (logical_bottom_overflow > LayoutUnit())
+ container_builder_.SetAnnotationOverflow(logical_bottom_overflow);
}
container_builder_.AddResult(*result,
- LogicalOffset(LayoutUnit(), ruby_text_top));
+ LogicalOffset(LayoutUnit(), ruby_text_box_top));
+ // RubyText provides baseline if RubyBase didn't.
+ // This behavior doesn't make much sense, but it's compatible with the legacy
+ // layout.
+ if (!container_builder_.Baseline())
+ PropagateBaselineFromChild(ruby_text_fragment, ruby_text_box_top);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h
index b7599118a1a..55a5c8352cc 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h
@@ -32,6 +32,9 @@ class NGFragment;
struct NGPreviousInflowPosition {
LayoutUnit logical_block_offset;
NGMarginStrut margin_strut;
+ // > 0: Block-end annotation space of the previous line
+ // < 0: Block-end annotation overflow of the previous line
+ LayoutUnit block_end_annotation_space;
bool self_collapsing_child_had_clearance;
};
@@ -113,7 +116,8 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
const LogicalSize child_available_size,
bool is_new_fc,
const base::Optional<LayoutUnit> bfc_block_offset = base::nullopt,
- bool has_clearance_past_adjoining_floats = false);
+ bool has_clearance_past_adjoining_floats = false,
+ LayoutUnit block_start_annotation_space = LayoutUnit());
// @return Estimated BFC block offset for the "to be layout" child.
NGInflowChildData ComputeChildData(const NGPreviousInflowPosition&,
@@ -215,14 +219,11 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
// for the node being laid out by this algorithm.
LayoutUnit FragmentainerSpaceAvailable() const;
- // Return true if the node being laid out by this fragmentainer has used all
- // the available space in the current fragmentainer.
- // |block_offset| is the border-edge relative block offset we want to check
- // whether fits within the fragmentainer or not.
- bool IsFragmentainerOutOfSpace(LayoutUnit block_offset) const;
-
- // Signal that we've reached the end of the fragmentainer.
- void SetFragmentainerOutOfSpace(NGPreviousInflowPosition*);
+ // Consume all remaining fragmentainer space. This happens when we decide to
+ // break before a child.
+ //
+ // https://www.w3.org/TR/css-break-3/#box-splitting
+ void ConsumeRemainingFragmentainerSpace(NGPreviousInflowPosition*);
// Final adjustments before fragment creation. We need to prevent the fragment
// from crossing fragmentainer boundaries, and rather create a break token if
@@ -342,15 +343,6 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
// |ruby_text_child|. This is called only if IsRubyText() returns true.
void LayoutRubyText(NGLayoutInputNode* ruby_text_child);
- // Border + padding sum, resolved from the node's computed style.
- const NGBoxStrut border_padding_;
-
- // Border + scrollbar + padding sum for the fragment to be generated (most
- // importantly, for non-first fragments, leading block border + scrollbar +
- // padding is zero).
- NGBoxStrut border_scrollbar_padding_;
-
- LogicalSize child_available_size_;
LogicalSize child_percentage_size_;
LogicalSize replaced_child_percentage_size_;
@@ -386,14 +378,6 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
// A or B breakpoint (between block-level siblings or line box siblings).
bool has_processed_first_child_ = false;
- // Set once we've inserted a break before a float. We need to know this, so
- // that we don't attempt to lay out any more floats in the current
- // fragmentainer. Floats aren't allowed have an earlier block-start offset
- // than earlier floats.
- bool broke_before_float_ = false;
-
- bool did_break_before_child_ = false;
-
NGExclusionSpace exclusion_space_;
// If set, this is the number of lines until a clamp. A value of 1 indicates
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc
index 6b75c41df3b..1af502775f3 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -45,7 +45,8 @@ class NGBlockLayoutAlgorithmTest : public NGBaseLayoutAlgorithmTest {
NGBlockLayoutAlgorithm algorithm({node, fragment_geometry, space});
MinMaxSizesInput input(
- /* percentage_resolution_block_size */ (LayoutUnit()));
+ /* percentage_resolution_block_size */ LayoutUnit(),
+ MinMaxSizesType::kContent);
return algorithm.ComputeMinMaxSizes(input).sizes;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
index 80d066499e2..2d1a57926ad 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -196,6 +196,10 @@ void UpdateLegacyMultiColumnFlowThread(
LayoutMultiColumnSet* column_set =
ToLayoutMultiColumnSetOrNull(flow_thread->FirstMultiColumnBox());
for (const auto& child : fragment.Children()) {
+ // TODO(almaher): Remove check for out of flow.
+ if (child->IsOutOfFlowPositioned())
+ continue;
+
if (child->GetLayoutObject() &&
child->GetLayoutObject()->IsColumnSpanAll()) {
// Column spanners are not part of the fragmentation context. We'll use
@@ -258,11 +262,16 @@ void UpdateLegacyMultiColumnFlowThread(
flow_thread->ClearNeedsLayout();
}
-NGConstraintSpace CreateConstraintSpaceForMinMax(const NGBlockNode& node) {
+NGConstraintSpace CreateConstraintSpaceForMinMax(
+ const NGBlockNode& node,
+ const MinMaxSizesInput& input) {
NGConstraintSpaceBuilder builder(node.Style().GetWritingMode(),
node.Style().GetWritingMode(),
node.CreatesNewFormattingContext());
builder.SetTextDirection(node.Style().Direction());
+ builder.SetAvailableSize(LogicalSize());
+ builder.SetPercentageResolutionSize(
+ {LayoutUnit(), input.percentage_resolution_block_size});
return builder.ToConstraintSpace();
}
@@ -351,7 +360,7 @@ bool CanUseCachedIntrinsicInlineSizes(const MinMaxSizesInput& input,
scoped_refptr<const NGLayoutResult> NGBlockNode::Layout(
const NGConstraintSpace& constraint_space,
const NGBlockBreakToken* break_token,
- const NGEarlyBreak* early_break) {
+ const NGEarlyBreak* early_break) const {
// Use the old layout code and synthesize a fragment.
if (!CanUseNewLayout())
return RunLegacyLayout(constraint_space);
@@ -508,7 +517,7 @@ scoped_refptr<const NGLayoutResult> NGBlockNode::Layout(
}
scoped_refptr<const NGLayoutResult> NGBlockNode::SimplifiedLayout(
- const NGPhysicalFragment& previous_fragment) {
+ const NGPhysicalFragment& previous_fragment) const {
scoped_refptr<const NGLayoutResult> previous_result =
box_->GetCachedLayoutResult();
DCHECK(previous_result);
@@ -587,7 +596,7 @@ NGBlockNode::CachedLayoutResultForOutOfFlowPositioned(
return cached_layout_result;
}
-void NGBlockNode::PrepareForLayout() {
+void NGBlockNode::PrepareForLayout() const {
auto* block = DynamicTo<LayoutBlock>(box_);
if (block && block->HasOverflowClip()) {
DCHECK(block->GetScrollableArea());
@@ -605,7 +614,7 @@ void NGBlockNode::FinishLayout(
LayoutBlockFlow* block_flow,
const NGConstraintSpace& constraint_space,
const NGBlockBreakToken* break_token,
- scoped_refptr<const NGLayoutResult> layout_result) {
+ scoped_refptr<const NGLayoutResult> layout_result) const {
// If we abort layout and don't clear the cached layout-result, we can end
// up in a state where the layout-object tree doesn't match fragment tree
// referenced by this layout-result.
@@ -676,7 +685,7 @@ void NGBlockNode::FinishLayout(
MinMaxSizesResult NGBlockNode::ComputeMinMaxSizes(
WritingMode container_writing_mode,
const MinMaxSizesInput& input,
- const NGConstraintSpace* constraint_space) {
+ const NGConstraintSpace* constraint_space) const {
// TODO(layoutng) Can UpdateMarkerTextIfNeeded call be moved
// somewhere else? List items need up-to-date markers before layout.
if (IsListItem())
@@ -687,6 +696,10 @@ MinMaxSizesResult NGBlockNode::ComputeMinMaxSizes(
// If we're orthogonal, run layout to compute the sizes.
if (is_orthogonal_flow_root) {
+ // If we have an aspect ratio, we may be able to avoid laying out the
+ // child as an optimization, if performance testing shows this to be
+ // important.
+
MinMaxSizes sizes;
// Some other areas of the code can query the intrinsic-sizes while outside
// of the layout phase.
@@ -706,6 +719,24 @@ MinMaxSizesResult NGBlockNode::ComputeMinMaxSizes(
return {sizes, /* depends_on_percentage_block_size */ false};
}
+ // Synthesize a zero space if not provided.
+ auto zero_constraint_space = CreateConstraintSpaceForMinMax(*this, input);
+ if (!constraint_space)
+ constraint_space = &zero_constraint_space;
+
+ if (Style().AspectRatio() && input.type == MinMaxSizesType::kContent) {
+ NGFragmentGeometry fragment_geometry =
+ CalculateInitialMinMaxFragmentGeometry(*constraint_space, *this);
+ NGBoxStrut border_padding =
+ fragment_geometry.border + fragment_geometry.padding;
+ LayoutUnit size_from_ar = ComputeInlineSizeFromAspectRatio(
+ *constraint_space, Style(), border_padding);
+ if (size_from_ar != kIndefiniteSize) {
+ return {{size_from_ar, size_from_ar},
+ Style().LogicalHeight().IsPercentOrCalc()};
+ }
+ }
+
bool can_use_cached_intrinsic_inline_sizes =
CanUseCachedIntrinsicInlineSizes(input, *this);
@@ -723,11 +754,6 @@ MinMaxSizesResult NGBlockNode::ComputeMinMaxSizes(
return {sizes, depends_on_percentage_block_size};
}
- // Synthesize a zero space if not provided.
- auto zero_constraint_space = CreateConstraintSpaceForMinMax(*this);
- if (!constraint_space)
- constraint_space = &zero_constraint_space;
-
NGFragmentGeometry fragment_geometry =
CalculateInitialMinMaxFragmentGeometry(*constraint_space, *this);
@@ -918,23 +944,42 @@ String NGBlockNode::ToString() const {
void NGBlockNode::CopyFragmentDataToLayoutBox(
const NGConstraintSpace& constraint_space,
const NGLayoutResult& layout_result,
- const NGBlockBreakToken* previous_break_token) {
+ const NGBlockBreakToken* previous_break_token) const {
const auto& physical_fragment =
To<NGPhysicalBoxFragment>(layout_result.PhysicalFragment());
NGBoxFragment fragment(constraint_space.GetWritingMode(),
constraint_space.Direction(), physical_fragment);
LogicalSize fragment_logical_size = fragment.Size();
- // For each fragment we process, we'll accumulate the logical height and
- // logical intrinsic content box height. We reset it at the first fragment,
- // and accumulate at each method call for fragments belonging to the same
- // layout object. Logical width will only be set at the first fragment and is
- // expected to remain the same throughout all subsequent fragments, since
- // legacy layout doesn't support non-uniform fragmentainer widths.
- LayoutUnit intrinsic_content_logical_height;
+ NGBoxStrut borders = fragment.Borders();
+ NGBoxStrut scrollbars = ComputeScrollbars(constraint_space, *this);
+ NGBoxStrut padding = fragment.Padding();
+ NGBoxStrut border_scrollbar_padding = borders + scrollbars + padding;
+ bool is_last_fragment = !physical_fragment.BreakToken();
+
+ // For each fragment we process, we'll accumulate the logical height. We reset
+ // it at the first fragment, and accumulate at each method call for fragments
+ // belonging to the same layout object. Logical width will only be set at the
+ // first fragment and is expected to remain the same throughout all subsequent
+ // fragments, since legacy layout doesn't support non-uniform fragmentainer
+ // widths.
if (LIKELY(physical_fragment.IsFirstForNode())) {
box_->SetSize(LayoutSize(physical_fragment.Size().width,
physical_fragment.Size().height));
+ // If this is a fragment from a node that didn't break into multiple
+ // fragments, write back the intrinsic size. We skip this if the node has
+ // fragmented, since intrinsic block-size is rather meaningless in that
+ // case, because the block-size may have been affected by something on the
+ // outside (i.e. the fragmentainer).
+ //
+ // If we had a fixed block size, our children will have sized themselves
+ // relative to the fixed size, which would make our intrinsic size incorrect
+ // (too big). So skip the write-back in that case, too.
+ if (LIKELY(is_last_fragment && !constraint_space.IsFixedBlockSize())) {
+ box_->SetIntrinsicContentLogicalHeight(
+ layout_result.IntrinsicBlockSize() -
+ border_scrollbar_padding.BlockSum());
+ }
} else {
DCHECK_EQ(box_->LogicalWidth(), fragment_logical_size.inline_size)
<< "Variable fragment inline size not supported";
@@ -942,24 +987,6 @@ void NGBlockNode::CopyFragmentDataToLayoutBox(
if (previous_break_token)
logical_height += previous_break_token->ConsumedBlockSize();
box_->SetLogicalHeight(logical_height);
- intrinsic_content_logical_height = box_->IntrinsicContentLogicalHeight();
- }
-
- intrinsic_content_logical_height += layout_result.IntrinsicBlockSize();
-
- NGBoxStrut borders = fragment.Borders();
- NGBoxStrut scrollbars = ComputeScrollbars(constraint_space, *this);
- NGBoxStrut padding = fragment.Padding();
- NGBoxStrut border_scrollbar_padding = borders + scrollbars + padding;
- bool is_last_fragment = !physical_fragment.BreakToken();
-
- if (LIKELY(is_last_fragment))
- intrinsic_content_logical_height -= border_scrollbar_padding.BlockSum();
- if (!constraint_space.IsFixedBlockSize()) {
- // If we had a fixed block size, our children will have sized themselves
- // relative to the fixed size, which would make our intrinsic size
- // incorrect (too big).
- box_->SetIntrinsicContentLogicalHeight(intrinsic_content_logical_height);
}
// TODO(mstensho): This should always be done by the parent algorithm, since
@@ -1041,7 +1068,7 @@ void NGBlockNode::CopyFragmentDataToLayoutBox(
void NGBlockNode::PlaceChildrenInLayoutBox(
const NGPhysicalBoxFragment& physical_fragment,
- const NGBlockBreakToken* previous_break_token) {
+ const NGBlockBreakToken* previous_break_token) const {
LayoutBox* rendered_legend = nullptr;
for (const auto& child_fragment : physical_fragment.Children()) {
// Skip any line-boxes we have as children, this is handled within
@@ -1078,12 +1105,14 @@ void NGBlockNode::PlaceChildrenInLayoutBox(
}
void NGBlockNode::PlaceChildrenInFlowThread(
- const NGPhysicalBoxFragment& physical_fragment) {
+ const NGPhysicalBoxFragment& physical_fragment) const {
const NGBlockBreakToken* previous_break_token = nullptr;
for (const auto& child : physical_fragment.Children()) {
const LayoutObject* child_object = child->GetLayoutObject();
if (child_object && child_object != box_) {
- DCHECK(child_object->IsColumnSpanAll());
+ // TODO(almaher): Remove check for out of flow.
+ DCHECK(child_object->IsColumnSpanAll() ||
+ child_object->IsOutOfFlowPositioned());
CopyChildFragmentPosition(To<NGPhysicalBoxFragment>(*child), child.offset,
physical_fragment);
continue;
@@ -1102,7 +1131,7 @@ void NGBlockNode::CopyChildFragmentPosition(
const NGPhysicalBoxFragment& child_fragment,
PhysicalOffset offset,
const NGPhysicalBoxFragment& container_fragment,
- const NGBlockBreakToken* previous_container_break_token) {
+ const NGBlockBreakToken* previous_container_break_token) const {
LayoutBox* layout_box = ToLayoutBox(child_fragment.GetMutableLayoutObject());
if (!layout_box)
return;
@@ -1140,7 +1169,7 @@ void NGBlockNode::CopyFragmentDataToLayoutBoxForInlineChildren(
const NGPhysicalContainerFragment& container,
LayoutUnit initial_container_width,
bool initial_container_is_flipped,
- PhysicalOffset offset) {
+ PhysicalOffset offset) const {
DCHECK(!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
for (const auto& child : container.Children()) {
if (child->IsContainer()) {
@@ -1185,7 +1214,7 @@ void NGBlockNode::CopyFragmentDataToLayoutBoxForInlineChildren(
void NGBlockNode::CopyFragmentItemsToLayoutBox(
const NGPhysicalBoxFragment& container,
- const NGFragmentItems& items) {
+ const NGFragmentItems& items) const {
DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
bool initial_container_is_flipped = Style().IsFlippedBlocksWritingMode();
@@ -1321,7 +1350,7 @@ scoped_refptr<const NGLayoutResult> NGBlockNode::LayoutAtomicInline(
}
scoped_refptr<const NGLayoutResult> NGBlockNode::RunLegacyLayout(
- const NGConstraintSpace& constraint_space) {
+ const NGConstraintSpace& constraint_space) const {
// This is an exit-point from LayoutNG to the legacy engine. This means that
// we need to be at a formatting context boundary, since NG and legacy don't
// cooperate on e.g. margin collapsing.
@@ -1371,7 +1400,7 @@ scoped_refptr<const NGLayoutResult> NGBlockNode::RunLegacyLayout(
// TODO(kojii): Implement use_first_line_style.
NGBoxFragmentBuilder builder(*this, box_->Style(), &constraint_space,
- writing_mode, box_->StyleRef().Direction());
+ {writing_mode, box_->StyleRef().Direction()});
builder.SetIsNewFormattingContext(
constraint_space.IsNewFormattingContext());
builder.SetInitialFragmentGeometry(fragment_geometry);
@@ -1452,7 +1481,7 @@ scoped_refptr<const NGLayoutResult> NGBlockNode::RunSimplifiedLayout(
void NGBlockNode::CopyBaselinesFromLegacyLayout(
const NGConstraintSpace& constraint_space,
- NGBoxFragmentBuilder* builder) {
+ NGBoxFragmentBuilder* builder) const {
// As the calls to query baselines from legacy layout are potentially
// expensive we only ask for them if needed.
// TODO(layout-dev): Once we have flexbox, and editing switched over to
@@ -1479,7 +1508,7 @@ void NGBlockNode::CopyBaselinesFromLegacyLayout(
}
LayoutUnit NGBlockNode::AtomicInlineBaselineFromLegacyLayout(
- const NGConstraintSpace& constraint_space) {
+ const NGConstraintSpace& constraint_space) const {
LineDirectionMode line_direction = box_->IsHorizontalWritingMode()
? LineDirectionMode::kHorizontalLine
: LineDirectionMode::kVerticalLine;
@@ -1512,7 +1541,7 @@ LayoutUnit NGBlockNode::AtomicInlineBaselineFromLegacyLayout(
// in the parents writing mode.
void NGBlockNode::UpdateShapeOutsideInfoIfNeeded(
const NGLayoutResult& layout_result,
- LayoutUnit percentage_resolution_inline_size) {
+ LayoutUnit percentage_resolution_inline_size) const {
if (!box_->IsFloating() || !box_->GetShapeOutsideInfo())
return;
@@ -1550,7 +1579,7 @@ void NGBlockNode::StoreMargins(const NGPhysicalBoxStrut& physical_margins) {
void NGBlockNode::AddColumnResult(
scoped_refptr<const NGLayoutResult> result,
- const NGBlockBreakToken* incoming_break_token) {
+ const NGBlockBreakToken* incoming_break_token) const {
wtf_size_t index = FragmentIndex(incoming_break_token);
GetFlowThread(To<LayoutBlockFlow>(box_))->AddLayoutResult(result, index);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_node.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_node.h
index 9befdc8f5e0..87891e8467f 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_node.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_node.h
@@ -37,7 +37,7 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
scoped_refptr<const NGLayoutResult> Layout(
const NGConstraintSpace& constraint_space,
const NGBlockBreakToken* break_token = nullptr,
- const NGEarlyBreak* = nullptr);
+ const NGEarlyBreak* = nullptr) const;
// This method is just for use within the |NGSimplifiedLayoutAlgorithm|.
//
@@ -45,7 +45,7 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
// space used to generate the |NGLayoutResult|.
// Otherwise it will simply return the previous layout result generated.
scoped_refptr<const NGLayoutResult> SimplifiedLayout(
- const NGPhysicalFragment& previous_fragment);
+ const NGPhysicalFragment& previous_fragment) const;
// This method is just for use within the |NGOutOfFlowLayoutPart|.
//
@@ -82,9 +82,10 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
// The constraint space is also used to perform layout when this block's
// writing mode is orthogonal to its parent's, in which case the constraint
// space is not optional.
- MinMaxSizesResult ComputeMinMaxSizes(WritingMode container_writing_mode,
- const MinMaxSizesInput&,
- const NGConstraintSpace* = nullptr);
+ MinMaxSizesResult ComputeMinMaxSizes(
+ WritingMode container_writing_mode,
+ const MinMaxSizesInput&,
+ const NGConstraintSpace* = nullptr) const;
MinMaxSizes ComputeMinMaxSizesFromLegacy(const MinMaxSizesInput&) const;
@@ -152,7 +153,7 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
// LayoutObject-less, but we still need to keep the fragments generated
// somewhere.
void AddColumnResult(scoped_refptr<const NGLayoutResult>,
- const NGBlockBreakToken* incoming_break_token);
+ const NGBlockBreakToken* incoming_break_token) const;
static bool CanUseNewLayout(const LayoutBox&);
bool CanUseNewLayout() const;
@@ -160,11 +161,12 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
String ToString() const;
private:
- void PrepareForLayout();
+ void PrepareForLayout() const;
// Runs layout on the underlying LayoutObject and creates a fragment for the
// resulting geometry.
- scoped_refptr<const NGLayoutResult> RunLegacyLayout(const NGConstraintSpace&);
+ scoped_refptr<const NGLayoutResult> RunLegacyLayout(
+ const NGConstraintSpace&) const;
scoped_refptr<const NGLayoutResult> RunSimplifiedLayout(
const NGLayoutAlgorithmParams&,
@@ -175,37 +177,39 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
void FinishLayout(LayoutBlockFlow*,
const NGConstraintSpace&,
const NGBlockBreakToken*,
- scoped_refptr<const NGLayoutResult>);
+ scoped_refptr<const NGLayoutResult>) const;
// After we run the layout algorithm, this function copies back the geometry
// data to the layout box.
void CopyFragmentDataToLayoutBox(
const NGConstraintSpace&,
const NGLayoutResult&,
- const NGBlockBreakToken* previous_break_token);
+ const NGBlockBreakToken* previous_break_token) const;
void CopyFragmentItemsToLayoutBox(const NGPhysicalBoxFragment& container,
- const NGFragmentItems& items);
+ const NGFragmentItems& items) const;
void CopyFragmentDataToLayoutBoxForInlineChildren(
const NGPhysicalContainerFragment& container,
LayoutUnit initial_container_width,
bool initial_container_is_flipped,
- PhysicalOffset offset = {});
- void PlaceChildrenInLayoutBox(const NGPhysicalBoxFragment&,
- const NGBlockBreakToken* previous_break_token);
- void PlaceChildrenInFlowThread(const NGPhysicalBoxFragment&);
+ PhysicalOffset offset = {}) const;
+ void PlaceChildrenInLayoutBox(
+ const NGPhysicalBoxFragment&,
+ const NGBlockBreakToken* previous_break_token) const;
+ void PlaceChildrenInFlowThread(const NGPhysicalBoxFragment&) const;
void CopyChildFragmentPosition(
const NGPhysicalBoxFragment& child_fragment,
PhysicalOffset,
const NGPhysicalBoxFragment& container_fragment,
- const NGBlockBreakToken* previous_container_break_token = nullptr);
+ const NGBlockBreakToken* previous_container_break_token = nullptr) const;
void CopyBaselinesFromLegacyLayout(const NGConstraintSpace&,
- NGBoxFragmentBuilder*);
- LayoutUnit AtomicInlineBaselineFromLegacyLayout(const NGConstraintSpace&);
+ NGBoxFragmentBuilder*) const;
+ LayoutUnit AtomicInlineBaselineFromLegacyLayout(
+ const NGConstraintSpace&) const;
void UpdateShapeOutsideInfoIfNeeded(
const NGLayoutResult&,
- LayoutUnit percentage_resolution_inline_size);
+ LayoutUnit percentage_resolution_inline_size) const;
};
template <>
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_node_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_node_test.cc
index 3ad5edcf391..7cf812f28b1 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_node_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_node_test.cc
@@ -178,7 +178,8 @@ TEST_F(NGBlockNodeForTest, MinAndMaxContent) {
box.ComputeMinMaxSizes(
WritingMode::kHorizontalTb,
MinMaxSizesInput(
- /* percentage_resolution_block_size */ LayoutUnit()))
+ /* percentage_resolution_block_size */ LayoutUnit(),
+ MinMaxSizesType::kContent))
.sizes;
EXPECT_EQ(LayoutUnit(kWidth), sizes.min_size);
EXPECT_EQ(LayoutUnit(kWidth), sizes.max_size);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc
index 8a0c0a6ebf2..532fef71209 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc
@@ -159,7 +159,10 @@ void NGBoxFragmentBuilder::AddBreakBeforeChild(
}
DCHECK(has_block_fragmentation_);
- SetDidBreak();
+
+ if (!has_inflow_child_break_inside_)
+ has_inflow_child_break_inside_ = !child.IsFloatingOrOutOfFlowPositioned();
+
if (auto* child_inline_node = DynamicTo<NGInlineNode>(child)) {
if (inline_break_tokens_.IsEmpty()) {
// In some cases we may want to break before the first line, as a last
@@ -197,6 +200,7 @@ void NGBoxFragmentBuilder::AddBreakToken(
scoped_refptr<const NGBreakToken> token) {
DCHECK(token.get());
child_break_tokens_.push_back(std::move(token));
+ has_inflow_child_break_inside_ = true;
}
void NGBoxFragmentBuilder::AddOutOfFlowLegacyCandidate(
@@ -245,9 +249,20 @@ void NGBoxFragmentBuilder::PropagateBreak(
const NGLayoutResult& child_layout_result) {
if (LIKELY(!has_block_fragmentation_))
return;
- if (!did_break_) {
- const auto* token = child_layout_result.PhysicalFragment().BreakToken();
- did_break_ = token && !token->IsFinished();
+ if (!has_inflow_child_break_inside_) {
+ // Figure out if this child break is in the same flow as this parent. If
+ // it's an out-of-flow positioned box, it's not. If it's in a parallel flow,
+ // it's also not.
+ const auto& child_fragment =
+ To<NGPhysicalBoxFragment>(child_layout_result.PhysicalFragment());
+ if (!child_fragment.IsFloatingOrOutOfFlowPositioned()) {
+ if (const auto* token = child_fragment.BreakToken()) {
+ if (!token->IsFinished() &&
+ (!token->IsBlockType() ||
+ !To<NGBlockBreakToken>(token)->IsAtBlockEnd()))
+ has_inflow_child_break_inside_ = true;
+ }
+ }
}
if (child_layout_result.HasForcedBreak()) {
SetHasForcedBreak();
@@ -280,10 +295,10 @@ scoped_refptr<const NGLayoutResult> NGBoxFragmentBuilder::ToBoxFragment(
child_break_tokens_.push_back(std::move(token));
}
}
- if (did_break_) {
+ if (DidBreakSelf() || HasChildBreakInside()) {
break_token_ = NGBlockBreakToken::Create(
node_, consumed_block_size_, sequence_number_, child_break_tokens_,
- break_appeal_, has_seen_all_children_);
+ break_appeal_, has_seen_all_children_, is_at_block_end_);
}
}
@@ -351,7 +366,7 @@ void NGBoxFragmentBuilder::ComputeInlineContainerGeometryFromFragmentTree(
// This function has detailed knowledge of inline fragment tree structure,
// and will break if this changes.
DCHECK_GE(InlineSize(), LayoutUnit());
- DCHECK_GE(BlockSize(), LayoutUnit());
+ DCHECK_GE(FragmentBlockSize(), LayoutUnit());
#if DCHECK_IS_ON()
// Make sure all entries are continuation root.
for (const auto& entry : *inline_containing_block_map)
@@ -407,7 +422,7 @@ void NGBoxFragmentBuilder::ComputeInlineContainerGeometry(
// This function requires that we have the final size of the fragment set
// upon the builder.
DCHECK_GE(InlineSize(), LayoutUnit());
- DCHECK_GE(BlockSize(), LayoutUnit());
+ DCHECK_GE(FragmentBlockSize(), LayoutUnit());
#if DCHECK_IS_ON()
// Make sure all entries are a continuation root.
@@ -420,9 +435,10 @@ void NGBoxFragmentBuilder::ComputeInlineContainerGeometry(
if (items_builder_) {
// To access the items correctly we need to convert them to the physical
// coordinate space.
+ DCHECK_EQ(items_builder_->GetWritingMode(), GetWritingMode());
+ DCHECK_EQ(items_builder_->Direction(), Direction());
GatherInlineContainerFragmentsFromItems(
- items_builder_->Items(GetWritingMode(), Direction(),
- ToPhysicalSize(Size(), GetWritingMode())),
+ items_builder_->Items(ToPhysicalSize(Size(), GetWritingMode())),
PhysicalOffset(), inline_containing_block_map, &containing_linebox_map);
return;
}
@@ -463,13 +479,15 @@ void NGBoxFragmentBuilder::SetLastBaselineToBlockEndMarginEdgeIfNeeded() {
// When overflow is present (within an atomic-inline baseline context) we
// should always use the block-end margin edge as the baseline.
NGBoxStrut margins = ComputeMarginsForSelf(*ConstraintSpace(), Style());
- SetLastBaseline(BlockSize() + margins.block_end);
+ SetLastBaseline(FragmentBlockSize() + margins.block_end);
}
#if DCHECK_IS_ON()
void NGBoxFragmentBuilder::CheckNoBlockFragmentation() const {
- DCHECK(!did_break_);
+ DCHECK(!HasChildBreakInside());
+ DCHECK(!HasInflowChildBreakInside());
+ DCHECK(!DidBreakSelf());
DCHECK(!has_forced_break_);
DCHECK_EQ(consumed_block_size_, LayoutUnit());
DCHECK_EQ(minimal_space_shortage_, LayoutUnit::Max());
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h
index 67cb8f120c3..26b0856df32 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h
@@ -10,9 +10,12 @@
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_fragment_geometry.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/mathml/ng_mathml_paint_info.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
@@ -29,31 +32,25 @@ class CORE_EXPORT NGBoxFragmentBuilder final
NGBoxFragmentBuilder(NGLayoutInputNode node,
scoped_refptr<const ComputedStyle> style,
const NGConstraintSpace* space,
- WritingMode writing_mode,
- TextDirection direction)
+ WritingDirectionMode writing_direction)
: NGContainerFragmentBuilder(node,
std::move(style),
space,
- writing_mode,
- direction),
+ writing_direction),
box_type_(NGPhysicalFragment::NGBoxType::kNormalBox),
- is_inline_formatting_context_(node.IsInline()),
- did_break_(false) {}
+ is_inline_formatting_context_(node.IsInline()) {}
// Build a fragment for LayoutObject without NGLayoutInputNode. LayoutInline
// has NGInlineItem but does not have corresponding NGLayoutInputNode.
NGBoxFragmentBuilder(LayoutObject* layout_object,
scoped_refptr<const ComputedStyle> style,
- WritingMode writing_mode,
- TextDirection direction)
+ WritingDirectionMode writing_direction)
: NGContainerFragmentBuilder(/* node */ nullptr,
std::move(style),
/* space */ nullptr,
- writing_mode,
- direction),
+ writing_direction),
box_type_(NGPhysicalFragment::NGBoxType::kNormalBox),
- is_inline_formatting_context_(true),
- did_break_(false) {
+ is_inline_formatting_context_(true) {
layout_object_ = layout_object;
}
@@ -62,6 +59,32 @@ class CORE_EXPORT NGBoxFragmentBuilder final
initial_fragment_geometry_ = &initial_fragment_geometry;
size_ = initial_fragment_geometry_->border_box_size;
is_initial_block_size_indefinite_ = size_.block_size == kIndefiniteSize;
+
+ border_padding_ =
+ initial_fragment_geometry.border + initial_fragment_geometry.padding;
+ border_scrollbar_padding_ =
+ border_padding_ + initial_fragment_geometry.scrollbar;
+ if (space_) {
+ child_available_size_ = CalculateChildAvailableSize(
+ *space_, To<NGBlockNode>(node_), size_, border_scrollbar_padding_);
+ }
+ }
+
+ void AdjustBorderScrollbarPaddingForFragmentation(
+ const NGBlockBreakToken* break_token) {
+ if (LIKELY(!break_token))
+ return;
+ if (break_token->IsBreakBefore())
+ return;
+ border_scrollbar_padding_.block_start = LayoutUnit();
+ }
+
+ void AdjustBorderScrollbarPaddingForTableCell() {
+ if (!space_->IsTableCell())
+ return;
+
+ border_scrollbar_padding_ +=
+ ComputeIntrinsicPadding(*space_, *style_, Scrollbar());
}
const NGFragmentGeometry& InitialFragmentGeometry() const {
@@ -69,6 +92,52 @@ class CORE_EXPORT NGBoxFragmentBuilder final
return *initial_fragment_geometry_;
}
+ // Use the block-size setters/getters further down instead of the inherited
+ // ones.
+ LayoutUnit BlockSize() const = delete;
+ void SetBlockSize(LayoutUnit block_size) = delete;
+
+ // Set the total border-box block-size of all the fragments to be generated
+ // from this node (as if we stitched them together). Layout algorithms are
+ // expected to pass this value, and at the end of layout (if block
+ // fragmentation is needed), the fragmentation machinery will be invoked to
+ // adjust the block-size to the correct size, ensuring that we break at the
+ // best location.
+ void SetFragmentsTotalBlockSize(LayoutUnit block_size) {
+#if DCHECK_IS_ON()
+ // Note that we just store the block-size in a shared field. We have a flag
+ // for debugging, to assert that we know what we're doing when attempting to
+ // access the data.
+ block_size_is_for_all_fragments_ = true;
+#endif
+ size_.block_size = block_size;
+ }
+ LayoutUnit FragmentsTotalBlockSize() const {
+#if DCHECK_IS_ON()
+ if (has_block_fragmentation_)
+ DCHECK(block_size_is_for_all_fragments_);
+#endif
+ return size_.block_size;
+ }
+
+ // Set the final block-size of this fragment.
+ void SetFragmentBlockSize(LayoutUnit block_size) {
+#if DCHECK_IS_ON()
+ // Note that we just store the block-size in a shared field. We have a flag
+ // for debugging, to assert that we know what we're doing when attempting to
+ // access the data.
+ block_size_is_for_all_fragments_ = false;
+#endif
+ size_.block_size = block_size;
+ }
+ LayoutUnit FragmentBlockSize() const {
+#if DCHECK_IS_ON()
+ if (has_block_fragmentation_)
+ DCHECK(!block_size_is_for_all_fragments_);
+#endif
+ return size_.block_size;
+ }
+
void SetOverflowBlockSize(LayoutUnit overflow_block_size) {
overflow_block_size_ = overflow_block_size;
}
@@ -92,6 +161,22 @@ class CORE_EXPORT NGBoxFragmentBuilder final
DCHECK(initial_fragment_geometry_);
return initial_fragment_geometry_->border_box_size;
}
+ const NGBoxStrut& BorderPadding() const {
+ DCHECK(initial_fragment_geometry_);
+ return border_padding_;
+ }
+ const NGBoxStrut& BorderScrollbarPadding() const {
+ DCHECK(initial_fragment_geometry_);
+ return border_scrollbar_padding_;
+ }
+ // The child available-size is subtly different from the content-box size of
+ // an element. For an anonymous-block the child available-size is equal to
+ // its non-anonymous parent (similar to percentages).
+ const LogicalSize& ChildAvailableSize() const {
+ DCHECK(initial_fragment_geometry_);
+ DCHECK(space_);
+ return child_available_size_;
+ }
// Add a break token for a child that doesn't yet have any fragments, because
// its first fragment is to be produced in the next fragmentainer. This will
@@ -108,6 +193,8 @@ class CORE_EXPORT NGBoxFragmentBuilder final
// descendants, propagating fragmentainer breaks, and more.
void AddResult(const NGLayoutResult&, const LogicalOffset);
+ // Manually add a break token to the builder. Note that we're assuming that
+ // this break token is for content in the same flow as this parent.
void AddBreakToken(scoped_refptr<const NGBreakToken>);
void AddOutOfFlowLegacyCandidate(NGBlockNode,
@@ -126,10 +213,31 @@ class CORE_EXPORT NGBoxFragmentBuilder final
sequence_number_ = sequence_number;
}
- // Specify that we broke.
- //
- // This will result in a fragment which has an unfinished break token.
- void SetDidBreak() { did_break_ = true; }
+ // Return true if we broke inside this node on our own initiative (typically
+ // not because of a child break, but rather due to the size of this node).
+ bool DidBreakSelf() const { return did_break_self_; }
+ void SetDidBreakSelf() { did_break_self_ = true; }
+
+ // Return true if we need to break before or inside any child, doesn't matter
+ // if it's in-flow or not. As long as there are only breaks in parallel flows,
+ // we may continue layout, but when we're done, we'll need to create a break
+ // token for this fragment nevertheless, so that we re-enter, descend and
+ // resume at the broken children in the next fragmentainer.
+ bool HasChildBreakInside() const {
+ if (!child_break_tokens_.IsEmpty())
+ return true;
+ // Inline nodes produce a "finished" trailing break token even if we don't
+ // need to block-fragment.
+ return !inline_break_tokens_.IsEmpty() &&
+ !inline_break_tokens_.back()->IsFinished();
+ }
+
+ // Return true if we need to break before or inside any in-flow child that
+ // doesn't establish a parallel flow. When this happens, we want to finish our
+ // fragment, create a break token, and resume in the next fragmentainer.
+ bool HasInflowChildBreakInside() const {
+ return has_inflow_child_break_inside_;
+ }
// Report space shortage, i.e. how much more space would have been sufficient
// to prevent some piece of content from breaking. This information may be
@@ -198,6 +306,9 @@ class CORE_EXPORT NGBoxFragmentBuilder final
// children have been fully laid out, or have break tokens. No more children
// left to discover.
void SetHasSeenAllChildren() { has_seen_all_children_ = true; }
+ bool HasSeenAllChildren() { return has_seen_all_children_; }
+
+ void SetIsAtBlockEnd() { is_at_block_end_ = true; }
void SetColumnSpanner(NGBlockNode spanner) { column_spanner_ = spanner; }
bool FoundColumnSpanner() const { return !!column_spanner_; }
@@ -246,6 +357,9 @@ class CORE_EXPORT NGBoxFragmentBuilder final
void SetBoxType(NGPhysicalFragment::NGBoxType box_type) {
box_type_ = box_type;
}
+ bool IsFragmentainerBoxType() const {
+ return BoxType() == NGPhysicalFragment::kColumnBox;
+ }
void SetIsFieldsetContainer() { is_fieldset_container_ = true; }
void SetIsLegacyLayoutRoot() { is_legacy_layout_root_ = true; }
@@ -254,8 +368,22 @@ class CORE_EXPORT NGBoxFragmentBuilder final
}
void SetIsMathMLFraction() { is_math_fraction_ = true; }
-
- bool DidBreak() const { return did_break_; }
+ void SetMathMLPaintInfo(
+ UChar operator_character,
+ scoped_refptr<const ShapeResultView> operator_shape_result_view,
+ LayoutUnit operator_inline_size,
+ LayoutUnit operator_ascent,
+ LayoutUnit operator_descent) {
+ if (!mathml_paint_info_)
+ mathml_paint_info_ = std::make_unique<NGMathMLPaintInfo>();
+
+ mathml_paint_info_->operator_shape_result_view =
+ std::move(operator_shape_result_view);
+
+ mathml_paint_info_->operator_inline_size = operator_inline_size;
+ mathml_paint_info_->operator_ascent = operator_ascent;
+ mathml_paint_info_->operator_descent = operator_descent;
+ }
void SetBorderEdges(NGBorderEdges border_edges) {
border_edges_ = border_edges;
@@ -329,12 +457,15 @@ class CORE_EXPORT NGBoxFragmentBuilder final
void SetHasForcedBreak() {
has_forced_break_ = true;
- minimal_space_shortage_ = LayoutUnit();
+ minimal_space_shortage_ = LayoutUnit::Max();
}
scoped_refptr<const NGLayoutResult> ToBoxFragment(WritingMode);
const NGFragmentGeometry* initial_fragment_geometry_ = nullptr;
+ NGBoxStrut border_padding_;
+ NGBoxStrut border_scrollbar_padding_;
+ LogicalSize child_available_size_;
LayoutUnit overflow_block_size_ = kIndefiniteSize;
LayoutUnit intrinsic_block_size_;
@@ -347,12 +478,14 @@ class CORE_EXPORT NGBoxFragmentBuilder final
bool is_initial_block_size_indefinite_ = false;
bool is_inline_formatting_context_;
bool is_first_for_node_ = true;
- bool did_break_;
+ bool did_break_self_ = false;
+ bool has_inflow_child_break_inside_ = false;
bool has_forced_break_ = false;
bool is_new_fc_ = false;
bool subtree_modified_margin_strut_ = false;
bool has_seen_all_children_ = false;
bool is_math_fraction_ = false;
+ bool is_at_block_end_ = false;
LayoutUnit consumed_block_size_;
unsigned sequence_number_ = 0;
@@ -373,6 +506,14 @@ class CORE_EXPORT NGBoxFragmentBuilder final
scoped_refptr<SerializedScriptValue> custom_layout_data_;
base::Optional<int> lines_until_clamp_;
+ std::unique_ptr<NGMathMLPaintInfo> mathml_paint_info_;
+
+#if DCHECK_IS_ON()
+ // Describes what size_.block_size represents; either the size of a single
+ // fragment (false), or the size of all fragments for a node (true).
+ bool block_size_is_for_all_fragments_ = false;
+#endif
+
friend class NGPhysicalBoxFragment;
friend class NGLayoutResult;
};
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_break_token.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_break_token.h
index 29c7bb6009b..5b927db4bfd 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_break_token.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_break_token.h
@@ -78,6 +78,7 @@ class CORE_EXPORT NGBreakToken : public RefCounted<NGBreakToken> {
flags_(0),
is_break_before_(false),
is_forced_break_(false),
+ is_at_block_end_(false),
break_appeal_(kBreakAppealPerfect),
has_seen_all_children_(false) {
DCHECK_EQ(type, static_cast<NGBreakTokenType>(node.Type()));
@@ -104,6 +105,11 @@ class CORE_EXPORT NGBreakToken : public RefCounted<NGBreakToken> {
unsigned is_forced_break_ : 1;
+ // Set when layout is past the block-end border edge. If we break when we're
+ // in this state, it means that something is overflowing, and thus establishes
+ // a parallel flow.
+ unsigned is_at_block_end_ : 1;
+
// If the break is unforced, this is the appeal of the break. Higher is
// better. Violating breaking rules decreases appeal. Forced breaks always
// have perfect appeal.
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
index 2db4791c47a..5950ccb01a1 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
@@ -88,32 +88,30 @@ void PushSpannerBreakTokens(
NGColumnLayoutAlgorithm::NGColumnLayoutAlgorithm(
const NGLayoutAlgorithmParams& params)
- : NGLayoutAlgorithm(params),
- early_break_(params.early_break),
- border_padding_(params.fragment_geometry.border +
- params.fragment_geometry.padding),
- border_scrollbar_padding_(border_padding_ +
- params.fragment_geometry.scrollbar) {
- AdjustForFragmentation(BreakToken(), &border_scrollbar_padding_);
+ : NGLayoutAlgorithm(params), early_break_(params.early_break) {
container_builder_.SetIsNewFormattingContext(
params.space.IsNewFormattingContext());
container_builder_.SetInitialFragmentGeometry(params.fragment_geometry);
+ container_builder_.AdjustBorderScrollbarPaddingForFragmentation(BreakToken());
}
scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::Layout() {
- LogicalSize border_box_size = container_builder_.InitialBorderBoxSize();
- content_box_size_ =
- ShrinkAvailableSize(border_box_size, border_scrollbar_padding_);
-
- DCHECK_GE(content_box_size_.inline_size, LayoutUnit());
+ const LogicalSize border_box_size = container_builder_.InitialBorderBoxSize();
+ // TODO(mstensho): This isn't the content-box size, as
+ // |BorderScrollbarPadding()| has been adjusted for fragmentation. Verify
+ // that this is the correct size.
+ column_block_size_ =
+ ShrinkLogicalSize(border_box_size, BorderScrollbarPadding()).block_size;
+
+ DCHECK_GE(ChildAvailableSize().inline_size, LayoutUnit());
column_inline_size_ =
- ResolveUsedColumnInlineSize(content_box_size_.inline_size, Style());
+ ResolveUsedColumnInlineSize(ChildAvailableSize().inline_size, Style());
column_inline_progression_ =
column_inline_size_ +
- ResolveUsedColumnGap(content_box_size_.inline_size, Style());
+ ResolveUsedColumnGap(ChildAvailableSize().inline_size, Style());
used_column_count_ =
- ResolveUsedColumnCount(content_box_size_.inline_size, Style());
+ ResolveUsedColumnCount(ChildAvailableSize().inline_size, Style());
// If we know the block-size of the fragmentainers in an outer fragmentation
// context (if any), our columns may be constrained by that, meaning that we
@@ -129,7 +127,7 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::Layout() {
container_builder_.SetIsBlockFragmentationContextRoot();
- intrinsic_block_size_ = border_scrollbar_padding_.block_start;
+ intrinsic_block_size_ = BorderScrollbarPadding().block_start;
NGBreakStatus break_status = LayoutChildren();
if (break_status == NGBreakStatus::kNeedsEarlierBreak) {
@@ -138,11 +136,13 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::Layout() {
return RelayoutAndBreakEarlier();
} else if (break_status == NGBreakStatus::kBrokeBefore) {
// If we want to break before, make sure that we're actually at the start.
- DCHECK(!BreakToken());
+ DCHECK(!IsResumingLayout(BreakToken()));
return container_builder_.Abort(NGLayoutResult::kOutOfFragmentainerSpace);
}
+ intrinsic_block_size_ += BorderScrollbarPadding().block_end;
+
// Figure out how much space we've already been able to process in previous
// fragments, if this multicol container participates in an outer
// fragmentation context.
@@ -155,22 +155,23 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::Layout() {
LayoutUnit block_size;
if (border_box_size.block_size == kIndefiniteSize) {
// Get the block size from the contents if it's auto.
- block_size = intrinsic_block_size_ + border_scrollbar_padding_.block_end;
+ block_size = intrinsic_block_size_;
} else {
// TODO(mstensho): end border and padding may overflow the parent
// fragmentainer, and we should avoid that.
block_size = border_box_size.block_size - previously_consumed_block_size;
}
- if (is_constrained_by_outer_fragmentation_context_) {
+ container_builder_.SetFragmentsTotalBlockSize(previously_consumed_block_size +
+ block_size);
+ container_builder_.SetIntrinsicBlockSize(intrinsic_block_size_);
+
+ if (ConstraintSpace().HasBlockFragmentation()) {
// In addition to establishing one, we're nested inside another
// fragmentation context.
FinishFragmentation(
- ConstraintSpace(), BreakToken(), block_size, intrinsic_block_size_,
+ Node(), ConstraintSpace(), BreakToken(), BorderPadding(),
FragmentainerSpaceAtBfcStart(ConstraintSpace()), &container_builder_);
- } else {
- container_builder_.SetBlockSize(block_size);
- container_builder_.SetIntrinsicBlockSize(intrinsic_block_size_);
}
NGOutOfFlowLayoutPart(
@@ -211,7 +212,7 @@ MinMaxSizesResult NGColumnLayoutAlgorithm::ComputeMinMaxSizes(
// TODO(mstensho): Need to include spanners.
- result.sizes += border_scrollbar_padding_.InlineSum();
+ result.sizes += BorderScrollbarPadding().InlineSum();
return result;
}
@@ -295,7 +296,12 @@ NGBreakStatus NGColumnLayoutAlgorithm::LayoutChildren() {
if (!result) {
// Not enough outer fragmentainer space to produce any columns at all.
- container_builder_.SetDidBreak();
+
+ // TODO(mstensho): Explicitly marking that we broke shouldn't be necessary
+ // here, ideally. But the fragmentation machinery needs this hint in some
+ // cases. There's probably a break token missing.
+ container_builder_.SetDidBreakSelf();
+
if (intrinsic_block_size_) {
// We have preceding initial border/padding, or a column spanner
// (possibly preceded by other spanners or even column content). So we
@@ -370,6 +376,9 @@ NGBreakStatus NGColumnLayoutAlgorithm::LayoutChildren() {
// resuming.
container_builder_.SetHasSeenAllChildren();
+ // TODO(mstensho): Truncate the child margin if it overflows the
+ // fragmentainer, by using AdjustedMarginAfterFinalChildFragment().
+
intrinsic_block_size_ += margin_strut.Sum();
}
@@ -379,7 +388,7 @@ NGBreakStatus NGColumnLayoutAlgorithm::LayoutChildren() {
scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow(
const NGBlockBreakToken* next_column_token,
NGMarginStrut* margin_strut) {
- LogicalSize column_size(column_inline_size_, content_box_size_.block_size);
+ LogicalSize column_size(column_inline_size_, column_block_size_);
// If block-size is non-auto, subtract the space for content we've consumed in
// previous fragments. This is necessary when we're nested inside another
@@ -462,7 +471,7 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow(
// preceding columns in this row and there are also no preceding rows.
bool is_first_fragmentainer = !column_break_token && !BreakToken();
- LayoutUnit column_inline_offset(border_scrollbar_padding_.inline_start);
+ LayoutUnit column_inline_offset(BorderScrollbarPadding().inline_start);
int actual_column_count = 0;
int forced_break_count = 0;
@@ -526,7 +535,6 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow(
if (zero_outer_space_left)
return nullptr;
- container_builder_.SetDidBreak();
container_builder_.SetBreakAppeal(kBreakAppealPerfect);
break;
}
@@ -535,52 +543,68 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow(
} while (column_break_token);
// TODO(mstensho): Nested column balancing.
- if (container_builder_.DidBreak())
+ if (container_builder_.DidBreakSelf())
break;
- if (!balance_columns && result->ColumnSpanner()) {
- // We always have to balance columns preceding a spanner, so if we didn't
- // do that initially, switch over to column balancing mode now, and lay
- // out again.
- balance_columns = true;
- new_columns.clear();
- column_size.block_size =
- CalculateBalancedColumnBlockSize(column_size, next_column_token);
- continue;
+ if (!balance_columns) {
+ if (result->ColumnSpanner()) {
+ // We always have to balance columns preceding a spanner, so if we
+ // didn't do that initially, switch over to column balancing mode now,
+ // and lay out again.
+ balance_columns = true;
+ new_columns.clear();
+ column_size.block_size =
+ CalculateBalancedColumnBlockSize(column_size, next_column_token);
+ continue;
+ }
+
+ // Balancing not enabled. We're done.
+ break;
}
- // If we overflowed (actual column count larger than what we have room for),
- // and we're supposed to calculate the column lengths automatically (column
- // balancing), see if we're able to stretch them.
+ // We're balancing columns. Check if the column block-size that we laid out
+ // with was satisfactory. If not, stretch and retry, if possible.
//
- // We can only stretch the columns if we have at least one column that could
- // take more content, and we also need to know the stretch amount (minimal
- // space shortage). We need at least one soft break opportunity to do
- // this. If forced breaks cause too many breaks, there's no stretch amount
- // that could prevent the actual column count from overflowing.
+ // If we overflowed (actual column count larger than what we have room for),
+ // see if we're able to stretch them. We can only stretch the columns if we
+ // have at least one column that could take more content.
//
+ // If we didn't exceed used column-count, we're done.
+ if (actual_column_count <= used_column_count_)
+ break;
+
+ // We're in a situation where we'd like to stretch the columns, but then we
+ // need to know the stretch amount (minimal space shortage).
+ if (minimal_space_shortage == LayoutUnit::Max())
+ break;
+
+ // We also need at least one soft break opportunity. If forced breaks cause
+ // too many breaks, there's no stretch amount that could prevent the columns
+ // from overflowing.
+ if (actual_column_count <= forced_break_count + 1)
+ break;
+
// TODO(mstensho): Handle this situation also when we're inside another
// balanced multicol container, rather than bailing (which we do now, to
// avoid infinite loops). If we exhaust the inner column-count in such
// cases, that piece of information may have to be propagated to the outer
// multicol, and instead stretch there (not here). We have no such mechanism
// in place yet.
- if (balance_columns && actual_column_count > used_column_count_ &&
- actual_column_count > forced_break_count + 1 &&
- minimal_space_shortage != LayoutUnit::Max() &&
- !ConstraintSpace().IsInsideBalancedColumns()) {
- LayoutUnit new_column_block_size = StretchColumnBlockSize(
- minimal_space_shortage, column_size.block_size);
-
- DCHECK_GE(new_column_block_size, column_size.block_size);
- if (new_column_block_size > column_size.block_size) {
- // Remove column fragments and re-attempt layout with taller columns.
- new_columns.clear();
- column_size.block_size = new_column_block_size;
- continue;
- }
- }
- break;
+ if (ConstraintSpace().IsInsideBalancedColumns())
+ break;
+
+ LayoutUnit new_column_block_size =
+ StretchColumnBlockSize(minimal_space_shortage, column_size.block_size);
+
+ // Give up if we cannot get taller columns. The multicol container may have
+ // a specified block-size preventing taller columns, for instance.
+ DCHECK_GE(new_column_block_size, column_size.block_size);
+ if (new_column_block_size <= column_size.block_size)
+ break;
+
+ // Remove column fragments and re-attempt layout with taller columns.
+ new_columns.clear();
+ column_size.block_size = new_column_block_size;
} while (true);
bool is_empty = false;
@@ -631,7 +655,7 @@ NGBreakStatus NGColumnLayoutAlgorithm::LayoutSpanner(
*spanner_break_token = nullptr;
const ComputedStyle& spanner_style = spanner_node.Style();
NGBoxStrut margins = ComputeMarginsFor(
- spanner_style, content_box_size_.inline_size,
+ spanner_style, ChildAvailableSize().inline_size,
ConstraintSpace().GetWritingMode(), ConstraintSpace().Direction());
if (break_token) {
@@ -693,11 +717,11 @@ NGBreakStatus NGColumnLayoutAlgorithm::LayoutSpanner(
NGFragment fragment(ConstraintSpace().GetWritingMode(),
result->PhysicalFragment());
- ResolveInlineMargins(spanner_style, Style(), content_box_size_.inline_size,
+ ResolveInlineMargins(spanner_style, Style(), ChildAvailableSize().inline_size,
fragment.InlineSize(), &margins);
LogicalOffset offset(
- border_scrollbar_padding_.inline_start + margins.inline_start,
+ BorderScrollbarPadding().inline_start + margins.inline_start,
block_offset);
container_builder_.AddResult(*result, offset);
@@ -815,7 +839,7 @@ LayoutUnit NGColumnLayoutAlgorithm::CalculateBalancedColumnBlockSize(
// Then distribute as many implicit breaks into the content runs as we need.
int used_column_count =
- ResolveUsedColumnCount(content_box_size_.inline_size, Style());
+ ResolveUsedColumnCount(ChildAvailableSize().inline_size, Style());
for (int columns_found = content_runs.size();
columns_found < used_column_count; columns_found++) {
// The tallest content run (with all assumed implicit breaks added so far
@@ -869,15 +893,15 @@ LayoutUnit NGColumnLayoutAlgorithm::ConstrainColumnBlockSize(
// First of all we need to convert the size to a value that can be compared
// against the resolved properties on the multicol container. That means that
// we have to convert the value from content-box to border-box.
- LayoutUnit extra = border_scrollbar_padding_.BlockSum();
+ LayoutUnit extra = BorderScrollbarPadding().BlockSum();
size += extra;
const ComputedStyle& style = Style();
LayoutUnit max = ResolveMaxBlockLength(
- ConstraintSpace(), style, border_padding_, style.LogicalMaxHeight(),
+ ConstraintSpace(), style, BorderPadding(), style.LogicalMaxHeight(),
LengthResolvePhase::kLayout);
LayoutUnit extent = ResolveMainBlockLength(
- ConstraintSpace(), style, border_padding_, style.LogicalHeight(), size,
+ ConstraintSpace(), style, BorderPadding(), style.LogicalHeight(), size,
LengthResolvePhase::kLayout);
if (extent != kIndefiniteSize) {
// A specified height/width will just constrain the maximum length.
@@ -987,8 +1011,8 @@ NGConstraintSpace NGColumnLayoutAlgorithm::CreateConstraintSpaceForSpanner(
LayoutUnit block_offset) const {
NGConstraintSpaceBuilder space_builder(
ConstraintSpace(), Style().GetWritingMode(), /* is_new_fc */ true);
- space_builder.SetAvailableSize(content_box_size_);
- space_builder.SetPercentageResolutionSize(content_box_size_);
+ space_builder.SetAvailableSize(ChildAvailableSize());
+ space_builder.SetPercentageResolutionSize(ChildAvailableSize());
if (ConstraintSpace().HasBlockFragmentation()) {
SetupSpaceBuilderForFragmentation(ConstraintSpace(), spanner, block_offset,
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.h
index 70735070448..44f402fdb9c 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.h
@@ -66,7 +66,7 @@ class CORE_EXPORT NGColumnLayoutAlgorithm
LayoutUnit ConstrainColumnBlockSize(LayoutUnit size) const;
LayoutUnit CurrentContentBlockOffset() const {
- return intrinsic_block_size_ - border_scrollbar_padding_.block_start;
+ return intrinsic_block_size_ - BorderScrollbarPadding().block_start;
}
// Finalize layout after breaking before column contents.
@@ -97,18 +97,10 @@ class CORE_EXPORT NGColumnLayoutAlgorithm
// When set, this will specify where to break before or inside.
const NGEarlyBreak* early_break_ = nullptr;
- // Border + padding sum, resolved from the node's computed style.
- const NGBoxStrut border_padding_;
-
- // Border + scrollbar + padding sum for the fragment to be generated (most
- // importantly, for non-first fragments, leading block border + scrollbar +
- // padding is zero).
- NGBoxStrut border_scrollbar_padding_;
-
- LogicalSize content_box_size_;
int used_column_count_;
LayoutUnit column_inline_size_;
LayoutUnit column_inline_progression_;
+ LayoutUnit column_block_size_;
LayoutUnit intrinsic_block_size_;
bool is_constrained_by_outer_fragmentation_context_ = false;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc
index 89e5c4de416..cbb3aa027fb 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc
@@ -2053,7 +2053,9 @@ TEST_F(NGColumnLayoutAlgorithmTest, UnsatisfiableOrphansAndWidows) {
EXPECT_EQ(expectation, dump);
}
-TEST_F(NGColumnLayoutAlgorithmTest, WidowsAndAbspos) {
+// TODO(1079031): Re-enable once layout for fragmented positioned elements is
+// complete.
+TEST_F(NGColumnLayoutAlgorithmTest, DISABLED_WidowsAndAbspos) {
SetBodyInnerHTML(R"HTML(
<style>
#parent {
@@ -2719,7 +2721,8 @@ TEST_F(NGColumnLayoutAlgorithmTest, MinMax) {
NGColumnLayoutAlgorithm algorithm({node, fragment_geometry, space});
base::Optional<MinMaxSizes> sizes;
MinMaxSizesInput zero_input(
- /* percentage_resolution_block_size */ (LayoutUnit()));
+ /* percentage_resolution_block_size */ LayoutUnit(),
+ MinMaxSizesType::kContent);
// Both column-count and column-width set.
style->SetColumnCount(3);
@@ -4327,7 +4330,9 @@ TEST_F(NGColumnLayoutAlgorithmTest, NestedWithTallSpanner) {
EXPECT_EQ(expectation, dump);
}
-TEST_F(NGColumnLayoutAlgorithmTest, AbsposFitsInOneColumn) {
+// TODO(1079031): Re-enable once layout for fragmented positioned elements is
+// complete.
+TEST_F(NGColumnLayoutAlgorithmTest, DISABLED_AbsposFitsInOneColumn) {
SetBodyInnerHTML(R"HTML(
<div id="container">
<div style="columns:3; width:320px; height:100px; column-gap:10px; column-fill:auto;">
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
index 6b49934f15d..069997ac3e0 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
@@ -460,6 +460,16 @@ class CORE_EXPORT NGConstraintSpace final {
return HasRareData() && rare_data_->is_restricted_block_size_table_cell;
}
+ // The amount of available space for block-start side annotation.
+ // For the first box, this is the padding-block-start value of the container.
+ // Otherwise, this comes from NGLayoutResult::BlockEndAnnotationSpace().
+ // If the value is negative, it's block-end annotation overflow of the
+ // previous box.
+ LayoutUnit BlockStartAnnotationSpace() const {
+ return HasRareData() ? rare_data_->BlockStartAnnotationSpace()
+ : LayoutUnit();
+ }
+
NGMarginStrut MarginStrut() const {
return HasRareData() ? rare_data_->MarginStrut() : NGMarginStrut();
}
@@ -676,6 +686,7 @@ class CORE_EXPORT NGConstraintSpace final {
: percentage_resolution_size(other.percentage_resolution_size),
replaced_percentage_resolution_block_size(
other.replaced_percentage_resolution_block_size),
+ block_start_annotation_space(other.block_start_annotation_space),
bfc_offset(other.bfc_offset),
fragmentainer_block_size(other.fragmentainer_block_size),
fragmentainer_offset_at_bfc(other.fragmentainer_offset_at_bfc),
@@ -784,6 +795,14 @@ class CORE_EXPORT NGConstraintSpace final {
return stretch_data_.IsInitialForMaySkipLayout();
}
+ LayoutUnit BlockStartAnnotationSpace() const {
+ return block_start_annotation_space;
+ }
+
+ void SetBlockStartAnnotationSpace(LayoutUnit space) {
+ block_start_annotation_space = space;
+ }
+
NGMarginStrut MarginStrut() const {
return data_union_type == kBlockData ? block_data_.margin_strut
: NGMarginStrut();
@@ -903,6 +922,7 @@ class CORE_EXPORT NGConstraintSpace final {
LogicalSize percentage_resolution_size;
LayoutUnit replaced_percentage_resolution_block_size;
+ LayoutUnit block_start_annotation_space;
NGBfcOffset bfc_offset;
LayoutUnit fragmentainer_block_size = kIndefiniteSize;
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 30655178c30..5da0ad3a734 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
@@ -215,6 +215,11 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
space_.bitfields_.cache_slot = static_cast<unsigned>(slot);
}
+ void SetBlockStartAnnotationSpace(LayoutUnit space) {
+ if (space)
+ space_.EnsureRareData()->SetBlockStartAnnotationSpace(space);
+ }
+
void SetMarginStrut(const NGMarginStrut& margin_strut) {
#if DCHECK_IS_ON()
DCHECK(!is_margin_strut_set_);
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 2be126bca70..02912fb434a 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
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/platform/text/writing_mode.h"
@@ -75,11 +76,40 @@ void NGContainerFragmentBuilder::PropagateChildData(
IsInlineContainerForNode(descendant.node, inline_container))
new_inline_container = inline_container;
+ // |oof_positioned_candidates_| should not have duplicated entries.
+ DCHECK(std::none_of(
+ oof_positioned_candidates_.begin(), oof_positioned_candidates_.end(),
+ [&descendant](const NGLogicalOutOfFlowPositionedNode& node) {
+ return node.node == descendant.node;
+ }));
oof_positioned_candidates_.emplace_back(descendant.node, static_position,
new_inline_container);
}
}
+ if (const NGPhysicalBoxFragment* fragment =
+ DynamicTo<NGPhysicalBoxFragment>(&child)) {
+ if (fragment->HasOutOfFlowPositionedFragmentainerDescendants()) {
+ const auto& out_of_flow_fragmentainer_descendants =
+ fragment->OutOfFlowPositionedFragmentainerDescendants();
+
+ for (const auto& descendant : out_of_flow_fragmentainer_descendants) {
+ const NGPhysicalContainerFragment* containing_block_fragment =
+ descendant.containing_block_fragment.get();
+ if (!containing_block_fragment)
+ containing_block_fragment = fragment;
+
+ NGLogicalStaticPosition static_position =
+ descendant.static_position.ConvertToLogical(
+ GetWritingMode(), Direction(), PhysicalSize());
+ oof_positioned_fragmentainer_descendants_.emplace_back(
+ descendant.node, static_position, descendant.inline_container,
+ /* needs_block_offset_adjustment */ false,
+ containing_block_fragment);
+ }
+ }
+ }
+
// For the |has_orthogonal_flow_roots_| flag, we don't care about the type of
// child (OOF-positioned, etc), it is for *any* descendant.
if (child.HasOrthogonalFlowRoots() ||
@@ -128,10 +158,9 @@ void NGContainerFragmentBuilder::PropagateChildData(
// Compute |has_floating_descendants_for_paint_| to optimize tree traversal
// in paint.
if (!has_floating_descendants_for_paint_) {
- // TODO(layout-dev): The |NGPhysicalFragment::IsAtomicInline| check should
- // be checking for any children which paint all phases atomically.
if (child.IsFloating() || child.IsLegacyLayoutRoot() ||
- (child.HasFloatingDescendantsForPaint() && !child.IsAtomicInline()))
+ (child.HasFloatingDescendantsForPaint() &&
+ !child.IsPaintedAtomically()))
has_floating_descendants_for_paint_ = true;
}
@@ -219,6 +248,11 @@ void NGContainerFragmentBuilder::AddOutOfFlowInlineChildCandidate(
NGLogicalStaticPosition::kBlockStart);
}
+void NGContainerFragmentBuilder::AddOutOfFlowFragmentainerDescendant(
+ const NGLogicalOutOfFlowPositionedNode& descendant) {
+ oof_positioned_fragmentainer_descendants_.push_back(descendant);
+}
+
void NGContainerFragmentBuilder::AddOutOfFlowDescendant(
const NGLogicalOutOfFlowPositionedNode& descendant) {
oof_positioned_descendants_.push_back(descendant);
@@ -251,6 +285,13 @@ void NGContainerFragmentBuilder::SwapOutOfFlowPositionedCandidates(
has_oof_candidate_that_needs_block_offset_adjustment_ = false;
}
+void NGContainerFragmentBuilder::SwapOutOfFlowFragmentainerDescendants(
+ Vector<NGLogicalOutOfFlowPositionedNode>* descendants) {
+ DCHECK(descendants->IsEmpty());
+ DCHECK(!has_oof_candidate_that_needs_block_offset_adjustment_);
+ std::swap(oof_positioned_fragmentainer_descendants_, *descendants);
+}
+
void NGContainerFragmentBuilder::
MoveOutOfFlowDescendantCandidatesToDescendants() {
DCHECK(oof_positioned_descendants_.IsEmpty());
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h
index 4edb57dcf10..1b007aafac9 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h
@@ -126,16 +126,26 @@ class CORE_EXPORT NGContainerFragmentBuilder : public NGFragmentBuilder {
const LogicalOffset& child_offset,
TextDirection inline_container_direction);
+ void AddOutOfFlowFragmentainerDescendant(
+ const NGLogicalOutOfFlowPositionedNode& descendant);
+
void AddOutOfFlowDescendant(
const NGLogicalOutOfFlowPositionedNode& descendant);
void SwapOutOfFlowPositionedCandidates(
Vector<NGLogicalOutOfFlowPositionedNode>* candidates);
+ void SwapOutOfFlowFragmentainerDescendants(
+ Vector<NGLogicalOutOfFlowPositionedNode>* descendants);
+
bool HasOutOfFlowPositionedCandidates() const {
return !oof_positioned_candidates_.IsEmpty();
}
+ bool HasOutOfFlowFragmentainerDescendants() const {
+ return !oof_positioned_fragmentainer_descendants_.IsEmpty();
+ }
+
// This method should only be used within the inline layout algorithm. It is
// used to convert all OOF-positioned candidates to descendants.
//
@@ -173,6 +183,20 @@ class CORE_EXPORT NGContainerFragmentBuilder : public NGFragmentBuilder {
is_fragmentation_context_root_ = true;
}
+ bool IsBlockFragmentationContextRoot() const {
+ return is_fragmentation_context_root_;
+ }
+
+ // See NGLayoutResult::AnnotationOverflow().
+ void SetAnnotationOverflow(LayoutUnit overflow) {
+ annotation_overflow_ = overflow;
+ }
+
+ // See NGLayoutRsult::BlockEndAnnotatioSpace().
+ void SetBlockEndAnnotationSpace(LayoutUnit space) {
+ block_end_annotation_space_ = space;
+ }
+
const NGConstraintSpace* ConstraintSpace() const { return space_; }
#if DCHECK_IS_ON()
@@ -187,9 +211,8 @@ class CORE_EXPORT NGContainerFragmentBuilder : public NGFragmentBuilder {
NGContainerFragmentBuilder(NGLayoutInputNode node,
scoped_refptr<const ComputedStyle> style,
const NGConstraintSpace* space,
- WritingMode writing_mode,
- TextDirection direction)
- : NGFragmentBuilder(std::move(style), writing_mode, direction),
+ WritingDirectionMode writing_direction)
+ : NGFragmentBuilder(std::move(style), writing_direction),
node_(node),
space_(space) {
layout_object_ = node.GetLayoutBox();
@@ -211,6 +234,8 @@ class CORE_EXPORT NGContainerFragmentBuilder : public NGFragmentBuilder {
NGExclusionSpace exclusion_space_;
Vector<NGLogicalOutOfFlowPositionedNode> oof_positioned_candidates_;
+ Vector<NGLogicalOutOfFlowPositionedNode>
+ oof_positioned_fragmentainer_descendants_;
Vector<NGLogicalOutOfFlowPositionedNode> oof_positioned_descendants_;
NGUnpositionedListMarker unpositioned_list_marker_;
@@ -225,6 +250,11 @@ class CORE_EXPORT NGContainerFragmentBuilder : public NGFragmentBuilder {
scoped_refptr<const NGEarlyBreak> early_break_;
NGBreakAppeal break_appeal_ = kBreakAppealLastResort;
+ // See NGLayoutResult::AnnotationOverflow().
+ LayoutUnit annotation_overflow_;
+ // See NGLayoutResult::BlockEndAnotationSpace().
+ LayoutUnit block_end_annotation_space_;
+
NGAdjoiningObjectTypes adjoining_object_types_ = kAdjoiningNone;
bool has_adjoining_object_descendants_ = false;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc
index 2e117e138f2..17ddb935ff0 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc
@@ -23,10 +23,9 @@ NGFieldsetLayoutAlgorithm::NGFieldsetLayoutAlgorithm(
const NGLayoutAlgorithmParams& params)
: NGLayoutAlgorithm(params),
writing_mode_(ConstraintSpace().GetWritingMode()),
- border_padding_(params.fragment_geometry.border +
- params.fragment_geometry.padding),
consumed_block_size_(BreakToken() ? BreakToken()->ConsumedBlockSize()
: LayoutUnit()) {
+ DCHECK(params.fragment_geometry.scrollbar.IsEmpty());
container_builder_.SetIsNewFormattingContext(
params.space.IsNewFormattingContext());
container_builder_.SetInitialFragmentGeometry(params.fragment_geometry);
@@ -38,21 +37,22 @@ NGFieldsetLayoutAlgorithm::NGFieldsetLayoutAlgorithm(
// Leading border and padding should only apply to the first fragment. We
// don't adjust the value of border_padding_ itself so that it can be used
// when calculating the block size of the last fragment.
- adjusted_border_padding_ = border_padding_;
+ adjusted_border_padding_ = BorderPadding();
AdjustForFragmentation(BreakToken(), &adjusted_border_padding_);
}
scoped_refptr<const NGLayoutResult> NGFieldsetLayoutAlgorithm::Layout() {
// Layout of a fieldset container consists of two parts: Create a child
// fragment for the rendered legend (if any), and create a child fragment for
- // the fieldset contents anonymous box (if any). Fieldset scrollbars and
- // padding will not be applied to the fieldset container itself, but rather to
- // the fieldset contents anonymous child box. The reason for this is that the
- // rendered legend shouldn't be part of the scrollport; the legend is
- // essentially a part of the block-start border, and should not scroll along
- // with the actual fieldset contents. Since scrollbars are handled by the
- // anonymous child box, and since padding is inside the scrollport, padding
- // also needs to be handled by the anonymous child.
+ // the fieldset contents anonymous box (if any).
+ // Fieldset scrollbars and padding will not be applied to the fieldset
+ // container itself, but rather to the fieldset contents anonymous child box.
+ // The reason for this is that the rendered legend shouldn't be part of the
+ // scrollport; the legend is essentially a part of the block-start border,
+ // and should not scroll along with the actual fieldset contents. Since
+ // scrollbars are handled by the anonymous child box, and since padding is
+ // inside the scrollport, padding also needs to be handled by the anonymous
+ // child.
// Calculate the amount of the border block-start that was consumed in
// previous fragments.
@@ -72,7 +72,7 @@ scoped_refptr<const NGLayoutResult> NGFieldsetLayoutAlgorithm::Layout() {
// Recompute the block-axis size now that we know our content size.
border_box_size_.block_size =
- ComputeBlockSizeForFragment(ConstraintSpace(), Style(), border_padding_,
+ ComputeBlockSizeForFragment(ConstraintSpace(), Style(), BorderPadding(),
intrinsic_block_size_ + consumed_block_size_,
border_box_size_.inline_size);
@@ -93,16 +93,16 @@ scoped_refptr<const NGLayoutResult> NGFieldsetLayoutAlgorithm::Layout() {
// TODO(almaher): end border and padding may overflow the parent
// fragmentainer, and we should avoid that.
- LayoutUnit block_size = border_box_size_.block_size - consumed_block_size_;
+ LayoutUnit all_fragments_block_size = border_box_size_.block_size;
+ container_builder_.SetIntrinsicBlockSize(intrinsic_block_size_);
+ container_builder_.SetFragmentsTotalBlockSize(all_fragments_block_size);
container_builder_.SetIsFieldsetContainer();
- if (ConstraintSpace().HasKnownFragmentainerBlockSize()) {
+
+ if (ConstraintSpace().HasBlockFragmentation()) {
FinishFragmentation(
- ConstraintSpace(), BreakToken(), block_size, intrinsic_block_size_,
+ Node(), ConstraintSpace(), BreakToken(), BorderPadding(),
FragmentainerSpaceAtBfcStart(ConstraintSpace()), &container_builder_);
- } else {
- container_builder_.SetIntrinsicBlockSize(intrinsic_block_size_);
- container_builder_.SetBlockSize(block_size);
}
NGOutOfFlowLayoutPart(Node(), ConstraintSpace(), borders_,
@@ -158,7 +158,7 @@ NGBreakStatus NGFieldsetLayoutAlgorithm::LayoutChildren() {
NGBoxStrut borders_with_legend = borders_;
borders_with_legend.block_start = intrinsic_block_size_;
LogicalSize adjusted_padding_box_size =
- ShrinkAvailableSize(border_box_size_, borders_with_legend);
+ ShrinkLogicalSize(border_box_size_, borders_with_legend);
if (adjusted_padding_box_size.block_size != kIndefiniteSize) {
// If intrinsic_block_size_ does not include the border block-start that was
@@ -226,10 +226,8 @@ NGBreakStatus NGFieldsetLayoutAlgorithm::LayoutLegend(
// Lay out the legend. While the fieldset container normally ignores its
// padding, the legend is laid out within what would have been the content
// box had the fieldset been a regular block with no weirdness.
- LogicalSize content_box_size =
- ShrinkAvailableSize(border_box_size_, adjusted_border_padding_);
- LogicalSize percentage_size =
- CalculateChildPercentageSize(ConstraintSpace(), Node(), content_box_size);
+ LogicalSize percentage_size = CalculateChildPercentageSize(
+ ConstraintSpace(), Node(), ChildAvailableSize());
NGBoxStrut legend_margins = ComputeMarginsFor(
legend.Style(), percentage_size.inline_size,
ConstraintSpace().GetWritingMode(), ConstraintSpace().Direction());
@@ -243,7 +241,7 @@ NGBreakStatus NGFieldsetLayoutAlgorithm::LayoutLegend(
LayoutUnit block_offset = legend_margins.block_start;
do {
auto legend_space = CreateConstraintSpaceForLegend(
- legend, content_box_size, percentage_size, block_offset);
+ legend, ChildAvailableSize(), percentage_size, block_offset);
result = legend.Layout(legend_space, legend_break_token.get());
// TODO(layout-dev): Handle abortions caused by block fragmentation.
@@ -277,8 +275,16 @@ NGBreakStatus NGFieldsetLayoutAlgorithm::LayoutLegend(
}
LayoutUnit legend_margin_box_block_size =
- NGFragment(writing_mode_, physical_fragment).BlockSize() +
- legend_margins.BlockSum();
+ legend_margins.block_start +
+ NGFragment(writing_mode_, physical_fragment).BlockSize();
+
+ LayoutUnit block_end_margin = legend_margins.block_end;
+ if (ConstraintSpace().HasKnownFragmentainerBlockSize()) {
+ block_end_margin = AdjustedMarginAfterFinalChildFragment(
+ ConstraintSpace(), legend_margin_box_block_size, block_end_margin);
+ }
+ legend_margin_box_block_size += block_end_margin;
+
LayoutUnit space_left = borders_.block_start - legend_margin_box_block_size;
if (space_left > LayoutUnit()) {
@@ -303,6 +309,8 @@ NGBreakStatus NGFieldsetLayoutAlgorithm::LayoutLegend(
// the size of the legend instead of the border.
intrinsic_block_size_ = legend_margin_box_block_size;
+ is_legend_past_border_ = true;
+
// Don't adjust the block-start offset of the fragment border if it broke.
if (BreakToken() || (ConstraintSpace().HasKnownFragmentainerBlockSize() &&
legend_margin_box_block_size >
@@ -345,11 +353,12 @@ NGBreakStatus NGFieldsetLayoutAlgorithm::LayoutFieldsetContent(
NGBreakStatus break_status = NGBreakStatus::kContinue;
if (ConstraintSpace().HasBlockFragmentation()) {
+ bool has_container_separation = is_legend_past_border_;
// TODO(almaher): The legend should be treated as out-of-flow.
break_status = BreakBeforeChildIfNeeded(
ConstraintSpace(), fieldset_content, *result.get(),
ConstraintSpace().FragmentainerOffsetAtBfc() + intrinsic_block_size_,
- /*has_container_separation*/ has_legend, &container_builder_);
+ has_container_separation, &container_builder_);
EBreakBetween break_after = JoinFragmentainerBreakValues(
result->FinalBreakAfter(), fieldset_content.Style().BreakAfter());
container_builder_.SetPreviousBreakAfter(break_after);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.h
index a6a6d9996a0..57fc9dfefa7 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.h
@@ -52,7 +52,6 @@ class CORE_EXPORT NGFieldsetLayoutAlgorithm
const WritingMode writing_mode_;
- const NGBoxStrut border_padding_;
NGBoxStrut borders_;
NGBoxStrut padding_;
@@ -76,6 +75,13 @@ class CORE_EXPORT NGFieldsetLayoutAlgorithm
// If true, this indicates that the legend broke during the current layout
// pass.
bool legend_broke_ = false;
+
+ // If true, the legend is taller than the block-start border, so that it
+ // sticks below it, allowing for a class C breakpoint [1] before any fieldset
+ // content.
+ //
+ // [1] https://www.w3.org/TR/css-break-3/#possible-breaks
+ bool is_legend_past_border_ = false;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc
index 8f88b0d0ee2..1ced64ad3c0 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc
@@ -45,7 +45,8 @@ class NGFieldsetLayoutAlgorithmTest
NGFieldsetLayoutAlgorithm algorithm({node, fragment_geometry, space});
MinMaxSizesInput input(
- /* percentage_resolution_block_size */ (LayoutUnit()));
+ /* percentage_resolution_block_size */ LayoutUnit(),
+ MinMaxSizesType::kContent);
return algorithm.ComputeMinMaxSizes(input).sizes;
}
@@ -1905,6 +1906,60 @@ TEST_F(NGFieldsetLayoutAlgorithmTest, SmallerLegendLargeBorderFragmentation) {
}
// Tests that a fieldset with a large border and a small legend fragment
+// correctly. In this case, since the legend doesn't stick below the block-start
+// border, there's no class C breakpoint before the fieldset contents.
+// Therefore, prefer breaking before the fieldset to breaking before the child
+// DIV.
+TEST_F(NGFieldsetLayoutAlgorithmTest, SmallerLegendLargeBorderFragmentation2) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset { margin:0; border:30px solid; padding:0px; width:100px; }
+ #legend { padding:0; width:10px; height:5px; }
+ </style>
+ <div id="container" style="width:300px;">
+ <div style="width:33px; height:70px;"></div>
+ <fieldset id="fieldset">
+ <legend id="legend"></legend>
+ <div style="width:44px; height:30px; break-inside:avoid;"></div>
+ </fieldset>
+ </div>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(100);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("container")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:300x100
+ offset:0,0 size:33x70
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ EXPECT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:300x90
+ offset:0,0 size:160x90
+ offset:30,12.5 size:10x5
+ offset:30,30 size:100x30
+ offset:0,0 size:44x30
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+// Tests that a fieldset with a large border and a small legend fragment
// correctly. In this case, the legend block offset is not adjusted because the
// legend breaks after attempting to adjust the offset.
TEST_F(NGFieldsetLayoutAlgorithmTest, SmallerLegendLargeBorderWithBreak) {
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_floats_utils.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_floats_utils.cc
index f772d4d8bbe..46cced99c7d 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_floats_utils.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_floats_utils.cc
@@ -196,9 +196,9 @@ NGPositionedFloat PositionFloat(NGUnpositionedFloat* unpositioned_float,
NGExclusionSpace* exclusion_space) {
DCHECK(unpositioned_float);
const NGConstraintSpace& parent_space = unpositioned_float->parent_space;
+ NGBlockNode node = unpositioned_float->node;
bool is_same_writing_mode =
- unpositioned_float->node.Style().GetWritingMode() ==
- parent_space.GetWritingMode();
+ node.Style().GetWritingMode() == parent_space.GetWritingMode();
bool is_fragmentable =
is_same_writing_mode && parent_space.HasBlockFragmentation();
@@ -206,6 +206,7 @@ NGPositionedFloat PositionFloat(NGUnpositionedFloat* unpositioned_float,
scoped_refptr<const NGLayoutResult> layout_result;
NGBoxStrut fragment_margins;
NGLayoutOpportunity opportunity;
+ bool need_break_before = false;
if (!is_fragmentable) {
// We may be able to re-use the fragment from when we calculated the
@@ -223,8 +224,7 @@ NGPositionedFloat PositionFloat(NGUnpositionedFloat* unpositioned_float,
float_fragment.InlineSize());
} else {
fragment_margins = ComputeMarginsFor(
- unpositioned_float->node.Style(),
- unpositioned_float->percentage_size.inline_size,
+ node.Style(), unpositioned_float->percentage_size.inline_size,
parent_space.GetWritingMode(), parent_space.Direction());
AdjustForFragmentation(unpositioned_float->token.get(), &fragment_margins);
@@ -250,8 +250,7 @@ NGPositionedFloat PositionFloat(NGUnpositionedFloat* unpositioned_float,
NGConstraintSpace space = CreateConstraintSpaceForFloat(
*unpositioned_float, fragmentainer_delta);
- layout_result = unpositioned_float->node.Layout(
- space, unpositioned_float->token.get());
+ layout_result = node.Layout(space, unpositioned_float->token.get());
// If we knew the right block-offset up front, we're done.
if (!optimistically_placed)
@@ -282,9 +281,42 @@ NGPositionedFloat PositionFloat(NGUnpositionedFloat* unpositioned_float,
break;
} while (true);
- if (const NGBreakToken* break_token =
- layout_result->PhysicalFragment().BreakToken())
- fragment_margins.block_end = LayoutUnit();
+ LayoutUnit fragmentainer_margin_edge_block_offset =
+ parent_space.FragmentainerOffsetAtBfc() +
+ opportunity.rect.start_offset.block_offset;
+
+ // Note that we don't check if we're at a valid class A, B or C breakpoint
+ // (we only check that we're not at the start of the fragmentainer (in which
+ // case breaking typically wouldn't eliminate the unappealing break inside
+ // the float)). While no other browsers do this either, we should consider
+ // doing this in the future. But for now, don't let the float affect the
+ // appeal of breaking inside this container.
+ //
+ // If we're past the fragmentainer start, we can consider breaking before
+ // this float. Otherwise we cannot, or there'd be no content
+ // progression. The common fragmentation machinery assumes that margins can
+ // collapse with fragmentainer boundaries, but this isn't the case for
+ // floats. We don't allow float margins to collapse with anything, nor be
+ // split into multiple fragmentainers. Hence this additional check. Note
+ // that we might want to reconsider this behavior, since browsers disagree
+ // (what we do now is relatively similar to legacy Blink, though). Should we
+ // split a margin in cases where it helps prevent fragmentainer overflow?
+ // Should we always split them if they occur at fragmentainer boundaries? Or
+ // even allow them to collapse with the fragmentainer boundary? Exact
+ // behavior is currently unspecified.
+ if (fragmentainer_margin_edge_block_offset > LayoutUnit()) {
+ LayoutUnit fragmentainer_block_offset =
+ fragmentainer_margin_edge_block_offset + fragment_margins.block_start;
+ if (!MovePastBreakpoint(parent_space, node, *layout_result,
+ fragmentainer_block_offset, kBreakAppealPerfect,
+ /* builder */ nullptr)) {
+ need_break_before = true;
+ } else if (layout_result->PhysicalFragment().BreakToken()) {
+ // We need to resume in the next fragmentainer, which means that
+ // there'll be no block-end margin here.
+ fragment_margins.block_end = LayoutUnit();
+ }
+ }
}
NGFragment float_fragment(parent_space.GetWritingMode(),
@@ -300,13 +332,25 @@ NGPositionedFloat PositionFloat(NGUnpositionedFloat* unpositioned_float,
}
// Add the float as an exclusion.
- scoped_refptr<const NGExclusion> exclusion =
- CreateExclusion(float_fragment, float_margin_bfc_offset, fragment_margins,
- *unpositioned_float,
- unpositioned_float->IsLineRight(parent_space.Direction())
- ? EFloat::kRight
- : EFloat::kLeft);
- exclusion_space->Add(std::move(exclusion));
+ if (need_break_before) {
+ // Create a special exclusion past everything. This will prevent us from
+ // adding any more floats in this formatting context to the current
+ // fragmentainer, and also make clearance behave correctly (e.g. an in-flow
+ // block with clear:left after a float:left that got pushed to the next
+ // fragmentainer means that the in-flow block also needs to be pushed, while
+ // if the in-flow block has clear:right, it may still be allowed in the
+ // current fragmentainer).
+ NGBfcOffset past_everything(LayoutUnit(), LayoutUnit::Max());
+ scoped_refptr<const NGExclusion> exclusion =
+ NGExclusion::Create(NGBfcRect(past_everything, past_everything),
+ node.Style().Floating(parent_space.Direction()));
+ exclusion_space->Add(std::move(exclusion));
+ } else {
+ scoped_refptr<const NGExclusion> exclusion = CreateExclusion(
+ float_fragment, float_margin_bfc_offset, fragment_margins,
+ *unpositioned_float, node.Style().Floating(parent_space.Direction()));
+ exclusion_space->Add(std::move(exclusion));
+ }
// Adjust the float's bfc_offset to its border-box (instead of margin-box).
NGBfcOffset float_bfc_offset(
@@ -314,7 +358,8 @@ NGPositionedFloat PositionFloat(NGUnpositionedFloat* unpositioned_float,
fragment_margins.LineLeft(parent_space.Direction()),
float_margin_bfc_offset.block_offset + fragment_margins.block_start);
- return NGPositionedFloat(std::move(layout_result), float_bfc_offset);
+ return NGPositionedFloat(std::move(layout_result), float_bfc_offset,
+ need_break_before);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h
index a1ceb920f02..221149e728d 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h
@@ -11,8 +11,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_style_variant.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
-#include "third_party/blink/renderer/platform/text/text_direction.h"
-#include "third_party/blink/renderer/platform/text/writing_mode.h"
+#include "third_party/blink/renderer/platform/text/writing_direction_mode.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
@@ -37,8 +36,13 @@ class CORE_EXPORT NGFragmentBuilder {
style_variant_ = style_variant;
}
- WritingMode GetWritingMode() const { return writing_mode_; }
- TextDirection Direction() const { return direction_; }
+ WritingDirectionMode GetWritingDirection() const {
+ return writing_direction_;
+ }
+ WritingMode GetWritingMode() const {
+ return writing_direction_.GetWritingMode();
+ }
+ TextDirection Direction() const { return writing_direction_.Direction(); }
LayoutUnit InlineSize() const { return size_.inline_size; }
LayoutUnit BlockSize() const { return size_.block_size; }
@@ -51,30 +55,26 @@ class CORE_EXPORT NGFragmentBuilder {
protected:
NGFragmentBuilder(scoped_refptr<const ComputedStyle> style,
- WritingMode writing_mode,
- TextDirection direction)
+ WritingDirectionMode writing_direction)
: style_(std::move(style)),
- writing_mode_(writing_mode),
- direction_(direction),
+ writing_direction_(writing_direction),
style_variant_(NGStyleVariant::kStandard) {
DCHECK(style_);
}
- NGFragmentBuilder(WritingMode writing_mode, TextDirection direction)
- : writing_mode_(writing_mode), direction_(direction) {}
+ explicit NGFragmentBuilder(WritingDirectionMode writing_direction)
+ : writing_direction_(writing_direction) {}
NGFragmentBuilder(const NGPhysicalFragment& fragment)
: style_(&fragment.Style()),
- writing_mode_(style_->GetWritingMode()),
- direction_(style_->Direction()),
+ writing_direction_(style_->GetWritingDirection()),
style_variant_(fragment.StyleVariant()),
- size_(fragment.Size().ConvertToLogical(writing_mode_)),
+ size_(fragment.Size().ConvertToLogical(GetWritingMode())),
layout_object_(fragment.GetMutableLayoutObject()),
is_hidden_for_paint_(fragment.IsHiddenForPaint()) {}
protected:
scoped_refptr<const ComputedStyle> style_;
- WritingMode writing_mode_;
- TextDirection direction_;
+ WritingDirectionMode writing_direction_;
NGStyleVariant style_variant_;
LogicalSize size_;
LayoutObject* layout_object_ = nullptr;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.cc
index 6275cba58ee..c3d6fe3245f 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.cc
@@ -97,7 +97,7 @@ void NGFragmentChildIterator::UpdateSelfFromFragment(
current_.link_.fragment->GetLayoutObject());
current_.break_token_for_fragmentainer_only_ = false;
} else if (is_fragmentation_context_root_ && previous_fragment) {
- if (previous_fragment->IsColumnBox()) {
+ if (previous_fragment->IsFragmentainerBox()) {
// The outgoing break token from one fragmentainer is the incoming break
// token to the next one. This is also true when there are column spanners
// between two columns (fragmentainers); the outgoing break token from the
@@ -112,8 +112,10 @@ void NGFragmentChildIterator::UpdateSelfFromFragment(
// rendered legend. We'll leave |current_block_break_token_| alone here,
// as it will be used as in incoming break token when we get to the next
// column.
+ // TODO(almaher): Remove check for out of flow.
DCHECK(
previous_fragment->IsRenderedLegend() ||
+ previous_fragment->IsOutOfFlowPositioned() ||
NGBlockNode(ToLayoutBox(previous_fragment->GetMutableLayoutObject()))
.IsColumnSpanAll());
@@ -129,28 +131,7 @@ void NGFragmentChildIterator::UpdateSelfFromFragment(
bool NGFragmentChildIterator::AdvanceWithCursor() {
DCHECK(current_.cursor_);
- const NGFragmentItem* item = current_.cursor_->CurrentItem();
- if (item->HasChildren()) {
- // If we're advancing past a non-atomic inline, we also need to advance past
- // any break tokens for fragments in there.
- for (wtf_size_t remaining = item->DescendantsCount(); remaining;
- remaining--) {
- if (item->IsFloating()) {
- SkipToBlockBreakToken();
- if (child_break_token_idx_ < child_break_tokens_.size()) {
- DCHECK_EQ(child_break_tokens_[child_break_token_idx_]
- ->InputNode()
- .GetLayoutBox(),
- item->GetLayoutObject());
- child_break_token_idx_++;
- }
- }
- current_.cursor_->MoveToNext();
- item = current_.cursor_->CurrentItem();
- }
- } else {
- current_.cursor_->MoveToNext();
- }
+ current_.cursor_->MoveToNextSkippingChildren();
UpdateSelfFromCursor();
if (current_.cursor_->CurrentItem())
return true;
@@ -175,25 +156,6 @@ void NGFragmentChildIterator::UpdateSelfFromCursor() {
return;
}
current_.link_ = {item->BoxFragment(), item->OffsetInContainerBlock()};
- if (!current_.link_.fragment || !current_.link_.fragment->IsFloating()) {
- DCHECK(!current_.link_.fragment ||
- current_.link_.fragment->GetLayoutObject()->IsInline());
- return;
- }
- if (!parent_break_token_)
- return;
- // Floats may fragment, in which case there's a designated break token for
- // them.
- SkipToBlockBreakToken();
- if (child_break_token_idx_ >= child_break_tokens_.size()) {
- current_.block_break_token_ = nullptr;
- return;
- }
- current_.block_break_token_ =
- To<NGBlockBreakToken>(child_break_tokens_[child_break_token_idx_]);
- DCHECK(!current_.link_.fragment->GetLayoutObject() ||
- current_.block_break_token_->InputNode().GetLayoutBox() ==
- current_.link_.fragment->GetLayoutObject());
}
void NGFragmentChildIterator::SkipToBoxFragment() {
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h
index c4927f0acad..5f295d91867 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h
@@ -89,7 +89,7 @@ class CORE_EXPORT NGFragmentChildIterator {
// be used by a subsequent fragmentainer. Other fragment types (such as
// column spanners) need to ignore it.
if (break_token_for_fragmentainer_only_ &&
- !link_.fragment->IsColumnBox())
+ !link_.fragment->IsFragmentainerBox())
return nullptr;
}
return block_break_token_;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_test.cc
index a0ddc40690f..db9a91cc8b3 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_test.cc
@@ -140,7 +140,7 @@ TEST_F(NGFragmentationTest, MultipleFragmentsNestedMulticol) {
SetBodyInnerHTML(R"HTML(
<div id="container">
<div id="outer_multicol" style="columns:3; column-fill:auto; height:100px; width:620px; column-gap:10px;">
- <div id="inner_multicol" style="columns:2;">
+ <div id="inner_multicol" style="columns:2; column-fill:auto;">
<div id="child1" style="width:11px; height:350px;"></div>
<div id="child2" style="width:22px; height:350px;"></div>
</div>
@@ -193,5 +193,54 @@ TEST_F(NGFragmentationTest, MultipleFragmentsNestedMulticol) {
EXPECT_EQ(child2->GetPhysicalFragment(3)->Size(), PhysicalSize(22, 100));
}
+TEST_F(NGFragmentationTest, HasSeenAllChildrenIfc) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="container">
+ <div style="columns:3; column-fill:auto; height:50px; line-height:20px; orphans:1; widows:1;">
+ <div id="ifc" style="height:300px;">
+ <br><br>
+ <br><br>
+ <br><br>
+ <br>
+ </div>
+ </div>
+ </div>
+ )HTML");
+
+ RunBlockLayoutAlgorithm(GetElementById("container"));
+
+ const LayoutBox* ifc = ToLayoutBox(GetLayoutObjectByElementId("ifc"));
+ ASSERT_EQ(ifc->PhysicalFragmentCount(), 6u);
+ const NGPhysicalBoxFragment* fragment = ifc->GetPhysicalFragment(0);
+ const NGBlockBreakToken* break_token =
+ DynamicTo<NGBlockBreakToken>(fragment->BreakToken());
+ ASSERT_TRUE(break_token);
+ EXPECT_FALSE(break_token->HasSeenAllChildren());
+
+ fragment = ifc->GetPhysicalFragment(1);
+ break_token = DynamicTo<NGBlockBreakToken>(fragment->BreakToken());
+ ASSERT_TRUE(break_token);
+ EXPECT_FALSE(break_token->HasSeenAllChildren());
+
+ fragment = ifc->GetPhysicalFragment(2);
+ break_token = DynamicTo<NGBlockBreakToken>(fragment->BreakToken());
+ ASSERT_TRUE(break_token);
+ EXPECT_FALSE(break_token->HasSeenAllChildren());
+
+ fragment = ifc->GetPhysicalFragment(3);
+ break_token = DynamicTo<NGBlockBreakToken>(fragment->BreakToken());
+ ASSERT_TRUE(break_token);
+ EXPECT_TRUE(break_token->HasSeenAllChildren());
+
+ fragment = ifc->GetPhysicalFragment(4);
+ break_token = DynamicTo<NGBlockBreakToken>(fragment->BreakToken());
+ ASSERT_TRUE(break_token);
+ EXPECT_TRUE(break_token->HasSeenAllChildren());
+
+ fragment = ifc->GetPhysicalFragment(5);
+ break_token = DynamicTo<NGBlockBreakToken>(fragment->BreakToken());
+ EXPECT_FALSE(break_token);
+}
+
} // anonymous namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
index abc1aa6fc79..92343c933f1 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
@@ -209,30 +210,101 @@ void SetupFragmentBuilderForFragmentation(
builder->SetSequenceNumber(sequence_number);
}
-void FinishFragmentation(const NGConstraintSpace& space,
+bool IsNodeFullyGrown(NGBlockNode node,
+ const NGConstraintSpace& space,
+ LayoutUnit current_total_block_size,
+ const NGBoxStrut& border_padding,
+ LayoutUnit inline_size) {
+ // Pass an "infinite" intrinsic size to see how the block-size is
+ // constrained. If it doesn't affect the block size, it means that the node
+ // cannot grow any further.
+ LayoutUnit max_block_size = ComputeBlockSizeForFragment(
+ space, node.Style(), border_padding, LayoutUnit::Max(), inline_size);
+ DCHECK_GE(max_block_size, current_total_block_size);
+ return max_block_size == current_total_block_size;
+}
+
+void FinishFragmentation(NGBlockNode node,
+ const NGConstraintSpace& space,
const NGBlockBreakToken* previous_break_token,
- LayoutUnit block_size,
- LayoutUnit intrinsic_block_size,
+ const NGBoxStrut& border_padding,
LayoutUnit space_left,
NGBoxFragmentBuilder* builder) {
LayoutUnit previously_consumed_block_size;
if (previous_break_token && !previous_break_token->IsBreakBefore())
previously_consumed_block_size = previous_break_token->ConsumedBlockSize();
- if (builder->DidBreak()) {
- // One of our children broke. Even if we fit within the remaining space, we
- // need to prepare a break token.
- builder->SetConsumedBlockSize(std::min(space_left, block_size) +
- previously_consumed_block_size);
- builder->SetBlockSize(std::min(space_left, block_size));
- builder->SetIntrinsicBlockSize(space_left);
+ LayoutUnit fragments_total_block_size = builder->FragmentsTotalBlockSize();
+ LayoutUnit wanted_block_size =
+ fragments_total_block_size - previously_consumed_block_size;
+ DCHECK_GE(wanted_block_size, LayoutUnit());
+
+ LayoutUnit final_block_size = wanted_block_size;
+ if (space_left != kIndefiniteSize)
+ final_block_size = std::min(final_block_size, space_left);
+ builder->SetConsumedBlockSize(previously_consumed_block_size +
+ final_block_size);
+ builder->SetFragmentBlockSize(final_block_size);
+
+ if (space_left == kIndefiniteSize) {
+ // We don't know how space is available (initial column balancing pass), so
+ // we won't break.
+ builder->SetIsAtBlockEnd();
return;
}
- if (block_size > space_left) {
- // Need a break inside this block.
- builder->SetConsumedBlockSize(space_left + previously_consumed_block_size);
- builder->SetDidBreak();
+ if (builder->HasChildBreakInside()) {
+ // We broke before or inside one of our children. Even if we fit within the
+ // remaining space, and even if the child involved in the break were to be
+ // in a parallel flow, we still need to prepare a break token for this node,
+ // so that we can resume layout of its broken or unstarted children in the
+ // next fragmentainer.
+ //
+ // If we're at the end of the node, we need to mark the outgoing break token
+ // as such. This is a way for the parent algorithm to determine whether we
+ // need to insert a break there, or whether we may continue with any sibling
+ // content. If we are allowed to continue, while there's still child content
+ // left to be laid out, said content ends up in a parallel flow.
+ // https://www.w3.org/TR/css-break-3/#parallel-flows
+ //
+ // TODO(mstensho): The spec actually says that we enter a parallel flow once
+ // we're past the block-end *content edge*, but here we're checking against
+ // the *border edge* instead. Does it matter?
+ if (previous_break_token && previous_break_token->IsAtBlockEnd()) {
+ builder->SetIsAtBlockEnd();
+ // We entered layout already at the end of the block (but with overflowing
+ // children). So we should take up no more space on our own.
+ DCHECK_EQ(wanted_block_size, LayoutUnit());
+ } else if (wanted_block_size <= space_left) {
+ // We have room for the calculated block-size in the current
+ // fragmentainer, but we need to figure out whether this node is going to
+ // produce more non-zero block-size fragments or not.
+ //
+ // If the block-size is constrained / fixed (in which case
+ // IsNodeFullyGrown() will return true now), we know that we're at the
+ // end. If block-size is unconstrained (or at least allowed to grow a bit
+ // more), we're only at the end if no in-flow content inside broke.
+ if (!builder->HasInflowChildBreakInside() ||
+ IsNodeFullyGrown(node, space, fragments_total_block_size,
+ border_padding,
+ builder->InitialBorderBoxSize().inline_size))
+ builder->SetIsAtBlockEnd();
+
+ // If we're going to break just because of floats or out-of-flow child
+ // breaks, no break appeal will have been recorded so far, since we only
+ // update the appeal at same-flow breakpoints, and since we start off by
+ // assuming the lowest appeal, upgrade it now. There's nothing here that
+ // makes breaking inside less appealing than perfect.
+ if (!builder->HasInflowChildBreakInside())
+ builder->SetBreakAppeal(kBreakAppealPerfect);
+ }
+ return;
+ }
+
+ if (wanted_block_size > space_left) {
+ // No child inside broke, but we need a break inside this block anyway, due
+ // to its size.
+ builder->SetDidBreakSelf();
NGBreakAppeal break_appeal = kBreakAppealPerfect;
if (!previously_consumed_block_size) {
// This is the first fragment generated for the node. Avoid breaking
@@ -246,18 +318,14 @@ void FinishFragmentation(const NGConstraintSpace& space,
break_appeal = kBreakAppealLastResort;
}
builder->SetBreakAppeal(break_appeal);
- builder->SetBlockSize(space_left);
- builder->SetIntrinsicBlockSize(space_left);
if (space.BlockFragmentationType() == kFragmentColumn &&
!space.IsInitialColumnBalancingPass())
- builder->PropagateSpaceShortage(block_size - space_left);
+ builder->PropagateSpaceShortage(wanted_block_size - space_left);
return;
}
// The end of the block fits in the current fragmentainer.
- builder->SetConsumedBlockSize(previously_consumed_block_size + block_size);
- builder->SetBlockSize(block_size);
- builder->SetIntrinsicBlockSize(intrinsic_block_size);
+ builder->SetIsAtBlockEnd();
}
NGBreakStatus BreakBeforeChildIfNeeded(const NGConstraintSpace& space,
@@ -386,7 +454,7 @@ bool MovePastBreakpoint(const NGConstraintSpace& space,
NGFragment fragment(space.GetWritingMode(), physical_fragment);
if (!space.HasKnownFragmentainerBlockSize()) {
- if (space.IsInitialColumnBalancingPass()) {
+ if (space.IsInitialColumnBalancingPass() && builder) {
if (child.IsMonolithic() ||
(child.IsBlock() &&
IsAvoidBreakValue(space, child.Style().BreakInside()))) {
@@ -408,13 +476,13 @@ bool MovePastBreakpoint(const NGConstraintSpace& space,
// If we haven't used any space at all in the fragmentainer yet, we cannot
// break before this child, or there'd be no progress. We'd risk creating an
// infinite number of fragmentainers without putting any content into them.
- bool refuse_break = space_left >= space.FragmentainerBlockSize();
+ bool refuse_break_before = space_left >= space.FragmentainerBlockSize();
// If the child starts past the end of the fragmentainer (probably due to a
// block-start margin), we must break before it.
bool must_break_before = space_left < LayoutUnit();
if (must_break_before) {
- DCHECK(!refuse_break);
+ DCHECK(!refuse_break_before);
return false;
}
@@ -426,15 +494,20 @@ bool MovePastBreakpoint(const NGConstraintSpace& space,
// Allow breaking inside if it has the same appeal or higher than breaking
// before or breaking earlier. Also, if breaking before is impossible, break
// inside regardless of appeal.
- if (refuse_break || (appeal_inside >= appeal_before &&
- (!builder->HasEarlyBreak() ||
- appeal_inside >= builder->BreakAppeal()))) {
- builder->SetBreakAppeal(appeal_inside);
+ bool want_break_inside = refuse_break_before;
+ if (!want_break_inside && appeal_inside >= appeal_before) {
+ if (!builder || !builder->HasEarlyBreak() ||
+ appeal_inside >= builder->BreakAppeal())
+ want_break_inside = true;
+ }
+ if (want_break_inside) {
+ if (builder)
+ builder->SetBreakAppeal(appeal_inside);
return true;
}
} else {
bool need_break;
- if (refuse_break) {
+ if (refuse_break_before) {
need_break = false;
} else if (child.IsMonolithic()) {
// If the monolithic piece of content (e.g. a line, or block-level
@@ -451,7 +524,7 @@ bool MovePastBreakpoint(const NGConstraintSpace& space,
}
if (!need_break) {
- if (child.IsBlock()) {
+ if (child.IsBlock() && builder) {
// If this doesn't happen, though, we're tentatively not going to break
// before or inside this child, but we'll check the appeal of breaking
// there anyway. It may be the best breakpoint we'll ever find. (Note
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h
index b12b66333ff..23c52f2d447 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h
@@ -70,8 +70,11 @@ NGBreakAppeal CalculateBreakAppealInside(const NGConstraintSpace& space,
// start of the current block formatting context. Note that if the start of the
// current block formatting context is in a previous fragmentainer, the size of
// the current fragmentainer is returned instead.
+// In the case of initial column balancing, the size is unknown, in which case
+// kIndefiniteSize is returned.
inline LayoutUnit FragmentainerSpaceAtBfcStart(const NGConstraintSpace& space) {
- DCHECK(space.HasKnownFragmentainerBlockSize());
+ if (!space.HasKnownFragmentainerBlockSize())
+ return kIndefiniteSize;
return space.FragmentainerBlockSize() - space.FragmentainerOffsetAtBfc();
}
@@ -111,11 +114,27 @@ inline void SetupFragmentBuilderForFragmentation(const NGConstraintSpace&,
const NGInlineBreakToken*,
NGLineBoxFragmentBuilder*) {}
-// Write fragmentation information to the fragment builder after layout.
-void FinishFragmentation(const NGConstraintSpace&,
+// Return true if the node is fully grown at its current size.
+// |current_total_block_size| is the total block-size of the node, as if all
+// fragments were stitched together.
+bool IsNodeFullyGrown(NGBlockNode,
+ const NGConstraintSpace&,
+ LayoutUnit current_total_block_size,
+ const NGBoxStrut& border_padding,
+ LayoutUnit inline_size);
+
+// Update and write fragmentation information to the fragment builder after
+// layout. This will update the block-size stored in the builder. When
+// calculating the block-size, a layout algorithm will include the accumulated
+// block-size of all fragments generated for this node - as if they were all
+// stitched together as one tall fragment. This is the most convenient thing to
+// do, since any block-size specified in CSS applies to the entire box,
+// regardless of fragmentation. This function will update the block-size to the
+// actual fragment size, by examining possible breakpoints, if necessary.
+void FinishFragmentation(NGBlockNode node,
+ const NGConstraintSpace&,
const NGBlockBreakToken* previous_break_token,
- LayoutUnit block_size,
- LayoutUnit intrinsic_block_size,
+ const NGBoxStrut& border_padding,
LayoutUnit space_left,
NGBoxFragmentBuilder*);
@@ -225,6 +244,19 @@ bool AttemptSoftBreak(const NGConstraintSpace&,
NGBreakAppeal appeal_before,
NGBoxFragmentBuilder*);
+// Return the adjusted child margin to be applied at the end of a fragment.
+// Margins should collapse with the fragmentainer boundary. |bfc_block_offset|
+// is the BFC offset where the margin should be applied (i.e. after the
+// block-end border edge of the last child fragment).
+inline LayoutUnit AdjustedMarginAfterFinalChildFragment(
+ const NGConstraintSpace& space,
+ LayoutUnit bfc_block_offset,
+ LayoutUnit block_end_margin) {
+ LayoutUnit space_left =
+ FragmentainerSpaceAtBfcStart(space) - bfc_block_offset;
+ return std::min(block_end_margin, space_left.ClampNegativeToZero());
+}
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_FRAGMENTATION_UTILS_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_grid_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_grid_layout_algorithm.cc
deleted file mode 100644
index ee14539bc1c..00000000000
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_grid_layout_algorithm.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/layout/ng/ng_grid_layout_algorithm.h"
-
-namespace blink {
-
-NGGridLayoutAlgorithm::NGGridLayoutAlgorithm(
- const NGLayoutAlgorithmParams& params)
- : NGLayoutAlgorithm(params) {
- DCHECK(params.space.IsNewFormattingContext());
- DCHECK(!params.break_token);
- container_builder_.SetIsNewFormattingContext(true);
- container_builder_.SetInitialFragmentGeometry(params.fragment_geometry);
-}
-
-scoped_refptr<const NGLayoutResult> NGGridLayoutAlgorithm::Layout() {
- return container_builder_.ToBoxFragment();
-}
-
-MinMaxSizesResult NGGridLayoutAlgorithm::ComputeMinMaxSizes(
- const MinMaxSizesInput& input) const {
- return {MinMaxSizes(), /* depends_on_percentage_block_size */ true};
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc
index e5ed5b152e8..a3b4b610629 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_ink_overflow.h"
#include "third_party/blink/renderer/core/layout/geometry/logical_rect.h"
+#include "third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h"
#include "third_party/blink/renderer/core/layout/line/line_orientation_utils.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
@@ -58,7 +59,8 @@ void NGInkOverflow::ComputeTextInkOverflow(
}
PhysicalRect local_ink_overflow =
- LogicalRect(ink_overflow).ConvertToPhysical(writing_mode, size);
+ WritingModeConverter({writing_mode, TextDirection::kLtr}, size)
+ .ToPhysical(LogicalRect(ink_overflow));
// Uniting the frame rect ensures that non-ink spaces such side bearings, or
// even space characters, are included in the visual rect for decorations.
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h
index 90c7bd7b3f0..2eaf870c75f 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h
@@ -77,8 +77,7 @@ class CORE_EXPORT NGLayoutAlgorithm : public NGLayoutAlgorithmOperations {
container_builder_(node,
style,
&space,
- space.GetWritingMode(),
- direction) {
+ {space.GetWritingMode(), direction}) {
if (UNLIKELY(space.HasBlockFragmentation())) {
DCHECK(space.IsAnonymous() || !node.IsMonolithic());
SetupFragmentBuilderForFragmentation(space, BreakToken(),
@@ -113,6 +112,16 @@ class CORE_EXPORT NGLayoutAlgorithm : public NGLayoutAlgorithmOperations {
const NGBreakTokenType* BreakToken() const { return break_token_.get(); }
+ const NGBoxStrut& BorderPadding() const {
+ return container_builder_.BorderPadding();
+ }
+ const NGBoxStrut& BorderScrollbarPadding() const {
+ return container_builder_.BorderScrollbarPadding();
+ }
+ const LogicalSize& ChildAvailableSize() const {
+ return container_builder_.ChildAvailableSize();
+ }
+
NGInputNodeType node_;
// The break token from which we are currently resuming layout.
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
index fe3212c1b9c..380dc1b5c3a 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
@@ -63,7 +63,7 @@ void AppendNodeToString(NGLayoutInputNode node,
MinMaxSizesResult NGLayoutInputNode::ComputeMinMaxSizes(
WritingMode writing_mode,
const MinMaxSizesInput& input,
- const NGConstraintSpace* space) {
+ const NGConstraintSpace* space) const {
if (auto* inline_node = DynamicTo<NGInlineNode>(this))
return inline_node->ComputeMinMaxSizes(writing_mode, input, space);
return To<NGBlockNode>(*this).ComputeMinMaxSizes(writing_mode, input, space);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
index 59c09f148d1..26ce67d1fc4 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
@@ -27,6 +27,11 @@ class NGPaintFragment;
struct MinMaxSizes;
struct PhysicalSize;
+// min/max-content take the CSS aspect-ratio property into account.
+// In some cases that's undesirable; this enum lets you choose not
+// to do that using |kIntrinsic|.
+enum class MinMaxSizesType { kContent, kIntrinsic };
+
// The input to the min/max inline size calculation algorithm for child nodes.
// Child nodes within the same formatting context need to know which floats are
// beside them.
@@ -41,11 +46,15 @@ struct MinMaxSizesInput {
//
// As we don't perform any tree walking, we need to pass the percentage
// resolution block-size for min/max down the min/max size calculation.
- explicit MinMaxSizesInput(LayoutUnit percentage_resolution_block_size)
- : percentage_resolution_block_size(percentage_resolution_block_size) {}
+ MinMaxSizesInput(LayoutUnit percentage_resolution_block_size,
+ MinMaxSizesType type)
+ : percentage_resolution_block_size(percentage_resolution_block_size),
+ type(type) {}
LayoutUnit float_left_inline_size;
LayoutUnit float_right_inline_size;
LayoutUnit percentage_resolution_block_size;
+
+ MinMaxSizesType type;
};
// The output of the min/max inline size calculation algorithm. Contains the
@@ -92,6 +101,9 @@ class CORE_EXPORT NGLayoutInputNode {
bool IsOutOfFlowPositioned() const {
return IsBlock() && box_->IsOutOfFlowPositioned();
}
+ bool IsFloatingOrOutOfFlowPositioned() const {
+ return IsFloating() || IsOutOfFlowPositioned();
+ }
bool IsReplaced() const { return box_->IsLayoutReplaced(); }
bool IsAbsoluteContainer() const {
return box_->CanContainAbsolutePositionObjects();
@@ -120,7 +132,7 @@ class CORE_EXPORT NGLayoutInputNode {
return IsBlock() && box_->IsLayoutNGFieldset();
}
bool IsRubyRun() const { return IsBlock() && box_->IsRubyRun(); }
- bool IsRubyText() const { return IsBlock() && box_->IsRubyText(); }
+ bool IsRubyText() const { return box_->IsRubyText(); }
// Return true if this is the legend child of a fieldset that gets special
// treatment (i.e. placed over the block-start border).
@@ -129,6 +141,8 @@ class CORE_EXPORT NGLayoutInputNode {
}
bool IsTable() const { return IsBlock() && box_->IsTable(); }
+ bool IsTableCaption() const { return IsBlock() && box_->IsTableCaption(); }
+
bool IsMathRoot() const { return box_->IsMathMLRoot(); }
bool IsAnonymousBlock() const { return box_->IsAnonymousBlock(); }
@@ -166,9 +180,10 @@ class CORE_EXPORT NGLayoutInputNode {
}
// Returns the border-box min/max content sizes for the node.
- MinMaxSizesResult ComputeMinMaxSizes(WritingMode,
- const MinMaxSizesInput&,
- const NGConstraintSpace* = nullptr);
+ MinMaxSizesResult ComputeMinMaxSizes(
+ WritingMode,
+ const MinMaxSizesInput&,
+ const NGConstraintSpace* = nullptr) const;
// Returns intrinsic sizing information for replaced elements.
// ComputeReplacedSize can use it to compute actual replaced size.
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc
index 6f3e2393746..337bfb89d45 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc
@@ -49,24 +49,6 @@ NGLayoutResult::NGLayoutResult(
bitfields_.subtree_modified_margin_strut =
builder->subtree_modified_margin_strut_;
intrinsic_block_size_ = builder->intrinsic_block_size_;
- // We don't support fragment caching when block-fragmenting, so mark the
- // result as non-reusable.
- if (builder->has_block_fragmentation_)
- EnsureRareData()->is_single_use = true;
- if (builder->minimal_space_shortage_ != LayoutUnit::Max()) {
-#if DCHECK_IS_ON()
- DCHECK(!HasRareData() || !rare_data_->has_tallest_unbreakable_block_size);
-#endif
- EnsureRareData()->minimal_space_shortage = builder->minimal_space_shortage_;
- }
- if (builder->tallest_unbreakable_block_size_ >= LayoutUnit()) {
- auto* rare_data = EnsureRareData();
- rare_data->tallest_unbreakable_block_size =
- builder->tallest_unbreakable_block_size_;
-#if DCHECK_IS_ON()
- rare_data->has_tallest_unbreakable_block_size = true;
-#endif
- }
if (builder->overflow_block_size_ != kIndefiniteSize &&
builder->overflow_block_size_ != intrinsic_block_size_) {
EnsureRareData()->overflow_block_size = builder->overflow_block_size_;
@@ -75,15 +57,45 @@ NGLayoutResult::NGLayoutResult(
EnsureRareData()->custom_layout_data =
std::move(builder->custom_layout_data_);
}
- if (builder->column_spanner_)
- EnsureRareData()->column_spanner = builder->column_spanner_;
if (builder->lines_until_clamp_)
EnsureRareData()->lines_until_clamp = *builder->lines_until_clamp_;
- bitfields_.initial_break_before =
- static_cast<unsigned>(builder->initial_break_before_);
- bitfields_.final_break_after =
- static_cast<unsigned>(builder->previous_break_after_);
- bitfields_.has_forced_break = builder->has_forced_break_;
+ if (builder->annotation_overflow_)
+ EnsureRareData()->annotation_overflow = builder->annotation_overflow_;
+ if (builder->block_end_annotation_space_) {
+ EnsureRareData()->block_end_annotation_space =
+ builder->block_end_annotation_space_;
+ }
+
+ if (builder->has_block_fragmentation_) {
+ RareData* rare_data = EnsureRareData();
+
+ // We don't support fragment caching when block-fragmenting, so mark the
+ // result as non-reusable.
+ rare_data->is_single_use = true;
+
+ if (builder->tallest_unbreakable_block_size_ >= LayoutUnit()) {
+ rare_data->tallest_unbreakable_block_size =
+ builder->tallest_unbreakable_block_size_;
+#if DCHECK_IS_ON()
+ rare_data->has_tallest_unbreakable_block_size = true;
+#endif
+ }
+ if (builder->minimal_space_shortage_ != LayoutUnit::Max()) {
+#if DCHECK_IS_ON()
+ DCHECK(!rare_data->has_tallest_unbreakable_block_size);
+#endif
+ rare_data->minimal_space_shortage = builder->minimal_space_shortage_;
+ }
+
+ if (builder->column_spanner_)
+ rare_data->column_spanner = builder->column_spanner_;
+
+ bitfields_.initial_break_before =
+ static_cast<unsigned>(builder->initial_break_before_);
+ bitfields_.final_break_after =
+ static_cast<unsigned>(builder->previous_break_after_);
+ bitfields_.has_forced_break = builder->has_forced_break_;
+ }
}
NGLayoutResult::NGLayoutResult(
@@ -174,6 +186,12 @@ NGLayoutResult::NGLayoutResult(
if (builder->end_margin_strut_ != NGMarginStrut())
EnsureRareData()->end_margin_strut = builder->end_margin_strut_;
+ if (builder->annotation_overflow_ > LayoutUnit())
+ EnsureRareData()->annotation_overflow = builder->annotation_overflow_;
+ if (builder->block_end_annotation_space_) {
+ EnsureRareData()->block_end_annotation_space =
+ builder->block_end_annotation_space_;
+ }
if (builder->unpositioned_list_marker_) {
EnsureRareData()->unpositioned_list_marker =
builder->unpositioned_list_marker_;
@@ -294,4 +312,12 @@ void NGLayoutResult::CheckSameForSimplifiedLayout(
}
#endif
+#if DCHECK_IS_ON()
+void NGLayoutResult::AssertSoleBoxFragment() const {
+ DCHECK(physical_fragment_->IsBox());
+ DCHECK(To<NGPhysicalBoxFragment>(PhysicalFragment()).IsFirstForNode());
+ DCHECK(!physical_fragment_->BreakToken());
+}
+#endif
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result.h
index 5d15b09f808..4674ca56060 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result.h
@@ -68,6 +68,24 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
return HasRareData() ? rare_data_->lines_until_clamp : 0;
}
+ // How much an annotation box overflow from this box.
+ // This is for LayoutNGRubyRun and line boxes.
+ // 0 : No overflow
+ // -N : Overflowing by N px at block-start side
+ // This happens only for LayoutRubyRun.
+ // N : Overflowing by N px at block-end side
+ LayoutUnit AnnotationOverflow() const {
+ return HasRareData() ? rare_data_->annotation_overflow : LayoutUnit();
+ }
+
+ // The amount of available space for block-start side annotations of the
+ // next box.
+ // This never be negative.
+ LayoutUnit BlockEndAnnotationSpace() const {
+ return HasRareData() ? rare_data_->block_end_annotation_space
+ : LayoutUnit();
+ }
+
LogicalOffset OutOfFlowPositionedOffset() const {
DCHECK(bitfields_.has_oof_positioned_offset);
return HasRareData() ? rare_data_->oof_positioned_offset
@@ -145,8 +163,18 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
return HasRareData() ? rare_data_->end_margin_strut : NGMarginStrut();
}
+ // Get the intrinsic block-size of the fragment (i.e. the block-size the
+ // fragment would get if no block-size constraints were applied). This is not
+ // supported (and should not be needed [1]) if the node got split into
+ // multiple fragments.
+ //
+ // [1] If a node gets block-fragmented, it means that it has possibly been
+ // constrained and/or stretched by something extrinsic (i.e. the
+ // fragmentainer), so the value returned here wouldn't be useful.
const LayoutUnit IntrinsicBlockSize() const {
- DCHECK(physical_fragment_->IsBox());
+#if DCHECK_IS_ON()
+ AssertSoleBoxFragment();
+#endif
return intrinsic_block_size_;
}
@@ -373,6 +401,8 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
NGExclusionSpace exclusion_space;
scoped_refptr<SerializedScriptValue> custom_layout_data;
LayoutUnit overflow_block_size = kIndefiniteSize;
+ LayoutUnit annotation_overflow;
+ LayoutUnit block_end_annotation_space;
#if DCHECK_IS_ON()
bool has_tallest_unbreakable_block_size = false;
#endif
@@ -383,6 +413,10 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
bool HasRareData() const { return bitfields_.has_rare_data; }
RareData* EnsureRareData();
+#if DCHECK_IS_ON()
+ void AssertSoleBoxFragment() const;
+#endif
+
struct Bitfields {
DISALLOW_NEW();
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_utils.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_utils.cc
index db86d7af448..1a629ac1261 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_utils.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_utils.cc
@@ -212,14 +212,17 @@ NGLayoutCacheStatus CalculateSizeBasedLayoutCacheStatusWithGeometry(
if (old_space.IsFixedBlockSize())
return NGLayoutCacheStatus::kNeedsLayout;
- // The intrinsic size of column flex-boxes can depend on the
- // %-resolution-block-size. This occurs when a flex-box has "max-height:
- // 100%" or similar on itself.
+ // The intrinsic size of flex-boxes can depend on the %-block-size. This
+ // occurs when:
+ // - A column flex-box has "max-height: 100%" (or similar) on itself.
+ // - A row flex-box has "height: 100%" (or similar) and children which
+ // stretch to this size.
//
// Due to this we can't use cached |NGLayoutResult::IntrinsicBlockSize|
// value, as the following |block_size| calculation would be incorrect.
- if (style.ResolvedIsColumnFlexDirection() &&
- layout_result.PhysicalFragment().DependsOnPercentageBlockSize()) {
+ // TODO(dgrogan): We can hit the cache here for row flexboxes when they
+ // don't have stretchy children.
+ if (layout_result.PhysicalFragment().DependsOnPercentageBlockSize()) {
if (new_space.PercentageResolutionBlockSize() !=
old_space.PercentageResolutionBlockSize())
return NGLayoutCacheStatus::kNeedsLayout;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
index 25629c7019c..261ed63c908 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
@@ -72,7 +72,7 @@ bool BlockLengthUnresolvable(
LengthResolvePhase phase,
const LayoutUnit* opt_percentage_resolution_block_size_for_min_max) {
if (length.IsAuto() || length.IsMinContent() || length.IsMaxContent() ||
- length.IsFitContent() || length.IsNone())
+ length.IsMinIntrinsic() || length.IsFitContent() || length.IsNone())
return true;
if (length.IsPercentOrCalc()) {
if (phase == LengthResolvePhase::kIntrinsic)
@@ -127,11 +127,12 @@ LayoutUnit ResolveInlineLengthInternal(
}
case Length::kMinContent:
case Length::kMaxContent:
+ case Length::kMinIntrinsic:
case Length::kFitContent: {
DCHECK(min_max_sizes.has_value());
LayoutUnit available_size = constraint_space.AvailableSize().inline_size;
LayoutUnit value;
- if (length.IsMinContent()) {
+ if (length.IsMinContent() || length.IsMinIntrinsic()) {
value = min_max_sizes->min_size;
} else if (length.IsMaxContent() || available_size == LayoutUnit::Max()) {
// If the available space is infinite, fit-content resolves to
@@ -200,6 +201,7 @@ LayoutUnit ResolveBlockLengthInternal(
case Length::kAuto:
case Length::kMinContent:
case Length::kMaxContent:
+ case Length::kMinIntrinsic:
case Length::kFitContent:
#if DCHECK_IS_ON()
// Due to how content_size is calculated, it should always include border
@@ -270,7 +272,7 @@ MinMaxSizesResult ComputeMinAndMaxContentContributionInternal(
: style.Height();
if (inline_size.IsAuto() || inline_size.IsPercentOrCalc() ||
inline_size.IsFillAvailable() || inline_size.IsFitContent()) {
- result = min_max_sizes_func();
+ result = min_max_sizes_func(MinMaxSizesType::kContent);
} else {
if (IsParallelWritingMode(parent_writing_mode, child_writing_mode)) {
MinMaxSizes sizes;
@@ -279,7 +281,10 @@ MinMaxSizesResult ComputeMinAndMaxContentContributionInternal(
result = {sizes, /* depends_on_percentage_block_size */ false};
} else {
auto IntrinsicBlockSizeFunc = [&]() -> LayoutUnit {
- return min_max_sizes_func().sizes.max_size;
+ return min_max_sizes_func(inline_size.IsMinIntrinsic()
+ ? MinMaxSizesType::kIntrinsic
+ : MinMaxSizesType::kContent)
+ .sizes.max_size;
};
MinMaxSizes sizes;
sizes = ResolveMainBlockLength(space, style, border_padding, inline_size,
@@ -326,7 +331,7 @@ MinMaxSizes ComputeMinAndMaxContentContributionForTest(
WritingMode parent_writing_mode,
const ComputedStyle& style,
const MinMaxSizes& min_max_sizes) {
- auto MinMaxSizesFunc = [&]() -> MinMaxSizesResult {
+ auto MinMaxSizesFunc = [&](MinMaxSizesType) -> MinMaxSizesResult {
return {min_max_sizes, false};
};
return ComputeMinAndMaxContentContributionInternal(parent_writing_mode, style,
@@ -374,17 +379,19 @@ MinMaxSizesResult ComputeMinAndMaxContentContribution(
}
}
- auto MinMaxSizesFunc = [&]() -> MinMaxSizesResult {
+ auto MinMaxSizesFunc = [&](MinMaxSizesType type) -> MinMaxSizesResult {
+ MinMaxSizesInput input_copy(input);
+ input_copy.type = type;
// We need to set up a constraint space with correct fallback available
// inline-size in case of orthogonal children.
NGConstraintSpace indefinite_constraint_space;
const NGConstraintSpace* child_constraint_space = nullptr;
if (!IsParallelWritingMode(parent_writing_mode, child_writing_mode)) {
- indefinite_constraint_space =
- CreateIndefiniteConstraintSpaceForChild(parent_style, child);
+ indefinite_constraint_space = CreateIndefiniteConstraintSpaceForChild(
+ parent_style, input_copy, child);
child_constraint_space = &indefinite_constraint_space;
}
- return child.ComputeMinMaxSizes(parent_writing_mode, input,
+ return child.ComputeMinMaxSizes(parent_writing_mode, input_copy,
child_constraint_space);
};
@@ -418,13 +425,12 @@ LayoutUnit ComputeInlineSizeForFragment(
const ComputedStyle& style = node.Style();
Length logical_width = style.LogicalWidth();
- auto MinMaxSizesFunc = [&]() -> MinMaxSizesResult {
+ auto MinMaxSizesFunc = [&](MinMaxSizesType type) -> MinMaxSizesResult {
if (override_min_max_sizes_for_test)
return {*override_min_max_sizes_for_test, false};
- return node.ComputeMinMaxSizes(
- space.GetWritingMode(),
- MinMaxSizesInput(space.PercentageResolutionBlockSize()), &space);
+ MinMaxSizesInput input(space.PercentageResolutionBlockSize(), type);
+ return node.ComputeMinMaxSizes(space.GetWritingMode(), input, &space);
};
Length min_length = style.LogicalMinWidth();
@@ -439,8 +445,9 @@ LayoutUnit ComputeInlineSizeForFragment(
// if we need to apply the implied minimum size:
// https://drafts.csswg.org/css-sizing-4/#aspect-ratio-minimum
if (style.OverflowInlineDirection() == EOverflow::kVisible &&
- min_length.IsAuto())
- min_length = Length::MinContent();
+ min_length.IsAuto()) {
+ min_length = Length::MinIntrinsic();
+ }
} else {
if (logical_width.IsAuto() && space.IsShrinkToFit())
logical_width = Length::FitContent();
@@ -498,8 +505,7 @@ LayoutUnit ComputeBlockSizeForFragmentInternal(
LengthResolvePhase::kLayout,
opt_percentage_resolution_block_size_for_min_max);
if (UNLIKELY((extent == kIndefiniteSize || logical_height.IsAuto()) &&
- style.LogicalAspectRatio() && inline_size &&
- !style.LogicalWidth().IsAuto())) {
+ style.LogicalAspectRatio() && inline_size)) {
extent =
BlockSizeFromAspectRatio(border_padding, *style.LogicalAspectRatio(),
style.BoxSizing(), *inline_size);
@@ -782,9 +788,9 @@ LayoutUnit ResolveUsedColumnInlineSize(LayoutUnit available_size,
LayoutUnit ResolveUsedColumnGap(LayoutUnit available_size,
const ComputedStyle& style) {
- if (style.ColumnGap().IsNormal())
- return LayoutUnit(style.GetFontDescription().ComputedPixelSize());
- return ValueForLength(style.ColumnGap().GetLength(), available_size);
+ if (const base::Optional<Length>& column_gap = style.ColumnGap())
+ return ValueForLength(*column_gap, available_size);
+ return LayoutUnit(style.GetFontDescription().ComputedPixelSize());
}
NGPhysicalBoxStrut ComputePhysicalMargins(
@@ -916,10 +922,9 @@ NGBoxStrut ComputePadding(const NGConstraintSpace& constraint_space,
return padding;
}
-NGBoxStrut ComputeScrollbars(const NGConstraintSpace& constraint_space,
- const NGLayoutInputNode node) {
+NGBoxStrut ComputeScrollbarsForNonAnonymous(const NGBlockNode& node) {
const ComputedStyle& style = node.Style();
- if (constraint_space.IsAnonymous() || style.IsOverflowVisible())
+ if (style.IsOverflowVisible())
return NGBoxStrut();
NGPhysicalBoxStrut sizes;
const LayoutBox* layout_box = node.GetLayoutBox();
@@ -1103,19 +1108,33 @@ NGFragmentGeometry CalculateInitialMinMaxFragmentGeometry(
return {/* border_box_size */ LogicalSize(), border, scrollbar, padding};
}
-LogicalSize ShrinkAvailableSize(LogicalSize size, const NGBoxStrut& inset) {
- DCHECK_NE(size.inline_size, kIndefiniteSize);
- size.inline_size -= inset.InlineSum();
- size.inline_size = std::max(size.inline_size, LayoutUnit());
-
+LogicalSize ShrinkLogicalSize(LogicalSize size, const NGBoxStrut& insets) {
+ if (size.inline_size != kIndefiniteSize) {
+ size.inline_size =
+ (size.inline_size - insets.InlineSum()).ClampNegativeToZero();
+ }
if (size.block_size != kIndefiniteSize) {
- size.block_size -= inset.BlockSum();
- size.block_size = std::max(size.block_size, LayoutUnit());
+ size.block_size =
+ (size.block_size - insets.BlockSum()).ClampNegativeToZero();
}
return size;
}
+LogicalSize CalculateChildAvailableSize(
+ const NGConstraintSpace& space,
+ const NGBlockNode& node,
+ const LogicalSize border_box_size,
+ const NGBoxStrut& border_scrollbar_padding) {
+ LogicalSize child_available_size =
+ ShrinkLogicalSize(border_box_size, border_scrollbar_padding);
+
+ if (space.IsAnonymous() || node.IsAnonymousBlock())
+ child_available_size.block_size = space.AvailableSize().block_size;
+
+ return child_available_size;
+}
+
namespace {
// Implements the common part of the child percentage size calculation. Deals
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
index ef8e775331d..d2a15b80bfd 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
@@ -91,8 +91,12 @@ inline LayoutUnit ResolveMinInlineLength(
return border_padding.InlineSum();
base::Optional<MinMaxSizes> min_max_sizes;
- if (length.IsIntrinsic())
- min_max_sizes = min_max_sizes_func().sizes;
+ if (length.IsIntrinsic()) {
+ min_max_sizes =
+ min_max_sizes_func(length.IsMinIntrinsic() ? MinMaxSizesType::kIntrinsic
+ : MinMaxSizesType::kContent)
+ .sizes;
+ }
return ResolveInlineLengthInternal(constraint_space, style, border_padding,
min_max_sizes, length);
@@ -126,8 +130,12 @@ inline LayoutUnit ResolveMaxInlineLength(
return LayoutUnit::Max();
base::Optional<MinMaxSizes> min_max_sizes;
- if (length.IsIntrinsic())
- min_max_sizes = min_max_sizes_func().sizes;
+ if (length.IsIntrinsic()) {
+ min_max_sizes =
+ min_max_sizes_func(length.IsMinIntrinsic() ? MinMaxSizesType::kIntrinsic
+ : MinMaxSizesType::kContent)
+ .sizes;
+ }
return ResolveInlineLengthInternal(constraint_space, style, border_padding,
min_max_sizes, length);
@@ -157,8 +165,12 @@ inline LayoutUnit ResolveMainInlineLength(
const MinMaxSizesFunc& min_max_sizes_func,
const Length& length) {
base::Optional<MinMaxSizes> min_max_sizes;
- if (length.IsIntrinsic())
- min_max_sizes = min_max_sizes_func().sizes;
+ if (length.IsIntrinsic()) {
+ min_max_sizes =
+ min_max_sizes_func(length.IsMinIntrinsic() ? MinMaxSizesType::kIntrinsic
+ : MinMaxSizesType::kContent)
+ .sizes;
+ }
return ResolveInlineLengthInternal(constraint_space, style, border_padding,
min_max_sizes, length);
@@ -451,8 +463,15 @@ inline NGLineBoxStrut ComputeLinePadding(
style.IsFlippedLinesWritingMode());
}
-CORE_EXPORT NGBoxStrut ComputeScrollbars(const NGConstraintSpace&,
- const NGLayoutInputNode);
+CORE_EXPORT NGBoxStrut ComputeScrollbarsForNonAnonymous(const NGBlockNode&);
+
+inline NGBoxStrut ComputeScrollbars(const NGConstraintSpace& space,
+ const NGBlockNode& node) {
+ if (space.IsAnonymous())
+ return NGBoxStrut();
+
+ return ComputeScrollbarsForNonAnonymous(node);
+}
// Return true if we need to know the inline size of the fragment in order to
// calculate its line-left offset. This is the case when we have auto margins,
@@ -500,10 +519,15 @@ CORE_EXPORT NGFragmentGeometry
CalculateInitialMinMaxFragmentGeometry(const NGConstraintSpace&,
const NGBlockNode&);
-// Shrink and return the available size by an inset. This may e.g. be used to
-// convert from border-box to content-box size. Indefinite block size is
-// allowed, in which case the inset will be ignored for block size.
-LogicalSize ShrinkAvailableSize(LogicalSize size, const NGBoxStrut& inset);
+// Shrinks the logical |size| by |insets|.
+LogicalSize ShrinkLogicalSize(LogicalSize size, const NGBoxStrut& insets);
+
+// Calculates the available size that children of the node should use.
+LogicalSize CalculateChildAvailableSize(
+ const NGConstraintSpace&,
+ const NGBlockNode& node,
+ const LogicalSize border_box_size,
+ const NGBoxStrut& border_scrollbar_padding);
// Calculates the percentage resolution size that children of the node should
// use.
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 4020a8fd3b7..74a8fcb12ec 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
@@ -19,6 +19,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
#include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
#include "third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
@@ -113,7 +114,7 @@ NGOutOfFlowLayoutPart::NGOutOfFlowLayoutPart(
default_containing_block_.direction = container_style.Direction();
default_containing_block_.content_size_for_absolute =
- ShrinkAvailableSize(container_builder_->Size(), border_scrollbar);
+ ShrinkLogicalSize(container_builder_->Size(), border_scrollbar);
default_containing_block_.content_size_for_fixed =
initial_containing_block_fixed_size
? *initial_containing_block_fixed_size
@@ -124,6 +125,15 @@ NGOutOfFlowLayoutPart::NGOutOfFlowLayoutPart(
}
void NGOutOfFlowLayoutPart::Run(const LayoutBox* only_layout) {
+ if (container_builder_->IsBlockFragmentationContextRoot()) {
+ Vector<NGLogicalOutOfFlowPositionedNode> fragmentainer_descendants;
+ container_builder_->SwapOutOfFlowFragmentainerDescendants(
+ &fragmentainer_descendants);
+
+ if (!fragmentainer_descendants.IsEmpty())
+ LayoutFragmentainerDescendants(&fragmentainer_descendants);
+ }
+
Vector<NGLogicalOutOfFlowPositionedNode> candidates;
const LayoutObject* current_container = container_builder_->GetLayoutObject();
// If the container is display-locked, then we skip the layout of descendants,
@@ -267,14 +277,53 @@ bool NGOutOfFlowLayoutPart::SweepLegacyCandidates(
return true;
}
+// Retrieve the stored ContainingBlockInfo needed for placing positioned nodes.
+// When fragmenting, the ContainingBlockInfo is not stored ahead of time and
+// must be generated on demand. The reason being that during fragmentation, we
+// wait to place positioned nodes until they've reached the fragmentation
+// context root. In such cases, we cannot use |default_containing_block_| since
+// the fragmentation root is not the containing block of the positioned nodes.
+// Rather, we must generate their ContainingBlockInfo based on the provided
+// |containing_block_fragment|.
const NGOutOfFlowLayoutPart::ContainingBlockInfo&
NGOutOfFlowLayoutPart::GetContainingBlockInfo(
- const NGLogicalOutOfFlowPositionedNode& candidate) const {
+ const NGLogicalOutOfFlowPositionedNode& candidate,
+ const NGPhysicalContainerFragment* containing_block_fragment) {
if (candidate.inline_container) {
const auto it = containing_blocks_map_.find(candidate.inline_container);
DCHECK(it != containing_blocks_map_.end());
return it->value;
}
+ if (containing_block_fragment) {
+ DCHECK(container_builder_->IsBlockFragmentationContextRoot());
+
+ const LayoutObject* containing_block =
+ containing_block_fragment->GetLayoutObject();
+ DCHECK(containing_block);
+ auto it = containing_blocks_map_.find(containing_block);
+ if (it != containing_blocks_map_.end())
+ return it->value;
+
+ const ComputedStyle& style = containing_block->StyleRef();
+ LogicalSize size = containing_block_fragment->Size().ConvertToLogical(
+ style.GetWritingMode());
+ const NGPhysicalBoxFragment* fragment =
+ To<NGPhysicalBoxFragment>(containing_block_fragment);
+
+ // TODO(1079031): This should eventually include scrollbar and border.
+ NGBoxStrut border = fragment->Borders().ConvertToLogical(
+ style.GetWritingMode(), style.Direction());
+ LogicalSize content_size = ShrinkLogicalSize(size, border);
+ LogicalOffset container_offset =
+ LogicalOffset(border.inline_start, border.block_start);
+
+ ContainingBlockInfo containing_block_info{style.Direction(), content_size,
+ content_size, container_offset};
+
+ return containing_blocks_map_
+ .insert(containing_block, containing_block_info)
+ .stored_value->value;
+ }
return default_containing_block_;
}
@@ -433,6 +482,10 @@ void NGOutOfFlowLayoutPart::LayoutCandidates(
candidate.static_position);
if (IsContainingBlockForCandidate(candidate) &&
(!only_layout || layout_box == only_layout)) {
+ if (container_space_.HasBlockFragmentation()) {
+ container_builder_->AddOutOfFlowFragmentainerDescendant(candidate);
+ continue;
+ }
scoped_refptr<const NGLayoutResult> result =
LayoutCandidate(candidate, only_layout);
container_builder_->AddChild(result->PhysicalFragment(),
@@ -521,7 +574,8 @@ scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::LayoutCandidate(
do {
scoped_refptr<const NGLayoutResult> layout_result =
Layout(node, candidate_constraint_space, candidate_static_position,
- container_content_size, container_info, only_layout);
+ container_content_size, container_info,
+ default_containing_block_.direction, only_layout);
if (!freeze_scrollbars.has_value()) {
// Since out-of-flow positioning sets up a constraint space with fixed
@@ -545,14 +599,85 @@ scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::LayoutCandidate(
} while (true);
}
+void NGOutOfFlowLayoutPart::LayoutFragmentainerDescendants(
+ Vector<NGLogicalOutOfFlowPositionedNode>* descendants) {
+ while (descendants->size() > 0) {
+ for (auto& descendant : *descendants) {
+ scoped_refptr<const NGLayoutResult> result =
+ LayoutFragmentainerDescendant(descendant);
+
+ // TODO(almaher): Add children to the correct fragmentainer.
+ container_builder_->AddChild(result->PhysicalFragment(),
+ result->OutOfFlowPositionedOffset(),
+ descendant.inline_container);
+ }
+ // Sweep any descendants that might have been added.
+ // This happens when an absolute container has a fixed child.
+ descendants->Shrink(0);
+ container_builder_->SwapOutOfFlowFragmentainerDescendants(descendants);
+ }
+}
+
+scoped_refptr<const NGLayoutResult>
+NGOutOfFlowLayoutPart::LayoutFragmentainerDescendant(
+ const NGLogicalOutOfFlowPositionedNode& descendant) {
+ // TODO(almaher): Properly implement the layout algorithm for fragmented
+ // positioned elements.
+ NGBlockNode node = descendant.node;
+ const NGPhysicalContainerFragment* containing_block_fragment =
+ descendant.containing_block_fragment.get();
+
+ DCHECK(containing_block_fragment &&
+ containing_block_fragment->GetLayoutObject() ==
+ node.GetLayoutBox()->ContainingBlock());
+
+ const ContainingBlockInfo& container_info =
+ GetContainingBlockInfo(descendant, containing_block_fragment);
+ const TextDirection default_direction =
+ containing_block_fragment->Style().Direction();
+ const ComputedStyle& descendant_style = node.Style();
+ const WritingMode descendant_writing_mode = descendant_style.GetWritingMode();
+ const TextDirection descendant_direction = descendant_style.Direction();
+
+ LogicalSize container_content_size =
+ container_info.ContentSize(descendant_style.GetPosition());
+ PhysicalSize container_physical_content_size =
+ ToPhysicalSize(container_content_size, writing_mode_);
+
+ // Adjust the |static_position| (which is currently relative to the default
+ // container's border-box). ng_absolute_utils expects the static position to
+ // be relative to the container's padding-box.
+ NGLogicalStaticPosition static_position = descendant.static_position;
+ static_position.offset -= container_info.container_offset;
+
+ NGLogicalStaticPosition descendant_static_position =
+ static_position
+ .ConvertToPhysical(writing_mode_, default_direction,
+ container_physical_content_size)
+ .ConvertToLogical(descendant_writing_mode, descendant_direction,
+ container_physical_content_size);
+
+ // Need a constraint space to resolve offsets.
+ NGConstraintSpaceBuilder builder(writing_mode_, descendant_writing_mode,
+ /* is_new_fc */ true);
+ builder.SetTextDirection(descendant_direction);
+ builder.SetAvailableSize(container_content_size);
+ builder.SetPercentageResolutionSize(container_content_size);
+ NGConstraintSpace descendant_constraint_space = builder.ToConstraintSpace();
+
+ return Layout(node, descendant_constraint_space, descendant_static_position,
+ container_content_size, container_info, default_direction,
+ nullptr);
+}
+
scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::Layout(
NGBlockNode node,
const NGConstraintSpace& candidate_constraint_space,
const NGLogicalStaticPosition& candidate_static_position,
LogicalSize container_content_size,
const ContainingBlockInfo& container_info,
+ const TextDirection default_direction,
const LayoutBox* only_layout) {
- const TextDirection default_direction = default_containing_block_.direction;
const ComputedStyle& candidate_style = node.Style();
const WritingMode candidate_writing_mode = candidate_style.GetWritingMode();
const TextDirection candidate_direction = candidate_style.Direction();
@@ -588,7 +713,7 @@ scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::Layout(
if (AbsoluteNeedsChildInlineSize(candidate_style) ||
NeedMinMaxSize(candidate_style) || should_be_considered_as_replaced) {
- MinMaxSizesInput input(kIndefiniteSize);
+ MinMaxSizesInput input(kIndefiniteSize, MinMaxSizesType::kContent);
if (is_replaced) {
input.percentage_resolution_block_size =
container_content_size_in_candidate_writing_mode.block_size;
@@ -610,19 +735,19 @@ scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::Layout(
base::Optional<LogicalSize> replaced_size;
base::Optional<LogicalSize> replaced_aspect_ratio;
- bool is_replaced_with_only_aspect_ratio = false;
+ bool has_aspect_ratio_without_intrinsic_size = false;
if (is_replaced) {
ComputeReplacedSize(node, candidate_constraint_space, min_max_sizes,
&replaced_size, &replaced_aspect_ratio);
- is_replaced_with_only_aspect_ratio = !replaced_size &&
- replaced_aspect_ratio &&
- !replaced_aspect_ratio->IsEmpty();
+ has_aspect_ratio_without_intrinsic_size = !replaced_size &&
+ replaced_aspect_ratio &&
+ !replaced_aspect_ratio->IsEmpty();
// If we only have aspect ratio, and no replaced size, intrinsic size
// defaults to 300x150. min_max_sizes gets computed from the intrinsic size.
// We reset the min_max_sizes because spec says that OOF-positioned size
// should not be constrained by intrinsic size in this case.
// https://www.w3.org/TR/CSS22/visudet.html#inline-replaced-width
- if (is_replaced_with_only_aspect_ratio)
+ if (has_aspect_ratio_without_intrinsic_size)
min_max_sizes = MinMaxSizes{LayoutUnit(), LayoutUnit::NearlyMax()};
} else if (should_be_considered_as_replaced) {
replaced_size =
@@ -641,10 +766,10 @@ scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::Layout(
if (!is_replaced && should_be_considered_as_replaced)
replaced_size.reset();
- // Replaced elements with only aspect ratio compute their block size from
+ // Elements with only aspect ratio compute their block size from
// inline size and aspect ratio.
// https://www.w3.org/TR/css-sizing-3/#intrinsic-sizes
- if (is_replaced_with_only_aspect_ratio) {
+ if (has_aspect_ratio_without_intrinsic_size) {
replaced_size = LogicalSize(
node_dimensions.size.inline_size,
(replaced_aspect_ratio->block_size *
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
index 777309f62ef..92bbec5bb1f 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
@@ -23,6 +23,7 @@ class NGBlockNode;
class NGBoxFragmentBuilder;
class NGConstraintSpace;
class NGLayoutResult;
+class NGPhysicalContainerFragment;
struct NGLogicalOutOfFlowPositionedNode;
// Helper class for positioning of out-of-flow blocks.
@@ -96,7 +97,8 @@ class CORE_EXPORT NGOutOfFlowLayoutPart {
bool SweepLegacyCandidates(HashSet<const LayoutObject*>* placed_objects);
const ContainingBlockInfo& GetContainingBlockInfo(
- const NGLogicalOutOfFlowPositionedNode&) const;
+ const NGLogicalOutOfFlowPositionedNode&,
+ const NGPhysicalContainerFragment* = nullptr);
void ComputeInlineContainingBlocks(
const Vector<NGLogicalOutOfFlowPositionedNode>&);
@@ -109,11 +111,18 @@ class CORE_EXPORT NGOutOfFlowLayoutPart {
const NGLogicalOutOfFlowPositionedNode&,
const LayoutBox* only_layout);
+ void LayoutFragmentainerDescendants(
+ Vector<NGLogicalOutOfFlowPositionedNode>* descendants);
+
+ scoped_refptr<const NGLayoutResult> LayoutFragmentainerDescendant(
+ const NGLogicalOutOfFlowPositionedNode&);
+
scoped_refptr<const NGLayoutResult> Layout(NGBlockNode,
const NGConstraintSpace&,
const NGLogicalStaticPosition&,
LogicalSize container_content_size,
const ContainingBlockInfo&,
+ const TextDirection,
const LayoutBox* only_layout);
bool IsContainingBlockForCandidate(const NGLogicalOutOfFlowPositionedNode&);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc
index c950e7f86e4..f1ec239d16c 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc
@@ -5,14 +5,44 @@
#include "third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_test.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
namespace blink {
namespace {
-using NGOutOfFlowLayoutPartTest = NGLayoutTest;
+class NGOutOfFlowLayoutPartTest
+ : public NGBaseLayoutAlgorithmTest,
+ private ScopedLayoutNGBlockFragmentationForTest {
+ protected:
+ NGOutOfFlowLayoutPartTest() : ScopedLayoutNGBlockFragmentationForTest(true) {}
+
+ scoped_refptr<const NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
+ Element* element) {
+ NGBlockNode container(ToLayoutBox(element->GetLayoutObject()));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize));
+ return NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(container, space);
+ }
+
+ String DumpFragmentTree(Element* element) {
+ auto fragment = RunBlockLayoutAlgorithm(element);
+ return DumpFragmentTree(fragment.get());
+ }
+
+ String DumpFragmentTree(const blink::NGPhysicalBoxFragment* fragment) {
+ NGPhysicalFragment::DumpFlags flags =
+ NGPhysicalFragment::DumpHeaderText | NGPhysicalFragment::DumpSubtree |
+ NGPhysicalFragment::DumpIndentation | NGPhysicalFragment::DumpOffset |
+ NGPhysicalFragment::DumpSize;
+
+ return fragment->DumpFragmentTree(flags);
+ }
+};
// Fixed blocks inside absolute blocks trigger otherwise unused while loop
// inside NGOutOfFlowLayoutPart::Run.
@@ -73,5 +103,55 @@ TEST_F(NGOutOfFlowLayoutPartTest, FixedInsideAbs) {
EXPECT_EQ(fixed_2->OffsetTop(), LayoutUnit(9));
}
+// Tests that positioned nodes fragment correctly.
+// TODO(almaher): Reenable once the layout algorithm for fragmented positioned
+// items is in a more stable state.
+TEST_F(NGOutOfFlowLayoutPartTest, DISABLED_PositionedFragmentation) {
+ SetBodyInnerHTML(
+ R"HTML(
+ <style>
+ #multicol {
+ column-count: 2; height: 40px; column-fill:auto;
+ }
+ .rel {
+ position: relative;
+ }
+ .abs {
+ position: absolute;
+ }
+ </style>
+ <div id="container">
+ <div id="multicol">
+ <div style="width:100px; height:50px;"></div>
+ <div class="rel">
+ <div class="abs" style="width:5px; top: 10px; height:5px;">
+ </div>
+ <div class="rel">
+ <div class="abs" style="width:10px; top: 20px; height:10px;">
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ )HTML");
+ String dump = DumpFragmentTree(GetElementById("container"));
+
+ // TODO(almaher): Positioned nodes are not currently placed in the correct
+ // fragment.
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:1000x40
+ offset:0,0 size:1000x40
+ offset:0,0 size:499.5x40
+ offset:0,0 size:100x40
+ offset:500.5,0 size:499.5x40
+ offset:0,0 size:100x10
+ offset:0,10 size:499.5x0
+ offset:0,0 size:499.5x0
+ offset:0,20 size:10x10
+ offset:0,10 size:5x5
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
} // namespace
} // namespace blink
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 3f9a5127140..6b332b1b4ee 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
@@ -19,8 +19,15 @@ namespace blink {
// as a positioned-node reaches its containing block, it gets placed, and
// doesn't bubble further up the tree.
//
+// However, when fragmentation comes into play, we no longer place a
+// positioned-node as soon as it reaches its containing block. Instead, we
+// continue to bubble the positioned node up until it reaches the
+// fragmentation context root. There, it will get placed and properly
+// fragmented.
+//
// This needs its static position [1] to be placed correctly in its containing
-// block.
+// block. And in the case of fragmentation, this also needs the containing block
+// fragment to be placed correctly within the fragmentation context root.
//
// This is struct is allowed to be stored/persisted.
//
@@ -30,14 +37,18 @@ struct CORE_EXPORT NGPhysicalOutOfFlowPositionedNode {
NGPhysicalStaticPosition static_position;
// Continuation root of the optional inline container.
const LayoutInline* inline_container;
+ scoped_refptr<const NGPhysicalContainerFragment> containing_block_fragment;
NGPhysicalOutOfFlowPositionedNode(
NGBlockNode node,
NGPhysicalStaticPosition static_position,
- const LayoutInline* inline_container = nullptr)
+ const LayoutInline* inline_container = nullptr,
+ scoped_refptr<const NGPhysicalContainerFragment>
+ containing_block_fragment = nullptr)
: node(node),
static_position(static_position),
- inline_container(inline_container) {
+ inline_container(inline_container),
+ containing_block_fragment(std::move(containing_block_fragment)) {
DCHECK(!inline_container ||
inline_container == inline_container->ContinuationRoot());
}
@@ -55,16 +66,20 @@ struct NGLogicalOutOfFlowPositionedNode {
// Continuation root of the optional inline container.
const LayoutInline* inline_container;
bool needs_block_offset_adjustment;
+ scoped_refptr<const NGPhysicalContainerFragment> containing_block_fragment;
NGLogicalOutOfFlowPositionedNode(
NGBlockNode node,
NGLogicalStaticPosition static_position,
const LayoutInline* inline_container = nullptr,
- bool needs_block_offset_adjustment = false)
+ bool needs_block_offset_adjustment = false,
+ scoped_refptr<const NGPhysicalContainerFragment>
+ containing_block_fragment = nullptr)
: node(node),
static_position(static_position),
inline_container(inline_container),
- needs_block_offset_adjustment(needs_block_offset_adjustment) {
+ needs_block_offset_adjustment(needs_block_offset_adjustment),
+ containing_block_fragment(std::move(containing_block_fragment)) {
DCHECK(!inline_container ||
inline_container == inline_container->ContinuationRoot());
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.cc
index 27aa6125ce8..3752e5dc4f9 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.cc
@@ -17,28 +17,21 @@ namespace blink {
NGPageLayoutAlgorithm::NGPageLayoutAlgorithm(
const NGLayoutAlgorithmParams& params)
- : NGLayoutAlgorithm(params),
- border_padding_(params.fragment_geometry.border +
- params.fragment_geometry.padding),
- border_scrollbar_padding_(border_padding_ +
- params.fragment_geometry.scrollbar) {
+ : NGLayoutAlgorithm(params) {
container_builder_.SetIsNewFormattingContext(
params.space.IsNewFormattingContext());
container_builder_.SetInitialFragmentGeometry(params.fragment_geometry);
}
scoped_refptr<const NGLayoutResult> NGPageLayoutAlgorithm::Layout() {
- LogicalSize border_box_size = container_builder_.InitialBorderBoxSize();
- LogicalSize content_box_size =
- ShrinkAvailableSize(border_box_size, border_scrollbar_padding_);
- LogicalSize page_size = content_box_size;
+ LogicalSize page_size = ChildAvailableSize();
NGConstraintSpace child_space = CreateConstraintSpaceForPages(page_size);
WritingMode writing_mode = ConstraintSpace().GetWritingMode();
scoped_refptr<const NGBlockBreakToken> break_token = BreakToken();
LayoutUnit intrinsic_block_size;
- LogicalOffset page_offset(border_scrollbar_padding_.StartOffset());
+ LogicalOffset page_offset = BorderScrollbarPadding().StartOffset();
// TODO(mstensho): Handle auto block size.
LogicalOffset page_progression(LayoutUnit(), page_size.block_size);
@@ -64,11 +57,11 @@ scoped_refptr<const NGLayoutResult> NGPageLayoutAlgorithm::Layout() {
container_builder_.SetIntrinsicBlockSize(intrinsic_block_size);
- // Recompute the block-axis size now that we know our content size.
- border_box_size.block_size = ComputeBlockSizeForFragment(
- ConstraintSpace(), Style(), border_padding_, intrinsic_block_size,
- border_box_size.inline_size);
- container_builder_.SetBlockSize(border_box_size.block_size);
+ // Compute the block-axis size now that we know our content size.
+ LayoutUnit block_size = ComputeBlockSizeForFragment(
+ ConstraintSpace(), Style(), BorderPadding(), intrinsic_block_size,
+ container_builder_.InitialBorderBoxSize().inline_size);
+ container_builder_.SetFragmentsTotalBlockSize(block_size);
NGOutOfFlowLayoutPart(
Node(), ConstraintSpace(),
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.h
index 4b9ebf55713..d8613b602c2 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.h
@@ -30,9 +30,6 @@ class CORE_EXPORT NGPageLayoutAlgorithm
private:
NGConstraintSpace CreateConstraintSpaceForPages(
const LogicalSize& size) const;
-
- NGBoxStrut border_padding_;
- NGBoxStrut border_scrollbar_padding_;
};
} // namespace blink
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 fd78b87d9c6..bd3601db795 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
@@ -52,15 +52,20 @@ scoped_refptr<const NGPhysicalBoxFragment> NGPhysicalBoxFragment::Create(
const NGPhysicalBoxStrut padding =
builder->initial_fragment_geometry_->padding.ConvertToPhysical(
builder->GetWritingMode(), builder->Direction());
+ auto& mathml_paint_info = builder->mathml_paint_info_;
size_t byte_size = sizeof(NGPhysicalBoxFragment) +
sizeof(NGLink) * builder->children_.size() +
(borders.IsZero() ? 0 : sizeof(borders)) +
- (padding.IsZero() ? 0 : sizeof(padding));
+ (padding.IsZero() ? 0 : sizeof(padding)) +
+ (mathml_paint_info ? sizeof(NGMathMLPaintInfo*) : 0);
if (const NGFragmentItemsBuilder* items_builder = builder->ItemsBuilder()) {
// Omit |NGFragmentItems| if there were no items; e.g., display-lock.
if (items_builder->Size())
byte_size += NGFragmentItems::ByteSizeFor(items_builder->Size());
}
+ if (builder->HasOutOfFlowFragmentainerDescendants())
+ byte_size += sizeof(NGPhysicalOutOfFlowPositionedNode);
+
// We store the children list inline in the fragment as a flexible
// array. Therefore, we need to make sure to allocate enough space for
// that array here, which requires a manual allocation + placement new.
@@ -68,8 +73,9 @@ scoped_refptr<const NGPhysicalBoxFragment> NGPhysicalBoxFragment::Create(
// we pass the buffer as a constructor argument.
void* data = ::WTF::Partitions::FastMalloc(
byte_size, ::WTF::GetStringWithTypeName<NGPhysicalBoxFragment>());
- new (data) NGPhysicalBoxFragment(PassKey(), builder, borders, padding,
- block_or_line_writing_mode);
+ new (data)
+ NGPhysicalBoxFragment(PassKey(), builder, borders, padding,
+ mathml_paint_info, block_or_line_writing_mode);
return base::AdoptRef(static_cast<NGPhysicalBoxFragment*>(data));
}
@@ -78,6 +84,7 @@ NGPhysicalBoxFragment::NGPhysicalBoxFragment(
NGBoxFragmentBuilder* builder,
const NGPhysicalBoxStrut& borders,
const NGPhysicalBoxStrut& padding,
+ std::unique_ptr<NGMathMLPaintInfo>& mathml_paint_info,
WritingMode block_or_line_writing_mode)
: NGPhysicalContainerFragment(builder,
block_or_line_writing_mode,
@@ -94,8 +101,9 @@ NGPhysicalBoxFragment::NGPhysicalBoxFragment(
has_fragment_items_ = true;
NGFragmentItems* items =
const_cast<NGFragmentItems*>(ComputeItemsAddress());
- items_builder->ToFragmentItems(block_or_line_writing_mode,
- builder->Direction(), Size(), items);
+ DCHECK_EQ(items_builder->GetWritingMode(), block_or_line_writing_mode);
+ DCHECK_EQ(items_builder->Direction(), builder->Direction());
+ items_builder->ToFragmentItems(Size(), items);
}
}
@@ -105,6 +113,13 @@ NGPhysicalBoxFragment::NGPhysicalBoxFragment(
has_padding_ = !padding.IsZero();
if (has_padding_)
*const_cast<NGPhysicalBoxStrut*>(ComputePaddingAddress()) = padding;
+ ink_overflow_computed_or_mathml_paint_info_ = !!mathml_paint_info;
+ if (ink_overflow_computed_or_mathml_paint_info_) {
+ memset(ComputeMathMLPaintInfoAddress(), 0, sizeof(NGMathMLPaintInfo));
+ new (static_cast<void*>(ComputeMathMLPaintInfoAddress()))
+ NGMathMLPaintInfo(*mathml_paint_info);
+ }
+
is_first_for_node_ = builder->is_first_for_node_;
is_fieldset_container_ = builder->is_fieldset_container_;
is_legacy_layout_root_ = builder->is_legacy_layout_root_;
@@ -130,6 +145,28 @@ NGPhysicalBoxFragment::NGPhysicalBoxFragment(
last_baseline_ = LayoutUnit::Min();
}
+ PhysicalSize size = Size();
+ has_oof_positioned_fragmentainer_descendants_ = false;
+ if (!builder->oof_positioned_fragmentainer_descendants_.IsEmpty()) {
+ has_oof_positioned_fragmentainer_descendants_ = true;
+ Vector<NGPhysicalOutOfFlowPositionedNode>*
+ oof_positioned_fragmentainer_descendants =
+ const_cast<Vector<NGPhysicalOutOfFlowPositionedNode>*>(
+ ComputeOutOfFlowPositionedFragmentainerDescendantsAddress());
+ new (oof_positioned_fragmentainer_descendants)
+ Vector<NGPhysicalOutOfFlowPositionedNode>();
+ oof_positioned_fragmentainer_descendants->ReserveCapacity(
+ builder->oof_positioned_fragmentainer_descendants_.size());
+ for (const auto& descendant :
+ builder->oof_positioned_fragmentainer_descendants_) {
+ oof_positioned_fragmentainer_descendants->emplace_back(
+ descendant.node,
+ descendant.static_position.ConvertToPhysical(
+ builder->Style().GetWritingMode(), builder->Direction(), size),
+ descendant.inline_container, descendant.containing_block_fragment);
+ }
+ }
+
#if DCHECK_IS_ON()
CheckIntegrity();
#endif
@@ -139,7 +176,7 @@ scoped_refptr<const NGLayoutResult>
NGPhysicalBoxFragment::CloneAsHiddenForPaint() const {
const ComputedStyle& style = Style();
NGBoxFragmentBuilder builder(GetMutableLayoutObject(), &style,
- style.GetWritingMode(), style.Direction());
+ style.GetWritingDirection());
builder.SetBoxType(BoxType());
NGFragmentGeometry initial_fragment_geometry{
Size().ConvertToLogical(style.GetWritingMode())};
@@ -327,7 +364,7 @@ PhysicalRect NGPhysicalBoxFragment::ScrollableOverflowFromChildren() const {
}
// Traverse child fragments.
- const bool children_inline = IsInlineFormattingContext();
+ const bool add_inline_children = !items && IsInlineFormattingContext();
// Only add overflow for fragments NG has not reflected into Legacy.
// These fragments are:
// - inline fragments,
@@ -337,7 +374,7 @@ PhysicalRect NGPhysicalBoxFragment::ScrollableOverflowFromChildren() const {
for (const auto& child : Children()) {
if (child->IsFloatingOrOutOfFlowPositioned()) {
context.AddFloatingOrOutOfFlowPositionedChild(*child, child.Offset());
- } else if (children_inline && child->IsLineBox()) {
+ } else if (add_inline_children && child->IsLineBox()) {
context.AddLineBoxChild(To<NGPhysicalLineBoxFragment>(*child),
child.Offset());
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
index 8b034f8a7db..d3ecedd282b 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h"
+#include "third_party/blink/renderer/core/layout/ng/mathml/ng_mathml_paint_info.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h"
#include "third_party/blink/renderer/platform/graphics/scroll_types.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
@@ -29,6 +30,7 @@ class CORE_EXPORT NGPhysicalBoxFragment final
NGBoxFragmentBuilder* builder,
const NGPhysicalBoxStrut& borders,
const NGPhysicalBoxStrut& padding,
+ std::unique_ptr<NGMathMLPaintInfo>& mathml_paint_info,
WritingMode block_or_line_writing_mode);
scoped_refptr<const NGLayoutResult> CloneAsHiddenForPaint() const;
@@ -36,6 +38,8 @@ class CORE_EXPORT NGPhysicalBoxFragment final
~NGPhysicalBoxFragment() {
if (has_fragment_items_)
ComputeItemsAddress()->~NGFragmentItems();
+ if (ink_overflow_computed_or_mathml_paint_info_)
+ ComputeMathMLPaintInfoAddress()->~NGMathMLPaintInfo();
for (const NGLink& child : Children())
child.fragment->Release();
}
@@ -70,6 +74,20 @@ class CORE_EXPORT NGPhysicalBoxFragment final
return *ComputePaddingAddress();
}
+ bool HasOutOfFlowPositionedFragmentainerDescendants() const {
+ return has_oof_positioned_fragmentainer_descendants_;
+ }
+
+ base::span<NGPhysicalOutOfFlowPositionedNode>
+ OutOfFlowPositionedFragmentainerDescendants() const {
+ if (!HasOutOfFlowPositionedFragmentainerDescendants())
+ return base::span<NGPhysicalOutOfFlowPositionedNode>();
+ Vector<NGPhysicalOutOfFlowPositionedNode>* descendants =
+ const_cast<Vector<NGPhysicalOutOfFlowPositionedNode>*>(
+ ComputeOutOfFlowPositionedFragmentainerDescendantsAddress());
+ return {descendants->data(), descendants->size()};
+ }
+
NGPixelSnappedPhysicalBoxStrut PixelSnappedPadding() const {
if (!has_padding_)
return NGPixelSnappedPhysicalBoxStrut();
@@ -152,15 +170,23 @@ class CORE_EXPORT NGPhysicalBoxFragment final
bool check_same_block_size) const;
#endif
+ bool HasExtraMathMLPainting() const {
+ return IsMathMLFraction() || ink_overflow_computed_or_mathml_paint_info_;
+ }
+
private:
const NGFragmentItems* ComputeItemsAddress() const {
- DCHECK(has_fragment_items_ || has_borders_ || has_padding_);
+ DCHECK(has_fragment_items_ || has_borders_ || has_padding_ ||
+ ink_overflow_computed_or_mathml_paint_info_ ||
+ has_oof_positioned_fragmentainer_descendants_);
const NGLink* children_end = children_ + Children().size();
return reinterpret_cast<const NGFragmentItems*>(children_end);
}
const NGPhysicalBoxStrut* ComputeBordersAddress() const {
- DCHECK(has_borders_ || has_padding_);
+ DCHECK(has_borders_ || has_padding_ ||
+ ink_overflow_computed_or_mathml_paint_info_ ||
+ has_oof_positioned_fragmentainer_descendants_);
const NGFragmentItems* items = ComputeItemsAddress();
if (!has_fragment_items_)
return reinterpret_cast<const NGPhysicalBoxStrut*>(items);
@@ -169,11 +195,31 @@ class CORE_EXPORT NGPhysicalBoxFragment final
}
const NGPhysicalBoxStrut* ComputePaddingAddress() const {
- DCHECK(has_padding_);
+ DCHECK(has_padding_ || ink_overflow_computed_or_mathml_paint_info_ ||
+ has_oof_positioned_fragmentainer_descendants_);
const NGPhysicalBoxStrut* address = ComputeBordersAddress();
return has_borders_ ? address + 1 : address;
}
+ NGMathMLPaintInfo* ComputeMathMLPaintInfoAddress() const {
+ DCHECK(ink_overflow_computed_or_mathml_paint_info_ ||
+ has_oof_positioned_fragmentainer_descendants_);
+ NGPhysicalBoxStrut* address =
+ const_cast<NGPhysicalBoxStrut*>(ComputePaddingAddress());
+ return has_padding_ ? reinterpret_cast<NGMathMLPaintInfo*>(address + 1)
+ : reinterpret_cast<NGMathMLPaintInfo*>(address);
+ }
+
+ const Vector<NGPhysicalOutOfFlowPositionedNode>*
+ ComputeOutOfFlowPositionedFragmentainerDescendantsAddress() const {
+ DCHECK(has_oof_positioned_fragmentainer_descendants_);
+ NGMathMLPaintInfo* address = ComputeMathMLPaintInfoAddress();
+ address =
+ ink_overflow_computed_or_mathml_paint_info_ ? address + 1 : address;
+ return reinterpret_cast<const Vector<NGPhysicalOutOfFlowPositionedNode>*>(
+ address);
+ }
+
#if DCHECK_IS_ON()
void CheckIntegrity() const;
#endif
@@ -181,7 +227,8 @@ class CORE_EXPORT NGPhysicalBoxFragment final
LayoutUnit baseline_;
LayoutUnit last_baseline_;
NGLink children_[];
- // borders and padding come from after |children_| if they are not zero.
+ // borders, padding, and oof_positioned_fragmentainer_descendants come after
+ // |children_| if they are not zero.
};
template <>
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc
index 929f8b346b1..5ddbaceda94 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h"
+#include "third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
@@ -19,11 +20,11 @@ namespace blink {
namespace {
struct SameSizeAsNGPhysicalContainerFragment : NGPhysicalFragment {
+ wtf_size_t size;
void* break_token;
std::unique_ptr<Vector<NGPhysicalOutOfFlowPositionedNode>>
oof_positioned_descendants_;
void* pointer;
- wtf_size_t size;
};
static_assert(sizeof(NGPhysicalContainerFragment) ==
@@ -39,13 +40,13 @@ NGPhysicalContainerFragment::NGPhysicalContainerFragment(
NGFragmentType type,
unsigned sub_type)
: NGPhysicalFragment(builder, type, sub_type),
+ num_children_(builder->children_.size()),
break_token_(std::move(builder->break_token_)),
oof_positioned_descendants_(
builder->oof_positioned_descendants_.IsEmpty()
? nullptr
: new Vector<NGPhysicalOutOfFlowPositionedNode>()),
- buffer_(buffer),
- num_children_(builder->children_.size()) {
+ buffer_(buffer) {
has_floating_descendants_for_paint_ =
builder->has_floating_descendants_for_paint_;
has_adjoining_object_descendants_ =
@@ -71,11 +72,12 @@ NGPhysicalContainerFragment::NGPhysicalContainerFragment(
// Because flexible arrays need to be the last member in a class, we need to
// have the buffer passed as a constructor argument and have the actual
// storage be part of the subclass.
+ const WritingModeConverter converter(
+ {block_or_line_writing_mode, builder->Direction()}, size);
wtf_size_t i = 0;
for (auto& child : builder->children_) {
- buffer[i].offset = child.offset.ConvertToPhysical(
- block_or_line_writing_mode, builder->Direction(), size,
- child.fragment->Size());
+ buffer[i].offset =
+ converter.ToPhysical(child.offset, child.fragment->Size());
// Call the move constructor to move without |AddRef|. Fragments in
// |builder| are not used after |this| was constructed.
static_assert(
@@ -110,6 +112,8 @@ void NGPhysicalContainerFragment::AddOutlineRectsForNormalChildren(
}
if (item.Type() == NGFragmentItem::kBox) {
if (const NGPhysicalBoxFragment* child_box = item.BoxFragment()) {
+ if (const NGPhysicalFragment* post_layout = child_box->PostLayout())
+ child_box = To<NGPhysicalBoxFragment>(post_layout);
DCHECK(!child_box->IsOutOfFlowPositioned());
AddOutlineRectsForDescendant(
{child_box, item.OffsetInContainerBlock()}, outline_rects,
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h
index f025de6caf1..a155b84e3f5 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h
@@ -187,6 +187,7 @@ class CORE_EXPORT NGPhysicalContainerFragment : public NGPhysicalFragment {
static bool DependsOnPercentageBlockSize(const NGContainerFragmentBuilder&);
+ wtf_size_t num_children_;
scoped_refptr<const NGBreakToken> break_token_;
const std::unique_ptr<Vector<NGPhysicalOutOfFlowPositionedNode>>
oof_positioned_descendants_;
@@ -194,7 +195,6 @@ class CORE_EXPORT NGPhysicalContainerFragment : public NGPhysicalFragment {
// Because flexible arrays need to be the last member in a class, the actual
// storage is in the subclass and we just keep a pointer to it here.
const NGLink* buffer_;
- wtf_size_t num_children_;
};
template <>
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
index 4d3daa543ce..c5370218ab6 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/dom/document_lifecycle.h"
+#include "third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h"
#include "third_party/blink/renderer/core/layout/layout_block.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_border_edges.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h"
@@ -23,6 +24,9 @@ namespace {
struct SameSizeAsNGPhysicalFragment
: RefCounted<const NGPhysicalFragment, NGPhysicalFragmentTraits> {
+ // |flags_for_free_maybe| is used to support an additional increase in size
+ // needed for DCHECK and 32-bit builds.
+ unsigned flags_for_free_maybe;
void* layout_object;
PhysicalSize size;
unsigned flags;
@@ -213,18 +217,18 @@ void NGPhysicalFragmentTraits::Destruct(const NGPhysicalFragment* fragment) {
NGPhysicalFragment::NGPhysicalFragment(NGFragmentBuilder* builder,
NGFragmentType type,
unsigned sub_type)
- : layout_object_(builder->layout_object_),
+ : has_floating_descendants_for_paint_(false),
+ layout_object_(builder->layout_object_),
size_(ToPhysicalSize(builder->size_, builder->GetWritingMode())),
type_(type),
sub_type_(sub_type),
style_variant_((unsigned)builder->style_variant_),
is_hidden_for_paint_(builder->is_hidden_for_paint_),
- has_floating_descendants_for_paint_(false),
is_fieldset_container_(false),
is_legacy_layout_root_(false),
is_painted_atomically_(false),
has_baseline_(false) {
- DCHECK(builder->layout_object_);
+ CHECK(builder->layout_object_);
}
NGPhysicalFragment::NGPhysicalFragment(LayoutObject* layout_object,
@@ -232,18 +236,18 @@ NGPhysicalFragment::NGPhysicalFragment(LayoutObject* layout_object,
PhysicalSize size,
NGFragmentType type,
unsigned sub_type)
- : layout_object_(layout_object),
+ : has_floating_descendants_for_paint_(false),
+ layout_object_(layout_object),
size_(size),
type_(type),
sub_type_(sub_type),
style_variant_((unsigned)style_variant),
is_hidden_for_paint_(false),
- has_floating_descendants_for_paint_(false),
is_fieldset_container_(false),
is_legacy_layout_root_(false),
is_painted_atomically_(false),
has_baseline_(false) {
- DCHECK(layout_object);
+ CHECK(layout_object);
}
// Keep the implementation of the destructor here, to avoid dependencies on
@@ -295,7 +299,7 @@ bool NGPhysicalFragment::IsPlacedByLayoutNG() const {
// to set.
if (IsLineBox())
return false;
- if (IsColumnBox())
+ if (IsFragmentainerBox())
return true;
const LayoutBlock* container = layout_object_->ContainingBlock();
if (!container)
@@ -315,14 +319,15 @@ const FragmentData* NGPhysicalFragment::GetFragmentData() const {
}
const NGPhysicalFragment* NGPhysicalFragment::PostLayout() const {
- if (IsBox() && !IsInlineBox()) {
- if (const auto* block = DynamicTo<LayoutBlockFlow>(GetLayoutObject())) {
- if (block->IsRelayoutBoundary()) {
- const NGPhysicalFragment* new_fragment = block->CurrentFragment();
- if (new_fragment && new_fragment != this)
- return new_fragment;
- }
- }
+ const auto* layout_box = ToLayoutBoxOrNull(GetLayoutObject());
+ if (UNLIKELY(!layout_box))
+ return nullptr;
+
+ if (layout_box->PhysicalFragmentCount() == 1) {
+ const NGPhysicalFragment* post_layout = layout_box->GetPhysicalFragment(0);
+ DCHECK(post_layout);
+ if (UNLIKELY(post_layout && post_layout != this))
+ return post_layout;
}
return nullptr;
}
@@ -506,6 +511,18 @@ bool NGPhysicalFragment::ShouldPaintDragCaret() const {
return false;
}
+LogicalRect NGPhysicalFragment::ConvertChildToLogical(
+ const PhysicalRect& physical_rect) const {
+ return WritingModeConverter(Style().GetWritingDirection(), Size())
+ .ToLogical(physical_rect);
+}
+
+PhysicalRect NGPhysicalFragment::ConvertChildToPhysical(
+ const LogicalRect& logical_rect) const {
+ return WritingModeConverter(Style().GetWritingDirection(), Size())
+ .ToPhysical(logical_rect);
+}
+
String NGPhysicalFragment::ToString() const {
StringBuilder output;
output.AppendFormat("Type: '%d' Size: '%s'", Type(),
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
index 4cebbebf948..d14c4b9eb1e 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
@@ -25,9 +25,9 @@ class FragmentData;
class Node;
class NGFragmentBuilder;
class NGInlineItem;
-class PaintLayer;
-
class NGPhysicalFragment;
+class PaintLayer;
+struct LogicalRect;
struct CORE_EXPORT NGPhysicalFragmentTraits {
static void Destruct(const NGPhysicalFragment*);
@@ -98,6 +98,7 @@ class CORE_EXPORT NGPhysicalFragment
bool IsColumnBox() const {
return IsBox() && BoxType() == NGBoxType::kColumnBox;
}
+ bool IsFragmentainerBox() const { return IsColumnBox(); }
// An atomic inline is represented as a kFragmentBox, such as inline block and
// replaced elements.
bool IsAtomicInline() const {
@@ -133,7 +134,7 @@ class CORE_EXPORT NGPhysicalFragment
//
// [1] https://www.w3.org/TR/css-display-3/#box-tree
// [2] https://www.w3.org/TR/css-break-3/#fragmentation-container
- bool IsCSSBox() const { return !IsLineBox() && !IsColumnBox(); }
+ bool IsCSSBox() const { return !IsLineBox() && !IsFragmentainerBox(); }
bool IsBlockFlow() const;
bool IsAnonymousBlock() const {
@@ -142,6 +143,7 @@ class CORE_EXPORT NGPhysicalFragment
bool IsListMarker() const {
return IsCSSBox() && layout_object_->IsLayoutNGOutsideListMarker();
}
+ bool IsRubyRun() const { return layout_object_->IsRubyRun(); }
// Return true if this fragment is a container established by a fieldset
// element. Such a fragment contains an optional rendered legend fragment and
@@ -336,6 +338,11 @@ class CORE_EXPORT NGPhysicalFragment
// be confused with the CSS 'direction' property.
TextDirection ResolvedDirection() const;
+ // Helper functions to convert between |PhysicalRect| and |LogicalRect| of a
+ // child.
+ LogicalRect ConvertChildToLogical(const PhysicalRect& physical_rect) const;
+ PhysicalRect ConvertChildToPhysical(const LogicalRect& logical_rect) const;
+
// Utility functions for caret painting. Note that carets are painted as part
// of the containing block's foreground.
bool ShouldPaintCursorCaret() const;
@@ -386,14 +393,6 @@ class CORE_EXPORT NGPhysicalFragment
const Vector<NGInlineItem>& InlineItemsOfContainingBlock() const;
- LayoutObject* layout_object_;
- const PhysicalSize size_;
-
- const unsigned type_ : 2; // NGFragmentType
- const unsigned sub_type_ : 3; // NGBoxType, NGTextType, or NGLineBoxType
- const unsigned style_variant_ : 2; // NGStyleVariant
- const unsigned is_hidden_for_paint_ : 1;
-
// The following bitfields are only to be used by NGPhysicalContainerFragment
// (it's defined here to save memory, since that class has no bitfields).
unsigned has_floating_descendants_for_paint_ : 1;
@@ -405,8 +404,6 @@ class CORE_EXPORT NGPhysicalFragment
// The following bitfields are only to be used by NGPhysicalLineBoxFragment
// (it's defined here to save memory, since that class has no bitfields).
unsigned has_propagated_descendants_ : 1;
- // base (line box) or resolve (text) direction
- unsigned base_or_resolved_direction_ : 1; // TextDirection
unsigned has_hanging_ : 1;
// The following bitfields are only to be used by NGPhysicalBoxFragment
@@ -416,8 +413,19 @@ class CORE_EXPORT NGPhysicalFragment
unsigned border_edge_ : 4; // NGBorderEdges::Physical
unsigned has_borders_ : 1;
unsigned has_padding_ : 1;
- unsigned is_math_fraction_ : 1;
unsigned is_first_for_node_ : 1;
+ unsigned has_oof_positioned_fragmentainer_descendants_ : 1;
+
+ LayoutObject* layout_object_;
+ const PhysicalSize size_;
+
+ const unsigned type_ : 2; // NGFragmentType
+ const unsigned sub_type_ : 3; // NGBoxType, NGTextType, or NGLineBoxType
+ const unsigned style_variant_ : 2; // NGStyleVariant
+ const unsigned is_hidden_for_paint_ : 1;
+ unsigned is_math_fraction_ : 1;
+ // base (line box) or resolve (text) direction
+ unsigned base_or_resolved_direction_ : 1; // TextDirection
// The following are only used by NGPhysicalBoxFragment but are initialized
// for all types to allow methods using them to be inlined.
@@ -429,10 +437,11 @@ class CORE_EXPORT NGPhysicalFragment
// The following bitfields are only to be used by NGPhysicalTextFragment
// (it's defined here to save memory, since that class has no bitfields).
- mutable unsigned ink_overflow_computed_ : 1;
+ mutable unsigned ink_overflow_computed_or_mathml_paint_info_ : 1;
// Note: We've used 32-bit bit field. If you need more bits, please think to
- // share bit fields.
+ // share bit fields, or put them before layout_object_ to fill the gap after
+ // RefCounted on 64-bit systems.
private:
friend struct NGPhysicalFragmentTraits;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_positioned_float.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_positioned_float.h
index e24bf5b2c18..84473ecc6d8 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_positioned_float.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_positioned_float.h
@@ -17,8 +17,11 @@ class NGLayoutResult;
// Contains the information necessary for copying back data to a FloatingObject.
struct CORE_EXPORT NGPositionedFloat {
NGPositionedFloat(scoped_refptr<const NGLayoutResult> layout_result,
- const NGBfcOffset& bfc_offset)
- : layout_result(layout_result), bfc_offset(bfc_offset) {}
+ const NGBfcOffset& bfc_offset,
+ bool need_break_before = false)
+ : layout_result(layout_result),
+ bfc_offset(bfc_offset),
+ need_break_before(need_break_before) {}
NGPositionedFloat(NGPositionedFloat&&) noexcept = default;
NGPositionedFloat(const NGPositionedFloat&) = default;
NGPositionedFloat& operator=(NGPositionedFloat&&) = default;
@@ -26,6 +29,7 @@ struct CORE_EXPORT NGPositionedFloat {
scoped_refptr<const NGLayoutResult> layout_result;
NGBfcOffset bfc_offset;
+ bool need_break_before = false;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc
index 58f9ccbd1c8..400a7226def 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.h"
+#include "third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_utils.h"
#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.h"
@@ -24,8 +25,7 @@ NGSimplifiedLayoutAlgorithm::NGSimplifiedLayoutAlgorithm(
const NGLayoutResult& result)
: NGLayoutAlgorithm(params),
previous_result_(result),
- writing_mode_(Style().GetWritingMode()),
- direction_(Style().Direction()) {
+ writing_direction_(Style().GetWritingDirection()) {
// Currently this only supports block-flow layout due to the static-position
// calculations. If support for other layout types is added this logic will
// need to be changed.
@@ -112,20 +112,19 @@ NGSimplifiedLayoutAlgorithm::NGSimplifiedLayoutAlgorithm(
container_builder_.SetOverflowBlockSize(result.OverflowBlockSize());
LayoutUnit new_block_size = ComputeBlockSizeForFragment(
- ConstraintSpace(), Style(),
- container_builder_.Borders() + container_builder_.Padding(),
- result.IntrinsicBlockSize(),
+ ConstraintSpace(), Style(), BorderPadding(), result.IntrinsicBlockSize(),
container_builder_.InitialBorderBoxSize().inline_size);
// Only block-flow is allowed to change its block-size during "simplified"
// layout, all other layout types must remain the same size.
if (is_block_flow) {
- container_builder_.SetBlockSize(new_block_size);
+ container_builder_.SetFragmentBlockSize(new_block_size);
} else {
LayoutUnit old_block_size =
- NGFragment(writing_mode_, physical_fragment).BlockSize();
+ NGFragment(writing_direction_.GetWritingMode(), physical_fragment)
+ .BlockSize();
DCHECK_EQ(old_block_size, new_block_size);
- container_builder_.SetBlockSize(old_block_size);
+ container_builder_.SetFragmentBlockSize(old_block_size);
}
// We need the previous physical container size to calculate the position of
@@ -193,8 +192,8 @@ scoped_refptr<const NGLayoutResult> NGSimplifiedLayoutAlgorithm::Layout() {
if (const NGFragmentItems* previous_items = previous_fragment.Items()) {
auto* items_builder = container_builder_.ItemsBuilder();
DCHECK(items_builder);
- items_builder->AddPreviousItems(*previous_items, writing_mode_,
- direction_,
+ DCHECK_EQ(items_builder->GetWritingDirection(), writing_direction_);
+ items_builder->AddPreviousItems(*previous_items,
previous_physical_container_size_);
}
}
@@ -217,7 +216,7 @@ scoped_refptr<const NGLayoutResult> NGSimplifiedLayoutAlgorithm::Layout() {
NOINLINE scoped_refptr<const NGLayoutResult>
NGSimplifiedLayoutAlgorithm::LayoutWithItemsBuilder() {
- NGFragmentItemsBuilder items_builder;
+ NGFragmentItemsBuilder items_builder(writing_direction_);
container_builder_.SetItemsBuilder(&items_builder);
scoped_refptr<const NGLayoutResult> result = Layout();
// Ensure stack-allocated |NGFragmentItemsBuilder| is not used anymore.
@@ -233,9 +232,10 @@ void NGSimplifiedLayoutAlgorithm::AddChildFragment(
DCHECK_EQ(old_fragment->Size(), new_fragment.Size());
// Determine the previous position in the logical coordinate system.
- LogicalOffset child_offset = old_fragment.Offset().ConvertToLogical(
- writing_mode_, direction_, previous_physical_container_size_,
- new_fragment.Size());
+ LogicalOffset child_offset =
+ WritingModeConverter(writing_direction_,
+ previous_physical_container_size_)
+ .ToLogical(old_fragment.Offset(), new_fragment.Size());
// Add the new fragment to the builder.
container_builder_.AddChild(new_fragment, child_offset);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.h
index bebbcf7425c..54963f70e9e 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.h
@@ -57,8 +57,7 @@ class CORE_EXPORT NGSimplifiedLayoutAlgorithm
const NGLayoutResult& previous_result_;
NGBoxStrut border_scrollbar_padding_;
- const WritingMode writing_mode_;
- const TextDirection direction_;
+ const WritingDirectionMode writing_direction_;
PhysicalSize previous_physical_container_size_;
};
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.cc
index bcda1289de2..1b4213395d2 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.cc
@@ -25,6 +25,7 @@ bool AdjustToClearance(LayoutUnit clearance_offset, NGBfcOffset* offset) {
NGConstraintSpace CreateIndefiniteConstraintSpaceForChild(
const ComputedStyle& container_style,
+ const MinMaxSizesInput& input,
NGLayoutInputNode child) {
WritingMode parent_writing_mode = container_style.GetWritingMode();
WritingMode child_writing_mode = child.Style().GetWritingMode();
@@ -37,7 +38,8 @@ NGConstraintSpace CreateIndefiniteConstraintSpaceForChild(
builder.SetCacheSlot(NGCacheSlot::kMeasure);
builder.SetAvailableSize(indefinite_size);
- builder.SetPercentageResolutionSize(indefinite_size);
+ builder.SetPercentageResolutionSize(
+ {kIndefiniteSize, input.percentage_resolution_block_size});
builder.SetReplacedPercentageResolutionSize(indefinite_size);
builder.SetIsShrinkToFit(child.Style().LogicalWidth().IsAuto());
return builder.ToConstraintSpace();
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.h
index af96da0cb51..916a2898678 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.h
@@ -21,12 +21,14 @@ CORE_EXPORT bool AdjustToClearance(LayoutUnit clearance_offset,
NGBfcOffset* offset);
// Create a child constraint space with no sizing data, except for fallback
-// inline sizing for orthongonal flow roots. This will not and can not be used
-// for final layout, but is needed in an intermediate measure pass that
-// calculates the min/max size contribution from a child that establishes an
-// orthogonal flow root.
+// inline sizing for orthogonal flow roots and a percentage resolution block
+// size based on |input| (for calculating aspect-ratio based sizes). This will
+// not and can not be used for final layout, but is needed in an intermediate
+// measure pass that calculates the min/max size contribution from a child that
+// establishes an orthogonal flow root.
NGConstraintSpace CreateIndefiniteConstraintSpaceForChild(
const ComputedStyle& container_style,
+ const MinMaxSizesInput& input,
NGLayoutInputNode child);
// Calculate and set the available inline fallback size for orthogonal flow
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.cc
index b67b5756cc9..d45bd12d0f5 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.cc
@@ -37,10 +37,12 @@ int NGTextDecorationOffset::ComputeUnderlineOffsetForUnder(
int offset_int = offset.Floor();
// Gaps are not needed for TextTop because it generally has internal
- // leadings.
+ // leadings. Overline needs to grow upwards, hence subtract thickness.
if (position_type == FontVerticalPositionType::TextTop)
- return offset_int;
- return !IsLineOverSide(position_type) ? offset_int + 1 : offset_int - 1;
+ return offset_int - floorf(text_decoration_thickness);
+ return !IsLineOverSide(position_type)
+ ? offset_int + 1
+ : offset_int - 1 - floorf(text_decoration_thickness);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc
index 5fed73b3c50..90f2147df54 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc
@@ -14,6 +14,19 @@
namespace blink {
+namespace {
+
+inline bool NeedsTableSection(const LayoutObject& object) {
+ // Return true if 'object' can't exist in an anonymous table without being
+ // wrapped in a table section box.
+ EDisplay display = object.StyleRef().Display();
+ return display != EDisplay::kTableCaption &&
+ display != EDisplay::kTableColumnGroup &&
+ display != EDisplay::kTableColumn;
+}
+
+} // namespace
+
LayoutNGTable::LayoutNGTable(Element* element)
: LayoutNGMixin<LayoutBlock>(element) {}
@@ -33,6 +46,61 @@ void LayoutNGTable::UpdateBlockLayout(bool relayout_children) {
UpdateInFlowBlockLayout();
}
+void LayoutNGTable::AddChild(LayoutObject* child, LayoutObject* before_child) {
+ bool wrap_in_anonymous_section = !child->IsTableCaption() &&
+ !child->IsLayoutTableCol() &&
+ !child->IsTableSection();
+
+ if (!wrap_in_anonymous_section) {
+ if (before_child && before_child->Parent() != this)
+ before_child = SplitAnonymousBoxesAroundChild(before_child);
+ LayoutBox::AddChild(child, before_child);
+ return;
+ }
+
+ if (!before_child && LastChild() && LastChild()->IsTableSection() &&
+ LastChild()->IsAnonymous() && !LastChild()->IsBeforeContent()) {
+ LastChild()->AddChild(child);
+ return;
+ }
+
+ if (before_child && !before_child->IsAnonymous() &&
+ before_child->Parent() == this) {
+ LayoutNGTableSection* section =
+ DynamicTo<LayoutNGTableSection>(before_child->PreviousSibling());
+ if (section && section->IsAnonymous()) {
+ section->AddChild(child);
+ return;
+ }
+ }
+
+ LayoutObject* last_box = before_child;
+ while (last_box && last_box->Parent()->IsAnonymous() &&
+ !last_box->IsTableSection() && NeedsTableSection(*last_box))
+ last_box = last_box->Parent();
+ if (last_box && last_box->IsAnonymous() && last_box->IsTablePart() &&
+ !IsAfterContent(last_box)) {
+ if (before_child == last_box)
+ before_child = last_box->SlowFirstChild();
+ last_box->AddChild(child, before_child);
+ return;
+ }
+
+ if (before_child && !before_child->IsTableSection() &&
+ NeedsTableSection(*before_child))
+ before_child = nullptr;
+
+ LayoutBox* section =
+ LayoutObjectFactory::CreateAnonymousTableSectionWithParent(*this);
+ AddChild(section, before_child);
+ section->AddChild(child);
+}
+
+LayoutBox* LayoutNGTable::CreateAnonymousBoxWithSameTypeAs(
+ const LayoutObject* parent) const {
+ return LayoutObjectFactory::CreateAnonymousTableWithParent(*parent);
+}
+
bool LayoutNGTable::IsFirstCell(const LayoutNGTableCellInterface& cell) const {
const LayoutNGTableRowInterface* row = cell.RowInterface();
if (row->FirstCellInterface() != &cell)
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h
index 06186b60675..e82945eff9a 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h
@@ -33,6 +33,12 @@ class CORE_EXPORT LayoutNGTable : public LayoutNGMixin<LayoutBlock>,
void UpdateBlockLayout(bool relayout_children) override;
+ void AddChild(LayoutObject* child,
+ LayoutObject* before_child = nullptr) override;
+
+ LayoutBox* CreateAnonymousBoxWithSameTypeAs(
+ const LayoutObject* parent) const override;
+
// LayoutBlock methods end.
// LayoutNGTableInterface methods start.
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc
index 8f501b93c79..cca5eb8198d 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc
@@ -37,6 +37,11 @@ void LayoutNGTableCell::ColSpanOrRowSpanChanged() {
UpdateColAndRowSpanFlags();
}
+LayoutBox* LayoutNGTableCell::CreateAnonymousBoxWithSameTypeAs(
+ const LayoutObject* parent) const {
+ return LayoutObjectFactory::CreateAnonymousTableCellWithParent(*parent);
+}
+
Length LayoutNGTableCell::StyleOrColLogicalWidth() const {
// TODO(atotic) TablesNG cannot easily get col width before layout.
return StyleRef().LogicalWidth();
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h
index 4c70aef0a31..c1295a4b73f 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h
@@ -37,6 +37,9 @@ class CORE_EXPORT LayoutNGTableCell
// compat.
const char* GetName() const final { return "LayoutNGTableCellNew"; }
+ LayoutBox* CreateAnonymousBoxWithSameTypeAs(
+ const LayoutObject* parent) const override;
+
// LayoutBlockFlow methods end.
// LayoutNGTableCellInterface methods start.
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc
index 48db1645c21..d790450ca6a 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h"
#include "third_party/blink/renderer/core/layout/layout_analyzer.h"
+#include "third_party/blink/renderer/core/layout/layout_object_factory.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h"
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row_interface.h"
@@ -20,6 +21,57 @@ bool LayoutNGTableRow::IsEmpty() const {
return !FirstChild();
}
+void LayoutNGTableRow::AddChild(LayoutObject* child,
+ LayoutObject* before_child) {
+ if (!child->IsTableCell()) {
+ LayoutObject* last = before_child;
+ if (!last)
+ last = LastCell();
+ if (last && last->IsAnonymous() && last->IsTableCell() &&
+ !last->IsBeforeOrAfterContent()) {
+ LayoutBlockFlow* last_cell = To<LayoutBlockFlow>(last);
+ if (before_child == last_cell)
+ before_child = last_cell->FirstChild();
+ last_cell->AddChild(child, before_child);
+ return;
+ }
+
+ if (before_child && !before_child->IsAnonymous() &&
+ before_child->Parent() == this) {
+ LayoutObject* cell = before_child->PreviousSibling();
+ if (cell && cell->IsTableCell() && cell->IsAnonymous()) {
+ cell->AddChild(child);
+ return;
+ }
+ }
+
+ // If before_child is inside an anonymous cell, insert into the cell.
+ if (last && !last->IsTableCell() && last->Parent() &&
+ last->Parent()->IsAnonymous() &&
+ !last->Parent()->IsBeforeOrAfterContent()) {
+ last->Parent()->AddChild(child, before_child);
+ return;
+ }
+
+ LayoutBlockFlow* cell =
+ LayoutObjectFactory::CreateAnonymousTableCellWithParent(*this);
+ AddChild(cell, before_child);
+ cell->AddChild(child);
+ return;
+ }
+
+ if (before_child && before_child->Parent() != this)
+ before_child = SplitAnonymousBoxesAroundChild(before_child);
+
+ DCHECK(!before_child || before_child->IsTableCell());
+ LayoutNGMixin<LayoutBlock>::AddChild(child, before_child);
+}
+
+LayoutBox* LayoutNGTableRow::CreateAnonymousBoxWithSameTypeAs(
+ const LayoutObject* parent) const {
+ return LayoutObjectFactory::CreateAnonymousTableRowWithParent(*parent);
+}
+
unsigned LayoutNGTableRow::RowIndex() const {
unsigned index = 0;
for (LayoutObject* child = Parent()->SlowFirstChild(); child;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h
index 8b08dd07582..14048ea90b6 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h
@@ -28,6 +28,12 @@ class CORE_EXPORT LayoutNGTableRow : public LayoutNGMixin<LayoutBlock>,
const char* GetName() const override { return "LayoutNGTableRow"; }
+ void AddChild(LayoutObject* child,
+ LayoutObject* before_child = nullptr) override;
+
+ LayoutBox* CreateAnonymousBoxWithSameTypeAs(
+ const LayoutObject* parent) const override;
+
// Whether a row has opaque background depends on many factors, e.g. border
// spacing, border collapsing, missing cells, etc.
// For simplicity, just conservatively assume all table rows are not opaque.
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc
index 06225acabcb..65b2c1fbbb3 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h"
#include "third_party/blink/renderer/core/layout/layout_analyzer.h"
+#include "third_party/blink/renderer/core/layout/layout_object_factory.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h"
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h"
@@ -25,6 +26,58 @@ bool LayoutNGTableSection::IsEmpty() const {
return true;
}
+void LayoutNGTableSection::AddChild(LayoutObject* child,
+ LayoutObject* before_child) {
+ if (!child->IsTableRow()) {
+ LayoutObject* last = before_child;
+ if (!last)
+ last = LastChild();
+ if (last && last->IsAnonymous() && last->IsTablePart() &&
+ !last->IsBeforeOrAfterContent()) {
+ if (before_child == last)
+ before_child = last->SlowFirstChild();
+ last->AddChild(child, before_child);
+ return;
+ }
+
+ if (before_child && !before_child->IsAnonymous() &&
+ before_child->Parent() == this) {
+ LayoutObject* row = before_child->PreviousSibling();
+ if (row && row->IsTableRow() && row->IsAnonymous()) {
+ row->AddChild(child);
+ return;
+ }
+ }
+
+ // If before_child is inside an anonymous cell/row, insert into the cell or
+ // into the anonymous row containing it, if there is one.
+ LayoutObject* last_box = last;
+ while (last_box && last_box->Parent()->IsAnonymous() &&
+ !last_box->IsTableRow())
+ last_box = last_box->Parent();
+ if (last_box && last_box->IsAnonymous() &&
+ !last_box->IsBeforeOrAfterContent()) {
+ last_box->AddChild(child, before_child);
+ return;
+ }
+
+ LayoutObject* row =
+ LayoutObjectFactory::CreateAnonymousTableRowWithParent(*this);
+ AddChild(row, before_child);
+ row->AddChild(child);
+ return;
+ }
+ if (before_child && before_child->Parent() != this)
+ before_child = SplitAnonymousBoxesAroundChild(before_child);
+
+ LayoutNGMixin<LayoutBlock>::AddChild(child, before_child);
+}
+
+LayoutBox* LayoutNGTableSection::CreateAnonymousBoxWithSameTypeAs(
+ const LayoutObject* parent) const {
+ return LayoutObjectFactory::CreateAnonymousTableSectionWithParent(*parent);
+}
+
LayoutNGTableInterface* LayoutNGTableSection::TableInterface() const {
return ToInterface<LayoutNGTableInterface>(Parent());
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h
index 64136c51551..8e9420392a3 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h
@@ -27,6 +27,12 @@ class CORE_EXPORT LayoutNGTableSection : public LayoutNGMixin<LayoutBlock>,
const char* GetName() const override { return "LayoutNGTableSection"; }
+ void AddChild(LayoutObject* child,
+ LayoutObject* before_child = nullptr) override;
+
+ LayoutBox* CreateAnonymousBoxWithSameTypeAs(
+ const LayoutObject* parent) const override;
+
bool AllowsOverflowClip() const override { return false; }
bool BackgroundIsKnownToBeOpaqueInRect(const PhysicalRect&) const override {
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc b/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc
new file mode 100644
index 00000000000..1d54f04fbe6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc
@@ -0,0 +1,631 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h"
+
+#include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
+
+namespace blink {
+
+namespace {
+
+// Implements spec distribution algorithm:
+// https://www.w3.org/TR/css-tables-3/#width-distribution-algorithm
+void DistributeInlineSizeToComputedInlineSizeAuto(
+ LayoutUnit target_inline_size,
+ LayoutUnit inline_border_spacing,
+ NGTableTypes::Column* start_column,
+ NGTableTypes::Column* end_column,
+ NGTableTypes::Columns* column_constraints) {
+ if (column_constraints->size() == 0)
+ return;
+
+ unsigned all_columns_count = 0;
+ unsigned percent_columns_count = 0;
+ unsigned fixed_columns_count = 0;
+ unsigned auto_columns_count = 0;
+
+ // What guesses mean is described in table specification.
+ // https://www.w3.org/TR/css-tables-3/#width-distribution-algorithm
+ enum { kMinGuess, kPercentageGuess, kSpecifiedGuess, kMaxGuess, kAboveMax };
+ // sizes are collected for all guesses except kAboveMax
+ LayoutUnit guess_sizes[kAboveMax];
+ LayoutUnit guess_size_total_increases[kAboveMax];
+ float total_percent = 0.0f;
+ LayoutUnit total_auto_max_inline_size;
+ LayoutUnit total_fixed_max_inline_size;
+
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ all_columns_count++;
+ if (!column->min_inline_size)
+ column->min_inline_size = LayoutUnit();
+ if (!column->max_inline_size)
+ column->max_inline_size = LayoutUnit();
+ if (column->percent) {
+ percent_columns_count++;
+ total_percent += *column->percent;
+ LayoutUnit percent_inline_size =
+ column->ResolvePercentInlineSize(target_inline_size);
+ guess_sizes[kMinGuess] += *column->min_inline_size;
+ guess_sizes[kPercentageGuess] += percent_inline_size;
+ guess_sizes[kSpecifiedGuess] += percent_inline_size;
+ guess_sizes[kMaxGuess] += percent_inline_size;
+ guess_size_total_increases[kPercentageGuess] +=
+ percent_inline_size - *column->min_inline_size;
+ } else if (column->is_constrained) { // Fixed column
+ fixed_columns_count++;
+ total_fixed_max_inline_size += *column->max_inline_size;
+ guess_sizes[kMinGuess] += *column->min_inline_size;
+ guess_sizes[kPercentageGuess] += *column->min_inline_size;
+ guess_sizes[kSpecifiedGuess] += *column->max_inline_size;
+ guess_sizes[kMaxGuess] += *column->max_inline_size;
+ guess_size_total_increases[kSpecifiedGuess] +=
+ *column->max_inline_size - *column->min_inline_size;
+ } else { // Auto column
+ auto_columns_count++;
+ total_auto_max_inline_size += *column->max_inline_size;
+ guess_sizes[kMinGuess] += *column->min_inline_size;
+ guess_sizes[kPercentageGuess] += *column->min_inline_size;
+ guess_sizes[kSpecifiedGuess] += *column->min_inline_size;
+ guess_sizes[kMaxGuess] += *column->max_inline_size;
+ guess_size_total_increases[kMaxGuess] +=
+ *column->max_inline_size - *column->min_inline_size;
+ }
+ }
+ // Distributing inline sizes can never cause cells to be < min_inline_size.
+ // Target inline size must be wider than sum of min inline sizes.
+ // This is always true for assignable_table_inline_size, but not for
+ // colspan_cells.
+ target_inline_size = std::max(target_inline_size, guess_sizes[kMinGuess]);
+
+ unsigned starting_guess = kAboveMax;
+ for (unsigned i = kMinGuess; i != kAboveMax; ++i) {
+ if (guess_sizes[i] >= target_inline_size) {
+ starting_guess = i;
+ break;
+ }
+ }
+ switch (starting_guess) {
+ case kMinGuess: {
+ // All columns are min inline size.
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ column->computed_inline_size =
+ column->min_inline_size.value_or(LayoutUnit());
+ }
+ } break;
+ case kPercentageGuess: {
+ // Percent columns grow, auto/fixed get min inline size.
+ LayoutUnit percent_inline_size_increases =
+ guess_size_total_increases[kPercentageGuess];
+ LayoutUnit distributable_inline_size =
+ target_inline_size - guess_sizes[kMinGuess];
+ LayoutUnit rounding_error_inline_size = distributable_inline_size;
+ NGTableTypes::Column* last_column = nullptr;
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ if (column->percent) {
+ last_column = column;
+ LayoutUnit percent_inline_size =
+ column->ResolvePercentInlineSize(target_inline_size);
+ LayoutUnit column_inline_size_increase =
+ percent_inline_size - *column->min_inline_size;
+ LayoutUnit delta;
+ if (percent_inline_size_increases != LayoutUnit()) {
+ delta = LayoutUnit(distributable_inline_size *
+ column_inline_size_increase.ToFloat() /
+ percent_inline_size_increases);
+ } else {
+ delta = LayoutUnit(distributable_inline_size.ToFloat() /
+ percent_columns_count);
+ }
+ rounding_error_inline_size -= delta;
+ column->computed_inline_size = *column->min_inline_size + delta;
+ } else {
+ // Auto/Fixed columns get min inline size.
+ column->computed_inline_size = *column->min_inline_size;
+ }
+ }
+ if (rounding_error_inline_size != LayoutUnit()) {
+ DCHECK(last_column);
+ last_column->computed_inline_size += rounding_error_inline_size;
+ }
+ } break;
+ case kSpecifiedGuess: {
+ // Fixed columns grow, auto gets min, percent gets %max
+ LayoutUnit fixed_inline_size_increase =
+ guess_size_total_increases[kSpecifiedGuess];
+ LayoutUnit distributable_inline_size =
+ target_inline_size - guess_sizes[kPercentageGuess];
+ LayoutUnit rounding_error_inline_size = distributable_inline_size;
+ NGTableTypes::Column* last_column = nullptr;
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ if (column->percent) {
+ column->computed_inline_size =
+ column->ResolvePercentInlineSize(target_inline_size);
+ } else if (column->is_constrained) {
+ last_column = column;
+ LayoutUnit column_inline_size_increase =
+ *column->max_inline_size - *column->min_inline_size;
+ LayoutUnit delta;
+ if (fixed_inline_size_increase != LayoutUnit()) {
+ delta = LayoutUnit(distributable_inline_size *
+ column_inline_size_increase.ToFloat() /
+ fixed_inline_size_increase);
+ } else {
+ delta = LayoutUnit(distributable_inline_size.ToFloat() /
+ fixed_columns_count);
+ }
+ rounding_error_inline_size -= delta;
+ column->computed_inline_size = *column->min_inline_size + delta;
+ } else {
+ column->computed_inline_size = *column->min_inline_size;
+ }
+ }
+ if (rounding_error_inline_size != LayoutUnit()) {
+ DCHECK(last_column);
+ last_column->computed_inline_size += rounding_error_inline_size;
+ }
+ } break;
+ case kMaxGuess: {
+ // Auto columns grow, fixed gets max, percent gets %max
+ LayoutUnit auto_inline_size_increase =
+ guess_size_total_increases[kMaxGuess];
+ LayoutUnit distributable_inline_size =
+ target_inline_size - guess_sizes[kSpecifiedGuess];
+ LayoutUnit rounding_error_inline_size = distributable_inline_size;
+ NGTableTypes::Column* last_column = nullptr;
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ if (column->percent) {
+ column->computed_inline_size =
+ column->ResolvePercentInlineSize(target_inline_size);
+ } else if (column->is_constrained) {
+ column->computed_inline_size = *column->max_inline_size;
+ } else {
+ last_column = column;
+ LayoutUnit column_inline_size_increase =
+ *column->max_inline_size - *column->min_inline_size;
+ LayoutUnit delta;
+ if (auto_inline_size_increase != LayoutUnit()) {
+ delta = LayoutUnit(distributable_inline_size *
+ column_inline_size_increase.ToFloat() /
+ auto_inline_size_increase);
+ } else {
+ delta = LayoutUnit(distributable_inline_size.ToFloat() /
+ auto_columns_count);
+ }
+ rounding_error_inline_size -= delta;
+ column->computed_inline_size = *column->min_inline_size + delta;
+ }
+ }
+ if (rounding_error_inline_size != LayoutUnit()) {
+ DCHECK(last_column);
+ last_column->computed_inline_size += rounding_error_inline_size;
+ }
+ } break;
+ case kAboveMax: {
+ LayoutUnit distributable_inline_size =
+ target_inline_size - guess_sizes[kMaxGuess];
+ if (auto_columns_count > 0) {
+ // Grow auto columns if available
+ LayoutUnit rounding_error_inline_size = distributable_inline_size;
+ NGTableTypes::Column* last_column = nullptr;
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ if (column->percent) {
+ column->computed_inline_size =
+ column->ResolvePercentInlineSize(target_inline_size);
+ } else if (column->is_constrained) {
+ column->computed_inline_size = *column->max_inline_size;
+ } else {
+ last_column = column;
+ LayoutUnit delta;
+ if (total_auto_max_inline_size > LayoutUnit()) {
+ delta = LayoutUnit(distributable_inline_size *
+ (*column->max_inline_size).ToFloat() /
+ total_auto_max_inline_size);
+ } else {
+ delta = distributable_inline_size / auto_columns_count;
+ }
+ rounding_error_inline_size -= delta;
+ column->computed_inline_size = *column->max_inline_size + delta;
+ }
+ }
+ if (rounding_error_inline_size != LayoutUnit()) {
+ DCHECK(last_column);
+ last_column->computed_inline_size += rounding_error_inline_size;
+ }
+ } else if (fixed_columns_count > 0) {
+ // Grow fixed columns if available.
+ LayoutUnit rounding_error_inline_size = distributable_inline_size;
+ NGTableTypes::Column* last_column = nullptr;
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ if (column->percent) {
+ column->computed_inline_size =
+ column->ResolvePercentInlineSize(target_inline_size);
+ } else if (column->is_constrained) {
+ last_column = column;
+ LayoutUnit delta;
+ if (total_fixed_max_inline_size > LayoutUnit()) {
+ delta = LayoutUnit(distributable_inline_size *
+ (*column->max_inline_size).ToFloat() /
+ total_fixed_max_inline_size);
+ } else {
+ delta = distributable_inline_size / fixed_columns_count;
+ }
+ rounding_error_inline_size -= delta;
+ column->computed_inline_size = *column->max_inline_size + delta;
+ } else {
+ DCHECK(false);
+ }
+ }
+ if (rounding_error_inline_size != LayoutUnit()) {
+ DCHECK(last_column);
+ last_column->computed_inline_size += rounding_error_inline_size;
+ }
+ } else if (percent_columns_count > 0) {
+ // Grow percent columns.
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ if (column->percent) {
+ if (total_percent > 0.0f) {
+ column->computed_inline_size = LayoutUnit(
+ *column->percent / total_percent * target_inline_size);
+ } else {
+ column->computed_inline_size =
+ distributable_inline_size / percent_columns_count;
+ }
+ } else {
+ DCHECK(false);
+ }
+ }
+ }
+ }
+ }
+
+#if DCHECK_IS_ON()
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ DCHECK_NE(column->computed_inline_size, kIndefiniteSize);
+ }
+#endif
+}
+
+void SynchronizeAssignableTableInlineSizeAndColumnsFixed(
+ LayoutUnit target_inline_size,
+ LayoutUnit inline_border_spacing,
+ NGTableTypes::Column* start_column,
+ NGTableTypes::Column* end_column) {
+ DCHECK_NE(start_column, end_column);
+ unsigned all_columns_count = 0;
+ unsigned percent_columns_count = 0;
+ unsigned auto_columns_count = 0;
+ unsigned auto_empty_columns_count = 0;
+ unsigned fixed_columns_count = 0;
+
+ float total_percent = 0.0f;
+ LayoutUnit total_percent_inline_size;
+ LayoutUnit total_auto_max_inline_size;
+ LayoutUnit total_fixed_inline_size;
+ LayoutUnit assigned_inline_size;
+
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ all_columns_count++;
+ if (!column->min_inline_size)
+ column->min_inline_size = LayoutUnit();
+ if (!column->max_inline_size)
+ column->max_inline_size = LayoutUnit();
+ if (column->percent) {
+ percent_columns_count++;
+ total_percent += *column->percent;
+ total_percent_inline_size +=
+ LayoutUnit(*column->percent / 100 * target_inline_size);
+ } else if (column->is_constrained) { // Fixed column
+ fixed_columns_count++;
+ total_fixed_inline_size += *column->max_inline_size;
+ } else {
+ auto_columns_count++;
+ if (*column->max_inline_size == LayoutUnit())
+ auto_empty_columns_count++;
+ total_auto_max_inline_size += *column->max_inline_size;
+ }
+ }
+
+ NGTableTypes::Column* last_distributed_column = nullptr;
+ // Distribute to fixed columns.
+ if (fixed_columns_count > 0) {
+ float scale = 1.0f;
+ bool scale_available = true;
+ LayoutUnit target_fixed_size =
+ (target_inline_size - total_percent_inline_size).ClampNegativeToZero();
+ bool scale_up =
+ total_fixed_inline_size < target_fixed_size && auto_columns_count == 0;
+ // Fixed columns grow if there are no auto columns. They fill up space not
+ // taken up by percentage columns.
+ bool scale_down = total_fixed_inline_size > target_inline_size;
+ if (scale_up || scale_down) {
+ if (total_fixed_inline_size != LayoutUnit()) {
+ scale = target_fixed_size.ToFloat() / total_fixed_inline_size;
+ } else {
+ scale_available = false;
+ }
+ }
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ if (!column->IsFixed())
+ continue;
+ last_distributed_column = column;
+ if (scale_available) {
+ column->computed_inline_size =
+ LayoutUnit(scale * *column->max_inline_size);
+ } else {
+ DCHECK_EQ(fixed_columns_count, all_columns_count);
+ column->computed_inline_size =
+ LayoutUnit(target_inline_size.ToFloat() / fixed_columns_count);
+ }
+ assigned_inline_size += column->computed_inline_size;
+ }
+ }
+ if (assigned_inline_size >= target_inline_size)
+ return;
+ // Distribute to percent columns.
+ if (percent_columns_count > 0) {
+ float scale = 1.0f;
+ bool scale_available = true;
+ // Percent columns only grow if there are no auto columns.
+ bool scale_up = total_percent_inline_size <
+ (target_inline_size - assigned_inline_size) &&
+ auto_columns_count == 0;
+ bool scale_down =
+ total_percent_inline_size > (target_inline_size - assigned_inline_size);
+ if (scale_up || scale_down) {
+ if (total_percent_inline_size != LayoutUnit()) {
+ scale = (target_inline_size - assigned_inline_size).ToFloat() /
+ total_percent_inline_size;
+ } else {
+ scale_available = false;
+ }
+ }
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ if (!column->percent)
+ continue;
+ last_distributed_column = column;
+ if (scale_available) {
+ column->computed_inline_size =
+ LayoutUnit(scale * *column->percent / 100 * target_inline_size);
+ } else {
+ column->computed_inline_size =
+ LayoutUnit((target_inline_size - assigned_inline_size).ToFloat() /
+ percent_columns_count);
+ }
+ assigned_inline_size += column->computed_inline_size;
+ }
+ }
+ // Distribute to auto columns.
+ LayoutUnit distributing_inline_size =
+ target_inline_size - assigned_inline_size;
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ if (column->percent || column->is_constrained)
+ continue;
+ last_distributed_column = column;
+ column->computed_inline_size =
+ LayoutUnit(distributing_inline_size / float(auto_columns_count));
+ assigned_inline_size += column->computed_inline_size;
+ }
+ LayoutUnit delta = target_inline_size - assigned_inline_size;
+ last_distributed_column->computed_inline_size += delta;
+}
+
+void DistributeColspanCellToColumnsFixed(
+ const NGTableTypes::ColspanCell& colspan_cell,
+ LayoutUnit inline_border_spacing,
+ NGTableTypes::Columns* column_constraints) {
+ // Fixed layout does not merge columns.
+ DCHECK_LE(colspan_cell.span,
+ column_constraints->size() - colspan_cell.start_column);
+ NGTableTypes::Column* start_column =
+ &(*column_constraints)[colspan_cell.start_column];
+ NGTableTypes::Column* end_column = start_column + colspan_cell.span;
+ DCHECK_NE(start_column, end_column);
+
+ LayoutUnit colspan_cell_min_inline_size;
+ LayoutUnit colspan_cell_max_inline_size;
+ if (colspan_cell.cell_inline_constraint.is_constrained) {
+ colspan_cell_min_inline_size =
+ (colspan_cell.cell_inline_constraint.min_inline_size -
+ (colspan_cell.span - 1) * inline_border_spacing)
+ .ClampNegativeToZero();
+ colspan_cell_max_inline_size =
+ (colspan_cell.cell_inline_constraint.max_inline_size -
+ (colspan_cell.span - 1) * inline_border_spacing)
+ .ClampNegativeToZero();
+ }
+
+ // Distribute min/max/percentage evenly between all cells.
+ // Colspanned cells only distribute min inline size if constrained.
+ LayoutUnit rounding_error_min_inline_size = colspan_cell_min_inline_size;
+ LayoutUnit rounding_error_max_inline_size = colspan_cell_max_inline_size;
+ float rounding_error_percent =
+ colspan_cell.cell_inline_constraint.percent.value_or(0.0f);
+
+ LayoutUnit new_min_size = LayoutUnit(colspan_cell_min_inline_size /
+ static_cast<float>(colspan_cell.span));
+ LayoutUnit new_max_size = LayoutUnit(colspan_cell_max_inline_size /
+ static_cast<float>(colspan_cell.span));
+ base::Optional<float> new_percent;
+ if (colspan_cell.cell_inline_constraint.percent) {
+ new_percent =
+ *colspan_cell.cell_inline_constraint.percent / colspan_cell.span;
+ }
+
+ NGTableTypes::Column* last_column;
+ for (NGTableTypes::Column* column = start_column; column < end_column;
+ ++column) {
+ last_column = column;
+ rounding_error_min_inline_size -= new_min_size;
+ rounding_error_max_inline_size -= new_max_size;
+ if (new_percent)
+ rounding_error_percent -= *new_percent;
+
+ if (!column->min_inline_size) {
+ column->is_constrained |=
+ colspan_cell.cell_inline_constraint.is_constrained;
+ column->min_inline_size = new_min_size;
+ }
+ if (!column->max_inline_size) {
+ column->is_constrained |=
+ colspan_cell.cell_inline_constraint.is_constrained;
+ column->max_inline_size = new_max_size;
+ }
+ if (!column->percent && new_percent)
+ column->percent = new_percent;
+ }
+ last_column->min_inline_size =
+ *last_column->min_inline_size + rounding_error_min_inline_size;
+ last_column->max_inline_size =
+ *last_column->max_inline_size + rounding_error_max_inline_size;
+ if (new_percent)
+ last_column->percent = *last_column->percent + rounding_error_percent;
+}
+
+void DistributeColspanCellToColumnsAuto(
+ const NGTableTypes::ColspanCell& colspan_cell,
+ LayoutUnit inline_border_spacing,
+ NGTableTypes::Columns* column_constraints) {
+ unsigned effective_span =
+ std::min(colspan_cell.span,
+ column_constraints->size() - colspan_cell.start_column);
+ NGTableTypes::Column* start_column =
+ &(*column_constraints)[colspan_cell.start_column];
+ NGTableTypes::Column* end_column = start_column + effective_span;
+
+ // Inline sizes for redistribution exclude border spacing.
+ LayoutUnit colspan_cell_min_inline_size =
+ (colspan_cell.cell_inline_constraint.min_inline_size -
+ (effective_span - 1) * inline_border_spacing)
+ .ClampNegativeToZero();
+ LayoutUnit colspan_cell_max_inline_size =
+ (colspan_cell.cell_inline_constraint.max_inline_size -
+ (effective_span - 1) * inline_border_spacing)
+ .ClampNegativeToZero();
+ base::Optional<float> colspan_cell_percent =
+ colspan_cell.cell_inline_constraint.percent;
+
+ if (colspan_cell_percent.has_value()) {
+ float columns_percent = 0.0f;
+ unsigned all_columns_count = 0;
+ unsigned percent_columns_count = 0;
+ unsigned nonpercent_columns_count = 0;
+ LayoutUnit nonpercent_columns_max_inline_size;
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ if (!column->max_inline_size)
+ column->max_inline_size = LayoutUnit();
+ if (!column->min_inline_size)
+ column->min_inline_size = LayoutUnit();
+ all_columns_count++;
+ if (column->percent) {
+ percent_columns_count++;
+ columns_percent += *column->percent;
+ } else {
+ nonpercent_columns_count++;
+ nonpercent_columns_max_inline_size += *column->max_inline_size;
+ }
+ }
+ float surplus_percent = *colspan_cell_percent - columns_percent;
+ if (surplus_percent > 0.0f && all_columns_count > percent_columns_count) {
+ // Distribute surplus percent to non-percent columns in proportion to
+ // max_inline_size.
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ if (column->percent)
+ continue;
+ float column_percent;
+ if (nonpercent_columns_max_inline_size != LayoutUnit()) {
+ // Column percentage is proportional to its max_inline_size.
+ column_percent = surplus_percent *
+ column->max_inline_size.value_or(LayoutUnit()) /
+ nonpercent_columns_max_inline_size;
+ } else {
+ // Distribute evenly instead.
+ // Legacy difference: Legacy forces max_inline_size to be at least
+ // 1px.
+ column_percent = surplus_percent / nonpercent_columns_count;
+ }
+ column->percent = column_percent;
+ }
+ }
+ }
+
+ // TODO(atotic) See crbug.com/531752 for discussion about differences
+ // between FF/Chrome.
+ // Minimum inline size gets distributed with standard distribution algorithm.
+ DistributeInlineSizeToComputedInlineSizeAuto(
+ colspan_cell_min_inline_size, inline_border_spacing, start_column,
+ end_column, column_constraints);
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ column->min_inline_size =
+ std::max(*column->min_inline_size, column->computed_inline_size);
+ }
+ DistributeInlineSizeToComputedInlineSizeAuto(
+ colspan_cell_max_inline_size, inline_border_spacing, start_column,
+ end_column, column_constraints);
+ for (NGTableTypes::Column* column = start_column; column != end_column;
+ ++column) {
+ column->max_inline_size =
+ std::max(*column->max_inline_size, column->computed_inline_size);
+ }
+}
+
+} // namespace
+
+void NGTableAlgorithmHelpers::DistributeColspanCellToColumns(
+ const NGTableTypes::ColspanCell& colspan_cell,
+ LayoutUnit inline_border_spacing,
+ bool is_fixed_layout,
+ NGTableTypes::Columns* column_constraints) {
+ // Clipped colspanned cells can end up having a span of 1 (which is not wide).
+ DCHECK_GT(colspan_cell.span, 1u);
+
+ if (is_fixed_layout) {
+ DistributeColspanCellToColumnsFixed(colspan_cell, inline_border_spacing,
+ column_constraints);
+ } else {
+ DistributeColspanCellToColumnsAuto(colspan_cell, inline_border_spacing,
+ column_constraints);
+ }
+}
+
+// Standard: https://www.w3.org/TR/css-tables-3/#width-distribution-algorithm
+// After synchroniziation, assignable table inline size and sum of column
+// final inline sizes will be equal.
+void NGTableAlgorithmHelpers::SynchronizeAssignableTableInlineSizeAndColumns(
+ LayoutUnit assignable_table_inline_size,
+ LayoutUnit inline_border_spacing,
+ bool is_fixed_layout,
+ NGTableTypes::Columns* column_constraints) {
+ if (column_constraints->size() == 0)
+ return;
+ NGTableTypes::Column* start_column = &(*column_constraints)[0];
+ NGTableTypes::Column* end_column = start_column + column_constraints->size();
+ if (is_fixed_layout) {
+ SynchronizeAssignableTableInlineSizeAndColumnsFixed(
+ assignable_table_inline_size, inline_border_spacing, start_column,
+ end_column);
+ } else {
+ DistributeInlineSizeToComputedInlineSizeAuto(
+ assignable_table_inline_size, inline_border_spacing, start_column,
+ end_column, column_constraints);
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h b/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h
new file mode 100644
index 00000000000..dd1d9f0e694
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h
@@ -0,0 +1,42 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_TABLE_NG_TABLE_LAYOUT_ALGORITHM_HELPERS_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_TABLE_NG_TABLE_LAYOUT_ALGORITHM_HELPERS_H_
+
+#include "third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h"
+#include "third_party/blink/renderer/core/style/computed_style_constants.h"
+
+namespace blink {
+
+// Table size distribution algorithms.
+class NGTableAlgorithmHelpers {
+ public:
+ // Compute maximum number of table columns that can deduced from
+ // single cell and its colspan.
+ static wtf_size_t ComputeMaxColumn(wtf_size_t current_column,
+ wtf_size_t colspan,
+ bool is_fixed_table_layout) {
+ // In fixed mode, every column is preserved.
+ if (is_fixed_table_layout)
+ return current_column + colspan;
+ return current_column + 1;
+ }
+
+ static void DistributeColspanCellToColumns(
+ const NGTableTypes::ColspanCell& colspan_cell,
+ LayoutUnit inline_border_spacing,
+ bool is_fixed_layout,
+ NGTableTypes::Columns* column_constraints);
+
+ static void SynchronizeAssignableTableInlineSizeAndColumns(
+ LayoutUnit assignable_table_inline_size,
+ LayoutUnit inline_border_spacing,
+ bool is_fixed_layout,
+ NGTableTypes::Columns* column_constraints);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_TABLE_NG_TABLE_LAYOUT_ALGORITHM_HELPERS_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc b/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc
new file mode 100644
index 00000000000..43df69d30d8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc
@@ -0,0 +1,360 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h"
+
+#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.h"
+#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h"
+#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.h"
+#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
+
+namespace blink {
+
+namespace {
+
+// Gathers css sizes. CSS values might be modified to enforce universal
+// invariants: css_max_inline_size >= css_min_inline_size
+// css_percentage_inline_size <= css_percentage_max_inline_size
+inline void InlineSizesFromStyle(
+ const ComputedStyle& style,
+ LayoutUnit inline_border_padding,
+ base::Optional<LayoutUnit>* inline_size,
+ base::Optional<LayoutUnit>* min_inline_size,
+ base::Optional<LayoutUnit>* max_inline_size,
+ base::Optional<float>* percentage_inline_size) {
+ const Length& length = style.LogicalWidth();
+ const Length& min_length = style.LogicalMinWidth();
+ const Length& max_length = style.LogicalMaxWidth();
+ bool is_content_box = style.BoxSizing() == EBoxSizing::kContentBox;
+ if (length.IsFixed()) {
+ *inline_size = LayoutUnit(length.Value());
+ if (is_content_box)
+ *inline_size = **inline_size + inline_border_padding;
+ }
+ if (min_length.IsFixed()) {
+ *min_inline_size = LayoutUnit(min_length.Value());
+ if (is_content_box)
+ *min_inline_size = **min_inline_size + inline_border_padding;
+ }
+ if (max_length.IsFixed()) {
+ *max_inline_size = LayoutUnit(max_length.Value());
+ if (is_content_box)
+ *max_inline_size = **max_inline_size + inline_border_padding;
+ if (*min_inline_size)
+ *max_inline_size = std::max(**min_inline_size, **max_inline_size);
+ }
+ if (length.IsPercent())
+ *percentage_inline_size = length.Percent();
+ if (*percentage_inline_size && max_length.IsPercent()) {
+ *percentage_inline_size =
+ std::min(**percentage_inline_size, max_length.Percent());
+ }
+ if (*min_inline_size && *max_inline_size)
+ DCHECK_GE(**max_inline_size, **min_inline_size);
+}
+
+} // namespace
+
+constexpr LayoutUnit NGTableTypes::kTableMaxInlineSize;
+
+// Implements https://www.w3.org/TR/css-tables-3/#computing-cell-measures
+// "outer min-content and outer max-content widths for colgroups"
+NGTableTypes::Column NGTableTypes::CreateColumn(
+ const ComputedStyle& style,
+ bool is_fixed_layout,
+ base::Optional<LayoutUnit> default_inline_size) {
+ base::Optional<LayoutUnit> inline_size;
+ base::Optional<LayoutUnit> min_inline_size;
+ base::Optional<LayoutUnit> max_inline_size;
+ base::Optional<float> percentage_inline_size;
+ InlineSizesFromStyle(style, LayoutUnit(), &inline_size, &min_inline_size,
+ &max_inline_size, &percentage_inline_size);
+ if (!inline_size)
+ inline_size = default_inline_size;
+ if (min_inline_size && inline_size)
+ inline_size = std::max(*inline_size, *min_inline_size);
+ bool is_constrained = inline_size.has_value();
+ if (percentage_inline_size && *percentage_inline_size == 0.0f)
+ percentage_inline_size.reset();
+ return Column{min_inline_size.value_or(LayoutUnit()), inline_size,
+ percentage_inline_size, is_constrained, kIndefiniteSize};
+}
+
+// Implements https://www.w3.org/TR/css-tables-3/#computing-cell-measures
+// "outer min-content and outer max-content widths for table cells"
+// Note: this method calls NGBlockNode::ComputeMinMaxSizes.
+NGTableTypes::CellInlineConstraint NGTableTypes::CreateCellInlineConstraint(
+ const NGLayoutInputNode& node,
+ WritingMode table_writing_mode,
+ bool is_fixed_layout,
+ const NGBoxStrut& cell_border,
+ const NGBoxStrut& cell_padding,
+ bool is_collapsed) {
+ base::Optional<LayoutUnit> css_inline_size;
+ base::Optional<LayoutUnit> css_min_inline_size;
+ base::Optional<LayoutUnit> css_max_inline_size;
+ base::Optional<float> css_percentage_inline_size;
+
+ // Algorithm:
+ // - Compute cell's minmax sizes.
+ // - Constrain by css inline-size/max-inline-size.
+ InlineSizesFromStyle(node.Style(), (cell_border + cell_padding).InlineSum(),
+ &css_inline_size, &css_min_inline_size,
+ &css_max_inline_size, &css_percentage_inline_size);
+
+ MinMaxSizesInput input(kIndefiniteSize, MinMaxSizesType::kContent);
+ MinMaxSizesResult min_max_size;
+ if (is_collapsed) {
+ NGConstraintSpaceBuilder builder(table_writing_mode,
+ node.Style().GetWritingMode(),
+ /* is_new_fc */ false);
+ builder.SetTableCellBorders(cell_border);
+ builder.SetIsTableCell(true);
+ NGConstraintSpace space = builder.ToConstraintSpace();
+ // It'd be nice to avoid computing minmax if not needed, but the criteria
+ // is not clear.
+ min_max_size = To<NGBlockNode>(node).ComputeMinMaxSizes(table_writing_mode,
+ input, &space);
+ } else {
+ min_max_size = node.ComputeMinMaxSizes(table_writing_mode, input);
+ }
+
+ // Compute min inline size.
+ LayoutUnit resolved_min_inline_size;
+ if (!is_fixed_layout) {
+ resolved_min_inline_size =
+ std::max(min_max_size.sizes.min_size,
+ css_min_inline_size.value_or(LayoutUnit()));
+ // https://quirks.spec.whatwg.org/#the-table-cell-nowrap-minimum-width-calculation-quirk
+ if (css_inline_size && node.GetDocument().InQuirksMode()) {
+ bool has_nowrap_attribute =
+ !To<Element>(node.GetLayoutBox()->GetNode())
+ ->FastGetAttribute(html_names::kNowrapAttr)
+ .IsNull();
+ if (has_nowrap_attribute && node.Style().AutoWrap()) {
+ resolved_min_inline_size =
+ std::max(resolved_min_inline_size, *css_inline_size);
+ }
+ }
+ }
+
+ // Compute resolved max inline size.
+ LayoutUnit content_max;
+ if (css_inline_size) {
+ content_max = *css_inline_size;
+ } else {
+ content_max = min_max_size.sizes.max_size;
+ }
+ if (css_max_inline_size)
+ content_max = std::min(content_max, *css_max_inline_size);
+ LayoutUnit resolved_max_inline_size =
+ std::max(resolved_min_inline_size, content_max);
+
+ bool is_constrained = css_inline_size.has_value();
+
+ DCHECK_LE(resolved_min_inline_size, resolved_max_inline_size);
+ return NGTableTypes::CellInlineConstraint{
+ resolved_min_inline_size, resolved_max_inline_size,
+ css_percentage_inline_size, is_constrained};
+}
+
+NGTableTypes::Section NGTableTypes::CreateSection(
+ const NGLayoutInputNode& section,
+ wtf_size_t start_row,
+ wtf_size_t rows,
+ LayoutUnit block_size) {
+ const Length& section_css_block_size = section.Style().LogicalHeight();
+ bool is_constrained = section_css_block_size.IsSpecified();
+ base::Optional<float> percent;
+ if (section_css_block_size.IsPercent())
+ percent = section_css_block_size.Percent();
+ bool is_tbody =
+ section.GetLayoutBox()->GetNode()->HasTagName(html_names::kTbodyTag);
+ return Section{start_row,
+ rows,
+ block_size,
+ percent,
+ is_constrained,
+ is_tbody,
+ /* needs_redistribution */ false};
+}
+
+NGTableTypes::CellBlockConstraint NGTableTypes::CreateCellBlockConstraint(
+ const NGLayoutInputNode& node,
+ LayoutUnit computed_block_size,
+ LayoutUnit baseline,
+ const NGBoxStrut& border_box_borders,
+ wtf_size_t row_index,
+ wtf_size_t column_index,
+ wtf_size_t rowspan) {
+ bool is_constrained = node.Style().LogicalHeight().IsFixed();
+ return CellBlockConstraint{computed_block_size,
+ baseline,
+ border_box_borders,
+ row_index,
+ column_index,
+ rowspan,
+ node.Style().VerticalAlign(),
+ is_constrained};
+}
+
+NGTableTypes::RowspanCell NGTableTypes::CreateRowspanCell(
+ wtf_size_t row_index,
+ wtf_size_t rowspan,
+ CellBlockConstraint* cell_block_constraint,
+ base::Optional<LayoutUnit> css_cell_block_size) {
+ if (css_cell_block_size) {
+ cell_block_constraint->min_block_size =
+ std::max(cell_block_constraint->min_block_size, *css_cell_block_size);
+ }
+ return RowspanCell{row_index, rowspan, *cell_block_constraint};
+}
+
+void NGTableTypes::CellInlineConstraint::Encompass(
+ const NGTableTypes::CellInlineConstraint& other) {
+ // Standard says:
+ // "A column is constrained if any of the cells spanning only that column has
+ // a computed width that is not "auto", and is not a percentage. This means
+ // that <td width=50></td><td max-width=100> would be treated with constrained
+ // column with width of 100.
+ if (other.min_inline_size > min_inline_size)
+ min_inline_size = other.min_inline_size;
+ if (is_constrained == other.is_constrained) {
+ max_inline_size = std::max(max_inline_size, other.max_inline_size);
+ } else if (is_constrained) {
+ max_inline_size = std::max(max_inline_size, other.min_inline_size);
+ } else {
+ DCHECK(other.is_constrained);
+ max_inline_size = std::max(min_inline_size, other.max_inline_size);
+ }
+ is_constrained = is_constrained || other.is_constrained;
+ max_inline_size = std::max(max_inline_size, other.max_inline_size);
+ percent = std::max(percent, other.percent);
+}
+
+void NGTableTypes::Column::Encompass(
+ const base::Optional<NGTableTypes::CellInlineConstraint>& cell) {
+ if (!cell)
+ return;
+
+ if (min_inline_size) {
+ if (min_inline_size < cell->min_inline_size) {
+ min_inline_size = cell->min_inline_size;
+ }
+ if (is_constrained) {
+ if (cell->is_constrained)
+ max_inline_size = std::max(*max_inline_size, cell->max_inline_size);
+ else
+ max_inline_size = std::max(*max_inline_size, cell->min_inline_size);
+ } else { // !is_constrained
+ max_inline_size = std::max(max_inline_size.value_or(LayoutUnit()),
+ cell->max_inline_size);
+ }
+ } else {
+ min_inline_size = cell->min_inline_size;
+ max_inline_size = cell->max_inline_size;
+ }
+ if (min_inline_size && max_inline_size) {
+ max_inline_size = std::max(*min_inline_size, *max_inline_size);
+ }
+ if (percent) {
+ if (cell->percent)
+ percent = std::max(*cell->percent, *percent);
+ } else {
+ percent = cell->percent;
+ }
+ is_constrained |= cell->is_constrained;
+}
+
+NGTableGroupedChildren::NGTableGroupedChildren(const NGBlockNode& table) {
+ for (NGLayoutInputNode child = table.FirstChild(); child;
+ child = child.NextSibling()) {
+ NGBlockNode block_child = To<NGBlockNode>(child);
+ if (block_child.IsTableCaption()) {
+ captions.push_back(block_child);
+ } else {
+ switch (child.Style().Display()) {
+ case EDisplay::kTableColumn:
+ case EDisplay::kTableColumnGroup:
+ columns.push_back(block_child);
+ break;
+ case EDisplay::kTableHeaderGroup:
+ headers.push_back(block_child);
+ break;
+ case EDisplay::kTableRowGroup:
+ bodies.push_back(block_child);
+ break;
+ case EDisplay::kTableFooterGroup:
+ footers.push_back(block_child);
+ break;
+ default:
+ NOTREACHED() << "unexpected table child";
+ }
+ }
+ }
+}
+
+NGTableGroupedChildrenIterator NGTableGroupedChildren::begin() const {
+ return NGTableGroupedChildrenIterator(*this);
+}
+
+NGTableGroupedChildrenIterator NGTableGroupedChildren::end() const {
+ return NGTableGroupedChildrenIterator(*this, /* is_end */ true);
+}
+
+NGTableGroupedChildrenIterator::NGTableGroupedChildrenIterator(
+ const NGTableGroupedChildren& grouped_children,
+ bool is_end)
+ : grouped_children_(grouped_children), current_vector_(nullptr) {
+ if (is_end) {
+ current_vector_ = &grouped_children_.footers;
+ current_iterator_ = current_vector_->end();
+ return;
+ }
+ AdvanceToNonEmptySection();
+}
+
+NGTableGroupedChildrenIterator& NGTableGroupedChildrenIterator::operator++() {
+ ++current_iterator_;
+ if (current_iterator_ == current_vector_->end())
+ AdvanceToNonEmptySection();
+ return *this;
+}
+
+NGBlockNode NGTableGroupedChildrenIterator::operator*() const {
+ return *current_iterator_;
+}
+
+bool NGTableGroupedChildrenIterator::operator==(
+ const NGTableGroupedChildrenIterator& rhs) const {
+ return rhs.current_vector_ == current_vector_ &&
+ rhs.current_iterator_ == current_iterator_;
+}
+
+bool NGTableGroupedChildrenIterator::operator!=(
+ const NGTableGroupedChildrenIterator& rhs) const {
+ return !(*this == rhs);
+}
+
+void NGTableGroupedChildrenIterator::AdvanceToNonEmptySection() {
+ if (current_vector_ == &grouped_children_.footers)
+ return;
+ if (!current_vector_) {
+ current_vector_ = &grouped_children_.headers;
+ } else if (current_vector_ == &grouped_children_.headers) {
+ current_vector_ = &grouped_children_.bodies;
+ } else if (current_vector_ == &grouped_children_.bodies) {
+ current_vector_ = &grouped_children_.footers;
+ }
+ current_iterator_ = current_vector_->begin();
+ // If new group is empty, recursively advance.
+ if (current_iterator_ == current_vector_->end()) {
+ AdvanceToNonEmptySection();
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h b/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h
new file mode 100644
index 00000000000..715a7337dd3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h
@@ -0,0 +1,287 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_TABLE_NG_TABLE_LAYOUT_ALGORITHM_TYPES_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_TABLE_NG_TABLE_LAYOUT_ALGORITHM_TYPES_H_
+
+#include "base/optional.h"
+#include "third_party/blink/renderer/core/layout/min_max_sizes.h"
+#include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h"
+#include "third_party/blink/renderer/core/style/computed_style_constants.h"
+#include "third_party/blink/renderer/platform/geometry/length.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+class ComputedStyle;
+class NGBlockNode;
+class NGLayoutInputNode;
+
+// Define constraint classes for NGTableLayoutAlgorithm.
+class NGTableTypes {
+ public:
+ static constexpr LayoutUnit kTableMaxInlineSize = LayoutUnit::Max();
+
+ // Inline constraint for a single cell.
+ // Takes into account the cell style, and min/max content-sizes.
+ struct CellInlineConstraint {
+ DISALLOW_NEW();
+ LayoutUnit min_inline_size;
+ LayoutUnit max_inline_size;
+ base::Optional<float> percent; // 100% is stored as 100.0f
+ bool is_constrained; // True if this cell has a specified inline-size.
+
+ void Encompass(const CellInlineConstraint&);
+ };
+
+ // Inline constraints for a cell that span multiple columns.
+ struct ColspanCell {
+ DISALLOW_NEW();
+ CellInlineConstraint cell_inline_constraint;
+ wtf_size_t start_column;
+ wtf_size_t span;
+ ColspanCell(const CellInlineConstraint& cell_inline_constraint,
+ unsigned start_column,
+ unsigned span)
+ : cell_inline_constraint(cell_inline_constraint),
+ start_column(start_column),
+ span(span) {}
+ // ColspanCells are distributed in column order.
+ bool operator<(const NGTableTypes::ColspanCell& rhs) const {
+ // '<' means left to right sort.
+ // Legacy sorts right-to-left, FF, Edge left-to-right.
+ if (span == rhs.span)
+ return start_column < rhs.start_column;
+ return span < rhs.span;
+ }
+ };
+
+ // Constraint for a column.
+ struct Column {
+ DISALLOW_NEW();
+ // These members are initialized from <col> and <colgroup>, then they
+ // accumulate data from |CellInlineConstraint|s.
+ base::Optional<LayoutUnit> min_inline_size;
+ base::Optional<LayoutUnit> max_inline_size;
+ base::Optional<float> percent; // 100% is stored as 100.0f
+ // True if any cell for this column is constrained.
+ bool is_constrained = false;
+
+ // The final inline-size of the column after all constraints have been
+ // applied.
+ LayoutUnit computed_inline_size;
+ void Encompass(const base::Optional<NGTableTypes::CellInlineConstraint>&);
+ LayoutUnit ResolvePercentInlineSize(
+ LayoutUnit percentage_resolution_inline_size) {
+ return std::max(
+ min_inline_size.value_or(LayoutUnit()),
+ LayoutUnit(*percent * percentage_resolution_inline_size / 100));
+ }
+ bool IsFixed() const {
+ return is_constrained && !percent && max_inline_size;
+ }
+ };
+
+ // Block constraint for a single cell.
+ struct CellBlockConstraint {
+ DISALLOW_NEW();
+ LayoutUnit min_block_size;
+ LayoutUnit baseline;
+ NGBoxStrut border_box_borders;
+ wtf_size_t row_index;
+ wtf_size_t column_index;
+ wtf_size_t rowspan;
+ EVerticalAlign vertical_align;
+ bool is_constrained; // True if this cell has a specified block-size.
+ CellBlockConstraint(LayoutUnit min_block_size,
+ LayoutUnit baseline,
+ NGBoxStrut border_box_borders,
+ wtf_size_t row_index,
+ wtf_size_t column_index,
+ wtf_size_t rowspan,
+ EVerticalAlign vertical_align,
+ bool is_constrained)
+ : min_block_size(min_block_size),
+ baseline(baseline),
+ border_box_borders(border_box_borders),
+ row_index(row_index),
+ column_index(column_index),
+ rowspan(rowspan),
+ vertical_align(vertical_align),
+ is_constrained(is_constrained) {}
+ };
+
+ // RowspanCells span multiple rows.
+ struct RowspanCell {
+ DISALLOW_NEW();
+ CellBlockConstraint cell_block_constraint;
+ wtf_size_t start_row;
+ wtf_size_t span;
+ RowspanCell(wtf_size_t start_row,
+ wtf_size_t span,
+ const CellBlockConstraint& cell_block_constraint)
+ : cell_block_constraint(cell_block_constraint),
+ start_row(start_row),
+ span(span) {}
+
+ // Original Legacy sorting criteria from
+ // CompareRowspanCellsInHeightDistributionOrder
+ bool operator<(const NGTableTypes::RowspanCell& rhs) const {
+ // Returns true if a |RowspanCell| is completely contained within another
+ // |RowspanCell|.
+ auto IsEnclosed = [](const NGTableTypes::RowspanCell& c1,
+ const NGTableTypes::RowspanCell& c2) {
+ return (c1.start_row >= c2.start_row) &&
+ (c1.start_row + c1.span) <= (c2.start_row + c2.span);
+ };
+
+ // If cells span the same rows, bigger cell is distributed first.
+ if (start_row == rhs.start_row && span == rhs.span) {
+ return cell_block_constraint.min_block_size >
+ rhs.cell_block_constraint.min_block_size;
+ }
+ // If one cell is fully enclosed by another, inner cell wins.
+ if (IsEnclosed(*this, rhs))
+ return true;
+ if (IsEnclosed(rhs, *this))
+ return false;
+ // Lower rows wins.
+ return start_row < rhs.start_row;
+ }
+ };
+
+ struct Row {
+ DISALLOW_NEW();
+ LayoutUnit block_size;
+ LayoutUnit baseline;
+ base::Optional<float> percent; // 100% is stored as 100.0f
+ wtf_size_t start_cell_index;
+ wtf_size_t cell_count;
+ // |is_constrained| is true if row has specified block-size, or contains
+ // constrained cells.
+ bool is_constrained;
+ bool has_baseline_aligned_percentage_block_size_descendants;
+ bool has_rowspan_start; // True if row originates a TD with rowspan > 1
+ bool is_collapsed;
+ };
+
+ struct ColumnLocation {
+ LayoutUnit offset; // inline offset from table edge.
+ LayoutUnit size;
+ };
+
+ struct Section {
+ wtf_size_t start_row;
+ wtf_size_t rowspan;
+ LayoutUnit block_size;
+ base::Optional<float> percent;
+ bool is_constrained;
+ bool is_tbody;
+ bool needs_redistribution;
+ };
+
+ static Column CreateColumn(const ComputedStyle&,
+ bool is_fixed_layout,
+ base::Optional<LayoutUnit> default_inline_size);
+
+ static CellInlineConstraint CreateCellInlineConstraint(
+ const NGLayoutInputNode&,
+ WritingMode table_writing_mode,
+ bool is_fixed_layout,
+ const NGBoxStrut& cell_border,
+ const NGBoxStrut& cell_padding,
+ bool is_collapsed);
+
+ static Section CreateSection(const NGLayoutInputNode&,
+ wtf_size_t start_row,
+ wtf_size_t rowspan,
+ LayoutUnit block_size);
+
+ static CellBlockConstraint CreateCellBlockConstraint(
+ const NGLayoutInputNode&,
+ LayoutUnit computed_block_size,
+ LayoutUnit baseline,
+ const NGBoxStrut& border_box_borders,
+ wtf_size_t row_index,
+ wtf_size_t column_index,
+ wtf_size_t rowspan);
+
+ static RowspanCell CreateRowspanCell(
+ wtf_size_t row_index,
+ wtf_size_t rowspan,
+ CellBlockConstraint*,
+ base::Optional<LayoutUnit> css_block_size);
+
+ using Columns = Vector<Column>;
+ // Inline constraints are optional because we need to distinguish between an
+ // empty cell, and a non-existent cell.
+ using CellInlineConstraints = Vector<base::Optional<CellInlineConstraint>>;
+ using ColspanCells = Vector<ColspanCell>;
+ using Caption = MinMaxSizes;
+ using CellBlockConstraints = Vector<CellBlockConstraint>;
+ using RowspanCells = Vector<RowspanCell>;
+ using Rows = Vector<Row>;
+ using Sections = Vector<Section>;
+ using ColumnLocations = Vector<ColumnLocation>;
+};
+
+class NGTableGroupedChildrenIterator;
+
+// Table's children grouped by type.
+// When iterating through members, make sure to handle out_of_flows correctly.
+struct NGTableGroupedChildren {
+ DISALLOW_NEW();
+
+ public:
+ explicit NGTableGroupedChildren(const NGBlockNode& table);
+
+ Vector<NGBlockNode> captions; // CAPTION
+ Vector<NGBlockNode> columns; // COLGROUP, COL
+
+ Vector<NGBlockNode> headers; // THEAD
+ Vector<NGBlockNode> bodies; // TBODY
+ Vector<NGBlockNode> footers; // TFOOT
+
+ // Default iterators iterate over tbody-like (THEAD/TBODY/TFOOT) elements.
+ NGTableGroupedChildrenIterator begin() const;
+ NGTableGroupedChildrenIterator end() const;
+};
+
+// Iterates table's sections in order:
+// thead, tbody, tfoot
+class NGTableGroupedChildrenIterator {
+ public:
+ explicit NGTableGroupedChildrenIterator(
+ const NGTableGroupedChildren& grouped_children,
+ bool is_end = false);
+
+ NGTableGroupedChildrenIterator& operator++();
+ NGBlockNode operator*() const;
+ bool operator==(const NGTableGroupedChildrenIterator& rhs) const;
+ bool operator!=(const NGTableGroupedChildrenIterator& rhs) const;
+
+ private:
+ void AdvanceToNonEmptySection();
+ const NGTableGroupedChildren& grouped_children_;
+ const Vector<NGBlockNode>* current_vector_;
+ Vector<NGBlockNode>::const_iterator current_iterator_;
+};
+
+} // namespace blink
+
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
+ blink::NGTableTypes::CellInlineConstraint)
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
+ blink::NGTableTypes::ColspanCell)
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::NGTableTypes::Column)
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
+ blink::NGTableTypes::CellBlockConstraint)
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
+ blink::NGTableTypes::RowspanCell)
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::NGTableTypes::Row)
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
+ blink::NGTableTypes::ColumnLocation)
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::NGTableTypes::Section)
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_TABLE_NG_TABLE_LAYOUT_ALGORITHM_TYPES_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/paint_containment_test.cc b/chromium/third_party/blink/renderer/core/layout/paint_containment_test.cc
index ed44fd54edb..ba4f6fc31d6 100644
--- a/chromium/third_party/blink/renderer/core/layout/paint_containment_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/paint_containment_test.cc
@@ -28,7 +28,7 @@ static void CheckIsClippingStackingContextAndContainer(
// clipping and stacking performed by paint containment.
DCHECK(obj.Layer());
PaintLayer* layer = obj.Layer();
- EXPECT_TRUE(layer->GetLayoutObject().StyleRef().IsStackingContext());
+ EXPECT_TRUE(layer->GetLayoutObject().IsStackingContext());
}
TEST_F(PaintContainmentTest, BlockPaintContainment) {
diff --git a/chromium/third_party/blink/renderer/core/layout/scroll_anchor.cc b/chromium/third_party/blink/renderer/core/layout/scroll_anchor.cc
index 3cc716658b7..117a16a2e5c 100644
--- a/chromium/third_party/blink/renderer/core/layout/scroll_anchor.cc
+++ b/chromium/third_party/blink/renderer/core/layout/scroll_anchor.cc
@@ -84,7 +84,10 @@ static LayoutRect RelativeBounds(const LayoutObject* layout_object,
PhysicalRect local_bounds;
if (layout_object->IsBox()) {
local_bounds = ToLayoutBox(layout_object)->PhysicalBorderBoxRect();
- if (!layout_object->HasOverflowClip()) {
+ // If we clip overflow then we can use the `PhysicalBorderBoxRect()`
+ // as our bounds. If not, we expand the bounds by the layout overflow and
+ // lowest floating object.
+ if (!layout_object->ShouldClipOverflow()) {
// BorderBoxRect doesn't include overflow content and floats.
LayoutUnit max_y =
std::max(local_bounds.Bottom(),
diff --git a/chromium/third_party/blink/renderer/core/layout/scroll_anchor.h b/chromium/third_party/blink/renderer/core/layout/scroll_anchor.h
index 463b1749bfe..bd1cdfb3f03 100644
--- a/chromium/third_party/blink/renderer/core/layout/scroll_anchor.h
+++ b/chromium/third_party/blink/renderer/core/layout/scroll_anchor.h
@@ -108,7 +108,7 @@ class CORE_EXPORT ScrollAnchor final {
// Notifies us that an object will be removed from the layout tree.
void NotifyRemoved(LayoutObject*);
- void Trace(Visitor* visitor) { visitor->Trace(scroller_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(scroller_); }
private:
void FindAnchor();
diff --git a/chromium/third_party/blink/renderer/core/layout/scroll_anchor_test.cc b/chromium/third_party/blink/renderer/core/layout/scroll_anchor_test.cc
index 02472dc4cc3..0272d82efb7 100644
--- a/chromium/third_party/blink/renderer/core/layout/scroll_anchor_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/scroll_anchor_test.cc
@@ -536,64 +536,6 @@ TEST_P(ScrollAnchorTest, FlexboxDelayedAdjustmentRespectsSANACLAP) {
EXPECT_EQ(100, ScrollerForElement(scroller)->ScrollOffsetInt().Height());
}
-// TODO(skobes): Convert this to web-platform-tests when document.rootScroller
-// is launched (http://crbug.com/505516).
-TEST_P(ScrollAnchorTest, NonDefaultRootScroller) {
- SetBodyInnerHTML(R"HTML(
- <style>
- ::-webkit-scrollbar {
- width: 0px; height: 0px;
- }
- body, html {
- margin: 0px; width: 100%; height: 100%;
- }
- #rootscroller {
- overflow: scroll; width: 100%; height: 100%;
- }
- .spacer {
- height: 600px; width: 100px;
- }
- #target {
- height: 100px; width: 100px; background-color: red;
- }
- </style>
- <div id='rootscroller'>
- <div id='firstChild' class='spacer'></div>
- <div id='target'></div>
- <div class='spacer'></div>
- </div>
- <div class='spacer'></div>
- )HTML");
-
- Element* root_scroller_element = GetDocument().getElementById("rootscroller");
-
- NonThrowableExceptionState non_throw;
- GetDocument().setRootScroller(root_scroller_element, non_throw);
- UpdateAllLifecyclePhasesForTest();
-
- ScrollableArea* scroller = ScrollerForElement(root_scroller_element);
-
- // By making the #rootScroller DIV the rootScroller, it should become the
- // layout viewport on the RootFrameViewport.
- ASSERT_EQ(scroller,
- &GetDocument().View()->GetRootFrameViewport()->LayoutViewport());
-
- // The #rootScroller DIV's anchor should have the RootFrameViewport set as
- // the scroller, rather than the FrameView's anchor.
-
- root_scroller_element->setScrollTop(600);
-
- SetHeight(GetDocument().getElementById("firstChild"), 1000);
-
- // Scroll anchoring should be applied to #rootScroller.
- EXPECT_EQ(1000, scroller->GetScrollOffset().Height());
- EXPECT_EQ(GetDocument().getElementById("target")->GetLayoutObject(),
- GetScrollAnchor(scroller).AnchorObject());
- // Scroll anchoring should not apply within main frame.
- EXPECT_EQ(0, LayoutViewport()->GetScrollOffset().Height());
- EXPECT_EQ(nullptr, GetScrollAnchor(LayoutViewport()).AnchorObject());
-}
-
// This test verifies that scroll anchoring is disabled when the document is in
// printing mode.
TEST_P(ScrollAnchorTest, AnchoringDisabledForPrinting) {
@@ -1131,19 +1073,19 @@ class ScrollAnchorFindInPageTest : public testing::Test {
test::RunPendingTasks();
}
- mojom::blink::FindOptionsPtr FindOptions(bool find_next = false) {
+ mojom::blink::FindOptionsPtr FindOptions(bool new_session = true) {
auto find_options = mojom::blink::FindOptions::New();
find_options->run_synchronously_for_testing = true;
- find_options->find_next = find_next;
+ find_options->new_session = new_session;
find_options->forward = true;
return find_options;
}
void Find(String search_text,
ScrollAnchorTestFindInPageClient& client,
- bool find_next = false) {
+ bool new_session = true) {
client.Reset();
- GetFindInPage()->Find(FAKE_FIND_ID, search_text, FindOptions(find_next));
+ GetFindInPage()->Find(FAKE_FIND_ID, search_text, FindOptions(new_session));
test::RunPendingTasks();
}
diff --git a/chromium/third_party/blink/renderer/core/layout/scrollbars_test.cc b/chromium/third_party/blink/renderer/core/layout/scrollbars_test.cc
index 455216a3abc..e5737780c21 100644
--- a/chromium/third_party/blink/renderer/core/layout/scrollbars_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/scrollbars_test.cc
@@ -2698,6 +2698,80 @@ TEST_F(ScrollbarsTest, CheckScrollCornerIfThereIsNoScrollbar) {
EXPECT_FALSE(scrollable_container->ScrollCorner());
}
+TEST_F(ScrollbarsTest, NoNeedsBeginFrameForCustomScrollbarAfterBeginFrame) {
+ WebView().MainFrameWidget()->Resize(WebSize(200, 200));
+
+ SimRequest request("https://example.com/test.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ ::-webkit-scrollbar { height: 20px; }
+ ::-webkit-scrollbar-thumb { background-color: blue; }
+ #target { width: 200px; height: 200px; overflow: scroll; }
+ </style>
+ <div id="target">
+ <div style="width: 500px; height: 500px"></div>
+ </div>
+ )HTML");
+
+ while (Compositor().NeedsBeginFrame())
+ Compositor().BeginFrame();
+
+ auto* target = GetDocument().getElementById("target");
+ auto* scrollbar = To<CustomScrollbar>(
+ target->GetLayoutBox()->GetScrollableArea()->HorizontalScrollbar());
+ LayoutCustomScrollbarPart* thumb = scrollbar->GetPart(kThumbPart);
+ auto thumb_size = thumb->Size();
+ EXPECT_FALSE(thumb->ShouldCheckForPaintInvalidation());
+ EXPECT_FALSE(Compositor().NeedsBeginFrame());
+
+ WebView().MainFrameWidget()->UpdateAllLifecyclePhases(
+ DocumentUpdateReason::kTest);
+ EXPECT_FALSE(thumb->ShouldCheckForPaintInvalidation());
+ EXPECT_FALSE(Compositor().NeedsBeginFrame());
+
+ target->setAttribute(html_names::kStyleAttr, "width: 400px");
+ EXPECT_TRUE(Compositor().NeedsBeginFrame());
+ Compositor().BeginFrame();
+ EXPECT_FALSE(thumb->ShouldCheckForPaintInvalidation());
+ EXPECT_FALSE(Compositor().NeedsBeginFrame());
+ EXPECT_NE(thumb_size, thumb->Size());
+}
+
+TEST_F(ScrollbarsTest, CustomScrollbarHypotheticalThickness) {
+ WebView().MainFrameWidget()->Resize(WebSize(200, 200));
+
+ SimRequest request("https://example.com/test.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ #target1::-webkit-scrollbar { width: 22px; height: 33px; }
+ #target2::-webkit-scrollbar:horizontal { height: 13px; }
+ ::-webkit-scrollbar:vertical { width: 21px; }
+ </style>
+ <div id="target1" style="width: 60px; height: 70px; overflow: scroll"></div>
+ <div id="target2" style="width: 80px; height: 90px; overflow: scroll"></div>
+ )HTML");
+
+ Compositor().BeginFrame();
+
+ auto* target1 = GetDocument().getElementById("target1");
+ auto* scrollable_area1 = target1->GetLayoutBox()->GetScrollableArea();
+ EXPECT_EQ(33, CustomScrollbar::HypotheticalScrollbarThickness(
+ scrollable_area1, kHorizontalScrollbar, target1));
+ EXPECT_EQ(22, CustomScrollbar::HypotheticalScrollbarThickness(
+ scrollable_area1, kVerticalScrollbar, target1));
+
+ auto* target2 = GetDocument().getElementById("target2");
+ auto* scrollable_area2 = target2->GetLayoutBox()->GetScrollableArea();
+ EXPECT_EQ(13, CustomScrollbar::HypotheticalScrollbarThickness(
+ scrollable_area2, kHorizontalScrollbar, target2));
+ EXPECT_EQ(21, CustomScrollbar::HypotheticalScrollbarThickness(
+ scrollable_area2, kVerticalScrollbar, target2));
+}
+
// For infinite scrolling page (load more content when scroll to bottom), user
// press on scrollbar button should keep scrolling after content loaded.
// Disable on Android since VirtualTime not work for Android.
@@ -2776,7 +2850,7 @@ TEST_F(ScrollbarsTestWithVirtualTimer,
// Verify that the scrollbar autopress timer requested some scrolls via
// gestures. The button was pressed for 2 seconds and the timer fires
// every 250ms - we should have at least 7 injected gesture updates.
- EXPECT_GT(WebWidgetClient().GetInjectedScrollGestureData().size(), 6u);
+ EXPECT_GT(WebWidgetClient().GetInjectedScrollEvents().size(), 6u);
}
class ScrollbarTrackMarginsTest : public ScrollbarsTest {
diff --git a/chromium/third_party/blink/renderer/core/layout/shapes/shape_outside_info.cc b/chromium/third_party/blink/renderer/core/layout/shapes/shape_outside_info.cc
index c9f477b2f0d..671fc265eb7 100644
--- a/chromium/third_party/blink/renderer/core/layout/shapes/shape_outside_info.cc
+++ b/chromium/third_party/blink/renderer/core/layout/shapes/shape_outside_info.cc
@@ -148,11 +148,11 @@ static bool CheckShapeImageOrigin(Document& document,
return true;
DCHECK(style_image.CachedImage());
- ImageResourceContent& image_resource = *(style_image.CachedImage());
- if (image_resource.IsAccessAllowed())
+ ImageResourceContent& image_content = *(style_image.CachedImage());
+ if (image_content.IsAccessAllowed())
return true;
- const KURL& url = image_resource.Url();
+ const KURL& url = image_content.Url();
String url_string = url.IsNull() ? "''" : url.ElidedString();
document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc
index 3d6fea7918c..0b8eb05e084 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc
@@ -28,13 +28,16 @@
#include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources_cache.h"
+#include "third_party/blink/renderer/core/layout/svg/transform_helper.h"
#include "third_party/blink/renderer/core/style/shadow_list.h"
#include "third_party/blink/renderer/core/svg/svg_element.h"
namespace blink {
LayoutSVGBlock::LayoutSVGBlock(SVGElement* element)
- : LayoutBlockFlow(element) {}
+ : LayoutBlockFlow(element),
+ needs_transform_update_(true),
+ transform_uses_reference_box_(false) {}
SVGElement* LayoutSVGBlock::GetElement() const {
return To<SVGElement>(LayoutObject::GetNode());
@@ -51,8 +54,40 @@ void LayoutSVGBlock::UpdateFromStyle() {
SetFloating(false);
}
+bool LayoutSVGBlock::CheckForImplicitTransformChange(bool bbox_changed) const {
+ // If the transform is relative to the reference box, check relevant
+ // conditions to see if we need to recompute the transform.
+ switch (StyleRef().TransformBox()) {
+ case ETransformBox::kViewBox:
+ return SVGLayoutSupport::LayoutSizeOfNearestViewportChanged(this);
+ case ETransformBox::kFillBox:
+ return bbox_changed;
+ }
+ NOTREACHED();
+ return false;
+}
+
+bool LayoutSVGBlock::UpdateTransformAfterLayout(bool bounds_changed) {
+ // If our transform depends on the reference box, we need to check if it needs
+ // to be updated.
+ if (!needs_transform_update_ && transform_uses_reference_box_) {
+ needs_transform_update_ = CheckForImplicitTransformChange(bounds_changed);
+ if (needs_transform_update_)
+ SetNeedsPaintPropertyUpdate();
+ }
+ if (!needs_transform_update_)
+ return false;
+ local_transform_ =
+ GetElement()->CalculateTransform(SVGElement::kIncludeMotionTransform);
+ needs_transform_update_ = false;
+ return true;
+}
+
void LayoutSVGBlock::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
+ transform_uses_reference_box_ =
+ TransformHelper::DependsOnReferenceBox(StyleRef());
+
// Since layout depends on the bounds of the filter, we need to force layout
// when the filter changes.
if (diff.FilterChanged())
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_block.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_block.h
index e95571ca527..d13579e59be 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_block.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_block.h
@@ -50,6 +50,7 @@ class LayoutSVGBlock : public LayoutBlockFlow {
LayoutGeometryMap&) const final;
AffineTransform LocalSVGTransform() const final { return local_transform_; }
+ void SetNeedsTransformUpdate() override { needs_transform_update_ = true; }
PaintLayerType LayerTypeRequired() const override { return kNoPaintLayer; }
@@ -63,11 +64,15 @@ class LayoutSVGBlock : public LayoutBlockFlow {
VisualRectFlags = kDefaultVisualRectFlags) const final;
AffineTransform local_transform_;
+ bool needs_transform_update_ : 1;
+ bool transform_uses_reference_box_ : 1;
bool IsOfType(LayoutObjectType type) const override {
return type == kLayoutObjectSVG || LayoutBlockFlow::IsOfType(type);
}
+ bool CheckForImplicitTransformChange(bool bbox_changed) const;
+ bool UpdateTransformAfterLayout(bool bounds_changed);
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
private:
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc
index 6c2f0e03a39..880a0925a42 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc
@@ -32,7 +32,7 @@
namespace blink {
LayoutSVGForeignObject::LayoutSVGForeignObject(SVGForeignObjectElement* node)
- : LayoutSVGBlock(node), needs_transform_update_(true) {}
+ : LayoutSVGBlock(node) {}
LayoutSVGForeignObject::~LayoutSVGForeignObject() = default;
@@ -92,12 +92,15 @@ void LayoutSVGForeignObject::UpdateLayout() {
auto* foreign = To<SVGForeignObjectElement>(GetElement());
- bool update_cached_boundaries_in_parents = false;
+ // Update our transform before layout, in case any of our descendants rely on
+ // the transform being somewhat accurate. The |needs_transform_update_| flag
+ // will be cleared after layout has been performed.
+ // TODO(fs): Remove this. AFAICS in all cases where we ancestors compute some
+ // form of CTM, they stop at their nearest ancestor LayoutSVGRoot, and thus
+ // will not care about this value.
if (needs_transform_update_) {
local_transform_ =
foreign->CalculateTransform(SVGElement::kIncludeMotionTransform);
- needs_transform_update_ = false;
- update_cached_boundaries_in_parents = true;
}
LayoutRect old_viewport = FrameRect();
@@ -110,19 +113,24 @@ void LayoutSVGForeignObject::UpdateLayout() {
SetX(ElementX());
SetY(ElementY());
- bool layout_changed = EverHadLayout() && SelfNeedsLayout();
+ const bool layout_changed = EverHadLayout() && SelfNeedsLayout();
LayoutBlock::UpdateLayout();
DCHECK(!NeedsLayout());
+ const bool bounds_changed = old_viewport != FrameRect();
- // If our bounds changed, notify the parents.
- if (!update_cached_boundaries_in_parents)
- update_cached_boundaries_in_parents = old_viewport != FrameRect();
- if (update_cached_boundaries_in_parents)
+ bool update_parent_boundaries = bounds_changed;
+ if (UpdateTransformAfterLayout(bounds_changed))
+ update_parent_boundaries = true;
+
+ // Notify ancestor about our bounds changing.
+ if (update_parent_boundaries)
LayoutSVGBlock::SetNeedsBoundariesUpdate();
// Invalidate all resources of this client if our layout changed.
if (layout_changed)
SVGResourcesCache::ClientLayoutChanged(*this);
+
+ DCHECK(!needs_transform_update_);
}
bool LayoutSVGForeignObject::NodeAtPointFromSVG(
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h
index 9d38aab5c10..71d3180c865 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h
@@ -81,8 +81,6 @@ class LayoutSVGForeignObject final : public LayoutSVGBlock {
LayoutSVGBlock::IsOfType(type);
}
- void SetNeedsTransformUpdate() override { needs_transform_update_ = true; }
-
PaintLayerType LayerTypeRequired() const override;
bool CreatesNewFormattingContext() const final {
@@ -101,8 +99,6 @@ class LayoutSVGForeignObject final : public LayoutSVGBlock {
LayoutUnit logical_top,
LogicalExtentComputedValues&) const override;
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
-
- bool needs_transform_update_;
};
template <>
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc
index fcfbf011d02..898ca496913 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc
@@ -216,8 +216,7 @@ void LayoutSVGResourceClipper::CalculateLocalClipBounds() {
SVGUnitTypes::SVGUnitType LayoutSVGResourceClipper::ClipPathUnits() const {
return To<SVGClipPathElement>(GetElement())
->clipPathUnits()
- ->CurrentValue()
- ->EnumValue();
+ ->CurrentEnumValue();
}
AffineTransform LayoutSVGResourceClipper::CalculateClipTransform(
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.cc
index f275e5646e8..82822ddcdc4 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.cc
@@ -52,17 +52,13 @@ FloatRect LayoutSVGResourceFilter::ResourceBoundingBox(
}
SVGUnitTypes::SVGUnitType LayoutSVGResourceFilter::FilterUnits() const {
- return To<SVGFilterElement>(GetElement())
- ->filterUnits()
- ->CurrentValue()
- ->EnumValue();
+ return To<SVGFilterElement>(GetElement())->filterUnits()->CurrentEnumValue();
}
SVGUnitTypes::SVGUnitType LayoutSVGResourceFilter::PrimitiveUnits() const {
return To<SVGFilterElement>(GetElement())
->primitiveUnits()
- ->CurrentValue()
- ->EnumValue();
+ ->CurrentEnumValue();
}
bool LayoutSVGResourceFilter::FindCycleFromSelf(
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.cc
index 9b7c605caa0..e2ebeba066b 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.cc
@@ -80,17 +80,11 @@ float LayoutSVGResourceMarker::Angle() const {
}
SVGMarkerUnitsType LayoutSVGResourceMarker::MarkerUnits() const {
- return To<SVGMarkerElement>(GetElement())
- ->markerUnits()
- ->CurrentValue()
- ->EnumValue();
+ return To<SVGMarkerElement>(GetElement())->markerUnits()->CurrentEnumValue();
}
SVGMarkerOrientType LayoutSVGResourceMarker::OrientType() const {
- return To<SVGMarkerElement>(GetElement())
- ->orientType()
- ->CurrentValue()
- ->EnumValue();
+ return To<SVGMarkerElement>(GetElement())->orientType()->CurrentEnumValue();
}
AffineTransform LayoutSVGResourceMarker::MarkerTransformation(
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc
index b1e201d9a8b..6519bf3bdcc 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc
@@ -93,17 +93,13 @@ void LayoutSVGResourceMasker::CalculateMaskContentVisualRect() {
}
SVGUnitTypes::SVGUnitType LayoutSVGResourceMasker::MaskUnits() const {
- return To<SVGMaskElement>(GetElement())
- ->maskUnits()
- ->CurrentValue()
- ->EnumValue();
+ return To<SVGMaskElement>(GetElement())->maskUnits()->CurrentEnumValue();
}
SVGUnitTypes::SVGUnitType LayoutSVGResourceMasker::MaskContentUnits() const {
return To<SVGMaskElement>(GetElement())
->maskContentUnits()
- ->CurrentValue()
- ->EnumValue();
+ ->CurrentEnumValue();
}
FloatRect LayoutSVGResourceMasker::ResourceBoundingBox(
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
index d38f416ffc2..d01837fe628 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
@@ -80,7 +80,10 @@ void LayoutSVGRoot::UnscaledIntrinsicSizingInfo(
intrinsic_sizing_info.has_width = svg->HasIntrinsicWidth();
intrinsic_sizing_info.has_height = svg->HasIntrinsicHeight();
- if (!intrinsic_sizing_info.size.IsEmpty()) {
+ if (const base::Optional<IntSize>& aspect_ratio = StyleRef().AspectRatio()) {
+ intrinsic_sizing_info.aspect_ratio.SetWidth(aspect_ratio->Width());
+ intrinsic_sizing_info.aspect_ratio.SetHeight(aspect_ratio->Height());
+ } else if (!intrinsic_sizing_info.size.IsEmpty()) {
intrinsic_sizing_info.aspect_ratio = intrinsic_sizing_info.size;
} else {
FloatSize view_box_size = svg->viewBox()->CurrentValue()->Value().Size();
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc
index 373e99fb652..c2161141311 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc
@@ -67,7 +67,6 @@ LayoutSVGText::LayoutSVGText(SVGTextElement* node)
: LayoutSVGBlock(node),
needs_reordering_(false),
needs_positioning_values_update_(false),
- needs_transform_update_(true),
needs_text_metrics_update_(false) {}
LayoutSVGText::~LayoutSVGText() {
@@ -248,18 +247,12 @@ void LayoutSVGText::UpdateLayout() {
needs_reordering_ = false;
- FloatRect new_boundaries = ObjectBoundingBox();
- bool bounds_changed = old_boundaries != new_boundaries;
+ const bool bounds_changed = old_boundaries != ObjectBoundingBox();
+ if (bounds_changed)
+ update_parent_boundaries = true;
- // Update the transform after laying out. Update if the bounds
- // changed too, since the transform could depend on the bounding
- // box.
- if (bounds_changed || needs_transform_update_) {
- local_transform_ =
- GetElement()->CalculateTransform(SVGElement::kIncludeMotionTransform);
- needs_transform_update_ = false;
+ if (UpdateTransformAfterLayout(bounds_changed))
update_parent_boundaries = true;
- }
ClearLayoutOverflow();
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text.h
index c5ebeb9f698..207d0f5dbeb 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text.h
@@ -39,7 +39,6 @@ class LayoutSVGText final : public LayoutSVGBlock {
void SetNeedsPositioningValuesUpdate() {
needs_positioning_values_update_ = true;
}
- void SetNeedsTransformUpdate() override { needs_transform_update_ = true; }
void SetNeedsTextMetricsUpdate() { needs_text_metrics_update_ = true; }
FloatRect VisualRectInLocalSVGCoordinates() const override;
FloatRect ObjectBoundingBox() const override;
@@ -97,7 +96,6 @@ class LayoutSVGText final : public LayoutSVGBlock {
bool needs_reordering_ : 1;
bool needs_positioning_values_update_ : 1;
- bool needs_transform_update_ : 1;
bool needs_text_metrics_update_ : 1;
Vector<LayoutSVGInlineText*> descendant_text_nodes_;
};
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc b/chromium/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
index 14eabbb2fcc..996b0bb4e4e 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
@@ -531,10 +531,8 @@ bool SVGLayoutSupport::IsLayoutableTextNode(const LayoutObject* object) {
bool SVGLayoutSupport::WillIsolateBlendingDescendantsForStyle(
const ComputedStyle& style) {
- const SVGComputedStyle& svg_style = style.SvgStyle();
-
- return style.HasIsolation() || style.HasOpacity() || style.HasBlendMode() ||
- style.HasFilter() || svg_style.HasMasker() || style.ClipPath();
+ return style.HasGroupingProperty(style.BoxReflect()) ||
+ style.SvgStyle().HasMasker();
}
bool SVGLayoutSupport::WillIsolateBlendingDescendantsForObject(
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_resources.cc b/chromium/third_party/blink/renderer/core/layout/svg/svg_resources.cc
index fd553642211..1d4fbf0c274 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_resources.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_resources.cc
@@ -740,7 +740,7 @@ bool FilterData::Invalidate(SVGFilterPrimitiveStandardAttributes& primitive,
return true;
}
-void FilterData::Trace(Visitor* visitor) {
+void FilterData::Trace(Visitor* visitor) const {
visitor->Trace(last_effect_);
visitor->Trace(node_map_);
}
@@ -842,7 +842,7 @@ bool SVGElementResourceClient::ClearFilterData() {
return !!filter_data;
}
-void SVGElementResourceClient::Trace(Visitor* visitor) {
+void SVGElementResourceClient::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(filter_data_);
SVGResourceClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_resources.h b/chromium/third_party/blink/renderer/core/layout/svg/svg_resources.h
index 7507e78f3fe..ad604b74b98 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_resources.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_resources.h
@@ -214,7 +214,7 @@ class FilterData final : public GarbageCollected<FilterData> {
void Dispose();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<FilterEffect> last_effect_;
@@ -256,7 +256,7 @@ class SVGElementResourceClient final
FilterData* UpdateFilterData();
bool ClearFilterData();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<SVGElement> element_;
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.cc b/chromium/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.cc
index 94ddd75bcb5..229d18e1e98 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.cc
@@ -176,8 +176,7 @@ void SVGTextChunkBuilder::HandleTextChunk(BoxListConstIterator box_start,
if (SVGTextContentElement* text_content_element =
SVGTextContentElement::ElementFromLineLayoutItem(
text_line_layout.Parent())) {
- length_adjust =
- text_content_element->lengthAdjust()->CurrentValue()->EnumValue();
+ length_adjust = text_content_element->lengthAdjust()->CurrentEnumValue();
SVGLengthContext length_context(text_content_element);
if (text_content_element->TextLengthIsSpecifiedByUser())
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_attributes_builder.cc b/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_attributes_builder.cc
index 6f537e09faf..f7a392f868c 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_attributes_builder.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_attributes_builder.cc
@@ -241,7 +241,7 @@ void SVGTextLayoutAttributesBuilder::FillCharacterDataMap(
}
void SVGTextLayoutAttributesBuilder::TextPosition::Trace(
- blink::Visitor* visitor) {
+ blink::Visitor* visitor) const {
visitor->Trace(element);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_attributes_builder.h b/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_attributes_builder.h
index 956c93cc526..28a4240ead9 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_attributes_builder.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_attributes_builder.h
@@ -58,7 +58,7 @@ class SVGTextLayoutAttributesBuilder {
unsigned new_length = 0)
: element(new_element), start(new_start), length(new_length) {}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
Member<SVGTextPositioningElement> element;
unsigned start;
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine.cc b/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine.cc
index 7628afd5795..764098650dc 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine.cc
@@ -185,8 +185,7 @@ void SVGTextLayoutEngine::BeginTextPathLayout(SVGInlineFlowBox* flow_box) {
if (SVGTextContentElement* text_content_element =
SVGTextContentElement::ElementFromLineLayoutItem(text_path)) {
SVGLengthContext length_context(text_content_element);
- length_adjust =
- text_content_element->lengthAdjust()->CurrentValue()->EnumValue();
+ length_adjust = text_content_element->lengthAdjust()->CurrentEnumValue();
if (text_content_element->TextLengthIsSpecifiedByUser())
desired_text_length =
text_content_element->textLength()->CurrentValue()->Value(
@@ -252,7 +251,7 @@ static bool DefinesTextLengthWithSpacing(const InlineFlowBox* start) {
SVGTextContentElement::ElementFromLineLayoutItem(
start->GetLineLayoutItem());
return text_content_element &&
- text_content_element->lengthAdjust()->CurrentValue()->EnumValue() ==
+ text_content_element->lengthAdjust()->CurrentEnumValue() ==
kSVGLengthAdjustSpacing &&
text_content_element->TextLengthIsSpecifiedByUser();
}
diff --git a/chromium/third_party/blink/renderer/core/layout/text_autosizer.cc b/chromium/third_party/blink/renderer/core/layout/text_autosizer.cc
index f3609dc9801..792b63379ec 100644
--- a/chromium/third_party/blink/renderer/core/layout/text_autosizer.cc
+++ b/chromium/third_party/blink/renderer/core/layout/text_autosizer.cc
@@ -1548,7 +1548,7 @@ void TextAutosizer::CheckSuperclusterConsistency() {
potentially_inconsistent_superclusters.clear();
}
-void TextAutosizer::Trace(Visitor* visitor) {
+void TextAutosizer::Trace(Visitor* visitor) const {
visitor->Trace(document_);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/text_autosizer.h b/chromium/third_party/blink/renderer/core/layout/text_autosizer.h
index 7a6390abf7b..923a6b2a7fc 100644
--- a/chromium/third_party/blink/renderer/core/layout/text_autosizer.h
+++ b/chromium/third_party/blink/renderer/core/layout/text_autosizer.h
@@ -80,7 +80,7 @@ class CORE_EXPORT TextAutosizer final : public GarbageCollected<TextAutosizer> {
bool PageNeedsAutosizing() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
class LayoutScope {
STACK_ALLOCATED();
diff --git a/chromium/third_party/blink/renderer/core/layout/text_decoration_offset.cc b/chromium/third_party/blink/renderer/core/layout/text_decoration_offset.cc
index 7bcc89c6f33..590f7b11d83 100644
--- a/chromium/third_party/blink/renderer/core/layout/text_decoration_offset.cc
+++ b/chromium/third_party/blink/renderer/core/layout/text_decoration_offset.cc
@@ -27,10 +27,12 @@ int TextDecorationOffset::ComputeUnderlineOffsetForUnder(
int offset_int = (farthest - logical_top).Floor();
// Gaps are not needed for TextTop because it generally has internal
- // leadings.
+ // leadings. Overline needs to grow upwards, hence subtract thickness.
if (position_type == FontVerticalPositionType::TextTop)
- return offset_int;
- return !IsLineOverSide(position_type) ? offset_int + 1 : offset_int - 1;
+ return offset_int - floorf(text_decoration_thickness);
+ return !IsLineOverSide(position_type)
+ ? offset_int + 1
+ : offset_int - 1 - floorf(text_decoration_thickness);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc b/chromium/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc
index cd5349c1f8f..2a0b93e9794 100644
--- a/chromium/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc
@@ -1294,4 +1294,51 @@ TEST_P(VisualRectMappingTest, InclusiveIntersect) {
kDefaultVisualRectFlags, false);
}
+TEST_P(VisualRectMappingTest, Perspective) {
+ ScopedTransformInteropForTest enabled(true);
+
+ GetDocument().SetBaseURLOverride(KURL("http://test.com"));
+ SetBodyInnerHTML(R"HTML(
+ <style>body { margin:0; }</style>
+ <div id='ancestor' style='perspective: 100px'>
+ <div>
+ <div id='child' style='width: 10px; height: 10px;
+ transform: rotateY(45deg); position: absolute'></div>
+ </div>
+ </div>
+ )HTML");
+
+ auto* ancestor =
+ ToLayoutBox(GetDocument().getElementById("ancestor")->GetLayoutObject());
+ auto* child =
+ ToLayoutBox(GetDocument().getElementById("child")->GetLayoutObject());
+
+ PhysicalRect rect(0, 0, 10, 10);
+ child->MapToVisualRectInAncestorSpace(ancestor, rect);
+ EXPECT_EQ(IntRect(1, 0, 8, 10), EnclosingIntRect(rect));
+}
+
+TEST_P(VisualRectMappingTest, PerspectiveWithAnonymousTable) {
+ ScopedTransformInteropForTest enabled(true);
+
+ GetDocument().SetBaseURLOverride(KURL("http://test.com"));
+ SetBodyInnerHTML(R"HTML(
+ <style>body { margin:0; }</style>
+ <div id='ancestor' style='display: table; perspective: 100px; width: 10px;
+ height: 10px;'>
+ <div id='child' style='display: table-cell; width: 10px; height: 10px;
+ transform: rotateY(45deg); position: absolute'></div>
+ </table>
+ )HTML");
+
+ auto* ancestor =
+ ToLayoutBox(GetDocument().getElementById("ancestor")->GetLayoutObject());
+ auto* child =
+ ToLayoutBox(GetDocument().getElementById("child")->GetLayoutObject());
+
+ PhysicalRect rect(0, 0, 10, 10);
+ child->MapToVisualRectInAncestorSpace(ancestor, rect);
+ EXPECT_EQ(IntRect(1, -1, 8, 12), EnclosingIntRect(rect));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/BUILD.gn b/chromium/third_party/blink/renderer/core/loader/BUILD.gn
index 4e0a703b636..52b3eb5f212 100644
--- a/chromium/third_party/blink/renderer/core/loader/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/loader/BUILD.gn
@@ -122,8 +122,8 @@ blink_core_sources("loader") {
"resource/image_resource_content.h",
"resource/image_resource_info.h",
"resource/image_resource_observer.h",
- "resource/link_fetch_resource.cc",
- "resource/link_fetch_resource.h",
+ "resource/link_prefetch_resource.cc",
+ "resource/link_prefetch_resource.h",
"resource/multipart_image_resource_parser.cc",
"resource/multipart_image_resource_parser.h",
"resource/script_resource.cc",
@@ -140,8 +140,6 @@ blink_core_sources("loader") {
"subresource_filter.h",
"subresource_integrity_helper.cc",
"subresource_integrity_helper.h",
- "text_resource_decoder_builder.cc",
- "text_resource_decoder_builder.h",
"text_track_loader.cc",
"text_track_loader.h",
"threadable_loader.cc",
diff --git a/chromium/third_party/blink/renderer/core/loader/appcache/application_cache.cc b/chromium/third_party/blink/renderer/core/loader/appcache/application_cache.cc
index 0e6a546ccbd..6ec475cd712 100644
--- a/chromium/third_party/blink/renderer/core/loader/appcache/application_cache.cc
+++ b/chromium/third_party/blink/renderer/core/loader/appcache/application_cache.cc
@@ -27,7 +27,6 @@
#include "third_party/blink/public/mojom/appcache/appcache.mojom-blink.h"
#include "third_party/blink/public/mojom/appcache/appcache_info.mojom-blink.h"
-#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -48,7 +47,7 @@ ApplicationCache::ApplicationCache(LocalFrame* frame)
cache_host->SetApplicationCache(this);
}
-void ApplicationCache::Trace(Visitor* visitor) {
+void ApplicationCache::Trace(Visitor* visitor) const {
EventTargetWithInlineData::Trace(visitor);
ExecutionContextClient::Trace(visitor);
}
@@ -150,14 +149,9 @@ const AtomicString& ApplicationCache::ToEventType(mojom::AppCacheEventID id) {
void ApplicationCache::RecordAPIUseType() const {
if (!GetFrame())
return;
-
- Document* document = GetFrame()->GetDocument();
-
- if (!document)
- return;
-
- CHECK(document->IsSecureContext());
- Deprecation::CountDeprecation(document,
+ LocalDOMWindow* window = GetFrame()->DomWindow();
+ CHECK(GetFrame()->DomWindow()->IsSecureContext());
+ Deprecation::CountDeprecation(window,
WebFeature::kApplicationCacheAPISecureOrigin);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/appcache/application_cache.h b/chromium/third_party/blink/renderer/core/loader/appcache/application_cache.h
index 65d4777c458..25abec8f09b 100644
--- a/chromium/third_party/blink/renderer/core/loader/appcache/application_cache.h
+++ b/chromium/third_party/blink/renderer/core/loader/appcache/application_cache.h
@@ -68,7 +68,7 @@ class ApplicationCache final : public EventTargetWithInlineData,
static const AtomicString& ToEventType(mojom::AppCacheEventID);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void RecordAPIUseType() const;
diff --git a/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc b/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc
index 5cd4936c13d..98109f3b1a5 100644
--- a/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc
+++ b/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc
@@ -234,7 +234,7 @@ void ApplicationCacheHost::ErrorEventRaised(
}
}
-void ApplicationCacheHost::Trace(Visitor* visitor) {
+void ApplicationCacheHost::Trace(Visitor* visitor) const {
visitor->Trace(backend_host_);
visitor->Trace(receiver_);
visitor->Trace(backend_remote_);
diff --git a/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host.h b/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host.h
index fc578e6c407..aa23aeb9fd7 100644
--- a/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host.h
+++ b/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host.h
@@ -111,11 +111,11 @@ class CORE_EXPORT ApplicationCacheHost
mojo::PendingRemote<network::mojom::blink::URLLoaderFactory>
url_loader_factory) override {}
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
protected:
HeapMojoRemote<mojom::blink::AppCacheHost,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
backend_host_;
mojom::blink::AppCacheStatus status_ =
mojom::blink::AppCacheStatus::APPCACHE_STATUS_UNCACHED;
@@ -136,10 +136,10 @@ class CORE_EXPORT ApplicationCacheHost
HeapMojoReceiver<mojom::blink::AppCacheFrontend,
ApplicationCacheHost,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
receiver_;
HeapMojoRemote<mojom::blink::AppCacheBackend,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
backend_remote_;
base::UnguessableToken host_id_;
diff --git a/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.cc b/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.cc
index c65efa31353..060211885e4 100644
--- a/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.cc
+++ b/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.cc
@@ -210,15 +210,15 @@ void ApplicationCacheHostForFrame::SelectCacheWithoutManifest() {
void ApplicationCacheHostForFrame::SelectCacheWithManifest(
const KURL& manifest_url) {
LocalFrame* frame = document_loader_->GetFrame();
- Document* document = frame->GetDocument();
- if (document->IsSandboxed(network::mojom::blink::WebSandboxFlags::kOrigin)) {
+ LocalDOMWindow* window = frame->DomWindow();
+ if (window->IsSandboxed(network::mojom::blink::WebSandboxFlags::kOrigin)) {
// Prevent sandboxes from establishing application caches.
SelectCacheWithoutManifest();
return;
}
- CHECK(document->IsSecureContext());
+ CHECK(window->IsSecureContext());
Deprecation::CountDeprecation(
- document, WebFeature::kApplicationCacheManifestSelectSecureOrigin);
+ window, WebFeature::kApplicationCacheManifestSelectSecureOrigin);
if (!backend_host_.is_bound())
return;
@@ -288,7 +288,7 @@ void ApplicationCacheHostForFrame::DidReceiveResponseForMainResource(
is_new_master_entry_ = OLD_ENTRY;
}
-void ApplicationCacheHostForFrame::Trace(Visitor* visitor) {
+void ApplicationCacheHostForFrame::Trace(Visitor* visitor) const {
visitor->Trace(dom_application_cache_);
visitor->Trace(local_frame_);
visitor->Trace(document_loader_);
diff --git a/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.h b/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.h
index e3a698f7f8b..413f986ea00 100644
--- a/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.h
+++ b/chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.h
@@ -45,7 +45,7 @@ class CORE_EXPORT ApplicationCacheHostForFrame : public ApplicationCacheHost {
void SelectCacheWithManifest(const KURL& manifest_url);
void DidReceiveResponseForMainResource(const ResourceResponse&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
enum IsNewMasterEntry { MAYBE_NEW_ENTRY, NEW_ENTRY, OLD_ENTRY };
diff --git a/chromium/third_party/blink/renderer/core/loader/base_fetch_context.cc b/chromium/third_party/blink/renderer/core/loader/base_fetch_context.cc
index 1214294c826..34743ad62e8 100644
--- a/chromium/third_party/blink/renderer/core/loader/base_fetch_context.cc
+++ b/chromium/third_party/blink/renderer/core/loader/base_fetch_context.cc
@@ -33,10 +33,10 @@ base::Optional<ResourceRequestBlockedReason> BaseFetchContext::CanRequest(
const KURL& url,
const ResourceLoaderOptions& options,
ReportingDisposition reporting_disposition,
- ResourceRequest::RedirectStatus redirect_status) const {
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info) const {
base::Optional<ResourceRequestBlockedReason> blocked_reason =
CanRequestInternal(type, resource_request, url, options,
- reporting_disposition, redirect_status);
+ reporting_disposition, redirect_info);
if (blocked_reason &&
reporting_disposition == ReportingDisposition::kReport) {
DispatchDidBlockRequest(resource_request, options.initiator_info,
@@ -60,7 +60,7 @@ bool BaseFetchContext::CalculateIfAdSubresource(
bool BaseFetchContext::SendConversionRequestInsteadOfRedirecting(
const KURL& url,
- ResourceRequest::RedirectStatus redirect_status,
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info,
ReportingDisposition reporting_disposition) const {
return false;
}
@@ -94,10 +94,11 @@ BaseFetchContext::CheckCSPForRequest(
const KURL& url,
const ResourceLoaderOptions& options,
ReportingDisposition reporting_disposition,
+ const KURL& url_before_redirects,
ResourceRequest::RedirectStatus redirect_status) const {
return CheckCSPForRequestInternal(
request_context, request_destination, url, options, reporting_disposition,
- redirect_status,
+ url_before_redirects, redirect_status,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly);
}
@@ -108,6 +109,7 @@ BaseFetchContext::CheckCSPForRequestInternal(
const KURL& url,
const ResourceLoaderOptions& options,
ReportingDisposition reporting_disposition,
+ const KURL& url_before_redirects,
ResourceRequest::RedirectStatus redirect_status,
ContentSecurityPolicy::CheckHeaderType check_header_type) const {
if (ShouldBypassMainWorldCSP() ||
@@ -117,11 +119,12 @@ BaseFetchContext::CheckCSPForRequestInternal(
}
const ContentSecurityPolicy* csp = GetContentSecurityPolicy();
- if (csp && !csp->AllowRequest(request_context, request_destination, url,
- options.content_security_policy_nonce,
- options.integrity_metadata,
- options.parser_disposition, redirect_status,
- reporting_disposition, check_header_type)) {
+ if (csp &&
+ !csp->AllowRequest(request_context, request_destination, url,
+ options.content_security_policy_nonce,
+ options.integrity_metadata, options.parser_disposition,
+ url_before_redirects, redirect_status,
+ reporting_disposition, check_header_type)) {
return ResourceRequestBlockedReason::kCSP;
}
return base::nullopt;
@@ -134,10 +137,9 @@ BaseFetchContext::CanRequestInternal(
const KURL& url,
const ResourceLoaderOptions& options,
ReportingDisposition reporting_disposition,
- ResourceRequest::RedirectStatus redirect_status) const {
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info) const {
if (GetResourceFetcherProperties().IsDetached()) {
- if (!resource_request.GetKeepalive() ||
- redirect_status == ResourceRequest::RedirectStatus::kNoRedirect) {
+ if (!resource_request.GetKeepalive() || !redirect_info) {
return ResourceRequestBlockedReason::kOther;
}
}
@@ -188,12 +190,17 @@ BaseFetchContext::CanRequestInternal(
network::mojom::RequestDestination request_destination =
resource_request.GetRequestDestination();
+ const KURL& url_before_redirects =
+ redirect_info ? redirect_info->original_url : url;
+ const ResourceRequestHead::RedirectStatus redirect_status =
+ redirect_info ? ResourceRequestHead::RedirectStatus::kFollowedRedirect
+ : ResourceRequestHead::RedirectStatus::kNoRedirect;
// We check the 'report-only' headers before upgrading the request (in
// populateResourceRequest). We check the enforced headers here to ensure we
// block things we ought to block.
if (CheckCSPForRequestInternal(
request_context, request_destination, url, options,
- reporting_disposition, redirect_status,
+ reporting_disposition, url_before_redirects, redirect_status,
ContentSecurityPolicy::CheckHeaderType::kCheckEnforce) ==
ResourceRequestBlockedReason::kCSP) {
return ResourceRequestBlockedReason::kCSP;
@@ -234,9 +241,9 @@ BaseFetchContext::CanRequestInternal(
// Check for mixed content. We do this second-to-last so that when folks block
// mixed content via CSP, they don't get a mixed content warning, but a CSP
// warning instead.
- if (ShouldBlockFetchByMixedContentCheck(
- request_context, resource_request.GetRedirectStatus(), url,
- reporting_disposition, resource_request.GetDevToolsId())) {
+ if (ShouldBlockFetchByMixedContentCheck(request_context, redirect_info, url,
+ reporting_disposition,
+ resource_request.GetDevToolsId())) {
return ResourceRequestBlockedReason::kMixedContent;
}
@@ -252,7 +259,7 @@ BaseFetchContext::CanRequestInternal(
return ResourceRequestBlockedReason::kOther;
}
- if (SendConversionRequestInsteadOfRedirecting(url, redirect_status,
+ if (SendConversionRequestInsteadOfRedirecting(url, redirect_info,
reporting_disposition)) {
return ResourceRequestBlockedReason::kOther;
}
@@ -269,7 +276,7 @@ BaseFetchContext::CanRequestInternal(
return base::nullopt;
}
-void BaseFetchContext::Trace(Visitor* visitor) {
+void BaseFetchContext::Trace(Visitor* visitor) const {
visitor->Trace(fetcher_properties_);
FetchContext::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/base_fetch_context.h b/chromium/third_party/blink/renderer/core/loader/base_fetch_context.h
index fa5bc0b3ba5..f8a33f9ae46 100644
--- a/chromium/third_party/blink/renderer/core/loader/base_fetch_context.h
+++ b/chromium/third_party/blink/renderer/core/loader/base_fetch_context.h
@@ -37,16 +37,17 @@ class CORE_EXPORT BaseFetchContext : public FetchContext {
const KURL&,
const ResourceLoaderOptions&,
ReportingDisposition,
- ResourceRequest::RedirectStatus) const override;
+ const base::Optional<ResourceRequest::RedirectInfo>&) const override;
base::Optional<ResourceRequestBlockedReason> CheckCSPForRequest(
mojom::RequestContextType,
network::mojom::RequestDestination request_destination,
const KURL&,
const ResourceLoaderOptions&,
ReportingDisposition,
+ const KURL& url_before_redirects,
ResourceRequest::RedirectStatus) const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const DetachableResourceFetcherProperties& GetResourceFetcherProperties()
const {
@@ -77,7 +78,7 @@ class CORE_EXPORT BaseFetchContext : public FetchContext {
// registration endpoint.
virtual bool SendConversionRequestInsteadOfRedirecting(
const KURL& url,
- ResourceRequest::RedirectStatus redirect_status,
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info,
ReportingDisposition reporting_disposition) const;
virtual const ContentSecurityPolicy* GetContentSecurityPolicy() const = 0;
@@ -102,7 +103,7 @@ class CORE_EXPORT BaseFetchContext : public FetchContext {
virtual bool IsSVGImageChromeClient() const = 0;
virtual bool ShouldBlockFetchByMixedContentCheck(
mojom::blink::RequestContextType request_context,
- ResourceRequest::RedirectStatus redirect_status,
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info,
const KURL& url,
ReportingDisposition reporting_disposition,
const base::Optional<String>& devtools_id) const = 0;
@@ -127,7 +128,7 @@ class CORE_EXPORT BaseFetchContext : public FetchContext {
const KURL&,
const ResourceLoaderOptions&,
ReportingDisposition,
- ResourceRequest::RedirectStatus) const;
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info) const;
base::Optional<ResourceRequestBlockedReason> CheckCSPForRequestInternal(
mojom::RequestContextType,
@@ -135,7 +136,8 @@ class CORE_EXPORT BaseFetchContext : public FetchContext {
const KURL&,
const ResourceLoaderOptions&,
ReportingDisposition,
- ResourceRequest::RedirectStatus,
+ const KURL& url_before_redirects,
+ ResourceRequest::RedirectStatus redirect_status,
ContentSecurityPolicy::CheckHeaderType) const;
};
diff --git a/chromium/third_party/blink/renderer/core/loader/base_fetch_context_test.cc b/chromium/third_party/blink/renderer/core/loader/base_fetch_context_test.cc
index 84dde4e10b7..73d1e056259 100644
--- a/chromium/third_party/blink/renderer/core/loader/base_fetch_context_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/base_fetch_context_test.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/loader/base_fetch_context.h"
+#include "base/optional.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
@@ -86,7 +87,7 @@ class MockBaseFetchContext final : public BaseFetchContext {
}
bool ShouldBlockFetchByMixedContentCheck(
mojom::RequestContextType,
- ResourceRequest::RedirectStatus,
+ const base::Optional<ResourceRequest::RedirectInfo>&,
const KURL&,
ReportingDisposition,
const base::Optional<String>&) const override {
@@ -106,7 +107,7 @@ class MockBaseFetchContext final : public BaseFetchContext {
}
void AddConsoleMessage(ConsoleMessage*) const override {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(execution_context_);
visitor->Trace(fetch_client_settings_object_);
BaseFetchContext::Trace(visitor);
@@ -170,8 +171,7 @@ TEST_F(BaseFetchContextTest, CanRequest) {
EXPECT_EQ(ResourceRequestBlockedReason::kCSP,
fetch_context_->CanRequest(
ResourceType::kScript, resource_request, url, options,
- ReportingDisposition::kReport,
- ResourceRequest::RedirectStatus::kFollowedRedirect));
+ ReportingDisposition::kReport, base::nullopt));
EXPECT_EQ(1u, policy->violation_reports_sent_.size());
}
@@ -195,6 +195,7 @@ TEST_F(BaseFetchContextTest, CheckCSPForRequest) {
mojom::RequestContextType::SCRIPT,
network::mojom::RequestDestination::kScript, url, options,
ReportingDisposition::kReport,
+ KURL(NullURL(), "http://www.redirecting.com/"),
ResourceRequest::RedirectStatus::kFollowedRedirect));
EXPECT_EQ(1u, policy->violation_reports_sent_.size());
}
@@ -210,55 +211,51 @@ TEST_F(BaseFetchContextTest, CanRequestWhenDetached) {
EXPECT_EQ(base::nullopt,
fetch_context_->CanRequest(
ResourceType::kRaw, request, url, ResourceLoaderOptions(),
- ReportingDisposition::kSuppressReporting,
- ResourceRequest::RedirectStatus::kNoRedirect));
-
- EXPECT_EQ(base::nullopt, fetch_context_->CanRequest(
- ResourceType::kRaw, keepalive_request, url,
- ResourceLoaderOptions(),
- ReportingDisposition::kSuppressReporting,
- ResourceRequest::RedirectStatus::kNoRedirect));
+ ReportingDisposition::kSuppressReporting, base::nullopt));
EXPECT_EQ(base::nullopt,
+ fetch_context_->CanRequest(ResourceType::kRaw, keepalive_request,
+ url, ResourceLoaderOptions(),
+ ReportingDisposition::kSuppressReporting,
+ base::nullopt));
+
+ ResourceRequest::RedirectInfo redirect_info(
+ KURL(NullURL(), "http://www.redirecting.com/"),
+ KURL(NullURL(), "http://www.redirecting.com/"));
+ EXPECT_EQ(base::nullopt,
fetch_context_->CanRequest(
ResourceType::kRaw, request, url, ResourceLoaderOptions(),
- ReportingDisposition::kSuppressReporting,
- ResourceRequest::RedirectStatus::kFollowedRedirect));
+ ReportingDisposition::kSuppressReporting, redirect_info));
- EXPECT_EQ(
- base::nullopt,
- fetch_context_->CanRequest(
- ResourceType::kRaw, keepalive_request, url, ResourceLoaderOptions(),
- ReportingDisposition::kSuppressReporting,
- ResourceRequest::RedirectStatus::kFollowedRedirect));
+ EXPECT_EQ(base::nullopt,
+ fetch_context_->CanRequest(ResourceType::kRaw, keepalive_request,
+ url, ResourceLoaderOptions(),
+ ReportingDisposition::kSuppressReporting,
+ redirect_info));
resource_fetcher_->ClearContext();
EXPECT_EQ(ResourceRequestBlockedReason::kOther,
fetch_context_->CanRequest(
ResourceType::kRaw, request, url, ResourceLoaderOptions(),
- ReportingDisposition::kSuppressReporting,
- ResourceRequest::RedirectStatus::kNoRedirect));
+ ReportingDisposition::kSuppressReporting, base::nullopt));
- EXPECT_EQ(
- ResourceRequestBlockedReason::kOther,
- fetch_context_->CanRequest(ResourceType::kRaw, keepalive_request, url,
- ResourceLoaderOptions(),
- ReportingDisposition::kSuppressReporting,
- ResourceRequest::RedirectStatus::kNoRedirect));
+ EXPECT_EQ(ResourceRequestBlockedReason::kOther,
+ fetch_context_->CanRequest(ResourceType::kRaw, keepalive_request,
+ url, ResourceLoaderOptions(),
+ ReportingDisposition::kSuppressReporting,
+ base::nullopt));
EXPECT_EQ(ResourceRequestBlockedReason::kOther,
fetch_context_->CanRequest(
ResourceType::kRaw, request, url, ResourceLoaderOptions(),
- ReportingDisposition::kSuppressReporting,
- ResourceRequest::RedirectStatus::kFollowedRedirect));
+ ReportingDisposition::kSuppressReporting, redirect_info));
- EXPECT_EQ(
- base::nullopt,
- fetch_context_->CanRequest(
- ResourceType::kRaw, keepalive_request, url, ResourceLoaderOptions(),
- ReportingDisposition::kSuppressReporting,
- ResourceRequest::RedirectStatus::kFollowedRedirect));
+ EXPECT_EQ(base::nullopt,
+ fetch_context_->CanRequest(ResourceType::kRaw, keepalive_request,
+ url, ResourceLoaderOptions(),
+ ReportingDisposition::kSuppressReporting,
+ redirect_info));
}
// Test that User Agent CSS can only load images with data urls.
@@ -271,23 +268,23 @@ TEST_F(BaseFetchContextTest, UACSSTest) {
ResourceLoaderOptions options;
options.initiator_info.name = fetch_initiator_type_names::kUacss;
+ ResourceRequest::RedirectInfo redirect_info(
+ KURL(NullURL(), "http://www.redirecting.com/"),
+ KURL(NullURL(), "http://www.redirecting.com/"));
EXPECT_EQ(ResourceRequestBlockedReason::kOther,
fetch_context_->CanRequest(
ResourceType::kScript, resource_request, test_url, options,
- ReportingDisposition::kReport,
- ResourceRequest::RedirectStatus::kFollowedRedirect));
+ ReportingDisposition::kReport, redirect_info));
EXPECT_EQ(ResourceRequestBlockedReason::kOther,
fetch_context_->CanRequest(
ResourceType::kImage, resource_request, test_url, options,
- ReportingDisposition::kReport,
- ResourceRequest::RedirectStatus::kFollowedRedirect));
+ ReportingDisposition::kReport, redirect_info));
EXPECT_EQ(base::nullopt,
fetch_context_->CanRequest(
ResourceType::kImage, resource_request, data_url, options,
- ReportingDisposition::kReport,
- ResourceRequest::RedirectStatus::kFollowedRedirect));
+ ReportingDisposition::kReport, redirect_info));
}
// Test that User Agent CSS can bypass CSP to load embedded images.
@@ -305,11 +302,13 @@ TEST_F(BaseFetchContextTest, UACSSTest_BypassCSP) {
ResourceLoaderOptions options;
options.initiator_info.name = fetch_initiator_type_names::kUacss;
+ ResourceRequest::RedirectInfo redirect_info(
+ KURL(NullURL(), "http://www.redirecting.com/"),
+ KURL(NullURL(), "http://www.redirecting.com/"));
EXPECT_EQ(base::nullopt,
fetch_context_->CanRequest(
ResourceType::kImage, resource_request, data_url, options,
- ReportingDisposition::kReport,
- ResourceRequest::RedirectStatus::kFollowedRedirect));
+ ReportingDisposition::kReport, redirect_info));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/cookie_jar.cc b/chromium/third_party/blink/renderer/core/loader/cookie_jar.cc
index 4593b594587..34d20e853a0 100644
--- a/chromium/third_party/blink/renderer/core/loader/cookie_jar.cc
+++ b/chromium/third_party/blink/renderer/core/loader/cookie_jar.cc
@@ -6,6 +6,7 @@
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
namespace blink {
@@ -15,7 +16,7 @@ CookieJar::CookieJar(blink::Document* document)
CookieJar::~CookieJar() = default;
-void CookieJar::Trace(Visitor* visitor) {
+void CookieJar::Trace(Visitor* visitor) const {
visitor->Trace(backend_);
visitor->Trace(document_);
}
@@ -57,7 +58,7 @@ bool CookieJar::CookiesEnabled() {
void CookieJar::RequestRestrictedCookieManagerIfNeeded() {
if (!backend_.is_bound() || !backend_.is_connected()) {
backend_.reset();
- document_->GetBrowserInterfaceBroker().GetInterface(
+ document_->GetFrame()->GetBrowserInterfaceBroker().GetInterface(
backend_.BindNewPipeAndPassReceiver(
document_->GetTaskRunner(TaskType::kInternalDefault)));
}
diff --git a/chromium/third_party/blink/renderer/core/loader/cookie_jar.h b/chromium/third_party/blink/renderer/core/loader/cookie_jar.h
index 44bb2eb945f..99729ec8ac3 100644
--- a/chromium/third_party/blink/renderer/core/loader/cookie_jar.h
+++ b/chromium/third_party/blink/renderer/core/loader/cookie_jar.h
@@ -18,7 +18,7 @@ class CookieJar : public GarbageCollected<CookieJar> {
public:
explicit CookieJar(blink::Document* document);
virtual ~CookieJar();
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
void SetCookie(const String& value);
String Cookies();
diff --git a/chromium/third_party/blink/renderer/core/loader/document_load_timing.cc b/chromium/third_party/blink/renderer/core/loader/document_load_timing.cc
index 4c623157ffb..5a8c0472bf8 100644
--- a/chromium/third_party/blink/renderer/core/loader/document_load_timing.cc
+++ b/chromium/third_party/blink/renderer/core/loader/document_load_timing.cc
@@ -44,7 +44,7 @@ DocumentLoadTiming::DocumentLoadTiming(DocumentLoader& document_loader)
tick_clock_(base::DefaultTickClock::GetInstance()),
document_loader_(document_loader) {}
-void DocumentLoadTiming::Trace(Visitor* visitor) {
+void DocumentLoadTiming::Trace(Visitor* visitor) const {
visitor->Trace(document_loader_);
}
@@ -138,6 +138,12 @@ void DocumentLoadTiming::SetNavigationStart(base::TimeTicks navigation_start) {
NotifyDocumentTimingChanged();
}
+void DocumentLoadTiming::MarkBackForwardCacheRestoreNavigationStart(
+ base::TimeTicks navigation_start) {
+ bfcache_restore_navigation_starts_.push_back(navigation_start);
+ NotifyDocumentTimingChanged();
+}
+
void DocumentLoadTiming::SetInputStart(base::TimeTicks input_start) {
input_start_ = input_start;
NotifyDocumentTimingChanged();
diff --git a/chromium/third_party/blink/renderer/core/loader/document_load_timing.h b/chromium/third_party/blink/renderer/core/loader/document_load_timing.h
index e1e59d2b432..2009765ba5d 100644
--- a/chromium/third_party/blink/renderer/core/loader/document_load_timing.h
+++ b/chromium/third_party/blink/renderer/core/loader/document_load_timing.h
@@ -53,6 +53,7 @@ class CORE_EXPORT DocumentLoadTiming final {
void MarkNavigationStart();
void SetNavigationStart(base::TimeTicks);
+ void MarkBackForwardCacheRestoreNavigationStart(base::TimeTicks);
void SetInputStart(base::TimeTicks);
@@ -81,6 +82,10 @@ class CORE_EXPORT DocumentLoadTiming final {
base::TimeTicks InputStart() const { return input_start_; }
base::TimeTicks NavigationStart() const { return navigation_start_; }
+ const WTF::Vector<base::TimeTicks>& BackForwardCacheRestoreNavigationStarts()
+ const {
+ return bfcache_restore_navigation_starts_;
+ }
base::TimeTicks UnloadEventStart() const { return unload_event_start_; }
base::TimeTicks UnloadEventEnd() const { return unload_event_end_; }
base::TimeTicks RedirectStart() const { return redirect_start_; }
@@ -99,7 +104,7 @@ class CORE_EXPORT DocumentLoadTiming final {
return reference_monotonic_time_;
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void SetTickClockForTesting(const base::TickClock* tick_clock);
void SetClockForTesting(const base::Clock* clock);
@@ -115,6 +120,7 @@ class CORE_EXPORT DocumentLoadTiming final {
base::TimeDelta reference_wall_time_;
base::TimeTicks input_start_;
base::TimeTicks navigation_start_;
+ WTF::Vector<base::TimeTicks> bfcache_restore_navigation_starts_;
base::TimeTicks unload_event_start_;
base::TimeTicks unload_event_end_;
base::TimeTicks redirect_start_;
diff --git a/chromium/third_party/blink/renderer/core/loader/document_loader.cc b/chromium/third_party/blink/renderer/core/loader/document_loader.cc
index 7faf30225b4..4aa41d6dc11 100644
--- a/chromium/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/document_loader.cc
@@ -36,6 +36,8 @@
#include "base/metrics/histogram_macros.h"
#include "base/time/default_tick_clock.h"
#include "services/network/public/cpp/features.h"
+#include "services/network/public/cpp/web_sandbox_flags.h"
+#include "services/network/public/mojom/web_sandbox_flags.mojom-blink.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/commit_result/commit_result.mojom-blink.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
@@ -46,6 +48,7 @@
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/scriptable_document_parser.h"
#include "third_party/blink/renderer/core/dom/weak_identifier_map.h"
+#include "third_party/blink/renderer/core/execution_context/window_agent_factory.h"
#include "third_party/blink/renderer/core/feature_policy/document_policy_parser.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
@@ -114,35 +117,127 @@
namespace blink {
+namespace {
+Vector<OriginTrialFeature> CopyInitiatorOriginTrials(
+ const WebVector<int>& initiator_origin_trial_features) {
+ Vector<OriginTrialFeature> result;
+ for (auto feature : initiator_origin_trial_features) {
+ // Convert from int to OriginTrialFeature. These values are passed between
+ // blink navigations. OriginTrialFeature isn't visible outside of blink (and
+ // doesn't need to be) so the values are transferred outside of blink as
+ // ints and casted to OriginTrialFeature once being processed in blink.
+ result.push_back(static_cast<OriginTrialFeature>(feature));
+ }
+ return result;
+}
+
+Vector<String> CopyForceEnabledOriginTrials(
+ const WebVector<WebString>& force_enabled_origin_trials) {
+ Vector<String> result;
+ result.ReserveInitialCapacity(
+ SafeCast<wtf_size_t>(force_enabled_origin_trials.size()));
+ for (const auto& trial : force_enabled_origin_trials)
+ result.push_back(trial);
+ return result;
+}
+
+} // namespace
+
DocumentLoader::DocumentLoader(
LocalFrame* frame,
WebNavigationType navigation_type,
ContentSecurityPolicy* content_security_policy,
std::unique_ptr<WebNavigationParams> navigation_params)
: params_(std::move(navigation_params)),
+ url_(params_->url),
+ http_method_(static_cast<String>(params_->http_method)),
+ referrer_(Referrer(params_->referrer.IsEmpty()
+ ? Referrer::NoReferrer()
+ : static_cast<String>(params_->referrer),
+ params_->referrer_policy)),
+ http_body_(params_->http_body),
+ http_content_type_(static_cast<String>(params_->http_content_type)),
+ origin_policy_(params_->origin_policy),
+ requestor_origin_(params_->requestor_origin),
+ unreachable_url_(params_->unreachable_url),
+ ip_address_space_(params_->ip_address_space),
+ grant_load_local_resources_(params_->grant_load_local_resources),
+ force_fetch_cache_mode_(params_->force_fetch_cache_mode),
+ frame_policy_(params_->frame_policy.value_or(FramePolicy())),
frame_(frame),
+ // For back/forward navigations, the browser passed a history item to use
+ // at commit time in |params_|. Set it as the current history item of this
+ // DocumentLoader. For other navigations, |history_item_| will be created
+ // when the FrameLoader calls SetHistoryItemStateForCommit.
+ history_item_(IsBackForwardLoadType(params_->frame_load_type)
+ ? params_->history_item
+ : nullptr),
+ original_url_(params_->url),
+ original_referrer_(referrer_),
+ response_(params_->response.ToResourceResponse()),
load_type_(params_->frame_load_type),
is_client_redirect_(params_->is_client_redirect),
- replaces_current_history_item_(false),
+ // TODO(japhet): This is needed because the browser process DCHECKs if the
+ // first entry we commit in a new frame has replacement set. It's unclear
+ // whether the DCHECK is right, investigate removing this special case.
+ // TODO(dgozman): we should get rid of this boolean field, and make client
+ // responsible for it's own view of "replaces current item", based on the
+ // frame load type.
+ replaces_current_history_item_(
+ load_type_ == WebFrameLoadType::kReplaceCurrentItem &&
+ (!frame_->Loader().Opener() || !url_.IsEmpty())),
data_received_(false),
+ // The input CSP is null when the CSP check done in the FrameLoader failed
+ content_security_policy_(
+ content_security_policy
+ ? content_security_policy
+ : MakeGarbageCollected<ContentSecurityPolicy>()),
+ was_blocked_by_csp_(!content_security_policy),
+ // Loading the document was blocked by the CSP check. Pretend that this
+ // was an empty document instead and don't reuse the original URL. More
+ // details in: https://crbug.com/622385.
+ // TODO(https://crbug.com/555418) Remove this once XFO moves to the
+ // browser.
+
+ // Update |origin_to_commit_| to contain an opaque origin with precursor
+ // information that is consistent with the final request URL.
+ // Note: this doesn't use |url_| for the origin calculation, because
+ // redirects are not yet accounted for (this happens later in
+ // StartLoadingInternal).
+ origin_to_commit_(
+ was_blocked_by_csp_
+ ? blink::SecurityOrigin::Create(response_.CurrentRequestUrl())
+ ->DeriveNewOpaqueOrigin()
+ : params_->origin_to_commit.IsNull()
+ ? nullptr
+ : params_->origin_to_commit.Get()->IsolatedCopy()),
navigation_type_(navigation_type),
document_load_timing_(*this),
service_worker_network_provider_(
std::move(params_->service_worker_network_provider)),
was_blocked_by_document_policy_(false),
- content_security_policy_(content_security_policy),
- // The CSP is null when the CSP check done in the FrameLoader failed.
- was_blocked_by_csp_(!content_security_policy),
state_(kNotStarted),
in_commit_data_(false),
data_buffer_(SharedBuffer::Create()),
devtools_navigation_token_(params_->devtools_navigation_token),
had_sticky_activation_(params_->is_user_activated),
+ had_transient_activation_(
+ LocalFrame::HasTransientUserActivation(frame_) ||
+ params_->had_transient_activation),
is_browser_initiated_(params_->is_browser_initiated),
was_discarded_(params_->was_discarded),
- use_counter_(),
+ loading_srcdoc_(url_.IsAboutSrcdocURL()),
+ loading_url_as_empty_document_(!params_->is_static_data &&
+ WillLoadUrlAsEmpty(url_)),
+ web_bundle_physical_url_(params_->web_bundle_physical_url),
+ web_bundle_claimed_url_(params_->web_bundle_claimed_url),
clock_(params_->tick_clock ? params_->tick_clock
- : base::DefaultTickClock::GetInstance()) {
+ : base::DefaultTickClock::GetInstance()),
+ initiator_origin_trial_features_(
+ CopyInitiatorOriginTrials(params_->initiator_origin_trial_features)),
+ force_enabled_origin_trials_(
+ CopyForceEnabledOriginTrials(params_->force_enabled_origin_trials)),
+ origin_isolation_restricted_(params_->origin_isolation_restricted) {
DCHECK(frame_);
// TODO(nasko): How should this work with OOPIF?
@@ -154,23 +249,6 @@ DocumentLoader::DocumentLoader(
archive_ = parent->Loader().GetDocumentLoader()->archive_;
}
- url_ = params_->url;
- original_url_ = url_;
- had_transient_activation_ = LocalFrame::HasTransientUserActivation(frame_) ||
- params_->had_transient_activation;
- http_method_ = params_->http_method;
- if (params_->referrer.IsEmpty()) {
- referrer_ = Referrer(Referrer::NoReferrer(), params_->referrer_policy);
- } else {
- referrer_ = Referrer(params_->referrer, params_->referrer_policy);
- }
-
- original_referrer_ = referrer_;
- http_body_ = params_->http_body;
- http_content_type_ = params_->http_content_type;
- origin_policy_ = params_->origin_policy;
- requestor_origin_ = params_->requestor_origin;
- unreachable_url_ = params_->unreachable_url;
if (frame_->IsMainFrame()) {
previews_state_ = params_->previews_state;
} else {
@@ -178,11 +256,6 @@ DocumentLoader::DocumentLoader(
if (auto* parent = DynamicTo<LocalFrame>(frame_->Tree().Parent()))
previews_state_ = parent->Loader().GetDocumentLoader()->previews_state_;
}
- ip_address_space_ = params_->ip_address_space;
- grant_load_local_resources_ = params_->grant_load_local_resources;
- force_fetch_cache_mode_ = params_->force_fetch_cache_mode;
- response_ = params_->response.ToResourceResponse();
- frame_policy_ = params_->frame_policy.value_or(FramePolicy());
document_policy_ = CreateDocumentPolicy();
@@ -205,76 +278,19 @@ DocumentLoader::DocumentLoader(
}
}
- // TODO(japhet): This is needed because the browser process DCHECKs if the
- // first entry we commit in a new frame has replacement set. It's unclear
- // whether the DCHECK is right, investigate removing this special case.
- // TODO(dgozman): we should get rid of this boolean field, and make client
- // responsible for it's own view of "replaces current item", based on the
- // frame load type.
- replaces_current_history_item_ =
- load_type_ == WebFrameLoadType::kReplaceCurrentItem &&
- (!frame_->Loader().Opener() || !url_.IsEmpty());
-
// The document URL needs to be added to the head of the list as that is
// where the redirects originated.
if (is_client_redirect_)
redirect_chain_.push_back(frame_->GetDocument()->Url());
- if (!params_->origin_to_commit.IsNull())
- origin_to_commit_ = params_->origin_to_commit.Get()->IsolatedCopy();
-
- loading_srcdoc_ = url_.IsAboutSrcdocURL();
- loading_url_as_empty_document_ =
- !params_->is_static_data && WillLoadUrlAsEmpty(url_);
-
- if (was_blocked_by_csp_) {
- // Loading the document was blocked by the CSP check. Pretend that this was
- // an empty document instead and don't reuse the original URL. More details
- // in: https://crbug.com/622385.
- // TODO(https://crbug.com/555418) Remove this once XFO moves to the browser.
-
- // Update |origin_to_commit_| to contain an opaque origin with precursor
- // information that is consistent with the final request URL.
- // Note: this doesn't use |url_| for the origin calculation, because
- // redirects are not yet accounted for (this happens later in
- // StartLoadingInternal).
- const auto request_url_origin =
- blink::SecurityOrigin::Create(response_.CurrentRequestUrl());
- origin_to_commit_ = request_url_origin->DeriveNewOpaqueOrigin();
- }
-
if (was_blocked_by_csp_ || was_blocked_by_document_policy_)
ReplaceWithEmptyDocument();
if (!GetFrameLoader().StateMachine()->CreatingInitialEmptyDocument())
redirect_chain_.push_back(url_);
- for (auto feature : params_->initiator_origin_trial_features) {
- // Convert from int to OriginTrialFeature. These values are passed between
- // blink navigations. OriginTrialFeature isn't visible outside of blink (and
- // doesn't need to be) so the values are transferred outside of blink as
- // ints and casted to OriginTrialFeature once being processed in blink.
- initiator_origin_trial_features_.push_back(
- static_cast<OriginTrialFeature>(feature));
- }
-
- // For back/forward navigations, the browser passed a history item to use at
- // commit time in |params_|. Set it as the current history item of this
- // DocumentLoader. For other navigations, |history_item_| will be created when
- // the FrameLoader calls SetHistoryItemStateForCommit.
- if (IsBackForwardLoadType(params_->frame_load_type)) {
- HistoryItem* history_item = params_->history_item;
- DCHECK(history_item);
- history_item_ = history_item;
- }
-
- web_bundle_physical_url_ = params_->web_bundle_physical_url;
- web_bundle_claimed_url_ = params_->web_bundle_claimed_url;
-
- force_enabled_origin_trials_.ReserveInitialCapacity(
- SafeCast<wtf_size_t>(params_->force_enabled_origin_trials.size()));
- for (const auto& trial : params_->force_enabled_origin_trials)
- force_enabled_origin_trials_.push_back(trial);
+ if (IsBackForwardLoadType(params_->frame_load_type))
+ DCHECK(history_item_);
}
FrameLoader& DocumentLoader::GetFrameLoader() const {
@@ -299,7 +315,7 @@ DocumentLoader::~DocumentLoader() {
DCHECK_EQ(state_, kSentDidFinishLoad);
}
-void DocumentLoader::Trace(Visitor* visitor) {
+void DocumentLoader::Trace(Visitor* visitor) const {
visitor->Trace(archive_);
visitor->Trace(frame_);
visitor->Trace(history_item_);
@@ -574,11 +590,8 @@ mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
DocumentLoader::TakePendingWorkerTimingReceiver(int request_id) {
if (!GetServiceWorkerNetworkProvider())
return mojo::NullReceiver();
- mojo::ScopedMessagePipeHandle pipe =
- GetServiceWorkerNetworkProvider()->TakePendingWorkerTimingReceiver(
- request_id);
- return mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>(
- std::move(pipe));
+ return GetServiceWorkerNetworkProvider()->TakePendingWorkerTimingReceiver(
+ request_id);
}
void DocumentLoader::BodyCodeCacheReceived(mojo_base::BigBuffer data) {
@@ -667,7 +680,8 @@ void DocumentLoader::BodyLoadingFinished(
}
GetFrameLoader().Progress().CompleteProgress(main_resource_identifier_);
probe::DidFailLoading(probe::ToCoreProbeSink(GetFrame()),
- main_resource_identifier_, this, resource_error);
+ main_resource_identifier_, this, resource_error,
+ frame_->GetDevToolsFrameToken());
GetFrame()->Console().DidFailLoading(this, main_resource_identifier_,
resource_error);
LoadFailed(resource_error);
@@ -1044,6 +1058,9 @@ void DocumentLoader::CommitSameDocumentNavigationInternal(
}
is_client_redirect_ =
client_redirect == ClientRedirectPolicy::kClientRedirect;
+ bool same_item_sequence_number =
+ history_item_ && history_item &&
+ history_item_->ItemSequenceNumber() == history_item->ItemSequenceNumber();
if (history_item)
history_item_ = history_item;
if (extra_data)
@@ -1055,8 +1072,16 @@ void DocumentLoader::CommitSameDocumentNavigationInternal(
initial_scroll_state_.was_scrolled_by_user = false;
frame_->GetDocument()->CheckCompleted();
- GetFrameLoader().DidFinishSameDocumentNavigation(url, frame_load_type,
- history_item);
+
+ // If the item sequence number didn't change, there's no need to trigger
+ // popstate, restore scroll positions, or scroll to fragments for this
+ // same-document navigation. It's possible to get a same-document navigation
+ // to a same ISN when a history navigation targets a frame that no longer
+ // exists (https://crbug.com/705550).
+ if (!same_item_sequence_number) {
+ GetFrameLoader().DidFinishSameDocumentNavigation(url, frame_load_type,
+ history_item);
+ }
}
void DocumentLoader::ProcessDataBuffer(const char* bytes, size_t length) {
@@ -1375,8 +1400,7 @@ void DocumentLoader::StartLoadingResponse() {
}
void DocumentLoader::DidInstallNewDocument(Document* document) {
- if (content_security_policy_)
- document->BindContentSecurityPolicy();
+ document->BindContentSecurityPolicy();
if (history_item_ && IsBackForwardLoadType(load_type_))
document->SetStateForNewControls(history_item_->GetDocumentState());
@@ -1517,6 +1541,18 @@ void MergeFeaturesFromOriginPolicy(WTF::StringBuilder& feature_policy,
}
}
+WindowAgent* GetWindowAgentForOrigin(LocalFrame* frame,
+ SecurityOrigin* origin) {
+ // TODO(keishi): Also check if AllowUniversalAccessFromFileURLs might
+ // dynamically change.
+ bool has_potential_universal_access_privilege =
+ !frame->GetSettings()->GetWebSecurityEnabled() ||
+ frame->GetSettings()->GetAllowUniversalAccessFromFileURLs();
+ return frame->window_agent_factory().GetAgentForOrigin(
+ has_potential_universal_access_privilege,
+ V8PerIsolateData::MainThreadIsolate(), origin);
+}
+
void DocumentLoader::InstallNewDocument(
const KURL& url,
const scoped_refptr<const SecurityOrigin> initiator_origin,
@@ -1535,8 +1571,10 @@ void DocumentLoader::InstallNewDocument(
}
// Re-validate Document Policy feature before installing the new document.
- if (!RuntimeEnabledFeatures::DocumentPolicyEnabled(owner_document))
+ if (!RuntimeEnabledFeatures::DocumentPolicyEnabled(
+ owner_document ? owner_document->GetExecutionContext() : nullptr)) {
document_policy_ = DocumentPolicy::ParsedDocumentPolicy{};
+ }
if (document_policy_.feature_state.contains(
mojom::blink::DocumentPolicyFeature::kForceLoadAtTop)) {
@@ -1548,7 +1586,7 @@ void DocumentLoader::InstallNewDocument(
DocumentInit init =
DocumentInit::Create()
- .WithDocumentLoader(this)
+ .WithDocumentLoader(this, content_security_policy_.Get())
.WithURL(url)
.WithTypeFrom(mime_type)
.WithOwnerDocument(owner_document)
@@ -1556,7 +1594,6 @@ void DocumentLoader::InstallNewDocument(
.WithOriginToCommit(origin_to_commit_)
.WithIPAddressSpace(ip_address_space_)
.WithSrcdocDocument(loading_srcdoc_)
- .WithBlockedByCSP(was_blocked_by_csp_)
.WithGrantLoadLocalResources(grant_load_local_resources_)
.WithFramePolicy(frame_policy_)
.WithNewRegistrationContext()
@@ -1576,22 +1613,34 @@ void DocumentLoader::InstallNewDocument(
response_.HttpHeaderField(http_names::kDocumentPolicyReportOnly))
.WithOriginTrialsHeader(
response_.HttpHeaderField(http_names::kOriginTrial))
- .WithContentSecurityPolicy(content_security_policy_.Get())
.WithWebBundleClaimedUrl(web_bundle_claimed_url_);
- if (commit_reason_ == CommitReason::kXSLT)
+ if (archive_) {
+ // The URL of a Document loaded from a MHTML archive is controlled by
+ // the Content-Location header. This would allow UXSS, since
+ // Content-Location can be arbitrarily controlled to control the
+ // Document's URL and origin. Instead, force a Document loaded from a
+ // MHTML archive to be sandboxed, providing exceptions only for creating
+ // new windows.
+ DCHECK(commit_reason_ == CommitReason::kRegular ||
+ commit_reason_ == CommitReason::kInitialization);
+ auto flags = (network::mojom::blink::WebSandboxFlags::kAll &
+ ~(network::mojom::blink::WebSandboxFlags::kPopups |
+ network::mojom::blink::WebSandboxFlags::
+ kPropagatesToAuxiliaryBrowsingContexts));
+ init = init.WithSandboxFlags(flags);
+ } else if (commit_reason_ == CommitReason::kXSLT) {
init = init.WithSandboxFlags(owner_document->GetSandboxFlags());
+ }
- // A javascript: url or XSLT inherits CSP from the document in which it was
- // executed.
- ContentSecurityPolicy* csp =
- IsJavaScriptURLOrXSLTCommit()
- ? frame_->GetDocument()->GetContentSecurityPolicy()
- : content_security_policy_.Get();
- global_object_reuse_policy_ =
- GetFrameLoader().ShouldReuseDefaultView(init.GetDocumentOrigin(), csp)
- ? GlobalObjectReusePolicy::kUseExisting
- : GlobalObjectReusePolicy::kCreateNew;
+ // We've not set the requisite state on the DocumentInit. Calculate the origin
+ // and cache it, so repeated GetDocumentOrigin() invocations return the same
+ // object.
+ init.CalculateAndCacheDocumentOrigin();
+
+ global_object_reuse_policy_ = init.ShouldReuseDOMWindow()
+ ? GlobalObjectReusePolicy::kUseExisting
+ : GlobalObjectReusePolicy::kCreateNew;
if (GetFrameLoader().StateMachine()->IsDisplayingInitialEmptyDocument()) {
GetFrameLoader().StateMachine()->AdvanceTo(
@@ -1603,9 +1652,6 @@ void DocumentLoader::InstallNewDocument(
previous_security_origin = frame_->GetDocument()->GetSecurityOrigin();
}
- bool was_cross_origin_to_parent_frame =
- previous_security_origin && frame_->IsCrossOriginToParentFrame();
-
// In some rare cases, we'll re-use a LocalDOMWindow for a new Document. For
// example, when a script calls window.open("..."), the browser gives
// JavaScript a window synchronously but kicks off the load in the window
@@ -1617,7 +1663,9 @@ void DocumentLoader::InstallNewDocument(
if (global_object_reuse_policy_ != GlobalObjectReusePolicy::kUseExisting) {
if (frame_->GetDocument())
frame_->GetDocument()->RemoveAllEventListenersRecursively();
- frame_->SetDOMWindow(MakeGarbageCollected<LocalDOMWindow>(*frame_));
+ frame_->SetDOMWindow(MakeGarbageCollected<LocalDOMWindow>(
+ *frame_,
+ GetWindowAgentForOrigin(frame_.Get(), init.GetDocumentOrigin().get())));
if (origin_policy_.has_value()) {
// Convert from WebVector<WebString> to WTF::Vector<WTF::String>
Vector<String> ids;
@@ -1627,8 +1675,21 @@ void DocumentLoader::InstallNewDocument(
frame_->DomWindow()->SetOriginPolicyIds(ids);
}
+ } else {
+ if (frame_->GetSettings()->GetShouldReuseGlobalForUnownedMainFrame() &&
+ frame_->IsMainFrame()) {
+ // When GetShouldReuseGlobalForUnownedMainFrame() causes a main frame's
+ // window to be reused, we should not inherit the initial empty document's
+ // Agent, which was a universal access Agent.
+ // This happens only in android webview.
+ frame_->DomWindow()->ResetWindowAgent(GetWindowAgentForOrigin(
+ frame_.Get(), init.GetDocumentOrigin().get()));
+ }
}
+ frame_->DomWindow()->SetOriginIsolationRestricted(
+ origin_isolation_restricted_);
+
WillCommitNavigation();
Document* document = frame_->DomWindow()->InstallNewDocument(init);
@@ -1676,12 +1737,6 @@ void DocumentLoader::InstallNewDocument(
// will use stale values from HTMLParserOption.
DidCommitNavigation();
- if (was_cross_origin_to_parent_frame !=
- frame_->IsCrossOriginToParentFrame()) {
- if (auto* owner = frame_->DeprecatedLocalOwner())
- owner->FrameCrossOriginToParentFrameChanged();
- }
-
if (initiator_origin) {
const scoped_refptr<const SecurityOrigin> url_origin =
SecurityOrigin::Create(Url());
@@ -1689,18 +1744,24 @@ void DocumentLoader::InstallNewDocument(
is_same_origin_navigation_ =
initiator_origin->IsSameOriginWith(url_origin.get()) &&
Url().ProtocolIsInHTTPFamily();
+ }
- // If the load is from a document from the same origin then we enable
- // deferred commits to avoid white flash on load. We only want to delay
- // commits on same origin loads to avoid confusing users. We also require
- // that this be an html document served via http.
- document->SetDeferredCompositorCommitIsAllowed(is_same_origin_navigation_ &&
- IsA<HTMLDocument>(document));
+ // The PaintHolding feature defers compositor commits until content has
+ // been painted or 500ms have passed, whichever comes first. The additional
+ // PaintHoldingCrossOrigin feature allows PaintHolding even for cross-origin
+ // navigations, otherwise only same-origin navigations have deferred commits.
+ // We also require that this be an html document served via http.
+ if (base::FeatureList::IsEnabled(blink::features::kPaintHolding) &&
+ IsA<HTMLDocument>(document) && Url().ProtocolIsInHTTPFamily() &&
+ (is_same_origin_navigation_ ||
+ base::FeatureList::IsEnabled(
+ blink::features::kPaintHoldingCrossOrigin))) {
+ document->SetDeferredCompositorCommitIsAllowed(true);
} else {
document->SetDeferredCompositorCommitIsAllowed(false);
}
- if (RuntimeEnabledFeatures::ForceLoadAtTopEnabled(document))
+ if (RuntimeEnabledFeatures::ForceLoadAtTopEnabled(frame_->DomWindow()))
CountUse(WebFeature::kForceLoadAtTop);
// Log if the document was blocked by CSP checks now that the new Document has
@@ -1780,7 +1841,10 @@ void DocumentLoader::CreateParserPostCommit() {
frame_->DomWindow(), &initiator_origin_trial_features_);
}
- ParserSynchronizationPolicy parsing_policy = kAllowAsynchronousParsing;
+ ParserSynchronizationPolicy parsing_policy =
+ RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()
+ ? kAllowDeferredParsing
+ : kAllowAsynchronousParsing;
if (IsJavaScriptURLOrXSLTCommit() ||
!Document::ThreadedParsingEnabledForTesting()) {
parsing_policy = kForceSynchronousParsing;
diff --git a/chromium/third_party/blink/renderer/core/loader/document_loader.h b/chromium/third_party/blink/renderer/core/loader/document_loader.h
index 073760ce6f2..10aaacaa3cb 100644
--- a/chromium/third_party/blink/renderer/core/loader/document_loader.h
+++ b/chromium/third_party/blink/renderer/core/loader/document_loader.h
@@ -103,6 +103,9 @@ enum class CommitResult : int32_t;
enum class GlobalObjectReusePolicy { kCreateNew, kUseExisting };
// The DocumentLoader fetches a main resource and handles the result.
+// TODO(https://crbug.com/855189). This was originally structured to have a
+// provisional load, then commit but that is no longer necessary and this class
+// can be simplified.
class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
public UseCounter,
public WebNavigationBodyLoader::Client {
@@ -220,10 +223,6 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
return application_cache_host_.Get();
}
- ClientHintsPreferences& GetClientHintsPreferences() {
- return client_hints_preferences_;
- }
-
WebURLRequest::PreviewsState GetPreviewsState() const {
return previews_state_;
}
@@ -253,7 +252,7 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
void LoadFailed(const ResourceError&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// For automation driver-initiated navigations over the devtools protocol,
// |devtools_navigation_token_| is used to tag the navigation. This navigation
@@ -432,6 +431,10 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
commit_reason_ == CommitReason::kXSLT;
}
+ // Params are saved in constructor and are cleared after StartLoading().
+ // TODO(dgozman): remove once StartLoading is merged with constructor.
+ std::unique_ptr<WebNavigationParams> params_;
+
// These fields are copied from WebNavigationParams, see there for definition.
KURL url_;
AtomicString http_method_;
@@ -440,18 +443,14 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
AtomicString http_content_type_;
WebURLRequest::PreviewsState previews_state_;
base::Optional<WebOriginPolicy> origin_policy_;
- scoped_refptr<const SecurityOrigin> requestor_origin_;
- KURL unreachable_url_;
+ const scoped_refptr<const SecurityOrigin> requestor_origin_;
+ const KURL unreachable_url_;
std::unique_ptr<WebNavigationBodyLoader> body_loader_;
- network::mojom::IPAddressSpace ip_address_space_ =
+ const network::mojom::IPAddressSpace ip_address_space_ =
network::mojom::IPAddressSpace::kUnknown;
- bool grant_load_local_resources_ = false;
- base::Optional<blink::mojom::FetchCacheMode> force_fetch_cache_mode_;
- FramePolicy frame_policy_;
-
- // Params are saved in constructor and are cleared after StartLoading().
- // TODO(dgozman): remove once StartLoading is merged with constructor.
- std::unique_ptr<WebNavigationParams> params_;
+ const bool grant_load_local_resources_ = false;
+ const base::Optional<blink::mojom::FetchCacheMode> force_fetch_cache_mode_;
+ const FramePolicy frame_policy_;
Member<LocalFrame> frame_;
@@ -470,7 +469,7 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
// A reference to actual request's url and referrer used to
// inititate this load.
KURL original_url_;
- Referrer original_referrer_;
+ const Referrer original_referrer_;
ResourceResponse response_;
@@ -482,8 +481,11 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
bool replaces_current_history_item_;
bool data_received_;
+ const Member<ContentSecurityPolicy> content_security_policy_;
+ const bool was_blocked_by_csp_;
+
+ const scoped_refptr<SecurityOrigin> origin_to_commit_;
WebNavigationType navigation_type_;
- scoped_refptr<SecurityOrigin> origin_to_commit_;
DocumentLoadTiming document_load_timing_;
@@ -498,9 +500,6 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
bool was_blocked_by_document_policy_;
Vector<PolicyParserMessageBuffer::Message> document_policy_parsing_messages_;
- const Member<ContentSecurityPolicy> content_security_policy_;
- const bool was_blocked_by_csp_;
-
ClientHintsPreferences client_hints_preferences_;
InitialScrollState initial_scroll_state_;
@@ -514,28 +513,28 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
// Used to protect against reentrancy into CommitData().
bool in_commit_data_;
scoped_refptr<SharedBuffer> data_buffer_;
- base::UnguessableToken devtools_navigation_token_;
+ const base::UnguessableToken devtools_navigation_token_;
bool defers_loading_ = false;
// Whether this load request comes with a sitcky user activation.
- bool had_sticky_activation_ = false;
+ const bool had_sticky_activation_ = false;
// Whether this load request had a user activation when created.
- bool had_transient_activation_ = false;
+ const bool had_transient_activation_ = false;
// Whether this load request was initiated by the browser.
- bool is_browser_initiated_ = false;
+ const bool is_browser_initiated_ = false;
// Whether this load request was initiated by the same origin.
bool is_same_origin_navigation_ = false;
// See WebNavigationParams for definition.
- bool was_discarded_ = false;
+ const bool was_discarded_ = false;
bool listing_ftp_directory_ = false;
bool loading_mhtml_archive_ = false;
- bool loading_srcdoc_ = false;
- bool loading_url_as_empty_document_ = false;
+ const bool loading_srcdoc_ = false;
+ const bool loading_url_as_empty_document_ = false;
CommitReason commit_reason_ = CommitReason::kRegular;
uint64_t main_resource_identifier_ = 0;
scoped_refptr<ResourceTimingInfo> navigation_timing_info_;
@@ -543,8 +542,8 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
WebScopedVirtualTimePauser virtual_time_pauser_;
Member<SourceKeyedCachedMetadataHandler> cached_metadata_handler_;
Member<PrefetchedSignedExchangeManager> prefetched_signed_exchange_manager_;
- KURL web_bundle_physical_url_;
- KURL web_bundle_claimed_url_;
+ const KURL web_bundle_physical_url_;
+ const KURL web_bundle_claimed_url_;
// This UseCounterHelper tracks feature usage associated with the lifetime of
// the document load. Features recorded prior to commit will be recorded
@@ -557,9 +556,9 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
const base::TickClock* clock_;
- Vector<OriginTrialFeature> initiator_origin_trial_features_;
+ const Vector<OriginTrialFeature> initiator_origin_trial_features_;
- Vector<String> force_enabled_origin_trials_;
+ const Vector<String> force_enabled_origin_trials_;
// Whether this load request is a result of a browser initiated same-document
// navigation.
@@ -567,6 +566,8 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
// Whether the document can be scrolled on load
bool navigation_scroll_allowed_ = true;
+
+ bool origin_isolation_restricted_ = false;
};
DECLARE_WEAK_IDENTIFIER_MAP(DocumentLoader);
diff --git a/chromium/third_party/blink/renderer/core/loader/document_loader_test.cc b/chromium/third_party/blink/renderer/core/loader/document_loader_test.cc
index c680b907120..43dc2a7f9e5 100644
--- a/chromium/third_party/blink/renderer/core/loader/document_loader_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/document_loader_test.cc
@@ -7,7 +7,9 @@
#include <utility>
#include "base/auto_reset.h"
+#include "base/test/scoped_feature_list.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-shared.h"
#include "third_party/blink/public/mojom/feature_policy/policy_disposition.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/frame_owner_element_type.mojom-blink.h"
@@ -255,9 +257,9 @@ TEST_F(DocumentLoaderSimTest, FramePolicyIntegrityOnNavigationCommit) {
iframe_resource.Finish();
auto* child_frame = To<WebLocalFrameImpl>(MainFrame().FirstChild());
- auto* child_document = child_frame->GetFrame()->GetDocument();
+ auto* child_window = child_frame->GetFrame()->DomWindow();
- EXPECT_TRUE(child_document->IsFeatureEnabled(
+ EXPECT_TRUE(child_window->IsFeatureEnabled(
blink::mojom::blink::FeaturePolicyFeature::kPayment));
}
// When runtime feature DocumentPolicy is not enabled, specifying
@@ -286,7 +288,7 @@ TEST_F(DocumentLoaderSimTest, DocumentPolicyNoEffectWhenFlagNotSet) {
iframe_resource.Finish();
auto* child_frame = To<WebLocalFrameImpl>(MainFrame().FirstChild());
- auto* child_document = child_frame->GetFrame()->GetDocument();
+ auto* child_window = child_frame->GetFrame()->DomWindow();
auto& console_messages = static_cast<frame_test_helpers::TestWebFrameClient*>(
child_frame->Client())
->ConsoleMessages();
@@ -295,24 +297,24 @@ TEST_F(DocumentLoaderSimTest, DocumentPolicyNoEffectWhenFlagNotSet) {
// violation blocking document load.
EXPECT_TRUE(console_messages.IsEmpty());
- EXPECT_EQ(child_document->Url(), KURL("https://example.com/foo.html"));
+ EXPECT_EQ(child_window->Url(), KURL("https://example.com/foo.html"));
- EXPECT_FALSE(child_document->IsUseCounted(
+ EXPECT_FALSE(child_window->document()->IsUseCounted(
mojom::WebFeature::kDocumentPolicyCausedPageUnload));
// Unoptimized-lossless-images should still be allowed in main document.
- EXPECT_TRUE(GetDocument().IsFeatureEnabled(
+ EXPECT_TRUE(Window().IsFeatureEnabled(
mojom::blink::DocumentPolicyFeature::kUnoptimizedLosslessImages,
PolicyValue(2.0)));
- EXPECT_TRUE(GetDocument().IsFeatureEnabled(
+ EXPECT_TRUE(Window().IsFeatureEnabled(
mojom::blink::DocumentPolicyFeature::kUnoptimizedLosslessImages,
PolicyValue(1.0)));
// Unoptimized-lossless-images should still be allowed in child document.
- EXPECT_TRUE(child_document->IsFeatureEnabled(
+ EXPECT_TRUE(child_window->IsFeatureEnabled(
mojom::blink::DocumentPolicyFeature::kUnoptimizedLosslessImages,
PolicyValue(2.0)));
- EXPECT_TRUE(child_document->IsFeatureEnabled(
+ EXPECT_TRUE(child_window->IsFeatureEnabled(
mojom::blink::DocumentPolicyFeature::kUnoptimizedLosslessImages,
PolicyValue(1.0)));
}
@@ -661,6 +663,29 @@ TEST_F(DocumentLoaderTest, CommitsNotDeferredOnDifferentOriginNavigation) {
EXPECT_FALSE(local_frame->GetDocument()->DeferredCompositorCommitIsAllowed());
}
+TEST_F(DocumentLoaderTest,
+ CommitsDeferredOnDifferentOriginNavigationWithCrossOriginEnabled) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeature(features::kPaintHoldingCrossOrigin);
+
+ const KURL& requestor_url =
+ KURL(NullURL(), "https://www.example.com/foo.html");
+ WebViewImpl* web_view_impl =
+ web_view_helper_.InitializeAndLoad("https://example.com/foo.html");
+
+ const KURL& other_origin_url =
+ KURL(NullURL(), "https://www.another.com/bar.html");
+ std::unique_ptr<WebNavigationParams> params =
+ WebNavigationParams::CreateWithHTMLBuffer(SharedBuffer::Create(),
+ other_origin_url);
+ params->requestor_origin = WebSecurityOrigin::Create(WebURL(requestor_url));
+ LocalFrame* local_frame =
+ To<LocalFrame>(web_view_impl->GetPage()->MainFrame());
+ local_frame->Loader().CommitNavigation(std::move(params), nullptr);
+
+ EXPECT_TRUE(local_frame->GetDocument()->DeferredCompositorCommitIsAllowed());
+}
+
TEST_F(DocumentLoaderTest, CommitsNotDeferredOnDifferentPortNavigation) {
const KURL& requestor_url =
KURL(NullURL(), "https://www.example.com:8000/foo.html");
@@ -680,6 +705,29 @@ TEST_F(DocumentLoaderTest, CommitsNotDeferredOnDifferentPortNavigation) {
EXPECT_FALSE(local_frame->GetDocument()->DeferredCompositorCommitIsAllowed());
}
+TEST_F(DocumentLoaderTest,
+ CommitsDeferredOnDifferentPortNavigationWithCrossOriginEnabled) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeature(features::kPaintHoldingCrossOrigin);
+
+ const KURL& requestor_url =
+ KURL(NullURL(), "https://www.example.com:8000/foo.html");
+ WebViewImpl* web_view_impl =
+ web_view_helper_.InitializeAndLoad("https://example.com:8000/foo.html");
+
+ const KURL& different_port_url =
+ KURL(NullURL(), "https://www.example.com:8080/bar.html");
+ std::unique_ptr<WebNavigationParams> params =
+ WebNavigationParams::CreateWithHTMLBuffer(SharedBuffer::Create(),
+ different_port_url);
+ params->requestor_origin = WebSecurityOrigin::Create(WebURL(requestor_url));
+ LocalFrame* local_frame =
+ To<LocalFrame>(web_view_impl->GetPage()->MainFrame());
+ local_frame->Loader().CommitNavigation(std::move(params), nullptr);
+
+ EXPECT_TRUE(local_frame->GetDocument()->DeferredCompositorCommitIsAllowed());
+}
+
TEST_F(DocumentLoaderTest, CommitsNotDeferredOnDataURLNavigation) {
const KURL& requestor_url =
KURL(NullURL(), "https://www.example.com/foo.html");
@@ -698,6 +746,28 @@ TEST_F(DocumentLoaderTest, CommitsNotDeferredOnDataURLNavigation) {
EXPECT_FALSE(local_frame->GetDocument()->DeferredCompositorCommitIsAllowed());
}
+TEST_F(DocumentLoaderTest,
+ CommitsNotDeferredOnDataURLNavigationWithCrossOriginEnabled) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeature(features::kPaintHoldingCrossOrigin);
+
+ const KURL& requestor_url =
+ KURL(NullURL(), "https://www.example.com/foo.html");
+ WebViewImpl* web_view_impl =
+ web_view_helper_.InitializeAndLoad("https://example.com/foo.html");
+
+ const KURL& data_url = KURL(NullURL(), "data:,Hello%2C%20World!");
+ std::unique_ptr<WebNavigationParams> params =
+ WebNavigationParams::CreateWithHTMLBuffer(SharedBuffer::Create(),
+ data_url);
+ params->requestor_origin = WebSecurityOrigin::Create(WebURL(requestor_url));
+ LocalFrame* local_frame =
+ To<LocalFrame>(web_view_impl->GetPage()->MainFrame());
+ local_frame->Loader().CommitNavigation(std::move(params), nullptr);
+
+ EXPECT_FALSE(local_frame->GetDocument()->DeferredCompositorCommitIsAllowed());
+}
+
TEST_F(DocumentLoaderTest, SameOriginNavigation) {
const KURL& requestor_url =
KURL(NullURL(), "https://www.example.com/foo.html");
diff --git a/chromium/third_party/blink/renderer/core/loader/empty_clients.h b/chromium/third_party/blink/renderer/core/loader/empty_clients.h
index 3379260227c..a3797ca04ff 100644
--- a/chromium/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/chromium/third_party/blink/renderer/core/loader/empty_clients.h
@@ -35,6 +35,7 @@
#include "cc/paint/paint_canvas.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/common/input/web_menu_source_type.h"
#include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
@@ -93,7 +94,8 @@ class CORE_EXPORT EmptyChromeClient : public ChromeClient {
void ChromeDestroyed() override {}
void SetWindowRect(const IntRect&, LocalFrame&) override {}
IntRect RootWindowRect(LocalFrame&) override { return IntRect(); }
- void Focus(LocalFrame*) override {}
+ void FocusPage() override {}
+ void DidFocusPage() override {}
bool CanTakeFocus(mojom::blink::FocusType) override { return false; }
void TakeFocus(mojom::blink::FocusType) override {}
void Show(NavigationPolicy) override {}
@@ -229,7 +231,6 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
bool InShadowTree() const override { return false; }
Frame* Opener() const override { return nullptr; }
- void SetOpener(Frame*) override {}
Frame* Parent() const override { return nullptr; }
Frame* Top() const override { return nullptr; }
@@ -413,25 +414,21 @@ class CORE_EXPORT EmptyRemoteFrameClient : public RemoteFrameClient {
mojo::PendingRemote<mojom::blink::BlobURLToken>,
const base::Optional<WebImpression>&) override {}
unsigned BackForwardLength() override { return 0; }
- void ForwardPostMessage(
- MessageEvent*,
- scoped_refptr<const SecurityOrigin> target,
- base::Optional<base::UnguessableToken> locked_agent_cluster_id,
- LocalFrame* source_frame) const override {}
void FrameRectsChanged(const IntRect& local_frame_rect,
const IntRect& transformed_frame_rect) override {}
void UpdateRemoteViewportIntersection(
const ViewportIntersectionState& intersection_state) override {}
- void AdvanceFocus(mojom::blink::FocusType, LocalFrame* source) override {}
uint32_t Print(const IntRect& rect, cc::PaintCanvas* canvas) const override {
return 0;
}
+ AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() override {
+ return AssociatedInterfaceProvider::GetEmptyAssociatedInterfaceProvider();
+ }
// FrameClient implementation.
bool InShadowTree() const override { return false; }
void Detached(FrameDetachType) override {}
Frame* Opener() const override { return nullptr; }
- void SetOpener(Frame*) override {}
Frame* Parent() const override { return nullptr; }
Frame* Top() const override { return nullptr; }
Frame* NextSibling() const override { return nullptr; }
diff --git a/chromium/third_party/blink/renderer/core/loader/font_preload_manager.cc b/chromium/third_party/blink/renderer/core/loader/font_preload_manager.cc
index babcddb8903..697a4733826 100644
--- a/chromium/third_party/blink/renderer/core/loader/font_preload_manager.cc
+++ b/chromium/third_party/blink/renderer/core/loader/font_preload_manager.cc
@@ -24,7 +24,7 @@ class FontPreloadFinishObserver final : public ResourceFinishObserver {
~FontPreloadFinishObserver() final = default;
- void Trace(blink::Visitor* visitor) final {
+ void Trace(blink::Visitor* visitor) const final {
visitor->Trace(font_resource_);
visitor->Trace(document_);
ResourceFinishObserver::Trace(visitor);
@@ -52,7 +52,7 @@ class ImperativeFontLoadFinishedCallback final
: document_(document) {}
~ImperativeFontLoadFinishedCallback() final = default;
- void Trace(Visitor* visitor) final {
+ void Trace(Visitor* visitor) const final {
visitor->Trace(document_);
FontFace::LoadFontCallback::Trace(visitor);
}
@@ -207,7 +207,7 @@ void FontPreloadManager::DisableTimeoutForTest() {
render_delay_timer_.Stop();
}
-void FontPreloadManager::Trace(Visitor* visitor) {
+void FontPreloadManager::Trace(Visitor* visitor) const {
visitor->Trace(finish_observers_);
visitor->Trace(document_);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/font_preload_manager.h b/chromium/third_party/blink/renderer/core/loader/font_preload_manager.h
index a7e4871c94e..3e98fc931a2 100644
--- a/chromium/third_party/blink/renderer/core/loader/font_preload_manager.h
+++ b/chromium/third_party/blink/renderer/core/loader/font_preload_manager.h
@@ -44,7 +44,7 @@ class CORE_EXPORT FontPreloadManager final {
// Exposed to web tests via internals.
void SetRenderDelayTimeoutForTest(base::TimeDelta timeout);
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
private:
friend class FontPreloadManagerTest;
diff --git a/chromium/third_party/blink/renderer/core/loader/font_preload_manager_test.cc b/chromium/third_party/blink/renderer/core/loader/font_preload_manager_test.cc
index a3ce32c60d9..57667142d75 100644
--- a/chromium/third_party/blink/renderer/core/loader/font_preload_manager_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/font_preload_manager_test.cc
@@ -64,6 +64,9 @@ TEST_F(FontPreloadManagerTest, FastFontFinishBeforeBody) {
href="https://example.com/font.woff">
)HTML");
+ // Make sure timer doesn't fire in case the test runs slow.
+ GetFontPreloadManager().SetRenderDelayTimeoutForTest(base::TimeDelta::Max());
+
// Rendering is blocked due to ongoing font preloading.
EXPECT_TRUE(Compositor().DeferMainFrameUpdate());
EXPECT_TRUE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
@@ -464,6 +467,9 @@ TEST_F(FontPreloadManagerTest, OptionalFontFastImperativeLoad) {
<span id=target>0123456789</span>
)HTML");
+ // Make sure timer doesn't fire in case the test runs slow.
+ GetFontPreloadManager().SetRenderDelayTimeoutForTest(base::TimeDelta::Max());
+
// Rendering is blocked due to font being preloaded.
EXPECT_TRUE(Compositor().DeferMainFrameUpdate());
EXPECT_TRUE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
diff --git a/chromium/third_party/blink/renderer/core/loader/form_submission.cc b/chromium/third_party/blink/renderer/core/loader/form_submission.cc
index 8bd486a40f1..bb4d1da51b1 100644
--- a/chromium/third_party/blink/renderer/core/loader/form_submission.cc
+++ b/chromium/third_party/blink/renderer/core/loader/form_submission.cc
@@ -328,7 +328,7 @@ FormSubmission* FormSubmission::Create(HTMLFormElement* form,
frame_request.OriginDocument());
}
-void FormSubmission::Trace(Visitor* visitor) {
+void FormSubmission::Trace(Visitor* visitor) const {
visitor->Trace(form_);
visitor->Trace(target_frame_);
visitor->Trace(origin_document_);
diff --git a/chromium/third_party/blink/renderer/core/loader/form_submission.h b/chromium/third_party/blink/renderer/core/loader/form_submission.h
index 0153ff0ba5b..b04284a2fd4 100644
--- a/chromium/third_party/blink/renderer/core/loader/form_submission.h
+++ b/chromium/third_party/blink/renderer/core/loader/form_submission.h
@@ -117,7 +117,7 @@ class FormSubmission final : public GarbageCollected<FormSubmission> {
// FormSubmission for DialogMethod
explicit FormSubmission(const String& result);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void Navigate();
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/chromium/third_party/blink/renderer/core/loader/frame_fetch_context.cc
index 51f3241349b..024e9accb55 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_fetch_context.cc
+++ b/chromium/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -224,7 +224,9 @@ struct FrameFetchContext::FrozenState final : GarbageCollected<FrozenState> {
const base::Optional<UserAgentMetadata> user_agent_metadata;
const bool is_svg_image_chrome_client;
- void Trace(Visitor* visitor) { visitor->Trace(content_security_policy); }
+ void Trace(Visitor* visitor) const {
+ visitor->Trace(content_security_policy);
+ }
};
ResourceFetcher* FrameFetchContext::CreateFetcherForCommittedDocument(
@@ -238,7 +240,7 @@ ResourceFetcher* FrameFetchContext::CreateFetcherForCommittedDocument(
properties,
MakeGarbageCollected<FrameFetchContext>(loader, document, properties),
frame->GetTaskRunner(TaskType::kNetworking),
- MakeGarbageCollected<LoaderFactoryForFrame>(loader, document));
+ MakeGarbageCollected<LoaderFactoryForFrame>(loader, *frame->DomWindow()));
init.use_counter = MakeGarbageCollected<DetachableUseCounter>(&document);
init.console_logger = MakeGarbageCollected<DetachableConsoleLogger>(
document.GetExecutionContext());
@@ -285,24 +287,20 @@ scoped_refptr<const SecurityOrigin> FrameFetchContext::GetTopFrameOrigin()
SubresourceFilter* FrameFetchContext::GetSubresourceFilter() const {
if (GetResourceFetcherProperties().IsDetached())
return nullptr;
- DocumentLoader* document_loader = MasterDocumentLoader();
- return document_loader ? document_loader->GetSubresourceFilter() : nullptr;
+ return document_loader_->GetSubresourceFilter();
}
PreviewsResourceLoadingHints*
FrameFetchContext::GetPreviewsResourceLoadingHints() const {
if (GetResourceFetcherProperties().IsDetached())
return nullptr;
- DocumentLoader* document_loader = MasterDocumentLoader();
- if (!document_loader)
- return nullptr;
- return document_loader->GetPreviewsResourceLoadingHints();
+ return document_loader_->GetPreviewsResourceLoadingHints();
}
WebURLRequest::PreviewsState FrameFetchContext::previews_state() const {
- DocumentLoader* document_loader = MasterDocumentLoader();
- return document_loader ? document_loader->GetPreviewsState()
- : WebURLRequest::kPreviewsUnspecified;
+ if (GetResourceFetcherProperties().IsDetached())
+ return WebURLRequest::kPreviewsUnspecified;
+ return document_loader_->GetPreviewsState();
}
LocalFrame* FrameFetchContext::GetFrame() const {
@@ -322,7 +320,7 @@ void FrameFetchContext::AddAdditionalRequestHeaders(ResourceRequest& request) {
return;
// Reload should reflect the current data saver setting.
- if (IsReloadLoadType(MasterDocumentLoader()->LoadType()))
+ if (IsReloadLoadType(document_loader_->LoadType()))
request.ClearHttpHeaderField(http_names::kSaveData);
if (save_data_enabled_)
@@ -352,11 +350,6 @@ mojom::FetchCacheMode FrameFetchContext::ResourceRequestCachePolicy(
return cache_mode;
}
-inline DocumentLoader* FrameFetchContext::MasterDocumentLoader() const {
- DCHECK(!GetResourceFetcherProperties().IsDetached());
- return document_loader_;
-}
-
void FrameFetchContext::PrepareRequest(
ResourceRequest& request,
const FetchInitiatorInfo& initiator_info,
@@ -364,9 +357,7 @@ void FrameFetchContext::PrepareRequest(
ResourceType resource_type) {
// TODO(yhirano): Clarify which statements are actually needed when
// this is called during redirect.
- const bool for_redirect =
- (request.GetRedirectStatus() ==
- ResourceRequest::RedirectStatus::kFollowedRedirect);
+ const bool for_redirect = request.GetRedirectInfo().has_value();
SetFirstPartyCookie(request);
if (request.GetRequestContext() ==
@@ -384,13 +375,12 @@ void FrameFetchContext::PrepareRequest(
if (GetResourceFetcherProperties().IsDetached())
return;
- DocumentLoader* document_loader = MasterDocumentLoader();
- if (document_loader->ForceFetchCacheMode())
- request.SetCacheMode(*document_loader->ForceFetchCacheMode());
+ if (document_loader_->ForceFetchCacheMode())
+ request.SetCacheMode(*document_loader_->ForceFetchCacheMode());
if (request.GetPreviewsState() == WebURLRequest::kPreviewsUnspecified) {
WebURLRequest::PreviewsState request_previews_state =
- document_loader->GetPreviewsState();
+ document_loader_->GetPreviewsState();
if (request_previews_state == WebURLRequest::kPreviewsUnspecified)
request_previews_state = WebURLRequest::kPreviewsOff;
request.SetPreviewsState(request_previews_state);
@@ -404,13 +394,14 @@ void FrameFetchContext::PrepareRequest(
WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant);
}
- probe::PrepareRequest(Probe(), document_loader, request, initiator_info,
+ probe::PrepareRequest(Probe(), document_loader_, request, initiator_info,
resource_type);
// ServiceWorker hook ups.
- if (document_loader->GetServiceWorkerNetworkProvider()) {
+ if (document_loader_->GetServiceWorkerNetworkProvider()) {
WrappedResourceRequest webreq(request);
- document_loader->GetServiceWorkerNetworkProvider()->WillSendRequest(webreq);
+ document_loader_->GetServiceWorkerNetworkProvider()->WillSendRequest(
+ webreq);
}
}
@@ -702,9 +693,10 @@ void FrameFetchContext::PopulateResourceRequest(
ResourceType type,
const ClientHintsPreferences& hints_preferences,
const FetchParameters::ResourceWidth& resource_width,
- ResourceRequest& request) {
+ ResourceRequest& request,
+ const FetchInitiatorInfo& initiator_info) {
if (!GetResourceFetcherProperties().IsDetached())
- probe::SetDevToolsIds(Probe(), request);
+ probe::SetDevToolsIds(Probe(), request, initiator_info);
ModifyRequestForCSP(request);
AddClientHintsIfNecessary(hints_preferences, resource_width, request);
@@ -770,9 +762,8 @@ void FrameFetchContext::DispatchDidBlockRequest(
ResourceType resource_type) const {
if (GetResourceFetcherProperties().IsDetached())
return;
- probe::DidBlockRequest(Probe(), resource_request, MasterDocumentLoader(),
- Url(), fetch_initiator_info, blocked_reason,
- resource_type);
+ probe::DidBlockRequest(Probe(), resource_request, document_loader_, Url(),
+ fetch_initiator_info, blocked_reason, resource_type);
}
bool FrameFetchContext::ShouldBypassMainWorldCSP() const {
@@ -792,15 +783,13 @@ bool FrameFetchContext::IsSVGImageChromeClient() const {
void FrameFetchContext::CountUsage(WebFeature feature) const {
if (GetResourceFetcherProperties().IsDetached())
return;
- if (DocumentLoader* loader = MasterDocumentLoader())
- loader->GetUseCounterHelper().Count(feature, GetFrame());
+ document_loader_->GetUseCounterHelper().Count(feature, GetFrame());
}
void FrameFetchContext::CountDeprecation(WebFeature feature) const {
if (GetResourceFetcherProperties().IsDetached())
return;
- if (MasterDocumentLoader())
- Deprecation::CountDeprecation(MasterDocumentLoader(), feature);
+ Deprecation::CountDeprecation(document_loader_, feature);
}
bool FrameFetchContext::ShouldBlockWebSocketByMixedContentCheck(
@@ -828,7 +817,7 @@ FrameFetchContext::CreateWebSocketHandshakeThrottle() {
bool FrameFetchContext::ShouldBlockFetchByMixedContentCheck(
mojom::RequestContextType request_context,
- ResourceRequest::RedirectStatus redirect_status,
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info,
const KURL& url,
ReportingDisposition reporting_disposition,
const base::Optional<String>& devtools_id) const {
@@ -836,9 +825,14 @@ bool FrameFetchContext::ShouldBlockFetchByMixedContentCheck(
// TODO(yhirano): Implement the detached case.
return false;
}
+ const KURL& url_before_redirects =
+ redirect_info ? redirect_info->original_url : url;
+ ResourceRequest::RedirectStatus redirect_status =
+ redirect_info ? RedirectStatus::kFollowedRedirect
+ : RedirectStatus::kNoRedirect;
return MixedContentChecker::ShouldBlockFetch(
- GetFrame(), request_context, redirect_status, url, devtools_id,
- reporting_disposition);
+ GetFrame(), request_context, url_before_redirects, redirect_status, url,
+ devtools_id, reporting_disposition);
}
bool FrameFetchContext::ShouldBlockFetchAsCredentialedSubresource(
@@ -996,7 +990,7 @@ FetchContext* FrameFetchContext::Detach() {
return this;
}
-void FrameFetchContext::Trace(Visitor* visitor) {
+void FrameFetchContext::Trace(Visitor* visitor) const {
visitor->Trace(document_loader_);
visitor->Trace(document_);
visitor->Trace(frozen_state_);
@@ -1023,22 +1017,21 @@ bool FrameFetchContext::CalculateIfAdSubresource(
bool FrameFetchContext::SendConversionRequestInsteadOfRedirecting(
const KURL& url,
- ResourceRequest::RedirectStatus redirect_status,
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info,
ReportingDisposition reporting_disposition) const {
- if (!RuntimeEnabledFeatures::ConversionMeasurementEnabled())
+ if (GetResourceFetcherProperties().IsDetached())
return false;
- if (GetResourceFetcherProperties().IsDetached())
+ if (!RuntimeEnabledFeatures::ConversionMeasurementEnabled(
+ document_->domWindow())) {
return false;
+ }
LocalFrame* frame = document_->GetFrame();
DCHECK(frame);
// Only register conversions pings that are redirects in the main frame.
- // TODO(https://crbug.com/1042919): This should also validate that the
- // redirect is same origin to ensure that the reporting domain has consented
- // to the registration event.
- if (!frame->IsMainFrame() ||
- redirect_status != ResourceRequest::RedirectStatus::kFollowedRedirect) {
+ if (!frame->IsMainFrame() || !redirect_info ||
+ !SecurityOrigin::AreSameOrigin(url, redirect_info->previous_url)) {
return false;
}
@@ -1047,7 +1040,7 @@ bool FrameFetchContext::SendConversionRequestInsteadOfRedirecting(
if (url.GetPath() != kWellKnownConversionRegsitrationPath)
return false;
- if (!document_->IsFeatureEnabled(
+ if (!document_->domWindow()->IsFeatureEnabled(
mojom::blink::FeaturePolicyFeature::kConversionMeasurement)) {
String message =
"The 'conversion-measurement' feature policy must be enabled to "
@@ -1094,12 +1087,20 @@ bool FrameFetchContext::SendConversionRequestInsteadOfRedirecting(
GetFrame()->GetRemoteNavigationAssociatedInterfaces()->GetInterface(
&conversion_host);
conversion_host->RegisterConversion(std::move(conversion));
+
+ // Log use counters once we have a conversion.
+ UseCounter::Count(document_->domWindow(),
+ mojom::blink::WebFeature::kConversionAPIAll);
+ UseCounter::Count(document_->domWindow(),
+ mojom::blink::WebFeature::kConversionRegistration);
+
return true;
}
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
FrameFetchContext::TakePendingWorkerTimingReceiver(int request_id) {
- return MasterDocumentLoader()->TakePendingWorkerTimingReceiver(request_id);
+ DCHECK(!GetResourceFetcherProperties().IsDetached());
+ return document_loader_->TakePendingWorkerTimingReceiver(request_id);
}
base::Optional<ResourceRequestBlockedReason> FrameFetchContext::CanRequest(
@@ -1108,7 +1109,7 @@ base::Optional<ResourceRequestBlockedReason> FrameFetchContext::CanRequest(
const KURL& url,
const ResourceLoaderOptions& options,
ReportingDisposition reporting_disposition,
- ResourceRequest::RedirectStatus redirect_status) const {
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info) const {
if (!GetResourceFetcherProperties().IsDetached() &&
document_->IsFreezingInProgress() && !resource_request.GetKeepalive()) {
AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
@@ -1118,7 +1119,7 @@ base::Optional<ResourceRequestBlockedReason> FrameFetchContext::CanRequest(
return ResourceRequestBlockedReason::kOther;
}
return BaseFetchContext::CanRequest(type, resource_request, url, options,
- reporting_disposition, redirect_status);
+ reporting_disposition, redirect_info);
}
CoreProbeSink* FrameFetchContext::Probe() const {
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_fetch_context.h b/chromium/third_party/blink/renderer/core/loader/frame_fetch_context.h
index caf0421f52f..98267170221 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_fetch_context.h
+++ b/chromium/third_party/blink/renderer/core/loader/frame_fetch_context.h
@@ -75,7 +75,8 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext {
const KURL& url,
const ResourceLoaderOptions& options,
ReportingDisposition reporting_disposition,
- ResourceRequest::RedirectStatus redirect_status) const override;
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info)
+ const override;
mojom::FetchCacheMode ResourceRequestCachePolicy(
const ResourceRequest&,
ResourceType,
@@ -91,7 +92,8 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext {
void PopulateResourceRequest(ResourceType,
const ClientHintsPreferences&,
const FetchParameters::ResourceWidth&,
- ResourceRequest&) override;
+ ResourceRequest&,
+ const FetchInitiatorInfo&) override;
// Exposed for testing.
void ModifyRequestForCSP(ResourceRequest&);
@@ -101,7 +103,7 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext {
FetchContext* Detach() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool CalculateIfAdSubresource(
const ResourceRequest& resource_request,
@@ -110,7 +112,7 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext {
bool SendConversionRequestInsteadOfRedirecting(
const KURL& url,
- ResourceRequest::RedirectStatus redirect_status,
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info,
ReportingDisposition reporting_disposition) const override;
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
@@ -125,7 +127,6 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext {
// relevant document loader or frame in either cases without null-checks.
//
// TODO(kinuko): Remove constness, these return non-const members.
- DocumentLoader* MasterDocumentLoader() const;
LocalFrame* GetFrame() const;
LocalFrameClient* GetLocalFrameClient() const;
@@ -151,7 +152,7 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext {
override;
bool ShouldBlockFetchByMixedContentCheck(
mojom::blink::RequestContextType request_context,
- ResourceRequest::RedirectStatus redirect_status,
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info,
const KURL& url,
ReportingDisposition reporting_disposition,
const base::Optional<String>& devtools_id) const override;
@@ -195,6 +196,7 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext {
CoreProbeSink* Probe() const;
+ // These are set on the constructor, and valid until Detach() is called.
Member<DocumentLoader> document_loader_;
Member<Document> document_;
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc b/chromium/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
index 6102a61dc8c..ce8c9720521 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
@@ -32,6 +32,7 @@
#include <memory>
+#include "base/optional.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -238,9 +239,9 @@ class FrameFetchContextSubresourceFilterTest : public FrameFetchContextTest {
.GetSecurityOrigin());
ResourceLoaderOptions options;
// DJKim
- return GetFetchContext()->CanRequest(
- ResourceType::kImage, resource_request, input_url, options,
- reporting_disposition, ResourceRequest::RedirectStatus::kNoRedirect);
+ return GetFetchContext()->CanRequest(ResourceType::kImage, resource_request,
+ input_url, options,
+ reporting_disposition, base::nullopt);
}
int filtered_load_callback_counter_;
@@ -1363,7 +1364,8 @@ TEST_F(FrameFetchContextTest, PopulateResourceRequestWhenDetached) {
dummy_page_holder = nullptr;
GetFetchContext()->PopulateResourceRequest(
- ResourceType::kRaw, client_hints_preferences, resource_width, request);
+ ResourceType::kRaw, client_hints_preferences, resource_width, request,
+ FetchInitiatorInfo());
// Should not crash.
}
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_load_request.cc b/chromium/third_party/blink/renderer/core/loader/frame_load_request.cc
index face9dd90dc..bd5813967f0 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_load_request.cc
+++ b/chromium/third_party/blink/renderer/core/loader/frame_load_request.cc
@@ -11,14 +11,15 @@
#include "third_party/blink/renderer/core/fileapi/public_url_manager.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
+#include "third_party/blink/renderer/platform/network/encoded_form_data.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
namespace blink {
-static void SetReferrerForRequest(Document* origin_document,
+static void SetReferrerForRequest(ExecutionContext* origin_context,
ResourceRequest& request) {
- DCHECK(origin_document);
+ DCHECK(origin_context);
// Always use the initiating document to generate the referrer. We need to
// generateReferrer(), because we haven't enforced
@@ -28,10 +29,10 @@ static void SetReferrerForRequest(Document* origin_document,
request.GetReferrerPolicy();
if (referrer_to_use == Referrer::ClientReferrerString())
- referrer_to_use = origin_document->OutgoingReferrer();
+ referrer_to_use = origin_context->OutgoingReferrer();
if (referrer_policy_to_use == network::mojom::ReferrerPolicy::kDefault)
- referrer_policy_to_use = origin_document->GetReferrerPolicy();
+ referrer_policy_to_use = origin_context->GetReferrerPolicy();
Referrer referrer = SecurityPolicy::GenerateReferrer(
referrer_policy_to_use, request.Url(), referrer_to_use);
@@ -65,15 +66,17 @@ FrameLoadRequest::FrameLoadRequest(Document* origin_document,
DCHECK(!resource_request_.RequestorOrigin());
resource_request_.SetRequestorOrigin(origin_document->GetSecurityOrigin());
- if (resource_request.Url().ProtocolIs("blob")) {
- blob_url_token_ = base::MakeRefCounted<
- base::RefCountedData<mojo::Remote<mojom::blink::BlobURLToken>>>();
- origin_document->GetPublicURLManager().Resolve(
- resource_request.Url(),
- blob_url_token_->data.BindNewPipeAndPassReceiver());
- }
+ if (auto* context = origin_document->GetExecutionContext()) {
+ if (resource_request.Url().ProtocolIs("blob")) {
+ blob_url_token_ = base::MakeRefCounted<
+ base::RefCountedData<mojo::Remote<mojom::blink::BlobURLToken>>>();
+ context->GetPublicURLManager().Resolve(
+ resource_request.Url(),
+ blob_url_token_->data.BindNewPipeAndPassReceiver());
+ }
- SetReferrerForRequest(origin_document_, resource_request_);
+ SetReferrerForRequest(context, resource_request_);
+ }
}
}
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_loader.cc b/chromium/third_party/blink/renderer/core/loader/frame_loader.cc
index 44f0a5f883c..9e6a9734b49 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -199,10 +199,9 @@ ResourceRequest FrameLoader::ResourceRequestForReload(
// was initiated by something in the current document and should therefore
// show the current document's url as the referrer.
if (client_redirect_policy == ClientRedirectPolicy::kClientRedirect) {
+ LocalDOMWindow* window = frame_->DomWindow();
Referrer referrer = SecurityPolicy::GenerateReferrer(
- frame_->GetDocument()->GetReferrerPolicy(),
- frame_->GetDocument()->Url(),
- frame_->GetDocument()->OutgoingReferrer());
+ window->GetReferrerPolicy(), window->Url(), window->OutgoingReferrer());
request.SetReferrerString(referrer.referrer);
request.SetReferrerPolicy(referrer.referrer_policy);
}
@@ -232,7 +231,7 @@ FrameLoader::~FrameLoader() {
DCHECK(detached_);
}
-void FrameLoader::Trace(Visitor* visitor) {
+void FrameLoader::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(progress_tracker_);
visitor->Trace(document_loader_);
@@ -263,8 +262,8 @@ void FrameLoader::Init() {
// Suppress finish notifications for initial empty documents, since they don't
// generate start notifications.
document_loader_->SetSentDidFinishLoad();
- if (frame_->GetPage()->Paused())
- frame_->SetLifecycleState(mojom::FrameLifecycleState::kPaused);
+ // Ensure that the frame sees the correct page lifecycle state.
+ frame_->OnPageLifecycleStateUpdated();
TakeObjectSnapshot();
}
@@ -440,8 +439,7 @@ Frame* FrameLoader::Opener() {
void FrameLoader::SetOpener(LocalFrame* opener) {
// If the frame is already detached, the opener has already been cleared.
- if (Client())
- Client()->SetOpener(opener);
+ frame_->SetOpener(opener);
}
bool FrameLoader::AllowPlugins(ReasonForCallingAllowPlugins reason) {
@@ -795,13 +793,15 @@ void FrameLoader::StartNavigation(FrameLoadRequest& request,
// Check for non-escaped new lines in the url.
if (url.PotentiallyDanglingMarkup() && url.ProtocolIsInHTTPFamily()) {
Deprecation::CountDeprecation(
- origin_document, WebFeature::kCanRequestURLHTTPContainingNewline);
+ origin_document ? origin_document->GetExecutionContext() : nullptr,
+ WebFeature::kCanRequestURLHTTPContainingNewline);
return;
}
if (url.ProtocolIsJavaScript()) {
if (!origin_document ||
- origin_document->CanExecuteScripts(kAboutToExecuteScript)) {
+ origin_document->GetExecutionContext()->CanExecuteScripts(
+ kAboutToExecuteScript)) {
frame_->GetDocument()->ProcessJavaScriptUrl(
url, request.ShouldCheckMainWorldContentSecurityPolicy());
}
@@ -1029,16 +1029,13 @@ void FrameLoader::CommitNavigation(
TakeObjectSnapshot();
}
-bool FrameLoader::WillStartNavigation(const WebNavigationInfo& info,
- bool is_history_navigation_in_new_frame) {
+bool FrameLoader::WillStartNavigation(const WebNavigationInfo& info) {
if (!CancelProvisionalLoaderForNewNavigation())
return false;
progress_tracker_->ProgressStarted();
client_navigation_ = std::make_unique<ClientNavigationState>();
client_navigation_->url = info.url_request.Url();
- client_navigation_->is_history_navigation_in_new_frame =
- is_history_navigation_in_new_frame;
frame_->GetFrameScheduler()->DidStartProvisionalLoad(frame_->IsMainFrame());
probe::DidStartProvisionalLoad(frame_);
virtual_time_pauser_.PauseVirtualTime();
@@ -1046,7 +1043,7 @@ bool FrameLoader::WillStartNavigation(const WebNavigationInfo& info,
return true;
}
-void FrameLoader::StopAllLoaders() {
+void FrameLoader::StopAllLoaders(bool abort_client) {
if (!frame_->IsNavigationAllowed() ||
frame_->GetDocument()->PageDismissalEventBeingDispatched() !=
Document::kNoDismissal) {
@@ -1060,13 +1057,16 @@ void FrameLoader::StopAllLoaders() {
for (Frame* child = frame_->Tree().FirstChild(); child;
child = child->Tree().NextSibling()) {
if (auto* child_local_frame = DynamicTo<LocalFrame>(child))
- child_local_frame->Loader().StopAllLoaders();
+ child_local_frame->Loader().StopAllLoaders(abort_client);
}
frame_->GetDocument()->CancelParsing();
if (document_loader_)
document_loader_->StopLoading();
- CancelClientNavigation();
+ if (abort_client)
+ CancelClientNavigation();
+ else
+ ClearClientNavigation();
frame_->CancelFormSubmission();
DidFinishNavigation(FrameLoader::NavigationFinishState::kSuccess);
@@ -1211,7 +1211,7 @@ void FrameLoader::CommitDocumentLoader(
}
void FrameLoader::RestoreScrollPositionAndViewState() {
- if (RuntimeEnabledFeatures::ForceLoadAtTopEnabled(frame_->GetDocument()) ||
+ if (RuntimeEnabledFeatures::ForceLoadAtTopEnabled(frame_->DomWindow()) ||
!frame_->GetPage() || !GetDocumentLoader() ||
!GetDocumentLoader()->GetHistoryItem() ||
!GetDocumentLoader()->GetHistoryItem()->GetViewState() ||
@@ -1335,24 +1335,45 @@ void FrameLoader::ProcessFragment(const KURL& url,
if (auto* boundary_local_frame = DynamicTo<LocalFrame>(boundary_frame))
boundary_local_frame->View()->SetSafeToPropagateScrollToParent(false);
- // If scroll position is restored from history fragment or scroll
- // restoration type is manual, then we should not override it unless this
- // is a same document reload.
- bool should_scroll_to_fragment =
- !RuntimeEnabledFeatures::ForceLoadAtTopEnabled(frame_->GetDocument()) &&
- GetDocumentLoader()->NavigationScrollAllowed() &&
- ((load_start_type == kNavigationWithinSameDocument &&
- !IsBackForwardLoadType(frame_load_type)) ||
- (!GetDocumentLoader()
- ->GetInitialScrollState()
- .did_restore_from_history &&
- !(GetDocumentLoader()->GetHistoryItem() &&
- GetDocumentLoader()->GetHistoryItem()->ScrollRestorationType() ==
- kScrollRestorationManual)));
-
- view->ProcessUrlFragment(url,
- load_start_type == kNavigationWithinSameDocument,
- should_scroll_to_fragment);
+ const bool is_same_document_navigation =
+ load_start_type == kNavigationWithinSameDocument;
+
+ // Pages can opt-in to manual scroll restoration so the page will handle
+ // restoring the past scroll offset during a history navigation. In these
+ // cases we assume the scroll was restored from history (by the page).
+ const bool uses_manual_scroll_restoration =
+ GetDocumentLoader()->GetHistoryItem() &&
+ GetDocumentLoader()->GetHistoryItem()->ScrollRestorationType() ==
+ kScrollRestorationManual;
+
+ // If we restored a scroll position from history, we shouldn't clobber it
+ // with the fragment.
+ const bool will_restore_scroll_from_history =
+ GetDocumentLoader()->GetInitialScrollState().did_restore_from_history ||
+ uses_manual_scroll_restoration;
+
+ // Scrolling at load can be blocked by document policy (or the equivalent
+ // ForceLoadAtTop REF currently in origin trial). This policy applies only to
+ // cross-document navigations.
+ const bool blocked_by_policy =
+ !is_same_document_navigation &&
+ (RuntimeEnabledFeatures::ForceLoadAtTopEnabled(frame_->DomWindow()) ||
+ !GetDocumentLoader()->NavigationScrollAllowed());
+
+ // We should avoid scrolling the fragment if it would clobber a history
+ // restored scroll state but still allow it on same document navigations
+ // after (i.e. if we navigate back and restore the scroll position, the user
+ // should still be able to click on a same-document fragment link and have it
+ // jump to the anchor).
+ const bool is_same_document_non_history_nav =
+ is_same_document_navigation && !IsBackForwardLoadType(frame_load_type);
+
+ const bool block_fragment_scroll =
+ blocked_by_policy ||
+ (will_restore_scroll_from_history && !is_same_document_non_history_nav);
+
+ view->ProcessUrlFragment(url, is_same_document_navigation,
+ !block_fragment_scroll);
if (auto* boundary_local_frame = DynamicTo<LocalFrame>(boundary_frame))
boundary_local_frame->View()->SetSafeToPropagateScrollToParent(true);
@@ -1408,6 +1429,15 @@ bool FrameLoader::ShouldClose(bool is_reload) {
}
}
+ // Now that none of the unloading frames canceled the BeforeUnload, tell each
+ // of them so they can advance to the appropriate load state.
+ frame_->GetDocument()->BeforeUnloadDoneWillUnload();
+ for (Member<LocalFrame>& descendant_frame : descendant_frames) {
+ if (!descendant_frame->Tree().IsDescendantOf(frame_))
+ continue;
+ descendant_frame->GetDocument()->BeforeUnloadDoneWillUnload();
+ }
+
return true;
}
@@ -1432,39 +1462,6 @@ void FrameLoader::DidDropNavigation() {
}
}
-void FrameLoader::MarkAsLoading() {
- // This should only be called for initial history navigation in child frame.
- DCHECK(!client_navigation_);
- DCHECK(frame_->GetDocument()->IsLoadCompleted());
- DCHECK(frame_->GetDocument()->HasFinishedParsing());
- progress_tracker_->ProgressStarted();
-}
-
-bool FrameLoader::ShouldReuseDefaultView(
- const scoped_refptr<const SecurityOrigin>& origin,
- const ContentSecurityPolicy* csp) {
- // Secure transitions can only happen when navigating from the initial empty
- // document.
- if (!state_machine_.IsDisplayingInitialEmptyDocument())
- return false;
-
- // The Window object should only be re-used if it is same-origin.
- // Since sandboxing turns the origin into an opaque origin it needs to also
- // be considered when deciding whether to reuse it.
- // Spec:
- // https://html.spec.whatwg.org/C/#initialise-the-document-object
- if ((csp && (csp->GetSandboxMask() &
- network::mojom::blink::WebSandboxFlags::kOrigin) !=
- network::mojom::blink::WebSandboxFlags::kNone) ||
- ((EffectiveSandboxFlags() &
- network::mojom::blink::WebSandboxFlags::kOrigin) !=
- network::mojom::blink::WebSandboxFlags::kNone)) {
- return false;
- }
-
- return frame_->GetDocument()->GetSecurityOrigin()->CanAccess(origin.get());
-}
-
bool FrameLoader::CancelProvisionalLoaderForNewNavigation() {
// This seems to correspond to step 9 of the specification:
// "9. Abort the active document of browsingContext."
@@ -1538,7 +1535,6 @@ void FrameLoader::SetFrameOwnerSandboxFlags(
}
void FrameLoader::DispatchDidClearDocumentOfWindowObject() {
- DCHECK(frame_->GetDocument());
if (state_machine_.CreatingInitialEmptyDocument())
return;
@@ -1548,7 +1544,7 @@ void FrameLoader::DispatchDidClearDocumentOfWindowObject() {
frame_->GetScriptController().WindowProxy(DOMWrapperWorld::MainWorld());
}
probe::DidClearDocumentOfWindowObject(frame_);
- if (!frame_->GetDocument()->CanExecuteScripts(kNotAboutToExecuteScript))
+ if (!frame_->DomWindow()->CanExecuteScripts(kNotAboutToExecuteScript))
return;
if (dispatching_did_clear_window_object_in_main_world_)
@@ -1561,8 +1557,7 @@ void FrameLoader::DispatchDidClearDocumentOfWindowObject() {
}
void FrameLoader::DispatchDidClearWindowObjectInMainWorld() {
- DCHECK(frame_->GetDocument());
- if (!frame_->GetDocument()->CanExecuteScripts(kNotAboutToExecuteScript))
+ if (!frame_->DomWindow()->CanExecuteScripts(kNotAboutToExecuteScript))
return;
if (dispatching_did_clear_window_object_in_main_world_)
@@ -1732,11 +1727,6 @@ inline void FrameLoader::TakeObjectSnapshot() const {
ToTracedValue());
}
-bool FrameLoader::IsClientNavigationInitialHistoryLoad() {
- return client_navigation_ &&
- client_navigation_->is_history_navigation_in_new_frame;
-}
-
ContentSecurityPolicy* FrameLoader::CreateCSPForInitialEmptyDocument() const {
ContentSecurityPolicy* csp = MakeGarbageCollected<ContentSecurityPolicy>();
@@ -1802,13 +1792,6 @@ ContentSecurityPolicy* FrameLoader::CreateCSP(
if (origin_policy)
ApplyOriginPolicy(csp, origin_policy.value());
- // Check CSP frame-ancestor:
- if (!base::FeatureList::IsEnabled(
- network::features::kOutOfBlinkFrameAncestors)) {
- if (!csp->AllowAncestors(frame_, response.CurrentRequestUrl()))
- return nullptr; // Document blocked.
- }
-
// Plugin inherits plugin's CSP from their navigation initiator.
DocumentInit::Type document_type =
DocumentInit::ComputeDocumentType(frame_, url, response.MimeType());
@@ -1835,8 +1818,10 @@ ContentSecurityPolicy* FrameLoader::CreateCSP(
// See:
// - https://w3c.github.io/webappsec-cspee/#required-csp-header
// - https://w3c.github.io/webappsec-cspee/#allow-csp-from-header
- if (RequiredCSP().IsEmpty())
+ if (RequiredCSP().IsEmpty() ||
+ base::FeatureList::IsEnabled(network::features::kOutOfBlinkCSPEE)) {
return csp;
+ }
const SecurityOrigin* parent_security_origin =
frame_->Tree().Parent()->GetSecurityContext()->GetSecurityOrigin();
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_loader.h b/chromium/third_party/blink/renderer/core/loader/frame_loader.h
index 17f1e061426..0403ce84509 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_loader.h
+++ b/chromium/third_party/blink/renderer/core/loader/frame_loader.h
@@ -107,19 +107,23 @@ class CORE_EXPORT FrameLoader final {
// Called before the browser process is asked to navigate this frame, to mark
// the frame as loading and save some navigation information for later use.
- bool WillStartNavigation(const WebNavigationInfo& info,
- bool is_history_navigation_in_new_frame);
+ bool WillStartNavigation(const WebNavigationInfo& info);
// This runs the "stop document loading" algorithm in HTML:
// https://html.spec.whatwg.org/C/browsing-the-web.html#stop-document-loading
// Note, this function only cancels ongoing navigation handled through
- // FrameLoader. You might also want to call
- // LocalFrameClient::AbortClientNavigation() if appropriate.
+ // FrameLoader.
+ //
+ // If |abort_client| is true, then the frame's client will have
+ // AbortClientNavigation() called if a navigation was aborted. Normally this
+ // should be passed as true, unless the navigation has been migrated to a
+ // provisional frame, while this frame is going away, so the navigation isn't
+ // actually being aborted.
//
// Warning: StopAllLoaders() may detach the LocalFrame to which this
// FrameLoader belongs. Callers need to be careful about checking the
// existence of the frame after StopAllLoaders() returns.
- void StopAllLoaders();
+ void StopAllLoaders(bool abort_client);
// Notifies the client that the initial empty document has been accessed, and
// thus it is no longer safe to show a provisional URL above the document
@@ -226,15 +230,9 @@ class CORE_EXPORT FrameLoader final {
// the navigation.
void CancelClientNavigation();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void DidDropNavigation();
- void MarkAsLoading();
-
- bool ShouldReuseDefaultView(const scoped_refptr<const SecurityOrigin>&,
- const ContentSecurityPolicy*);
-
- bool IsClientNavigationInitialHistoryLoad();
bool HasAccessedInitialDocument() { return has_accessed_initial_document_; }
@@ -308,7 +306,6 @@ class CORE_EXPORT FrameLoader final {
// is either committed or cancelled.
struct ClientNavigationState {
KURL url;
- bool is_history_navigation_in_new_frame = false;
};
std::unique_ptr<ClientNavigationState> client_navigation_;
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_loader_state_machine.cc b/chromium/third_party/blink/renderer/core/loader/frame_loader_state_machine.cc
index 147466e8bdb..542d3bd03a0 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_loader_state_machine.cc
+++ b/chromium/third_party/blink/renderer/core/loader/frame_loader_state_machine.cc
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/loader/frame_loader_state_machine.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_loader_test.cc b/chromium/third_party/blink/renderer/core/loader/frame_loader_test.cc
new file mode 100644
index 00000000000..ed60733049c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/loader/frame_loader_test.cc
@@ -0,0 +1,111 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "build/build_config.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
+#include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
+#include "third_party/blink/renderer/core/html/html_anchor_element.h"
+#include "third_party/blink/renderer/core/page/chrome_client_impl.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
+
+namespace blink {
+
+class FrameLoaderSimTest : public SimTest {
+ public:
+ FrameLoaderSimTest() = default;
+
+ void SetUp() override {
+ SimTest::SetUp();
+ WebView().MainFrameWidgetBase()->UpdateAllLifecyclePhases(
+ DocumentUpdateReason::kTest);
+ }
+};
+
+// Ensure that the load event progress is progressed through BeforeUnload only
+// if the event is uncanceled.
+TEST_F(FrameLoaderSimTest, LoadEventProgressBeforeUnloadCanceled) {
+ SimRequest request("https://example.com/test.html", "text/html");
+ SimRequest request_a("https://example.com/subframe-a.html", "text/html");
+ SimRequest request_b("https://example.com/subframe-b.html", "text/html");
+ SimRequest request_c("https://example.com/subframe-c.html", "text/html");
+ SimRequest request_unload("https://example.com/next-page.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <iframe src="subframe-a.html"></iframe>
+ )HTML");
+
+ request_a.Complete(R"HTML(
+ <!DOCTYPE html>
+ <iframe src="subframe-b.html"></iframe>
+ <a id="link" href="next-page.html">Next Page</a>
+ )HTML");
+ request_b.Complete(R"HTML(
+ <!DOCTYPE html>
+ <script>
+ window.onbeforeunload = (e) => {
+ e.returnValue = '';
+ e.preventDefault();
+ };
+ </script>
+ <iframe src="subframe-c.html"></iframe>
+ )HTML");
+ request_c.Complete(R"HTML(
+ <!DOCTYPE html>
+ )HTML");
+ Compositor().BeginFrame();
+
+ auto* main_frame = To<LocalFrame>(GetDocument().GetPage()->MainFrame());
+ auto* frame_a = To<LocalFrame>(main_frame->Tree().FirstChild());
+ auto* frame_b = To<LocalFrame>(frame_a->Tree().FirstChild());
+ auto* frame_c = To<LocalFrame>(frame_b->Tree().FirstChild());
+
+ ASSERT_FALSE(main_frame->GetDocument()->BeforeUnloadStarted());
+ ASSERT_FALSE(frame_a->GetDocument()->BeforeUnloadStarted());
+ ASSERT_FALSE(frame_b->GetDocument()->BeforeUnloadStarted());
+ ASSERT_FALSE(frame_c->GetDocument()->BeforeUnloadStarted());
+
+ // We'll only allow canceling a beforeunload if there's a sticky user
+ // activation present so simulate a user gesture.
+ frame_b->NotifyUserActivationInLocalTree();
+
+ auto& chrome_client =
+ To<ChromeClientImpl>(WebView().GetPage()->GetChromeClient());
+
+ // Simulate the user canceling the navigation away. Since the navigation was
+ // "canceled", we expect that each of the frames should remain in their state
+ // before the beforeunload was dispatched.
+ {
+ chrome_client.SetBeforeUnloadConfirmPanelResultForTesting(false);
+
+ // Note: We can't perform a navigation to check this because the
+ // beforeunload event is dispatched from content's RenderFrameImpl, Blink
+ // tests mock this out using a WebFrameTestProxy which doesn't check
+ // beforeunload before navigating.
+ ASSERT_FALSE(frame_a->Loader().ShouldClose());
+
+ EXPECT_FALSE(main_frame->GetDocument()->BeforeUnloadStarted());
+ EXPECT_FALSE(frame_a->GetDocument()->BeforeUnloadStarted());
+ EXPECT_FALSE(frame_b->GetDocument()->BeforeUnloadStarted());
+ EXPECT_FALSE(frame_c->GetDocument()->BeforeUnloadStarted());
+ }
+
+ // Now test the opposite, the user allowing the navigation away.
+ {
+ chrome_client.SetBeforeUnloadConfirmPanelResultForTesting(true);
+ ASSERT_TRUE(frame_a->Loader().ShouldClose());
+
+ // The navigation was in frame a so it shouldn't affect the parent.
+ EXPECT_FALSE(main_frame->GetDocument()->BeforeUnloadStarted());
+ EXPECT_TRUE(frame_a->GetDocument()->BeforeUnloadStarted());
+ EXPECT_TRUE(frame_b->GetDocument()->BeforeUnloadStarted());
+ EXPECT_TRUE(frame_c->GetDocument()->BeforeUnloadStarted());
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.cc b/chromium/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.cc
index 75dca1637b0..c30d3c169a7 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.cc
+++ b/chromium/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.cc
@@ -47,7 +47,7 @@ FrameResourceFetcherProperties::FrameResourceFetcherProperties(
*document.domWindow())),
web_bundle_physical_url_(document_loader.WebBundlePhysicalUrl()) {}
-void FrameResourceFetcherProperties::Trace(Visitor* visitor) {
+void FrameResourceFetcherProperties::Trace(Visitor* visitor) const {
visitor->Trace(document_loader_);
visitor->Trace(document_);
visitor->Trace(fetch_client_settings_object_);
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.h b/chromium/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.h
index 25519cc9a76..ce8860e969c 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.h
+++ b/chromium/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.h
@@ -24,7 +24,7 @@ class CORE_EXPORT FrameResourceFetcherProperties final
Document& document);
~FrameResourceFetcherProperties() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// ResourceFetcherProperties implementation
const FetchClientSettingsObject& GetFetchClientSettingsObject()
diff --git a/chromium/third_party/blink/renderer/core/loader/history_item.cc b/chromium/third_party/blink/renderer/core/loader/history_item.cc
index 459e06d9fe3..1efec6470d9 100644
--- a/chromium/third_party/blink/renderer/core/loader/history_item.cc
+++ b/chromium/third_party/blink/renderer/core/loader/history_item.cc
@@ -163,7 +163,7 @@ ResourceRequest HistoryItem::GenerateResourceRequest(
return request;
}
-void HistoryItem::Trace(Visitor* visitor) {
+void HistoryItem::Trace(Visitor* visitor) const {
visitor->Trace(document_state_);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/history_item.h b/chromium/third_party/blink/renderer/core/loader/history_item.h
index b3d21d3c893..e800cd9e463 100644
--- a/chromium/third_party/blink/renderer/core/loader/history_item.h
+++ b/chromium/third_party/blink/renderer/core/loader/history_item.h
@@ -119,7 +119,7 @@ class CORE_EXPORT HistoryItem final : public GarbageCollected<HistoryItem> {
ResourceRequest GenerateResourceRequest(mojom::FetchCacheMode);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
String url_string_;
diff --git a/chromium/third_party/blink/renderer/core/loader/http_equiv.cc b/chromium/third_party/blink/renderer/core/loader/http_equiv.cc
index 171d9b1f632..33c54d1ee86 100644
--- a/chromium/third_party/blink/renderer/core/loader/http_equiv.cc
+++ b/chromium/third_party/blink/renderer/core/loader/http_equiv.cc
@@ -16,13 +16,16 @@
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/loader/private/frame_client_hints_preferences_context.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
+#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h"
#include "third_party/blink/renderer/platform/network/http_names.h"
#include "third_party/blink/renderer/platform/network/http_parsers.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h"
+#include "v8/include/v8.h"
namespace blink {
@@ -44,6 +47,35 @@ bool AllowScriptFromSourceWithoutNotifying(
return allow_script;
}
+// Gets the url of the currently executing script. Returns empty url, if no
+// script is executing (e.g. during parsing of a meta tag in markup), or the
+// script context is otherwise unavailable.
+// TODO(crbug.com/1073920): Extract this function into a reusable location. This
+// function was cloned from:
+// https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/renderer/core/frame/ad_tracker.cc;l=92;drc=51291f88a8f94602d26403716e2dfa781f8846ee?originalUrl=https:%2F%2Fcs.chromium.org%2F
+// There's also a similar implementation here:
+// https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc;l=97;drc=f002f3b90c510002b98aa08c2fe7f3d93372007e?originalUrl=https:%2F%2Fcs.chromium.org%2F
+KURL GetCurrentScriptUrl() {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ if (!isolate || !isolate->InContext())
+ return NullURL();
+
+ // CurrentStackTrace is 10x faster than CaptureStackTrace if all that you need
+ // is the url of the script at the top of the stack. See crbug.com/1057211 for
+ // more detail.
+ v8::Local<v8::StackTrace> stack_trace =
+ v8::StackTrace::CurrentStackTrace(isolate, /*frame_limit=*/1);
+ if (stack_trace.IsEmpty() || stack_trace->GetFrameCount() < 1)
+ return NullURL();
+
+ v8::Local<v8::StackFrame> frame = stack_trace->GetFrame(isolate, 0);
+ v8::Local<v8::String> script_name = frame->GetScriptNameOrSourceURL();
+ if (script_name.IsEmpty() || !script_name->Length())
+ return NullURL();
+
+ return KURL(ToCoreString(script_name));
+}
+
} // namespace
void HttpEquiv::Process(Document& document,
@@ -80,8 +112,9 @@ void HttpEquiv::Process(Document& document,
else
document.GetContentSecurityPolicy()->ReportMetaOutsideHead(content);
} else if (EqualIgnoringASCIICase(equiv, http_names::kOriginTrial)) {
- if (in_document_head_element)
- document.GetOriginTrialContext()->AddToken(content);
+ if (in_document_head_element) {
+ ProcessHttpEquivOriginTrial(document, content);
+ }
}
}
@@ -136,6 +169,29 @@ void HttpEquiv::ProcessHttpEquivDefaultStyle(Document& document,
document.GetStyleEngine().SetHttpDefaultStyle(content);
}
+void HttpEquiv::ProcessHttpEquivOriginTrial(Document& document,
+ const AtomicString& content) {
+ // For meta tags injected by script, process the token with the origin of the
+ // external script, if available.
+ // NOTE: The external script origin is not considered security-critical. See
+ // the comment thread in the design doc for details:
+ // https://docs.google.com/document/d/1xALH9W7rWmX0FpjudhDeS2TNTEOXuPn4Tlc9VmuPdHA/edit?disco=AAAAJyG8StI
+ if (RuntimeEnabledFeatures::ThirdPartyOriginTrialsEnabled()) {
+ KURL external_script_url = GetCurrentScriptUrl();
+
+ if (external_script_url.IsValid()) {
+ scoped_refptr<SecurityOrigin> external_origin =
+ SecurityOrigin::Create(external_script_url);
+ document.GetOriginTrialContext()->AddTokenFromExternalScript(
+ content, external_origin.get());
+ return;
+ }
+ }
+
+ // Process token as usual, without an external script origin.
+ document.GetOriginTrialContext()->AddToken(content);
+}
+
void HttpEquiv::ProcessHttpEquivRefresh(Document& document,
const AtomicString& content,
Element* element) {
diff --git a/chromium/third_party/blink/renderer/core/loader/http_equiv.h b/chromium/third_party/blink/renderer/core/loader/http_equiv.h
index d6a2ca432fb..d7eb5795cc2 100644
--- a/chromium/third_party/blink/renderer/core/loader/http_equiv.h
+++ b/chromium/third_party/blink/renderer/core/loader/http_equiv.h
@@ -34,6 +34,8 @@ class HttpEquiv {
private:
static void ProcessHttpEquivDefaultStyle(Document&,
const AtomicString& content);
+ static void ProcessHttpEquivOriginTrial(Document&,
+ const AtomicString& content);
static void ProcessHttpEquivRefresh(Document&,
const AtomicString& content,
Element*);
diff --git a/chromium/third_party/blink/renderer/core/loader/http_refresh_scheduler.cc b/chromium/third_party/blink/renderer/core/loader/http_refresh_scheduler.cc
index eabd1ac445c..fbd4c419dfc 100644
--- a/chromium/third_party/blink/renderer/core/loader/http_refresh_scheduler.cc
+++ b/chromium/third_party/blink/renderer/core/loader/http_refresh_scheduler.cc
@@ -141,7 +141,7 @@ void HttpRefreshScheduler::Cancel() {
refresh_.reset();
}
-void HttpRefreshScheduler::Trace(Visitor* visitor) {
+void HttpRefreshScheduler::Trace(Visitor* visitor) const {
visitor->Trace(document_);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/http_refresh_scheduler.h b/chromium/third_party/blink/renderer/core/loader/http_refresh_scheduler.h
index 3eebdd97534..b92be4e00f8 100644
--- a/chromium/third_party/blink/renderer/core/loader/http_refresh_scheduler.h
+++ b/chromium/third_party/blink/renderer/core/loader/http_refresh_scheduler.h
@@ -56,7 +56,7 @@ class CORE_EXPORT HttpRefreshScheduler final
void MaybeStartTimer();
void Cancel();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void NavigateTask();
diff --git a/chromium/third_party/blink/renderer/core/loader/idleness_detector.cc b/chromium/third_party/blink/renderer/core/loader/idleness_detector.cc
index 402f57cc5f9..fa6dd8e7bec 100644
--- a/chromium/third_party/blink/renderer/core/loader/idleness_detector.cc
+++ b/chromium/third_party/blink/renderer/core/loader/idleness_detector.cc
@@ -221,7 +221,7 @@ void IdlenessDetector::NetworkQuietTimerFired(TimerBase*) {
}
}
-void IdlenessDetector::Trace(Visitor* visitor) {
+void IdlenessDetector::Trace(Visitor* visitor) const {
visitor->Trace(local_frame_);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/idleness_detector.h b/chromium/third_party/blink/renderer/core/loader/idleness_detector.h
index ba49a55c62a..0dac8000cf4 100644
--- a/chromium/third_party/blink/renderer/core/loader/idleness_detector.h
+++ b/chromium/third_party/blink/renderer/core/loader/idleness_detector.h
@@ -42,7 +42,7 @@ class CORE_EXPORT IdlenessDetector
base::TimeTicks GetNetworkIdleTime();
bool NetworkIsAlmostIdle();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
friend class IdlenessDetectorTest;
diff --git a/chromium/third_party/blink/renderer/core/loader/image_loader.cc b/chromium/third_party/blink/renderer/core/loader/image_loader.cc
index 8553ebd9e40..a08aac3dd99 100644
--- a/chromium/third_party/blink/renderer/core/loader/image_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/image_loader.cc
@@ -74,9 +74,9 @@ namespace blink {
namespace {
-bool CheckForUnoptimizedImagePolicy(Document& document,
+bool CheckForUnoptimizedImagePolicy(ExecutionContext* context,
ImageResourceContent* new_image) {
- if (!new_image)
+ if (!context || !new_image)
return false;
// Render the image as a placeholder image if the image is not sufficiently
@@ -85,15 +85,50 @@ bool CheckForUnoptimizedImagePolicy(Document& document,
// Note: UnoptimizedImagePolicies is currently part of DocumentPolicy.
// The original runtime feature UnoptimizedImagePolicies is no longer used,
// and are planned to be removed.
- if (RuntimeEnabledFeatures::DocumentPolicyEnabled(&document) &&
- !new_image->IsAcceptableCompressionRatio(
- *document.GetExecutionContext())) {
+ if (RuntimeEnabledFeatures::DocumentPolicyEnabled(context) &&
+ !new_image->IsAcceptableCompressionRatio(*context)) {
return true;
}
return false;
}
+// Returns whether subresource redirect can be attempted for the image fetch.
+// Redirect to other origins could be disabled due to CSP or CORS restrictions.
+bool ShouldEnableSubresourceRedirect(HTMLImageElement* image_element,
+ const KURL& url) {
+ // Allow redirection only when DataSaver is enabled and subresource redirect
+ // feature is enabled which allows redirecting to better optimized versions.
+ if (!base::FeatureList::IsEnabled(blink::features::kSubresourceRedirect) ||
+ !GetNetworkStateNotifier().SaveDataEnabled()) {
+ return false;
+ }
+ // Enable subresource redirect only for <img> elements created by parser.
+ // Images created from javascript, fetched via XHR/Fetch API should not be
+ // subresource redirected due to the additional CORB/CORS handling needed for
+ // them.
+ if (!image_element || !image_element->ElementCreatedByParser()) {
+ return false;
+ }
+ // Create a cross origin URL by appending a string to the original host. This
+ // is used to find whether CSP is restricting image fetches from other
+ // origins.
+ KURL cross_origin_url = url;
+ cross_origin_url.SetHost(url.Host() + "crossorigin.com");
+ auto* content_security_policy =
+ image_element->GetExecutionContext()->GetContentSecurityPolicy();
+ if (content_security_policy &&
+ !content_security_policy->AllowImageFromSource(
+ cross_origin_url, cross_origin_url, RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting)) {
+ return false;
+ }
+ // Allow subresource redirect only when cross-origin attribute is not set,
+ // which indicates CORS validation is not triggered for the image.
+ return (GetCrossOriginAttributeValue(image_element->FastGetAttribute(
+ html_names::kCrossoriginAttr)) == kCrossOriginAttributeNotSet);
+}
+
} // namespace
static ImageLoader::BypassMainWorldBehavior ShouldBypassMainWorldCSP(
@@ -284,7 +319,7 @@ void ImageLoader::RejectPendingDecodes(UpdateType update_type) {
}
}
-void ImageLoader::Trace(Visitor* visitor) {
+void ImageLoader::Trace(Visitor* visitor) const {
visitor->Trace(image_content_);
visitor->Trace(image_content_for_image_document_);
visitor->Trace(element_);
@@ -392,7 +427,8 @@ static void ConfigureRequest(
element.GetDocument().GetSecurityOrigin(), cross_origin);
}
- if (RuntimeEnabledFeatures::PriorityHintsEnabled(&element.GetDocument())) {
+ if (RuntimeEnabledFeatures::PriorityHintsEnabled(
+ element.GetExecutionContext())) {
mojom::FetchImportanceMode importance_mode =
GetFetchImportanceAttributeValue(
element.FastGetAttribute(html_names::kImportanceAttr));
@@ -535,10 +571,8 @@ void ImageLoader::DoUpdateFromElement(
ConfigureRequest(params, bypass_behavior, *element_,
document.GetFrame()->GetClientHintsPreferences());
- if ((update_behavior != kUpdateForcedReload &&
- lazy_image_load_state_ == LazyImageLoadState::kNone) ||
- (update_behavior == kUpdateSizeChanged &&
- lazy_image_load_state_ == LazyImageLoadState::kDeferred)) {
+ if (update_behavior != kUpdateForcedReload &&
+ lazy_image_load_state_ != LazyImageLoadState::kFullImage) {
const auto* frame = document.GetFrame();
if (auto* html_image = DynamicTo<HTMLImageElement>(GetElement())) {
LoadingAttributeValue loading_attr = GetLoadingAttributeValue(
@@ -568,21 +602,11 @@ void ImageLoader::DoUpdateFromElement(
params.SetLazyImageNonBlocking();
}
- // Enable subresource redirect for <img> elements created by parser when
- // data saver is on. Images created from javascript, fetched via XHR/Fetch
- // API should not be subresource redirected due to the additional CORB/CORS
- // handling needed for them.
- // TODO(rajendrant): Disable subresource redirect when CORS,
- // content-security-policy does not allow cross-origin accesses.
- if (auto* html_image = DynamicTo<HTMLImageElement>(GetElement())) {
- if (base::FeatureList::IsEnabled(blink::features::kSubresourceRedirect) &&
- html_image->ElementCreatedByParser() &&
- GetNetworkStateNotifier().SaveDataEnabled()) {
- auto& resource_request = params.MutableResourceRequest();
- resource_request.SetPreviewsState(
- resource_request.GetPreviewsState() |
- WebURLRequest::kSubresourceRedirectOn);
- }
+ if (ShouldEnableSubresourceRedirect(
+ DynamicTo<HTMLImageElement>(GetElement()), params.Url())) {
+ auto& resource_request = params.MutableResourceRequest();
+ resource_request.SetPreviewsState(resource_request.GetPreviewsState() |
+ WebURLRequest::kSubresourceRedirectOn);
}
new_image_content = ImageResourceContent::Fetch(params, document.Fetcher());
@@ -712,8 +736,7 @@ void ImageLoader::UpdateFromElement(
// Don't load images for inactive documents or active documents without V8
// context. We don't want to slow down the raw HTML parsing case by loading
// images we don't intend to display.
- Document& document = element_->GetDocument();
- if (!document.IsContextDestroyed() && document.IsActive())
+ if (element_->GetDocument().IsActive())
EnqueueImageLoadingMicroTask(update_behavior, referrer_policy);
}
@@ -766,13 +789,13 @@ void ImageLoader::ImageChanged(ImageResourceContent* content,
std::make_unique<IncrementLoadEventDelayCount>(document);
}
-void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) {
+void ImageLoader::ImageNotifyFinished(ImageResourceContent* content) {
RESOURCE_LOADING_DVLOG(1)
<< "ImageLoader::imageNotifyFinished " << this
<< "; has pending load event=" << pending_load_event_.IsActive();
DCHECK(failed_load_url_.IsEmpty());
- DCHECK_EQ(resource, image_content_.Get());
+ DCHECK_EQ(content, image_content_.Get());
CHECK(!image_complete_);
@@ -816,7 +839,8 @@ void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) {
// HTMLImageElement.
// crbug.com/930281
auto* html_image_element = DynamicTo<HTMLImageElement>(element_.Get());
- if (CheckForUnoptimizedImagePolicy(element_->GetDocument(), image_content_) &&
+ if (CheckForUnoptimizedImagePolicy(element_->GetExecutionContext(),
+ image_content_) &&
html_image_element)
html_image_element->SetImagePolicyViolated();
@@ -825,10 +849,10 @@ void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) {
if (html_image_element)
LazyImageHelper::RecordMetricsOnLoadFinished(html_image_element);
- if (resource->ErrorOccurred()) {
+ if (content->ErrorOccurred()) {
pending_load_event_.Cancel();
- base::Optional<ResourceError> error = resource->GetResourceError();
+ base::Optional<ResourceError> error = content->GetResourceError();
if (error && error->IsAccessCheck())
CrossSiteOrCSPViolationOccurred(AtomicString(error->FailingURL()));
@@ -1015,7 +1039,7 @@ void ImageLoader::DecodeRequest::NotifyDecodeDispatched() {
state_ = kDispatched;
}
-void ImageLoader::DecodeRequest::Trace(Visitor* visitor) {
+void ImageLoader::DecodeRequest::Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
visitor->Trace(loader_);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/image_loader.h b/chromium/third_party/blink/renderer/core/loader/image_loader.h
index a2c3147fbc0..bcafb8c8fcc 100644
--- a/chromium/third_party/blink/renderer/core/loader/image_loader.h
+++ b/chromium/third_party/blink/renderer/core/loader/image_loader.h
@@ -53,7 +53,7 @@ class CORE_EXPORT ImageLoader : public GarbageCollected<ImageLoader>,
explicit ImageLoader(Element*);
~ImageLoader() override;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
enum UpdateFromElementBehavior {
// This should be the update behavior when the element is attached to a
@@ -282,7 +282,7 @@ class CORE_EXPORT ImageLoader : public GarbageCollected<ImageLoader>,
DecodeRequest(ImageLoader*, ScriptPromiseResolver*);
~DecodeRequest() = default;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
uint64_t request_id() const { return request_id_; }
State state() const { return state_; }
diff --git a/chromium/third_party/blink/renderer/core/loader/interactive_detector.cc b/chromium/third_party/blink/renderer/core/loader/interactive_detector.cc
index 09ac77e0bdb..7db2d3b0d25 100644
--- a/chromium/third_party/blink/renderer/core/loader/interactive_detector.cc
+++ b/chromium/third_party/blink/renderer/core/loader/interactive_detector.cc
@@ -139,6 +139,11 @@ base::Optional<base::TimeDelta> InteractiveDetector::GetFirstInputDelay()
return page_event_times_.first_input_delay;
}
+WTF::Vector<base::Optional<base::TimeDelta>>
+InteractiveDetector::GetFirstInputDelaysAfterBackForwardCacheRestore() const {
+ return page_event_times_.first_input_delays_after_back_forward_cache_restore;
+}
+
base::Optional<base::TimeTicks> InteractiveDetector::GetFirstInputTimestamp()
const {
return page_event_times_.first_input_timestamp;
@@ -154,6 +159,21 @@ base::Optional<base::TimeTicks> InteractiveDetector::GetLongestInputTimestamp()
return page_event_times_.longest_input_timestamp;
}
+base::Optional<base::TimeDelta>
+InteractiveDetector::GetFirstInputProcessingTime() const {
+ return page_event_times_.first_input_processing_time;
+}
+
+base::Optional<base::TimeTicks> InteractiveDetector::GetFirstScrollTimestamp()
+ const {
+ return page_event_times_.first_scroll_timestamp;
+}
+
+base::Optional<base::TimeDelta> InteractiveDetector::GetFirstScrollDelay()
+ const {
+ return page_event_times_.frist_scroll_delay;
+}
+
bool InteractiveDetector::PageWasBackgroundedSinceEvent(
base::TimeTicks event_time) {
DCHECK(GetSupplementable());
@@ -174,7 +194,7 @@ bool InteractiveDetector::PageWasBackgroundedSinceEvent(
}
return false;
-} // namespace blink
+}
void InteractiveDetector::HandleForInputDelay(
const Event& event,
@@ -224,7 +244,6 @@ void InteractiveDetector::HandleForInputDelay(
event_timestamp = event_platform_timestamp;
}
- pending_pointerdown_delay_ = base::TimeDelta();
pending_pointerdown_timestamp_ = base::TimeTicks();
bool interactive_timing_metrics_changed = false;
@@ -260,12 +279,19 @@ void InteractiveDetector::HandleForInputDelay(
g_num_long_input_events++;
}
- // Record input delay UKM.
- ukm::SourceId source_id = GetSupplementable()->UkmSourceID();
- DCHECK_NE(source_id, ukm::kInvalidSourceId);
- ukm::builders::InputEvent(source_id)
- .SetInteractiveTiming_InputDelay(delay.InMilliseconds())
- .Record(GetUkmRecorder());
+ // ELements in |first_input_delays_after_back_forward_cache_restore| is
+ // allocated when the page is restored from the back-forward cache. If the
+ // last element exists and this is nullopt value, the first input has not come
+ // yet after the last time when the page is restored from the cache.
+ if (!page_event_times_.first_input_delays_after_back_forward_cache_restore
+ .IsEmpty() &&
+ !page_event_times_.first_input_delays_after_back_forward_cache_restore
+ .back()
+ .has_value()) {
+ page_event_times_.first_input_delays_after_back_forward_cache_restore
+ .back() = delay;
+ }
+
if (GetSupplementable()->Loader()) {
GetSupplementable()->Loader()->DidObserveInputDelay(delay);
}
@@ -588,7 +614,7 @@ void InteractiveDetector::ContextDestroyed() {
LongTaskDetector::Instance().UnregisterObserver(this);
}
-void InteractiveDetector::Trace(Visitor* visitor) {
+void InteractiveDetector::Trace(Visitor* visitor) const {
Supplement<Document>::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
}
@@ -610,4 +636,75 @@ void InteractiveDetector::SetUkmRecorderForTesting(
ukm::UkmRecorder* test_ukm_recorder) {
ukm_recorder_ = test_ukm_recorder;
}
+
+void InteractiveDetector::RecordInputEventTimingUKM(
+ const Event& event,
+ base::TimeTicks event_timestamp,
+ base::TimeTicks processing_start,
+ base::TimeTicks processing_end) {
+ DCHECK(event.isTrusted());
+
+ // This only happens sometimes on tests unrelated to InteractiveDetector. It
+ // is safe to ignore events that are not properly initialized.
+ if (event_timestamp.is_null())
+ return;
+
+ // We can't report a pointerDown until the pointerUp, in case it turns into a
+ // scroll.
+ if (event.type() == event_type_names::kPointerdown) {
+ pending_pointerdown_processing_time_ = processing_end - processing_start;
+ return;
+ }
+
+ base::TimeDelta input_delay;
+ base::TimeDelta processing_time;
+ if (event.type() == event_type_names::kPointerup) {
+ // PointerUp by itself is not considered a significant input.
+ if (!pending_pointerdown_processing_time_)
+ return;
+
+ input_delay = pending_pointerdown_delay_;
+ processing_time = pending_pointerdown_processing_time_.value();
+ } else {
+ processing_time = processing_end - processing_start;
+ input_delay = processing_start - event_timestamp;
+ }
+ pending_pointerdown_delay_ = base::TimeDelta();
+ pending_pointerdown_processing_time_ = base::nullopt;
+
+ // Record InputDelay and Input Event Processing Time UKM.
+ ukm::SourceId source_id = GetSupplementable()->UkmSourceID();
+ DCHECK_NE(source_id, ukm::kInvalidSourceId);
+ ukm::builders::InputEvent(source_id)
+ .SetInteractiveTiming_InputDelay(input_delay.InMilliseconds())
+ .SetInteractiveTiming_ProcessingTime(processing_time.InMilliseconds())
+ .Record(GetUkmRecorder());
+
+ if (!page_event_times_.first_input_processing_time) {
+ page_event_times_.first_input_processing_time = processing_time;
+ if (GetSupplementable()->Loader()) {
+ GetSupplementable()->Loader()->DidChangePerformanceTiming();
+ }
+ }
+}
+
+void InteractiveDetector::DidObserveFirstScrollDelay(
+ base::TimeDelta first_scroll_delay,
+ base::TimeTicks first_scroll_timestamp) {
+ if (!page_event_times_.frist_scroll_delay.has_value()) {
+ page_event_times_.frist_scroll_delay = first_scroll_delay;
+ page_event_times_.first_scroll_timestamp = first_scroll_timestamp;
+ if (GetSupplementable()->Loader()) {
+ GetSupplementable()->Loader()->DidChangePerformanceTiming();
+ }
+ }
+}
+
+void InteractiveDetector::OnRestoredFromBackForwardCache() {
+ // Allocate the last element with 0, which indicates that the first input
+ // after this navigation doesn't happen yet.
+ page_event_times_.first_input_delays_after_back_forward_cache_restore
+ .push_back(base::nullopt);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/interactive_detector.h b/chromium/third_party/blink/renderer/core/loader/interactive_detector.h
index 09e8622eb06..ef1d8c8185d 100644
--- a/chromium/third_party/blink/renderer/core/loader/interactive_detector.h
+++ b/chromium/third_party/blink/renderer/core/loader/interactive_detector.h
@@ -88,6 +88,9 @@ class CORE_EXPORT InteractiveDetector
// pointer down followed by a pointer up.
base::Optional<base::TimeDelta> GetFirstInputDelay() const;
+ WTF::Vector<base::Optional<base::TimeDelta>>
+ GetFirstInputDelaysAfterBackForwardCacheRestore() const;
+
// The timestamp of the event whose delay is reported by GetFirstInputDelay().
base::Optional<base::TimeTicks> GetFirstInputTimestamp() const;
@@ -100,6 +103,15 @@ class CORE_EXPORT InteractiveDetector
// GetLongestInputDelay().
base::Optional<base::TimeTicks> GetLongestInputTimestamp() const;
+ // The duration of event handlers processing the first input event.
+ base::Optional<base::TimeDelta> GetFirstInputProcessingTime() const;
+
+ // The duration between the user's first scroll and display update.
+ base::Optional<base::TimeTicks> GetFirstScrollTimestamp() const;
+
+ // The hardware timestamp of the first scroll after a navigation.
+ base::Optional<base::TimeDelta> GetFirstScrollDelay() const;
+
// Process an input event, updating first_input_delay and
// first_input_timestamp if needed.
void HandleForInputDelay(const Event&,
@@ -109,7 +121,7 @@ class CORE_EXPORT InteractiveDetector
// ExecutionContextLifecycleObserver
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void SetTaskRunnerForTesting(
scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_testing);
@@ -120,6 +132,16 @@ class CORE_EXPORT InteractiveDetector
void SetUkmRecorderForTesting(ukm::UkmRecorder* test_ukm_recorder);
+ void RecordInputEventTimingUKM(const Event& event,
+ base::TimeTicks event_timestamp,
+ base::TimeTicks processing_start,
+ base::TimeTicks processing_end);
+
+ void DidObserveFirstScrollDelay(base::TimeDelta first_scroll_delay,
+ base::TimeTicks first_scroll_timestamp);
+
+ void OnRestoredFromBackForwardCache();
+
private:
friend class InteractiveDetectorTest;
@@ -142,6 +164,12 @@ class CORE_EXPORT InteractiveDetector
base::Optional<base::TimeDelta> longest_input_delay;
base::Optional<base::TimeTicks> first_input_timestamp;
base::Optional<base::TimeTicks> longest_input_timestamp;
+ base::Optional<base::TimeDelta> first_input_processing_time;
+ base::Optional<base::TimeTicks> first_scroll_timestamp;
+ base::Optional<base::TimeDelta> frist_scroll_delay;
+
+ WTF::Vector<base::Optional<base::TimeDelta>>
+ first_input_delays_after_back_forward_cache_restore;
} page_event_times_;
struct VisibilityChangeEvent {
@@ -202,6 +230,10 @@ class CORE_EXPORT InteractiveDetector
void OnLongTaskDetected(base::TimeTicks start_time,
base::TimeTicks end_time) override;
+ // The duration of event handlers processing the event for the previous
+ // pointer down.
+ base::Optional<base::TimeDelta> pending_pointerdown_processing_time_;
+
// The duration between the hardware timestamp and when we received the event
// for the previous pointer down. Only non-zero if we've received a pointer
// down event, and haven't yet reported the first input delay.
diff --git a/chromium/third_party/blink/renderer/core/loader/interactive_detector_test.cc b/chromium/third_party/blink/renderer/core/loader/interactive_detector_test.cc
index 4bfb1c4ce00..5df21440c5e 100644
--- a/chromium/third_party/blink/renderer/core/loader/interactive_detector_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/interactive_detector_test.cc
@@ -21,6 +21,7 @@
namespace blink {
using InputEvent = ukm::builders::InputEvent;
+using PageLoad = ukm::builders::PageLoad;
class NetworkActivityCheckerForTest
: public InteractiveDetector::NetworkActivityChecker {
@@ -567,23 +568,31 @@ TEST_F(InteractiveDetectorTest, LongTaskAfterTTIDoesNothing) {
}
TEST_F(InteractiveDetectorTest, RecordInputDelayUKM) {
- base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
+ base::TimeDelta delay = base::TimeDelta::FromMilliseconds(20);
+ base::TimeDelta processing_time = base::TimeDelta::FromMilliseconds(10);
Event event;
event.SetTrusted(true);
event.SetType(event_type_names::kClick);
base::TimeTicks processing_start = Now() + delay;
base::TimeTicks event_platform_timestamp = Now();
+ base::TimeTicks processing_end = processing_start + processing_time;
ukm::TestAutoSetUkmRecorder test_ukm_recorder;
GetDetector()->SetUkmRecorderForTesting(&test_ukm_recorder);
- GetDetector()->HandleForInputDelay(event, event_platform_timestamp,
- processing_start);
+ GetDetector()->RecordInputEventTimingUKM(event, event_platform_timestamp,
+ processing_start, processing_end);
auto entries = test_ukm_recorder.GetEntriesByName(InputEvent::kEntryName);
EXPECT_EQ(1ul, entries.size());
auto* entry = entries[0];
test_ukm_recorder.ExpectEntryMetric(
entry, InputEvent::kInteractiveTiming_InputDelayName,
delay.InMilliseconds());
+ test_ukm_recorder.ExpectEntryMetric(
+ entry, InputEvent::kInteractiveTiming_ProcessingTimeName,
+ processing_time.InMilliseconds());
+ EXPECT_EQ(
+ GetDetector()->GetFirstInputProcessingTime().value().InMilliseconds(),
+ processing_time.InMilliseconds());
}
// In tests for Total Blocking Time (TBT) we call SetTimeToInteractive() instead
diff --git a/chromium/third_party/blink/renderer/core/loader/lazy_image_helper.cc b/chromium/third_party/blink/renderer/core/loader/lazy_image_helper.cc
index 2678cc365a5..db0a913e6da 100644
--- a/chromium/third_party/blink/renderer/core/loader/lazy_image_helper.cc
+++ b/chromium/third_party/blink/renderer/core/loader/lazy_image_helper.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/frame_owner.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/html_image_element.h"
@@ -74,12 +75,6 @@ void LazyImageHelper::StartMonitoring(blink::Element* element) {
if (auto* html_image = DynamicTo<HTMLImageElement>(element)) {
LoadingAttributeValue effective_loading_attr = GetLoadingAttributeValue(
html_image->FastGetAttribute(html_names::kLoadingAttr));
- // If the 'lazyload' feature policy is enforced, the attribute value
- // loading='eager' is considered as 'auto'.
- if (effective_loading_attr == LoadingAttributeValue::kEager &&
- document->IsLazyLoadPolicyEnforced()) {
- effective_loading_attr = LoadingAttributeValue::kAuto;
- }
DCHECK_NE(effective_loading_attr, LoadingAttributeValue::kEager);
if (effective_loading_attr == LoadingAttributeValue::kAuto) {
deferral_message = DeferralMessage::kLoadEventsDeferred;
@@ -109,7 +104,7 @@ LazyImageHelper::DetermineEligibilityAndTrackVisibilityMetrics(
// Do not lazyload image elements when JavaScript is disabled, regardless of
// the `loading` attribute.
- if (!frame.GetDocument()->CanExecuteScripts(kNotAboutToExecuteScript))
+ if (!frame.DomWindow()->CanExecuteScripts(kNotAboutToExecuteScript))
return LazyImageHelper::Eligibility::kDisabled;
const auto lazy_load_image_setting = frame.GetLazyLoadImageSetting();
@@ -128,8 +123,7 @@ LazyImageHelper::DetermineEligibilityAndTrackVisibilityMetrics(
}
}
- if (loading_attr == LoadingAttributeValue::kEager &&
- !frame.GetDocument()->IsLazyLoadPolicyEnforced()) {
+ if (loading_attr == LoadingAttributeValue::kEager) {
UseCounter::Count(frame.GetDocument(),
WebFeature::kLazyLoadImageLoadingAttributeEager);
return LazyImageHelper::Eligibility::kDisabled;
diff --git a/chromium/third_party/blink/renderer/core/loader/link_loader.cc b/chromium/third_party/blink/renderer/core/loader/link_loader.cc
index 031eeedf530..30921607f31 100644
--- a/chromium/third_party/blink/renderer/core/loader/link_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/link_loader.cc
@@ -104,7 +104,7 @@ class LinkLoader::FinishObserver final : public ResourceFinishObserver {
resource_ = nullptr;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(loader_);
visitor->Trace(resource_);
blink::ResourceFinishObserver::Trace(visitor);
@@ -234,7 +234,8 @@ void LinkLoader::LoadStylesheet(const LinkLoadParameters& params,
mojom::FetchImportanceMode importance_mode =
GetFetchImportanceAttributeValue(params.importance);
DCHECK(importance_mode == mojom::FetchImportanceMode::kImportanceAuto ||
- RuntimeEnabledFeatures::PriorityHintsEnabled(&document));
+ RuntimeEnabledFeatures::PriorityHintsEnabled(
+ document.GetExecutionContext()));
resource_request.SetFetchImportanceMode(importance_mode);
ResourceLoaderOptions options;
@@ -279,7 +280,7 @@ void LinkLoader::Abort() {
}
}
-void LinkLoader::Trace(Visitor* visitor) {
+void LinkLoader::Trace(Visitor* visitor) const {
visitor->Trace(finish_observer_);
visitor->Trace(client_);
visitor->Trace(prerender_);
diff --git a/chromium/third_party/blink/renderer/core/loader/link_loader.h b/chromium/third_party/blink/renderer/core/loader/link_loader.h
index 925ba7787c3..3c7e61192ad 100644
--- a/chromium/third_party/blink/renderer/core/loader/link_loader.h
+++ b/chromium/third_party/blink/renderer/core/loader/link_loader.h
@@ -73,7 +73,7 @@ class CORE_EXPORT LinkLoader final : public SingleModuleClient,
Resource* GetResourceForTesting();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class FinishObserver;
diff --git a/chromium/third_party/blink/renderer/core/loader/link_loader_client.h b/chromium/third_party/blink/renderer/core/loader/link_loader_client.h
index 3b47304175d..7a1b0ac66fd 100644
--- a/chromium/third_party/blink/renderer/core/loader/link_loader_client.h
+++ b/chromium/third_party/blink/renderer/core/loader/link_loader_client.h
@@ -41,7 +41,7 @@ namespace blink {
class CORE_EXPORT LinkLoaderClient : public GarbageCollectedMixin {
public:
virtual ~LinkLoaderClient() = default;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
virtual bool ShouldLoadLink() = 0;
diff --git a/chromium/third_party/blink/renderer/core/loader/link_loader_test.cc b/chromium/third_party/blink/renderer/core/loader/link_loader_test.cc
index fa6fc74d28b..40272f4ce07 100644
--- a/chromium/third_party/blink/renderer/core/loader/link_loader_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/link_loader_test.cc
@@ -42,7 +42,9 @@ class MockLinkLoaderClient final
public:
explicit MockLinkLoaderClient(bool should_load) : should_load_(should_load) {}
- void Trace(Visitor* visitor) override { LinkLoaderClient::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ LinkLoaderClient::Trace(visitor);
+ }
bool ShouldLoadLink() override { return should_load_; }
bool IsLinkCreatedByParser() override { return true; }
@@ -594,7 +596,8 @@ TEST_P(LinkLoaderTestPrefetchPrivacyChanges, PrefetchPrivacyChanges) {
: network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade);
}
- platform_->GetURLLoaderMockFactory()->UnregisterAllURLsAndClearMemoryCache();
+ WebURLLoaderMockFactory::GetSingletonInstance()
+ ->UnregisterAllURLsAndClearMemoryCache();
}
class LinkLoaderTest : public testing::Test,
@@ -660,7 +663,7 @@ TEST_F(LinkLoaderTest, Prefetch) {
resource->GetResourceRequest().GetReferrerPolicy());
}
}
- platform_->GetURLLoaderMockFactory()
+ WebURLLoaderMockFactory::GetSingletonInstance()
->UnregisterAllURLsAndClearMemoryCache();
}
}
diff --git a/chromium/third_party/blink/renderer/core/loader/loader_factory_for_frame.cc b/chromium/third_party/blink/renderer/core/loader/loader_factory_for_frame.cc
index dd52906f326..648c9cb7487 100644
--- a/chromium/third_party/blink/renderer/core/loader/loader_factory_for_frame.cc
+++ b/chromium/third_party/blink/renderer/core/loader/loader_factory_for_frame.cc
@@ -12,8 +12,8 @@
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_url_loader_factory.h"
-#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/fileapi/public_url_manager.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.h"
@@ -23,15 +23,15 @@
namespace blink {
LoaderFactoryForFrame::LoaderFactoryForFrame(DocumentLoader& document_loader,
- Document& document)
+ LocalDOMWindow& window)
: document_loader_(document_loader),
- document_(document),
+ window_(window),
prefetched_signed_exchange_manager_(
document_loader.GetPrefetchedSignedExchangeManager()) {}
-void LoaderFactoryForFrame::Trace(Visitor* visitor) {
+void LoaderFactoryForFrame::Trace(Visitor* visitor) const {
visitor->Trace(document_loader_);
- visitor->Trace(document_);
+ visitor->Trace(window_);
visitor->Trace(prefetched_signed_exchange_manager_);
LoaderFactory::Trace(visitor);
}
@@ -69,10 +69,10 @@ std::unique_ptr<WebURLLoader> LoaderFactoryForFrame::CreateURLLoader(
// callsite when we make Shared Worker loading off-main-thread.
if (request.Url().ProtocolIs("blob") && !url_loader_factory &&
request.GetRequestContext() != mojom::RequestContextType::SHARED_WORKER) {
- document_->GetPublicURLManager().Resolve(
+ window_->GetPublicURLManager().Resolve(
request.Url(), url_loader_factory.InitWithNewPipeAndPassReceiver());
}
- LocalFrame* frame = document_->GetFrame();
+ LocalFrame* frame = window_->GetFrame();
DCHECK(frame);
FrameScheduler* frame_scheduler = frame->GetFrameScheduler();
DCHECK(frame_scheduler);
@@ -84,7 +84,7 @@ std::unique_ptr<WebURLLoader> LoaderFactoryForFrame::CreateURLLoader(
// resource loader handle's task runner.
if (url_loader_factory) {
return Platform::Current()
- ->WrapURLLoaderFactory(url_loader_factory.PassPipe())
+ ->WrapURLLoaderFactory(std::move(url_loader_factory))
->CreateURLLoader(
webreq, frame_scheduler->CreateResourceLoadingTaskRunnerHandle());
}
diff --git a/chromium/third_party/blink/renderer/core/loader/loader_factory_for_frame.h b/chromium/third_party/blink/renderer/core/loader/loader_factory_for_frame.h
index cdea44d046b..0b003e51986 100644
--- a/chromium/third_party/blink/renderer/core/loader/loader_factory_for_frame.h
+++ b/chromium/third_party/blink/renderer/core/loader/loader_factory_for_frame.h
@@ -12,15 +12,15 @@
namespace blink {
-class Document;
class DocumentLoader;
+class LocalDOMWindow;
class PrefetchedSignedExchangeManager;
class LoaderFactoryForFrame final : public ResourceFetcher::LoaderFactory {
public:
- LoaderFactoryForFrame(DocumentLoader& loader, Document& document);
+ LoaderFactoryForFrame(DocumentLoader& loader, LocalDOMWindow& window);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// LoaderFactory implementations
std::unique_ptr<WebURLLoader> CreateURLLoader(
@@ -31,7 +31,7 @@ class LoaderFactoryForFrame final : public ResourceFetcher::LoaderFactory {
private:
const Member<DocumentLoader> document_loader_;
- const Member<Document> document_;
+ const Member<LocalDOMWindow> window_;
const Member<PrefetchedSignedExchangeManager>
prefetched_signed_exchange_manager_;
};
diff --git a/chromium/third_party/blink/renderer/core/loader/loader_factory_for_worker.cc b/chromium/third_party/blink/renderer/core/loader/loader_factory_for_worker.cc
index 1e5089d1b52..ea8c5d668c7 100644
--- a/chromium/third_party/blink/renderer/core/loader/loader_factory_for_worker.cc
+++ b/chromium/third_party/blink/renderer/core/loader/loader_factory_for_worker.cc
@@ -18,7 +18,7 @@
namespace blink {
-void LoaderFactoryForWorker::Trace(Visitor* visitor) {
+void LoaderFactoryForWorker::Trace(Visitor* visitor) const {
visitor->Trace(global_scope_);
LoaderFactory::Trace(visitor);
}
@@ -49,7 +49,7 @@ std::unique_ptr<WebURLLoader> LoaderFactoryForWorker::CreateURLLoader(
}
if (url_loader_factory) {
- return web_context_->WrapURLLoaderFactory(url_loader_factory.PassPipe())
+ return web_context_->WrapURLLoaderFactory(std::move(url_loader_factory))
->CreateURLLoader(wrapped, CreateTaskRunnerHandle(task_runner));
}
diff --git a/chromium/third_party/blink/renderer/core/loader/loader_factory_for_worker.h b/chromium/third_party/blink/renderer/core/loader/loader_factory_for_worker.h
index 7ab80943df2..ea8e48f579b 100644
--- a/chromium/third_party/blink/renderer/core/loader/loader_factory_for_worker.h
+++ b/chromium/third_party/blink/renderer/core/loader/loader_factory_for_worker.h
@@ -25,7 +25,7 @@ class LoaderFactoryForWorker : public ResourceFetcher::LoaderFactory {
scoped_refptr<WebWorkerFetchContext> web_context)
: global_scope_(global_scope), web_context_(std::move(web_context)) {}
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// LoaderFactory implementations
std::unique_ptr<WebURLLoader> CreateURLLoader(
diff --git a/chromium/third_party/blink/renderer/core/loader/long_task_detector.cc b/chromium/third_party/blink/renderer/core/loader/long_task_detector.cc
index 488eb143003..7e1499b1ddd 100644
--- a/chromium/third_party/blink/renderer/core/loader/long_task_detector.cc
+++ b/chromium/third_party/blink/renderer/core/loader/long_task_detector.cc
@@ -48,7 +48,7 @@ void LongTaskDetector::DidProcessTask(base::TimeTicks start_time,
}
}
-void LongTaskDetector::Trace(Visitor* visitor) {
+void LongTaskDetector::Trace(Visitor* visitor) const {
visitor->Trace(observers_);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/long_task_detector.h b/chromium/third_party/blink/renderer/core/loader/long_task_detector.h
index b32e9165efb..dc6f0dbab5c 100644
--- a/chromium/third_party/blink/renderer/core/loader/long_task_detector.h
+++ b/chromium/third_party/blink/renderer/core/loader/long_task_detector.h
@@ -37,7 +37,7 @@ class CORE_EXPORT LongTaskDetector final
void RegisterObserver(LongTaskObserver*);
void UnregisterObserver(LongTaskObserver*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
static constexpr base::TimeDelta kLongTaskThreshold =
base::TimeDelta::FromMilliseconds(50);
diff --git a/chromium/third_party/blink/renderer/core/loader/mixed_content_checker.cc b/chromium/third_party/blink/renderer/core/loader/mixed_content_checker.cc
index 53a51cbceae..96c1a04d2ce 100644
--- a/chromium/third_party/blink/renderer/core/loader/mixed_content_checker.cc
+++ b/chromium/third_party/blink/renderer/core/loader/mixed_content_checker.cc
@@ -420,6 +420,7 @@ void MixedContentChecker::Count(Frame* frame,
bool MixedContentChecker::ShouldBlockFetch(
LocalFrame* frame,
mojom::RequestContextType request_context,
+ const KURL& url_before_redirects,
ResourceRequest::RedirectStatus redirect_status,
const KURL& url,
const base::Optional<String>& devtools_id,
@@ -450,7 +451,7 @@ bool MixedContentChecker::ShouldBlockFetch(
MixedContentChecker::Count(mixed_frame, request_context, frame);
if (ContentSecurityPolicy* policy =
frame->GetSecurityContext()->GetContentSecurityPolicy())
- policy->ReportMixedContent(url, redirect_status);
+ policy->ReportMixedContent(url_before_redirects, redirect_status);
Settings* settings = mixed_frame->GetSettings();
// Use the current local frame's client; the embedder doesn't distinguish
@@ -543,8 +544,9 @@ bool MixedContentChecker::ShouldBlockFetch(
// receive an issue with a devtools_id which it can match to a request.
CreateMixedContentIssue(
MainResourceUrlForFrame(mixed_frame), url, request_context, frame,
- allowed ? mojom::blink::MixedContentResolutionStatus::MixedContentWarning
- : mojom::blink::MixedContentResolutionStatus::MixedContentBlocked,
+ allowed
+ ? mojom::blink::MixedContentResolutionStatus::kMixedContentWarning
+ : mojom::blink::MixedContentResolutionStatus::kMixedContentBlocked,
devtools_id);
return !allowed;
}
@@ -553,6 +555,7 @@ bool MixedContentChecker::ShouldBlockFetch(
bool MixedContentChecker::ShouldBlockFetchOnWorker(
const WorkerFetchContext& worker_fetch_context,
mojom::RequestContextType request_context,
+ const KURL& url_before_redirects,
ResourceRequest::RedirectStatus redirect_status,
const KURL& url,
ReportingDisposition reporting_disposition,
@@ -567,7 +570,7 @@ bool MixedContentChecker::ShouldBlockFetchOnWorker(
worker_fetch_context.CountUsage(WebFeature::kMixedContentPresent);
worker_fetch_context.CountUsage(WebFeature::kMixedContentBlockable);
if (auto* policy = worker_fetch_context.GetContentSecurityPolicy())
- policy->ReportMixedContent(url, redirect_status);
+ policy->ReportMixedContent(url_before_redirects, redirect_status);
// Blocks all mixed content request from worklets.
// TODO(horo): Revise this when the spec is updated.
@@ -665,8 +668,9 @@ bool MixedContentChecker::IsWebSocketAllowed(
CreateMixedContentIssue(
MainResourceUrlForFrame(mixed_frame), url,
mojom::blink::RequestContextType::FETCH, frame,
- allowed ? mojom::blink::MixedContentResolutionStatus::MixedContentWarning
- : mojom::blink::MixedContentResolutionStatus::MixedContentBlocked,
+ allowed
+ ? mojom::blink::MixedContentResolutionStatus::kMixedContentWarning
+ : mojom::blink::MixedContentResolutionStatus::kMixedContentBlocked,
base::Optional<String>());
return allowed;
}
@@ -740,7 +744,7 @@ bool MixedContentChecker::IsMixedFormAction(
CreateMixedContentIssue(
MainResourceUrlForFrame(mixed_frame), url,
mojom::blink::RequestContextType::FORM, frame,
- mojom::blink::MixedContentResolutionStatus::MixedContentWarning,
+ mojom::blink::MixedContentResolutionStatus::kMixedContentWarning,
base::Optional<String>());
return true;
@@ -780,22 +784,22 @@ bool MixedContentChecker::ShouldAutoupgrade(
void MixedContentChecker::CheckMixedPrivatePublic(
LocalFrame* frame,
const AtomicString& resource_ip_address) {
- if (!frame || !frame->GetDocument() || !frame->GetDocument()->Loader())
+ if (!frame)
return;
// Just count these for the moment, don't block them.
if (network_utils::IsReservedIPAddress(resource_ip_address) &&
- frame->GetDocument()->GetSecurityContext().AddressSpace() ==
+ frame->GetSecurityContext()->AddressSpace() ==
network::mojom::IPAddressSpace::kPublic) {
- UseCounter::Count(frame->GetDocument(),
+ UseCounter::Count(frame->DomWindow(),
WebFeature::kMixedContentPrivateHostnameInPublicHostname);
// We can simplify the IP checks here, as we've already verified that
// |resourceIPAddress| is a reserved IP address, which means it's also a
// valid IP address in a normalized form.
if (resource_ip_address.StartsWith("127.0.0.") ||
resource_ip_address == "[::1]") {
- UseCounter::Count(frame->GetDocument(),
- frame->GetDocument()->IsSecureContext()
+ UseCounter::Count(frame->DomWindow(),
+ frame->DomWindow()->IsSecureContext()
? WebFeature::kLoopbackEmbeddedInSecureContext
: WebFeature::kLoopbackEmbeddedInNonSecureContext);
}
@@ -832,6 +836,7 @@ void MixedContentChecker::MixedContentFound(
const KURL& mixed_content_url,
mojom::RequestContextType request_context,
bool was_allowed,
+ const KURL& url_before_redirects,
bool had_redirect,
std::unique_ptr<SourceLocation> source_location) {
// Logs to the frame console.
@@ -842,15 +847,15 @@ void MixedContentChecker::MixedContentFound(
CreateMixedContentIssue(
main_resource_url, mixed_content_url, request_context, frame,
was_allowed
- ? mojom::blink::MixedContentResolutionStatus::MixedContentWarning
- : mojom::blink::MixedContentResolutionStatus::MixedContentBlocked,
+ ? mojom::blink::MixedContentResolutionStatus::kMixedContentWarning
+ : mojom::blink::MixedContentResolutionStatus::kMixedContentBlocked,
base::Optional<String>());
// Reports to the CSP policy.
ContentSecurityPolicy* policy =
frame->GetSecurityContext()->GetContentSecurityPolicy();
if (policy) {
policy->ReportMixedContent(
- mixed_content_url,
+ url_before_redirects,
had_redirect ? ResourceRequest::RedirectStatus::kFollowedRedirect
: ResourceRequest::RedirectStatus::kNoRedirect);
}
@@ -935,7 +940,7 @@ void MixedContentChecker::UpgradeInsecureRequest(
resource_request.Url(), context,
window->document()->GetFrame(),
mojom::blink::MixedContentResolutionStatus::
- MixedContentAutomaticallyUpgraded,
+ kMixedContentAutomaticallyUpgraded,
resource_request.GetDevToolsId());
}
resource_request.SetIsAutomaticUpgrade(true);
diff --git a/chromium/third_party/blink/renderer/core/loader/mixed_content_checker.h b/chromium/third_party/blink/renderer/core/loader/mixed_content_checker.h
index c5ad31eb998..cbb019bfcca 100644
--- a/chromium/third_party/blink/renderer/core/loader/mixed_content_checker.h
+++ b/chromium/third_party/blink/renderer/core/loader/mixed_content_checker.h
@@ -71,6 +71,7 @@ class CORE_EXPORT MixedContentChecker final {
public:
static bool ShouldBlockFetch(LocalFrame* frame,
mojom::blink::RequestContextType request_context,
+ const KURL& url_before_redirects,
ResourceRequest::RedirectStatus redirect_status,
const KURL& url,
const base::Optional<String>& devtools_id,
@@ -79,6 +80,7 @@ class CORE_EXPORT MixedContentChecker final {
static bool ShouldBlockFetchOnWorker(const WorkerFetchContext&,
mojom::RequestContextType,
+ const KURL& url_before_redirects,
ResourceRequest::RedirectStatus,
const KURL&,
ReportingDisposition,
@@ -119,6 +121,7 @@ class CORE_EXPORT MixedContentChecker final {
const KURL& mixed_content_url,
mojom::RequestContextType,
bool was_allowed,
+ const KURL& url_before_redirects,
bool had_redirect,
std::unique_ptr<SourceLocation>);
diff --git a/chromium/third_party/blink/renderer/core/loader/mixed_content_checker_test.cc b/chromium/third_party/blink/renderer/core/loader/mixed_content_checker_test.cc
index 7a36999af2e..bcc41cc0348 100644
--- a/chromium/third_party/blink/renderer/core/loader/mixed_content_checker_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/mixed_content_checker_test.cc
@@ -205,14 +205,16 @@ TEST(MixedContentCheckerTest, DetectMixedFavicon) {
// Test that a mixed content favicon is correctly blocked.
EXPECT_TRUE(MixedContentChecker::ShouldBlockFetch(
&dummy_page_holder->GetFrame(), mojom::RequestContextType::FAVICON,
- ResourceRequest::RedirectStatus::kNoRedirect, http_favicon_url,
- base::Optional<String>(), ReportingDisposition::kSuppressReporting));
+ http_favicon_url, ResourceRequest::RedirectStatus::kNoRedirect,
+ http_favicon_url, base::Optional<String>(),
+ ReportingDisposition::kSuppressReporting));
// Test that a secure favicon is not blocked.
EXPECT_FALSE(MixedContentChecker::ShouldBlockFetch(
&dummy_page_holder->GetFrame(), mojom::RequestContextType::FAVICON,
- ResourceRequest::RedirectStatus::kNoRedirect, https_favicon_url,
- base::Optional<String>(), ReportingDisposition::kSuppressReporting));
+ https_favicon_url, ResourceRequest::RedirectStatus::kNoRedirect,
+ https_favicon_url, base::Optional<String>(),
+ ReportingDisposition::kSuppressReporting));
}
class TestFetchClientSettingsObject : public FetchClientSettingsObject {
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc b/chromium/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc
index 29765436437..860134d9706 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc
@@ -48,7 +48,7 @@ void DocumentModuleScriptFetcher::NotifyFinished(Resource* resource) {
client_->NotifyFetchFinished(params, error_messages);
}
-void DocumentModuleScriptFetcher::Trace(Visitor* visitor) {
+void DocumentModuleScriptFetcher::Trace(Visitor* visitor) const {
ModuleScriptFetcher::Trace(visitor);
visitor->Trace(client_);
ResourceClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.h b/chromium/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.h
index 4ac35597297..6012aa2c8aa 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.h
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.h
@@ -33,7 +33,7 @@ class CORE_EXPORT DocumentModuleScriptFetcher final
void NotifyFinished(Resource*) override;
String DebugName() const override { return "DocumentModuleScriptFetcher"; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Client> client_;
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc b/chromium/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc
index 1862a248eb4..8667eba3cc0 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc
@@ -110,7 +110,7 @@ void InstalledServiceWorkerModuleScriptFetcher::Fetch(
client->NotifyFetchFinished(params, HeapVector<Member<ConsoleMessage>>());
}
-void InstalledServiceWorkerModuleScriptFetcher::Trace(Visitor* visitor) {
+void InstalledServiceWorkerModuleScriptFetcher::Trace(Visitor* visitor) const {
ModuleScriptFetcher::Trace(visitor);
visitor->Trace(global_scope_);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.h b/chromium/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.h
index e68a730dfec..7be9182c42a 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.h
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.h
@@ -29,7 +29,7 @@ class CORE_EXPORT InstalledServiceWorkerModuleScriptFetcher final
ModuleGraphLevel,
ModuleScriptFetcher::Client*) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String DebugName() const override {
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetcher.cc b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetcher.cc
index af7f699107c..5a29760fc6d 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetcher.cc
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetcher.cc
@@ -28,7 +28,7 @@ void ModuleScriptFetcher::Client::OnFailed() {
NotifyFetchFinished(base::nullopt, HeapVector<Member<ConsoleMessage>>());
}
-void ModuleScriptFetcher::Trace(Visitor* visitor) {
+void ModuleScriptFetcher::Trace(Visitor* visitor) const {
ResourceClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetcher.h b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetcher.h
index 9b034af0c37..8018964df93 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetcher.h
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetcher.h
@@ -49,7 +49,7 @@ class CORE_EXPORT ModuleScriptFetcher : public ResourceClient {
ModuleGraphLevel,
Client*) = 0;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
static bool WasModuleLoadSuccessful(
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc
index 60517e94b89..f51db68c182 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc
@@ -279,7 +279,7 @@ void ModuleScriptLoader::NotifyFetchFinished(
AdvanceState(State::kFinished);
}
-void ModuleScriptLoader::Trace(Visitor* visitor) {
+void ModuleScriptLoader::Trace(Visitor* visitor) const {
visitor->Trace(modulator_);
visitor->Trace(module_script_);
visitor->Trace(registry_);
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader.h b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader.h
index 1874e4cfb89..8fe7414f4b9 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader.h
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader.h
@@ -67,7 +67,7 @@ class CORE_EXPORT ModuleScriptLoader final
bool IsInitialState() const { return state_ == State::kInitial; }
bool HasFinished() const { return state_ == State::kFinished; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
friend class WorkletModuleResponsesMapTest;
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.cc b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.cc
index 9f250d20293..e4b145e195a 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.cc
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.cc
@@ -8,7 +8,7 @@
namespace blink {
-void ModuleScriptLoaderRegistry::Trace(Visitor* visitor) {
+void ModuleScriptLoaderRegistry::Trace(Visitor* visitor) const {
visitor->Trace(active_loaders_);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.h b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.h
index af8cb737342..1aac234058d 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.h
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.h
@@ -19,7 +19,7 @@ class CORE_EXPORT ModuleScriptLoaderRegistry final
public:
ModuleScriptLoaderRegistry() = default;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
friend class ModuleScriptLoader;
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc
index 27198816336..0f36eea7c4b 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc
@@ -53,7 +53,9 @@ class TestModuleScriptLoaderClient final
TestModuleScriptLoaderClient() = default;
~TestModuleScriptLoaderClient() override = default;
- void Trace(Visitor* visitor) override { visitor->Trace(module_script_); }
+ void Trace(Visitor* visitor) const override {
+ visitor->Trace(module_script_);
+ }
void NotifyNewSingleModuleFinished(ModuleScript* module_script) override {
was_notify_finished_ = true;
@@ -108,14 +110,14 @@ class ModuleScriptLoaderTestModulator final : public DummyModulator {
return MakeGarbageCollected<DocumentModuleScriptFetcher>(pass_key);
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<ScriptState> script_state_;
Vector<ModuleRequest> requests_;
};
-void ModuleScriptLoaderTestModulator::Trace(Visitor* visitor) {
+void ModuleScriptLoaderTestModulator::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
DummyModulator::Trace(visitor);
}
@@ -491,7 +493,8 @@ void ModuleScriptLoaderTest::TestFetchURL(
TestModuleScriptLoaderClient* client) {
KURL url("https://example.test/module.js");
url_test_helpers::RegisterMockedURLLoad(
- url, test::CoreTestDataPath("module.js"), "text/javascript");
+ url, test::CoreTestDataPath("module.js"), "text/javascript",
+ platform_->GetURLLoaderMockFactory());
auto* registry = MakeGarbageCollected<ModuleScriptLoaderRegistry>();
ModuleScriptLoader::Fetch(ModuleScriptFetchRequest::CreateForTest(url),
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc b/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
index 5e710b04a5b..89f8ccd977e 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
@@ -87,7 +87,7 @@ ModuleTreeLinker::ModuleTreeLinker(
CHECK(client);
}
-void ModuleTreeLinker::Trace(Visitor* visitor) {
+void ModuleTreeLinker::Trace(Visitor* visitor) const {
visitor->Trace(fetch_client_settings_object_fetcher_);
visitor->Trace(modulator_);
visitor->Trace(registry_);
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h b/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h
index c4a664b1987..bd15eda9db5 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h
@@ -60,7 +60,7 @@ class CORE_EXPORT ModuleTreeLinker final : public SingleModuleClient {
ModuleTreeLinkerRegistry*,
ModuleTreeClient*);
~ModuleTreeLinker() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool IsFetching() const {
return State::kFetchingSelf <= state_ && state_ < State::kFinished;
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.cc b/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.cc
index 152aace03c0..86f6f3bde6b 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.cc
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.cc
@@ -11,7 +11,7 @@
namespace blink {
-void ModuleTreeLinkerRegistry::Trace(Visitor* visitor) {
+void ModuleTreeLinkerRegistry::Trace(Visitor* visitor) const {
visitor->Trace(active_tree_linkers_);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h b/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h
index 9bfb1121d9e..a5bb392548d 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h
@@ -20,7 +20,7 @@ class CORE_EXPORT ModuleTreeLinkerRegistry final
public:
ModuleTreeLinkerRegistry() = default;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override {
return "ModuleTreeLinkerRegistry";
}
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc b/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc
index ce6ccc0ef19..662eefc3890 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc
@@ -34,7 +34,7 @@ class TestModuleTreeClient final : public ModuleTreeClient {
public:
TestModuleTreeClient() = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(module_script_);
ModuleTreeClient::Trace(visitor);
}
@@ -60,7 +60,7 @@ class ModuleTreeLinkerTestModulator final : public DummyModulator {
: script_state_(script_state) {}
~ModuleTreeLinkerTestModulator() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
enum class ResolveResult { kFailure, kSuccess };
@@ -182,7 +182,7 @@ class ModuleTreeLinkerTestModulator final : public DummyModulator {
bool instantiate_should_fail_ = false;
};
-void ModuleTreeLinkerTestModulator::Trace(Visitor* visitor) {
+void ModuleTreeLinkerTestModulator::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(pending_clients_);
visitor->Trace(module_map_);
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc b/chromium/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc
index 2b00996a03a..54ef8fc78e4 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc
@@ -51,7 +51,7 @@ void WorkerModuleScriptFetcher::Fetch(
this, ScriptResource::kNoStreaming);
}
-void WorkerModuleScriptFetcher::Trace(Visitor* visitor) {
+void WorkerModuleScriptFetcher::Trace(Visitor* visitor) const {
ModuleScriptFetcher::Trace(visitor);
visitor->Trace(client_);
visitor->Trace(global_scope_);
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.h b/chromium/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.h
index 9453005523a..7f1d67bbc2e 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.h
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.h
@@ -31,7 +31,7 @@ class CORE_EXPORT WorkerModuleScriptFetcher final
ModuleGraphLevel,
ModuleScriptFetcher::Client*) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Implements ResourceClient
diff --git a/chromium/third_party/blink/renderer/core/loader/ping_loader.cc b/chromium/third_party/blink/renderer/core/loader/ping_loader.cc
index 181b50c9f92..1babd22966b 100644
--- a/chromium/third_party/blink/renderer/core/loader/ping_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/ping_loader.cc
@@ -37,6 +37,7 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/fileapi/file.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/html/forms/form_data.h"
@@ -185,12 +186,9 @@ class BeaconFormData final : public Beacon {
bool SendBeaconCommon(LocalFrame* frame,
const KURL& url,
const Beacon& beacon) {
- if (!frame->GetDocument())
- return false;
-
- if (!frame->GetDocument()
+ if (!frame->DomWindow()
->GetContentSecurityPolicyForWorld()
- ->AllowConnectToSource(url)) {
+ ->AllowConnectToSource(url, url, RedirectStatus::kNoRedirect)) {
// We're simulating a network failure here, so we return 'true'.
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/loader/ping_loader_test.cc b/chromium/third_party/blink/renderer/core/loader/ping_loader_test.cc
index 86454344997..742011e67a2 100644
--- a/chromium/third_party/blink/renderer/core/loader/ping_loader_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/ping_loader_test.cc
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/core/loader/frame_loader.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/network/encoded_form_data.h"
+#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -42,8 +43,11 @@ class PartialResourceRequest {
class PingLocalFrameClient : public EmptyLocalFrameClient {
public:
+ explicit PingLocalFrameClient(TestingPlatformSupport* platform)
+ : platform_(platform) {}
+
std::unique_ptr<WebURLLoaderFactory> CreateURLLoaderFactory() override {
- return Platform::Current()->CreateDefaultURLLoaderFactory();
+ return platform_->CreateDefaultURLLoaderFactory();
}
void DispatchWillSendRequest(ResourceRequest& request) override {
@@ -55,12 +59,14 @@ class PingLocalFrameClient : public EmptyLocalFrameClient {
private:
PartialResourceRequest ping_request_;
+ TestingPlatformSupport* platform_;
};
class PingLoaderTest : public PageTestBase {
public:
void SetUp() override {
- client_ = MakeGarbageCollected<PingLocalFrameClient>();
+ client_ = MakeGarbageCollected<PingLocalFrameClient>(
+ platform_.GetTestingPlatformSupport());
PageTestBase::SetupPageWithClients(nullptr, client_);
}
@@ -95,6 +101,7 @@ class PingLoaderTest : public PageTestBase {
}
protected:
+ ScopedTestingPlatformSupport<TestingPlatformSupport> platform_;
Persistent<PingLocalFrameClient> client_;
};
diff --git a/chromium/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.cc b/chromium/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.cc
index 0215b9965b1..b6cb0dc170c 100644
--- a/chromium/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.cc
+++ b/chromium/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.h"
+#include <utility>
+
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
@@ -186,7 +188,7 @@ PrefetchedSignedExchangeManager::PrefetchedSignedExchangeManager(
PrefetchedSignedExchangeManager::~PrefetchedSignedExchangeManager() {}
-void PrefetchedSignedExchangeManager::Trace(Visitor* visitor) {
+void PrefetchedSignedExchangeManager::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
}
@@ -234,7 +236,7 @@ PrefetchedSignedExchangeManager::CreatePrefetchedSignedExchangeURLLoader(
mojo::PendingRemote<network::mojom::blink::URLLoaderFactory>
loader_factory) {
return Platform::Current()
- ->WrapURLLoaderFactory(loader_factory.PassPipe())
+ ->WrapURLLoaderFactory(std::move(loader_factory))
->CreateURLLoader(
request,
frame_->GetFrameScheduler()->CreateResourceLoadingTaskRunnerHandle());
@@ -300,16 +302,13 @@ void PrefetchedSignedExchangeManager::TriggerLoad() {
continue;
auto* prefetched_exchange = maching_prefetched_exchanges.at(i);
mojo::Remote<network::mojom::blink::URLLoaderFactory> loader_factory(
- mojo::PendingRemote<network::mojom::blink::URLLoaderFactory>(
- std::move(prefetched_exchange->loader_factory_handle),
- network::mojom::URLLoaderFactory::Version_));
+ std::move(prefetched_exchange->loader_factory));
mojo::PendingRemote<network::mojom::blink::URLLoaderFactory>
loader_factory_clone;
loader_factory->Clone(
loader_factory_clone.InitWithNewPipeAndPassReceiver());
// Reset loader_factory_handle to support loading the same resource again.
- prefetched_exchange->loader_factory_handle =
- loader_factory_clone.PassPipe();
+ prefetched_exchange->loader_factory = std::move(loader_factory_clone);
loader->SetURLLoader(CreatePrefetchedSignedExchangeURLLoader(
loader->request(), loader_factory.Unbind()));
}
diff --git a/chromium/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.h b/chromium/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.h
index 2b3b35bc8b7..e476d43094f 100644
--- a/chromium/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.h
+++ b/chromium/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.h
@@ -47,7 +47,7 @@ class PrefetchedSignedExchangeManager final
prefetched_exchanges_map);
~PrefetchedSignedExchangeManager();
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
// Returns a loader if there is a matching resource in
// |alternative_resources_|, otherwise returns null. This only checks the
diff --git a/chromium/third_party/blink/renderer/core/loader/preload_helper.cc b/chromium/third_party/blink/renderer/core/loader/preload_helper.cc
index 775f84c3426..74a6e2126f4 100644
--- a/chromium/third_party/blink/renderer/core/loader/preload_helper.cc
+++ b/chromium/third_party/blink/renderer/core/loader/preload_helper.cc
@@ -30,7 +30,7 @@
#include "third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h"
#include "third_party/blink/renderer/core/loader/resource/font_resource.h"
#include "third_party/blink/renderer/core/loader/resource/image_resource.h"
-#include "third_party/blink/renderer/core/loader/resource/link_fetch_resource.h"
+#include "third_party/blink/renderer/core/loader/resource/link_prefetch_resource.h"
#include "third_party/blink/renderer/core/loader/resource/script_resource.h"
#include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h"
#include "third_party/blink/renderer/core/page/viewport_description.h"
@@ -517,8 +517,15 @@ Resource* PreloadHelper::PrefetchIfNeeded(const LinkLoadParameters& params,
ResourceRequest resource_request(params.href);
- if (EqualIgnoringASCIICase(params.as, "document"))
+ // Later a security check is done asserting that the initiator of a
+ // cross-origin prefetch request is same-origin with the origin that the
+ // browser process is aware of. However, since opaque request initiators are
+ // always cross-origin with every other origin, we must not request
+ // cross-origin prefetches from opaque requestors.
+ if (EqualIgnoringASCIICase(params.as, "document") &&
+ !document.GetSecurityOrigin()->IsOpaque()) {
resource_request.SetPrefetchMaybeForTopLevelNavigation(true);
+ }
// This request could have originally been a preload header on a prefetch
// response, that was promoted to a prefetch request by LoadLinksFromHeader.
@@ -550,9 +557,8 @@ Resource* PreloadHelper::PrefetchIfNeeded(const LinkLoadParameters& params,
RuntimeEnabledFeatures::
SignedExchangePrefetchCacheForNavigationsEnabled() ||
RuntimeEnabledFeatures::SignedExchangeSubresourcePrefetchEnabled(
- &document));
- return LinkFetchResource::Fetch(ResourceType::kLinkPrefetch,
- link_fetch_params, document.Fetcher());
+ document.GetExecutionContext()));
+ return LinkPrefetchResource::Fetch(link_fetch_params, document.Fetcher());
}
return nullptr;
}
@@ -594,7 +600,7 @@ void PreloadHelper::LoadLinksFromHeader(
if (alternate_resource_info && params.rel.IsLinkPreload()) {
DCHECK(document);
DCHECK(RuntimeEnabledFeatures::SignedExchangeSubresourcePrefetchEnabled(
- document));
+ document->GetExecutionContext()));
KURL url = params.href;
base::Optional<ResourceType> resource_type =
PreloadHelper::GetResourceTypeFromAsAttribute(params.as);
diff --git a/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints.cc b/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints.cc
index 79e250203ee..0adf586b888 100644
--- a/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints.cc
+++ b/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints.cc
@@ -155,7 +155,7 @@ void PreviewsResourceLoadingHints::ReportBlockedLoading(
GetConsoleLogStringForBlockedLoad(resource_url)));
}
-void PreviewsResourceLoadingHints::Trace(Visitor* visitor) {
+void PreviewsResourceLoadingHints::Trace(Visitor* visitor) const {
visitor->Trace(execution_context_);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints.h b/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints.h
index edd00fe6753..ecefad6ce83 100644
--- a/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints.h
+++ b/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints.h
@@ -51,7 +51,7 @@ class CORE_EXPORT PreviewsResourceLoadingHints final
const KURL& resource_url,
ResourceLoadPriority resource_load_priority) const;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
// Records UKM on the utilization of patterns to block during the document
// load. This is expected to be called once after the document finishes
diff --git a/chromium/third_party/blink/renderer/core/loader/private/prerender_client.h b/chromium/third_party/blink/renderer/core/loader/private/prerender_client.h
index cc62574b54c..9965225e95f 100644
--- a/chromium/third_party/blink/renderer/core/loader/private/prerender_client.h
+++ b/chromium/third_party/blink/renderer/core/loader/private/prerender_client.h
@@ -46,7 +46,7 @@ class PLATFORM_EXPORT PrerenderClient : public GarbageCollectedMixin {
virtual void DidSendLoadForPrerender() = 0;
virtual void DidSendDOMContentLoadedForPrerender() = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/private/prerender_handle.cc b/chromium/third_party/blink/renderer/core/loader/private/prerender_handle.cc
index 08821a5c267..81d26a81df4 100644
--- a/chromium/third_party/blink/renderer/core/loader/private/prerender_handle.cc
+++ b/chromium/third_party/blink/renderer/core/loader/private/prerender_handle.cc
@@ -52,8 +52,9 @@ PrerenderHandle* PrerenderHandle::Create(Document& document,
if (!document.GetFrame())
return nullptr;
+ ExecutionContext* context = document.GetExecutionContext();
Referrer referrer = SecurityPolicy::GenerateReferrer(
- document.GetReferrerPolicy(), url, document.OutgoingReferrer());
+ context->GetReferrerPolicy(), url, context->OutgoingReferrer());
mojom::blink::PrerenderAttributesPtr attributes =
mojom::blink::PrerenderAttributes::New();
@@ -61,12 +62,12 @@ PrerenderHandle* PrerenderHandle::Create(Document& document,
attributes->rel_types = prerender_rel_types;
attributes->referrer = mojom::blink::Referrer::New(
KURL(NullURL(), referrer.referrer), referrer.referrer_policy);
- attributes->initiator_origin = document.GetSecurityOrigin();
+ attributes->initiator_origin = context->GetSecurityOrigin();
attributes->view_size =
gfx::Size(document.GetFrame()->GetMainFrameViewportSize());
mojo::Remote<mojom::blink::PrerenderProcessor> prerender_processor;
- document.GetFrame()->Client()->GetBrowserInterfaceBroker().GetInterface(
+ context->GetBrowserInterfaceBroker().GetInterface(
prerender_processor.BindNewPipeAndPassReceiver());
mojo::PendingRemote<mojom::blink::PrerenderHandleClient>
@@ -74,33 +75,34 @@ PrerenderHandle* PrerenderHandle::Create(Document& document,
auto receiver = prerender_handle_client.InitWithNewPipeAndPassReceiver();
HeapMojoRemote<mojom::blink::PrerenderHandle,
- HeapMojoWrapperMode::kWithoutContextObserver>
- remote_handle(document.GetExecutionContext());
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
+ remote_handle(context);
prerender_processor->AddPrerender(
std::move(attributes), std::move(prerender_handle_client),
remote_handle.BindNewPipeAndPassReceiver(
- document.GetTaskRunner(TaskType::kMiscPlatformAPI)));
+ context->GetTaskRunner(TaskType::kMiscPlatformAPI)));
- return MakeGarbageCollected<PrerenderHandle>(PassKey(), document, client, url,
+ return MakeGarbageCollected<PrerenderHandle>(PassKey(), context, client, url,
std::move(remote_handle),
std::move(receiver));
}
PrerenderHandle::PrerenderHandle(
PassKey pass_key,
- Document& document,
+ ExecutionContext* context,
PrerenderClient* client,
const KURL& url,
HeapMojoRemote<mojom::blink::PrerenderHandle,
- HeapMojoWrapperMode::kWithoutContextObserver> remote_handle,
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
+ remote_handle,
mojo::PendingReceiver<mojom::blink::PrerenderHandleClient> receiver)
- : ExecutionContextLifecycleObserver(document.GetExecutionContext()),
+ : ExecutionContextLifecycleObserver(context),
url_(url),
client_(client),
remote_handle_(std::move(remote_handle)),
- receiver_(this, document.GetExecutionContext()) {
+ receiver_(this, context) {
receiver_.Bind(std::move(receiver),
- document.GetTaskRunner(TaskType::kMiscPlatformAPI));
+ context->GetTaskRunner(TaskType::kMiscPlatformAPI));
}
PrerenderHandle::~PrerenderHandle() = default;
@@ -153,7 +155,7 @@ void PrerenderHandle::OnPrerenderStop() {
client_->DidStopPrerender();
}
-void PrerenderHandle::Trace(Visitor* visitor) {
+void PrerenderHandle::Trace(Visitor* visitor) const {
visitor->Trace(client_);
visitor->Trace(remote_handle_);
visitor->Trace(receiver_);
diff --git a/chromium/third_party/blink/renderer/core/loader/private/prerender_handle.h b/chromium/third_party/blink/renderer/core/loader/private/prerender_handle.h
index 0935af059b6..96b7a72c773 100644
--- a/chromium/third_party/blink/renderer/core/loader/private/prerender_handle.h
+++ b/chromium/third_party/blink/renderer/core/loader/private/prerender_handle.h
@@ -44,6 +44,7 @@
namespace blink {
+class ExecutionContext;
class Document;
class PrerenderClient;
@@ -60,13 +61,14 @@ class PrerenderHandle final : public GarbageCollected<PrerenderHandle>,
unsigned prerender_rel_types);
using PassKey = util::PassKey<PrerenderHandle>;
- PrerenderHandle(PassKey,
- Document&,
- PrerenderClient*,
- const KURL&,
- HeapMojoRemote<mojom::blink::PrerenderHandle,
- HeapMojoWrapperMode::kWithoutContextObserver>,
- mojo::PendingReceiver<mojom::blink::PrerenderHandleClient>);
+ PrerenderHandle(
+ PassKey,
+ ExecutionContext*,
+ PrerenderClient*,
+ const KURL&,
+ HeapMojoRemote<mojom::blink::PrerenderHandle,
+ HeapMojoWrapperMode::kForceWithoutContextObserver>,
+ mojo::PendingReceiver<mojom::blink::PrerenderHandleClient>);
~PrerenderHandle() override;
void Dispose();
@@ -82,7 +84,7 @@ class PrerenderHandle final : public GarbageCollected<PrerenderHandle>,
void OnPrerenderDomContentLoaded() override;
void OnPrerenderStop() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void Detach();
@@ -90,11 +92,11 @@ class PrerenderHandle final : public GarbageCollected<PrerenderHandle>,
KURL url_;
WeakMember<PrerenderClient> client_;
HeapMojoRemote<mojom::blink::PrerenderHandle,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
remote_handle_;
HeapMojoReceiver<mojom::blink::PrerenderHandleClient,
PrerenderHandle,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
receiver_;
DISALLOW_COPY_AND_ASSIGN(PrerenderHandle);
diff --git a/chromium/third_party/blink/renderer/core/loader/progress_tracker.cc b/chromium/third_party/blink/renderer/core/loader/progress_tracker.cc
index 13bf10794fe..63402b91a22 100644
--- a/chromium/third_party/blink/renderer/core/loader/progress_tracker.cc
+++ b/chromium/third_party/blink/renderer/core/loader/progress_tracker.cc
@@ -67,7 +67,7 @@ ProgressTracker::ProgressTracker(LocalFrame* frame)
ProgressTracker::~ProgressTracker() = default;
-void ProgressTracker::Trace(Visitor* visitor) {
+void ProgressTracker::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/progress_tracker.h b/chromium/third_party/blink/renderer/core/loader/progress_tracker.h
index 09d9b696b02..af80d1c07a9 100644
--- a/chromium/third_party/blink/renderer/core/loader/progress_tracker.h
+++ b/chromium/third_party/blink/renderer/core/loader/progress_tracker.h
@@ -52,7 +52,7 @@ class CORE_EXPORT ProgressTracker final
public:
explicit ProgressTracker(LocalFrame*);
~ProgressTracker();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void Dispose();
double EstimatedProgress() const;
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc b/chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc
index 9a89f9b5747..238f528f9dc 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc
+++ b/chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc
@@ -88,7 +88,7 @@ void CSSStyleSheetResource::SetParsedStyleSheetCache(
UpdateDecodedSize();
}
-void CSSStyleSheetResource::Trace(Visitor* visitor) {
+void CSSStyleSheetResource::Trace(Visitor* visitor) const {
visitor->Trace(parsed_style_sheet_cache_);
TextResource::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h b/chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h
index c863f63f94b..d72509a4df8 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h
+++ b/chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h
@@ -55,7 +55,7 @@ class CORE_EXPORT CSSStyleSheetResource final : public TextResource {
const TextResourceDecoderOptions&);
~CSSStyleSheetResource() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void OnMemoryDump(WebMemoryDumpLevelOfDetail,
WebProcessMemoryDump*) const override;
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource_test.cc b/chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource_test.cc
index cc2a29ff02a..f558a840c2f 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource_test.cc
@@ -151,7 +151,8 @@ TEST_F(CSSStyleSheetResourceTest,
contents->CheckLoaded();
EXPECT_TRUE(contents->IsCacheableForResource());
- contents->EnsureRuleSet(MediaQueryEvaluator(), kRuleHasNoSpecialState);
+ contents->EnsureRuleSet(MediaQueryEvaluator(GetDocument().GetFrame()),
+ kRuleHasNoSpecialState);
EXPECT_TRUE(contents->HasRuleSet());
css_resource->SaveParsedStyleSheet(contents);
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/font_resource.cc b/chromium/third_party/blink/renderer/core/loader/resource/font_resource.cc
index 53320e7669b..5f4a0f2d1cf 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/font_resource.cc
+++ b/chromium/third_party/blink/renderer/core/loader/resource/font_resource.cc
@@ -117,10 +117,16 @@ scoped_refptr<FontCustomPlatformData> FontResource::GetCustomFontData() {
if (Data())
font_data_ = FontCustomPlatformData::Create(Data(), ots_parsing_message_);
- if (!font_data_)
+ if (!font_data_) {
SetStatus(ResourceStatus::kDecodeError);
- else
+ } else {
+ // Call observers once and remove them.
+ HeapHashSet<WeakMember<FontResourceClearDataObserver>> observers;
+ observers.swap(clear_data_observers_);
+ for (const auto& observer : observers)
+ observer->FontResourceDataWillBeCleared();
ClearData();
+ }
}
return font_data_;
}
@@ -206,4 +212,14 @@ void FontResource::OnMemoryDump(WebMemoryDumpLevelOfDetail level,
memory_dump->AddSuballocation(dump->Guid(), "malloc");
}
+void FontResource::AddClearDataObserver(
+ FontResourceClearDataObserver* observer) const {
+ clear_data_observers_.insert(observer);
+}
+
+void FontResource::Trace(Visitor* visitor) const {
+ visitor->Trace(clear_data_observers_);
+ Resource::Trace(visitor);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/font_resource.h b/chromium/third_party/blink/renderer/core/loader/resource/font_resource.h
index 713dc38d4c0..b2f096bba34 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/font_resource.h
+++ b/chromium/third_party/blink/renderer/core/loader/resource/font_resource.h
@@ -42,6 +42,16 @@ class ResourceFetcher;
class FontCustomPlatformData;
class FontResourceClient;
+// An observer that will be notified when original data is cleared
+// from the resource. Inspector may collect this data and store it for
+// future inspection.
+class CORE_EXPORT FontResourceClearDataObserver : public GarbageCollectedMixin {
+ public:
+ // Called before the original data is cleared. Only called once,
+ // and observer is automatically removed.
+ virtual void FontResourceDataWillBeCleared() = 0;
+};
+
class CORE_EXPORT FontResource final : public Resource {
public:
static FontResource* Fetch(FetchParameters&,
@@ -50,6 +60,7 @@ class CORE_EXPORT FontResource final : public Resource {
FontResource(const ResourceRequest&, const ResourceLoaderOptions&);
~FontResource() override;
+ void Trace(Visitor*) const override;
void DidAddClient(ResourceClient*) override;
@@ -71,6 +82,8 @@ class CORE_EXPORT FontResource final : public Resource {
void OnMemoryDump(WebMemoryDumpLevelOfDetail,
WebProcessMemoryDump*) const override;
+ void AddClearDataObserver(FontResourceClearDataObserver* observer) const;
+
private:
class FontResourceFactory : public NonTextResourceFactory {
public:
@@ -103,6 +116,8 @@ class CORE_EXPORT FontResource final : public Resource {
bool cors_failed_;
TaskHandle font_load_short_limit_;
TaskHandle font_load_long_limit_;
+ mutable HeapHashSet<WeakMember<FontResourceClearDataObserver>>
+ clear_data_observers_;
friend class MemoryCache;
FRIEND_TEST_ALL_PREFIXES(CacheAwareFontResourceTest, CacheAwareFontLoading);
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/image_resource.cc b/chromium/third_party/blink/renderer/core/loader/resource/image_resource.cc
index 96def6caf44..878dcb69bbe 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/image_resource.cc
+++ b/chromium/third_party/blink/renderer/core/loader/resource/image_resource.cc
@@ -78,7 +78,7 @@ class ImageResource::ImageResourceInfoImpl final
: resource_(resource) {
DCHECK(resource_);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(resource_);
ImageResourceInfo::Trace(visitor);
}
@@ -230,7 +230,7 @@ void ImageResource::OnMemoryDump(WebMemoryDumpLevelOfDetail level_of_detail,
dump->AddScalar("size", "bytes", content_->GetImage()->Data()->size());
}
-void ImageResource::Trace(Visitor* visitor) {
+void ImageResource::Trace(Visitor* visitor) const {
visitor->Trace(multipart_parser_);
visitor->Trace(content_);
Resource::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/image_resource.h b/chromium/third_party/blink/renderer/core/loader/resource/image_resource.h
index 557800e494d..ca847b311a3 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/image_resource.h
+++ b/chromium/third_party/blink/renderer/core/loader/resource/image_resource.h
@@ -102,7 +102,7 @@ class CORE_EXPORT ImageResource final
void OnMemoryDump(WebMemoryDumpLevelOfDetail,
WebProcessMemoryDump*) const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
enum class MultipartParsingState : uint8_t {
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/image_resource_content.cc b/chromium/third_party/blink/renderer/core/loader/resource/image_resource_content.cc
index 3f5e21f8f29..efa24670f1a 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/image_resource_content.cc
+++ b/chromium/third_party/blink/renderer/core/loader/resource/image_resource_content.cc
@@ -36,7 +36,9 @@ class NullImageResourceInfo final
public:
NullImageResourceInfo() = default;
- void Trace(Visitor* visitor) override { ImageResourceInfo::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ ImageResourceInfo::Trace(visitor);
+ }
private:
const KURL& Url() const override { return url_; }
@@ -103,7 +105,7 @@ void ImageResourceContent::SetImageResourceInfo(ImageResourceInfo* info) {
info_ = info;
}
-void ImageResourceContent::Trace(Visitor* visitor) {
+void ImageResourceContent::Trace(Visitor* visitor) const {
visitor->Trace(info_);
ImageObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/image_resource_content.h b/chromium/third_party/blink/renderer/core/loader/resource/image_resource_content.h
index 72db3c60520..f041f4441e6 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/image_resource_content.h
+++ b/chromium/third_party/blink/renderer/core/loader/resource/image_resource_content.h
@@ -39,8 +39,6 @@ class ResourceResponse;
// https://docs.google.com/document/d/1O-fB83mrE0B_V8gzXNqHgmRLCvstTB4MMi3RnVLr8bE/edit?usp=sharing
// TODO(hiroshige): Make ImageResourceContent ResourceClient and remove the
// word 'observer' from ImageResource.
-// TODO(hiroshige): Rename local variables of type ImageResourceContent to
-// e.g. |imageContent|. Currently they have Resource-like names.
class CORE_EXPORT ImageResourceContent final
: public GarbageCollected<ImageResourceContent>,
public ImageObserver {
@@ -84,7 +82,7 @@ class CORE_EXPORT ImageResourceContent final
return size_available_ != Image::kSizeUnavailable;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Content status and deriving predicates.
// https://docs.google.com/document/d/1O-fB83mrE0B_V8gzXNqHgmRLCvstTB4MMi3RnVLr8bE/edit#heading=h.6cyqmir0f30h
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/image_resource_info.h b/chromium/third_party/blink/renderer/core/loader/resource/image_resource_info.h
index b3a105a6b7c..dd3b101afc4 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/image_resource_info.h
+++ b/chromium/third_party/blink/renderer/core/loader/resource/image_resource_info.h
@@ -58,7 +58,7 @@ class CORE_EXPORT ImageResourceInfo : public GarbageCollectedMixin {
virtual bool IsAdResource() const = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/image_resource_test.cc b/chromium/third_party/blink/renderer/core/loader/resource/image_resource_test.cc
index a960dd7d1d6..814e5fd4bfe 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/image_resource_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/resource/image_resource_test.cc
@@ -379,7 +379,7 @@ class MockFinishObserver : public ResourceFinishObserver {
MOCK_METHOD0(NotifyFinished, void());
String DebugName() const override { return "MockFinishObserver"; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
blink::ResourceFinishObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/link_fetch_resource.cc b/chromium/third_party/blink/renderer/core/loader/resource/link_fetch_resource.cc
deleted file mode 100644
index 8baa208a419..00000000000
--- a/chromium/third_party/blink/renderer/core/loader/resource/link_fetch_resource.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/loader/resource/link_fetch_resource.h"
-
-#include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink.h"
-#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
-#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
-
-namespace blink {
-
-Resource* LinkFetchResource::Fetch(ResourceType type,
- FetchParameters& params,
- ResourceFetcher* fetcher) {
- DCHECK_EQ(type, ResourceType::kLinkPrefetch);
- return fetcher->RequestResource(params, LinkResourceFactory(type), nullptr);
-}
-
-LinkFetchResource::LinkFetchResource(const ResourceRequest& request,
- ResourceType type,
- const ResourceLoaderOptions& options)
- : Resource(request, type, options) {}
-
-LinkFetchResource::~LinkFetchResource() = default;
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/link_fetch_resource.h b/chromium/third_party/blink/renderer/core/loader/resource/link_fetch_resource.h
deleted file mode 100644
index 0b190ff4b6b..00000000000
--- a/chromium/third_party/blink/renderer/core/loader/resource/link_fetch_resource.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_LINK_FETCH_RESOURCE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_LINK_FETCH_RESOURCE_H_
-
-#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
-#include "third_party/blink/renderer/platform/loader/fetch/resource_client.h"
-
-namespace blink {
-
-class FetchParameters;
-class ResourceFetcher;
-
-class LinkFetchResource final : public Resource {
- public:
- static Resource* Fetch(ResourceType, FetchParameters&, ResourceFetcher*);
-
- LinkFetchResource(const ResourceRequest&,
- ResourceType,
- const ResourceLoaderOptions&);
- ~LinkFetchResource() override;
-
- private:
- class LinkResourceFactory : public NonTextResourceFactory {
- public:
- explicit LinkResourceFactory(ResourceType type)
- : NonTextResourceFactory(type) {}
-
- Resource* Create(const ResourceRequest& request,
- const ResourceLoaderOptions& options) const override {
- return MakeGarbageCollected<LinkFetchResource>(request, GetType(),
- options);
- }
- };
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_LINK_FETCH_RESOURCE_H_
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/link_prefetch_resource.cc b/chromium/third_party/blink/renderer/core/loader/resource/link_prefetch_resource.cc
new file mode 100644
index 00000000000..6f03e210cbd
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/loader/resource/link_prefetch_resource.cc
@@ -0,0 +1,33 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/loader/resource/link_prefetch_resource.h"
+
+#include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink.h"
+#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
+
+namespace blink {
+
+Resource* LinkPrefetchResource::Fetch(FetchParameters& params,
+ ResourceFetcher* fetcher) {
+ return fetcher->RequestResource(params, Factory(), nullptr);
+}
+
+LinkPrefetchResource::LinkPrefetchResource(const ResourceRequest& request,
+ const ResourceLoaderOptions& options)
+ : Resource(request, ResourceType::kLinkPrefetch, options) {}
+
+LinkPrefetchResource::~LinkPrefetchResource() = default;
+
+LinkPrefetchResource::Factory::Factory()
+ : NonTextResourceFactory(ResourceType::kLinkPrefetch) {}
+
+Resource* LinkPrefetchResource::Factory::Create(
+ const ResourceRequest& request,
+ const ResourceLoaderOptions& options) const {
+ return MakeGarbageCollected<LinkPrefetchResource>(request, options);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/link_prefetch_resource.h b/chromium/third_party/blink/renderer/core/loader/resource/link_prefetch_resource.h
new file mode 100644
index 00000000000..04ca1b72645
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/loader/resource/link_prefetch_resource.h
@@ -0,0 +1,35 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_LINK_PREFETCH_RESOURCE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_LINK_PREFETCH_RESOURCE_H_
+
+#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
+
+namespace blink {
+
+class FetchParameters;
+class ResourceFetcher;
+
+// This is the implementation of Resource for <link rel='prefetch'>.
+class LinkPrefetchResource final : public Resource {
+ public:
+ static Resource* Fetch(FetchParameters&, ResourceFetcher*);
+
+ LinkPrefetchResource(const ResourceRequest&, const ResourceLoaderOptions&);
+ ~LinkPrefetchResource() override;
+
+ private:
+ class Factory final : public NonTextResourceFactory {
+ public:
+ Factory();
+
+ Resource* Create(const ResourceRequest& request,
+ const ResourceLoaderOptions& options) const override;
+ };
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_LINK_PREFETCH_RESOURCE_H_
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.cc b/chromium/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.cc
index 385afece9ba..b4cc463f97e 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.cc
+++ b/chromium/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.cc
@@ -184,7 +184,7 @@ wtf_size_t MultipartImageResourceParser::FindBoundary(const Vector<char>& data,
return boundary_position;
}
-void MultipartImageResourceParser::Trace(Visitor* visitor) {
+void MultipartImageResourceParser::Trace(Visitor* visitor) const {
visitor->Trace(client_);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.h b/chromium/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.h
index b41f34b18c3..94ef1df10dd 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.h
+++ b/chromium/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.h
@@ -58,7 +58,7 @@ class CORE_EXPORT MultipartImageResourceParser final
virtual ~Client() = default;
virtual void OnePartInMultipartReceived(const ResourceResponse&) = 0;
virtual void MultipartDataReceived(const char* bytes, size_t) = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
MultipartImageResourceParser(const ResourceResponse&,
@@ -68,7 +68,7 @@ class CORE_EXPORT MultipartImageResourceParser final
void Finish();
void Cancel() { is_cancelled_ = true; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
static wtf_size_t SkippableLengthForTest(const Vector<char>& data,
wtf_size_t size) {
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/script_resource.cc b/chromium/third_party/blink/renderer/core/loader/resource/script_resource.cc
index 4b30c7c7ede..ac30a12e584 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/script_resource.cc
+++ b/chromium/third_party/blink/renderer/core/loader/resource/script_resource.cc
@@ -80,29 +80,8 @@ ScriptResource* ScriptResource::Fetch(FetchParameters& params,
StreamingAllowed streaming_allowed) {
DCHECK(IsRequestContextSupported(
params.GetResourceRequest().GetRequestContext()));
- ScriptResource* resource = ToScriptResource(
- fetcher->RequestResource(params, ScriptResourceFactory(), client));
-
- if (streaming_allowed == kAllowStreaming) {
- // Start streaming the script as soon as we get it.
- resource->StartStreaming(fetcher->GetTaskRunner());
- } else {
- // Advance the |streaming_state_| to kStreamingNotAllowed by calling
- // SetClientIsWaitingForFinished unless it is explicitly allowed.'
- //
- // Do this in a task rather than directly to make sure that we don't call
- // the finished callbacks of other clients synchronously.
-
- // TODO(leszeks): Previous behaviour, without script streaming, was to
- // synchronously notify the given client, with the assumption that other
- // clients were already finished. If this behaviour becomes necessary, we
- // would have to either check that streaming wasn't started (if that would
- // be a logic error), or cancel any existing streaming.
- fetcher->GetTaskRunner()->PostTask(
- FROM_HERE, WTF::Bind(&ScriptResource::SetClientIsWaitingForFinished,
- WrapWeakPersistent(resource)));
- }
-
+ ScriptResource* resource = ToScriptResource(fetcher->RequestResource(
+ params, ScriptResourceFactory(streaming_allowed), client));
return resource;
}
@@ -114,32 +93,36 @@ ScriptResource* ScriptResource::CreateForTest(
ResourceLoaderOptions options;
TextResourceDecoderOptions decoder_options(
TextResourceDecoderOptions::kPlainTextContent, encoding);
- return MakeGarbageCollected<ScriptResource>(request, options,
- decoder_options);
+ return MakeGarbageCollected<ScriptResource>(request, options, decoder_options,
+ kNoStreaming);
}
ScriptResource::ScriptResource(
const ResourceRequest& resource_request,
const ResourceLoaderOptions& options,
- const TextResourceDecoderOptions& decoder_options)
+ const TextResourceDecoderOptions& decoder_options,
+ StreamingAllowed streaming_allowed)
: TextResource(resource_request,
ResourceType::kScript,
options,
- decoder_options) {}
-
-ScriptResource::~ScriptResource() = default;
+ decoder_options) {
+ static bool script_streaming_enabled =
+ base::FeatureList::IsEnabled(features::kScriptStreaming);
-void ScriptResource::Prefinalize() {
- // Reset and cancel the watcher. This has to be called in the prefinalizer,
- // rather than relying on the destructor, as accesses by the watcher of the
- // script resource between prefinalization and destruction are invalid. See
- // https://crbug.com/905975#c34 for more details.
- watcher_.reset();
+ if (!script_streaming_enabled) {
+ DisableStreaming(
+ ScriptStreamer::NotStreamingReason::kDisabledByFeatureList);
+ } else if (streaming_allowed == kNoStreaming) {
+ DisableStreaming(ScriptStreamer::NotStreamingReason::kStreamingDisabled);
+ } else if (!Url().ProtocolIsInHTTPFamily()) {
+ DisableStreaming(ScriptStreamer::NotStreamingReason::kNotHTTP);
+ }
}
-void ScriptResource::Trace(Visitor* visitor) {
+ScriptResource::~ScriptResource() = default;
+
+void ScriptResource::Trace(Visitor* visitor) const {
visitor->Trace(streamer_);
- visitor->Trace(response_body_loader_client_);
TextResource::Trace(visitor);
}
@@ -151,7 +134,7 @@ void ScriptResource::OnMemoryDump(WebMemoryDumpLevelOfDetail level_of_detail,
}
const ParkableString& ScriptResource::SourceText() {
- CHECK(IsFinishedInternal());
+ CHECK(IsLoaded());
if (source_text_.IsNull() && Data()) {
String source_text = DecodedText();
@@ -180,19 +163,10 @@ String ScriptResource::TextForInspector() const {
}
// 2. We have finished loading with no data received, so no streaming ever
- // happened or streaming was suppressed. Note that the finished
- // notification may not have come through yet because of task posting, so
- // NotifyFinished may not have been called yet. Regardless, there was no
- // data, so the text should be empty.
- //
- // TODO(crbug/909858) Currently this CHECK can occasionally fail, but this
- // doesn't seem to cause real issues immediately. For now, we suppress the
- // crashes on release builds by making this a DCHECK and continue baking the
- // script streamer control (crbug/865098) on beta, while investigating the
- // failure reason on canary.
- DCHECK(!IsFinishedInternal() || !streamer_ ||
+ // happened or streaming was suppressed.
+ DCHECK(!streamer_ ||
streamer_->StreamingSuppressedReason() ==
- ScriptStreamer::kScriptTooSmall);
+ ScriptStreamer::NotStreamingReason::kScriptTooSmall);
return "";
}
@@ -225,22 +199,20 @@ void ScriptResource::DestroyDecodedDataForFailedRevalidation() {
source_text_ = ParkableString();
// Make sure there's no streaming.
DCHECK(!streamer_);
- DCHECK_EQ(streaming_state_, StreamingState::kStreamingNotAllowed);
+ DCHECK_EQ(streaming_state_, StreamingState::kStreamingDisabled);
SetDecodedSize(0);
}
void ScriptResource::SetRevalidatingRequest(
const ResourceRequestHead& request) {
- CHECK_EQ(streaming_state_, StreamingState::kFinishedNotificationSent);
+ CHECK(IsLoaded());
if (streamer_) {
- CHECK(streamer_->IsStreamingFinished());
+ CHECK(streamer_->IsFinished());
streamer_ = nullptr;
}
// Revalidation requests don't actually load the current Resource, so disable
// streaming.
- not_streaming_reason_ = ScriptStreamer::kRevalidate;
- streaming_state_ = StreamingState::kStreamingNotAllowed;
- CheckStreamingState();
+ DisableStreaming(ScriptStreamer::NotStreamingReason::kRevalidate);
TextResource::SetRevalidatingRequest(request);
}
@@ -253,7 +225,7 @@ bool ScriptResource::CanUseCacheValidator() const {
return false;
// Do not revalidate until streaming is complete.
- if (!IsFinishedInternal())
+ if (!IsLoaded())
return false;
return Resource::CanUseCacheValidator();
@@ -262,264 +234,103 @@ bool ScriptResource::CanUseCacheValidator() const {
void ScriptResource::ResponseBodyReceived(
ResponseBodyLoaderDrainableInterface& body_loader,
scoped_refptr<base::SingleThreadTaskRunner> loader_task_runner) {
- ResponseBodyLoaderClient* response_body_loader_client;
- CHECK(!data_pipe_);
- data_pipe_ = body_loader.DrainAsDataPipe(&response_body_loader_client);
- if (!data_pipe_)
+ if (streaming_state_ == StreamingState::kStreamingDisabled)
return;
- response_body_loader_client_ = response_body_loader_client;
- watcher_ = std::make_unique<mojo::SimpleWatcher>(
- FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, loader_task_runner);
+ CHECK_EQ(streaming_state_, StreamingState::kWaitingForDataPipe);
- watcher_->Watch(data_pipe_.get(), MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
- WTF::BindRepeating(&ScriptResource::OnDataPipeReadable,
- WrapWeakPersistent(this)));
- CHECK(data_pipe_);
+ // Checked in the constructor.
+ CHECK(Url().ProtocolIsInHTTPFamily());
+ CHECK(base::FeatureList::IsEnabled(features::kScriptStreaming));
- MojoResult ready_result;
- mojo::HandleSignalsState ready_state;
- MojoResult rv = watcher_->Arm(&ready_result, &ready_state);
- if (rv == MOJO_RESULT_OK)
+ ResponseBodyLoaderClient* response_body_loader_client;
+ mojo::ScopedDataPipeConsumerHandle data_pipe =
+ body_loader.DrainAsDataPipe(&response_body_loader_client);
+ if (!data_pipe) {
+ DisableStreaming(ScriptStreamer::NotStreamingReason::kNoDataPipe);
return;
-
- DCHECK_EQ(MOJO_RESULT_FAILED_PRECONDITION, rv);
- OnDataPipeReadable(ready_result, ready_state);
-}
-
-void ScriptResource::OnDataPipeReadable(MojoResult result,
- const mojo::HandleSignalsState& state) {
- switch (result) {
- case MOJO_RESULT_OK:
- // All good, so read the data that we were notified that we received.
- break;
-
- case MOJO_RESULT_CANCELLED:
- // The consumer handle got closed, which means this script resource is
- // done loading, and did so without streaming (otherwise the watcher
- // wouldn't have been armed, and the handle ownership would have passed to
- // the streamer).
- CHECK(streaming_state_ == StreamingState::kFinishedNotificationSent ||
- streaming_state_ == StreamingState::kStreamingNotAllowed);
- return;
-
- case MOJO_RESULT_FAILED_PRECONDITION:
- // This means the producer finished and streamed to completion.
- watcher_.reset();
- response_body_loader_client_->DidFinishLoadingBody();
- response_body_loader_client_ = nullptr;
- return;
-
- case MOJO_RESULT_SHOULD_WAIT:
- NOTREACHED();
- return;
-
- default:
- // Some other error occurred.
- watcher_.reset();
- response_body_loader_client_->DidFailLoadingBody();
- response_body_loader_client_ = nullptr;
- return;
}
- CHECK(state.readable());
- CHECK(data_pipe_);
-
- const void* data;
- uint32_t data_size;
- MojoReadDataFlags flags_to_pass = MOJO_READ_DATA_FLAG_NONE;
- MojoResult begin_read_result =
- data_pipe_->BeginReadData(&data, &data_size, flags_to_pass);
- // There should be data, so this read should succeed.
- CHECK_EQ(begin_read_result, MOJO_RESULT_OK);
-
- response_body_loader_client_->DidReceiveData(
- base::make_span(reinterpret_cast<const char*>(data), data_size));
-
- MojoResult end_read_result = data_pipe_->EndReadData(data_size);
-
- CHECK_EQ(end_read_result, MOJO_RESULT_OK);
CheckStreamingState();
- if (streamer_) {
- DCHECK_EQ(streaming_state_, StreamingState::kStreaming);
- if (streamer_->TryStartStreaming(&data_pipe_,
- response_body_loader_client_.Get())) {
- CHECK(!data_pipe_);
- // This reset will also cancel the watcher.
- watcher_.reset();
- return;
- }
- }
+ CHECK(!ErrorOccurred());
- // TODO(leszeks): Depending on how small the chunks are, we may want to
- // loop until a certain number of bytes are synchronously read rather than
- // going back to the scheduler.
- watcher_->ArmOrNotify();
+ streamer_ = MakeGarbageCollected<ScriptStreamer>(
+ this, std::move(data_pipe), response_body_loader_client,
+ v8::ScriptCompiler::kNoCompileOptions, loader_task_runner);
+ CHECK_EQ(no_streamer_reason_, ScriptStreamer::NotStreamingReason::kInvalid);
+ AdvanceStreamingState(StreamingState::kStreaming);
}
void ScriptResource::NotifyFinished() {
DCHECK(IsLoaded());
switch (streaming_state_) {
- case StreamingState::kCanStartStreaming:
- // Do nothing, expect either a StartStreaming() call to transition us to
- // kStreaming, or an SetClientIsWaitingForFinished() call to transition us
- // into kStreamingNotAllowed. These will then transition again since
- // IsLoaded will be true.
+ case StreamingState::kWaitingForDataPipe:
+ // We never received a response body, otherwise the state would be
+ // one of kStreaming or kNoStreaming. So, either there was an error, or
+ // there was no response body loader (thus no data pipe) at all. Either
+ // way, we want to disable streaming.
+ if (ErrorOccurred()) {
+ DisableStreaming(ScriptStreamer::NotStreamingReason::kErrorOccurred);
+ } else {
+ DisableStreaming(ScriptStreamer::NotStreamingReason::kNoDataPipe);
+ }
break;
+
case StreamingState::kStreaming:
- AdvanceStreamingState(StreamingState::kWaitingForStreamingToEnd);
DCHECK(streamer_);
- streamer_->NotifyFinished();
- // Don't call the base NotifyFinished until streaming finishes too (which
- // might happen immediately in the above ScriptStreamer::NotifyFinished
- // call)
- break;
- case StreamingState::kStreamingNotAllowed:
- watcher_.reset();
- data_pipe_.reset();
- response_body_loader_client_ = nullptr;
- AdvanceStreamingState(StreamingState::kFinishedNotificationSent);
- TextResource::NotifyFinished();
+ if (!streamer_->IsFinished()) {
+ // This notification didn't come from the streaming finishing, so it
+ // must be an external error (e.g. cancelling the resource).
+ CHECK(ErrorOccurred());
+ streamer_->Cancel();
+ streamer_.Release();
+ DisableStreaming(ScriptStreamer::NotStreamingReason::kErrorOccurred);
+ }
break;
- case StreamingState::kWaitingForStreamingToEnd:
- case StreamingState::kFinishedNotificationSent:
- // Not possible.
- CHECK(false);
+
+ case StreamingState::kStreamingDisabled:
+ // If streaming is already disabled, we can just continue as before.
break;
}
-}
-
-bool ScriptResource::IsFinishedInternal() const {
CheckStreamingState();
- return streaming_state_ == StreamingState::kFinishedNotificationSent;
-}
-
-void ScriptResource::StreamingFinished() {
- CHECK(streamer_);
- CHECK_EQ(streaming_state_, StreamingState::kWaitingForStreamingToEnd);
- CHECK(!data_pipe_ || streamer_->StreamingSuppressed());
- // We may still have a watcher if a) streaming never started (e.g. script too
- // small) and b) an external error triggered the finished notification.
- watcher_.reset();
- data_pipe_.reset();
- response_body_loader_client_ = nullptr;
- AdvanceStreamingState(StreamingState::kFinishedNotificationSent);
TextResource::NotifyFinished();
}
-void ScriptResource::StartStreaming(
- scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner) {
- CheckStreamingState();
-
- if (streamer_) {
- return;
- }
-
- if (streaming_state_ != StreamingState::kCanStartStreaming) {
- return;
- }
-
- // Don't bother streaming if there was an error, it won't work anyway.
- if (ErrorOccurred()) {
- return;
- }
-
- static const bool script_streaming_enabled =
- base::FeatureList::IsEnabled(features::kScriptStreaming);
- if (!script_streaming_enabled) {
- return;
- }
-
- CHECK(!IsCacheValidator());
-
- streamer_ =
- ScriptStreamer::Create(this, loading_task_runner, &not_streaming_reason_);
- if (streamer_) {
- AdvanceStreamingState(StreamingState::kStreaming);
-
- // If there is any data already, send it to the streamer.
- if (Data()) {
- // Note that we don't need to iterate through the segments of the data, as
- // the streamer will do that itself.
- CHECK_GT(Data()->size(), 0u);
- if (data_pipe_) {
- if (streamer_->TryStartStreaming(&data_pipe_,
- response_body_loader_client_.Get())) {
- CHECK(!data_pipe_);
- // This reset will also cancel the watcher.
- watcher_.reset();
- } else {
- CHECK(data_pipe_);
- }
- }
- }
- // If the we're is already loaded, notify the streamer about that too.
- if (IsLoaded()) {
- AdvanceStreamingState(StreamingState::kWaitingForStreamingToEnd);
-
- // Do this in a task rather than directly to make sure that we don't call
- // the finished callback in the same stack as starting streaming -- this
- // can cause issues with the client expecting to be not finished when
- // starting streaming (e.g. ClassicPendingScript::IsReady == false), but
- // ending up finished by the end of this method.
- loading_task_runner->PostTask(FROM_HERE,
- WTF::Bind(&ScriptStreamer::NotifyFinished,
- WrapPersistent(streamer_.Get())));
- }
- }
-
- CheckStreamingState();
- return;
-}
-
-void ScriptResource::SetClientIsWaitingForFinished() {
- // No-op if streaming already started or finished.
- CheckStreamingState();
- if (streaming_state_ != StreamingState::kCanStartStreaming)
- return;
-
- AdvanceStreamingState(StreamingState::kStreamingNotAllowed);
- not_streaming_reason_ = ScriptStreamer::kStreamingDisabled;
- // Trigger the finished notification if needed.
- if (IsLoaded()) {
- watcher_.reset();
- data_pipe_.reset();
- response_body_loader_client_ = nullptr;
- AdvanceStreamingState(StreamingState::kFinishedNotificationSent);
- TextResource::NotifyFinished();
- }
-}
-
ScriptStreamer* ScriptResource::TakeStreamer() {
- CHECK(IsFinishedInternal());
+ CHECK(IsLoaded());
if (!streamer_)
return nullptr;
ScriptStreamer* streamer = streamer_;
+ // A second use of the streamer is not possible, so we null it out and disable
+ // streaming for subsequent uses.
streamer_ = nullptr;
- not_streaming_reason_ = ScriptStreamer::kSecondScriptResourceUse;
+ DisableStreaming(
+ ScriptStreamer::NotStreamingReason::kSecondScriptResourceUse);
return streamer;
}
+void ScriptResource::DisableStreaming(
+ ScriptStreamer::NotStreamingReason no_streamer_reason) {
+ CHECK_NE(no_streamer_reason, ScriptStreamer::NotStreamingReason::kInvalid);
+ if (no_streamer_reason_ != ScriptStreamer::NotStreamingReason::kInvalid) {
+ // Streaming is already disabled, no need to disable it again.
+ return;
+ }
+ no_streamer_reason_ = no_streamer_reason;
+ AdvanceStreamingState(StreamingState::kStreamingDisabled);
+}
+
void ScriptResource::AdvanceStreamingState(StreamingState new_state) {
switch (streaming_state_) {
- case StreamingState::kCanStartStreaming:
+ case StreamingState::kWaitingForDataPipe:
CHECK(new_state == StreamingState::kStreaming ||
- new_state == StreamingState::kStreamingNotAllowed);
+ new_state == StreamingState::kStreamingDisabled);
break;
case StreamingState::kStreaming:
- CHECK(streamer_);
- CHECK_EQ(new_state, StreamingState::kWaitingForStreamingToEnd);
- break;
- case StreamingState::kWaitingForStreamingToEnd:
- CHECK(streamer_);
- CHECK_EQ(new_state, StreamingState::kFinishedNotificationSent);
- break;
- case StreamingState::kStreamingNotAllowed:
- CHECK_EQ(new_state, StreamingState::kFinishedNotificationSent);
+ CHECK_EQ(new_state, StreamingState::kStreamingDisabled);
break;
- case StreamingState::kFinishedNotificationSent:
+ case StreamingState::kStreamingDisabled:
CHECK(false);
break;
}
@@ -532,35 +343,21 @@ void ScriptResource::CheckStreamingState() const {
// TODO(leszeks): Eventually convert these CHECKs into DCHECKs once the logic
// is a bit more baked in.
switch (streaming_state_) {
- case StreamingState::kCanStartStreaming:
+ case StreamingState::kWaitingForDataPipe:
CHECK(!streamer_);
+ CHECK_EQ(no_streamer_reason_,
+ ScriptStreamer::NotStreamingReason::kInvalid);
break;
case StreamingState::kStreaming:
CHECK(streamer_);
- CHECK(!streamer_->IsFinished());
- // kStreaming can be entered both when loading (if streaming is started
- // before load completes) or when loaded (if streaming is started after
- // load completes). In the latter case, the state will almost immediately
- // advance to kWaitingForStreamingToEnd.
- CHECK(IsLoaded() || IsLoading());
+ CHECK(streamer_->CanStartStreaming() || streamer_->IsStreamingStarted() ||
+ streamer_->IsStreamingSuppressed());
+ CHECK(IsLoading() || streamer_->IsFinished());
break;
- case StreamingState::kWaitingForStreamingToEnd:
- CHECK(streamer_);
- CHECK(!streamer_->IsFinished());
- CHECK(IsLoaded());
- break;
- case StreamingState::kStreamingNotAllowed:
+ case StreamingState::kStreamingDisabled:
CHECK(!streamer_);
- // TODO(leszeks): We could CHECK(!IsLoaded()) if not for the immediate
- // kCanStartStreaming -> kStreamingNotAllowed -> kFinishedNotificationSent
- // transition in SetClientIsWaitingForFinished when IsLoaded.
- break;
- case StreamingState::kFinishedNotificationSent:
- CHECK(!streamer_ || streamer_->IsFinished());
- CHECK(!watcher_ || !watcher_->IsWatching());
- CHECK(!data_pipe_);
- CHECK(!response_body_loader_client_);
- CHECK(IsLoaded());
+ CHECK_NE(no_streamer_reason_,
+ ScriptStreamer::NotStreamingReason::kInvalid);
break;
}
}
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/script_resource.h b/chromium/third_party/blink/renderer/core/loader/resource/script_resource.h
index 791b32f9ac2..1c951a901e7 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/script_resource.h
+++ b/chromium/third_party/blink/renderer/core/loader/resource/script_resource.h
@@ -37,16 +37,11 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h"
-namespace mojo {
-class SimpleWatcher;
-}
-
namespace blink {
class FetchParameters;
class KURL;
class ResourceFetcher;
-class ResponseBodyLoaderClient;
class SingleCachedMetadataHandler;
// ScriptResource is a resource representing a JavaScript script. It is only
@@ -60,19 +55,9 @@ class SingleCachedMetadataHandler;
// See also:
// https://docs.google.com/document/d/143GOPl_XVgLPFfO-31b_MdBcnjklLEX2OIg_6eN6fQ4
class CORE_EXPORT ScriptResource final : public TextResource {
- USING_PRE_FINALIZER(ScriptResource, Prefinalize);
-
public:
- // For scripts fetched with kAllowStreaming, the ScriptResource expects users
- // to call StartStreaming to start streaming the loaded data, and
- // SetClientIsWaitingForFinished when they actually want the data to be
- // available for execute. Note that StartStreaming can fail, so the client of
- // an unfinished resource has to call SetClientIsWaitingForFinished to
- // guarantee that it receives a finished callback.
- //
- // Scripts fetched with kNoStreaming will (asynchronously) call
- // SetClientIsWaitingForFinished on the resource, so the user does not have to
- // call it again. This is effectively the "legacy" behaviour.
+ // The script resource will always try to start streaming if kAllowStreaming
+ // is passed in.
enum StreamingAllowed { kNoStreaming, kAllowStreaming };
static ScriptResource* Fetch(FetchParameters&,
@@ -86,48 +71,21 @@ class CORE_EXPORT ScriptResource final : public TextResource {
ScriptResource(const ResourceRequest&,
const ResourceLoaderOptions&,
- const TextResourceDecoderOptions&);
+ const TextResourceDecoderOptions&,
+ StreamingAllowed);
~ScriptResource() override;
void ResponseBodyReceived(
ResponseBodyLoaderDrainableInterface& body_loader,
scoped_refptr<base::SingleThreadTaskRunner> loader_task_runner) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void OnMemoryDump(WebMemoryDumpLevelOfDetail,
WebProcessMemoryDump*) const override;
void SetSerializedCachedMetadata(mojo_base::BigBuffer data) override;
- void StartStreaming(
- scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner);
-
- // State that a client of the script resource will no longer try to start
- // streaming, and is now waiting for the resource to call the client's finish
- // callback (regardless of whether the resource is finished loading or
- // finished streaming). Specifically, it causes the kCanStartStreaming to
- // kStreamingNotAllowed transition. Streaming cannot be started after this is
- // called.
- //
- // If the resource is already streaming, this will be a no-op, and the client
- // will still only get the finished notification when the streaming completes.
- //
- // This function should never be called synchronously (except by
- // NotifyFinished) as it can trigger all clients' finished callbacks, which in
- // turn can invoke JavaScript execution.
- //
- // TODO(leszeks): Eventually Fetch (with streaming allowed) will be the only
- // way of starting streaming, and SetClientIsWaitingForFinished will not be
- // part of the public interface.
- void SetClientIsWaitingForFinished();
-
- // Called (only) by ScriptStreamer when streaming completes.
- //
- // This function should never be called synchronously as it can trigger all
- // clients' finished callbacks, which in turn can invoke JavaScript execution.
- void StreamingFinished();
-
const ParkableString& SourceText();
// Get the resource's current text. This can return partial data, so should
@@ -141,7 +99,7 @@ class CORE_EXPORT ScriptResource final : public TextResource {
ScriptStreamer* TakeStreamer();
ScriptStreamer::NotStreamingReason NoStreamerReason() const {
- return not_streaming_reason_;
+ return no_streamer_reason_;
}
// Used in DCHECKs
@@ -160,44 +118,53 @@ class CORE_EXPORT ScriptResource final : public TextResource {
// ScriptResources are considered finished when either:
// 1. Loading + streaming completes, or
- // 2. Loading completes + streaming was never started + someone called
- // "SetClientIsWaitingForFinished" to block streaming from ever starting.
+ // 2. Loading completes + streaming is disabled.
void NotifyFinished() override;
- bool IsFinishedInternal() const override;
private:
// Valid state transitions:
//
- // kCanStartStreaming -> kStreaming -> kWaitingForStreamingToEnd
- // -> kFinishedNotificationSent
- // kCanStartStreaming -> kStreamingNotAllowed -> kFinishedNotificationSent
+ // kWaitingForDataPipe DisableStreaming()
+ // |---------------------------.
+ // | |
+ // v v
+ // kStreaming -----------------> kStreamingDisabled
+ //
enum class StreamingState {
- kCanStartStreaming, // Streaming can be started.
- kStreamingNotAllowed, // Streaming can no longer be started.
- kStreaming, // Both loading the resource and streaming.
- kWaitingForStreamingToEnd, // Resource loaded but streaming not complete.
- kFinishedNotificationSent // Everything complete and finish sent.
+ // Streaming is allowed on this resource, but we're waiting to receive a
+ // data pipe.
+ kWaitingForDataPipe,
+ // The script streamer is active, and has the data pipe.
+ kStreaming,
+
+ // Streaming was disabled, either manually or because we got a body with
+ // no data-pipe.
+ kStreamingDisabled,
};
class ScriptResourceFactory : public ResourceFactory {
public:
- ScriptResourceFactory()
+ explicit ScriptResourceFactory(StreamingAllowed streaming_allowed)
: ResourceFactory(ResourceType::kScript,
- TextResourceDecoderOptions::kPlainTextContent) {}
+ TextResourceDecoderOptions::kPlainTextContent),
+ streaming_allowed_(streaming_allowed) {}
Resource* Create(
const ResourceRequest& request,
const ResourceLoaderOptions& options,
const TextResourceDecoderOptions& decoder_options) const override {
- return MakeGarbageCollected<ScriptResource>(request, options,
- decoder_options);
+ return MakeGarbageCollected<ScriptResource>(
+ request, options, decoder_options, streaming_allowed_);
}
- };
- void Prefinalize();
+ private:
+ StreamingAllowed streaming_allowed_;
+ };
bool CanUseCacheValidator() const override;
+ void DisableStreaming(ScriptStreamer::NotStreamingReason no_streamer_reason);
+
void AdvanceStreamingState(StreamingState new_state);
// Check that invariants for the state hold.
@@ -208,14 +175,10 @@ class CORE_EXPORT ScriptResource final : public TextResource {
ParkableString source_text_;
- mojo::ScopedDataPipeConsumerHandle data_pipe_;
- std::unique_ptr<mojo::SimpleWatcher> watcher_;
- Member<ResponseBodyLoaderClient> response_body_loader_client_;
-
Member<ScriptStreamer> streamer_;
- ScriptStreamer::NotStreamingReason not_streaming_reason_ =
- ScriptStreamer::kDidntTryToStartStreaming;
- StreamingState streaming_state_ = StreamingState::kCanStartStreaming;
+ ScriptStreamer::NotStreamingReason no_streamer_reason_ =
+ ScriptStreamer::NotStreamingReason::kInvalid;
+ StreamingState streaming_state_ = StreamingState::kWaitingForDataPipe;
};
DEFINE_RESOURCE_TYPE_CASTS(Script);
diff --git a/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.cc b/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.cc
index a6cf0175f6a..0e077ae9341 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.cc
+++ b/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.cc
@@ -153,7 +153,7 @@ void ResourceLoadObserverForFrame::DidReceiveResponse(
CountUsage(WebFeature::kLinkRelPrefetchForSignedExchanges);
if (RuntimeEnabledFeatures::SignedExchangeSubresourcePrefetchEnabled(
- document_) &&
+ document_->GetExecutionContext()) &&
resource->LastResourceResponse()) {
// See if the outer response (which must be the last response in
// the redirect chain) had provided alternate links for the prefetch.
@@ -250,7 +250,9 @@ void ResourceLoadObserverForFrame::DidFailLoading(
LocalFrame* frame = document_->GetFrame();
DCHECK(frame);
frame->Loader().Progress().CompleteProgress(identifier);
- probe::DidFailLoading(GetProbe(), identifier, document_loader_, error);
+
+ probe::DidFailLoading(GetProbe(), identifier, document_loader_, error,
+ frame->GetDevToolsFrameToken());
// Notification to FrameConsole should come AFTER InspectorInstrumentation
// call, DevTools front-end relies on this.
@@ -268,7 +270,7 @@ void ResourceLoadObserverForFrame::DidFailLoading(
document_->CheckCompleted();
}
-void ResourceLoadObserverForFrame::Trace(Visitor* visitor) {
+void ResourceLoadObserverForFrame::Trace(Visitor* visitor) const {
visitor->Trace(document_loader_);
visitor->Trace(document_);
visitor->Trace(fetcher_properties_);
diff --git a/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.h b/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.h
index 33241651752..1cc328b811c 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.h
+++ b/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.h
@@ -58,7 +58,7 @@ class CORE_EXPORT ResourceLoadObserverForFrame final
const ResourceError&,
int64_t encoded_data_length,
IsInternalRequest) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
CoreProbeSink* GetProbe();
diff --git a/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_worker.cc b/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_worker.cc
index 5bb26b925b4..8cb72012920 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_worker.cc
+++ b/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_worker.cc
@@ -17,10 +17,12 @@ namespace blink {
ResourceLoadObserverForWorker::ResourceLoadObserverForWorker(
CoreProbeSink& probe,
const ResourceFetcherProperties& properties,
- scoped_refptr<WebWorkerFetchContext> web_context)
+ scoped_refptr<WebWorkerFetchContext> web_context,
+ const base::UnguessableToken& devtools_worker_token)
: probe_(probe),
fetcher_properties_(properties),
- web_context_(std::move(web_context)) {}
+ web_context_(std::move(web_context)),
+ devtools_worker_token_(devtools_worker_token) {}
ResourceLoadObserverForWorker::~ResourceLoadObserverForWorker() = default;
@@ -99,10 +101,11 @@ void ResourceLoadObserverForWorker::DidFailLoading(const KURL&,
const ResourceError& error,
int64_t,
IsInternalRequest) {
- probe::DidFailLoading(probe_, identifier, nullptr, error);
+ probe::DidFailLoading(probe_, identifier, nullptr, error,
+ devtools_worker_token_);
}
-void ResourceLoadObserverForWorker::Trace(Visitor* visitor) {
+void ResourceLoadObserverForWorker::Trace(Visitor* visitor) const {
visitor->Trace(probe_);
visitor->Trace(fetcher_properties_);
ResourceLoadObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_worker.h b/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_worker.h
index 2776a28d205..4fdb198ad61 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_worker.h
+++ b/chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_worker.h
@@ -8,6 +8,7 @@
#include <inttypes.h>
#include "base/containers/span.h"
+#include "base/unguessable_token.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h"
namespace blink {
@@ -19,9 +20,11 @@ class WebWorkerFetchContext;
// ResourceLoadObserver implementation associated with a worker or worklet.
class ResourceLoadObserverForWorker final : public ResourceLoadObserver {
public:
- ResourceLoadObserverForWorker(CoreProbeSink& probe,
- const ResourceFetcherProperties& properties,
- scoped_refptr<WebWorkerFetchContext>);
+ ResourceLoadObserverForWorker(
+ CoreProbeSink& probe,
+ const ResourceFetcherProperties& properties,
+ scoped_refptr<WebWorkerFetchContext>,
+ const base::UnguessableToken& devtools_worker_token);
~ResourceLoadObserverForWorker() override;
// ResourceLoadObserver implementation.
@@ -54,12 +57,13 @@ class ResourceLoadObserverForWorker final : public ResourceLoadObserver {
const ResourceError&,
int64_t encoded_data_length,
IsInternalRequest) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const Member<CoreProbeSink> probe_;
const Member<const ResourceFetcherProperties> fetcher_properties_;
const scoped_refptr<WebWorkerFetchContext> web_context_;
+ const base::UnguessableToken devtools_worker_token_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/subresource_filter.cc b/chromium/third_party/blink/renderer/core/loader/subresource_filter.cc
index 2c4b51cd6ce..5df97da9837 100644
--- a/chromium/third_party/blink/renderer/core/loader/subresource_filter.cc
+++ b/chromium/third_party/blink/renderer/core/loader/subresource_filter.cc
@@ -144,7 +144,7 @@ void SubresourceFilter::ReportLoad(
}
}
-void SubresourceFilter::Trace(Visitor* visitor) {
+void SubresourceFilter::Trace(Visitor* visitor) const {
visitor->Trace(execution_context_);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/subresource_filter.h b/chromium/third_party/blink/renderer/core/loader/subresource_filter.h
index 4b11327cbe8..57ad65b81a4 100644
--- a/chromium/third_party/blink/renderer/core/loader/subresource_filter.h
+++ b/chromium/third_party/blink/renderer/core/loader/subresource_filter.h
@@ -40,7 +40,7 @@ class CORE_EXPORT SubresourceFilter final
// Reports the resource request id as an ad to the |subresource_filter_|.
void ReportAdRequestId(int request_id);
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
void ReportLoad(const KURL& resource_url,
diff --git a/chromium/third_party/blink/renderer/core/loader/text_track_loader.cc b/chromium/third_party/blink/renderer/core/loader/text_track_loader.cc
index f932278a1d4..cb6e2a64f52 100644
--- a/chromium/third_party/blink/renderer/core/loader/text_track_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/text_track_loader.cc
@@ -157,7 +157,7 @@ void TextTrackLoader::GetNewStyleSheets(
cue_parser_->GetNewStyleSheets(output_sheets);
}
-void TextTrackLoader::Trace(Visitor* visitor) {
+void TextTrackLoader::Trace(Visitor* visitor) const {
visitor->Trace(client_);
visitor->Trace(cue_parser_);
visitor->Trace(document_);
diff --git a/chromium/third_party/blink/renderer/core/loader/text_track_loader.h b/chromium/third_party/blink/renderer/core/loader/text_track_loader.h
index 4338729ca99..d696306a5d9 100644
--- a/chromium/third_party/blink/renderer/core/loader/text_track_loader.h
+++ b/chromium/third_party/blink/renderer/core/loader/text_track_loader.h
@@ -62,7 +62,7 @@ class TextTrackLoader final : public GarbageCollected<TextTrackLoader>,
void GetNewCues(HeapVector<Member<TextTrackCue>>& output_cues);
void GetNewStyleSheets(HeapVector<Member<CSSStyleSheet>>& output_sheets);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// RawResourceClient
diff --git a/chromium/third_party/blink/renderer/core/loader/threadable_loader.cc b/chromium/third_party/blink/renderer/core/loader/threadable_loader.cc
index 4fed84a7914..6f29364283e 100644
--- a/chromium/third_party/blink/renderer/core/loader/threadable_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/threadable_loader.cc
@@ -122,7 +122,7 @@ class ThreadableLoader::DetachedClient final
}
void DidFail(const ResourceError&) override { self_keep_alive_.Clear(); }
void DidFailRedirectCheck() override { self_keep_alive_.Clear(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(loader_);
ThreadableLoaderClient::Trace(visitor);
}
@@ -682,7 +682,6 @@ bool ThreadableLoader::RedirectReceived(
ResourceRequest cross_origin_request;
cross_origin_request.CopyFrom(new_request);
- cross_origin_request.SetInitialUrlForResourceTiming(initial_request_url_);
// Remove any headers that may have been added by the network layer that cause
// access control to fail.
@@ -1071,7 +1070,7 @@ LocalFrame* ThreadableLoader::GetFrame() const {
return window ? window->GetFrame() : nullptr;
}
-void ThreadableLoader::Trace(Visitor* visitor) {
+void ThreadableLoader::Trace(Visitor* visitor) const {
visitor->Trace(execution_context_);
visitor->Trace(client_);
visitor->Trace(resource_fetcher_);
diff --git a/chromium/third_party/blink/renderer/core/loader/threadable_loader.h b/chromium/third_party/blink/renderer/core/loader/threadable_loader.h
index d6b9c5edf8c..4a1a8149adb 100644
--- a/chromium/third_party/blink/renderer/core/loader/threadable_loader.h
+++ b/chromium/third_party/blink/renderer/core/loader/threadable_loader.h
@@ -131,7 +131,7 @@ class CORE_EXPORT ThreadableLoader final
void SetDefersLoading(bool);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
class AssignOnScopeExit;
diff --git a/chromium/third_party/blink/renderer/core/loader/threaded_icon_loader.cc b/chromium/third_party/blink/renderer/core/loader/threaded_icon_loader.cc
index d4697bf4a2d..388a3877900 100644
--- a/chromium/third_party/blink/renderer/core/loader/threaded_icon_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/threaded_icon_loader.cc
@@ -178,7 +178,7 @@ void ThreadedIconLoader::DidFailRedirectCheck() {
std::move(icon_callback_).Run(SkBitmap(), -1);
}
-void ThreadedIconLoader::Trace(Visitor* visitor) {
+void ThreadedIconLoader::Trace(Visitor* visitor) const {
visitor->Trace(threadable_loader_);
ThreadableLoaderClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/threaded_icon_loader.h b/chromium/third_party/blink/renderer/core/loader/threaded_icon_loader.h
index 2aa8f77e51d..658ebf57038 100644
--- a/chromium/third_party/blink/renderer/core/loader/threaded_icon_loader.h
+++ b/chromium/third_party/blink/renderer/core/loader/threaded_icon_loader.h
@@ -51,7 +51,7 @@ class CORE_EXPORT ThreadedIconLoader final
void DidFail(const ResourceError& error) override;
void DidFailRedirectCheck() override;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
void DecodeAndResizeImageOnBackgroundThread(
diff --git a/chromium/third_party/blink/renderer/core/loader/threaded_icon_loader_test.cc b/chromium/third_party/blink/renderer/core/loader/threaded_icon_loader_test.cc
index e4102f3c39f..8add4aee86b 100644
--- a/chromium/third_party/blink/renderer/core/loader/threaded_icon_loader_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/threaded_icon_loader_test.cc
@@ -35,7 +35,7 @@ class ThreadedIconLoaderTest : public PageTestBase {
}
void TearDown() override {
- platform_->GetURLLoaderMockFactory()
+ WebURLLoaderMockFactory::GetSingletonInstance()
->UnregisterAllURLsAndClearMemoryCache();
}
@@ -65,7 +65,8 @@ class ThreadedIconLoaderTest : public PageTestBase {
WTF::Bind(&ThreadedIconLoaderTest::DidGetIcon, WTF::Unretained(this),
run_loop.QuitClosure(), WTF::Unretained(&icon),
WTF::Unretained(&resize_scale)));
- platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
+ WebURLLoaderMockFactory::GetSingletonInstance()
+ ->ServeAsynchronousRequests();
run_loop.Run();
return {icon, resize_scale};
diff --git a/chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc b/chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc
index 2df53f0f86f..eae4c6d82a2 100644
--- a/chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc
+++ b/chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc
@@ -339,7 +339,7 @@ class WebAssociatedURLLoaderImpl::Observer final
parent_->ContextDestroyed();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
ExecutionContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/worker_fetch_context.cc b/chromium/third_party/blink/renderer/core/loader/worker_fetch_context.cc
index 3d37ba03f5b..841314e3ab8 100644
--- a/chromium/third_party/blink/renderer/core/loader/worker_fetch_context.cc
+++ b/chromium/third_party/blink/renderer/core/loader/worker_fetch_context.cc
@@ -142,13 +142,18 @@ WorkerFetchContext::CreateWebSocketHandshakeThrottle() {
bool WorkerFetchContext::ShouldBlockFetchByMixedContentCheck(
mojom::RequestContextType request_context,
- ResourceRequest::RedirectStatus redirect_status,
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info,
const KURL& url,
ReportingDisposition reporting_disposition,
const base::Optional<String>& devtools_id) const {
+ RedirectStatus redirect_status = redirect_info
+ ? RedirectStatus::kFollowedRedirect
+ : RedirectStatus::kNoRedirect;
+ const KURL& url_before_redirects =
+ redirect_info ? redirect_info->original_url : url;
return MixedContentChecker::ShouldBlockFetchOnWorker(
- *this, request_context, redirect_status, url, reporting_disposition,
- global_scope_->IsWorkletGlobalScope());
+ *this, request_context, url_before_redirects, redirect_status, url,
+ reporting_disposition, global_scope_->IsWorkletGlobalScope());
}
bool WorkerFetchContext::ShouldBlockFetchAsCredentialedSubresource(
@@ -242,9 +247,10 @@ void WorkerFetchContext::PopulateResourceRequest(
ResourceType type,
const ClientHintsPreferences& hints_preferences,
const FetchParameters::ResourceWidth& resource_width,
- ResourceRequest& out_request) {
+ ResourceRequest& out_request,
+ const FetchInitiatorInfo& initiator_info) {
if (!GetResourceFetcherProperties().IsDetached())
- probe::SetDevToolsIds(Probe(), out_request);
+ probe::SetDevToolsIds(Probe(), out_request, initiator_info);
MixedContentChecker::UpgradeInsecureRequest(
out_request,
&GetResourceFetcherProperties().GetFetchClientSettingsObject(),
@@ -257,10 +263,8 @@ void WorkerFetchContext::PopulateResourceRequest(
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
WorkerFetchContext::TakePendingWorkerTimingReceiver(int request_id) {
- mojo::ScopedMessagePipeHandle pipe =
- GetWebWorkerFetchContext()->TakePendingWorkerTimingReceiver(request_id);
- return mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>(
- std::move(pipe));
+ return GetWebWorkerFetchContext()->TakePendingWorkerTimingReceiver(
+ request_id);
}
void WorkerFetchContext::SetFirstPartyCookie(ResourceRequest& out_request) {
@@ -282,7 +286,7 @@ bool WorkerFetchContext::AllowRunningInsecureContent(
enabled_per_settings, url);
}
-void WorkerFetchContext::Trace(Visitor* visitor) {
+void WorkerFetchContext::Trace(Visitor* visitor) const {
visitor->Trace(global_scope_);
visitor->Trace(subresource_filter_);
visitor->Trace(content_security_policy_);
diff --git a/chromium/third_party/blink/renderer/core/loader/worker_fetch_context.h b/chromium/third_party/blink/renderer/core/loader/worker_fetch_context.h
index 0dcad4fa1e4..146a2041b4c 100644
--- a/chromium/third_party/blink/renderer/core/loader/worker_fetch_context.h
+++ b/chromium/third_party/blink/renderer/core/loader/worker_fetch_context.h
@@ -61,7 +61,7 @@ class WorkerFetchContext final : public BaseFetchContext {
override;
bool ShouldBlockFetchByMixedContentCheck(
mojom::blink::RequestContextType request_context,
- ResourceRequest::RedirectStatus redirect_status,
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info,
const KURL& url,
ReportingDisposition reporting_disposition,
const base::Optional<String>& devtools_id) const override;
@@ -82,7 +82,8 @@ class WorkerFetchContext final : public BaseFetchContext {
void PopulateResourceRequest(ResourceType,
const ClientHintsPreferences&,
const FetchParameters::ResourceWidth&,
- ResourceRequest&) override;
+ ResourceRequest&,
+ const FetchInitiatorInfo&) override;
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
TakePendingWorkerTimingReceiver(int request_id) override;
@@ -94,7 +95,7 @@ class WorkerFetchContext final : public BaseFetchContext {
bool AllowRunningInsecureContent(bool enabled_per_settings,
const KURL& url) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SetFirstPartyCookie(ResourceRequest&);
diff --git a/chromium/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.cc b/chromium/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.cc
index ee0ce16266f..470f225bd17 100644
--- a/chromium/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.cc
+++ b/chromium/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.cc
@@ -23,7 +23,7 @@ WorkerResourceFetcherProperties::WorkerResourceFetcherProperties(
DCHECK(web_context_);
}
-void WorkerResourceFetcherProperties::Trace(Visitor* visitor) {
+void WorkerResourceFetcherProperties::Trace(Visitor* visitor) const {
visitor->Trace(global_scope_);
visitor->Trace(fetch_client_settings_object_);
ResourceFetcherProperties::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.h b/chromium/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.h
index 9d9de5f8ae3..76295616ff3 100644
--- a/chromium/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.h
+++ b/chromium/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.h
@@ -23,7 +23,7 @@ class WorkerResourceFetcherProperties final : public ResourceFetcherProperties {
scoped_refptr<WebWorkerFetchContext> web_context);
~WorkerResourceFetcherProperties() override = default;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// ResourceFetcherProperties implementation
const FetchClientSettingsObject& GetFetchClientSettingsObject()
diff --git a/chromium/third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.cc b/chromium/third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.cc
index 40ee616d1ee..0f908d0af80 100644
--- a/chromium/third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.cc
+++ b/chromium/third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.cc
@@ -70,7 +70,8 @@ void WorkerResourceTimingNotifierImpl::AddResourceTiming(
DCHECK(inside_execution_context_->IsContextThread());
GetPerformance(*inside_execution_context_)
->AddResourceTiming(std::move(info), initiator_type,
- std::move(worker_timing_receiver));
+ std::move(worker_timing_receiver),
+ inside_execution_context_);
} else {
PostCrossThreadTask(
*task_runner_, FROM_HERE,
@@ -93,10 +94,11 @@ void WorkerResourceTimingNotifierImpl::AddCrossThreadResourceTiming(
DCHECK(outside_execution_context_->IsContextThread());
GetPerformance(*outside_execution_context_)
->AddResourceTiming(std::move(info), AtomicString(initiator_type),
- std::move(worker_timing_receiver));
+ std::move(worker_timing_receiver),
+ outside_execution_context_);
}
-void WorkerResourceTimingNotifierImpl::Trace(Visitor* visitor) {
+void WorkerResourceTimingNotifierImpl::Trace(Visitor* visitor) const {
visitor->Trace(inside_execution_context_);
WorkerResourceTimingNotifier::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.h b/chromium/third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.h
index 25dace026bc..15363367201 100644
--- a/chromium/third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.h
+++ b/chromium/third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.h
@@ -45,7 +45,7 @@ class CORE_EXPORT WorkerResourceTimingNotifierImpl final
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
worker_timing_receiver) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void AddCrossThreadResourceTiming(
diff --git a/chromium/third_party/blink/renderer/core/mathml/mathml_attribute_names.json5 b/chromium/third_party/blink/renderer/core/mathml/mathml_attribute_names.json5
index 3e0704cca59..63ae83845a6 100644
--- a/chromium/third_party/blink/renderer/core/mathml/mathml_attribute_names.json5
+++ b/chromium/third_party/blink/renderer/core/mathml/mathml_attribute_names.json5
@@ -18,6 +18,7 @@
"mathcolor",
"mathsize",
"mathvariant",
+ "scriptlevel",
"width",
],
}
diff --git a/chromium/third_party/blink/renderer/core/mathml/mathml_element.cc b/chromium/third_party/blink/renderer/core/mathml/mathml_element.cc
index a3460c2b2f0..e41bfba7ec2 100644
--- a/chromium/third_party/blink/renderer/core/mathml/mathml_element.cc
+++ b/chromium/third_party/blink/renderer/core/mathml/mathml_element.cc
@@ -34,7 +34,6 @@ static inline bool IsDisallowedMathSizeAttribute(const AtomicString& value) {
}
bool MathMLElement::IsPresentationAttribute(const QualifiedName& name) const {
- // TODO(crbug.com/1023292): add support for displaystyle and scriptlevel.
if (name == html_names::kDirAttr || name == mathml_names::kMathsizeAttr ||
name == mathml_names::kMathcolorAttr ||
name == mathml_names::kMathbackgroundAttr ||
@@ -49,8 +48,6 @@ void MathMLElement::CollectStyleForPresentationAttribute(
const QualifiedName& name,
const AtomicString& value,
MutableCSSPropertyValueSet* style) {
- // TODO(crbug.com/1023292, crbug.com/1023296): add support for display,
- // displaystyle and scriptlevel.
if (name == html_names::kDirAttr) {
if (IsValidDirAttribute(value)) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kDirection,
diff --git a/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.cc b/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
index 8489761ad5a..ef6032339a6 100644
--- a/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
+++ b/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
@@ -8,42 +8,124 @@
#include "mojo/public/cpp/base/big_buffer.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "third_party/blink/public/mojom/blob/blob.mojom-blink.h"
+#include "third_party/blink/renderer/core/events/message_event.h"
+#include "third_party/blink/renderer/core/frame/user_activation.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
+#include "third_party/blink/public/web/web_dom_message_event.h"
+
namespace blink {
-BlinkTransferableMessage::BlinkTransferableMessage() = default;
-BlinkTransferableMessage::~BlinkTransferableMessage() = default;
+// static
+BlinkTransferableMessage BlinkTransferableMessage::FromMessageEvent(
+ MessageEvent* message_event,
+ base::Optional<base::UnguessableToken> cluster_id) {
+ BlinkTransferableMessage result;
+ SerializedScriptValue* serialized_script_value =
+ message_event->DataAsSerializedScriptValue();
-BlinkTransferableMessage::BlinkTransferableMessage(BlinkTransferableMessage&&) =
- default;
-BlinkTransferableMessage& BlinkTransferableMessage::operator=(
- BlinkTransferableMessage&&) = default;
+ // Message data and cluster ID (optional).
+ base::span<const uint8_t> message_wire_data =
+ serialized_script_value->GetWireData();
+ result.message = SerializedScriptValue::Create(
+ reinterpret_cast<const char*>(message_wire_data.data()),
+ message_wire_data.size());
+ result.locked_agent_cluster_id = cluster_id;
-scoped_refptr<StaticBitmapImage> ToStaticBitmapImage(
- const SkBitmap& sk_bitmap) {
- sk_sp<SkImage> image = SkImage::MakeFromBitmap(sk_bitmap);
- if (!image)
- return nullptr;
+ // Ports
+ Vector<MessagePortChannel> ports = message_event->ReleaseChannels();
+ result.ports.AppendRange(ports.begin(), ports.end());
- return UnacceleratedStaticBitmapImage::Create(std::move(image));
-}
+ // User activation and |allow_autoplay|.
+ UserActivation* user_activation = message_event->userActivation();
+ if (user_activation) {
+ result.user_activation = mojom::blink::UserActivationSnapshot::New(
+ user_activation->hasBeenActive(), user_activation->isActive());
+ }
+ result.transfer_user_activation = message_event->transferUserActivation();
+ result.allow_autoplay = message_event->allowAutoplay();
-base::Optional<SkBitmap> ToSkBitmap(
- const scoped_refptr<blink::StaticBitmapImage>& static_bitmap_image) {
- const sk_sp<SkImage> image =
- static_bitmap_image->PaintImageForCurrentFrame().GetSkImage();
- SkBitmap result;
- if (image && image->asLegacyBitmap(
- &result, SkImage::LegacyBitmapMode::kRO_LegacyBitmapMode)) {
- return result;
+ // Blobs.
+ for (const auto& blob : serialized_script_value->BlobDataHandles()) {
+ result.message->BlobDataHandles().Set(
+ blob.value->Uuid(),
+ BlobDataHandle::Create(blob.value->Uuid(), blob.value->GetType(),
+ blob.value->size(),
+ mojo::PendingRemote<mojom::blink::Blob>(
+ blob.value->CloneBlobRemote().PassPipe(),
+ mojom::blink::Blob::Version_)));
}
- return base::nullopt;
+
+ // Stream channels.
+ auto& stream_channels = serialized_script_value->GetStreamChannels();
+ result.message->GetStreamChannels().AppendRange(stream_channels.begin(),
+ stream_channels.end());
+ // Array buffer contents array.
+ auto& source_array_buffer_contents_array =
+ serialized_script_value->GetArrayBufferContentsArray();
+ if (!source_array_buffer_contents_array.IsEmpty()) {
+ SerializedScriptValue::ArrayBufferContentsArray array_buffer_contents_array;
+ array_buffer_contents_array.ReserveInitialCapacity(
+ base::checked_cast<wtf_size_t>(
+ source_array_buffer_contents_array.size()));
+
+ for (auto& source_contents : source_array_buffer_contents_array) {
+ uint8_t* allocation_start = static_cast<uint8_t*>(source_contents.Data());
+ mojo_base::BigBuffer buffer(
+ base::make_span(allocation_start, source_contents.DataLength()));
+ ArrayBufferContents contents(buffer.size(), 1,
+ ArrayBufferContents::kNotShared,
+ ArrayBufferContents::kDontInitialize);
+ // Check if we allocated the backing store of the ArrayBufferContents
+ // correctly.
+ CHECK_EQ(contents.DataLength(), buffer.size());
+ memcpy(contents.Data(), buffer.data(), buffer.size());
+ array_buffer_contents_array.push_back(std::move(contents));
+ }
+ result.message->SetArrayBufferContentsArray(
+ std::move(array_buffer_contents_array));
+ }
+
+ // Image bitmap contents array.
+ auto& source_image_bitmap_contents_array =
+ serialized_script_value->GetImageBitmapContentsArray();
+ if (!source_image_bitmap_contents_array.IsEmpty()) {
+ SerializedScriptValue::ImageBitmapContentsArray image_bitmap_contents_array;
+ image_bitmap_contents_array.ReserveInitialCapacity(
+ base::checked_cast<wtf_size_t>(
+ source_image_bitmap_contents_array.size()));
+
+ for (auto& contents : image_bitmap_contents_array) {
+ base::Optional<SkBitmap> sk_bitmap = ToSkBitmap(contents);
+ if (!sk_bitmap)
+ continue;
+
+ const scoped_refptr<StaticBitmapImage> bitmap_contents =
+ ToStaticBitmapImage(sk_bitmap.value());
+ if (!bitmap_contents)
+ continue;
+ image_bitmap_contents_array.push_back(bitmap_contents);
+ }
+ result.message->SetImageBitmapContentsArray(
+ std::move(image_bitmap_contents_array));
+ }
+
+ // Native file system transfer tokens.
+ for (auto& token : serialized_script_value->NativeFileSystemTokens()) {
+ uint32_t token_version = token.version();
+ mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken>
+ converted_token(token.PassPipe(), token_version);
+ result.message->NativeFileSystemTokens().push_back(
+ std::move(converted_token));
+ }
+
+ return result;
}
-BlinkTransferableMessage ToBlinkTransferableMessage(
+// static
+BlinkTransferableMessage BlinkTransferableMessage::FromTransferableMessage(
TransferableMessage message) {
BlinkTransferableMessage result;
result.message = SerializedScriptValue::Create(
@@ -129,72 +211,33 @@ BlinkTransferableMessage ToBlinkTransferableMessage(
return result;
}
-TransferableMessage ToTransferableMessage(BlinkTransferableMessage message) {
- TransferableMessage result;
- result.encoded_message = message.message->GetWireData();
- result.blobs.reserve(message.message->BlobDataHandles().size());
- for (const auto& blob : message.message->BlobDataHandles()) {
- result.blobs.push_back(mojom::SerializedBlob::New(
- blob.value->Uuid().Utf8(), blob.value->GetType().Utf8(),
- blob.value->size(),
- mojo::PendingRemote<mojom::Blob>(
- blob.value->CloneBlobRemote().PassPipe(), mojom::Blob::Version_)));
- }
- if (message.sender_origin) {
- result.sender_origin = message.sender_origin->ToUrlOrigin();
- }
- result.stack_trace_id = message.sender_stack_trace_id.id;
- result.stack_trace_debugger_id_first =
- message.sender_stack_trace_id.debugger_id.first;
- result.stack_trace_debugger_id_second =
- message.sender_stack_trace_id.debugger_id.second;
- result.stack_trace_should_pause = message.sender_stack_trace_id.should_pause;
- result.locked_agent_cluster_id = message.locked_agent_cluster_id;
- result.ports.assign(message.ports.begin(), message.ports.end());
- auto& stream_channels = message.message->GetStreamChannels();
- result.stream_channels.assign(stream_channels.begin(), stream_channels.end());
- if (message.user_activation) {
- result.user_activation = mojom::UserActivationSnapshot::New(
- message.user_activation->has_been_active,
- message.user_activation->was_active);
- }
- result.transfer_user_activation = message.transfer_user_activation;
- result.allow_autoplay = message.allow_autoplay;
+BlinkTransferableMessage::BlinkTransferableMessage() = default;
+BlinkTransferableMessage::~BlinkTransferableMessage() = default;
- auto& array_buffer_contents_array =
- message.message->GetArrayBufferContentsArray();
- result.array_buffer_contents_array.reserve(
- array_buffer_contents_array.size());
- for (auto& contents : array_buffer_contents_array) {
- uint8_t* allocation_start = static_cast<uint8_t*>(contents.Data());
- mojo_base::BigBuffer buffer(
- base::make_span(allocation_start, contents.DataLength()));
- result.array_buffer_contents_array.push_back(
- mojom::SerializedArrayBufferContents::New(std::move(buffer)));
- }
+BlinkTransferableMessage::BlinkTransferableMessage(BlinkTransferableMessage&&) =
+ default;
+BlinkTransferableMessage& BlinkTransferableMessage::operator=(
+ BlinkTransferableMessage&&) = default;
- auto& image_bitmap_contents_array =
- message.message->GetImageBitmapContentsArray();
- result.image_bitmap_contents_array.reserve(
- image_bitmap_contents_array.size());
- for (auto& contents : image_bitmap_contents_array) {
- base::Optional<SkBitmap> bitmap = ToSkBitmap(contents);
- if (!bitmap)
- continue;
- result.image_bitmap_contents_array.push_back(std::move(bitmap.value()));
- }
+scoped_refptr<StaticBitmapImage> ToStaticBitmapImage(
+ const SkBitmap& sk_bitmap) {
+ sk_sp<SkImage> image = SkImage::MakeFromBitmap(sk_bitmap);
+ if (!image)
+ return nullptr;
- // Convert the PendingRemote<NativeFileSystemTransferToken> from the
- // blink::mojom::blink namespace to the blink::mojom namespace.
- result.native_file_system_tokens.reserve(
- message.message->NativeFileSystemTokens().size());
- for (auto& token : message.message->NativeFileSystemTokens()) {
- uint32_t token_version = token.version();
- mojo::PendingRemote<mojom::NativeFileSystemTransferToken> converted_token(
- token.PassPipe(), token_version);
- result.native_file_system_tokens.push_back(std::move(converted_token));
+ return UnacceleratedStaticBitmapImage::Create(std::move(image));
+}
+
+base::Optional<SkBitmap> ToSkBitmap(
+ const scoped_refptr<blink::StaticBitmapImage>& static_bitmap_image) {
+ const sk_sp<SkImage> image =
+ static_bitmap_image->PaintImageForCurrentFrame().GetSkImage();
+ SkBitmap result;
+ if (image && image->asLegacyBitmap(
+ &result, SkImage::LegacyBitmapMode::kRO_LegacyBitmapMode)) {
+ return result;
}
- return result;
+ return base::nullopt;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.h b/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.h
index 3957bed8775..19209e459f6 100644
--- a/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.h
+++ b/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.h
@@ -12,15 +12,23 @@
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/messaging/blink_cloneable_message.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
namespace blink {
+class MessageEvent;
+
// This struct represents messages as they are posted over a message port. This
// type can be serialized as a blink::mojom::TransferableMessage struct.
// This is the renderer-side equivalent of blink::TransferableMessage, where
// this struct uses blink types, while the other struct uses std:: types.
struct CORE_EXPORT BlinkTransferableMessage : BlinkCloneableMessage {
+ static BlinkTransferableMessage FromMessageEvent(
+ MessageEvent*,
+ base::Optional<base::UnguessableToken> cluster_id = base::nullopt);
+ static BlinkTransferableMessage FromTransferableMessage(TransferableMessage);
+
BlinkTransferableMessage();
~BlinkTransferableMessage();
@@ -44,14 +52,6 @@ CORE_EXPORT scoped_refptr<blink::StaticBitmapImage> ToStaticBitmapImage(
CORE_EXPORT base::Optional<SkBitmap> ToSkBitmap(
const scoped_refptr<blink::StaticBitmapImage>& static_bitmap_image);
-CORE_EXPORT BlinkTransferableMessage
- ToBlinkTransferableMessage(TransferableMessage);
-// Returned message will still be backed by the SerializedScriptValue in the
-// input message, so is only valid as long as that SerializedScriptValue is
-// alive. Call EnsureDataIsOwned on the returned message if you need it to live
-// longer.
-CORE_EXPORT TransferableMessage ToTransferableMessage(BlinkTransferableMessage);
-
} // namespace blink
namespace WTF {
diff --git a/chromium/third_party/blink/renderer/core/messaging/message_channel.cc b/chromium/third_party/blink/renderer/core/messaging/message_channel.cc
index 97f827e508a..cfefad90a44 100644
--- a/chromium/third_party/blink/renderer/core/messaging/message_channel.cc
+++ b/chromium/third_party/blink/renderer/core/messaging/message_channel.cc
@@ -40,7 +40,7 @@ MessageChannel::MessageChannel(ExecutionContext* context)
port2_->Entangle(pipe.TakePort1());
}
-void MessageChannel::Trace(Visitor* visitor) {
+void MessageChannel::Trace(Visitor* visitor) const {
visitor->Trace(port1_);
visitor->Trace(port2_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/messaging/message_channel.h b/chromium/third_party/blink/renderer/core/messaging/message_channel.h
index 59f7132f1cb..f3dd0134cdd 100644
--- a/chromium/third_party/blink/renderer/core/messaging/message_channel.h
+++ b/chromium/third_party/blink/renderer/core/messaging/message_channel.h
@@ -49,7 +49,7 @@ class CORE_EXPORT MessageChannel final : public ScriptWrappable {
MessagePort* port1() const { return port1_; }
MessagePort* port2() const { return port2_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<MessagePort> port1_;
diff --git a/chromium/third_party/blink/renderer/core/messaging/message_port.cc b/chromium/third_party/blink/renderer/core/messaging/message_port.cc
index 267fb73bf66..9e9de51e37e 100644
--- a/chromium/third_party/blink/renderer/core/messaging/message_port.cc
+++ b/chromium/third_party/blink/renderer/core/messaging/message_port.cc
@@ -261,7 +261,7 @@ MessagePortArray* MessagePort::EntanglePorts(
return connector_->handle().value();
}
-void MessagePort::Trace(Visitor* visitor) {
+void MessagePort::Trace(Visitor* visitor) const {
ExecutionContextLifecycleObserver::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/messaging/message_port.h b/chromium/third_party/blink/renderer/core/messaging/message_port.h
index 0235fe07fb5..d30195fc3cf 100644
--- a/chromium/third_party/blink/renderer/core/messaging/message_port.h
+++ b/chromium/third_party/blink/renderer/core/messaging/message_port.h
@@ -132,7 +132,7 @@ class CORE_EXPORT MessagePort : public EventTargetWithInlineData,
// For testing only: allows inspection of the entangled channel.
::MojoHandle EntangledHandleForTesting() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// mojo::MessageReceiver implementation.
diff --git a/chromium/third_party/blink/renderer/core/messaging/post_message_options.idl b/chromium/third_party/blink/renderer/core/messaging/post_message_options.idl
index 94df9264d70..bf93402416e 100644
--- a/chromium/third_party/blink/renderer/core/messaging/post_message_options.idl
+++ b/chromium/third_party/blink/renderer/core/messaging/post_message_options.idl
@@ -6,5 +6,5 @@
dictionary PostMessageOptions {
sequence<object> transfer = [];
- [RuntimeEnabled=UserActivationAPI] boolean includeUserActivation = false;
+ boolean includeUserActivation = false;
};
diff --git a/chromium/third_party/blink/renderer/core/mojo/mojo_watcher.cc b/chromium/third_party/blink/renderer/core/mojo/mojo_watcher.cc
index b9f8e2bdcc2..c7bd5290b8c 100644
--- a/chromium/third_party/blink/renderer/core/mojo/mojo_watcher.cc
+++ b/chromium/third_party/blink/renderer/core/mojo/mojo_watcher.cc
@@ -49,7 +49,7 @@ MojoResult MojoWatcher::cancel() {
return MOJO_RESULT_OK;
}
-void MojoWatcher::Trace(Visitor* visitor) {
+void MojoWatcher::Trace(Visitor* visitor) const {
visitor->Trace(callback_);
ScriptWrappable::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/mojo/mojo_watcher.h b/chromium/third_party/blink/renderer/core/mojo/mojo_watcher.h
index 1de31f7482e..82194ca4d0b 100644
--- a/chromium/third_party/blink/renderer/core/mojo/mojo_watcher.h
+++ b/chromium/third_party/blink/renderer/core/mojo/mojo_watcher.h
@@ -34,7 +34,7 @@ class MojoWatcher final : public ScriptWrappable,
MojoResult cancel();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// ActiveScriptWrappable
bool HasPendingActivity() const final;
diff --git a/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.cc b/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.cc
index 2251830a146..1463cf5e75c 100644
--- a/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.cc
+++ b/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.cc
@@ -100,7 +100,7 @@ void MojoInterfaceInterceptor::stop() {
context->GetBrowserInterfaceBroker().SetBinderForTesting(interface_name, {});
}
-void MojoInterfaceInterceptor::Trace(Visitor* visitor) {
+void MojoInterfaceInterceptor::Trace(Visitor* visitor) const {
EventTargetWithInlineData::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h b/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h
index c45bfdcc387..615d279bade 100644
--- a/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h
+++ b/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h
@@ -48,7 +48,7 @@ class MojoInterfaceInterceptor final
DEFINE_ATTRIBUTE_EVENT_LISTENER(interfacerequest, kInterfacerequest)
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// EventTargetWithInlineData
const AtomicString& InterfaceName() const override;
diff --git a/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.cc b/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.cc
index 1356522ce63..68c83db29e9 100644
--- a/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.cc
+++ b/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.cc
@@ -12,7 +12,7 @@ namespace blink {
MojoInterfaceRequestEvent::~MojoInterfaceRequestEvent() = default;
-void MojoInterfaceRequestEvent::Trace(Visitor* visitor) {
+void MojoInterfaceRequestEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
visitor->Trace(handle_);
}
diff --git a/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.h b/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.h
index 7427b07786d..a5e98a80e5d 100644
--- a/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.h
+++ b/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.h
@@ -39,7 +39,7 @@ class MojoInterfaceRequestEvent final : public Event {
return event_interface_names::kMojoInterfaceRequestEvent;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<MojoHandle> handle_;
diff --git a/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc b/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc
index 9066cc0ccd5..80a67a00a11 100644
--- a/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc
+++ b/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc
@@ -22,6 +22,7 @@
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_factory.h"
#include "third_party/blink/renderer/core/html/canvas/image_data.h"
+#include "third_party/blink/renderer/core/html/canvas/ukm_parameters.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
#include "third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h"
@@ -43,7 +44,8 @@ namespace blink {
OffscreenCanvas::OffscreenCanvas(ExecutionContext* context, const IntSize& size)
: CanvasRenderingContextHost(
- CanvasRenderingContextHost::HostType::kOffscreenCanvasHost),
+ CanvasRenderingContextHost::HostType::kOffscreenCanvasHost,
+ base::make_optional<UkmParameters>()),
execution_context_(context),
size_(size) {
// Other code in Blink watches for destruction of the context; be
@@ -150,7 +152,7 @@ void OffscreenCanvas::setHeight(unsigned height) {
void OffscreenCanvas::SetSize(const IntSize& size) {
// Setting size of a canvas also resets it.
if (size == size_) {
- if (context_ && context_->Is2d()) {
+ if (context_ && context_->IsRenderingContext2D()) {
context_->Reset();
origin_clean_ = true;
}
@@ -166,7 +168,7 @@ void OffscreenCanvas::SetSize(const IntSize& size) {
if (context_) {
if (context_->Is3d()) {
context_->Reshape(size_.Width(), size_.Height());
- } else if (context_->Is2d()) {
+ } else if (context_->IsRenderingContext2D()) {
context_->Reset();
origin_clean_ = true;
}
@@ -214,7 +216,6 @@ ImageBitmap* OffscreenCanvas::transferToImageBitmap(
scoped_refptr<Image> OffscreenCanvas::GetSourceImageForCanvas(
SourceImageStatus* status,
- AccelerationHint hint,
const FloatSize& size) {
if (!context_) {
*status = kInvalidSourceImageStatus;
@@ -228,7 +229,7 @@ scoped_refptr<Image> OffscreenCanvas::GetSourceImageForCanvas(
*status = kZeroSizeCanvasSourceImageStatus;
return nullptr;
}
- scoped_refptr<Image> image = context_->GetImage(hint);
+ scoped_refptr<Image> image = context_->GetImage();
if (!image)
image = CreateTransparentImage(Size());
*status = image ? kNormalSourceImageStatus : kInvalidSourceImageStatus;
@@ -379,14 +380,14 @@ CanvasResourceProvider* OffscreenCanvas::GetOrCreateResourceProvider() {
provider = CanvasResourceProvider::CreateSharedImageProvider(
surface_size, SharedGpuContext::ContextProviderWrapper(),
FilterQuality(), context_->ColorParams(), false /*is_origin_top_left*/,
- CanvasResourceProvider::RasterMode::kGPU, shared_image_usage_flags);
+ RasterMode::kGPU, shared_image_usage_flags);
} else if (HasPlaceholderCanvas() && composited_mode) {
// Only try a SoftwareComposited SharedImage if the context has Placeholder
// canvas and the composited mode is enabled.
provider = CanvasResourceProvider::CreateSharedImageProvider(
surface_size, SharedGpuContext::ContextProviderWrapper(),
FilterQuality(), context_->ColorParams(), false /*is_origin_top_left*/,
- CanvasResourceProvider::RasterMode::kCPU, shared_image_usage_flags);
+ RasterMode::kCPU, shared_image_usage_flags);
}
if (!provider && HasPlaceholderCanvas()) {
@@ -396,8 +397,7 @@ CanvasResourceProvider* OffscreenCanvas::GetOrCreateResourceProvider() {
base::WeakPtr<CanvasResourceDispatcher> dispatcher_weakptr =
GetOrCreateResourceDispatcher()->GetWeakPtr();
provider = CanvasResourceProvider::CreateSharedBitmapProvider(
- surface_size, SharedGpuContext::ContextProviderWrapper(),
- FilterQuality(), context_->ColorParams(),
+ surface_size, FilterQuality(), context_->ColorParams(),
std::move(dispatcher_weakptr));
}
@@ -512,7 +512,7 @@ void OffscreenCanvas::UpdateMemoryUsage() {
memory_usage_ = new_memory_usage;
}
-void OffscreenCanvas::Trace(Visitor* visitor) {
+void OffscreenCanvas::Trace(Visitor* visitor) const {
visitor->Trace(context_);
visitor->Trace(execution_context_);
EventTargetWithInlineData::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h b/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h
index 2d535354ff7..6b3e3ad2ef9 100644
--- a/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h
+++ b/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h
@@ -124,7 +124,6 @@ class CORE_EXPORT OffscreenCanvas final
void Commit(scoped_refptr<CanvasResource> bitmap_image,
const SkIRect& damage_rect) override;
bool ShouldAccelerate2dContext() const override;
- unsigned GetMSAASampleCountFor2dContext() const override { return 0; }
CanvasResourceDispatcher* GetOrCreateResourceDispatcher() override;
// Partial CanvasResourceHost implementation
@@ -159,7 +158,6 @@ class CORE_EXPORT OffscreenCanvas final
// CanvasImageSource implementation
scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*,
- AccelerationHint,
const FloatSize&) final;
bool WouldTaintOrigin() const final { return !origin_clean_; }
FloatSize ElementSize(const FloatSize& default_object_size,
@@ -179,7 +177,7 @@ class CORE_EXPORT OffscreenCanvas final
FontSelector* GetFontSelector() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
class ScopedInsideWorkerRAF {
STACK_ALLOCATED();
diff --git a/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc b/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc
index 3a3e37569db..462286b0ac0 100644
--- a/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc
+++ b/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
+#include <ostream>
+
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "services/network/public/cpp/features.h"
@@ -93,6 +95,40 @@ bool IsCrossNavigationFeature(OriginTrialFeature feature) {
return origin_trials::GetNavigationOriginTrialFeatures().Contains(feature);
}
+std::ostream& operator<<(std::ostream& stream, OriginTrialTokenStatus status) {
+// Included for debug builds only for reduced binary size.
+#ifndef NDEBUG
+ switch (status) {
+ case OriginTrialTokenStatus::kSuccess:
+ return stream << "kSuccess";
+ case OriginTrialTokenStatus::kNotSupported:
+ return stream << "kNotSupported";
+ case OriginTrialTokenStatus::kInsecure:
+ return stream << "kInsecure";
+ case OriginTrialTokenStatus::kExpired:
+ return stream << "kExpired";
+ case OriginTrialTokenStatus::kWrongOrigin:
+ return stream << "kWrongOrigin";
+ case OriginTrialTokenStatus::kInvalidSignature:
+ return stream << "kInvalidSignature";
+ case OriginTrialTokenStatus::kMalformed:
+ return stream << "kMalformed";
+ case OriginTrialTokenStatus::kWrongVersion:
+ return stream << "kWrongVersion";
+ case OriginTrialTokenStatus::kFeatureDisabled:
+ return stream << "kFeatureDisabled";
+ case OriginTrialTokenStatus::kTokenDisabled:
+ return stream << "kTokenDisabled";
+ case OriginTrialTokenStatus::kFeatureDisabledForUser:
+ return stream << "kFeatureDisabledForUser";
+ }
+ NOTREACHED();
+ return stream;
+#else
+ return stream << (static_cast<int>(status));
+#endif // ifndef NDEBUG
+}
+
} // namespace
OriginTrialContext::OriginTrialContext()
@@ -192,23 +228,51 @@ OriginTrialContext::GetEnabledNavigationFeatures() const {
}
void OriginTrialContext::AddToken(const String& token) {
+ AddTokenInternal(token, GetSecurityOrigin(), IsSecureContext(), nullptr,
+ false);
+}
+
+void OriginTrialContext::AddTokenFromExternalScript(
+ const String& token,
+ const SecurityOrigin* origin) {
+ bool is_script_origin_secure = false;
+ if (origin &&
+ RuntimeEnabledFeatures::ThirdPartyOriginTrialsEnabled(context_)) {
+ DVLOG(1) << "AddTokenFromExternalScript: "
+ << (origin ? origin->ToString() : "null");
+ is_script_origin_secure = origin->IsPotentiallyTrustworthy();
+ } else {
+ origin = nullptr;
+ }
+ AddTokenInternal(token, GetSecurityOrigin(), IsSecureContext(), origin,
+ is_script_origin_secure);
+}
+
+void OriginTrialContext::AddTokenInternal(const String& token,
+ const SecurityOrigin* origin,
+ bool is_origin_secure,
+ const SecurityOrigin* script_origin,
+ bool is_script_origin_secure) {
if (token.IsEmpty())
return;
tokens_.push_back(token);
- if (EnableTrialFromToken(GetSecurityOrigin(), IsSecureContext(), token)) {
- // Only install pending features if the provided token is valid. Otherwise,
- // there was no change to the list of enabled features.
+
+ bool enabled = EnableTrialFromToken(origin, is_origin_secure, script_origin,
+ is_script_origin_secure, token);
+ if (enabled) {
+ // Only install pending features if the provided token is valid.
+ // Otherwise, there was no change to the list of enabled features.
InitializePendingFeatures();
}
}
void OriginTrialContext::AddTokens(const Vector<String>& tokens) {
- AddTokens(GetSecurityOrigin(), IsSecureContext(), tokens);
+ AddTokens(tokens, GetSecurityOrigin(), IsSecureContext());
}
-void OriginTrialContext::AddTokens(const SecurityOrigin* origin,
- bool is_secure,
- const Vector<String>& tokens) {
+void OriginTrialContext::AddTokens(const Vector<String>& tokens,
+ const SecurityOrigin* origin,
+ bool is_secure) {
if (tokens.IsEmpty())
return;
bool found_valid = false;
@@ -282,15 +346,15 @@ bool OriginTrialContext::IsFeatureEnabled(OriginTrialFeature feature) const {
// - Spec: https://w3c.github.io/webcomponents/spec/imports/#terminology
// - Spec issue: https://github.com/w3c/webcomponents/issues/197
// For the purposes of origin trials, we consider imported documents to be
- // part of the master document. Thus, check if the trial is enabled in the
- // master document and use that result.
+ // part of the tree_root document. Thus, check if the trial is enabled in the
+ // tree_root document and use that result.
auto* window = DynamicTo<LocalDOMWindow>(context_.Get());
auto* document = window ? window->document() : nullptr;
if (!document || !document->IsHTMLImport())
return false;
const OriginTrialContext* context =
- document->MasterDocument().GetOriginTrialContext();
+ document->TreeRootDocument().GetOriginTrialContext();
if (!context)
return false;
return context->IsFeatureEnabled(feature);
@@ -381,9 +445,44 @@ bool OriginTrialContext::EnableTrialFromName(const String& trial_name,
return did_enable_feature;
}
+OriginTrialTokenStatus OriginTrialContext::ValidateTokenResult(
+ const String& trial_name,
+ bool is_origin_secure,
+ bool is_script_origin_secure,
+ bool is_third_party) {
+ bool is_secure = is_origin_secure;
+ if (is_third_party) {
+ if (!origin_trials::IsTrialEnabledForThirdPartyOrigins(trial_name)) {
+ DVLOG(1) << "ValidateTokenResult: feature disabled for third party trial";
+ return OriginTrialTokenStatus::kFeatureDisabled;
+ }
+ // For third-party tokens, both the current origin and the the script origin
+ // must be secure.
+ is_secure &= is_script_origin_secure;
+ }
+
+ // Origin trials are only enabled for secure origins. The only exception
+ // is for deprecation trials.
+ if (!is_secure &&
+ !origin_trials::IsTrialEnabledForInsecureContext(trial_name)) {
+ DVLOG(1) << "ValidateTokenResult: not secure";
+ return OriginTrialTokenStatus::kInsecure;
+ }
+ return OriginTrialTokenStatus::kSuccess;
+}
+
bool OriginTrialContext::EnableTrialFromToken(const SecurityOrigin* origin,
bool is_secure,
const String& token) {
+ return EnableTrialFromToken(origin, is_secure, nullptr, false, token);
+}
+
+bool OriginTrialContext::EnableTrialFromToken(
+ const SecurityOrigin* origin,
+ bool is_origin_secure,
+ const SecurityOrigin* script_origin,
+ bool is_script_origin_secure,
+ const String& token) {
DCHECK(!token.IsEmpty());
if (!trial_token_validator_) {
@@ -393,33 +492,31 @@ bool OriginTrialContext::EnableTrialFromToken(const SecurityOrigin* origin,
bool valid = false;
StringUTF8Adaptor token_string(token);
+ url::Origin script_url_origin;
+ if (script_origin)
+ script_url_origin = script_origin->ToUrlOrigin();
TrialTokenResult token_result = trial_token_validator_->ValidateToken(
- token_string.AsStringPiece(), origin->ToUrlOrigin(), base::Time::Now());
- DVLOG(1) << "EnableTrialFromToken: token_result = "
- << static_cast<int>(token_result.status) << ", token = " << token;
-
- if (token_result.status == OriginTrialTokenStatus::kSuccess) {
+ token_string.AsStringPiece(), origin->ToUrlOrigin(),
+ script_origin ? &script_url_origin : nullptr, base::Time::Now());
+ DVLOG(1) << "EnableTrialFromToken: token_result = " << token_result.status
+ << ", token = " << token;
+ OriginTrialTokenStatus status = token_result.status;
+ if (status == OriginTrialTokenStatus::kSuccess) {
String trial_name = String::FromUTF8(token_result.feature_name.data(),
token_result.feature_name.size());
if (origin_trials::IsTrialValid(trial_name)) {
- // Origin trials are only enabled for secure origins. The only exception
- // is for deprecation trials.
- if (is_secure ||
- origin_trials::IsTrialEnabledForInsecureContext(trial_name)) {
+ status = ValidateTokenResult(trial_name, is_origin_secure,
+ is_script_origin_secure,
+ token_result.is_third_party);
+ if (status == OriginTrialTokenStatus::kSuccess)
valid = EnableTrialFromName(trial_name, token_result.expiry_time);
- } else {
- // Insecure origin and trial is restricted to secure origins.
- DVLOG(1) << "EnableTrialFromToken: not secure";
- token_result.status = OriginTrialTokenStatus::kInsecure;
- }
}
}
-
- RecordTokenValidationResultHistogram(token_result.status);
+ RecordTokenValidationResultHistogram(status);
return valid;
}
-void OriginTrialContext::Trace(Visitor* visitor) {
+void OriginTrialContext::Trace(Visitor* visitor) const {
visitor->Trace(context_);
}
diff --git a/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.h b/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.h
index c4b6352fa64..9db55366de4 100644
--- a/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.h
+++ b/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.h
@@ -73,10 +73,15 @@ class CORE_EXPORT OriginTrialContext final
const Vector<OriginTrialFeature>*);
void AddToken(const String& token);
+ // Add a token injected from external script. The token may be a third-party
+ // token, which will be validated against the given origin of the injecting
+ // script.
+ void AddTokenFromExternalScript(const String& token,
+ const SecurityOrigin* origin);
void AddTokens(const Vector<String>& tokens);
- void AddTokens(const SecurityOrigin* origin,
- bool is_secure,
- const Vector<String>& tokens);
+ void AddTokens(const Vector<String>& tokens,
+ const SecurityOrigin* origin,
+ bool is_secure);
void ActivateNavigationFeaturesFromInitiator(
const Vector<OriginTrialFeature>& features);
@@ -120,9 +125,17 @@ class CORE_EXPORT OriginTrialContext final
// enabled.
void InitializePendingFeatures();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
+ // Handle token from document origin or third party origins, initialize
+ // features if the token is valid.
+ void AddTokenInternal(const String& token,
+ const SecurityOrigin* origin,
+ bool is_origin_secure,
+ const SecurityOrigin* script_origin,
+ bool is_script_origin_secure);
+
// If this returns false, the trial cannot be enabled (e.g. due to it is
// invalid in the browser's present configuration).
bool CanEnableTrialFromName(const StringView& trial_name);
@@ -137,6 +150,20 @@ class CORE_EXPORT OriginTrialContext final
bool EnableTrialFromToken(const SecurityOrigin* origin,
bool is_secure,
const String& token);
+ // Validate the trial token injected by external script from script_origin.
+ // If is_third_party flag is set on the token, script_origin will be used for
+ // validation. Otherwise it's the same as above.
+ bool EnableTrialFromToken(const SecurityOrigin* origin,
+ bool is_origin_secure,
+ const SecurityOrigin* script_origin,
+ bool is_script_origin_secure,
+ const String& token);
+
+ // Validate the token result returned from token validator.
+ OriginTrialTokenStatus ValidateTokenResult(const String& trial_name,
+ bool is_secure,
+ bool is_secure_script_origin,
+ bool is_third_party);
// Installs JavaScript bindings on the relevant objects for the specified
// OriginTrialFeature.
diff --git a/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context_test.cc b/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context_test.cc
index bfa33fb28be..5536f337608 100644
--- a/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context_test.cc
+++ b/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context_test.cc
@@ -11,6 +11,7 @@
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/feature_policy/feature_policy_parser.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/html/html_head_element.h"
#include "third_party/blink/renderer/core/html/html_meta_element.h"
@@ -30,6 +31,7 @@ namespace {
const char kFrobulateTrialName[] = "Frobulate";
const char kFrobulateDeprecationTrialName[] = "FrobulateDeprecation";
const char kFrobulateNavigationTrialName[] = "FrobulateNavigation";
+const char kFrobulateThirdPartyTrialName[] = "FrobulateThirdParty";
const char kFrobulateEnabledOrigin[] = "https://www.example.com";
const char kFrobulateEnabledOriginUnsecure[] = "http://www.example.com";
@@ -52,14 +54,22 @@ class MockTokenValidator : public TrialTokenValidator {
call_count_++;
return response_;
}
+ TrialTokenResult ValidateToken(base::StringPiece token,
+ const url::Origin& origin,
+ const url::Origin* script_origin,
+ base::Time current_time) const override {
+ return ValidateToken(token, origin, current_time);
+ }
// Useful methods for controlling the validator
void SetResponse(OriginTrialTokenStatus status,
const std::string& feature,
- base::Time expiry = base::Time()) {
+ base::Time expiry = base::Time(),
+ bool is_third_party = false) {
response_.status = status;
response_.feature_name = feature;
response_.expiry_time = expiry;
+ response_.is_third_party = is_third_party;
}
int CallCount() { return call_count_; }
@@ -107,6 +117,20 @@ class OriginTrialContextTest : public testing::Test {
feature);
}
+ bool IsFeatureEnabledForThirdPartyOrigin(const String& origin,
+ const String& script_origin,
+ OriginTrialFeature feature) {
+ UpdateSecurityOrigin(origin);
+ KURL script_url(script_origin);
+ scoped_refptr<const SecurityOrigin> script_security_origin =
+ SecurityOrigin::Create(script_url);
+ // Need at least one token to ensure the token validator is called.
+ execution_context_->GetOriginTrialContext()->AddTokenFromExternalScript(
+ kTokenPlaceholder, script_security_origin.get());
+ return execution_context_->GetOriginTrialContext()->IsFeatureEnabled(
+ feature);
+ }
+
base::Time GetFeatureExpiry(OriginTrialFeature feature) {
return execution_context_->GetOriginTrialContext()->GetFeatureExpiry(
feature);
@@ -239,6 +263,91 @@ TEST_F(OriginTrialContextTest,
EXPECT_FALSE(is_origin_enabled);
}
+// The feature should not be enabled if token is valid and enabled for third
+// party origin but trial is not enabled for third party origin.
+TEST_F(OriginTrialContextTest, EnabledNonThirdPartyTrialWithThirdPartyToken) {
+ TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess,
+ kFrobulateTrialName, base::Time(), true);
+ bool is_origin_enabled = IsFeatureEnabledForThirdPartyOrigin(
+ kFrobulateEnabledOrigin, kFrobulateEnabledOrigin,
+ OriginTrialFeature::kOriginTrialsSampleAPI);
+ EXPECT_FALSE(is_origin_enabled);
+ EXPECT_EQ(1, TokenValidator()->CallCount());
+ ExpectStatusUniqueMetric(OriginTrialTokenStatus::kFeatureDisabled, 1);
+}
+
+// The feature should not be enabled if token is enabled for third
+// party origin but it's not injected by external script.
+TEST_F(OriginTrialContextTest, ThirdPartyTokenNotFromExternalScript) {
+ TokenValidator()->SetResponse(OriginTrialTokenStatus::kWrongOrigin,
+ kFrobulateThirdPartyTrialName, base::Time(),
+ true);
+ bool is_origin_enabled = IsFeatureEnabledForThirdPartyOrigin(
+ kFrobulateEnabledOrigin, kFrobulateEnabledOrigin,
+ OriginTrialFeature::kOriginTrialsSampleAPIThirdParty);
+ EXPECT_FALSE(is_origin_enabled);
+ EXPECT_EQ(1, TokenValidator()->CallCount());
+ ExpectStatusUniqueMetric(OriginTrialTokenStatus::kWrongOrigin, 1);
+}
+
+// The feature should not be enabled if token is injected from insecure external
+// script even if document origin is secure.
+TEST_F(OriginTrialContextTest, ThirdPartyTokenFromInsecureExternalScript) {
+ TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess,
+ kFrobulateThirdPartyTrialName, base::Time(),
+ true);
+ bool is_origin_enabled = IsFeatureEnabledForThirdPartyOrigin(
+ kFrobulateEnabledOrigin, kFrobulateEnabledOriginUnsecure,
+ OriginTrialFeature::kOriginTrialsSampleAPIThirdParty);
+ EXPECT_FALSE(is_origin_enabled);
+ EXPECT_EQ(1, TokenValidator()->CallCount());
+ ExpectStatusUniqueMetric(OriginTrialTokenStatus::kInsecure, 1);
+}
+
+// The feature should not be enabled if token is injected from insecure external
+// script when the document origin is also insecure.
+TEST_F(OriginTrialContextTest,
+ ThirdPartyTokenFromInsecureExternalScriptOnInsecureDocument) {
+ TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess,
+ kFrobulateThirdPartyTrialName, base::Time(),
+ true);
+ bool is_origin_enabled = IsFeatureEnabledForThirdPartyOrigin(
+ kFrobulateEnabledOriginUnsecure, kFrobulateEnabledOriginUnsecure,
+ OriginTrialFeature::kOriginTrialsSampleAPIThirdParty);
+ EXPECT_FALSE(is_origin_enabled);
+ EXPECT_EQ(1, TokenValidator()->CallCount());
+ ExpectStatusUniqueMetric(OriginTrialTokenStatus::kInsecure, 1);
+}
+
+// The feature should not be enabled if token is injected from secure external
+// script when the document is insecure.
+TEST_F(OriginTrialContextTest, ThirdPartyTokenOnInsecureDocument) {
+ TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess,
+ kFrobulateThirdPartyTrialName, base::Time(),
+ true);
+ bool is_origin_enabled = IsFeatureEnabledForThirdPartyOrigin(
+ kFrobulateEnabledOriginUnsecure, kFrobulateEnabledOrigin,
+ OriginTrialFeature::kOriginTrialsSampleAPIThirdParty);
+ EXPECT_FALSE(is_origin_enabled);
+ EXPECT_EQ(1, TokenValidator()->CallCount());
+ ExpectStatusUniqueMetric(OriginTrialTokenStatus::kInsecure, 1);
+}
+
+// The feature should be enabled if 1) token is valid for third party origin
+// 2) token is enabled for third party origin and 3) trial is enabled for
+// third party origin.
+TEST_F(OriginTrialContextTest, EnabledThirdPartyTrialWithThirdPartyToken) {
+ TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess,
+ kFrobulateThirdPartyTrialName, base::Time(),
+ true);
+ bool is_origin_enabled = IsFeatureEnabledForThirdPartyOrigin(
+ kFrobulateEnabledOrigin, kFrobulateEnabledOrigin,
+ OriginTrialFeature::kOriginTrialsSampleAPIThirdParty);
+ EXPECT_TRUE(is_origin_enabled);
+ EXPECT_EQ(1, TokenValidator()->CallCount());
+ ExpectStatusUniqueMetric(OriginTrialTokenStatus::kSuccess, 1);
+}
+
TEST_F(OriginTrialContextTest, ParseHeaderValue) {
std::unique_ptr<Vector<String>> tokens;
ASSERT_TRUE(tokens = OriginTrialContext::ParseHeaderValue(" foo\t "));
@@ -298,10 +407,10 @@ TEST_F(OriginTrialContextTest, ParseHeaderValue_NotCommaSeparated) {
}
TEST_F(OriginTrialContextTest, FeaturePolicy) {
- // Create a dummy document with an OriginTrialContext.
+ // Create a dummy window/document with an OriginTrialContext.
auto dummy = std::make_unique<DummyPageHolder>();
- Document* document = &dummy->GetDocument();
- OriginTrialContext* context = document->GetOriginTrialContext();
+ LocalDOMWindow* window = dummy->GetFrame().DomWindow();
+ OriginTrialContext* context = window->GetOriginTrialContext();
// Enable the sample origin trial API ("Frobulate").
context->AddFeature(OriginTrialFeature::kOriginTrialsSampleAPI);
@@ -316,11 +425,12 @@ TEST_F(OriginTrialContextTest, FeaturePolicy) {
// feature policy is successfully enabled via the origin trial.
scoped_refptr<const SecurityOrigin> security_origin =
SecurityOrigin::CreateFromString(kFrobulateEnabledOrigin);
- Vector<String> messages;
+
+ PolicyParserMessageBuffer logger;
ParsedFeaturePolicy result;
result = FeaturePolicyParser::Parse("frobulate", security_origin, nullptr,
- &messages, feature_map, document);
- EXPECT_TRUE(messages.IsEmpty());
+ logger, feature_map, window);
+ EXPECT_TRUE(logger.GetMessages().IsEmpty());
ASSERT_EQ(1u, result.size());
EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFrobulate, result[0].feature);
}
diff --git a/chromium/third_party/blink/renderer/core/page/BUILD.gn b/chromium/third_party/blink/renderer/core/page/BUILD.gn
index 42581ab6109..0d838c8d3e1 100644
--- a/chromium/third_party/blink/renderer/core/page/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/page/BUILD.gn
@@ -116,5 +116,5 @@ blink_core_sources("page") {
"viewport_description.h",
]
- public_deps = [ "//ui/base/cursor" ]
+ public_deps = [ "//ui/base/cursor:cursor_base" ]
}
diff --git a/chromium/third_party/blink/renderer/core/page/autoscroll_controller.cc b/chromium/third_party/blink/renderer/core/page/autoscroll_controller.cc
index 03fef21a0df..842409734af 100644
--- a/chromium/third_party/blink/renderer/core/page/autoscroll_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/autoscroll_controller.cc
@@ -92,7 +92,7 @@ static const ui::Cursor& MiddleClickAutoscrollCursor(
AutoscrollController::AutoscrollController(Page& page) : page_(&page) {}
-void AutoscrollController::Trace(Visitor* visitor) {
+void AutoscrollController::Trace(Visitor* visitor) const {
visitor->Trace(page_);
}
diff --git a/chromium/third_party/blink/renderer/core/page/autoscroll_controller.h b/chromium/third_party/blink/renderer/core/page/autoscroll_controller.h
index 4a6f4edad3a..7e04c417625 100644
--- a/chromium/third_party/blink/renderer/core/page/autoscroll_controller.h
+++ b/chromium/third_party/blink/renderer/core/page/autoscroll_controller.h
@@ -67,7 +67,7 @@ class CORE_EXPORT AutoscrollController final
public:
explicit AutoscrollController(Page&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// Selection and drag-and-drop autoscroll.
void Animate();
diff --git a/chromium/third_party/blink/renderer/core/page/chrome_client.cc b/chromium/third_party/blink/renderer/core/page/chrome_client.cc
index 89d0c40a289..f562f2d1f8c 100644
--- a/chromium/third_party/blink/renderer/core/page/chrome_client.cc
+++ b/chromium/third_party/blink/renderer/core/page/chrome_client.cc
@@ -43,7 +43,7 @@
namespace blink {
-void ChromeClient::Trace(Visitor* visitor) {
+void ChromeClient::Trace(Visitor* visitor) const {
visitor->Trace(last_mouse_over_node_);
}
@@ -261,11 +261,13 @@ void ChromeClient::SetToolTip(LocalFrame& frame,
last_tool_tip_point_ = location.Point();
last_tool_tip_text_ = tool_tip;
last_mouse_over_node_ = result.InnerNodeOrImageMapImage();
+ current_tool_tip_text_for_test_ = last_tool_tip_text_;
SetToolTip(frame, tool_tip, tool_tip_direction);
}
void ChromeClient::ClearToolTip(LocalFrame& frame) {
- // Do not check m_lastToolTip* and do not update them intentionally.
+ current_tool_tip_text_for_test_ = String();
+ // Do not check last_tool_tip_* and do not update them intentionally.
// We don't want to show tooltips with same content after clearToolTip().
SetToolTip(frame, String(), TextDirection::kLtr);
}
diff --git a/chromium/third_party/blink/renderer/core/page/chrome_client.h b/chromium/third_party/blink/renderer/core/page/chrome_client.h
index 8d4391d7d98..7079dcd64c2 100644
--- a/chromium/third_party/blink/renderer/core/page/chrome_client.h
+++ b/chromium/third_party/blink/renderer/core/page/chrome_client.h
@@ -35,10 +35,10 @@
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "third_party/blink/public/common/dom_storage/session_storage_namespace_id.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
+#include "third_party/blink/public/common/page/web_drag_operation.h"
#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/public/platform/blame_context.h"
-#include "third_party/blink/public/platform/web_drag_operation.h"
#include "third_party/blink/public/platform/web_float_rect.h"
#include "third_party/blink/public/web/web_swap_result.h"
#include "third_party/blink/public/web/web_widget_client.h"
@@ -148,7 +148,8 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
// part of.
virtual IntRect RootWindowRect(LocalFrame&) = 0;
- virtual void Focus(LocalFrame*) = 0;
+ virtual void FocusPage() = 0;
+ virtual void DidFocusPage() = 0;
virtual bool CanTakeFocus(mojom::blink::FocusType) = 0;
virtual void TakeFocus(mojom::blink::FocusType) = 0;
@@ -313,6 +314,9 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
const HitTestResult&);
virtual void SetToolTip(LocalFrame&, const String&, TextDirection) = 0;
void ClearToolTip(LocalFrame&);
+ String GetLastToolTipTextForTesting() {
+ return current_tool_tip_text_for_test_;
+ }
bool Print(LocalFrame*);
@@ -493,7 +497,7 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
// tracing/debugging purposes.
virtual int GetLayerTreeId(LocalFrame& frame) = 0;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
virtual void DidUpdateTextAutosizerPageInfo(const WebTextAutosizerPageInfo&) {
}
@@ -506,6 +510,10 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
// enabled). This only includes the zoom initiated by the user (ctrl +/-).
virtual double UserZoomFactor() const { return 1; }
+ virtual void SetDelegatedInkMetadata(
+ LocalFrame* frame,
+ std::unique_ptr<viz::DelegatedInkMetadata> metadata) {}
+
protected:
ChromeClient() = default;
@@ -537,6 +545,9 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
WeakMember<Node> last_mouse_over_node_;
PhysicalOffset last_tool_tip_point_;
String last_tool_tip_text_;
+ // |last_tool_tip_text_| is kept even if ClearToolTip is called. This is for
+ // the tooltip text that is cleared when ClearToolTip is called.
+ String current_tool_tip_text_for_test_;
FRIEND_TEST_ALL_PREFIXES(ChromeClientTest, SetToolTipFlood);
FRIEND_TEST_ALL_PREFIXES(ChromeClientTest, SetToolTipEmptyString);
diff --git a/chromium/third_party/blink/renderer/core/page/chrome_client_impl.cc b/chromium/third_party/blink/renderer/core/page/chrome_client_impl.cc
index e4267ec821f..45bf5dc5521 100644
--- a/chromium/third_party/blink/renderer/core/page/chrome_client_impl.cc
+++ b/chromium/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -172,7 +172,7 @@ ChromeClientImpl::~ChromeClientImpl() {
DCHECK(file_chooser_queue_.IsEmpty());
}
-void ChromeClientImpl::Trace(Visitor* visitor) {
+void ChromeClientImpl::Trace(Visitor* visitor) const {
visitor->Trace(popup_opening_observers_);
visitor->Trace(external_date_time_chooser_);
ChromeClient::Trace(visitor);
@@ -200,11 +200,13 @@ IntRect ChromeClientImpl::RootWindowRect(LocalFrame& frame) {
return IntRect(client->WindowRect());
}
-void ChromeClientImpl::Focus(LocalFrame* calling_frame) {
- if (web_view_->Client()) {
- web_view_->Client()->DidFocus(
- calling_frame ? WebLocalFrameImpl::FromFrame(calling_frame) : nullptr);
- }
+void ChromeClientImpl::FocusPage() {
+ web_view_->Focus();
+}
+
+void ChromeClientImpl::DidFocusPage() {
+ if (web_view_->Client())
+ web_view_->Client()->DidFocus();
}
bool ChromeClientImpl::CanTakeFocus(mojom::blink::FocusType) {
@@ -285,7 +287,7 @@ void ChromeClientImpl::DidOverscroll(
return;
// TODO(darin): Change caller to pass LocalFrame.
DCHECK(web_view_->MainFrameImpl());
- web_view_->MainFrameImpl()->FrameWidgetImpl()->Client()->DidOverscroll(
+ web_view_->MainFrameImpl()->FrameWidgetImpl()->DidOverscroll(
overscroll_delta, accumulated_overscroll, position_in_viewport,
velocity_in_viewport);
}
@@ -297,9 +299,8 @@ void ChromeClientImpl::InjectGestureScrollEvent(
ScrollGranularity granularity,
CompositorElementId scrollable_area_element_id,
WebInputEvent::Type injected_type) {
- WebWidgetClient* client = local_frame.GetWidgetForLocalRoot()->Client();
- client->InjectGestureScrollEvent(device, delta, granularity,
- scrollable_area_element_id, injected_type);
+ local_frame.GetWidgetForLocalRoot()->InjectGestureScrollEvent(
+ device, delta, granularity, scrollable_area_element_id, injected_type);
}
void ChromeClientImpl::SetOverscrollBehavior(
@@ -351,12 +352,23 @@ bool ChromeClientImpl::CanOpenBeforeUnloadConfirmPanel() {
bool ChromeClientImpl::OpenBeforeUnloadConfirmPanelDelegate(LocalFrame* frame,
bool is_reload) {
NotifyPopupOpeningObservers();
+
+ if (before_unload_confirm_panel_result_for_testing_.has_value()) {
+ bool success = before_unload_confirm_panel_result_for_testing_.value();
+ before_unload_confirm_panel_result_for_testing_.reset();
+ return success;
+ }
bool success = false;
// Synchronous mojo call.
frame->GetLocalFrameHostRemote().RunBeforeUnloadConfirm(is_reload, &success);
return success;
}
+void ChromeClientImpl::SetBeforeUnloadConfirmPanelResultForTesting(
+ bool result) {
+ before_unload_confirm_panel_result_for_testing_ = result;
+}
+
void ChromeClientImpl::CloseWindowSoon() {
if (web_view_->Client())
web_view_->Client()->CloseWindowSoon();
@@ -569,16 +581,16 @@ void ChromeClientImpl::ShowMouseOverURL(const HitTestResult& result) {
void ChromeClientImpl::SetToolTip(LocalFrame& frame,
const String& tooltip_text,
TextDirection dir) {
- WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(frame);
+ WebFrameWidgetBase* widget =
+ WebLocalFrameImpl::FromFrame(frame)->LocalRootFrameWidget();
if (!tooltip_text.IsEmpty()) {
- web_frame->LocalRootFrameWidget()->Client()->SetToolTipText(
- tooltip_text, ToBaseTextDirection(dir));
+ widget->SetToolTipText(tooltip_text, dir);
did_request_non_empty_tool_tip_ = true;
} else if (did_request_non_empty_tool_tip_) {
- // WebWidgetClient::setToolTipText will send an IPC message. We'd like to
- // reduce the number of setToolTipText calls.
- web_frame->LocalRootFrameWidget()->Client()->SetToolTipText(
- tooltip_text, ToBaseTextDirection(dir));
+ // WebFrameWidgetBase::SetToolTipText will send a Mojo message via
+ // mojom::blink::WidgetHost. We'd like to reduce the number of
+ // SetToolTipText calls.
+ widget->SetToolTipText(tooltip_text, dir);
did_request_non_empty_tool_tip_ = false;
}
}
@@ -721,7 +733,7 @@ void ChromeClientImpl::SetCursorInternal(const ui::Cursor& cursor,
// TODO(dcheng): Why is this null check necessary?
if (FrameWidget* widget = local_frame->GetWidgetForLocalRoot())
- widget->Client()->DidChangeCursor(cursor);
+ widget->DidChangeCursor(cursor);
}
void ChromeClientImpl::SetCursorForPlugin(const ui::Cursor& cursor,
@@ -1050,8 +1062,7 @@ void ChromeClientImpl::SetTouchAction(LocalFrame* frame,
if (!widget)
return;
- if (WebWidgetClient* client = widget->Client())
- client->SetTouchAction(static_cast<TouchAction>(touch_action));
+ widget->ProcessTouchAction(touch_action);
}
bool ChromeClientImpl::RequestPointerLock(
@@ -1092,7 +1103,6 @@ void ChromeClientImpl::DidAssociateFormControlsAfterLoad(LocalFrame* frame) {
void ChromeClientImpl::ShowVirtualKeyboardOnElementFocus(LocalFrame& frame) {
WebLocalFrameImpl::FromFrame(frame)
->LocalRootFrameWidget()
- ->Client()
->ShowVirtualKeyboardOnElementFocus();
}
@@ -1123,7 +1133,7 @@ void ChromeClientImpl::DidChangeValueInTextField(
// Value changes caused by |document.execCommand| calls should not be
// interpreted as a user action. See https://crbug.com/764760.
if (!doc.IsRunningExecCommand()) {
- UseCounter::Count(doc, doc.IsSecureContext()
+ UseCounter::Count(doc, doc.GetExecutionContext()->IsSecureContext()
? WebFeature::kFieldEditInSecureContext
: WebFeature::kFieldEditInNonSecureContext);
doc.MaybeQueueSendDidEditFieldInInsecureContext();
@@ -1233,4 +1243,10 @@ double ChromeClientImpl::UserZoomFactor() const {
return PageZoomLevelToZoomFactor(web_view_->ZoomLevel());
}
+void ChromeClientImpl::SetDelegatedInkMetadata(
+ LocalFrame* frame,
+ std::unique_ptr<viz::DelegatedInkMetadata> metadata) {
+ frame->GetWidgetForLocalRoot()->SetDelegatedInkMetadata(std::move(metadata));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/chrome_client_impl.h b/chromium/third_party/blink/renderer/core/page/chrome_client_impl.h
index 85cb78cf795..fce5a33179b 100644
--- a/chromium/third_party/blink/renderer/core/page/chrome_client_impl.h
+++ b/chromium/third_party/blink/renderer/core/page/chrome_client_impl.h
@@ -61,14 +61,15 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
public:
explicit ChromeClientImpl(WebViewImpl*);
~ChromeClientImpl() override;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// ChromeClient methods:
WebViewImpl* GetWebView() const override;
void ChromeDestroyed() override;
void SetWindowRect(const IntRect&, LocalFrame&) override;
IntRect RootWindowRect(LocalFrame&) override;
- void Focus(LocalFrame*) override;
+ void FocusPage() override;
+ void DidFocusPage() override;
bool CanTakeFocus(mojom::blink::FocusType) override;
void TakeFocus(mojom::blink::FocusType) override;
void SetKeyboardFocusURL(Element* new_focus_element) override;
@@ -115,6 +116,10 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
bool CanOpenBeforeUnloadConfirmPanel() override;
bool OpenBeforeUnloadConfirmPanelDelegate(LocalFrame*,
bool is_reload) override;
+ // Used in tests to set a mock value for a before unload confirmation dialog
+ // box. The value is cleared after being read.
+ void SetBeforeUnloadConfirmPanelResultForTesting(bool result_success);
+
void CloseWindowSoon() override;
bool OpenJavaScriptAlertDelegate(LocalFrame*, const String&) override;
bool OpenJavaScriptConfirmDelegate(LocalFrame*, const String&) override;
@@ -199,6 +204,9 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
// ChromeClient methods:
String AcceptLanguages() override;
void SetCursorForPlugin(const ui::Cursor&, LocalFrame*) override;
+ void SetDelegatedInkMetadata(
+ LocalFrame* frame,
+ std::unique_ptr<viz::DelegatedInkMetadata> metadata) override;
// ChromeClientImpl:
void SetNewWindowNavigationPolicy(WebNavigationPolicy);
@@ -298,6 +306,7 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
bool cursor_overridden_;
Member<ExternalDateTimeChooser> external_date_time_chooser_;
bool did_request_non_empty_tool_tip_;
+ base::Optional<bool> before_unload_confirm_panel_result_for_testing_;
FRIEND_TEST_ALL_PREFIXES(FileChooserQueueTest, DerefQueuedChooser);
};
diff --git a/chromium/third_party/blink/renderer/core/page/chrome_client_impl_test.cc b/chromium/third_party/blink/renderer/core/page/chrome_client_impl_test.cc
index efc5c45929e..279c7f8a2df 100644
--- a/chromium/third_party/blink/renderer/core/page/chrome_client_impl_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/chrome_client_impl_test.cc
@@ -109,7 +109,7 @@ class FakeColorChooserClient : public GarbageCollected<FakeColorChooserClient>,
: owner_element_(owner_element) {}
~FakeColorChooserClient() override = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(owner_element_);
ColorChooserClient::Trace(visitor);
}
@@ -139,7 +139,7 @@ class FakeDateTimeChooserClient
: owner_element_(owner_element) {}
~FakeDateTimeChooserClient() override = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(owner_element_);
DateTimeChooserClient::Trace(visitor);
}
@@ -240,7 +240,7 @@ class MockFileChooserClient : public GarbageCollected<MockFileChooserClient>,
public:
explicit MockFileChooserClient(LocalFrame* frame) : frame_(frame) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(frame_);
FileChooserClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/page/chrome_client_test.cc b/chromium/third_party/blink/renderer/core/page/chrome_client_test.cc
index 360f45f00c2..9c0b9d93c8d 100644
--- a/chromium/third_party/blink/renderer/core/page/chrome_client_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/chrome_client_test.cc
@@ -43,7 +43,7 @@ TEST_F(ChromeClientTest, SetToolTipFlood) {
ChromeClient* client = &logger;
HitTestLocation location(PhysicalOffset(10, 20));
HitTestResult result(HitTestRequest(HitTestRequest::kMove), location);
- auto* doc = MakeGarbageCollected<Document>();
+ auto* doc = Document::CreateForTest();
auto* element = MakeGarbageCollected<HTMLElement>(html_names::kDivTag, *doc);
element->setAttribute(html_names::kTitleAttr, "tooltip");
result.SetInnerNode(element);
@@ -76,7 +76,7 @@ TEST_F(ChromeClientTest, SetToolTipEmptyString) {
ChromeClient* client = MakeGarbageCollected<EmptyChromeClient>();
HitTestLocation location(PhysicalOffset(10, 20));
HitTestResult result(HitTestRequest(HitTestRequest::kMove), location);
- auto& doc = *MakeGarbageCollected<Document>();
+ auto& doc = *Document::CreateForTest();
auto& input_element =
*MakeGarbageCollected<HTMLInputElement>(doc, CreateElementFlags());
input_element.setAttribute(html_names::kTypeAttr, "file");
diff --git a/chromium/third_party/blink/renderer/core/page/context_menu_controller.cc b/chromium/third_party/blink/renderer/core/page/context_menu_controller.cc
index 27aa332df8a..536644ad390 100644
--- a/chromium/third_party/blink/renderer/core/page/context_menu_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/context_menu_controller.cc
@@ -46,6 +46,7 @@
#include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h"
#include "third_party/blink/renderer/core/events/mouse_event.h"
#include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/picture_in_picture_controller.h"
#include "third_party/blink/renderer/core/frame/settings.h"
@@ -74,7 +75,7 @@ ContextMenuController::ContextMenuController(Page* page) : page_(page) {}
ContextMenuController::~ContextMenuController() = default;
-void ContextMenuController::Trace(Visitor* visitor) {
+void ContextMenuController::Trace(Visitor* visitor) const {
visitor->Trace(page_);
visitor->Trace(menu_provider_);
visitor->Trace(hit_test_result_);
@@ -430,7 +431,7 @@ bool ContextMenuController::ShowContextMenu(LocalFrame* frame,
WebContextMenuData::kCheckableMenuItemChecked;
}
- data.referrer_policy = selected_frame->GetDocument()->GetReferrerPolicy();
+ data.referrer_policy = selected_frame->DomWindow()->GetReferrerPolicy();
if (menu_provider_) {
// Filter out custom menu elements and add them into the data.
diff --git a/chromium/third_party/blink/renderer/core/page/context_menu_controller.h b/chromium/third_party/blink/renderer/core/page/context_menu_controller.h
index 27492a41cdf..e3629660a8c 100644
--- a/chromium/third_party/blink/renderer/core/page/context_menu_controller.h
+++ b/chromium/third_party/blink/renderer/core/page/context_menu_controller.h
@@ -48,7 +48,7 @@ class CORE_EXPORT ContextMenuController final
public:
explicit ContextMenuController(Page*);
~ContextMenuController();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void ClearContextMenu();
diff --git a/chromium/third_party/blink/renderer/core/page/context_menu_provider.h b/chromium/third_party/blink/renderer/core/page/context_menu_provider.h
index d4051b9068e..9df648c8565 100644
--- a/chromium/third_party/blink/renderer/core/page/context_menu_provider.h
+++ b/chromium/third_party/blink/renderer/core/page/context_menu_provider.h
@@ -41,7 +41,7 @@ struct WebMenuItemInfo;
class ContextMenuProvider : public GarbageCollected<ContextMenuProvider> {
public:
virtual ~ContextMenuProvider() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
virtual WebVector<WebMenuItemInfo> PopulateContextMenu() = 0;
virtual void ContextMenuItemSelected(unsigned action) = 0;
diff --git a/chromium/third_party/blink/renderer/core/page/create_window.cc b/chromium/third_party/blink/renderer/core/page/create_window.cc
index 4c24bcbf3d1..9430b4a8120 100644
--- a/chromium/third_party/blink/renderer/core/page/create_window.cc
+++ b/chromium/third_party/blink/renderer/core/page/create_window.cc
@@ -320,8 +320,8 @@ Frame* CreateNewWindow(LocalFrame& opener_frame,
// TODO(japhet): Does network::mojom::ReferrerPolicy need to be proagated
// for RemoteFrames?
if (new_local_frame) {
- new_local_frame->GetDocument()->SetReferrerPolicy(
- opener_frame.GetDocument()->GetReferrerPolicy());
+ new_local_frame->DomWindow()->SetReferrerPolicy(
+ opener_frame.DomWindow()->GetReferrerPolicy());
}
}
@@ -330,7 +330,7 @@ Frame* CreateNewWindow(LocalFrame& opener_frame,
if (!opener_frame.CanNavigate(*frame))
return nullptr;
if (!features.noopener)
- frame->Client()->SetOpener(&opener_frame);
+ frame->SetOpener(&opener_frame);
return frame;
}
diff --git a/chromium/third_party/blink/renderer/core/page/drag_controller.cc b/chromium/third_party/blink/renderer/core/page/drag_controller.cc
index 0673abb855e..dcb22899b50 100644
--- a/chromium/third_party/blink/renderer/core/page/drag_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/drag_controller.cc
@@ -30,9 +30,9 @@
#include "base/memory/scoped_refptr.h"
#include "build/build_config.h"
+#include "third_party/blink/public/common/page/web_drag_operation.h"
#include "third_party/blink/public/platform/web_common.h"
#include "third_party/blink/public/platform/web_drag_data.h"
-#include "third_party/blink/public/platform/web_drag_operation.h"
#include "third_party/blink/public/platform/web_screen_info.h"
#include "third_party/blink/renderer/core/clipboard/data_object.h"
#include "third_party/blink/renderer/core/clipboard/data_transfer.h"
@@ -712,12 +712,13 @@ bool DragController::CanProcessDrag(DragData* drag_data,
if (!local_root.ContentLayoutObject())
return false;
- PhysicalOffset point = local_root.View()->ConvertFromRootFrame(
- PhysicalOffset::FromFloatPointRound(drag_data->ClientPosition()));
+ const PhysicalOffset point_in_local_root =
+ local_root.View()->ConvertFromRootFrame(
+ PhysicalOffset::FromFloatPointRound(drag_data->ClientPosition()));
- HitTestLocation location(point);
- HitTestResult result =
- local_root.GetEventHandler().HitTestResultAtLocation(location);
+ const HitTestResult result =
+ local_root.GetEventHandler().HitTestResultAtLocation(
+ HitTestLocation(point_in_local_root));
if (!result.InnerNode())
return false;
@@ -732,9 +733,16 @@ bool DragController::CanProcessDrag(DragData* drag_data,
return false;
}
- if (did_initiate_drag_ && document_under_mouse_ == drag_initiator_ &&
- result.IsSelected(location))
- return false;
+ if (did_initiate_drag_ && document_under_mouse_ == drag_initiator_) {
+ const PhysicalOffset point_in_frame =
+ result.InnerNode()
+ ->GetDocument()
+ .GetFrame()
+ ->View()
+ ->ConvertFromRootFrame(PhysicalOffset::FromFloatPointRound(
+ drag_data->ClientPosition()));
+ return !result.IsSelected(HitTestLocation(point_in_frame));
+ }
return true;
}
@@ -753,9 +761,7 @@ static DragOperation DefaultOperationForDrag(DragOperation src_op_mask) {
if (src_op_mask & kDragOperationLink)
return kDragOperationLink;
- // FIXME: Does IE really return "generic" even if no operations were allowed
- // by the source?
- return kDragOperationGeneric;
+ return kDragOperationNone;
}
bool DragController::TryDHTMLDrag(DragData* drag_data,
@@ -1367,7 +1373,7 @@ void DragController::ContextDestroyed() {
drag_state_ = nullptr;
}
-void DragController::Trace(Visitor* visitor) {
+void DragController::Trace(Visitor* visitor) const {
visitor->Trace(page_);
visitor->Trace(document_under_mouse_);
visitor->Trace(drag_initiator_);
diff --git a/chromium/third_party/blink/renderer/core/page/drag_controller.h b/chromium/third_party/blink/renderer/core/page/drag_controller.h
index f6b18181e61..10c95f5abc5 100644
--- a/chromium/third_party/blink/renderer/core/page/drag_controller.h
+++ b/chromium/third_party/blink/renderer/core/page/drag_controller.h
@@ -93,7 +93,7 @@ class CORE_EXPORT DragController final
// ExecutionContextLifecycleObserver.
void ContextDestroyed() final;
- void Trace(Visitor*) final;
+ void Trace(Visitor*) const final;
private:
DispatchEventResult DispatchTextInputEventFor(LocalFrame*, DragData*);
diff --git a/chromium/third_party/blink/renderer/core/page/drag_data.cc b/chromium/third_party/blink/renderer/core/page/drag_data.cc
index 69e381d92eb..b50ffd80d6b 100644
--- a/chromium/third_party/blink/renderer/core/page/drag_data.cc
+++ b/chromium/third_party/blink/renderer/core/page/drag_data.cc
@@ -41,13 +41,11 @@ namespace blink {
DragData::DragData(DataObject* data,
const FloatPoint& client_position,
const FloatPoint& global_position,
- DragOperation source_operation_mask,
- DragApplicationFlags flags)
+ DragOperation source_operation_mask)
: client_position_(client_position),
global_position_(global_position),
platform_drag_data_(data),
- dragging_source_operation_mask_(source_operation_mask),
- application_flags_(flags) {}
+ dragging_source_operation_mask_(source_operation_mask) {}
bool DragData::ContainsHTML() const {
return platform_drag_data_->Types().Contains(kMimeTypeTextHTML);
diff --git a/chromium/third_party/blink/renderer/core/page/drag_data.h b/chromium/third_party/blink/renderer/core/page/drag_data.h
index e59749135cf..5918a350542 100644
--- a/chromium/third_party/blink/renderer/core/page/drag_data.h
+++ b/chromium/third_party/blink/renderer/core/page/drag_data.h
@@ -40,14 +40,6 @@ class DataObject;
class DocumentFragment;
class LocalFrame;
-enum DragApplicationFlags {
- kDragApplicationNone = 0,
- kDragApplicationIsModal = 1,
- kDragApplicationIsSource = 2,
- kDragApplicationHasAttachedSheet = 4,
- kDragApplicationIsCopyKeyDown = 8
-};
-
class CORE_EXPORT DragData {
STACK_ALLOCATED();
@@ -59,11 +51,9 @@ class CORE_EXPORT DragData {
DragData(DataObject*,
const FloatPoint& client_position,
const FloatPoint& global_position,
- DragOperation,
- DragApplicationFlags = kDragApplicationNone);
+ DragOperation);
const FloatPoint& ClientPosition() const { return client_position_; }
const FloatPoint& GlobalPosition() const { return global_position_; }
- DragApplicationFlags Flags() const { return application_flags_; }
DataObject* PlatformData() const { return platform_drag_data_; }
DragOperation DraggingSourceOperationMask() const {
return dragging_source_operation_mask_;
@@ -89,7 +79,6 @@ class CORE_EXPORT DragData {
const FloatPoint global_position_;
DataObject* const platform_drag_data_;
const DragOperation dragging_source_operation_mask_;
- const DragApplicationFlags application_flags_;
bool ContainsHTML() const;
};
diff --git a/chromium/third_party/blink/renderer/core/page/drag_image_test.cc b/chromium/third_party/blink/renderer/core/page/drag_image_test.cc
index ffed0154fca..6a2c5d59475 100644
--- a/chromium/third_party/blink/renderer/core/page/drag_image_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/drag_image_test.cc
@@ -77,6 +77,8 @@ class TestImage : public Image {
}
PaintImage PaintImageForCurrentFrame() override {
+ if (!image_)
+ return PaintImage();
return CreatePaintImageBuilder()
.set_image(image_, cc::PaintImage::GetNextContentId())
.TakePaintImage();
diff --git a/chromium/third_party/blink/renderer/core/page/drag_state.h b/chromium/third_party/blink/renderer/core/page/drag_state.h
index b886c94d278..f9fc5095531 100644
--- a/chromium/third_party/blink/renderer/core/page/drag_state.h
+++ b/chromium/third_party/blink/renderer/core/page/drag_state.h
@@ -45,7 +45,7 @@ class DragState final : public GarbageCollected<DragState> {
// Used on only the source side of dragging.
Member<DataTransfer> drag_data_transfer_;
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(drag_src_);
visitor->Trace(drag_data_transfer_);
}
diff --git a/chromium/third_party/blink/renderer/core/page/focus_controller.cc b/chromium/third_party/blink/renderer/core/page/focus_controller.cc
index dc65fa82354..4a4a65e0526 100644
--- a/chromium/third_party/blink/renderer/core/page/focus_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/focus_controller.cc
@@ -113,7 +113,7 @@ class FocusNavigation : public GarbageCollected<FocusNavigation> {
return FindOwner(*root_);
}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(root_);
visitor->Trace(slot_);
}
@@ -1360,7 +1360,7 @@ void FocusController::NotifyFocusChangedObservers() const {
it->FocusedFrameChanged();
}
-void FocusController::Trace(Visitor* visitor) {
+void FocusController::Trace(Visitor* visitor) const {
visitor->Trace(page_);
visitor->Trace(focused_frame_);
visitor->Trace(focus_changed_observers_);
diff --git a/chromium/third_party/blink/renderer/core/page/focus_controller.h b/chromium/third_party/blink/renderer/core/page/focus_controller.h
index b22ebd992f4..7f1e61819b9 100644
--- a/chromium/third_party/blink/renderer/core/page/focus_controller.h
+++ b/chromium/third_party/blink/renderer/core/page/focus_controller.h
@@ -102,7 +102,7 @@ class CORE_EXPORT FocusController final
void RegisterFocusChangedObserver(FocusChangedObserver*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Element* FindFocusableElement(mojom::blink::FocusType, Element&, OwnerMap&);
diff --git a/chromium/third_party/blink/renderer/core/page/frame_tree.cc b/chromium/third_party/blink/renderer/core/page/frame_tree.cc
index 3c3ef06af37..848f9170ecd 100644
--- a/chromium/third_party/blink/renderer/core/page/frame_tree.cc
+++ b/chromium/third_party/blink/renderer/core/page/frame_tree.cc
@@ -217,7 +217,8 @@ FrameTree::FindResult FrameTree::FindOrCreateFrameForNavigation(
if (frame && !new_window) {
if (frame->GetPage() != current_frame->GetPage())
- frame->GetPage()->GetChromeClient().Focus(current_frame);
+ frame->FocusPage(current_frame);
+
// Focusing can fire onblur, so check for detach.
if (!frame->GetPage())
frame = nullptr;
@@ -349,7 +350,7 @@ Frame* FrameTree::TraverseNext(const Frame* stay_within) const {
return nullptr;
}
-void FrameTree::Trace(Visitor* visitor) {
+void FrameTree::Trace(Visitor* visitor) const {
visitor->Trace(this_frame_);
}
diff --git a/chromium/third_party/blink/renderer/core/page/frame_tree.h b/chromium/third_party/blink/renderer/core/page/frame_tree.h
index 8bfb2cd5898..43c3e5d7250 100644
--- a/chromium/third_party/blink/renderer/core/page/frame_tree.h
+++ b/chromium/third_party/blink/renderer/core/page/frame_tree.h
@@ -87,7 +87,7 @@ class CORE_EXPORT FrameTree final {
unsigned ScopedChildCount() const;
void InvalidateScopedChildCount();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Frame* FindFrameForNavigationInternal(const AtomicString& name,
diff --git a/chromium/third_party/blink/renderer/core/page/link_highlight.cc b/chromium/third_party/blink/renderer/core/page/link_highlight.cc
index 2bf0e6a56f4..9d7882d95f1 100644
--- a/chromium/third_party/blink/renderer/core/page/link_highlight.cc
+++ b/chromium/third_party/blink/renderer/core/page/link_highlight.cc
@@ -25,7 +25,7 @@ LinkHighlight::~LinkHighlight() {
RemoveHighlight();
}
-void LinkHighlight::Trace(Visitor* visitor) {
+void LinkHighlight::Trace(Visitor* visitor) const {
visitor->Trace(page_);
}
diff --git a/chromium/third_party/blink/renderer/core/page/link_highlight.h b/chromium/third_party/blink/renderer/core/page/link_highlight.h
index 9e793ff77b3..7dc64a7a640 100644
--- a/chromium/third_party/blink/renderer/core/page/link_highlight.h
+++ b/chromium/third_party/blink/renderer/core/page/link_highlight.h
@@ -28,7 +28,7 @@ class CORE_EXPORT LinkHighlight final : public GarbageCollected<LinkHighlight> {
explicit LinkHighlight(Page&);
virtual ~LinkHighlight();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
void ResetForPageNavigation();
diff --git a/chromium/third_party/blink/renderer/core/page/named_pages_mapper.cc b/chromium/third_party/blink/renderer/core/page/named_pages_mapper.cc
index 7a000869f81..060d9662514 100644
--- a/chromium/third_party/blink/renderer/core/page/named_pages_mapper.cc
+++ b/chromium/third_party/blink/renderer/core/page/named_pages_mapper.cc
@@ -32,6 +32,11 @@ void NamedPagesMapper::AddNamedPage(const AtomicString& page_name,
entries_.emplace_back(page_name);
}
+void NamedPagesMapper::NameFirstPage(const AtomicString& page_name) {
+ DCHECK_GE(entries_.size(), 1u);
+ entries_.front().page_name = page_name;
+}
+
const AtomicString& NamedPagesMapper::NamedPageAtIndex(int page_index) const {
for (const Entry& entry : entries_) {
if (page_index <= entry.last_page_index)
diff --git a/chromium/third_party/blink/renderer/core/page/named_pages_mapper.h b/chromium/third_party/blink/renderer/core/page/named_pages_mapper.h
index ec244e81006..f9b6a602d01 100644
--- a/chromium/third_party/blink/renderer/core/page/named_pages_mapper.h
+++ b/chromium/third_party/blink/renderer/core/page/named_pages_mapper.h
@@ -33,6 +33,11 @@ class CORE_EXPORT NamedPagesMapper {
// deleted.
void AddNamedPage(const AtomicString& page_name, int page_index);
+ // Give the first page a name. We normally name pages as we go through layout
+ // and find breaks needed because of named pages, but if the first page has a
+ // name, it means that no break is inserted there.
+ void NameFirstPage(const AtomicString& page_name);
+
const AtomicString& LastPageName() const { return entries_.back().page_name; }
const AtomicString& NamedPageAtIndex(int page_index) const;
diff --git a/chromium/third_party/blink/renderer/core/page/named_pages_mapper_test.cc b/chromium/third_party/blink/renderer/core/page/named_pages_mapper_test.cc
index 566eebf9d65..5187da55840 100644
--- a/chromium/third_party/blink/renderer/core/page/named_pages_mapper_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/named_pages_mapper_test.cc
@@ -121,5 +121,25 @@ TEST(NamedPagesMapperTest, FirstPageIsNamed) {
EXPECT_EQ(mapper.NamedPageAtIndex(100), "xxx");
}
+TEST(NamedPagesMapperTest, NameFirstPage) {
+ NamedPagesMapper mapper;
+ mapper.AddNamedPage("named", 2);
+ mapper.AddNamedPage("another", 3);
+ EXPECT_EQ(mapper.LastPageName(), "another");
+ EXPECT_EQ(mapper.NamedPageAtIndex(0), AtomicString());
+ EXPECT_EQ(mapper.NamedPageAtIndex(1), AtomicString());
+ EXPECT_EQ(mapper.NamedPageAtIndex(2), "named");
+ EXPECT_EQ(mapper.NamedPageAtIndex(3), "another");
+ EXPECT_EQ(mapper.NamedPageAtIndex(100), "another");
+
+ mapper.NameFirstPage("rootname");
+ EXPECT_EQ(mapper.LastPageName(), "another");
+ EXPECT_EQ(mapper.NamedPageAtIndex(0), "rootname");
+ EXPECT_EQ(mapper.NamedPageAtIndex(1), "rootname");
+ EXPECT_EQ(mapper.NamedPageAtIndex(2), "named");
+ EXPECT_EQ(mapper.NamedPageAtIndex(3), "another");
+ EXPECT_EQ(mapper.NamedPageAtIndex(100), "another");
+}
+
} // anonymous namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/page.cc b/chromium/third_party/blink/renderer/core/page/page.cc
index 608f9d8f2b4..8f2a7581185 100644
--- a/chromium/third_party/blink/renderer/core/page/page.cc
+++ b/chromium/third_party/blink/renderer/core/page/page.cc
@@ -21,8 +21,10 @@
#include "third_party/blink/renderer/core/page/page.h"
+#include "base/compiler_specific.h"
#include "base/feature_list.h"
#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink-forward.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
@@ -32,6 +34,7 @@
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/css/vision_deficiency.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/dom/node_rare_data.h"
#include "third_party/blink/renderer/core/dom/visited_link_state.h"
#include "third_party/blink/renderer/core/editing/drag_caret.h"
#include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
@@ -52,6 +55,7 @@
#include "third_party/blink/renderer/core/frame/viewport_data.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
+#include "third_party/blink/renderer/core/html/portal/document_portals.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/inspector/console_message_storage.h"
#include "third_party/blink/renderer/core/inspector/inspector_issue_storage.h"
@@ -89,6 +93,19 @@
namespace blink {
+namespace {
+// This seems like a reasonable upper bound, and otherwise mutually
+// recursive frameset pages can quickly bring the program to its knees
+// with exponential growth in the number of frames.
+const int kMaxNumberOfFrames = 1000;
+
+// It is possible to use a reduced frame limit for testing, but only two values
+// are permitted, the default or reduced limit.
+const int kTenFrames = 10;
+
+bool g_limit_max_frames_to_ten_for_testing = false;
+} // namespace
+
// Function defined in third_party/blink/public/web/blink.h.
void ResetPluginCache(bool reload_pages) {
// At this point we already know that the browser has refreshed its list, so
@@ -199,11 +216,9 @@ Page::Page(PageClients& page_clients)
MakeGarbageCollected<ValidationMessageClientImpl>(*this)),
opened_by_dom_(false),
tab_key_cycles_through_elements_(true),
- paused_(false),
device_scale_factor_(1),
visibility_state_(mojom::blink::PageVisibilityState::kVisible),
is_ordinary_(false),
- page_lifecycle_state_(kDefaultPageLifecycleState),
is_cursor_visible_(true),
subframe_count_(0),
next_related_page_(this),
@@ -232,7 +247,7 @@ void Page::CloseSoon() {
// TODO(dcheng): Try to remove this in a followup, it's not obviously needed.
if (auto* main_local_frame = DynamicTo<LocalFrame>(main_frame_.Get()))
- main_local_frame->Loader().StopAllLoaders();
+ main_local_frame->Loader().StopAllLoaders(/*abort_client=*/true);
GetChromeClient().CloseWindowSoon();
}
@@ -328,9 +343,6 @@ void Page::DocumentDetached(Document* document) {
if (validation_message_client_)
validation_message_client_->DocumentDetached(*document);
- if (agent_metrics_collector_)
- agent_metrics_collector_->DidDetachDocument(*document);
-
GetChromeClient().DocumentDetached(*document);
}
@@ -416,13 +428,11 @@ void Page::SetPaused(bool paused) {
return;
paused_ = paused;
- mojom::FrameLifecycleState state = paused
- ? mojom::FrameLifecycleState::kPaused
- : mojom::FrameLifecycleState::kRunning;
for (Frame* frame = MainFrame(); frame;
frame = frame->Tree().TraverseNext()) {
- if (auto* local_frame = DynamicTo<LocalFrame>(frame))
- local_frame->SetLifecycleState(state);
+ if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
+ local_frame->OnPageLifecycleStateUpdated();
+ }
}
}
@@ -540,55 +550,46 @@ bool Page::IsPageVisible() const {
return visibility_state_ == mojom::blink::PageVisibilityState::kVisible;
}
-void Page::SetLifecycleState(PageLifecycleState state) {
- if (state == page_lifecycle_state_)
+void Page::OnSetPageFrozen(bool frozen) {
+ if (frozen_ == frozen)
return;
- DCHECK_NE(state, PageLifecycleState::kUnknown);
-
- base::Optional<mojom::FrameLifecycleState> next_state;
- if (state == PageLifecycleState::kFrozen) {
- next_state = mojom::FrameLifecycleState::kFrozen;
- } else if (page_lifecycle_state_ == PageLifecycleState::kFrozen) {
- // TODO(fmeawad): Only resume the page that just became visible, blocked
- // on task queues per frame.
- DCHECK(state == PageLifecycleState::kActive ||
- state == PageLifecycleState::kHiddenBackgrounded ||
- state == PageLifecycleState::kHiddenForegrounded);
- next_state = mojom::FrameLifecycleState::kRunning;
- }
+ frozen_ = frozen;
- if (next_state) {
- const bool dispatch_before_unload_on_freeze =
- base::FeatureList::IsEnabled(features::kDispatchBeforeUnloadOnFreeze);
- for (Frame* frame = main_frame_.Get(); frame;
- frame = frame->Tree().TraverseNext()) {
- if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
- // TODO(chrisha): Determine if dispatching the before unload
- // makes sense and if so put it into a specification.
- if (dispatch_before_unload_on_freeze &&
- next_state == mojom::FrameLifecycleState::kFrozen) {
- local_frame->DispatchBeforeUnloadEventForFreeze();
- }
- local_frame->SetLifecycleState(next_state.value());
- }
+ for (Frame* frame = main_frame_.Get(); frame;
+ frame = frame->Tree().TraverseNext()) {
+ if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
+ local_frame->OnPageLifecycleStateUpdated();
}
}
- page_lifecycle_state_ = state;
-}
-
-PageLifecycleState Page::LifecycleState() const {
- return page_lifecycle_state_;
}
bool Page::IsCursorVisible() const {
return is_cursor_visible_;
}
+// static
+int Page::MaxNumberOfFrames() {
+ if (UNLIKELY(g_limit_max_frames_to_ten_for_testing))
+ return kTenFrames;
+ return kMaxNumberOfFrames;
+}
+
+// static
+void Page::SetMaxNumberOfFramesToTenForTesting(bool enabled) {
+ g_limit_max_frames_to_ten_for_testing = enabled;
+}
+
#if DCHECK_IS_ON()
void CheckFrameCountConsistency(int expected_frame_count, Frame* frame) {
DCHECK_GE(expected_frame_count, 0);
int actual_frame_count = 0;
+
+ if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
+ actual_frame_count += static_cast<int>(
+ DocumentPortals::From(*local_frame->GetDocument()).GetPortals().size());
+ }
+
for (; frame; frame = frame->Tree().TraverseNext())
++actual_frame_count;
@@ -886,7 +887,7 @@ void Page::AcceptLanguagesChanged() {
frames[i]->DomWindow()->AcceptLanguagesChanged();
}
-void Page::Trace(Visitor* visitor) {
+void Page::Trace(Visitor* visitor) const {
visitor->Trace(animator_);
visitor->Trace(autoscroll_controller_);
visitor->Trace(chrome_client_);
@@ -1089,4 +1090,12 @@ void Page::PrepareForLeakDetection() {
page->RemoveSupplement<InternalSettingsPageSupplementBase>();
}
+// Ensure the 10 bits reserved for connected frame count in NodeRareData are
+// sufficient.
+static_assert(kMaxNumberOfFrames <
+ (1 << NodeRareData::kConnectedFrameCountBits),
+ "Frame limit should fit in rare data count");
+static_assert(kTenFrames < kMaxNumberOfFrames,
+ "Reduced frame limit for testing should actually be lower");
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/page.h b/chromium/third_party/blink/renderer/core/page/page.h
index 181c13e9e6e..d397e83eb4d 100644
--- a/chromium/third_party/blink/renderer/core/page/page.h
+++ b/chromium/third_party/blink/renderer/core/page/page.h
@@ -246,6 +246,10 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
bool Paused() const { return paused_; }
void SetPaused(bool);
+ // Frozen state corresponds to "lifecycle state for CPU suspension"
+ // https://wicg.github.io/page-lifecycle/#sec-lifecycle-states
+ bool Frozen() const { return frozen_; }
+
void SetPageScaleFactor(float);
float PageScaleFactor() const;
@@ -270,16 +274,13 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
mojom::blink::PageVisibilityState GetVisibilityState() const;
bool IsPageVisible() const;
- PageLifecycleState LifecycleState() const;
-
bool IsCursorVisible() const;
void SetIsCursorVisible(bool is_visible) { is_cursor_visible_ = is_visible; }
// Don't allow more than a certain number of frames in a page.
- // This seems like a reasonable upper bound, and otherwise mutually
- // recursive frameset pages can quickly bring the program to its knees
- // with exponential growth in the number of frames.
- static const int kMaxNumberOfFrames = 1000;
+ static int MaxNumberOfFrames();
+ static void SetMaxNumberOfFramesToTenForTesting(bool enabled);
+
void IncrementSubframeCount() { ++subframe_count_; }
void DecrementSubframeCount() {
DCHECK_GT(subframe_count_, 0);
@@ -300,7 +301,7 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
void AcceptLanguagesChanged();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void AnimationHostInitialized(cc::AnimationHost&, LocalFrameView*);
void WillCloseAnimationHost(LocalFrameView*);
@@ -317,7 +318,7 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
bool IsOrdinary() const override;
void ReportIntervention(const String& message) override;
bool RequestBeginMainFrameNotExpected(bool new_state) override;
- void SetLifecycleState(PageLifecycleState) override;
+ void OnSetPageFrozen(bool is_frozen) override;
bool LocalMainFrameNetworkIsAlmostIdle() const override;
void AddAutoplayFlags(int32_t flags);
@@ -425,7 +426,6 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
bool is_closing_;
bool tab_key_cycles_through_elements_;
- bool paused_;
float device_scale_factor_;
@@ -433,10 +433,16 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
bool is_ordinary_;
- PageLifecycleState page_lifecycle_state_;
-
bool is_cursor_visible_;
+ // See Page::Paused and Page::Frozen for the detailed description of paused
+ // and frozen state. The main distinction is that "frozen" state is
+ // web-exposed (onfreeze / onresume) and controlled from the browser process,
+ // while "paused" state is an implementation detail of handling sync IPCs and
+ // controlled from the renderer.
+ bool paused_ = false;
+ bool frozen_ = false;
+
#if DCHECK_IS_ON()
bool is_painting_ = false;
#endif
diff --git a/chromium/third_party/blink/renderer/core/page/page_animator.cc b/chromium/third_party/blink/renderer/core/page/page_animator.cc
index e05f3c22d1f..c9caf01bffb 100644
--- a/chromium/third_party/blink/renderer/core/page/page_animator.cc
+++ b/chromium/third_party/blink/renderer/core/page/page_animator.cc
@@ -39,7 +39,7 @@ PageAnimator::PageAnimator(Page& page)
servicing_animations_(false),
updating_layout_and_style_for_painting_(false) {}
-void PageAnimator::Trace(Visitor* visitor) {
+void PageAnimator::Trace(Visitor* visitor) const {
visitor->Trace(page_);
}
@@ -61,7 +61,6 @@ void PageAnimator::ServiceScriptedAnimations(
if (document->View()->ShouldThrottleRendering()) {
document->GetDocumentAnimations()
.UpdateAnimationTimingForAnimationFrame();
- document->SetCurrentFrameIsThrottled(true);
continue;
}
// Disallow throttling in case any script needs to do a synchronous
@@ -109,11 +108,6 @@ void PageAnimator::PostAnimate() {
documents.push_back(To<LocalFrame>(frame)->GetDocument());
}
- // Run the post-animation frame callbacks. See
- // https://github.com/WICG/requestPostAnimationFrame
- for (auto& document : documents)
- document->RunPostAnimationFrameCallbacks();
-
// If we don't have an imminently incoming frame, we need to let the
// AnimationClock update its own time to properly service out-of-lifecycle
// events such as setInterval (see https://crbug.com/995806). This isn't a
diff --git a/chromium/third_party/blink/renderer/core/page/page_animator.h b/chromium/third_party/blink/renderer/core/page/page_animator.h
index 181a6e5f37a..668870277de 100644
--- a/chromium/third_party/blink/renderer/core/page/page_animator.h
+++ b/chromium/third_party/blink/renderer/core/page/page_animator.h
@@ -23,7 +23,7 @@ class CORE_EXPORT PageAnimator final : public GarbageCollected<PageAnimator> {
public:
explicit PageAnimator(Page&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void ScheduleVisualUpdate(LocalFrame*);
void ServiceScriptedAnimations(
base::TimeTicks monotonic_animation_start_time);
diff --git a/chromium/third_party/blink/renderer/core/page/page_popup_controller.cc b/chromium/third_party/blink/renderer/core/page/page_popup_controller.cc
index 5985d67b1b7..4d14a5f9be6 100644
--- a/chromium/third_party/blink/renderer/core/page/page_popup_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/page_popup_controller.cc
@@ -114,7 +114,7 @@ void PagePopupController::setWindowRect(int x, int y, int width, int height) {
popup_.SetWindowRect(IntRect(x, y, width, height));
}
-void PagePopupController::Trace(Visitor* visitor) {
+void PagePopupController::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
Supplement<Page>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/page/page_popup_controller.h b/chromium/third_party/blink/renderer/core/page/page_popup_controller.h
index 2e256d7f5de..cde742e43bb 100644
--- a/chromium/third_party/blink/renderer/core/page/page_popup_controller.h
+++ b/chromium/third_party/blink/renderer/core/page/page_popup_controller.h
@@ -68,7 +68,7 @@ class PagePopupController : public ScriptWrappable, public Supplement<Page> {
static CSSFontSelector* CreateCSSFontSelector(Document& popup_document);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
PagePopup& popup_;
diff --git a/chromium/third_party/blink/renderer/core/page/page_visibility_observer.cc b/chromium/third_party/blink/renderer/core/page/page_visibility_observer.cc
index 2cab0c51ea9..9ad5f413d2d 100644
--- a/chromium/third_party/blink/renderer/core/page/page_visibility_observer.cc
+++ b/chromium/third_party/blink/renderer/core/page/page_visibility_observer.cc
@@ -29,7 +29,7 @@ void PageVisibilityObserver::SetPage(Page* page) {
page_->PageVisibilityObserverList().AddObserver(this);
}
-void PageVisibilityObserver::Trace(Visitor* visitor) {
+void PageVisibilityObserver::Trace(Visitor* visitor) const {
visitor->Trace(page_);
}
diff --git a/chromium/third_party/blink/renderer/core/page/page_visibility_observer.h b/chromium/third_party/blink/renderer/core/page/page_visibility_observer.h
index 29e0b32773e..26aee04792e 100644
--- a/chromium/third_party/blink/renderer/core/page/page_visibility_observer.h
+++ b/chromium/third_party/blink/renderer/core/page/page_visibility_observer.h
@@ -44,7 +44,7 @@ class CORE_EXPORT PageVisibilityObserver : public GarbageCollectedMixin {
Page* GetPage() const { return page_; }
void SetPage(Page*);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
protected:
explicit PageVisibilityObserver(Page*);
diff --git a/chromium/third_party/blink/renderer/core/page/plugin_data.cc b/chromium/third_party/blink/renderer/core/page/plugin_data.cc
index 9b6a945105c..89beb74dae8 100644
--- a/chromium/third_party/blink/renderer/core/page/plugin_data.cc
+++ b/chromium/third_party/blink/renderer/core/page/plugin_data.cc
@@ -33,7 +33,7 @@
namespace blink {
-void MimeClassInfo::Trace(Visitor* visitor) {
+void MimeClassInfo::Trace(Visitor* visitor) const {
visitor->Trace(plugin_);
}
@@ -42,7 +42,7 @@ MimeClassInfo::MimeClassInfo(const String& type,
PluginInfo& plugin)
: type_(type), description_(description), plugin_(&plugin) {}
-void PluginInfo::Trace(Visitor* visitor) {
+void PluginInfo::Trace(Visitor* visitor) const {
visitor->Trace(mimes_);
}
@@ -80,7 +80,7 @@ wtf_size_t PluginInfo::GetMimeClassInfoSize() const {
return mimes_.size();
}
-void PluginData::Trace(Visitor* visitor) {
+void PluginData::Trace(Visitor* visitor) const {
visitor->Trace(plugins_);
visitor->Trace(mimes_);
}
diff --git a/chromium/third_party/blink/renderer/core/page/plugin_data.h b/chromium/third_party/blink/renderer/core/page/plugin_data.h
index d0260f9f6b1..fe5aa20243d 100644
--- a/chromium/third_party/blink/renderer/core/page/plugin_data.h
+++ b/chromium/third_party/blink/renderer/core/page/plugin_data.h
@@ -35,7 +35,7 @@ class PluginInfo;
class CORE_EXPORT MimeClassInfo final : public GarbageCollected<MimeClassInfo> {
public:
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
MimeClassInfo(const String& type, const String& desc, PluginInfo&);
@@ -55,7 +55,7 @@ class CORE_EXPORT MimeClassInfo final : public GarbageCollected<MimeClassInfo> {
class CORE_EXPORT PluginInfo final : public GarbageCollected<PluginInfo> {
public:
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
PluginInfo(const String& name,
const String& filename,
@@ -90,7 +90,7 @@ class CORE_EXPORT PluginInfo final : public GarbageCollected<PluginInfo> {
class CORE_EXPORT PluginData final : public GarbageCollected<PluginData> {
public:
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
PluginData() = default;
diff --git a/chromium/third_party/blink/renderer/core/page/pointer_lock_controller.cc b/chromium/third_party/blink/renderer/core/page/pointer_lock_controller.cc
index 11281892726..dc60c252125 100644
--- a/chromium/third_party/blink/renderer/core/page/pointer_lock_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/pointer_lock_controller.cc
@@ -60,27 +60,25 @@ ScriptPromise PointerLockController::RequestPointerLock(
return promise;
}
- target->GetDocument().CountUseOnlyInCrossOriginIframe(
+ LocalDOMWindow* window = To<LocalDOMWindow>(target->GetExecutionContext());
+ window->CountUseOnlyInCrossOriginIframe(
WebFeature::kElementRequestPointerLockIframe);
if (target->IsInShadowTree()) {
- UseCounter::Count(target->GetDocument(),
- WebFeature::kElementRequestPointerLockInShadow);
+ UseCounter::Count(window, WebFeature::kElementRequestPointerLockInShadow);
}
if (options && options->unadjustedMovement()) {
- UseCounter::Count(target->GetDocument(),
- WebFeature::kPointerLockUnadjustedMovement);
+ UseCounter::Count(window, WebFeature::kPointerLockUnadjustedMovement);
}
- if (target->GetDocument().IsSandboxed(
+ if (window->IsSandboxed(
network::mojom::blink::WebSandboxFlags::kPointerLock)) {
// FIXME: This message should be moved off the console once a solution to
// https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
- target->GetDocument().AddConsoleMessage(
- MakeGarbageCollected<ConsoleMessage>(
- mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError,
- "Blocked pointer lock on an element because the element's frame is "
- "sandboxed and the 'allow-pointer-lock' permission is not set."));
+ window->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kSecurity,
+ mojom::blink::ConsoleMessageLevel::kError,
+ "Blocked pointer lock on an element because the element's frame is "
+ "sandboxed and the 'allow-pointer-lock' permission is not set."));
EnqueueEvent(event_type_names::kPointerlockerror, target);
exception_state.ThrowSecurityError(
"Blocked pointer lock on an element because the element's frame is "
@@ -104,7 +102,7 @@ ScriptPromise PointerLockController::RequestPointerLock(
// Attempt to change options if necessary.
if (unadjusted_movement_requested != current_unadjusted_movement_setting_) {
if (!page_->GetChromeClient().RequestPointerLockChange(
- target->GetDocument().GetFrame(),
+ window->GetFrame(),
WTF::Bind(&PointerLockController::ChangeLockRequestCallback,
WrapWeakPersistent(this), WrapWeakPersistent(target),
WrapPersistent(resolver),
@@ -123,7 +121,7 @@ ScriptPromise PointerLockController::RequestPointerLock(
// Subsequent steps are handled in the browser process.
} else if (page_->GetChromeClient().RequestPointerLock(
- target->GetDocument().GetFrame(),
+ window->GetFrame(),
WTF::Bind(&PointerLockController::LockRequestCallback,
WrapWeakPersistent(this), WrapPersistent(resolver),
unadjusted_movement_requested),
@@ -334,10 +332,19 @@ void PointerLockController::EnqueueEvent(const AtomicString& type,
}
}
-void PointerLockController::Trace(Visitor* visitor) {
+void PointerLockController::Trace(Visitor* visitor) const {
visitor->Trace(page_);
visitor->Trace(element_);
visitor->Trace(document_of_removed_element_while_waiting_for_unlock_);
}
+// static
+Element* PointerLockController::GetPointerLockedElement(LocalFrame* frame) {
+ if (Page* p = frame->GetPage()) {
+ if (!p->GetPointerLockController().LockPending())
+ return p->GetPointerLockController().GetElement();
+ }
+ return nullptr;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/pointer_lock_controller.h b/chromium/third_party/blink/renderer/core/page/pointer_lock_controller.h
index 0e5cb12c531..30cc549972e 100644
--- a/chromium/third_party/blink/renderer/core/page/pointer_lock_controller.h
+++ b/chromium/third_party/blink/renderer/core/page/pointer_lock_controller.h
@@ -74,7 +74,9 @@ class CORE_EXPORT PointerLockController final
// changed if pointer is not locked.
void GetPointerLockPosition(FloatPoint* lock_position,
FloatPoint* lock_screen_position);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
+
+ static Element* GetPointerLockedElement(LocalFrame* frame);
private:
void ClearElement();
diff --git a/chromium/third_party/blink/renderer/core/page/print_context.cc b/chromium/third_party/blink/renderer/core/page/print_context.cc
index 6db481721e1..d4065c2f4bf 100644
--- a/chromium/third_party/blink/renderer/core/page/print_context.cc
+++ b/chromium/third_party/blink/renderer/core/page/print_context.cc
@@ -325,7 +325,7 @@ bool PrintContext::IsFrameValid() const {
frame_->GetDocument()->GetLayoutView();
}
-void PrintContext::Trace(Visitor* visitor) {
+void PrintContext::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(linked_destinations_);
}
diff --git a/chromium/third_party/blink/renderer/core/page/print_context.h b/chromium/third_party/blink/renderer/core/page/print_context.h
index c58518d79c3..28786678c6b 100644
--- a/chromium/third_party/blink/renderer/core/page/print_context.h
+++ b/chromium/third_party/blink/renderer/core/page/print_context.h
@@ -103,7 +103,7 @@ class CORE_EXPORT PrintContext : public GarbageCollected<PrintContext> {
int margin_left);
static int NumberOfPages(LocalFrame*, const FloatSize& page_size_in_pixels);
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
bool use_printing_layout() const;
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc b/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc
index 66e45f475a4..7e0c6fb83b9 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc
@@ -171,7 +171,7 @@ void ElementFragmentAnchor::DidScroll(mojom::blink::ScrollType type) {
needs_invoke_ = false;
}
-void ElementFragmentAnchor::Trace(Visitor* visitor) {
+void ElementFragmentAnchor::Trace(Visitor* visitor) const {
visitor->Trace(anchor_node_);
visitor->Trace(frame_);
FragmentAnchor::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.h b/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.h
index 56998427d8f..ae6cdfeceb0 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.h
@@ -55,7 +55,7 @@ class CORE_EXPORT ElementFragmentAnchor final : public FragmentAnchor {
// Does nothing as an element anchor does not have any dismissal work.
bool Dismiss() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
FRIEND_TEST_ALL_PREFIXES(ElementFragmentAnchorTest,
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/fragment_anchor.cc b/chromium/third_party/blink/renderer/core/page/scrolling/fragment_anchor.cc
index 0d8e0886b96..ab0905757bf 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/fragment_anchor.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/fragment_anchor.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/page/scrolling/fragment_anchor.h"
#include "base/metrics/histogram_macros.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/html_document.h"
@@ -22,8 +23,7 @@ FragmentAnchor* FragmentAnchor::TryCreate(const KURL& url,
FragmentAnchor* anchor = nullptr;
const bool text_fragment_identifiers_enabled =
- RuntimeEnabledFeatures::TextFragmentIdentifiersEnabled(
- frame.GetDocument());
+ RuntimeEnabledFeatures::TextFragmentIdentifiersEnabled(frame.DomWindow());
// The text fragment anchor will be created if we successfully parsed the
// text directive but we only do the text matching later on.
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/fragment_anchor.h b/chromium/third_party/blink/renderer/core/page/scrolling/fragment_anchor.h
index e8d1eddcff1..d7c38a949a2 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/fragment_anchor.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/fragment_anchor.h
@@ -57,7 +57,7 @@ class CORE_EXPORT FragmentAnchor : public GarbageCollected<FragmentAnchor> {
// dismissed and can be disposed.
virtual bool Dismiss() = 0;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc
index d8c85d609f0..460fcc1c093 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc
@@ -299,8 +299,7 @@ class NonCompositedMainThreadScrollingReasonsTest
: public MainThreadScrollingReasonsTest {
static const uint32_t kLCDTextRelatedReasons =
cc::MainThreadScrollingReason::kHasTransformAndLCDText |
- cc::MainThreadScrollingReason::kBackgroundNotOpaqueInRectAndLCDText |
- cc::MainThreadScrollingReason::kIsNotStackingContextAndLCDText;
+ cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText;
protected:
NonCompositedMainThreadScrollingReasonsTest() {
@@ -387,64 +386,24 @@ TEST_F(NonCompositedMainThreadScrollingReasonsTest, TransformTest) {
TEST_F(NonCompositedMainThreadScrollingReasonsTest, BackgroundNotOpaqueTest) {
TestNonCompositedReasons(
"background-not-opaque",
- cc::MainThreadScrollingReason::kBackgroundNotOpaqueInRectAndLCDText);
+ cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText);
}
TEST_F(NonCompositedMainThreadScrollingReasonsTest,
CantPaintScrollingBackgroundTest) {
TestNonCompositedReasons(
"cant-paint-scrolling-background",
- cc::MainThreadScrollingReason::kCantPaintScrollingBackground);
+ cc::MainThreadScrollingReason::kCantPaintScrollingBackgroundAndLCDText);
}
TEST_F(NonCompositedMainThreadScrollingReasonsTest, ClipTest) {
- TestNonCompositedReasons(
- "clip", cc::MainThreadScrollingReason::kHasClipRelatedProperty |
- cc::MainThreadScrollingReason::kCantPaintScrollingBackground);
+ TestNonCompositedReasons("clip",
+ cc::MainThreadScrollingReason::kNotScrollingOnMain);
}
TEST_F(NonCompositedMainThreadScrollingReasonsTest, ClipPathTest) {
- uint32_t clip_reason = cc::MainThreadScrollingReason::kHasClipRelatedProperty;
- GetWebView()->GetSettings()->SetPreferCompositingToLCDTextEnabled(false);
- Document* document = GetFrame()->GetDocument();
- // Test ancestor with ClipPath
- Element* element = document->body();
- element->classList().Add("clip-path");
- Element* container = document->getElementById("scroller1");
- ASSERT_TRUE(container);
- ForceFullCompositingUpdate();
-
- PaintLayerScrollableArea* scrollable_area =
- ToLayoutBoxModelObject(container->GetLayoutObject())->GetScrollableArea();
- EXPECT_MAIN_THREAD_SCROLLING_REASON(
- clip_reason,
- scrollable_area->GetNonCompositedMainThreadScrollingReasons());
- EXPECT_NO_MAIN_THREAD_SCROLLING_REASON(GetViewMainThreadScrollingReasons());
-
- // Remove clip path from ancestor.
- element->classList().Remove("clip-path");
- ForceFullCompositingUpdate();
-
- EXPECT_NO_MAIN_THREAD_SCROLLING_REASON(
- scrollable_area->GetNonCompositedMainThreadScrollingReasons());
- EXPECT_NO_MAIN_THREAD_SCROLLING_REASON(GetViewMainThreadScrollingReasons());
-
- // Test descendant with ClipPath
- element = document->getElementById("content1");
- ASSERT_TRUE(element);
- element->classList().Add("clip-path");
- ForceFullCompositingUpdate();
- EXPECT_MAIN_THREAD_SCROLLING_REASON(
- clip_reason,
- scrollable_area->GetNonCompositedMainThreadScrollingReasons());
- EXPECT_NO_MAIN_THREAD_SCROLLING_REASON(GetViewMainThreadScrollingReasons());
-
- // Remove clip path from descendant.
- element->classList().Remove("clip-path");
- ForceFullCompositingUpdate();
- EXPECT_NO_MAIN_THREAD_SCROLLING_REASON(
- scrollable_area->GetNonCompositedMainThreadScrollingReasons());
- EXPECT_NO_MAIN_THREAD_SCROLLING_REASON(GetViewMainThreadScrollingReasons());
+ TestNonCompositedReasons("clip-path",
+ cc::MainThreadScrollingReason::kNotScrollingOnMain);
}
TEST_F(NonCompositedMainThreadScrollingReasonsTest, BoxShadowTest) {
@@ -455,17 +414,21 @@ TEST_F(NonCompositedMainThreadScrollingReasonsTest, BoxShadowTest) {
TEST_F(NonCompositedMainThreadScrollingReasonsTest, InsetBoxShadowTest) {
TestNonCompositedReasons(
"inset-box-shadow",
- cc::MainThreadScrollingReason::kCantPaintScrollingBackground);
+ cc::MainThreadScrollingReason::kCantPaintScrollingBackgroundAndLCDText);
}
TEST_F(NonCompositedMainThreadScrollingReasonsTest, StackingContextTest) {
- TestNonCompositedReasons(
- "non-stacking-context",
- cc::MainThreadScrollingReason::kIsNotStackingContextAndLCDText);
+ TestNonCompositedReasons("non-stacking-context",
+ cc::MainThreadScrollingReason::kNotScrollingOnMain);
+}
+
+TEST_F(NonCompositedMainThreadScrollingReasonsTest, BorderRadiusTest) {
+ TestNonCompositedReasons("border-radius",
+ cc::MainThreadScrollingReason::kNotScrollingOnMain);
}
TEST_F(NonCompositedMainThreadScrollingReasonsTest,
- CompositedWithLCDTextRelatedReasonsTest) {
+ ForcedComositingWithLCDRelatedReasons) {
// With "will-change:transform" we composite elements with
// LCDTextRelatedReasons only. For elements with other
// NonCompositedReasons, we don't create scrollingLayer for their
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/overscroll_controller.cc b/chromium/third_party/blink/renderer/core/page/scrolling/overscroll_controller.cc
index d75c02219ed..15aa9a9dbcc 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/overscroll_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/overscroll_controller.cc
@@ -35,7 +35,7 @@ OverscrollController::OverscrollController(
ChromeClient& chrome_client)
: visual_viewport_(&visual_viewport), chrome_client_(&chrome_client) {}
-void OverscrollController::Trace(Visitor* visitor) {
+void OverscrollController::Trace(Visitor* visitor) const {
visitor->Trace(visual_viewport_);
visitor->Trace(chrome_client_);
}
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/overscroll_controller.h b/chromium/third_party/blink/renderer/core/page/scrolling/overscroll_controller.h
index 23b7a4b4dba..1840c419db2 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/overscroll_controller.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/overscroll_controller.h
@@ -36,7 +36,7 @@ class OverscrollController : public GarbageCollected<OverscrollController> {
const FloatPoint& position_in_root_frame,
const FloatSize& velocity_in_root_frame);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
WeakMember<const VisualViewport> visual_viewport_;
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc b/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc
index c235d4199aa..ea5bcb98149 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc
@@ -99,7 +99,7 @@ PaintLayerScrollableArea* GetScrollableArea(const Element& element) {
RootScrollerController::RootScrollerController(Document& document)
: document_(&document), effective_root_scroller_(&document) {}
-void RootScrollerController::Trace(Visitor* visitor) {
+void RootScrollerController::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(root_scroller_);
visitor->Trace(effective_root_scroller_);
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h b/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h
index 26c95b6fb1d..dd5e111aa24 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h
@@ -39,7 +39,7 @@ class CORE_EXPORT RootScrollerController
public:
explicit RootScrollerController(Document&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// Sets the element that will be used as the root scroller. This can be
// nullptr, in which case we'll use the default element (documentElement) as
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
index 04f670c9f17..04003caf96b 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
@@ -49,12 +49,10 @@ namespace blink {
namespace {
class RootScrollerTest : public testing::Test,
- private ScopedImplicitRootScrollerForTest,
- private ScopedSetRootScrollerForTest {
+ private ScopedImplicitRootScrollerForTest {
public:
RootScrollerTest()
- : ScopedImplicitRootScrollerForTest(false),
- ScopedSetRootScrollerForTest(true),
+ : ScopedImplicitRootScrollerForTest(true),
base_url_("http://www.test.com/") {
RegisterMockedHttpURLLoad("overflow-scrolling.html");
RegisterMockedHttpURLLoad("root-scroller.html");
@@ -68,15 +66,6 @@ class RootScrollerTest : public testing::Test,
url_test_helpers::UnregisterAllURLsAndClearMemoryCache();
}
- void SetAndSelectRootScroller(Document& document, Element* element) {
- document.setRootScroller(element, ASSERT_NO_EXCEPTION);
- if (document.GetFrame()) {
- LocalFrameView* root_view = document.GetFrame()->LocalFrameRoot().View();
- if (root_view)
- UpdateAllLifecyclePhases(root_view);
- }
- }
-
WebViewImpl* Initialize(const String& page_name,
frame_test_helpers::TestWebWidgetClient* client) {
return InitializeInternal(base_url_ + page_name, client);
@@ -201,13 +190,10 @@ class RootScrollerTest : public testing::Test,
RuntimeEnabledFeatures::Backup features_backup_;
};
-// Test that no root scroller element is set if setRootScroller isn't called on
-// any elements. The document Node should be the default effective root
-// scroller.
+// Test that the document Node should be the default effective root scroller.
TEST_F(RootScrollerTest, TestDefaultRootScroller) {
Initialize("overflow-scrolling.html");
- ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());
EXPECT_EQ(MainFrame()->GetDocument(),
EffectiveRootScroller(MainFrame()->GetDocument()));
}
@@ -215,7 +201,7 @@ TEST_F(RootScrollerTest, TestDefaultRootScroller) {
// Make sure that replacing the documentElement doesn't change the effective
// root scroller when no root scroller is set.
TEST_F(RootScrollerTest, defaultEffectiveRootScrollerIsDocumentNode) {
- Initialize("root-scroller.html");
+ Initialize("overflow-scrolling.html");
Document* document = MainFrame()->GetDocument();
Element* iframe = document->CreateRawElement(html_names::kIFrameTag);
@@ -238,11 +224,12 @@ TEST_F(RootScrollerTest, defaultEffectiveRootScrollerIsDocumentNode) {
class OverscrollTestWebWidgetClient
: public frame_test_helpers::TestWebWidgetClient {
public:
- MOCK_METHOD4(DidOverscroll,
+ MOCK_METHOD5(DidOverscroll,
void(const gfx::Vector2dF&,
const gfx::Vector2dF&,
const gfx::PointF&,
- const gfx::Vector2dF&));
+ const gfx::Vector2dF&,
+ cc::OverscrollBehavior));
};
// Tests that setting an element as the root scroller causes it to control url
@@ -250,10 +237,10 @@ class OverscrollTestWebWidgetClient
TEST_F(RootScrollerTest, TestSetRootScroller) {
OverscrollTestWebWidgetClient client;
Initialize("root-scroller.html", &client);
+ UpdateAllLifecyclePhases(MainFrameView());
Element* container = MainFrame()->GetDocument()->getElementById("container");
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);
- ASSERT_EQ(container, MainFrame()->GetDocument()->rootScroller());
+ ASSERT_EQ(container, EffectiveRootScroller(MainFrame()->GetDocument()));
// Content is 1000x1000, WebView size is 400x400 but hiding the top controls
// makes it 400x450 so max scroll is 550px.
@@ -288,7 +275,8 @@ TEST_F(RootScrollerTest, TestSetRootScroller) {
// overscroll.
EXPECT_CALL(client,
DidOverscroll(gfx::Vector2dF(0, 50), gfx::Vector2dF(0, 50),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ gfx::PointF(100, 100), gfx::Vector2dF(),
+ cc::OverscrollBehavior()));
GetWebView()->MainFrameWidget()->HandleInputEvent(GenerateTouchGestureEvent(
WebInputEvent::Type::kGestureScrollUpdate, 0, -500));
EXPECT_FLOAT_EQ(maximum_scroll, container->scrollTop());
@@ -301,7 +289,8 @@ TEST_F(RootScrollerTest, TestSetRootScroller) {
// Continue the gesture overscroll.
EXPECT_CALL(client,
DidOverscroll(gfx::Vector2dF(0, 20), gfx::Vector2dF(0, 70),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ gfx::PointF(100, 100), gfx::Vector2dF(),
+ cc::OverscrollBehavior()));
GetWebView()->MainFrameWidget()->HandleInputEvent(GenerateTouchGestureEvent(
WebInputEvent::Type::kGestureScrollUpdate, 0, -20));
EXPECT_FLOAT_EQ(maximum_scroll, container->scrollTop());
@@ -321,7 +310,8 @@ TEST_F(RootScrollerTest, TestSetRootScroller) {
EXPECT_CALL(client,
DidOverscroll(gfx::Vector2dF(0, 30), gfx::Vector2dF(0, 30),
- gfx::PointF(100, 100), gfx::Vector2dF()));
+ gfx::PointF(100, 100), gfx::Vector2dF(),
+ cc::OverscrollBehavior()));
GetWebView()->MainFrameWidget()->HandleInputEvent(GenerateTouchGestureEvent(
WebInputEvent::Type::kGestureScrollUpdate, 0, -30));
EXPECT_FLOAT_EQ(maximum_scroll, container->scrollTop());
@@ -354,50 +344,21 @@ TEST_F(RootScrollerTest, TestSetRootScroller) {
}
// Tests that removing the element that is the root scroller from the DOM tree
-// doesn't remove it as the root scroller but it does change the effective root
-// scroller.
+// changes the effective root scroller.
TEST_F(RootScrollerTest, TestRemoveRootScrollerFromDom) {
Initialize("root-scroller.html");
- ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());
-
Element* container = MainFrame()->GetDocument()->getElementById("container");
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);
UpdateAllLifecyclePhases(MainFrameView());
- EXPECT_EQ(container, MainFrame()->GetDocument()->rootScroller());
EXPECT_EQ(container, EffectiveRootScroller(MainFrame()->GetDocument()));
MainFrame()->GetDocument()->body()->RemoveChild(container);
UpdateAllLifecyclePhases(MainFrameView());
- EXPECT_EQ(container, MainFrame()->GetDocument()->rootScroller());
EXPECT_NE(container, EffectiveRootScroller(MainFrame()->GetDocument()));
}
-// Tests that setting an element that isn't a valid scroller as the root
-// scroller doesn't change the effective root scroller.
-TEST_F(RootScrollerTest, TestSetRootScrollerOnInvalidElement) {
- Initialize("root-scroller.html");
-
- {
- // Set to a non-block element. Should be rejected and a console message
- // logged.
- Element* element = MainFrame()->GetDocument()->getElementById("nonBlock");
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), element);
- EXPECT_EQ(element, MainFrame()->GetDocument()->rootScroller());
- EXPECT_NE(element, EffectiveRootScroller(MainFrame()->GetDocument()));
- }
-
- {
- // Set to an element with no size.
- Element* element = MainFrame()->GetDocument()->getElementById("empty");
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), element);
- EXPECT_EQ(element, MainFrame()->GetDocument()->rootScroller());
- EXPECT_NE(element, EffectiveRootScroller(MainFrame()->GetDocument()));
- }
-}
-
// Test that the effective root scroller resets to the document Node when the
// current root scroller element becomes invalid as a scroller.
TEST_F(RootScrollerTest, TestRootScrollerBecomesInvalid) {
@@ -405,199 +366,31 @@ TEST_F(RootScrollerTest, TestRootScrollerBecomesInvalid) {
Element* container = MainFrame()->GetDocument()->getElementById("container");
- ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());
- ASSERT_EQ(MainFrame()->GetDocument(),
- EffectiveRootScroller(MainFrame()->GetDocument()));
-
{
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);
-
- EXPECT_EQ(container, MainFrame()->GetDocument()->rootScroller());
EXPECT_EQ(container, EffectiveRootScroller(MainFrame()->GetDocument()));
ExecuteScript(
"document.querySelector('#container').style.display = 'inline'");
UpdateAllLifecyclePhases(MainFrameView());
- EXPECT_EQ(container, MainFrame()->GetDocument()->rootScroller());
EXPECT_EQ(MainFrame()->GetDocument(),
EffectiveRootScroller(MainFrame()->GetDocument()));
}
ExecuteScript("document.querySelector('#container').style.display = 'block'");
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), nullptr);
- EXPECT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());
- EXPECT_EQ(MainFrame()->GetDocument(),
- EffectiveRootScroller(MainFrame()->GetDocument()));
+ UpdateAllLifecyclePhases(MainFrameView());
{
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);
-
- EXPECT_EQ(container, MainFrame()->GetDocument()->rootScroller());
EXPECT_EQ(container, EffectiveRootScroller(MainFrame()->GetDocument()));
ExecuteScript("document.querySelector('#container').style.width = '98%'");
UpdateAllLifecyclePhases(MainFrameView());
- EXPECT_EQ(container, MainFrame()->GetDocument()->rootScroller());
EXPECT_EQ(MainFrame()->GetDocument(),
EffectiveRootScroller(MainFrame()->GetDocument()));
}
}
-// Tests that setting the root scroller of the top document to an element that
-// belongs to a nested document works.
-TEST_F(RootScrollerTest, TestSetRootScrollerOnElementInIframe) {
- Initialize("root-scroller-iframe.html");
-
- ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());
-
- {
- // Trying to set an element from a nested document should fail.
- auto* iframe = To<HTMLFrameOwnerElement>(
- MainFrame()->GetDocument()->getElementById("iframe"));
- Element* inner_container =
- iframe->contentDocument()->getElementById("container");
-
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), inner_container);
-
- EXPECT_EQ(inner_container, MainFrame()->GetDocument()->rootScroller());
- EXPECT_EQ(inner_container,
- EffectiveRootScroller(MainFrame()->GetDocument()));
- }
-
- {
- // Setting the iframe itself should also work.
- auto* iframe = To<HTMLFrameOwnerElement>(
- MainFrame()->GetDocument()->getElementById("iframe"));
-
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), iframe);
-
- EXPECT_EQ(iframe, MainFrame()->GetDocument()->rootScroller());
- EXPECT_EQ(iframe, EffectiveRootScroller(MainFrame()->GetDocument()));
- }
-}
-
-// Tests that setting a valid element as the root scroller on a document within
-// an iframe works as expected.
-TEST_F(RootScrollerTest, TestRootScrollerWithinIframe) {
- Initialize("root-scroller-iframe.html");
-
- ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());
-
- {
- auto* iframe = To<HTMLFrameOwnerElement>(
- MainFrame()->GetDocument()->getElementById("iframe"));
-
- EXPECT_EQ(iframe->contentDocument(),
- EffectiveRootScroller(iframe->contentDocument()));
-
- Element* inner_container =
- iframe->contentDocument()->getElementById("container");
- SetAndSelectRootScroller(*iframe->contentDocument(), inner_container);
-
- EXPECT_EQ(inner_container, iframe->contentDocument()->rootScroller());
- EXPECT_EQ(inner_container,
- EffectiveRootScroller(iframe->contentDocument()));
- }
-}
-
-// Tests that setting an iframe as the root scroller makes the iframe the
-// effective root scroller in the parent frame.
-TEST_F(RootScrollerTest, SetRootScrollerIframeBecomesEffective) {
- Initialize("root-scroller-iframe.html");
- ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());
-
- {
- // Try to set the root scroller in the main frame to be the iframe
- // element.
- auto* iframe = To<HTMLFrameOwnerElement>(
- MainFrame()->GetDocument()->getElementById("iframe"));
-
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), iframe);
-
- EXPECT_EQ(iframe, MainFrame()->GetDocument()->rootScroller());
- EXPECT_EQ(iframe, EffectiveRootScroller(MainFrame()->GetDocument()));
-
- Element* container = iframe->contentDocument()->getElementById("container");
-
- SetAndSelectRootScroller(*iframe->contentDocument(), container);
-
- EXPECT_EQ(container, iframe->contentDocument()->rootScroller());
- EXPECT_EQ(container, EffectiveRootScroller(iframe->contentDocument()));
- EXPECT_EQ(iframe, MainFrame()->GetDocument()->rootScroller());
- EXPECT_EQ(iframe, EffectiveRootScroller(MainFrame()->GetDocument()));
- }
-}
-
-// Tests that the global root scroller is correctly calculated when getting the
-// root scroller layer and that the viewport apply scroll is set on it.
-TEST_F(RootScrollerTest, SetRootScrollerIframeUsesCorrectLayerAndCallback) {
- // TODO(bokan): The expectation and actual in the checks here are backwards.
- Initialize("root-scroller-iframe.html");
- ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());
-
- auto* iframe = To<HTMLFrameOwnerElement>(
- MainFrame()->GetDocument()->getElementById("iframe"));
- Element* container = iframe->contentDocument()->getElementById("container");
-
- const TopDocumentRootScrollerController& main_controller =
- MainFrame()->GetDocument()->GetPage()->GlobalRootScrollerController();
-
- // No root scroller set, the document node should be the global root and the
- // main LocalFrameView's scroll layer should be the layer to use.
- {
- EXPECT_TRUE(main_controller.IsViewportScrollCallback(
- MainFrame()->GetDocument()->GetApplyScroll()));
- }
-
- // Set a root scroller in the iframe. Since the main document didn't set a
- // root scroller, the global root scroller shouldn't change.
- {
- SetAndSelectRootScroller(*iframe->contentDocument(), container);
-
- EXPECT_TRUE(main_controller.IsViewportScrollCallback(
- MainFrame()->GetDocument()->GetApplyScroll()));
- }
-
- // Setting the iframe as the root scroller in the main frame should now
- // link the root scrollers so the container should now be the global root
- // scroller.
- {
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), iframe);
-
- EXPECT_FALSE(main_controller.IsViewportScrollCallback(
- MainFrame()->GetDocument()->GetApplyScroll()));
- EXPECT_TRUE(
- main_controller.IsViewportScrollCallback(container->GetApplyScroll()));
- }
-
- // Unsetting the root scroller in the iframe should reset its effective root
- // scroller to the iframe's document node and thus it becomes the global root
- // scroller.
- {
- SetAndSelectRootScroller(*iframe->contentDocument(), nullptr);
- EXPECT_FALSE(
- main_controller.IsViewportScrollCallback(container->GetApplyScroll()));
- EXPECT_FALSE(main_controller.IsViewportScrollCallback(
- MainFrame()->GetDocument()->GetApplyScroll()));
- EXPECT_TRUE(main_controller.IsViewportScrollCallback(
- iframe->contentDocument()->GetApplyScroll()));
- }
-
- // Finally, unsetting the main frame's root scroller should reset it to the
- // document node and corresponding layer.
- {
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), nullptr);
- EXPECT_TRUE(main_controller.IsViewportScrollCallback(
- MainFrame()->GetDocument()->GetApplyScroll()));
- EXPECT_FALSE(
- main_controller.IsViewportScrollCallback(container->GetApplyScroll()));
- EXPECT_FALSE(main_controller.IsViewportScrollCallback(
- iframe->contentDocument()->GetApplyScroll()));
- }
-}
-
// Ensures that disconnecting the element currently set as the root scroller
// recomputes the effective root scroller, before a lifecycle update.
TEST_F(RootScrollerTest, RemoveCurrentRootScroller) {
@@ -605,40 +398,40 @@ TEST_F(RootScrollerTest, RemoveCurrentRootScroller) {
WebURL base_url = url_test_helpers::ToKURL("http://www.test.com/");
frame_test_helpers::LoadHTMLString(GetWebView()->MainFrameImpl(),
- "<!DOCTYPE html>"
- "<style>"
- " body {"
- " margin: 0px;"
- " }"
- " #container {"
- " width: 100%;"
- " height: 100%;"
- " position: absolute;"
- " overflow: auto;"
- " }"
- "</style>"
- "<div id='container'></div>",
+ R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body,html {
+ width: 100%;
+ height: 100%;
+ margin: 0px;
+ }
+ #container {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ overflow: auto;
+ }
+ #spacer {
+ width: 200vw;
+ height: 200vh;
+ }
+ </style>
+ <div id='container'>
+ <div id='spacer'></diiv>
+ </div>)HTML",
base_url);
RootScrollerController& controller =
MainFrame()->GetDocument()->GetRootScrollerController();
Element* container = MainFrame()->GetDocument()->getElementById("container");
+ UpdateAllLifecyclePhases(MainFrameView());
+ ASSERT_EQ(container, controller.EffectiveRootScroller());
- // Set the div as the rootScroller. After a lifecycle update it will be the
- // effective root scroller.
- {
- MainFrame()->GetDocument()->setRootScroller(container, ASSERT_NO_EXCEPTION);
- ASSERT_EQ(container, controller.Get());
- UpdateAllLifecyclePhases(MainFrameView());
- ASSERT_EQ(container, controller.EffectiveRootScroller());
- }
-
- // Remove the div from the document. It should remain the
- // document.rootScroller, however, it should be demoted from the effective
+ // Remove the div from the document. It should be demoted from the effective
// root scroller. The effective will fallback to the document Node.
{
MainFrame()->GetDocument()->body()->setTextContent("");
- EXPECT_EQ(container, controller.Get());
EXPECT_EQ(MainFrame()->GetDocument(), controller.EffectiveRootScroller());
}
}
@@ -648,22 +441,32 @@ TEST_F(RootScrollerTest, RemoveCurrentRootScroller) {
// OuterViewport, we need something to replace them with.
TEST_F(RootScrollerTest, AlwaysCreateCompositedScrollingLayers) {
Initialize();
+ GetWebView()->GetSettings()->SetPreferCompositingToLCDTextEnabled(false);
WebURL base_url = url_test_helpers::ToKURL("http://www.test.com/");
frame_test_helpers::LoadHTMLString(GetWebView()->MainFrameImpl(),
- "<!DOCTYPE html>"
- "<style>"
- " body {"
- " margin: 0px;"
- " }"
- " #container {"
- " width: 100%;"
- " height: 100%;"
- " position: absolute;"
- " overflow: auto;"
- " }"
- "</style>"
- "<div id='container'></div>",
+ R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body,html {
+ width: 100%;
+ height: 100%;
+ margin: 0px;
+ }
+ #container {
+ width: 98%;
+ height: 100%;
+ position: absolute;
+ overflow: auto;
+ }
+ #spacer {
+ width: 200vw;
+ height: 200vh;
+ }
+ </style>
+ <div id='container'>
+ <div id='spacer'></div>
+ </div>)HTML",
base_url);
GetWebView()->ResizeWithBrowserControls(IntSize(400, 400), 50, 0, true);
@@ -677,83 +480,26 @@ TEST_F(RootScrollerTest, AlwaysCreateCompositedScrollingLayers) {
ASSERT_FALSE(layer->HasCompositedLayerMapping());
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);
+ ExecuteScript("document.querySelector('#container').style.width = '100%'");
+ ASSERT_EQ(container, EffectiveRootScroller(MainFrame()->GetDocument()));
ASSERT_TRUE(layer->HasCompositedLayerMapping());
EXPECT_TRUE(layer->GetCompositedLayerMapping()->ScrollingContentsLayer());
- EXPECT_TRUE(layer->GetCompositedLayerMapping()->ScrollingLayer());
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), nullptr);
+ ExecuteScript("document.querySelector('#container').style.width = '98%'");
+ ASSERT_EQ(MainFrame()->GetDocument(),
+ EffectiveRootScroller(MainFrame()->GetDocument()));
EXPECT_FALSE(layer->HasCompositedLayerMapping());
}
-TEST_F(RootScrollerTest, TestSetRootScrollerCausesViewportLayerChange) {
- // TODO(bokan): Need a test that changing root scrollers actually sets the
- // outer viewport layer on the compositor, even in the absence of other
- // compositing changes. crbug.com/505516
-}
-
-// Tests that trying to set an element as the root scroller of a document inside
-// an iframe fails when that element belongs to the parent document.
-// TODO(bokan): Recent changes mean this is now possible but should be fixed.
-TEST_F(RootScrollerTest,
- DISABLED_TestSetRootScrollerOnElementFromOutsideIframe) {
- Initialize("root-scroller-iframe.html");
-
- ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());
- {
- // Try to set the the root scroller of the child document to be the
- // <iframe> element in the parent document.
- auto* iframe = To<HTMLFrameOwnerElement>(
- MainFrame()->GetDocument()->getElementById("iframe"));
- Element* body =
- MainFrame()->GetDocument()->QuerySelector("body", ASSERT_NO_EXCEPTION);
-
- EXPECT_EQ(nullptr, iframe->contentDocument()->rootScroller());
-
- iframe->contentDocument()->setRootScroller(iframe);
-
- EXPECT_EQ(iframe, iframe->contentDocument()->rootScroller());
-
- // Try to set the root scroller of the child document to be the
- // <body> element of the parent document.
- iframe->contentDocument()->setRootScroller(body);
-
- EXPECT_EQ(body, iframe->contentDocument()->rootScroller());
- }
-}
-
-// Do a basic sanity check that setting as root scroller an iframe that's remote
-// doesn't crash or otherwise fail catastrophically.
-TEST_F(RootScrollerTest, RemoteIFrame) {
- Initialize("root-scroller-iframe.html");
-
- // Initialization: Replace the iframe with a remote frame.
- MainWebFrame()->FirstChild()->Swap(frame_test_helpers::CreateRemote());
-
- // Set the root scroller in the local main frame to the iframe (which is
- // remote). Make sure we don't promote a remote frame to the root scroller.
- {
- Element* iframe = MainFrame()->GetDocument()->getElementById("iframe");
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), iframe);
- EXPECT_EQ(iframe, MainFrame()->GetDocument()->rootScroller());
- EXPECT_EQ(MainFrame()->GetDocument(),
- EffectiveRootScroller(MainFrame()->GetDocument()));
- UpdateAllLifecyclePhases(MainFrameView());
- }
-}
-
// Make sure that if an effective root scroller becomes a remote frame, it's
// immediately demoted.
TEST_F(RootScrollerTest, IFrameSwapToRemote) {
Initialize("root-scroller-iframe.html");
Element* iframe = MainFrame()->GetDocument()->getElementById("iframe");
- {
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), iframe);
- ASSERT_EQ(iframe, EffectiveRootScroller(MainFrame()->GetDocument()));
- }
+ ASSERT_EQ(iframe, EffectiveRootScroller(MainFrame()->GetDocument()));
// Swap in a remote frame. Make sure we revert back to the document.
{
@@ -768,124 +514,6 @@ TEST_F(RootScrollerTest, IFrameSwapToRemote) {
}
}
-// Do a basic sanity check that the scrolling and root scroller machinery
-// doesn't fail catastrophically in site isolation when the main frame is
-// remote. Setting a root scroller in OOPIF isn't implemented yet but we should
-// still scroll as before and not crash. TODO(crbug.com/730269): appears to
-// segfault during teardown on TSAN.
-#if defined(THREAD_SANITIZER)
-TEST_F(RootScrollerTest, DISABLED_RemoteMainFrame) {
-#else
-TEST_F(RootScrollerTest, RemoteMainFrame) {
-#endif
- WebLocalFrameImpl* local_frame;
- WebFrameWidget* widget;
-
- Initialize("root-scroller-iframe.html");
-
- // Initialization: Set the main frame to be a RemoteFrame and add a local
- // child.
- {
- WebRemoteFrameImpl* remote_main_frame = frame_test_helpers::CreateRemote();
- helper_.LocalMainFrame()->Swap(remote_main_frame);
- remote_main_frame->SetReplicatedOrigin(
- WebSecurityOrigin(SecurityOrigin::CreateUniqueOpaque()), false);
- local_frame = frame_test_helpers::CreateLocalChild(*remote_main_frame);
-
- frame_test_helpers::LoadFrame(
- local_frame, base_url_.Utf8() + "root-scroller-child.html");
- widget = local_frame->FrameWidget();
- widget->Resize(WebSize(400, 400));
- }
-
- Document* document = local_frame->GetFrameView()->GetFrame().GetDocument();
- Element* container = document->getElementById("container");
-
- // Try scrolling in the iframe.
- {
- widget->HandleInputEvent(GenerateWheelGestureEvent(
- WebInputEvent::Type::kGestureScrollBegin, 0, -100));
- widget->HandleInputEvent(GenerateWheelGestureEvent(
- WebInputEvent::Type::kGestureScrollUpdate, 0, -100));
- widget->HandleInputEvent(
- GenerateWheelGestureEvent(WebInputEvent::Type::kGestureScrollEnd));
- EXPECT_EQ(100, container->scrollTop());
- }
-
- // Set the container Element as the root scroller.
- {
- SetAndSelectRootScroller(*document, container);
- EXPECT_EQ(container, document->rootScroller());
- }
-
- // Try scrolling in the iframe now that it has a root scroller set.
- {
- widget->HandleInputEvent(GenerateWheelGestureEvent(
- WebInputEvent::Type::kGestureScrollBegin, 0, -100));
- widget->HandleInputEvent(GenerateWheelGestureEvent(
- WebInputEvent::Type::kGestureScrollUpdate, 0, -100));
- widget->HandleInputEvent(
- GenerateWheelGestureEvent(WebInputEvent::Type::kGestureScrollEnd));
-
- // TODO(bokan): This doesn't work right now because we notice in
- // Element::nativeApplyScroll that the container is the
- // effectiveRootScroller but the only way we expect to get to
- // nativeApplyScroll is if the effective scroller had its applyScroll
- // ViewportScrollCallback removed. Keep the scrolls to guard crashes
- // but the expectations on when a ViewportScrollCallback have changed
- // and should be updated.
- // EXPECT_EQ(200, container->scrollTop());
- }
-}
-
-// Ensure a non-main local root doesn't interfere with the global root
-// scroller. This happens in this situation: Local <- Remote <- Local. This
-// tests the crash in https://crbug.com/800566.
-TEST_F(RootScrollerTest, NonMainLocalRootLifecycle) {
- WebLocalFrameImpl* non_main_local_root = nullptr;
-
- // Setup a Local <- Remote <- Local frame hierarchy.
- {
- Initialize();
- WebURL base_url = url_test_helpers::ToKURL("http://www.test.com/");
- frame_test_helpers::LoadHTMLString(GetWebView()->MainFrameImpl(),
- R"HTML(
- <!DOCTYPE html>
- <iframe></iframe>
- )HTML",
- base_url);
- UpdateAllLifecyclePhases(MainFrameView());
-
- WebRemoteFrameImpl* remote_frame = frame_test_helpers::CreateRemote();
- WebLocalFrameImpl* child =
- To<WebLocalFrameImpl>(helper_.LocalMainFrame()->FirstChild());
- child->Swap(remote_frame);
- remote_frame->SetReplicatedOrigin(
- WebSecurityOrigin(SecurityOrigin::CreateUniqueOpaque()), false);
-
- non_main_local_root = frame_test_helpers::CreateLocalChild(*remote_frame);
- ASSERT_EQ(non_main_local_root->LocalRoot(), non_main_local_root);
- ASSERT_TRUE(non_main_local_root->Parent());
- }
-
- const TopDocumentRootScrollerController& global_controller =
- MainFrame()->GetDocument()->GetPage()->GlobalRootScrollerController();
-
- ASSERT_EQ(MainFrame()->GetDocument(), global_controller.GlobalRootScroller());
-
- UpdateAllLifecyclePhases(MainFrameView());
-
- // Put the local main frame into Layout clean and have the non-main local
- // root do a complete lifecycle update.
- helper_.LocalMainFrame()->GetFrameView()->SetNeedsLayout();
- helper_.LocalMainFrame()->GetFrameView()->UpdateLifecycleToLayoutClean(
- DocumentUpdateReason::kTest);
- UpdateAllLifecyclePhases(non_main_local_root->GetFrameView());
- UpdateAllLifecyclePhases(helper_.LocalMainFrame()->GetFrameView());
-
- EXPECT_EQ(MainFrame()->GetDocument(), global_controller.GlobalRootScroller());
-}
-
// Tests that removing the root scroller element from the DOM resets the
// effective root scroller without waiting for any lifecycle events.
TEST_F(RootScrollerTest, RemoveRootScrollerFromDom) {
@@ -894,17 +522,8 @@ TEST_F(RootScrollerTest, RemoveRootScrollerFromDom) {
{
auto* iframe = To<HTMLFrameOwnerElement>(
MainFrame()->GetDocument()->getElementById("iframe"));
- Element* inner_container =
- iframe->contentDocument()->getElementById("container");
-
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), iframe);
- SetAndSelectRootScroller(*iframe->contentDocument(), inner_container);
- ASSERT_EQ(iframe, MainFrame()->GetDocument()->rootScroller());
ASSERT_EQ(iframe, EffectiveRootScroller(MainFrame()->GetDocument()));
- ASSERT_EQ(inner_container, iframe->contentDocument()->rootScroller());
- ASSERT_EQ(inner_container,
- EffectiveRootScroller(iframe->contentDocument()));
iframe->contentDocument()->body()->setInnerHTML("");
@@ -937,7 +556,7 @@ TEST_F(RootScrollerTest, UseVisualViewportScrollbars) {
Initialize("root-scroller.html");
Element* container = MainFrame()->GetDocument()->getElementById("container");
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);
+ ASSERT_EQ(container, EffectiveRootScroller(MainFrame()->GetDocument()));
ScrollableArea* container_scroller =
ToLayoutBox(container->GetLayoutObject())->GetScrollableArea();
@@ -957,15 +576,7 @@ TEST_F(RootScrollerTest, UseVisualViewportScrollbarsIframe) {
auto* child_frame =
To<LocalFrame>(To<HTMLFrameOwnerElement>(iframe)->ContentFrame());
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), iframe);
-
- WebLocalFrame* child_web_frame =
- MainWebFrame()->FirstChild()->ToWebLocalFrame();
- ExecuteScript(
- "document.getElementById('container').style.width = '200%';"
- "document.getElementById('container').style.height = '200%';",
- *child_web_frame);
-
+ ASSERT_EQ(iframe, EffectiveRootScroller(MainFrame()->GetDocument()));
UpdateAllLifecyclePhases(MainFrameView());
ScrollableArea* container_scroller = child_frame->View()->LayoutViewport();
@@ -1003,7 +614,7 @@ TEST_F(RootScrollerTest, TopControlsAdjustmentAppliedToRootScroller) {
UpdateAllLifecyclePhases(MainFrameView());
Element* container = MainFrame()->GetDocument()->getElementById("container");
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);
+ ASSERT_EQ(container, EffectiveRootScroller(MainFrame()->GetDocument()));
ScrollableArea* container_scroller =
ToLayoutBox(container->GetLayoutObject())->GetScrollableArea();
@@ -1046,7 +657,7 @@ TEST_F(RootScrollerTest, RotationAnchoring) {
Element* container =
MainFrame()->GetDocument()->getElementById("container");
- SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);
+ ASSERT_EQ(container, EffectiveRootScroller(MainFrame()->GetDocument()));
container_scroller =
ToLayoutBox(container->GetLayoutObject())->GetScrollableArea();
@@ -1117,19 +728,17 @@ TEST_F(RootScrollerTest, IFrameRootScrollerGetsNonFixedLayoutSize) {
Initialize("root-scroller-iframe.html");
UpdateAllLifecyclePhases(MainFrameView());
- Document* document = MainFrame()->GetDocument();
auto* iframe = To<HTMLFrameOwnerElement>(
MainFrame()->GetDocument()->getElementById("iframe"));
auto* iframe_view = To<LocalFrame>(iframe->ContentFrame())->View();
ASSERT_EQ(IntSize(400, 400), iframe_view->GetLayoutSize());
ASSERT_EQ(IntSize(400, 400), iframe_view->Size());
- ASSERT_TRUE(iframe_view->LayoutSizeFixedToFrameSize());
// Make the iframe the rootscroller. This should cause the iframe's layout
// size to be manually controlled.
{
- SetAndSelectRootScroller(*document, iframe);
+ ASSERT_EQ(iframe, EffectiveRootScroller(MainFrame()->GetDocument()));
EXPECT_FALSE(iframe_view->LayoutSizeFixedToFrameSize());
EXPECT_EQ(IntSize(400, 400), iframe_view->GetLayoutSize());
EXPECT_EQ(IntSize(400, 400), iframe_view->Size());
@@ -1171,24 +780,25 @@ TEST_F(RootScrollerTest, IFrameRootScrollerGetsNonFixedLayoutSize) {
UpdateAllLifecyclePhases(MainFrameView());
EXPECT_EQ(IntSize(400, 400), iframe_view->GetLayoutSize());
EXPECT_EQ(IntSize(400, 450), iframe_view->Size());
- SetAndSelectRootScroller(*document, nullptr);
+ ExecuteScript("document.querySelector('#iframe').style.opacity = '0.5'");
+ ASSERT_EQ(MainFrame()->GetDocument(),
+ EffectiveRootScroller(MainFrame()->GetDocument()));
EXPECT_TRUE(iframe_view->LayoutSizeFixedToFrameSize());
EXPECT_EQ(IntSize(400, 400), iframe_view->GetLayoutSize());
EXPECT_EQ(IntSize(400, 400), iframe_view->Size());
}
}
-// Ensure that removing the root scroller element causes an update to the RFV's
-// layout viewport immediately since old layout viewport is now part of a
-// detached layout hierarchy.
+// Ensure that removing the root scroller element causes an update to the
+// RootFrameViewport's layout viewport immediately since old layout viewport is
+// now part of a detached layout hierarchy.
TEST_F(RootScrollerTest, ImmediateUpdateOfLayoutViewport) {
Initialize("root-scroller-iframe.html");
- Document* document = MainFrame()->GetDocument();
auto* iframe = To<HTMLFrameOwnerElement>(
MainFrame()->GetDocument()->getElementById("iframe"));
- SetAndSelectRootScroller(*document, iframe);
+ ASSERT_EQ(iframe, EffectiveRootScroller(MainFrame()->GetDocument()));
RootScrollerController& main_controller =
MainFrame()->GetDocument()->GetRootScrollerController();
@@ -1206,9 +816,9 @@ TEST_F(RootScrollerTest, ImmediateUpdateOfLayoutViewport) {
&MainFrameView()->GetRootFrameViewport()->LayoutViewport());
}
-class RootScrollerSimTest : public SimTest {
+class ImplicitRootScrollerSimTest : public SimTest {
public:
- RootScrollerSimTest() : implicit_root_scroller_for_test_(false) {}
+ ImplicitRootScrollerSimTest() : implicit_root_scroller_for_test_(true) {}
void SetUp() override {
SimTest::SetUp();
@@ -1219,51 +829,10 @@ class RootScrollerSimTest : public SimTest {
ScopedImplicitRootScrollerForTest implicit_root_scroller_for_test_;
};
-// Test that setting a root scroller causes us to request a begin frame.
-// However, until a frame is produced, the effective root scroller should
-// not change.
-TEST_F(RootScrollerSimTest, SetCausesNeedsBeginFrame) {
- WebView().MainFrameWidget()->Resize(WebSize(800, 600));
- SimRequest request("https://example.com/test.html", "text/html");
- LoadURL("https://example.com/test.html");
- request.Complete(R"HTML(
- <!DOCTYPE html>
- <style>
- body, html {
- margin: 0;
- width: 100%;
- height: 100%;
- }
- #container {
- width: 100%;
- height: 100%;
- overflow: scroll;
- }
- </style>
- <div id="container"></div>
- )HTML");
- Compositor().BeginFrame();
- ASSERT_FALSE(Compositor().NeedsBeginFrame());
-
- Element* container = GetDocument().getElementById("container");
- GetDocument().setRootScroller(container);
-
- // Setting the root scroller should cause us to need a new frame but we
- // shouldn't have set the effective yet.
- EXPECT_TRUE(Compositor().NeedsBeginFrame());
- EXPECT_EQ(GetDocument(),
- GetDocument().GetRootScrollerController().EffectiveRootScroller());
-
- Compositor().BeginFrame();
-
- EXPECT_EQ(container,
- GetDocument().GetRootScrollerController().EffectiveRootScroller());
-}
-
// Test that the cached IsEffectiveRootScroller bit on LayoutObject is set
// correctly when the Document is the effective root scroller. It becomes the
// root scroller before Document has a LayoutView.
-TEST_F(RootScrollerSimTest, DocumentEffectiveSetsCachedBit) {
+TEST_F(ImplicitRootScrollerSimTest, DocumentEffectiveSetsCachedBit) {
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
@@ -1277,7 +846,7 @@ TEST_F(RootScrollerSimTest, DocumentEffectiveSetsCachedBit) {
// Test that layout from outside a lifecycle wont select a new effective root
// scroller.
-TEST_F(RootScrollerSimTest, NonLifecycleLayoutDoesntCauseReselection) {
+TEST_F(ImplicitRootScrollerSimTest, NonLifecycleLayoutDoesntCauseReselection) {
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
@@ -1294,11 +863,16 @@ TEST_F(RootScrollerSimTest, NonLifecycleLayoutDoesntCauseReselection) {
height: 100%;
overflow: scroll;
}
+ #spacer {
+ width: 200vw;
+ height: 200vh;
+ }
</style>
- <div id="container"></div>
+ <div id="container">
+ <div id="spacer"></div>
+ </div>
)HTML");
Element* container = GetDocument().getElementById("container");
- GetDocument().setRootScroller(container);
Compositor().BeginFrame();
ASSERT_EQ(container,
GetDocument().GetRootScrollerController().EffectiveRootScroller());
@@ -1329,7 +903,7 @@ TEST_F(RootScrollerSimTest, NonLifecycleLayoutDoesntCauseReselection) {
// layout. This will cause us to recalculate the effective root scroller while
// the current one is valid in all ways except that it no longer has a content
// frame. This test passes if it doesn't crash. https://crbug.com/805317.
-TEST_F(RootScrollerSimTest, RecomputeEffectiveWithNoContentFrame) {
+TEST_F(ImplicitRootScrollerSimTest, RecomputeEffectiveWithNoContentFrame) {
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest request("https://example.com/test.html", "text/html");
SimRequest first_request("https://example.com/first.html", "text/html");
@@ -1348,11 +922,18 @@ TEST_F(RootScrollerSimTest, RecomputeEffectiveWithNoContentFrame) {
height: 100%;
margin: 0px;
}
- iframe {
+ #first {
width: 100%;
height: 100%;
border: 0;
}
+ #second {
+ width: 10px;
+ height: 10px;
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ }
</style>
<iframe id="first" src="https://example.com/first.html">
</iframe>
@@ -1368,6 +949,11 @@ TEST_F(RootScrollerSimTest, RecomputeEffectiveWithNoContentFrame) {
first_request.Complete(R"HTML(
<!DOCTYPE html>
+ <style>
+ body {
+ height: 300vh;
+ }
+ </style>
)HTML");
second_request.Complete(R"HTML(
@@ -1382,7 +968,6 @@ TEST_F(RootScrollerSimTest, RecomputeEffectiveWithNoContentFrame) {
)HTML");
Element* container = GetDocument().getElementById("first");
- GetDocument().GetRootScrollerController().Set(container);
Compositor().BeginFrame();
ASSERT_EQ(container,
@@ -1397,15 +982,17 @@ TEST_F(RootScrollerSimTest, RecomputeEffectiveWithNoContentFrame) {
// Test that the element is considered to be viewport filling only if its
// padding box fills the viewport. That means it must have no border.
-TEST_F(RootScrollerSimTest, UsePaddingBoxForViewportFillingCondition) {
+TEST_F(ImplicitRootScrollerSimTest, UsePaddingBoxForViewportFillingCondition) {
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(R"HTML(
<!DOCTYPE html>
<style>
- body {
+ html,body {
margin: 0;
+ width: 100%;
+ height: 100%;
}
#container {
position: absolute;
@@ -1414,12 +1001,17 @@ TEST_F(RootScrollerSimTest, UsePaddingBoxForViewportFillingCondition) {
box-sizing: border-box;
overflow: scroll;
}
+ #spacer {
+ width: 200vw;
+ height: 200vh;
+ }
</style>
- <div id="container"></div>
+ <div id="container">
+ <div id="spacer"></div>
+ </div>
)HTML");
Element* container = GetDocument().getElementById("container");
- GetDocument().setRootScroller(container);
Compositor().BeginFrame();
ASSERT_EQ(container,
@@ -1435,7 +1027,7 @@ TEST_F(RootScrollerSimTest, UsePaddingBoxForViewportFillingCondition) {
// Tests that the root scroller doesn't affect visualViewport pageLeft and
// pageTop.
-TEST_F(RootScrollerSimTest, RootScrollerDoesntAffectVisualViewport) {
+TEST_F(ImplicitRootScrollerSimTest, RootScrollerDoesntAffectVisualViewport) {
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
@@ -1476,10 +1068,6 @@ TEST_F(RootScrollerSimTest, RootScrollerDoesntAffectVisualViewport) {
Compositor().BeginFrame();
Element* container = GetDocument().getElementById("container");
- GetDocument().setRootScroller(container);
-
- Compositor().BeginFrame();
-
ASSERT_EQ(container,
GetDocument().GetRootScrollerController().EffectiveRootScroller());
container->setScrollTop(50);
@@ -1493,7 +1081,7 @@ TEST_F(RootScrollerSimTest, RootScrollerDoesntAffectVisualViewport) {
// Tests that we don't crash or violate lifecycle assumptions when we resize
// from within layout.
-TEST_F(RootScrollerSimTest, ResizeFromResizeAfterLayout) {
+TEST_F(ImplicitRootScrollerSimTest, ResizeFromResizeAfterLayout) {
WebView().GetSettings()->SetShrinksViewportContentToFit(true);
WebView().SetDefaultPageScaleLimits(0.25f, 5);
@@ -1509,11 +1097,6 @@ TEST_F(RootScrollerSimTest, ResizeFromResizeAfterLayout) {
margin: 0px;
}
- #spacer {
- width: 1000px;
- height: 1000px;
- }
-
#container {
width: 100%;
height: 100%;
@@ -1529,8 +1112,6 @@ TEST_F(RootScrollerSimTest, ResizeFromResizeAfterLayout) {
Compositor().BeginFrame();
Element* container = GetDocument().getElementById("container");
- GetDocument().setRootScroller(container);
- Compositor().BeginFrame();
ASSERT_EQ(container,
GetDocument().GetRootScrollerController().EffectiveRootScroller());
ASSERT_EQ(IntSize(800, 600), GetDocument().View()->Size());
@@ -1544,22 +1125,6 @@ TEST_F(RootScrollerSimTest, ResizeFromResizeAfterLayout) {
ASSERT_EQ(IntSize(2000, 1500), GetDocument().View()->Size());
}
-class ImplicitRootScrollerSimTest : public SimTest {
- public:
- ImplicitRootScrollerSimTest()
- : root_scroller_for_test_(false),
- implicit_root_scroller_for_test_(true) {}
-
- void SetUp() override {
- SimTest::SetUp();
- WebView().GetPage()->GetSettings().SetViewportEnabled(true);
- }
-
- private:
- ScopedSetRootScrollerForTest root_scroller_for_test_;
- ScopedImplicitRootScrollerForTest implicit_root_scroller_for_test_;
-};
-
// Tests basic implicit root scroller mode with a <div>.
TEST_F(ImplicitRootScrollerSimTest, ImplicitRootScroller) {
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
@@ -2427,8 +1992,6 @@ TEST_F(ImplicitRootScrollerSimTest,
</script>
)HTML");
Element* container = GetDocument().getElementById("container");
- GetDocument().setRootScroller(container);
-
Compositor().BeginFrame();
ASSERT_EQ(container,
@@ -3157,7 +2720,7 @@ TEST_F(ImplicitRootScrollerSimTest, AppliedAtFractionalZoom) {
<< "<iframe> should remain promoted when URL bar is hidden";
}
-class RootScrollerHitTest : public RootScrollerSimTest {
+class RootScrollerHitTest : public ImplicitRootScrollerSimTest {
public:
void CheckHitTestAtBottomOfScreen(Element* target) {
HideTopControlsWithMaximalScroll();
@@ -3220,6 +2783,7 @@ TEST_F(RootScrollerHitTest, HitTestInAreaRevealedByURLBarSameLayer) {
<!DOCTYPE html>
<style>
body, html {
+ width: 100%;
height: 100%;
margin: 0px;
}
@@ -3243,11 +2807,11 @@ TEST_F(RootScrollerHitTest, HitTestInAreaRevealedByURLBarSameLayer) {
</div>
)HTML");
+ Compositor().BeginFrame();
Element* container = GetDocument().getElementById("container");
Element* target = GetDocument().getElementById("target");
- GetDocument().setRootScroller(container, ASSERT_NO_EXCEPTION);
-
- Compositor().BeginFrame();
+ ASSERT_EQ(container,
+ GetDocument().GetRootScrollerController().EffectiveRootScroller());
// This test checks hit testing while the target is in the same PaintLayer as
// the root scroller.
@@ -3274,6 +2838,7 @@ TEST_F(RootScrollerHitTest, HitTestInAreaRevealedByURLBarDifferentLayer) {
<style>
body, html {
height: 100%;
+ width: 100%;
margin: 0px;
}
#spacer {
@@ -3297,11 +2862,11 @@ TEST_F(RootScrollerHitTest, HitTestInAreaRevealedByURLBarDifferentLayer) {
</div>
)HTML");
+ Compositor().BeginFrame();
Element* container = GetDocument().getElementById("container");
Element* target = GetDocument().getElementById("target");
- GetDocument().setRootScroller(container, ASSERT_NO_EXCEPTION);
-
- Compositor().BeginFrame();
+ ASSERT_EQ(container,
+ GetDocument().GetRootScrollerController().EffectiveRootScroller());
// Ensure the target and container weren't put into the same layer.
ASSERT_NE(ToLayoutBox(target->GetLayoutObject())->EnclosingLayer(),
@@ -3310,167 +2875,6 @@ TEST_F(RootScrollerHitTest, HitTestInAreaRevealedByURLBarDifferentLayer) {
CheckHitTestAtBottomOfScreen(target);
}
-// Test that hit testing in the area revealed at the bottom of the screen
-// revealed by hiding the URL bar works properly when using a root scroller
-// inside an iframe, when the target and scroller are in different PaintLayers.
-TEST_F(RootScrollerHitTest, HitTestHideURLBarDifferentLayerIframe) {
- WebView().ResizeWithBrowserControls(IntSize(400, 400), 50, 50, true);
- GetBrowserControls().SetShownRatio(1, 1);
- SimRequest main_request("https://example.com/test.html", "text/html");
- SimRequest child_request("https://example.com/child.html", "text/html");
-
- LoadURL("https://example.com/test.html");
- main_request.Complete(R"HTML(
- <!DOCTYPE html>
- <style>
- ::-webkit-scrollbar {
- width: 0px;
- height: 0px;
- }
- body, html {
- width: 100%;
- height: 100%;
- margin: 0px;
- }
- iframe {
- width: 100%;
- height: 100%;
- border: 0;
- }
- </style>
- <iframe id="container" src="child.html">
- </iframe>
- )HTML");
-
- // Add a target at the bottom of the root scroller that's the size of the url
- // bar. We'll test that hiding the URL bar appropriately adjusts clipping so
- // that we can hit this target.
- child_request.Complete(R"HTML(
- <!DOCTYPE html>
- <style>
- body, html {
- height: 100%;
- margin: 0px;
- }
- #spacer {
- height: 1000px;
- }
- #container {
- position: absolute;
- width: 100%;
- height: 100%;
- overflow: auto;
- }
- #target {
- width: 100%;
- height: 50px;
- will-change: transform;
- }
- </style>
- <div id='container'>
- <div id='spacer'></div>
- <div id='target'></div>
- </div>
- )HTML");
-
- Element* container = GetDocument().getElementById("container");
- GetDocument().setRootScroller(container, ASSERT_NO_EXCEPTION);
-
- Document* child_document =
- To<HTMLFrameOwnerElement>(container)->contentDocument();
- Element* child_container = child_document->getElementById("container");
- child_document->setRootScroller(child_container, ASSERT_NO_EXCEPTION);
-
- Compositor().BeginFrame();
-
- // Ensure the target and container weren't put into the same layer.
- Element* target = child_document->getElementById("target");
- ASSERT_NE(ToLayoutBox(target->GetLayoutObject())->EnclosingLayer(),
- ToLayoutBox(child_container->GetLayoutObject())->Layer());
-
- CheckHitTestAtBottomOfScreen(target);
-}
-
-// Test that hit testing in the area revealed at the bottom of the screen
-// revealed by hiding the URL bar works properly when using a root scroller
-// inside an iframe, when the target and scroller are in the same PaintLayer.
-TEST_F(RootScrollerHitTest, HitTestHideURLBarSameLayerIframe) {
- WebView().ResizeWithBrowserControls(IntSize(400, 400), 50, 50, true);
- GetBrowserControls().SetShownRatio(1, 1);
- SimRequest main_request("https://example.com/test.html", "text/html");
- SimRequest child_request("https://example.com/child.html", "text/html");
-
- LoadURL("https://example.com/test.html");
- main_request.Complete(R"HTML(
- <!DOCTYPE html>
- <style>
- ::-webkit-scrollbar {
- width: 0px;
- height: 0px;
- }
- body, html {
- width: 100%;
- height: 100%;
- margin: 0px;
- }
- iframe {
- width: 100%;
- height: 100%;
- border: 0;
- }
- </style>
- <iframe id="container" src="child.html">
- </iframe>
- )HTML");
-
- // Add a target at the bottom of the root scroller that's the size of the url
- // bar. We'll test that hiding the URL bar appropriately adjusts clipping so
- // that we can hit this target.
- child_request.Complete(R"HTML(
- <!DOCTYPE html>
- <style>
- body, html {
- height: 100%;
- margin: 0px;
- }
- #spacer {
- height: 1000px;
- }
- #container {
- position: absolute;
- width: 100%;
- height: 100%;
- overflow: auto;
- }
- #target {
- width: 100%;
- height: 50px;
- }
- </style>
- <div id='container'>
- <div id='spacer'></div>
- <div id='target'></div>
- </div>
- )HTML");
-
- Element* container = GetDocument().getElementById("container");
- GetDocument().setRootScroller(container, ASSERT_NO_EXCEPTION);
-
- Document* child_document =
- To<HTMLFrameOwnerElement>(container)->contentDocument();
- Element* child_container = child_document->getElementById("container");
- child_document->setRootScroller(child_container, ASSERT_NO_EXCEPTION);
-
- Compositor().BeginFrame();
-
- // Ensure the target and container weren't put into the same layer.
- Element* target = child_document->getElementById("target");
- ASSERT_EQ(ToLayoutBox(target->GetLayoutObject())->EnclosingLayer(),
- ToLayoutBox(child_container->GetLayoutObject())->Layer());
-
- CheckHitTestAtBottomOfScreen(target);
-}
-
} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_customization_callbacks.h b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_customization_callbacks.h
index b7cb6767780..0cc04b45ee8 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_customization_callbacks.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_customization_callbacks.h
@@ -27,7 +27,7 @@ class CORE_EXPORT ScrollCustomizationCallbacks
bool InScrollPhase(Node*) const;
void SetInScrollPhase(Node*, bool);
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(apply_scroll_callbacks_);
visitor->Trace(distribute_scroll_callbacks_);
visitor->Trace(in_scrolling_phase_);
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc
index c3fa3decc25..95580d30cc0 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc
@@ -145,17 +145,17 @@ TEST_F(NonCompositedMainThreadScrollingReasonRecordTest,
// Test touch scroll.
Scroll(box, WebGestureDevice::kTouchscreen);
EXPECT_TOUCH_BUCKET(kHasTransformAndLCDText, 1);
- EXPECT_TOUCH_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1);
+ EXPECT_TOUCH_BUCKET(kNotOpaqueForTextAndLCDText, 1);
Scroll(box, WebGestureDevice::kTouchscreen);
EXPECT_TOUCH_BUCKET(kHasTransformAndLCDText, 2);
- EXPECT_TOUCH_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 2);
+ EXPECT_TOUCH_BUCKET(kNotOpaqueForTextAndLCDText, 2);
EXPECT_TOUCH_TOTAL(4);
// Test wheel scroll.
Scroll(box, WebGestureDevice::kTouchpad);
EXPECT_WHEEL_BUCKET(kHasTransformAndLCDText, 1);
- EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1);
+ EXPECT_WHEEL_BUCKET(kNotOpaqueForTextAndLCDText, 1);
EXPECT_WHEEL_TOTAL(2);
}
@@ -182,7 +182,7 @@ TEST_F(NonCompositedMainThreadScrollingReasonRecordTest,
Scroll(box, WebGestureDevice::kTouchpad);
EXPECT_WHEEL_BUCKET(kHasTransformAndLCDText, 1);
- EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1);
+ EXPECT_WHEEL_BUCKET(kNotOpaqueForTextAndLCDText, 1);
EXPECT_WHEEL_TOTAL(2);
box->setAttribute("class", "composited transform box");
@@ -192,7 +192,7 @@ TEST_F(NonCompositedMainThreadScrollingReasonRecordTest,
->GetScrollableArea()
->GetNonCompositedMainThreadScrollingReasons());
EXPECT_WHEEL_BUCKET(kHasTransformAndLCDText, 1);
- EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1);
+ EXPECT_WHEEL_BUCKET(kNotOpaqueForTextAndLCDText, 1);
EXPECT_WHEEL_TOTAL(2);
}
@@ -216,14 +216,14 @@ TEST_F(NonCompositedMainThreadScrollingReasonRecordTest,
Scroll(box, WebGestureDevice::kTouchpad);
EXPECT_WHEEL_BUCKET(kHasTransformAndLCDText, 1);
- EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1);
+ EXPECT_WHEEL_BUCKET(kNotOpaqueForTextAndLCDText, 1);
EXPECT_WHEEL_TOTAL(2);
box->setAttribute("class", "hidden transform box");
UpdateAllLifecyclePhases();
Scroll(box, WebGestureDevice::kTouchpad);
EXPECT_WHEEL_BUCKET(kHasTransformAndLCDText, 1);
- EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1);
+ EXPECT_WHEEL_BUCKET(kNotOpaqueForTextAndLCDText, 1);
EXPECT_WHEEL_TOTAL(2);
}
@@ -258,10 +258,9 @@ TEST_F(NonCompositedMainThreadScrollingReasonRecordTest, NestedScrollersTest) {
// Scrolling the inner box will gather reasons from the scrolling chain. The
// inner box itself has no reason because it's composited. Other scrollable
// areas from the chain have corresponding reasons.
- EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1);
- EXPECT_WHEEL_BUCKET(kIsNotStackingContextAndLCDText, 1);
+ EXPECT_WHEEL_BUCKET(kNotOpaqueForTextAndLCDText, 1);
EXPECT_WHEEL_BUCKET(kHasTransformAndLCDText, 0);
- EXPECT_WHEEL_TOTAL(2);
+ EXPECT_WHEEL_TOTAL(1);
}
} // namespace
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.h b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.h
index 040650db2ee..f33a31bc2f0 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.h
@@ -94,7 +94,7 @@ class CORE_EXPORT ScrollState final : public ScriptWrappable {
ScrollStateData* Data() const { return data_.get(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(node_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state_callback.cc b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state_callback.cc
index 1d5cae38d2b..dba7b179425 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state_callback.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state_callback.cc
@@ -8,7 +8,7 @@
namespace blink {
-void ScrollStateCallbackV8Impl::Trace(Visitor* visitor) {
+void ScrollStateCallbackV8Impl::Trace(Visitor* visitor) const {
visitor->Trace(callback_);
ScrollStateCallback::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state_callback.h b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state_callback.h
index 29273973a58..88600d0a941 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state_callback.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state_callback.h
@@ -22,7 +22,7 @@ class ScrollStateCallback : public GarbageCollected<ScrollStateCallback> {
public:
virtual ~ScrollStateCallback() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
virtual void Invoke(ScrollState*) = 0;
@@ -56,7 +56,7 @@ class ScrollStateCallbackV8Impl : public ScrollStateCallback {
: ScrollStateCallback(native_scroll_behavior), callback_(callback) {}
~ScrollStateCallbackV8Impl() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Invoke(ScrollState*) override;
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state_test.cc
index 742c55e5773..434d34fcabc 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state_test.cc
@@ -68,8 +68,8 @@ TEST_F(ScrollStateTest, ConsumeDeltaNative) {
TEST_F(ScrollStateTest, CurrentNativeScrollingElement) {
ScrollState* scroll_state = CreateScrollState(0, 0, false, false);
- auto* element = MakeGarbageCollected<Element>(
- QualifiedName::Null(), MakeGarbageCollected<Document>());
+ auto* element = MakeGarbageCollected<Element>(QualifiedName::Null(),
+ Document::CreateForTest());
scroll_state->SetCurrentNativeScrollingNode(element);
EXPECT_EQ(element, scroll_state->CurrentNativeScrollingNode());
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
index 1b15feae5db..84ebc73220f 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -64,7 +64,7 @@ ScrollingCoordinator::~ScrollingCoordinator() {
DCHECK(!page_);
}
-void ScrollingCoordinator::Trace(Visitor* visitor) {
+void ScrollingCoordinator::Trace(Visitor* visitor) const {
visitor->Trace(page_);
visitor->Trace(horizontal_scrollbars_);
visitor->Trace(vertical_scrollbars_);
@@ -166,7 +166,7 @@ static void ForAllPaintingGraphicsLayers(GraphicsLayer& layer,
return;
}
- if (layer.PaintsContentOrHitTest())
+ if (layer.PaintsContentOrHitTest() && layer.HasLayerState())
function(layer);
for (auto* child : layer.Children())
@@ -477,6 +477,7 @@ void ScrollingCoordinator::WillCloseAnimationHost(LocalFrameView* view) {
void ScrollingCoordinator::WillBeDestroyed() {
DCHECK(page_);
page_ = nullptr;
+ weak_ptr_factory_.InvalidateWeakPtrs();
}
bool ScrollingCoordinator::CoordinatesScrollingForFrameView(
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h
index 260822a8a3b..0590be5b439 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h
@@ -65,7 +65,7 @@ class CORE_EXPORT ScrollingCoordinator final
public:
explicit ScrollingCoordinator(Page*);
~ScrollingCoordinator() override;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// The LocalFrameView argument is optional, nullptr causes the the scrolling
// animation host and timeline to be owned by the ScrollingCoordinator. When
@@ -137,6 +137,7 @@ class CORE_EXPORT ScrollingCoordinator final
void DidChangeScrollbarsHidden(CompositorElementId, bool hidden) override;
base::WeakPtr<ScrollingCoordinator> GetWeakPtr() {
+ DCHECK(page_);
return weak_ptr_factory_.GetWeakPtr();
}
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
index 773db7a3d4b..2ae2b525a0b 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
@@ -1670,13 +1670,13 @@ TEST_P(ScrollingTest, MainThreadScrollAndDeltaFromImplSide) {
EXPECT_EQ(gfx::ScrollOffset(0, 210), CurrentScrollOffset(element_id));
}
-class ScrollingSimTest : public SimTest, public PaintTestConfigurations {
+class UnifiedScrollingSimTest : public SimTest, public PaintTestConfigurations {
public:
- ScrollingSimTest() : scroll_unification_enabled_(true) {}
+ UnifiedScrollingSimTest() : scroll_unification_enabled_(true) {}
void SetUp() override {
SimTest::SetUp();
- WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true);
+ WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(false);
WebView().MainFrameWidgetBase()->Resize(IntSize(1000, 1000));
WebView().MainFrameWidgetBase()->UpdateAllLifecyclePhases(
DocumentUpdateReason::kTest);
@@ -1708,14 +1708,14 @@ class ScrollingSimTest : public SimTest, public PaintTestConfigurations {
scroll_unification_enabled_;
};
-INSTANTIATE_PAINT_TEST_SUITE_P(ScrollingSimTest);
+INSTANTIATE_PAINT_TEST_SUITE_P(UnifiedScrollingSimTest);
// Tests that the compositor gets a scroll node for noncomposited scrollers by
-// loading a page with a scroller that has a clip path, and ensuring that
-// scroller generates a compositor scroll node with the proper noncomposited
-// reasons set. It then removes the clip property and ensures the compositor
-// node updates accordingly.
-TEST_P(ScrollingSimTest, ScrollNodeForNonCompositedScroller) {
+// loading a page with a scroller that has an inset box-shadow, and ensuring
+// that scroller generates a compositor scroll node with the proper
+// noncomposited reasons set. It then removes the box-shadow property and
+// ensures the compositor node updates accordingly.
+TEST_P(UnifiedScrollingSimTest, ScrollNodeForNonCompositedScroller) {
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(R"HTML(
@@ -1727,7 +1727,8 @@ TEST_P(ScrollingSimTest, ScrollNodeForNonCompositedScroller) {
overflow: auto;
position: absolute;
top: 300px;
- clip: rect(0px, 200px, 200px, 50px);
+ background: white;
+ box-shadow: 10px 10px black inset;
}
#spacer {
width: 100%;
@@ -1743,8 +1744,9 @@ TEST_P(ScrollingSimTest, ScrollNodeForNonCompositedScroller) {
Element* noncomposited_element =
MainFrame().GetFrame()->GetDocument()->getElementById("noncomposited");
auto* scrollable_area = noncomposited_element->GetScrollableArea();
- ASSERT_EQ(cc::MainThreadScrollingReason::kHasClipRelatedProperty,
- scrollable_area->GetNonCompositedMainThreadScrollingReasons());
+ ASSERT_EQ(
+ cc::MainThreadScrollingReason::kCantPaintScrollingBackgroundAndLCDText,
+ scrollable_area->GetNonCompositedMainThreadScrollingReasons());
const auto* scroll_node = ScrollNodeForScrollableArea(scrollable_area);
ASSERT_TRUE(scroll_node);
@@ -1755,8 +1757,10 @@ TEST_P(ScrollingSimTest, ScrollNodeForNonCompositedScroller) {
->property_trees()
->scroll_tree.IsComposited(*scroll_node));
- // Now remove the clip property and ensure the compositor scroll node changes.
- noncomposited_element->setAttribute(html_names::kStyleAttr, "clip: auto");
+ // Now remove the box-shadow property and ensure the compositor scroll node
+ // changes.
+ noncomposited_element->setAttribute(html_names::kStyleAttr,
+ "box-shadow: none");
Compositor().BeginFrame();
EXPECT_EQ(0u, scrollable_area->GetNonCompositedMainThreadScrollingReasons());
@@ -1770,7 +1774,8 @@ TEST_P(ScrollingSimTest, ScrollNodeForNonCompositedScroller) {
// Tests that the compositor retains the scroll node for a composited scroller
// when it becomes noncomposited, and ensures the scroll node has its
// IsComposited state updated accordingly.
-TEST_P(ScrollingSimTest, ScrollNodeForCompositedToNonCompositedScroller) {
+TEST_P(UnifiedScrollingSimTest,
+ ScrollNodeForCompositedToNonCompositedScroller) {
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(R"HTML(
@@ -1782,6 +1787,7 @@ TEST_P(ScrollingSimTest, ScrollNodeForCompositedToNonCompositedScroller) {
overflow: auto;
position: absolute;
top: 300px;
+ background: white;
}
#spacer {
width: 100%;
@@ -1808,14 +1814,15 @@ TEST_P(ScrollingSimTest, ScrollNodeForCompositedToNonCompositedScroller) {
->property_trees()
->scroll_tree.IsComposited(*scroll_node));
- // Now add a clip property to make the node noncomposited and ensure the
- // compositor scroll node updates accordingly.
+ // Now add an inset box-shadow property to make the node noncomposited and
+ // ensure the compositor scroll node updates accordingly.
composited_element->setAttribute(html_names::kStyleAttr,
- "clip: rect(0px, 200px, 200px, 50px)");
+ "box-shadow: 10px 10px black inset");
Compositor().BeginFrame();
- ASSERT_EQ(cc::MainThreadScrollingReason::kHasClipRelatedProperty,
- scrollable_area->GetNonCompositedMainThreadScrollingReasons());
+ ASSERT_EQ(
+ cc::MainThreadScrollingReason::kCantPaintScrollingBackgroundAndLCDText,
+ scrollable_area->GetNonCompositedMainThreadScrollingReasons());
EXPECT_EQ(scroll_node->element_id, scrollable_area->GetScrollElementId());
EXPECT_FALSE(RootCcLayer()
->layer_tree_host()
@@ -1825,9 +1832,9 @@ TEST_P(ScrollingSimTest, ScrollNodeForCompositedToNonCompositedScroller) {
// Tests that the compositor gets a scroll node for noncomposited scrollers
// embedded in an iframe, by loading a document with an iframe that has a
-// scroller with a clip path, and ensuring that scroller generates a compositor
-// scroll node with the proper noncomposited reasons set.
-TEST_P(ScrollingSimTest, ScrollNodeForEmbeddedScrollers) {
+// scroller with an inset box shadow, and ensuring that scroller generates a
+// compositor scroll node with the proper noncomposited reasons set.
+TEST_P(UnifiedScrollingSimTest, ScrollNodeForEmbeddedScrollers) {
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(R"HTML(
@@ -1842,13 +1849,17 @@ TEST_P(ScrollingSimTest, ScrollNodeForEmbeddedScrollers) {
<iframe id="iframe" srcdoc="
<!DOCTYPE html>
<style>
+ body {
+ background: white;
+ }
#scroller {
width: 200px;
height: 200px;
overflow: auto;
position: absolute;
top: 50px;
- clip: rect(0px, 200px, 200px, 50px);
+ background: white;
+ box-shadow: 10px 10px black inset;
}
#spacer {
width: 100%;
@@ -1893,7 +1904,7 @@ TEST_P(ScrollingSimTest, ScrollNodeForEmbeddedScrollers) {
ASSERT_TRUE(child_scroll_node);
EXPECT_EQ(
- cc::MainThreadScrollingReason::kHasClipRelatedProperty,
+ cc::MainThreadScrollingReason::kCantPaintScrollingBackgroundAndLCDText,
child_scrollable_area->GetNonCompositedMainThreadScrollingReasons());
EXPECT_EQ(child_scroll_node->element_id,
child_scrollable_area->GetScrollElementId());
@@ -1906,7 +1917,7 @@ TEST_P(ScrollingSimTest, ScrollNodeForEmbeddedScrollers) {
// Similar to the above test, but for deeper nesting iframes to ensure we
// generate scroll nodes that are deeper than the main frame's children.
-TEST_P(ScrollingSimTest, ScrollNodeForNestedEmbeddedScrollers) {
+TEST_P(UnifiedScrollingSimTest, ScrollNodeForNestedEmbeddedScrollers) {
SimRequest request("https://example.com/test.html", "text/html");
SimRequest child_request_1("https://example.com/child1.html", "text/html");
SimRequest child_request_2("https://example.com/child2.html", "text/html");
@@ -1944,7 +1955,8 @@ TEST_P(ScrollingSimTest, ScrollNodeForNestedEmbeddedScrollers) {
overflow: auto;
position: absolute;
top: 50px;
- clip: rect(0px, 200px, 200px, 50px);
+ background: white;
+ box-shadow: 10px 10px black inset;
}
#spacer {
width: 100%;
@@ -1976,7 +1988,7 @@ TEST_P(ScrollingSimTest, ScrollNodeForNestedEmbeddedScrollers) {
ASSERT_TRUE(child_scroll_node);
EXPECT_EQ(
- cc::MainThreadScrollingReason::kHasClipRelatedProperty,
+ cc::MainThreadScrollingReason::kCantPaintScrollingBackgroundAndLCDText,
child_scrollable_area->GetNonCompositedMainThreadScrollingReasons());
EXPECT_EQ(child_scroll_node->element_id,
child_scrollable_area->GetScrollElementId());
@@ -1988,11 +2000,12 @@ TEST_P(ScrollingSimTest, ScrollNodeForNestedEmbeddedScrollers) {
}
// Tests that the compositor gets a scroll node for opacity 0 noncomposited
-// scrollers by loading a page with an opacity 0 scroller that has a clip path,
-// and ensuring that scroller generates a compositor scroll node with the proper
-// noncomposited reasons set. The test also ensures that there is no scroll node
-// for a display:none scroller, as there is no scrollable area.
-TEST_P(ScrollingSimTest, ScrollNodeForInvisibleNonCompositedScroller) {
+// scrollers by loading a page with an opacity 0 scroller that has an inset
+// box-shadow, and ensuring that scroller generates a compositor scroll node
+// with the proper noncomposited reasons set. The test also ensures that there
+// is no scroll node for a display:none scroller, as there is no scrollable
+// area.
+TEST_P(UnifiedScrollingSimTest, ScrollNodeForInvisibleNonCompositedScroller) {
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(R"HTML(
@@ -2004,7 +2017,8 @@ TEST_P(ScrollingSimTest, ScrollNodeForInvisibleNonCompositedScroller) {
overflow: auto;
position: absolute;
top: 300px;
- clip: rect(0px, 200px, 200px, 50px);
+ background: white;
+ box-shadow: 10px 10px black inset;
}
#invisible {
opacity: 0;
@@ -2033,7 +2047,7 @@ TEST_P(ScrollingSimTest, ScrollNodeForInvisibleNonCompositedScroller) {
->getElementById("invisible")
->GetScrollableArea();
ASSERT_EQ(
- cc::MainThreadScrollingReason::kHasClipRelatedProperty,
+ cc::MainThreadScrollingReason::kCantPaintScrollingBackgroundAndLCDText,
invisible_scrollable_area->GetNonCompositedMainThreadScrollingReasons());
const auto* invisible_scroll_node =
@@ -2060,7 +2074,7 @@ TEST_P(ScrollingSimTest, ScrollNodeForInvisibleNonCompositedScroller) {
// Tests that the compositor gets a scroll node for scrollable input boxes,
// which are unique as they are not a composited scroller but also do not have
// NonCompositedMainThreadScrollingReasons.
-TEST_P(ScrollingSimTest, ScrollNodeForInputBox) {
+TEST_P(UnifiedScrollingSimTest, ScrollNodeForInputBox) {
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(R"HTML(
@@ -2089,6 +2103,125 @@ TEST_P(ScrollingSimTest, ScrollNodeForInputBox) {
->scroll_tree.IsComposited(*scroll_node));
}
+class ScrollingSimTest : public SimTest,
+ public testing::WithParamInterface<bool> {
+ public:
+ ScrollingSimTest() : scroll_unification_enabled_(GetParam()) {}
+
+ void SetUp() override {
+ SimTest::SetUp();
+ WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true);
+ WebView().MainFrameWidgetBase()->Resize(IntSize(1000, 1000));
+ WebView().MainFrameWidgetBase()->UpdateAllLifecyclePhases(
+ DocumentUpdateReason::kTest);
+ }
+
+ WebCoalescedInputEvent GenerateGestureEvent(WebInputEvent::Type type,
+ int delta_x = 0,
+ int delta_y = 0) {
+ WebGestureEvent event(type, WebInputEvent::kNoModifiers,
+ WebInputEvent::GetStaticTimeStampForTests(),
+ WebGestureDevice::kTouchscreen);
+ event.SetPositionInWidget(gfx::PointF(100, 100));
+ if (type == WebInputEvent::Type::kGestureScrollUpdate) {
+ event.data.scroll_update.delta_x = delta_x;
+ event.data.scroll_update.delta_y = delta_y;
+ } else if (type == WebInputEvent::Type::kGestureScrollBegin) {
+ event.data.scroll_begin.delta_x_hint = delta_x;
+ event.data.scroll_begin.delta_y_hint = delta_y;
+ }
+ return WebCoalescedInputEvent(event, ui::LatencyInfo());
+ }
+
+ unsigned NumObjectsNeedingLayout() {
+ bool is_partial = false;
+ unsigned num_objects_need_layout = 0;
+ unsigned total_objects = 0;
+ GetDocument().View()->CountObjectsNeedingLayout(num_objects_need_layout,
+ total_objects, is_partial);
+ return num_objects_need_layout;
+ }
+
+ protected:
+ protected:
+ RuntimeEnabledFeaturesTestHelpers::ScopedScrollUnification
+ scroll_unification_enabled_;
+};
+
+INSTANTIATE_TEST_SUITE_P(All, ScrollingSimTest, testing::Bool());
+
+// Pre-scroll-unification, ensures that ScrollBegin and ScrollUpdate cause
+// layout and ScrollEnd does not. Post unification, Blink will not handle these
+// events but ensure that a unification main-thread-hit-test does cause layout.
+TEST_P(ScrollingSimTest, ScrollLayoutTriggers) {
+ SimRequest request("https://example.com/test.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ #box {
+ position: absolute;
+ }
+ body {
+ height: 5000px;
+ }
+ </style>
+ <div id='box'></div>
+ )HTML");
+ Compositor().BeginFrame();
+ ASSERT_EQ(0u, NumObjectsNeedingLayout());
+
+ Element* box = GetDocument().getElementById("box");
+ if (RuntimeEnabledFeatures::ScrollUnificationEnabled()) {
+ // Dirty the layout
+ box->setAttribute(html_names::kStyleAttr, "height: 10px");
+ GetDocument().UpdateStyleAndLayoutTree();
+ ASSERT_NE(NumObjectsNeedingLayout(), 0u);
+
+ // The hit test (which may be performed by a scroll begin) should cause a
+ // layout to occur.
+ WebView().HitTestResultAt(gfx::PointF(10, 10));
+ EXPECT_EQ(NumObjectsNeedingLayout(), 0u);
+
+ } else {
+ // ScrollBegin should trigger a layout.
+ {
+ // Dirty the layout
+ box->setAttribute(html_names::kStyleAttr, "height: 10px");
+ GetDocument().UpdateStyleAndLayoutTree();
+ ASSERT_NE(NumObjectsNeedingLayout(), 0u);
+
+ WebView().MainFrameWidget()->HandleInputEvent(GenerateGestureEvent(
+ WebInputEvent::Type::kGestureScrollBegin, 0, 10));
+ EXPECT_EQ(NumObjectsNeedingLayout(), 0u);
+ }
+
+ // ScrollUpdate should trigger a layout.
+ {
+ // Dirty the layout
+ box->setAttribute(html_names::kStyleAttr, "height: 11px");
+ GetDocument().UpdateStyleAndLayoutTree();
+ ASSERT_NE(NumObjectsNeedingLayout(), 0u);
+
+ WebView().MainFrameWidget()->HandleInputEvent(GenerateGestureEvent(
+ WebInputEvent::Type::kGestureScrollUpdate, 0, 10));
+ EXPECT_EQ(NumObjectsNeedingLayout(), 0u);
+ }
+
+ // ScrollEnd shouldn't trigger a layout.
+ {
+ // Dirty the layout
+ box->setAttribute(html_names::kStyleAttr, "height: 12px");
+ GetDocument().UpdateStyleAndLayoutTree();
+ ASSERT_NE(NumObjectsNeedingLayout(), 0u);
+
+ WebView().MainFrameWidget()->HandleInputEvent(
+ GenerateGestureEvent(WebInputEvent::Type::kGestureScrollEnd, 0, 0));
+ EXPECT_NE(NumObjectsNeedingLayout(), 0u);
+ }
+ }
+}
+
class ScrollingTestWithAcceleratedContext : public ScrollingTest {
protected:
void SetUp() override {
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.h b/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.h
index dd591a27b95..98f72b36490 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.h
@@ -36,7 +36,7 @@ class CORE_EXPORT SnapCoordinator final
public:
explicit SnapCoordinator();
~SnapCoordinator();
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
void AddSnapContainer(LayoutBox& snap_container);
void RemoveSnapContainer(LayoutBox& snap_container);
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc
index 7af1b2bfbd5..124287ba623 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc
@@ -113,7 +113,7 @@ TextFragmentAnchor* TextFragmentAnchor::TryCreateFragmentDirective(
bool same_document_navigation,
bool should_scroll) {
DCHECK(RuntimeEnabledFeatures::TextFragmentIdentifiersEnabled(
- frame.GetDocument()));
+ frame.DomWindow()));
if (!frame.GetDocument()->GetFragmentDirective())
return nullptr;
@@ -166,13 +166,40 @@ TextFragmentAnchor::TextFragmentAnchor(
}
bool TextFragmentAnchor::Invoke() {
+ // Wait until the page has been made visible before searching.
+ if (!frame_->GetPage()->IsPageVisible() && !page_has_been_visible_)
+ return true;
+ else
+ page_has_been_visible_ = true;
+
+ // We need to keep this TextFragmentAnchor alive if we're proxying an
+ // element fragment anchor.
if (element_fragment_anchor_) {
DCHECK(search_finished_);
- // We need to keep this TextFragmentAnchor alive if we're proxying an
- // element fragment anchor.
return true;
}
+ // Only invoke once, and then a second time once the document is loaded.
+ // Otherwise page load performance could be significantly
+ // degraded, since TextFragmentFinder has O(n) performance. The reason
+ // for invoking twice is to give client-side rendered sites more opportunity
+ // to add text that can participate in text fragment invocation.
+ if (!frame_->GetDocument()->IsLoadCompleted()) {
+ // When parsing is complete the following sequence happens:
+ // 1. Invoke with beforematch_state_ == kNoMatchFound. This runs a match and
+ // causes beforematch_state_ to be set to kEventQueued, and queues
+ // a task to set beforematch_state_ to be set to kFiredEvent.
+ // 2. (maybe) Invoke with beforematch_state_ == kEventQueued.
+ // 3. Invoke with beforematch_state_ == kFiredEvent. This runs a match and
+ // causes text_searched_after_parsing_finished_ to become true.
+ // 4. Any future calls to Invoke before loading are ignored.
+ //
+ // TODO(chrishtr): if layout is not dirtied, we don't need to re-run
+ // the text finding again and again for each of the above steps.
+ if (has_performed_first_text_search_ && beforematch_state_ != kEventQueued)
+ return true;
+ }
+
// If we're done searching, return true if this hasn't been dismissed yet so
// that this is kept alive.
if (search_finished_)
@@ -188,6 +215,10 @@ bool TextFragmentAnchor::Invoke() {
if (user_scrolled_ && !did_scroll_into_view_)
metrics_->ScrollCancelled();
+ if (!did_find_match_) {
+ metrics_->DidStartSearch();
+ }
+
first_match_needs_scroll_ = should_scroll_ && !user_scrolled_;
{
@@ -200,6 +231,9 @@ bool TextFragmentAnchor::Invoke() {
finder.FindMatch(*frame_->GetDocument());
}
+ if (beforematch_state_ != kEventQueued)
+ has_performed_first_text_search_ = true;
+
// Stop searching for matching text once the load event has fired. This may
// cause ScrollToTextFragment to not work on pages which dynamically load
// content: http://crbug.com/963045
@@ -216,10 +250,18 @@ bool TextFragmentAnchor::Invoke() {
void TextFragmentAnchor::Installed() {}
void TextFragmentAnchor::DidScroll(mojom::blink::ScrollType type) {
- if (!IsExplicitScrollType(type))
+ if (type != mojom::blink::ScrollType::kUser &&
+ type != mojom::blink::ScrollType::kCompositor) {
return;
+ }
+ Dismiss();
user_scrolled_ = true;
+
+ if (did_non_zero_scroll_ &&
+ frame_->View()->GetScrollableArea()->GetScrollOffset().IsZero()) {
+ metrics_->DidScrollToTop();
+ }
}
void TextFragmentAnchor::PerformPreRafActions() {
@@ -231,7 +273,7 @@ void TextFragmentAnchor::PerformPreRafActions() {
}
}
-void TextFragmentAnchor::Trace(Visitor* visitor) {
+void TextFragmentAnchor::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(element_fragment_anchor_);
visitor->Trace(metrics_);
@@ -337,6 +379,7 @@ void TextFragmentAnchor::DidFindMatch(
// main document scroll.
if (!frame_->View()->GetScrollableArea()->GetScrollOffset().IsZero() ||
scrolled_bounding_box.offset != bounding_box.offset) {
+ did_non_zero_scroll_ = true;
metrics_->DidNonZeroScroll();
}
}
@@ -344,6 +387,12 @@ void TextFragmentAnchor::DidFindMatch(
EphemeralRange(ToPositionInDOMTree(range.StartPosition()),
ToPositionInDOMTree(range.EndPosition()));
frame_->GetDocument()->Markers().AddTextFragmentMarker(dom_range);
+
+ // Set the sequential focus navigation to the start of selection.
+ // Even if this element isn't focusable, "Tab" press will
+ // start the search to find the next focusable element from this element.
+ frame_->GetDocument()->SetSequentialFocusNavigationStartingPoint(
+ range.StartPosition().NodeAsRangeFirstNode());
}
void TextFragmentAnchor::DidFindAmbiguousMatch() {
@@ -411,4 +460,9 @@ void TextFragmentAnchor::FireBeforeMatchEvent(Element* element) {
beforematch_state_ = kFiredEvent;
}
+void TextFragmentAnchor::SetTickClockForTesting(
+ const base::TickClock* tick_clock) {
+ metrics_->SetTickClockForTesting(tick_clock);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h
index 787896028d2..d4c99354fba 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h
@@ -56,7 +56,9 @@ class CORE_EXPORT TextFragmentAnchor final : public FragmentAnchor,
// Removes text match highlights if any highlight is in view.
bool Dismiss() override;
- void Trace(Visitor*) override;
+ void SetTickClockForTesting(const base::TickClock* tick_clock);
+
+ void Trace(Visitor*) const override;
// TextFragmentFinder::Client interface
void DidFindMatch(
@@ -99,6 +101,16 @@ class CORE_EXPORT TextFragmentAnchor final : public FragmentAnchor,
// history navigations and reloads, where we want to restore the highlight but
// not scroll into view again.
bool should_scroll_ = false;
+ // Whether the page has been made visible. Used to ensure we wait until the
+ // page has been made visible to start matching, to help prevent brute force
+ // search attacks.
+ bool page_has_been_visible_ = false;
+ // Whether we performed a non-zero scroll to scroll a match into view. Used
+ // to determine whether the user subsequently scrolls back to the top.
+ bool did_non_zero_scroll_ = false;
+
+ // Whether a text fragment finder was run.
+ bool has_performed_first_text_search_ = false;
enum BeforematchState {
kNoMatchFound, // DidFindMatch has not been called.
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.cc b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.cc
index 9604860dd66..10fdb64e91a 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.cc
@@ -6,6 +6,7 @@
#include "base/check.h"
#include "base/metrics/histogram_macros.h"
+#include "base/time/default_tick_clock.h"
#include "base/trace_event/trace_event.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
@@ -19,12 +20,11 @@ const size_t kMaxTraceEventStringLength = 1000;
} // namespace
TextFragmentAnchorMetrics::TextFragmentAnchorMetrics(Document* document)
- : document_(document) {}
+ : document_(document), tick_clock_(base::DefaultTickClock::GetInstance()) {}
void TextFragmentAnchorMetrics::DidCreateAnchor(int selector_count,
int directive_length) {
UseCounter::Count(document_, WebFeature::kTextFragmentAnchor);
- create_time_ = base::TimeTicks::Now();
selector_count_ = selector_count;
directive_length_ = directive_length;
}
@@ -45,21 +45,46 @@ void TextFragmentAnchorMetrics::ScrollCancelled() {
scroll_cancelled_ = true;
}
+void TextFragmentAnchorMetrics::DidStartSearch() {
+ if (search_start_time_.is_null())
+ search_start_time_ = tick_clock_->NowTicks();
+}
+
void TextFragmentAnchorMetrics::DidScroll() {
if (first_scroll_into_view_time_.is_null())
- first_scroll_into_view_time_ = base::TimeTicks::Now();
+ first_scroll_into_view_time_ = tick_clock_->NowTicks();
}
void TextFragmentAnchorMetrics::DidNonZeroScroll() {
did_non_zero_scroll_ = true;
}
+void TextFragmentAnchorMetrics::DidScrollToTop() {
+ if (did_scroll_to_top_)
+ return;
+ did_scroll_to_top_ = true;
+
+ base::TimeTicks scroll_to_top_time = tick_clock_->NowTicks();
+
+ DCHECK(!first_scroll_into_view_time_.is_null());
+ DCHECK(scroll_to_top_time >= first_scroll_into_view_time_);
+
+ base::TimeDelta time_to_scroll_to_top(scroll_to_top_time -
+ first_scroll_into_view_time_);
+ UMA_HISTOGRAM_TIMES("TextFragmentAnchor.TimeToScrollToTop",
+ time_to_scroll_to_top);
+ TRACE_EVENT_INSTANT1("blink", "TextFragmentAnchorMetrics::ReportMetrics",
+ TRACE_EVENT_SCOPE_THREAD, "time_to_scroll_to_top",
+ time_to_scroll_to_top.InMilliseconds());
+}
+
void TextFragmentAnchorMetrics::ReportMetrics() {
#ifndef NDEBUG
DCHECK(!metrics_reported_);
#endif
DCHECK(selector_count_);
DCHECK(matches_.size() <= selector_count_);
+ DCHECK(!search_start_time_.is_null());
if (matches_.size() > 0) {
UseCounter::Count(document_, WebFeature::kTextFragmentAnchorMatchFound);
@@ -96,6 +121,11 @@ void TextFragmentAnchorMetrics::ReportMetrics() {
TRACE_EVENT_INSTANT1("blink", "TextFragmentAnchorMetrics::ReportMetrics",
TRACE_EVENT_SCOPE_THREAD, "exact_text_length",
match.text.length());
+
+ UMA_HISTOGRAM_BOOLEAN("TextFragmentAnchor.ListItemMatch",
+ match.is_list_item);
+ UMA_HISTOGRAM_BOOLEAN("TextFragmentAnchor.TableCellMatch",
+ match.is_table_cell);
} else if (match.selector.Type() == TextFragmentSelector::kRange) {
UMA_HISTOGRAM_COUNTS_1000("TextFragmentAnchor.RangeMatchLength",
match.text.length());
@@ -114,6 +144,9 @@ void TextFragmentAnchorMetrics::ReportMetrics() {
TRACE_EVENT_INSTANT1("blink", "TextFragmentAnchorMetrics::ReportMetrics",
TRACE_EVENT_SCOPE_THREAD, "end_text_length",
match.selector.End().length());
+
+ // We only record ListItemMatch and TableCellMatch for exact matches
+ DCHECK(!match.is_list_item && !match.is_table_cell);
}
UMA_HISTOGRAM_ENUMERATION("TextFragmentAnchor.Parameters",
@@ -131,7 +164,9 @@ void TextFragmentAnchorMetrics::ReportMetrics() {
TRACE_EVENT_SCOPE_THREAD, "scroll_cancelled",
scroll_cancelled_);
- if (first_scroll_into_view_time_ > create_time_) {
+ if (!first_scroll_into_view_time_.is_null()) {
+ DCHECK(first_scroll_into_view_time_ >= search_start_time_);
+
UMA_HISTOGRAM_BOOLEAN("TextFragmentAnchor.DidScrollIntoView",
did_non_zero_scroll_);
TRACE_EVENT_INSTANT1("blink", "TextFragmentAnchorMetrics::ReportMetrics",
@@ -139,7 +174,7 @@ void TextFragmentAnchorMetrics::ReportMetrics() {
did_non_zero_scroll_);
base::TimeDelta time_to_scroll_into_view(first_scroll_into_view_time_ -
- create_time_);
+ search_start_time_);
UMA_HISTOGRAM_TIMES("TextFragmentAnchor.TimeToScrollIntoView",
time_to_scroll_into_view);
TRACE_EVENT_INSTANT1("blink", "TextFragmentAnchorMetrics::ReportMetrics",
@@ -160,7 +195,7 @@ void TextFragmentAnchorMetrics::Dismissed() {
TRACE_EVENT_SCOPE_THREAD);
}
-void TextFragmentAnchorMetrics::Trace(Visitor* visitor) {
+void TextFragmentAnchorMetrics::Trace(Visitor* visitor) const {
visitor->Trace(document_);
}
@@ -193,4 +228,9 @@ TextFragmentAnchorMetrics::GetParametersForMatch(const Match& match) {
return parameters;
}
+void TextFragmentAnchorMetrics::SetTickClockForTesting(
+ const base::TickClock* tick_clock) {
+ tick_clock_ = tick_clock;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h
index 22a227b56b2..c7b177d11f9 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h
@@ -22,6 +22,8 @@ class CORE_EXPORT TextFragmentAnchorMetrics final
String text;
TextFragmentSelector selector;
+ bool is_list_item = false;
+ bool is_table_cell = false;
};
// An enum to indicate which parameters were specified in the text fragment.
@@ -49,15 +51,21 @@ class CORE_EXPORT TextFragmentAnchorMetrics final
void ScrollCancelled();
+ void DidStartSearch();
+
void DidScroll();
void DidNonZeroScroll();
+ void DidScrollToTop();
+
void ReportMetrics();
void Dismissed();
- void Trace(Visitor*);
+ void SetTickClockForTesting(const base::TickClock* tick_clock);
+
+ void Trace(Visitor*) const;
private:
TextFragmentAnchorParameters GetParametersForMatch(const Match& match);
@@ -73,9 +81,12 @@ class CORE_EXPORT TextFragmentAnchorMetrics final
Vector<Match> matches_;
bool ambiguous_match_ = false;
bool scroll_cancelled_ = false;
- base::TimeTicks create_time_;
+ base::TimeTicks search_start_time_;
base::TimeTicks first_scroll_into_view_time_;
bool did_non_zero_scroll_ = false;
+ bool did_scroll_to_top_ = false;
+
+ const base::TickClock* tick_clock_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc
index 7f7ab2151be..fbc40855ee0 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc
@@ -4,7 +4,9 @@
#include "third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h"
+#include "base/test/simple_test_tick_clock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/scroll/scroll_enums.mojom-blink.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
@@ -125,6 +127,16 @@ TEST_F(TextFragmentAnchorMetricsTest, UMAMetricsCollected) {
static_cast<int>(
TextFragmentAnchorMetrics::TextFragmentAnchorParameters::kExactText),
1);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollToTop", 0);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ListItemMatch", 1);
+ histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.ListItemMatch", 0,
+ 1);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TableCellMatch", 1);
+ histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.TableCellMatch", 0,
+ 1);
}
// Test UMA metrics collection when there is no match found
@@ -181,6 +193,12 @@ TEST_F(TextFragmentAnchorMetricsTest, NoMatchFound) {
histogram_tester_.ExpectTotalCount("TextFragmentAnchor.EndTextLength", 0);
histogram_tester_.ExpectTotalCount("TextFragmentAnchor.Parameters", 0);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollToTop", 0);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ListItemMatch", 0);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TableCellMatch", 0);
}
// Test that we don't collect any metrics when there is no text directive
@@ -221,6 +239,12 @@ TEST_F(TextFragmentAnchorMetricsTest, NoTextFragmentAnchor) {
histogram_tester_.ExpectTotalCount("TextFragmentAnchor.EndTextLength", 0);
histogram_tester_.ExpectTotalCount("TextFragmentAnchor.Parameters", 0);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollToTop", 0);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ListItemMatch", 0);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TableCellMatch", 0);
}
// Test that the correct metrics are collected when we found a match but didn't
@@ -278,6 +302,16 @@ TEST_F(TextFragmentAnchorMetricsTest, MatchFoundNoScroll) {
static_cast<int>(
TextFragmentAnchorMetrics::TextFragmentAnchorParameters::kExactText),
1);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollToTop", 0);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ListItemMatch", 1);
+ histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.ListItemMatch", 0,
+ 1);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TableCellMatch", 1);
+ histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.TableCellMatch", 0,
+ 1);
}
// Test that the correct metrics are collected for all possible combinations of
@@ -361,6 +395,16 @@ TEST_F(TextFragmentAnchorMetricsTest, ExactTextParameters) {
static_cast<int>(TextFragmentAnchorMetrics::TextFragmentAnchorParameters::
kExactTextWithContext),
1);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollToTop", 0);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ListItemMatch", 4);
+ histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.ListItemMatch", 0,
+ 4);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TableCellMatch", 4);
+ histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.TableCellMatch", 0,
+ 4);
}
// Test that the correct metrics are collected for all possible combinations of
@@ -460,11 +504,37 @@ TEST_F(TextFragmentAnchorMetricsTest, TextRangeParameters) {
static_cast<int>(TextFragmentAnchorMetrics::TextFragmentAnchorParameters::
kTextRangeWithContext),
1);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollToTop", 0);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ListItemMatch", 0);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TableCellMatch", 0);
}
+class TextFragmentAnchorScrollMetricsTest
+ : public TextFragmentAnchorMetricsTest,
+ public testing::WithParamInterface<mojom::blink::ScrollType> {
+ protected:
+ bool IsUserScrollType() {
+ return GetParam() == mojom::blink::ScrollType::kCompositor ||
+ GetParam() == mojom::blink::ScrollType::kUser;
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(
+ ScrollTypes,
+ TextFragmentAnchorScrollMetricsTest,
+ testing::Values(mojom::blink::ScrollType::kUser,
+ mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollType::kClamping,
+ mojom::blink::ScrollType::kCompositor,
+ mojom::blink::ScrollType::kAnchoring,
+ mojom::blink::ScrollType::kSequenced));
+
// Test that the ScrollCancelled metric gets reported when a user scroll cancels
// the scroll into view.
-TEST_F(TextFragmentAnchorMetricsTest, ScrollCancelled) {
+TEST_P(TextFragmentAnchorScrollMetricsTest, ScrollCancelled) {
// This test isn't relevant with this flag enabled. When it's enabled,
// there's no way to block rendering and the fragment is installed and
// invoked as soon as parsing finishes which means the user cannot scroll
@@ -491,8 +561,10 @@ TEST_F(TextFragmentAnchorMetricsTest, ScrollCancelled) {
)HTML");
Compositor().PaintFrame();
- GetDocument().View()->LayoutViewport()->ScrollBy(
- ScrollOffset(0, 100), mojom::blink::ScrollType::kUser);
+
+ mojom::blink::ScrollType scroll_type = GetParam();
+ GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, 100),
+ scroll_type);
// Set the target text to visible and change its position to cause a layout
// and invoke the fragment anchor.
@@ -503,6 +575,27 @@ TEST_F(TextFragmentAnchorMetricsTest, ScrollCancelled) {
Compositor().BeginFrame();
BeginEmptyFrame();
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ScrollCancelled", 1);
+
+ // A user scroll should have caused this to be canceled, other kinds of
+ // scrolls should have no effect.
+ if (IsUserScrollType()) {
+ histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.ScrollCancelled",
+ 1, 1);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.DidScrollIntoView",
+ 0);
+ histogram_tester_.ExpectTotalCount(
+ "TextFragmentAnchor.TimeToScrollIntoView", 0);
+ } else {
+ histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.ScrollCancelled",
+ 0, 1);
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.DidScrollIntoView",
+ 1);
+ histogram_tester_.ExpectTotalCount(
+ "TextFragmentAnchor.TimeToScrollIntoView", 1);
+ }
+
histogram_tester_.ExpectTotalCount("TextFragmentAnchor.SelectorCount", 1);
histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.SelectorCount", 1,
1);
@@ -514,15 +607,6 @@ TEST_F(TextFragmentAnchorMetricsTest, ScrollCancelled) {
histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.AmbiguousMatch", 0,
1);
- histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ScrollCancelled", 1);
- histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.ScrollCancelled", 1,
- 1);
-
- histogram_tester_.ExpectTotalCount("TextFragmentAnchor.DidScrollIntoView", 0);
-
- histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollIntoView",
- 0);
-
histogram_tester_.ExpectTotalCount("TextFragmentAnchor.DirectiveLength", 1);
histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.DirectiveLength", 9,
1);
@@ -541,6 +625,108 @@ TEST_F(TextFragmentAnchorMetricsTest, ScrollCancelled) {
static_cast<int>(
TextFragmentAnchorMetrics::TextFragmentAnchorParameters::kExactText),
1);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollToTop", 0);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ListItemMatch", 1);
+ histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.ListItemMatch", 0,
+ 1);
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TableCellMatch", 1);
+ histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.TableCellMatch", 0,
+ 1);
+}
+
+// Test that the user scrolling back to the top of the page reports metrics
+TEST_P(TextFragmentAnchorScrollMetricsTest, TimeToScrollToTop) {
+ mojom::blink::ScrollType scroll_type = GetParam();
+
+ // Set the page to be initially hidden to delay the text fragment so that we
+ // can set the mock TickClock.
+ WebView().SetVisibilityState(mojom::blink::PageVisibilityState::kHidden,
+ /*initial_state=*/true);
+
+ SimRequest request("https://example.com/test.html#:~:text=test%20page",
+ "text/html");
+ LoadURL("https://example.com/test.html#:~:text=test%20page");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ height: 2200px;
+ }
+ p {
+ position: absolute;
+ top: 1000px;
+ }
+ </style>
+ <p>This is a test page</p>
+ )HTML");
+ RunAsyncMatchingTasks();
+
+ BeginEmptyFrame();
+ BeginEmptyFrame();
+
+ // Set the test TickClock and then render the page visible to activate the
+ // text fragment.
+ base::SimpleTestTickClock tick_clock;
+ tick_clock.SetNowTicks(base::TimeTicks::Now());
+ static_cast<TextFragmentAnchor*>(GetDocument().View()->GetFragmentAnchor())
+ ->SetTickClockForTesting(&tick_clock);
+ WebView().SetVisibilityState(mojom::blink::PageVisibilityState::kVisible,
+ /*initial_state=*/false);
+ BeginEmptyFrame();
+ BeginEmptyFrame();
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollToTop", 0);
+
+ const int64_t time_to_scroll_to_top = 500;
+ tick_clock.Advance(base::TimeDelta::FromMilliseconds(time_to_scroll_to_top));
+
+ ASSERT_GT(GetDocument().View()->LayoutViewport()->GetScrollOffset().Height(),
+ 100);
+
+ // Ensure scrolling but not to the top isn't counted.
+ {
+ GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, -20),
+ scroll_type);
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollToTop",
+ 0);
+ }
+
+ // Scroll to top and ensure the metric is recorded, but only for user type
+ // scrolls.
+ {
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(),
+ scroll_type);
+
+ if (IsUserScrollType()) {
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollToTop",
+ 1);
+ histogram_tester_.ExpectUniqueSample(
+ "TextFragmentAnchor.TimeToScrollToTop", time_to_scroll_to_top, 1);
+ } else {
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollToTop",
+ 0);
+ }
+ }
+
+ // Scroll down and then back up to the top again to ensure the metric is
+ // recorded only once.
+ {
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 100), scroll_type);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(),
+ scroll_type);
+
+ if (IsUserScrollType()) {
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollToTop",
+ 1);
+ } else {
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TimeToScrollToTop",
+ 0);
+ }
+ }
}
// Test that the TapToDismiss feature gets use counted when the user taps to
@@ -624,6 +810,96 @@ TEST_F(TextFragmentAnchorMetricsTest, InvalidFragmentDirective) {
}
}
+// Test recording of the ListItemMatch metric
+TEST_F(TextFragmentAnchorMetricsTest, ListItemMatch) {
+ SimRequest request("https://example.com/test.html#:~:text=list", "text/html");
+ LoadURL("https://example.com/test.html#:~:text=list");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <ul>
+ <li>Some test content</li>
+ <li>Within a list item</li>
+ </ul>
+ )HTML");
+ RunAsyncMatchingTasks();
+
+ BeginEmptyFrame();
+ BeginEmptyFrame();
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ListItemMatch", 1);
+ histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.ListItemMatch", 1,
+ 1);
+}
+
+// Test recording of the TableCellMatch metric
+TEST_F(TextFragmentAnchorMetricsTest, TableCellMatch) {
+ SimRequest request("https://example.com/test.html#:~:text=table",
+ "text/html");
+ LoadURL("https://example.com/test.html#:~:text=table");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <table>
+ <tr>
+ <td>Some test content</td>
+ <td>Within a table cell</td>
+ </tr>
+ </table>
+ )HTML");
+ RunAsyncMatchingTasks();
+
+ BeginEmptyFrame();
+ BeginEmptyFrame();
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TableCellMatch", 1);
+ histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.TableCellMatch", 1,
+ 1);
+}
+
+// Test recording of ListItemMatch for a match nested in a list item
+TEST_F(TextFragmentAnchorMetricsTest, NestedListItemMatch) {
+ SimRequest request("https://example.com/test.html#:~:text=list", "text/html");
+ LoadURL("https://example.com/test.html#:~:text=list");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <ol>
+ <li>Some test content</li>
+ <li>Within a <span>list</span> item</li>
+ </ol>
+ )HTML");
+ RunAsyncMatchingTasks();
+
+ BeginEmptyFrame();
+ BeginEmptyFrame();
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.ListItemMatch", 1);
+ histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.ListItemMatch", 1,
+ 1);
+}
+
+// Test recording of TableCellMatch for a match nested in a table cell
+TEST_F(TextFragmentAnchorMetricsTest, NestedTableCellMatch) {
+ SimRequest request("https://example.com/test.html#:~:text=table",
+ "text/html");
+ LoadURL("https://example.com/test.html#:~:text=table");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <table>
+ <tr>
+ <td>Some test content</td>
+ <td>Within a <span>table</span> cell</td>
+ </tr>
+ </table>
+ )HTML");
+ RunAsyncMatchingTasks();
+
+ BeginEmptyFrame();
+ BeginEmptyFrame();
+
+ histogram_tester_.ExpectTotalCount("TextFragmentAnchor.TableCellMatch", 1);
+ histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.TableCellMatch", 1,
+ 1);
+}
+
class TextFragmentRelatedMetricTest : public TextFragmentAnchorMetricsTest,
public testing::WithParamInterface<bool> {
public:
@@ -651,25 +927,34 @@ TEST_P(TextFragmentRelatedMetricTest, ElementIdSuccessFailureCounts) {
// result of the element-id fragment if a text directive is successfully
// parsed. If the feature is off we treat the text directive as an element-id
// and should count the result.
- const int kUncountedOrNotFound = GetParam() ? kUncounted : kNotFound;
const int kUncountedOrFound = GetParam() ? kUncounted : kFound;
- // When the TextFragmentAnchors feature is on, we'll strip the fragment
- // directive (i.e. anything after :~:) leaving just the element anchor.
- const int kFoundIfDirectiveStripped = GetParam() ? kFound : kNotFound;
+ // Note: We'll strip the fragment directive (i.e. anything after :~:) leaving
+ // just the element anchor. The fragment directive stripping behavior is now
+ // shipped unflagged so it should always be performed.
Vector<std::pair<String, int>> test_cases = {
{"", kUncounted},
{"#element", kFound},
{"#doesntExist", kNotFound},
- {"#element:~:foo", kFoundIfDirectiveStripped},
+ // `:~:foo` will be stripped so #element will be found and #doesntexist
+ // ##element will be not found.
+ {"#element:~:foo", kFound},
{"#doesntexist:~:foo", kNotFound},
{"##element", kNotFound},
- {"#element:~:text=doesntexist", kUncountedOrNotFound},
- {"#element:~:text=page", kUncountedOrNotFound},
- {"#:~:text=doesntexist", kUncountedOrNotFound},
- {"#:~:text=page", kUncountedOrNotFound},
- {"#:~:text=name", kUncountedOrFound},
+ // If the feature is on, `:~:text=` will parse so we shouldn't count.
+ // Otherwise, it'll just be stripped so #element will be found.
+ {"#element:~:text=doesntexist", kUncountedOrFound},
+ {"#element:~:text=page", kUncountedOrFound},
+ // If the feature is on, `:~:text` is parsed so we don't count. If it's
+ // off the entire fragment is a directive that's stripped so no search is
+ // performed either.
+ {"#:~:text=doesntexist", kUncounted},
+ {"#:~:text=page", kUncounted},
+ {"#:~:text=name", kUncounted},
+ // If the feature is enabled, `:~:text` parses and we don't count the
+ // element-id. If the feature is off, we still strip the :~: directive
+ // and the remaining fragment does match an element id.
{"#element:~:text=name", kUncountedOrFound}};
const int kNotFoundSample = 0;
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
index c675298719c..8419b78aa1e 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
@@ -873,8 +873,28 @@ TEST_F(TextFragmentAnchorTest, OneContextTerm) {
EXPECT_EQ(10u, markers.at(0)->EndOffset());
}
+class TextFragmentAnchorScrollTest
+ : public TextFragmentAnchorTest,
+ public testing::WithParamInterface<mojom::blink::ScrollType> {
+ protected:
+ bool IsUserScrollType() {
+ return GetParam() == mojom::blink::ScrollType::kCompositor ||
+ GetParam() == mojom::blink::ScrollType::kUser;
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(
+ ScrollTypes,
+ TextFragmentAnchorScrollTest,
+ testing::Values(mojom::blink::ScrollType::kUser,
+ mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollType::kClamping,
+ mojom::blink::ScrollType::kCompositor,
+ mojom::blink::ScrollType::kAnchoring,
+ mojom::blink::ScrollType::kSequenced));
+
// Test that a user scroll cancels the scroll into view.
-TEST_F(TextFragmentAnchorTest, ScrollCancelled) {
+TEST_P(TextFragmentAnchorScrollTest, ScrollCancelled) {
SimRequest request("https://example.com/test.html#:~:text=test", "text/html");
SimSubresourceRequest css_request("https://example.com/test.css", "text/css");
SimSubresourceRequest img_request("https://example.com/test.png",
@@ -898,9 +918,11 @@ TEST_F(TextFragmentAnchorTest, ScrollCancelled) {
)HTML");
Compositor().PaintFrame();
+ mojom::blink::ScrollType scroll_type = GetParam();
+
if (!RuntimeEnabledFeatures::BlockHTMLParserOnStyleSheetsEnabled()) {
- GetDocument().View()->LayoutViewport()->ScrollBy(
- ScrollOffset(0, 100), mojom::blink::ScrollType::kUser);
+ GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, 100),
+ scroll_type);
// Set the target text to visible and change its position to cause a layout
// and invoke the fragment anchor in the next begin frame.
css_request.Complete("p { visibility: visible; top: 1001px; }");
@@ -920,8 +942,8 @@ TEST_F(TextFragmentAnchorTest, ScrollCancelled) {
// Before invoking again, perform a user scroll. This should abort future
// scrolls during fragment invocation.
- GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 0), mojom::blink::ScrollType::kUser);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 0),
+ scroll_type);
ASSERT_FALSE(ViewportRect().Contains(BoundingRectInFrame(p)));
img_request.Complete("");
@@ -936,7 +958,14 @@ TEST_F(TextFragmentAnchorTest, ScrollCancelled) {
Compositor().BeginFrame();
Element& p = *GetDocument().getElementById("text");
- EXPECT_FALSE(ViewportRect().Contains(BoundingRectInFrame(p)));
+
+ // If the scroll was a user scroll then we shouldn't try to keep the fragment
+ // in view. Otherwise, we should.
+ if (IsUserScrollType()) {
+ EXPECT_FALSE(ViewportRect().Contains(BoundingRectInFrame(p)));
+ } else {
+ EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)));
+ }
EXPECT_EQ(p, *GetDocument().CssTarget());
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
@@ -950,6 +979,55 @@ TEST_F(TextFragmentAnchorTest, ScrollCancelled) {
EXPECT_EQ(14u, markers.at(0)->EndOffset());
}
+// Test that user scrolling dismisses the highlight.
+TEST_P(TextFragmentAnchorScrollTest, DismissTextHighlightOnUserScroll) {
+ SimRequest request(
+ "https://example.com/"
+ "test.html#:~:text=test%20page&text=more%20text",
+ "text/html");
+ LoadURL(
+ "https://example.com/"
+ "test.html#:~:text=test%20page&text=more%20text");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ height: 2200px;
+ }
+ #first {
+ position: absolute;
+ top: 1000px;
+ }
+ #second {
+ position: absolute;
+ top: 2000px;
+ }
+ </style>
+ <p id="first">This is a test page</p>
+ <p id="second">With some more text</p>
+ )HTML");
+ RunAsyncMatchingTasks();
+
+ // Render two frames to handle the async step added by the beforematch event.
+ Compositor().BeginFrame();
+ Compositor().BeginFrame();
+
+ ASSERT_EQ(2u, GetDocument().Markers().Markers().size());
+
+ mojom::blink::ScrollType scroll_type = GetParam();
+ LayoutViewport()->ScrollBy(ScrollOffset(0, -10), scroll_type);
+
+ Compositor().BeginFrame();
+
+ if (IsUserScrollType()) {
+ EXPECT_EQ(0u, GetDocument().Markers().Markers().size());
+ EXPECT_FALSE(GetDocument().View()->GetFragmentAnchor());
+ } else {
+ EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
+ EXPECT_TRUE(GetDocument().View()->GetFragmentAnchor());
+ }
+}
+
// Ensure that the text fragment anchor has no effect in an iframe. This is
// disabled in iframes by design, for security reasons.
TEST_F(TextFragmentAnchorTest, DisabledInIframes) {
@@ -1119,11 +1197,12 @@ TEST_F(TextFragmentAnchorTest, TargetStaysInView) {
<p id="text">test</p>
)HTML");
RunAsyncMatchingTasks();
-
- // Render two frames to handle the async step added by the beforematch event.
Compositor().BeginFrame();
Compositor().BeginFrame();
+ EXPECT_FALSE(GetDocument().IsLoadCompleted());
+ EXPECT_TRUE(GetDocument().HasFinishedParsing());
+
ScrollOffset first_scroll_offset = LayoutViewport()->GetScrollOffset();
ASSERT_NE(ScrollOffset(), first_scroll_offset);
@@ -1137,8 +1216,13 @@ TEST_F(TextFragmentAnchorTest, TargetStaysInView) {
<rect fill="green" width="200" height="2000"/>
</svg>
)SVG");
+ RunPendingTasks();
+ EXPECT_TRUE(GetDocument().IsLoadCompleted());
+ EXPECT_TRUE(GetDocument().HasFinishedParsing());
+
RunAsyncMatchingTasks();
Compositor().BeginFrame();
+ Compositor().BeginFrame();
// Ensure the target text is still in view and stayed centered
ASSERT_NE(first_scroll_offset, LayoutViewport()->GetScrollOffset());
@@ -1772,6 +1856,8 @@ TEST_F(TextFragmentAnchorTest, NonTextDirectives) {
<p id="first">This is a test page</p>
<p id="second">This is some more text</p>
)HTML");
+ RunPendingTasks();
+
// Render two frames to handle the async step added by the beforematch event.
Compositor().BeginFrame();
Compositor().BeginFrame();
@@ -1819,6 +1905,79 @@ TEST_F(TextFragmentAnchorTest, CssTarget) {
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
}
+// Ensure the text fragment anchor matching only occurs after the page becomes
+// visible.
+TEST_F(TextFragmentAnchorTest, PageVisibility) {
+ WebView().SetVisibilityState(mojom::blink::PageVisibilityState::kHidden,
+ /*initial_state=*/true);
+ SimRequest request("https://example.com/test.html#:~:text=test", "text/html");
+ LoadURL("https://example.com/test.html#:~:text=test");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ height: 1200px;
+ }
+ p {
+ position: absolute;
+ top: 1000px;
+ }
+ </style>
+ <p id="text">This is a test page</p>
+ )HTML");
+ RunAsyncMatchingTasks();
+
+ // Render two frames and ensure matching and scrolling does not occur.
+ BeginEmptyFrame();
+ BeginEmptyFrame();
+
+ Element& p = *GetDocument().getElementById("text");
+ EXPECT_FALSE(ViewportRect().Contains(BoundingRectInFrame(p)));
+ EXPECT_EQ(0u, GetDocument().Markers().Markers().size());
+ EXPECT_EQ(nullptr, GetDocument().CssTarget());
+
+ // Set the page visible and verify the match.
+ WebView().SetVisibilityState(mojom::blink::PageVisibilityState::kVisible,
+ /*initial_state=*/false);
+ BeginEmptyFrame();
+ BeginEmptyFrame();
+
+ EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)));
+ EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
+ EXPECT_EQ(p, *GetDocument().CssTarget());
+}
+
+// Test that a text directive can match across comment nodes
+TEST_F(TextFragmentAnchorTest, MatchAcrossCommentNode) {
+ SimRequest request("https://example.com/test.html#:~:text=abcdef",
+ "text/html");
+ LoadURL("https://example.com/test.html#:~:text=abcdef");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ height: 1200px;
+ }
+ div {
+ position: absolute;
+ top: 1000px;
+ }
+ </style>
+ <div id="text"><span>abc</span><!--comment--><span>def</span></div>
+ )HTML");
+ RunAsyncMatchingTasks();
+
+ // Render two frames to handle the async step added by the beforematch event.
+ Compositor().BeginFrame();
+ Compositor().BeginFrame();
+
+ Element& div = *GetDocument().getElementById("text");
+
+ EXPECT_EQ(div, *GetDocument().CssTarget());
+ EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(div)));
+ EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
+}
+
} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_finder.cc b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_finder.cc
index 275576fe690..ff63206e8c4 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_finder.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_finder.cc
@@ -10,11 +10,13 @@
#include "third_party/blink/renderer/core/display_lock/display_lock_document_state.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/range.h"
+#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/finder/find_buffer.h"
#include "third_party/blink/renderer/core/editing/finder/find_options.h"
#include "third_party/blink/renderer/core/editing/iterators/character_iterator.h"
#include "third_party/blink/renderer/core/editing/position.h"
+#include "third_party/blink/renderer/core/html/list_item_ordinal.h"
#include "third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h"
#include "third_party/blink/renderer/platform/text/text_boundaries.h"
@@ -171,6 +173,28 @@ EphemeralRangeInFlatTree FindMatchInRangeWithContext(
return EphemeralRangeInFlatTree();
}
+bool ContainedByListItem(const EphemeralRangeInFlatTree& range) {
+ Node* node = range.CommonAncestorContainer();
+ while (node) {
+ if (ListItemOrdinal::IsListItem(*node)) {
+ return true;
+ }
+ node = node->parentNode();
+ }
+ return false;
+}
+
+bool ContainedByTableCell(const EphemeralRangeInFlatTree& range) {
+ Node* node = range.CommonAncestorContainer();
+ while (node) {
+ if (IsTableCell(node)) {
+ return true;
+ }
+ node = node->parentNode();
+ }
+ return false;
+}
+
} // namespace
TextFragmentFinder::TextFragmentFinder(Client& client,
@@ -199,6 +223,13 @@ void TextFragmentFinder::FindMatch(Document& document) {
// we can just use the text from the selector.
DCHECK_EQ(selector_.Start().length(), PlainText(match).length());
match_metrics.text = selector_.Start();
+
+ if (ContainedByListItem(match)) {
+ match_metrics.is_list_item = true;
+ }
+ if (ContainedByTableCell(match)) {
+ match_metrics.is_table_cell = true;
+ }
} else if (selector_.Type() == TextFragmentSelector::SelectorType::kRange) {
match_metrics.text = PlainText(match);
}
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.cc b/chromium/third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.cc
index 965191f2609..be9702485eb 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.cc
@@ -38,7 +38,7 @@ ScrollableArea* GetScrollableArea(Node* node) {
TopDocumentRootScrollerController::TopDocumentRootScrollerController(Page& page)
: page_(&page) {}
-void TopDocumentRootScrollerController::Trace(Visitor* visitor) {
+void TopDocumentRootScrollerController::Trace(Visitor* visitor) const {
visitor->Trace(viewport_apply_scroll_);
visitor->Trace(global_root_scroller_);
visitor->Trace(page_);
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h b/chromium/third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h
index e44a32a8c60..20e937fd343 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h
@@ -31,7 +31,7 @@ class CORE_EXPORT TopDocumentRootScrollerController
public:
explicit TopDocumentRootScrollerController(Page&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// PaintLayerScrollableAreas need to notify this class when they're being
// disposed so that we can remove them as the root scroller.
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/viewport_scroll_callback.cc b/chromium/third_party/blink/renderer/core/page/scrolling/viewport_scroll_callback.cc
index 89a5d9ad278..94682aee1a7 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/viewport_scroll_callback.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/viewport_scroll_callback.cc
@@ -25,7 +25,7 @@ ViewportScrollCallback::ViewportScrollCallback(
ViewportScrollCallback::~ViewportScrollCallback() = default;
-void ViewportScrollCallback::Trace(Visitor* visitor) {
+void ViewportScrollCallback::Trace(Visitor* visitor) const {
visitor->Trace(browser_controls_);
visitor->Trace(overscroll_controller_);
visitor->Trace(root_frame_viewport_);
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/viewport_scroll_callback.h b/chromium/third_party/blink/renderer/core/page/scrolling/viewport_scroll_callback.h
index 081f04da55d..3c43c57ccca 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/viewport_scroll_callback.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/viewport_scroll_callback.h
@@ -41,7 +41,7 @@ class ViewportScrollCallback : public ScrollStateCallback {
void Invoke(ScrollState*) override;
void SetScroller(ScrollableArea*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool ShouldScrollBrowserControls(const ScrollOffset&,
diff --git a/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.cc b/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
index 7b4d0e8e8b6..29d1df15043 100644
--- a/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
@@ -302,7 +302,7 @@ void SpatialNavigationController::DidDetachFrameView(
}
}
-void SpatialNavigationController::Trace(Visitor* visitor) {
+void SpatialNavigationController::Trace(Visitor* visitor) const {
visitor->Trace(interest_element_);
visitor->Trace(page_);
visitor->Trace(spatial_navigation_host_);
diff --git a/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.h b/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.h
index efd72e2dc6f..50116b760b0 100644
--- a/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.h
+++ b/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.h
@@ -49,7 +49,7 @@ class CORE_EXPORT SpatialNavigationController final
void FocusedNodeChanged(Document*);
void FullscreenStateChanged(Element* element);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// Entry-point into SpatialNavigation advancement. Will return true if an
diff --git a/chromium/third_party/blink/renderer/core/page/touch_adjustment.cc b/chromium/third_party/blink/renderer/core/page/touch_adjustment.cc
index f313ea77855..e5d95d49ca3 100644
--- a/chromium/third_party/blink/renderer/core/page/touch_adjustment.cc
+++ b/chromium/third_party/blink/renderer/core/page/touch_adjustment.cc
@@ -60,7 +60,7 @@ class SubtargetGeometry {
public:
SubtargetGeometry(Node* node, const FloatQuad& quad)
: node_(node), quad_(quad) {}
- void Trace(Visitor* visitor) { visitor->Trace(node_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(node_); }
Node* GetNode() const { return node_; }
FloatQuad Quad() const { return quad_; }
diff --git a/chromium/third_party/blink/renderer/core/page/validation_message_client.h b/chromium/third_party/blink/renderer/core/page/validation_message_client.h
index 1096a92e09b..e23056b5dc7 100644
--- a/chromium/third_party/blink/renderer/core/page/validation_message_client.h
+++ b/chromium/third_party/blink/renderer/core/page/validation_message_client.h
@@ -68,7 +68,7 @@ class ValidationMessageClient : public GarbageCollectedMixin {
// For CompositeAfterPaint.
virtual void PaintOverlay(GraphicsContext&) {}
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/validation_message_client_impl.cc b/chromium/third_party/blink/renderer/core/page/validation_message_client_impl.cc
index f96d766bb3c..7e5b29d8864 100644
--- a/chromium/third_party/blink/renderer/core/page/validation_message_client_impl.cc
+++ b/chromium/third_party/blink/renderer/core/page/validation_message_client_impl.cc
@@ -217,7 +217,7 @@ void ValidationMessageClientImpl::PaintOverlay(GraphicsContext& context) {
overlay_->Paint(context);
}
-void ValidationMessageClientImpl::Trace(Visitor* visitor) {
+void ValidationMessageClientImpl::Trace(Visitor* visitor) const {
visitor->Trace(page_);
visitor->Trace(current_anchor_);
ValidationMessageClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/page/validation_message_client_impl.h b/chromium/third_party/blink/renderer/core/page/validation_message_client_impl.h
index 6f422df20ab..34fd9d7f108 100644
--- a/chromium/third_party/blink/renderer/core/page/validation_message_client_impl.h
+++ b/chromium/third_party/blink/renderer/core/page/validation_message_client_impl.h
@@ -57,7 +57,7 @@ class CORE_EXPORT ValidationMessageClientImpl final
const String& sub_message,
TextDirection sub_message_dir) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
ValidationMessageOverlayDelegate* GetDelegateForTesting() const {
return overlay_delegate_;
diff --git a/chromium/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc b/chromium/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc
index ffc35f8455f..bc6fc1bac57 100644
--- a/chromium/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc
+++ b/chromium/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc
@@ -34,7 +34,7 @@ class ValidationMessageChromeClient : public EmptyChromeClient {
LocalFrameView* anchor_view)
: main_chrome_client_(main_chrome_client), anchor_view_(anchor_view) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(main_chrome_client_);
visitor->Trace(anchor_view_);
EmptyChromeClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/page/zoom_test.cc b/chromium/third_party/blink/renderer/core/page/zoom_test.cc
deleted file mode 100644
index 487d958607d..00000000000
--- a/chromium/third_party/blink/renderer/core/page/zoom_test.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/frame/local_dom_window.h"
-#include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/core/frame/local_frame_view.h"
-#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
-
-namespace blink {
-
-class FractionalZoomSimTest : public SimTest {};
-
-TEST_F(FractionalZoomSimTest, CheckCSSMediaQueryWidthEqualsWindowInnerWidth) {
- WebView().MainFrameWidget()->Resize(WebSize(1081, 1921));
-
- // 1081/2.75 = 393.091
- // 1081/2.00 = 540.500
- // 1081/1.50 = 720.667
- std::vector<float> factors = {2.75f, 2.00f, 1.50f};
- for (auto factor : factors) {
- WebView().SetZoomFactorForDeviceScaleFactor(factor);
- EXPECT_EQ(GetDocument().View()->ViewportSizeForMediaQueries().Width(),
- GetDocument().GetFrame()->DomWindow()->innerWidth());
- }
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/applied_decoration_painter.cc b/chromium/third_party/blink/renderer/core/paint/applied_decoration_painter.cc
index 2c372e384af..a408b2f123e 100644
--- a/chromium/third_party/blink/renderer/core/paint/applied_decoration_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/applied_decoration_painter.cc
@@ -59,13 +59,13 @@ Path AppliedDecorationPainter::PrepareDottedDashedStrokePath() {
// These coordinate transforms need to match what's happening in
// GraphicsContext's drawLineForText and drawLine.
int y = floorf(start_point_.Y() +
- std::max<float>(decoration_info_.thickness / 2.0f, 0.5f));
+ std::max<float>(resolved_thickness_ / 2.0f, 0.5f));
Path stroke_path;
FloatPoint rounded_start_point(start_point_.X(), y);
FloatPoint rounded_end_point(rounded_start_point +
FloatPoint(decoration_info_.width, 0));
context_.AdjustLineToPixelBoundaries(rounded_start_point, rounded_end_point,
- roundf(decoration_info_.thickness));
+ roundf(resolved_thickness_));
stroke_path.MoveTo(rounded_start_point);
stroke_path.AddLineTo(rounded_end_point);
return stroke_path;
@@ -73,7 +73,7 @@ Path AppliedDecorationPainter::PrepareDottedDashedStrokePath() {
FloatRect AppliedDecorationPainter::Bounds() {
StrokeData stroke_data;
- stroke_data.SetThickness(decoration_info_.thickness);
+ stroke_data.SetThickness(resolved_thickness_);
switch (decoration_.Style()) {
case ETextDecorationStyle::kDotted:
@@ -88,14 +88,14 @@ FloatRect AppliedDecorationPainter::Bounds() {
if (double_offset_ > 0) {
return FloatRect(start_point_.X(), start_point_.Y(),
decoration_info_.width,
- double_offset_ + decoration_info_.thickness);
+ double_offset_ + resolved_thickness_);
}
return FloatRect(start_point_.X(), start_point_.Y() + double_offset_,
decoration_info_.width,
- -double_offset_ + decoration_info_.thickness);
+ -double_offset_ + resolved_thickness_);
case ETextDecorationStyle::kSolid:
return FloatRect(start_point_.X(), start_point_.Y(),
- decoration_info_.width, decoration_info_.thickness);
+ decoration_info_.width, resolved_thickness_);
default:
break;
}
@@ -165,7 +165,7 @@ Path AppliedDecorationPainter::PrepareWavyStrokePath() {
start_point_ +
FloatPoint(decoration_info_.width, double_offset_ * wavy_offset_factor_));
- context_.AdjustLineToPixelBoundaries(p1, p2, decoration_info_.thickness);
+ context_.AdjustLineToPixelBoundaries(p1, p2, resolved_thickness_);
Path path;
path.MoveTo(p1);
@@ -178,13 +178,12 @@ Path AppliedDecorationPainter::PrepareWavyStrokePath() {
// The minimum height of the curve is also approximately 3 pixels. Increases
// the curve's height
// as strockThickness increases to make the curve looks better.
- float control_point_distance =
- 3 * std::max<float>(2, decoration_info_.thickness);
+ float control_point_distance = 3 * std::max<float>(2, resolved_thickness_);
// Increment used to form the diamond shape between start point (p1), control
// points and end point (p2) along the axis of the decoration. Makes the
// curve wider as strockThickness increases to make the curve looks better.
- float step = 2 * std::max<float>(2, decoration_info_.thickness);
+ float step = 2 * std::max<float>(2, resolved_thickness_);
bool is_vertical_line = (p1.X() == p2.X());
diff --git a/chromium/third_party/blink/renderer/core/paint/applied_decoration_painter.h b/chromium/third_party/blink/renderer/core/paint/applied_decoration_painter.h
index f7d49cea0c9..cd37112be5f 100644
--- a/chromium/third_party/blink/renderer/core/paint/applied_decoration_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/applied_decoration_painter.h
@@ -28,12 +28,15 @@ class AppliedDecorationPainter final {
const DecorationInfo& decoration_info,
float start_point_y_offset,
const AppliedTextDecoration& decoration,
+ size_t decoration_info_thickness_index,
float double_offset,
int wavy_offset_factor)
: context_(context),
start_point_(decoration_info.local_origin +
FloatPoint(0, start_point_y_offset)),
decoration_info_(decoration_info),
+ resolved_thickness_(decoration_info.applied_decorations_thickness
+ [decoration_info_thickness_index]),
decoration_(decoration),
double_offset_(double_offset),
wavy_offset_factor_(wavy_offset_factor) {}
@@ -50,6 +53,7 @@ class AppliedDecorationPainter final {
GraphicsContext& context_;
const FloatPoint start_point_;
const DecorationInfo& decoration_info_;
+ float resolved_thickness_;
const AppliedTextDecoration& decoration_;
const float double_offset_;
const int wavy_offset_factor_;
diff --git a/chromium/third_party/blink/renderer/core/paint/box_border_painter.cc b/chromium/third_party/blink/renderer/core/paint/box_border_painter.cc
index 49772004f87..eba80981180 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_border_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_border_painter.cc
@@ -294,7 +294,7 @@ void DrawSolidBorderRect(GraphicsContext& context,
float border_width,
const Color& color) {
FloatRect stroke_rect(border_rect);
- border_width = roundf(border_width);
+ border_width = floorf(border_width);
stroke_rect.Inflate(-border_width / 2);
bool was_antialias = context.ShouldAntialias();
@@ -846,7 +846,7 @@ void BoxBorderPainter::PaintSide(GraphicsContext& context,
if (use_path)
path = &border_info.rounded_border_path;
else
- side_rect.SetHeight(roundf(edge.Width()));
+ side_rect.SetHeight(floorf(edge.Width()));
PaintOneBorderSide(context, side_rect, BoxSide::kTop, BoxSide::kLeft,
BoxSide::kRight, path, border_info.anti_alias, color,
@@ -861,7 +861,7 @@ void BoxBorderPainter::PaintSide(GraphicsContext& context,
if (use_path)
path = &border_info.rounded_border_path;
else
- side_rect.ShiftYEdgeTo(side_rect.MaxY() - roundf(edge.Width()));
+ side_rect.ShiftYEdgeTo(side_rect.MaxY() - floorf(edge.Width()));
PaintOneBorderSide(context, side_rect, BoxSide::kBottom, BoxSide::kLeft,
BoxSide::kRight, path, border_info.anti_alias, color,
@@ -876,7 +876,7 @@ void BoxBorderPainter::PaintSide(GraphicsContext& context,
if (use_path)
path = &border_info.rounded_border_path;
else
- side_rect.SetWidth(roundf(edge.Width()));
+ side_rect.SetWidth(floorf(edge.Width()));
PaintOneBorderSide(context, side_rect, BoxSide::kLeft, BoxSide::kTop,
BoxSide::kBottom, path, border_info.anti_alias, color,
@@ -891,7 +891,7 @@ void BoxBorderPainter::PaintSide(GraphicsContext& context,
if (use_path)
path = &border_info.rounded_border_path;
else
- side_rect.ShiftXEdgeTo(side_rect.MaxX() - roundf(edge.Width()));
+ side_rect.ShiftXEdgeTo(side_rect.MaxX() - floorf(edge.Width()));
PaintOneBorderSide(context, side_rect, BoxSide::kRight, BoxSide::kTop,
BoxSide::kBottom, path, border_info.anti_alias, color,
@@ -1009,8 +1009,8 @@ void BoxBorderPainter::PaintOneBorderSide(
ObjectPainter::DrawLineForBoxSide(
graphics_context, side_rect.X(), side_rect.Y(), side_rect.MaxX(),
side_rect.MaxY(), side, color, edge_to_render.BorderStyle(),
- miter1 != kNoMiter ? roundf(adjacent_edge1.Width()) : 0,
- miter2 != kNoMiter ? roundf(adjacent_edge2.Width()) : 0, antialias);
+ miter1 != kNoMiter ? floorf(adjacent_edge1.Width()) : 0,
+ miter2 != kNoMiter ? floorf(adjacent_edge2.Width()) : 0, antialias);
}
}
diff --git a/chromium/third_party/blink/renderer/core/paint/box_painter.cc b/chromium/third_party/blink/renderer/core/paint/box_painter.cc
index b07886218ca..57eea701f66 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_painter.cc
@@ -106,7 +106,9 @@ void BoxPainter::PaintBoxDecorationBackground(
// composited in PaintArtifactCompositor::UpdateNonFastScrollableRegions.
if (layout_box_.HasLayer() &&
layout_box_.Layer()->GetCompositedLayerMapping() &&
- layout_box_.Layer()->GetCompositedLayerMapping()->HasScrollingLayer()) {
+ layout_box_.Layer()
+ ->GetCompositedLayerMapping()
+ ->ScrollingContentsLayer()) {
needs_scroll_hit_test = false;
}
}
diff --git a/chromium/third_party/blink/renderer/core/paint/box_painter_base.cc b/chromium/third_party/blink/renderer/core/paint/box_painter_base.cc
index 660f62adc5b..b2ee041e40c 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_painter_base.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_painter_base.cc
@@ -839,9 +839,6 @@ void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
interpolation_quality_context.emplace(context,
geometry.ImageInterpolationQuality());
- if (bg_layer.MaskSourceType() == EMaskSourceType::kLuminance)
- context.SetColorFilter(kColorFilterLuminanceToAlpha);
-
if (ShouldApplyBlendOperation(info, bg_layer)) {
composite_op = WebCoreCompositeToSkiaComposite(bg_layer.Composite(),
bg_layer.GetBlendMode());
diff --git a/chromium/third_party/blink/renderer/core/paint/box_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/box_painter_test.cc
index e2568b1663a..bca3edbf0ae 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_painter_test.cc
@@ -220,7 +220,7 @@ TEST_P(BoxPainterTest, ScrollHitTestProperties) {
width: 200px;
height: 200px;
overflow-y: scroll;
- background: green;
+ background: rgba(0, 128, 0, 0.5); /* to prevent compositing */
}
#child { width: 100px; height: 300px; background: green; }
</style>
@@ -235,9 +235,8 @@ TEST_P(BoxPainterTest, ScrollHitTestProperties) {
// The scroll hit test should be after the container background but before the
// scrolled contents.
- EXPECT_EQ(
- kBackgroundPaintInGraphicsLayer | kBackgroundPaintInScrollingContents,
- container.ComputeBackgroundPaintLocationIfComposited());
+ EXPECT_EQ(kBackgroundPaintInGraphicsLayer,
+ container.ComputeBackgroundPaintLocationIfComposited());
EXPECT_EQ(kBackgroundPaintInGraphicsLayer,
container.GetBackgroundPaintLocation());
EXPECT_THAT(
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
index 91ceb4707ee..1b460151f02 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -167,7 +167,7 @@ static FloatPoint StickyPositionOffsetForLayer(PaintLayer& layer) {
static bool NeedsDecorationOutlineLayer(const PaintLayer& paint_layer,
const LayoutObject& layout_object) {
- int min_border_width = std::min(
+ const int min_border_width = std::min(
layout_object.StyleRef().BorderTopWidth(),
std::min(layout_object.StyleRef().BorderLeftWidth(),
std::min(layout_object.StyleRef().BorderRightWidth(),
@@ -178,23 +178,45 @@ static bool NeedsDecorationOutlineLayer(const PaintLayer& paint_layer,
paint_layer.GetScrollableArea()->UsesCompositedScrolling()) ||
layout_object.IsCanvas() || IsA<LayoutVideo>(layout_object);
+ // Unlike normal outlines (whole width is outside of the offset), focus
+ // rings can be drawn with the center of the path aligned with the offset, so
+ // only 2/3 of the width is outside of the offset.
+ const int outline_drawn_inside =
+ layout_object.StyleRef().OutlineStyleIsAuto()
+ ? std::ceil(
+ layout_object.StyleRef().GetOutlineStrokeWidthForFocusRing() /
+ 3.f) +
+ 1
+ : 0;
+
return could_obscure_decorations && layout_object.StyleRef().HasOutline() &&
- layout_object.StyleRef().OutlineOffsetInt() < -min_border_width;
+ (layout_object.StyleRef().OutlineOffsetInt() - outline_drawn_inside) <
+ -min_border_width;
}
CompositedLayerMapping::CompositedLayerMapping(PaintLayer& layer)
: owning_layer_(layer),
pending_update_scope_(kGraphicsLayerUpdateNone),
- scrolling_contents_are_empty_(false),
draws_background_onto_content_layer_(false) {
CreatePrimaryGraphicsLayer();
}
CompositedLayerMapping::~CompositedLayerMapping() {
+ RemoveSquashedLayers(non_scrolling_squashed_layers_);
+ RemoveSquashedLayers(squashed_layers_in_scrolling_contents_);
+ UpdateOverflowControlsLayers(false, false, false);
+ UpdateForegroundLayer(false);
+ UpdateMaskLayer(false);
+ UpdateScrollingContentsLayer(false);
+ UpdateSquashingLayers(false);
+}
+
+void CompositedLayerMapping::RemoveSquashedLayers(
+ Vector<GraphicsLayerPaintInfo>& squashed_layers) {
// Do not leave the destroyed pointer dangling on any Layers that painted to
// this mapping's squashing layer.
- for (wtf_size_t i = 0; i < squashed_layers_.size(); ++i) {
- PaintLayer* old_squashed_layer = squashed_layers_[i].paint_layer;
+ for (auto& squashed_layer : squashed_layers) {
+ PaintLayer* old_squashed_layer = squashed_layer.paint_layer;
// Assert on incorrect mappings between layers and groups
DCHECK_EQ(old_squashed_layer->GroupedMapping(), this);
if (old_squashed_layer->GroupedMapping() == this) {
@@ -203,12 +225,6 @@ CompositedLayerMapping::~CompositedLayerMapping() {
old_squashed_layer->SetLostGroupedMapping(true);
}
}
-
- UpdateOverflowControlsLayers(false, false, false);
- UpdateForegroundLayer(false);
- UpdateMaskLayer(false);
- UpdateScrollingLayers(false);
- UpdateSquashingLayers(false);
}
std::unique_ptr<GraphicsLayer> CompositedLayerMapping::CreateGraphicsLayer(
@@ -254,6 +270,24 @@ void CompositedLayerMapping::CreatePrimaryGraphicsLayer() {
graphics_layer_->SetHitTestable(true);
}
+void CompositedLayerMapping::UpdateGraphicsLayerContentsOpaque(
+ bool should_check_children) {
+ if (BackgroundPaintsOntoGraphicsLayer()) {
+ bool contents_opaque = owning_layer_.BackgroundIsKnownToBeOpaqueInRect(
+ CompositedBounds(), should_check_children);
+ graphics_layer_->SetContentsOpaque(contents_opaque);
+ if (!contents_opaque) {
+ graphics_layer_->SetContentsOpaqueForText(
+ GetLayoutObject().TextIsKnownToBeOnOpaqueBackground());
+ }
+ } else {
+ // If we only paint the background onto the scrolling contents layer we
+ // are going to leave a hole in the m_graphicsLayer where the background
+ // is so it is not opaque.
+ graphics_layer_->SetContentsOpaque(false);
+ }
+}
+
void CompositedLayerMapping::UpdateContentsOpaque() {
// If there is a foreground layer, children paint into that layer and
// not graphics_layer_, and so don't contribute to the opaqueness of the
@@ -283,45 +317,55 @@ void CompositedLayerMapping::UpdateContentsOpaque() {
// determined from the main thread. Or can it?
graphics_layer_->SetContentsOpaque(false);
} else if (BackgroundPaintsOntoScrollingContentsLayer()) {
- DCHECK(HasScrollingLayer());
+ DCHECK(scrolling_contents_layer_);
// Backgrounds painted onto the foreground are clipped by the padding box
// rect.
// TODO(flackr): This should actually check the entire overflow rect
// within the scrolling contents layer but since we currently only trigger
// this for solid color backgrounds the answer will be the same.
- scrolling_contents_layer_->SetContentsOpaque(
- owning_layer_.BackgroundIsKnownToBeOpaqueInRect(
- ToLayoutBox(GetLayoutObject()).PhysicalPaddingBoxRect(),
- should_check_children));
-
- if (BackgroundPaintsOntoGraphicsLayer()) {
- graphics_layer_->SetContentsOpaque(
- owning_layer_.BackgroundIsKnownToBeOpaqueInRect(
- CompositedBounds(), should_check_children));
- } else {
- // If we only paint the background onto the scrolling contents layer we
- // are going to leave a hole in the m_graphicsLayer where the background
- // is so it is not opaque.
- graphics_layer_->SetContentsOpaque(false);
+ bool contents_opaque = owning_layer_.BackgroundIsKnownToBeOpaqueInRect(
+ ToLayoutBox(GetLayoutObject()).PhysicalPaddingBoxRect(),
+ should_check_children);
+ scrolling_contents_layer_->SetContentsOpaque(contents_opaque);
+ if (!contents_opaque) {
+ scrolling_contents_layer_->SetContentsOpaqueForText(
+ GetLayoutObject().TextIsKnownToBeOnOpaqueBackground());
}
+
+ UpdateGraphicsLayerContentsOpaque(should_check_children);
} else {
DCHECK(BackgroundPaintsOntoGraphicsLayer());
- if (HasScrollingLayer())
+ if (scrolling_contents_layer_)
scrolling_contents_layer_->SetContentsOpaque(false);
- graphics_layer_->SetContentsOpaque(
- owning_layer_.BackgroundIsKnownToBeOpaqueInRect(CompositedBounds(),
- should_check_children));
+ UpdateGraphicsLayerContentsOpaque(should_check_children);
+ }
+
+ if (non_scrolling_squashing_layer_) {
+ non_scrolling_squashing_layer_->SetContentsOpaque(false);
+ bool contents_opaque_for_text = true;
+ for (const GraphicsLayerPaintInfo& squashed_layer :
+ non_scrolling_squashed_layers_) {
+ if (!squashed_layer.paint_layer->GetLayoutObject()
+ .TextIsKnownToBeOnOpaqueBackground()) {
+ contents_opaque_for_text = false;
+ break;
+ }
+ }
+ non_scrolling_squashing_layer_->SetContentsOpaqueForText(
+ contents_opaque_for_text);
}
}
void CompositedLayerMapping::UpdateRasterizationPolicy() {
bool transformed_rasterization_allowed =
!(owning_layer_.GetCompositingReasons() &
- CompositingReason::kComboAllDirectReasons);
+ CompositingReason::kComboTransformedRasterizationDisallowedReasons);
graphics_layer_->CcLayer()->SetTransformedRasterizationAllowed(
transformed_rasterization_allowed);
- if (squashing_layer_)
- squashing_layer_->CcLayer()->SetTransformedRasterizationAllowed(true);
+ if (non_scrolling_squashing_layer_) {
+ non_scrolling_squashing_layer_->CcLayer()
+ ->SetTransformedRasterizationAllowed(true);
+ }
}
void CompositedLayerMapping::UpdateCompositedBounds() {
@@ -360,7 +404,7 @@ bool CompositedLayerMapping::UpdateGraphicsLayerConfiguration(
compositor->NeedsContentsCompositingLayer(&owning_layer_)))
layer_config_changed = true;
- if (UpdateScrollingLayers(owning_layer_.NeedsCompositedScrolling()))
+ if (UpdateScrollingContentsLayer(owning_layer_.NeedsCompositedScrolling()))
layer_config_changed = true;
// If the outline needs to draw over the composited scrolling contents layer
@@ -377,25 +421,19 @@ bool CompositedLayerMapping::UpdateGraphicsLayerConfiguration(
RequiresScrollCornerLayer()))
layer_config_changed = true;
- if (UpdateSquashingLayers(!squashed_layers_.IsEmpty()))
+ if (UpdateSquashingLayers(!non_scrolling_squashed_layers_.IsEmpty()))
layer_config_changed = true;
- if (layer_config_changed)
- UpdateInternalHierarchy();
-
- // A mask layer is not part of the hierarchy proper, it's an auxiliary layer
- // that's plugged into another GraphicsLayer that is part of the hierarchy.
- // It has no parent or child GraphicsLayer. For that reason, we process it
- // here, after the hierarchy has been updated.
bool has_mask =
CSSMaskPainter::MaskBoundingBox(GetLayoutObject(), PhysicalOffset())
.has_value();
bool has_clip_path =
ClipPathClipper::LocalClipPathBoundingBox(GetLayoutObject()).has_value();
- if (UpdateMaskLayer(has_mask || has_clip_path)) {
- graphics_layer_->SetMaskLayer(mask_layer_.get());
+ if (UpdateMaskLayer(has_mask || has_clip_path))
layer_config_changed = true;
- }
+
+ if (layer_config_changed)
+ UpdateInternalHierarchy();
UpdateBackgroundColor();
@@ -410,9 +448,6 @@ bool CompositedLayerMapping::UpdateGraphicsLayerConfiguration(
remote->GetCcLayer(), remote->WebLayerHasFixedContentsOpaque());
}
}
- if (PaintLayerCompositor::AttachFrameContentLayersToIframeLayer(
- ToLayoutEmbeddedContent(layout_object)))
- layer_config_changed = true;
} else if (IsA<LayoutVideo>(layout_object)) {
auto* media_element = To<HTMLMediaElement>(layout_object.GetNode());
graphics_layer_->SetContentsToCcLayer(
@@ -555,7 +590,7 @@ void CompositedLayerMapping::UpdateSquashingLayerGeometry(
const IntPoint& snapped_offset_from_composited_ancestor,
Vector<GraphicsLayerPaintInfo>& layers,
Vector<PaintLayer*>& layers_needing_paint_invalidation) {
- if (!squashing_layer_)
+ if (!non_scrolling_squashing_layer_)
return;
IntPoint graphics_layer_parent_location;
@@ -656,24 +691,24 @@ void CompositedLayerMapping::UpdateSquashingLayerGeometry(
layers[i].paint_layer->SetSubpixelAccumulation(subpixel_accumulation);
}
- squashing_layer_->SetSize(gfx::Size(squash_layer_bounds.Size()));
- // We can't squashing_layer_->SetOffsetFromLayoutObject().
+ non_scrolling_squashing_layer_->SetSize(
+ gfx::Size(squash_layer_bounds.Size()));
+ // We can't non_scrolling_squashing_layer_->SetOffsetFromLayoutObject().
// Squashing layer has special paint and invalidation logic that already
// compensated for compositing bounds, setting it here would end up
// double adjustment.
auto new_offset = squash_layer_bounds.Location() -
snapped_offset_from_composited_ancestor +
ToIntSize(graphics_layer_parent_location);
- if (new_offset != squashing_layer_offset_from_layout_object_) {
- squashing_layer_offset_from_layout_object_ = new_offset;
+ if (new_offset != non_scrolling_squashing_layer_offset_from_layout_object_) {
+ non_scrolling_squashing_layer_offset_from_layout_object_ = new_offset;
// Need to update squashing LayerState according to the new offset.
// The pre-paint tree walk does this.
GetLayoutObject().SetNeedsPaintPropertyUpdate();
}
- for (wtf_size_t i = 0; i < layers.size(); ++i) {
- LocalClipRectForSquashedLayer(owning_layer_, layers, layers[i]);
- }
+ for (auto& layer : layers)
+ UpdateLocalClipRectForSquashedLayer(owning_layer_, layers, layer);
}
void CompositedLayerMapping::UpdateGraphicsLayerGeometry(
@@ -691,14 +726,11 @@ void CompositedLayerMapping::UpdateGraphicsLayerGeometry(
UpdateOverflowControlsHostLayerGeometry(compositing_container);
UpdateSquashingLayerGeometry(
compositing_container, snapped_offset_from_composited_ancestor,
- squashed_layers_, layers_needing_paint_invalidation);
+ non_scrolling_squashed_layers_, layers_needing_paint_invalidation);
UpdateMaskLayerGeometry();
- // TODO(yigu): Currently the decoration layer uses the same contentSize
- // as the foreground layer. There are scenarios where the sizes could be
- // different so the decoration layer size should be calculated separately.
UpdateDecorationOutlineLayerGeometry(local_compositing_bounds.Size());
- UpdateScrollingLayerGeometry();
+ UpdateScrollingContentsLayerGeometry(layers_needing_paint_invalidation);
UpdateForegroundLayerGeometry();
if (owning_layer_.GetScrollableArea() &&
@@ -788,22 +820,22 @@ void CompositedLayerMapping::UpdateMaskLayerGeometry() {
graphics_layer_->OffsetFromLayoutObject());
}
-void CompositedLayerMapping::UpdateScrollingLayerGeometry() {
- if (!scrolling_layer_)
+void CompositedLayerMapping::UpdateScrollingContentsLayerGeometry(
+ Vector<PaintLayer*>& layers_needing_paint_invalidation) {
+ if (!scrolling_contents_layer_) {
+ DCHECK(squashed_layers_in_scrolling_contents_.IsEmpty());
return;
+ }
DCHECK(scrolling_contents_layer_);
LayoutBox& layout_box = ToLayoutBox(GetLayoutObject());
IntRect overflow_clip_rect = PixelSnappedIntRect(
layout_box.OverflowClipRect(owning_layer_.SubpixelAccumulation()));
- auto old_scroll_container_size = scrolling_layer_->Size();
- scrolling_layer_->SetSize(gfx::Size(overflow_clip_rect.Size()));
bool scroll_container_size_changed =
- old_scroll_container_size != scrolling_layer_->Size();
-
- scrolling_layer_->SetOffsetFromLayoutObject(
- ToIntSize(overflow_clip_rect.Location()));
+ previous_scroll_container_size_ != overflow_clip_rect.Size();
+ if (scroll_container_size_changed)
+ previous_scroll_container_size_ = overflow_clip_rect.Size();
PaintLayerScrollableArea* scrollable_area = owning_layer_.GetScrollableArea();
IntSize scroll_size = scrollable_area->PixelSnappedContentsSize(
@@ -825,6 +857,33 @@ void CompositedLayerMapping::UpdateScrollingLayerGeometry() {
scrolling_contents_layer_->SetOffsetFromLayoutObject(
overflow_clip_rect.Location() - scrollable_area->ScrollOrigin());
+
+ for (auto& layer : squashed_layers_in_scrolling_contents_) {
+ layer.composited_bounds = layer.paint_layer->BoundingBoxForCompositing();
+ PhysicalOffset offset_from_scrolling_contents_layer =
+ layer.paint_layer->ComputeOffsetFromAncestor(owning_layer_) +
+ owning_layer_.SubpixelAccumulation() -
+ PhysicalOffset(scrolling_contents_layer_->OffsetFromLayoutObject());
+ IntSize new_offset_from_layout_object =
+ -ToIntSize(RoundedIntPoint(offset_from_scrolling_contents_layer));
+ PhysicalOffset subpixel_accumulation =
+ offset_from_scrolling_contents_layer +
+ PhysicalOffset(new_offset_from_layout_object);
+
+ if (layer.offset_from_layout_object_set &&
+ layer.offset_from_layout_object != new_offset_from_layout_object) {
+ ObjectPaintInvalidator(layer.paint_layer->GetLayoutObject())
+ .InvalidatePaintIncludingNonCompositingDescendants();
+ layers_needing_paint_invalidation.push_back(layer.paint_layer);
+ }
+ layer.offset_from_layout_object = new_offset_from_layout_object;
+ layer.offset_from_layout_object_set = true;
+ layer.paint_layer->SetSubpixelAccumulation(subpixel_accumulation);
+ }
+ for (auto& layer : squashed_layers_in_scrolling_contents_) {
+ UpdateLocalClipRectForSquashedLayer(
+ owning_layer_, squashed_layers_in_scrolling_contents_, layer);
+ }
}
bool CompositedLayerMapping::RequiresHorizontalScrollbarLayer() const {
@@ -852,7 +911,7 @@ void CompositedLayerMapping::UpdateForegroundLayerGeometry() {
IntRect compositing_bounds(
IntPoint(graphics_layer_->OffsetFromLayoutObject()),
IntSize(graphics_layer_->Size()));
- if (scrolling_layer_) {
+ if (scrolling_contents_layer_) {
// Override compositing bounds to include full overflow if composited
// scrolling is used.
compositing_bounds =
@@ -885,47 +944,36 @@ void CompositedLayerMapping::UpdateDecorationOutlineLayerGeometry(
}
void CompositedLayerMapping::UpdateInternalHierarchy() {
- // m_foregroundLayer has to be inserted in the correct order with child
- // layers, so it's not inserted here.
+ // foreground_layer_ has to be inserted in the correct order with child
+ // layers in SetSubLayers(), so it's not inserted here.
graphics_layer_->RemoveFromParent();
- // Layer to which children should be attached as we build the hierarchy.
- GraphicsLayer* bottom_layer = graphics_layer_.get();
- auto update_bottom_layer = [&bottom_layer](GraphicsLayer* layer) {
- if (layer) {
- bottom_layer->AddChild(layer);
- bottom_layer = layer;
- }
- };
-
- update_bottom_layer(scrolling_layer_.get());
+ if (scrolling_contents_layer_)
+ graphics_layer_->AddChild(scrolling_contents_layer_.get());
// Now constructing the subtree for the overflow controls.
- bottom_layer = graphics_layer_.get();
- update_bottom_layer(overflow_controls_host_layer_.get());
- if (layer_for_horizontal_scrollbar_) {
- overflow_controls_host_layer_->AddChild(
- layer_for_horizontal_scrollbar_.get());
- }
- if (layer_for_vertical_scrollbar_) {
- overflow_controls_host_layer_->AddChild(
- layer_for_vertical_scrollbar_.get());
+ if (overflow_controls_host_layer_) {
+ graphics_layer_->AddChild(overflow_controls_host_layer_.get());
+ if (layer_for_horizontal_scrollbar_) {
+ overflow_controls_host_layer_->AddChild(
+ layer_for_horizontal_scrollbar_.get());
+ }
+ if (layer_for_vertical_scrollbar_) {
+ overflow_controls_host_layer_->AddChild(
+ layer_for_vertical_scrollbar_.get());
+ }
+ if (layer_for_scroll_corner_)
+ overflow_controls_host_layer_->AddChild(layer_for_scroll_corner_.get());
}
- if (layer_for_scroll_corner_)
- overflow_controls_host_layer_->AddChild(layer_for_scroll_corner_.get());
- // Now add the DecorationOutlineLayer as a subtree to GraphicsLayer
- if (decoration_outline_layer_.get())
+ if (decoration_outline_layer_)
graphics_layer_->AddChild(decoration_outline_layer_.get());
- // The squashing containment layer, if it exists, becomes a no-op parent.
- if (squashing_layer_) {
- if (squashing_containment_layer_) {
- squashing_containment_layer_->RemoveAllChildren();
- squashing_containment_layer_->AddChild(graphics_layer_.get());
- squashing_containment_layer_->AddChild(squashing_layer_.get());
- }
- }
+ if (mask_layer_)
+ graphics_layer_->AddChild(mask_layer_.get());
+
+ if (non_scrolling_squashing_layer_)
+ graphics_layer_->AddChild(non_scrolling_squashing_layer_.get());
}
void CompositedLayerMapping::UpdatePaintingPhases() {
@@ -975,15 +1023,15 @@ void CompositedLayerMapping::UpdateDrawsContentAndPaintsHitTest() {
GetPluginContainer(GetLayoutObject())->WantsWheelEvents()));
graphics_layer_->SetPaintsHitTest(paints_hit_test || paints_scroll_hit_test);
- if (scrolling_layer_) {
- // m_scrollingLayer never has backing store.
- // m_scrollingContentsLayer only needs backing store if the scrolled
+ if (scrolling_contents_layer_) {
+ // scrolling_contents_layer_ only needs backing store if the scrolled
// contents need to paint.
- scrolling_contents_are_empty_ =
- !owning_layer_.HasVisibleContent() ||
- !(GetLayoutObject().StyleRef().HasBackground() ||
- GetLayoutObject().HasNonInitialBackdropFilter() || PaintsChildren());
- scrolling_contents_layer_->SetDrawsContent(!scrolling_contents_are_empty_);
+ bool has_painted_scrolling_contents =
+ !squashed_layers_in_scrolling_contents_.IsEmpty() ||
+ (owning_layer_.HasVisibleContent() &&
+ (GetLayoutObject().StyleRef().HasBackground() ||
+ GetLayoutObject().HasNonInitialBackdropFilter() || PaintsChildren()));
+ scrolling_contents_layer_->SetDrawsContent(has_painted_scrolling_contents);
scrolling_contents_layer_->SetPaintsHitTest(paints_hit_test);
}
@@ -1145,85 +1193,32 @@ void CompositedLayerMapping::PositionOverflowControlsLayers() {
}
}
-enum ApplyToGraphicsLayersModeFlags {
- kApplyToLayersAffectedByPreserve3D = (1 << 0),
- kApplyToSquashingLayer = (1 << 1),
- kApplyToScrollbarLayers = (1 << 2),
- kApplyToMaskLayers = (1 << 3),
- kApplyToContentLayers = (1 << 4),
- kApplyToChildContainingLayers =
- (1 << 5), // layers between m_graphicsLayer and children
- kApplyToNonScrollingContentLayers = (1 << 6),
- kApplyToScrollingContentLayers = (1 << 7),
- kApplyToDecorationOutlineLayer = (1 << 8),
- kApplyToAllGraphicsLayers =
- (kApplyToSquashingLayer | kApplyToScrollbarLayers | kApplyToMaskLayers |
- kApplyToLayersAffectedByPreserve3D | kApplyToContentLayers |
- kApplyToScrollingContentLayers | kApplyToDecorationOutlineLayer)
+enum ApplyToGraphicsLayersMode {
+ kApplyToContentLayers,
+ kApplyToAllGraphicsLayers,
};
-typedef unsigned ApplyToGraphicsLayersMode;
-
-// Flags to layers mapping matrix:
-// bit 0 1 2 3 4 5 6 7 8
-// ChildTransform * *
-// Main * * *
-// Clipping * *
-// Scrolling * *
-// ScrollingContents * * * *
-// Foreground * * *
-// Squashing *
-// Mask * * *
-// HorizontalScrollbar *
-// VerticalScrollbar *
-// ScrollCorner *
-// DecorationOutline * *
-template <typename Func>
+
+template <typename Function>
static void ApplyToGraphicsLayers(const CompositedLayerMapping* mapping,
- const Func& f,
+ const Function& function,
ApplyToGraphicsLayersMode mode) {
- DCHECK(mode);
-
- if (((mode & kApplyToLayersAffectedByPreserve3D) ||
- (mode & kApplyToContentLayers) ||
- (mode & kApplyToNonScrollingContentLayers)) &&
- mapping->MainGraphicsLayer())
- f(mapping->MainGraphicsLayer());
- if (((mode & kApplyToLayersAffectedByPreserve3D) ||
- (mode & kApplyToChildContainingLayers)) &&
- mapping->ScrollingLayer())
- f(mapping->ScrollingLayer());
- if (((mode & kApplyToLayersAffectedByPreserve3D) ||
- (mode & kApplyToContentLayers) ||
- (mode & kApplyToChildContainingLayers) ||
- (mode & kApplyToScrollingContentLayers)) &&
- mapping->ScrollingContentsLayer())
- f(mapping->ScrollingContentsLayer());
- if (((mode & kApplyToLayersAffectedByPreserve3D) ||
- (mode & kApplyToContentLayers) ||
- (mode & kApplyToScrollingContentLayers)) &&
- mapping->ForegroundLayer())
- f(mapping->ForegroundLayer());
-
- if ((mode & kApplyToSquashingLayer) && mapping->SquashingLayer())
- f(mapping->SquashingLayer());
-
- if (((mode & kApplyToMaskLayers) || (mode & kApplyToContentLayers) ||
- (mode & kApplyToNonScrollingContentLayers)) &&
- mapping->MaskLayer())
- f(mapping->MaskLayer());
-
- if ((mode & kApplyToScrollbarLayers) &&
- mapping->LayerForHorizontalScrollbar())
- f(mapping->LayerForHorizontalScrollbar());
- if ((mode & kApplyToScrollbarLayers) && mapping->LayerForVerticalScrollbar())
- f(mapping->LayerForVerticalScrollbar());
- if ((mode & kApplyToScrollbarLayers) && mapping->LayerForScrollCorner())
- f(mapping->LayerForScrollCorner());
-
- if (((mode & kApplyToDecorationOutlineLayer) ||
- (mode & kApplyToNonScrollingContentLayers)) &&
- mapping->DecorationOutlineLayer())
- f(mapping->DecorationOutlineLayer());
+ auto null_checking_function = [&function](GraphicsLayer* layer) {
+ if (layer)
+ function(layer);
+ };
+
+ null_checking_function(mapping->MainGraphicsLayer());
+ null_checking_function(mapping->ScrollingContentsLayer());
+ null_checking_function(mapping->ForegroundLayer());
+ null_checking_function(mapping->MaskLayer());
+ null_checking_function(mapping->DecorationOutlineLayer());
+
+ if (mode == kApplyToAllGraphicsLayers) {
+ null_checking_function(mapping->NonScrollingSquashingLayer());
+ null_checking_function(mapping->LayerForHorizontalScrollbar());
+ null_checking_function(mapping->LayerForVerticalScrollbar());
+ null_checking_function(mapping->LayerForScrollCorner());
+ }
}
// You receive an element id if you have an animation, or you're a scroller (and
@@ -1301,24 +1296,18 @@ bool CompositedLayerMapping::UpdateMaskLayer(bool needs_mask_layer) {
return layer_changed;
}
-bool CompositedLayerMapping::UpdateScrollingLayers(
- bool needs_scrolling_layers) {
+bool CompositedLayerMapping::UpdateScrollingContentsLayer(
+ bool needs_scrolling_contents_layer) {
ScrollingCoordinator* scrolling_coordinator =
owning_layer_.GetScrollingCoordinator();
auto* scrollable_area = owning_layer_.GetScrollableArea();
if (scrollable_area)
- scrollable_area->SetUsesCompositedScrolling(needs_scrolling_layers);
+ scrollable_area->SetUsesCompositedScrolling(needs_scrolling_contents_layer);
bool layer_changed = false;
- if (needs_scrolling_layers) {
- if (!scrolling_layer_) {
- // Outer layer which corresponds with the scroll view.
- scrolling_layer_ =
- CreateGraphicsLayer(CompositingReason::kLayerForScrollingContainer);
- scrolling_layer_->SetDrawsContent(false);
- scrolling_layer_->SetHitTestable(false);
-
+ if (needs_scrolling_contents_layer) {
+ if (!scrolling_contents_layer_) {
// Inner layer which renders the content that scrolls.
scrolling_contents_layer_ =
CreateGraphicsLayer(CompositingReason::kLayerForScrollingContents);
@@ -1327,8 +1316,6 @@ bool CompositedLayerMapping::UpdateScrollingLayers(
auto element_id = scrollable_area->GetScrollElementId();
scrolling_contents_layer_->SetElementId(element_id);
- scrolling_layer_->AddChild(scrolling_contents_layer_.get());
-
layer_changed = true;
if (scrolling_coordinator && scrollable_area) {
scrolling_coordinator->ScrollableAreaScrollLayerDidChange(
@@ -1338,8 +1325,7 @@ bool CompositedLayerMapping::UpdateScrollingLayers(
layout_view->GetFrameView()->ScrollableAreasDidChange();
}
}
- } else if (scrolling_layer_) {
- scrolling_layer_ = nullptr;
+ } else if (scrolling_contents_layer_) {
scrolling_contents_layer_ = nullptr;
layer_changed = true;
if (scrolling_coordinator && scrollable_area) {
@@ -1359,32 +1345,21 @@ bool CompositedLayerMapping::UpdateSquashingLayers(
bool layers_changed = false;
if (needs_squashing_layers) {
- if (!squashing_layer_) {
- squashing_layer_ =
+ if (!non_scrolling_squashing_layer_) {
+ non_scrolling_squashing_layer_ =
CreateGraphicsLayer(CompositingReason::kLayerForSquashingContents);
- squashing_layer_->SetDrawsContent(true);
- squashing_layer_->SetHitTestable(true);
- layers_changed = true;
- }
- if (!squashing_containment_layer_) {
- squashing_containment_layer_ =
- CreateGraphicsLayer(CompositingReason::kLayerForSquashingContainer);
+ non_scrolling_squashing_layer_->SetDrawsContent(true);
+ non_scrolling_squashing_layer_->SetHitTestable(true);
layers_changed = true;
}
- DCHECK(squashing_layer_);
+ DCHECK(non_scrolling_squashing_layer_);
} else {
- if (squashing_layer_) {
- squashing_layer_->RemoveFromParent();
- squashing_layer_ = nullptr;
+ if (non_scrolling_squashing_layer_) {
+ non_scrolling_squashing_layer_->RemoveFromParent();
+ non_scrolling_squashing_layer_ = nullptr;
layers_changed = true;
}
- if (squashing_containment_layer_) {
- squashing_containment_layer_->RemoveFromParent();
- squashing_containment_layer_ = nullptr;
- layers_changed = true;
- }
- DCHECK(!squashing_layer_);
- DCHECK(!squashing_containment_layer_);
+ DCHECK(!non_scrolling_squashing_layer_);
}
return layers_changed;
@@ -1421,9 +1396,13 @@ Color CompositedLayerMapping::LayoutObjectBackgroundColor() const {
void CompositedLayerMapping::UpdateBackgroundColor() {
auto color = LayoutObjectBackgroundColor().Rgb();
- graphics_layer_->SetBackgroundColor(color);
- if (scrolling_contents_layer_)
- scrolling_contents_layer_->SetBackgroundColor(color);
+ graphics_layer_->SetBackgroundColor(
+ BackgroundPaintsOntoGraphicsLayer() ? color : SK_ColorTRANSPARENT);
+ if (scrolling_contents_layer_) {
+ scrolling_contents_layer_->SetBackgroundColor(
+ BackgroundPaintsOntoScrollingContentsLayer() ? color
+ : SK_ColorTRANSPARENT);
+ }
}
bool CompositedLayerMapping::PaintsChildren() const {
@@ -1439,7 +1418,7 @@ bool CompositedLayerMapping::PaintsChildren() const {
static bool IsCompositedPlugin(LayoutObject& layout_object) {
return layout_object.IsEmbeddedObject() &&
- ToLayoutEmbeddedObject(layout_object).RequiresAcceleratedCompositing();
+ layout_object.AdditionalCompositingReasons();
}
bool CompositedLayerMapping::HasVisibleNonCompositingDescendant(
@@ -1468,7 +1447,7 @@ bool CompositedLayerMapping::ContainsPaintedContent() const {
// fill the border box entirely, and set background color on the layer in that
// case, instead of allocating backing store and painting.
auto* layout_video = DynamicTo<LayoutVideo>(layout_object);
- if (layout_video && layout_video->ShouldDisplayVideo())
+ if (layout_video && layout_video->GetDisplayMode() == LayoutVideo::kVideo)
return owning_layer_.HasBoxDecorationsOrBackground();
if (layout_object.GetNode() && layout_object.GetNode()->IsDocumentNode()) {
@@ -1556,13 +1535,6 @@ GraphicsLayer* CompositedLayerMapping::DetachLayerForOverflowControls() {
return overflow_controls_host_layer_.get();
}
-GraphicsLayer* CompositedLayerMapping::DetachLayerForDecorationOutline() {
- if (!decoration_outline_layer_.get())
- return nullptr;
- decoration_outline_layer_->RemoveFromParent();
- return decoration_outline_layer_.get();
-}
-
GraphicsLayer* CompositedLayerMapping::ParentForSublayers() const {
if (scrolling_contents_layer_)
return scrolling_contents_layer_.get();
@@ -1572,28 +1544,28 @@ GraphicsLayer* CompositedLayerMapping::ParentForSublayers() const {
void CompositedLayerMapping::SetSublayers(
const GraphicsLayerVector& sublayers) {
- GraphicsLayer* overflow_controls_container =
- overflow_controls_host_layer_.get();
GraphicsLayer* parent = ParentForSublayers();
- bool needs_overflow_controls_reattached =
- overflow_controls_container &&
- overflow_controls_container->Parent() == parent;
-
- parent->SetChildren(sublayers);
- // If we have scrollbars, but are not using composited scrolling, then
- // parentForSublayers may return m_graphicsLayer. In that case, the above
- // call to setChildren has clobbered the overflow controls host layer, so we
- // need to reattach it.
- if (needs_overflow_controls_reattached)
- parent->AddChild(overflow_controls_container);
-}
+ // TODO(szager): Remove after diagnosing crash crbug.com/1092673
+ CHECK(parent);
+
+ // Some layers are managed by CompositedLayerMapping under |parent| need to
+ // be reattached after SetChildren() below which will clobber all children.
+ GraphicsLayerVector layers_needing_reattachment;
+ auto add_layer_needing_reattachment =
+ [parent, &layers_needing_reattachment](GraphicsLayer* layer) {
+ if (layer && layer->Parent() == parent)
+ layers_needing_reattachment.push_back(layer);
+ };
+ add_layer_needing_reattachment(overflow_controls_host_layer_.get());
+ add_layer_needing_reattachment(decoration_outline_layer_.get());
+ add_layer_needing_reattachment(mask_layer_.get());
+ add_layer_needing_reattachment(non_scrolling_squashing_layer_.get());
-GraphicsLayer* CompositedLayerMapping::ChildForSuperlayers() const {
- if (squashing_containment_layer_)
- return squashing_containment_layer_.get();
+ parent->SetChildren(sublayers);
- return graphics_layer_.get();
+ for (GraphicsLayer* layer : layers_needing_reattachment)
+ parent->AddChild(layer);
}
GraphicsLayerUpdater::UpdateType CompositedLayerMapping::UpdateTypeForChildren(
@@ -1603,6 +1575,19 @@ GraphicsLayerUpdater::UpdateType CompositedLayerMapping::UpdateTypeForChildren(
return update_type;
}
+GraphicsLayer* CompositedLayerMapping::SquashingLayer(
+ const PaintLayer& squashed_layer) const {
+#if DCHECK_IS_ON()
+ AssertInSquashedLayersVector(squashed_layer);
+#endif
+ if (MayBeSquashedIntoScrollingContents(squashed_layer)) {
+ DCHECK(ScrollingContentsLayer());
+ return ScrollingContentsLayer();
+ }
+ DCHECK(NonScrollingSquashingLayer());
+ return NonScrollingSquashingLayer();
+}
+
struct SetContentsNeedsDisplayFunctor {
void operator()(GraphicsLayer* layer) const {
if (layer->PaintsContentOrHitTest())
@@ -1610,13 +1595,12 @@ struct SetContentsNeedsDisplayFunctor {
}
};
-void CompositedLayerMapping::SetSquashingContentsNeedDisplay() {
+void CompositedLayerMapping::SetAllLayersNeedDisplay() {
ApplyToGraphicsLayers(this, SetContentsNeedsDisplayFunctor(),
- kApplyToSquashingLayer);
+ kApplyToAllGraphicsLayers);
}
void CompositedLayerMapping::SetContentsNeedDisplay() {
- // FIXME: need to split out paint invalidations for the background.
ApplyToGraphicsLayers(this, SetContentsNeedsDisplayFunctor(),
kApplyToContentLayers);
}
@@ -1646,20 +1630,23 @@ const GraphicsLayerPaintInfo* CompositedLayerMapping::ContainingSquashedLayer(
return nullptr;
}
-const GraphicsLayerPaintInfo* CompositedLayerMapping::ContainingSquashedLayer(
+const GraphicsLayerPaintInfo*
+CompositedLayerMapping::ContainingSquashedLayerInSquashingLayer(
const LayoutObject* layout_object,
- unsigned max_squashed_layer_index) {
- return CompositedLayerMapping::ContainingSquashedLayer(
- layout_object, squashed_layers_, max_squashed_layer_index);
+ unsigned max_squashed_layer_index) const {
+ return ContainingSquashedLayer(layout_object, non_scrolling_squashed_layers_,
+ max_squashed_layer_index);
}
-void CompositedLayerMapping::LocalClipRectForSquashedLayer(
+void CompositedLayerMapping::UpdateLocalClipRectForSquashedLayer(
const PaintLayer& reference_layer,
const Vector<GraphicsLayerPaintInfo>& layers,
GraphicsLayerPaintInfo& paint_info) {
const LayoutObject* clipping_container =
paint_info.paint_layer->ClippingContainer();
- if (clipping_container == reference_layer.ClippingContainer()) {
+ if (clipping_container == reference_layer.ClippingContainer() ||
+ // When squashing into scrolling contents without other clips.
+ clipping_container == &reference_layer.GetLayoutObject()) {
paint_info.local_clip_rect_for_squashed_layer =
ClipRect(PhysicalRect(LayoutRect::InfiniteIntRect()));
paint_info.offset_from_clip_rect_root = PhysicalOffset();
@@ -1672,7 +1659,7 @@ void CompositedLayerMapping::LocalClipRectForSquashedLayer(
const GraphicsLayerPaintInfo* ancestor_paint_info =
ContainingSquashedLayer(clipping_container, layers, layers.size());
// Must be there, otherwise
- // CompositingLayerAssigner::canSquashIntoCurrentSquashingOwner would have
+ // CompositingLayerAssigner::GetReasonsPreventingSquashing() would have
// disallowed squashing.
DCHECK(ancestor_paint_info);
@@ -1924,7 +1911,7 @@ IntRect CompositedLayerMapping::ComputeInterestRect(
return previous_interest_rect;
if (graphics_layer != graphics_layer_.get() &&
- graphics_layer != squashing_layer_.get() &&
+ graphics_layer != non_scrolling_squashing_layer_.get() &&
graphics_layer != scrolling_contents_layer_.get())
return whole_layer_rect;
@@ -1968,6 +1955,31 @@ bool CompositedLayerMapping::AdjustForCompositedScrolling(
return false;
}
+static constexpr PaintLayerFlags PaintLayerFlagsFromGraphicsLayerPaintingPhase(
+ GraphicsLayerPaintingPhase graphics_layer_painting_phase) {
+ PaintLayerFlags paint_layer_flags = 0;
+ if (graphics_layer_painting_phase & kGraphicsLayerPaintBackground)
+ paint_layer_flags |= kPaintLayerPaintingCompositingBackgroundPhase;
+ else
+ paint_layer_flags |= kPaintLayerPaintingSkipRootBackground;
+ if (graphics_layer_painting_phase & kGraphicsLayerPaintForeground)
+ paint_layer_flags |= kPaintLayerPaintingCompositingForegroundPhase;
+ if (graphics_layer_painting_phase & kGraphicsLayerPaintMask)
+ paint_layer_flags |= kPaintLayerPaintingCompositingMaskPhase;
+ if (graphics_layer_painting_phase & kGraphicsLayerPaintOverflowContents)
+ paint_layer_flags |= kPaintLayerPaintingOverflowContents;
+ if (graphics_layer_painting_phase & kGraphicsLayerPaintCompositedScroll)
+ paint_layer_flags |= kPaintLayerPaintingCompositingScrollingPhase;
+ if (graphics_layer_painting_phase & kGraphicsLayerPaintDecoration)
+ paint_layer_flags |= kPaintLayerPaintingCompositingDecorationPhase;
+ return paint_layer_flags;
+}
+
+// Always paint all phases for squashed layers.
+static constexpr PaintLayerFlags kPaintLayerFlagsForSquashedLayer =
+ PaintLayerFlagsFromGraphicsLayerPaintingPhase(
+ kGraphicsLayerPaintAllWithOverflowClip);
+
void CompositedLayerMapping::PaintContents(
const GraphicsLayer* graphics_layer,
GraphicsContext& context,
@@ -1993,21 +2005,9 @@ void CompositedLayerMapping::PaintContents(
inspector_paint_event::Data(&owning_layer_.GetLayoutObject(),
PhysicalRect(interest_rect), graphics_layer));
- PaintLayerFlags paint_layer_flags = 0;
- if (graphics_layer_painting_phase & kGraphicsLayerPaintBackground)
- paint_layer_flags |= kPaintLayerPaintingCompositingBackgroundPhase;
- else
- paint_layer_flags |= kPaintLayerPaintingSkipRootBackground;
- if (graphics_layer_painting_phase & kGraphicsLayerPaintForeground)
- paint_layer_flags |= kPaintLayerPaintingCompositingForegroundPhase;
- if (graphics_layer_painting_phase & kGraphicsLayerPaintMask)
- paint_layer_flags |= kPaintLayerPaintingCompositingMaskPhase;
- if (graphics_layer_painting_phase & kGraphicsLayerPaintOverflowContents)
- paint_layer_flags |= kPaintLayerPaintingOverflowContents;
- if (graphics_layer_painting_phase & kGraphicsLayerPaintCompositedScroll)
- paint_layer_flags |= kPaintLayerPaintingCompositingScrollingPhase;
- if (graphics_layer_painting_phase & kGraphicsLayerPaintDecoration)
- paint_layer_flags |= kPaintLayerPaintingCompositingDecorationPhase;
+ PaintLayerFlags paint_layer_flags =
+ PaintLayerFlagsFromGraphicsLayerPaintingPhase(
+ graphics_layer_painting_phase);
if (graphics_layer == graphics_layer_.get() ||
graphics_layer == foreground_layer_.get() ||
@@ -2033,10 +2033,23 @@ void CompositedLayerMapping::PaintContents(
// compute and cache clipRects.
DoPaintTask(paint_info, *graphics_layer, paint_layer_flags, context,
interest_rect);
- } else if (graphics_layer == squashing_layer_.get()) {
- for (wtf_size_t i = 0; i < squashed_layers_.size(); ++i) {
- DoPaintTask(squashed_layers_[i], *graphics_layer, paint_layer_flags,
- context, interest_rect);
+
+ if (graphics_layer == scrolling_contents_layer_.get() &&
+ !squashed_layers_in_scrolling_contents_.IsEmpty()) {
+ // We have squashed_layers_in_scrolling_contents_ only if owning_layer_
+ // is not a stacking context, thus doesn't have foreground_layer_.
+ // (Otherwise we would need to squash into foreground_layer_.)
+ DCHECK(!foreground_layer_);
+ for (auto& squashed_layer : squashed_layers_in_scrolling_contents_) {
+ DoPaintTask(squashed_layer, *graphics_layer,
+ kPaintLayerFlagsForSquashedLayer, context, interest_rect);
+ }
+ }
+ } else if (graphics_layer == non_scrolling_squashing_layer_.get()) {
+ DCHECK_EQ(kPaintLayerFlagsForSquashedLayer, paint_layer_flags);
+ for (auto& squashed_layer : non_scrolling_squashed_layers_) {
+ DoPaintTask(squashed_layer, *graphics_layer, paint_layer_flags, context,
+ interest_rect);
}
} else if (IsScrollableAreaLayer(graphics_layer)) {
PaintScrollableArea(graphics_layer, context, interest_rect);
@@ -2144,109 +2157,129 @@ void CompositedLayerMapping::VerifyNotPainting() {
}
#endif
-bool CompositedLayerMapping::InvalidateLayerIfNoPrecedingEntry(
- wtf_size_t index_to_clear) {
- PaintLayer* layer_to_remove = squashed_layers_[index_to_clear].paint_layer;
- wtf_size_t previous_index = 0;
- for (; previous_index < index_to_clear; ++previous_index) {
- if (squashed_layers_[previous_index].paint_layer == layer_to_remove)
- break;
- }
- if (previous_index == index_to_clear &&
- layer_to_remove->GroupedMapping() == this) {
- Compositor()->PaintInvalidationOnCompositingChange(layer_to_remove);
- return true;
- }
- return false;
-}
-
-bool CompositedLayerMapping::UpdateSquashingLayerAssignment(
- PaintLayer* squashed_layer,
+bool CompositedLayerMapping::UpdateSquashingLayerAssignmentInternal(
+ Vector<GraphicsLayerPaintInfo>& squashed_layers,
+ PaintLayer& squashed_layer,
wtf_size_t next_squashed_layer_index) {
GraphicsLayerPaintInfo paint_info;
- paint_info.paint_layer = squashed_layer;
+ paint_info.paint_layer = &squashed_layer;
// NOTE: composited bounds are updated elsewhere
// NOTE: offsetFromLayoutObject is updated elsewhere
// Change tracking on squashing layers: at the first sign of something
// changed, just invalidate the layer.
// FIXME: Perhaps we can find a tighter more clever mechanism later.
- if (next_squashed_layer_index < squashed_layers_.size()) {
+ if (next_squashed_layer_index < squashed_layers.size()) {
if (paint_info.paint_layer ==
- squashed_layers_[next_squashed_layer_index].paint_layer)
+ squashed_layers[next_squashed_layer_index].paint_layer)
return false;
-
- // Must invalidate before adding the squashed layer to the mapping.
- Compositor()->PaintInvalidationOnCompositingChange(squashed_layer);
-
- // If the layer which was previously at |nextSquashedLayerIndex| is not
- // earlier in the grouped mapping, invalidate its current backing now, since
- // it will move later or be removed from the squashing layer.
- InvalidateLayerIfNoPrecedingEntry(next_squashed_layer_index);
-
- squashed_layers_.insert(next_squashed_layer_index, paint_info);
+ squashed_layers.insert(next_squashed_layer_index, paint_info);
} else {
- // Must invalidate before adding the squashed layer to the mapping.
- Compositor()->PaintInvalidationOnCompositingChange(squashed_layer);
- squashed_layers_.push_back(paint_info);
+ squashed_layers.push_back(paint_info);
}
- squashed_layer->SetGroupedMapping(
+ // Must invalidate before adding the squashed layer to the mapping.
+ Compositor()->PaintInvalidationOnCompositingChange(&squashed_layer);
+ squashed_layer.SetGroupedMapping(
this, PaintLayer::kInvalidateLayerAndRemoveFromMapping);
return true;
}
+bool CompositedLayerMapping::UpdateSquashingLayerAssignment(
+ PaintLayer& squashed_layer,
+ wtf_size_t next_squashed_layer_in_non_scrolling_squashing_layer_index,
+ wtf_size_t next_squashed_layer_in_scrolling_contents_index) {
+ if (MayBeSquashedIntoScrollingContents(squashed_layer)) {
+ return UpdateSquashingLayerAssignmentInternal(
+ squashed_layers_in_scrolling_contents_, squashed_layer,
+ next_squashed_layer_in_scrolling_contents_index);
+ }
+ return UpdateSquashingLayerAssignmentInternal(
+ non_scrolling_squashed_layers_, squashed_layer,
+ next_squashed_layer_in_non_scrolling_squashing_layer_index);
+}
+
void CompositedLayerMapping::RemoveLayerFromSquashingGraphicsLayer(
- const PaintLayer* layer) {
- wtf_size_t layer_index = 0;
- for (; layer_index < squashed_layers_.size(); ++layer_index) {
- if (squashed_layers_[layer_index].paint_layer == layer)
- break;
+ const PaintLayer& layer) {
+ // We must try to remove the layer from both vectors because
+ // MayBeSquashedIntoScrollingContents() may not reflect the previous status.
+ for (wtf_size_t i = 0; i < non_scrolling_squashed_layers_.size(); ++i) {
+ if (non_scrolling_squashed_layers_[i].paint_layer == &layer) {
+ non_scrolling_squashed_layers_.EraseAt(i);
+ return;
+ }
+ }
+ for (wtf_size_t i = 0; i < squashed_layers_in_scrolling_contents_.size();
+ ++i) {
+ if (squashed_layers_in_scrolling_contents_[i].paint_layer == &layer) {
+ squashed_layers_in_scrolling_contents_.EraseAt(i);
+ return;
+ }
}
// Assert on incorrect mappings between layers and groups
- DCHECK_LT(layer_index, squashed_layers_.size());
- if (layer_index == squashed_layers_.size())
- return;
-
- squashed_layers_.EraseAt(layer_index);
+ NOTREACHED();
}
-#if DCHECK_IS_ON()
-bool CompositedLayerMapping::VerifyLayerInSquashingVector(
- const PaintLayer* layer) {
- for (wtf_size_t layer_index = 0; layer_index < squashed_layers_.size();
- ++layer_index) {
- if (squashed_layers_[layer_index].paint_layer == layer)
+static bool LayerInSquashedLayersVector(
+ const Vector<GraphicsLayerPaintInfo>& squashed_layers,
+ const PaintLayer& layer) {
+ for (auto& squashed_layer : squashed_layers) {
+ if (squashed_layer.paint_layer == &layer)
return true;
}
-
return false;
}
+
+#if DCHECK_IS_ON()
+void CompositedLayerMapping::AssertInSquashedLayersVector(
+ const PaintLayer& squashed_layer) const {
+ auto* in = &non_scrolling_squashed_layers_;
+ auto* out = &squashed_layers_in_scrolling_contents_;
+ if (MayBeSquashedIntoScrollingContents(squashed_layer))
+ std::swap(in, out);
+ DCHECK(LayerInSquashedLayersVector(*in, squashed_layer));
+ DCHECK(!LayerInSquashedLayersVector(*out, squashed_layer));
+}
#endif
+static void RemoveExtraSquashedLayers(
+ Vector<GraphicsLayerPaintInfo>& squashed_layers,
+ wtf_size_t new_count,
+ Vector<PaintLayer*>& layers_needing_paint_invalidation) {
+ DCHECK_GE(squashed_layers.size(), new_count);
+ if (squashed_layers.size() == new_count)
+ return;
+ for (auto i = new_count; i < squashed_layers.size(); i++)
+ layers_needing_paint_invalidation.push_back(squashed_layers[i].paint_layer);
+ squashed_layers.Shrink(new_count);
+}
+
void CompositedLayerMapping::FinishAccumulatingSquashingLayers(
- wtf_size_t next_squashed_layer_index,
+ wtf_size_t new_non_scrolling_squashed_layer_count,
+ wtf_size_t new_squashed_layer_in_scrolling_contents_count,
Vector<PaintLayer*>& layers_needing_paint_invalidation) {
- if (next_squashed_layer_index < squashed_layers_.size()) {
- // Any additional squashed Layers in the array no longer belong here, but
- // they might have been added already at an earlier index. Clear pointers on
- // those that do not appear in the valid set before removing all the extra
- // entries.
- for (wtf_size_t i = next_squashed_layer_index; i < squashed_layers_.size();
- ++i) {
- if (InvalidateLayerIfNoPrecedingEntry(i)) {
- squashed_layers_[i].paint_layer->SetGroupedMapping(
- nullptr, PaintLayer::kDoNotInvalidateLayerAndRemoveFromMapping);
- squashed_layers_[i].paint_layer->SetLostGroupedMapping(true);
- }
- layers_needing_paint_invalidation.push_back(
- squashed_layers_[i].paint_layer);
+ wtf_size_t first_removed_layer = layers_needing_paint_invalidation.size();
+ RemoveExtraSquashedLayers(non_scrolling_squashed_layers_,
+ new_non_scrolling_squashed_layer_count,
+ layers_needing_paint_invalidation);
+ RemoveExtraSquashedLayers(squashed_layers_in_scrolling_contents_,
+ new_squashed_layer_in_scrolling_contents_count,
+ layers_needing_paint_invalidation);
+ for (auto i = first_removed_layer;
+ i < layers_needing_paint_invalidation.size(); i++) {
+ PaintLayer* layer = layers_needing_paint_invalidation[i];
+ // Deal with layers that are no longer squashed. Need to check both vectors
+ // to exclude the layers that are still squashed. A layer may change from
+ // scrolling to non-scrolling or vice versa and still be squashed.
+ if (!LayerInSquashedLayersVector(non_scrolling_squashed_layers_, *layer) &&
+ !LayerInSquashedLayersVector(squashed_layers_in_scrolling_contents_,
+ *layer)) {
+ Compositor()->PaintInvalidationOnCompositingChange(layer);
+ layer->SetGroupedMapping(
+ nullptr, PaintLayer::kDoNotInvalidateLayerAndRemoveFromMapping);
+ layer->SetLostGroupedMapping(true);
}
-
- squashed_layers_.EraseAt(
- next_squashed_layer_index,
- squashed_layers_.size() - next_squashed_layer_index);
}
}
@@ -2255,12 +2288,10 @@ String CompositedLayerMapping::DebugName(
String name;
if (graphics_layer == graphics_layer_.get()) {
name = owning_layer_.DebugName();
- } else if (graphics_layer == squashing_containment_layer_.get()) {
- name = "Squashing Containment Layer";
- } else if (graphics_layer == squashing_layer_.get()) {
+ } else if (graphics_layer == non_scrolling_squashing_layer_.get()) {
name = "Squashing Layer (first squashed layer: " +
- (squashed_layers_.size() > 0
- ? squashed_layers_[0].paint_layer->DebugName()
+ (non_scrolling_squashed_layers_.size() > 0
+ ? non_scrolling_squashed_layers_[0].paint_layer->DebugName()
: "") +
")";
} else if (graphics_layer == foreground_layer_.get()) {
@@ -2275,8 +2306,6 @@ String CompositedLayerMapping::DebugName(
name = "Scroll Corner Layer";
} else if (graphics_layer == overflow_controls_host_layer_.get()) {
name = "Overflow Controls Host Layer";
- } else if (graphics_layer == scrolling_layer_.get()) {
- name = "Scrolling Layer";
} else if (graphics_layer == scrolling_contents_layer_.get()) {
name = "Scrolling Contents Layer";
} else if (graphics_layer == decoration_outline_layer_.get()) {
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h b/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
index 5a4ed36ff32..28cd8d2dd55 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
@@ -113,29 +113,27 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
return decoration_outline_layer_.get();
}
- bool HasScrollingLayer() const { return scrolling_layer_.get(); }
- GraphicsLayer* ScrollingLayer() const { return scrolling_layer_.get(); }
GraphicsLayer* ScrollingContentsLayer() const {
return scrolling_contents_layer_.get();
}
- bool HasMaskLayer() const { return mask_layer_.get(); }
GraphicsLayer* MaskLayer() const { return mask_layer_.get(); }
GraphicsLayer* ParentForSublayers() const;
- GraphicsLayer* ChildForSuperlayers() const;
void SetSublayers(const GraphicsLayerVector&);
- GraphicsLayer* SquashingContainmentLayer() const {
- return squashing_containment_layer_.get();
+ // Returns the GraphicsLayer that |layer| is squashed into, which may be
+ // NonScrollingSquashingLayer or ScrollingContentsLayer.
+ GraphicsLayer* SquashingLayer(const PaintLayer& squashed_layer) const;
+
+ GraphicsLayer* NonScrollingSquashingLayer() const {
+ return non_scrolling_squashing_layer_.get();
}
- GraphicsLayer* SquashingLayer() const { return squashing_layer_.get(); }
- const IntSize& SquashingLayerOffsetFromLayoutObject() const {
- return squashing_layer_offset_from_layout_object_;
+ const IntSize& NonScrollingSquashingLayerOffsetFromLayoutObject() const {
+ return non_scrolling_squashing_layer_offset_from_layout_object_;
}
- void SetSquashingContentsNeedDisplay();
- void SetContentsNeedDisplay();
+ void SetAllLayersNeedDisplay();
// Let all DrawsContent GraphicsLayers check raster invalidations after
// a no-change paint.
@@ -148,18 +146,26 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
void PositionOverflowControlsLayers();
+ bool MayBeSquashedIntoScrollingContents(const PaintLayer& layer) const {
+ return layer.AncestorScrollingLayer() == &owning_layer_;
+ }
+
// Returns true if the assignment actually changed the assigned squashing
// layer.
- bool UpdateSquashingLayerAssignment(PaintLayer* squashed_layer,
- wtf_size_t next_squashed_layer_index);
- void RemoveLayerFromSquashingGraphicsLayer(const PaintLayer*);
+ bool UpdateSquashingLayerAssignment(
+ PaintLayer& squashed_layer,
+ wtf_size_t next_non_scrolling_squashed_layer_index,
+ wtf_size_t next_squashed_layer_in_scrolling_contents_index);
+ void RemoveLayerFromSquashingGraphicsLayer(const PaintLayer&);
#if DCHECK_IS_ON()
- bool VerifyLayerInSquashingVector(const PaintLayer*);
+ void AssertInSquashedLayersVector(const PaintLayer&) const;
#endif
void FinishAccumulatingSquashingLayers(
- wtf_size_t next_squashed_layer_index,
+ wtf_size_t new_non_scrolling_squashed_layer_count,
+ wtf_size_t new_squashed_layer_in_scrolling_contents_count,
Vector<PaintLayer*>& layers_needing_paint_invalidation);
+
void UpdateElementId();
// GraphicsLayerClient interface
@@ -208,9 +214,6 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
// position.
GraphicsLayer* DetachLayerForOverflowControls();
- // We may similarly need to reattach the layer for outlines and decorations.
- GraphicsLayer* DetachLayerForDecorationOutline();
-
void SetBlendMode(BlendMode);
bool NeedsGraphicsLayerUpdate() {
@@ -243,9 +246,9 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
// If there is a squashed layer painting into this CLM that is an ancestor of
// the given LayoutObject, return it. Otherwise return nullptr.
- const GraphicsLayerPaintInfo* ContainingSquashedLayer(
+ const GraphicsLayerPaintInfo* ContainingSquashedLayerInSquashingLayer(
const LayoutObject*,
- unsigned max_squashed_layer_index);
+ unsigned max_squashed_layer_index) const;
// Returns whether an adjustment happend.
bool AdjustForCompositedScrolling(const GraphicsLayer*,
@@ -315,7 +318,8 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
void UpdateForegroundLayerGeometry();
void UpdateDecorationOutlineLayerGeometry(
const IntSize& relative_compositing_bounds_size);
- void UpdateScrollingLayerGeometry();
+ void UpdateScrollingContentsLayerGeometry(
+ Vector<PaintLayer*>& layers_needing_paint_invalidation);
void CreatePrimaryGraphicsLayer();
@@ -344,10 +348,11 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
bool RequiresHorizontalScrollbarLayer() const;
bool RequiresVerticalScrollbarLayer() const;
bool RequiresScrollCornerLayer() const;
- bool UpdateScrollingLayers(bool scrolling_layers);
+ bool UpdateScrollingContentsLayer(bool needs_scrolling_contents_layer);
bool UpdateSquashingLayers(bool needs_squashing_layers);
void UpdateDrawsContentAndPaintsHitTest();
void UpdateCompositedBounds();
+ void UpdateGraphicsLayerContentsOpaque(bool should_check_children);
// Also sets subpixelAccumulation on the layer.
void ComputeBoundsOfOwningLayer(
@@ -386,14 +391,18 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
// contains this squashed layer's clipping ancestor. The clip rect is
// returned in the coordinate space of the given squashed layer. If there is
// no such containing layer, returns the infinite rect.
- static void LocalClipRectForSquashedLayer(
+ static void UpdateLocalClipRectForSquashedLayer(
const PaintLayer& reference_layer,
const Vector<GraphicsLayerPaintInfo>& layers,
GraphicsLayerPaintInfo&);
- // Clear the groupedMapping entry on the layer at the given index, only if
- // that layer does not appear earlier in the set of layers for this object.
- bool InvalidateLayerIfNoPrecedingEntry(wtf_size_t);
+ bool UpdateSquashingLayerAssignmentInternal(
+ Vector<GraphicsLayerPaintInfo>& squashed_layers,
+ PaintLayer& squashed_layer,
+ wtf_size_t next_squashed_layer_index);
+ void RemoveSquashedLayers(Vector<GraphicsLayerPaintInfo>& squashed_layers);
+
+ void SetContentsNeedDisplay();
PaintLayer& owning_layer_;
@@ -401,27 +410,33 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
// looks like this:
//
// + graphics_layer_
- // + (scrolling_layer_ + scrolling_contents_layer_) [OPTIONAL]
- // | + overflow_controls_host_layer_ [OPTIONAL]
- // | + layer_for_vertical_scrollbar_ [OPTIONAL]
- // | + layer_for_horizontal_scrollbar_ [OPTIONAL]
- // | + layer_for_scroll_corner_ [OPTIONAL]
+ // + contents layers (or contents layers under scrolling_contents_layer_)
+ // + overflow_controls_host_layer_ [OPTIONAL]
+ // | + layer_for_vertical_scrollbar_ [OPTIONAL]
+ // | + layer_for_horizontal_scrollbar_ [OPTIONAL]
+ // | + layer_for_scroll_corner_ [OPTIONAL]
// + decoration_outline_layer_ [OPTIONAL]
+ // + mask_layer_ [ OPTIONAL ]
+ // + non_scrolling_squashing_layer_ [ OPTIONAL ]
+ //
// The overflow controls may need to be repositioned in the graphics layer
// tree by the RLC to ensure that they stack above scrolling content.
+ //
+ // Contents layers are directly under |graphics_layer_|, or under
+ // |scrolling_contents_layer_| when the layer is using composited scrolling.
+ // If owning_layer_ is a stacking context, contents layers include:
+ // - negative z-index children
+ // - foreground_layer_
+ // - normal flow and positive z-index children
+ // If owning_layer_ is not a stacking context, contents layers are normal
+ // flow children.
std::unique_ptr<GraphicsLayer> graphics_layer_;
// Only used if the layer is using composited scrolling.
- std::unique_ptr<GraphicsLayer> scrolling_layer_;
-
- // Only used if the layer is using composited scrolling.
std::unique_ptr<GraphicsLayer> scrolling_contents_layer_;
+ IntSize previous_scroll_container_size_;
- // This layer is also added to the hierarchy by the RLB, but in a different
- // way than the layers above. It's added to graphics_layer_ as its mask layer
- // (naturally) if we have a mask, and isn't part of the typical hierarchy (it
- // has no children).
// Only used if we have a mask.
std::unique_ptr<GraphicsLayer> mask_layer_;
@@ -450,32 +465,26 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
// DecorationLayer which paints outline.
std::unique_ptr<GraphicsLayer> decoration_outline_layer_;
- // A squashing CLM has the following structure:
- // squashing_containment_layer_
- // + graphics_layer_
- // + squashing_layer_
- //
- // Stacking children of a squashed layer receive graphics layers that are
- // parented to the composited ancestor of the squashed layer (i.e. nearest
- // enclosing composited layer that is not
- // squashed).
+ // Only used when |non_scrolling_squashed_layers_| is not empty. This is
+ // the backing that |non_scrolling_squashed_layers_| paint into.
+ std::unique_ptr<GraphicsLayer> non_scrolling_squashing_layer_;
+ IntSize non_scrolling_squashing_layer_offset_from_layout_object_;
- // Only used if any squashed layers exist, this contains the squashed layers
- // as siblings to the rest of the GraphicsLayer tree chunk.
- std::unique_ptr<GraphicsLayer> squashing_containment_layer_;
+ // Layers that are squashed into |non_scrolling_squashing_layer_|.
+ Vector<GraphicsLayerPaintInfo> non_scrolling_squashed_layers_;
- // Only used if any squashed layers exist, this is the backing that squashed
- // layers paint into.
- std::unique_ptr<GraphicsLayer> squashing_layer_;
- Vector<GraphicsLayerPaintInfo> squashed_layers_;
- IntSize squashing_layer_offset_from_layout_object_;
+ // Layers that are squashed into |scrolling_contents_layer_|. This is used
+ // when |owning_layer_| is scrollable but is not a stacking context, and
+ // there are scrolling stacked children that can be squashed into the
+ // scrolling contents without breaking stacking order. We don't need a special
+ // layer like |non_scrolling_squashing_layer_| because these squashed layers
+ // are always contained by |scrolling_contents_layer_|.
+ Vector<GraphicsLayerPaintInfo> squashed_layers_in_scrolling_contents_;
PhysicalRect composited_bounds_;
unsigned pending_update_scope_ : 2;
- unsigned scrolling_contents_are_empty_ : 1;
-
bool draws_background_onto_content_layer_;
friend class CompositedLayerMappingTest;
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc b/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc
index b43664bfed7..e7c6fea5694 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc
@@ -21,6 +21,8 @@
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
+#include "third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.h"
+
namespace blink {
// TODO(wangxianzhu): Though these tests don't directly apply in
@@ -54,6 +56,29 @@ class CompositedLayerMappingTest : public RenderingTest {
return graphics_layer->previous_interest_rect_;
}
+ static const GraphicsLayerPaintInfo* GetSquashedLayer(
+ const Vector<GraphicsLayerPaintInfo>& squashed_layers,
+ const PaintLayer& layer) {
+ for (const auto& squashed_layer : squashed_layers) {
+ if (squashed_layer.paint_layer == &layer)
+ return &squashed_layer;
+ }
+ return nullptr;
+ }
+
+ const GraphicsLayerPaintInfo* GetNonScrollingSquashedLayer(
+ const CompositedLayerMapping& mapping,
+ const PaintLayer& layer) {
+ return GetSquashedLayer(mapping.non_scrolling_squashed_layers_, layer);
+ }
+
+ const GraphicsLayerPaintInfo* GetSquashedLayerInScrollingContents(
+ const CompositedLayerMapping& mapping,
+ const PaintLayer& layer) {
+ return GetSquashedLayer(mapping.squashed_layers_in_scrolling_contents_,
+ layer);
+ }
+
private:
void SetUp() override {
EnableCompositing();
@@ -819,7 +844,7 @@ TEST_F(CompositedLayerMappingTest,
// The following rect is at (-4000, 190, 4100, 100) in viewport coordinates.
EXPECT_EQ(IntRect(6000, 0, 4100, 100),
grouped_mapping->ComputeInterestRect(
- grouped_mapping->SquashingLayer(), IntRect()));
+ grouped_mapping->NonScrollingSquashingLayer(), IntRect()));
}
TEST_F(CompositedLayerMappingTest,
@@ -846,7 +871,7 @@ TEST_F(CompositedLayerMappingTest,
// The following rect is at (-4000, 0, 4400, 1000) in viewport coordinates.
EXPECT_EQ(IntRect(5600, 0, 4400, 1000),
grouped_mapping->ComputeInterestRect(
- grouped_mapping->SquashingLayer(), IntRect()));
+ grouped_mapping->NonScrollingSquashingLayer(), IntRect()));
}
TEST_F(CompositedLayerMappingTest, InterestRectOfIframeInScrolledDiv) {
@@ -1136,32 +1161,6 @@ TEST_F(CompositedLayerMappingTest,
EXPECT_FALSE(mapping->DecorationOutlineLayer());
}
-TEST_F(CompositedLayerMappingTest,
- BackgroundPaintedIntoGraphicsLayerIfNotCompositedScrolling) {
- GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled(
- true);
- SetBodyInnerHTML(R"HTML(
- <div id='container' style='overflow: scroll; width: 300px; height:
- 300px; background: white; will-change: transform;'>
- <div style='background-color: blue; width: 2000px; height: 2000px;
- clip-path: circle(600px at 1000px 1000px);'></div>
- </div>
- )HTML");
-
- const auto* container = ToLayoutBox(GetLayoutObjectByElementId("container"));
- EXPECT_EQ(kBackgroundPaintInScrollingContents,
- container->ComputeBackgroundPaintLocationIfComposited());
-
- // We currently don't use composited scrolling when the container has a
- // border-radius so even though we can paint the background onto the scrolling
- // contents layer we don't have a scrolling contents layer to paint into in
- // this case.
- const auto* mapping = container->Layer()->GetCompositedLayerMapping();
- EXPECT_FALSE(mapping->HasScrollingLayer());
- EXPECT_EQ(kBackgroundPaintInGraphicsLayer,
- container->GetBackgroundPaintLocation());
-}
-
TEST_F(CompositedLayerMappingTest, StickyPositionMainThreadOffset) {
SetBodyInnerHTML(R"HTML(
<style>.composited { backface-visibility: hidden; }
@@ -1338,7 +1337,6 @@ TEST_F(CompositedLayerMappingTest,
SetBodyInnerHTML(R"HTML(
<div id='target1' style='will-change: transform;'>foo</div>
<div id='target2' style='will-change: opacity;'>bar</div>
- <div id='target3' style='backface-visibility: hidden;'>ham</div>
)HTML");
{
@@ -1361,16 +1359,6 @@ TEST_F(CompositedLayerMappingTest,
EXPECT_FALSE(
target_graphics_layer->CcLayer()->transformed_rasterization_allowed());
}
- {
- LayoutObject* target = GetLayoutObjectByElementId("target3");
- ASSERT_TRUE(target && target->IsBox());
- PaintLayer* target_layer = ToLayoutBox(target)->Layer();
- GraphicsLayer* target_graphics_layer =
- target_layer ? target_layer->GraphicsLayerBacking() : nullptr;
- ASSERT_TRUE(target_graphics_layer);
- EXPECT_FALSE(
- target_graphics_layer->CcLayer()->transformed_rasterization_allowed());
- }
}
TEST_F(CompositedLayerMappingTest, TransformedRasterizationForInlineTransform) {
@@ -1395,6 +1383,63 @@ TEST_F(CompositedLayerMappingTest, TransformedRasterizationForInlineTransform) {
target_graphics_layer->CcLayer()->transformed_rasterization_allowed());
}
+TEST_F(CompositedLayerMappingTest,
+ TransformedRasterizationForScrollDependentPosition) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="target"
+ style="transform: translateX(0.3px);
+ position: fixed; top: 20px; left: 30px;">
+ FIXED
+ </div>
+ <div style="height: 4000px; width: 4000px;
+ background: silver;">
+ </div>
+ )HTML");
+
+ LayoutObject* target = GetLayoutObjectByElementId("target");
+ ASSERT_TRUE(target && target->IsBox());
+ PaintLayer* target_layer = ToLayoutBox(target)->Layer();
+ GraphicsLayer* target_graphics_layer =
+ target_layer ? target_layer->GraphicsLayerBacking() : nullptr;
+ ASSERT_TRUE(target_graphics_layer);
+ EXPECT_TRUE(
+ target_graphics_layer->CcLayer()->transformed_rasterization_allowed());
+}
+
+TEST_F(CompositedLayerMappingTest,
+ TransformedRasterizationForTrivial3DTransform) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="target" style="transform: translate3d(0.3px, 0px, 0px);">
+ Trivial 3D Transform
+ </div>
+ )HTML");
+
+ LayoutObject* target = GetLayoutObjectByElementId("target");
+ ASSERT_TRUE(target && target->IsBox());
+ PaintLayer* target_layer = ToLayoutBox(target)->Layer();
+ GraphicsLayer* target_graphics_layer =
+ target_layer ? target_layer->GraphicsLayerBacking() : nullptr;
+ ASSERT_TRUE(target_graphics_layer);
+ EXPECT_TRUE(
+ target_graphics_layer->CcLayer()->transformed_rasterization_allowed());
+}
+
+TEST_F(CompositedLayerMappingTest,
+ TransformedRasterizationForBackfaceVisibilityHidden) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="target" style="backface-visibility: hidden;">EXAMPLE</div>
+ )HTML");
+
+ LayoutObject* target = GetLayoutObjectByElementId("target");
+ ASSERT_TRUE(target && target->IsBox());
+ PaintLayer* target_layer = ToLayoutBox(target)->Layer();
+ GraphicsLayer* target_graphics_layer =
+ target_layer ? target_layer->GraphicsLayerBacking() : nullptr;
+ ASSERT_TRUE(target_graphics_layer);
+ EXPECT_TRUE(
+ target_graphics_layer->CcLayer()->transformed_rasterization_allowed());
+}
+
TEST_F(CompositedLayerMappingTest, ScrollingContainerBoundsChange) {
GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled(
true);
@@ -1484,15 +1529,15 @@ TEST_F(CompositedLayerMappingTest, ScrollingLayerBackgroundColor) {
target->setAttribute(html_names::kClassAttr, "color");
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(Color(0, 0, 255), graphics_layer->BackgroundColor());
+ EXPECT_EQ(Color::kTransparent, graphics_layer->BackgroundColor());
EXPECT_EQ(Color(0, 0, 255), scrolling_contents_layer->BackgroundColor());
}
TEST_F(CompositedLayerMappingTest, ScrollLayerSizingSubpixelAccumulation) {
// This test verifies that when subpixel accumulation causes snapping it
- // applies to both the scrolling and scrolling contents layers. Verify that
- // the mapping doesn't have any vertical scrolling introduced as a result of
- // the snapping behavior. https://crbug.com/801381.
+ // applies to the scrolling contents layer. Verify that the mapping doesn't
+ // have any vertical scrolling introduced as a result of the snapping
+ // behavior. https://crbug.com/801381.
GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled(
true);
@@ -1525,10 +1570,9 @@ TEST_F(CompositedLayerMappingTest, ScrollLayerSizingSubpixelAccumulation) {
->Layer()
->GetCompositedLayerMapping();
ASSERT_TRUE(mapping);
- ASSERT_TRUE(mapping->ScrollingLayer());
ASSERT_TRUE(mapping->ScrollingContentsLayer());
- EXPECT_EQ(mapping->ScrollingLayer()->Size().height(),
- mapping->ScrollingContentsLayer()->Size().height());
+ EXPECT_EQ(gfx::Size(200, 200), mapping->MainGraphicsLayer()->Size());
+ EXPECT_EQ(gfx::Size(1000, 200), mapping->ScrollingContentsLayer()->Size());
}
TEST_F(CompositedLayerMappingTest, SquashingScrollInterestRect) {
@@ -1550,8 +1594,9 @@ TEST_F(CompositedLayerMappingTest, SquashingScrollInterestRect) {
ScrollOffset(0, 5000), mojom::blink::ScrollType::kUser);
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(IntRect(0, 1000, 200, 5000),
- squashed->GroupedMapping()->SquashingLayer()->InterestRect());
+ EXPECT_EQ(
+ IntRect(0, 1000, 200, 5000),
+ squashed->GroupedMapping()->SquashingLayer(*squashed)->InterestRect());
}
TEST_F(CompositedLayerMappingTest,
@@ -1868,4 +1913,107 @@ TEST_F(CompositedLayerMappingTest, FrameAttribution) {
CompositorElementIdNamespace::kDOMNodeId));
}
+TEST_F(CompositedLayerMappingTest, SquashIntoScrollingContents) {
+ GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled(
+ true);
+ SetBodyInnerHTML(R"HTML(
+ <div style="position: absolute; top: 0.5px; left: 0.75px; z-index: 1">
+ <div style="height: 0.75px"></div>
+ <div id="scroller" style="width: 100px; height: 100px; overflow: scroll;
+ border: 10px solid blue">
+ <div id="target1" style="position: relative; top: 10.5px; left: 5.5px;
+ width: 10px; height: 10px; background: green"></div>
+ <div style="height: 300px"></div>
+ <div id="target2" style="position: relative; z-index: 2;
+ width: 10px; height: 10px; background: green"></div>
+ </div>
+ <div style="position: absolute; z-index: 1; top: 50px;
+ width: 10px; height: 10px; background: blue">
+ </div>
+ </div>
+ )HTML");
+
+ auto* scroller = ToLayoutBox(GetLayoutObjectByElementId("scroller"))->Layer();
+ auto* target1 = ToLayoutBox(GetLayoutObjectByElementId("target1"))->Layer();
+ auto* target2 = ToLayoutBox(GetLayoutObjectByElementId("target2"))->Layer();
+
+ auto* scroller_mapping = scroller->GetCompositedLayerMapping();
+ ASSERT_TRUE(scroller_mapping);
+ EXPECT_EQ(IntSize(),
+ scroller_mapping->MainGraphicsLayer()->OffsetFromLayoutObject());
+ EXPECT_EQ(
+ IntSize(10, 10),
+ scroller_mapping->ScrollingContentsLayer()->OffsetFromLayoutObject());
+ EXPECT_EQ(PhysicalOffset(LayoutUnit(-0.25), LayoutUnit(0.25)),
+ scroller->SubpixelAccumulation());
+
+ EXPECT_EQ(scroller_mapping, target1->GroupedMapping());
+ EXPECT_EQ(scroller_mapping->ScrollingContentsLayer(),
+ scroller_mapping->SquashingLayer(*target1));
+ EXPECT_EQ(scroller_mapping->ScrollingContentsLayer(),
+ target1->GraphicsLayerBacking());
+ EXPECT_EQ(PhysicalOffset(LayoutUnit(0.25), LayoutUnit(-0.25)),
+ target1->SubpixelAccumulation());
+ const GraphicsLayerPaintInfo* target1_info =
+ GetSquashedLayerInScrollingContents(*scroller_mapping, *target1);
+ ASSERT_TRUE(target1_info);
+ EXPECT_TRUE(target1_info->offset_from_layout_object_set);
+ EXPECT_EQ(IntSize(-5, -11), target1_info->offset_from_layout_object);
+ EXPECT_EQ(ClipRect(), target1_info->local_clip_rect_for_squashed_layer);
+
+ // target2 can't be squashed because the absolute position div is between
+ // the scrolling contents and target2.
+ EXPECT_FALSE(target2->GroupedMapping());
+ EXPECT_TRUE(target2->HasCompositedLayerMapping());
+}
+
+TEST_F(CompositedLayerMappingTest,
+ SwitchSquashingBetweenScrollingAndNonScrolling) {
+ GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled(
+ true);
+ SetBodyInnerHTML(R"HTML(
+ <style>.scroll { overflow: scroll; }</style>
+ <div id="container"
+ style="backface-visibility: hidden; width: 100px; height: 100px">
+ <div id="squashed"
+ style="z-index: 1; position: relative; width: 10px; height: 10px"></div>
+ <div id="filler" style="height: 300px"></div>
+ </div>
+ )HTML");
+
+ auto* container_element = GetDocument().getElementById("container");
+ auto* container = container_element->GetLayoutBox()->Layer();
+ auto* squashed = ToLayoutBox(GetLayoutObjectByElementId("squashed"))->Layer();
+ auto* mapping = container->GetCompositedLayerMapping();
+ ASSERT_TRUE(mapping);
+ EXPECT_EQ(mapping, squashed->GroupedMapping());
+ EXPECT_EQ(mapping->NonScrollingSquashingLayer(),
+ squashed->GraphicsLayerBacking());
+ EXPECT_EQ(mapping->NonScrollingSquashingLayer(),
+ mapping->SquashingLayer(*squashed));
+ EXPECT_TRUE(GetNonScrollingSquashedLayer(*mapping, *squashed));
+ EXPECT_FALSE(GetSquashedLayerInScrollingContents(*mapping, *squashed));
+
+ container_element->setAttribute(html_names::kClassAttr, "scroll");
+ UpdateAllLifecyclePhasesForTest();
+ ASSERT_EQ(mapping, container->GetCompositedLayerMapping());
+ EXPECT_EQ(mapping, squashed->GroupedMapping());
+ EXPECT_EQ(mapping->ScrollingContentsLayer(),
+ squashed->GraphicsLayerBacking());
+ EXPECT_EQ(mapping->ScrollingContentsLayer(),
+ mapping->SquashingLayer(*squashed));
+ EXPECT_FALSE(GetNonScrollingSquashedLayer(*mapping, *squashed));
+ EXPECT_TRUE(GetSquashedLayerInScrollingContents(*mapping, *squashed));
+
+ container_element->setAttribute(html_names::kClassAttr, "");
+ UpdateAllLifecyclePhasesForTest();
+ ASSERT_EQ(mapping, container->GetCompositedLayerMapping());
+ EXPECT_EQ(mapping->NonScrollingSquashingLayer(),
+ squashed->GraphicsLayerBacking());
+ EXPECT_EQ(mapping->NonScrollingSquashingLayer(),
+ mapping->SquashingLayer(*squashed));
+ EXPECT_TRUE(GetNonScrollingSquashedLayer(*mapping, *squashed));
+ EXPECT_FALSE(GetSquashedLayerInScrollingContents(*mapping, *squashed));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc
index ed18dfe1b7f..cabdc250564 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/layout/layout_block.h"
+#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
@@ -189,6 +190,13 @@ void CompositingInputsUpdater::UpdateSelfAndDescendantsRecursively(
descendant_has_direct_compositing_reason |=
LayerOrDescendantShouldBeComposited(child);
}
+ if (!descendant_has_direct_compositing_reason &&
+ layer->GetLayoutObject().IsLayoutEmbeddedContent()) {
+ if (ToLayoutEmbeddedContent(layer->GetLayoutObject())
+ .ContentDocumentIsCompositing()) {
+ descendant_has_direct_compositing_reason = true;
+ }
+ }
layer->SetDescendantHasDirectOrScrollingCompositingReason(
descendant_has_direct_compositing_reason);
@@ -249,7 +257,7 @@ void CompositingInputsUpdater::UpdateAncestorInfo(PaintLayer* const layer,
case kNotComposited:
break;
case kPaintsIntoOwnBacking:
- if (style.IsStackingContext())
+ if (layout_object.IsStackingContext())
enclosing_stacking_composited_layer = layer;
break;
case kPaintsIntoGroupedBacking:
@@ -336,7 +344,7 @@ void CompositingInputsUpdater::UpdateAncestorInfo(PaintLayer* const layer,
if (layout_object.HasClip())
info.clip_chain_parent_for_fixed = layer;
- if (style.IsStackingContext()) {
+ if (layout_object.IsStackingContext()) {
info.escape_clip_to = nullptr;
const LayoutBoxModelObject* clipping_container =
ClippingContainerFromClipChainParent(layer);
@@ -360,14 +368,12 @@ void CompositingInputsUpdater::UpdateAncestorInfo(PaintLayer* const layer,
// <div style="position:absolute;"></div>
// </div>
// </div>
- if (info.escape_clip_to_for_absolute && style.ZIndex() < 0 &&
+ if (info.escape_clip_to_for_absolute && style.EffectiveZIndex() < 0 &&
!info.escape_clip_to_for_absolute->GetLayoutObject()
- .StyleRef()
.IsStackingContext())
info.escape_clip_to_for_absolute = nullptr;
- if (info.escape_clip_to_for_fixed && style.ZIndex() < 0 &&
+ if (info.escape_clip_to_for_fixed && style.EffectiveZIndex() < 0 &&
!info.escape_clip_to_for_fixed->GetLayoutObject()
- .StyleRef()
.IsStackingContext())
info.escape_clip_to_for_fixed = nullptr;
@@ -465,7 +471,7 @@ void CompositingInputsUpdater::UpdateAncestorDependentCompositingInputs(
properties.clip_parent = info.escape_clip_to;
properties.ancestor_scrolling_layer = info.scrolling_ancestor;
- if (info.needs_reparent_scroll && layout_object.StyleRef().IsStacked())
+ if (info.needs_reparent_scroll && layout_object.IsStacked())
properties.scroll_parent = info.scrolling_ancestor;
properties.nearest_contained_layout_layer =
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater_test.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater_test.cc
index 4f66645c2eb..51eb893804a 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater_test.cc
@@ -14,6 +14,12 @@ class CompositingInputsUpdaterTest : public RenderingTest {
public:
CompositingInputsUpdaterTest()
: RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()) {}
+
+ protected:
+ void SetUp() override {
+ EnableCompositing();
+ RenderingTest::SetUp();
+ }
};
// Tests that transitioning a sticky away from an ancestor overflow layer that
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc
index eb8bc29eb7f..4e47cecad90 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/core/animation/scroll_timeline.h"
#include "third_party/blink/renderer/core/animation/worklet_animation_controller.h"
+#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_video.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/page/page.h"
@@ -54,9 +55,10 @@ void CompositingLayerAssigner::Assign(
SquashingState squashing_state;
AssignLayersToBackingsInternal(update_root, squashing_state,
layers_needing_paint_invalidation);
- if (squashing_state.has_most_recent_mapping) {
+ if (squashing_state.most_recent_mapping) {
squashing_state.most_recent_mapping->FinishAccumulatingSquashingLayers(
- squashing_state.next_squashed_layer_index,
+ squashing_state.next_non_scrolling_squashed_layer_index,
+ squashing_state.next_squashed_layer_in_scrolling_contents_index,
layers_needing_paint_invalidation);
}
}
@@ -64,19 +66,29 @@ void CompositingLayerAssigner::Assign(
void CompositingLayerAssigner::SquashingState::
UpdateSquashingStateForNewMapping(
CompositedLayerMapping* new_composited_layer_mapping,
- bool has_new_composited_layer_mapping,
Vector<PaintLayer*>& layers_needing_paint_invalidation) {
// The most recent backing is done accumulating any more squashing layers.
- if (has_most_recent_mapping) {
+ if (most_recent_mapping) {
most_recent_mapping->FinishAccumulatingSquashingLayers(
- next_squashed_layer_index, layers_needing_paint_invalidation);
+ next_non_scrolling_squashed_layer_index,
+ next_squashed_layer_in_scrolling_contents_index,
+ layers_needing_paint_invalidation);
}
- next_squashed_layer_index = 0;
+ next_non_scrolling_squashed_layer_index = 0;
+ next_squashed_layer_in_scrolling_contents_index = 0;
bounding_rect = IntRect();
most_recent_mapping = new_composited_layer_mapping;
- has_most_recent_mapping = has_new_composited_layer_mapping;
have_assigned_backings_to_entire_squashing_layer_subtree = false;
+ // We may squash layers with CompositingReason::kOverflowScrollingParent into
+ // scrolling contents. These layers are stacked, and scrolled by a
+ // non-stacking-context scroller. See CompositingReasonFinder.
+ next_layer_may_squash_into_scrolling_contents =
+ most_recent_mapping &&
+ most_recent_mapping->OwningLayer().NeedsCompositedScrolling() &&
+ !most_recent_mapping->OwningLayer()
+ .GetLayoutObject()
+ .IsStackingContext();
}
bool CompositingLayerAssigner::SquashingWouldExceedSparsityTolerance(
@@ -133,7 +145,7 @@ CompositingLayerAssigner::GetReasonsPreventingSquashing(
if (!squashing_state.have_assigned_backings_to_entire_squashing_layer_subtree)
return SquashingDisallowedReason::kWouldBreakPaintOrder;
- DCHECK(squashing_state.has_most_recent_mapping);
+ DCHECK(squashing_state.most_recent_mapping);
const PaintLayer& squashing_layer =
squashing_state.most_recent_mapping->OwningLayer();
@@ -150,22 +162,31 @@ CompositingLayerAssigner::GetReasonsPreventingSquashing(
kSquashingLayoutEmbeddedContentIsDisallowed;
}
- if (SquashingWouldExceedSparsityTolerance(layer, squashing_state))
- return SquashingDisallowedReason::kSquashingSparsityExceeded;
+ // The layer may squash into scrolling contents if the squashing layer allows,
+ // and it's scrolled and clipped by the squashing layer.
+ bool may_squash_into_scrolling_contents =
+ squashing_state.next_layer_may_squash_into_scrolling_contents &&
+ layer->AncestorScrollingLayer() == &squashing_layer &&
+ layer->ClippingContainer() == &squashing_layer.GetLayoutObject();
+ if (!may_squash_into_scrolling_contents) {
+ if (SquashingWouldExceedSparsityTolerance(layer, squashing_state))
+ return SquashingDisallowedReason::kSquashingSparsityExceeded;
+
+ if (layer->ClippingContainer() != squashing_layer.ClippingContainer() &&
+ !squashing_layer.GetCompositedLayerMapping()
+ ->ContainingSquashedLayerInSquashingLayer(
+ layer->ClippingContainer(),
+ squashing_state.next_non_scrolling_squashed_layer_index))
+ return SquashingDisallowedReason::kClippingContainerMismatch;
+
+ if (layer->ScrollsWithRespectTo(&squashing_layer))
+ return SquashingDisallowedReason::kScrollsWithRespectToSquashingLayer;
+ }
if (layer->GetLayoutObject().StyleRef().HasBlendMode() ||
squashing_layer.GetLayoutObject().StyleRef().HasBlendMode())
return SquashingDisallowedReason::kSquashingBlendingIsDisallowed;
- if (layer->ClippingContainer() != squashing_layer.ClippingContainer() &&
- !squashing_layer.GetCompositedLayerMapping()->ContainingSquashedLayer(
- layer->ClippingContainer(),
- squashing_state.next_squashed_layer_index))
- return SquashingDisallowedReason::kClippingContainerMismatch;
-
- if (layer->ScrollsWithRespectTo(&squashing_layer))
- return SquashingDisallowedReason::kScrollsWithRespectToSquashingLayer;
-
if (layer->OpacityAncestor() != squashing_layer.OpacityAncestor())
return SquashingDisallowedReason::kOpacityAncestorMismatch;
@@ -227,11 +248,12 @@ void CompositingLayerAssigner::UpdateSquashingAssignment(
// A layer that is squashed with other layers cannot have its own
// CompositedLayerMapping.
DCHECK(!layer->HasCompositedLayerMapping());
- DCHECK(squashing_state.has_most_recent_mapping);
+ DCHECK(squashing_state.most_recent_mapping);
bool changed_squashing_layer =
squashing_state.most_recent_mapping->UpdateSquashingLayerAssignment(
- layer, squashing_state.next_squashed_layer_index);
+ *layer, squashing_state.next_non_scrolling_squashed_layer_index,
+ squashing_state.next_squashed_layer_in_scrolling_contents_index);
if (!changed_squashing_layer)
return;
@@ -281,7 +303,10 @@ void CompositingLayerAssigner::AssignLayersToBackingsInternal(
layer->SetCompositingReasons(layer->GetCompositingReasons() |
CompositingReason::kSquashingDisallowed);
layer->SetSquashingDisallowedReasons(reasons_preventing_squashing);
+ squashing_state.next_layer_may_squash_into_scrolling_contents = false;
}
+ } else {
+ squashing_state.next_layer_may_squash_into_scrolling_contents = false;
}
CompositingStateTransitionType composited_layer_update =
@@ -315,11 +340,17 @@ void CompositingLayerAssigner::AssignLayersToBackingsInternal(
(composited_layer_update == kNoCompositingStateChange &&
layer->GroupedMapping());
if (layer_is_squashed) {
- squashing_state.next_squashed_layer_index++;
- IntRect layer_bounds = layer->ClippedAbsoluteBoundingBox();
- squashing_state.total_area_of_squashed_rects +=
- layer_bounds.Size().Area();
- squashing_state.bounding_rect.Unite(layer_bounds);
+ if (layer->AncestorScrollingLayer() ==
+ &squashing_state.most_recent_mapping->OwningLayer()) {
+ squashing_state.next_squashed_layer_in_scrolling_contents_index++;
+ } else {
+ squashing_state.next_non_scrolling_squashed_layer_index++;
+ squashing_state.next_layer_may_squash_into_scrolling_contents = false;
+ IntRect layer_bounds = layer->ClippedAbsoluteBoundingBox();
+ squashing_state.total_area_of_squashed_rects +=
+ layer_bounds.Size().Area();
+ squashing_state.bounding_rect.Unite(layer_bounds);
+ }
}
}
@@ -337,8 +368,7 @@ void CompositingLayerAssigner::AssignLayersToBackingsInternal(
layer->GetCompositingState() == kPaintsIntoOwnBacking) {
DCHECK(!RequiresSquashing(layer->GetCompositingReasons()));
squashing_state.UpdateSquashingStateForNewMapping(
- layer->GetCompositedLayerMapping(), layer->HasCompositedLayerMapping(),
- layers_needing_paint_invalidation);
+ layer->GetCompositedLayerMapping(), layers_needing_paint_invalidation);
}
if (layer->StackingDescendantNeedsCompositingLayerAssignment()) {
@@ -351,12 +381,22 @@ void CompositingLayerAssigner::AssignLayersToBackingsInternal(
}
if (layer->NeedsCompositingLayerAssignment()) {
- if (squashing_state.has_most_recent_mapping &&
+ if (squashing_state.most_recent_mapping &&
&squashing_state.most_recent_mapping->OwningLayer() == layer) {
squashing_state.have_assigned_backings_to_entire_squashing_layer_subtree =
true;
}
}
+
+ // If this is an iframe whose content document is composited, then we can't
+ // squash layers painted after the iframe with layers painted before it.
+ if (layer->GetLayoutObject().IsLayoutEmbeddedContent() &&
+ ToLayoutEmbeddedContent(layer->GetLayoutObject())
+ .ContentDocumentIsCompositing()) {
+ squashing_state.have_assigned_backings_to_entire_squashing_layer_subtree =
+ false;
+ }
+
layer->ClearNeedsCompositingLayerAssignment();
}
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.h b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.h
index 557f55726ee..8763b86c3fe 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.h
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.h
@@ -55,40 +55,41 @@ class CompositingLayerAssigner {
private:
struct SquashingState {
- SquashingState()
- : most_recent_mapping(nullptr),
- has_most_recent_mapping(false),
- have_assigned_backings_to_entire_squashing_layer_subtree(false),
- next_squashed_layer_index(0),
- total_area_of_squashed_rects(0) {}
-
void UpdateSquashingStateForNewMapping(
CompositedLayerMapping*,
- bool has_new_composited_paint_layer_mapping,
Vector<PaintLayer*>& layers_needing_paint_invalidation);
// The most recent composited backing that the layer should squash onto if
// needed.
- CompositedLayerMapping* most_recent_mapping;
- bool has_most_recent_mapping;
+ CompositedLayerMapping* most_recent_mapping = nullptr;
// Whether all Layers in the stacking subtree rooted at the most recent
// mapping's owning layer have had CompositedLayerMappings assigned. Layers
// cannot squash into a CompositedLayerMapping owned by a stacking ancestor,
// since this changes paint order.
- bool have_assigned_backings_to_entire_squashing_layer_subtree;
+ bool have_assigned_backings_to_entire_squashing_layer_subtree = false;
+
+ // This is set to true when most_recent_mapping supports composited
+ // scrolling, and reset to false whenever any layer is not squashed into
+ // scrolling contents, to ensure all layers squashed into scrolling contents
+ // are continuous with the scroller in stacking order, without any other
+ // layer interlacing among them.
+ bool next_layer_may_squash_into_scrolling_contents = false;
// Counter that tracks what index the next Layer would be if it gets
- // squashed to the current squashing layer.
- wtf_size_t next_squashed_layer_index;
+ // squashed to the current non scrolling squashing layer.
+ wtf_size_t next_non_scrolling_squashed_layer_index = 0;
+ // Same as above but for layers squashed into scrolling contents layer.
+ wtf_size_t next_squashed_layer_in_scrolling_contents_index = 0;
- // The absolute bounding rect of all the squashed layers.
+ // The absolute bounding rect of all the squashed layers (not including
+ // those squashed into scrolling contents).
IntRect bounding_rect;
// This is simply the sum of the areas of the squashed rects. This can be
// very skewed if the rects overlap, but should be close enough to drive a
- // heuristic.
- uint64_t total_area_of_squashed_rects;
+ // heuristic (not including those squashed into scrolling contents).
+ uint64_t total_area_of_squashed_rects = 0;
};
void AssignLayersToBackingsInternal(
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner_test.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner_test.cc
index 7cdb1c5cc0a..97e640ca330 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner_test.cc
@@ -11,6 +11,10 @@
namespace blink {
class CompositedLayerAssignerTest : public RenderingTest {
+ public:
+ CompositedLayerAssignerTest()
+ : RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()) {}
+
private:
void SetUp() override {
EnableCompositing();
@@ -30,6 +34,11 @@ TEST_F(CompositedLayerAssignerTest, SquashingSimple) {
PaintLayer* squashed =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("squashed"))->Layer();
EXPECT_EQ(kPaintsIntoGroupedBacking, squashed->GetCompositingState());
+ CompositedLayerMapping* mapping = squashed->GroupedMapping();
+ EXPECT_EQ(mapping->NonScrollingSquashingLayer(),
+ mapping->SquashingLayer(*squashed));
+ EXPECT_EQ(mapping->NonScrollingSquashingLayer(),
+ squashed->GraphicsLayerBacking());
}
TEST_F(CompositedLayerAssignerTest, SquashingAcrossClipPathDisallowed) {
@@ -92,4 +101,23 @@ TEST_F(CompositedLayerAssignerTest,
EXPECT_EQ(kPaintsIntoOwnBacking, squashed->GetCompositingState());
}
+TEST_F(CompositedLayerAssignerTest,
+ SquashingAcrossCompositedInnerDocumentDisallowed) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="bottom" style="position: absolute; will-change: transform">Bottom</div>
+ <div id="middle" style="position: absolute">
+ <iframe style="border: 10px solid magenta"></iframe>
+ </div>
+ <div id="top" style="position: absolute; width: 200px; height: 200px; background: green;">Top</div>
+ )HTML");
+ SetChildFrameHTML(R"HTML(
+ <style>body {will-change: transform; background: blue}</style>
+ )HTML");
+ LocalFrameView* frame_view = GetDocument().View();
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
+ PaintLayer* top =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("top"))->Layer();
+ EXPECT_EQ(kPaintsIntoOwnBacking, top->GetCompositingState());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc
index 331af079b05..5f9339e521a 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc
@@ -89,25 +89,17 @@ void CompositingLayerPropertyUpdater::Update(const LayoutObject& object) {
PropertyTreeState scrollbar_layer_state =
container_layer_state.value_or(
fragment_data.LocalBorderBoxProperties());
- // OverflowControlsClip should be applied within the scrollbar
- // layers.
+ // OverflowControlsClip should be applied within the scrollbar layers.
if (const auto* properties = fragment_data.PaintProperties()) {
- if (const auto* clip = properties->OverflowControlsClip()) {
+ if (const auto* clip = properties->OverflowControlsClip())
scrollbar_layer_state.SetClip(*clip);
- } else if (const auto* css_clip = properties->CssClip()) {
- DCHECK(css_clip->Parent());
- scrollbar_layer_state.SetClip(*css_clip->Parent());
- }
- }
- if (const auto* properties = fragment_data.PaintProperties()) {
if (scrollbar_or_corner == ScrollbarOrCorner::kHorizontalScrollbar) {
if (const auto* effect = properties->HorizontalScrollbarEffect()) {
scrollbar_layer_state.SetEffect(*effect);
}
- }
-
- if (scrollbar_or_corner == ScrollbarOrCorner::kVerticalScrollbar) {
+ } else if (scrollbar_or_corner ==
+ ScrollbarOrCorner::kVerticalScrollbar) {
if (const auto* effect = properties->VerticalScrollbarEffect())
scrollbar_layer_state.SetEffect(*effect);
}
@@ -174,7 +166,7 @@ void CompositingLayerPropertyUpdater::Update(const LayoutObject& object) {
fragment_data.ContentsProperties(), offset);
}
- if (auto* squashing_layer = mapping->SquashingLayer()) {
+ if (auto* squashing_layer = mapping->NonScrollingSquashingLayer()) {
auto state = fragment_data.PreEffectProperties();
// The squashing layer's ClippingContainer is the common ancestor of clip
// state of all squashed layers, so we should use its clip state. This skips
@@ -186,8 +178,8 @@ void CompositingLayerPropertyUpdater::Update(const LayoutObject& object) {
? clipping_container->FirstFragment().ContentsProperties().Clip()
: ClipPaintPropertyNode::Root());
squashing_layer->SetLayerState(
- state,
- snapped_paint_offset + mapping->SquashingLayerOffsetFromLayoutObject());
+ state, snapped_paint_offset +
+ mapping->NonScrollingSquashingLayerOffsetFromLayoutObject());
}
if (auto* mask_layer = mapping->MaskLayer()) {
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc
index b7946eb5674..e991dfac93c 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc
@@ -42,7 +42,7 @@ TEST_F(CompositingLayerPropertyUpdaterTest, MaskLayerState) {
EXPECT_TRUE(paint_properties->CssClip());
EXPECT_TRUE(paint_properties->MaskClip());
EXPECT_EQ(paint_properties->MaskClip(),
- &mask_layer->layer_state_->state.Clip());
+ &mask_layer->GetPropertyTreeState().Clip());
}
TEST_F(CompositingLayerPropertyUpdaterTest,
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
index dece8c8a2b8..92adfb6a894 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
@@ -35,23 +35,6 @@ CompositingReasons CompositingReasonFinder::DirectReasons(
NonStyleDeterminedDirectReasons(layer);
}
-bool CompositingReasonFinder::RequiresCompositingForScrollableFrame(
- const LayoutView& layout_view) {
- // Need this done first to determine overflow.
- DCHECK(!layout_view.NeedsLayout());
- if (layout_view.GetDocument().IsInMainFrame())
- return false;
-
- const auto& settings = *layout_view.GetDocument().GetSettings();
- if (!settings.GetPreferCompositingToLCDTextEnabled())
- return false;
-
- if (layout_view.GetFrameView()->Size().IsEmpty())
- return false;
-
- return layout_view.GetFrameView()->LayoutViewport()->ScrollsOverflow();
-}
-
CompositingReasons
CompositingReasonFinder::PotentialCompositingReasonsFromStyle(
const LayoutObject& layout_object) {
@@ -62,8 +45,7 @@ CompositingReasonFinder::PotentialCompositingReasonsFromStyle(
const ComputedStyle& style = layout_object.StyleRef();
- if (RequiresCompositingFor3DTransform(layout_object))
- reasons |= CompositingReason::k3DTransform;
+ reasons |= CompositingReasonsFor3DTransform(layout_object);
if (style.BackfaceVisibility() == EBackfaceVisibility::kHidden)
reasons |= CompositingReason::kBackfaceVisibilityHidden;
@@ -73,11 +55,12 @@ CompositingReasonFinder::PotentialCompositingReasonsFromStyle(
// If the implementation of CreatesGroup changes, we need to be aware of that
// in this part of code.
- DCHECK((style.HasOpacity() || layout_object.HasMask() ||
+ DCHECK((style.HasNonInitialOpacity() || layout_object.HasMask() ||
layout_object.HasClipPath() ||
layout_object.HasFilterInducingProperty() ||
- layout_object.HasNonInitialBackdropFilter() ||
- style.HasBlendMode()) == layout_object.CreatesGroup());
+ layout_object.HasNonInitialBackdropFilter() || style.HasBlendMode() ||
+ (!style.HasAutoClip() && style.HasOutOfFlowPosition()) ||
+ style.HasIsolation()) == layout_object.CreatesGroup());
if (style.HasMask() || style.ClipPath())
reasons |= CompositingReason::kMaskWithCompositedDescendants;
@@ -97,9 +80,6 @@ CompositingReasonFinder::PotentialCompositingReasonsFromStyle(
if (layout_object.HasReflection())
reasons |= CompositingReason::kReflectionWithCompositedDescendants;
- if (layout_object.HasClipRelatedProperty())
- reasons |= CompositingReason::kClipsCompositingDescendants;
-
DCHECK(!(reasons & ~CompositingReason::kComboAllStyleDeterminedReasons));
return reasons;
}
@@ -124,6 +104,19 @@ static bool ShouldPreferCompositingForLayoutView(
return false;
}
+static CompositingReasons BackfaceInvisibility3DAncestorReason(
+ const PaintLayer& layer) {
+ if (RuntimeEnabledFeatures::TransformInteropEnabled()) {
+ if (auto* compositing_container = layer.CompositingContainer()) {
+ if (compositing_container->GetLayoutObject()
+ .StyleRef()
+ .BackfaceVisibility() == EBackfaceVisibility::kHidden)
+ return CompositingReason::kBackfaceInvisibility3DAncestor;
+ }
+ }
+ return CompositingReason::kNone;
+}
+
CompositingReasons CompositingReasonFinder::DirectReasonsForPaintProperties(
const LayoutObject& object) {
// TODO(wangxianzhu): Don't depend on PaintLayer for CompositeAfterPaint.
@@ -134,8 +127,7 @@ CompositingReasons CompositingReasonFinder::DirectReasonsForPaintProperties(
auto reasons = CompositingReasonsForAnimation(object) |
CompositingReasonsForWillChange(style);
- if (RequiresCompositingFor3DTransform(object))
- reasons |= CompositingReason::k3DTransform;
+ reasons |= CompositingReasonsFor3DTransform(object);
auto* layer = ToLayoutBoxModelObject(object).Layer();
if (layer->Has3DTransformedDescendant()) {
@@ -161,9 +153,9 @@ CompositingReasons CompositingReasonFinder::DirectReasonsForPaintProperties(
bool force_prefer_compositing_to_lcd_text =
reasons != CompositingReason::kNone ||
// In CompositeAfterPaint though we don't treat hidden backface as
- // a direct compositing reason, it's very likely that the object will
- // be composited, and it also indicates preference of compositing,
- // so we prefer composited scrolling here.
+ // a direct compositing reason, it's very likely that the object
+ // will be composited, and it also indicates preference of
+ // compositing, so we prefer composited scrolling here.
style.BackfaceVisibility() == EBackfaceVisibility::kHidden ||
(object.IsLayoutView() &&
ShouldPreferCompositingForLayoutView(To<LayoutView>(object)));
@@ -179,25 +171,36 @@ CompositingReasons CompositingReasonFinder::DirectReasonsForPaintProperties(
}
}
+ reasons |= BackfaceInvisibility3DAncestorReason(*layer);
+
if (object.CanHaveAdditionalCompositingReasons())
reasons |= object.AdditionalCompositingReasons();
return reasons;
}
-bool CompositingReasonFinder::RequiresCompositingFor3DTransform(
+CompositingReasons CompositingReasonFinder::CompositingReasonsFor3DTransform(
const LayoutObject& layout_object) {
- // Note that we ask the layoutObject if it has a transform, because the style
- // may have transforms, but the layoutObject may be an inline that doesn't
- // support them.
+ // Note that we ask the layoutObject if it has a transform, because the
+ // style may have transforms, but the layoutObject may be an inline that
+ // doesn't support them.
if (!layout_object.HasTransformRelatedProperty())
- return false;
+ return CompositingReason::kNone;
// Don't composite "trivial" 3D transforms such as translateZ(0).
- if (Platform::Current()->IsLowEndDevice())
- return layout_object.StyleRef().HasNonTrivial3DTransformOperation();
+ if (Platform::Current()->IsLowEndDevice()) {
+ return layout_object.StyleRef().HasNonTrivial3DTransformOperation()
+ ? CompositingReason::k3DTransform
+ : CompositingReason::kNone;
+ }
+
+ if (layout_object.StyleRef().Has3DTransformOperation()) {
+ return layout_object.StyleRef().HasNonTrivial3DTransformOperation()
+ ? CompositingReason::k3DTransform
+ : CompositingReason::kTrivial3DTransform;
+ }
- return layout_object.StyleRef().Has3DTransformOperation();
+ return CompositingReason::kNone;
}
CompositingReasons CompositingReasonFinder::NonStyleDeterminedDirectReasons(
@@ -213,12 +216,17 @@ CompositingReasons CompositingReasonFinder::NonStyleDeterminedDirectReasons(
if (RequiresCompositingForRootScroller(layer))
direct_reasons |= CompositingReason::kRootScroller;
- // Composite |layer| if it is inside of an ancestor scrolling layer, but that
- // scrolling layer is not on the stacking context ancestor chain of |layer|.
- // See the definition of the scrollParent property in Layer for more detail.
+ // Composite |layer| if it is inside of an ancestor scrolling layer, but
+ // that scrolling layer is not on the stacking context ancestor chain of
+ // |layer|. See the definition of the scrollParent property in Layer for
+ // more detail.
if (const PaintLayer* scrolling_ancestor = layer.AncestorScrollingLayer()) {
- if (scrolling_ancestor->NeedsCompositedScrolling() && layer.ScrollParent())
+ if (scrolling_ancestor->NeedsCompositedScrolling() &&
+ layer.ScrollParent()) {
+ DCHECK(!scrolling_ancestor->GetLayoutObject()
+ .IsStackingContext());
direct_reasons |= CompositingReason::kOverflowScrollingParent;
+ }
}
if (RequiresCompositingForScrollDependentPosition(layer))
@@ -241,15 +249,14 @@ CompositingReasons CompositingReasonFinder::NonStyleDeterminedDirectReasons(
}
}
- if (layer.IsRootLayer() &&
- (RequiresCompositingForScrollableFrame(*layout_object.View()) ||
- layout_object.GetFrame()->IsLocalRoot())) {
+ if (layer.IsRootLayer() && layout_object.GetFrame()->IsLocalRoot())
direct_reasons |= CompositingReason::kRoot;
- }
if (layout_object.CanHaveAdditionalCompositingReasons())
direct_reasons |= layout_object.AdditionalCompositingReasons();
+ direct_reasons |= BackfaceInvisibility3DAncestorReason(layer);
+
DCHECK(
!(direct_reasons & CompositingReason::kComboAllStyleDeterminedReasons));
return direct_reasons;
@@ -303,8 +310,8 @@ bool CompositingReasonFinder::RequiresCompositingForRootScroller(
const PaintLayer& layer) {
// The root scroller needs composited scrolling layers even if it doesn't
// actually have scrolling since CC has these assumptions baked in for the
- // viewport. Because this is only needed for CC, we can skip it if compositing
- // is not enabled.
+ // viewport. Because this is only needed for CC, we can skip it if
+ // compositing is not enabled.
const auto& settings = *layer.GetLayoutObject().GetDocument().GetSettings();
if (!settings.GetAcceleratedCompositingEnabled())
return false;
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h
index 212d9ef4c33..4ff02d7fe9f 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h
@@ -15,7 +15,6 @@ namespace blink {
class PaintLayer;
class LayoutObject;
class ComputedStyle;
-class LayoutView;
class CORE_EXPORT CompositingReasonFinder {
DISALLOW_NEW();
@@ -34,11 +33,11 @@ class CORE_EXPORT CompositingReasonFinder {
static CompositingReasons DirectReasonsForPaintProperties(
const LayoutObject&);
- static bool RequiresCompositingForScrollableFrame(const LayoutView&);
static CompositingReasons CompositingReasonsForAnimation(const LayoutObject&);
static CompositingReasons CompositingReasonsForWillChange(
const ComputedStyle&);
- static bool RequiresCompositingFor3DTransform(const LayoutObject&);
+ static CompositingReasons CompositingReasonsFor3DTransform(
+ const LayoutObject&);
static bool RequiresCompositingForRootScroller(const PaintLayer&);
static bool RequiresCompositingForScrollDependentPosition(const PaintLayer&);
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
index 980a9ef8dc2..18ac27bd17e 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
@@ -218,14 +218,15 @@ TEST_F(CompositingReasonFinderTest, PromoteCrossOriginIframe) {
)HTML");
UpdateAllLifecyclePhasesForTest();
- Element* iframe = GetDocument().getElementById("iframe");
+ HTMLFrameOwnerElement* iframe =
+ To<HTMLFrameOwnerElement>(GetDocument().getElementById("iframe"));
ASSERT_TRUE(iframe);
- PaintLayer* iframe_layer =
- ToLayoutBoxModelObject(iframe->GetLayoutObject())->Layer();
+ ASSERT_FALSE(iframe->ContentFrame()->IsCrossOriginToMainFrame());
+ LayoutView* iframe_layout_view =
+ To<LocalFrame>(iframe->ContentFrame())->ContentLayoutObject();
+ ASSERT_TRUE(iframe_layout_view);
+ PaintLayer* iframe_layer = iframe_layout_view->Layer();
ASSERT_TRUE(iframe_layer);
- ASSERT_FALSE(To<HTMLFrameOwnerElement>(iframe)
- ->ContentFrame()
- ->IsCrossOriginToMainFrame());
EXPECT_EQ(kNotComposited, iframe_layer->DirectCompositingReasons());
SetBodyInnerHTML(R"HTML(
@@ -234,15 +235,135 @@ TEST_F(CompositingReasonFinderTest, PromoteCrossOriginIframe) {
)HTML");
UpdateAllLifecyclePhasesForTest();
- iframe = GetDocument().getElementById("iframe");
- ASSERT_TRUE(iframe);
- iframe_layer = ToLayoutBoxModelObject(iframe->GetLayoutObject())->Layer();
+ iframe = To<HTMLFrameOwnerElement>(GetDocument().getElementById("iframe"));
+ iframe_layout_view =
+ To<LocalFrame>(iframe->ContentFrame())->ContentLayoutObject();
+ iframe_layer = iframe_layout_view->Layer();
ASSERT_TRUE(iframe_layer);
- ASSERT_TRUE(To<HTMLFrameOwnerElement>(iframe)
- ->ContentFrame()
- ->IsCrossOriginToMainFrame());
+ ASSERT_TRUE(iframe->ContentFrame()->IsCrossOriginToMainFrame());
EXPECT_EQ(CompositingReason::kIFrame,
iframe_layer->DirectCompositingReasons());
}
+TEST_F(CompositingReasonFinderTest,
+ CompositeWithBackfaceVisibilityAncestorAndPreserve3D) {
+ ScopedTransformInteropForTest enabled(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ div { width: 100px; height: 100px; position: relative }
+ </style>
+ <div style="backface-visibility: hidden; transform-style: preserve-3d">
+ <div id=target></div>
+ </div>
+ )HTML");
+
+ PaintLayer* target_layer =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
+
+ EXPECT_EQ(CompositingReason::kBackfaceInvisibility3DAncestor,
+ target_layer->PotentialCompositingReasonsFromNonStyle());
+ EXPECT_EQ(kPaintsIntoOwnBacking, target_layer->GetCompositingState());
+}
+
+TEST_F(CompositingReasonFinderTest,
+ CompositeWithBackfaceVisibilityAncestorAndPreserve3DWithInterveningDiv) {
+ ScopedTransformInteropForTest enabled(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ div { width: 100px; height: 100px }
+ </style>
+ <div style="backface-visibility: hidden; transform-style: preserve-3d">
+ <div>
+ <div id=target style="position: relative"></div>
+ </div>
+ </div>
+ )HTML");
+
+ PaintLayer* target_layer =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
+
+ EXPECT_EQ(CompositingReason::kBackfaceInvisibility3DAncestor,
+ target_layer->PotentialCompositingReasonsFromNonStyle());
+ EXPECT_EQ(kPaintsIntoOwnBacking, target_layer->GetCompositingState());
+}
+
+TEST_F(CompositingReasonFinderTest,
+ CompositeWithBackfaceVisibilityAncestorWithInterveningStackingDiv) {
+ ScopedTransformInteropForTest enabled(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ div { width: 100px; height: 100px }
+ </style>
+ <div style="backface-visibility: hidden; transform-style: preserve-3d">
+ <div id=intermediate style="isolation: isolate">
+ <div id=target style="position: relative"></div>
+ </div>
+ </div>
+ )HTML");
+
+ PaintLayer* intermediate_layer =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("intermediate"))
+ ->Layer();
+
+ PaintLayer* target_layer =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
+
+ EXPECT_EQ(CompositingReason::kBackfaceInvisibility3DAncestor,
+ intermediate_layer->PotentialCompositingReasonsFromNonStyle());
+ EXPECT_EQ(kPaintsIntoOwnBacking, intermediate_layer->GetCompositingState());
+
+ EXPECT_EQ(CompositingReason::kNone,
+ target_layer->PotentialCompositingReasonsFromNonStyle());
+ EXPECT_NE(kPaintsIntoOwnBacking, target_layer->GetCompositingState());
+}
+
+TEST_F(CompositingReasonFinderTest,
+ CompositeWithBackfaceVisibilityAncestorAndFlattening) {
+ ScopedTransformInteropForTest enabled(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ div { width: 100px; height: 100px; position: relative }
+ </style>
+ <div style="backface-visibility: hidden;">
+ <div id=target></div>
+ </div>
+ )HTML");
+
+ PaintLayer* target_layer =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
+
+ EXPECT_EQ(CompositingReason::kNone,
+ target_layer->PotentialCompositingReasonsFromNonStyle());
+ EXPECT_NE(kPaintsIntoOwnBacking, target_layer->GetCompositingState());
+}
+
+TEST_F(CompositingReasonFinderTest, CompositeWithBackfaceVisibility) {
+ ScopedTransformInteropForTest enabled(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ div { width: 100px; height: 100px; position: relative }
+ </style>
+ <div id=target style="backface-visibility: hidden;">
+ <div></div>
+ </div>
+ )HTML");
+
+ PaintLayer* target_layer =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
+
+ EXPECT_EQ(CompositingReason::kNone,
+ target_layer->PotentialCompositingReasonsFromNonStyle());
+ EXPECT_EQ(kPaintsIntoOwnBacking, target_layer->GetCompositingState());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc
index 1407cb0447d..c983a141d09 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc
@@ -27,6 +27,7 @@
#include "third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h"
#include "base/macros.h"
+#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
@@ -179,13 +180,15 @@ static CompositingReasons SubtreeReasonsForCompositing(
CompositingReason::kComboCompositedDescendants;
if (layer->ShouldIsolateCompositedDescendants()) {
- DCHECK(layer->GetLayoutObject().StyleRef().IsStackingContext());
+ DCHECK(layer->GetLayoutObject().IsStackingContext());
subtree_reasons |= CompositingReason::kIsolateCompositedDescendants;
}
- if (layer->GetLayoutObject().StyleRef().GetPosition() == EPosition::kFixed) {
+ if (layer->GetLayoutObject().IsVideo() &&
+ To<HTMLMediaElement>(layer->GetLayoutObject().GetNode())
+ ->IsFullscreen()) {
subtree_reasons |=
- CompositingReason::kPositionFixedWithCompositedDescendants;
+ CompositingReason::kFullscreenVideoWithCompositedDescendants;
}
// A layer with preserve-3d or perspective only needs to be composited if
@@ -376,11 +379,22 @@ void CompositingRequirementsUpdater::UpdateRecursive(
RecursionData child_recursion_data = current_recursion_data;
child_recursion_data.subtree_is_compositing_ = false;
+ // Embedded objects treat the embedded document as a child for the purposes
+ // of composited layer decisions. Look into the embedded document to determine
+ // if it is composited.
+ bool contains_composited_layer =
+ (layer->GetLayoutObject().IsLayoutEmbeddedContent() &&
+ ToLayoutEmbeddedContent(layer->GetLayoutObject())
+ .ContentDocumentIsCompositing());
+
bool will_be_composited_or_squashed =
can_be_composited && RequiresCompositingOrSquashing(reasons_to_composite);
- if (will_be_composited_or_squashed) {
- // This layer now acts as the ancestor for child layers.
- child_recursion_data.compositing_ancestor_ = layer;
+
+ if (will_be_composited_or_squashed || contains_composited_layer) {
+ if (will_be_composited_or_squashed) {
+ // This layer now acts as the ancestor for child layers.
+ child_recursion_data.compositing_ancestor_ = layer;
+ }
// Here we know that all children and the layer's own contents can blindly
// paint into this layer's backing, until a descendant is composited. So, we
@@ -499,7 +513,7 @@ void CompositingRequirementsUpdater::UpdateRecursive(
// Now that the subtree has been traversed, we can check for compositing
// reasons that depended on the state of the subtree.
- if (layer->GetLayoutObject().StyleRef().IsStackingContext()) {
+ if (layer->GetLayoutObject().IsStackingContext()) {
layer->SetShouldIsolateCompositedDescendants(
child_recursion_data.has_unisolated_composited_blending_descendant_);
} else {
@@ -508,30 +522,21 @@ void CompositingRequirementsUpdater::UpdateRecursive(
child_recursion_data.has_unisolated_composited_blending_descendant_;
}
- // Embedded objects treat the embedded document as a child for the purposes
- // of composited layer decisions. Look into the embedded document to determine
- // if it is composited.
- bool contains_composited_iframe =
- layer->GetLayoutObject().IsLayoutEmbeddedContent() &&
- ToLayoutEmbeddedContent(layer->GetLayoutObject())
- .RequiresAcceleratedCompositing();
-
// Subsequent layers in the parent's stacking context may also need to
// composite.
- if (child_recursion_data.subtree_is_compositing_)
+ if (child_recursion_data.subtree_is_compositing_ || contains_composited_layer)
current_recursion_data.subtree_is_compositing_ = true;
// Set the flag to say that this SC has compositing children.
layer->SetHasCompositingDescendant(
child_recursion_data.subtree_is_compositing_ ||
- contains_composited_iframe);
+ contains_composited_layer);
if (layer->IsRootLayer()) {
// The root layer needs to be composited if anything else in the tree is
// composited. Otherwise, we can disable compositing entirely.
if (child_recursion_data.subtree_is_compositing_ ||
- RequiresCompositingOrSquashing(reasons_to_composite) ||
- compositor->RootShouldAlwaysComposite()) {
+ RequiresCompositingOrSquashing(reasons_to_composite)) {
#if DCHECK_IS_ON()
// The reason for compositing should not be due to composited scrolling.
// It should only be compositing in order to represent composited content
@@ -551,9 +556,11 @@ void CompositingRequirementsUpdater::UpdateRecursive(
// the overlap map. Layers that are not separately composited will paint
// into their compositing ancestor's backing, and so are still considered
// for overlap.
- if (child_recursion_data.compositing_ancestor_ &&
- !child_recursion_data.compositing_ancestor_->IsRootLayer())
+ if ((child_recursion_data.compositing_ancestor_ &&
+ !child_recursion_data.compositing_ancestor_->IsRootLayer()) ||
+ contains_composited_layer) {
overlap_map.Add(layer, abs_bounds, use_clipped_bounding_rect);
+ }
// Now check for reasons to become composited that depend on the state of
// descendant layers.
@@ -586,20 +593,16 @@ void CompositingRequirementsUpdater::UpdateRecursive(
current_recursion_data.subtree_is_compositing_ = true;
// Turn overlap testing off for later layers if it's already off, or if we
- // have an animating transform. Note that if the layer clips its
- // descendants, there's no reason to propagate the child animation to the
- // parent layers. That's because we know for sure the animation is contained
- // inside the clipping rectangle, which is already added to the overlap map.
- bool is_composited_clipping_layer =
- can_be_composited && (reasons_to_composite &
- CompositingReason::kClipsCompositingDescendants);
- if ((!child_recursion_data.testing_overlap_ &&
- !is_composited_clipping_layer) ||
- layer->GetLayoutObject().StyleRef().HasCurrentTransformAnimation())
+ // have an animating transform.
+ if (!child_recursion_data.testing_overlap_ ||
+ layer->GetLayoutObject().StyleRef().HasCurrentTransformAnimation()) {
current_recursion_data.testing_overlap_ = false;
+ }
- if (child_recursion_data.compositing_ancestor_ == layer)
+ if (child_recursion_data.compositing_ancestor_ == layer ||
+ contains_composited_layer) {
overlap_map.FinishCurrentOverlapTestingContext();
+ }
descendant_has3d_transform |=
any_descendant_has3d_transform || layer->Has3DTransform();
@@ -608,13 +611,18 @@ void CompositingRequirementsUpdater::UpdateRecursive(
// Layer assignment is needed for allocating or removing composited
// layers related to this PaintLayer; hence the below conditions.
if (reasons_to_composite || layer->GetCompositingState() != kNotComposited ||
- layer->LostGroupedMapping())
+ layer->LostGroupedMapping()) {
layer->SetNeedsCompositingLayerAssignment();
+ } else if (contains_composited_layer) {
+ // If this is an iframe whose content document is composited, then we need
+ // CompositedLayerAssigner to process this layer, to ensure that we don't
+ // squash layers painted before the iframe with layers painted after it.
+ layer->PropagateDescendantNeedsCompositingLayerAssignment();
+ }
// At this point we have finished collecting all reasons to composite this
// layer.
layer->SetCompositingReasons(reasons_to_composite);
-
// If we've skipped recursing down to children but children needed an
// update, remember this on the display lock context, so that we can restore
// the dirty bit when the lock is unlocked.
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater_test.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater_test.cc
index 15bb8e48d76..b78757326d2 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater_test.cc
@@ -54,33 +54,6 @@ TEST_F(CompositingRequirementsUpdaterTest,
EXPECT_EQ(CompositingReason::kOverlap, target->GetCompositingReasons());
}
-TEST_F(CompositingRequirementsUpdaterTest,
- NoDescendantReasonForNonSelfPaintingLayer) {
- SetBodyInnerHTML(R"HTML(
- <style>
- #target {
- overflow: auto;
- width: 100px;
- height: 100px;
- }
- </style>
- <div id=target>
- <div style="backface-visibility: hidden"></div>
- </div>
- )HTML");
-
- PaintLayer* target =
- ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
- EXPECT_FALSE(target->GetCompositingReasons());
-
- // Now make |target| self-painting.
- GetDocument().getElementById("target")->setAttribute(html_names::kStyleAttr,
- "position: relative");
- UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(CompositingReason::kClipsCompositingDescendants,
- target->GetCompositingReasons());
-}
-
// This test sets up a situation where a squashed PaintLayer loses its
// backing, but does not change visual rect. Therefore the compositing system
// must invalidate it because of change of backing.
@@ -156,7 +129,8 @@ TEST_F(CompositingRequirementsUpdaterTest, NonTrivial3DTransforms) {
ToLayoutBox(transform_3d)->Layer()->GetCompositingReasons());
const auto* transform_2d = GetLayoutObjectByElementId("2d-transform");
EXPECT_FALSE(transform_2d->StyleRef().HasNonTrivial3DTransformOperation());
- EXPECT_TRUE(ToLayoutBox(transform_2d)->Layer()->GetCompositingReasons());
+ EXPECT_TRUE(CompositingReason::kTrivial3DTransform &
+ ToLayoutBox(transform_2d)->Layer()->GetCompositingReasons());
const auto* transform_3d_translate_z =
GetLayoutObjectByElementId("3d-transform-translate-z");
@@ -170,6 +144,7 @@ TEST_F(CompositingRequirementsUpdaterTest, NonTrivial3DTransforms) {
EXPECT_FALSE(
transform_2d_translate_z->StyleRef().HasNonTrivial3DTransformOperation());
EXPECT_TRUE(
+ CompositingReason::kTrivial3DTransform &
ToLayoutBox(transform_2d_translate_z)->Layer()->GetCompositingReasons());
const auto* transform_2d_translate_x =
GetLayoutObjectByElementId("2d-transform-translate-x");
@@ -184,7 +159,8 @@ TEST_F(CompositingRequirementsUpdaterTest, NonTrivial3DTransforms) {
ToLayoutBox(xform_rot_x_3d)->Layer()->GetCompositingReasons());
const auto* xform_rot_x_2d = GetLayoutObjectByElementId("2d-transform-rot-x");
EXPECT_FALSE(xform_rot_x_2d->StyleRef().HasNonTrivial3DTransformOperation());
- EXPECT_TRUE(ToLayoutBox(xform_rot_x_2d)->Layer()->GetCompositingReasons());
+ EXPECT_TRUE(CompositingReason::kTrivial3DTransform &
+ ToLayoutBox(xform_rot_x_2d)->Layer()->GetCompositingReasons());
const auto* xform_rot_z_2d = GetLayoutObjectByElementId("2d-transform-rot-z");
EXPECT_FALSE(xform_rot_z_2d->StyleRef().HasNonTrivial3DTransformOperation());
EXPECT_FALSE(ToLayoutBox(xform_rot_z_2d)->Layer()->GetCompositingReasons());
@@ -195,7 +171,8 @@ TEST_F(CompositingRequirementsUpdaterTest, NonTrivial3DTransforms) {
ToLayoutBox(rotation_y_3d)->Layer()->GetCompositingReasons());
const auto* rotation_y_2d = GetLayoutObjectByElementId("2d-rotation-y");
EXPECT_FALSE(rotation_y_2d->StyleRef().HasNonTrivial3DTransformOperation());
- EXPECT_TRUE(ToLayoutBox(rotation_y_2d)->Layer()->GetCompositingReasons());
+ EXPECT_TRUE(CompositingReason::kTrivial3DTransform &
+ ToLayoutBox(rotation_y_2d)->Layer()->GetCompositingReasons());
const auto* rotation_z_2d = GetLayoutObjectByElementId("2d-rotation-z");
EXPECT_FALSE(rotation_z_2d->StyleRef().HasNonTrivial3DTransformOperation());
EXPECT_FALSE(ToLayoutBox(rotation_z_2d)->Layer()->GetCompositingReasons());
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_test.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_test.cc
index 8a90f5ad5cd..09b703eb8c8 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_test.cc
@@ -13,6 +13,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/web/web_script_source.h"
+#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
@@ -254,18 +255,12 @@ TEST_P(CompositingTest, BackgroundColorInScrollingContentsLayer) {
ASSERT_TRUE(scroller_box->GetBackgroundPaintLocation() ==
kBackgroundPaintInScrollingContents);
- // In CAP mode, background_color is only set on the cc::Layer which draws the
- // background; in pre-CAP mode, it is set on both the main layer and the
- // scrolling contents layer.
- bool cap_mode = RuntimeEnabledFeatures::CompositeAfterPaintEnabled();
-
// The root layer and root scrolling contents layer get background_color by
// blending the CSS background-color of the <html> element with
// LocalFrameView::BaseBackgroundColor(), which is white by default.
auto* layer = CcLayersByName(RootCcLayer(), "LayoutView #document")[0];
SkColor expected_color = SkColorSetRGB(10, 20, 30);
- EXPECT_EQ(layer->background_color(),
- cap_mode ? SK_ColorTRANSPARENT : expected_color);
+ EXPECT_EQ(layer->background_color(), SK_ColorTRANSPARENT);
auto* scrollable_area = GetLocalFrameView()->LayoutViewport();
layer = ScrollingContentsCcLayerByScrollElementId(
RootCcLayer(), scrollable_area->GetScrollElementId());
@@ -275,8 +270,7 @@ TEST_P(CompositingTest, BackgroundColorInScrollingContentsLayer) {
// the layer-defining element.
expected_color = SkColorSetRGB(30, 40, 50);
layer = CcLayerByDOMElementId("scroller");
- EXPECT_EQ(layer->background_color(),
- cap_mode ? SK_ColorTRANSPARENT : expected_color);
+ EXPECT_EQ(layer->background_color(), SK_ColorTRANSPARENT);
scrollable_area = scroller_box->GetScrollableArea();
layer = ScrollingContentsCcLayerByScrollElementId(
RootCcLayer(), scrollable_area->GetScrollElementId());
@@ -319,11 +313,6 @@ TEST_P(CompositingTest, BackgroundColorInGraphicsLayer) {
ASSERT_TRUE(scroller_box->GetBackgroundPaintLocation() ==
kBackgroundPaintInGraphicsLayer);
- // In CAP mode, background_color is only set on the cc::Layer which draws the
- // background; in pre-CAP mode, it is set on both the main layer and the
- // scrolling contents layer.
- bool cap_mode = RuntimeEnabledFeatures::CompositeAfterPaintEnabled();
-
// The root layer and root scrolling contents layer get background_color by
// blending the CSS background-color of the <html> element with
// LocalFrameView::BaseBackgroundColor(), which is white by default. In this
@@ -334,8 +323,8 @@ TEST_P(CompositingTest, BackgroundColorInGraphicsLayer) {
auto* scrollable_area = GetLocalFrameView()->LayoutViewport();
layer = ScrollingContentsCcLayerByScrollElementId(
RootCcLayer(), scrollable_area->GetScrollElementId());
- EXPECT_EQ(layer->background_color(),
- cap_mode ? SK_ColorTRANSPARENT : SK_ColorWHITE);
+ EXPECT_EQ(layer->background_color(), SK_ColorTRANSPARENT);
+ EXPECT_EQ(layer->SafeOpaqueBackgroundColor(), SK_ColorTRANSPARENT);
// Non-root layers set background_color based on the CSS background color of
// the layer-defining element.
@@ -345,8 +334,8 @@ TEST_P(CompositingTest, BackgroundColorInGraphicsLayer) {
scrollable_area = scroller_box->GetScrollableArea();
layer = ScrollingContentsCcLayerByScrollElementId(
RootCcLayer(), scrollable_area->GetScrollElementId());
- EXPECT_EQ(layer->background_color(),
- cap_mode ? SK_ColorTRANSPARENT : expected_color);
+ EXPECT_EQ(layer->background_color(), SK_ColorTRANSPARENT);
+ EXPECT_EQ(layer->SafeOpaqueBackgroundColor(), SK_ColorTRANSPARENT);
}
class CompositingSimTest : public PaintTestConfigurations, public SimTest {
@@ -368,6 +357,15 @@ class CompositingSimTest : public PaintTestConfigurations, public SimTest {
return layers.IsEmpty() ? nullptr : layers[0];
}
+ const cc::Layer* CcLayerByOwnerNodeId(Node* node) {
+ DOMNodeId id = DOMNodeIds::IdForNode(node);
+ for (auto& layer : RootCcLayer()->children()) {
+ if (layer->debug_info() && layer->debug_info()->owner_node_id == id)
+ return layer.get();
+ }
+ return nullptr;
+ }
+
Element* GetElementById(const AtomicString& id) {
return MainFrame().GetFrame()->GetDocument()->getElementById(id);
}
@@ -1101,7 +1099,8 @@ TEST_P(CompositingSimTest, SafeOpaqueBackgroundColorGetsSet) {
auto* grouped_mapping =
GetElementById("topleft")->GetLayoutBox()->Layer()->GroupedMapping();
- auto* squashed_layer = grouped_mapping->SquashingLayer()->CcLayer();
+ auto* squashed_layer =
+ grouped_mapping->NonScrollingSquashingLayer()->CcLayer();
ASSERT_NE(nullptr, squashed_layer);
// Top left and bottom right are squashed.
@@ -1222,7 +1221,14 @@ TEST_P(CompositingSimTest, PromoteCrossOriginIframe) {
blink::features::kCompositeCrossOriginIframes, true);
InitializeWithHTML("<!DOCTYPE html><iframe id=iframe sandbox></iframe>");
Compositor().BeginFrame();
- EXPECT_TRUE(CcLayerByDOMElementId("iframe"));
+ Document* iframe_doc =
+ To<HTMLFrameOwnerElement>(GetElementById("iframe"))->contentDocument();
+ Node* owner_node = iframe_doc;
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ owner_node = iframe_doc->documentElement();
+ auto* layer = CcLayerByOwnerNodeId(owner_node);
+ EXPECT_TRUE(layer);
+ EXPECT_EQ(layer->bounds(), gfx::Size(300, 150));
}
// On initial layout, the iframe is not yet loaded and is not considered
@@ -1244,7 +1250,12 @@ TEST_P(CompositingSimTest, PromoteCrossOriginIframeAfterLoading) {
frame_resource.Complete("<!DOCTYPE html>");
Compositor().BeginFrame();
- EXPECT_TRUE(CcLayerByDOMElementId("iframe"));
+ Document* iframe_doc =
+ To<HTMLFrameOwnerElement>(GetElementById("iframe"))->contentDocument();
+ Node* owner_node = iframe_doc;
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ owner_node = iframe_doc->documentElement();
+ EXPECT_TRUE(CcLayerByOwnerNodeId(owner_node));
}
// An iframe that is cross-origin to the parent should be composited. This test
@@ -1271,8 +1282,18 @@ TEST_P(CompositingSimTest, PromoteCrossOriginToParent) {
grandchild_resource.Complete("<!DOCTYPE html>");
Compositor().BeginFrame();
- EXPECT_TRUE(CcLayerByDOMElementId("main_iframe"));
- EXPECT_TRUE(CcLayerByDOMElementId("child_iframe"));
+ Document* iframe_doc =
+ To<HTMLFrameOwnerElement>(GetElementById("main_iframe"))
+ ->contentDocument();
+ EXPECT_TRUE(CcLayerByOwnerNodeId(iframe_doc));
+
+ iframe_doc =
+ To<HTMLFrameOwnerElement>(iframe_doc->getElementById("child_iframe"))
+ ->contentDocument();
+ Node* owner_node = iframe_doc;
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ owner_node = iframe_doc->documentElement();
+ EXPECT_TRUE(CcLayerByOwnerNodeId(owner_node));
}
// Initially the iframe is cross-origin and should be composited. After changing
@@ -1293,10 +1314,16 @@ TEST_P(CompositingSimTest, PromoteCrossOriginIframeAfterDomainChange) {
frame_resource.Complete("<!DOCTYPE html>");
Compositor().BeginFrame();
- EXPECT_TRUE(CcLayerByDOMElementId("iframe"));
-
auto* iframe_element =
To<HTMLIFrameElement>(GetDocument().getElementById("iframe"));
+
+ Document* iframe_doc =
+ To<HTMLFrameOwnerElement>(GetElementById("iframe"))->contentDocument();
+ Node* owner_node = iframe_doc;
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ owner_node = iframe_doc->documentElement();
+ EXPECT_TRUE(CcLayerByOwnerNodeId(owner_node));
+
NonThrowableExceptionState exception_state;
GetDocument().setDomain(String("origin-a.com"), exception_state);
iframe_element->contentDocument()->setDomain(String("origin-a.com"),
@@ -1305,7 +1332,12 @@ TEST_P(CompositingSimTest, PromoteCrossOriginIframeAfterDomainChange) {
// using BeginFrame.
UpdateAllLifecyclePhases();
- EXPECT_FALSE(CcLayerByDOMElementId("iframe"));
+ iframe_doc =
+ To<HTMLFrameOwnerElement>(GetElementById("iframe"))->contentDocument();
+ owner_node = iframe_doc;
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ owner_node = iframe_doc->documentElement();
+ EXPECT_FALSE(CcLayerByOwnerNodeId(owner_node));
}
// This test sets up nested frames with domains A -> B -> A. Initially, the
@@ -1333,8 +1365,18 @@ TEST_P(CompositingSimTest, PromoteCrossOriginToParentIframeAfterDomainChange) {
grandchild_resource.Complete("<!DOCTYPE html>");
Compositor().BeginFrame();
- EXPECT_TRUE(CcLayerByDOMElementId("main_iframe"));
- EXPECT_TRUE(CcLayerByDOMElementId("child_iframe"));
+ Document* iframe_doc =
+ To<HTMLFrameOwnerElement>(GetElementById("main_iframe"))
+ ->contentDocument();
+ EXPECT_TRUE(CcLayerByOwnerNodeId(iframe_doc));
+
+ iframe_doc =
+ To<HTMLFrameOwnerElement>(iframe_doc->getElementById("child_iframe"))
+ ->contentDocument();
+ Node* owner_node = iframe_doc;
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ owner_node = iframe_doc->documentElement();
+ EXPECT_TRUE(CcLayerByOwnerNodeId(owner_node));
auto* main_iframe_element =
To<HTMLIFrameElement>(GetDocument().getElementById("main_iframe"));
@@ -1351,8 +1393,35 @@ TEST_P(CompositingSimTest, PromoteCrossOriginToParentIframeAfterDomainChange) {
// using BeginFrame.
UpdateAllLifecyclePhases();
- EXPECT_FALSE(CcLayerByDOMElementId("main_iframe"));
- EXPECT_FALSE(CcLayerByDOMElementId("child_iframe"));
+ iframe_doc = To<HTMLFrameOwnerElement>(GetElementById("main_iframe"))
+ ->contentDocument();
+ EXPECT_FALSE(CcLayerByOwnerNodeId(iframe_doc));
+
+ iframe_doc =
+ To<HTMLFrameOwnerElement>(iframe_doc->getElementById("child_iframe"))
+ ->contentDocument();
+ owner_node = iframe_doc;
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ owner_node = iframe_doc->documentElement();
+ EXPECT_FALSE(CcLayerByOwnerNodeId(owner_node));
+}
+
+// Regression test for https://crbug.com/1095167. Render surfaces require that
+// EffectNode::stable_id is set.
+TEST_P(CompositingTest, EffectNodesShouldHaveStableIds) {
+ InitializeWithHTML(*WebView()->MainFrameImpl()->GetFrame(), R"HTML(
+ <div style="overflow: hidden; border-radius: 2px; height: 10px;">
+ <div style="backdrop-filter: grayscale(3%);">
+ a
+ <span style="backdrop-filter: grayscale(3%);">b</span>
+ </div>
+ </div>
+ )HTML");
+ auto* property_trees = RootCcLayer()->layer_tree_host()->property_trees();
+ for (const auto& effect_node : property_trees->effect_tree.nodes()) {
+ if (effect_node.parent_id != -1)
+ EXPECT_TRUE(!!effect_node.stable_id);
+ }
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.cc b/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.cc
index fce32e76d78..bea6453330a 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.cc
@@ -16,6 +16,9 @@ namespace {
std::unique_ptr<JSONObject> GraphicsLayerAsJSON(const GraphicsLayer* layer,
LayerTreeFlags flags) {
auto json = CCLayerAsJSON(layer->CcLayer(), flags);
+ // CCLayerAsJSON() doesn't know the name before paint or if the layer is a
+ // legacy GraphicsLayer which doesn't contribute to the cc layer list.
+ json->SetString("name", layer->DebugName());
// Content dumped after this point, down to AppendAdditionalInfoAsJSON, is
// specific to GraphicsLayer tree dumping when called from one of the methods
@@ -35,14 +38,6 @@ std::unique_ptr<JSONObject> GraphicsLayerAsJSON(const GraphicsLayer* layer,
if (!layer->ContentsAreVisible())
json->SetBoolean("contentsVisible", false);
- // MaskLayers are output via ForeignLayerDisplayItem iteration in the other
- // dumping code paths.
- if (layer->MaskLayer()) {
- auto mask_layer_json = std::make_unique<JSONArray>();
- mask_layer_json->PushObject(GraphicsLayerAsJSON(layer->MaskLayer(), flags));
- json->SetArray("maskLayer", std::move(mask_layer_json));
- }
-
if (layer->HasLayerState() && (flags & (kLayerTreeIncludesDebugInfo |
kLayerTreeIncludesPaintRecords))) {
json->SetString("layerState", layer->GetPropertyTreeState().ToString());
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc b/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc
index 6e5eaa164fe..311d4a87190 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc
@@ -60,8 +60,6 @@ void GraphicsLayerTreeBuilder::RebuildRecursive(
PaintLayer& layer,
GraphicsLayerVector& child_layers,
PendingOverflowControlReparents& pending_reparents) {
- const ComputedStyle& style = layer.GetLayoutObject().StyleRef();
-
// Make the layer compositing if necessary, and set up clipping and content
// layers. Note that we can only do work here that is independent of whether
// the descendant layers have been processed. computeCompositingRequirements()
@@ -90,6 +88,15 @@ void GraphicsLayerTreeBuilder::RebuildRecursive(
bool recursion_blocked_by_display_lock =
layer.GetLayoutObject().PrePaintBlockedByDisplayLock(
DisplayLockLifecycleTarget::kChildren);
+ // If the recursion is blocked meaningfully (i.e. we would have recursed,
+ // since the layer has children), then we should inform the display-lock
+ // context that we blocked a graphics layer recursion, so that we can ensure
+ // to rebuild the tree once we're unlocked.
+ if (recursion_blocked_by_display_lock && layer.FirstChild()) {
+ auto* context = layer.GetLayoutObject().GetDisplayLockContext();
+ DCHECK(context);
+ context->NotifyGraphicsLayerRebuildBlocked();
+ }
if (layer.IsStackingContextWithNegativeZOrderChildren()) {
if (!recursion_blocked_by_display_lock) {
@@ -118,12 +125,30 @@ void GraphicsLayerTreeBuilder::RebuildRecursive(
}
}
- if (has_composited_layer_mapping) {
- bool parented = false;
- if (layer.GetLayoutObject().IsLayoutEmbeddedContent()) {
- parented = PaintLayerCompositor::AttachFrameContentLayersToIframeLayer(
- ToLayoutEmbeddedContent(layer.GetLayoutObject()));
+ if (layer.GetLayoutObject().IsLayoutEmbeddedContent()) {
+ DCHECK(this_layer_children.IsEmpty());
+ PaintLayerCompositor* inner_compositor =
+ PaintLayerCompositor::FrameContentsCompositor(
+ ToLayoutEmbeddedContent(layer.GetLayoutObject()));
+ if (inner_compositor) {
+ // If the embedded frame is render-throttled, it might not be compositing
+ // clean at this point. In that case, we still need to connect its
+ // existing root graphics layer, so we need to query the stale compositing
+ // state.
+ DisableCompositingQueryAsserts disabler;
+ if (inner_compositor->InCompositingMode()) {
+ if (GraphicsLayer* inner_root_layer =
+ inner_compositor->RootGraphicsLayer()) {
+ layer_vector_for_children->push_back(inner_root_layer);
+ }
+ }
+ inner_compositor->ClearRootLayerAttachmentDirty();
}
+ }
+
+ if (has_composited_layer_mapping) {
+ // TODO(szager): Remove after diagnosing crash crbug.com/1092673
+ CHECK(current_composited_layer_mapping);
// Apply all pending reparents by inserting the overflow controls
// root layers into |this_layer_children|. To do this, first sort
@@ -148,25 +173,19 @@ void GraphicsLayerTreeBuilder::RebuildRecursive(
}
}
- if (!parented && !this_layer_children.IsEmpty()) {
- // Ensure we don't clobber the decoration outline layer.
- if (auto* layer = current_composited_layer_mapping
- ->DetachLayerForDecorationOutline()) {
- this_layer_children.push_back(layer);
- }
+ if (!this_layer_children.IsEmpty())
current_composited_layer_mapping->SetSublayers(this_layer_children);
- }
if (ShouldAppendLayer(layer)) {
child_layers.push_back(
- current_composited_layer_mapping->ChildForSuperlayers());
+ current_composited_layer_mapping->MainGraphicsLayer());
}
}
// Also insert for self, to handle the case of scrollers with negative
// z-index children (the scrolbars should still paint on top of the
// scroller itself).
- if (style.IsStacked() && has_composited_layer_mapping &&
+ if (layer.GetLayoutObject().IsStacked() && has_composited_layer_mapping &&
layer.GetCompositedLayerMapping()->NeedsToReparentOverflowControls())
pending_reparents.Set(&layer, child_layers.size());
@@ -174,7 +193,7 @@ void GraphicsLayerTreeBuilder::RebuildRecursive(
// Overlay scrollbars need to paint on top of all content under the scroller,
// so keep overwriting if we find a PaintLayer that is later in paint order.
const PaintLayer* scroll_parent = layer.ScrollParent();
- if (style.IsStacked() && scroll_parent &&
+ if (layer.GetLayoutObject().IsStacked() && scroll_parent &&
scroll_parent->HasCompositedLayerMapping() &&
scroll_parent->GetCompositedLayerMapping()
->NeedsToReparentOverflowControls())
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc b/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc
index 8ab1291f868..76837334e57 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/layout/layout_block.h"
+#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
@@ -50,7 +51,7 @@ GraphicsLayerUpdater::UpdateContext::UpdateContext(const UpdateContext& other,
if (compositing_state != kNotComposited &&
compositing_state != kPaintsIntoGroupedBacking) {
compositing_ancestor_ = &layer;
- if (layer.GetLayoutObject().StyleRef().IsStackingContext())
+ if (layer.GetLayoutObject().IsStackingContext())
compositing_stacking_context_ = &layer;
}
// Any composited content under SVG must be a descendant of (but not
@@ -76,7 +77,7 @@ const PaintLayer* GraphicsLayerUpdater::UpdateContext::CompositingContainer(
return layer.EnclosingLayerWithCompositedLayerMapping(kExcludeSelf);
const PaintLayer* compositing_container;
- if (layer.GetLayoutObject().StyleRef().IsStacked() &&
+ if (layer.GetLayoutObject().IsStacked() &&
!layer.IsReplacedNormalFlowStacking()) {
compositing_container = compositing_stacking_context_;
} else if ((layer.Parent() &&
@@ -122,13 +123,13 @@ void GraphicsLayerUpdater::UpdateRecursive(
CompositedLayerMapping* mapping = layer.GetCompositedLayerMapping();
if (update_type == kForceUpdate || mapping->NeedsGraphicsLayerUpdate()) {
- bool had_scrolling_layer = mapping->ScrollingLayer();
+ bool had_scrolling_layer = mapping->ScrollingContentsLayer();
const auto* compositing_container = context.CompositingContainer(layer);
if (mapping->UpdateGraphicsLayerConfiguration(compositing_container)) {
needs_rebuild_tree_ = true;
// Change of existence of scrolling layer affects visual rect offsets of
// descendants via LayoutObject::ScrollAdjustmentForPaintInvalidation().
- if (had_scrolling_layer != !!mapping->ScrollingLayer())
+ if (had_scrolling_layer != !!mapping->ScrollingContentsLayer())
layers_needing_paint_invalidation.push_back(&layer);
}
mapping->UpdateGraphicsLayerGeometry(compositing_container,
@@ -140,6 +141,15 @@ void GraphicsLayerUpdater::UpdateRecursive(
}
}
+ if (layer.GetLayoutObject().IsLayoutEmbeddedContent()) {
+ if (PaintLayerCompositor* inner_compositor =
+ PaintLayerCompositor::FrameContentsCompositor(
+ ToLayoutEmbeddedContent(layer.GetLayoutObject()))) {
+ if (inner_compositor->RootLayerAttachmentDirty())
+ needs_rebuild_tree_ = true;
+ }
+ }
+
PaintLayer* first_child =
layer.GetLayoutObject().PrePaintBlockedByDisplayLock(
DisplayLockLifecycleTarget::kChildren)
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc b/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc
index 3f7a2b6c166..c7e2c69e8f6 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc
@@ -38,9 +38,7 @@
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/core/html/html_iframe_element.h"
-#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
-#include "third_party/blink/renderer/core/layout/layout_video.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
@@ -70,20 +68,11 @@ PaintLayerCompositor::PaintLayerCompositor(LayoutView& layout_view)
DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
}
-PaintLayerCompositor::~PaintLayerCompositor() {
- DCHECK_EQ(root_layer_attachment_, kRootLayerUnattached);
-}
+PaintLayerCompositor::~PaintLayerCompositor() = default;
void PaintLayerCompositor::CleanUp() {
if (InCompositingMode())
- DetachRootLayer();
-}
-
-void PaintLayerCompositor::DidLayout() {
- // FIXME: Technically we only need to do this when the LocalFrameView's
- // isScrollable method would return a different value.
- root_should_always_composite_dirty_ = true;
- EnableCompositingModeIfNeeded();
+ SetOwnerNeedsCompositingUpdate();
}
bool PaintLayerCompositor::InCompositingMode() const {
@@ -100,77 +89,12 @@ bool PaintLayerCompositor::StaleInCompositingMode() const {
void PaintLayerCompositor::SetCompositingModeEnabled(bool enable) {
if (enable == compositing_)
return;
-
compositing_ = enable;
-
- if (compositing_)
- AttachRootLayer();
- else
- DetachRootLayer();
-
- // Schedule an update in the parent frame so the <iframe>'s layer in the owner
- // document matches the compositing state here.
- if (HTMLFrameOwnerElement* owner_element =
- layout_view_.GetDocument().LocalOwner())
- owner_element->SetNeedsCompositingUpdate();
-}
-
-void PaintLayerCompositor::EnableCompositingModeIfNeeded() {
- if (!root_should_always_composite_dirty_)
- return;
-
- root_should_always_composite_dirty_ = false;
- if (compositing_)
- return;
-
- if (RootShouldAlwaysComposite()) {
- // FIXME: Is this needed? It was added in
- // https://bugs.webkit.org/show_bug.cgi?id=26651.
- // No tests fail if it's deleted.
- SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree);
- SetCompositingModeEnabled(true);
- }
-}
-
-bool PaintLayerCompositor::RootShouldAlwaysComposite() const {
- // If compositing is disabled for the WebView, then nothing composites.
- if (!layout_view_.GetDocument()
- .GetSettings()
- ->GetAcceleratedCompositingEnabled())
- return false;
- // Local roots composite always, when compositing is enabled globally.
- if (layout_view_.GetFrame()->IsLocalRoot())
- return true;
- // Some non-local roots of embedded content do not have a LocalFrameView
- // so they are not visible and should not get compositor layers.
- if (!layout_view_.GetFrameView())
- return false;
- // Non-local root frames will composite only if needed for scrolling.
- return CompositingReasonFinder::RequiresCompositingForScrollableFrame(
- layout_view_);
}
void PaintLayerCompositor::UpdateAcceleratedCompositingSettings() {
- root_should_always_composite_dirty_ = true;
- if (root_layer_attachment_ != kRootLayerUnattached)
- RootLayer()->SetNeedsCompositingInputsUpdate();
-}
-
-static LayoutVideo* FindFullscreenVideoLayoutObject(Document& document) {
- // Recursively find the document that is in fullscreen.
- Element* fullscreen_element = Fullscreen::FullscreenElementFrom(document);
- Document* content_document = &document;
- while (auto* frame_owner =
- DynamicTo<HTMLFrameOwnerElement>(fullscreen_element)) {
- content_document = frame_owner->contentDocument();
- if (!content_document)
- return nullptr;
- fullscreen_element = Fullscreen::FullscreenElementFrom(*content_document);
- }
- if (!IsA<HTMLVideoElement>(fullscreen_element))
- return nullptr;
- LayoutObject* layout_object = fullscreen_element->GetLayoutObject();
- return To<LayoutVideo>(layout_object);
+ if (auto* root_layer = RootLayer())
+ root_layer->SetNeedsCompositingInputsUpdate();
}
void PaintLayerCompositor::UpdateIfNeededRecursive(
@@ -231,11 +155,6 @@ void PaintLayerCompositor::UpdateIfNeededRecursiveInternal(
ScriptForbiddenScope forbid_script;
- // FIXME: EnableCompositingModeIfNeeded() can trigger a
- // CompositingUpdateRebuildTree, which asserts that it's not
- // InCompositingUpdate().
- EnableCompositingModeIfNeeded();
-
#if DCHECK_IS_ON()
view->SetIsUpdatingDescendantDependentFlags(true);
#endif
@@ -277,7 +196,6 @@ void PaintLayerCompositor::UpdateIfNeededRecursiveInternal(
#if DCHECK_IS_ON()
void PaintLayerCompositor::AssertNoUnresolvedDirtyBits() {
DCHECK_EQ(pending_update_type_, kCompositingUpdateNone);
- DCHECK(!root_should_always_composite_dirty_);
}
#endif
@@ -294,18 +212,6 @@ void PaintLayerCompositor::SetNeedsCompositingUpdate(
Lifecycle().EnsureStateAtMost(DocumentLifecycle::kLayoutClean);
}
-GraphicsLayer* PaintLayerCompositor::OverlayFullscreenVideoGraphicsLayer()
- const {
- LayoutVideo* video =
- FindFullscreenVideoLayoutObject(layout_view_.GetDocument());
- if (!video || !video->Layer()->HasCompositedLayerMapping() ||
- !video->VideoElement()->UsesOverlayFullscreenVideo()) {
- return nullptr;
- }
-
- return video->Layer()->GetCompositedLayerMapping()->MainGraphicsLayer();
-}
-
void PaintLayerCompositor::UpdateWithoutAcceleratedCompositing(
CompositingUpdateType update_type) {
DCHECK(!layout_view_.GetDocument()
@@ -426,9 +332,8 @@ void PaintLayerCompositor::UpdateIfNeeded(
// Save off our current parent. We need this in subframes, because our
// parent attached us to itself via AttachFrameContentLayersToIframeLayer().
if (!IsMainFrame() && update_root->GetCompositedLayerMapping()) {
- current_parent = update_root->GetCompositedLayerMapping()
- ->ChildForSuperlayers()
- ->Parent();
+ current_parent =
+ update_root->GetCompositedLayerMapping()->MainGraphicsLayer()->Parent();
}
#if DCHECK_IS_ON()
@@ -459,11 +364,10 @@ void PaintLayerCompositor::UpdateIfNeeded(
if (!child_list.IsEmpty()) {
CHECK(compositing_);
DCHECK_EQ(1u, child_list.size());
- // If this is a popup, don't hook into the layer tree.
- if (layout_view_.GetDocument().GetPage()->GetChromeClient().IsPopup())
- current_parent = nullptr;
- if (current_parent)
- current_parent->SetChildren(child_list);
+ // Schedule an update in the parent frame so the <iframe>'s layer in the
+ // owner document matches the compositing state here.
+ SetOwnerNeedsCompositingUpdate();
+ root_layer_attachment_dirty_ = true;
}
}
@@ -545,13 +449,6 @@ bool PaintLayerCompositor::AllocateOrClearCompositedLayerMapping(
if (!composited_layer_mapping_changed)
return false;
- if (layer->GetLayoutObject().IsLayoutEmbeddedContent()) {
- PaintLayerCompositor* inner_compositor = FrameContentsCompositor(
- ToLayoutEmbeddedContent(layer->GetLayoutObject()));
- if (inner_compositor && inner_compositor->StaleInCompositingMode())
- inner_compositor->AttachRootLayer();
- }
-
layer->ClearClipRects(kPaintingClipRects);
// Compositing state affects whether to create paint offset translation of
@@ -579,8 +476,9 @@ void PaintLayerCompositor::PaintInvalidationOnCompositingChange(
}
PaintLayerCompositor* PaintLayerCompositor::FrameContentsCompositor(
- LayoutEmbeddedContent& layout_object) {
- auto* element = DynamicTo<HTMLFrameOwnerElement>(layout_object.GetNode());
+ const LayoutEmbeddedContent& layout_object) {
+ const auto* element =
+ DynamicTo<HTMLFrameOwnerElement>(layout_object.GetNode());
if (!element)
return nullptr;
@@ -591,31 +489,9 @@ PaintLayerCompositor* PaintLayerCompositor::FrameContentsCompositor(
return nullptr;
}
-bool PaintLayerCompositor::AttachFrameContentLayersToIframeLayer(
- LayoutEmbeddedContent& layout_object) {
- PaintLayerCompositor* inner_compositor =
- FrameContentsCompositor(layout_object);
- if (!inner_compositor || !inner_compositor->StaleInCompositingMode() ||
- inner_compositor->root_layer_attachment_ !=
- kRootLayerAttachedViaEnclosingFrame)
- return false;
-
- PaintLayer* layer = layout_object.Layer();
- if (!layer->HasCompositedLayerMapping())
- return false;
-
- DisableCompositingQueryAsserts disabler;
- inner_compositor->RootLayer()->EnsureCompositedLayerMapping();
- layer->GetCompositedLayerMapping()->SetSublayers(
- GraphicsLayerVector(1, inner_compositor->RootGraphicsLayer()));
- return true;
-}
-
static void FullyInvalidatePaintRecursive(PaintLayer* layer) {
- if (layer->GetCompositingState() == kPaintsIntoOwnBacking) {
- layer->GetCompositedLayerMapping()->SetContentsNeedDisplay();
- layer->GetCompositedLayerMapping()->SetSquashingContentsNeedDisplay();
- }
+ if (layer->GetCompositingState() == kPaintsIntoOwnBacking)
+ layer->GetCompositedLayerMapping()->SetAllLayersNeedDisplay();
for (PaintLayer* child = layer->FirstChild(); child;
child = child->NextSibling())
@@ -637,40 +513,10 @@ PaintLayer* PaintLayerCompositor::RootLayer() const {
GraphicsLayer* PaintLayerCompositor::RootGraphicsLayer() const {
if (CompositedLayerMapping* clm = RootLayer()->GetCompositedLayerMapping())
- return clm->ChildForSuperlayers();
+ return clm->MainGraphicsLayer();
return nullptr;
}
-GraphicsLayer* PaintLayerCompositor::GetXrOverlayLayer() const {
- // immersive-ar DOM overlay mode is very similar to fullscreen video, using
- // the AR camera image instead of a video element as a background that's
- // separately composited in the browser. The fullscreened DOM content is shown
- // on top of that, same as HTML video controls.
- DCHECK(IsMainFrame());
- if (!layout_view_.GetDocument().IsXrOverlay())
- return nullptr;
-
- Element* fullscreen_element =
- Fullscreen::FullscreenElementFrom(layout_view_.GetDocument());
- if (!fullscreen_element)
- return nullptr;
-
- LayoutBoxModelObject* box = fullscreen_element->GetLayoutBoxModelObject();
- if (!box) {
- // Currently, only HTML fullscreen elements are supported for this mode,
- // not others such as SVG or MathML.
- DVLOG(1) << "no LayoutBoxModelObject for element " << fullscreen_element;
- return nullptr;
- }
-
- // The fullscreen element will be in its own layer due to
- // CompositingReasonFinder treating this scenario as a direct_reason.
- PaintLayer* layer = box->Layer();
- DCHECK(layer);
- GraphicsLayer* full_screen_layer = layer->GraphicsLayerBacking(box);
- return full_screen_layer;
-}
-
GraphicsLayer* PaintLayerCompositor::PaintRootGraphicsLayer() const {
if (layout_view_.GetDocument().GetPage()->GetChromeClient().IsPopup() ||
!IsMainFrame())
@@ -678,10 +524,11 @@ GraphicsLayer* PaintLayerCompositor::PaintRootGraphicsLayer() const {
// Start from the full screen overlay layer if exists. Other layers will be
// skipped during painting.
- if (auto* layer = GetXrOverlayLayer())
- return layer;
- if (auto* layer = OverlayFullscreenVideoGraphicsLayer())
- return layer;
+ if (PaintLayer* layer =
+ layout_view_.GetFrameView()->GetFullScreenOverlayLayer()) {
+ if (layer->HasCompositedLayerMapping())
+ return layer->GetCompositedLayerMapping()->MainGraphicsLayer();
+ }
return RootGraphicsLayer();
}
@@ -733,9 +580,6 @@ static void UpdateTrackingRasterInvalidationsRecursive(
for (wtf_size_t i = 0; i < graphics_layer->Children().size(); ++i)
UpdateTrackingRasterInvalidationsRecursive(graphics_layer->Children()[i]);
-
- if (GraphicsLayer* mask_layer = graphics_layer->MaskLayer())
- UpdateTrackingRasterInvalidationsRecursive(mask_layer);
}
void PaintLayerCompositor::UpdateTrackingRasterInvalidations() {
@@ -748,47 +592,11 @@ void PaintLayerCompositor::UpdateTrackingRasterInvalidations() {
UpdateTrackingRasterInvalidationsRecursive(root_layer);
}
-void PaintLayerCompositor::AttachRootLayer() {
- if (root_layer_attachment_ != kRootLayerUnattached)
- return;
-
- // With CompositeAfterPaint, PaintArtifactCompositor is responsible for the
- // root layer.
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- return;
-
- // The root layer of local frame root doesn't need to attach to anything.
- if (layout_view_.GetFrame()->IsLocalRoot()) {
- root_layer_attachment_ = kRootLayerOfLocalFrameRoot;
- return;
- }
-
- HTMLFrameOwnerElement* owner_element =
- layout_view_.GetDocument().LocalOwner();
- DCHECK(owner_element);
- // The layer will get hooked up via
- // CompositedLayerMapping::updateGraphicsLayerConfiguration() for the
- // frame's layoutObject in the parent document.
- owner_element->SetNeedsCompositingUpdate();
- if (owner_element->GetLayoutObject()) {
- ToLayoutBoxModelObject(owner_element->GetLayoutObject())
- ->Layer()
- ->SetNeedsCompositingInputsUpdate();
- }
- root_layer_attachment_ = kRootLayerAttachedViaEnclosingFrame;
-}
-
-void PaintLayerCompositor::DetachRootLayer() {
- if (root_layer_attachment_ == kRootLayerAttachedViaEnclosingFrame) {
- // The layer will get unhooked up via
- // CompositedLayerMapping::updateGraphicsLayerConfiguration() for the
- // frame's layoutObject in the parent document.
- if (HTMLFrameOwnerElement* owner_element =
- layout_view_.GetDocument().LocalOwner())
- owner_element->SetNeedsCompositingUpdate();
+void PaintLayerCompositor::SetOwnerNeedsCompositingUpdate() {
+ if (HTMLFrameOwnerElement* owner_element =
+ layout_view_.GetDocument().LocalOwner()) {
+ owner_element->SetNeedsCompositingUpdate();
}
-
- root_layer_attachment_ = kRootLayerUnattached;
}
ScrollingCoordinator* PaintLayerCompositor::GetScrollingCoordinator() const {
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h b/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h
index e747e628c87..e41c6fe752f 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h
@@ -38,6 +38,7 @@ namespace blink {
class PaintLayer;
class GraphicsLayer;
class LayoutEmbeddedContent;
+class LayoutView;
class Page;
class Scrollbar;
class ScrollingCoordinator;
@@ -80,10 +81,6 @@ class CORE_EXPORT PaintLayerCompositor {
// pointers out of this object become invalid.
void CleanUp();
- // Called after layout is performed on the LocalFrame holding the LayoutView,
- // during the document lifecycle update.
- void DidLayout();
-
void UpdateIfNeededRecursive(DocumentLifecycle::LifecycleState target_state);
// Return true if this LayoutView is in "compositing mode" (i.e. has one or
@@ -95,8 +92,6 @@ class CORE_EXPORT PaintLayerCompositor {
// to the native view/window system.
void SetCompositingModeEnabled(bool);
- bool RootShouldAlwaysComposite() const;
-
// Notifies about changes to PreferCompositingToLCDText or
// AcceleratedCompositing.
void UpdateAcceleratedCompositingSettings();
@@ -124,9 +119,8 @@ class CORE_EXPORT PaintLayerCompositor {
// swapped out for an overlay video or immersive-ar DOM overlay layer.
GraphicsLayer* PaintRootGraphicsLayer() const;
- static PaintLayerCompositor* FrameContentsCompositor(LayoutEmbeddedContent&);
- // Return true if the layers changed.
- static bool AttachFrameContentLayersToIframeLayer(LayoutEmbeddedContent&);
+ static PaintLayerCompositor* FrameContentsCompositor(
+ const LayoutEmbeddedContent&);
void UpdateTrackingRasterInvalidations();
@@ -137,6 +131,9 @@ class CORE_EXPORT PaintLayerCompositor {
// Whether the layer could ever be composited.
bool CanBeComposited(const PaintLayer*) const;
+ bool RootLayerAttachmentDirty() const { return root_layer_attachment_dirty_; }
+ void ClearRootLayerAttachmentDirty() { root_layer_attachment_dirty_ = false; }
+
// FIXME: Move allocateOrClearCompositedLayerMapping to
// CompositingLayerAssigner once we've fixed the compositing chicken/egg
// issues.
@@ -170,17 +167,12 @@ class CORE_EXPORT PaintLayerCompositor {
void UpdateIfNeeded(DocumentLifecycle::LifecycleState target_state,
CompositingReasonsStats&);
- void AttachRootLayer();
- void DetachRootLayer();
+ void SetOwnerNeedsCompositingUpdate();
Page* GetPage() const;
ScrollingCoordinator* GetScrollingCoordinator() const;
- void EnableCompositingModeIfNeeded();
-
- GraphicsLayer* OverlayFullscreenVideoGraphicsLayer() const;
-
// Checks the given graphics layer against the compositor's horizontal and
// vertical scrollbar graphics layers, returning the associated Scrollbar
// instance if any, else nullptr.
@@ -188,32 +180,15 @@ class CORE_EXPORT PaintLayerCompositor {
bool IsMainFrame() const;
- GraphicsLayer* GetXrOverlayLayer() const;
-
LayoutView& layout_view_;
bool compositing_ = false;
-
- // The root layer doesn't composite if it's a non-scrollable frame.
- // So, after a layout we set this dirty bit to know that we need
- // to recompute whether the root layer should composite even if
- // none of its descendants composite.
- // FIXME: Get rid of all the callers of SetCompositingModeEnabled()
- // except the one in UpdateIfNeeded(), then rename this to
- // compositing_dirty_.
- bool root_should_always_composite_dirty_ = true;
+ bool root_layer_attachment_dirty_ = false;
// After initialization, compositing updates must be done, so start dirty.
CompositingUpdateType pending_update_type_ =
kCompositingUpdateAfterCompositingInputChange;
- enum RootLayerAttachment {
- kRootLayerUnattached,
- kRootLayerAttachedViaEnclosingFrame,
- kRootLayerOfLocalFrameRoot // which doesn't need to attach to anything.
- };
- RootLayerAttachment root_layer_attachment_ = kRootLayerUnattached;
-
CompositingInputsRoot compositing_inputs_root_;
FRIEND_TEST_ALL_PREFIXES(FrameThrottlingTest,
diff --git a/chromium/third_party/blink/renderer/core/paint/custom_scrollbar_theme.cc b/chromium/third_party/blink/renderer/core/paint/custom_scrollbar_theme.cc
index 75934b0f5c3..0dc66be6b15 100644
--- a/chromium/third_party/blink/renderer/core/paint/custom_scrollbar_theme.cc
+++ b/chromium/third_party/blink/renderer/core/paint/custom_scrollbar_theme.cc
@@ -205,25 +205,7 @@ void CustomScrollbarTheme::PaintTickmarks(GraphicsContext& context,
void CustomScrollbarTheme::PaintIntoRect(
const LayoutCustomScrollbarPart& layout_custom_scrollbar_part,
GraphicsContext& graphics_context,
- const PhysicalOffset& paint_offset,
- const PhysicalRect& rect,
- const CustomScrollbar* scrollbar) {
- // Make sure our dimensions match the rect.
- // TODO(crbug.com/856802): Setting these is a bad layering violation!
- // Move these into layout stage.
- const_cast<LayoutCustomScrollbarPart&>(layout_custom_scrollbar_part)
- .SetLocation((rect.offset - paint_offset).ToLayoutPoint());
- const_cast<LayoutCustomScrollbarPart&>(layout_custom_scrollbar_part)
- .SetWidth(rect.size.width);
- const_cast<LayoutCustomScrollbarPart&>(layout_custom_scrollbar_part)
- .SetHeight(rect.size.height);
- // TODO(crbug.com/856802): Move this into PaintPropertyTreeBuilder.
- layout_custom_scrollbar_part.GetMutableForPainting()
- .FirstFragment()
- .SetPaintOffset((scrollbar ? PhysicalOffset(scrollbar->Location())
- : PhysicalOffset()) +
- layout_custom_scrollbar_part.PhysicalLocation());
-
+ const PhysicalRect& rect) {
PaintInfo paint_info(graphics_context, PixelSnappedIntRect(rect),
PaintPhase::kForeground, kGlobalPaintNormalPhase,
kPaintLayerNoFlag);
@@ -239,9 +221,7 @@ void CustomScrollbarTheme::PaintPart(GraphicsContext& context,
const auto* part_layout_object = custom_scrollbar.GetPart(part);
if (!part_layout_object)
return;
- PaintIntoRect(*part_layout_object, context,
- PhysicalOffset(custom_scrollbar.Location()), PhysicalRect(rect),
- &custom_scrollbar);
+ PaintIntoRect(*part_layout_object, context, PhysicalRect(rect));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/custom_scrollbar_theme.h b/chromium/third_party/blink/renderer/core/paint/custom_scrollbar_theme.h
index eecbdda3cd1..221d9d899a4 100644
--- a/chromium/third_party/blink/renderer/core/paint/custom_scrollbar_theme.h
+++ b/chromium/third_party/blink/renderer/core/paint/custom_scrollbar_theme.h
@@ -30,17 +30,16 @@
namespace blink {
-class CustomScrollbar;
class LayoutCustomScrollbarPart;
class WebMouseEvent;
-struct PhysicalOffset;
struct PhysicalRect;
class CustomScrollbarTheme final : public ScrollbarTheme {
public:
~CustomScrollbarTheme() override = default;
- int ScrollbarThickness(ScrollbarControlSize control_size) override {
+ int ScrollbarThickness(
+ ScrollbarControlSize control_size = kRegularScrollbar) override {
return GetTheme().ScrollbarThickness(control_size);
}
@@ -84,9 +83,7 @@ class CustomScrollbarTheme final : public ScrollbarTheme {
static void PaintIntoRect(const LayoutCustomScrollbarPart&,
GraphicsContext&,
- const PhysicalOffset& paint_offset,
- const PhysicalRect&,
- const CustomScrollbar* = nullptr);
+ const PhysicalRect&);
protected:
ScrollbarPart HitTest(const Scrollbar&, const IntPoint&) override;
diff --git a/chromium/third_party/blink/renderer/core/paint/decoration_info.h b/chromium/third_party/blink/renderer/core/paint/decoration_info.h
index 7da9c66328c..affebdf7cce 100644
--- a/chromium/third_party/blink/renderer/core/paint/decoration_info.h
+++ b/chromium/third_party/blink/renderer/core/paint/decoration_info.h
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -35,10 +36,9 @@ struct DecorationInfo final {
float baseline;
const ComputedStyle* style;
const SimpleFontData* font_data;
- float thickness;
- float double_offset;
FontBaseline baseline_type;
ResolvedUnderlinePosition underline_position;
+ Vector<float> applied_decorations_thickness;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/document_marker_painter.cc b/chromium/third_party/blink/renderer/core/paint/document_marker_painter.cc
index 0d0459e9d09..82079c00fac 100644
--- a/chromium/third_party/blink/renderer/core/paint/document_marker_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/document_marker_painter.cc
@@ -108,7 +108,7 @@ void DrawDocumentMarker(GraphicsContext& context,
#endif
const auto rect = SkRect::MakeWH(width, kMarkerHeight * zoom);
- const auto local_matrix = SkMatrix::MakeScale(zoom, zoom);
+ const auto local_matrix = SkMatrix::Scale(zoom, zoom);
PaintFlags flags;
flags.setAntiAlias(true);
@@ -126,18 +126,25 @@ void DrawDocumentMarker(GraphicsContext& context,
} // namespace
+bool DocumentMarkerPainter::ShouldPaintMarkerUnderline(
+ const StyleableMarker& marker) {
+ if (marker.HasThicknessNone() ||
+ (marker.UnderlineColor() == Color::kTransparent &&
+ !marker.UseTextColor()) ||
+ marker.UnderlineStyle() == ui::mojom::ImeTextSpanUnderlineStyle::kNone) {
+ return false;
+ }
+ return true;
+}
+
void DocumentMarkerPainter::PaintStyleableMarkerUnderline(
GraphicsContext& context,
const PhysicalOffset& box_origin,
const StyleableMarker& marker,
const ComputedStyle& style,
const FloatRect& marker_rect,
- LayoutUnit logical_height) {
- if (marker.HasThicknessNone() ||
- (marker.UnderlineColor() == Color::kTransparent &&
- !marker.UseTextColor()))
- return;
-
+ LayoutUnit logical_height,
+ bool in_dark_mode) {
// start of line to draw, relative to box_origin.X()
LayoutUnit start = LayoutUnit(marker_rect.X());
LayoutUnit width = LayoutUnit(marker_rect.Width());
@@ -165,7 +172,7 @@ void DocumentMarkerPainter::PaintStyleableMarkerUnderline(
}
Color marker_color =
- marker.UseTextColor()
+ (marker.UseTextColor() || in_dark_mode)
? style.VisitedDependentColor(GetCSSPropertyWebkitTextFillColor())
: marker.UnderlineColor();
if (marker.UnderlineStyle() !=
diff --git a/chromium/third_party/blink/renderer/core/paint/document_marker_painter.h b/chromium/third_party/blink/renderer/core/paint/document_marker_painter.h
index 6920657f1dc..9c23f50dec6 100644
--- a/chromium/third_party/blink/renderer/core/paint/document_marker_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/document_marker_painter.h
@@ -32,7 +32,8 @@ class DocumentMarkerPainter {
const StyleableMarker& marker,
const ComputedStyle& style,
const FloatRect& marker_rect,
- LayoutUnit logical_height);
+ LayoutUnit logical_height,
+ bool in_dark_mode);
static void PaintDocumentMarker(GraphicsContext& context,
const PhysicalOffset& box_origin,
const ComputedStyle& style,
@@ -41,6 +42,7 @@ class DocumentMarkerPainter {
static TextPaintStyle ComputeTextPaintStyleFrom(const ComputedStyle& style,
const TextMarkerBase& marker,
bool in_forced_colors_mode);
+ static bool ShouldPaintMarkerUnderline(const StyleableMarker& marker);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/fieldset_painter.cc b/chromium/third_party/blink/renderer/core/paint/fieldset_painter.cc
index e9f12e51372..c85f6937a0d 100644
--- a/chromium/third_party/blink/renderer/core/paint/fieldset_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/fieldset_painter.cc
@@ -44,6 +44,8 @@ void FieldsetPainter::PaintBoxDecorationBackground(
}
BoxDecorationData box_decoration_data(paint_info, layout_fieldset_);
+ // TODO(crbug.com/786475): Fieldset should not scroll.
+ DCHECK(!box_decoration_data.IsPaintingScrollingBackground());
if (box_decoration_data.ShouldPaint() &&
!DrawingRecorder::UseCachedDrawingIfPossible(
paint_info.context, layout_fieldset_, paint_info.phase)) {
diff --git a/chromium/third_party/blink/renderer/core/paint/filter_effect_builder.cc b/chromium/third_party/blink/renderer/core/paint/filter_effect_builder.cc
index 9c77e9224ab..ef7aa477af6 100644
--- a/chromium/third_party/blink/renderer/core/paint/filter_effect_builder.cc
+++ b/chromium/third_party/blink/renderer/core/paint/filter_effect_builder.cc
@@ -424,8 +424,7 @@ Filter* FilterEffectBuilder::BuildReferenceFilter(
return nullptr;
FloatRect filter_region =
SVGLengthContext::ResolveRectangle<SVGFilterElement>(
- filter_element,
- filter_element->filterUnits()->CurrentValue()->EnumValue(),
+ filter_element, filter_element->filterUnits()->CurrentEnumValue(),
reference_box_);
// TODO(fs): We rely on the presence of a node map here to opt-in to the
// check for an empty filter region. The reason for this is that we lack a
@@ -434,7 +433,7 @@ Filter* FilterEffectBuilder::BuildReferenceFilter(
return nullptr;
bool primitive_bounding_box_mode =
- filter_element->primitiveUnits()->CurrentValue()->EnumValue() ==
+ filter_element->primitiveUnits()->CurrentEnumValue() ==
SVGUnitTypes::kSvgUnitTypeObjectboundingbox;
Filter::UnitScaling unit_scaling =
primitive_bounding_box_mode ? Filter::kBoundingBox : Filter::kUserSpace;
diff --git a/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc b/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc
index 65743da01fe..69a02a1afe7 100644
--- a/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc
+++ b/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc
@@ -227,7 +227,7 @@ void FirstMeaningfulPaintDetector::SetTickClockForTesting(
g_clock = clock;
}
-void FirstMeaningfulPaintDetector::Trace(Visitor* visitor) {
+void FirstMeaningfulPaintDetector::Trace(Visitor* visitor) const {
visitor->Trace(paint_timing_);
}
diff --git a/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h b/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h
index f4314fb7f41..8f84a2695b7 100644
--- a/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h
+++ b/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h
@@ -47,7 +47,7 @@ class CORE_EXPORT FirstMeaningfulPaintDetector
// The caller owns the |clock| which must outlive the paint detector.
static void SetTickClockForTesting(const base::TickClock* clock);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
enum HadUserInput { kNoUserInput, kHadUserInput, kHadUserInputEnumMax };
diff --git a/chromium/third_party/blink/renderer/core/paint/html_canvas_painter.cc b/chromium/third_party/blink/renderer/core/paint/html_canvas_painter.cc
index 63a0cd08826..97562416956 100644
--- a/chromium/third_party/blink/renderer/core/paint/html_canvas_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/html_canvas_painter.cc
@@ -37,9 +37,11 @@ void HTMLCanvasPainter::PaintReplaced(const PaintInfo& paint_info,
paint_rect.Move(paint_offset);
auto* canvas = To<HTMLCanvasElement>(layout_html_canvas_.GetNode());
- canvas->UpdateFilterQuality();
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ bool flatten_composited_layers =
+ paint_info.GetGlobalPaintFlags() & kGlobalPaintFlattenCompositingLayers;
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+ !flatten_composited_layers) {
if (auto* layer = canvas->ContentsCcLayer()) {
IntRect pixel_snapped_rect = PixelSnappedIntRect(paint_rect);
layer->SetBounds(gfx::Size(pixel_snapped_rect.Size()));
@@ -59,9 +61,7 @@ void HTMLCanvasPainter::PaintReplaced(const PaintInfo& paint_info,
DrawingRecorder recorder(context, layout_html_canvas_, paint_info.phase);
ScopedInterpolationQuality interpolation_quality_scope(
context, InterpolationQualityForCanvas(layout_html_canvas_.StyleRef()));
- canvas->Paint(
- context, paint_rect,
- paint_info.GetGlobalPaintFlags() == kGlobalPaintFlattenCompositingLayers);
+ canvas->Paint(context, paint_rect, flatten_composited_layers);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc
index c3b20fb9d6d..89854cbe949 100644
--- a/chromium/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc
@@ -56,9 +56,8 @@ class HTMLCanvasPainterTestForCAP : public PaintControllerPaintTest {
std::unique_ptr<Canvas2DLayerBridge> MakeCanvas2DLayerBridge(
const IntSize& size) {
- return std::make_unique<Canvas2DLayerBridge>(
- size, Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams());
+ return std::make_unique<Canvas2DLayerBridge>(size, RasterMode::kGPU,
+ CanvasColorParams());
}
private:
diff --git a/chromium/third_party/blink/renderer/core/paint/image_element_timing.cc b/chromium/third_party/blink/renderer/core/paint/image_element_timing.cc
index 771c75aa95b..e99db9eafb8 100644
--- a/chromium/third_party/blink/renderer/core/paint/image_element_timing.cc
+++ b/chromium/third_party/blink/renderer/core/paint/image_element_timing.cc
@@ -260,7 +260,7 @@ void ImageElementTiming::NotifyImageRemoved(const LayoutObject* layout_object,
images_notified_.erase(std::make_pair(layout_object, image));
}
-void ImageElementTiming::Trace(Visitor* visitor) {
+void ImageElementTiming::Trace(Visitor* visitor) const {
visitor->Trace(element_timings_);
visitor->Trace(background_image_timestamps_);
Supplement<LocalDOMWindow>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/paint/image_element_timing.h b/chromium/third_party/blink/renderer/core/paint/image_element_timing.h
index 18db86a4047..71e07fb2235 100644
--- a/chromium/third_party/blink/renderer/core/paint/image_element_timing.h
+++ b/chromium/third_party/blink/renderer/core/paint/image_element_timing.h
@@ -63,7 +63,7 @@ class CORE_EXPORT ImageElementTiming final
void NotifyImageRemoved(const LayoutObject*,
const ImageResourceContent* image);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class ImageElementTimingTest;
@@ -98,7 +98,7 @@ class CORE_EXPORT ImageElementTiming final
element(element) {}
~ElementTimingInfo() = default;
- void Trace(Visitor* visitor) { visitor->Trace(element); }
+ void Trace(Visitor* visitor) const { visitor->Trace(element); }
String url;
FloatRect rect;
diff --git a/chromium/third_party/blink/renderer/core/paint/image_element_timing_test.cc b/chromium/third_party/blink/renderer/core/paint/image_element_timing_test.cc
index c39619a98a3..e9bdc18a44b 100644
--- a/chromium/third_party/blink/renderer/core/paint/image_element_timing_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/image_element_timing_test.cc
@@ -102,10 +102,10 @@ class ImageElementTimingTest : public testing::Test,
SkImageInfo::MakeN32Premul(width, height, src_rgb_color_space);
sk_sp<SkSurface> surface(SkSurface::MakeRaster(raster_image_info));
sk_sp<SkImage> image = surface->makeImageSnapshot();
- ImageResourceContent* original_image_resource =
+ ImageResourceContent* original_image_content =
ImageResourceContent::CreateLoaded(
UnacceleratedStaticBitmapImage::Create(image).get());
- return original_image_resource;
+ return original_image_content;
}
};
diff --git a/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc b/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
index c58112fd2e9..33d5293fc10 100644
--- a/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
+++ b/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
@@ -122,7 +122,9 @@ ImageRecord* ImagePaintTimingDetector::UpdateCandidate() {
PaintTimingDetector& detector = frame_view_->GetPaintTimingDetector();
// Two different candidates are rare to have the same time and size.
// So when they are unchanged, the candidate is considered unchanged.
- bool changed = detector.NotifyIfChangedLargestImagePaint(time, size);
+ bool changed = detector.NotifyIfChangedLargestImagePaint(
+ time, size, records_manager_.LargestRemovedImagePaintTime(),
+ records_manager_.LargestRemovedImageSize());
if (changed) {
if (!time.is_null()) {
DCHECK(largest_image_record->loaded);
@@ -341,11 +343,11 @@ ImageRecord* ImageRecordsManager::FindLargestPaintCandidate() const {
return size_ordered_set_.begin()->get();
}
-void ImageRecordsManager::Trace(Visitor* visitor) {
+void ImageRecordsManager::Trace(Visitor* visitor) const {
visitor->Trace(frame_view_);
}
-void ImagePaintTimingDetector::Trace(Visitor* visitor) {
+void ImagePaintTimingDetector::Trace(Visitor* visitor) const {
visitor->Trace(records_manager_);
visitor->Trace(frame_view_);
visitor->Trace(callback_manager_);
diff --git a/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.h b/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.h
index 2e9b233ff9b..82d1621e321 100644
--- a/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.h
+++ b/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.h
@@ -85,6 +85,18 @@ class CORE_EXPORT ImageRecordsManager {
inline void RemoveVisibleRecord(const RecordId& record_id) {
base::WeakPtr<ImageRecord> record =
visible_images_.find(record_id)->value->AsWeakPtr();
+ if (!record->paint_time.is_null()) {
+ DCHECK_GT(record->first_size, 0u);
+ if (record->first_size > largest_removed_image_size_) {
+ largest_removed_image_size_ = record->first_size;
+ largest_removed_image_paint_time_ = record->paint_time;
+ } else if (record->first_size == largest_removed_image_size_) {
+ // Ensure we use the lower timestamp in the case of a tie.
+ DCHECK(!largest_removed_image_paint_time_.is_null());
+ largest_removed_image_paint_time_ =
+ std::min(largest_removed_image_paint_time_, record->paint_time);
+ }
+ }
size_ordered_set_.erase(record);
visible_images_.erase(record_id);
// Leave out |images_queued_for_paint_time_| intentionally because the null
@@ -142,7 +154,14 @@ class CORE_EXPORT ImageRecordsManager {
return images_queued_for_paint_time_.back()->frame_index;
}
- void Trace(Visitor* visitor);
+ uint64_t LargestRemovedImageSize() const {
+ return largest_removed_image_size_;
+ }
+ base::TimeTicks LargestRemovedImagePaintTime() const {
+ return largest_removed_image_paint_time_;
+ }
+
+ void Trace(Visitor* visitor) const;
private:
// Find the image record of an visible image.
@@ -178,6 +197,11 @@ class CORE_EXPORT ImageRecordsManager {
Member<LocalFrameView> frame_view_;
+ // We store the size and paint time of the largest removed image in order to
+ // compute experimental LCP correctly.
+ uint64_t largest_removed_image_size_ = 0u;
+ base::TimeTicks largest_removed_image_paint_time_;
+
DISALLOW_COPY_AND_ASSIGN(ImageRecordsManager);
};
@@ -239,7 +263,7 @@ class CORE_EXPORT ImagePaintTimingDetector final
// Return the candidate.
ImageRecord* UpdateCandidate();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
friend class LargestContentfulPaintCalculatorTest;
diff --git a/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc b/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc
index 4ed10990516..ff6a7ea2d0c 100644
--- a/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc
@@ -33,12 +33,12 @@
namespace blink {
-#define SIMPLE_IMAGE \
- "url(data:image/gif;base64," \
- "R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)"
+#define SIMPLE_IMAGE \
+ "data:image/gif;base64," \
+ "R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
#define LARGE_IMAGE \
- "url(data:image/gif;base64," \
+ "data:image/gif;base64," \
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSF" \
"lzAAAN1wAADdcBQiibeAAAAb5JREFUOMulkr1KA0EQgGdvTwwnYmER0gQsrFKmSy+pLESw9Qm0" \
"F/ICNnba+h6iEOuAEWslKJKTOyJJvIT72d1xZuOFC0giOLA77O7Mt/PnNptN+I+49Xr9GhH3f3" \
@@ -48,7 +48,7 @@ namespace blink {
"Ign+2BsVA8jVYuWlgJ3yBj0icgq2uoK+lg4t+ZvLomSKamSQ4AI5BcMADtMhyNoSgNIISUaFNt" \
"wlazcDcBc4gjjVwCWid2usCWroYEhnaqbzFJLUzAHIXRDChXCcQP8zhkSZ5eNLgHAUzwDcRu4C" \
"oIRn/wsGUQIIy4Vr9TH6SYFCNzw4nALn5627K4vIttOUOwfa5YnrDYzt/9OLv9I5l8kk5hZ3XL" \
- "O20b7tbR7zHLy/BX8G0IeBEM7ZN1NGIaFUaKLgAAAAAElFTkSuQmCC)"
+ "O20b7tbR7zHLy/BX8G0IeBEM7ZN1NGIaFUaKLgAAAAAElFTkSuQmCC"
class ImagePaintTimingDetectorTest : public testing::Test,
public PaintTestConfigurations {
@@ -158,10 +158,22 @@ class ImagePaintTimingDetectorTest : public testing::Test,
GetPaintTimingDetector().GetImagePaintTimingDetector()->UpdateCandidate();
}
- base::TimeTicks LargestPaintStoredResult() {
+ base::TimeTicks LargestPaintTime() {
return GetPaintTimingDetector().largest_image_paint_time_;
}
+ uint64_t LargestPaintSize() {
+ return GetPaintTimingDetector().largest_image_paint_size_;
+ }
+
+ base::TimeTicks ExperimentalLargestPaintTime() {
+ return GetPaintTimingDetector().experimental_largest_image_paint_time_;
+ }
+
+ uint64_t ExperimentalLargestPaintSize() {
+ return GetPaintTimingDetector().experimental_largest_image_paint_size_;
+ }
+
static constexpr base::TimeDelta kQuantumOfTime =
base::TimeDelta::FromMilliseconds(10);
@@ -236,14 +248,6 @@ class ImagePaintTimingDetectorTest : public testing::Test,
To<HTMLImageElement>(element)->SetImageForTest(content);
}
- void SetVideoImageAndPaint(AtomicString id, int width, int height) {
- Element* element = GetDocument().getElementById(id);
- DCHECK(element);
- // Set image and make it loaded.
- ImageResourceContent* content = CreateImageForTest(width, height);
- To<HTMLVideoElement>(element)->SetImageForTest(content);
- }
-
void SetSVGImageAndPaint(AtomicString id, int width, int height) {
Element* element = GetDocument().getElementById(id);
// Set image and make it loaded.
@@ -275,10 +279,10 @@ class ImagePaintTimingDetectorTest : public testing::Test,
SkImageInfo::MakeN32Premul(width, height, src_rgb_color_space);
sk_sp<SkSurface> surface(SkSurface::MakeRaster(raster_image_info));
sk_sp<SkImage> image = surface->makeImageSnapshot();
- ImageResourceContent* original_image_resource =
+ ImageResourceContent* original_image_content =
ImageResourceContent::CreateLoaded(
UnacceleratedStaticBitmapImage::Create(image).get());
- return original_image_resource;
+ return original_image_content;
}
PaintTimingCallbackManager::CallbackQueue callback_queue_;
@@ -296,6 +300,8 @@ TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_NoImage) {
)HTML");
ImageRecord* record = FindLargestPaintCandidate();
EXPECT_FALSE(record);
+ EXPECT_EQ(ExperimentalLargestPaintTime(), base::TimeTicks());
+ EXPECT_EQ(ExperimentalLargestPaintSize(), 0ul);
}
TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_OneImage) {
@@ -308,6 +314,7 @@ TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_OneImage) {
EXPECT_TRUE(record);
EXPECT_EQ(record->first_size, 25ul);
EXPECT_TRUE(record->loaded);
+ EXPECT_EQ(ExperimentalLargestPaintSize(), 25ul);
}
TEST_P(ImagePaintTimingDetectorTest, InsertionOrderIsSecondaryRankingKey) {
@@ -333,6 +340,7 @@ TEST_P(ImagePaintTimingDetectorTest, InsertionOrderIsSecondaryRankingKey) {
EXPECT_EQ(FindLargestPaintCandidate()->node_id,
DOMNodeIds::ExistingIdForNode(image1));
+ EXPECT_EQ(ExperimentalLargestPaintSize(), 25ul);
}
TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_TraceEvent_Candidate) {
@@ -387,6 +395,8 @@ TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_TraceEvent_NoCandidate) {
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
GetDocument().getElementById("target")->remove();
UpdateAllLifecyclePhases();
+ // Experimental size still 25, not affected by removal.
+ EXPECT_EQ(ExperimentalLargestPaintSize(), 25ul);
}
auto analyzer = trace_analyzer::Stop();
trace_analyzer::TraceEventVector events;
@@ -429,6 +439,8 @@ TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_TraceEvent_NoCandidate) {
TEST_P(ImagePaintTimingDetectorTest, UpdatePerformanceTiming) {
EXPECT_EQ(GetPerformanceTiming().LargestImagePaintSize(), 0u);
EXPECT_EQ(GetPerformanceTiming().LargestImagePaint(), 0u);
+ EXPECT_EQ(GetPerformanceTiming().ExperimentalLargestImagePaintSize(), 0u);
+ EXPECT_EQ(GetPerformanceTiming().ExperimentalLargestImagePaint(), 0u);
SetBodyInnerHTML(R"HTML(
<img id="target"></img>
)HTML");
@@ -436,12 +448,16 @@ TEST_P(ImagePaintTimingDetectorTest, UpdatePerformanceTiming) {
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
EXPECT_EQ(GetPerformanceTiming().LargestImagePaintSize(), 25u);
EXPECT_GT(GetPerformanceTiming().LargestImagePaint(), 0u);
+ EXPECT_EQ(GetPerformanceTiming().ExperimentalLargestImagePaintSize(), 25u);
+ EXPECT_GT(GetPerformanceTiming().ExperimentalLargestImagePaint(), 0u);
}
TEST_P(ImagePaintTimingDetectorTest,
PerformanceTimingHasZeroTimeNonZeroSizeWhenTheLargestIsNotPainted) {
EXPECT_EQ(GetPerformanceTiming().LargestImagePaintSize(), 0u);
EXPECT_EQ(GetPerformanceTiming().LargestImagePaint(), 0u);
+ EXPECT_EQ(GetPerformanceTiming().ExperimentalLargestImagePaintSize(), 0u);
+ EXPECT_EQ(GetPerformanceTiming().ExperimentalLargestImagePaint(), 0u);
SetBodyInnerHTML(R"HTML(
<img id="target"></img>
)HTML");
@@ -449,6 +465,8 @@ TEST_P(ImagePaintTimingDetectorTest,
UpdateAllLifecyclePhases();
EXPECT_EQ(GetPerformanceTiming().LargestImagePaintSize(), 25u);
EXPECT_EQ(GetPerformanceTiming().LargestImagePaint(), 0u);
+ EXPECT_EQ(GetPerformanceTiming().ExperimentalLargestImagePaintSize(), 25u);
+ EXPECT_EQ(GetPerformanceTiming().ExperimentalLargestImagePaint(), 0u);
}
TEST_P(ImagePaintTimingDetectorTest, UpdatePerformanceTimingToZero) {
@@ -459,10 +477,15 @@ TEST_P(ImagePaintTimingDetectorTest, UpdatePerformanceTimingToZero) {
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
EXPECT_EQ(GetPerformanceTiming().LargestImagePaintSize(), 25u);
EXPECT_GT(GetPerformanceTiming().LargestImagePaint(), 0u);
+ EXPECT_EQ(GetPerformanceTiming().ExperimentalLargestImagePaintSize(), 25u);
+ EXPECT_GT(GetPerformanceTiming().ExperimentalLargestImagePaint(), 0u);
GetDocument().body()->RemoveChild(GetDocument().getElementById("target"));
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
EXPECT_EQ(GetPerformanceTiming().LargestImagePaintSize(), 0u);
EXPECT_EQ(GetPerformanceTiming().LargestImagePaint(), 0u);
+ // Experimental values are not reset.
+ EXPECT_EQ(GetPerformanceTiming().ExperimentalLargestImagePaintSize(), 25u);
+ EXPECT_GT(GetPerformanceTiming().ExperimentalLargestImagePaint(), 0u);
}
TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_OpacityZero) {
@@ -559,6 +582,8 @@ TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_Largest) {
SetImageAndPaint("larger", 9, 9);
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
+ EXPECT_EQ(LargestPaintSize(), 81ul);
+ EXPECT_EQ(ExperimentalLargestPaintSize(), 81ul);
}
TEST_P(ImagePaintTimingDetectorTest,
@@ -590,14 +615,21 @@ TEST_P(ImagePaintTimingDetectorTest,
ImageRecord* record;
record = FindLargestPaintCandidate();
EXPECT_TRUE(record);
- EXPECT_NE(LargestPaintStoredResult(), base::TimeTicks());
+ EXPECT_NE(LargestPaintTime(), base::TimeTicks());
+ EXPECT_EQ(LargestPaintSize(), 25ul);
+ EXPECT_NE(ExperimentalLargestPaintTime(), base::TimeTicks());
+ EXPECT_EQ(ExperimentalLargestPaintSize(), 25ul);
GetDocument().getElementById("parent")->RemoveChild(
GetDocument().getElementById("target"));
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
record = FindLargestPaintCandidate();
EXPECT_FALSE(record);
- EXPECT_EQ(LargestPaintStoredResult(), base::TimeTicks());
+ EXPECT_EQ(LargestPaintTime(), base::TimeTicks());
+ EXPECT_EQ(LargestPaintSize(), 0u);
+ // Experimental values not reset after removal.
+ EXPECT_NE(ExperimentalLargestPaintTime(), base::TimeTicks());
+ EXPECT_EQ(ExperimentalLargestPaintSize(), 25ul);
}
TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_UpdateOnRemoving) {
@@ -611,15 +643,15 @@ TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_UpdateOnRemoving) {
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
ImageRecord* record1 = FindLargestPaintCandidate();
EXPECT_TRUE(record1);
- EXPECT_NE(LargestPaintStoredResult(), base::TimeTicks());
- base::TimeTicks first_largest_image_paint = LargestPaintStoredResult();
+ EXPECT_NE(LargestPaintTime(), base::TimeTicks());
+ base::TimeTicks first_largest_image_paint = LargestPaintTime();
SetImageAndPaint("target2", 10, 10);
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
ImageRecord* record2 = FindLargestPaintCandidate();
EXPECT_TRUE(record2);
- EXPECT_NE(LargestPaintStoredResult(), base::TimeTicks());
- base::TimeTicks second_largest_image_paint = LargestPaintStoredResult();
+ EXPECT_NE(LargestPaintTime(), base::TimeTicks());
+ base::TimeTicks second_largest_image_paint = LargestPaintTime();
EXPECT_NE(record1, record2);
EXPECT_NE(first_largest_image_paint, second_largest_image_paint);
@@ -629,7 +661,10 @@ TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_UpdateOnRemoving) {
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
ImageRecord* record1_2 = FindLargestPaintCandidate();
EXPECT_EQ(record1, record1_2);
- EXPECT_EQ(first_largest_image_paint, LargestPaintStoredResult());
+ EXPECT_EQ(first_largest_image_paint, LargestPaintTime());
+ EXPECT_EQ(LargestPaintSize(), 25u);
+ EXPECT_EQ(second_largest_image_paint, ExperimentalLargestPaintTime());
+ EXPECT_EQ(ExperimentalLargestPaintSize(), 100u);
}
TEST_P(ImagePaintTimingDetectorTest,
@@ -706,7 +741,7 @@ TEST_P(ImagePaintTimingDetectorTest,
SetBodyInnerHTML(R"HTML(
<style>
#target {
- background-image: )HTML" SIMPLE_IMAGE R"HTML(;
+ background-image: url()HTML" SIMPLE_IMAGE R"HTML();
}
</style>
<div id="parent">
@@ -824,16 +859,18 @@ TEST_P(ImagePaintTimingDetectorTest,
SetImageAndPaint("target1", 5, 5);
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
base::TimeTicks time2 = test_task_runner_->NowTicks();
- base::TimeTicks result1 = LargestPaintStoredResult();
+ base::TimeTicks result1 = LargestPaintTime();
EXPECT_GE(result1, time1);
EXPECT_GE(time2, result1);
+ EXPECT_EQ(result1, ExperimentalLargestPaintTime());
SetImageAndPaint("target2", 10, 10);
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
base::TimeTicks time3 = test_task_runner_->NowTicks();
- base::TimeTicks result2 = LargestPaintStoredResult();
+ base::TimeTicks result2 = LargestPaintTime();
EXPECT_GE(result2, time2);
EXPECT_GE(time3, result2);
+ EXPECT_EQ(result2, ExperimentalLargestPaintTime());
}
TEST_P(ImagePaintTimingDetectorTest, OneSwapPromiseForOneFrame) {
@@ -870,11 +907,9 @@ TEST_P(ImagePaintTimingDetectorTest, OneSwapPromiseForOneFrame) {
TEST_P(ImagePaintTimingDetectorTest, VideoImage) {
SetBodyInnerHTML(R"HTML(
- <video id="target"></video>
+ <video id="target" poster=")HTML" LARGE_IMAGE R"HTML("></video>
)HTML");
- SetVideoImageAndPaint("target", 5, 5);
-
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
ImageRecord* record = FindLargestPaintCandidate();
EXPECT_TRUE(record);
@@ -910,7 +945,7 @@ TEST_P(ImagePaintTimingDetectorTest, BackgroundImage) {
SetBodyInnerHTML(R"HTML(
<style>
div {
- background-image: )HTML" SIMPLE_IMAGE R"HTML(;
+ background-image: url()HTML" SIMPLE_IMAGE R"HTML();
}
</style>
<div>place-holder</div>
@@ -925,7 +960,7 @@ TEST_P(ImagePaintTimingDetectorTest,
SetBodyInnerHTML(R"HTML(
<style>
img {
- background-image: )HTML" LARGE_IMAGE R"HTML(;
+ background-image: url()HTML" LARGE_IMAGE R"HTML();
}
</style>
<img id="target">
@@ -941,12 +976,14 @@ TEST_P(ImagePaintTimingDetectorTest,
}
TEST_P(ImagePaintTimingDetectorTest, BackgroundImage_IgnoreBody) {
- SetBodyInnerHTML("<style>body { background-image: " SIMPLE_IMAGE "}</style>");
+ SetBodyInnerHTML("<style>body { background-image: url(" SIMPLE_IMAGE
+ ")}</style>");
EXPECT_EQ(CountVisibleImageRecords(), 0u);
}
TEST_P(ImagePaintTimingDetectorTest, BackgroundImage_IgnoreHtml) {
- SetBodyInnerHTML("<style>html { background-image: " SIMPLE_IMAGE "}</style>");
+ SetBodyInnerHTML("<style>html { background-image: url(" SIMPLE_IMAGE
+ ")}</style>");
EXPECT_EQ(CountVisibleImageRecords(), 0u);
}
@@ -973,7 +1010,7 @@ TEST_P(ImagePaintTimingDetectorTest, BackgroundImageTrackedDifferently) {
width: 50px;
height: 50px;
background-image:
- )HTML" SIMPLE_IMAGE "," LARGE_IMAGE R"HTML(;
+ url()HTML" SIMPLE_IMAGE "), url(" LARGE_IMAGE R"HTML();
}
</style>
<div id="d"></div>
@@ -1118,7 +1155,7 @@ TEST_P(ImagePaintTimingDetectorTest,
#d {
width: 50px;
height: 50px;
- background-image: )HTML" SIMPLE_IMAGE R"HTML(;
+ background-image: url()HTML" SIMPLE_IMAGE R"HTML();
}
</style>
<div id="d"></div>
@@ -1136,7 +1173,7 @@ TEST_P(ImagePaintTimingDetectorTest,
#d {
width: 5px;
height: 5px;
- background-image: )HTML" LARGE_IMAGE R"HTML(;
+ background-image: url()HTML" LARGE_IMAGE R"HTML();
}
</style>
<div id="d"></div>
diff --git a/chromium/third_party/blink/renderer/core/paint/image_painter.cc b/chromium/third_party/blink/renderer/core/paint/image_painter.cc
index 6436abe2bb9..39b384a8670 100644
--- a/chromium/third_party/blink/renderer/core/paint/image_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/image_painter.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/html_area_element.h"
#include "third_party/blink/renderer/core/html/html_image_element.h"
@@ -40,7 +41,7 @@ bool CheckForOversizedImagesPolicy(const LayoutImage& layout_image,
scoped_refptr<Image> image) {
DCHECK(image);
if (!RuntimeEnabledFeatures::UnoptimizedImagePoliciesEnabled(
- &layout_image.GetDocument()))
+ layout_image.GetDocument().GetExecutionContext()))
return false;
DoubleSize layout_size(layout_image.ContentSize());
@@ -60,7 +61,7 @@ bool CheckForOversizedImagesPolicy(const LayoutImage& layout_image,
const String& image_url =
cached_image ? cached_image->Url().GetString() : g_empty_string;
- return !layout_image.GetDocument().IsFeatureEnabled(
+ return !layout_image.GetDocument().domWindow()->IsFeatureEnabled(
mojom::blink::DocumentPolicyFeature::kOversizedImages,
blink::PolicyValue(
std::max(downscale_ratio_width, downscale_ratio_height),
diff --git a/chromium/third_party/blink/renderer/core/paint/inline_text_box_painter.cc b/chromium/third_party/blink/renderer/core/paint/inline_text_box_painter.cc
index 065c32ba2e8..73f689d1ed7 100644
--- a/chromium/third_party/blink/renderer/core/paint/inline_text_box_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/inline_text_box_painter.cc
@@ -618,7 +618,8 @@ void InlineTextBoxPainter::PaintDocumentMarkers(
paint_info.context, box_origin, style, font,
styleable_marker.BackgroundColor(), marker_offsets.start,
marker_offsets.end);
- } else {
+ } else if (DocumentMarkerPainter::ShouldPaintMarkerUnderline(
+ styleable_marker)) {
PaintStyleableMarkerUnderline(paint_info.context, box_origin,
styleable_marker, style, font);
}
@@ -826,7 +827,8 @@ void InlineTextBoxPainter::PaintStyleableMarkerUnderline(
run, FloatPoint(), 0, marker_offsets.start, marker_offsets.end);
DocumentMarkerPainter::PaintStyleableMarkerUnderline(
context, PhysicalOffsetToBeNoop(box_origin), marker, style, marker_rect,
- inline_text_box_.LogicalHeight());
+ inline_text_box_.LogicalHeight(),
+ inline_text_box_.GetLineLayoutItem().GetDocument().InDarkMode());
}
void InlineTextBoxPainter::PaintTextMarkerForeground(
diff --git a/chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.cc b/chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.cc
index dd110c79c0b..f09faa6c209 100644
--- a/chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.cc
+++ b/chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.cc
@@ -188,7 +188,7 @@ void LargestContentfulPaintCalculator::UpdateLargestContentfulPaint(
}
}
-void LargestContentfulPaintCalculator::Trace(Visitor* visitor) {
+void LargestContentfulPaintCalculator::Trace(Visitor* visitor) const {
visitor->Trace(window_performance_);
}
diff --git a/chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.h b/chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.h
index 45d35a591a0..e4165114a7a 100644
--- a/chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.h
+++ b/chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.h
@@ -23,7 +23,7 @@ class CORE_EXPORT LargestContentfulPaintCalculator final
base::Optional<base::WeakPtr<TextRecord>> largest_text,
base::Optional<const ImageRecord*> largest_image);
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
private:
friend class LargestContentfulPaintCalculatorTest;
diff --git a/chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator_test.cc b/chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator_test.cc
index e381d016fd8..8d465e6fa60 100644
--- a/chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator_test.cc
@@ -60,10 +60,10 @@ class LargestContentfulPaintCalculatorTest : public RenderingTest {
SkImageInfo::MakeN32Premul(width, height, src_rgb_color_space);
sk_sp<SkSurface> surface(SkSurface::MakeRaster(raster_image_info));
sk_sp<SkImage> image = surface->makeImageSnapshot();
- ImageResourceContent* original_image_resource =
+ ImageResourceContent* original_image_content =
ImageResourceContent::CreateLoaded(
UnacceleratedStaticBitmapImage::Create(image).get());
- return original_image_resource;
+ return original_image_content;
}
LargestContentType LastReportedType() {
diff --git a/chromium/third_party/blink/renderer/core/paint/line_box_list_painter.cc b/chromium/third_party/blink/renderer/core/paint/line_box_list_painter.cc
index 7717975490b..46b375c630a 100644
--- a/chromium/third_party/blink/renderer/core/paint/line_box_list_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/line_box_list_painter.cc
@@ -163,7 +163,8 @@ void LineBoxListPainter::PaintBackplate(
DrawingRecorder recorder(paint_info.context, layout_object,
DisplayItem::kForcedColorsModeBackplate);
- Color backplate_color = style.ForcedBackplateColor();
+ Color backplate_color =
+ layout_object.GetDocument().GetStyleEngine().ForcedBackgroundColor();
const auto& backplates = GetBackplates(paint_offset);
for (const auto backplate : backplates)
paint_info.context.FillRect(FloatRect(backplate), backplate_color);
diff --git a/chromium/third_party/blink/renderer/core/paint/list_marker_painter.cc b/chromium/third_party/blink/renderer/core/paint/list_marker_painter.cc
index 129ae0e73ca..3bc67a67f39 100644
--- a/chromium/third_party/blink/renderer/core/paint/list_marker_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/list_marker_painter.cc
@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/core/paint/list_marker_painter.h"
#include "third_party/blink/renderer/core/layout/layout_list_item.h"
-#include "third_party/blink/renderer/core/layout/layout_list_marker.h"
+#include "third_party/blink/renderer/core/layout/list_marker.h"
#include "third_party/blink/renderer/core/layout/list_marker_text.h"
#include "third_party/blink/renderer/core/paint/box_model_object_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
@@ -93,12 +93,12 @@ void ListMarkerPainter::Paint(const PaintInfo& paint_info) {
return;
}
- LayoutListMarker::ListStyleCategory style_category =
+ ListMarker::ListStyleCategory style_category =
layout_list_marker_.GetListStyleCategory();
- if (style_category == LayoutListMarker::ListStyleCategory::kNone)
+ if (style_category == ListMarker::ListStyleCategory::kNone)
return;
- if (style_category == LayoutListMarker::ListStyleCategory::kSymbol) {
+ if (style_category == ListMarker::ListStyleCategory::kSymbol) {
PaintSymbol(paint_info, &layout_list_marker_,
layout_list_marker_.StyleRef(), PixelSnappedIntRect(marker));
return;
@@ -156,7 +156,7 @@ void ListMarkerPainter::Paint(const PaintInfo& paint_info) {
text_run.SetText(reversed_text.ToString());
}
- if (style_category == LayoutListMarker::ListStyleCategory::kStaticString) {
+ if (style_category == ListMarker::ListStyleCategory::kStaticString) {
// Don't add a suffix.
context.DrawText(font, text_run_paint_info, text_origin, kInvalidDOMNodeId);
context.GetPaintController().SetTextPainted();
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
index 61f9f6343f7..2be39a801ef 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -67,8 +67,25 @@ inline bool HasSelection(const LayoutObject* layout_object) {
inline bool IsVisibleToPaint(const NGPhysicalFragment& fragment,
const ComputedStyle& style) {
- return !fragment.IsHiddenForPaint() &&
- style.Visibility() == EVisibility::kVisible;
+ if (fragment.IsHiddenForPaint() ||
+ style.Visibility() != EVisibility::kVisible)
+ return false;
+
+ // When |NGLineTruncator| sets |IsHiddenForPaint|, it sets to the fragment in
+ // the line. However, when it has self-painting layer, the fragment stored in
+ // |LayoutBlockFlow| will be painted. Check |IsHiddenForPaint| of the fragment
+ // in the inline formatting context.
+ if (UNLIKELY(fragment.IsAtomicInline() && fragment.HasSelfPaintingLayer())) {
+ const LayoutObject* layout_object = fragment.GetLayoutObject();
+ if (layout_object->IsInLayoutNGInlineFormattingContext()) {
+ NGInlineCursor cursor;
+ cursor.MoveTo(*layout_object);
+ if (cursor && cursor.Current().IsHiddenForPaint())
+ return false;
+ }
+ }
+
+ return true;
}
inline bool IsVisibleToPaint(const NGFragmentItem& item,
@@ -108,6 +125,11 @@ bool HitTestCulledInlineAncestors(
const HitTestLocation& hit_test_location,
const PhysicalOffset fallback_accumulated_offset) {
DCHECK(current != limit && current->IsDescendantOf(limit));
+
+ // Check ancestors only when |current| is the first fragment in this line.
+ if (previous_sibling && current == previous_sibling.GetLayoutObject())
+ return false;
+
for (LayoutObject* parent = current->Parent(); parent && parent != limit;
current = parent, parent = parent->Parent()) {
// |culled_parent| is a culled inline element to be hit tested, since it's
@@ -410,6 +432,9 @@ void NGBoxFragmentPainter::PaintInternal(const PaintInfo& paint_info) {
if (original_phase != PaintPhase::kSelfBlockBackgroundOnly &&
original_phase != PaintPhase::kSelfOutlineOnly &&
+ // For now all scrollers with overlay overflow controls are
+ // self-painting layers, so we don't need to traverse descendants
+ // here.
original_phase != PaintPhase::kOverlayOverflowControls) {
if (original_phase == PaintPhase::kMask ||
!box_fragment_.GetLayoutObject()->IsBox()) {
@@ -422,6 +447,26 @@ void NGBoxFragmentPainter::PaintInternal(const PaintInfo& paint_info) {
}
}
+ // If the caret's node's fragment's containing block is this block, and
+ // the paint action is PaintPhaseForeground, then paint the caret.
+ if (original_phase == PaintPhase::kForeground &&
+ box_fragment_.ShouldPaintCarets()) {
+ // Apply overflow clip if needed.
+ // reveal-caret-of-multiline-contenteditable.html needs this.
+ // TDOO(yoisn): We should share this code with |BlockPainter::Paint()|
+ base::Optional<ScopedPaintChunkProperties> paint_chunk_properties;
+ if (const auto* fragment = paint_state.FragmentToPaint()) {
+ if (const auto* properties = fragment->PaintProperties()) {
+ if (const auto* overflow_clip = properties->OverflowClip()) {
+ paint_chunk_properties.emplace(
+ paint_info.context.GetPaintController(), *overflow_clip,
+ *box_fragment_.GetLayoutObject(), DisplayItem::kCaret);
+ }
+ }
+ }
+ PaintCarets(paint_info, paint_offset);
+ }
+
if (ShouldPaintSelfOutline(original_phase)) {
info.phase = PaintPhase::kSelfOutlineOnly;
PaintObject(info, paint_offset);
@@ -488,8 +533,8 @@ void NGBoxFragmentPainter::PaintObject(
NGFragmentPainter(box_fragment_, GetDisplayItemClient())
.AddURLRectIfNeeded(paint_info, paint_offset);
}
- if (is_visible && box_fragment_.IsMathMLFraction())
- NGMathMLPainter(box_fragment_).PaintFractionBar(paint_info, paint_offset);
+ if (is_visible && box_fragment_.HasExtraMathMLPainting())
+ NGMathMLPainter(box_fragment_).Paint(paint_info, paint_offset);
}
if (paint_phase != PaintPhase::kSelfOutlineOnly &&
@@ -555,12 +600,6 @@ void NGBoxFragmentPainter::PaintObject(
NGFragmentPainter(box_fragment_, GetDisplayItemClient())
.PaintOutline(paint_info, paint_offset);
}
-
- // If the caret's node's fragment's containing block is this block, and
- // the paint action is PaintPhaseForeground, then paint the caret.
- if (paint_phase == PaintPhase::kForeground &&
- physical_box_fragment.ShouldPaintCarets())
- PaintCarets(paint_info, paint_offset);
}
void NGBoxFragmentPainter::PaintCarets(const PaintInfo& paint_info,
@@ -641,7 +680,7 @@ void NGBoxFragmentPainter::PaintBlockChildren(const PaintInfo& paint_info,
// that assumes that we have a LayoutObject (and FragmentData).
PhysicalOffset child_offset = paint_offset + child.offset;
- if (box_child_fragment.IsColumnBox()) {
+ if (box_child_fragment.IsFragmentainerBox()) {
// This is a fragmentainer, and when node inside a fragmentation
// context paints multiple block fragments, we need to distinguish
// between them somehow, for paint caching to work. Therefore,
@@ -789,7 +828,7 @@ void NGBoxFragmentPainter::PaintFloatingChildren(
continue;
}
- if (child_container->IsColumnBox()) {
+ if (child_container->IsFragmentainerBox()) {
// This is a fragmentainer, and when node inside a fragmentation context
// paints multiple block fragments, we need to distinguish between them
// somehow, for paint caching to work. Therefore, establish a display item
@@ -909,7 +948,7 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackground(
// composited in PaintArtifactCompositor::UpdateNonFastScrollableRegions.
const auto* layer = PhysicalFragment().Layer();
if (layer && layer->GetCompositedLayerMapping() &&
- layer->GetCompositedLayerMapping()->HasScrollingLayer()) {
+ layer->GetCompositedLayerMapping()->ScrollingContentsLayer()) {
needs_scroll_hit_test = false;
}
}
@@ -1235,6 +1274,13 @@ void NGBoxFragmentPainter::PaintInlineItems(const PaintInfo& paint_info,
while (*cursor) {
const NGFragmentItem* item = cursor->CurrentItem();
DCHECK(item);
+ if (UNLIKELY(item->IsLayoutObjectDestroyedOrMoved())) {
+ // TODO(crbug.com/1099613): This should not happen, as long as it is
+ // really layout-clean.
+ NOTREACHED();
+ cursor->MoveToNextSkippingChildren();
+ continue;
+ }
switch (item->Type()) {
case NGFragmentItem::kText:
case NGFragmentItem::kGeneratedText:
@@ -1262,19 +1308,27 @@ inline void NGBoxFragmentPainter::PaintLineBox(
const DisplayItemClient& display_item_client,
const NGPaintFragment* line_box_paint_fragment,
const NGFragmentItem* line_box_item,
+ wtf_size_t line_fragment_id,
const PaintInfo& paint_info,
const PhysicalOffset& child_offset) {
if (paint_info.phase != PaintPhase::kForeground)
return;
+ base::Optional<ScopedDisplayItemFragment> display_item_fragment;
if (ShouldRecordHitTestData(paint_info)) {
+ if (line_box_item)
+ display_item_fragment.emplace(paint_info.context, line_fragment_id);
PhysicalRect border_box = line_box_fragment.LocalRect();
border_box.offset += child_offset;
paint_info.context.GetPaintController().RecordHitTestData(
display_item_client, PixelSnappedIntRect(border_box),
PhysicalFragment().EffectiveAllowedTouchAction());
}
+
+ // Paint the background of the `::first-line` line box.
if (NGLineBoxFragmentPainter::NeedsPaint(line_box_fragment)) {
+ if (!display_item_fragment && line_box_item)
+ display_item_fragment.emplace(paint_info.context, line_fragment_id);
NGLineBoxFragmentPainter line_box_painter(
line_box_fragment, line_box_paint_fragment, line_box_item,
PhysicalFragment(), paint_fragment_);
@@ -1353,8 +1407,10 @@ void NGBoxFragmentPainter::PaintLineBoxChildren(
continue;
}
DCHECK(child_fragment.IsLineBox());
- PaintLineBox(child_fragment, *line, line, /* line_box_item */ nullptr,
- paint_info, child_offset);
+ PaintLineBox(
+ child_fragment, *line, line, /* line_box_item */ nullptr,
+ // |line_fragment_id| is used only when |NGFragmentItem| is enabled.
+ /* line_fragment_id */ 0, paint_info, child_offset);
PaintInlineChildren(line->Children(), paint_info, child_offset);
}
}
@@ -1364,6 +1420,7 @@ void NGBoxFragmentPainter::PaintLineBoxChildItems(
const PaintInfo& paint_info,
const PhysicalOffset& paint_offset) {
const bool is_horizontal = box_fragment_.Style().IsHorizontalWritingMode();
+ wtf_size_t line_fragment_id = NGFragmentItem::kInitialLineFragmentId;
for (; *children; children->MoveToNextSkippingChildren()) {
const NGFragmentItem* child_item = children->CurrentItem();
DCHECK(child_item);
@@ -1390,9 +1447,9 @@ void NGBoxFragmentPainter::PaintLineBoxChildItems(
const NGPhysicalLineBoxFragment* line_box_fragment =
child_item->LineBoxFragment();
DCHECK(line_box_fragment);
- PaintLineBox(*line_box_fragment, *child_item,
+ PaintLineBox(*line_box_fragment, *child_item->GetDisplayItemClient(),
/* line_box_paint_fragment */ nullptr, child_item,
- paint_info, child_offset);
+ line_fragment_id++, paint_info, child_offset);
NGInlineCursor line_box_cursor = children->CursorForDescendants();
PaintInlineItems(paint_info, paint_offset,
child_item->OffsetInContainerBlock(), &line_box_cursor);
@@ -1430,7 +1487,11 @@ void NGBoxFragmentPainter::PaintBackplate(NGInlineCursor* line_boxes,
DrawingRecorder recorder(paint_info.context, GetDisplayItemClient(),
DisplayItem::kForcedColorsModeBackplate);
- Color backplate_color = style.ForcedBackplateColor();
+ Color backplate_color = PhysicalFragment()
+ .GetLayoutObject()
+ ->GetDocument()
+ .GetStyleEngine()
+ .ForcedBackgroundColor();
const auto& backplates = BuildBackplate(line_boxes, paint_offset);
for (const auto backplate : backplates)
paint_info.context.FillRect(FloatRect(backplate), backplate_color);
@@ -1534,6 +1595,8 @@ void NGBoxFragmentPainter::PaintTextItem(const NGInlineCursor& cursor,
!(item.IsLineBreak() && HasSelection(item.GetLayoutObject())))
return;
+ ScopedDisplayItemFragment display_item_fragment(paint_info.context,
+ item.FragmentId());
NGTextFragmentPainter<NGInlineCursor> text_painter(cursor, parent_offset);
text_painter.Paint(paint_info, paint_offset);
}
@@ -2156,12 +2219,16 @@ bool NGBoxFragmentPainter::HitTestBlockChildren(
const PhysicalOffset child_offset = accumulated_offset + child.offset;
- bool hit_child =
- block_child.IsPaintedAtomically()
- ? HitTestAllPhasesInFragment(block_child, hit_test_location,
- child_offset, &result)
- : NodeAtPointInFragment(block_child, hit_test_location,
- child_offset, action, &result);
+ bool hit_child = false;
+ if (block_child.IsPaintedAtomically()) {
+ if (action == kHitTestForeground) {
+ hit_child = HitTestAllPhasesInFragment(block_child, hit_test_location,
+ child_offset, &result);
+ }
+ } else {
+ hit_child = NodeAtPointInFragment(block_child, hit_test_location,
+ child_offset, action, &result);
+ }
if (hit_child) {
if (const LayoutObject* child_object = block_child.GetLayoutObject()) {
@@ -2239,6 +2306,14 @@ bool NGBoxFragmentPainter::HitTestItemsChildren(
for (NGInlineBackwardCursor cursor(children); cursor;) {
const NGFragmentItem* item = cursor.Current().Item();
DCHECK(item);
+ if (UNLIKELY(item->IsLayoutObjectDestroyedOrMoved())) {
+ // TODO(crbug.com/1099613): This should not happen, as long as it is
+ // really layout-clean.
+ NOTREACHED();
+ cursor.MoveToPreviousSibling();
+ continue;
+ }
+
if (item->HasSelfPaintingLayer()) {
cursor.MoveToPreviousSibling();
continue;
@@ -2315,7 +2390,20 @@ bool NGBoxFragmentPainter::HitTestFloatingChildren(
const auto* child_container =
DynamicTo<NGPhysicalContainerFragment>(&child_fragment);
- if (!child_container || !child_container->HasFloatingDescendantsForPaint())
+ if (!child_container)
+ continue;
+ // If this is a legacy root, fallback to legacy. It does not have
+ // |HasFloatingDescendantsForPaint()| set, but it may have floating
+ // descendants.
+ if (child_container->IsLegacyLayoutRoot() &&
+ RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ if (child_container->GetMutableLayoutObject()->NodeAtPoint(
+ *hit_test.result, hit_test.location, child_offset,
+ hit_test.action))
+ return true;
+ continue;
+ }
+ if (!child_container->HasFloatingDescendantsForPaint())
continue;
if (child_container->HasOverflowClip()) {
@@ -2349,6 +2437,8 @@ bool NGBoxFragmentPainter::HitTestFloatingChildItems(
cursor.MoveToPreviousSibling()) {
const NGFragmentItem* item = cursor.Current().Item();
DCHECK(item);
+ if (UNLIKELY(item->IsLayoutObjectDestroyedOrMoved()))
+ continue;
if (item->Type() == NGFragmentItem::kBox) {
if (const NGPhysicalBoxFragment* child_box = item->BoxFragment()) {
if (child_box->HasSelfPaintingLayer())
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h b/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
index d497ad8adc5..40c885fef4d 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
@@ -134,6 +134,7 @@ class NGBoxFragmentPainter : public BoxPainterBase {
const DisplayItemClient& display_item_client,
const NGPaintFragment* line_box_paint_fragment,
const NGFragmentItem* line_box_item,
+ wtf_size_t line_fragment_id,
const PaintInfo&,
const PhysicalOffset& paint_offset);
void PaintBackplate(NGInlineCursor* descendants,
@@ -386,7 +387,7 @@ inline NGBoxFragmentPainter::NGBoxFragmentPainter(
const NGFragmentItem& item,
const NGPhysicalBoxFragment& fragment)
: NGBoxFragmentPainter(fragment,
- item,
+ *item.GetDisplayItemClient(),
/* paint_fragment */ nullptr,
&inline_box_cursor,
&item) {
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_fieldset_painter.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_fieldset_painter.cc
index fe8baf7fa64..6d94c26b31e 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_fieldset_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_fieldset_painter.cc
@@ -42,6 +42,8 @@ void NGFieldsetPainter::PaintFieldsetDecorationBackground(
PhysicalRect paint_rect(paint_offset, fieldset_size);
const auto& fragment = fieldset_;
BoxDecorationData box_decoration_data(paint_info, fragment);
+ // TODO(crbug.com/786475): Fieldset should not scroll.
+ DCHECK(!box_decoration_data.IsPaintingScrollingBackground());
if (!box_decoration_data.ShouldPaint())
return;
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.cc
index 3badb3849dd..278e40cc8f7 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.cc
@@ -17,6 +17,7 @@
#include "third_party/blink/renderer/core/style/nine_piece_image.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
+#include "third_party/blink/renderer/platform/graphics/paint/scoped_display_item_fragment.h"
namespace blink {
@@ -33,23 +34,16 @@ inline bool HasMultiplePaintFragments(const LayoutObject& layout_object) {
return HasMultipleItems(NGPaintFragment::InlineFragmentsFor(&layout_object));
}
-inline bool MayHaveMultipleFragmentItems(const LayoutObject& layout_object) {
- // TODO(crbug.com/1061423): NGInlineCursor is currently unable to deal with
- // objects split into multiple fragmentainers (e.g. columns). Just return true
- // if it's possible that this object participates in a fragmentation
- // context. This will give false positives, but that should be harmless, given
- // the way the return value is used by the caller.
- if (layout_object.IsInsideFlowThread())
- return true;
-
- NGInlineCursor cursor;
- cursor.MoveTo(layout_object);
- DCHECK(cursor);
- if (cursor) {
- cursor.MoveToNextForSameLayoutObject();
- return cursor;
- }
- return false;
+inline bool MayHaveMultipleFragmentItems(const NGFragmentItem& item,
+ const LayoutObject& layout_object) {
+ return !item.IsFirstForNode() || !item.IsLastForNode() ||
+ // TODO(crbug.com/1061423): NGInlineCursor is currently unable to deal
+ // with objects split into multiple fragmentainers (e.g. columns). Just
+ // return true if it's possible that this object participates in a
+ // fragmentation context. This will give false positives, but that
+ // should be harmless, given the way the return value is used by the
+ // caller.
+ UNLIKELY(layout_object.IsInsideFlowThread());
}
} // namespace
@@ -64,6 +58,12 @@ const NGBorderEdges NGInlineBoxFragmentPainter::BorderEdges() const {
void NGInlineBoxFragmentPainter::Paint(const PaintInfo& paint_info,
const PhysicalOffset& paint_offset) {
+ base::Optional<ScopedDisplayItemFragment> display_item_fragment;
+ if (inline_box_item_) {
+ display_item_fragment.emplace(paint_info.context,
+ inline_box_item_->FragmentId());
+ }
+
const PhysicalOffset adjusted_paint_offset =
paint_offset + (inline_box_paint_fragment_
? inline_box_paint_fragment_->Offset()
@@ -121,9 +121,11 @@ void NGInlineBoxFragmentPainterBase::PaintBackgroundBorderShadow(
DCHECK(inline_box_fragment_.GetLayoutObject());
const LayoutObject& layout_object = *inline_box_fragment_.GetLayoutObject();
+ DCHECK(inline_box_paint_fragment_ || inline_box_item_);
bool object_may_have_multiple_boxes =
- inline_box_paint_fragment_ ? HasMultiplePaintFragments(layout_object)
- : MayHaveMultipleFragmentItems(layout_object);
+ inline_box_paint_fragment_
+ ? HasMultiplePaintFragments(layout_object)
+ : MayHaveMultipleFragmentItems(*inline_box_item_, layout_object);
// TODO(eae): Switch to LayoutNG version of BackgroundImageGeometry.
BackgroundImageGeometry geometry(*static_cast<const LayoutBoxModelObject*>(
@@ -155,6 +157,14 @@ void NGLineBoxFragmentPainter::PaintBackgroundBorderShadow(
DCHECK_EQ(paint_info.phase, PaintPhase::kForeground);
DCHECK_EQ(inline_box_fragment_.Type(), NGPhysicalFragment::kFragmentLineBox);
DCHECK(NeedsPaint(inline_box_fragment_));
+#if DCHECK_IS_ON()
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ DCHECK(inline_box_item_);
+ // |NGFragmentItem| uses the fragment id when painting the background of
+ // line boxes. Please see |NGFragmentItem::kInitialLineFragmentId|.
+ DCHECK_NE(paint_info.context.GetPaintController().CurrentFragment(), 0u);
+ }
+#endif
if (line_style_ == style_ ||
line_style_.Visibility() != EVisibility::kVisible)
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h b/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h
index 5b2529a74ae..960628c2067 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h
@@ -99,7 +99,7 @@ class NGInlineBoxFragmentPainterBase : public InlineBoxPainterBase {
if (inline_box_paint_fragment_)
return *inline_box_paint_fragment_;
DCHECK(inline_box_item_);
- return *inline_box_item_;
+ return *inline_box_item_->GetDisplayItemClient();
}
const virtual NGBorderEdges BorderEdges() const = 0;
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_mathml_painter.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_mathml_painter.cc
index 68e778f333d..fe901934dc4 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_mathml_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_mathml_painter.cc
@@ -55,4 +55,15 @@ void NGMathMLPainter::PaintFractionBar(const PaintInfo& info,
}
}
+void NGMathMLPainter::Paint(const PaintInfo& info,
+ PhysicalOffset paint_offset) {
+ // Fraction
+ if (box_fragment_.IsMathMLFraction()) {
+ PaintFractionBar(info, paint_offset);
+ return;
+ }
+
+ // TODO(rbuis): paint operator and radicals.
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_mathml_painter.h b/chromium/third_party/blink/renderer/core/paint/ng/ng_mathml_painter.h
index 70233e8017f..fd2a96af6d6 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_mathml_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_mathml_painter.h
@@ -20,6 +20,7 @@ class NGMathMLPainter {
public:
explicit NGMathMLPainter(const NGPhysicalBoxFragment& box_fragment)
: box_fragment_(box_fragment) {}
+ void Paint(const PaintInfo&, PhysicalOffset);
void PaintFractionBar(const PaintInfo&, PhysicalOffset);
private:
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
index ce2576b1aa0..d4c342cf935 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
@@ -46,63 +46,6 @@ struct SameSizeAsNGPaintFragment : public RefCounted<NGPaintFragment>,
static_assert(sizeof(NGPaintFragment) == sizeof(SameSizeAsNGPaintFragment),
"NGPaintFragment should stay small.");
-LogicalRect ComputeLogicalRectFor(const PhysicalRect& physical_rect,
- WritingMode writing_mode,
- TextDirection text_direction,
- const PhysicalSize& outer_size) {
- const LogicalOffset logical_offset = physical_rect.offset.ConvertToLogical(
- writing_mode, text_direction, outer_size, physical_rect.size);
- const LogicalSize logical_size =
- physical_rect.size.ConvertToLogical(writing_mode);
- return {logical_offset, logical_size};
-}
-
-LogicalRect ComputeLogicalRectFor(const PhysicalRect& physical_rect,
- const NGPaintFragment& paint_fragment) {
- return ComputeLogicalRectFor(
- physical_rect, paint_fragment.Style().GetWritingMode(),
- paint_fragment.PhysicalFragment().ResolvedDirection(),
- paint_fragment.Size());
-}
-
-LogicalRect ComputeLogicalRectFor(const PhysicalRect& physical_rect,
- const NGInlineCursor& cursor) {
- if (const NGPaintFragment* paint_fragment = cursor.CurrentPaintFragment())
- return ComputeLogicalRectFor(physical_rect, *paint_fragment);
-
- const NGFragmentItem& item = *cursor.CurrentItem();
- return ComputeLogicalRectFor(physical_rect, item.GetWritingMode(),
- item.ResolvedDirection(), item.Size());
-}
-
-PhysicalRect ComputePhysicalRectFor(const LogicalRect& logical_rect,
- WritingMode writing_mode,
- TextDirection text_direction,
- const PhysicalSize& outer_size) {
- const PhysicalSize physical_size =
- ToPhysicalSize(logical_rect.size, writing_mode);
- const PhysicalOffset physical_offset = logical_rect.offset.ConvertToPhysical(
- writing_mode, text_direction, outer_size, physical_size);
-
- return {physical_offset, physical_size};
-}
-PhysicalRect ComputePhysicalRectFor(const LogicalRect& logical_rect,
- const NGPaintFragment& paint_fragment) {
- return ComputePhysicalRectFor(
- logical_rect, paint_fragment.Style().GetWritingMode(),
- paint_fragment.PhysicalFragment().ResolvedDirection(),
- paint_fragment.Size());
-}
-
-PhysicalRect ComputePhysicalRectFor(const LogicalRect& logical_rect,
- const NGInlineCursor& cursor) {
- if (const NGPaintFragment* paint_fragment = cursor.CurrentPaintFragment())
- return ComputePhysicalRectFor(logical_rect, *paint_fragment);
- const NGFragmentItem& item = *cursor.CurrentItem();
- return ComputePhysicalRectFor(logical_rect, item.GetWritingMode(),
- item.ResolvedDirection(), item.Size());
-}
-
LogicalRect ExpandedSelectionRectForSoftLineBreakIfNeeded(
const LogicalRect& rect,
const NGInlineCursor& cursor,
@@ -142,22 +85,7 @@ LogicalRect ExpandSelectionRectToLineHeight(const LogicalRect& rect,
cursor.Current().OffsetInContainerBlock(),
line.Current().Size());
return ExpandSelectionRectToLineHeight(
- rect, ComputeLogicalRectFor(line_physical_rect, cursor));
-}
-
-LogicalOffset ChildLogicalOffsetInParent(const NGPaintFragment& child) {
- DCHECK(child.Parent());
- const NGPaintFragment& parent = *child.Parent();
- return child.Offset().ConvertToLogical(parent.Style().GetWritingMode(),
- parent.Style().Direction(),
- parent.Size(), child.Size());
-}
-
-LogicalSize ChildLogicalSizeInParent(const NGPaintFragment& child) {
- DCHECK(child.Parent());
- const NGPaintFragment& parent = *child.Parent();
- return NGFragment(parent.Style().GetWritingMode(), child.PhysicalFragment())
- .Size();
+ rect, cursor.Current().ConvertChildToLogical(line_physical_rect));
}
base::Optional<PositionWithAffinity> PositionForPointInChild(
@@ -530,7 +458,7 @@ void NGPaintFragment::ClearAssociationWithLayoutObject() {
}
}
if (fragment.IsLineBox() || fragment.IsInlineBox() ||
- fragment.IsColumnBox()) {
+ fragment.IsFragmentainerBox()) {
child->ClearAssociationWithLayoutObject();
} else {
DCHECK(fragment.IsText() || fragment.IsFormattingContextRoot());
@@ -815,7 +743,8 @@ PhysicalRect ComputeLocalSelectionRectForText(
const LayoutSelectionStatus& selection_status) {
const PhysicalRect selection_rect =
cursor.CurrentLocalRect(selection_status.start, selection_status.end);
- LogicalRect logical_rect = ComputeLogicalRectFor(selection_rect, cursor);
+ LogicalRect logical_rect =
+ cursor.Current().ConvertChildToLogical(selection_rect);
// Let LocalRect for line break have a space width to paint line break
// when it is only character in a line or only selected in a line.
if (selection_status.start != selection_status.end &&
@@ -834,7 +763,7 @@ PhysicalRect ComputeLocalSelectionRectForText(
const LogicalRect line_height_expanded_rect =
ExpandSelectionRectToLineHeight(line_break_extended_rect, cursor);
const PhysicalRect physical_rect =
- ComputePhysicalRectFor(line_height_expanded_rect, cursor);
+ cursor.Current().ConvertChildToPhysical(line_height_expanded_rect);
return physical_rect;
}
@@ -844,11 +773,12 @@ PhysicalRect ComputeLocalSelectionRectForReplaced(
const NGInlineCursor& cursor) {
DCHECK(cursor.Current().GetLayoutObject()->IsLayoutReplaced());
const PhysicalRect selection_rect = PhysicalRect({}, cursor.Current().Size());
- LogicalRect logical_rect = ComputeLogicalRectFor(selection_rect, cursor);
+ LogicalRect logical_rect =
+ cursor.Current().ConvertChildToLogical(selection_rect);
const LogicalRect line_height_expanded_rect =
ExpandSelectionRectToLineHeight(logical_rect, cursor);
const PhysicalRect physical_rect =
- ComputePhysicalRectFor(line_height_expanded_rect, cursor);
+ cursor.Current().ConvertChildToPhysical(line_height_expanded_rect);
return physical_rect;
}
@@ -897,10 +827,11 @@ PositionWithAffinity NGPaintFragment::PositionForPointInInlineLevelBox(
if (child->PhysicalFragment().IsFloating())
continue;
- const LayoutUnit child_inline_min =
- ChildLogicalOffsetInParent(*child).inline_offset;
+ const LogicalRect logical_child_rect =
+ PhysicalFragment().ConvertChildToLogical(child->Rect());
+ const LayoutUnit child_inline_min = logical_child_rect.offset.inline_offset;
const LayoutUnit child_inline_max =
- child_inline_min + ChildLogicalSizeInParent(*child).inline_size;
+ child_inline_min + logical_child_rect.size.inline_size;
// Try to resolve if |point| falls in any child in inline direction.
if (inline_point >= child_inline_min && inline_point <= child_inline_max) {
@@ -936,25 +867,6 @@ PositionWithAffinity NGPaintFragment::PositionForPointInInlineLevelBox(
return child_position.value();
}
- if (PhysicalFragment().IsLineBox()) {
- // There are no inline items to hit in this line box, e.g. <span> with
- // size and border. We try in lines before |this| line in the block.
- // See editing/selection/last-empty-inline.html
- NGInlineCursor cursor(*Parent());
- cursor.MoveTo(*this);
- const PhysicalOffset point_in_line = point - OffsetInContainerBlock();
- for (;;) {
- cursor.MoveToPreviousLine();
- if (!cursor)
- break;
- const NGPaintFragment& line = *cursor.CurrentPaintFragment();
- const PhysicalOffset adjusted_point =
- point_in_line + line.OffsetInContainerBlock();
- if (auto position = line.PositionForPointInInlineLevelBox(adjusted_point))
- return position;
- }
- }
-
return PositionWithAffinity();
}
@@ -972,23 +884,29 @@ PositionWithAffinity NGPaintFragment::PositionForPointInInlineFormattingContext(
PhysicalSize(LayoutUnit(1), LayoutUnit(1)));
const LayoutUnit block_point = logical_point.block_offset;
- // Stores the closest line box child above |point| in the block direction.
+ // Stores the closest line box child below |point| in the block direction.
// Used if we can't find any child |point| falls in to resolve the position.
- const NGPaintFragment* closest_line_before = nullptr;
- LayoutUnit closest_line_before_block_offset = LayoutUnit::Min();
+ const NGPaintFragment* closest_line_below = nullptr;
+ LayoutUnit closest_line_below_block_offset = LayoutUnit::Min();
- // Stores the closest line box child below |point| in the block direction.
+ // Stores the closest line box child above |point| in the block direction.
// Used if we can't find any child |point| falls in to resolve the position.
- const NGPaintFragment* closest_line_after = nullptr;
- LayoutUnit closest_line_after_block_offset = LayoutUnit::Max();
+ const NGPaintFragment* closest_line_above = nullptr;
+ LayoutUnit closest_line_above_block_offset = LayoutUnit::Max();
for (const NGPaintFragment* child : Children()) {
- if (!child->PhysicalFragment().IsLineBox() || child->Children().IsEmpty())
+ if (!child->PhysicalFragment().IsLineBox())
+ continue;
+ if (!NGInlineCursor(*child).TryToMoveToFirstInlineLeafChild()) {
+ // editing/selection/last-empty-inline.html requires this to skip
+ // empty <span> with padding.
continue;
+ }
- const LayoutUnit line_min = ChildLogicalOffsetInParent(*child).block_offset;
- const LayoutUnit line_max =
- line_min + ChildLogicalSizeInParent(*child).block_size;
+ const LogicalRect logical_child_rect =
+ PhysicalFragment().ConvertChildToLogical(child->Rect());
+ const LayoutUnit line_min = logical_child_rect.offset.block_offset;
+ const LayoutUnit line_max = line_min + logical_child_rect.size.block_size;
// Try to resolve if |point| falls in a line box in block direction.
// Hitting on line bottom doesn't count, to match legacy behavior.
@@ -1000,30 +918,61 @@ PositionWithAffinity NGPaintFragment::PositionForPointInInlineFormattingContext(
}
if (block_point < line_min) {
- if (line_min < closest_line_after_block_offset) {
- closest_line_after = child;
- closest_line_after_block_offset = line_min;
+ if (line_min < closest_line_above_block_offset) {
+ closest_line_above = child;
+ closest_line_above_block_offset = line_min;
}
}
if (block_point >= line_max) {
- if (line_max > closest_line_before_block_offset) {
- closest_line_before = child;
- closest_line_before_block_offset = line_max;
+ if (line_max > closest_line_below_block_offset) {
+ closest_line_below = child;
+ closest_line_below_block_offset = line_max;
}
}
}
- if (closest_line_after) {
- if (auto child_position =
- PositionForPointInChild(*closest_line_after, point))
+ // Note: |move_caret_to_boundary| is true for Mac and Unix.
+ const bool move_caret_to_boundary =
+ To<LayoutBlockFlow>(GetLayoutObject())
+ ->ShouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
+
+ // At here, |point| is not inside any line in |this|:
+ // |closest_line_above|
+ // |point|
+ // |closest_line_below|
+ if (closest_line_above) {
+ if (move_caret_to_boundary) {
+ // Tests[1-3] reach here.
+ // [1] editing/selection/click-in-margins-inside-editable-div.html
+ // [2] fast/writing-mode/flipped-blocks-hit-test-line-edges.html
+ // [3] All/LayoutViewHitTestTest.HitTestHorizontal/4
+ NGInlineCursor line_box(*this);
+ line_box.MoveTo(*closest_line_above);
+ if (auto first_position = line_box.PositionForStartOfLine())
+ return PositionWithAffinity(first_position.GetPosition());
+ } else if (auto child_position =
+ PositionForPointInChild(*closest_line_above, point)) {
return child_position.value();
+ }
}
- if (closest_line_before) {
- if (auto child_position =
- PositionForPointInChild(*closest_line_before, point))
+ if (closest_line_below) {
+ if (move_caret_to_boundary) {
+ // Tests[1-3] reach here.
+ // [1] editing/selection/click-in-margins-inside-editable-div.html
+ // [2] fast/writing-mode/flipped-blocks-hit-test-line-edges.html
+ // [3] All/LayoutViewHitTestTest.HitTestHorizontal/4
+ NGInlineCursor line_box(*this);
+ line_box.MoveTo(*closest_line_below);
+ if (auto last_position = line_box.PositionForEndOfLine())
+ return PositionWithAffinity(last_position.GetPosition());
+ } else if (auto child_position =
+ PositionForPointInChild(*closest_line_below, point)) {
+ // Test[1] reaches here.
+ // [1] editing/selection/last-empty-inline.html
return child_position.value();
+ }
}
// TODO(xiaochengh): Looking at only the closest lines may not be enough,
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
index 383c5d217f3..d734ec6b4e6 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
@@ -330,6 +330,7 @@ class CORE_EXPORT NGPaintFragment : public RefCounted<NGPaintFragment>,
//
scoped_refptr<const NGPhysicalFragment> physical_fragment_;
+ // The offset to |parent_| comes from |NGLink::Offset()|.
PhysicalOffset offset_;
NGPaintFragment* parent_;
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc
index 23d62f21cb8..f0c24930a67 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc
@@ -11,7 +11,8 @@
#include "third_party/blink/renderer/core/editing/markers/text_match_marker.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/layout/geometry/logical_rect.h"
-#include "third_party/blink/renderer/core/layout/layout_list_marker.h"
+#include "third_party/blink/renderer/core/layout/layout_ruby_run.h"
+#include "third_party/blink/renderer/core/layout/list_marker.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h"
@@ -55,8 +56,9 @@ Color SelectionBackgroundColor(const Document& document,
// TODO(yosin): Remove |AsDisplayItemClient| once the transition to
// |NGFragmentItem| is done. http://crbug.com/982194
-inline const NGFragmentItem& AsDisplayItemClient(const NGInlineCursor& cursor) {
- return *cursor.CurrentItem();
+inline const DisplayItemClient& AsDisplayItemClient(
+ const NGInlineCursor& cursor) {
+ return *cursor.Current().GetDisplayItemClient();
}
inline const NGPaintFragment& AsDisplayItemClient(
@@ -329,12 +331,16 @@ void PaintDocumentMarkers(GraphicsContext& context,
styleable_marker.BackgroundColor());
break;
}
- const SimpleFontData* font_data = style.GetFont().PrimaryFont();
- DocumentMarkerPainter::PaintStyleableMarkerUnderline(
- context, box_origin, styleable_marker, style,
- FloatRect(MarkerRectForForeground(
- text_fragment, text, paint_start_offset, paint_end_offset)),
- LayoutUnit(font_data->GetFontMetrics().Height()));
+ if (DocumentMarkerPainter::ShouldPaintMarkerUnderline(
+ styleable_marker)) {
+ const SimpleFontData* font_data = style.GetFont().PrimaryFont();
+ DocumentMarkerPainter::PaintStyleableMarkerUnderline(
+ context, box_origin, styleable_marker, style,
+ FloatRect(MarkerRectForForeground(
+ text_fragment, text, paint_start_offset, paint_end_offset)),
+ LayoutUnit(font_data->GetFontMetrics().Height()),
+ text_fragment.GetNode()->GetDocument().InDarkMode());
+ }
} break;
default:
@@ -430,6 +436,35 @@ class SelectionPaintState {
bool paint_selected_text_separately_;
};
+// Check if text-emphasis and ruby annotation text are on different sides.
+// See InlineTextBox::GetEmphasisMarkPosition().
+//
+// TODO(layout-dev): The current behavior is compatible with the legacy layout.
+// However, the specification asks to draw emphasis marks over ruby annotation
+// text.
+// https://drafts.csswg.org/css-text-decor-4/#text-emphasis-position-property
+bool ShouldPaintEmphasisMark(const ComputedStyle& style,
+ const LayoutObject& layout_object) {
+ if (style.GetTextEmphasisMark() == TextEmphasisMark::kNone)
+ return false;
+ const LayoutObject* containing_block = layout_object.ContainingBlock();
+ if (!containing_block || !containing_block->IsRubyBase())
+ return true;
+ const LayoutObject* parent = containing_block->Parent();
+ if (!parent || !parent->IsRubyRun())
+ return true;
+ const LayoutRubyText* ruby_text = ToLayoutRubyRun(parent)->RubyText();
+ if (!ruby_text)
+ return true;
+ if (!NGInlineCursor(*ruby_text))
+ return true;
+ const LineLogicalSide ruby_logical_side =
+ parent->StyleRef().GetRubyPosition() == RubyPosition::kBefore
+ ? LineLogicalSide::kOver
+ : LineLogicalSide::kUnder;
+ return ruby_logical_side != style.GetTextEmphasisLineLogicalSide();
+}
+
} // namespace
StringView NGTextPainterCursor::CurrentText() const {
@@ -450,7 +485,7 @@ void NGTextFragmentPainter<Cursor>::PaintSymbol(
const PaintInfo& paint_info,
const PhysicalOffset& paint_offset) {
PhysicalRect marker_rect(
- LayoutListMarker::RelativeSymbolMarkerRect(style, box_size.width));
+ ListMarker::RelativeSymbolMarkerRect(style, box_size.width));
marker_rect.Move(paint_offset);
IntRect rect = PixelSnappedIntRect(marker_rect);
@@ -593,7 +628,7 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info,
NGTextPainter text_painter(context, font, fragment_paint_info, visual_rect,
text_origin, box_rect, is_horizontal);
- if (style.GetTextEmphasisMark() != TextEmphasisMark::kNone) {
+ if (ShouldPaintEmphasisMark(style, *layout_object)) {
text_painter.SetEmphasisMark(style.TextEmphasisMarkString(),
style.GetTextEmphasisPosition());
}
diff --git a/chromium/third_party/blink/renderer/core/paint/nine_piece_image_grid.cc b/chromium/third_party/blink/renderer/core/paint/nine_piece_image_grid.cc
index 33ee31f82c5..2ef411fcfe1 100644
--- a/chromium/third_party/blink/renderer/core/paint/nine_piece_image_grid.cc
+++ b/chromium/third_party/blink/renderer/core/paint/nine_piece_image_grid.cc
@@ -16,15 +16,15 @@ static int ComputeEdgeWidth(const BorderImageLength& border_slice,
int image_side,
int box_extent) {
if (border_slice.IsNumber())
- return LayoutUnit(border_slice.Number() * border_side).Round();
+ return LayoutUnit(border_slice.Number() * border_side).Floor();
if (border_slice.length().IsAuto())
return image_side;
- return ValueForLength(border_slice.length(), LayoutUnit(box_extent)).Round();
+ return ValueForLength(border_slice.length(), LayoutUnit(box_extent)).Floor();
}
static int ComputeEdgeSlice(const Length& slice, int maximum) {
return std::min<int>(maximum,
- ValueForLength(slice, LayoutUnit(maximum)).Round());
+ ValueForLength(slice, LayoutUnit(maximum)).Floor());
}
// Scale the width of the |start| and |end| edges using |scale_factor|.
diff --git a/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.cc b/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.cc
index e3f8aeb9891..5d36207bda4 100644
--- a/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.cc
+++ b/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.cc
@@ -38,12 +38,12 @@ TraverseNonCompositingDescendantsBelongingToAncestorPaintInvalidationContainer(
// an ancestor. This function traverses all such descendants. See (legacy
// layout only: Case 1a and) Case 2 below for details.
DCHECK(object.IsPaintInvalidationContainer() &&
- (!object.StyleRef().IsStackingContext() ||
+ (!object.IsStackingContext() ||
MayBeSkippedContainerForFloating(object)));
LayoutObject* descendant = object.NextInPreOrder(&object);
while (descendant) {
- if (!descendant->HasLayer() || !descendant->StyleRef().IsStacked()) {
+ if (!descendant->HasLayer() || !descendant->IsStacked()) {
// Case 1: The descendant is not stacked (or is stacked but has not been
// allocated a layer yet during style change), so either it's a paint
// invalidation container in the same situation as |object|, or its paint
@@ -73,7 +73,7 @@ TraverseNonCompositingDescendantsBelongingToAncestorPaintInvalidationContainer(
// thus recur into the subtree.
TraverseNonCompositingDescendantsInPaintOrder(*descendant, functor);
descendant = descendant->NextInPreOrderAfterChildren(&object);
- } else if (descendant->StyleRef().IsStackingContext() &&
+ } else if (descendant->IsStackingContext() &&
!MayBeSkippedContainerForFloating(*descendant)) {
// Case 3: The descendant is an invalidation container and is a stacking
// context. No objects in the subtree can have invalidation container
@@ -101,7 +101,7 @@ static void TraverseNonCompositingDescendantsInPaintOrder(
if (!descendant->IsPaintInvalidationContainer()) {
functor(*descendant);
descendant = descendant->NextInPreOrder(&object);
- } else if (descendant->StyleRef().IsStackingContext() &&
+ } else if (descendant->IsStackingContext() &&
!MayBeSkippedContainerForFloating(*descendant)) {
// The descendant is an invalidation container and is a stacking context.
// No objects in the subtree can have invalidation container outside of
@@ -135,21 +135,6 @@ static void SetPaintingLayerNeedsRepaintDuringTraverse(
}
void ObjectPaintInvalidator::
- InvalidateDisplayItemClientsIncludingNonCompositingDescendants(
- PaintInvalidationReason reason) {
- // This is valid because we want to invalidate the client in the display item
- // list of the current backing.
- DisableCompositingQueryAsserts disabler;
-
- SlowSetPaintingLayerNeedsRepaint();
- TraverseNonCompositingDescendantsInPaintOrder(
- object_, [reason](const LayoutObject& object) {
- SetPaintingLayerNeedsRepaintDuringTraverse(object);
- object.InvalidateDisplayItemClients(reason);
- });
-}
-
-void ObjectPaintInvalidator::
InvalidatePaintIncludingNonCompositingDescendants() {
DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
SlowSetPaintingLayerNeedsRepaint();
diff --git a/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.h b/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.h
index 4af0b34356f..acf8e168368 100644
--- a/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.h
+++ b/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.h
@@ -36,9 +36,6 @@ class CORE_EXPORT ObjectPaintInvalidator {
InvalidateDisplayItemClient(client, reason);
}
- void InvalidateDisplayItemClientsIncludingNonCompositingDescendants(
- PaintInvalidationReason);
-
// The caller should ensure the painting layer has been SetNeedsRepaint
// before calling this function.
void InvalidateDisplayItemClient(const DisplayItemClient& client,
diff --git a/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc b/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc
index a84527533ee..e46dac85dc8 100644
--- a/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc
@@ -8,6 +8,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
@@ -33,8 +34,7 @@ class ObjectPaintInvalidatorTest : public RenderingTest {
using ::testing::ElementsAre;
-TEST_F(ObjectPaintInvalidatorTest,
- TraverseNonCompositingDescendantsInPaintOrder) {
+TEST_F(ObjectPaintInvalidatorTest, TraverseNonCompositingDescendants) {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
@@ -64,58 +64,51 @@ TEST_F(ObjectPaintInvalidatorTest,
)HTML");
auto* container = GetLayoutObjectByElementId("container");
- auto* normal_child = GetLayoutObjectByElementId("normal-child");
+ auto* container_layer = ToLayoutBoxModelObject(container)->Layer();
auto* stacked_child = GetLayoutObjectByElementId("stacked-child");
+ auto* stacked_child_layer = ToLayoutBoxModelObject(stacked_child)->Layer();
auto* composited_stacking_context =
GetLayoutObjectByElementId("composited-stacking-context");
- auto* normal_child_of_composited_stacking_context =
- GetLayoutObjectByElementId("normal-child-of-composited-stacking-context");
+ auto* composited_stacking_context_layer =
+ ToLayoutBoxModelObject(composited_stacking_context)->Layer();
auto* stacked_child_of_composited_stacking_context =
GetLayoutObjectByElementId(
"stacked-child-of-composited-stacking-context");
+ auto* stacked_child_of_composited_stacking_context_layer =
+ ToLayoutBoxModelObject(stacked_child_of_composited_stacking_context)
+ ->Layer();
auto* composited_non_stacking_context =
GetLayoutObjectByElementId("composited-non-stacking-context");
- auto* normal_child_of_composited_non_stacking_context =
- GetLayoutObjectByElementId(
- "normal-child-of-composited-non-stacking-context");
+ auto* composited_non_stacking_context_layer =
+ ToLayoutBoxModelObject(composited_non_stacking_context)->Layer();
auto* stacked_child_of_composited_non_stacking_context =
GetLayoutObjectByElementId(
"stacked-child-of-composited-non-stacking-context");
+ auto* stacked_child_of_composited_non_stacking_context_layer =
+ ToLayoutBoxModelObject(stacked_child_of_composited_non_stacking_context)
+ ->Layer();
auto* non_stacked_layered_child_of_composited_non_stacking_context =
GetLayoutObjectByElementId(
"non-stacked-layered-child-of-composited-non-stacking-context");
-
- ValidateDisplayItemClient(container);
- ValidateDisplayItemClient(normal_child);
- ValidateDisplayItemClient(stacked_child);
- ValidateDisplayItemClient(composited_stacking_context);
- ValidateDisplayItemClient(normal_child_of_composited_stacking_context);
- ValidateDisplayItemClient(stacked_child_of_composited_stacking_context);
- ValidateDisplayItemClient(composited_non_stacking_context);
- ValidateDisplayItemClient(normal_child_of_composited_non_stacking_context);
- ValidateDisplayItemClient(stacked_child_of_composited_non_stacking_context);
- ValidateDisplayItemClient(
- non_stacked_layered_child_of_composited_non_stacking_context);
+ auto* non_stacked_layered_child_of_composited_non_stacking_context_layer =
+ ToLayoutBoxModelObject(
+ non_stacked_layered_child_of_composited_non_stacking_context)
+ ->Layer();
ObjectPaintInvalidator(*container)
- .InvalidateDisplayItemClientsIncludingNonCompositingDescendants(
- PaintInvalidationReason::kSubtree);
-
- EXPECT_FALSE(IsValidDisplayItemClient(container));
- EXPECT_FALSE(IsValidDisplayItemClient(normal_child));
- EXPECT_FALSE(IsValidDisplayItemClient(stacked_child));
- EXPECT_TRUE(IsValidDisplayItemClient(composited_stacking_context));
- EXPECT_TRUE(
- IsValidDisplayItemClient(normal_child_of_composited_stacking_context));
- EXPECT_TRUE(
- IsValidDisplayItemClient(stacked_child_of_composited_stacking_context));
- EXPECT_TRUE(IsValidDisplayItemClient(composited_non_stacking_context));
- EXPECT_TRUE(IsValidDisplayItemClient(
- normal_child_of_composited_non_stacking_context));
- EXPECT_FALSE(IsValidDisplayItemClient(
- stacked_child_of_composited_non_stacking_context));
- EXPECT_TRUE(IsValidDisplayItemClient(
- non_stacked_layered_child_of_composited_non_stacking_context));
+ .InvalidatePaintIncludingNonCompositingDescendants();
+
+ EXPECT_TRUE(container_layer->SelfNeedsRepaint());
+ EXPECT_TRUE(stacked_child_layer->SelfNeedsRepaint());
+ EXPECT_FALSE(composited_stacking_context_layer->SelfNeedsRepaint());
+ EXPECT_FALSE(
+ stacked_child_of_composited_stacking_context_layer->SelfNeedsRepaint());
+ EXPECT_FALSE(composited_non_stacking_context_layer->SelfNeedsRepaint());
+ EXPECT_TRUE(stacked_child_of_composited_non_stacking_context_layer
+ ->SelfNeedsRepaint());
+ EXPECT_FALSE(
+ non_stacked_layered_child_of_composited_non_stacking_context_layer
+ ->SelfNeedsRepaint());
}
TEST_F(ObjectPaintInvalidatorTest, TraverseFloatUnderCompositedInline) {
@@ -145,11 +138,9 @@ TEST_F(ObjectPaintInvalidatorTest, TraverseFloatUnderCompositedInline) {
ToLayoutBoxModelObject(composited_container)->Layer();
auto* span = GetLayoutObjectByElementId("span");
auto* span_layer = ToLayoutBoxModelObject(span)->Layer();
- auto* text = span->SlowFirstChild();
- auto fragments = NGPaintFragment::InlineFragmentsFor(span);
EXPECT_TRUE(span->IsPaintInvalidationContainer());
- EXPECT_TRUE(span->StyleRef().IsStackingContext());
+ EXPECT_TRUE(span->IsStackingContext());
if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
EXPECT_EQ(span, &target->ContainerForPaintInvalidation());
EXPECT_EQ(span_layer, target->PaintingLayer());
@@ -158,23 +149,11 @@ TEST_F(ObjectPaintInvalidatorTest, TraverseFloatUnderCompositedInline) {
EXPECT_EQ(containing_block_layer, target->PaintingLayer());
}
- ValidateDisplayItemClient(target);
- ValidateDisplayItemClient(containing_block);
- ValidateDisplayItemClient(composited_container);
- if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
- for (auto* fragment : fragments)
- ValidateDisplayItemClient(fragment);
- } else {
- ValidateDisplayItemClient(span);
- ValidateDisplayItemClient(text);
- }
-
// Traversing from target should mark needsRepaint on correct layers.
EXPECT_FALSE(containing_block_layer->SelfNeedsRepaint());
EXPECT_FALSE(composited_container_layer->DescendantNeedsRepaint());
ObjectPaintInvalidator(*target)
- .InvalidateDisplayItemClientsIncludingNonCompositingDescendants(
- PaintInvalidationReason::kSubtree);
+ .InvalidatePaintIncludingNonCompositingDescendants();
if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
EXPECT_FALSE(containing_block_layer->SelfOrDescendantNeedsRepaint());
EXPECT_FALSE(composited_container_layer->SelfOrDescendantNeedsRepaint());
@@ -186,28 +165,15 @@ TEST_F(ObjectPaintInvalidatorTest, TraverseFloatUnderCompositedInline) {
EXPECT_TRUE(composited_container_layer->DescendantNeedsRepaint());
EXPECT_FALSE(span_layer->SelfNeedsRepaint());
}
- EXPECT_FALSE(IsValidDisplayItemClient(target));
- ValidateDisplayItemClient(target);
- EXPECT_TRUE(IsValidDisplayItemClient(containing_block));
- EXPECT_TRUE(IsValidDisplayItemClient(composited_container));
- if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
- for (auto* fragment : fragments)
- EXPECT_TRUE(IsValidDisplayItemClient(fragment));
- } else {
- EXPECT_TRUE(IsValidDisplayItemClient(span));
- EXPECT_TRUE(IsValidDisplayItemClient(text));
- }
composited_container_layer->ClearNeedsRepaintRecursively();
// Traversing from span should mark needsRepaint on correct layers for target.
- ValidateDisplayItemClient(target);
EXPECT_FALSE(containing_block_layer->SelfOrDescendantNeedsRepaint());
EXPECT_FALSE(composited_container_layer->SelfOrDescendantNeedsRepaint());
EXPECT_FALSE(span_layer->SelfOrDescendantNeedsRepaint());
ObjectPaintInvalidator(*span)
- .InvalidateDisplayItemClientsIncludingNonCompositingDescendants(
- PaintInvalidationReason::kSubtree);
+ .InvalidatePaintIncludingNonCompositingDescendants();
if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
EXPECT_FALSE(containing_block_layer->SelfOrDescendantNeedsRepaint());
EXPECT_FALSE(composited_container_layer->SelfOrDescendantNeedsRepaint());
@@ -219,22 +185,6 @@ TEST_F(ObjectPaintInvalidatorTest, TraverseFloatUnderCompositedInline) {
}
EXPECT_TRUE(span_layer->SelfNeedsRepaint());
- EXPECT_FALSE(IsValidDisplayItemClient(target));
- ValidateDisplayItemClient(target);
- EXPECT_TRUE(IsValidDisplayItemClient(containing_block));
- EXPECT_TRUE(IsValidDisplayItemClient(composited_container));
- if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
- for (auto* fragment : fragments) {
- EXPECT_FALSE(IsValidDisplayItemClient(fragment));
- ValidateDisplayItemClient(fragment);
- }
- } else {
- EXPECT_FALSE(IsValidDisplayItemClient(span));
- ValidateDisplayItemClient(span);
- EXPECT_FALSE(IsValidDisplayItemClient(text));
- ValidateDisplayItemClient(text);
- }
-
composited_container_layer->ClearNeedsRepaintRecursively();
// Traversing from compositedContainer should not reach target.
@@ -242,25 +192,10 @@ TEST_F(ObjectPaintInvalidatorTest, TraverseFloatUnderCompositedInline) {
EXPECT_FALSE(composited_container_layer->SelfOrDescendantNeedsRepaint());
EXPECT_FALSE(span_layer->SelfOrDescendantNeedsRepaint());
ObjectPaintInvalidator(*composited_container)
- .InvalidateDisplayItemClientsIncludingNonCompositingDescendants(
- PaintInvalidationReason::kSubtree);
+ .InvalidatePaintIncludingNonCompositingDescendants();
EXPECT_TRUE(containing_block_layer->SelfNeedsRepaint());
EXPECT_TRUE(composited_container_layer->DescendantNeedsRepaint());
EXPECT_FALSE(span_layer->SelfNeedsRepaint());
-
- if (RuntimeEnabledFeatures::LayoutNGEnabled())
- EXPECT_TRUE(IsValidDisplayItemClient(target));
- else
- EXPECT_FALSE(IsValidDisplayItemClient(target));
- EXPECT_FALSE(IsValidDisplayItemClient(containing_block));
- EXPECT_FALSE(IsValidDisplayItemClient(composited_container));
- if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
- for (auto* fragment : fragments)
- EXPECT_TRUE(IsValidDisplayItemClient(fragment));
- } else {
- EXPECT_TRUE(IsValidDisplayItemClient(span));
- EXPECT_TRUE(IsValidDisplayItemClient(text));
- }
}
TEST_F(ObjectPaintInvalidatorTest, TraverseStackedFloatUnderCompositedInline) {
@@ -278,17 +213,18 @@ TEST_F(ObjectPaintInvalidatorTest, TraverseStackedFloatUnderCompositedInline) {
auto* span = GetLayoutObjectByElementId("span");
auto* span_layer = ToLayoutBoxModelObject(span)->Layer();
auto* text = span->SlowFirstChild();
- auto fragments = NGPaintFragment::InlineFragmentsFor(span);
EXPECT_TRUE(span->IsPaintInvalidationContainer());
- EXPECT_TRUE(span->StyleRef().IsStackingContext());
+ EXPECT_TRUE(span->IsStackingContext());
EXPECT_EQ(span, &target->ContainerForPaintInvalidation());
EXPECT_EQ(target_layer, target->PaintingLayer());
ValidateDisplayItemClient(target);
if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
- for (auto* fragment : fragments)
- ValidateDisplayItemClient(fragment);
+ NGInlineCursor fragments;
+ for (fragments.MoveTo(*span); fragments;
+ fragments.MoveToNextForSameLayoutObject())
+ ValidateDisplayItemClient(fragments.Current().GetDisplayItemClient());
} else {
ValidateDisplayItemClient(span);
ValidateDisplayItemClient(text);
@@ -297,18 +233,8 @@ TEST_F(ObjectPaintInvalidatorTest, TraverseStackedFloatUnderCompositedInline) {
// Traversing from span should reach target.
EXPECT_FALSE(span_layer->SelfNeedsRepaint());
ObjectPaintInvalidator(*span)
- .InvalidateDisplayItemClientsIncludingNonCompositingDescendants(
- PaintInvalidationReason::kSubtree);
+ .InvalidatePaintIncludingNonCompositingDescendants();
EXPECT_TRUE(span_layer->SelfNeedsRepaint());
-
- EXPECT_FALSE(IsValidDisplayItemClient(target));
- if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
- for (auto* fragment : fragments)
- EXPECT_FALSE(IsValidDisplayItemClient(fragment));
- } else {
- EXPECT_FALSE(IsValidDisplayItemClient(span));
- EXPECT_FALSE(IsValidDisplayItemClient(text));
- }
}
TEST_F(ObjectPaintInvalidatorTest, InvalidatePaintRectangle) {
diff --git a/chromium/third_party/blink/renderer/core/paint/object_painter_base.cc b/chromium/third_party/blink/renderer/core/paint/object_painter_base.cc
index 78936e5ee6b..610c819b837 100644
--- a/chromium/third_party/blink/renderer/core/paint/object_painter_base.cc
+++ b/chromium/third_party/blink/renderer/core/paint/object_painter_base.cc
@@ -563,7 +563,8 @@ void ObjectPainterBase::PaintOutlineRects(
float border_radius = GetFocusRingBorderRadius(style);
paint_info.context.DrawFocusRing(
pixel_snapped_outline_rects, style.GetOutlineStrokeWidthForFocusRing(),
- style.OutlineOffsetInt(), border_radius, min_border_width, color);
+ style.OutlineOffsetInt(), border_radius, min_border_width, color,
+ style.UsedColorScheme());
return;
}
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc b/chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc
index 34461098c5c..5a194d5b38a 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
namespace blink {
@@ -31,6 +32,9 @@ void SetUpHTML(PaintAndRasterInvalidationTest& test) {
.solid {
background: blue;
}
+ .translucent {
+ background: rgba(0, 0, 255, 0.5);
+ }
.gradient {
background-image: linear-gradient(blue, yellow);
}
@@ -382,6 +386,8 @@ TEST_P(PaintAndRasterInvalidationTest, CompositedLayoutViewGradientResize) {
}
TEST_P(PaintAndRasterInvalidationTest, NonCompositedLayoutViewResize) {
+ ScopedPreferNonCompositedScrollingForTest non_composited_scrolling(true);
+
SetBodyInnerHTML(R"HTML(
<style>
body { margin: 0 }
@@ -458,6 +464,8 @@ TEST_P(PaintAndRasterInvalidationTest, FullInvalidationWithHTMLTransform) {
}
TEST_P(PaintAndRasterInvalidationTest, NonCompositedLayoutViewGradientResize) {
+ ScopedPreferNonCompositedScrollingForTest non_composited_scrolling(true);
+
SetBodyInnerHTML(R"HTML(
<style>
body { margin: 0 }
@@ -640,7 +648,8 @@ TEST_P(PaintAndRasterInvalidationTest,
SetUpHTML(*this);
Element* target = GetDocument().getElementById("target");
auto* object = target->GetLayoutObject();
- target->setAttribute(html_names::kClassAttr, "solid local-attachment scroll");
+ target->setAttribute(html_names::kClassAttr,
+ "translucent local-attachment scroll");
target->setInnerHTML(
"<div id=child style='width: 500px; height: 500px'></div>",
ASSERT_NO_EXCEPTION);
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc b/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc
index 593e66c86fc..f4e07991151 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc
@@ -32,12 +32,17 @@ TEST_P(PaintControllerPaintTest, FullDocumentPaintingWithCaret) {
GetDocument().GetPage()->GetFocusController().SetActive(true);
GetDocument().GetPage()->GetFocusController().SetFocused(true);
auto& div = *To<Element>(GetDocument().body()->firstChild());
- InlineTextBox& text_inline_box =
- *ToLayoutText(div.firstChild()->GetLayoutObject())->FirstTextBox();
+ auto& layout_text = *To<Text>(div.firstChild())->GetLayoutObject();
+ const DisplayItemClient* text_inline_box = layout_text.FirstTextBox();
+ if (layout_text.IsInLayoutNGInlineFormattingContext()) {
+ NGInlineCursor cursor;
+ cursor.MoveTo(layout_text);
+ text_inline_box = cursor.Current().GetDisplayItemClient();
+ }
EXPECT_THAT(RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
kDocumentBackgroundType),
- IsSameId(&text_inline_box, kForegroundType)));
+ IsSameId(text_inline_box, kForegroundType)));
div.focus();
UpdateAllLifecyclePhasesForTest();
@@ -46,7 +51,7 @@ TEST_P(PaintControllerPaintTest, FullDocumentPaintingWithCaret) {
RootPaintController().GetDisplayItemList(),
ElementsAre(
IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType),
- IsSameId(&text_inline_box, kForegroundType),
+ IsSameId(text_inline_box, kForegroundType),
// New!
IsSameId(&CaretDisplayItemClientForTesting(), DisplayItem::kCaret)));
}
@@ -60,16 +65,19 @@ TEST_P(PaintControllerPaintTest, InlineRelayout) {
*To<LayoutBlock>(GetDocument().body()->firstChild()->GetLayoutObject());
LayoutText& text = *ToLayoutText(div_block.FirstChild());
const DisplayItemClient* first_text_box = text.FirstTextBox();
+ wtf_size_t first_text_box_fragment_id = 0;
if (text.IsInLayoutNGInlineFormattingContext()) {
NGInlineCursor cursor;
cursor.MoveTo(text);
first_text_box = cursor.Current().GetDisplayItemClient();
+ first_text_box_fragment_id = cursor.Current().FragmentId();
}
EXPECT_THAT(RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
kDocumentBackgroundType),
- IsSameId(first_text_box, kForegroundType)));
+ IsSameId(first_text_box, kForegroundType,
+ first_text_box_fragment_id)));
div.setAttribute(html_names::kStyleAttr, "width: 10px; height: 200px");
UpdateAllLifecyclePhasesForTest();
@@ -77,6 +85,7 @@ TEST_P(PaintControllerPaintTest, InlineRelayout) {
LayoutText& new_text = *ToLayoutText(div_block.FirstChild());
const DisplayItemClient* new_first_text_box = text.FirstTextBox();
const DisplayItemClient* second_text_box = nullptr;
+ wtf_size_t second_text_box_fragment_id = 0;
if (!text.IsInLayoutNGInlineFormattingContext()) {
second_text_box = new_text.FirstTextBox()->NextForSameLayoutObject();
} else {
@@ -85,13 +94,16 @@ TEST_P(PaintControllerPaintTest, InlineRelayout) {
new_first_text_box = cursor.Current().GetDisplayItemClient();
cursor.MoveToNextForSameLayoutObject();
second_text_box = cursor.Current().GetDisplayItemClient();
+ second_text_box_fragment_id = cursor.Current().FragmentId();
}
EXPECT_THAT(RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
kDocumentBackgroundType),
- IsSameId(new_first_text_box, kForegroundType),
- IsSameId(second_text_box, kForegroundType)));
+ IsSameId(new_first_text_box, kForegroundType,
+ first_text_box_fragment_id),
+ IsSameId(second_text_box, kForegroundType,
+ second_text_box_fragment_id)));
}
TEST_P(PaintControllerPaintTest, ChunkIdClientCacheFlag) {
@@ -310,6 +322,9 @@ TEST_P(PaintControllerPaintTestForCAP, ScrollHitTestOrder) {
ElementsAre(
IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType),
IsSameId(&container, kBackgroundType),
+ IsSameId(&container.GetScrollableArea()
+ ->GetScrollingBackgroundDisplayItemClient(),
+ kBackgroundType),
IsSameId(&child, kBackgroundType)));
HitTestData view_scroll_hit_test;
view_scroll_hit_test.scroll_translation =
@@ -340,10 +355,9 @@ TEST_P(PaintControllerPaintTestForCAP, ScrollHitTestOrder) {
PaintChunk::Id(container, DisplayItem::kScrollHitTest),
container.FirstFragment().LocalBorderBoxProperties(),
&container_scroll_hit_test, IntRect(0, 0, 200, 200)),
- IsPaintChunk(
- 2, 3,
- PaintChunk::Id(container, kClippedContentsBackgroundChunkType),
- container.FirstFragment().ContentsProperties())));
+ IsPaintChunk(2, 4,
+ PaintChunk::Id(container, kScrollingBackgroundChunkType),
+ container.FirstFragment().ContentsProperties())));
}
TEST_P(PaintControllerPaintTestForCAP, NonStackingScrollHitTestOrder) {
@@ -385,6 +399,9 @@ TEST_P(PaintControllerPaintTestForCAP, NonStackingScrollHitTestOrder) {
IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType),
IsSameId(&neg_z_child, kBackgroundType),
IsSameId(&container, kBackgroundType),
+ IsSameId(&container.GetScrollableArea()
+ ->GetScrollingBackgroundDisplayItemClient(),
+ kBackgroundType),
IsSameId(&child, kBackgroundType),
IsSameId(&pos_z_child, kBackgroundType)));
HitTestData container_scroll_hit_test;
@@ -413,12 +430,11 @@ TEST_P(PaintControllerPaintTestForCAP, NonStackingScrollHitTestOrder) {
PaintChunk::Id(container, DisplayItem::kScrollHitTest),
container.FirstFragment().LocalBorderBoxProperties(),
&container_scroll_hit_test, IntRect(0, 0, 200, 200)),
+ IsPaintChunk(3, 5,
+ PaintChunk::Id(container, kScrollingBackgroundChunkType),
+ container.FirstFragment().ContentsProperties()),
IsPaintChunk(
- 3, 4,
- PaintChunk::Id(container, kClippedContentsBackgroundChunkType),
- container.FirstFragment().ContentsProperties()),
- IsPaintChunk(
- 4, 5,
+ 5, 6,
PaintChunk::Id(*pos_z_child.Layer(), DisplayItem::kLayerChunk),
pos_z_child.FirstFragment().LocalBorderBoxProperties())));
}
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_event.h b/chromium/third_party/blink/renderer/core/paint/paint_event.h
index 02962212e7f..72a6100b094 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_event.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_event.h
@@ -11,9 +11,11 @@ namespace blink {
// SwapPromise swap times for.
enum class PaintEvent {
kFirstPaint,
+ kFirstPaintAfterBackForwardCacheRestore,
kFirstContentfulPaint,
kProvisionalFirstMeaningfulPaint,
kFirstImagePaint,
+ kPortalActivatedPaint,
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc b/chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc
index 12031a700f8..a05cd364f3a 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc
@@ -202,7 +202,7 @@ void PaintInvalidator::UpdatePaintInvalidationContainer(
if (object.IsPaintInvalidationContainer()) {
context.paint_invalidation_container = ToLayoutBoxModelObject(&object);
- if (object.StyleRef().IsStackingContext() || object.IsSVGRoot())
+ if (object.IsStackingContext() || object.IsSVGRoot())
context.paint_invalidation_container_for_stacked_contents =
ToLayoutBoxModelObject(&object);
} else if (IsA<LayoutView>(object)) {
@@ -223,7 +223,7 @@ void PaintInvalidator::UpdatePaintInvalidationContainer(
// check can be removed as floats will be painted by the correct layer.
context.paint_invalidation_container =
&object.ContainerForPaintInvalidation();
- } else if (object.StyleRef().IsStacked() &&
+ } else if (object.IsStacked() &&
// This is to exclude some objects (e.g. LayoutText) inheriting
// stacked style from parent but aren't actually stacked.
object.HasLayer() &&
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer.cc
index 5d77cf4adbb..d02b46d6f68 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -164,7 +164,6 @@ PaintLayer::PaintLayer(LayoutBoxModelObject& layout_object)
previous_paint_result_(kFullyPainted),
needs_paint_phase_descendant_outlines_(false),
needs_paint_phase_float_(false),
- has_descendant_with_clip_path_(false),
has_non_isolated_descendant_with_blend_mode_(false),
has_fixed_position_descendant_(false),
has_sticky_position_descendant_(false),
@@ -564,7 +563,8 @@ void PaintLayer::MapPointInPaintInvalidationContainerToBacking(
return;
GraphicsLayer* squashing_layer =
- paint_invalidation_layer->GroupedMapping()->SquashingLayer();
+ paint_invalidation_layer->GroupedMapping()->SquashingLayer(
+ *paint_invalidation_layer);
PropertyTreeState source_state =
paint_invalidation_container.FirstFragment().LocalBorderBoxProperties();
@@ -580,31 +580,6 @@ void PaintLayer::MapPointInPaintInvalidationContainerToBacking(
point -= PhysicalOffset(squashing_layer->GetOffsetFromTransformNode());
}
-void PaintLayer::MapQuadInPaintInvalidationContainerToBacking(
- const LayoutBoxModelObject& paint_invalidation_container,
- FloatQuad& quad) {
- PaintLayer* paint_invalidation_layer = paint_invalidation_container.Layer();
- if (!paint_invalidation_layer->GroupedMapping())
- return;
-
- GraphicsLayer* squashing_layer =
- paint_invalidation_layer->GroupedMapping()->SquashingLayer();
-
- PropertyTreeState source_state =
- paint_invalidation_container.FirstFragment().LocalBorderBoxProperties();
- PropertyTreeState dest_state = squashing_layer->GetPropertyTreeState();
-
- // Move the rect into the source_state transform space, map to dest_state
- // transform space, then move into squashing layer state.
- quad.Move(
- FloatSize(paint_invalidation_container.FirstFragment().PaintOffset()));
- GeometryMapper::SourceToDestinationProjection(source_state.Transform(),
- dest_state.Transform())
- .MapQuad(quad);
- quad.Move(
- -ToFloatSize(FloatPoint(squashing_layer->GetOffsetFromTransformNode())));
-}
-
void PaintLayer::DirtyVisibleContentStatus() {
MarkAncestorChainForFlagsUpdate();
// Non-self-painting layers paint into their ancestor layer, and count as part
@@ -637,7 +612,6 @@ void PaintLayer::UpdateDescendantDependentFlags() {
has_non_isolated_descendant_with_blend_mode_;
has_visible_descendant_ = false;
has_non_isolated_descendant_with_blend_mode_ = false;
- has_descendant_with_clip_path_ = false;
has_fixed_position_descendant_ = false;
has_sticky_position_descendant_ = false;
has_non_contained_absolute_position_descendant_ = false;
@@ -667,13 +641,10 @@ void PaintLayer::UpdateDescendantDependentFlags() {
has_visible_descendant_ = true;
has_non_isolated_descendant_with_blend_mode_ |=
- (!child_style.IsStackingContext() &&
+ (!child->GetLayoutObject().IsStackingContext() &&
child->HasNonIsolatedDescendantWithBlendMode()) ||
child_style.HasBlendMode();
- has_descendant_with_clip_path_ |= child->HasDescendantWithClipPath() ||
- child->GetLayoutObject().HasClipPath();
-
has_fixed_position_descendant_ |=
child->HasFixedPositionDescendant() ||
child_style.GetPosition() == EPosition::kFixed;
@@ -688,9 +659,9 @@ void PaintLayer::UpdateDescendantDependentFlags() {
}
if (!has_stacked_descendant_in_current_stacking_context_) {
- if (child_style.IsStacked()) {
+ if (child->GetLayoutObject().IsStacked()) {
has_stacked_descendant_in_current_stacking_context_ = true;
- } else if (!child_style.IsStackingContext()) {
+ } else if (!child->GetLayoutObject().IsStackingContext()) {
has_stacked_descendant_in_current_stacking_context_ =
child->has_stacked_descendant_in_current_stacking_context_;
}
@@ -959,7 +930,7 @@ PhysicalOffset PaintLayer::ComputeOffsetFromAncestor(
PaintLayer* PaintLayer::CompositingContainer() const {
if (IsReplacedNormalFlowStacking())
return Parent();
- if (!GetLayoutObject().StyleRef().IsStacked()) {
+ if (!GetLayoutObject().IsStacked()) {
if (IsSelfPaintingLayer() || GetLayoutObject().IsColumnSpanAll())
return Parent();
return ContainingLayer();
@@ -970,7 +941,7 @@ PaintLayer* PaintLayer::CompositingContainer() const {
PaintLayer* PaintLayer::AncestorStackingContext() const {
for (PaintLayer* ancestor = Parent(); ancestor;
ancestor = ancestor->Parent()) {
- if (ancestor->GetLayoutObject().StyleRef().IsStackingContext())
+ if (ancestor->GetLayoutObject().IsStackingContext())
return ancestor;
}
return nullptr;
@@ -1048,6 +1019,11 @@ void PaintLayer::SetNeedsCompositingInputsUpdate(bool mark_ancestor_flags) {
MarkAncestorChainForFlagsUpdate(NeedsDescendantDependentUpdate);
}
+void PaintLayer::SetNeedsGraphicsLayerRebuild() {
+ if (Compositor())
+ Compositor()->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree);
+}
+
void PaintLayer::SetNeedsVisualOverflowRecalc() {
DCHECK(IsSelfPaintingLayer());
needs_visual_overflow_recalc_ = true;
@@ -1228,14 +1204,13 @@ void PaintLayer::AddChild(PaintLayer* child, PaintLayer* before_child) {
SetNeedsCompositingInputsUpdate();
- const ComputedStyle& child_style = child->GetLayoutObject().StyleRef();
-
if (Compositor()) {
- if (!child_style.IsStacked() && !GetLayoutObject().DocumentBeingDestroyed())
+ if (!child->GetLayoutObject().IsStacked() &&
+ !GetLayoutObject().DocumentBeingDestroyed())
Compositor()->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree);
}
- if (child_style.IsStacked() || child->FirstChild()) {
+ if (child->GetLayoutObject().IsStacked() || child->FirstChild()) {
// Dirty the z-order list in which we are contained. The
// ancestorStackingContextNode() can be null in the case where we're
// building up generated content layers. This is ok, since the lists will
@@ -1273,12 +1248,9 @@ void PaintLayer::RemoveChild(PaintLayer* old_child) {
if (last_ == old_child)
last_ = old_child->PreviousSibling();
- const ComputedStyle& old_child_style =
- old_child->GetLayoutObject().StyleRef();
-
if (!GetLayoutObject().DocumentBeingDestroyed()) {
if (Compositor()) {
- if (!old_child_style.IsStacked())
+ if (!old_child->GetLayoutObject().IsStacked())
Compositor()->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree);
if (Compositor()->GetCompositingInputsRoot() == old_child)
@@ -1317,7 +1289,7 @@ void PaintLayer::RemoveOnlyThisLayerAfterStyleChange(
if (!parent_)
return;
- if (old_style && old_style->IsStacked())
+ if (old_style && GetLayoutObject().IsStacked(*old_style))
DirtyStackingContextZOrderLists();
bool did_set_paint_invalidation = false;
@@ -1392,10 +1364,10 @@ void PaintLayer::InsertOnlyThisLayerAfterStyleChange() {
bool did_set_paint_invalidation = false;
if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
!IsA<LayoutView>(GetLayoutObject()) && GetLayoutObject().IsRooted() &&
- GetLayoutObject().StyleRef().IsStacked()) {
+ GetLayoutObject().IsStacked()) {
const LayoutBoxModelObject& previous_paint_invalidation_container =
GetLayoutObject().Parent()->ContainerForPaintInvalidation();
- if (!previous_paint_invalidation_container.StyleRef().IsStackingContext()) {
+ if (!previous_paint_invalidation_container.IsStackingContext()) {
ObjectPaintInvalidator(GetLayoutObject())
.InvalidatePaintIncludingNonSelfPaintingLayerDescendants();
// Set needsRepaint along the original compositingContainer chain.
@@ -1527,7 +1499,7 @@ void PaintLayer::UpdateStackingNode() {
bool needs_stacking_node =
has_stacked_descendant_in_current_stacking_context_ &&
- GetLayoutObject().StyleRef().IsStackingContext();
+ GetLayoutObject().IsStackingContext();
if (needs_stacking_node != !!stacking_node_) {
if (needs_stacking_node)
@@ -2356,7 +2328,10 @@ bool PaintLayer::IsReplacedNormalFlowStacking() const {
void PaintLayer::SetNeedsCompositingLayerAssignment() {
needs_compositing_layer_assignment_ = true;
+ PropagateDescendantNeedsCompositingLayerAssignment();
+}
+void PaintLayer::PropagateDescendantNeedsCompositingLayerAssignment() {
for (PaintLayer* curr = CompositingContainer();
curr && !curr->StackingDescendantNeedsCompositingLayerAssignment();
curr = curr->CompositingContainer()) {
@@ -2595,9 +2570,9 @@ PhysicalRect PaintLayer::BoundingBoxForCompositingOverlapTest() const {
style.BackdropFilter().MapRect(FloatRect(bounding_box)));
}
- if (base::FeatureList::IsEnabled(features::kMaxOverlapBoundsForFixed) &&
- !bounding_box.IsEmpty()) {
- if (FixedToViewport()) {
+ if (FixedToViewport()) {
+ if (base::FeatureList::IsEnabled(features::kMaxOverlapBoundsForFixed) &&
+ !bounding_box.IsEmpty()) {
DCHECK_EQ(style.GetPosition(), EPosition::kFixed);
// Note that we only expand the bounding box for overlap testing when the
// fixed's containing block is the viewport. This keeps us from expanding
@@ -2786,7 +2761,7 @@ GraphicsLayer* PaintLayer::GraphicsLayerBacking(const LayoutObject* obj) const {
case kNotComposited:
return nullptr;
case kPaintsIntoGroupedBacking:
- return GroupedMapping()->SquashingLayer();
+ return GroupedMapping()->SquashingLayer(*this);
default:
return (obj != &GetLayoutObject() &&
GetCompositedLayerMapping()->ScrollingContentsLayer())
@@ -2848,13 +2823,13 @@ void PaintLayer::SetGroupedMapping(CompositedLayerMapping* grouped_mapping,
if (options == kInvalidateLayerAndRemoveFromMapping && old_grouped_mapping) {
old_grouped_mapping->SetNeedsGraphicsLayerUpdate(
kGraphicsLayerUpdateSubtree);
- old_grouped_mapping->RemoveLayerFromSquashingGraphicsLayer(this);
+ old_grouped_mapping->RemoveLayerFromSquashingGraphicsLayer(*this);
}
if (rare_data_ || grouped_mapping)
EnsureRareData().grouped_mapping = grouped_mapping;
#if DCHECK_IS_ON()
- DCHECK(!grouped_mapping ||
- grouped_mapping->VerifyLayerInSquashingVector(this));
+ if (grouped_mapping)
+ grouped_mapping->AssertInSquashedLayersVector(*this);
#endif
if (options == kInvalidateLayerAndRemoveFromMapping && grouped_mapping)
grouped_mapping->SetNeedsGraphicsLayerUpdate(kGraphicsLayerUpdateSubtree);
@@ -2896,7 +2871,7 @@ bool PaintLayer::SupportsSubsequenceCaching() const {
return false;
// Create subsequence for only stacking contexts whose painting are atomic.
- return GetLayoutObject().StyleRef().IsStackingContext();
+ return GetLayoutObject().IsStackingContext();
}
ScrollingCoordinator* PaintLayer::GetScrollingCoordinator() {
@@ -3431,20 +3406,22 @@ void PaintLayer::SetSelfNeedsRepaint() {
}
void PaintLayer::MarkCompositingContainerChainForNeedsRepaint() {
- // Need to access compositingState(). We've ensured correct flag setting when
- // compositingState() changes.
- DisableCompositingQueryAsserts disabler;
PaintLayer* layer = this;
while (true) {
- if (layer->GetCompositingState() == kPaintsIntoOwnBacking)
- return;
- if (CompositedLayerMapping* grouped_mapping = layer->GroupedMapping()) {
- // TODO(wkorman): As we clean up the CompositedLayerMapping needsRepaint
- // logic to delegate to scrollbars, we may be able to remove the line
- // below as well.
- grouped_mapping->OwningLayer().SetNeedsRepaint();
- return;
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ // Need to access compositingState(). We've ensured correct flag setting
+ // when compositingState() changes.
+ DisableCompositingQueryAsserts disabler;
+ if (layer->GetCompositingState() == kPaintsIntoOwnBacking)
+ return;
+ if (CompositedLayerMapping* grouped_mapping = layer->GroupedMapping()) {
+ // TODO(wkorman): As we clean up the CompositedLayerMapping needsRepaint
+ // logic to delegate to scrollbars, we may be able to remove the line
+ // below as well.
+ grouped_mapping->OwningLayer().SetNeedsRepaint();
+ return;
+ }
}
// For a non-self-painting layer having self-painting descendant, the
@@ -3537,18 +3514,23 @@ void PaintLayer::DirtyStackingContextZOrderLists() {
}
DisableCompositingQueryAsserts::DisableCompositingQueryAsserts()
- : disabler_(&g_compositing_query_mode, kCompositingQueriesAreAllowed) {}
+ : disabler_(&g_compositing_query_mode, kCompositingQueriesAreAllowed) {
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+}
} // namespace blink
#if DCHECK_IS_ON()
void showLayerTree(const blink::PaintLayer* layer) {
- blink::DisableCompositingQueryAsserts disabler;
if (!layer) {
LOG(ERROR) << "Cannot showLayerTree. Root is (nil)";
return;
}
+ base::Optional<blink::DisableCompositingQueryAsserts> disabler;
+ if (!blink::RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ disabler.emplace();
+
if (blink::LocalFrame* frame = layer->GetLayoutObject().GetFrame()) {
WTF::String output =
ExternalRepresentation(frame,
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer.h b/chromium/third_party/blink/renderer/core/paint/paint_layer.h
index 641f83bf27a..2abb8527540 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer.h
@@ -326,8 +326,6 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
return PixelSnappedIntSize(Size(), location);
}
- void SetSizeHackForLayoutTreeAsText(const LayoutSize& size) { size_ = size; }
-
#if DCHECK_IS_ON()
bool NeedsPositionUpdate() const { return needs_position_update_; }
#endif
@@ -354,7 +352,7 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
void UpdateTransformationMatrix();
bool IsStackingContextWithNegativeZOrderChildren() const {
- DCHECK(!stacking_node_ || GetLayoutObject().StyleRef().IsStackingContext());
+ DCHECK(!stacking_node_ || GetLayoutObject().IsStackingContext());
return stacking_node_ && !stacking_node_->NegZOrderList().IsEmpty();
}
@@ -615,9 +613,6 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
static void MapPointInPaintInvalidationContainerToBacking(
const LayoutBoxModelObject& paint_invalidation_container,
PhysicalOffset&);
- static void MapQuadInPaintInvalidationContainerToBacking(
- const LayoutBoxModelObject& paint_invalidation_container,
- FloatQuad&);
bool PaintsWithTransparency(GlobalPaintFlags global_paint_flags) const {
return IsTransparent() && !PaintsIntoOwnBacking(global_paint_flags);
@@ -819,6 +814,10 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
void SetNeedsVisualOverflowRecalc();
void SetNeedsCompositingInputsUpdate(bool mark_ancestor_flags = true);
+ // Notifies the Compositor if one exists that it should rebuild the graphics
+ // layer tree.
+ void SetNeedsGraphicsLayerRebuild();
+
// This methods marks everything from this layer up to the |ancestor| argument
// (both included).
void SetChildNeedsCompositingInputsUpdateUpToAncestor(PaintLayer* ancestor);
@@ -893,10 +892,6 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
const PaintLayer* MaskAncestor() const {
return GetAncestorDependentCompositingInputs().mask_ancestor;
}
- bool HasDescendantWithClipPath() const {
- DCHECK(!needs_descendant_dependent_flags_update_);
- return has_descendant_with_clip_path_;
- }
bool HasFixedPositionDescendant() const {
DCHECK(!needs_descendant_dependent_flags_update_);
return has_fixed_position_descendant_;
@@ -1109,6 +1104,7 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
void SetNeedsCompositingLayerAssignment();
void ClearNeedsCompositingLayerAssignment();
+ void PropagateDescendantNeedsCompositingLayerAssignment();
bool NeedsCompositingLayerAssignment() const {
return needs_compositing_layer_assignment_;
@@ -1339,7 +1335,6 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
// These bitfields are part of ancestor/descendant dependent compositing
// inputs.
- unsigned has_descendant_with_clip_path_ : 1;
unsigned has_non_isolated_descendant_with_blend_mode_ : 1;
unsigned has_fixed_position_descendant_ : 1;
unsigned has_sticky_position_descendant_ : 1;
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.cc
index 0456b7a1ad8..857904097fe 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.cc
@@ -51,7 +51,7 @@ PaintLayer* PaintLayerPaintOrderIterator::Next() {
for (; current_normal_flow_child_;
current_normal_flow_child_ =
current_normal_flow_child_->NextSibling()) {
- if (current_normal_flow_child_->GetLayoutObject().StyleRef().IsStacked())
+ if (current_normal_flow_child_->GetLayoutObject().IsStacked())
continue;
PaintLayer* normal_flow_child = current_normal_flow_child_;
@@ -94,7 +94,7 @@ PaintLayer* PaintLayerPaintOrderReverseIterator::Next() {
for (; current_normal_flow_child_;
current_normal_flow_child_ =
current_normal_flow_child_->PreviousSibling()) {
- if (current_normal_flow_child_->GetLayoutObject().StyleRef().IsStacked())
+ if (current_normal_flow_child_->GetLayoutObject().IsStacked())
continue;
PaintLayer* normal_flow_child = current_normal_flow_child_;
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.cc
index 09b97a19387..e68cb5c2e41 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.cc
@@ -233,12 +233,6 @@ void PaintLayerPainter::AdjustForPaintProperties(
painting_info.root_layer->GetLayoutObject().FirstFragment();
const auto* source_transform =
&first_root_fragment.LocalBorderBoxProperties().Transform();
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
- IsMainFrameNotClippingContents(*painting_info.root_layer)) {
- // Use PostScrollTranslation as the source transform to avoid clipping of
- // the scrolling contents in CullRect::ApplyTransforms().
- source_transform = &first_root_fragment.PostScrollTranslation();
- }
const auto& destination_transform =
first_fragment.LocalBorderBoxProperties().Transform();
if (source_transform == &destination_transform)
@@ -255,14 +249,18 @@ void PaintLayerPainter::AdjustForPaintProperties(
// Convert old_cull_rect into the layer's transform space.
old_cull_rect->MoveBy(RoundedIntPoint(first_fragment.PaintOffset()));
}
-
- // Don't clip to the view scrolling container when printing because we
- // need to print the whole document.
- bool clip_to_scroll_container =
- !(context.Printing() &&
- (paint_flags & kPaintLayerPaintingOverflowContents));
+ if (paint_flags & kPaintLayerPaintingOverflowContents) {
+ // Use PostScrollTranslation as the source transform to avoid clipping
+ // of the scrolling contents in CullRect::ApplyTransforms().
+ source_transform = &first_root_fragment.PostScrollTranslation();
+ // Map cull_rect into scrolling contents space (i.e. source_transform).
+ if (const auto* properties = first_root_fragment.PaintProperties()) {
+ if (const auto* scroll_translation = properties->ScrollTranslation())
+ cull_rect.Move(-scroll_translation->Translation2D());
+ }
+ }
cull_rect.ApplyTransforms(*source_transform, destination_transform,
- old_cull_rect, clip_to_scroll_container);
+ old_cull_rect);
// Convert cull_rect from the layer's transform space to the layer's local
// space.
cull_rect.MoveBy(-RoundedIntPoint(first_fragment.PaintOffset()));
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_painting_info.h b/chromium/third_party/blink/renderer/core/paint/paint_layer_painting_info.h
index 397525ff3c7..2cd173d8695 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_painting_info.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_painting_info.h
@@ -45,7 +45,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_LAYER_PAINTING_INFO_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_LAYER_PAINTING_INFO_H_
-#include "base/logging.h"
+#include "base/check_op.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_offset.h"
#include "third_party/blink/renderer/core/paint/paint_phase.h"
#include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h"
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
index 3255f724c37..595fd20ad05 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -254,7 +254,7 @@ void PaintLayerScrollableArea::ApplyPendingHistoryRestoreScrollOffset() {
pending_view_state_.reset();
}
-void PaintLayerScrollableArea::Trace(Visitor* visitor) {
+void PaintLayerScrollableArea::Trace(Visitor* visitor) const {
visitor->Trace(scrollbar_manager_);
visitor->Trace(scroll_anchor_);
visitor->Trace(scrolling_background_display_item_client_);
@@ -314,6 +314,9 @@ GraphicsLayer* PaintLayerScrollableArea::GraphicsLayerForScrolling() const {
GraphicsLayer* PaintLayerScrollableArea::GraphicsLayerForHorizontalScrollbar()
const {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return nullptr;
+
// See crbug.com/343132.
DisableCompositingQueryAsserts disabler;
@@ -326,6 +329,9 @@ GraphicsLayer* PaintLayerScrollableArea::GraphicsLayerForHorizontalScrollbar()
GraphicsLayer* PaintLayerScrollableArea::GraphicsLayerForVerticalScrollbar()
const {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return nullptr;
+
// See crbug.com/343132.
DisableCompositingQueryAsserts disabler;
@@ -335,6 +341,9 @@ GraphicsLayer* PaintLayerScrollableArea::GraphicsLayerForVerticalScrollbar()
}
GraphicsLayer* PaintLayerScrollableArea::GraphicsLayerForScrollCorner() const {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return nullptr;
+
// See crbug.com/343132.
DisableCompositingQueryAsserts disabler;
@@ -440,8 +449,8 @@ PaintLayerScrollableArea::ConvertFromScrollbarToContainingEmbeddedContentView(
IntRect rect = scrollbar_rect;
rect.Move(ScrollbarOffset(scrollbar));
-
- return view->GetFrameView()->ConvertFromLayoutObject(*GetLayoutBox(), rect);
+ return PixelSnappedIntRect(
+ GetLayoutBox()->LocalToAbsoluteRect(PhysicalRect(rect)));
}
IntPoint
@@ -454,7 +463,8 @@ PaintLayerScrollableArea::ConvertFromScrollbarToContainingEmbeddedContentView(
IntPoint point = scrollbar_point;
point.Move(ScrollbarOffset(scrollbar));
- return view->GetFrameView()->ConvertFromLayoutObject(*GetLayoutBox(), point);
+ return RoundedIntPoint(
+ GetLayoutBox()->LocalToAbsolutePoint(PhysicalOffset(point)));
}
IntPoint
@@ -465,9 +475,8 @@ PaintLayerScrollableArea::ConvertFromContainingEmbeddedContentViewToScrollbar(
if (!view)
return parent_point;
- IntPoint point = view->GetFrameView()->ConvertToLayoutObject(*GetLayoutBox(),
- parent_point);
-
+ IntPoint point(RoundedIntPoint(
+ GetLayoutBox()->AbsoluteToLocalPoint(PhysicalOffset(parent_point))));
point.Move(-ScrollbarOffset(scrollbar));
return point;
}
@@ -511,10 +520,6 @@ void PaintLayerScrollableArea::UpdateScrollOffset(
TRACE_EVENT1("devtools.timeline", "ScrollLayer", "data",
inspector_scroll_layer_event::Data(GetLayoutBox()));
- // FIXME(420741): Resolve circular dependency between scroll offset and
- // compositing state, and remove this disabler.
- DisableCompositingQueryAsserts disabler;
-
// Update the positions of our child layers (if needed as only fixed layers
// should be impacted by a scroll).
if (!frame_view->IsInPerformLayout()) {
@@ -1119,10 +1124,6 @@ void PaintLayerScrollableArea::UpdateAfterLayout() {
// the data changes, then this will try to re-snap.
SetSnapContainerDataNeedsUpdate(true);
{
- // Hits in
- // compositing/overflow/automatically-opt-into-composited-scrolling-after-style-change.html.
- DisableCompositingQueryAsserts disabler;
-
UpdateScrollbarEnabledState();
UpdateScrollbarProportions();
@@ -1134,7 +1135,6 @@ void PaintLayerScrollableArea::UpdateAfterLayout() {
UpdateScrollableAreaSet();
}
- DisableCompositingQueryAsserts disabler;
PositionOverflowControls();
}
@@ -1474,7 +1474,7 @@ int PaintLayerScrollableArea::HypotheticalScrollbarThickness(
style_source.StyleRef().HasPseudoElementStyle(kPseudoIdScrollbar);
if (has_custom_scrollbar_style) {
return CustomScrollbar::HypotheticalScrollbarThickness(
- orientation, *GetLayoutBox(), style_source);
+ this, orientation, To<Element>(style_source.GetNode()));
}
ScrollbarControlSize scrollbar_size = kRegularScrollbar;
@@ -1864,23 +1864,44 @@ void PaintLayerScrollableArea::PositionOverflowControls() {
if (!HasOverflowControls())
return;
- if (Scrollbar* vertical_scrollbar = VerticalScrollbar())
+ if (Scrollbar* vertical_scrollbar = VerticalScrollbar()) {
vertical_scrollbar->SetFrameRect(RectForVerticalScrollbar());
+ if (auto* custom_scrollbar = DynamicTo<CustomScrollbar>(vertical_scrollbar))
+ custom_scrollbar->PositionScrollbarParts();
+ }
- if (Scrollbar* horizontal_scrollbar = HorizontalScrollbar())
+ if (Scrollbar* horizontal_scrollbar = HorizontalScrollbar()) {
horizontal_scrollbar->SetFrameRect(RectForHorizontalScrollbar());
+ if (auto* custom_scrollbar =
+ DynamicTo<CustomScrollbar>(horizontal_scrollbar))
+ custom_scrollbar->PositionScrollbarParts();
+ }
- if (scroll_corner_)
- scroll_corner_->SetFrameRect(LayoutRect(ScrollCornerRect()));
+ if (scroll_corner_) {
+ LayoutRect rect(ScrollCornerRect());
+ scroll_corner_->SetFrameRect(rect);
+ // TODO(crbug.com/1020913): This should be part of PaintPropertyTreeBuilder
+ // when we support subpixel layout of overflow controls.
+ scroll_corner_->GetMutableForPainting().FirstFragment().SetPaintOffset(
+ PhysicalOffset(rect.Location()));
+ }
- if (resizer_)
- resizer_->SetFrameRect(LayoutRect(ResizerCornerRect(kResizerForPointer)));
+ if (resizer_) {
+ LayoutRect rect(ResizerCornerRect(kResizerForPointer));
+ resizer_->SetFrameRect(rect);
+ // TODO(crbug.com/1020913): This should be part of PaintPropertyTreeBuilder
+ // when we support subpixel layout of overflow controls.
+ resizer_->GetMutableForPainting().FirstFragment().SetPaintOffset(
+ PhysicalOffset(rect.Location()));
+ }
// FIXME, this should eventually be removed, once we are certain that
// composited controls get correctly positioned on a compositor update. For
// now, conservatively leaving this unchanged.
- if (Layer()->HasCompositedLayerMapping())
+ if (Layer()->HasCompositedLayerMapping()) {
+ DisableCompositingQueryAsserts disabler;
Layer()->GetCompositedLayerMapping()->PositionOverflowControlsLayers();
+ }
}
void PaintLayerScrollableArea::UpdateScrollCornerStyle() {
@@ -2360,6 +2381,7 @@ void PaintLayerScrollableArea::UpdateScrollableAreaSet() {
void PaintLayerScrollableArea::UpdateCompositingLayersAfterScroll() {
DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+ DisableCompositingQueryAsserts disabler;
PaintLayerCompositor* compositor = GetLayoutBox()->View()->Compositor();
if (!compositor || !compositor->InCompositingMode())
return;
@@ -2509,7 +2531,8 @@ bool PaintLayerScrollableArea::ComputeNeedsCompositedScrollingInternal(
}
if (!force_prefer_compositing_to_lcd_text &&
- !LayerNodeMayNeedCompositedScrolling(layer_)) {
+ (RuntimeEnabledFeatures::PreferNonCompositedScrollingEnabled() ||
+ !LayerNodeMayNeedCompositedScrolling(layer_))) {
return false;
}
@@ -2525,36 +2548,20 @@ bool PaintLayerScrollableArea::ComputeNeedsCompositedScrollingInternal(
cc::MainThreadScrollingReason::kHasTransformAndLCDText;
needs_composited_scrolling = false;
}
- if (!layer_->BackgroundIsKnownToBeOpaqueInRect(
- box->PhysicalPaddingBoxRect(), true)) {
+ if (!box->TextIsKnownToBeOnOpaqueBackground()) {
non_composited_main_thread_scrolling_reasons_ |=
- cc::MainThreadScrollingReason::kBackgroundNotOpaqueInRectAndLCDText;
- needs_composited_scrolling = false;
- }
- if (!box->StyleRef().IsStackingContext()) {
- non_composited_main_thread_scrolling_reasons_ |=
- cc::MainThreadScrollingReason::kIsNotStackingContextAndLCDText;
+ cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText;
needs_composited_scrolling = false;
}
if (!(background_paint_location_if_composited &
kBackgroundPaintInScrollingContents) &&
box->StyleRef().HasBackground()) {
- non_composited_main_thread_scrolling_reasons_ |=
- cc::MainThreadScrollingReason::kCantPaintScrollingBackground;
+ non_composited_main_thread_scrolling_reasons_ |= cc::
+ MainThreadScrollingReason::kCantPaintScrollingBackgroundAndLCDText;
needs_composited_scrolling = false;
}
}
- // TODO(crbug.com/645957): We may remove this condition. This is also
- // duplicate and inconsistent with the condition in
- // LayoutBoxModelObject::ComputeBackgroundPaintLocationIfComposited().
- if (box->HasClip() || layer_->HasDescendantWithClipPath() ||
- !!layer_->ClipPathAncestor()) {
- non_composited_main_thread_scrolling_reasons_ |=
- cc::MainThreadScrollingReason::kHasClipRelatedProperty;
- needs_composited_scrolling = false;
- }
-
DCHECK(!(non_composited_main_thread_scrolling_reasons_ &
~cc::MainThreadScrollingReason::kNonCompositedReasons));
return needs_composited_scrolling;
@@ -2622,9 +2629,6 @@ Vector<IntRect> PaintLayerScrollableArea::GetTickmarks() const {
void PaintLayerScrollableArea::ScrollbarManager::SetHasHorizontalScrollbar(
bool has_scrollbar) {
if (has_scrollbar) {
- // This doesn't hit in any tests, but since the equivalent code in
- // setHasVerticalScrollbar does, presumably this code does as well.
- DisableCompositingQueryAsserts disabler;
if (!h_bar_) {
h_bar_ = CreateScrollbar(kHorizontalScrollbar);
h_bar_is_attached_ = 1;
@@ -2643,7 +2647,6 @@ void PaintLayerScrollableArea::ScrollbarManager::SetHasHorizontalScrollbar(
void PaintLayerScrollableArea::ScrollbarManager::SetHasVerticalScrollbar(
bool has_scrollbar) {
if (has_scrollbar) {
- DisableCompositingQueryAsserts disabler;
if (!v_bar_) {
v_bar_ = CreateScrollbar(kVerticalScrollbar);
v_bar_is_attached_ = 1;
@@ -2735,7 +2738,7 @@ void PaintLayerScrollableArea::ScrollbarManager::Dispose() {
}
void PaintLayerScrollableArea::ScrollbarManager::Trace(
- blink::Visitor* visitor) {
+ blink::Visitor* visitor) const {
visitor->Trace(scrollable_area_);
visitor->Trace(h_bar_);
visitor->Trace(v_bar_);
@@ -3021,13 +3024,13 @@ void PaintLayerScrollableArea::InvalidatePaintOfScrollControlsIfNeeded(
SetScrollCornerAndResizerVisualRect(scroll_corner_and_resizer_visual_rect);
if (LayoutCustomScrollbarPart* scroll_corner = ScrollCorner()) {
ObjectPaintInvalidator(*scroll_corner)
- .InvalidateDisplayItemClientsIncludingNonCompositingDescendants(
- PaintInvalidationReason::kScrollControl);
+ .SlowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(
+ *scroll_corner, PaintInvalidationReason::kScrollControl);
}
if (LayoutCustomScrollbarPart* resizer = Resizer()) {
ObjectPaintInvalidator(*resizer)
- .InvalidateDisplayItemClientsIncludingNonCompositingDescendants(
- PaintInvalidationReason::kScrollControl);
+ .SlowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(
+ *resizer, PaintInvalidationReason::kScrollControl);
}
if (!GraphicsLayerForScrollCorner()) {
context.painting_layer->SetNeedsRepaint();
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
index afe17a03130..9fa418d2978 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -165,7 +165,7 @@ class CORE_EXPORT PaintLayerScrollableArea final
void DestroyDetachedScrollbars();
void Dispose();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Scrollbar* CreateScrollbar(ScrollbarOrientation);
@@ -566,7 +566,7 @@ class CORE_EXPORT PaintLayerScrollableArea final
bool HasHorizontalOverflow() const;
bool HasVerticalOverflow() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const DisplayItemClient& GetScrollingBackgroundDisplayItemClient() const {
return scrolling_background_display_item_client_;
@@ -777,7 +777,7 @@ class CORE_EXPORT PaintLayerScrollableArea final
const PaintLayerScrollableArea& scrollable_area)
: scrollable_area_(&scrollable_area) {}
- void Trace(Visitor* visitor) { visitor->Trace(scrollable_area_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(scrollable_area_); }
private:
IntRect VisualRect() const final;
@@ -795,7 +795,7 @@ class CORE_EXPORT PaintLayerScrollableArea final
const PaintLayerScrollableArea& scrollable_area)
: scrollable_area_(&scrollable_area) {}
- void Trace(Visitor* visitor) { visitor->Trace(scrollable_area_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(scrollable_area_); }
private:
IntRect VisualRect() const final;
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
index 000716d5f62..ca3aabfef41 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
@@ -194,7 +194,7 @@ TEST_P(PaintLayerScrollableAreaTest,
outline-offset: -2px;'>
<div class='spacer'></div>
</div>
- <div id='scroller16' class='scroller' style='position: absolute;
+ <div id='css-clip' class='scroller' style='position: absolute;
background: white; clip: rect(0px,10px,10px,0px);'>
<div class='spacer'></div>
</div>
@@ -300,11 +300,9 @@ TEST_P(PaintLayerScrollableAreaTest,
EXPECT_EQ(kBackgroundPaintInScrollingContents,
GetBackgroundPaintLocation("scroller15"));
- // #scroller16 cannot paint background into scrolling contents layer because
- // the scroller has a clip which would not be respected by the scrolling
- // contents layer.
- EXPECT_EQ(kBackgroundPaintInGraphicsLayer,
- GetBackgroundPaintLocation("scroller16"));
+ // css-clip doesn't affect background paint location.
+ EXPECT_EQ(kBackgroundPaintInScrollingContents,
+ GetBackgroundPaintLocation("css-clip"));
// #scroller17 can only be painted once as it is translucent, and it must
// be painted in the graphics layer to be under the translucent border.
@@ -346,10 +344,7 @@ TEST_P(PaintLayerScrollableAreaTest, OpaqueContainedLayersPromoted) {
EXPECT_TRUE(GraphicsLayerContentsOpaque(scroller));
}
-// Tests that we don't promote scrolling content which would not be contained.
-// Promoting the scroller would also require promoting the positioned div
-// which would lose subpixel anti-aliasing due to its transparent background.
-TEST_P(PaintLayerScrollableAreaTest, NonContainedLayersNotPromoted) {
+TEST_P(PaintLayerScrollableAreaTest, NonStackingContextScrollerPromoted) {
SetBodyInnerHTML(R"HTML(
<style>
#scroller { overflow: scroll; height: 200px; width: 200px;
@@ -364,7 +359,7 @@ TEST_P(PaintLayerScrollableAreaTest, NonContainedLayersNotPromoted) {
</div>
)HTML");
- EXPECT_FALSE(UsesCompositedScrolling(GetLayoutObjectByElementId("scroller")));
+ EXPECT_TRUE(UsesCompositedScrolling(GetLayoutObjectByElementId("scroller")));
}
TEST_P(PaintLayerScrollableAreaTest, TransparentLayersNotPromoted) {
@@ -646,35 +641,6 @@ TEST_P(PaintLayerScrollableAreaTest, OverlayScrollbarColorThemeUpdated) {
black_layer->GetScrollableArea()->GetScrollbarOverlayColorTheme());
}
-// Test that css clip applied to the scroller will cause the
-// scrolling contents layer to not be promoted.
-TEST_P(PaintLayerScrollableAreaTest,
- OnlyAutoClippedScrollingContentsLayerPromoted) {
- SetBodyInnerHTML(R"HTML(
- <style>
- .clip { clip: rect(0px,60px,50px,0px); }
- #scroller { position: absolute; overflow: auto;
- height: 100px; width: 100px; background: grey;
- will-change:transform; }
- #scrolled { height: 300px; }
- </style>
- <div id="scroller"><div id="scrolled"></div></div>
- )HTML");
-
- Element* scroller = GetDocument().getElementById("scroller");
- EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject()));
-
- // Add clip to scroller.
- scroller->setAttribute(html_names::kClassAttr, "clip");
- UpdateAllLifecyclePhasesForTest();
- EXPECT_FALSE(UsesCompositedScrolling(scroller->GetLayoutObject()));
-
- // Change the scroller to be auto clipped again.
- scroller->removeAttribute("class");
- UpdateAllLifecyclePhasesForTest();
- EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject()));
-}
-
TEST_P(PaintLayerScrollableAreaTest, HideTooltipWhenScrollPositionChanges) {
SetBodyInnerHTML(R"HTML(
<style>
@@ -1005,15 +971,16 @@ TEST_P(PaintLayerScrollableAreaTest,
auto* scrollable_area = scroller->GetScrollableArea();
EXPECT_EQ(kBackgroundPaintInScrollingContents,
scroller->ComputeBackgroundPaintLocationIfComposited());
- EXPECT_EQ(kBackgroundPaintInGraphicsLayer,
+ EXPECT_EQ(kBackgroundPaintInScrollingContents,
scroller->GetBackgroundPaintLocation());
+ EXPECT_TRUE(UsesCompositedScrolling(scroller));
// Programmatically changing the scroll offset.
scrollable_area->SetScrollOffset(ScrollOffset(0, 1),
mojom::blink::ScrollType::kProgrammatic);
- // Full invalidation because there is no separate scrolling contents layer.
- EXPECT_TRUE(scroller->ShouldDoFullPaintInvalidation());
- EXPECT_TRUE(scroller->BackgroundNeedsFullPaintInvalidation());
+ // No paint invalidation because it uses composited scrolling.
+ EXPECT_FALSE(scroller->ShouldDoFullPaintInvalidation());
+ EXPECT_FALSE(scroller->BackgroundNeedsFullPaintInvalidation());
EXPECT_TRUE(scroller->NeedsPaintPropertyUpdate());
UpdateAllLifecyclePhasesForTest();
@@ -1044,8 +1011,9 @@ TEST_P(PaintLayerScrollableAreaTest,
EXPECT_EQ(
kBackgroundPaintInGraphicsLayer | kBackgroundPaintInScrollingContents,
scroller->ComputeBackgroundPaintLocationIfComposited());
- EXPECT_EQ(kBackgroundPaintInGraphicsLayer,
- scroller->GetBackgroundPaintLocation());
+ EXPECT_EQ(
+ kBackgroundPaintInGraphicsLayer | kBackgroundPaintInScrollingContents,
+ scroller->GetBackgroundPaintLocation());
// Programmatically changing the scroll offset.
scrollable_area->SetScrollOffset(ScrollOffset(0, 1),
@@ -1138,7 +1106,7 @@ TEST_P(PaintLayerScrollableAreaTest,
ToLayoutBox(GetLayoutObjectByElementId("fixed-background"));
EXPECT_EQ(kBackgroundPaintInScrollingContents,
fixed_background_div->ComputeBackgroundPaintLocationIfComposited());
- EXPECT_EQ(kBackgroundPaintInGraphicsLayer,
+ EXPECT_EQ(kBackgroundPaintInScrollingContents,
fixed_background_div->GetBackgroundPaintLocation());
auto* div_scrollable_area = fixed_background_div->GetScrollableArea();
auto* view_scrollable_area = GetLayoutView().GetScrollableArea();
@@ -1604,7 +1572,9 @@ class ScrollTimelineForTest : public ScrollTimeline {
}
bool Invalidated() const { return invalidated_; }
void ResetInvalidated() { invalidated_ = false; }
- void Trace(Visitor* visitor) override { ScrollTimeline::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ ScrollTimeline::Trace(visitor);
+ }
private:
bool invalidated_;
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc
index e660390d496..78e866e7a4f 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc
@@ -62,7 +62,7 @@ namespace blink {
// layer about some of its state.
PaintLayerStackingNode::PaintLayerStackingNode(PaintLayer& layer)
: layer_(layer), z_order_lists_dirty_(true) {
- DCHECK(layer.GetLayoutObject().StyleRef().IsStackingContext());
+ DCHECK(layer.GetLayoutObject().IsStackingContext());
}
PaintLayerStackingNode::~PaintLayerStackingNode() {
@@ -103,16 +103,16 @@ void PaintLayerStackingNode::DirtyZOrderLists() {
}
static bool ZIndexLessThan(const PaintLayer* first, const PaintLayer* second) {
- DCHECK(first->GetLayoutObject().StyleRef().IsStacked());
- DCHECK(second->GetLayoutObject().StyleRef().IsStacked());
- return first->GetLayoutObject().StyleRef().ZIndex() <
- second->GetLayoutObject().StyleRef().ZIndex();
+ DCHECK(first->GetLayoutObject().IsStacked());
+ DCHECK(second->GetLayoutObject().IsStacked());
+ return first->GetLayoutObject().StyleRef().EffectiveZIndex() <
+ second->GetLayoutObject().StyleRef().EffectiveZIndex();
}
static bool SetIfHigher(const PaintLayer*& first, const PaintLayer* second) {
if (!second)
return false;
- DCHECK_GE(second->GetLayoutObject().StyleRef().ZIndex(), 0);
+ DCHECK_GE(second->GetLayoutObject().StyleRef().EffectiveZIndex(), 0);
// |second| appears later in the tree, so it's higher than |first| if its
// z-index >= |first|'s z-index.
if (!first || !ZIndexLessThan(second, first)) {
@@ -158,7 +158,7 @@ struct PaintLayerStackingNode::HighestLayers {
// A negative z-index child will not cause reparent of overlay scrollbars
// because the ancestor scroller either has auto z-index which is above
// the child or has negative z-index which is a stacking context.
- if (!style.IsStacked() || style.ZIndex() < 0)
+ if (!layer.GetLayoutObject().IsStacked() || style.EffectiveZIndex() < 0)
return;
if (style.GetPosition() == EPosition::kAbsolute)
@@ -210,7 +210,7 @@ void PaintLayerStackingNode::RebuildZOrderLists() {
child = child->NextSibling()) {
auto* child_element = DynamicTo<Element>(child->GetNode());
if (child_element && child_element->IsInTopLayer() &&
- child->StyleRef().IsStacked()) {
+ child->IsStacked()) {
pos_z_order_list_.push_back(ToLayoutBoxModelObject(child)->Layer());
}
}
@@ -236,12 +236,13 @@ void PaintLayerStackingNode::CollectLayers(PaintLayer& paint_layer,
const auto& object = paint_layer.GetLayoutObject();
const auto& style = object.StyleRef();
- if (style.IsStacked()) {
- auto& list = style.ZIndex() >= 0 ? pos_z_order_list_ : neg_z_order_list_;
+ if (object.IsStacked()) {
+ auto& list =
+ style.EffectiveZIndex() >= 0 ? pos_z_order_list_ : neg_z_order_list_;
list.push_back(&paint_layer);
}
- if (style.IsStackingContext())
+ if (object.IsStackingContext())
return;
base::Optional<HighestLayers> subtree_highest_layers;
@@ -301,17 +302,20 @@ bool PaintLayerStackingNode::StyleDidChange(PaintLayer& paint_layer,
bool was_stacked = false;
int old_z_index = 0;
if (old_style) {
- was_stacking_context = old_style->IsStackingContext();
- old_z_index = old_style->ZIndex();
- was_stacked = old_style->IsStacked();
+ was_stacking_context =
+ paint_layer.GetLayoutObject().IsStackingContext(*old_style);
+ old_z_index = old_style->EffectiveZIndex();
+ was_stacked = paint_layer.GetLayoutObject().IsStacked(*old_style);
}
const ComputedStyle& new_style = paint_layer.GetLayoutObject().StyleRef();
- bool should_be_stacking_context = new_style.IsStackingContext();
- bool should_be_stacked = new_style.IsStacked();
+ bool should_be_stacking_context =
+ paint_layer.GetLayoutObject().IsStackingContext();
+ bool should_be_stacked = paint_layer.GetLayoutObject().IsStacked();
if (should_be_stacking_context == was_stacking_context &&
- was_stacked == should_be_stacked && old_z_index == new_style.ZIndex())
+ was_stacked == should_be_stacked &&
+ old_z_index == new_style.EffectiveZIndex())
return false;
// Need to force requirements update, due to change of stacking order.
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_test.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_test.cc
index 0a92e59cf2f..feb65777ad2 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_test.cc
@@ -277,8 +277,6 @@ TEST_P(PaintLayerTest, HasNonIsolatedDescendantWithBlendMode) {
EXPECT_TRUE(parent->HasNonIsolatedDescendantWithBlendMode());
EXPECT_TRUE(stacking_parent->HasNonIsolatedDescendantWithBlendMode());
EXPECT_FALSE(stacking_grandparent->HasNonIsolatedDescendantWithBlendMode());
-
- EXPECT_FALSE(parent->HasDescendantWithClipPath());
EXPECT_TRUE(parent->HasVisibleDescendant());
}
@@ -1094,23 +1092,6 @@ TEST_P(PaintLayerTest, NegativeZIndexChangeToPositive) {
PaintLayerPaintOrderIterator(*target, kPositiveZOrderChildren).Next());
}
-TEST_P(PaintLayerTest, HasDescendantWithClipPath) {
- SetBodyInnerHTML(R"HTML(
- <div id='parent' style='position:relative'>
- <div id='clip-path' style='clip-path: circle(50px at 0 100px)'>
- </div>
- </div>
- )HTML");
- PaintLayer* parent = GetPaintLayerByElementId("parent");
- PaintLayer* clip_path = GetPaintLayerByElementId("clip-path");
-
- EXPECT_TRUE(parent->HasDescendantWithClipPath());
- EXPECT_FALSE(clip_path->HasDescendantWithClipPath());
-
- EXPECT_FALSE(parent->HasNonIsolatedDescendantWithBlendMode());
- EXPECT_TRUE(parent->HasVisibleDescendant());
-}
-
TEST_P(PaintLayerTest, HasVisibleDescendant) {
SetBodyInnerHTML(R"HTML(
<div id='invisible' style='position:relative'>
@@ -1123,9 +1104,7 @@ TEST_P(PaintLayerTest, HasVisibleDescendant) {
EXPECT_TRUE(invisible->HasVisibleDescendant());
EXPECT_FALSE(visible->HasVisibleDescendant());
-
EXPECT_FALSE(invisible->HasNonIsolatedDescendantWithBlendMode());
- EXPECT_FALSE(invisible->HasDescendantWithClipPath());
}
TEST_P(PaintLayerTest, Has3DTransformedDescendant) {
@@ -1892,7 +1871,7 @@ TEST_P(PaintLayerTest, CompositingContainerSelfPaintingNonStackedFloat) {
// The target layer is self-painting, but not stacked.
PaintLayer* target = GetPaintLayerByElementId("target");
EXPECT_TRUE(target->IsSelfPaintingLayer());
- EXPECT_FALSE(target->GetLayoutObject().StyleRef().IsStacked());
+ EXPECT_FALSE(target->GetLayoutObject().IsStacked());
PaintLayer* container = GetPaintLayerByElementId("container");
PaintLayer* span = GetPaintLayerByElementId("span");
@@ -2022,7 +2001,7 @@ TEST_P(PaintLayerTest, NeedsRepaintOnRemovingStackedLayer) {
// |container| is not the CompositingContainer of |target| because |target|
// is stacked but |container| is not a stacking context.
- EXPECT_TRUE(target_layer->GetLayoutObject().StyleRef().IsStacked());
+ EXPECT_TRUE(target_layer->GetLayoutObject().IsStacked());
EXPECT_NE(body_layer, target_layer->CompositingContainer());
auto* old_compositing_container = target_layer->CompositingContainer();
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index 5249eba7361..0702a0fc65a 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -412,6 +412,13 @@ static bool NeedsPaintOffsetTranslation(
if (NeedsReplacedContentTransform(object))
return true;
+ // Reference filter and reflection (which creates a reference filter) requires
+ // zero paint offset.
+ if (box_model.HasLayer() &&
+ (object.StyleRef().Filter().HasReferenceFilter() ||
+ object.HasReflection()))
+ return true;
+
// Don't let paint offset cross composited layer boundaries, to avoid
// unnecessary full layer paint/raster invalidation when paint offset in
// ancestor transform node changes which should not affect the descendants
@@ -708,6 +715,10 @@ static CompositingReasons CompositingReasonsForTransformProperty() {
reasons |= CompositingReason::kWillChangeOpacity;
reasons |= CompositingReason::kWillChangeFilter;
reasons |= CompositingReason::kWillChangeBackdropFilter;
+
+ if (RuntimeEnabledFeatures::TransformInteropEnabled())
+ reasons |= CompositingReason::kBackfaceInvisibility3DAncestor;
+
return reasons;
}
@@ -840,6 +851,9 @@ void FragmentPaintPropertyTreeBuilder::UpdateTransform() {
}
}
+ // properties_->Transform() is present if a CSS transform is present,
+ // and is also present if transform-style: preserve-3d is set.
+ // See NeedsTransform.
if (properties_->Transform()) {
context_.current.transform = properties_->Transform();
if (object_.StyleRef().Preserves3D()) {
@@ -850,6 +864,13 @@ void FragmentPaintPropertyTreeBuilder::UpdateTransform() {
context_.current.rendering_context_id = 0;
context_.current.should_flatten_inherited_transform = true;
}
+ } else if (RuntimeEnabledFeatures::TransformInteropEnabled() &&
+ !object_.IsAnonymous()) {
+ // With kTransformInterop enabled, 3D rendering contexts follow the
+ // DOM ancestor chain, so flattening should apply regardless of
+ // presence of transform.
+ context_.current.rendering_context_id = 0;
+ context_.current.should_flatten_inherited_transform = true;
}
}
@@ -897,7 +918,7 @@ static bool NeedsEffect(const LayoutObject& object,
// don't create layer thus are not actual stacking contexts, so the HasLayer()
// condition. TODO(crbug.com/892734): Support effects for LayoutTableCol.
const bool is_css_isolated_group =
- object.HasLayer() && style.IsStackingContext();
+ object.HasLayer() && object.IsStackingContext();
if (!is_css_isolated_group && !object.IsSVG())
return false;
@@ -1218,7 +1239,6 @@ static bool NeedsFilter(const LayoutObject& object,
if (!object.IsBoxModelObject() || !ToLayoutBoxModelObject(object).Layer())
return false;
- // TODO(trchen): SVG caches filters in SVGResources. Implement it.
if (object.StyleRef().HasFilter() || object.HasReflection())
return true;
@@ -1231,7 +1251,6 @@ void FragmentPaintPropertyTreeBuilder::UpdateFilter() {
if (NeedsFilter(object_, full_context_.direct_compositing_reasons)) {
EffectPaintPropertyNode::State state;
state.local_transform_space = context_.current.transform;
- state.filters_origin = FloatPoint(context_.current.paint_offset);
if (auto* layer = ToLayoutBoxModelObject(object_).Layer()) {
// Try to use the cached filter.
@@ -1984,6 +2003,13 @@ void FragmentPaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation() {
CompositingReason::kDirectReasonsForScrollTranslationProperty;
state.rendering_context_id = context_.current.rendering_context_id;
state.scroll = properties_->Scroll();
+ // If scroll and transform are both present, we should use the
+ // transform property tree node to determine visibility of the
+ // scrolling contents.
+ if (object_.StyleRef().HasTransform() &&
+ object_.StyleRef().BackfaceVisibility() ==
+ EBackfaceVisibility::kHidden)
+ state.flags.delegates_to_parent_for_backface = true;
auto effective_change_type = properties_->UpdateScrollTranslation(
*context_.current.transform, std::move(state));
if (effective_change_type ==
@@ -2360,15 +2386,21 @@ void FragmentPaintPropertyTreeBuilder::UpdatePaintOffset() {
box_model_object.OffsetForInFlowPosition();
break;
case EPosition::kAbsolute: {
+ // TODO(almaher): Remove call to IsInNGFragmentTraversal().
DCHECK(full_context_.container_for_absolute_position ==
- box_model_object.Container());
+ box_model_object.Container() ||
+ (IsInNGFragmentTraversal() &&
+ box_model_object.IsInsideFlowThread()));
context_.current = context_.absolute_position;
// Absolutely positioned content in an inline should be positioned
// relative to the inline.
const auto* container = full_context_.container_for_absolute_position;
if (container && container->IsLayoutInline()) {
- DCHECK(container->CanContainAbsolutePositionObjects());
+ // TODO(almaher): Remove call to IsInNGFragmentTraversal().
+ DCHECK(container->CanContainAbsolutePositionObjects() ||
+ (IsInNGFragmentTraversal() &&
+ box_model_object.IsInsideFlowThread()));
DCHECK(box_model_object.IsBox());
context_.current.paint_offset +=
ToLayoutInline(container)->OffsetForInFlowPositionedInline(
@@ -2379,8 +2411,11 @@ void FragmentPaintPropertyTreeBuilder::UpdatePaintOffset() {
case EPosition::kSticky:
break;
case EPosition::kFixed: {
+ // TODO(almaher): Remove call to IsInNGFragmentTraversal().
DCHECK(full_context_.container_for_fixed_position ==
- box_model_object.Container());
+ box_model_object.Container() ||
+ (IsInNGFragmentTraversal() &&
+ box_model_object.IsInsideFlowThread()));
context_.current = context_.fixed_position;
// Fixed-position elements that are fixed to the viewport have a
// transform above the scroll of the LayoutView. Child content is
@@ -2515,7 +2550,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateForObjectLocationAndSize(
fragment_data_.InvalidateClipPathCache();
if (object_.IsBox()) {
- // See PaintLayerScrollableArea::PixelSnappedBorderBoxRect() for the
+ // See PaintLayerScrollableArea::PixelSnappedBorderBoxSize() for the
// reason of this.
if (auto* scrollable_area = ToLayoutBox(object_).GetScrollableArea())
scrollable_area->PositionOverflowControls();
@@ -2602,6 +2637,13 @@ void FragmentPaintPropertyTreeBuilder::UpdateForSelf() {
UpdateCssClip();
UpdateFilter();
UpdateOverflowControlsClip();
+ } else if (RuntimeEnabledFeatures::TransformInteropEnabled() &&
+ !object_.IsAnonymous()) {
+ // With kTransformInterop enabled, 3D rendering contexts follow the
+ // DOM ancestor chain, so flattening should apply regardless of
+ // presence of transform.
+ context_.current.rendering_context_id = 0;
+ context_.current.should_flatten_inherited_transform = true;
}
UpdateLocalBorderBoxContext();
}
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
index b72bed915f5..fa63c760af9 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
@@ -803,6 +803,30 @@ TEST_P(PaintPropertyTreeBuilderTest, WillChangeContents) {
GetDocument().View()->GetLayoutView());
}
+TEST_P(PaintPropertyTreeBuilderTest,
+ BackfaceVisibilityWithPseudoStacking3DChildren) {
+ ScopedTransformInteropForTest enabled(true);
+ // TODO(chrishtr): implement for CAP. This entails computing
+ // has_backface_invisible_ancestor_in_same_3d_context in the pre-paint tree
+ // walk.
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return;
+
+ SetBodyInnerHTML(R"HTML(
+ <div style="backface-visibility: hidden; transform-style: preserve-3d">
+ <div id=child style="isolation: isolate"></div>
+ </div>
+ )HTML");
+
+ // The child needs a transform node to communicate that it is backface
+ // visible to the compositor.
+ EXPECT_NE(nullptr, PaintPropertiesForElement("child")->Transform());
+ EXPECT_EQ(PaintPropertiesForElement("child")
+ ->Transform()
+ ->GetBackfaceVisibilityForTesting(),
+ TransformPaintPropertyNode::BackfaceVisibility::kVisible);
+}
+
TEST_P(PaintPropertyTreeBuilderTest, NoEffectAndFilterForNonStackingContext) {
SetBodyInnerHTML(R"HTML(
<div id="target" style="will-change: right; backface-visibility: hidden">
@@ -1803,11 +1827,10 @@ TEST_P(PaintPropertyTreeBuilderTest, TransformNodesAcrossSubframes) {
// frame's transform tree.
// This asserts that we have the following tree structure:
// Transform transform=translation=1.000000,2.000000,3.000000
- // PaintOffsetTranslation transform=Identity
- // PreTranslation transform=translation=7.000000,7.000000,0.000000
- // PaintOffsetTranslation transform=Identity
- // ScrollTranslation transform=translation=0.000000,0.000000,0.000000
- // Transform transform=translation=4.000000,5.000000,6.000000
+ // PreTranslation transform=translation=7.000000,7.000000,0.000000
+ // PaintOffsetTranslation transform=Identity
+ // ScrollTranslation transform=translation=0.000000,0.000000,0.000000
+ // Transform transform=translation=4.000000,5.000000,6.000000
auto* inner_document_scroll_translation = inner_div_transform->Parent();
EXPECT_TRUE(inner_document_scroll_translation->IsIdentity());
auto* paint_offset_translation = inner_document_scroll_translation->Parent();
@@ -1821,16 +1844,8 @@ TEST_P(PaintPropertyTreeBuilderTest, TransformNodesAcrossSubframes) {
EXPECT_EQ(div_with_transform_properties->Transform(),
iframe_pre_translation->Parent());
} else {
- LayoutObject* iframe_element = GetLayoutObjectByElementId("iframe");
- const ObjectPaintProperties* iframe_element_properties =
- iframe_element->FirstFragment().PaintProperties();
- EXPECT_EQ(iframe_element_properties->PaintOffsetTranslation(),
- iframe_pre_translation->Parent());
- EXPECT_EQ(
- FloatSize(),
- iframe_element_properties->PaintOffsetTranslation()->Translation2D());
EXPECT_EQ(div_with_transform_properties->Transform(),
- iframe_element_properties->PaintOffsetTranslation()->Parent());
+ iframe_pre_translation->Parent());
}
}
@@ -2864,7 +2879,9 @@ TEST_P(PaintPropertyTreeBuilderTest, Preserve3DCreatesSharedRenderingContext) {
EXPECT_NE(a_properties->Transform(), b_properties->Transform());
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_TRUE(a_properties->Transform()->HasRenderingContext());
+ EXPECT_FALSE(a_properties->Transform()->FlattensInheritedTransform());
EXPECT_TRUE(b_properties->Transform()->HasRenderingContext());
+ EXPECT_FALSE(b_properties->Transform()->FlattensInheritedTransform());
EXPECT_EQ(a_properties->Transform()->RenderingContextId(),
b_properties->Transform()->RenderingContextId());
}
@@ -2874,6 +2891,94 @@ TEST_P(PaintPropertyTreeBuilderTest, Preserve3DCreatesSharedRenderingContext) {
frame_view->GetLayoutView());
}
+TEST_P(PaintPropertyTreeBuilderTest,
+ IntermediateElementPreventsSharedRenderingContext) {
+ ScopedTransformInteropForTest enabled(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <div id='parent' style='transform-style: preserve-3d'>
+ <div>
+ <div id='a' style='transform: translateZ(0); width: 30px; height: 40px'>
+ </div>
+ </div>
+ <div id='b' style='transform: translateZ(0); width: 20px; height: 10px'>
+ </div>
+ </div>
+ )HTML");
+ LocalFrameView* frame_view = GetDocument().View();
+
+ LayoutObject* a = GetLayoutObjectByElementId("a");
+ const ObjectPaintProperties* a_properties =
+ a->FirstFragment().PaintProperties();
+ LayoutObject* b = GetLayoutObjectByElementId("b");
+ const ObjectPaintProperties* b_properties =
+ b->FirstFragment().PaintProperties();
+ ASSERT_TRUE(a_properties->Transform() && b_properties->Transform());
+ EXPECT_NE(a_properties->Transform(), b_properties->Transform());
+
+ const ObjectPaintProperties* parent_properties =
+ b->FirstFragment().PaintProperties();
+
+ EXPECT_FALSE(a_properties->Transform()->HasRenderingContext());
+ EXPECT_TRUE(a_properties->Transform()->FlattensInheritedTransform());
+ EXPECT_TRUE(b_properties->Transform()->HasRenderingContext());
+ EXPECT_FALSE(b_properties->Transform()->FlattensInheritedTransform());
+ EXPECT_NE(a_properties->Transform()->RenderingContextId(),
+ b_properties->Transform()->RenderingContextId());
+
+ EXPECT_EQ(parent_properties->Transform()->RenderingContextId(),
+ b_properties->Transform()->RenderingContextId());
+
+ CHECK_EXACT_VISUAL_RECT(PhysicalRect(8, 8, 30, 40), a,
+ frame_view->GetLayoutView());
+ CHECK_EXACT_VISUAL_RECT(PhysicalRect(8, 48, 20, 10), b,
+ frame_view->GetLayoutView());
+}
+
+TEST_P(PaintPropertyTreeBuilderTest,
+ IntermediateElementWithPropertiesPreventsSharedRenderingContext) {
+ ScopedTransformInteropForTest enabled(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <div id='parent' style='transform-style: preserve-3d'>
+ <div style="overflow: hidden">
+ <div id='a' style='transform: translateZ(0); width: 30px; height: 40px'>
+ </div>
+ </div>
+ <div id='b' style='transform: translateZ(0); width: 20px; height: 10px'>
+ </div>
+ </div>
+ )HTML");
+ LocalFrameView* frame_view = GetDocument().View();
+
+ LayoutObject* a = GetLayoutObjectByElementId("a");
+ const ObjectPaintProperties* a_properties =
+ a->FirstFragment().PaintProperties();
+ LayoutObject* b = GetLayoutObjectByElementId("b");
+ const ObjectPaintProperties* b_properties =
+ b->FirstFragment().PaintProperties();
+ ASSERT_TRUE(a_properties->Transform() && b_properties->Transform());
+ EXPECT_NE(a_properties->Transform(), b_properties->Transform());
+
+ const ObjectPaintProperties* parent_properties =
+ b->FirstFragment().PaintProperties();
+
+ EXPECT_FALSE(a_properties->Transform()->HasRenderingContext());
+ EXPECT_TRUE(a_properties->Transform()->FlattensInheritedTransform());
+ EXPECT_TRUE(b_properties->Transform()->HasRenderingContext());
+ EXPECT_FALSE(b_properties->Transform()->FlattensInheritedTransform());
+ EXPECT_NE(a_properties->Transform()->RenderingContextId(),
+ b_properties->Transform()->RenderingContextId());
+
+ EXPECT_EQ(parent_properties->Transform()->RenderingContextId(),
+ b_properties->Transform()->RenderingContextId());
+
+ CHECK_EXACT_VISUAL_RECT(PhysicalRect(8, 8, 30, 40), a,
+ frame_view->GetLayoutView());
+ CHECK_EXACT_VISUAL_RECT(PhysicalRect(8, 48, 20, 10), b,
+ frame_view->GetLayoutView());
+}
+
TEST_P(PaintPropertyTreeBuilderTest, FlatTransformStyleEndsRenderingContext) {
SetBodyInnerHTML(R"HTML(
<style>
@@ -4555,11 +4660,14 @@ TEST_P(PaintPropertyTreeBuilderTest, Reflection) {
"</div>");
const ObjectPaintProperties* filter_properties =
GetLayoutObjectByElementId("filter")->FirstFragment().PaintProperties();
- EXPECT_TRUE(filter_properties->Filter()->Parent()->IsRoot());
EXPECT_EQ(DocScrollTranslation(),
+ filter_properties->PaintOffsetTranslation()->Parent());
+ EXPECT_EQ(FloatSize(8, 8),
+ filter_properties->PaintOffsetTranslation()->Translation2D());
+ EXPECT_TRUE(filter_properties->Filter()->Parent()->IsRoot());
+ EXPECT_EQ(filter_properties->PaintOffsetTranslation(),
&filter_properties->Filter()->LocalTransformSpace());
EXPECT_EQ(DocContentClip(), filter_properties->Filter()->OutputClip());
- EXPECT_EQ(FloatPoint(8, 8), filter_properties->Filter()->FiltersOrigin());
}
TEST_P(PaintPropertyTreeBuilderTest, SimpleFilter) {
@@ -4568,11 +4676,11 @@ TEST_P(PaintPropertyTreeBuilderTest, SimpleFilter) {
"</div>");
const ObjectPaintProperties* filter_properties =
GetLayoutObjectByElementId("filter")->FirstFragment().PaintProperties();
+ EXPECT_FALSE(filter_properties->PaintOffsetTranslation());
EXPECT_TRUE(filter_properties->Filter()->Parent()->IsRoot());
EXPECT_EQ(DocScrollTranslation(),
&filter_properties->Filter()->LocalTransformSpace());
EXPECT_EQ(DocContentClip(), filter_properties->Filter()->OutputClip());
- EXPECT_EQ(FloatPoint(8, 8), filter_properties->Filter()->FiltersOrigin());
}
TEST_P(PaintPropertyTreeBuilderTest, FilterReparentClips) {
@@ -4592,7 +4700,6 @@ TEST_P(PaintPropertyTreeBuilderTest, FilterReparentClips) {
filter_properties->Filter()->OutputClip());
EXPECT_EQ(DocScrollTranslation(),
&filter_properties->Filter()->LocalTransformSpace());
- EXPECT_EQ(FloatPoint(8, 8), filter_properties->Filter()->FiltersOrigin());
const PropertyTreeState& child_paint_state =
GetLayoutObjectByElementId("child")
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_timing.cc b/chromium/third_party/blink/renderer/core/paint/paint_timing.cc
index f3ea3825c3b..3aaf31583dd 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_timing.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_timing.cc
@@ -55,7 +55,7 @@ PaintTiming& PaintTiming::From(Document& document) {
}
void PaintTiming::MarkFirstPaint() {
- // Test that m_firstPaint is non-zero here, as well as in setFirstPaint, so
+ // Test that |first_paint_| is non-zero here, as well as in setFirstPaint, so
// we avoid invoking monotonicallyIncreasingTime() on every call to
// markFirstPaint().
if (!first_paint_.is_null())
@@ -64,7 +64,7 @@ void PaintTiming::MarkFirstPaint() {
}
void PaintTiming::MarkFirstContentfulPaint() {
- // Test that m_firstContentfulPaint is non-zero here, as well as in
+ // Test that |first_contentful_paint_| is non-zero here, as well as in
// setFirstContentfulPaint, so we avoid invoking
// monotonicallyIncreasingTime() on every call to
// markFirstContentfulPaint().
@@ -81,6 +81,26 @@ void PaintTiming::MarkFirstImagePaint() {
RegisterNotifySwapTime(PaintEvent::kFirstImagePaint);
}
+void PaintTiming::MarkFirstEligibleToPaint() {
+ if (!first_eligible_to_paint_.is_null())
+ return;
+
+ first_eligible_to_paint_ = clock_->NowTicks();
+ NotifyPaintTimingChanged();
+}
+
+// We deliberately use |first_paint_| here rather than |first_paint_swap_|,
+// because |first_paint_swap_| is set asynchronously and we need to be able to
+// rely on a synchronous check that SetFirstPaintSwap hasn't been scheduled or
+// run.
+void PaintTiming::MarkIneligibleToPaint() {
+ if (first_eligible_to_paint_.is_null() || !first_paint_.is_null())
+ return;
+
+ first_eligible_to_paint_ = base::TimeTicks();
+ NotifyPaintTimingChanged();
+}
+
void PaintTiming::SetFirstMeaningfulPaintCandidate(base::TimeTicks timestamp) {
if (!first_meaningful_paint_candidate_.is_null())
return;
@@ -120,11 +140,22 @@ void PaintTiming::NotifyPaint(bool is_first_paint,
fmp_detector_->NotifyPaint();
}
+void PaintTiming::OnPortalActivate() {
+ last_portal_activated_swap_ = base::TimeTicks();
+ RegisterNotifySwapTime(PaintEvent::kPortalActivatedPaint);
+}
+
+void PaintTiming::SetPortalActivatedPaint(base::TimeTicks stamp) {
+ DCHECK(last_portal_activated_swap_.is_null());
+ last_portal_activated_swap_ = stamp;
+ NotifyPaintTimingChanged();
+}
+
void PaintTiming::SetTickClockForTesting(const base::TickClock* clock) {
clock_ = clock;
}
-void PaintTiming::Trace(Visitor* visitor) {
+void PaintTiming::Trace(Visitor* visitor) const {
visitor->Trace(fmp_detector_);
Supplement<Document>::Trace(visitor);
}
@@ -146,6 +177,13 @@ void PaintTiming::NotifyPaintTimingChanged() {
void PaintTiming::SetFirstPaint(base::TimeTicks stamp) {
if (!first_paint_.is_null())
return;
+
+ LocalFrame* frame = GetFrame();
+ if (frame && frame->GetDocument()) {
+ Document* document = frame->GetDocument();
+ document->MarkFirstPaint();
+ }
+
first_paint_ = stamp;
RegisterNotifySwapTime(PaintEvent::kFirstPaint);
}
@@ -204,12 +242,18 @@ void PaintTiming::ReportSwapTime(PaintEvent event,
case PaintEvent::kFirstPaint:
SetFirstPaintSwap(timestamp);
return;
+ case PaintEvent::kFirstPaintAfterBackForwardCacheRestore:
+ SetFirstPaintAfterBackForwardCacheRestoreSwap(timestamp);
+ return;
case PaintEvent::kFirstContentfulPaint:
SetFirstContentfulPaintSwap(timestamp);
return;
case PaintEvent::kFirstImagePaint:
SetFirstImagePaintSwap(timestamp);
return;
+ case PaintEvent::kPortalActivatedPaint:
+ SetPortalActivatedPaint(timestamp);
+ return;
default:
NOTREACHED();
}
@@ -261,6 +305,16 @@ void PaintTiming::SetFirstImagePaintSwap(base::TimeTicks stamp) {
NotifyPaintTimingChanged();
}
+void PaintTiming::SetFirstPaintAfterBackForwardCacheRestoreSwap(
+ base::TimeTicks stamp) {
+ // The last element is already allocated when the page is restored from the
+ // cache.
+ DCHECK(!first_paints_after_back_forward_cache_restore_swap_.IsEmpty());
+ DCHECK(first_paints_after_back_forward_cache_restore_swap_.back().is_null());
+ first_paints_after_back_forward_cache_restore_swap_.back() = stamp;
+ NotifyPaintTimingChanged();
+}
+
void PaintTiming::ReportSwapResultHistogram(WebSwapResult result) {
DEFINE_STATIC_LOCAL(
EnumerationHistogram, did_swap_histogram,
@@ -269,4 +323,12 @@ void PaintTiming::ReportSwapResultHistogram(WebSwapResult result) {
did_swap_histogram.Count(static_cast<uint32_t>(result));
}
+void PaintTiming::OnRestoredFromBackForwardCache() {
+ // Allocate the last element with 0, which indicates that the first paint
+ // after this navigation doesn't happen yet.
+ first_paints_after_back_forward_cache_restore_swap_.push_back(
+ base::TimeTicks());
+ RegisterNotifySwapTime(PaintEvent::kFirstPaintAfterBackForwardCacheRestore);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_timing.h b/chromium/third_party/blink/renderer/core/paint/paint_timing.h
index cf47d323ac1..b1a28f83a20 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_timing.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_timing.h
@@ -55,12 +55,26 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>,
// contentful paint hasn't been recorded yet.
void MarkFirstImagePaint();
+ // MarkFirstEligibleToPaint records the first time that the frame is not
+ // throttled and so is eligible to paint. A null value indicates throttling.
+ void MarkFirstEligibleToPaint();
+
+ // MarkIneligibleToPaint resets the paint eligibility timestamp to null.
+ // A null value indicates throttling. This call is ignored if a first
+ // contentful paint has already been recorded.
+ void MarkIneligibleToPaint();
+
void SetFirstMeaningfulPaintCandidate(base::TimeTicks timestamp);
void SetFirstMeaningfulPaint(
base::TimeTicks swap_stamp,
FirstMeaningfulPaintDetector::HadUserInput had_input);
void NotifyPaint(bool is_first_paint, bool text_painted, bool image_painted);
+ // Notifies the PaintTiming that this Document received the onPortalActivate
+ // event.
+ void OnPortalActivate();
+ void SetPortalActivatedPaint(base::TimeTicks stamp);
+
// The getters below return monotonically-increasing seconds, or zero if the
// given paint event has not yet occurred. See the comments for
// monotonicallyIncreasingTime in wtf/Time.h for additional details.
@@ -69,6 +83,13 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>,
// current document.
base::TimeTicks FirstPaint() const { return first_paint_swap_; }
+ // Times when the first paint happens after the page is restored from the
+ // back-forward cache. If the element value is zero time tick, the first paint
+ // event did not happen for that navigation.
+ WTF::Vector<base::TimeTicks> FirstPaintsAfterBackForwardCacheRestore() const {
+ return first_paints_after_back_forward_cache_restore_swap_;
+ }
+
// FirstContentfulPaint returns the first time that 'contentful' content was
// painted. For instance, the first time that text or image content was
// painted.
@@ -79,12 +100,23 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>,
// FirstImagePaint returns the first time that image content was painted.
base::TimeTicks FirstImagePaint() const { return first_image_paint_swap_; }
+ // FirstEligibleToPaint returns the first time that the frame is not
+ // throttled and is eligible to paint. A null value indicates throttling.
+ base::TimeTicks FirstEligibleToPaint() const {
+ return first_eligible_to_paint_;
+ }
+
// FirstMeaningfulPaint returns the first time that page's primary content
// was painted.
base::TimeTicks FirstMeaningfulPaint() const {
return first_meaningful_paint_swap_;
}
+ // The time that the first paint happened after a portal activation.
+ base::TimeTicks LastPortalActivatedPaint() const {
+ return last_portal_activated_swap_;
+ }
+
// FirstMeaningfulPaintCandidate indicates the first time we considered a
// paint to qualify as the potentially first meaningful paint. Unlike
// firstMeaningfulPaint, this signal is available in real time, but it may be
@@ -105,7 +137,9 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>,
// The caller owns the |clock| which must outlive the PaintTiming.
void SetTickClockForTesting(const base::TickClock* clock);
- void Trace(Visitor*) override;
+ void OnRestoredFromBackForwardCache();
+
+ void Trace(Visitor*) const override;
private:
LocalFrame* GetFrame() const;
@@ -132,6 +166,8 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>,
void SetFirstContentfulPaintSwap(base::TimeTicks stamp);
void SetFirstImagePaintSwap(base::TimeTicks stamp);
+ void SetFirstPaintAfterBackForwardCacheRestoreSwap(base::TimeTicks stamp);
+
void RegisterNotifySwapTime(PaintEvent);
base::TimeTicks FirstPaintRendered() const { return first_paint_; }
@@ -145,12 +181,17 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>,
// confirm the deltas and discrepancies look reasonable.
base::TimeTicks first_paint_;
base::TimeTicks first_paint_swap_;
+ WTF::Vector<base::TimeTicks>
+ first_paints_after_back_forward_cache_restore_swap_;
base::TimeTicks first_image_paint_;
base::TimeTicks first_image_paint_swap_;
base::TimeTicks first_contentful_paint_;
base::TimeTicks first_contentful_paint_swap_;
base::TimeTicks first_meaningful_paint_swap_;
base::TimeTicks first_meaningful_paint_candidate_;
+ base::TimeTicks first_eligible_to_paint_;
+
+ base::TimeTicks last_portal_activated_swap_;
Member<FirstMeaningfulPaintDetector> fmp_detector_;
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.cc b/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.cc
index 60f259f22eb..c36dae1d1cb 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.cc
@@ -97,6 +97,10 @@ void PaintTimingDetector::NotifyPaintFinished() {
}
if (callback_manager_->CountCallbacks() > 0)
callback_manager_->RegisterPaintTimeCallbackForCombinedCallbacks();
+ LocalDOMWindow* window = frame_view_->GetFrame().DomWindow();
+ if (window) {
+ DOMWindowPerformance::performance(*window)->OnPaintFinished();
+ }
}
// static
@@ -239,11 +243,33 @@ PaintTimingDetector::GetLargestContentfulPaintCalculator() {
bool PaintTimingDetector::NotifyIfChangedLargestImagePaint(
base::TimeTicks image_paint_time,
- uint64_t image_paint_size) {
+ uint64_t image_paint_size,
+ base::TimeTicks removed_image_paint_time,
+ uint64_t removed_image_paint_size) {
+ // The experimental version (where we look at largest seen so far, regardless
+ // of node removal) cannot change when the regular version does not change.
if (!HasLargestImagePaintChanged(image_paint_time, image_paint_size))
return false;
+
largest_image_paint_time_ = image_paint_time;
largest_image_paint_size_ = image_paint_size;
+ // Compute experimental LCP by using the largest size (smallest paint time in
+ // case of tie).
+ if (removed_image_paint_size < image_paint_size) {
+ experimental_largest_image_paint_time_ = image_paint_time;
+ experimental_largest_image_paint_size_ = image_paint_size;
+ } else if (removed_image_paint_size > image_paint_size) {
+ experimental_largest_image_paint_time_ = removed_image_paint_time;
+ experimental_largest_image_paint_size_ = removed_image_paint_size;
+ } else {
+ experimental_largest_image_paint_size_ = image_paint_size;
+ if (image_paint_time.is_null()) {
+ experimental_largest_image_paint_time_ = removed_image_paint_time;
+ } else {
+ experimental_largest_image_paint_time_ =
+ std::min(image_paint_time, removed_image_paint_time);
+ }
+ }
DidChangePerformanceTiming();
return true;
}
@@ -251,10 +277,17 @@ bool PaintTimingDetector::NotifyIfChangedLargestImagePaint(
bool PaintTimingDetector::NotifyIfChangedLargestTextPaint(
base::TimeTicks text_paint_time,
uint64_t text_paint_size) {
+ // The experimental version (where we look at largest seen so far, regardless
+ // of node removal) cannot change when the regular version does not change.
if (!HasLargestTextPaintChanged(text_paint_time, text_paint_size))
return false;
largest_text_paint_time_ = text_paint_time;
largest_text_paint_size_ = text_paint_size;
+ if (experimental_largest_text_paint_size_ < text_paint_size) {
+ DCHECK(!text_paint_time.is_null());
+ experimental_largest_text_paint_time_ = text_paint_time;
+ experimental_largest_text_paint_size_ = text_paint_size;
+ }
DidChangePerformanceTiming();
return true;
}
@@ -399,7 +432,7 @@ ScopedPaintTimingDetectorBlockPaintHook::
data_->property_tree_state_);
}
-void PaintTimingDetector::Trace(Visitor* visitor) {
+void PaintTimingDetector::Trace(Visitor* visitor) const {
visitor->Trace(text_paint_timing_detector_);
visitor->Trace(image_paint_timing_detector_);
visitor->Trace(frame_view_);
@@ -439,7 +472,7 @@ void PaintTimingCallbackManagerImpl::ReportPaintTime(
frame_view_->GetPaintTimingDetector().UpdateLargestContentfulPaintCandidate();
}
-void PaintTimingCallbackManagerImpl::Trace(Visitor* visitor) {
+void PaintTimingCallbackManagerImpl::Trace(Visitor* visitor) const {
visitor->Trace(frame_view_);
PaintTimingCallbackManager::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.h b/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.h
index c4329f86b54..ea04c56312c 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.h
@@ -90,7 +90,7 @@ class PaintTimingCallbackManagerImpl final
WebSwapResult,
base::TimeTicks paint_time);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<LocalFrameView> frame_view_;
@@ -141,8 +141,19 @@ class CORE_EXPORT PaintTimingDetector
void NotifyInputEvent(WebInputEvent::Type);
bool NeedToNotifyInputOrScroll() const;
void NotifyScroll(mojom::blink::ScrollType);
+
// The returned value indicates whether the candidates have changed.
- bool NotifyIfChangedLargestImagePaint(base::TimeTicks, uint64_t size);
+ // To compute experimental LCP (including removals) for images we need to know
+ // the time and size of removed images in order to account for cases where the
+ // largest image is removed while it is still loading: in this case, we would
+ // first update the experimental LCP size to be the image size, so we need to
+ // be able to decrease the size. To do this, the simplest way to achieve the
+ // correct results is to store the largest image removed which did receive a
+ // paint time.
+ bool NotifyIfChangedLargestImagePaint(base::TimeTicks image_paint_time,
+ uint64_t image_size,
+ base::TimeTicks removed_image_time,
+ uint64_t removed_image_size);
bool NotifyIfChangedLargestTextPaint(base::TimeTicks, uint64_t size);
void DidChangePerformanceTiming();
@@ -173,6 +184,22 @@ class CORE_EXPORT PaintTimingDetector
uint64_t LargestImagePaintSize() const { return largest_image_paint_size_; }
base::TimeTicks LargestTextPaint() const { return largest_text_paint_time_; }
uint64_t LargestTextPaintSize() const { return largest_text_paint_size_; }
+ // Experimental counterparts of the above methods. Currently these values are
+ // computed by looking at the largest content seen so far, without caring
+ // about whether the content remains alive on the page or not.
+ base::TimeTicks ExperimentalLargestImagePaint() const {
+ return experimental_largest_image_paint_time_;
+ }
+ uint64_t ExperimentalLargestImagePaintSize() const {
+ return experimental_largest_image_paint_size_;
+ }
+ base::TimeTicks ExperimentalLargestTextPaint() const {
+ return experimental_largest_text_paint_time_;
+ }
+ uint64_t ExperimentalLargestTextPaintSize() const {
+ return experimental_largest_text_paint_size_;
+ }
+
base::TimeTicks FirstInputOrScrollNotifiedTimestamp() const {
return first_input_or_scroll_notified_timestamp_;
}
@@ -180,7 +207,7 @@ class CORE_EXPORT PaintTimingDetector
void UpdateLargestContentfulPaintCandidate();
base::Optional<PaintTimingVisualizer>& Visualizer() { return visualizer_; }
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
private:
// Method called to stop recording the Largest Contentful Paint.
@@ -207,12 +234,16 @@ class CORE_EXPORT PaintTimingDetector
base::Optional<PaintTimingVisualizer> visualizer_;
- // Largest image information.
base::TimeTicks largest_image_paint_time_;
uint64_t largest_image_paint_size_ = 0;
- // Largest text information.
base::TimeTicks largest_text_paint_time_;
uint64_t largest_text_paint_size_ = 0;
+
+ base::TimeTicks experimental_largest_image_paint_time_;
+ uint64_t experimental_largest_image_paint_size_ = 0;
+ base::TimeTicks experimental_largest_text_paint_time_;
+ uint64_t experimental_largest_text_paint_size_ = 0;
+
bool is_recording_largest_contentful_paint_ = true;
};
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_timing_test_helper.h b/chromium/third_party/blink/renderer/core/paint/paint_timing_test_helper.h
index e23dfda5dec..ee8ec99608c 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_timing_test_helper.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_timing_test_helper.h
@@ -26,7 +26,7 @@ class MockPaintTimingCallbackManager final
size_t CountCallbacks() { return callback_queue_.size(); }
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
private:
PaintTimingCallbackManager::CallbackQueue callback_queue_;
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 18e6d7aa22b..ab5cc7560a9 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
@@ -547,9 +547,9 @@ void PrePaintTreeWalk::WalkNGChildren(const LayoutObject* parent,
continue;
}
} else if (!object) {
- // A column doesn't paint anything itself. Just include its offset and
- // descend into children.
- DCHECK((*iterator)->BoxFragment()->IsColumnBox());
+ // A fragmentainer doesn't paint anything itself. Just include its offset
+ // and descend into children.
+ DCHECK((*iterator)->BoxFragment()->IsFragmentainerBox());
PhysicalOffset offset = (*iterator)->Link().offset;
PaintPropertyTreeBuilderFragmentContext::ContainingBlockContext*
fragment_context = nullptr;
diff --git a/chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc b/chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc
index f302470dafb..26797e53353 100644
--- a/chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc
+++ b/chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc
@@ -37,7 +37,8 @@ SVGFilterRecordingContext::SVGFilterRecordingContext(
const PaintInfo& initial_paint_info)
// Create a new controller and context so the contents of the filter can be
// drawn and cached.
- : paint_controller_(std::make_unique<PaintController>()),
+ : paint_controller_(
+ std::make_unique<PaintController>(PaintController::kTransient)),
context_(std::make_unique<GraphicsContext>(*paint_controller_)),
paint_info_(*context_, initial_paint_info) {
// Use initial_paint_info's current paint chunk properties so that any new
diff --git a/chromium/third_party/blink/renderer/core/paint/scrollable_area_painter.cc b/chromium/third_party/blink/renderer/core/paint/scrollable_area_painter.cc
index 83dcd2c8bc4..2a285d4100d 100644
--- a/chromium/third_party/blink/renderer/core/paint/scrollable_area_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/scrollable_area_painter.cc
@@ -39,7 +39,6 @@ void ScrollableAreaPainter::PaintResizer(GraphicsContext& context,
if (!cull_rect.Intersects(abs_rect))
return;
CustomScrollbarTheme::PaintIntoRect(*resizer, context,
- PhysicalOffset(paint_offset),
PhysicalRect(abs_rect));
return;
}
@@ -249,7 +248,6 @@ void ScrollableAreaPainter::PaintScrollCorner(GraphicsContext& context,
if (!cull_rect.Intersects(abs_rect))
return;
CustomScrollbarTheme::PaintIntoRect(*scroll_corner, context,
- PhysicalOffset(paint_offset),
PhysicalRect(abs_rect));
return;
}
diff --git a/chromium/third_party/blink/renderer/core/paint/table_section_painter.cc b/chromium/third_party/blink/renderer/core/paint/table_section_painter.cc
index 374063ce4c3..6bb60ef408f 100644
--- a/chromium/third_party/blink/renderer/core/paint/table_section_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/table_section_painter.cc
@@ -304,9 +304,13 @@ void TableSectionPainter::PaintBoxDecorationBackground(
if (may_have_background) {
PaintInfo paint_info_for_cells = paint_info.ForDescendants();
for (auto r = dirtied_rows.Start(); r < dirtied_rows.End(); r++) {
+ base::Optional<ScopedPaintState> row_paint_state;
for (auto c = dirtied_columns.Start(); c < dirtied_columns.End(); c++) {
- if (const auto* cell = layout_table_section_.OriginatingCellAt(r, c))
- PaintBackgroundsBehindCell(*cell, paint_info_for_cells);
+ if (const auto* cell = layout_table_section_.OriginatingCellAt(r, c)) {
+ if (!row_paint_state)
+ row_paint_state.emplace(*cell->Row(), paint_info_for_cells);
+ PaintBackgroundsBehindCell(*cell, row_paint_state->GetPaintInfo());
+ }
}
}
}
diff --git a/chromium/third_party/blink/renderer/core/paint/text_element_timing.cc b/chromium/third_party/blink/renderer/core/paint/text_element_timing.cc
index 676b3e86c54..e6eaba9125d 100644
--- a/chromium/third_party/blink/renderer/core/paint/text_element_timing.cc
+++ b/chromium/third_party/blink/renderer/core/paint/text_element_timing.cc
@@ -77,7 +77,7 @@ void TextElementTiming::OnTextObjectPainted(const TextRecord& record) {
element);
}
-void TextElementTiming::Trace(Visitor* visitor) {
+void TextElementTiming::Trace(Visitor* visitor) const {
Supplement<LocalDOMWindow>::Trace(visitor);
visitor->Trace(performance_);
}
diff --git a/chromium/third_party/blink/renderer/core/paint/text_element_timing.h b/chromium/third_party/blink/renderer/core/paint/text_element_timing.h
index 10f91076462..4e5318fe59b 100644
--- a/chromium/third_party/blink/renderer/core/paint/text_element_timing.h
+++ b/chromium/third_party/blink/renderer/core/paint/text_element_timing.h
@@ -52,7 +52,7 @@ class CORE_EXPORT TextElementTiming final
// resolved. Dispatches PerformanceElementTiming entries to WindowPerformance.
void OnTextObjectPainted(const TextRecord&);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
Member<WindowPerformance> performance_;
diff --git a/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc b/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
index 196fc8e59cd..8f82f4d91d7 100644
--- a/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
+++ b/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
@@ -197,7 +197,7 @@ void TextPaintTimingDetector::StopRecordingLargestTextPaint() {
records_manager_.CleanUpLargestTextPaint();
}
-void TextPaintTimingDetector::Trace(Visitor* visitor) {
+void TextPaintTimingDetector::Trace(Visitor* visitor) const {
visitor->Trace(records_manager_);
visitor->Trace(frame_view_);
visitor->Trace(callback_manager_);
@@ -210,7 +210,7 @@ LargestTextPaintManager::LargestTextPaintManager(
frame_view_(frame_view),
paint_timing_detector_(paint_timing_detector) {}
-void LargestTextPaintManager::Trace(Visitor* visitor) {
+void LargestTextPaintManager::Trace(Visitor* visitor) const {
visitor->Trace(frame_view_);
visitor->Trace(paint_timing_detector_);
}
@@ -327,7 +327,7 @@ TextRecordsManager::TextRecordsManager(
ltp_manager_.emplace(frame_view, paint_timing_detector);
}
-void TextRecordsManager::Trace(Visitor* visitor) {
+void TextRecordsManager::Trace(Visitor* visitor) const {
visitor->Trace(text_element_timing_);
visitor->Trace(ltp_manager_);
}
diff --git a/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.h b/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
index 6f48bf95211..40e8a7a9d28 100644
--- a/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
+++ b/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
@@ -80,7 +80,7 @@ class CORE_EXPORT LargestTextPaintManager {
SetCachedResultInvalidated(true);
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
friend class LargestContentfulPaintCalculatorTest;
@@ -148,7 +148,7 @@ class CORE_EXPORT TextRecordsManager {
return ltp_manager_.has_value();
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
friend class LargestContentfulPaintCalculatorTest;
@@ -216,7 +216,7 @@ class CORE_EXPORT TextPaintTimingDetector final
return records_manager_.UpdateCandidate();
}
void ReportSwapTime(base::TimeTicks timestamp);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
friend class LargestContentfulPaintCalculatorTest;
diff --git a/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc b/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc
index ff95b06c384..f4ec5862f13 100644
--- a/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc
@@ -133,10 +133,22 @@ class TextPaintTimingDetectorTest : public testing::Test {
GetLargestTextPaintManager()->UpdateCandidate();
}
- base::TimeTicks LargestPaintStoredResult() {
+ base::TimeTicks LargestPaintTime() {
return GetPaintTimingDetector().largest_text_paint_time_;
}
+ uint64_t LargestPaintSize() {
+ return GetPaintTimingDetector().largest_text_paint_size_;
+ }
+
+ base::TimeTicks ExperimentalLargestPaintTime() {
+ return GetPaintTimingDetector().experimental_largest_text_paint_time_;
+ }
+
+ uint64_t ExperimentalLargestPaintSize() {
+ return GetPaintTimingDetector().experimental_largest_text_paint_size_;
+ }
+
void SetBodyInnerHTML(const std::string& content) {
frame_test_helpers::LoadHTMLString(
web_view_helper_.GetWebView()->MainFrameImpl(), content,
@@ -161,9 +173,15 @@ class TextPaintTimingDetectorTest : public testing::Test {
GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
}
+ static constexpr base::TimeDelta kQuantumOfTime =
+ base::TimeDelta::FromMilliseconds(10);
+
// This only triggers ReportSwapTime in main frame.
void UpdateAllLifecyclePhasesAndSimulateSwapTime() {
UpdateAllLifecyclePhases();
+ // Advance the clock for a bit so different swap callbacks get different
+ // times.
+ AdvanceClock(kQuantumOfTime);
while (mock_callback_manager_->CountCallbacks() > 0)
InvokeCallback();
}
@@ -253,6 +271,8 @@ class ParameterizedTextPaintTimingDetectorTest
}
};
+constexpr base::TimeDelta TextPaintTimingDetectorTest::kQuantumOfTime;
+
INSTANTIATE_TEST_SUITE_P(All,
ParameterizedTextPaintTimingDetectorTest,
testing::Bool());
@@ -282,6 +302,8 @@ TEST_F(TextPaintTimingDetectorTest, InsertionOrderIsSecondaryRankingKey) {
UpdateAllLifecyclePhasesAndSimulateSwapTime();
EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id,
DOMNodeIds::ExistingIdForNode(first));
+ EXPECT_EQ(LargestPaintSize(), ExperimentalLargestPaintSize());
+ EXPECT_EQ(LargestPaintTime(), ExperimentalLargestPaintTime());
}
TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_TraceEvent_Candidate) {
@@ -334,6 +356,10 @@ TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_TraceEvent_NoCandidate) {
UpdateAllLifecyclePhasesAndSimulateSwapTime();
RemoveElement(element);
UpdateAllLifecyclePhases();
+ EXPECT_EQ(LargestPaintSize(), 0u);
+ EXPECT_EQ(LargestPaintTime(), base::TimeTicks());
+ EXPECT_GT(ExperimentalLargestPaintSize(), 0u);
+ EXPECT_NE(ExperimentalLargestPaintTime(), base::TimeTicks());
}
auto analyzer = trace_analyzer::Stop();
trace_analyzer::TraceEventVector events;
@@ -415,6 +441,8 @@ TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_LargestText) {
EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id,
DOMNodeIds::ExistingIdForNode(large_text));
+ EXPECT_EQ(LargestPaintSize(), ExperimentalLargestPaintSize());
+ EXPECT_EQ(LargestPaintTime(), ExperimentalLargestPaintTime());
}
TEST_F(TextPaintTimingDetectorTest, UpdateResultWhenCandidateChanged) {
@@ -424,16 +452,18 @@ TEST_F(TextPaintTimingDetectorTest, UpdateResultWhenCandidateChanged) {
)HTML");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
base::TimeTicks time2 = NowTicks();
- base::TimeTicks first_largest = LargestPaintStoredResult();
+ base::TimeTicks first_largest = LargestPaintTime();
EXPECT_GE(first_largest, time1);
EXPECT_GE(time2, first_largest);
+ EXPECT_EQ(first_largest, ExperimentalLargestPaintTime());
AppendDivElementToBody("a long-long-long text");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
base::TimeTicks time3 = NowTicks();
- base::TimeTicks second_largest = LargestPaintStoredResult();
+ base::TimeTicks second_largest = LargestPaintTime();
EXPECT_GE(second_largest, time2);
EXPECT_GE(time3, second_largest);
+ EXPECT_EQ(second_largest, ExperimentalLargestPaintTime());
}
// There is a risk that a text that is just recorded is selected to be the
@@ -477,7 +507,10 @@ TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_ReportFirstPaintTime) {
AdvanceClock(base::TimeDelta::FromSecondsD(1));
base::WeakPtr<TextRecord> record = TextRecordOfLargestTextPaint();
EXPECT_TRUE(record);
- EXPECT_EQ(record->paint_time, start_time + base::TimeDelta::FromSecondsD(1));
+ EXPECT_EQ(record->paint_time,
+ start_time + base::TimeDelta::FromSecondsD(1) + kQuantumOfTime);
+ EXPECT_EQ(LargestPaintSize(), ExperimentalLargestPaintSize());
+ EXPECT_EQ(LargestPaintTime(), ExperimentalLargestPaintTime());
}
TEST_F(TextPaintTimingDetectorTest,
@@ -505,11 +538,20 @@ TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_IgnoreRemovedText) {
UpdateAllLifecyclePhasesAndSimulateSwapTime();
EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id,
DOMNodeIds::ExistingIdForNode(large_text));
+ uint64_t experimental_size = ExperimentalLargestPaintSize();
+ base::TimeTicks experimental_time = ExperimentalLargestPaintTime();
+ EXPECT_EQ(LargestPaintSize(), experimental_size);
+ EXPECT_EQ(LargestPaintTime(), experimental_time);
+ EXPECT_GT(experimental_size, 0u);
+ EXPECT_GT(experimental_time, base::TimeTicks());
RemoveElement(large_text);
UpdateAllLifecyclePhasesAndSimulateSwapTime();
EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id,
DOMNodeIds::ExistingIdForNode(small_text));
+ // Experimental values should remain unchanged.
+ EXPECT_EQ(ExperimentalLargestPaintSize(), experimental_size);
+ EXPECT_EQ(ExperimentalLargestPaintTime(), experimental_time);
}
TEST_F(TextPaintTimingDetectorTest,
@@ -580,12 +622,20 @@ TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_ReportLastNullCandidate) {
UpdateAllLifecyclePhasesAndSimulateSwapTime();
EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id,
DOMNodeIds::ExistingIdForNode(text));
- EXPECT_NE(LargestPaintStoredResult(), base::TimeTicks());
+ base::TimeTicks largest_paint_time = LargestPaintTime();
+ EXPECT_NE(largest_paint_time, base::TimeTicks());
+ EXPECT_EQ(largest_paint_time, ExperimentalLargestPaintTime());
+ uint64_t largest_paint_size = LargestPaintSize();
+ EXPECT_NE(largest_paint_size, 0u);
+ EXPECT_EQ(largest_paint_size, ExperimentalLargestPaintSize());
RemoveElement(text);
UpdateAllLifecyclePhasesAndSimulateSwapTime();
EXPECT_FALSE(TextRecordOfLargestTextPaint());
- EXPECT_EQ(LargestPaintStoredResult(), base::TimeTicks());
+ EXPECT_EQ(LargestPaintTime(), base::TimeTicks());
+ // Experimental values remain unchanged.
+ EXPECT_EQ(largest_paint_time, ExperimentalLargestPaintTime());
+ EXPECT_EQ(largest_paint_size, ExperimentalLargestPaintSize());
}
TEST_F(TextPaintTimingDetectorTest,
diff --git a/chromium/third_party/blink/renderer/core/paint/text_painter_base.cc b/chromium/third_party/blink/renderer/core/paint/text_painter_base.cc
index 813881f8a8c..6e1adafcaae 100644
--- a/chromium/third_party/blink/renderer/core/paint/text_painter_base.cc
+++ b/chromium/third_party/blink/renderer/core/paint/text_painter_base.cc
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style/shadow_list.h"
#include "third_party/blink/renderer/platform/fonts/font.h"
+#include "third_party/blink/renderer/platform/geometry/length_functions.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -20,6 +21,101 @@
namespace blink {
+namespace {
+
+// We usually use the text decoration thickness to determine how far
+// ink-skipped text decorations should be away from the glyph
+// contours. Cap this at 5 CSS px in each direction when thickness
+// growths larger than that. A value of 13 closely matches FireFox'
+// implementation.
+constexpr float kDecorationClipMaxDilation = 13;
+
+static ResolvedUnderlinePosition ResolveUnderlinePosition(
+ const ComputedStyle& style,
+ FontBaseline baseline_type) {
+ // |auto| should resolve to |under| to avoid drawing through glyphs in
+ // scripts where it would not be appropriate (e.g., ideographs.)
+ // However, this has performance implications. For now, we only work with
+ // vertical text.
+ switch (baseline_type) {
+ case kAlphabeticBaseline:
+ if (style.TextUnderlinePosition() & kTextUnderlinePositionUnder)
+ return ResolvedUnderlinePosition::kUnder;
+ if (style.TextUnderlinePosition() & kTextUnderlinePositionFromFont)
+ return ResolvedUnderlinePosition::kNearAlphabeticBaselineFromFont;
+ return ResolvedUnderlinePosition::kNearAlphabeticBaselineAuto;
+ case kIdeographicBaseline:
+ // Compute language-appropriate default underline position.
+ // https://drafts.csswg.org/css-text-decor-3/#default-stylesheet
+ UScriptCode script = style.GetFontDescription().GetScript();
+ if (script == USCRIPT_KATAKANA_OR_HIRAGANA || script == USCRIPT_HANGUL) {
+ if (style.TextUnderlinePosition() & kTextUnderlinePositionLeft) {
+ return ResolvedUnderlinePosition::kUnder;
+ }
+ return ResolvedUnderlinePosition::kOver;
+ }
+ if (style.TextUnderlinePosition() & kTextUnderlinePositionRight) {
+ return ResolvedUnderlinePosition::kOver;
+ }
+ return ResolvedUnderlinePosition::kUnder;
+ }
+ NOTREACHED();
+ return ResolvedUnderlinePosition::kNearAlphabeticBaselineAuto;
+}
+
+static bool ShouldSetDecorationAntialias(const ComputedStyle& style) {
+ for (const auto& decoration : style.AppliedTextDecorations()) {
+ ETextDecorationStyle decoration_style = decoration.Style();
+ if (decoration_style == ETextDecorationStyle::kDotted ||
+ decoration_style == ETextDecorationStyle::kDashed)
+ return true;
+ }
+ return false;
+}
+
+float ComputeDecorationThickness(
+ const TextDecorationThickness text_decoration_thickness,
+ const ComputedStyle& style,
+ const SimpleFontData* font_data) {
+ float auto_underline_thickness =
+ std::max(1.f, style.ComputedFontSize() / 10.f);
+
+ if (text_decoration_thickness.IsAuto())
+ return auto_underline_thickness;
+
+ // In principle we would not need to test for font_data if
+ // |text_decoration_thickness.Thickness()| is fixed, but a null font_data here
+ // would be a rare / error situation anyway, so practically, we can
+ // early out here.
+ if (!font_data)
+ return auto_underline_thickness;
+
+ if (text_decoration_thickness.IsFromFont()) {
+ base::Optional<float> underline_thickness_font_metric =
+ font_data->GetFontMetrics().UnderlineThickness().value();
+
+ if (!underline_thickness_font_metric)
+ return auto_underline_thickness;
+
+ return std::max(1.f, underline_thickness_font_metric.value());
+ }
+
+ DCHECK(!text_decoration_thickness.IsFromFont());
+
+ const Length& thickness_length = text_decoration_thickness.Thickness();
+ float font_size = font_data->PlatformData().size();
+ float text_decoration_thickness_pixels =
+ FloatValueForLength(thickness_length, font_size);
+
+ return std::max(1.f, text_decoration_thickness_pixels);
+}
+
+float DoubleOffsetFromThickness(float thickness_pixels) {
+ return thickness_pixels + 1.0f;
+}
+
+} // anonymous namespace
+
TextPainterBase::TextPainterBase(GraphicsContext& context,
const Font& font,
const PhysicalOffset& text_origin,
@@ -70,8 +166,7 @@ void TextPainterBase::UpdateGraphicsContext(
if (text_style.stroke_width > 0) {
TextDrawingModeFlags new_mode = mode | kTextModeStroke;
if (mode != new_mode) {
- if (!state_saver.Saved())
- state_saver.Save();
+ state_saver.SaveIfNeeded();
context.SetTextDrawingMode(new_mode);
mode = new_mode;
}
@@ -88,8 +183,7 @@ void TextPainterBase::UpdateGraphicsContext(
}
if (text_style.shadow) {
- if (!state_saver.Saved())
- state_saver.Save();
+ state_saver.SaveIfNeeded();
context.SetDrawLooper(text_style.shadow->CreateDrawLooper(
DrawLooperBuilder::kShadowIgnoresAlpha, text_style.current_color,
horizontal));
@@ -195,7 +289,6 @@ void TextPainterBase::PaintDecorationsExceptLineThrough(
GraphicsContext& context = paint_info.context;
GraphicsContextStateSaver state_saver(context);
UpdateGraphicsContext(context, text_style, horizontal_, state_saver);
- context.SetStrokeThickness(decoration_info.thickness);
if (has_combined_text_)
context.ConcatCTM(Rotation(text_bounds_, kClockwise));
@@ -209,20 +302,31 @@ void TextPainterBase::PaintDecorationsExceptLineThrough(
underline_position = ResolvedUnderlinePosition::kUnder;
}
- for (const AppliedTextDecoration& decoration : decorations) {
+ DCHECK_EQ(decorations.size(),
+ decoration_info.applied_decorations_thickness.size());
+ for (size_t applied_decorations_index = 0;
+ applied_decorations_index < decorations.size();
+ ++applied_decorations_index) {
+ const AppliedTextDecoration& decoration =
+ decorations[applied_decorations_index];
TextDecoration lines = decoration.Lines();
bool has_underline = EnumHasFlags(lines, TextDecoration::kUnderline);
bool has_overline = EnumHasFlags(lines, TextDecoration::kOverline);
if (flip_underline_and_overline)
std::swap(has_underline, has_overline);
+ float resolved_thickness =
+ decoration_info
+ .applied_decorations_thickness[applied_decorations_index];
+ context.SetStrokeThickness(resolved_thickness);
+
if (has_underline && decoration_info.font_data) {
const int underline_offset = decoration_offset.ComputeUnderlineOffset(
underline_position, decoration_info.font_data->GetFontMetrics(),
- decoration_info.thickness);
- PaintDecorationUnderOrOverLine(context, decoration_info, decoration,
- underline_offset,
- decoration_info.double_offset);
+ resolved_thickness);
+ PaintDecorationUnderOrOverLine(
+ context, decoration_info, decoration, applied_decorations_index,
+ underline_offset, DoubleOffsetFromThickness(resolved_thickness));
}
if (has_overline) {
@@ -230,11 +334,11 @@ void TextPainterBase::PaintDecorationsExceptLineThrough(
flip_underline_and_overline ? FontVerticalPositionType::TopOfEmHeight
: FontVerticalPositionType::TextTop;
const int overline_offset =
- decoration_offset.ComputeUnderlineOffsetForUnder(
- decoration_info.thickness, position);
- PaintDecorationUnderOrOverLine(context, decoration_info, decoration,
- overline_offset,
- -decoration_info.double_offset);
+ decoration_offset.ComputeUnderlineOffsetForUnder(resolved_thickness,
+ position);
+ PaintDecorationUnderOrOverLine(
+ context, decoration_info, decoration, applied_decorations_index,
+ overline_offset, -DoubleOffsetFromThickness(resolved_thickness));
}
// We could instead build a vector of the TextDecoration instances needing
@@ -256,18 +360,36 @@ void TextPainterBase::PaintDecorationsOnlyLineThrough(
GraphicsContext& context = paint_info.context;
GraphicsContextStateSaver state_saver(context);
UpdateGraphicsContext(context, text_style, horizontal_, state_saver);
- context.SetStrokeThickness(decoration_info.thickness);
if (has_combined_text_)
context.ConcatCTM(Rotation(text_bounds_, kClockwise));
- for (const AppliedTextDecoration& decoration : decorations) {
+ DCHECK_EQ(decorations.size(),
+ decoration_info.applied_decorations_thickness.size());
+ for (size_t applied_decoration_index = 0;
+ applied_decoration_index < decorations.size();
+ ++applied_decoration_index) {
+ const AppliedTextDecoration& decoration =
+ decorations[applied_decoration_index];
TextDecoration lines = decoration.Lines();
if (EnumHasFlags(lines, TextDecoration::kLineThrough)) {
- const float line_through_offset = 2 * decoration_info.baseline / 3;
+ float resolved_thickness =
+ decoration_info
+ .applied_decorations_thickness[applied_decoration_index];
+ context.SetStrokeThickness(resolved_thickness);
+ // For increased line thickness, the line-through decoration needs to grow
+ // in both directions from its origin, subtract half the thickness to keep
+ // it centered at the same origin.
+ const float line_through_offset =
+ 2 * decoration_info.baseline / 3 - resolved_thickness / 2;
+ // Floor double_offset in order to avoid double-line gap to appear
+ // of different size depending on position where the double line
+ // is drawn because of rounding downstream in
+ // GraphicsContext::DrawLineForText.
AppliedDecorationPainter decoration_painter(
context, decoration_info, line_through_offset, decoration,
- decoration_info.double_offset, 0);
+ applied_decoration_index,
+ floorf(DoubleOffsetFromThickness(resolved_thickness)), 0);
// No skip: ink for line-through,
// compare https://github.com/w3c/csswg-drafts/issues/711
decoration_painter.Paint();
@@ -279,68 +401,6 @@ void TextPainterBase::PaintDecorationsOnlyLineThrough(
context.ConcatCTM(Rotation(text_bounds_, kCounterclockwise));
}
-namespace {
-
-static ResolvedUnderlinePosition ResolveUnderlinePosition(
- const ComputedStyle& style,
- FontBaseline baseline_type) {
- // |auto| should resolve to |under| to avoid drawing through glyphs in
- // scripts where it would not be appropriate (e.g., ideographs.)
- // However, this has performance implications. For now, we only work with
- // vertical text.
- switch (baseline_type) {
- case kAlphabeticBaseline:
- if (style.TextUnderlinePosition() & kTextUnderlinePositionUnder)
- return ResolvedUnderlinePosition::kUnder;
- if (style.TextUnderlinePosition() & kTextUnderlinePositionFromFont)
- return ResolvedUnderlinePosition::kNearAlphabeticBaselineFromFont;
- return ResolvedUnderlinePosition::kNearAlphabeticBaselineAuto;
- case kIdeographicBaseline:
- // Compute language-appropriate default underline position.
- // https://drafts.csswg.org/css-text-decor-3/#default-stylesheet
- UScriptCode script = style.GetFontDescription().GetScript();
- if (script == USCRIPT_KATAKANA_OR_HIRAGANA || script == USCRIPT_HANGUL) {
- if (style.TextUnderlinePosition() & kTextUnderlinePositionLeft) {
- return ResolvedUnderlinePosition::kUnder;
- }
- return ResolvedUnderlinePosition::kOver;
- }
- if (style.TextUnderlinePosition() & kTextUnderlinePositionRight) {
- return ResolvedUnderlinePosition::kOver;
- }
- return ResolvedUnderlinePosition::kUnder;
- }
- NOTREACHED();
- return ResolvedUnderlinePosition::kNearAlphabeticBaselineAuto;
-}
-
-static bool ShouldSetDecorationAntialias(const ComputedStyle& style) {
- for (const auto& decoration : style.AppliedTextDecorations()) {
- ETextDecorationStyle decoration_style = decoration.Style();
- if (decoration_style == ETextDecorationStyle::kDotted ||
- decoration_style == ETextDecorationStyle::kDashed)
- return true;
- }
- return false;
-}
-
-float ComputeDecorationThickness(const ComputedStyle* style,
- const SimpleFontData* font_data) {
- // TODO(https://crbug.com/785230): Implement text-decoration-thickness setting
- // and the from-font keyword here. We previously tried reading
- // font_data->FontMetrics().UnderlineThickness() here but that never returned
- // anything other than 0. Removed no-op implementation until we implement
- // from-font behavior here. Keep font_data argument for now as this will be
- // needed for the from-font implementation.
-
- // Set the thickness of the line to be 10% (or something else ?)of the
- // computed font size and not less than 1px. Using computedFontSize should
- // take care of zoom as well.
- return std::max(1.f, style->ComputedFontSize() / 10.f);
-}
-
-} // anonymous namespace
-
void TextPainterBase::ComputeDecorationInfo(
DecorationInfo& decoration_info,
const PhysicalOffset& box_origin,
@@ -364,45 +424,67 @@ void TextPainterBase::ComputeDecorationInfo(
? decoration_info.font_data->GetFontMetrics().FloatAscent()
: 0;
- if ((decoration_info.underline_position ==
+ for (const AppliedTextDecoration& decoration :
+ style.AppliedTextDecorations()) {
+ decoration_info.applied_decorations_thickness.push_back(
+ ComputeUnderlineThickness(decoration_info.underline_position,
+ decoration.Thickness(), style,
+ decorating_box_style));
+ }
+ DCHECK_EQ(style.AppliedTextDecorations().size(),
+ decoration_info.applied_decorations_thickness.size());
+}
+
+float TextPainterBase::ComputeUnderlineThickness(
+ const ResolvedUnderlinePosition& underline_position,
+ const TextDecorationThickness& applied_decoration_thickness,
+ const ComputedStyle& style,
+ const ComputedStyle* decorating_box_style) {
+ float thickness = 0;
+ if ((underline_position ==
ResolvedUnderlinePosition::kNearAlphabeticBaselineAuto) ||
- decoration_info.underline_position ==
+ underline_position ==
ResolvedUnderlinePosition::kNearAlphabeticBaselineFromFont) {
- decoration_info.thickness = ComputeDecorationThickness(
- decoration_info.style, decoration_info.font_data);
+ thickness = ComputeDecorationThickness(applied_decoration_thickness, style,
+ style.GetFont().PrimaryFont());
} else {
// Compute decorating box. Position and thickness are computed from the
// decorating box.
// Only for non-Roman for now for the performance implications.
// https:// drafts.csswg.org/css-text-decor-3/#decorating-box
if (decorating_box_style) {
- decoration_info.thickness = ComputeDecorationThickness(
- decorating_box_style, decorating_box_style->GetFont().PrimaryFont());
+ thickness = ComputeDecorationThickness(
+ applied_decoration_thickness, *decorating_box_style,
+ decorating_box_style->GetFont().PrimaryFont());
} else {
- decoration_info.thickness = ComputeDecorationThickness(
- decoration_info.style, decoration_info.font_data);
+ thickness = ComputeDecorationThickness(
+ applied_decoration_thickness, style, style.GetFont().PrimaryFont());
}
}
-
- // Offset between lines - always non-zero, so lines never cross each other.
- decoration_info.double_offset = decoration_info.thickness + 1.f;
+ return thickness;
}
void TextPainterBase::PaintDecorationUnderOrOverLine(
GraphicsContext& context,
const DecorationInfo& decoration_info,
const AppliedTextDecoration& decoration,
+ size_t decoration_info_thickness_index,
int line_offset,
float decoration_offset) {
AppliedDecorationPainter decoration_painter(
- context, decoration_info, line_offset, decoration, decoration_offset, 1);
+ context, decoration_info, line_offset, decoration,
+ decoration_info_thickness_index, decoration_offset, 1);
if (decoration_info.style->TextDecorationSkipInk() ==
ETextDecorationSkipInk::kAuto) {
FloatRect decoration_bounds = decoration_painter.Bounds();
- ClipDecorationsStripe(-decoration_info.baseline + decoration_bounds.Y() -
- decoration_info.local_origin.Y(),
- decoration_bounds.Height(),
- decoration_info.thickness);
+ ClipDecorationsStripe(
+ -decoration_info.baseline + decoration_bounds.Y() -
+ decoration_info.local_origin.Y(),
+ decoration_bounds.Height(),
+ std::min(
+ decoration_info
+ .applied_decorations_thickness[decoration_info_thickness_index],
+ kDecorationClipMaxDilation));
}
decoration_painter.Paint();
}
diff --git a/chromium/third_party/blink/renderer/core/paint/text_painter_base.h b/chromium/third_party/blink/renderer/core/paint/text_painter_base.h
index 4b139148cd4..067eec8bcd5 100644
--- a/chromium/third_party/blink/renderer/core/paint/text_painter_base.h
+++ b/chromium/third_party/blink/renderer/core/paint/text_painter_base.h
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/paint/decoration_info.h"
#include "third_party/blink/renderer/core/paint/text_paint_style.h"
#include "third_party/blink/renderer/core/style/applied_text_decoration.h"
+#include "third_party/blink/renderer/core/style/text_decoration_thickness.h"
#include "third_party/blink/renderer/platform/fonts/font.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/transforms/affine_transform.h"
@@ -64,6 +65,7 @@ class CORE_EXPORT TextPainterBase {
void PaintDecorationUnderOrOverLine(GraphicsContext&,
const DecorationInfo&,
const AppliedTextDecoration&,
+ size_t decoration_info_thickness_index,
int line_offset,
float decoration_offset);
@@ -75,6 +77,12 @@ class CORE_EXPORT TextPainterBase {
const ComputedStyle&,
const ComputedStyle* decorating_box_style);
+ float ComputeUnderlineThickness(
+ const ResolvedUnderlinePosition& underline_position,
+ const TextDecorationThickness& applied_decoration_thickness,
+ const ComputedStyle&,
+ const ComputedStyle* decorating_box_style);
+
static Color TextColorForWhiteBackground(Color);
static TextPaintStyle TextPaintingStyle(const Document&,
const ComputedStyle&,
diff --git a/chromium/third_party/blink/renderer/core/paint/theme_painter_default.cc b/chromium/third_party/blink/renderer/core/paint/theme_painter_default.cc
index 9da24a1c670..59108647463 100644
--- a/chromium/third_party/blink/renderer/core/paint/theme_painter_default.cc
+++ b/chromium/third_party/blink/renderer/core/paint/theme_painter_default.cc
@@ -350,20 +350,32 @@ bool ThemePainterDefault::PaintSliderTrack(const LayoutObject& o,
auto* input = DynamicTo<HTMLInputElement>(o.GetNode());
extra_params.slider.thumb_x = 0;
extra_params.slider.thumb_y = 0;
+ extra_params.slider.right_to_left = !o.StyleRef().IsLeftToRightDirection();
if (input) {
Element* thumb_element = input->UserAgentShadowRoot()
? input->UserAgentShadowRoot()->getElementById(
shadow_element_names::SliderThumb())
: nullptr;
LayoutBox* thumb = thumb_element ? thumb_element->GetLayoutBox() : nullptr;
+ LayoutBox* input_box = input->GetLayoutBox();
if (thumb) {
IntRect thumb_rect = PixelSnappedIntRect(thumb->FrameRect());
if (features::IsFormControlsRefreshEnabled()) {
- extra_params.slider.thumb_x = thumb_rect.X();
- extra_params.slider.thumb_y = thumb_rect.Y();
+ extra_params.slider.thumb_x = thumb_rect.X() +
+ input_box->PaddingLeft().ToInt() +
+ input_box->BorderLeft().ToInt();
+ extra_params.slider.thumb_y = thumb_rect.Y() +
+ input_box->PaddingTop().ToInt() +
+ input_box->BorderTop().ToInt();
} else {
- extra_params.slider.thumb_x = thumb_rect.X() / zoom_level;
- extra_params.slider.thumb_y = thumb_rect.Y() / zoom_level;
+ extra_params.slider.thumb_x =
+ (thumb_rect.X() + input_box->PaddingLeft().ToInt() +
+ input_box->BorderLeft().ToInt()) /
+ zoom_level;
+ extra_params.slider.thumb_y =
+ (thumb_rect.Y() + input_box->PaddingTop().ToInt() +
+ input_box->BorderTop().ToInt()) /
+ zoom_level;
}
}
}
diff --git a/chromium/third_party/blink/renderer/core/paint/video_painter.cc b/chromium/third_party/blink/renderer/core/paint/video_painter.cc
index b15d3ec197a..128778a92e3 100644
--- a/chromium/third_party/blink/renderer/core/paint/video_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/video_painter.cc
@@ -19,11 +19,15 @@ namespace blink {
void VideoPainter::PaintReplaced(const PaintInfo& paint_info,
const PhysicalOffset& paint_offset) {
+ if (paint_info.phase != PaintPhase::kForeground &&
+ paint_info.phase != PaintPhase::kSelectionDragImage)
+ return;
+
WebMediaPlayer* media_player =
layout_video_.MediaElement()->GetWebMediaPlayer();
- bool displaying_poster =
- layout_video_.VideoElement()->ShouldDisplayPosterImage();
- if (!displaying_poster && !media_player)
+ bool should_display_poster =
+ layout_video_.GetDisplayMode() == LayoutVideo::kPoster;
+ if (!should_display_poster && !media_player)
return;
PhysicalRect replaced_rect = layout_video_.ReplacedContentRect();
@@ -57,8 +61,9 @@ void VideoPainter::PaintReplaced(const PaintInfo& paint_info,
paint_info.GetGlobalPaintFlags() & kGlobalPaintFlattenCompositingLayers;
bool paint_with_foreign_layer =
- !displaying_poster && !force_software_video_paint &&
- RuntimeEnabledFeatures::CompositeAfterPaintEnabled();
+ RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+ paint_info.phase == PaintPhase::kForeground && !should_display_poster &&
+ !force_software_video_paint;
if (paint_with_foreign_layer) {
if (cc::Layer* layer = layout_video_.MediaElement()->CcLayer()) {
layer->SetBounds(gfx::Size(snapped_replaced_rect.Size()));
@@ -73,7 +78,7 @@ void VideoPainter::PaintReplaced(const PaintInfo& paint_info,
DrawingRecorder recorder(context, layout_video_, paint_info.phase);
- if (displaying_poster || !force_software_video_paint) {
+ if (should_display_poster || !force_software_video_paint) {
// This will display the poster image, if one is present, and otherwise
// paint nothing.
DCHECK(paint_info.PaintContainer());
diff --git a/chromium/third_party/blink/renderer/core/paint/video_painter.h b/chromium/third_party/blink/renderer/core/paint/video_painter.h
index c8f0ccbd4ac..eb089b13333 100644
--- a/chromium/third_party/blink/renderer/core/paint/video_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/video_painter.h
@@ -17,7 +17,8 @@ class VideoPainter {
STACK_ALLOCATED();
public:
- VideoPainter(const LayoutVideo& layout_video) : layout_video_(layout_video) {}
+ explicit VideoPainter(const LayoutVideo& layout_video)
+ : layout_video_(layout_video) {}
void PaintReplaced(const PaintInfo&, const PhysicalOffset& paint_offset);
diff --git a/chromium/third_party/blink/renderer/core/paint/video_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/video_painter_test.cc
index 0c436ef3b43..a9c0aae8449 100644
--- a/chromium/third_party/blink/renderer/core/paint/video_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/video_painter_test.cc
@@ -165,7 +165,8 @@ TEST_P(VideoPaintPreviewTest, URLIsRecordedWhenPaintingPreview) {
canvas->SetPaintPreviewTracker(&tracker);
EXPECT_EQ(0lu, tracker.GetLinks().size());
- GetLocalMainFrame().CapturePaintPreview(WebRect(bounds()), canvas);
+ GetLocalMainFrame().CapturePaintPreview(WebRect(bounds()), canvas,
+ /*include_linked_destinations=*/true);
ASSERT_EQ(1lu, tracker.GetLinks().size());
EXPECT_EQ("http://test.com/", tracker.GetLinks()[0]->url);
diff --git a/chromium/third_party/blink/renderer/core/paint/view_painter.cc b/chromium/third_party/blink/renderer/core/paint/view_painter.cc
index 1c0acf43c74..b0f016148db 100644
--- a/chromium/third_party/blink/renderer/core/paint/view_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/view_painter.cc
@@ -88,7 +88,7 @@ void ViewPainter::PaintBoxDecorationBackground(const PaintInfo& paint_info) {
layout_view_.Layer()->GetCompositedLayerMapping() &&
layout_view_.Layer()
->GetCompositedLayerMapping()
- ->HasScrollingLayer()) {
+ ->ScrollingContentsLayer()) {
paints_scroll_hit_test = false;
}
}
diff --git a/chromium/third_party/blink/renderer/core/probe/core_probes.json5 b/chromium/third_party/blink/renderer/core/probe/core_probes.json5
index e1c6bec6800..e6286093795 100644
--- a/chromium/third_party/blink/renderer/core/probe/core_probes.json5
+++ b/chromium/third_party/blink/renderer/core/probe/core_probes.json5
@@ -24,6 +24,11 @@
"ExecuteScript",
]
},
+ InspectorIssueReporter: {
+ probes: [
+ "DidFailLoading",
+ ]
+ },
InspectorAnimationAgent: {
probes: [
"AnimationPlayStateChanged",
@@ -45,6 +50,7 @@
InspectorCSSAgent: {
probes: [
"ActiveStyleSheetsUpdated",
+ "DidMutateStyleSheet",
"DocumentDetached",
"FontsUpdated",
"ForcePseudoState",
diff --git a/chromium/third_party/blink/renderer/core/probe/core_probes.pidl b/chromium/third_party/blink/renderer/core/probe/core_probes.pidl
index 495e90dc865..70bc6c41e37 100644
--- a/chromium/third_party/blink/renderer/core/probe/core_probes.pidl
+++ b/chromium/third_party/blink/renderer/core/probe/core_probes.pidl
@@ -101,7 +101,7 @@ interface CoreProbes {
void DidReceiveEncodedDataLength(CoreProbeSink*, DocumentLoader* loader, uint64_t identifier, size_t encoded_data_length);
void DidFinishLoading(CoreProbeSink*, uint64_t identifier, DocumentLoader*, base::TimeTicks finish_time, int64_t encoded_data_length, int64_t decoded_body_length, bool should_report_corb_blocking);
void DidReceiveCorsRedirectResponse(ExecutionContext*, uint64_t identifier, DocumentLoader*, const ResourceResponse&, Resource*);
- void DidFailLoading(CoreProbeSink*, uint64_t identifier, DocumentLoader*, const ResourceError&);
+ void DidFailLoading([Keep] CoreProbeSink*, uint64_t identifier, DocumentLoader*, const ResourceError&, const base::UnguessableToken&);
void WillSendEventSourceRequest(ExecutionContext*);
void WillDispatchEventSourceEvent(ExecutionContext*, uint64_t identifier, const AtomicString& event_name, const AtomicString& event_id, const String& data);
void WillLoadXHR([Keep] ExecutionContext*, const AtomicString& method, const KURL& url, bool async, const HTTPHeaderMap& headers, bool include_credentials);
@@ -144,7 +144,7 @@ interface CoreProbes {
void AnimationPlayStateChanged(Document*, Animation*, Animation::AnimationPlayState old_play_state, Animation::AnimationPlayState new_play_state);
void WindowOpen([Keep] Document*, const String& url, const AtomicString& window_name, const WebWindowFeatures& window_features, bool user_gestrue);
void ConsoleMessageAdded(ExecutionContext*, ConsoleMessage*);
- void InspectorIssueAdded(ExecutionContext*, InspectorIssue*);
+ void InspectorIssueAdded(CoreProbeSink*, InspectorIssue*);
void WillRunJavaScriptDialog(LocalFrame* frame);
void DidRunJavaScriptDialog(LocalFrame* frame);
void DocumentWriteFetchScript([Keep] Document*);
@@ -180,5 +180,6 @@ interface CoreProbes {
void PlayerMessagesLogged(ExecutionContext* context, String player_id, const Vector<InspectorPlayerMessage>& messages);
void PlayerPropertiesChanged(ExecutionContext* context, String player_id, const Vector<InspectorPlayerProperty>& properties);
void PlayersCreated(ExecutionContext* context, const Vector<WebString>& players);
- void SetDevToolsIds(CoreProbeSink*, ResourceRequest& request);
+ void SetDevToolsIds(CoreProbeSink*, ResourceRequest& request, const FetchInitiatorInfo&);
+ void DidMutateStyleSheet(Document*, CSSStyleSheet* style_sheet);
}
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observation.cc b/chromium/third_party/blink/renderer/core/resize_observer/resize_observation.cc
index 27293da6a2b..763ebbac99b 100644
--- a/chromium/third_party/blink/renderer/core/resize_observer/resize_observation.cc
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observation.cc
@@ -108,7 +108,7 @@ LayoutSize ResizeObservation::ComputeTargetSize() const {
return LayoutSize();
}
-void ResizeObservation::Trace(Visitor* visitor) {
+void ResizeObservation::Trace(Visitor* visitor) const {
visitor->Trace(target_);
visitor->Trace(observer_);
}
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observation.h b/chromium/third_party/blink/renderer/core/resize_observer/resize_observation.h
index 66c0ac6561c..ae5d70f971d 100644
--- a/chromium/third_party/blink/renderer/core/resize_observer/resize_observation.h
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observation.h
@@ -33,7 +33,7 @@ class CORE_EXPORT ResizeObservation final
LayoutSize ComputeTargetSize() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
WeakMember<Element> target_;
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer.cc b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer.cc
index cb90e34bb18..4b4d3ffafab 100644
--- a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer.cc
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer.cc
@@ -199,7 +199,7 @@ bool ResizeObserver::HasPendingActivity() const {
return !observations_.IsEmpty();
}
-void ResizeObserver::Trace(Visitor* visitor) {
+void ResizeObserver::Trace(Visitor* visitor) const {
visitor->Trace(callback_);
visitor->Trace(delegate_);
visitor->Trace(observations_);
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer.h b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer.h
index 18af42d6c8e..640b8156112 100644
--- a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer.h
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer.h
@@ -39,7 +39,7 @@ class CORE_EXPORT ResizeObserver final
virtual ~Delegate() = default;
virtual void OnResize(
const HeapVector<Member<ResizeObserverEntry>>& entries) = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
static ResizeObserver* Create(ScriptState*, V8ResizeObserverCallback*);
@@ -66,7 +66,7 @@ class CORE_EXPORT ResizeObserver final
// ScriptWrappable override:
bool HasPendingActivity() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void observeInternal(Element* target, ResizeObserverBoxOptions box_option);
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_controller.cc b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_controller.cc
index 51bba948c6d..16683c8d697 100644
--- a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_controller.cc
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_controller.cc
@@ -71,7 +71,7 @@ void ResizeObserverController::ClearObservations() {
observer->ClearObservations();
}
-void ResizeObserverController::Trace(Visitor* visitor) {
+void ResizeObserverController::Trace(Visitor* visitor) const {
Supplement<LocalDOMWindow>::Trace(visitor);
visitor->Trace(observers_);
}
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_controller.h b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_controller.h
index 5985219e001..698d2020e75 100644
--- a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_controller.h
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_controller.h
@@ -55,7 +55,7 @@ class CORE_EXPORT ResizeObserverController final
loop_limit_error_dispatched = is_dispatched;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// For testing only.
const HeapLinkedHashSet<WeakMember<ResizeObserver>>& Observers() {
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.cc b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.cc
index 92e6fc56cf0..16fd0f24317 100644
--- a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.cc
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.cc
@@ -116,7 +116,7 @@ ResizeObserverEntry::ResizeObserverEntry(Element* target) : target_(target) {
}
}
-void ResizeObserverEntry::Trace(Visitor* visitor) {
+void ResizeObserverEntry::Trace(Visitor* visitor) const {
visitor->Trace(target_);
visitor->Trace(content_rect_);
visitor->Trace(content_box_size_);
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.h b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.h
index 39494322080..c2cc3174d15 100644
--- a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.h
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.h
@@ -37,7 +37,7 @@ class CORE_EXPORT ResizeObserverEntry final : public ScriptWrappable {
return device_pixel_content_box_size_;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Element> target_;
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc
index f39ef42669e..baad1da807d 100644
--- a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc
@@ -38,7 +38,7 @@ class TestResizeObserverDelegate : public ResizeObserver::Delegate {
ExecutionContext* GetExecutionContext() const { return window_.Get(); }
int CallCount() const { return call_count_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
ResizeObserver::Delegate::Trace(visitor);
visitor->Trace(window_);
}
@@ -257,7 +257,7 @@ TEST_F(ResizeObserverUnitTest, TestMemoryLeaks) {
v8::HandleScope scope(v8::Isolate::GetCurrent());
ScriptController& script_controller =
- GetDocument().ExecutingFrame()->GetScriptController();
+ Window().GetFrame()->GetScriptController();
//
// Test whether ResizeObserver is kept alive by direct JS reference
diff --git a/chromium/third_party/blink/renderer/core/scheduler_integration_tests/frame_throttling_test.cc b/chromium/third_party/blink/renderer/core/scheduler_integration_tests/frame_throttling_test.cc
index b137d33dc27..658ec6cf8b4 100644
--- a/chromium/third_party/blink/renderer/core/scheduler_integration_tests/frame_throttling_test.cc
+++ b/chromium/third_party/blink/renderer/core/scheduler_integration_tests/frame_throttling_test.cc
@@ -12,7 +12,6 @@
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element.h"
-#include "third_party/blink/renderer/core/exported/web_remote_frame_impl.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
@@ -1513,4 +1512,68 @@ TEST_P(FrameThrottlingTest, GraphicsLayerCollection) {
EXPECT_EQ(display_item_count, paint_controller->GetDisplayItemList().size());
}
+TEST_P(FrameThrottlingTest, NestedFramesInRemoteFrameHiddenAndShown) {
+ InitializeRemote();
+
+ SimRequest local_root_resource("https://example.com/", "text/html");
+ SimRequest frame_resource("https://example.com/iframe.html", "text/html");
+ SimRequest child_frame_resource("https://example.com/child-iframe.html",
+ "text/html");
+
+ LoadURL("https://example.com/");
+ local_root_resource.Complete(
+ "<iframe id=frame sandbox src=iframe.html></iframe>");
+ frame_resource.Complete(
+ "<iframe id=child-frame sandbox src=child-iframe.html></iframe>");
+ child_frame_resource.Complete("");
+
+ ViewportIntersectionState intersection;
+ intersection.main_frame_document_intersection = WebRect(0, 0, 100, 100);
+ intersection.main_frame_viewport_size = WebSize(100, 100);
+ intersection.viewport_intersection = WebRect(0, 0, 100, 100);
+ LocalFrameRoot().FrameWidget()->Resize(WebSize(300, 200));
+ LocalFrameRoot().FrameWidget()->SetRemoteViewportIntersection(intersection);
+
+ auto* root_document = LocalFrameRoot().GetFrame()->GetDocument();
+ auto* frame_document =
+ To<HTMLIFrameElement>(root_document->getElementById("frame"))
+ ->contentDocument();
+ auto* frame_view = frame_document->View();
+ auto* child_document =
+ To<HTMLIFrameElement>(frame_document->getElementById("child-frame"))
+ ->contentDocument();
+ auto* child_view = child_document->View();
+
+ CompositeFrame();
+ EXPECT_FALSE(frame_view->CanThrottleRendering());
+ EXPECT_FALSE(child_view->CanThrottleRendering());
+
+ // Hide the frame without any other change.
+ LocalFrameRoot().WasHidden();
+ EXPECT_TRUE(frame_view->CanThrottleRendering());
+ EXPECT_TRUE(child_view->CanThrottleRendering());
+ EXPECT_FALSE(Compositor().NeedsBeginFrame());
+
+ // Simulate a trivial style change that doesn't trigger layout, compositing
+ // update, but schedules layout tree update.
+ frame_document->documentElement()->setAttribute(html_names::kStyleAttr,
+ "color: blue");
+ // This is needed to reproduce crbug.com/1054644 before the fix.
+ frame_view->SetNeedsPaintPropertyUpdate();
+
+ // Show the frame without any other change.
+ LocalFrameRoot().WasShown();
+ LocalFrameRoot().FrameWidget()->SetRemoteViewportIntersection(intersection);
+ CompositeFrame();
+ EXPECT_FALSE(frame_view->CanThrottleRendering());
+ // The child frame's throtting status is not updated because the parent
+ // document has pending visual update.
+ EXPECT_TRUE(child_view->CanThrottleRendering());
+
+ CompositeFrame();
+ EXPECT_FALSE(frame_view->CanThrottleRendering());
+ // The child frame's throttling status should be updated now.
+ EXPECT_FALSE(child_view->CanThrottleRendering());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/script/classic_pending_script.cc b/chromium/third_party/blink/renderer/core/script/classic_pending_script.cc
index c3838502cf1..42196efc43c 100644
--- a/chromium/third_party/blink/renderer/core/script/classic_pending_script.cc
+++ b/chromium/third_party/blink/renderer/core/script/classic_pending_script.cc
@@ -168,26 +168,22 @@ void RecordNotStreamingReasonHistogram(
switch (type) {
case ScriptSchedulingType::kParserBlocking: {
UMA_HISTOGRAM_ENUMERATION(
- "WebCore.Scripts.ParsingBlocking.NotStreamingReason", reason,
- ScriptStreamer::NotStreamingReason::kCount);
+ "WebCore.Scripts.ParsingBlocking.NotStreamingReason", reason);
break;
}
case ScriptSchedulingType::kDefer: {
UMA_HISTOGRAM_ENUMERATION("WebCore.Scripts.Deferred.NotStreamingReason",
- reason,
- ScriptStreamer::NotStreamingReason::kCount);
+ reason);
break;
}
case ScriptSchedulingType::kAsync: {
UMA_HISTOGRAM_ENUMERATION("WebCore.Scripts.Async.NotStreamingReason",
- reason,
- ScriptStreamer::NotStreamingReason::kCount);
+ reason);
break;
}
default: {
UMA_HISTOGRAM_ENUMERATION("WebCore.Scripts.Other.NotStreamingReason",
- reason,
- ScriptStreamer::NotStreamingReason::kCount);
+ reason);
break;
}
}
@@ -201,7 +197,7 @@ void ClassicPendingScript::RecordStreamingHistogram(
ScriptStreamer::NotStreamingReason reason) {
RecordStartedStreamingHistogram(type, can_use_streamer);
if (!can_use_streamer) {
- DCHECK_NE(ScriptStreamer::kInvalid, reason);
+ DCHECK_NE(ScriptStreamer::NotStreamingReason::kInvalid, reason);
RecordNotStreamingReasonHistogram(type, reason);
}
}
@@ -212,23 +208,13 @@ void ClassicPendingScript::DisposeInternal() {
integrity_failure_ = false;
}
-void ClassicPendingScript::WatchForLoad(PendingScriptClient* client) {
- if (is_external_) {
- // Once we are watching the ClassicPendingScript for load, we won't ever
- // try to start streaming this resource via this ClassicPendingScript, so
- // we mark the resource to instead get a finished notification when loading
- // (rather than streaming) completes.
- //
- // Do this in a task rather than directly to make sure the IsReady state
- // of PendingScript does not change during this call.
- GetElement()
- ->GetDocument()
- .GetTaskRunner(TaskType::kNetworking)
- ->PostTask(FROM_HERE,
- WTF::Bind(&ScriptResource::SetClientIsWaitingForFinished,
- WrapPersistent(ToScriptResource(GetResource()))));
- }
- PendingScript::WatchForLoad(client);
+bool ClassicPendingScript::IsEligibleForDelay() const {
+ DCHECK_EQ(GetSchedulingType(), ScriptSchedulingType::kAsync);
+ // We don't delay async scripts that have matched a resource in the preload
+ // cache, because we're using <link rel=preload> as a signal that the script
+ // is higher-than-usual priority, and therefore should be executed earlier
+ // rather than later.
+ return !GetResource()->IsLinkPreload();
}
void ClassicPendingScript::NotifyFinished(Resource* resource) {
@@ -293,7 +279,7 @@ void ClassicPendingScript::NotifyFinished(Resource* resource) {
AdvanceReadyState(error_occurred ? kErrorOccurred : kReady);
}
-void ClassicPendingScript::Trace(Visitor* visitor) {
+void ClassicPendingScript::Trace(Visitor* visitor) const {
ResourceClient::Trace(visitor);
MemoryPressureListener::Trace(visitor);
PendingScript::Trace(visitor);
@@ -343,7 +329,7 @@ ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url) const {
DCHECK(!GetResource());
RecordStreamingHistogram(GetSchedulingType(), false,
- ScriptStreamer::kInlineScript);
+ ScriptStreamer::NotStreamingReason::kInlineScript);
ScriptSourceCode source_code(source_text_for_inline_script_,
source_location_type_, cache_handler,
@@ -356,7 +342,7 @@ ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url) const {
DCHECK(GetResource()->IsLoaded());
ScriptResource* resource = ToScriptResource(GetResource());
- auto* fetcher = GetElement()->GetDocument().ContextDocument()->Fetcher();
+ auto* fetcher = GetElement()->GetExecutionContext()->Fetcher();
// If the MIME check fails, which is considered as load failure.
if (!AllowedByNosniff::MimeTypeAsScript(
fetcher->GetUseCounter(), &fetcher->GetConsoleLogger(),
@@ -366,24 +352,25 @@ ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url) const {
}
// Check if we can use the script streamer.
- bool streamer_ready = false;
+ bool did_stream = false;
ScriptStreamer::NotStreamingReason not_streamed_reason =
resource->NoStreamerReason();
ScriptStreamer* streamer = resource->TakeStreamer();
if (streamer) {
- DCHECK_EQ(not_streamed_reason, ScriptStreamer::kInvalid);
- if (streamer->StreamingSuppressed()) {
+ DCHECK_EQ(not_streamed_reason,
+ ScriptStreamer::NotStreamingReason::kInvalid);
+ if (streamer->IsStreamingSuppressed()) {
not_streamed_reason = streamer->StreamingSuppressedReason();
} else if (ready_state_ == kErrorOccurred) {
- not_streamed_reason = ScriptStreamer::kErrorOccurred;
- } else {
- // Streamer can be used to compile script.
+ not_streamed_reason = ScriptStreamer::NotStreamingReason::kErrorOccurred;
+ } else if (not_streamed_reason ==
+ ScriptStreamer::NotStreamingReason::kInvalid) {
+ // streamer can be used to compile script.
CHECK_EQ(ready_state_, kReady);
- not_streamed_reason = ScriptStreamer::kInvalid;
- streamer_ready = true;
+ did_stream = true;
}
}
- RecordStreamingHistogram(GetSchedulingType(), streamer_ready,
+ RecordStreamingHistogram(GetSchedulingType(), did_stream,
not_streamed_reason);
TRACE_EVENT_WITH_FLOW1(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
@@ -391,7 +378,7 @@ ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url) const {
TRACE_EVENT_FLAG_FLOW_IN, "not_streamed_reason",
not_streamed_reason);
- ScriptSourceCode source_code(streamer_ready ? streamer : nullptr, resource,
+ ScriptSourceCode source_code(did_stream ? streamer : nullptr, resource,
not_streamed_reason);
// The base URL for external classic script is
//
@@ -439,34 +426,6 @@ void ClassicPendingScript::OnPurgeMemory() {
// here.
}
-void ClassicPendingScript::StartStreamingIfPossible() {
- // We can start streaming in two states: While still loading
- // (kWaitingForResource), or after having loaded (kReady).
- if (ready_state_ != kWaitingForResource && ready_state_ != kReady)
- return;
-
- Document* document = &GetElement()->GetDocument();
- if (!document || !document->GetFrame())
- return;
-
- // Parser blocking scripts tend to do a lot of work in the 'finished'
- // callbacks, while async + in-order scripts all do control-like activities
- // (like posting new tasks). Use the 'control' queue only for control tasks.
- // (More details in discussion for cl 500147.)
- auto task_type = GetSchedulingType() == ScriptSchedulingType::kParserBlocking
- ? TaskType::kNetworking
- : TaskType::kNetworkingControl;
-
- ReadyState ready_state_before_stream = ready_state_;
- ToScriptResource(GetResource())
- ->StartStreaming(document->GetTaskRunner(task_type));
- // We have to make sure that the ready state is not changed by starting
- // streaming, just in case we're relying on IsReady being false.
- CHECK_EQ(ready_state_before_stream, ready_state_);
-
- return;
-}
-
bool ClassicPendingScript::WasCanceled() const {
if (!is_external_)
return false;
diff --git a/chromium/third_party/blink/renderer/core/script/classic_pending_script.h b/chromium/third_party/blink/renderer/core/script/classic_pending_script.h
index cb4784990ae..d9f07521ede 100644
--- a/chromium/third_party/blink/renderer/core/script/classic_pending_script.h
+++ b/chromium/third_party/blink/renderer/core/script/classic_pending_script.h
@@ -58,23 +58,16 @@ class CORE_EXPORT ClassicPendingScript final : public PendingScript,
bool is_external);
~ClassicPendingScript() override;
- // ScriptStreamer callbacks.
- void SetStreamer(ScriptStreamer*);
- void StreamingFinished();
-
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
mojom::ScriptType GetScriptType() const override {
return mojom::ScriptType::kClassic;
}
- void WatchForLoad(PendingScriptClient*) override;
-
ClassicScript* GetSource(const KURL& document_url) const override;
bool IsReady() const override;
bool IsExternal() const override { return is_external_; }
bool WasCanceled() const override;
- void StartStreamingIfPossible() override;
KURL UrlForTracing() const override;
void DisposeInternal() override;
@@ -82,6 +75,8 @@ class CORE_EXPORT ClassicPendingScript final : public PendingScript,
not_streamed_reason_ = reason;
}
+ bool IsEligibleForDelay() const override;
+
private:
// See AdvanceReadyState implementation for valid state transitions.
enum ReadyState {
diff --git a/chromium/third_party/blink/renderer/core/script/classic_script.cc b/chromium/third_party/blink/renderer/core/script/classic_script.cc
index df884115ba2..93c3fe90a9f 100644
--- a/chromium/third_party/blink/renderer/core/script/classic_script.cc
+++ b/chromium/third_party/blink/renderer/core/script/classic_script.cc
@@ -13,7 +13,7 @@
namespace blink {
-void ClassicScript::Trace(Visitor* visitor) {
+void ClassicScript::Trace(Visitor* visitor) const {
Script::Trace(visitor);
visitor->Trace(script_source_code_);
}
diff --git a/chromium/third_party/blink/renderer/core/script/classic_script.h b/chromium/third_party/blink/renderer/core/script/classic_script.h
index 2142a2799b7..2ee2fb81c09 100644
--- a/chromium/third_party/blink/renderer/core/script/classic_script.h
+++ b/chromium/third_party/blink/renderer/core/script/classic_script.h
@@ -24,7 +24,7 @@ class CORE_EXPORT ClassicScript final : public Script {
script_source_code_(script_source_code),
sanitize_script_errors_(sanitize_script_errors) {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const ScriptSourceCode& GetScriptSourceCode() const {
return script_source_code_;
diff --git a/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver.cc b/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver.cc
index 5b317c6c994..8e45173e0dc 100644
--- a/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver.cc
+++ b/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver.cc
@@ -30,7 +30,7 @@ class DynamicImportTreeClient final : public ModuleTreeClient {
ScriptPromiseResolver* promise_resolver)
: url_(url), modulator_(modulator), promise_resolver_(promise_resolver) {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Implements ModuleTreeClient:
@@ -48,7 +48,7 @@ class ModuleResolutionCallback : public ScriptFunction {
ScriptPromiseResolver* promise_resolver)
: ScriptFunction(script_state), promise_resolver_(promise_resolver) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(promise_resolver_);
ScriptFunction::Trace(visitor);
}
@@ -77,7 +77,7 @@ class ModuleResolutionSuccessCallback final : public ModuleResolutionCallback {
return self->BindToV8Function();
}
- void Trace(Visitor* visitor) final {
+ void Trace(Visitor* visitor) const final {
visitor->Trace(module_script_);
ModuleResolutionCallback::Trace(visitor);
}
@@ -234,7 +234,7 @@ void DynamicImportTreeClient::NotifyModuleTreeLoadFinished(
promise_resolver_->Resolve(module_namespace);
}
-void DynamicImportTreeClient::Trace(Visitor* visitor) {
+void DynamicImportTreeClient::Trace(Visitor* visitor) const {
visitor->Trace(modulator_);
visitor->Trace(promise_resolver_);
ModuleTreeClient::Trace(visitor);
@@ -242,7 +242,7 @@ void DynamicImportTreeClient::Trace(Visitor* visitor) {
} // namespace
-void DynamicModuleResolver::Trace(Visitor* visitor) {
+void DynamicModuleResolver::Trace(Visitor* visitor) const {
visitor->Trace(modulator_);
}
@@ -322,6 +322,27 @@ void DynamicModuleResolver::ResolveDynamically(
return;
}
+ switch (referrer_info.GetBaseUrlSource()) {
+ case ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSSameOrigin:
+ if (!modulator_->ResolveModuleSpecifier(specifier, BlankURL())
+ .IsValid()) {
+ UseCounter::Count(
+ ExecutionContext::From(modulator_->GetScriptState()),
+ WebFeature::kDynamicImportModuleScriptRelativeClassicSameOrigin);
+ }
+ break;
+ case ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSCrossOrigin:
+ if (!modulator_->ResolveModuleSpecifier(specifier, BlankURL())
+ .IsValid()) {
+ UseCounter::Count(
+ ExecutionContext::From(modulator_->GetScriptState()),
+ WebFeature::kDynamicImportModuleScriptRelativeClassicCrossOrigin);
+ }
+ break;
+ case ReferrerScriptInfo::BaseUrlSource::kOther:
+ break;
+ }
+
// <spec step="4.4">Set fetch options to the descendant script fetch options
// for referencing script's fetch options.</spec>
//
diff --git a/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver.h b/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver.h
index e73c78d383b..0052276c6b1 100644
--- a/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver.h
+++ b/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver.h
@@ -23,7 +23,7 @@ class ScriptPromiseResolver;
class CORE_EXPORT DynamicModuleResolver final
: public GarbageCollected<DynamicModuleResolver> {
public:
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
explicit DynamicModuleResolver(Modulator* modulator)
: modulator_(modulator) {}
diff --git a/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc b/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
index 258e069216c..727bbf4c401 100644
--- a/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
+++ b/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
@@ -50,7 +50,7 @@ class DynamicModuleResolverTestModulator final : public DummyModulator {
}
bool fetch_tree_was_called() const { return fetch_tree_was_called_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Implements Modulator:
@@ -108,7 +108,7 @@ class DynamicModuleResolverTestModulator final : public DummyModulator {
bool fetch_tree_was_called_ = false;
};
-void DynamicModuleResolverTestModulator::Trace(Visitor* visitor) {
+void DynamicModuleResolverTestModulator::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(pending_client_);
DummyModulator::Trace(visitor);
@@ -408,7 +408,8 @@ TEST_P(DynamicModuleResolverTest, ResolveWithReferrerScriptInfoBaseURL) {
KURL correct_base_url("https://example.com/correct/baz.js");
resolver->ResolveDynamically(
"./dependency.js", wrong_base_url,
- ReferrerScriptInfo(correct_base_url, ScriptFetchOptions()),
+ ReferrerScriptInfo(correct_base_url, ScriptFetchOptions(),
+ ReferrerScriptInfo::BaseUrlSource::kOther),
promise_resolver);
v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate());
diff --git a/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.cc b/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.cc
index 648a0b0e563..32dcfa5418b 100644
--- a/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.cc
+++ b/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.cc
@@ -88,7 +88,7 @@ FetchClientSettingsObjectImpl::GetUpgradeInsecureNavigationsSet() const {
.InsecureNavigationsToUpgrade();
}
-void FetchClientSettingsObjectImpl::Trace(Visitor* visitor) {
+void FetchClientSettingsObjectImpl::Trace(Visitor* visitor) const {
visitor->Trace(execution_context_);
FetchClientSettingsObject::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h b/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h
index 783ca717269..6707c9bad03 100644
--- a/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h
+++ b/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h
@@ -50,7 +50,7 @@ class CORE_EXPORT FetchClientSettingsObjectImpl final
const InsecureNavigationsSet& GetUpgradeInsecureNavigationsSet()
const override;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<ExecutionContext> execution_context_;
diff --git a/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.cc b/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.cc
index e46c3e69a88..3d974faab56 100644
--- a/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.cc
+++ b/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.cc
@@ -523,7 +523,6 @@ void HTMLParserScriptRunner::RequestParsingBlockingScript(
// Callers will attempt to run the m_parserBlockingScript if possible before
// returning control to the parser.
if (!ParserBlockingScript()->IsReady()) {
- parser_blocking_script_->StartStreamingIfPossible();
parser_blocking_script_->WatchForLoad(this);
}
}
@@ -532,12 +531,6 @@ void HTMLParserScriptRunner::RequestDeferredScript(
ScriptLoader* script_loader) {
PendingScript* pending_script =
script_loader->TakePendingScript(ScriptSchedulingType::kDefer);
- if (!pending_script)
- return;
-
- if (!pending_script->IsReady()) {
- pending_script->StartStreamingIfPossible();
- }
DCHECK(!script_loader->IsForceDeferred());
DCHECK(pending_script->IsExternalOrModule());
@@ -553,12 +546,6 @@ void HTMLParserScriptRunner::RequestForceDeferredScript(
ScriptLoader* script_loader) {
PendingScript* pending_script =
script_loader->TakePendingScript(ScriptSchedulingType::kForceDefer);
- if (!pending_script)
- return;
-
- if (!pending_script->IsReady()) {
- pending_script->StartStreamingIfPossible();
- }
DCHECK(script_loader->IsForceDeferred());
@@ -699,7 +686,7 @@ void HTMLParserScriptRunner::RecordMetricsAtParseEnd() const {
}
}
-void HTMLParserScriptRunner::Trace(Visitor* visitor) {
+void HTMLParserScriptRunner::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(host_);
visitor->Trace(parser_blocking_script_);
diff --git a/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.h b/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.h
index d219180da29..b12d7cec3b4 100644
--- a/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.h
+++ b/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.h
@@ -106,7 +106,7 @@ class HTMLParserScriptRunner final
// is preparing to stop but before |ExecuteScriptsWaitingForParsing|.
void RecordMetricsAtParseEnd() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override {
return "HTMLParserScriptRunner";
}
diff --git a/chromium/third_party/blink/renderer/core/script/html_parser_script_runner_host.h b/chromium/third_party/blink/renderer/core/script/html_parser_script_runner_host.h
index 1a4770c0a2a..90d1e9799e6 100644
--- a/chromium/third_party/blink/renderer/core/script/html_parser_script_runner_host.h
+++ b/chromium/third_party/blink/renderer/core/script/html_parser_script_runner_host.h
@@ -37,7 +37,7 @@ class PendingScript;
class CORE_EXPORT HTMLParserScriptRunnerHost : public GarbageCollectedMixin {
public:
virtual ~HTMLParserScriptRunnerHost() = default;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
virtual void NotifyScriptLoaded(PendingScript*) = 0;
virtual HTMLInputStream& InputStream() = 0;
diff --git a/chromium/third_party/blink/renderer/core/script/import_map.h b/chromium/third_party/blink/renderer/core/script/import_map.h
index 7236bd5f710..a52d1943b6a 100644
--- a/chromium/third_party/blink/renderer/core/script/import_map.h
+++ b/chromium/third_party/blink/renderer/core/script/import_map.h
@@ -62,7 +62,7 @@ class CORE_EXPORT ImportMap final : public GarbageCollected<ImportMap> {
String ToString() const;
- void Trace(Visitor*) {}
+ void Trace(Visitor*) const {}
private:
using MatchResult = SpecifierMap::const_iterator;
diff --git a/chromium/third_party/blink/renderer/core/script/js_module_script.cc b/chromium/third_party/blink/renderer/core/script/js_module_script.cc
index 5341b21cbc5..0e405957b1a 100644
--- a/chromium/third_party/blink/renderer/core/script/js_module_script.cc
+++ b/chromium/third_party/blink/renderer/core/script/js_module_script.cc
@@ -174,7 +174,7 @@ void JSModuleScript::ProduceCache() {
produce_cache_data_ = nullptr;
}
-void JSModuleScript::Trace(Visitor* visitor) {
+void JSModuleScript::Trace(Visitor* visitor) const {
visitor->Trace(produce_cache_data_);
ModuleScript::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/script/js_module_script.h b/chromium/third_party/blink/renderer/core/script/js_module_script.h
index d35598276cd..3309db52e0a 100644
--- a/chromium/third_party/blink/renderer/core/script/js_module_script.h
+++ b/chromium/third_party/blink/renderer/core/script/js_module_script.h
@@ -57,7 +57,7 @@ class CORE_EXPORT JSModuleScript final : public ModuleScript,
void ProduceCache() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override { return "JSModuleScript"; }
private:
diff --git a/chromium/third_party/blink/renderer/core/script/mock_script_element_base.h b/chromium/third_party/blink/renderer/core/script/mock_script_element_base.h
index 350d9f0682a..b42be3483b4 100644
--- a/chromium/third_party/blink/renderer/core/script/mock_script_element_base.h
+++ b/chromium/third_party/blink/renderer/core/script/mock_script_element_base.h
@@ -58,7 +58,9 @@ class MockScriptElementBase : public GarbageCollected<MockScriptElementBase>,
ScriptElementBase::Type GetScriptElementType() override {
return ScriptElementBase::Type::kHTMLScriptElement;
}
- void Trace(Visitor* visitor) override { ScriptElementBase::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ ScriptElementBase::Trace(visitor);
+ }
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/script/modulator.h b/chromium/third_party/blink/renderer/core/script/modulator.h
index 60512cf7c1a..98857d7c5ea 100644
--- a/chromium/third_party/blink/renderer/core/script/modulator.h
+++ b/chromium/third_party/blink/renderer/core/script/modulator.h
@@ -44,7 +44,7 @@ class CORE_EXPORT SingleModuleClient
public NameClient {
public:
virtual ~SingleModuleClient() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
const char* NameInHeapSnapshot() const override {
return "SingleModuleClient";
}
@@ -58,7 +58,7 @@ class CORE_EXPORT ModuleTreeClient : public GarbageCollected<ModuleTreeClient>,
public NameClient {
public:
virtual ~ModuleTreeClient() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
const char* NameInHeapSnapshot() const override { return "ModuleTreeClient"; }
virtual void NotifyModuleTreeLoadFinished(ModuleScript*) = 0;
@@ -106,7 +106,7 @@ class CORE_EXPORT Modulator : public GarbageCollected<Modulator>,
static void SetModulator(ScriptState*, Modulator*);
static void ClearModulator(ScriptState*);
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
const char* NameInHeapSnapshot() const override { return "Modulator"; }
virtual ModuleRecordResolver* GetModuleRecordResolver() = 0;
diff --git a/chromium/third_party/blink/renderer/core/script/modulator_impl_base.cc b/chromium/third_party/blink/renderer/core/script/modulator_impl_base.cc
index 3de8263baaf..6802367e0e4 100644
--- a/chromium/third_party/blink/renderer/core/script/modulator_impl_base.cc
+++ b/chromium/third_party/blink/renderer/core/script/modulator_impl_base.cc
@@ -403,7 +403,7 @@ ModuleEvaluationResult ModulatorImplBase::ExecuteModule(
return ModuleEvaluationResult::Empty();
}
-void ModulatorImplBase::Trace(Visitor* visitor) {
+void ModulatorImplBase::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(map_);
visitor->Trace(tree_linker_registry_);
diff --git a/chromium/third_party/blink/renderer/core/script/modulator_impl_base.h b/chromium/third_party/blink/renderer/core/script/modulator_impl_base.h
index be2a95e7f1d..03f875ba1cd 100644
--- a/chromium/third_party/blink/renderer/core/script/modulator_impl_base.h
+++ b/chromium/third_party/blink/renderer/core/script/modulator_impl_base.h
@@ -27,7 +27,7 @@ class ScriptState;
class ModulatorImplBase : public Modulator {
public:
~ModulatorImplBase() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit ModulatorImplBase(ScriptState*);
diff --git a/chromium/third_party/blink/renderer/core/script/module_map.cc b/chromium/third_party/blink/renderer/core/script/module_map.cc
index 4a984faacf5..67ed1cb5493 100644
--- a/chromium/third_party/blink/renderer/core/script/module_map.cc
+++ b/chromium/third_party/blink/renderer/core/script/module_map.cc
@@ -25,7 +25,7 @@ class ModuleMap::Entry final : public GarbageCollected<Entry>,
explicit Entry(ModuleMap*);
~Entry() override {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override { return "ModuleMap::Entry"; }
// Notify fetched |m_moduleScript| to the client asynchronously.
@@ -53,7 +53,7 @@ ModuleMap::Entry::Entry(ModuleMap* map) : map_(map) {
DCHECK(map_);
}
-void ModuleMap::Entry::Trace(Visitor* visitor) {
+void ModuleMap::Entry::Trace(Visitor* visitor) const {
visitor->Trace(module_script_);
visitor->Trace(map_);
visitor->Trace(clients_);
@@ -100,7 +100,7 @@ ModuleMap::ModuleMap(Modulator* modulator)
DCHECK(modulator);
}
-void ModuleMap::Trace(Visitor* visitor) {
+void ModuleMap::Trace(Visitor* visitor) const {
visitor->Trace(map_);
visitor->Trace(modulator_);
visitor->Trace(loader_registry_);
diff --git a/chromium/third_party/blink/renderer/core/script/module_map.h b/chromium/third_party/blink/renderer/core/script/module_map.h
index 46d98e67aa3..e62710753ec 100644
--- a/chromium/third_party/blink/renderer/core/script/module_map.h
+++ b/chromium/third_party/blink/renderer/core/script/module_map.h
@@ -33,7 +33,7 @@ class CORE_EXPORT ModuleMap final : public GarbageCollected<ModuleMap>,
public:
explicit ModuleMap(Modulator*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override { return "ModuleMap"; }
// https://html.spec.whatwg.org/C/#fetch-a-single-module-script
diff --git a/chromium/third_party/blink/renderer/core/script/module_map_test.cc b/chromium/third_party/blink/renderer/core/script/module_map_test.cc
index 193deaab4f9..31220e164a6 100644
--- a/chromium/third_party/blink/renderer/core/script/module_map_test.cc
+++ b/chromium/third_party/blink/renderer/core/script/module_map_test.cc
@@ -31,7 +31,7 @@ class TestSingleModuleClient final : public SingleModuleClient {
TestSingleModuleClient() = default;
~TestSingleModuleClient() override {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(module_script_);
SingleModuleClient::Trace(visitor);
}
@@ -89,7 +89,7 @@ class ModuleMapTestModulator final : public DummyModulator {
explicit ModuleMapTestModulator(ScriptState*);
~ModuleMapTestModulator() override {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
TestModuleRecordResolver* GetTestModuleRecordResolver() {
return resolver_.Get();
@@ -126,7 +126,7 @@ class ModuleMapTestModulator final : public DummyModulator {
modulator_->test_requests_.push_back(test_request);
}
String DebugName() const override { return "TestModuleScriptFetcher"; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
ModuleScriptFetcher::Trace(visitor);
visitor->Trace(modulator_);
}
@@ -158,7 +158,7 @@ class ModuleMapTestModulator final : public DummyModulator {
client_->NotifyFetchFinished(*params_,
HeapVector<Member<ConsoleMessage>>());
}
- void Trace(Visitor* visitor) { visitor->Trace(client_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(client_); }
private:
base::Optional<ModuleScriptCreationParams> params_;
@@ -174,7 +174,7 @@ ModuleMapTestModulator::ModuleMapTestModulator(ScriptState* script_state)
: script_state_(script_state),
resolver_(MakeGarbageCollected<TestModuleRecordResolver>()) {}
-void ModuleMapTestModulator::Trace(Visitor* visitor) {
+void ModuleMapTestModulator::Trace(Visitor* visitor) const {
visitor->Trace(test_requests_);
visitor->Trace(script_state_);
visitor->Trace(resolver_);
diff --git a/chromium/third_party/blink/renderer/core/script/module_pending_script.cc b/chromium/third_party/blink/renderer/core/script/module_pending_script.cc
index 29449ea2056..7686ac53a4d 100644
--- a/chromium/third_party/blink/renderer/core/script/module_pending_script.cc
+++ b/chromium/third_party/blink/renderer/core/script/module_pending_script.cc
@@ -31,7 +31,7 @@ void ModulePendingScriptTreeClient::NotifyModuleTreeLoadFinished(
pending_script_->NotifyModuleTreeLoadFinished();
}
-void ModulePendingScriptTreeClient::Trace(Visitor* visitor) {
+void ModulePendingScriptTreeClient::Trace(Visitor* visitor) const {
visitor->Trace(module_script_);
visitor->Trace(pending_script_);
ModuleTreeClient::Trace(visitor);
@@ -54,7 +54,7 @@ void ModulePendingScript::DisposeInternal() {
module_tree_client_ = nullptr;
}
-void ModulePendingScript::Trace(Visitor* visitor) {
+void ModulePendingScript::Trace(Visitor* visitor) const {
visitor->Trace(module_tree_client_);
PendingScript::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/script/module_pending_script.h b/chromium/third_party/blink/renderer/core/script/module_pending_script.h
index 230d4632c4d..d128a3a584f 100644
--- a/chromium/third_party/blink/renderer/core/script/module_pending_script.h
+++ b/chromium/third_party/blink/renderer/core/script/module_pending_script.h
@@ -29,7 +29,7 @@ class ModulePendingScriptTreeClient final : public ModuleTreeClient {
ModuleScript* GetModuleScript() const { return module_script_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Implements ModuleTreeClient
@@ -55,7 +55,7 @@ class CORE_EXPORT ModulePendingScript : public PendingScript {
return module_tree_client_->GetModuleScript();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// PendingScript
@@ -67,8 +67,6 @@ class CORE_EXPORT ModulePendingScript : public PendingScript {
bool IsExternal() const override { return is_external_; }
bool WasCanceled() const override { return false; }
- void StartStreamingIfPossible() override {}
-
KURL UrlForTracing() const override { return NullURL(); }
void DisposeInternal() override;
diff --git a/chromium/third_party/blink/renderer/core/script/module_record_resolver.h b/chromium/third_party/blink/renderer/core/script/module_record_resolver.h
index cf07f65dfd1..d9f7219d25d 100644
--- a/chromium/third_party/blink/renderer/core/script/module_record_resolver.h
+++ b/chromium/third_party/blink/renderer/core/script/module_record_resolver.h
@@ -26,7 +26,7 @@ class CORE_EXPORT ModuleRecordResolver
: public GarbageCollected<ModuleRecordResolver> {
public:
virtual ~ModuleRecordResolver() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
// Notifies the ModuleRecordResolver that a ModuleScript exists.
// This hook gives a chance for the resolver impl to populate module record
diff --git a/chromium/third_party/blink/renderer/core/script/module_record_resolver_impl.cc b/chromium/third_party/blink/renderer/core/script/module_record_resolver_impl.cc
index a0be66aa0ab..8b234d805af 100644
--- a/chromium/third_party/blink/renderer/core/script/module_record_resolver_impl.cc
+++ b/chromium/third_party/blink/renderer/core/script/module_record_resolver_impl.cc
@@ -120,7 +120,7 @@ void ModuleRecordResolverImpl::ContextDestroyed() {
record_to_module_script_map_.clear();
}
-void ModuleRecordResolverImpl::Trace(Visitor* visitor) {
+void ModuleRecordResolverImpl::Trace(Visitor* visitor) const {
ModuleRecordResolver::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
visitor->Trace(record_to_module_script_map_);
diff --git a/chromium/third_party/blink/renderer/core/script/module_record_resolver_impl.h b/chromium/third_party/blink/renderer/core/script/module_record_resolver_impl.h
index 116fead2bad..5b0c7d6e1bb 100644
--- a/chromium/third_party/blink/renderer/core/script/module_record_resolver_impl.h
+++ b/chromium/third_party/blink/renderer/core/script/module_record_resolver_impl.h
@@ -32,7 +32,7 @@ class CORE_EXPORT ModuleRecordResolverImpl final
: ExecutionContextLifecycleObserver(execution_context),
modulator_(modulator) {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
USING_GARBAGE_COLLECTED_MIXIN(ModuleRecordResolverImpl);
private:
diff --git a/chromium/third_party/blink/renderer/core/script/module_record_resolver_impl_test.cc b/chromium/third_party/blink/renderer/core/script/module_record_resolver_impl_test.cc
index 98df6107d5b..67250f9fdb6 100644
--- a/chromium/third_party/blink/renderer/core/script/module_record_resolver_impl_test.cc
+++ b/chromium/third_party/blink/renderer/core/script/module_record_resolver_impl_test.cc
@@ -28,7 +28,7 @@ class ModuleRecordResolverImplTestModulator final : public DummyModulator {
ModuleRecordResolverImplTestModulator() {}
~ModuleRecordResolverImplTestModulator() override {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void SetScriptState(ScriptState* script_state) {
script_state_ = script_state;
@@ -60,7 +60,7 @@ class ModuleRecordResolverImplTestModulator final : public DummyModulator {
Member<ModuleScript> module_script_;
};
-void ModuleRecordResolverImplTestModulator::Trace(Visitor* visitor) {
+void ModuleRecordResolverImplTestModulator::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(module_script_);
DummyModulator::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/script/module_script.cc b/chromium/third_party/blink/renderer/core/script/module_script.cc
index 1274503deb5..c41bd4ca46a 100644
--- a/chromium/third_party/blink/renderer/core/script/module_script.cc
+++ b/chromium/third_party/blink/renderer/core/script/module_script.cc
@@ -93,7 +93,7 @@ KURL ModuleScript::ResolveModuleSpecifier(const String& module_request,
return url;
}
-void ModuleScript::Trace(Visitor* visitor) {
+void ModuleScript::Trace(Visitor* visitor) const {
visitor->Trace(settings_object_);
visitor->Trace(record_.UnsafeCast<v8::Value>());
visitor->Trace(parse_error_);
diff --git a/chromium/third_party/blink/renderer/core/script/module_script.h b/chromium/third_party/blink/renderer/core/script/module_script.h
index aabe3a6cb27..d106054a188 100644
--- a/chromium/third_party/blink/renderer/core/script/module_script.h
+++ b/chromium/third_party/blink/renderer/core/script/module_script.h
@@ -49,7 +49,7 @@ class CORE_EXPORT ModuleScript : public Script {
KURL ResolveModuleSpecifier(const String& module_request,
String* failure_reason = nullptr) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
virtual void ProduceCache() {}
const KURL& SourceURL() const { return source_url_; }
diff --git a/chromium/third_party/blink/renderer/core/script/module_script_test.cc b/chromium/third_party/blink/renderer/core/script/module_script_test.cc
index 5bab441e36d..15b8c5ab8fc 100644
--- a/chromium/third_party/blink/renderer/core/script/module_script_test.cc
+++ b/chromium/third_party/blink/renderer/core/script/module_script_test.cc
@@ -40,7 +40,7 @@ class ModuleScriptTestModulator final : public DummyModulator {
return Vector<ModuleRequest>();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(script_state_);
DummyModulator::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/script/pending_import_map.cc b/chromium/third_party/blink/renderer/core/script/pending_import_map.cc
index b9bc112044f..2242897135c 100644
--- a/chromium/third_party/blink/renderer/core/script/pending_import_map.cc
+++ b/chromium/third_party/blink/renderer/core/script/pending_import_map.cc
@@ -97,7 +97,7 @@ void PendingImportMap::RegisterImportMap() const {
// TODO(hiroshige): Implement this when external import maps are implemented.
}
-void PendingImportMap::Trace(Visitor* visitor) {
+void PendingImportMap::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(import_map_);
visitor->Trace(error_to_rethrow_);
diff --git a/chromium/third_party/blink/renderer/core/script/pending_import_map.h b/chromium/third_party/blink/renderer/core/script/pending_import_map.h
index 0f922ff09b6..219d0d6f42b 100644
--- a/chromium/third_party/blink/renderer/core/script/pending_import_map.h
+++ b/chromium/third_party/blink/renderer/core/script/pending_import_map.h
@@ -48,7 +48,7 @@ class CORE_EXPORT PendingImportMap final
void RegisterImportMap() const;
- virtual void Trace(Visitor* visitor);
+ virtual void Trace(Visitor* visitor) const;
private:
Member<ScriptElementBase> element_;
diff --git a/chromium/third_party/blink/renderer/core/script/pending_script.cc b/chromium/third_party/blink/renderer/core/script/pending_script.cc
index fca268bff72..dbc2ffb9f2c 100644
--- a/chromium/third_party/blink/renderer/core/script/pending_script.cc
+++ b/chromium/third_party/blink/renderer/core/script/pending_script.cc
@@ -291,7 +291,7 @@ void PendingScript::ExecuteScriptBlockInternal(
element->DispatchLoadEvent();
}
-void PendingScript::Trace(Visitor* visitor) {
+void PendingScript::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(client_);
visitor->Trace(original_execution_context_);
diff --git a/chromium/third_party/blink/renderer/core/script/pending_script.h b/chromium/third_party/blink/renderer/core/script/pending_script.h
index 93d76b77028..791ea7f8f3c 100644
--- a/chromium/third_party/blink/renderer/core/script/pending_script.h
+++ b/chromium/third_party/blink/renderer/core/script/pending_script.h
@@ -53,7 +53,7 @@ class CORE_EXPORT PendingScriptClient : public GarbageCollectedMixin {
// streaming finishes.
virtual void PendingScriptFinished(PendingScript*) = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
// A container for an script after "prepare a script" until it is executed.
@@ -84,7 +84,7 @@ class CORE_EXPORT PendingScript : public GarbageCollected<PendingScript>,
virtual mojom::ScriptType GetScriptType() const = 0;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override { return "PendingScript"; }
// Returns nullptr when "script's script is null", i.e. an error occurred.
@@ -95,9 +95,6 @@ class CORE_EXPORT PendingScript : public GarbageCollected<PendingScript>,
virtual bool IsExternal() const = 0;
virtual bool WasCanceled() const = 0;
- // Support for script streaming.
- virtual void StartStreamingIfPossible() = 0;
-
// Used only for tracing, and can return a null URL.
// TODO(hiroshige): It's preferable to return the base URL consistently
// https://html.spec.whatwg.org/C/#concept-script-base-url
@@ -132,6 +129,8 @@ class CORE_EXPORT PendingScript : public GarbageCollected<PendingScript>,
// This is virtual only for testing.
virtual void ExecuteScriptBlock(const KURL&);
+ virtual bool IsEligibleForDelay() const { return false; }
+
protected:
PendingScript(ScriptElementBase*, const TextPosition& starting_position);
diff --git a/chromium/third_party/blink/renderer/core/script/script.h b/chromium/third_party/blink/renderer/core/script/script.h
index 8e0ba7ce576..60972560342 100644
--- a/chromium/third_party/blink/renderer/core/script/script.h
+++ b/chromium/third_party/blink/renderer/core/script/script.h
@@ -22,7 +22,7 @@ class WorkerGlobalScope;
// https://html.spec.whatwg.org/C/#concept-script
class CORE_EXPORT Script : public GarbageCollected<Script> {
public:
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
virtual ~Script() {}
diff --git a/chromium/third_party/blink/renderer/core/script/script_element_base.cc b/chromium/third_party/blink/renderer/core/script/script_element_base.cc
index 696561165e8..aeabdc0ac08 100644
--- a/chromium/third_party/blink/renderer/core/script/script_element_base.cc
+++ b/chromium/third_party/blink/renderer/core/script/script_element_base.cc
@@ -19,10 +19,9 @@ ScriptLoader* ScriptLoaderFromElement(Element* element) {
return script_loader;
}
-ScriptLoader* ScriptElementBase::InitializeScriptLoader(bool parser_inserted,
- bool already_started) {
- return MakeGarbageCollected<ScriptLoader>(this, parser_inserted,
- already_started);
+ScriptLoader* ScriptElementBase::InitializeScriptLoader(
+ CreateElementFlags flags) {
+ return MakeGarbageCollected<ScriptLoader>(this, flags);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/script/script_element_base.h b/chromium/third_party/blink/renderer/core/script/script_element_base.h
index 55490546971..f415bc447e9 100644
--- a/chromium/third_party/blink/renderer/core/script/script_element_base.h
+++ b/chromium/third_party/blink/renderer/core/script/script_element_base.h
@@ -22,6 +22,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_SCRIPT_ELEMENT_BASE_H_
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/dom/create_element_flags.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
@@ -99,8 +100,7 @@ class CORE_EXPORT ScriptElementBase : public GarbageCollectedMixin {
virtual Type GetScriptElementType() = 0;
protected:
- ScriptLoader* InitializeScriptLoader(bool parser_inserted,
- bool already_started);
+ ScriptLoader* InitializeScriptLoader(CreateElementFlags);
virtual ScriptLoader* Loader() const = 0;
};
diff --git a/chromium/third_party/blink/renderer/core/script/script_loader.cc b/chromium/third_party/blink/renderer/core/script/script_loader.cc
index 2f9144280a1..dd099aed2db 100644
--- a/chromium/third_party/blink/renderer/core/script/script_loader.cc
+++ b/chromium/third_party/blink/renderer/core/script/script_loader.cc
@@ -75,8 +75,7 @@
namespace blink {
ScriptLoader::ScriptLoader(ScriptElementBase* element,
- bool parser_inserted,
- bool already_started)
+ const CreateElementFlags flags)
: element_(element),
will_be_parser_executed_(false),
will_execute_when_document_finished_parsing_(false),
@@ -88,14 +87,21 @@ ScriptLoader::ScriptLoader(ScriptElementBase* element,
// TODO(hiroshige): Cloning is implemented together with
// {HTML,SVG}ScriptElement::cloneElementWithoutAttributesAndChildren().
// Clean up these later.
- if (already_started)
+ if (flags.WasAlreadyStarted())
already_started_ = true;
- if (parser_inserted) {
- // <spec href="https://html.spec.whatwg.org/C/#parser-inserted">... It is
+ if (flags.IsCreatedByParser()) {
+ // <spec href="https://html.spec.whatwg.org/C/#parser-inserted">script
+ // elements with non-null parser documents are known as
+ // "parser-inserted".</spec>
+ // For more information on why this is not implemented in terms of a
+ // non-null parser document, see the documentation in the header file.
+ parser_inserted_ = true;
+
+ // <spec href="https://html.spec.whatwg.org/C/#parser-document">... It is
// set by the HTML parser and the XML parser on script elements they insert
// ...</spec>
- parser_inserted_ = true;
+ parser_document_ = flags.ParserDocument();
// <spec href="https://html.spec.whatwg.org/C/#non-blocking">... It is unset
// by the HTML parser and the XML parser on script elements they insert.
@@ -106,8 +112,9 @@ ScriptLoader::ScriptLoader(ScriptElementBase* element,
ScriptLoader::~ScriptLoader() {}
-void ScriptLoader::Trace(Visitor* visitor) {
+void ScriptLoader::Trace(Visitor* visitor) const {
visitor->Trace(element_);
+ visitor->Trace(parser_document_);
visitor->Trace(pending_script_);
visitor->Trace(prepared_pending_script_);
visitor->Trace(resource_keep_alive_);
@@ -254,7 +261,7 @@ network::mojom::CredentialsMode ScriptLoader::ModuleScriptCredentialsMode(
bool ShouldBlockSyncScriptForFeaturePolicy(const ScriptElementBase* element,
mojom::ScriptType script_type,
bool parser_inserted) {
- if (element->GetDocument().IsFeatureEnabled(
+ if (element->GetExecutionContext()->IsFeatureEnabled(
mojom::blink::FeaturePolicyFeature::kSyncScript)) {
return false;
}
@@ -339,9 +346,9 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
// <spec step="10">If the element is flagged as "parser-inserted", but the
// element's node document is not the Document of the parser that created the
// element, then return.</spec>
- //
- // FIXME: If script is parser inserted, verify it's still in the original
- // document.
+ if (parser_inserted_ && parser_document_ != &element_->GetDocument()) {
+ return false;
+ }
// <spec step="11">If scripting is disabled for the script element, then
// return. The script is not executed.</spec>
@@ -350,14 +357,8 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
// is disabled for a node if there is no such browsing context, or if
// scripting is disabled in that browsing context.</spec>
Document& element_document = element_->GetDocument();
- // TODO(timothygu): Investigate if we could switch from ExecutingFrame() to
- // ExecutingWindow().
- if (!element_document.ExecutingFrame())
- return false;
-
- LocalDOMWindow* context_window =
- To<LocalDOMWindow>(element_->GetExecutionContext());
- if (!context_window->GetFrame())
+ LocalDOMWindow* context_window = element_document.ExecutingWindow();
+ if (!context_window)
return false;
if (!context_window->CanExecuteScripts(kAboutToExecuteScript))
return false;
@@ -842,6 +843,8 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
// script is ready, execute the script block and then remove the element
// from the set of scripts that will execute as soon as possible.</spec>
pending_script_ = TakePendingScript(ScriptSchedulingType::kAsync);
+ // This is for the UKM count of async scripts in a document.
+ context_window->document()->IncrementAsyncScriptCount();
// TODO(hiroshige): Here the context document is used as "node document"
// while Step 14 uses |elementDocument| as "node document". Fix this.
context_window->document()->GetScriptRunner()->QueueScriptForExecution(
diff --git a/chromium/third_party/blink/renderer/core/script/script_loader.h b/chromium/third_party/blink/renderer/core/script/script_loader.h
index b0aee119e05..3b25658c65d 100644
--- a/chromium/third_party/blink/renderer/core/script/script_loader.h
+++ b/chromium/third_party/blink/renderer/core/script/script_loader.h
@@ -53,9 +53,9 @@ class CORE_EXPORT ScriptLoader final : public GarbageCollected<ScriptLoader>,
USING_GARBAGE_COLLECTED_MIXIN(ScriptLoader);
public:
- ScriptLoader(ScriptElementBase*, bool created_by_parser, bool is_evaluated);
+ ScriptLoader(ScriptElementBase*, const CreateElementFlags);
~ScriptLoader() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override { return "ScriptLoader"; }
enum LegacyTypeSupport {
@@ -152,8 +152,22 @@ class CORE_EXPORT ScriptLoader final : public GarbageCollected<ScriptLoader>,
// script elements must have this flag unset ...</spec>
bool already_started_ = false;
- // <spec href="https://html.spec.whatwg.org/C/#parser-inserted">... Initially,
- // script elements must have this flag unset. ...</spec>
+ // <spec href="https://html.spec.whatwg.org/C/#parser-document">... Initially,
+ // its value must be null. It is set by the HTML parser and the XML parser on
+ // script elements they insert ...</spec>
+ // We use a WeakMember here because we're keeping the parser-inserted
+ // information separately from the parser document, so ScriptLoader doesn't
+ // need to keep the parser document alive.
+ WeakMember<Document> parser_document_;
+
+ // <spec href="https://html.spec.whatwg.org/C/#parser-inserted">script
+ // elements with non-null parser documents are known as
+ // "parser-inserted".</spec>
+ // Note that we don't actually implement "parser inserted" in terms of a
+ // non-null |parser_document_| like the spec, because it is possible for
+ // |CreateElementFlags::created_by_parser_| to be true even when
+ // |CreateElementFlags::parser_document_| is null. Therefore, we have to
+ // store this information separately.
bool parser_inserted_ = false;
// <spec href="https://html.spec.whatwg.org/C/#non-blocking">... Initially,
diff --git a/chromium/third_party/blink/renderer/core/script/script_runner.cc b/chromium/third_party/blink/renderer/core/script/script_runner.cc
index 5ba5e0baa44..920ebaa82d7 100644
--- a/chromium/third_party/blink/renderer/core/script/script_runner.cc
+++ b/chromium/third_party/blink/renderer/core/script/script_runner.cc
@@ -26,6 +26,8 @@
#include "third_party/blink/renderer/core/script/script_runner.h"
#include <algorithm>
+#include "base/feature_list.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -51,7 +53,6 @@ ScriptRunner::ScriptRunner(Document* document)
void ScriptRunner::QueueScriptForExecution(PendingScript* pending_script) {
DCHECK(pending_script);
document_->IncrementLoadEventDelayCount();
- pending_script->StartStreamingIfPossible();
switch (pending_script->GetSchedulingType()) {
case ScriptSchedulingType::kAsync:
pending_async_scripts_.insert(pending_script);
@@ -115,8 +116,43 @@ void ScriptRunner::ScheduleReadyInOrderScripts() {
}
}
+void ScriptRunner::DelayAsyncScriptUntilMilestoneReached(
+ PendingScript* pending_script) {
+ DCHECK(!delay_async_script_milestone_reached_);
+ SECURITY_CHECK(pending_async_scripts_.Contains(pending_script));
+ pending_async_scripts_.erase(pending_script);
+
+ // When the ScriptRunner is notified via
+ // |NotifyDelayedAsyncScriptsMilestoneReached()|, the scripts in
+ // |pending_delayed_async_scripts_| will be scheduled for execution.
+ pending_delayed_async_scripts_.push_back(pending_script);
+}
+
+void ScriptRunner::NotifyDelayedAsyncScriptsMilestoneReached() {
+ delay_async_script_milestone_reached_ = true;
+ while (!pending_delayed_async_scripts_.IsEmpty()) {
+ PendingScript* pending_script = pending_delayed_async_scripts_.TakeFirst();
+ DCHECK_EQ(pending_script->GetSchedulingType(),
+ ScriptSchedulingType::kAsync);
+
+ async_scripts_to_execute_soon_.push_back(pending_script);
+ PostTask(FROM_HERE);
+ }
+}
+
+bool ScriptRunner::CanDelayAsyncScripts() {
+ static bool flags_enabled =
+ base::FeatureList::IsEnabled(features::kDelayAsyncScriptExecution) ||
+ RuntimeEnabledFeatures::
+ DelayAsyncScriptExecutionUntilFinishedParsingEnabled() ||
+ RuntimeEnabledFeatures::
+ DelayAsyncScriptExecutionUntilFirstPaintOrFinishedParsingEnabled();
+ return !delay_async_script_milestone_reached_ && flags_enabled;
+}
+
void ScriptRunner::NotifyScriptReady(PendingScript* pending_script) {
SECURITY_CHECK(pending_script);
+
switch (pending_script->GetSchedulingType()) {
case ScriptSchedulingType::kAsync:
// SECURITY_CHECK() makes us crash in a controlled way in error cases
@@ -125,6 +161,11 @@ void ScriptRunner::NotifyScriptReady(PendingScript* pending_script) {
// to detach).
SECURITY_CHECK(pending_async_scripts_.Contains(pending_script));
+ if (pending_script->IsEligibleForDelay() && CanDelayAsyncScripts()) {
+ DelayAsyncScriptUntilMilestoneReached(pending_script);
+ return;
+ }
+
pending_async_scripts_.erase(pending_script);
async_scripts_to_execute_soon_.push_back(pending_script);
@@ -236,8 +277,7 @@ void ScriptRunner::ExecuteTask() {
// This method is triggered by ScriptRunner::PostTask, and runs directly from
// the scheduler. So, the call stack is safe to reenter.
scheduler::CooperativeSchedulingManager::AllowedStackScope
- whitelisted_stack_scope(
- scheduler::CooperativeSchedulingManager::Instance());
+ allowed_stack_scope(scheduler::CooperativeSchedulingManager::Instance());
if (IsExecutionSuspended())
return;
@@ -249,11 +289,12 @@ void ScriptRunner::ExecuteTask() {
return;
}
-void ScriptRunner::Trace(Visitor* visitor) {
+void ScriptRunner::Trace(Visitor* visitor) const {
ExecutionContextLifecycleStateObserver::Trace(visitor);
visitor->Trace(document_);
visitor->Trace(pending_in_order_scripts_);
visitor->Trace(pending_async_scripts_);
+ visitor->Trace(pending_delayed_async_scripts_);
visitor->Trace(async_scripts_to_execute_soon_);
visitor->Trace(in_order_scripts_to_execute_soon_);
}
diff --git a/chromium/third_party/blink/renderer/core/script/script_runner.h b/chromium/third_party/blink/renderer/core/script/script_runner.h
index 08362220752..0e31ae24613 100644
--- a/chromium/third_party/blink/renderer/core/script/script_runner.h
+++ b/chromium/third_party/blink/renderer/core/script/script_runner.h
@@ -58,7 +58,7 @@ class CORE_EXPORT ScriptRunner final
}
void SetForceDeferredExecution(bool force_deferred);
void NotifyScriptReady(PendingScript*);
-
+ void NotifyDelayedAsyncScriptsMilestoneReached();
void ContextLifecycleStateChanged(mojom::FrameLifecycleState) final;
void ContextDestroyed() final {}
@@ -68,7 +68,7 @@ class CORE_EXPORT ScriptRunner final
task_runner_ = task_runner;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override { return "ScriptRunner"; }
private:
@@ -78,6 +78,11 @@ class CORE_EXPORT ScriptRunner final
bool RemovePendingInOrderScript(PendingScript*);
void ScheduleReadyInOrderScripts();
+ // Used to delay async scripts. These scripts are delayed until
+ // |NotifyDelayedAsyncScriptsMilestoneReached()| is called.
+ bool CanDelayAsyncScripts();
+ void DelayAsyncScriptUntilMilestoneReached(PendingScript*);
+
void PostTask(const base::Location&);
void PostTasksForReadyScripts(const base::Location&);
@@ -97,6 +102,7 @@ class CORE_EXPORT ScriptRunner final
HeapDeque<Member<PendingScript>> pending_in_order_scripts_;
HeapHashSet<Member<PendingScript>> pending_async_scripts_;
+ HeapDeque<Member<PendingScript>> pending_delayed_async_scripts_;
// http://www.whatwg.org/specs/web-apps/current-work/#set-of-scripts-that-will-execute-as-soon-as-possible
HeapDeque<Member<PendingScript>> async_scripts_to_execute_soon_;
@@ -111,6 +117,14 @@ class CORE_EXPORT ScriptRunner final
// with HTMLParserScriptRunner::suspended_async_script_execution_.
bool is_force_deferred_ = false;
+ // Scripts in |pending_delayed_async_scripts_| are delayed until the
+ // |NotifyDelayedAsyncScriptsMilestoneReached()| is called. After this point,
+ // the ScriptRunner no longer delays async scripts. This bool is used to
+ // ensure we don't continue delaying async scripts after this point. See the
+ // design doc:
+ // https://docs.google.com/document/u/1/d/1G-IUrT4enARZlsIrFQ4d4cRVe9MRTJASfWwolV09JZE/edit.
+ bool delay_async_script_milestone_reached_ = false;
+
DISALLOW_COPY_AND_ASSIGN(ScriptRunner);
};
diff --git a/chromium/third_party/blink/renderer/core/script/script_runner_test.cc b/chromium/third_party/blink/renderer/core/script/script_runner_test.cc
index 422b9f38bfa..266233e9dde 100644
--- a/chromium/third_party/blink/renderer/core/script/script_runner_test.cc
+++ b/chromium/third_party/blink/renderer/core/script/script_runner_test.cc
@@ -50,8 +50,6 @@ class MockPendingScript : public PendingScript {
MOCK_METHOD0(RemoveFromMemoryCache, void());
MOCK_METHOD1(ExecuteScriptBlock, void(const KURL&));
- void StartStreamingIfPossible() override {}
-
bool IsReady() const override { return is_ready_; }
void SetIsReady(bool is_ready) { is_ready_ = is_ready; }
diff --git a/chromium/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.cc b/chromium/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.cc
index f07bb63048d..23d74aa1d03 100644
--- a/chromium/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.cc
+++ b/chromium/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.cc
@@ -202,7 +202,7 @@ v8::MaybeLocal<v8::Value> ValueWrapperSyntheticModuleScript::EvaluationSteps(
return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
}
-void ValueWrapperSyntheticModuleScript::Trace(Visitor* visitor) {
+void ValueWrapperSyntheticModuleScript::Trace(Visitor* visitor) const {
visitor->Trace(export_value_);
ModuleScript::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.h b/chromium/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.h
index 1c51738e900..184fe69619d 100644
--- a/chromium/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.h
+++ b/chromium/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.h
@@ -70,7 +70,7 @@ class CORE_EXPORT ValueWrapperSyntheticModuleScript final
v8::Local<v8::Context> context,
v8::Local<v8::Module> module);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
TraceWrapperV8Reference<v8::Value> export_value_;
diff --git a/chromium/third_party/blink/renderer/core/script/xml_parser_script_runner.cc b/chromium/third_party/blink/renderer/core/script/xml_parser_script_runner.cc
index c4c945b8f7b..01b2e9c9e4c 100644
--- a/chromium/third_party/blink/renderer/core/script/xml_parser_script_runner.cc
+++ b/chromium/third_party/blink/renderer/core/script/xml_parser_script_runner.cc
@@ -26,7 +26,7 @@ XMLParserScriptRunner::~XMLParserScriptRunner() {
DCHECK(!parser_blocking_script_);
}
-void XMLParserScriptRunner::Trace(Visitor* visitor) {
+void XMLParserScriptRunner::Trace(Visitor* visitor) const {
visitor->Trace(parser_blocking_script_);
visitor->Trace(host_);
PendingScriptClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/script/xml_parser_script_runner.h b/chromium/third_party/blink/renderer/core/script/xml_parser_script_runner.h
index 9ed0ddc0baf..2b44ca3c4d8 100644
--- a/chromium/third_party/blink/renderer/core/script/xml_parser_script_runner.h
+++ b/chromium/third_party/blink/renderer/core/script/xml_parser_script_runner.h
@@ -32,7 +32,7 @@ class XMLParserScriptRunner final
void ProcessScriptElement(Document&, Element*, TextPosition);
void Detach();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// from PendingScriptClient
diff --git a/chromium/third_party/blink/renderer/core/script/xml_parser_script_runner_host.h b/chromium/third_party/blink/renderer/core/script/xml_parser_script_runner_host.h
index c6abd9f884d..5a5753f9cdc 100644
--- a/chromium/third_party/blink/renderer/core/script/xml_parser_script_runner_host.h
+++ b/chromium/third_party/blink/renderer/core/script/xml_parser_script_runner_host.h
@@ -13,7 +13,7 @@ namespace blink {
class CORE_EXPORT XMLParserScriptRunnerHost : public GarbageCollectedMixin {
public:
virtual ~XMLParserScriptRunnerHost() = default;
- void Trace(Visitor*) override {}
+ void Trace(Visitor*) const override {}
virtual void NotifyScriptExecuted() = 0;
};
diff --git a/chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc b/chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc
index f4d02dacf88..683df2318be 100644
--- a/chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc
@@ -202,7 +202,7 @@ void ProgrammaticScrollAnimator::AnimationFinished() {
}
}
-void ProgrammaticScrollAnimator::Trace(Visitor* visitor) {
+void ProgrammaticScrollAnimator::Trace(Visitor* visitor) const {
visitor->Trace(scrollable_area_);
ScrollAnimatorCompositorCoordinator::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h b/chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h
index 5bf0f85eca8..4b90b1fb982 100644
--- a/chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h
+++ b/chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h
@@ -52,7 +52,7 @@ class ProgrammaticScrollAnimator : public ScrollAnimatorCompositorCoordinator {
void LayerForCompositedScrollingDidChange(
CompositorAnimationTimeline*) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void NotifyOffsetChanged(const ScrollOffset&);
diff --git a/chromium/third_party/blink/renderer/core/scroll/scroll_animator.cc b/chromium/third_party/blink/renderer/core/scroll/scroll_animator.cc
index d2dc57d9b30..cda134a8f21 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scroll_animator.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator.cc
@@ -407,7 +407,7 @@ bool ScrollAnimator::RegisterAndScheduleAnimation() {
return true;
}
-void ScrollAnimator::Trace(Visitor* visitor) {
+void ScrollAnimator::Trace(Visitor* visitor) const {
ScrollAnimatorBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/scroll/scroll_animator.h b/chromium/third_party/blink/renderer/core/scroll/scroll_animator.h
index c4366bd6c44..7a87645e920 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scroll_animator.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator.h
@@ -131,7 +131,7 @@ class CORE_EXPORT ScrollAnimator : public ScrollAnimatorBase {
void LayerForCompositedScrollingDidChange(
CompositorAnimationTimeline*) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
// Returns whether or not the animation was sent to the compositor.
diff --git a/chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.cc b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.cc
index 3b9e3cb4915..c40dd121b87 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.cc
@@ -87,7 +87,7 @@ void ScrollAnimatorBase::NotifyOffsetChanged() {
ScrollOffsetChanged(current_offset_, mojom::blink::ScrollType::kUser);
}
-void ScrollAnimatorBase::Trace(Visitor* visitor) {
+void ScrollAnimatorBase::Trace(Visitor* visitor) const {
visitor->Trace(scrollable_area_);
ScrollAnimatorCompositorCoordinator::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.h b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.h
index 272f188e19a..be126476aac 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.h
@@ -116,7 +116,7 @@ class CORE_EXPORT ScrollAnimatorBase
virtual bool SetScrollbarsVisibleForTesting(bool) { return false; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
virtual void NotifyOffsetChanged();
diff --git a/chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h
index 03517d90b8c..48c6b27a280 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h
@@ -111,7 +111,7 @@ class CORE_EXPORT ScrollAnimatorCompositorCoordinator
RunState RunStateForTesting() { return run_state_; }
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
explicit ScrollAnimatorCompositorCoordinator();
diff --git a/chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.h b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.h
index a5b81033633..3138cef9228 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.h
@@ -114,7 +114,9 @@ class CORE_EXPORT ScrollAnimatorMac : public ScrollAnimatorBase {
void SendContentAreaScrolledSoon(const ScrollOffset& scroll_delta);
- void Trace(Visitor* visitor) override { ScrollAnimatorBase::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ ScrollAnimatorBase::Trace(visitor);
+ }
private:
base::scoped_nsobject<id> scroll_animation_helper_;
diff --git a/chromium/third_party/blink/renderer/core/scroll/scroll_animator_test.cc b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_test.cc
index f1a21a1ea30..fe724fdddaf 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scroll_animator_test.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_test.cc
@@ -137,7 +137,7 @@ class MockScrollableAreaForAnimatorTest
return ScrollbarTheme::GetTheme();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(animator);
ScrollableArea::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/scroll/scroll_test.cc b/chromium/third_party/blink/renderer/core/scroll/scroll_test.cc
index 11bd7a2e223..c4a6d27d25d 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scroll_test.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_test.cc
@@ -270,7 +270,13 @@ TEST_F(ScrollAnimatorSimTest, TestRootFrameBothViewportsUserScrollCallBack) {
// Test that the callback of user scroll will be executed when the animation
// finishes at ScrollAnimator::TickAnimation for div user scroll.
-TEST_F(ScrollAnimatorSimTest, TestDivUserScrollCallBack) {
+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
+// Flaky under sanitizers, see http://crbug.com/1092550
+#define MAYBE_TestDivUserScrollCallBack DISABLED_TestDivUserScrollCallBack
+#else
+#define MAYBE_TestDivUserScrollCallBack TestDivUserScrollCallBack
+#endif
+TEST_F(ScrollAnimatorSimTest, MAYBE_TestDivUserScrollCallBack) {
GetDocument().GetSettings()->SetScrollAnimatorEnabled(true);
WebView().MainFrameWidget()->Resize(WebSize(800, 500));
SimRequest request("https://example.com/test.html", "text/html");
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollable_area.cc b/chromium/third_party/blink/renderer/core/scroll/scrollable_area.cc
index fdadcbb9872..05af54e8c57 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollable_area.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollable_area.cc
@@ -33,12 +33,14 @@
#include "build/build_config.h"
#include "cc/input/main_thread_scrolling_reason.h"
+#include "cc/input/scroll_utils.h"
#include "cc/input/scrollbar.h"
#include "cc/input/snap_selection_strategy.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/animation/scroll_timeline.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
+#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_shift_tracker.h"
@@ -58,13 +60,13 @@ namespace blink {
int ScrollableArea::PixelsPerLineStep(LocalFrame* frame) {
if (!frame)
- return kPixelsPerLineStep;
+ return cc::kPixelsPerLineStep;
return frame->GetPage()->GetChromeClient().WindowToViewportScalar(
- frame, kPixelsPerLineStep);
+ frame, cc::kPixelsPerLineStep);
}
float ScrollableArea::MinFractionToStepWhenPaging() {
- return kMinFractionToStepWhenPaging;
+ return cc::kMinFractionToStepWhenPaging;
}
int ScrollableArea::MaxOverlapBetweenPages() const {
@@ -74,7 +76,7 @@ int ScrollableArea::MaxOverlapBetweenPages() const {
// static
float ScrollableArea::DirectionBasedScrollDelta(ScrollGranularity granularity) {
return (granularity == ScrollGranularity::kScrollByPercentage)
- ? kPercentDeltaForDirectionalScroll
+ ? cc::kPercentDeltaForDirectionalScroll
: 1;
}
@@ -172,6 +174,34 @@ float ScrollableArea::ScrollStep(ScrollGranularity granularity,
}
}
+ScrollOffset ScrollableArea::ResolveScrollDelta(ScrollGranularity granularity,
+ const ScrollOffset& delta) {
+ gfx::SizeF step(ScrollStep(granularity, kHorizontalScrollbar),
+ ScrollStep(granularity, kVerticalScrollbar));
+
+ if (granularity == ScrollGranularity::kScrollByPercentage) {
+ LocalFrame* local_frame = GetLayoutBox()->GetFrame();
+ DCHECK(local_frame);
+ gfx::SizeF viewport = gfx::SizeF(
+ FloatSize(local_frame->GetPage()->GetVisualViewport().Size()));
+
+ // Convert to screen coordinates (physical pixels).
+ float page_scale_factor = local_frame->GetPage()->PageScaleFactor();
+ step.Scale(page_scale_factor);
+
+ gfx::Vector2dF pixel_delta =
+ cc::ScrollUtils::ResolveScrollPercentageToPixels(gfx::Vector2dF(delta),
+ step, viewport);
+
+ // Rescale back to rootframe coordinates.
+ pixel_delta.Scale(1 / page_scale_factor);
+
+ return ScrollOffset(pixel_delta.x(), pixel_delta.y());
+ }
+
+ return delta.ScaledBy(step.width(), step.height());
+}
+
ScrollResult ScrollableArea::UserScroll(ScrollGranularity granularity,
const ScrollOffset& delta,
ScrollCallback on_finish) {
@@ -184,11 +214,7 @@ ScrollResult ScrollableArea::UserScroll(ScrollGranularity granularity,
base::ScopedClosureRunner run_on_return(WTF::Bind(
&ScrollableArea::RunScrollCompleteCallbacks, WrapWeakPersistent(this)));
- float step_x = ScrollStep(granularity, kHorizontalScrollbar);
- float step_y = ScrollStep(granularity, kVerticalScrollbar);
-
- ScrollOffset pixel_delta(delta);
- pixel_delta.Scale(step_x, step_y);
+ ScrollOffset pixel_delta = ResolveScrollDelta(granularity, delta);
ScrollOffset scrollable_axis_delta(
UserInputScrollable(kHorizontalScrollbar) ? pixel_delta.Width() : 0,
@@ -350,7 +376,10 @@ PhysicalRect ScrollableArea::ScrollIntoView(
void ScrollableArea::ScrollOffsetChanged(const ScrollOffset& offset,
mojom::blink::ScrollType scroll_type) {
- TRACE_EVENT0("blink", "ScrollableArea::scrollOffsetChanged");
+ TRACE_EVENT2("input", "ScrollableArea::scrollOffsetChanged", "x",
+ offset.Width(), "y", offset.Height());
+ TRACE_EVENT_INSTANT1("input", "Type", TRACE_EVENT_SCOPE_THREAD, "type",
+ scroll_type);
ScrollOffset old_offset = GetScrollOffset();
ScrollOffset truncated_offset = ShouldUseIntegerScrollOffset()
@@ -929,7 +958,7 @@ bool ScrollableArea::PerformSnapping(
return true;
}
-void ScrollableArea::Trace(Visitor* visitor) {
+void ScrollableArea::Trace(Visitor* visitor) const {
visitor->Trace(scroll_animator_);
visitor->Trace(programmatic_scroll_animator_);
}
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollable_area.h b/chromium/third_party/blink/renderer/core/scroll/scrollable_area.h
index 56c34cab314..f0eb978ce51 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollable_area.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollable_area.h
@@ -478,7 +478,7 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin {
// for layout movements (bit.ly/scroll-anchoring).
virtual bool ShouldPerformScrollAnchoring() const { return false; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
virtual void ClearScrollableArea();
@@ -551,6 +551,10 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin {
virtual const Document* GetDocument() const;
+ // Resolves into un-zoomed physical pixels a scroll |delta| based on its
+ // ScrollGranularity units.
+ ScrollOffset ResolveScrollDelta(ScrollGranularity, const ScrollOffset& delta);
+
private:
FRIEND_TEST_ALL_PREFIXES(ScrollableAreaTest,
PopupOverlayScrollbarShouldNotFadeOut);
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar.cc
index 8c67ff69697..ef2efa584da 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar.cc
@@ -93,7 +93,7 @@ Scrollbar::Scrollbar(ScrollableArea* scrollable_area,
Scrollbar::~Scrollbar() = default;
-void Scrollbar::Trace(Visitor* visitor) {
+void Scrollbar::Trace(Visitor* visitor) const {
visitor->Trace(scrollable_area_);
visitor->Trace(chrome_client_);
visitor->Trace(style_source_);
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar.h
index 0c90f64ec9e..bf3475fc0d4 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar.h
@@ -111,7 +111,7 @@ class CORE_EXPORT Scrollbar : public GarbageCollected<Scrollbar>,
// Called by the ScrollableArea when the scroll offset changes.
// Will trigger paint invalidation if required.
- void OffsetDidChange(mojom::blink::ScrollType scroll_type);
+ virtual void OffsetDidChange(mojom::blink::ScrollType scroll_type);
virtual void DisconnectFromScrollableArea();
ScrollableArea* GetScrollableArea() const { return scrollable_area_; }
@@ -204,7 +204,7 @@ class CORE_EXPORT Scrollbar : public GarbageCollected<Scrollbar>,
WebColorScheme UsedColorScheme() const;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
protected:
void AutoscrollTimerFired(TimerBase*);
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.cc
index 340cd67b2aa..e9332965fee 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.cc
@@ -88,6 +88,10 @@ bool ScrollbarLayerDelegate::SupportsDragSnapBack() const {
return scrollbar_->GetTheme().SupportsDragSnapBack();
}
+bool ScrollbarLayerDelegate::JumpOnTrackClick() const {
+ return scrollbar_->GetTheme().JumpOnTrackClick();
+}
+
gfx::Rect ScrollbarLayerDelegate::BackButtonRect() const {
IntRect back_button_rect = scrollbar_->GetTheme().BackButtonRect(*scrollbar_);
if (!back_button_rect.IsEmpty())
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h
index 3eafffa8643..dcdb884fb7f 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h
@@ -29,6 +29,7 @@ class CORE_EXPORT ScrollbarLayerDelegate : public cc::Scrollbar {
bool IsSolidColor() const override;
bool IsOverlay() const override;
bool SupportsDragSnapBack() const override;
+ bool JumpOnTrackClick() const override;
// The following rects are all relative to the scrollbar's origin.
gfx::Rect ThumbRect() const override;
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar_test_suite.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar_test_suite.h
index 8871777f578..47f4e26870c 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar_test_suite.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_test_suite.h
@@ -125,7 +125,7 @@ class MockScrollableArea : public GarbageCollected<MockScrollableArea>,
using ScrollableArea::ShowNonMacOverlayScrollbars;
using ScrollableArea::VerticalScrollbarNeedsPaintInvalidation;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(chrome_client_);
ScrollableArea::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.h
index acbfd1d3912..5e26b132bfa 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.h
@@ -120,6 +120,7 @@ class CORE_EXPORT ScrollbarTheme {
}
virtual bool SupportsDragSnapBack() const { return false; }
+ virtual bool JumpOnTrackClick() const { return false; }
// The position of the thumb relative to the track.
int ThumbPosition(const Scrollbar& scrollbar) {
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h
index c34380e4696..102fe79adb5 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h
@@ -65,6 +65,7 @@ class PLATFORM_EXPORT ScrollbarThemeMac : public ScrollbarTheme {
const IntRect&) override;
bool ShouldCenterOnThumb(const Scrollbar&, const WebMouseEvent&) override;
+ bool JumpOnTrackClick() const override;
bool ShouldRepaintAllPartsOnInvalidation() const override { return false; }
ScrollbarPart PartsToInvalidateOnThumbPositionChange(
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm
index 368227b5a29..58612701d4c 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm
@@ -43,9 +43,6 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
-#include "ui/gfx/mac/cocoa_scrollbar_painter.h"
-
-using gfx::CocoaScrollbarPainter;
@interface BlinkScrollbarObserver : NSObject {
blink::Scrollbar* _scrollbar;
@@ -227,21 +224,34 @@ ScrollbarPainter ScrollbarThemeMac::PainterForScrollbar(
[GetScrollbarPainterMap().at(const_cast<Scrollbar*>(&scrollbar)) painter];
}
-CocoaScrollbarPainter::Params GetPaintParams(const Scrollbar& scrollbar,
- bool overlay) {
- CocoaScrollbarPainter::Params params;
- params.orientation = CocoaScrollbarPainter::Orientation::kVerticalOnRight;
- if (scrollbar.Orientation() == kHorizontalScrollbar)
- params.orientation = CocoaScrollbarPainter::Orientation::kHorizontal;
- if (scrollbar.IsLeftSideVerticalScrollbar())
- params.orientation = CocoaScrollbarPainter::Orientation::kVerticalOnLeft;
-
- params.dark_mode = scrollbar.UsedColorScheme() == WebColorScheme::kDark;
- params.overlay = overlay;
- if (overlay)
- params.dark_mode = scrollbar.GetScrollbarOverlayColorTheme() ==
- kScrollbarOverlayColorThemeLight;
- params.hovered = scrollbar.HoveredPart() != ScrollbarPart::kNoPart;
+WebThemeEngine::ExtraParams GetPaintParams(const Scrollbar& scrollbar,
+ bool overlay) {
+ WebThemeEngine::ExtraParams params;
+
+ params.scrollbar_extra.orientation =
+ WebThemeEngine::ScrollbarOrientation::kVerticalOnRight;
+ if (scrollbar.Orientation() == kHorizontalScrollbar) {
+ params.scrollbar_extra.orientation =
+ WebThemeEngine::ScrollbarOrientation::kHorizontal;
+ } else if (scrollbar.IsLeftSideVerticalScrollbar()) {
+ params.scrollbar_extra.orientation =
+ WebThemeEngine::ScrollbarOrientation::kVerticalOnLeft;
+ }
+
+ params.scrollbar_extra.scrollbar_theme =
+ (scrollbar.UsedColorScheme() == WebColorScheme::kDark) ? kDark : kLight;
+ params.scrollbar_extra.is_overlay = overlay;
+
+ if (overlay) {
+ params.scrollbar_extra.scrollbar_theme =
+ (scrollbar.GetScrollbarOverlayColorTheme() ==
+ kScrollbarOverlayColorThemeLight)
+ ? kDark
+ : kLight;
+ }
+
+ params.scrollbar_extra.is_hovering =
+ scrollbar.HoveredPart() != ScrollbarPart::kNoPart;
return params;
}
@@ -271,11 +281,18 @@ void ScrollbarThemeMac::PaintTrack(GraphicsContext& context,
if (opacity != 1)
context.BeginLayer(opacity);
- CocoaScrollbarPainter::Params params =
+ WebThemeEngine::ExtraParams params =
GetPaintParams(scrollbar, UsesOverlayScrollbars());
- SkIRect bounds = SkIRect::MakeXYWH(0, 0, scrollbar.FrameRect().Width(),
- scrollbar.FrameRect().Height());
- CocoaScrollbarPainter::PaintTrack(context.Canvas(), bounds, params);
+ IntRect bounds(0, 0, scrollbar.FrameRect().Width(),
+ scrollbar.FrameRect().Height());
+ WebThemeEngine::Part track_part =
+ params.scrollbar_extra.orientation ==
+ WebThemeEngine::ScrollbarOrientation::kHorizontal
+ ? WebThemeEngine::Part::kPartScrollbarHorizontalTrack
+ : WebThemeEngine::Part::kPartScrollbarVerticalTrack;
+ Platform::Current()->ThemeEngine()->Paint(
+ context.Canvas(), track_part, WebThemeEngine::State::kStateNormal,
+ WebRect(bounds), &params, params.scrollbar_extra.scrollbar_theme);
if (opacity != 1)
context.EndLayer();
}
@@ -298,10 +315,13 @@ void ScrollbarThemeMac::PaintScrollCorner(GraphicsContext& context,
GraphicsContextStateSaver state_saver(context);
context.Translate(rect.X(), rect.Y());
- SkIRect bounds = SkIRect::MakeXYWH(0, 0, rect.Width(), rect.Height());
- CocoaScrollbarPainter::Params params =
+ IntRect bounds(0, 0, rect.Width(), rect.Height());
+ WebThemeEngine::ExtraParams params =
GetPaintParams(*vertical_scrollbar, UsesOverlayScrollbars());
- CocoaScrollbarPainter::PaintCorner(context.Canvas(), bounds, params);
+ Platform::Current()->ThemeEngine()->Paint(
+ context.Canvas(), WebThemeEngine::Part::kPartScrollbarCorner,
+ WebThemeEngine::State::kStateNormal, WebRect(bounds), &params,
+ params.scrollbar_extra.scrollbar_theme);
}
void ScrollbarThemeMac::PaintThumbInternal(GraphicsContext& context,
@@ -360,22 +380,20 @@ void ScrollbarThemeMac::PaintThumbInternal(GraphicsContext& context,
if (!scrollbar.Enabled())
return;
- CocoaScrollbarPainter::Params params =
+ WebThemeEngine::ExtraParams params =
GetPaintParams(scrollbar, UsesOverlayScrollbars());
// Compute the bounds for the thumb, accounting for lack of engorgement.
- SkIRect bounds;
- switch (params.orientation) {
- case CocoaScrollbarPainter::Orientation::kVerticalOnRight:
- bounds = SkIRect::MakeXYWH(rect.Width() - thumb_size, 0, thumb_size,
- rect.Height());
+ IntRect bounds;
+ switch (params.scrollbar_extra.orientation) {
+ case WebThemeEngine::ScrollbarOrientation::kVerticalOnRight:
+ bounds = IntRect(rect.Width() - thumb_size, 0, thumb_size, rect.Height());
break;
- case CocoaScrollbarPainter::Orientation::kVerticalOnLeft:
- bounds = SkIRect::MakeXYWH(0, 0, thumb_size, rect.Height());
+ case WebThemeEngine::ScrollbarOrientation::kVerticalOnLeft:
+ bounds = IntRect(0, 0, thumb_size, rect.Height());
break;
- case CocoaScrollbarPainter::Orientation::kHorizontal:
- bounds = SkIRect::MakeXYWH(0, rect.Height() - thumb_size, rect.Width(),
- thumb_size);
+ case WebThemeEngine::ScrollbarOrientation::kHorizontal:
+ bounds = IntRect(0, rect.Height() - thumb_size, rect.Width(), thumb_size);
break;
}
@@ -383,7 +401,15 @@ void ScrollbarThemeMac::PaintThumbInternal(GraphicsContext& context,
FloatRect float_local_rect(local_rect);
context.BeginLayer(opacity, SkBlendMode::kSrcOver, &float_local_rect);
}
- CocoaScrollbarPainter::PaintThumb(context.Canvas(), bounds, params);
+
+ WebThemeEngine::Part thumb_part =
+ params.scrollbar_extra.orientation ==
+ WebThemeEngine::ScrollbarOrientation::kHorizontal
+ ? WebThemeEngine::Part::kPartScrollbarHorizontalThumb
+ : WebThemeEngine::Part::kPartScrollbarVerticalThumb;
+ Platform::Current()->ThemeEngine()->Paint(
+ context.Canvas(), thumb_part, WebThemeEngine::State::kStateNormal,
+ WebRect(bounds), &params, params.scrollbar_extra.scrollbar_theme);
if (opacity != 1.0f)
context.EndLayer();
}
@@ -460,6 +486,10 @@ float ScrollbarThemeMac::Opacity(const Scrollbar& scrollbar) const {
return [scrollbar_painter knobAlpha];
}
+bool ScrollbarThemeMac::JumpOnTrackClick() const {
+ return s_jump_on_track_click;
+}
+
// static
void ScrollbarThemeMac::UpdateScrollbarsWithNSDefaults(
base::Optional<float> initial_button_delay,
diff --git a/chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.cc b/chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.cc
index 707905fc146..cc4a299ec11 100644
--- a/chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.cc
@@ -9,7 +9,7 @@
namespace blink {
-void SequencedScroll::Trace(Visitor* visitor) {
+void SequencedScroll::Trace(Visitor* visitor) const {
visitor->Trace(scrollable_area);
}
@@ -76,7 +76,7 @@ void SmoothScrollSequencer::DidDisposeScrollableArea(
}
}
-void SmoothScrollSequencer::Trace(Visitor* visitor) {
+void SmoothScrollSequencer::Trace(Visitor* visitor) const {
visitor->Trace(queue_);
visitor->Trace(current_scrollable_);
}
diff --git a/chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h b/chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h
index 3d120d4cff1..98b5f196207 100644
--- a/chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h
+++ b/chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h
@@ -33,7 +33,7 @@ struct SequencedScroll final : public GarbageCollected<SequencedScroll> {
ScrollOffset scroll_offset;
mojom::blink::ScrollBehavior scroll_behavior;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
};
// A sequencer that queues the nested scrollers from inside to outside,
@@ -63,7 +63,7 @@ class CORE_EXPORT SmoothScrollSequencer final
void DidDisposeScrollableArea(const ScrollableArea&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
HeapVector<Member<SequencedScroll>> queue_;
diff --git a/chromium/third_party/blink/renderer/core/streams/.eslintrc.js b/chromium/third_party/blink/renderer/core/streams/.eslintrc.js
deleted file mode 100644
index 5abd6cd4c23..00000000000
--- a/chromium/third_party/blink/renderer/core/streams/.eslintrc.js
+++ /dev/null
@@ -1,163 +0,0 @@
-// ESLint rules for the Blink streams implementation.
-// Based on the devtools rules, with extensive additions and modifications to
-// reflect existing usage.
-
-// eslint-disable-next-line no-undef
-module.exports = {
- root: true,
-
- env: {browser: true, es6: true},
-
- parserOptions: {ecmaVersion: 8},
-
- // ESLint rules
- //
- // All available rules: http://eslint.org/docs/rules/
- //
- // All rules should have severity "error". For individual exceptions, use
- // comments like:
- // eslint-disable-next-line no-console
- //
- // If a rule is causing problems in multiple places, just remove it.
- rules: {
- // syntax preferences
- quotes: [
- 'error', 'single',
- {avoidEscape: true, allowTemplateLiterals: true}
- ],
- semi: 'error',
- 'no-extra-semi': 'error',
- 'comma-style': ['error', 'last'],
- 'wrap-iife': ['error', 'inside'],
- 'spaced-comment': 'error',
- eqeqeq: 'error',
- 'accessor-pairs':
- ['error', {getWithoutSet: false, setWithoutGet: false}],
- curly: ['error', 'all'],
- 'new-parens': 'error',
- 'func-call-spacing': 'error',
- 'arrow-parens': ['error', 'as-needed'],
-
- 'max-len': ['error', {code: 80, ignoreUrls: true}],
-
- // Security
- strict: ['error', 'function'],
-
- // no
- 'no-alert': 'error',
- 'no-caller': 'error',
- 'no-cond-assign': 'error',
- 'no-console': 'error',
- 'no-debugger': 'error',
- 'no-dupe-args': 'error',
- 'no-dupe-keys': 'error',
- 'no-duplicate-case': 'error',
- 'no-else-return': 'error',
- 'no-empty': 'error',
- 'no-empty-character-class': 'error',
- 'no-empty-pattern': 'error',
- 'no-eq-null': 'error',
- 'no-ex-assign': 'error',
- 'no-extra-boolean-cast': 'error',
- 'no-extra-parens': [
- 'error', 'all', {
- conditionalAssign: false,
- nestedBinaryExpressions: false,
- returnAssign: false
- }
- ],
- 'no-eval': 'error',
- 'no-fallthrough': 'error',
- 'no-floating-decimal': 'error',
- 'no-func-assign': 'error',
- 'no-implied-eval': 'error',
- 'no-implicit-coercion': 'error',
- 'no-implicit-globals': 'error',
- 'no-inner-declarations': 'off',
- 'no-invalid-regexp': 'error',
- 'no-irregular-whitespace': 'error',
- 'no-labels': 'error',
- 'no-loop-func': 'off',
- 'no-magic-numbers': 'off',
- 'no-multi-str': 'error',
- 'no-negated-in-lhs': 'error',
- 'no-new-func': 'error',
- 'no-new-wrappers': 'error',
- 'no-new-object': 'error',
- 'no-octal': 'error',
- 'no-octal-escape': 'error',
- 'no-self-compare': 'error',
- 'no-sequences': 'error',
- 'no-shadow-restricted-names': 'error',
- 'no-sparse-arrays': 'error',
- 'no-undef': 'error',
- 'no-unexpected-multiline': 'error',
- 'no-unsafe-finally': 'error',
- 'no-unreachable': 'error',
- 'no-unsafe-negation': 'error',
- 'no-unused-vars': 'error',
- 'no-useless-call': 'error',
- 'no-useless-concat': 'error',
- 'no-useless-escape': 'error',
- 'no-void': 'error',
- 'no-with': 'error',
- radix: 'error',
- 'use-isnan': 'error',
- 'valid-typeof': 'error',
-
- // ES6
- 'no-const-assign': 'error',
- 'no-dupe-class-members': 'error',
- 'no-new-symbol': 'error',
- 'no-this-before-super': 'error',
- 'no-var': 'error',
- 'prefer-const': 'error',
- 'prefer-rest-params': 'error',
- 'prefer-spread': 'error',
- 'template-curly-spacing': ['error', 'never'],
-
- // spacing details
- 'space-infix-ops': 'error',
- 'space-in-parens': ['error', 'never'],
- 'no-whitespace-before-property': 'error',
- 'keyword-spacing': [
- 'error', {
- overrides: {
- if: {after: true},
- else: {after: true},
- for: {after: true},
- while: {after: true},
- do: {after: true},
- switch: {after: true},
- return: {after: true}
- }
- }
- ],
- 'arrow-spacing': ['error', {after: true, before: true}],
- 'one-var': ['error', 'never'],
- 'operator-assignment': ['error', 'always'],
- 'operator-linebreak': ['error', 'after'],
- 'padded-blocks': ['error', 'never'],
- 'space-before-blocks': ['error', 'always'],
- 'space-before-function-paren': ['error', 'never'],
- 'space-unary-ops': ['error', {words: true, nonwords: false}],
-
- // file whitespace
- 'no-multiple-empty-lines': 'error',
- 'no-mixed-spaces-and-tabs': 'error',
- 'no-trailing-spaces': 'error',
- 'linebreak-style': ['error', 'unix'],
-
- indent: ['error', 2, {SwitchCase: 1}],
-
- 'brace-style': ['error', '1tbs', {allowSingleLine: true}],
-
- 'key-spacing': [
- 'error', {beforeColon: false, afterColon: true, mode: 'strict'}
- ],
-
- 'quote-props': ['error', 'as-needed'],
-
- 'unicode-bom': ['error', 'never']
- }
-};
diff --git a/chromium/third_party/blink/renderer/core/streams/PRESUBMIT.py b/chromium/third_party/blink/renderer/core/streams/PRESUBMIT.py
deleted file mode 100644
index 7935e32c18d..00000000000
--- a/chromium/third_party/blink/renderer/core/streams/PRESUBMIT.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (c) 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# pylint: disable=invalid-name,import-error
-"""Run eslint on the Streams API Javascript files.
-
-See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
-for more details about the presubmit API built into depot_tools, and see
-https://chromium.googlesource.com/chromium/src/+/master/styleguide/web/web.md
-for the rules we're checking against here.
-"""
-
-
-def CheckChangeOnUpload(input_api, output_api):
- return common_checks(input_api, output_api)
-
-
-def CheckChangeOnCommit(input_api, output_api):
- return common_checks(input_api, output_api)
-
-
-def common_checks(input_api, output_api):
- import sys
- web_dev_style_path = input_api.os_path.join(
- input_api.change.RepositoryRoot(), 'tools')
- oldpath = sys.path
- sys.path = [input_api.PresubmitLocalPath(), web_dev_style_path] + sys.path
- from web_dev_style import js_checker
- sys.path = oldpath
-
- def is_resource(maybe_resource):
- return maybe_resource.AbsoluteLocalPath().endswith('.js')
-
- return js_checker.JSChecker(
- input_api, output_api, file_filter=is_resource).RunChecks()
diff --git a/chromium/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.cc b/chromium/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.cc
index b747c7180e9..cbd98202946 100644
--- a/chromium/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.cc
+++ b/chromium/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.cc
@@ -93,7 +93,7 @@ ScriptValue ByteLengthQueuingStrategy::size(ScriptState* script_state) const {
ByteLengthQueuingStrategySizeFunction::CreateFunction(script_state));
}
-void ByteLengthQueuingStrategy::Trace(Visitor* visitor) {
+void ByteLengthQueuingStrategy::Trace(Visitor* visitor) const {
visitor->Trace(high_water_mark_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.h b/chromium/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.h
index c1544212c8a..620b5a88593 100644
--- a/chromium/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.h
+++ b/chromium/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.h
@@ -30,7 +30,7 @@ class ByteLengthQueuingStrategy final : public ScriptWrappable {
ScriptValue highWaterMark(ScriptState*) const;
ScriptValue size(ScriptState*) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const TraceWrapperV8Reference<v8::Value> high_water_mark_;
diff --git a/chromium/third_party/blink/renderer/core/streams/count_queuing_strategy.cc b/chromium/third_party/blink/renderer/core/streams/count_queuing_strategy.cc
index 079e8b7261f..4bd19c96b35 100644
--- a/chromium/third_party/blink/renderer/core/streams/count_queuing_strategy.cc
+++ b/chromium/third_party/blink/renderer/core/streams/count_queuing_strategy.cc
@@ -64,7 +64,7 @@ ScriptValue CountQueuingStrategy::size(ScriptState* script_state) const {
CountQueuingStrategySizeFunction::CreateFunction(script_state));
}
-void CountQueuingStrategy::Trace(Visitor* visitor) {
+void CountQueuingStrategy::Trace(Visitor* visitor) const {
visitor->Trace(high_water_mark_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/streams/count_queuing_strategy.h b/chromium/third_party/blink/renderer/core/streams/count_queuing_strategy.h
index cd001b1dadb..7a291762758 100644
--- a/chromium/third_party/blink/renderer/core/streams/count_queuing_strategy.h
+++ b/chromium/third_party/blink/renderer/core/streams/count_queuing_strategy.h
@@ -30,7 +30,7 @@ class CORE_EXPORT CountQueuingStrategy final : public ScriptWrappable {
ScriptValue highWaterMark(ScriptState*) const;
ScriptValue size(ScriptState*) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const TraceWrapperV8Reference<v8::Value> high_water_mark_;
diff --git a/chromium/third_party/blink/renderer/core/streams/miscellaneous_operations.cc b/chromium/third_party/blink/renderer/core/streams/miscellaneous_operations.cc
index 967342344e4..ffaeaa9689c 100644
--- a/chromium/third_party/blink/renderer/core/streams/miscellaneous_operations.cc
+++ b/chromium/third_party/blink/renderer/core/streams/miscellaneous_operations.cc
@@ -94,7 +94,7 @@ class JavaScriptSizeAlgorithm final : public StrategySizeAlgorithm {
return number->Value();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(function_);
StrategySizeAlgorithm::Trace(visitor);
}
@@ -138,7 +138,7 @@ class JavaScriptStreamAlgorithmWithoutExtraArg final : public StreamAlgorithm {
recv_.NewLocal(isolate), argc, argv);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(recv_);
visitor->Trace(method_);
StreamAlgorithm::Trace(visitor);
@@ -183,7 +183,7 @@ class JavaScriptStreamAlgorithmWithExtraArg final : public StreamAlgorithm {
recv_.NewLocal(isolate), full_argc, full_argv);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(recv_);
visitor->Trace(method_);
visitor->Trace(extra_arg_);
@@ -226,7 +226,7 @@ class JavaScriptStreamStartAlgorithm : public StreamStartAlgorithm {
return PromiseResolve(script_state, value);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(recv_);
visitor->Trace(controller_);
StreamStartAlgorithm::Trace(visitor);
@@ -485,7 +485,7 @@ void ScriptValueToObject(ScriptState* script_state,
v8::Local<v8::Object>* object,
ExceptionState& exception_state) {
auto* isolate = script_state->GetIsolate();
- CHECK(!value.IsEmpty());
+ DCHECK(!value.IsEmpty());
auto v8_value = value.V8Value();
// All the object parameters in the standard are default-initialised to an
// empty object.
diff --git a/chromium/third_party/blink/renderer/core/streams/queue_with_sizes.cc b/chromium/third_party/blink/renderer/core/streams/queue_with_sizes.cc
index d46e3d88095..280c8b5e2bd 100644
--- a/chromium/third_party/blink/renderer/core/streams/queue_with_sizes.cc
+++ b/chromium/third_party/blink/renderer/core/streams/queue_with_sizes.cc
@@ -34,7 +34,7 @@ class QueueWithSizes::ValueSizePair final
double Size() { return size_; }
- void Trace(Visitor* visitor) { visitor->Trace(value_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(value_); }
private:
TraceWrapperV8Reference<v8::Value> value_;
@@ -111,7 +111,7 @@ void QueueWithSizes::ResetQueue() {
queue_total_size_ = 0;
}
-void QueueWithSizes::Trace(Visitor* visitor) {
+void QueueWithSizes::Trace(Visitor* visitor) const {
visitor->Trace(queue_);
}
diff --git a/chromium/third_party/blink/renderer/core/streams/queue_with_sizes.h b/chromium/third_party/blink/renderer/core/streams/queue_with_sizes.h
index fee10c349a7..343134e8bbb 100644
--- a/chromium/third_party/blink/renderer/core/streams/queue_with_sizes.h
+++ b/chromium/third_party/blink/renderer/core/streams/queue_with_sizes.h
@@ -48,7 +48,7 @@ class CORE_EXPORT QueueWithSizes final
// https://streams.spec.whatwg.org/#reset-queue
void ResetQueue();
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
private:
class ValueSizePair;
diff --git a/chromium/third_party/blink/renderer/core/streams/readable_stream.cc b/chromium/third_party/blink/renderer/core/streams/readable_stream.cc
index a2b20b814cb..87b6e39d075 100644
--- a/chromium/third_party/blink/renderer/core/streams/readable_stream.cc
+++ b/chromium/third_party/blink/renderer/core/streams/readable_stream.cc
@@ -99,7 +99,7 @@ ReadableStream::PipeOptions::PipeOptions(ScriptState* script_state,
}
}
-void ReadableStream::PipeOptions::Trace(Visitor* visitor) {
+void ReadableStream::PipeOptions::Trace(Visitor* visitor) const {
visitor->Trace(signal_);
}
@@ -228,7 +228,7 @@ class ReadableStream::PipeToEngine final
return promise_->GetScriptPromise(script_state_);
}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(pipe_options_);
visitor->Trace(reader_);
@@ -270,7 +270,7 @@ class ReadableStream::PipeToEngine final
return (instance_->*method_)(value);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(instance_);
ScriptFunction::Trace(visitor);
}
@@ -756,7 +756,7 @@ class ReadableStream::TeeEngine final : public GarbageCollected<TeeEngine> {
ReadableStream* Branch1() const { return branch_[0]; }
ReadableStream* Branch2() const { return branch_[1]; }
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(stream_);
visitor->Trace(reader_);
visitor->Trace(reason_[0]);
@@ -808,7 +808,7 @@ class ReadableStream::TeeEngine::PullAlgorithm final : public StreamAlgorithm {
MakeGarbageCollected<ResolveFunction>(script_state, engine_));
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(engine_);
StreamAlgorithm::Trace(visitor);
}
@@ -901,7 +901,7 @@ class ReadableStream::TeeEngine::PullAlgorithm final : public StreamAlgorithm {
}
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(engine_);
PromiseHandler::Trace(visitor);
}
@@ -960,7 +960,7 @@ class ReadableStream::TeeEngine::CancelAlgorithm final
return engine_->cancel_promise_->V8Promise(isolate);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(engine_);
StreamAlgorithm::Trace(visitor);
}
@@ -1070,7 +1070,7 @@ void ReadableStream::TeeEngine::Start(ScriptState* script_state,
engine_->controller_[1], r);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(engine_);
PromiseHandler::Trace(visitor);
}
@@ -1210,8 +1210,7 @@ ReadableStream::ReadableStream() = default;
ReadableStream::~ReadableStream() = default;
-bool ReadableStream::locked(ScriptState* script_state,
- ExceptionState& exception_state) const {
+bool ReadableStream::locked() const {
// https://streams.spec.whatwg.org/#rs-locked
// 2. Return ! IsReadableStreamLocked(this).
return IsLocked(this);
@@ -1652,7 +1651,7 @@ v8::Local<v8::Value> ReadableStream::GetStoredError(
return stored_error_.NewLocal(isolate);
}
-void ReadableStream::Trace(Visitor* visitor) {
+void ReadableStream::Trace(Visitor* visitor) const {
visitor->Trace(readable_stream_controller_);
visitor->Trace(reader_);
visitor->Trace(stored_error_);
diff --git a/chromium/third_party/blink/renderer/core/streams/readable_stream.h b/chromium/third_party/blink/renderer/core/streams/readable_stream.h
index 56dd9f80d8c..c12ac7ecf5a 100644
--- a/chromium/third_party/blink/renderer/core/streams/readable_stream.h
+++ b/chromium/third_party/blink/renderer/core/streams/readable_stream.h
@@ -49,7 +49,7 @@ class CORE_EXPORT ReadableStream : public ScriptWrappable {
bool PreventCancel() const { return prevent_cancel_; }
AbortSignal* Signal() const { return signal_; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
bool GetBoolean(ScriptState* script_state,
@@ -102,7 +102,7 @@ class CORE_EXPORT ReadableStream : public ScriptWrappable {
~ReadableStream() override;
// https://streams.spec.whatwg.org/#rs-constructor
- bool locked(ScriptState*, ExceptionState&) const;
+ bool locked() const;
ScriptPromise cancel(ScriptState*, ExceptionState&);
@@ -143,25 +143,15 @@ class CORE_EXPORT ReadableStream : public ScriptWrappable {
ReadableStream** branch2,
ExceptionState&);
- base::Optional<bool> IsLocked(ScriptState*, ExceptionState&) const {
- return IsLocked(this);
- }
+ bool IsLocked() const { return IsLocked(this); }
- base::Optional<bool> IsDisturbed(ScriptState*, ExceptionState&) const {
- return IsDisturbed(this);
- }
+ bool IsDisturbed() const { return IsDisturbed(this); }
- base::Optional<bool> IsReadable(ScriptState*, ExceptionState&) const {
- return IsReadable(this);
- }
+ bool IsReadable() const { return IsReadable(this); }
- base::Optional<bool> IsClosed(ScriptState*, ExceptionState&) const {
- return IsClosed(this);
- }
+ bool IsClosed() const { return IsClosed(this); }
- base::Optional<bool> IsErrored(ScriptState*, ExceptionState&) const {
- return IsErrored(this);
- }
+ bool IsErrored() const { return IsErrored(this); }
void LockAndDisturb(ScriptState*, ExceptionState&);
@@ -178,8 +168,6 @@ class CORE_EXPORT ReadableStream : public ScriptWrappable {
ReadableStreamDefaultReader* GetReaderNotForAuthorCode(ScriptState*,
ExceptionState&);
- bool IsBroken() const { return false; }
-
//
// Readable stream abstract operations
//
@@ -220,7 +208,7 @@ class CORE_EXPORT ReadableStream : public ScriptWrappable {
v8::Local<v8::Value> GetStoredError(v8::Isolate*) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class ReadableStreamDefaultController;
diff --git a/chromium/third_party/blink/renderer/core/streams/readable_stream.idl b/chromium/third_party/blink/renderer/core/streams/readable_stream.idl
index 785e3944536..e2d7d380864 100644
--- a/chromium/third_party/blink/renderer/core/streams/readable_stream.idl
+++ b/chromium/third_party/blink/renderer/core/streams/readable_stream.idl
@@ -7,8 +7,7 @@
Exposed=(Window,Worker,Worklet)
] interface ReadableStream {
[CallWith=ScriptState, RaisesException] constructor(optional any underlyingSource, optional any strategy);
- // As long as we use V8Extras, anything can raise an exception.
- [RaisesException, CallWith=ScriptState, NotEnumerable] readonly attribute boolean locked;
+ [NotEnumerable] readonly attribute boolean locked;
// TODO(yhirano): function length is different from what's specced. Fix it.
[RaisesException, CallWith=ScriptState, NotEnumerable] Promise<any> cancel(
diff --git a/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc b/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc
index b349d0fee8d..56e9d793a90 100644
--- a/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc
+++ b/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc
@@ -256,7 +256,7 @@ const char* ReadableStreamDefaultController::EnqueueExceptionMessage(
return "Cannot enqueue a chunk into a closed readable stream";
}
-void ReadableStreamDefaultController::Trace(Visitor* visitor) {
+void ReadableStreamDefaultController::Trace(Visitor* visitor) const {
visitor->Trace(cancel_algorithm_);
visitor->Trace(controlled_readable_stream_);
visitor->Trace(pull_algorithm_);
@@ -390,7 +390,7 @@ void ReadableStreamDefaultController::CallPullIfNeeded(
}
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(controller_);
PromiseHandler::Trace(visitor);
}
@@ -411,7 +411,7 @@ void ReadableStreamDefaultController::CallPullIfNeeded(
Error(GetScriptState(), controller_, e);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(controller_);
PromiseHandler::Trace(visitor);
}
@@ -553,7 +553,7 @@ void ReadableStreamDefaultController::SetUp(
CallPullIfNeeded(GetScriptState(), controller_);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(controller_);
PromiseHandler::Trace(visitor);
}
@@ -574,7 +574,7 @@ void ReadableStreamDefaultController::SetUp(
Error(GetScriptState(), controller_, r);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(controller_);
PromiseHandler::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.h b/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.h
index 02f4a769990..396f0060e2e 100644
--- a/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.h
+++ b/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.h
@@ -70,7 +70,7 @@ class ReadableStreamDefaultController : public ScriptWrappable {
static const char* EnqueueExceptionMessage(
const ReadableStreamDefaultController*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class ReadableStream;
diff --git a/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.cc b/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.cc
index ec720e176f4..de413361f3b 100644
--- a/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.cc
+++ b/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.cc
@@ -82,7 +82,8 @@ void ReadableStreamDefaultControllerWithScriptScope::Error(
controller_ = nullptr;
}
-void ReadableStreamDefaultControllerWithScriptScope::Trace(Visitor* visitor) {
+void ReadableStreamDefaultControllerWithScriptScope::Trace(
+ Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(controller_);
}
diff --git a/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h b/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h
index e72ca373c1b..9c3dc2f15d9 100644
--- a/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h
+++ b/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h
@@ -48,7 +48,7 @@ class CORE_EXPORT ReadableStreamDefaultControllerWithScriptScope
Error(js_error);
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
const Member<ScriptState> script_state_;
diff --git a/chromium/third_party/blink/renderer/core/streams/readable_stream_reader.cc b/chromium/third_party/blink/renderer/core/streams/readable_stream_reader.cc
index 0039f56ee59..01bce0e6f94 100644
--- a/chromium/third_party/blink/renderer/core/streams/readable_stream_reader.cc
+++ b/chromium/third_party/blink/renderer/core/streams/readable_stream_reader.cc
@@ -198,7 +198,7 @@ void ReadableStreamReader::GenericRelease(ScriptState* script_state,
reader->owner_readable_stream_ = nullptr;
}
-void ReadableStreamReader::Trace(Visitor* visitor) {
+void ReadableStreamReader::Trace(Visitor* visitor) const {
visitor->Trace(closed_promise_);
visitor->Trace(owner_readable_stream_);
visitor->Trace(read_requests_);
diff --git a/chromium/third_party/blink/renderer/core/streams/readable_stream_reader.h b/chromium/third_party/blink/renderer/core/streams/readable_stream_reader.h
index 08dc0ff4569..5cd37cdd2f6 100644
--- a/chromium/third_party/blink/renderer/core/streams/readable_stream_reader.h
+++ b/chromium/third_party/blink/renderer/core/streams/readable_stream_reader.h
@@ -63,7 +63,7 @@ class CORE_EXPORT ReadableStreamReader : public ScriptWrappable {
StreamPromiseResolver* ClosedPromise() { return closed_promise_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class ReadableStreamDefaultController;
diff --git a/chromium/third_party/blink/renderer/core/streams/readable_stream_test.cc b/chromium/third_party/blink/renderer/core/streams/readable_stream_test.cc
index 45e68f90acc..f1f144c9ee3 100644
--- a/chromium/third_party/blink/renderer/core/streams/readable_stream_test.cc
+++ b/chromium/third_party/blink/renderer/core/streams/readable_stream_test.cc
@@ -175,26 +175,20 @@ TEST_F(ReadableStreamTest, GetReader) {
script_state, js_underlying_source, ASSERT_NO_EXCEPTION);
ASSERT_TRUE(stream);
- EXPECT_EQ(stream->IsLocked(script_state, ASSERT_NO_EXCEPTION),
- base::make_optional(false));
- EXPECT_EQ(stream->IsLocked(script_state, ASSERT_NO_EXCEPTION),
- base::make_optional(false));
- EXPECT_EQ(stream->IsDisturbed(script_state, ASSERT_NO_EXCEPTION),
- base::make_optional(false));
+ EXPECT_FALSE(stream->locked());
+ EXPECT_FALSE(stream->IsLocked());
+ EXPECT_FALSE(stream->IsDisturbed());
ReadableStreamDefaultReader* reader =
stream->getReader(script_state, ASSERT_NO_EXCEPTION);
- EXPECT_TRUE(stream->locked(script_state, ASSERT_NO_EXCEPTION));
- EXPECT_EQ(stream->IsLocked(script_state, ASSERT_NO_EXCEPTION),
- base::make_optional(true));
- EXPECT_EQ(stream->IsDisturbed(script_state, ASSERT_NO_EXCEPTION),
- base::make_optional(false));
+ EXPECT_TRUE(stream->locked());
+ EXPECT_TRUE(stream->IsLocked());
+ EXPECT_FALSE(stream->IsDisturbed());
reader->read(script_state, ASSERT_NO_EXCEPTION);
- EXPECT_EQ(stream->IsDisturbed(script_state, ASSERT_NO_EXCEPTION),
- base::make_optional(true));
+ EXPECT_TRUE(stream->IsDisturbed());
}
TEST_F(ReadableStreamTest, Cancel) {
@@ -272,29 +266,22 @@ TEST_F(ReadableStreamTest, Tee) {
ReadableStream* branch2 = nullptr;
stream->Tee(script_state, &branch1, &branch2, ASSERT_NO_EXCEPTION);
- EXPECT_EQ(stream->IsLocked(script_state, ASSERT_NO_EXCEPTION),
- base::make_optional(true));
- EXPECT_EQ(stream->IsDisturbed(script_state, ASSERT_NO_EXCEPTION),
- base::make_optional(false));
+ EXPECT_TRUE(stream->IsLocked());
+ EXPECT_FALSE(stream->IsDisturbed());
ASSERT_TRUE(branch1);
ASSERT_TRUE(branch2);
- EXPECT_EQ(branch1->IsLocked(script_state, ASSERT_NO_EXCEPTION),
- base::make_optional(false));
- EXPECT_EQ(branch1->IsDisturbed(script_state, ASSERT_NO_EXCEPTION),
- base::make_optional(false));
- EXPECT_EQ(branch2->IsLocked(script_state, ASSERT_NO_EXCEPTION),
- base::make_optional(false));
- EXPECT_EQ(branch2->IsDisturbed(script_state, ASSERT_NO_EXCEPTION),
- base::make_optional(false));
+ EXPECT_FALSE(branch1->IsLocked());
+ EXPECT_FALSE(branch1->IsDisturbed());
+ EXPECT_FALSE(branch2->IsLocked());
+ EXPECT_FALSE(branch2->IsDisturbed());
auto result1 = ReadAll(scope, branch1);
ASSERT_TRUE(result1);
EXPECT_EQ(*result1, "hello, bye");
- EXPECT_EQ(stream->IsDisturbed(script_state, ASSERT_NO_EXCEPTION),
- base::make_optional(true));
+ EXPECT_TRUE(stream->IsDisturbed());
auto result2 = ReadAll(scope, branch2);
ASSERT_TRUE(result2);
@@ -304,7 +291,6 @@ TEST_F(ReadableStreamTest, Tee) {
TEST_F(ReadableStreamTest, Close) {
V8TestingScope scope;
ScriptState* script_state = scope.GetScriptState();
- ExceptionState& exception_state = scope.GetExceptionState();
auto* underlying_source =
MakeGarbageCollected<TestUnderlyingSource>(script_state);
@@ -313,28 +299,21 @@ TEST_F(ReadableStreamTest, Close) {
ASSERT_TRUE(stream);
- EXPECT_EQ(stream->IsReadable(script_state, exception_state),
- base::make_optional(true));
- EXPECT_EQ(stream->IsClosed(script_state, exception_state),
- base::make_optional(false));
- EXPECT_EQ(stream->IsErrored(script_state, exception_state),
- base::make_optional(false));
+ EXPECT_TRUE(stream->IsReadable());
+ EXPECT_FALSE(stream->IsClosed());
+ EXPECT_FALSE(stream->IsErrored());
underlying_source->Close();
- EXPECT_EQ(stream->IsReadable(script_state, exception_state),
- base::make_optional(false));
- EXPECT_EQ(stream->IsClosed(script_state, exception_state),
- base::make_optional(true));
- EXPECT_EQ(stream->IsErrored(script_state, exception_state),
- base::make_optional(false));
+ EXPECT_FALSE(stream->IsReadable());
+ EXPECT_TRUE(stream->IsClosed());
+ EXPECT_FALSE(stream->IsErrored());
}
TEST_F(ReadableStreamTest, Error) {
V8TestingScope scope;
ScriptState* script_state = scope.GetScriptState();
v8::Isolate* isolate = scope.GetIsolate();
- ExceptionState& exception_state = scope.GetExceptionState();
auto* underlying_source =
MakeGarbageCollected<TestUnderlyingSource>(script_state);
@@ -343,21 +322,15 @@ TEST_F(ReadableStreamTest, Error) {
ASSERT_TRUE(stream);
- EXPECT_EQ(stream->IsReadable(script_state, exception_state),
- base::make_optional(true));
- EXPECT_EQ(stream->IsClosed(script_state, exception_state),
- base::make_optional(false));
- EXPECT_EQ(stream->IsErrored(script_state, exception_state),
- base::make_optional(false));
+ EXPECT_TRUE(stream->IsReadable());
+ EXPECT_FALSE(stream->IsClosed());
+ EXPECT_FALSE(stream->IsErrored());
underlying_source->Error(ScriptValue(isolate, v8::Undefined(isolate)));
- EXPECT_EQ(stream->IsReadable(script_state, exception_state),
- base::make_optional(false));
- EXPECT_EQ(stream->IsClosed(script_state, exception_state),
- base::make_optional(false));
- EXPECT_EQ(stream->IsErrored(script_state, exception_state),
- base::make_optional(true));
+ EXPECT_FALSE(stream->IsReadable());
+ EXPECT_FALSE(stream->IsClosed());
+ EXPECT_TRUE(stream->IsErrored());
}
TEST_F(ReadableStreamTest, LockAndDisturb) {
@@ -372,18 +345,14 @@ TEST_F(ReadableStreamTest, LockAndDisturb) {
ASSERT_TRUE(stream);
- EXPECT_EQ(stream->IsLocked(script_state, exception_state),
- base::make_optional(false));
- EXPECT_EQ(stream->IsDisturbed(script_state, exception_state),
- base::make_optional(false));
+ EXPECT_FALSE(stream->IsLocked());
+ EXPECT_FALSE(stream->IsDisturbed());
stream->LockAndDisturb(script_state, exception_state);
ASSERT_FALSE(exception_state.HadException());
- EXPECT_EQ(stream->IsLocked(script_state, exception_state),
- base::make_optional(true));
- EXPECT_EQ(stream->IsDisturbed(script_state, exception_state),
- base::make_optional(true));
+ EXPECT_TRUE(stream->IsLocked());
+ EXPECT_TRUE(stream->IsDisturbed());
}
TEST_F(ReadableStreamTest, Serialize) {
@@ -403,7 +372,7 @@ TEST_F(ReadableStreamTest, Serialize) {
MakeGarbageCollected<MessageChannel>(scope.GetExecutionContext());
stream->Serialize(script_state, channel->port1(), ASSERT_NO_EXCEPTION);
- EXPECT_TRUE(stream->IsLocked(script_state, ASSERT_NO_EXCEPTION));
+ EXPECT_TRUE(stream->IsLocked());
auto* transferred = ReadableStream::Deserialize(
script_state, channel->port2(), ASSERT_NO_EXCEPTION);
diff --git a/chromium/third_party/blink/renderer/core/streams/stream_algorithms.h b/chromium/third_party/blink/renderer/core/streams/stream_algorithms.h
index 839ccd74464..c56a8ff7137 100644
--- a/chromium/third_party/blink/renderer/core/streams/stream_algorithms.h
+++ b/chromium/third_party/blink/renderer/core/streams/stream_algorithms.h
@@ -30,7 +30,7 @@ class StrategySizeAlgorithm : public GarbageCollected<StrategySizeAlgorithm> {
v8::Local<v8::Value> chunk,
ExceptionState&) = 0;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
};
// Base class for start algorithms, ie. those that are derived from the start()
@@ -43,7 +43,7 @@ class StreamStartAlgorithm : public GarbageCollected<StreamStartAlgorithm> {
virtual v8::MaybeLocal<v8::Promise> Run(ScriptState*, ExceptionState&) = 0;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
};
// Base class for algorithms which take one or more arguments and return a
@@ -58,7 +58,7 @@ class StreamAlgorithm : public GarbageCollected<StreamAlgorithm> {
int argc,
v8::Local<v8::Value> argv[]) = 0;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/streams/stream_promise_resolver.cc b/chromium/third_party/blink/renderer/core/streams/stream_promise_resolver.cc
index 98d0ff08ee6..eeb38184306 100644
--- a/chromium/third_party/blink/renderer/core/streams/stream_promise_resolver.cc
+++ b/chromium/third_party/blink/renderer/core/streams/stream_promise_resolver.cc
@@ -93,7 +93,7 @@ v8::Promise::PromiseState StreamPromiseResolver::State(
return V8Promise(isolate)->State();
}
-void StreamPromiseResolver::Trace(Visitor* visitor) {
+void StreamPromiseResolver::Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
}
diff --git a/chromium/third_party/blink/renderer/core/streams/stream_promise_resolver.h b/chromium/third_party/blink/renderer/core/streams/stream_promise_resolver.h
index 500ecd7b211..b4528cf63b9 100644
--- a/chromium/third_party/blink/renderer/core/streams/stream_promise_resolver.h
+++ b/chromium/third_party/blink/renderer/core/streams/stream_promise_resolver.h
@@ -75,7 +75,7 @@ class CORE_EXPORT StreamPromiseResolver final
// Returns true if the the promise is not pending.
bool IsSettled() const { return is_settled_; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
TraceWrapperV8Reference<v8::Promise::Resolver> resolver_;
diff --git a/chromium/third_party/blink/renderer/core/streams/stream_promise_resolver_test.cc b/chromium/third_party/blink/renderer/core/streams/stream_promise_resolver_test.cc
index 6d6293997ff..9b4d9b9f582 100644
--- a/chromium/third_party/blink/renderer/core/streams/stream_promise_resolver_test.cc
+++ b/chromium/third_party/blink/renderer/core/streams/stream_promise_resolver_test.cc
@@ -105,7 +105,7 @@ TEST(StreamPromiseResolverTest, ResolveDoesNothingInsideResolve) {
ThenGetter(ScriptState* script_state, StreamPromiseResolver* promise)
: ScriptFunction(script_state), promise_(promise) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(promise_);
ScriptFunction::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/streams/transferable_streams.cc b/chromium/third_party/blink/renderer/core/streams/transferable_streams.cc
index ee7dbc81708..00cfc362ae3 100644
--- a/chromium/third_party/blink/renderer/core/streams/transferable_streams.cc
+++ b/chromium/third_party/blink/renderer/core/streams/transferable_streams.cc
@@ -337,7 +337,7 @@ class CrossRealmTransformStream
// event is fired on the message port. It should error the stream.
virtual void HandleError(v8::Local<v8::Value> error) = 0;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
};
// Handles MessageEvents from the MessagePort.
@@ -377,7 +377,7 @@ class CrossRealmTransformMessageListener final : public NativeEventListener {
target_->HandleMessage(static_cast<MessageType>(type_value), value);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(target_);
NativeEventListener::Trace(visitor);
}
@@ -412,7 +412,7 @@ class CrossRealmTransformErrorListener final : public NativeEventListener {
target_->HandleError(error_value);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(target_);
NativeEventListener::Trace(visitor);
}
@@ -438,7 +438,7 @@ class CrossRealmTransformWritable final : public CrossRealmTransformStream {
void HandleMessage(MessageType type, v8::Local<v8::Value> value) override;
void HandleError(v8::Local<v8::Value> error) override;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(script_state_);
visitor->Trace(message_port_);
visitor->Trace(backpressure_promise_);
@@ -482,7 +482,7 @@ class CrossRealmTransformWritable::WriteAlgorithm final
MakeGarbageCollected<DoWriteOnResolve>(script_state, chunk, this));
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(writable_);
StreamAlgorithm::Trace(visitor);
}
@@ -504,7 +504,7 @@ class CrossRealmTransformWritable::WriteAlgorithm final
chunk_.NewLocal(script_state->GetIsolate()));
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(chunk_);
visitor->Trace(target_);
PromiseHandlerWithValue::Trace(visitor);
@@ -571,7 +571,7 @@ class CrossRealmTransformWritable::CloseAlgorithm final
return PromiseResolveWithUndefined(script_state);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(writable_);
StreamAlgorithm::Trace(visitor);
}
@@ -605,7 +605,7 @@ class CrossRealmTransformWritable::AbortAlgorithm final
return PromiseResolveWithUndefined(script_state);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(writable_);
StreamAlgorithm::Trace(visitor);
}
@@ -693,7 +693,7 @@ class CrossRealmTransformReadable final : public CrossRealmTransformStream {
void HandleMessage(MessageType type, v8::Local<v8::Value> value) override;
void HandleError(v8::Local<v8::Value> error) override;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(script_state_);
visitor->Trace(message_port_);
visitor->Trace(backpressure_promise_);
@@ -739,7 +739,7 @@ class CrossRealmTransformReadable::PullAlgorithm final
return readable_->backpressure_promise_->V8Promise(isolate);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(readable_);
StreamAlgorithm::Trace(visitor);
}
@@ -776,7 +776,7 @@ class CrossRealmTransformReadable::CancelAlgorithm final
return PromiseResolveWithUndefined(script_state);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(readable_);
StreamAlgorithm::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/streams/transform_stream.cc b/chromium/third_party/blink/renderer/core/streams/transform_stream.cc
index 0c6edb5295a..bd3f3061642 100644
--- a/chromium/third_party/blink/renderer/core/streams/transform_stream.cc
+++ b/chromium/third_party/blink/renderer/core/streams/transform_stream.cc
@@ -63,7 +63,7 @@ class TransformStream::FlushAlgorithm final : public StreamAlgorithm {
controller_ = controller;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(transformer_);
visitor->Trace(controller_);
StreamAlgorithm::Trace(visitor);
@@ -109,7 +109,7 @@ class TransformStream::TransformAlgorithm final : public StreamAlgorithm {
controller_ = controller;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(transformer_);
visitor->Trace(controller_);
StreamAlgorithm::Trace(visitor);
@@ -262,7 +262,7 @@ TransformStream::TransformStream(ReadableStream* readable,
WritableStream* writable)
: readable_(readable), writable_(writable) {}
-void TransformStream::Trace(Visitor* visitor) {
+void TransformStream::Trace(Visitor* visitor) const {
visitor->Trace(backpressure_change_promise_);
visitor->Trace(readable_);
visitor->Trace(transform_stream_controller_);
@@ -284,7 +284,7 @@ class TransformStream::ReturnStartPromiseAlgorithm final
return start_promise_->V8Promise(script_state->GetIsolate());
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(start_promise_);
StreamStartAlgorithm::Trace(visitor);
}
@@ -363,7 +363,7 @@ class TransformStream::DefaultSinkWriteAlgorithm final
chunk_.NewLocal(isolate));
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
visitor->Trace(chunk_);
ScriptFunction::Trace(visitor);
@@ -387,7 +387,7 @@ class TransformStream::DefaultSinkWriteAlgorithm final
script_state, controller, chunk);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
StreamAlgorithm::Trace(visitor);
}
@@ -416,7 +416,7 @@ class TransformStream::DefaultSinkAbortAlgorithm final
return PromiseResolveWithUndefined(script_state);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
StreamAlgorithm::Trace(visitor);
}
@@ -484,7 +484,7 @@ class TransformStream::DefaultSinkCloseAlgorithm final
return v8::Undefined(GetScriptState()->GetIsolate());
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(readable_);
PromiseHandlerWithValue::Trace(visitor);
}
@@ -510,7 +510,7 @@ class TransformStream::DefaultSinkCloseAlgorithm final
stream_->readable_->GetStoredError(GetScriptState()->GetIsolate()));
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
PromiseHandlerWithValue::Trace(visitor);
}
@@ -526,7 +526,7 @@ class TransformStream::DefaultSinkCloseAlgorithm final
MakeGarbageCollected<RejectFunction>(script_state, stream_));
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
StreamAlgorithm::Trace(visitor);
}
@@ -561,7 +561,7 @@ class TransformStream::DefaultSourcePullAlgorithm final
script_state->GetIsolate());
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
StreamAlgorithm::Trace(visitor);
}
@@ -593,7 +593,7 @@ class TransformStream::DefaultSourceCancelAlgorithm final
return PromiseResolveWithUndefined(script_state);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
StreamAlgorithm::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/streams/transform_stream.h b/chromium/third_party/blink/renderer/core/streams/transform_stream.h
index 9210c3753e6..1db4d3c6565 100644
--- a/chromium/third_party/blink/renderer/core/streams/transform_stream.h
+++ b/chromium/third_party/blink/renderer/core/streams/transform_stream.h
@@ -79,7 +79,7 @@ class CORE_EXPORT TransformStream final : public ScriptWrappable {
ReadableStream* Readable() const { return readable_; }
WritableStream* Writable() const { return writable_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class TransformStreamDefaultController;
diff --git a/chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc b/chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc
index 1949264041e..fc1749b6004 100644
--- a/chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc
+++ b/chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc
@@ -78,7 +78,7 @@ void TransformStreamDefaultController::terminate(ScriptState* script_state) {
Terminate(script_state, this);
}
-void TransformStreamDefaultController::Trace(Visitor* visitor) {
+void TransformStreamDefaultController::Trace(Visitor* visitor) const {
visitor->Trace(controlled_transform_stream_);
visitor->Trace(flush_algorithm_);
visitor->Trace(transform_algorithm_);
@@ -121,7 +121,7 @@ class TransformStreamDefaultController::DefaultTransformAlgorithm final
return PromiseResolveWithUndefined(script_state);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(controller_);
StreamAlgorithm::Trace(visitor);
}
@@ -334,7 +334,7 @@ v8::Local<v8::Promise> TransformStreamDefaultController::PerformTransform(
return PromiseReject(GetScriptState(), r);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
PromiseHandlerWithValue::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.h b/chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.h
index 39f5b58537a..f4d188b1449 100644
--- a/chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.h
+++ b/chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.h
@@ -39,7 +39,7 @@ class CORE_EXPORT TransformStreamDefaultController : public ScriptWrappable {
// https://streams.spec.whatwg.org/#ts-default-controller-terminate
void terminate(ScriptState*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class TransformStream;
diff --git a/chromium/third_party/blink/renderer/core/streams/transform_stream_test.cc b/chromium/third_party/blink/renderer/core/streams/transform_stream_test.cc
index 13debfef60a..d8583a4b058 100644
--- a/chromium/third_party/blink/renderer/core/streams/transform_stream_test.cc
+++ b/chromium/third_party/blink/renderer/core/streams/transform_stream_test.cc
@@ -102,7 +102,7 @@ class TestTransformer : public TransformStreamTransformer {
ScriptState* GetScriptState() override { return script_state_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(script_state_);
TransformStreamTransformer::Trace(visitor);
}
@@ -140,7 +140,7 @@ class MockTransformStreamTransformer : public TransformStreamTransformer {
ScriptState* GetScriptState() override { return script_state_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(script_state_);
TransformStreamTransformer::Trace(visitor);
}
@@ -418,7 +418,7 @@ TEST_F(TransformStreamTest, WaitInTransform) {
void ResolvePromise() { transform_promise_resolver_->Resolve(); }
bool FlushCalled() const { return flush_called_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(transform_promise_resolver_);
TestTransformer::Trace(visitor);
}
@@ -478,7 +478,7 @@ TEST_F(TransformStreamTest, WaitInFlush) {
void ResolvePromise() { flush_promise_resolver_->Resolve(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(flush_promise_resolver_);
TestTransformer::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/streams/transform_stream_transformer.h b/chromium/third_party/blink/renderer/core/streams/transform_stream_transformer.h
index a7f0090cc85..48ac197c709 100644
--- a/chromium/third_party/blink/renderer/core/streams/transform_stream_transformer.h
+++ b/chromium/third_party/blink/renderer/core/streams/transform_stream_transformer.h
@@ -38,7 +38,7 @@ class CORE_EXPORT TransformStreamTransformer
// Returns the ScriptState associated with this Transformer.
virtual ScriptState* GetScriptState() = 0;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
private:
DISALLOW_COPY_AND_ASSIGN(TransformStreamTransformer);
diff --git a/chromium/third_party/blink/renderer/core/streams/underlying_sink_base.h b/chromium/third_party/blink/renderer/core/streams/underlying_sink_base.h
index 5e2a020fa2e..3b07d87f064 100644
--- a/chromium/third_party/blink/renderer/core/streams/underlying_sink_base.h
+++ b/chromium/third_party/blink/renderer/core/streams/underlying_sink_base.h
@@ -52,7 +52,7 @@ class CORE_EXPORT UnderlyingSinkBase : public ScriptWrappable {
return write(script_state, chunk, controller_, exception_state);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(controller_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/streams/underlying_source_base.cc b/chromium/third_party/blink/renderer/core/streams/underlying_source_base.cc
index f966b055246..3163c3f63e9 100644
--- a/chromium/third_party/blink/renderer/core/streams/underlying_source_base.cc
+++ b/chromium/third_party/blink/renderer/core/streams/underlying_source_base.cc
@@ -63,7 +63,7 @@ void UnderlyingSourceBase::ContextDestroyed() {
}
}
-void UnderlyingSourceBase::Trace(Visitor* visitor) {
+void UnderlyingSourceBase::Trace(Visitor* visitor) const {
visitor->Trace(controller_);
ScriptWrappable::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/streams/underlying_source_base.h b/chromium/third_party/blink/renderer/core/streams/underlying_source_base.h
index a94d9fc5523..a09c7f27f9d 100644
--- a/chromium/third_party/blink/renderer/core/streams/underlying_source_base.h
+++ b/chromium/third_party/blink/renderer/core/streams/underlying_source_base.h
@@ -27,7 +27,7 @@ class CORE_EXPORT UnderlyingSourceBase
USING_GARBAGE_COLLECTED_MIXIN(UnderlyingSourceBase);
public:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
~UnderlyingSourceBase() override = default;
ScriptPromise startWrapper(ScriptState*, ScriptValue stream);
diff --git a/chromium/third_party/blink/renderer/core/streams/writable_stream.cc b/chromium/third_party/blink/renderer/core/streams/writable_stream.cc
index 8446b4a9e33..5d63e8f4697 100644
--- a/chromium/third_party/blink/renderer/core/streams/writable_stream.cc
+++ b/chromium/third_party/blink/renderer/core/streams/writable_stream.cc
@@ -52,7 +52,7 @@ class WritableStream::PendingAbortRequest final
bool WasAlreadyErroring() { return was_already_erroring_; }
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(promise_);
visitor->Trace(reason_);
}
@@ -537,7 +537,7 @@ void WritableStream::FinishErroring(ScriptState* script_state,
RejectCloseAndClosedPromiseIfNeeded(GetScriptState(), stream_);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
visitor->Trace(promise_);
PromiseHandler::Trace(visitor);
@@ -565,7 +565,7 @@ void WritableStream::FinishErroring(ScriptState* script_state,
RejectCloseAndClosedPromiseIfNeeded(GetScriptState(), stream_);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
visitor->Trace(promise_);
PromiseHandler::Trace(visitor);
@@ -819,7 +819,7 @@ v8::Local<v8::Value> WritableStream::CreateCannotActionOnStateStreamException(
CreateCannotActionOnStateStreamMessage(isolate, action, state_name));
}
-void WritableStream::Trace(Visitor* visitor) {
+void WritableStream::Trace(Visitor* visitor) const {
visitor->Trace(close_request_);
visitor->Trace(in_flight_write_request_);
visitor->Trace(in_flight_close_request_);
diff --git a/chromium/third_party/blink/renderer/core/streams/writable_stream.h b/chromium/third_party/blink/renderer/core/streams/writable_stream.h
index 99775e5fa1e..c6e012bdb9a 100644
--- a/chromium/third_party/blink/renderer/core/streams/writable_stream.h
+++ b/chromium/third_party/blink/renderer/core/streams/writable_stream.h
@@ -212,7 +212,7 @@ class CORE_EXPORT WritableStream : public ScriptWrappable {
const char* action,
State);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
// Used when creating a stream from JavaScript. Called from Create().
diff --git a/chromium/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc b/chromium/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc
index 3d6680a03d1..d366fe47be4 100644
--- a/chromium/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc
+++ b/chromium/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc
@@ -166,7 +166,7 @@ void WritableStreamDefaultController::SetUp(
controller);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
PromiseHandler::Trace(visitor);
}
@@ -195,7 +195,7 @@ void WritableStreamDefaultController::SetUp(
WritableStream::DealWithRejection(GetScriptState(), stream_, r);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
PromiseHandler::Trace(visitor);
}
@@ -392,7 +392,7 @@ void WritableStreamDefaultController::ErrorIfNeeded(
}
}
-void WritableStreamDefaultController::Trace(Visitor* visitor) {
+void WritableStreamDefaultController::Trace(Visitor* visitor) const {
visitor->Trace(abort_algorithm_);
visitor->Trace(close_algorithm_);
visitor->Trace(controlled_writable_stream_);
@@ -511,7 +511,7 @@ void WritableStreamDefaultController::ProcessClose(
WritableStream::FinishInFlightClose(GetScriptState(), stream_);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
PromiseHandler::Trace(visitor);
}
@@ -533,7 +533,7 @@ void WritableStreamDefaultController::ProcessClose(
reason);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
PromiseHandler::Trace(visitor);
}
@@ -608,7 +608,7 @@ void WritableStreamDefaultController::ProcessWrite(
controller_);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
visitor->Trace(controller_);
PromiseHandler::Trace(visitor);
@@ -643,7 +643,7 @@ void WritableStreamDefaultController::ProcessWrite(
reason);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(stream_);
visitor->Trace(controller_);
PromiseHandler::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/streams/writable_stream_default_controller.h b/chromium/third_party/blink/renderer/core/streams/writable_stream_default_controller.h
index 82a702badf4..191a06daa48 100644
--- a/chromium/third_party/blink/renderer/core/streams/writable_stream_default_controller.h
+++ b/chromium/third_party/blink/renderer/core/streams/writable_stream_default_controller.h
@@ -107,7 +107,7 @@ class CORE_EXPORT WritableStreamDefaultController final
WritableStreamDefaultController*,
v8::Local<v8::Value> error);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// https://streams.spec.whatwg.org/#writable-stream-default-controller-clear-algorithms
diff --git a/chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc b/chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc
index d6adf54e57d..940f5a964ba 100644
--- a/chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc
+++ b/chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc
@@ -472,7 +472,7 @@ void WritableStreamDefaultWriter::SetReadyPromise(
ready_promise_ = ready_promise;
}
-void WritableStreamDefaultWriter::Trace(Visitor* visitor) {
+void WritableStreamDefaultWriter::Trace(Visitor* visitor) const {
visitor->Trace(closed_promise_);
visitor->Trace(owner_writable_stream_);
visitor->Trace(ready_promise_);
diff --git a/chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.h b/chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.h
index cb8fc99f655..f81f40b9326 100644
--- a/chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.h
+++ b/chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.h
@@ -106,7 +106,7 @@ class CORE_EXPORT WritableStreamDefaultWriter final : public ScriptWrappable {
void SetReadyPromise(StreamPromiseResolver*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// https://streams.spec.whatwg.org/#writable-stream-default-writer-abort
diff --git a/chromium/third_party/blink/renderer/core/style/BUILD.gn b/chromium/third_party/blink/renderer/core/style/BUILD.gn
index 61caa6d6da5..9c8276c7a62 100644
--- a/chromium/third_party/blink/renderer/core/style/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/style/BUILD.gn
@@ -40,7 +40,6 @@ blink_core_sources("rendering") {
"filter_operation.h",
"filter_operations.cc",
"filter_operations.h",
- "gap_length.h",
"grid_area.h",
"grid_length.h",
"grid_position.h",
@@ -81,10 +80,13 @@ blink_core_sources("rendering") {
"style_inherited_variables.h",
"style_initial_data.cc",
"style_initial_data.h",
+ "style_name.h",
+ "style_name_or_keyword.h",
"style_non_inherited_variables.h",
"style_offset_rotation.h",
"style_path.cc",
"style_path.h",
+ "style_pending_image.cc",
"style_pending_image.h",
"style_ray.cc",
"style_ray.h",
@@ -106,3 +108,16 @@ blink_core_sources("svg_style") {
"svg_computed_style_defs.h",
]
}
+
+blink_core_tests("unit_tests") {
+ sources = [
+ "border_value_test.cc",
+ "computed_style_test.cc",
+ "filter_operations_test.cc",
+ "style_difference_test.cc",
+ "style_name_or_keyword_test.cc",
+ "style_name_test.cc",
+ "style_variables_test.cc",
+ "svg_computed_style_test.cc",
+ ]
+}
diff --git a/chromium/third_party/blink/renderer/core/style/applied_text_decoration.cc b/chromium/third_party/blink/renderer/core/style/applied_text_decoration.cc
index 0d7e2dd9fb6..81bf42fe900 100644
--- a/chromium/third_party/blink/renderer/core/style/applied_text_decoration.cc
+++ b/chromium/third_party/blink/renderer/core/style/applied_text_decoration.cc
@@ -8,13 +8,16 @@ namespace blink {
AppliedTextDecoration::AppliedTextDecoration(TextDecoration line,
ETextDecorationStyle style,
- Color color)
+ Color color,
+ TextDecorationThickness thickness)
: lines_(static_cast<unsigned>(line)),
style_(static_cast<unsigned>(style)),
- color_(color) {}
+ color_(color),
+ thickness_(thickness) {}
bool AppliedTextDecoration::operator==(const AppliedTextDecoration& o) const {
- return color_ == o.color_ && lines_ == o.lines_ && style_ == o.style_;
+ return color_ == o.color_ && lines_ == o.lines_ && style_ == o.style_ &&
+ thickness_ == o.thickness_;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/style/applied_text_decoration.h b/chromium/third_party/blink/renderer/core/style/applied_text_decoration.h
index 5d8855aa661..29a6f8a71a7 100644
--- a/chromium/third_party/blink/renderer/core/style/applied_text_decoration.h
+++ b/chromium/third_party/blink/renderer/core/style/applied_text_decoration.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_APPLIED_TEXT_DECORATION_H_
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
+#include "third_party/blink/renderer/core/style/text_decoration_thickness.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -15,7 +16,10 @@ class AppliedTextDecoration {
DISALLOW_NEW();
public:
- AppliedTextDecoration(TextDecoration, ETextDecorationStyle, Color);
+ AppliedTextDecoration(TextDecoration,
+ ETextDecorationStyle,
+ Color,
+ TextDecorationThickness);
TextDecoration Lines() const { return static_cast<TextDecoration>(lines_); }
ETextDecorationStyle Style() const {
@@ -24,6 +28,8 @@ class AppliedTextDecoration {
Color GetColor() const { return color_; }
void SetColor(Color color) { color_ = color; }
+ TextDecorationThickness Thickness() const { return thickness_; }
+
bool operator==(const AppliedTextDecoration&) const;
bool operator!=(const AppliedTextDecoration& o) const {
return !(*this == o);
@@ -33,6 +39,7 @@ class AppliedTextDecoration {
unsigned lines_ : kTextDecorationBits;
unsigned style_ : 3; // ETextDecorationStyle
Color color_;
+ TextDecorationThickness thickness_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/style/border_value.h b/chromium/third_party/blink/renderer/core/style/border_value.h
index af4aa75c443..49f6cb153ec 100644
--- a/chromium/third_party/blink/renderer/core/style/border_value.h
+++ b/chromium/third_party/blink/renderer/core/style/border_value.h
@@ -47,10 +47,7 @@ class BorderValue {
friend class ComputedStyle;
public:
- BorderValue()
- : color_(0),
- color_is_current_color_(true),
- style_(static_cast<unsigned>(EBorderStyle::kNone)) {
+ BorderValue() : style_(static_cast<unsigned>(EBorderStyle::kNone)) {
SetWidth(3);
}
@@ -60,13 +57,8 @@ class BorderValue {
SetWidth(width);
}
- bool IsTransparent() const {
- return !color_is_current_color_ && !color_.Alpha();
- }
-
bool operator==(const BorderValue& o) const {
- return width_ == o.width_ && style_ == o.style_ && color_ == o.color_ &&
- color_is_current_color_ == o.color_is_current_color_;
+ return width_ == o.width_ && style_ == o.style_ && color_ == o.color_;
}
// The default width is 3px, but if the style is none we compute a value of 0
@@ -83,15 +75,9 @@ class BorderValue {
bool operator!=(const BorderValue& o) const { return !(*this == o); }
- void SetColor(const StyleColor& color) {
- color_ = color.Resolve(Color());
- color_is_current_color_ = color.IsCurrentColor();
- }
+ void SetColor(const StyleColor& color) { color_ = color; }
- StyleColor GetColor() const {
- return color_is_current_color_ ? StyleColor::CurrentColor()
- : StyleColor(color_);
- }
+ StyleColor GetColor() const { return color_; }
float Width() const {
return static_cast<float>(width_) / kBorderWidthDenominator;
@@ -107,11 +93,6 @@ class BorderValue {
EBorderStyle Style() const { return static_cast<EBorderStyle>(style_); }
void SetStyle(EBorderStyle style) { style_ = static_cast<unsigned>(style); }
- bool ColorIsCurrentColor() const { return color_is_current_color_; }
- void SetColorIsCurrentColor(bool color_is_current_color) {
- color_is_current_color_ = static_cast<unsigned>(color_is_current_color);
- }
-
protected:
static unsigned WidthToFixedPoint(float width) {
DCHECK_GE(width, 0);
@@ -122,8 +103,7 @@ class BorderValue {
return static_cast<unsigned>(width * kBorderWidthDenominator);
}
- Color color_;
- unsigned color_is_current_color_ : 1;
+ StyleColor color_;
unsigned width_ : 26; // Fixed point width
unsigned style_ : 4; // EBorderStyle
diff --git a/chromium/third_party/blink/renderer/core/style/border_value_test.cc b/chromium/third_party/blink/renderer/core/style/border_value_test.cc
index f4095851f85..7bbf92798e5 100644
--- a/chromium/third_party/blink/renderer/core/style/border_value_test.cc
+++ b/chromium/third_party/blink/renderer/core/style/border_value_test.cc
@@ -54,14 +54,4 @@ TEST(BorderValueTest, BorderValueWidth) {
EXPECT_EQ(kMaxForBorderWidth, border.Width());
}
-TEST(BorderValueTest, BorderValueColor) {
- BorderValue border1 =
- BorderValue(EBorderStyle::kSolid, StyleColor::CurrentColor(), 5);
- EXPECT_EQ(border1.ColorIsCurrentColor(), true);
-
- BorderValue border2 =
- BorderValue(EBorderStyle::kSolid, StyleColor(Color(128, 0, 0)), 5);
- EXPECT_EQ(border2.ColorIsCurrentColor(), false);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/style/cached_ua_style.cc b/chromium/third_party/blink/renderer/core/style/cached_ua_style.cc
index 24635bca223..fc43a506a75 100644
--- a/chromium/third_party/blink/renderer/core/style/cached_ua_style.cc
+++ b/chromium/third_party/blink/renderer/core/style/cached_ua_style.cc
@@ -12,15 +12,7 @@ bool CachedUAStyle::BorderColorEquals(const ComputedStyle& other) const {
return (border_left_color == other.BorderLeftColorInternal() &&
border_right_color == other.BorderRightColorInternal() &&
border_top_color == other.BorderTopColorInternal() &&
- border_bottom_color == other.BorderBottomColorInternal()) &&
- (border_left_color_is_current_color ==
- other.BorderLeftColorIsCurrentColor() &&
- border_right_color_is_current_color ==
- other.BorderRightColorIsCurrentColor() &&
- border_top_color_is_current_color ==
- other.BorderTopColorIsCurrentColor() &&
- border_bottom_color_is_current_color ==
- other.BorderBottomColorIsCurrentColor());
+ border_bottom_color == other.BorderBottomColorInternal());
}
bool CachedUAStyle::BorderWidthEquals(const ComputedStyle& other) const {
@@ -54,13 +46,6 @@ CachedUAStyle::CachedUAStyle(const ComputedStyle* style)
border_right_color(style->BorderRightColorInternal()),
border_top_color(style->BorderTopColorInternal()),
border_bottom_color(style->BorderBottomColorInternal()),
- border_left_color_is_current_color(
- style->BorderLeftColorIsCurrentColor()),
- border_right_color_is_current_color(
- style->BorderRightColorIsCurrentColor()),
- border_top_color_is_current_color(style->BorderTopColorIsCurrentColor()),
- border_bottom_color_is_current_color(
- style->BorderBottomColorIsCurrentColor()),
border_left_style(static_cast<unsigned>(style->BorderLeftStyle())),
border_right_style(static_cast<unsigned>(style->BorderRightStyle())),
border_top_style(static_cast<unsigned>(style->BorderTopStyle())),
diff --git a/chromium/third_party/blink/renderer/core/style/cached_ua_style.h b/chromium/third_party/blink/renderer/core/style/cached_ua_style.h
index 9bd97ccbcf6..66e2f1eb3e9 100644
--- a/chromium/third_party/blink/renderer/core/style/cached_ua_style.h
+++ b/chromium/third_party/blink/renderer/core/style/cached_ua_style.h
@@ -58,14 +58,10 @@ class CachedUAStyle {
LengthSize top_right_;
LengthSize bottom_left_;
LengthSize bottom_right_;
- Color border_left_color;
- Color border_right_color;
- Color border_top_color;
- Color border_bottom_color;
- bool border_left_color_is_current_color;
- bool border_right_color_is_current_color;
- bool border_top_color_is_current_color;
- bool border_bottom_color_is_current_color;
+ StyleColor border_left_color;
+ StyleColor border_right_color;
+ StyleColor border_top_color;
+ StyleColor border_bottom_color;
unsigned border_left_style : 4; // EBorderStyle
unsigned border_right_style : 4; // EBorderStyle
unsigned border_top_style : 4; // EBorderStyle
diff --git a/chromium/third_party/blink/renderer/core/style/computed_style.cc b/chromium/third_party/blink/renderer/core/style/computed_style.cc
index d64f2c49712..e8148b3400d 100644
--- a/chromium/third_party/blink/renderer/core/style/computed_style.cc
+++ b/chromium/third_party/blink/renderer/core/style/computed_style.cc
@@ -82,7 +82,7 @@
namespace blink {
struct SameSizeAsBorderValue {
- RGBA32 color_;
+ StyleColor color_;
unsigned bitfield_;
};
@@ -288,7 +288,7 @@ ComputedStyle::ComputeDifferenceIgnoringInheritedFirstLineStyle(
old_style.JustifyItems() != new_style.JustifyItems())
return Difference::kInherited;
bool non_inherited_equal = old_style.NonInheritedEqual(new_style);
- if (!non_inherited_equal && old_style.HasExplicitlyInheritedProperties()) {
+ if (!non_inherited_equal && old_style.ChildHasExplicitInheritance()) {
return Difference::kInherited;
}
bool variables_independent = RuntimeEnabledFeatures::CSSCascadeEnabled() &&
@@ -1050,35 +1050,33 @@ static bool HasPropertyThatCreatesStackingContext(
return false;
}
-void ComputedStyle::UpdateIsStackingContext(bool is_document_element,
- bool is_in_top_layer,
- bool is_svg_stacking) {
- if (IsStackingContext())
+void ComputedStyle::UpdateIsStackingContextWithoutContainment(
+ bool is_document_element,
+ bool is_in_top_layer,
+ bool is_svg_stacking) {
+ if (IsStackingContextWithoutContainment())
return;
// Force a stacking context for transform-style: preserve-3d. This happens
// even if preserves-3d is ignored due to a 'grouping property' being present
- // which requires flattening. See ComputedStyle::UsedTransformStyle3D() and
- // ComputedStyle::HasGroupingProperty().
+ // which requires flattening. See:
+ // ComputedStyle::HasGroupingPropertyForUsedTransformStyle3D().
// This is legacy behavior that is left ambiguous in the official specs.
- // See https://crbug.com/663650 for more details."
+ // See https://crbug.com/663650 for more details.
if (TransformStyle3D() == ETransformStyle3D::kPreserve3d) {
- SetIsStackingContext(true);
+ SetIsStackingContextWithoutContainment(true);
return;
}
if (is_document_element || is_in_top_layer || is_svg_stacking ||
- StyleType() == kPseudoIdBackdrop || HasOpacity() ||
- HasTransformRelatedProperty() || HasMask() || ClipPath() ||
- BoxReflect() || HasFilterInducingProperty() || HasBackdropFilter() ||
- HasBlendMode() || HasIsolation() || HasViewportConstrainedPosition() ||
- GetPosition() == EPosition::kSticky ||
+ StyleType() == kPseudoIdBackdrop || HasTransformRelatedProperty() ||
+ HasStackingGroupingProperty(BoxReflect()) ||
+ HasViewportConstrainedPosition() || GetPosition() == EPosition::kSticky ||
HasPropertyThatCreatesStackingContext(WillChangeProperties()) ||
/* TODO(882625): This becomes unnecessary when will-change correctly takes
into account active animations. */
- ShouldCompositeForCurrentAnimations() || ContainsPaint() ||
- ContainsLayout()) {
- SetIsStackingContext(true);
+ ShouldCompositeForCurrentAnimations()) {
+ SetIsStackingContextWithoutContainment(true);
}
}
@@ -1440,15 +1438,15 @@ FloatRoundedRect ComputedStyle::GetRoundedInnerBorderFor(
bool horizontal = IsHorizontalWritingMode();
int left_width = (!horizontal || include_logical_left_edge)
- ? roundf(BorderLeftWidth())
+ ? floorf(BorderLeftWidth())
: 0;
int right_width = (!horizontal || include_logical_right_edge)
- ? roundf(BorderRightWidth())
+ ? floorf(BorderRightWidth())
: 0;
int top_width =
- (horizontal || include_logical_left_edge) ? roundf(BorderTopWidth()) : 0;
+ (horizontal || include_logical_left_edge) ? floorf(BorderTopWidth()) : 0;
int bottom_width = (horizontal || include_logical_right_edge)
- ? roundf(BorderBottomWidth())
+ ? floorf(BorderBottomWidth())
: 0;
return GetRoundedInnerBorderFor(
@@ -1544,6 +1542,15 @@ void ComputedStyle::ClearResetDirectives() {
it->value.ClearReset();
}
+void ComputedStyle::ClearSetDirectives() {
+ if (!GetCounterDirectives())
+ return;
+
+ auto& map = AccessCounterDirectives();
+ for (auto& value_pair : map)
+ value_pair.value.ClearSet();
+}
+
AtomicString ComputedStyle::LocaleForLineBreakIterator() const {
LineBreakIteratorMode mode = LineBreakIteratorMode::kDefault;
switch (GetLineBreak()) {
@@ -1854,7 +1861,8 @@ const Vector<AppliedTextDecoration>& ComputedStyle::AppliedTextDecorations()
Vector<AppliedTextDecoration>, underline,
(1, AppliedTextDecoration(
TextDecoration::kUnderline, ETextDecorationStyle::kSolid,
- VisitedDependentColor(GetCSSPropertyTextDecorationColor()))));
+ VisitedDependentColor(GetCSSPropertyTextDecorationColor()),
+ TextDecorationThickness())));
// Since we only have one of these in memory, just update the color before
// returning.
underline.at(0).SetColor(
@@ -2151,7 +2159,7 @@ void ComputedStyle::ApplyTextDecorations(
SetHasSimpleUnderlineInternal(false);
AddAppliedTextDecoration(AppliedTextDecoration(
TextDecoration::kUnderline, ETextDecorationStyle::kSolid,
- parent_text_decoration_color));
+ parent_text_decoration_color, TextDecorationThickness()));
}
if (override_existing_colors && AppliedTextDecorationsInternal())
OverrideTextDecorationColors(current_text_decoration_color);
@@ -2164,14 +2172,16 @@ void ComputedStyle::ApplyTextDecorations(
ETextDecorationStyle decoration_style = TextDecorationStyle();
bool is_simple_underline = decoration_lines == TextDecoration::kUnderline &&
decoration_style == ETextDecorationStyle::kSolid &&
- TextDecorationColor().IsCurrentColor();
+ TextDecorationColor().IsCurrentColor() &&
+ TextUnderlineOffset().IsAuto();
if (is_simple_underline && !AppliedTextDecorationsInternal()) {
SetHasSimpleUnderlineInternal(true);
return;
}
AddAppliedTextDecoration(AppliedTextDecoration(
- decoration_lines, decoration_style, current_text_decoration_color));
+ decoration_lines, decoration_style, current_text_decoration_color,
+ GetTextDecorationThickness()));
}
void ComputedStyle::ClearAppliedTextDecorations() {
@@ -2199,8 +2209,6 @@ void ComputedStyle::ClearMultiCol() {
LayoutUnit(ComputedStyleInitialValues::InitialColumnRuleWidth()));
SetColumnRuleColorInternal(
ComputedStyleInitialValues::InitialColumnRuleColor());
- SetColumnRuleColorIsCurrentColor(
- ComputedStyleInitialValues::InitialColumnRuleColorIsCurrentColor());
SetInternalVisitedColumnRuleColorInternal(
ComputedStyleInitialValues::InitialInternalVisitedColumnRuleColor());
SetColumnCountInternal(ComputedStyleInitialValues::InitialColumnCount());
@@ -2433,8 +2441,8 @@ void ComputedStyle::GetBorderEdgeInfo(BorderEdge edges[],
}
void ComputedStyle::CopyChildDependentFlagsFrom(const ComputedStyle& other) {
- if (other.HasExplicitlyInheritedProperties())
- SetHasExplicitlyInheritedProperties();
+ if (other.ChildHasExplicitInheritance())
+ SetChildHasExplicitInheritance();
}
bool ComputedStyle::ShadowListHasCurrentColor(const ShadowList* shadow_list) {
diff --git a/chromium/third_party/blink/renderer/core/style/computed_style.h b/chromium/third_party/blink/renderer/core/style/computed_style.h
index 0f4b33439a2..83799d8ca7f 100644
--- a/chromium/third_party/blink/renderer/core/style/computed_style.h
+++ b/chromium/third_party/blink/renderer/core/style/computed_style.h
@@ -52,6 +52,7 @@
#include "third_party/blink/renderer/platform/graphics/touch_action.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
+#include "third_party/blink/renderer/platform/text/writing_direction_mode.h"
#include "third_party/blink/renderer/platform/text/writing_mode_utils.h"
#include "third_party/blink/renderer/platform/transforms/transform_operations.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -574,32 +575,28 @@ class ComputedStyle : public ComputedStyleBase,
// border-left-color
void SetBorderLeftColor(const StyleColor& color) {
if (BorderLeftColor() != color) {
- SetBorderLeftColorInternal(color.Resolve(Color()));
- SetBorderLeftColorIsCurrentColor(color.IsCurrentColor());
+ SetBorderLeftColorInternal(color);
}
}
// border-right-color
void SetBorderRightColor(const StyleColor& color) {
if (BorderRightColor() != color) {
- SetBorderRightColorInternal(color.Resolve(Color()));
- SetBorderRightColorIsCurrentColor(color.IsCurrentColor());
+ SetBorderRightColorInternal(color);
}
}
// border-top-color
void SetBorderTopColor(const StyleColor& color) {
if (BorderTopColor() != color) {
- SetBorderTopColorInternal(color.Resolve(Color()));
- SetBorderTopColorIsCurrentColor(color.IsCurrentColor());
+ SetBorderTopColorInternal(color);
}
}
// border-bottom-color
void SetBorderBottomColor(const StyleColor& color) {
if (BorderBottomColor() != color) {
- SetBorderBottomColorInternal(color.Resolve(Color()));
- SetBorderBottomColorIsCurrentColor(color.IsCurrentColor());
+ SetBorderBottomColorInternal(color);
}
}
@@ -632,8 +629,7 @@ class ComputedStyle : public ComputedStyleBase,
// column-rule-color (aka -webkit-column-rule-color)
void SetColumnRuleColor(const StyleColor& c) {
if (ColumnRuleColor() != c) {
- SetColumnRuleColorInternal(c.Resolve(Color()));
- SetColumnRuleColorIsCurrentColor(c.IsCurrentColor());
+ SetColumnRuleColorInternal(c);
}
}
@@ -681,7 +677,8 @@ class ComputedStyle : public ComputedStyleBase,
// We only need do layout for opacity changes if adding or losing opacity
// could trigger a change
// in us being a stacking context.
- if (IsStackingContext() == other.IsStackingContext() ||
+ if (IsStackingContextWithoutContainment() ==
+ other.IsStackingContextWithoutContainment() ||
HasOpacity() == other.HasOpacity()) {
// FIXME: We would like to use SimplifiedLayout here, but we can't quite
// do that yet. We need to make sure SimplifiedLayout can operate
@@ -709,7 +706,6 @@ class ComputedStyle : public ComputedStyleBase,
other.OutlineStyle() == EBorderStyle::kNone)
return true;
return OutlineWidthInternal() == other.OutlineWidthInternal() &&
- OutlineColorIsCurrentColor() == other.OutlineColorIsCurrentColor() &&
OutlineColor() == other.OutlineColor() &&
OutlineStyle() == other.OutlineStyle() &&
OutlineOffset() == other.OutlineOffset() &&
@@ -719,8 +715,7 @@ class ComputedStyle : public ComputedStyleBase,
// outline-color
void SetOutlineColor(const StyleColor& v) {
if (OutlineColor() != v) {
- SetOutlineColorInternal(v.Resolve(Color()));
- SetOutlineColorIsCurrentColor(v.IsCurrentColor());
+ SetOutlineColorInternal(v);
}
}
@@ -869,6 +864,23 @@ class ComputedStyle : public ComputedStyleBase,
SetScrollMarginBottom(v);
}
+ // scrollbar-gutter
+ inline bool ScrollbarGutterIsAuto() const {
+ return ScrollbarGutter() == kScrollbarGutterAuto;
+ }
+ inline bool ScrollbarGutterIsStable() const {
+ return ScrollbarGutter() & kScrollbarGutterStable;
+ }
+ inline bool ScrollbarGutterIsAlways() const {
+ return ScrollbarGutter() & kScrollbarGutterAlways;
+ }
+ inline bool ScrollbarGutterIsBoth() const {
+ return ScrollbarGutter() & kScrollbarGutterBoth;
+ }
+ inline bool ScrollbarGutterIsForce() const {
+ return ScrollbarGutter() & kScrollbarGutterForce;
+ }
+
// shape-image-threshold (aka -webkit-shape-image-threshold)
void SetShapeImageThreshold(float shape_image_threshold) {
float clamped_shape_image_threshold =
@@ -907,6 +919,13 @@ class ComputedStyle : public ComputedStyleBase,
SetHasAutoZIndexInternal(true);
SetZIndexInternal(0);
}
+ // This returns the z-index if it applies (i.e. positioned element or grid or
+ // flex children), and 0 otherwise. Note that for most situations,
+ // `EffectiveZIndex()` is what the code should use to determine how to stack
+ // the element. `ZIndex()` is still available and returns the value as
+ // specified in style (used for e.g. style comparisons and computed style
+ // reporting)
+ int EffectiveZIndex() const { return EffectiveZIndexZero() ? 0 : ZIndex(); }
CORE_EXPORT bool SetEffectiveZoom(float);
@@ -983,20 +1002,17 @@ class ComputedStyle : public ComputedStyleBase,
// -webkit-text-emphasis-color (aka -epub-text-emphasis-color)
void SetTextEmphasisColor(const StyleColor& color) {
- SetTextEmphasisColorInternal(color.Resolve(Color()));
- SetTextEmphasisColorIsCurrentColorInternal(color.IsCurrentColor());
+ SetTextEmphasisColorInternal(color);
}
// -webkit-text-fill-color
void SetTextFillColor(const StyleColor& color) {
- SetTextFillColorInternal(color.Resolve(Color()));
- SetTextFillColorIsCurrentColorInternal(color.IsCurrentColor());
+ SetTextFillColorInternal(color);
}
// -webkit-text-stroke-color
void SetTextStrokeColor(const StyleColor& color) {
- SetTextStrokeColorInternal(color.Resolve(Color()));
- SetTextStrokeColorIsCurrentColorInternal(color.IsCurrentColor());
+ SetTextStrokeColorInternal(color);
}
// caret-color
@@ -1204,9 +1220,7 @@ class ComputedStyle : public ComputedStyleBase,
bool LoadingCustomFontsEqual(const ComputedStyle&) const;
bool InheritedDataShared(const ComputedStyle&) const;
- bool HasChildDependentFlags() const {
- return HasExplicitlyInheritedProperties();
- }
+ bool HasChildDependentFlags() const { return ChildHasExplicitInheritance(); }
void CopyChildDependentFlagsFrom(const ComputedStyle&);
// Counters.
@@ -1222,6 +1236,7 @@ class ComputedStyle : public ComputedStyleBase,
}
void ClearIncrementDirectives();
void ClearResetDirectives();
+ void ClearSetDirectives();
bool IsDeprecatedWebkitBox() const {
return Display() == EDisplay::kWebkitBox ||
@@ -1282,8 +1297,7 @@ class ComputedStyle : public ComputedStyleBase,
return !HasAutoColumnCount() || !HasAutoColumnWidth();
}
bool ColumnRuleIsTransparent() const {
- return !ColumnRuleColorIsCurrentColor() &&
- !ColumnRuleColorInternal().Alpha();
+ return !ColumnRuleColorInternal().Resolve(GetColor()).Alpha();
}
bool ColumnRuleEquivalent(const ComputedStyle& other_style) const;
bool HasColumnRule() const {
@@ -1475,6 +1489,9 @@ class ComputedStyle : public ComputedStyleBase,
}
// Writing mode utility functions.
+ WritingDirectionMode GetWritingDirection() const {
+ return {GetWritingMode(), Direction()};
+ }
bool IsHorizontalWritingMode() const {
return blink::IsHorizontalWritingMode(GetWritingMode());
}
@@ -1804,14 +1821,11 @@ class ComputedStyle : public ComputedStyleBase,
bool BorderLeftEquals(const ComputedStyle& o) const {
return BorderLeftWidthInternal() == o.BorderLeftWidthInternal() &&
BorderLeftStyle() == o.BorderLeftStyle() &&
- BorderLeftColor() == o.BorderLeftColor() &&
- BorderLeftColorIsCurrentColor() == o.BorderLeftColorIsCurrentColor();
+ BorderLeftColor() == o.BorderLeftColor();
}
bool BorderLeftEquals(const BorderValue& o) const {
return BorderLeftWidthInternal().ToFloat() == o.Width() &&
- BorderLeftStyle() == o.Style() &&
- BorderLeftColor() == o.GetColor() &&
- BorderLeftColorIsCurrentColor() == o.ColorIsCurrentColor();
+ BorderLeftStyle() == o.Style() && BorderLeftColor() == o.GetColor();
}
bool BorderLeftVisuallyEqual(const ComputedStyle& o) const {
@@ -1827,15 +1841,12 @@ class ComputedStyle : public ComputedStyleBase,
bool BorderRightEquals(const ComputedStyle& o) const {
return BorderRightWidthInternal() == o.BorderRightWidthInternal() &&
BorderRightStyle() == o.BorderRightStyle() &&
- BorderRightColor() == o.BorderRightColor() &&
- BorderRightColorIsCurrentColor() ==
- o.BorderRightColorIsCurrentColor();
+ BorderRightColor() == o.BorderRightColor();
}
bool BorderRightEquals(const BorderValue& o) const {
return BorderRightWidthInternal().ToFloat() == o.Width() &&
BorderRightStyle() == o.Style() &&
- BorderRightColor() == o.GetColor() &&
- BorderRightColorIsCurrentColor() == o.ColorIsCurrentColor();
+ BorderRightColor() == o.GetColor();
}
bool BorderRightVisuallyEqual(const ComputedStyle& o) const {
@@ -1861,13 +1872,11 @@ class ComputedStyle : public ComputedStyleBase,
bool BorderTopEquals(const ComputedStyle& o) const {
return BorderTopWidthInternal() == o.BorderTopWidthInternal() &&
BorderTopStyle() == o.BorderTopStyle() &&
- BorderTopColor() == o.BorderTopColor() &&
- BorderTopColorIsCurrentColor() == o.BorderTopColorIsCurrentColor();
+ BorderTopColor() == o.BorderTopColor();
}
bool BorderTopEquals(const BorderValue& o) const {
return BorderTopWidthInternal().ToFloat() == o.Width() &&
- BorderTopStyle() == o.Style() && BorderTopColor() == o.GetColor() &&
- BorderTopColorIsCurrentColor() == o.ColorIsCurrentColor();
+ BorderTopStyle() == o.Style() && BorderTopColor() == o.GetColor();
}
bool BorderBottomVisuallyEqual(const ComputedStyle& o) const {
@@ -1883,15 +1892,12 @@ class ComputedStyle : public ComputedStyleBase,
bool BorderBottomEquals(const ComputedStyle& o) const {
return BorderBottomWidthInternal() == o.BorderBottomWidthInternal() &&
BorderBottomStyle() == o.BorderBottomStyle() &&
- BorderBottomColor() == o.BorderBottomColor() &&
- BorderBottomColorIsCurrentColor() ==
- o.BorderBottomColorIsCurrentColor();
+ BorderBottomColor() == o.BorderBottomColor();
}
bool BorderBottomEquals(const BorderValue& o) const {
return BorderBottomWidthInternal().ToFloat() == o.Width() &&
BorderBottomStyle() == o.Style() &&
- BorderBottomColor() == o.GetColor() &&
- BorderBottomColorIsCurrentColor() == o.ColorIsCurrentColor();
+ BorderBottomColor() == o.GetColor();
}
bool BorderEquals(const ComputedStyle& o) const {
@@ -1928,26 +1934,22 @@ class ComputedStyle : public ComputedStyleBase,
void ResetBorderTop() {
SetBorderTopStyle(EBorderStyle::kNone);
SetBorderTopWidth(3);
- SetBorderTopColorInternal(0);
- SetBorderTopColorIsCurrentColor(true);
+ SetBorderTopColorInternal(StyleColor::CurrentColor());
}
void ResetBorderRight() {
SetBorderRightStyle(EBorderStyle::kNone);
SetBorderRightWidth(3);
- SetBorderRightColorInternal(0);
- SetBorderRightColorIsCurrentColor(true);
+ SetBorderRightColorInternal(StyleColor::CurrentColor());
}
void ResetBorderBottom() {
SetBorderBottomStyle(EBorderStyle::kNone);
SetBorderBottomWidth(3);
- SetBorderBottomColorInternal(0);
- SetBorderBottomColorIsCurrentColor(true);
+ SetBorderBottomColorInternal(StyleColor::CurrentColor());
}
void ResetBorderLeft() {
SetBorderLeftStyle(EBorderStyle::kNone);
SetBorderLeftWidth(3);
- SetBorderLeftColorInternal(0);
- SetBorderLeftColorIsCurrentColor(true);
+ SetBorderLeftColorInternal(StyleColor::CurrentColor());
}
void SetBorderRadius(const LengthSize& s) {
@@ -2318,8 +2320,9 @@ class ComputedStyle : public ComputedStyleBase,
return !Transform().Operations().IsEmpty();
}
ETransformStyle3D UsedTransformStyle3D() const {
- return HasGroupingProperty() ? ETransformStyle3D::kFlat
- : TransformStyle3D();
+ return HasGroupingPropertyForUsedTransformStyle3D()
+ ? ETransformStyle3D::kFlat
+ : TransformStyle3D();
}
// Returns whether the transform operations for |otherStyle| differ from the
// operations for this style instance. Note that callers may want to also
@@ -2380,12 +2383,52 @@ class ComputedStyle : public ComputedStyleBase,
}
// Returns whether this style contains any grouping property as defined by
- // [css-transforms]. The main purpose of this is to adjust the used value of
- // transform-style property.
- // Note: We currently don't include every grouping property on the spec to
- // maintain backward compatibility. [css-transforms]
- // https://drafts.csswg.org/css-transforms/#grouping-property-values
- bool HasGroupingProperty() const {
+ // https://drafts.csswg.org/css-transforms-2/#grouping-property-values.
+ //
+ // |has_box_reflection| is a parameter instead of checking |BoxReflect()|
+ // because box reflection styles only apply for some objects (see:
+ // |LayoutObject::HasReflection()|).
+ bool HasGroupingProperty(bool has_box_reflection) const {
+ if (HasStackingGroupingProperty(has_box_reflection))
+ return true;
+ // TODO(pdr): Also check for overflow because the spec requires "overflow:
+ // any value other than visible or clip."
+ if (!HasAutoClip() && HasOutOfFlowPosition())
+ return true;
+ return false;
+ }
+
+ // This is the subset of grouping properties (see: |HasGroupingProperty|) that
+ // also create stacking contexts.
+ bool HasStackingGroupingProperty(bool has_box_reflection) const {
+ if (HasNonInitialOpacity())
+ return true;
+ if (HasNonInitialFilter())
+ return true;
+ if (has_box_reflection)
+ return true;
+ if (ClipPath())
+ return true;
+ if (HasIsolation())
+ return true;
+ if (HasMask())
+ return true;
+ if (HasBlendMode())
+ return true;
+ if (HasNonInitialBackdropFilter())
+ return true;
+ return false;
+ }
+
+ // Grouping requires creating a flattened representation of the descendant
+ // elements before they can be applied, and therefore force the element to
+ // have a used style of flat for preserve-3d.
+ // Until |RuntimeEnabledFeatures::TransformInteropEnabled()| launches, the
+ // approach is different from the spec to maintain backwards compatibility.
+ // TODO(chrishtr): replace this with |HasGroupingProperty()|.
+ CORE_EXPORT bool HasGroupingPropertyForUsedTransformStyle3D() const {
+ if (RuntimeEnabledFeatures::TransformInteropEnabled())
+ return HasGroupingProperty(BoxReflect()) || !IsOverflowVisible();
return !IsOverflowVisible() || HasFilterInducingProperty() ||
HasNonInitialOpacity();
}
@@ -2430,11 +2473,13 @@ class ComputedStyle : public ComputedStyleBase,
// they don't determine the stacking of the elements underneath them. (Note:
// There are also other elements treated as stacking context during painting,
// but not managed in stacks. See ObjectPainter::PaintAllPhasesAtomically().)
- CORE_EXPORT void UpdateIsStackingContext(bool is_document_element,
- bool is_in_top_layer,
- bool is_svg_stacking);
- bool IsStacked() const {
- return IsStackingContext() || GetPosition() != EPosition::kStatic;
+ CORE_EXPORT void UpdateIsStackingContextWithoutContainment(
+ bool is_document_element,
+ bool is_in_top_layer,
+ bool is_svg_stacking);
+ bool IsStackedWithoutContainment() const {
+ return IsStackingContextWithoutContainment() ||
+ GetPosition() != EPosition::kStatic;
}
// Pseudo element styles.
@@ -2448,18 +2493,6 @@ class ComputedStyle : public ComputedStyleBase,
bool CanContainAbsolutePositionObjects() const {
return GetPosition() != EPosition::kStatic;
}
- // TODO(pdr): Should this function be unified with
- // LayoutObject::ComputeIsFixedContainer?
- bool CanContainFixedPositionObjects(bool is_document_element) const {
- return HasTransformRelatedProperty() ||
- // Filter establishes containing block for non-document elements:
- // https://drafts.fxtf.org/filter-effects-1/#FilterProperty
- // Backdrop-filter creates a containing block for fixed and absolute
- // positioned elements:
- // https://drafts.fxtf.org/filter-effects-2/#backdrop-filter-operation
- (!is_document_element &&
- (HasNonInitialFilter() || HasNonInitialBackdropFilter()));
- }
// Whitespace utility functions.
static bool Is(EWhiteSpace a, EWhiteSpace b) {
@@ -2620,11 +2653,6 @@ class ComputedStyle : public ComputedStyleBase,
return DarkColorScheme() ? Color::kWhite : Color::kBlack;
}
- Color ForcedBackplateColor() const {
- return LayoutTheme::GetTheme().SystemColor(CSSValueID::kCanvas,
- WebColorScheme::kLight);
- }
-
bool GeneratesMarkerImage() const {
return Display() == EDisplay::kListItem && ListStyleImage() &&
!ListStyleImage()->ErrorOccurred();
@@ -2672,19 +2700,13 @@ class ComputedStyle : public ComputedStyleBase,
SetInternalVisitedTextDecorationColorInternal(v);
}
void SetInternalVisitedTextEmphasisColor(const StyleColor& color) {
- SetInternalVisitedTextEmphasisColorInternal(color.Resolve(Color()));
- SetInternalVisitedTextEmphasisColorIsCurrentColorInternal(
- color.IsCurrentColor());
+ SetInternalVisitedTextEmphasisColorInternal(color);
}
void SetInternalVisitedTextFillColor(const StyleColor& color) {
- SetInternalVisitedTextFillColorInternal(color.Resolve(Color()));
- SetInternalVisitedTextFillColorIsCurrentColorInternal(
- color.IsCurrentColor());
+ SetInternalVisitedTextFillColorInternal(color);
}
void SetInternalVisitedTextStrokeColor(const StyleColor& color) {
- SetInternalVisitedTextStrokeColorInternal(color.Resolve(Color()));
- SetInternalVisitedTextStrokeColorIsCurrentColorInternal(
- color.IsCurrentColor());
+ SetInternalVisitedTextStrokeColorInternal(color);
}
void SetInternalVisitedCaretColor(const StyleAutoColor& color) {
SetInternalVisitedCaretColorInternal(color.Resolve(Color()));
@@ -2744,26 +2766,10 @@ class ComputedStyle : public ComputedStyleBase,
// Color accessors are all private to make sure callers use
// VisitedDependentColor instead to access them.
- StyleColor BorderLeftColor() const {
- return BorderLeftColorIsCurrentColor()
- ? StyleColor::CurrentColor()
- : StyleColor(BorderLeftColorInternal());
- }
- StyleColor BorderRightColor() const {
- return BorderRightColorIsCurrentColor()
- ? StyleColor::CurrentColor()
- : StyleColor(BorderRightColorInternal());
- }
- StyleColor BorderTopColor() const {
- return BorderTopColorIsCurrentColor()
- ? StyleColor::CurrentColor()
- : StyleColor(BorderTopColorInternal());
- }
- StyleColor BorderBottomColor() const {
- return BorderBottomColorIsCurrentColor()
- ? StyleColor::CurrentColor()
- : StyleColor(BorderBottomColorInternal());
- }
+ StyleColor BorderLeftColor() const { return BorderLeftColorInternal(); }
+ StyleColor BorderRightColor() const { return BorderRightColorInternal(); }
+ StyleColor BorderTopColor() const { return BorderTopColorInternal(); }
+ StyleColor BorderBottomColor() const { return BorderBottomColorInternal(); }
StyleColor BackgroundColor() const { return BackgroundColorInternal(); }
StyleAutoColor CaretColor() const {
@@ -2774,30 +2780,11 @@ class ComputedStyle : public ComputedStyleBase,
return StyleAutoColor(CaretColorInternal());
}
Color GetColor() const;
- StyleColor ColumnRuleColor() const {
- return ColumnRuleColorIsCurrentColor()
- ? StyleColor::CurrentColor()
- : StyleColor(ColumnRuleColorInternal());
- }
- StyleColor OutlineColor() const {
- return OutlineColorIsCurrentColor() ? StyleColor::CurrentColor()
- : StyleColor(OutlineColorInternal());
- }
- StyleColor TextEmphasisColor() const {
- return TextEmphasisColorIsCurrentColorInternal()
- ? StyleColor::CurrentColor()
- : StyleColor(TextEmphasisColorInternal());
- }
- StyleColor TextFillColor() const {
- return TextFillColorIsCurrentColorInternal()
- ? StyleColor::CurrentColor()
- : StyleColor(TextFillColorInternal());
- }
- StyleColor TextStrokeColor() const {
- return TextStrokeColorIsCurrentColorInternal()
- ? StyleColor::CurrentColor()
- : StyleColor(TextStrokeColorInternal());
- }
+ StyleColor ColumnRuleColor() const { return ColumnRuleColorInternal(); }
+ StyleColor OutlineColor() const { return OutlineColorInternal(); }
+ StyleColor TextEmphasisColor() const { return TextEmphasisColorInternal(); }
+ StyleColor TextFillColor() const { return TextFillColorInternal(); }
+ StyleColor TextStrokeColor() const { return TextStrokeColorInternal(); }
Color InternalVisitedColor() const { return InternalVisitedColorInternal(); }
StyleAutoColor InternalVisitedCaretColor() const {
if (InternalVisitedCaretColorIsCurrentColorInternal())
@@ -2861,19 +2848,13 @@ class ComputedStyle : public ComputedStyleBase,
return InternalVisitedTextDecorationColorInternal();
}
StyleColor InternalVisitedTextEmphasisColor() const {
- return InternalVisitedTextEmphasisColorIsCurrentColorInternal()
- ? StyleColor::CurrentColor()
- : StyleColor(InternalVisitedTextEmphasisColorInternal());
+ return InternalVisitedTextEmphasisColorInternal();
}
StyleColor InternalVisitedTextFillColor() const {
- return InternalVisitedTextFillColorIsCurrentColorInternal()
- ? StyleColor::CurrentColor()
- : StyleColor(InternalVisitedTextFillColorInternal());
+ return InternalVisitedTextFillColorInternal();
}
StyleColor InternalVisitedTextStrokeColor() const {
- return InternalVisitedTextStrokeColorIsCurrentColorInternal()
- ? StyleColor::CurrentColor()
- : StyleColor(InternalVisitedTextStrokeColorInternal());
+ return InternalVisitedTextStrokeColorInternal();
}
StyleColor DecorationColorIncludingFallback(bool visited_link) const;
diff --git a/chromium/third_party/blink/renderer/core/style/computed_style_constants.h b/chromium/third_party/blink/renderer/core/style/computed_style_constants.h
index d7a8d8cafc8..1a127b1998e 100644
--- a/chromium/third_party/blink/renderer/core/style/computed_style_constants.h
+++ b/chromium/third_party/blink/renderer/core/style/computed_style_constants.h
@@ -130,9 +130,6 @@ enum class EFillSizeType : unsigned {
// CSS3 Background Position
enum class BackgroundEdgeOrigin : unsigned { kTop, kRight, kBottom, kLeft };
-// CSS Mask Source Types
-enum class EMaskSourceType : unsigned { kAlpha, kLuminance };
-
// CSS3 Image Values
enum class QuoteType : unsigned { kOpen, kClose, kNoOpen, kNoClose };
@@ -263,6 +260,21 @@ enum class LineLogicalSide {
kUnder,
};
+constexpr size_t kScrollbarGutterBits = 4;
+enum ScrollbarGutter {
+ kScrollbarGutterAuto = 0x0,
+ kScrollbarGutterStable = 0x1,
+ kScrollbarGutterAlways = 0x2,
+ kScrollbarGutterBoth = 0x4,
+ kScrollbarGutterForce = 0x8
+};
+inline ScrollbarGutter operator|(ScrollbarGutter a, ScrollbarGutter b) {
+ return ScrollbarGutter(int(a) | int(b));
+}
+inline ScrollbarGutter& operator|=(ScrollbarGutter& a, ScrollbarGutter b) {
+ return a = a | b;
+}
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_CONSTANTS_H_
diff --git a/chromium/third_party/blink/renderer/core/style/computed_style_diff_functions.json5 b/chromium/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
index b87986adc2b..73f43d6d10b 100644
--- a/chromium/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
+++ b/chromium/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
@@ -1,5 +1,5 @@
{
- // This file specifies the fields we want to diff in the various diff functions
+ // This file specifies the fields we want to diff in the various diff functions
// in ComputedStyle.
parameters: {
@@ -9,7 +9,7 @@
default: [],
},
- // A list of methods to diff (these can be public getters of fields or
+ // A list of methods to diff (these can be public getters of fields or
// functions that use fields to determine a value).
// Each entry is expressed as a dict of two fields:
// 1. method: the method to be diffed
@@ -23,7 +23,7 @@
// Each entry is expressed as a dict of two fields:
// 1. predicate: the predicate to be tested
// 2. field_dependencies: lists the properties this predicate test depends on.
- // TODO: Note that you also have to pass in the arguments for the predicate.
+ // TODO: Note that you also have to pass in the arguments for the predicate.
// This may be removed in the future if we are always passing the other ComputedStyle
predicates_to_test: {
default: [],
@@ -32,8 +32,8 @@
data: [
{
name: "ScrollAnchorDisablingPropertyChanged",
- fields_to_diff: ["width", "min-width", "max-width", "height", "min-height", "max-height", "margin-top", "margin-left", "margin-right", "margin-bottom",
- "left", "right", "top", "bottom", "padding-top",
+ fields_to_diff: ["width", "min-width", "max-width", "height", "min-height", "max-height", "margin-top", "margin-left", "margin-right", "margin-bottom",
+ "left", "right", "top", "bottom", "padding-top",
"padding-left", "padding-right", "padding-bottom",
"contain-intrinsic-size"],
methods_to_diff: [
@@ -80,37 +80,37 @@
},
{
name: "DiffNeedsFullLayoutAndPaintInvalidation",
- fields_to_diff: ["padding-top", "padding-left", "padding-right",
+ fields_to_diff: ["padding-top", "padding-left", "padding-right",
"padding-bottom", "appearance", "-webkit-line-clamp",
"text-overflow", "shape-margin", "order", "-webkit-highlight",
"text-indent", "text-align-last", "TextIndentLine", "EffectiveZoom",
- "word-break", "overflow-wrap", "-webkit-line-break",
- "-webkit-text-security", "hyphens", "HyphenationLimitBefore",
- "HyphenationLimitAfter", "-webkit-hyphenate-character",
- "image-orientation", "-webkit-ruby-position",
- "TextEmphasisMark", "-webkit-text-emphasis-position",
- "TextEmphasisCustomMark", "text-justify", "text-orientation",
- "text-combine-upright", "tab-size", "text-size-adjust",
- "list-style-image", "line-height-step",
+ "word-break", "overflow-wrap", "-webkit-line-break",
+ "-webkit-text-security", "hyphens", "HyphenationLimitBefore",
+ "HyphenationLimitAfter", "-webkit-hyphenate-character",
+ "image-orientation", "-webkit-ruby-position",
+ "TextEmphasisMark", "-webkit-text-emphasis-position",
+ "TextEmphasisCustomMark", "text-justify", "text-orientation",
+ "text-combine-upright", "tab-size", "text-size-adjust",
+ "list-style-image", "line-height-step",
"-webkit-text-stroke-width", "line-height",
- "-webkit-border-horizontal-spacing",
- "-webkit-border-vertical-spacing", "TextAutosizingMultiplier",
- "NamedGridColumnLines", "NamedGridRowLines", "OrderedNamedGridColumnLines",
- "OrderedNamedGridRowLines", "AutoRepeatNamedGridColumnLines",
- "AutoRepeatNamedGridRowLines", "AutoRepeatOrderedNamedGridColumnLines",
- "AutoRepeatOrderedNamedGridRowLines", "ImplicitNamedGridColumnLines",
- "ImplicitNamedGridRowLines", "NamedGridArea", "grid-auto-rows",
+ "-webkit-border-horizontal-spacing",
+ "-webkit-border-vertical-spacing", "TextAutosizingMultiplier",
+ "NamedGridColumnLines", "NamedGridRowLines", "OrderedNamedGridColumnLines",
+ "OrderedNamedGridRowLines", "AutoRepeatNamedGridColumnLines",
+ "AutoRepeatNamedGridRowLines", "AutoRepeatOrderedNamedGridColumnLines",
+ "AutoRepeatOrderedNamedGridRowLines", "ImplicitNamedGridColumnLines",
+ "ImplicitNamedGridRowLines", "NamedGridArea", "grid-auto-rows",
"grid-template-rows", "grid-template-columns", "grid-auto-columns", "row-gap",
- "NamedGridAreaRowCount", "NamedGridAreaColumnCount",
- "GridAutoRepeatColumns", "GridAutoRepeatRows", "GridAutoRepeatColumnsInsertionPoint",
- "GridAutoRepeatRowsInsertionPoint", "grid-auto-flow", "GridAutoRepeatColumnsType",
- "GridAutoRepeatRowsType", "-webkit-box-flex",
- "-webkit-box-ordinal-group", "flex-basis",
- "flex-shrink", "flex-grow", "flex-direction", "flex-wrap", "-webkit-box-align",
+ "NamedGridAreaRowCount", "NamedGridAreaColumnCount",
+ "GridAutoRepeatColumns", "GridAutoRepeatRows", "GridAutoRepeatColumnsInsertionPoint",
+ "GridAutoRepeatRowsInsertionPoint", "grid-auto-flow", "GridAutoRepeatColumnsType",
+ "GridAutoRepeatRowsType", "-webkit-box-flex",
+ "-webkit-box-ordinal-group", "flex-basis",
+ "flex-shrink", "flex-grow", "flex-direction", "flex-wrap", "-webkit-box-align",
"-webkit-box-pack", "-webkit-box-orient",
"grid-row-start", "grid-row-end", "grid-column-start", "grid-column-end",
"column-gap", "column-width", "column-rule-style",
- "column-rule-width", "column-rule-color", "ColumnRuleColorIsCurrentColor", "-internal-visited-column-rule-color",
+ "column-rule-width", "column-rule-color", "-internal-visited-column-rule-color",
"column-count", "HasAutoColumnCount", "HasAutoColumnWidth", "column-fill", "column-span",],
methods_to_diff: [
{
@@ -181,7 +181,8 @@
},
{
predicate: "a.OpacityChangedStackingContext(b)",
- field_dependencies: ["IsStackingContext", "opacity"]
+ field_dependencies: ["IsStackingContextWithoutContainment",
+ "opacity"]
},
]
},
@@ -286,7 +287,7 @@
},
{
predicate: "a.OutlineVisuallyEqual(b)",
- field_dependencies: ["outline-width", "outline-color", "OutlineColorIsCurrentColor", "outline-offset", "outline-style", "OutlineStyleIsAuto"]
+ field_dependencies: ["outline-width", "outline-color", "outline-offset", "outline-style", "OutlineStyleIsAuto"]
},
{
predicate: "a.InternalVisitedBorderLeftColorHasNotChanged(b)",
@@ -334,8 +335,8 @@
fields_to_diff: ["z-index"],
methods_to_diff: [
{
- method: "IsStackingContext()",
- field_dependencies: ["IsStackingContext"]
+ method: "IsStackingContextWithoutContainment()",
+ field_dependencies: ["IsStackingContextWithoutContainment"]
},
]
},
@@ -350,7 +351,7 @@
name: "UpdatePropertySpecificDifferencesTransform",
fields_to_diff: ["transform", "translate", "rotate",
"scale", "offset-path", "offset-rotate", "transform-origin",
- "offset-position", "offset-anchor", "offset-distance",
+ "offset-position", "offset-anchor", "offset-distance",
"perspective", "perspective-origin", "transform-box"],
methods_to_diff: [
{
@@ -358,8 +359,8 @@
// while hasTransform() differs, as it checks a number of conditions aside
// from just the matrix, including but not limited to animation state.
method: "HasTransform()",
- field_dependencies: ["transform", "offset-position",
- "HasCurrentTransformAnimation", "translate", "rotate",
+ field_dependencies: ["transform", "offset-position",
+ "HasCurrentTransformAnimation", "translate", "rotate",
"scale"]
},
]
@@ -394,7 +395,7 @@
},
{
predicate: "a.OutlineVisuallyEqual(b)",
- field_dependencies: ["outline-width", "outline-color", "OutlineColorIsCurrentColor", "outline-offset", "outline-style", "OutlineStyleIsAuto"]
+ field_dependencies: ["outline-width", "outline-color", "outline-offset", "outline-style", "OutlineStyleIsAuto"]
},
{
predicate: "a.BorderVisualOverflowEqual(b)",
diff --git a/chromium/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 b/chromium/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
index 4331914478e..63dec850bae 100644
--- a/chromium/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
+++ b/chromium/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
@@ -35,34 +35,6 @@
custom_compare: true,
},
{
- name: "BorderLeftColorIsCurrentColor",
- field_template: "primitive",
- default_value: "true",
- type_name: "bool",
- field_group: "surround",
- },
- {
- name: "BorderRightColorIsCurrentColor",
- field_template: "primitive",
- default_value: "true",
- type_name: "bool",
- field_group: "surround",
- },
- {
- name: "BorderTopColorIsCurrentColor",
- field_template: "primitive",
- default_value: "true",
- type_name: "bool",
- field_group: "surround",
- },
- {
- name: "BorderBottomColorIsCurrentColor",
- field_template: "primitive",
- default_value: "true",
- type_name: "bool",
- field_group: "surround",
- },
- {
name: "Display",
field_template: "keyword",
type_name: "EDisplay",
@@ -190,15 +162,22 @@
default_value: "false",
custom_compare: true,
},
- // Explicitly inherits a non-inherited property
+ // Set on parent style when a child explicitly inherits a
+ // non-inherited property
{
- name: "HasExplicitlyInheritedProperties",
+ name: "ChildHasExplicitInheritance",
field_template: "monotonic_flag",
default_value: "false",
custom_copy: true,
custom_compare: true,
mutable: true,
},
+ // Explicitly inherits a non-inherited property
+ {
+ name: "HasExplicitInheritance",
+ field_template: "monotonic_flag",
+ default_value: "false",
+ },
// These are set if we used viewport or rem units when resolving a length.
// FIXME: HasViewportUnits should be a monotonic_flag.
{
@@ -352,33 +331,6 @@
computed_style_custom_functions: ["setter"],
},
{
- name: "TextStrokeColorIsCurrentColor",
- inherited: true,
- field_template: "primitive",
- type_name: "bool",
- default_value: "true",
- field_group: "*",
- computed_style_custom_functions: ["getter", "setter"],
- },
- {
- name: "TextFillColorIsCurrentColor",
- inherited: true,
- field_template: "primitive",
- type_name: "bool",
- default_value: "true",
- field_group: "*",
- computed_style_custom_functions: ["getter", "setter"],
- },
- {
- name: "TextEmphasisColorIsCurrentColor",
- inherited: true,
- field_template: "primitive",
- type_name: "bool",
- default_value: "true",
- field_group: "*",
- computed_style_custom_functions: ["getter", "setter"],
- },
- {
name: "CaretColorIsCurrentColor",
inherited: true,
field_template: "primitive",
@@ -397,33 +349,6 @@
computed_style_custom_functions: ["getter", "setter"],
},
{
- name: "InternalVisitedTextStrokeColorIsCurrentColor",
- inherited: true,
- field_template: "primitive",
- type_name: "bool",
- default_value: "true",
- field_group: "*",
- computed_style_custom_functions: ["getter", "setter"],
- },
- {
- name: "InternalVisitedTextFillColorIsCurrentColor",
- inherited: true,
- field_template: "primitive",
- type_name: "bool",
- default_value: "true",
- field_group: "*",
- computed_style_custom_functions: ["getter", "setter"],
- },
- {
- name: "InternalVisitedTextEmphasisColorIsCurrentColor",
- inherited: true,
- field_template: "primitive",
- type_name: "bool",
- default_value: "true",
- field_group: "*",
- computed_style_custom_functions: ["getter", "setter"],
- },
- {
name: "InternalVisitedCaretColorIsCurrentColor",
inherited: true,
field_template: "primitive",
@@ -651,13 +576,6 @@
include_paths: ["third_party/blink/renderer/platform/geometry/float_size.h"],
},
{
- name: "OutlineColorIsCurrentColor",
- field_template: "primitive",
- default_value: "true",
- type_name: "bool",
- field_group: "*",
- },
- {
name: "OutlineStyleIsAuto",
field_template: "primitive",
type_name: "bool",
@@ -776,9 +694,10 @@
// whereas a containing stacking context defines in which order the stacking
// contexts below are painted.
// See CSS 2.1, Appendix E (https://www.w3.org/TR/CSS21/zindex.html) for more
- // details.
+ // details. Note that this field does _not_ consider paint or layout
+ // containment, since it depends on the type of layout object created.
{
- name: "IsStackingContext",
+ name: "IsStackingContextWithoutContainment",
field_template: "primitive",
type_name: "bool",
field_group: "*",
@@ -834,13 +753,6 @@
default_value: "false",
},
{
- name: "ColumnRuleColorIsCurrentColor",
- field_template: "primitive",
- default_value: "true",
- type_name: "bool",
- field_group: "*->multi-col",
- },
- {
name: "HasAutoColumnWidth",
field_template: "primitive",
type_name: "bool",
@@ -1122,5 +1034,20 @@
field_group: "*",
getter: "GetMathFractionBarThickness",
},
+ {
+ name: "MathScriptLevel",
+ inherited: true,
+ field_template: "primitive",
+ type_name: "short",
+ default_value: "0",
+ field_group: "*",
+ },
+ {
+ name: "EffectiveZIndexZero",
+ field_template: "primitive",
+ type_name: "bool",
+ field_group: "*",
+ default_value: "false",
+ },
],
}
diff --git a/chromium/third_party/blink/renderer/core/style/computed_style_test.cc b/chromium/third_party/blink/renderer/core/style/computed_style_test.cc
index f7dce414130..a4f03d62016 100644
--- a/chromium/third_party/blink/renderer/core/style/computed_style_test.cc
+++ b/chromium/third_party/blink/renderer/core/style/computed_style_test.cc
@@ -119,8 +119,8 @@ TEST(ComputedStyleTest, FocusRingOutset) {
TEST(ComputedStyleTest, SVGStackingContext) {
scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
- style->UpdateIsStackingContext(false, false, true);
- EXPECT_TRUE(style->IsStackingContext());
+ style->UpdateIsStackingContextWithoutContainment(false, false, true);
+ EXPECT_TRUE(style->IsStackingContextWithoutContainment());
}
TEST(ComputedStyleTest, Preserve3dForceStackingContext) {
@@ -128,17 +128,18 @@ TEST(ComputedStyleTest, Preserve3dForceStackingContext) {
style->SetTransformStyle3D(ETransformStyle3D::kPreserve3d);
style->SetOverflowX(EOverflow::kHidden);
style->SetOverflowY(EOverflow::kHidden);
- style->UpdateIsStackingContext(false, false, false);
+ style->UpdateIsStackingContextWithoutContainment(false, false, false);
EXPECT_EQ(ETransformStyle3D::kFlat, style->UsedTransformStyle3D());
- EXPECT_TRUE(style->IsStackingContext());
+ EXPECT_TRUE(style->IsStackingContextWithoutContainment());
}
TEST(ComputedStyleTest, LayoutContainmentStackingContext) {
scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
- EXPECT_FALSE(style->IsStackingContext());
+ EXPECT_FALSE(style->IsStackingContextWithoutContainment());
style->SetContain(kContainsLayout);
- style->UpdateIsStackingContext(false, false, false);
- EXPECT_TRUE(style->IsStackingContext());
+ style->UpdateIsStackingContextWithoutContainment(false, false, false);
+ // Containment doesn't change IsStackingContextWithoutContainment
+ EXPECT_FALSE(style->IsStackingContextWithoutContainment());
}
TEST(ComputedStyleTest, FirstPublicPseudoStyle) {
@@ -457,7 +458,7 @@ TEST(ComputedStyleTest, BorderStyle) {
} while (false)
TEST(ComputedStyleTest, AnimationFlags) {
- Persistent<Document> document = MakeGarbageCollected<Document>();
+ Persistent<Document> document = Document::CreateForTest();
TEST_ANIMATION_FLAG(HasCurrentTransformAnimation, kNonInherited);
TEST_ANIMATION_FLAG(HasCurrentOpacityAnimation, kNonInherited);
TEST_ANIMATION_FLAG(HasCurrentFilterAnimation, kNonInherited);
@@ -740,7 +741,8 @@ TEST(ComputedStyleTest, ApplyInternalLightDarkColor) {
ScopedCSSCascadeForTest scoped_cascade_enabled(true);
auto* color_declaration =
- ParseDeclarationBlock("color:-internal-light-dark(black, white)");
+ ParseDeclarationBlock("color:-internal-light-dark(black, white)",
+ CSSParserMode::kUASheetMode);
auto* dark_declaration = ParseDeclarationBlock("color-scheme:dark");
auto* light_declaration = ParseDeclarationBlock("color-scheme:light");
diff --git a/chromium/third_party/blink/renderer/core/style/content_data.cc b/chromium/third_party/blink/renderer/core/style/content_data.cc
index 3ef58f358b1..dea85fb4c13 100644
--- a/chromium/third_party/blink/renderer/core/style/content_data.cc
+++ b/chromium/third_party/blink/renderer/core/style/content_data.cc
@@ -48,7 +48,7 @@ ContentData* ContentData::Clone() const {
return result;
}
-void ContentData::Trace(Visitor* visitor) {
+void ContentData::Trace(Visitor* visitor) const {
visitor->Trace(next_);
}
@@ -67,7 +67,7 @@ LayoutObject* ImageContentData::CreateLayoutObject(
return image;
}
-void ImageContentData::Trace(Visitor* visitor) {
+void ImageContentData::Trace(Visitor* visitor) const {
visitor->Trace(image_);
ContentData::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/style/content_data.h b/chromium/third_party/blink/renderer/core/style/content_data.h
index c381a50dbbe..7f35df66f9f 100644
--- a/chromium/third_party/blink/renderer/core/style/content_data.h
+++ b/chromium/third_party/blink/renderer/core/style/content_data.h
@@ -67,7 +67,7 @@ class ContentData : public GarbageCollected<ContentData> {
virtual bool Equals(const ContentData&) const = 0;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
virtual ContentData* CloneInternal() const = 0;
@@ -102,7 +102,7 @@ class ImageContentData final : public ContentData {
*GetImage();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
ContentData* CloneInternal() const override {
diff --git a/chromium/third_party/blink/renderer/core/style/counter_directives.cc b/chromium/third_party/blink/renderer/core/style/counter_directives.cc
index 9f56e37978d..64506531ff8 100644
--- a/chromium/third_party/blink/renderer/core/style/counter_directives.cc
+++ b/chromium/third_party/blink/renderer/core/style/counter_directives.cc
@@ -26,9 +26,9 @@
namespace blink {
bool operator==(const CounterDirectives& a, const CounterDirectives& b) {
- return a.IsIncrement() == b.IsIncrement() &&
- a.IncrementValue() == b.IncrementValue() &&
- a.IsReset() == b.IsReset() && a.ResetValue() == b.ResetValue();
+ return a.reset_value_ == b.reset_value_ &&
+ a.increment_value_ == b.increment_value_ &&
+ a.set_value_ == b.set_value_;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/style/counter_directives.h b/chromium/third_party/blink/renderer/core/style/counter_directives.h
index cc096ba5e58..1e6ba203d46 100644
--- a/chromium/third_party/blink/renderer/core/style/counter_directives.h
+++ b/chromium/third_party/blink/renderer/core/style/counter_directives.h
@@ -30,6 +30,7 @@
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/numerics/checked_math.h"
+#include "base/optional.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
@@ -42,65 +43,63 @@ class CounterDirectives {
DISALLOW_NEW();
public:
- CounterDirectives()
- : is_reset_set_(false),
- is_increment_set_(false),
- reset_value_(0),
- increment_value_(0) {}
+ CounterDirectives() = default;
// FIXME: The code duplication here could possibly be replaced by using two
// maps, or by using a container that held two generic Directive objects.
- bool IsReset() const { return is_reset_set_; }
- int ResetValue() const { return reset_value_; }
- void SetResetValue(int value) {
- reset_value_ = value;
- is_reset_set_ = true;
- }
- void ClearReset() {
- reset_value_ = 0;
- is_reset_set_ = false;
- }
+ bool IsReset() const { return !!reset_value_; }
+ int ResetValue() const { return *reset_value_; }
+ void SetResetValue(int value) { reset_value_ = value; }
+ void ClearReset() { reset_value_.reset(); }
void InheritReset(const CounterDirectives& parent) {
reset_value_ = parent.reset_value_;
- is_reset_set_ = parent.is_reset_set_;
}
- bool IsIncrement() const { return is_increment_set_; }
- int IncrementValue() const { return increment_value_; }
+ bool IsIncrement() const { return !!increment_value_; }
+ int IncrementValue() const { return *increment_value_; }
void AddIncrementValue(int value) {
- increment_value_ = clampTo<int>((double)increment_value_ + value);
- is_increment_set_ = true;
- }
- void ClearIncrement() {
- increment_value_ = 0;
- is_increment_set_ = false;
+ increment_value_ = clampTo<int>(
+ (increment_value_ ? static_cast<double>(*increment_value_) : 0.0) +
+ value);
}
+ void ClearIncrement() { increment_value_.reset(); }
void InheritIncrement(const CounterDirectives& parent) {
increment_value_ = parent.increment_value_;
- is_increment_set_ = parent.is_increment_set_;
}
- bool IsDefined() const { return IsReset() || IsIncrement(); }
+ bool IsSet() const { return !!set_value_; }
+ int SetValue() const { return *set_value_; }
+ void SetSetValue(int value) { set_value_ = value; }
+ void ClearSet() { set_value_.reset(); }
+ void InheritSet(const CounterDirectives& parent) {
+ set_value_ = parent.set_value_;
+ }
+
+ bool IsDefined() const { return IsReset() || IsIncrement() || IsSet(); }
int CombinedValue() const {
- DCHECK(is_reset_set_ || !reset_value_);
- DCHECK(is_increment_set_ || !increment_value_);
+ // If there is a counter-set, it overrides over values.
+ // https://drafts.csswg.org/css-lists-3/#auto-numbering
+ if (IsSet())
+ return SetValue();
+
// According to the spec, if an increment would overflow or underflow the
// counter, we are allowed to ignore the increment.
// https://drafts.csswg.org/css-lists-3/#valdef-counter-reset-custom-ident-integer
- return base::CheckAdd(reset_value_, increment_value_)
- .ValueOrDefault(reset_value_);
+ return base::CheckAdd(reset_value_.value_or(0),
+ increment_value_.value_or(0))
+ .ValueOrDefault(reset_value_.value_or(0));
}
+ friend bool operator==(const CounterDirectives&, const CounterDirectives&);
+
private:
- bool is_reset_set_;
- bool is_increment_set_;
- int reset_value_;
- int increment_value_;
+ base::Optional<int> reset_value_;
+ base::Optional<int> increment_value_;
+ base::Optional<int> set_value_;
};
-bool operator==(const CounterDirectives&, const CounterDirectives&);
inline bool operator!=(const CounterDirectives& a, const CounterDirectives& b) {
return !(a == b);
}
diff --git a/chromium/third_party/blink/renderer/core/style/cursor_data.h b/chromium/third_party/blink/renderer/core/style/cursor_data.h
index fcd07de43d6..5acb3cfa14b 100644
--- a/chromium/third_party/blink/renderer/core/style/cursor_data.h
+++ b/chromium/third_party/blink/renderer/core/style/cursor_data.h
@@ -56,7 +56,7 @@ class CursorData {
// Hot spot in the image in logical pixels.
const IntPoint& HotSpot() const { return hot_spot_; }
- void Trace(Visitor* visitor) { visitor->Trace(image_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(image_); }
private:
Member<StyleImage> image_;
diff --git a/chromium/third_party/blink/renderer/core/style/fill_layer.cc b/chromium/third_party/blink/renderer/core/style/fill_layer.cc
index 1b0c37c0e6f..232bb81fdee 100644
--- a/chromium/third_party/blink/renderer/core/style/fill_layer.cc
+++ b/chromium/third_party/blink/renderer/core/style/fill_layer.cc
@@ -61,8 +61,6 @@ FillLayer::FillLayer(EFillLayerType type, bool use_initial_values)
? static_cast<unsigned>(FillLayer::InitialFillSizeType(type))
: static_cast<unsigned>(EFillSizeType::kSizeNone)),
blend_mode_(static_cast<unsigned>(FillLayer::InitialFillBlendMode(type))),
- mask_source_type_(
- static_cast<unsigned>(FillLayer::InitialFillMaskSourceType(type))),
background_x_origin_(static_cast<unsigned>(BackgroundEdgeOrigin::kLeft)),
background_y_origin_(static_cast<unsigned>(BackgroundEdgeOrigin::kTop)),
image_set_(use_initial_values),
@@ -77,7 +75,6 @@ FillLayer::FillLayer(EFillLayerType type, bool use_initial_values)
background_y_origin_set_(false),
composite_set_(use_initial_values || type == EFillLayerType::kMask),
blend_mode_set_(use_initial_values),
- mask_source_type_set_(use_initial_values),
type_(static_cast<unsigned>(type)),
layers_clip_max_(0),
any_layer_uses_content_box_(false),
@@ -101,7 +98,6 @@ FillLayer::FillLayer(const FillLayer& o)
composite_(o.composite_),
size_type_(o.size_type_),
blend_mode_(o.blend_mode_),
- mask_source_type_(o.mask_source_type_),
background_x_origin_(o.background_x_origin_),
background_y_origin_(o.background_y_origin_),
image_set_(o.image_set_),
@@ -116,7 +112,6 @@ FillLayer::FillLayer(const FillLayer& o)
background_y_origin_set_(o.background_y_origin_set_),
composite_set_(o.composite_set_),
blend_mode_set_(o.blend_mode_set_),
- mask_source_type_set_(o.mask_source_type_set_),
type_(o.type_),
layers_clip_max_(0),
any_layer_uses_content_box_(false),
@@ -152,7 +147,6 @@ FillLayer& FillLayer::operator=(const FillLayer& o) {
repeat_x_ = o.repeat_x_;
repeat_y_ = o.repeat_y_;
size_type_ = o.size_type_;
- mask_source_type_ = o.mask_source_type_;
image_set_ = o.image_set_;
attachment_set_ = o.attachment_set_;
@@ -164,7 +158,6 @@ FillLayer& FillLayer::operator=(const FillLayer& o) {
repeat_y_set_ = o.repeat_y_set_;
pos_x_set_ = o.pos_x_set_;
pos_y_set_ = o.pos_y_set_;
- mask_source_type_set_ = o.mask_source_type_set_;
type_ = o.type_;
@@ -182,7 +175,6 @@ bool FillLayer::LayerPropertiesEqual(const FillLayer& o) const {
composite_ == o.composite_ && blend_mode_ == o.blend_mode_ &&
origin_ == o.origin_ && repeat_x_ == o.repeat_x_ &&
repeat_y_ == o.repeat_y_ && size_type_ == o.size_type_ &&
- mask_source_type_ == o.mask_source_type_ &&
size_length_ == o.size_length_ && type_ == o.type_;
}
diff --git a/chromium/third_party/blink/renderer/core/style/fill_layer.h b/chromium/third_party/blink/renderer/core/style/fill_layer.h
index b4d9f183c5e..7233c8b3e0b 100644
--- a/chromium/third_party/blink/renderer/core/style/fill_layer.h
+++ b/chromium/third_party/blink/renderer/core/style/fill_layer.h
@@ -87,9 +87,6 @@ class CORE_EXPORT FillLayer {
FillSize Size() const {
return FillSize(static_cast<EFillSizeType>(size_type_), size_length_);
}
- EMaskSourceType MaskSourceType() const {
- return static_cast<EMaskSourceType>(mask_source_type_);
- }
const FillLayer* Next() const { return next_; }
FillLayer* Next() { return next_; }
@@ -114,7 +111,6 @@ class CORE_EXPORT FillLayer {
bool IsSizeSet() const {
return size_type_ != static_cast<unsigned>(EFillSizeType::kSizeNone);
}
- bool IsMaskSourceTypeSet() const { return mask_source_type_set_; }
void SetImage(StyleImage* i) {
image_ = i;
@@ -177,10 +173,6 @@ class CORE_EXPORT FillLayer {
size_type_ = static_cast<unsigned>(f.type);
size_length_ = f.size;
}
- void SetMaskSourceType(EMaskSourceType m) {
- mask_source_type_ = static_cast<unsigned>(m);
- mask_source_type_set_ = true;
- }
void ClearImage() {
image_.Clear();
@@ -205,7 +197,6 @@ class CORE_EXPORT FillLayer {
void ClearSize() {
size_type_ = static_cast<unsigned>(EFillSizeType::kSizeNone);
}
- void ClearMaskSourceType() { mask_source_type_set_ = false; }
FillLayer& operator=(const FillLayer&);
FillLayer(const FillLayer&);
@@ -289,9 +280,6 @@ class CORE_EXPORT FillLayer {
return Length::Percent(0.0);
}
static StyleImage* InitialFillImage(EFillLayerType) { return nullptr; }
- static EMaskSourceType InitialFillMaskSourceType(EFillLayerType) {
- return EMaskSourceType::kAlpha;
- }
private:
friend class ComputedStyle;
@@ -325,7 +313,6 @@ class CORE_EXPORT FillLayer {
unsigned composite_ : 4; // CompositeOperator
unsigned size_type_ : 2; // EFillSizeType
unsigned blend_mode_ : 5; // BlendMode
- unsigned mask_source_type_ : 1; // EMaskSourceType
unsigned background_x_origin_ : 2; // BackgroundEdgeOrigin
unsigned background_y_origin_ : 2; // BackgroundEdgeOrigin
@@ -341,7 +328,6 @@ class CORE_EXPORT FillLayer {
unsigned background_y_origin_set_ : 1;
unsigned composite_set_ : 1;
unsigned blend_mode_set_ : 1;
- unsigned mask_source_type_set_ : 1;
unsigned type_ : 1; // EFillLayerType
diff --git a/chromium/third_party/blink/renderer/core/style/filter_operation.cc b/chromium/third_party/blink/renderer/core/style/filter_operation.cc
index a3c22480f25..e8d60dd3f54 100644
--- a/chromium/third_party/blink/renderer/core/style/filter_operation.cc
+++ b/chromium/third_party/blink/renderer/core/style/filter_operation.cc
@@ -35,16 +35,7 @@
namespace blink {
-FilterOperation* FilterOperation::Blend(const FilterOperation* from,
- const FilterOperation* to,
- double progress) {
- DCHECK(from || to);
- if (to)
- return to->Blend(from, progress);
- return from->Blend(nullptr, 1 - progress);
-}
-
-void ReferenceFilterOperation::Trace(Visitor* visitor) {
+void ReferenceFilterOperation::Trace(Visitor* visitor) const {
visitor->Trace(resource_);
visitor->Trace(filter_);
FilterOperation::Trace(visitor);
@@ -78,132 +69,22 @@ bool ReferenceFilterOperation::operator==(const FilterOperation& o) const {
return url_ == other.url_ && resource_ == other.resource_;
}
-FilterOperation* BasicColorMatrixFilterOperation::Blend(
- const FilterOperation* from,
- double progress) const {
- double from_amount;
- if (from) {
- SECURITY_DCHECK(from->IsSameType(*this));
- from_amount = To<BasicColorMatrixFilterOperation>(from)->Amount();
- } else {
- switch (type_) {
- case GRAYSCALE:
- case SEPIA:
- case HUE_ROTATE:
- from_amount = 0;
- break;
- case SATURATE:
- from_amount = 1;
- break;
- default:
- from_amount = 0;
- NOTREACHED();
- }
- }
-
- double result = blink::Blend(from_amount, amount_, progress);
- switch (type_) {
- case HUE_ROTATE:
- break;
- case GRAYSCALE:
- case SEPIA:
- result = clampTo<double>(result, 0, 1);
- break;
- case SATURATE:
- result = clampTo<double>(result, 0);
- break;
- default:
- NOTREACHED();
- }
- return MakeGarbageCollected<BasicColorMatrixFilterOperation>(result, type_);
-}
-
-FilterOperation* BasicComponentTransferFilterOperation::Blend(
- const FilterOperation* from,
- double progress) const {
- double from_amount;
- if (from) {
- SECURITY_DCHECK(from->IsSameType(*this));
- from_amount = To<BasicComponentTransferFilterOperation>(from)->Amount();
- } else {
- switch (type_) {
- case OPACITY:
- case CONTRAST:
- case BRIGHTNESS:
- from_amount = 1;
- break;
- case INVERT:
- from_amount = 0;
- break;
- default:
- from_amount = 0;
- NOTREACHED();
- }
- }
-
- double result = blink::Blend(from_amount, amount_, progress);
- switch (type_) {
- case BRIGHTNESS:
- case CONTRAST:
- result = clampTo<double>(result, 0);
- break;
- case INVERT:
- case OPACITY:
- result = clampTo<double>(result, 0, 1);
- break;
- default:
- NOTREACHED();
- }
- return MakeGarbageCollected<BasicComponentTransferFilterOperation>(result,
- type_);
-}
-
FloatRect BlurFilterOperation::MapRect(const FloatRect& rect) const {
float std_deviation = FloatValueForLength(std_deviation_, 0);
return FEGaussianBlur::MapEffect(FloatSize(std_deviation, std_deviation),
rect);
}
-FilterOperation* BlurFilterOperation::Blend(const FilterOperation* from,
- double progress) const {
- Length::Type length_type = std_deviation_.GetType();
- if (!from)
- return MakeGarbageCollected<BlurFilterOperation>(std_deviation_.Blend(
- Length(length_type), progress, kValueRangeNonNegative));
-
- const auto* from_op = To<BlurFilterOperation>(from);
- return MakeGarbageCollected<BlurFilterOperation>(std_deviation_.Blend(
- from_op->std_deviation_, progress, kValueRangeNonNegative));
-}
-
FloatRect DropShadowFilterOperation::MapRect(const FloatRect& rect) const {
float std_deviation = shadow_.Blur();
return FEDropShadow::MapEffect(FloatSize(std_deviation, std_deviation),
shadow_.Location(), rect);
}
-FilterOperation* DropShadowFilterOperation::Blend(const FilterOperation* from,
- double progress) const {
- if (!from) {
- return MakeGarbageCollected<DropShadowFilterOperation>(shadow_.Blend(
- ShadowData::NeutralValue(), progress, Color::kTransparent));
- }
-
- const auto& from_op = To<DropShadowFilterOperation>(*from);
- return MakeGarbageCollected<DropShadowFilterOperation>(
- shadow_.Blend(from_op.shadow_, progress, Color::kTransparent));
-}
-
FloatRect BoxReflectFilterOperation::MapRect(const FloatRect& rect) const {
return reflection_.MapRect(rect);
}
-FilterOperation* BoxReflectFilterOperation::Blend(const FilterOperation* from,
- double progress) const {
- NOTREACHED();
- return nullptr;
-}
-
bool BoxReflectFilterOperation::operator==(const FilterOperation& o) const {
if (!IsSameType(o))
return false;
diff --git a/chromium/third_party/blink/renderer/core/style/filter_operation.h b/chromium/third_party/blink/renderer/core/style/filter_operation.h
index 78dace4e737..6b855675aea 100644
--- a/chromium/third_party/blink/renderer/core/style/filter_operation.h
+++ b/chromium/third_party/blink/renderer/core/style/filter_operation.h
@@ -87,11 +87,8 @@ class CORE_EXPORT FilterOperation : public GarbageCollected<FilterOperation> {
}
virtual ~FilterOperation() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
- static FilterOperation* Blend(const FilterOperation* from,
- const FilterOperation* to,
- double progress);
virtual bool operator==(const FilterOperation&) const = 0;
bool operator!=(const FilterOperation& o) const { return !(*this == o); }
@@ -117,8 +114,6 @@ class CORE_EXPORT FilterOperation : public GarbageCollected<FilterOperation> {
OperationType type_;
private:
- virtual FilterOperation* Blend(const FilterOperation* from,
- double progress) const = 0;
DISALLOW_COPY_AND_ASSIGN(FilterOperation);
};
@@ -140,15 +135,9 @@ class CORE_EXPORT ReferenceFilterOperation : public FilterOperation {
void AddClient(SVGResourceClient&);
void RemoveClient(SVGResourceClient&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
- FilterOperation* Blend(const FilterOperation* from,
- double progress) const override {
- NOTREACHED();
- return nullptr;
- }
-
bool operator==(const FilterOperation&) const override;
AtomicString url_;
@@ -173,8 +162,6 @@ class CORE_EXPORT BasicColorMatrixFilterOperation : public FilterOperation {
double Amount() const { return amount_; }
private:
- FilterOperation* Blend(const FilterOperation* from,
- double progress) const override;
bool operator==(const FilterOperation& o) const override {
if (!IsSameType(o))
return false;
@@ -214,8 +201,6 @@ class CORE_EXPORT BasicComponentTransferFilterOperation
bool AffectsOpacity() const override { return type_ == OPACITY; }
private:
- FilterOperation* Blend(const FilterOperation* from,
- double progress) const override;
bool operator==(const FilterOperation& o) const override {
if (!IsSameType(o))
return false;
@@ -254,8 +239,6 @@ class CORE_EXPORT BlurFilterOperation : public FilterOperation {
FloatRect MapRect(const FloatRect&) const override;
private:
- FilterOperation* Blend(const FilterOperation* from,
- double progress) const override;
bool operator==(const FilterOperation& o) const override {
if (!IsSameType(o))
return false;
@@ -286,8 +269,6 @@ class CORE_EXPORT DropShadowFilterOperation : public FilterOperation {
FloatRect MapRect(const FloatRect&) const override;
private:
- FilterOperation* Blend(const FilterOperation* from,
- double progress) const override;
bool operator==(const FilterOperation& o) const override {
if (!IsSameType(o))
return false;
@@ -318,8 +299,6 @@ class CORE_EXPORT BoxReflectFilterOperation : public FilterOperation {
FloatRect MapRect(const FloatRect&) const override;
private:
- FilterOperation* Blend(const FilterOperation* from,
- double progress) const override;
bool operator==(const FilterOperation&) const override;
BoxReflection reflection_;
diff --git a/chromium/third_party/blink/renderer/core/style/filter_operations.cc b/chromium/third_party/blink/renderer/core/style/filter_operations.cc
index e0f03d3a438..c583faf46fc 100644
--- a/chromium/third_party/blink/renderer/core/style/filter_operations.cc
+++ b/chromium/third_party/blink/renderer/core/style/filter_operations.cc
@@ -31,7 +31,7 @@ namespace blink {
FilterOperations::FilterOperations() = default;
-void FilterOperations::Trace(Visitor* visitor) {
+void FilterOperations::Trace(Visitor* visitor) const {
visitor->Trace(operations_);
}
@@ -91,6 +91,13 @@ bool FilterOperations::HasFilterThatMovesPixels() const {
[](const auto& operation) { return operation->MovesPixels(); });
}
+bool FilterOperations::HasReferenceFilter() const {
+ return std::any_of(
+ operations_.begin(), operations_.end(), [](const auto& operation) {
+ return operation->GetType() == FilterOperation::REFERENCE;
+ });
+}
+
void FilterOperations::AddClient(SVGResourceClient& client) const {
for (FilterOperation* operation : operations_) {
if (operation->GetType() == FilterOperation::REFERENCE)
diff --git a/chromium/third_party/blink/renderer/core/style/filter_operations.h b/chromium/third_party/blink/renderer/core/style/filter_operations.h
index 7e1f4f20a02..e80a2d172e7 100644
--- a/chromium/third_party/blink/renderer/core/style/filter_operations.h
+++ b/chromium/third_party/blink/renderer/core/style/filter_operations.h
@@ -69,11 +69,12 @@ class CORE_EXPORT FilterOperations {
bool HasFilterThatAffectsOpacity() const;
bool HasFilterThatMovesPixels() const;
+ bool HasReferenceFilter() const;
void AddClient(SVGResourceClient&) const;
void RemoveClient(SVGResourceClient&) const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
FilterOperationVector operations_;
@@ -89,7 +90,7 @@ class FilterOperationsWrapper
const FilterOperations& Operations() const { return operations_; }
- void Trace(Visitor* visitor) { visitor->Trace(operations_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(operations_); }
private:
FilterOperations operations_;
diff --git a/chromium/third_party/blink/renderer/core/style/gap_length.h b/chromium/third_party/blink/renderer/core/style/gap_length.h
deleted file mode 100644
index d0a356f1a6a..00000000000
--- a/chromium/third_party/blink/renderer/core/style/gap_length.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_GAP_LENGTH_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_GAP_LENGTH_H_
-
-#include "third_party/blink/renderer/platform/geometry/length.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class GapLength {
- DISALLOW_NEW();
-
- public:
- GapLength() : is_normal_(true) {}
- GapLength(const Length& length) : is_normal_(false), length_(length) {
- DCHECK(length.IsSpecified());
- }
-
- bool IsNormal() const { return is_normal_; }
- const Length& GetLength() const {
- DCHECK(!IsNormal());
- return length_;
- }
-
- bool operator==(const GapLength& o) const {
- return is_normal_ == o.is_normal_ && length_ == o.length_;
- }
-
- bool operator!=(const GapLength& o) const {
- return is_normal_ != o.is_normal_ || length_ != o.length_;
- }
-
- private:
- bool is_normal_;
- Length length_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_GAP_LENGTH_H_
diff --git a/chromium/third_party/blink/renderer/core/style/shadow_data.cc b/chromium/third_party/blink/renderer/core/style/shadow_data.cc
index ea0d0c0e6ce..2dc12f440e6 100644
--- a/chromium/third_party/blink/renderer/core/style/shadow_data.cc
+++ b/chromium/third_party/blink/renderer/core/style/shadow_data.cc
@@ -33,17 +33,6 @@ bool ShadowData::operator==(const ShadowData& o) const {
style_ == o.style_ && color_ == o.color_;
}
-ShadowData ShadowData::Blend(const ShadowData& from,
- double progress,
- const Color& current_color) const {
- DCHECK_EQ(Style(), from.Style());
- return ShadowData(blink::Blend(from.Location(), Location(), progress),
- clampTo(blink::Blend(from.Blur(), Blur(), progress), 0.0f),
- blink::Blend(from.Spread(), Spread(), progress), Style(),
- blink::Blend(from.GetColor().Resolve(current_color),
- GetColor().Resolve(current_color), progress));
-}
-
ShadowData ShadowData::NeutralValue() {
return ShadowData(FloatPoint(0, 0), 0, 0, kNormal,
StyleColor(Color::kTransparent));
diff --git a/chromium/third_party/blink/renderer/core/style/shadow_data.h b/chromium/third_party/blink/renderer/core/style/shadow_data.h
index 495b9acb7da..be718e3c62d 100644
--- a/chromium/third_party/blink/renderer/core/style/shadow_data.h
+++ b/chromium/third_party/blink/renderer/core/style/shadow_data.h
@@ -55,9 +55,6 @@ class CORE_EXPORT ShadowData {
bool operator==(const ShadowData&) const;
bool operator!=(const ShadowData& o) const { return !(*this == o); }
- ShadowData Blend(const ShadowData& from,
- double progress,
- const Color& current_color) const;
static ShadowData NeutralValue();
float X() const { return location_.X(); }
diff --git a/chromium/third_party/blink/renderer/core/style/shape_value.h b/chromium/third_party/blink/renderer/core/style/shape_value.h
index c416b4bd49c..01c84eed0ae 100644
--- a/chromium/third_party/blink/renderer/core/style/shape_value.h
+++ b/chromium/third_party/blink/renderer/core/style/shape_value.h
@@ -68,7 +68,7 @@ class ShapeValue final : public GarbageCollected<ShapeValue> {
bool operator==(const ShapeValue& other) const;
- virtual void Trace(Visitor* visitor) { visitor->Trace(image_); }
+ virtual void Trace(Visitor* visitor) const { visitor->Trace(image_); }
private:
ShapeValueType type_;
diff --git a/chromium/third_party/blink/renderer/core/style/style_difference.cc b/chromium/third_party/blink/renderer/core/style/style_difference.cc
index 76f510c2a30..04f0d3006a3 100644
--- a/chromium/third_party/blink/renderer/core/style/style_difference.cc
+++ b/chromium/third_party/blink/renderer/core/style/style_difference.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/style/style_difference.h"
+#include "base/notreached.h"
+
namespace blink {
std::ostream& operator<<(std::ostream& out, const StyleDifference& diff) {
diff --git a/chromium/third_party/blink/renderer/core/style/style_fetched_image.cc b/chromium/third_party/blink/renderer/core/style/style_fetched_image.cc
index a029869c544..63006da9bab 100644
--- a/chromium/third_party/blink/renderer/core/style/style_fetched_image.cc
+++ b/chromium/third_party/blink/renderer/core/style/style_fetched_image.cc
@@ -195,7 +195,7 @@ bool StyleFetchedImage::GetImageAnimationPolicy(ImageAnimationPolicy& policy) {
return true;
}
-void StyleFetchedImage::Trace(Visitor* visitor) {
+void StyleFetchedImage::Trace(Visitor* visitor) const {
visitor->Trace(image_);
visitor->Trace(document_);
StyleImage::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/style/style_fetched_image.h b/chromium/third_party/blink/renderer/core/style/style_fetched_image.h
index fed3be5dda2..0c160297fcb 100644
--- a/chromium/third_party/blink/renderer/core/style/style_fetched_image.h
+++ b/chromium/third_party/blink/renderer/core/style/style_fetched_image.h
@@ -74,7 +74,7 @@ class StyleFetchedImage final : public StyleImage,
void LoadDeferredImage(const Document& document);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool IsEqual(const StyleImage&) const override;
diff --git a/chromium/third_party/blink/renderer/core/style/style_fetched_image_set.cc b/chromium/third_party/blink/renderer/core/style/style_fetched_image_set.cc
index 187b447aa94..632281d59ba 100644
--- a/chromium/third_party/blink/renderer/core/style/style_fetched_image_set.cc
+++ b/chromium/third_party/blink/renderer/core/style/style_fetched_image_set.cc
@@ -143,7 +143,7 @@ bool StyleFetchedImageSet::KnownToBeOpaque(const Document&,
return best_fit_image_->GetImage()->CurrentFrameKnownToBeOpaque();
}
-void StyleFetchedImageSet::Trace(Visitor* visitor) {
+void StyleFetchedImageSet::Trace(Visitor* visitor) const {
visitor->Trace(best_fit_image_);
visitor->Trace(image_set_value_);
StyleImage::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/style/style_fetched_image_set.h b/chromium/third_party/blink/renderer/core/style/style_fetched_image_set.h
index 4b9b9275ae3..f01558c1c7c 100644
--- a/chromium/third_party/blink/renderer/core/style/style_fetched_image_set.h
+++ b/chromium/third_party/blink/renderer/core/style/style_fetched_image_set.h
@@ -80,7 +80,7 @@ class StyleFetchedImageSet final : public StyleImage,
bool KnownToBeOpaque(const Document&, const ComputedStyle&) const override;
ImageResourceContent* CachedImage() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool IsEqual(const StyleImage& other) const override;
diff --git a/chromium/third_party/blink/renderer/core/style/style_filter_data.h b/chromium/third_party/blink/renderer/core/style/style_filter_data.h
index 7c441074556..be87273a01d 100644
--- a/chromium/third_party/blink/renderer/core/style/style_filter_data.h
+++ b/chromium/third_party/blink/renderer/core/style/style_filter_data.h
@@ -43,7 +43,7 @@ class StyleFilterData final : public GarbageCollected<StyleFilterData> {
bool operator==(const StyleFilterData&) const;
bool operator!=(const StyleFilterData& o) const { return !(*this == o); }
- void Trace(Visitor* visitor) { visitor->Trace(operations_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(operations_); }
FilterOperations operations_;
};
diff --git a/chromium/third_party/blink/renderer/core/style/style_generated_image.cc b/chromium/third_party/blink/renderer/core/style/style_generated_image.cc
index 28764bd5896..1b0148ca70d 100644
--- a/chromium/third_party/blink/renderer/core/style/style_generated_image.cc
+++ b/chromium/third_party/blink/renderer/core/style/style_generated_image.cc
@@ -99,7 +99,7 @@ bool StyleGeneratedImage::KnownToBeOpaque(const Document& document,
return image_generator_value_->KnownToBeOpaque(document, style);
}
-void StyleGeneratedImage::Trace(Visitor* visitor) {
+void StyleGeneratedImage::Trace(Visitor* visitor) const {
visitor->Trace(image_generator_value_);
StyleImage::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/style/style_generated_image.h b/chromium/third_party/blink/renderer/core/style/style_generated_image.h
index 2cfdc6e236f..f1b708f7bf1 100644
--- a/chromium/third_party/blink/renderer/core/style/style_generated_image.h
+++ b/chromium/third_party/blink/renderer/core/style/style_generated_image.h
@@ -64,7 +64,7 @@ class CORE_EXPORT StyleGeneratedImage final : public StyleImage {
bool IsUsingCustomProperty(const AtomicString& custom_property_name,
const Document&) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool IsEqual(const StyleImage&) const override;
diff --git a/chromium/third_party/blink/renderer/core/style/style_image.h b/chromium/third_party/blink/renderer/core/style/style_image.h
index 6c25142c4d2..c0fa8eff995 100644
--- a/chromium/third_party/blink/renderer/core/style/style_image.h
+++ b/chromium/third_party/blink/renderer/core/style/style_image.h
@@ -146,7 +146,7 @@ class CORE_EXPORT StyleImage : public GarbageCollected<StyleImage> {
return is_lazyload_possibly_deferred_;
}
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
StyleImage()
diff --git a/chromium/third_party/blink/renderer/core/style/style_name.h b/chromium/third_party/blink/renderer/core/style/style_name.h
new file mode 100644
index 00000000000..1604bd17be3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/style/style_name.h
@@ -0,0 +1,43 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_NAME_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_NAME_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
+
+namespace blink {
+
+// Represents any named entity, provided by e.g. <custom-ident> | <string>.
+//
+// The StyleName will remember whether it came from a <custom-ident> or a
+// a <string>, such that it can be serialized accordingly.
+class CORE_EXPORT StyleName {
+ public:
+ enum class Type { kCustomIdent, kString };
+
+ StyleName() = default;
+ explicit StyleName(const AtomicString& value, Type type)
+ : type_(type), value_(value) {}
+
+ Type GetType() const { return type_; }
+
+ bool IsCustomIdent() const { return type_ == Type::kCustomIdent; }
+
+ const AtomicString& GetValue() const { return value_; }
+
+ bool operator==(const StyleName& other) const {
+ return type_ == other.type_ && value_ == other.value_;
+ }
+ bool operator!=(const StyleName& other) const { return !(*this == other); }
+
+ private:
+ Type type_ = Type::kString;
+ AtomicString value_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_NAME_H_
diff --git a/chromium/third_party/blink/renderer/core/style/style_name_or_keyword.h b/chromium/third_party/blink/renderer/core/style/style_name_or_keyword.h
new file mode 100644
index 00000000000..3f2e99cb971
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/style/style_name_or_keyword.h
@@ -0,0 +1,48 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_NAME_OR_KEYWORD_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_NAME_OR_KEYWORD_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/css_value_keywords.h"
+#include "third_party/blink/renderer/core/style/style_name.h"
+
+namespace blink {
+
+class CORE_EXPORT StyleNameOrKeyword {
+ public:
+ explicit StyleNameOrKeyword(StyleName name)
+ : keyword_(CSSValueID::kInvalid), name_(name) {}
+ explicit StyleNameOrKeyword(CSSValueID keyword) : keyword_(keyword) {
+ DCHECK_NE(keyword, CSSValueID::kInvalid);
+ }
+
+ bool IsKeyword() const { return keyword_ != CSSValueID::kInvalid; }
+
+ CSSValueID GetKeyword() const {
+ DCHECK(IsKeyword());
+ return keyword_;
+ }
+
+ const StyleName& GetName() const {
+ DCHECK(!IsKeyword());
+ return name_;
+ }
+
+ bool operator==(const StyleNameOrKeyword& other) const {
+ return keyword_ == other.keyword_ && name_ == other.name_;
+ }
+ bool operator!=(const StyleNameOrKeyword& other) const {
+ return !(*this == other);
+ }
+
+ private:
+ CSSValueID keyword_;
+ StyleName name_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_NAME_OR_KEYWORD_H_
diff --git a/chromium/third_party/blink/renderer/core/style/style_name_or_keyword_test.cc b/chromium/third_party/blink/renderer/core/style/style_name_or_keyword_test.cc
new file mode 100644
index 00000000000..0a83044c0c6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/style/style_name_or_keyword_test.cc
@@ -0,0 +1,46 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/style/style_name_or_keyword.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+TEST(StyleNameOrKeywordTest, StyleName) {
+ StyleName name_custom_ident("foo", StyleName::Type::kCustomIdent);
+ StyleName name_string("foo", StyleName::Type::kString);
+
+ EXPECT_FALSE(StyleNameOrKeyword(name_custom_ident).IsKeyword());
+ EXPECT_FALSE(StyleNameOrKeyword(name_string).IsKeyword());
+
+ EXPECT_EQ(name_custom_ident, StyleNameOrKeyword(name_custom_ident).GetName());
+ EXPECT_EQ(name_string, StyleNameOrKeyword(name_string).GetName());
+}
+
+TEST(StyleNameOrKeywordTest, Keyword) {
+ EXPECT_TRUE(StyleNameOrKeyword(CSSValueID::kAuto).IsKeyword());
+ EXPECT_TRUE(StyleNameOrKeyword(CSSValueID::kNone).IsKeyword());
+
+ EXPECT_EQ(CSSValueID::kAuto,
+ StyleNameOrKeyword(CSSValueID::kAuto).GetKeyword());
+ EXPECT_EQ(CSSValueID::kNone,
+ StyleNameOrKeyword(CSSValueID::kNone).GetKeyword());
+}
+
+TEST(StyleNameOrKeywordTest, Equality) {
+ StyleName name_custom_ident("foo", StyleName::Type::kCustomIdent);
+ StyleName name_string("foo", StyleName::Type::kString);
+
+ EXPECT_EQ(StyleNameOrKeyword(CSSValueID::kAuto),
+ StyleNameOrKeyword(CSSValueID::kAuto));
+ EXPECT_EQ(StyleNameOrKeyword(name_string), StyleNameOrKeyword(name_string));
+ EXPECT_EQ(StyleNameOrKeyword(name_custom_ident),
+ StyleNameOrKeyword(name_custom_ident));
+ EXPECT_NE(StyleNameOrKeyword(name_custom_ident),
+ StyleNameOrKeyword(name_string));
+ EXPECT_NE(StyleNameOrKeyword(CSSValueID::kAuto),
+ StyleNameOrKeyword(CSSValueID::kNone));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/style/style_name_test.cc b/chromium/third_party/blink/renderer/core/style/style_name_test.cc
new file mode 100644
index 00000000000..86e59ad8408
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/style/style_name_test.cc
@@ -0,0 +1,54 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/style/style_name.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+TEST(StyleNameTest, DefaultConstructor) {
+ StyleName name;
+ EXPECT_FALSE(name.IsCustomIdent());
+ EXPECT_TRUE(name.GetValue().IsNull());
+}
+
+TEST(StyleNameTest, Copy) {
+ StyleName name_string("foo", StyleName::Type::kString);
+ StyleName name_custom_ident("foo", StyleName::Type::kCustomIdent);
+
+ StyleName name_string_copy1(name_string);
+ StyleName name_custom_ident_copy1(name_custom_ident);
+
+ StyleName name_string_copy2 = name_string;
+ StyleName name_custom_ident_copy2 = name_custom_ident;
+
+ EXPECT_EQ(name_string, name_string_copy1);
+ EXPECT_EQ(name_string, name_string_copy2);
+
+ EXPECT_EQ(name_custom_ident, name_custom_ident_copy1);
+ EXPECT_EQ(name_custom_ident, name_custom_ident_copy2);
+}
+
+TEST(StyleNameTest, CustomIdent) {
+ StyleName name("foo", StyleName::Type::kCustomIdent);
+ EXPECT_TRUE(name.IsCustomIdent());
+ EXPECT_EQ("foo", name.GetValue());
+}
+
+TEST(StyleNameTest, String) {
+ StyleName name("foo", StyleName::Type::kString);
+ EXPECT_FALSE(name.IsCustomIdent());
+ EXPECT_EQ("foo", name.GetValue());
+}
+
+TEST(StyleNameTest, Equals) {
+ EXPECT_EQ(StyleName("foo", StyleName::Type::kString),
+ StyleName("foo", StyleName::Type::kString));
+ EXPECT_NE(StyleName("foo", StyleName::Type::kString),
+ StyleName("bar", StyleName::Type::kString));
+ EXPECT_NE(StyleName("foo", StyleName::Type::kString),
+ StyleName("foo", StyleName::Type::kCustomIdent));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/style/style_pending_image.cc b/chromium/third_party/blink/renderer/core/style/style_pending_image.cc
new file mode 100644
index 00000000000..68468ada2a8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/style/style_pending_image.cc
@@ -0,0 +1,26 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/style/style_pending_image.h"
+
+#include "third_party/blink/renderer/core/style/computed_style.h"
+
+namespace blink {
+
+CSSValue* StylePendingImage::ComputedCSSValue(const ComputedStyle& style,
+ bool allow_visited_style) const {
+ DCHECK(style.IsEnsuredInDisplayNone() ||
+ style.Display() == EDisplay::kContents);
+
+ if (CSSImageValue* image_value = CssImageValue())
+ return image_value->ValueWithURLMadeAbsolute();
+ if (CSSImageSetValue* image_set_value = CssImageSetValue())
+ return image_set_value->ValueWithURLsMadeAbsolute();
+ if (CSSImageGeneratorValue* image_generator_value = CssImageGeneratorValue())
+ return image_generator_value->ComputedCSSValue(style, allow_visited_style);
+ NOTREACHED();
+ return CssValue();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/style/style_pending_image.h b/chromium/third_party/blink/renderer/core/style/style_pending_image.h
index 5d15580d62e..ff28692bbd9 100644
--- a/chromium/third_party/blink/renderer/core/style/style_pending_image.h
+++ b/chromium/third_party/blink/renderer/core/style/style_pending_image.h
@@ -40,8 +40,9 @@ class ImageResourceObserver;
// StylePendingImage is a placeholder StyleImage that is entered into the
// ComputedStyle during style resolution, in order to avoid loading images that
-// are not referenced by the final style. They should never exist in a
-// ComputedStyle after it has been returned from the style selector.
+// are not referenced by the final style. They should only exist in a
+// ComputedStyle for non-rendered elements created with EnsureComputedStyle or
+// display:contents.
class StylePendingImage final : public StyleImage {
public:
explicit StylePendingImage(const CSSValue& value)
@@ -53,11 +54,8 @@ class StylePendingImage final : public StyleImage {
CSSValue* CssValue() const override { return value_; }
- CSSValue* ComputedCSSValue(const ComputedStyle&,
- bool allow_visited_style) const override {
- NOTREACHED();
- return nullptr;
- }
+ CSSValue* ComputedCSSValue(const ComputedStyle& style,
+ bool allow_visited_style) const override;
CSSImageValue* CssImageValue() const {
return DynamicTo<CSSImageValue>(value_.Get());
@@ -92,7 +90,7 @@ class StylePendingImage final : public StyleImage {
return false;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(value_);
StyleImage::Trace(visitor);
}
@@ -100,8 +98,6 @@ class StylePendingImage final : public StyleImage {
private:
bool IsEqual(const StyleImage& other) const override;
- // TODO(sashab): Replace this with <const CSSValue> once Member<>
- // supports const types.
Member<CSSValue> value_;
};
diff --git a/chromium/third_party/blink/renderer/core/style/style_ray.cc b/chromium/third_party/blink/renderer/core/style/style_ray.cc
index 891b1946f35..3d6b5d6af68 100644
--- a/chromium/third_party/blink/renderer/core/style/style_ray.cc
+++ b/chromium/third_party/blink/renderer/core/style/style_ray.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/style/style_ray.h"
+#include "base/notreached.h"
+
namespace blink {
scoped_refptr<StyleRay> StyleRay::Create(float angle,
diff --git a/chromium/third_party/blink/renderer/core/style/svg_computed_style.cc b/chromium/third_party/blink/renderer/core/style/svg_computed_style.cc
index de38223180b..e7d26e458dc 100644
--- a/chromium/third_party/blink/renderer/core/style/svg_computed_style.cc
+++ b/chromium/third_party/blink/renderer/core/style/svg_computed_style.cc
@@ -208,12 +208,8 @@ bool SVGComputedStyle::DiffNeedsPaintInvalidation(
// Painting related properties only need paint invalidation.
if (misc.Get() != other.misc.Get()) {
if (misc->flood_color != other.misc->flood_color ||
- misc->flood_color_is_current_color !=
- other.misc->flood_color_is_current_color ||
misc->flood_opacity != other.misc->flood_opacity ||
- misc->lighting_color != other.misc->lighting_color ||
- misc->lighting_color_is_current_color !=
- other.misc->lighting_color_is_current_color)
+ misc->lighting_color != other.misc->lighting_color)
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/style/svg_computed_style.h b/chromium/third_party/blink/renderer/core/style/svg_computed_style.h
index f5d3a27411a..b46d52fe893 100644
--- a/chromium/third_party/blink/renderer/core/style/svg_computed_style.h
+++ b/chromium/third_party/blink/renderer/core/style/svg_computed_style.h
@@ -248,17 +248,14 @@ class SVGComputedStyle : public RefCounted<SVGComputedStyle> {
void SetFloodColor(const StyleColor& style_color) {
if (FloodColor() != style_color) {
StyleMiscData* mutable_misc = misc.Access();
- mutable_misc->flood_color = style_color.Resolve(Color());
- mutable_misc->flood_color_is_current_color = style_color.IsCurrentColor();
+ mutable_misc->flood_color = style_color;
}
}
void SetLightingColor(const StyleColor& style_color) {
if (LightingColor() != style_color) {
StyleMiscData* mutable_misc = misc.Access();
- mutable_misc->lighting_color = style_color.Resolve(Color());
- mutable_misc->lighting_color_is_current_color =
- style_color.IsCurrentColor();
+ mutable_misc->lighting_color = style_color;
}
}
@@ -325,15 +322,8 @@ class SVGComputedStyle : public RefCounted<SVGComputedStyle> {
float StopOpacity() const { return stops->opacity; }
const StyleColor& StopColor() const { return stops->color; }
float FloodOpacity() const { return misc->flood_opacity; }
- StyleColor FloodColor() const {
- return misc->flood_color_is_current_color ? StyleColor::CurrentColor()
- : StyleColor(misc->flood_color);
- }
- StyleColor LightingColor() const {
- return misc->lighting_color_is_current_color
- ? StyleColor::CurrentColor()
- : StyleColor(misc->lighting_color);
- }
+ StyleColor FloodColor() const { return misc->flood_color; }
+ StyleColor LightingColor() const { return misc->lighting_color; }
const Length& BaselineShiftValue() const {
return misc->baseline_shift_value;
}
diff --git a/chromium/third_party/blink/renderer/core/style/svg_computed_style_defs.cc b/chromium/third_party/blink/renderer/core/style/svg_computed_style_defs.cc
index fb02ba1479f..b578cb8b4e0 100644
--- a/chromium/third_party/blink/renderer/core/style/svg_computed_style_defs.cc
+++ b/chromium/third_party/blink/renderer/core/style/svg_computed_style_defs.cc
@@ -107,27 +107,20 @@ StyleMiscData::StyleMiscData()
: baseline_shift_value(SVGComputedStyle::InitialBaselineShiftValue()),
flood_color(SVGComputedStyle::InitialFloodColor()),
lighting_color(SVGComputedStyle::InitialLightingColor()),
- flood_opacity(SVGComputedStyle::InitialFloodOpacity()),
- flood_color_is_current_color(false),
- lighting_color_is_current_color(false) {}
+ flood_opacity(SVGComputedStyle::InitialFloodOpacity()) {}
StyleMiscData::StyleMiscData(const StyleMiscData& other)
: RefCounted<StyleMiscData>(),
baseline_shift_value(other.baseline_shift_value),
flood_color(other.flood_color),
lighting_color(other.lighting_color),
- flood_opacity(other.flood_opacity),
- flood_color_is_current_color(other.flood_color_is_current_color),
- lighting_color_is_current_color(other.lighting_color_is_current_color) {}
+ flood_opacity(other.flood_opacity) {}
bool StyleMiscData::operator==(const StyleMiscData& other) const {
return flood_color == other.flood_color &&
lighting_color == other.lighting_color &&
baseline_shift_value == other.baseline_shift_value &&
- flood_opacity == other.flood_opacity &&
- flood_color_is_current_color == other.flood_color_is_current_color &&
- lighting_color_is_current_color ==
- other.lighting_color_is_current_color;
+ flood_opacity == other.flood_opacity;
}
StyleResourceData::StyleResourceData()
diff --git a/chromium/third_party/blink/renderer/core/style/svg_computed_style_defs.h b/chromium/third_party/blink/renderer/core/style/svg_computed_style_defs.h
index 33f2bcf35ef..217720bdda5 100644
--- a/chromium/third_party/blink/renderer/core/style/svg_computed_style_defs.h
+++ b/chromium/third_party/blink/renderer/core/style/svg_computed_style_defs.h
@@ -282,14 +282,11 @@ class CORE_EXPORT StyleMiscData : public RefCounted<StyleMiscData> {
Length baseline_shift_value;
- Color flood_color;
- Color lighting_color;
+ StyleColor flood_color;
+ StyleColor lighting_color;
float flood_opacity;
- bool flood_color_is_current_color;
- bool lighting_color_is_current_color;
-
private:
StyleMiscData();
StyleMiscData(const StyleMiscData&);
diff --git a/chromium/third_party/blink/renderer/core/style/text_decoration_thickness.cc b/chromium/third_party/blink/renderer/core/style/text_decoration_thickness.cc
index 0e98a748385..e924e0795b6 100644
--- a/chromium/third_party/blink/renderer/core/style/text_decoration_thickness.cc
+++ b/chromium/third_party/blink/renderer/core/style/text_decoration_thickness.cc
@@ -6,7 +6,8 @@
namespace blink {
-TextDecorationThickness::TextDecorationThickness() = default;
+TextDecorationThickness::TextDecorationThickness()
+ : thickness_(Length::Auto()) {}
TextDecorationThickness::TextDecorationThickness(const Length& length)
: thickness_(length) {}
@@ -16,11 +17,6 @@ TextDecorationThickness::TextDecorationThickness(CSSValueID from_font_keyword) {
thickness_from_font_ = true;
}
-Length TextDecorationThickness::Thickness() const {
- DCHECK(!thickness_from_font_);
- return thickness_;
-}
-
bool TextDecorationThickness::operator==(
const TextDecorationThickness& other) const {
return thickness_from_font_ == other.thickness_from_font_ &&
diff --git a/chromium/third_party/blink/renderer/core/style/text_decoration_thickness.h b/chromium/third_party/blink/renderer/core/style/text_decoration_thickness.h
index 132967ad6fe..fd5bacfbe49 100644
--- a/chromium/third_party/blink/renderer/core/style/text_decoration_thickness.h
+++ b/chromium/third_party/blink/renderer/core/style/text_decoration_thickness.h
@@ -21,7 +21,11 @@ class TextDecorationThickness {
explicit TextDecorationThickness(CSSValueID from_font_keyword);
bool IsFromFont() const { return thickness_from_font_; }
- Length Thickness() const;
+ const Length& Thickness() const {
+ DCHECK(!thickness_from_font_);
+ return thickness_;
+ }
+ bool IsAuto() const { return !thickness_from_font_ && thickness_.IsAuto(); }
bool operator==(const TextDecorationThickness&) const;
diff --git a/chromium/third_party/blink/renderer/core/svg/animation/element_smil_animations.cc b/chromium/third_party/blink/renderer/core/svg/animation/element_smil_animations.cc
index a6dce92358f..c9ddae660c6 100644
--- a/chromium/third_party/blink/renderer/core/svg/animation/element_smil_animations.cc
+++ b/chromium/third_party/blink/renderer/core/svg/animation/element_smil_animations.cc
@@ -41,7 +41,7 @@ bool ElementSMILAnimations::Apply(SMILTime elapsed) {
return did_apply;
}
-void ElementSMILAnimations::Trace(Visitor* visitor) {
+void ElementSMILAnimations::Trace(Visitor* visitor) const {
visitor->Trace(sandwiches_);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/animation/element_smil_animations.h b/chromium/third_party/blink/renderer/core/svg/animation/element_smil_animations.h
index b2c905dfa2c..706ff4c7167 100644
--- a/chromium/third_party/blink/renderer/core/svg/animation/element_smil_animations.h
+++ b/chromium/third_party/blink/renderer/core/svg/animation/element_smil_animations.h
@@ -27,7 +27,7 @@ class ElementSMILAnimations : public GarbageCollected<ElementSMILAnimations> {
bool Apply(SMILTime elapsed);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
HeapHashMap<QualifiedName, Member<SMILAnimationSandwich>> sandwiches_;
diff --git a/chromium/third_party/blink/renderer/core/svg/animation/priority_queue.h b/chromium/third_party/blink/renderer/core/svg/animation/priority_queue.h
index 55c59b33f03..86030bc43e8 100644
--- a/chromium/third_party/blink/renderer/core/svg/animation/priority_queue.h
+++ b/chromium/third_party/blink/renderer/core/svg/animation/priority_queue.h
@@ -55,7 +55,7 @@ class PriorityQueue {
const EntryType& operator[](wtf_size_t index) const { return heap_[index]; }
- void Trace(Visitor* visitor) { visitor->Trace(heap_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(heap_); }
private:
FRIEND_TEST_ALL_PREFIXES(PriorityQueueTest, Updates);
@@ -142,6 +142,8 @@ inline void PriorityQueue<PriorityType, ElementType>::Remove(
Swap(heap_[index], heap_.back());
heap_.pop_back();
element->PriorityQueueHandle() = kNotFound;
+ if (index == heap_.size() || PercolateUp(index) != index)
+ return;
PercolateDown(index);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/animation/priority_queue_test.cc b/chromium/third_party/blink/renderer/core/svg/animation/priority_queue_test.cc
index c59a67911ea..f5619087da1 100644
--- a/chromium/third_party/blink/renderer/core/svg/animation/priority_queue_test.cc
+++ b/chromium/third_party/blink/renderer/core/svg/animation/priority_queue_test.cc
@@ -17,7 +17,7 @@ class TestNode : public GarbageCollected<TestNode> {
wtf_size_t& PriorityQueueHandle() { return handle_; }
- void Trace(Visitor*) {}
+ void Trace(Visitor*) const {}
private:
wtf_size_t handle_;
@@ -84,6 +84,35 @@ TEST(PriorityQueueTest, RemovalMin) {
}
}
+TEST(PriorityQueueTest, RemovalFilledFromOtherSubtree) {
+ TestPriorityQueue queue;
+ using PairType = std::pair<int, Member<TestNode>>;
+ HeapVector<PairType> vector;
+ EXPECT_TRUE(queue.IsEmpty());
+ // Build a heap/queue where the left subtree contains priority 3 and the right
+ // contains priority 4:
+ //
+ // /-{[6]=4} {[index]=priority}
+ // /-{[2]=4}-{[5]=4}
+ // {[0]=3}
+ // \-{[1]=3}-{[4]=3}
+ // \-{[3]=3}
+ // \-{[7]=3}
+ //
+ for (int n : {3, 3, 4, 3, 3, 4, 4, 3}) {
+ TestNode* node = MakeGarbageCollected<TestNode>();
+ queue.Insert(n, node);
+ vector.push_back<PairType>({n, node});
+ }
+ EXPECT_FALSE(queue.IsEmpty());
+ EXPECT_EQ(queue.size(), 8u);
+ VerifyHeap(queue);
+
+ queue.Remove(vector[6].second);
+ EXPECT_EQ(queue.size(), 7u);
+ VerifyHeap(queue);
+}
+
TEST(PriorityQueueTest, RemovalReverse) {
TestPriorityQueue queue;
using PairType = std::pair<int, Member<TestNode>>;
diff --git a/chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc b/chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc
index 2efc2b2b522..2e8ef9ab3fa 100644
--- a/chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc
+++ b/chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc
@@ -119,7 +119,7 @@ bool SMILAnimationSandwich::ApplyAnimationValues() {
return true;
}
-void SMILAnimationSandwich::Trace(Visitor* visitor) {
+void SMILAnimationSandwich::Trace(Visitor* visitor) const {
visitor->Trace(sandwich_);
visitor->Trace(active_);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.h b/chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.h
index 7c0f5d26ec8..cce746343e8 100644
--- a/chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.h
+++ b/chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.h
@@ -106,7 +106,7 @@ class SMILAnimationSandwich : public GarbageCollected<SMILAnimationSandwich> {
bool IsEmpty() { return sandwich_.IsEmpty(); }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// Results are accumulated to the first animation element that animates and
diff --git a/chromium/third_party/blink/renderer/core/svg/animation/smil_repeat_count.h b/chromium/third_party/blink/renderer/core/svg/animation/smil_repeat_count.h
index 23d1f4810e3..5cebc9deea0 100644
--- a/chromium/third_party/blink/renderer/core/svg/animation/smil_repeat_count.h
+++ b/chromium/third_party/blink/renderer/core/svg/animation/smil_repeat_count.h
@@ -8,7 +8,7 @@
#include <cmath>
#include <limits>
-#include "base/logging.h"
+#include "base/check_op.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.cc b/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.cc
index ad245c6aec1..7e47120ead8 100644
--- a/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.cc
+++ b/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.cc
@@ -598,7 +598,7 @@ void SMILTimeContainer::AdvanceFrameForTesting() {
SetElapsed(Elapsed() + kFrameDuration);
}
-void SMILTimeContainer::Trace(Visitor* visitor) {
+void SMILTimeContainer::Trace(Visitor* visitor) const {
visitor->Trace(animated_targets_);
visitor->Trace(priority_queue_);
visitor->Trace(owner_svg_element_);
diff --git a/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.h b/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.h
index a7201b8dea7..81370a979f0 100644
--- a/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.h
+++ b/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.h
@@ -76,7 +76,7 @@ class CORE_EXPORT SMILTimeContainer final
void AdvanceFrameForTesting();
bool EventsDisabled() const { return !should_dispatch_events_; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
enum FrameSchedulingState {
diff --git a/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
index 016afbac7c9..eaf691d749a 100644
--- a/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
@@ -135,7 +135,7 @@ class ConditionEventListener final : public NativeEventListener {
animation_->Elapsed() + condition_->Offset(), SMILTimeOrigin::kEvent);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(animation_);
visitor->Trace(condition_);
NativeEventListener::Trace(visitor);
@@ -161,7 +161,7 @@ SVGSMILElement::Condition::Condition(Type type,
SVGSMILElement::Condition::~Condition() = default;
-void SVGSMILElement::Condition::Trace(Visitor* visitor) {
+void SVGSMILElement::Condition::Trace(Visitor* visitor) const {
visitor->Trace(base_element_);
visitor->Trace(base_id_observer_);
visitor->Trace(event_listener_);
@@ -1311,7 +1311,7 @@ void SVGSMILElement::DidChangeAnimationTarget() {
is_scheduled_ = true;
}
-void SVGSMILElement::Trace(Visitor* visitor) {
+void SVGSMILElement::Trace(Visitor* visitor) const {
visitor->Trace(target_element_);
visitor->Trace(target_id_observer_);
visitor->Trace(time_container_);
diff --git a/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.h b/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
index 436c4979bb6..953756ce205 100644
--- a/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
@@ -148,7 +148,7 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
wtf_size_t& PriorityQueueHandle() { return queue_handle_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
enum BeginOrEnd { kBegin, kEnd };
@@ -215,7 +215,7 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
unsigned repeat);
~Condition();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
Type GetType() const { return type_; }
BeginOrEnd GetBeginOrEnd() const { return begin_or_end_; }
diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_fe_image.cc b/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_fe_image.cc
index cf6c426f47f..d14e7fe5fe6 100644
--- a/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_fe_image.cc
+++ b/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_fe_image.cc
@@ -56,7 +56,7 @@ FEImage::FEImage(Filter* filter,
FilterEffect::SetOperatingInterpolationSpace(kInterpolationSpaceSRGB);
}
-void FEImage::Trace(Visitor* visitor) {
+void FEImage::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(preserve_aspect_ratio_);
FilterEffect::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_fe_image.h b/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_fe_image.h
index fd0be877c6b..cbf1cff8164 100644
--- a/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_fe_image.h
+++ b/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_fe_image.h
@@ -45,7 +45,7 @@ class FEImage final : public FilterEffect {
WTF::TextStream& ExternalRepresentation(WTF::TextStream&,
int indention) const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~FEImage() override = default;
diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc b/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc
index 10bad549ae3..1ebaa99c828 100644
--- a/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc
+++ b/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc
@@ -97,7 +97,7 @@ void SVGFilterGraphNodeMap::InvalidateDependentEffects(FilterEffect* effect) {
InvalidateDependentEffects(effect_reference);
}
-void SVGFilterGraphNodeMap::Trace(Visitor* visitor) {
+void SVGFilterGraphNodeMap::Trace(Visitor* visitor) const {
visitor->Trace(effect_element_);
visitor->Trace(effect_references_);
}
@@ -165,7 +165,7 @@ void SVGFilterBuilder::BuildGraph(Filter* filter,
EColorInterpolation filter_color_interpolation =
ColorInterpolationForElement(filter_element, CI_AUTO);
SVGUnitTypes::SVGUnitType primitive_units =
- filter_element.primitiveUnits()->CurrentValue()->EnumValue();
+ filter_element.primitiveUnits()->CurrentEnumValue();
for (SVGElement* element = Traversal<SVGElement>::FirstChild(filter_element);
element; element = Traversal<SVGElement>::NextSibling(*element)) {
diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h b/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h
index 5aa68df7966..29a254455b2 100644
--- a/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h
+++ b/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h
@@ -60,7 +60,7 @@ class SVGFilterGraphNodeMap final
void InvalidateDependentEffects(FilterEffect*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
FilterEffectSet& EffectReferences(FilterEffect* effect) {
diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.cc b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.cc
index 6f555dcfa2d..19ba9b12982 100644
--- a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.cc
+++ b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.cc
@@ -61,7 +61,6 @@
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/geometry/length_functions.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
-#include "third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/image_observer.h"
#include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h"
@@ -925,11 +924,4 @@ String SVGImage::FilenameExtension() const {
return "svg";
}
-DarkModeClassification SVGImage::CheckTypeSpecificConditionsForDarkMode(
- const FloatRect& dest_rect,
- DarkModeImageClassifier* classifier) {
- classifier->SetImageType(DarkModeImageClassifier::ImageType::kSvg);
- return DarkModeClassification::kNotClassified;
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.h b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.h
index 3841f0e2120..2977258ebd8 100644
--- a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.h
+++ b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.h
@@ -126,10 +126,6 @@ class CORE_EXPORT SVGImage final : public Image {
PaintImage PaintImageForCurrentFrame() override;
- DarkModeClassification CheckTypeSpecificConditionsForDarkMode(
- const FloatRect& dest_rect,
- DarkModeImageClassifier* classifier) override;
-
protected:
// Whether or not size is available yet.
bool IsSizeAvailable() override;
diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h
index 3a59c9578a4..1dcec7fa3ce 100644
--- a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h
+++ b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h
@@ -69,6 +69,8 @@ class SVGImageForContainer final : public Image {
image, container_size_without_zoom, zoom, url));
}
+ bool IsSVGImageForContainer() const override { return true; }
+
IntSize Size() const override;
FloatSize SizeAsFloat(RespectImageOrientationEnum) const override;
@@ -89,13 +91,6 @@ class SVGImageForContainer final : public Image {
PaintImage PaintImageForCurrentFrame() override;
- DarkModeClassification CheckTypeSpecificConditionsForDarkMode(
- const FloatRect& dest_rect,
- DarkModeImageClassifier* classifier) override {
- return image_->CheckTypeSpecificConditionsForDarkMode(dest_rect,
- classifier);
- }
-
protected:
void DrawPattern(GraphicsContext&,
const FloatRect&,
diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc
index 6a7a5717eed..ea002b2956f 100644
--- a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc
+++ b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc
@@ -21,8 +21,6 @@
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
-#include "third_party/blink/renderer/platform/graphics/dark_mode_generic_classifier.h"
-#include "third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_flags.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
@@ -32,11 +30,6 @@
#include "third_party/skia/include/utils/SkNullCanvas.h"
namespace blink {
-namespace {
-
-const float kEpsilon = 0.00001;
-
-} // namespace
class SVGImageTest : public testing::Test, private ScopedMockOverlayScrollbars {
public:
@@ -71,30 +64,6 @@ class SVGImageTest : public testing::Test, private ScopedMockOverlayScrollbars {
Image::kSyncDecode);
}
- // Loads the image from |file_name|, computes features into |features|,
- // and returns the classification result.
- bool GetFeaturesAndClassification(
- const String& file_name,
- DarkModeImageClassifier::Features* features) {
- CHECK(features);
- SCOPED_TRACE(file_name);
- LoadUsingFileName(file_name);
- DarkModeImageClassifier dark_mode_image_classifier;
- dark_mode_image_classifier.SetImageType(
- DarkModeImageClassifier::ImageType::kSvg);
- auto features_or_null = dark_mode_image_classifier.GetFeatures(
- image_.get(), FloatRect(0, 0, image_->width(), image_->height()));
- CHECK(features_or_null.has_value());
- (*features) = features_or_null.value();
- DarkModeClassification result =
- dark_mode_generic_classifier_.ClassifyWithFeatures(*features);
- return result == DarkModeClassification::kApplyFilter;
- }
-
- DarkModeGenericClassifier* classifier() {
- return &dark_mode_generic_classifier_;
- }
-
private:
class PauseControlImageObserver
: public GarbageCollected<PauseControlImageObserver>,
@@ -113,14 +82,15 @@ class SVGImageTest : public testing::Test, private ScopedMockOverlayScrollbars {
void AsyncLoadCompleted(const blink::Image*) override {}
- void Trace(Visitor* visitor) override { ImageObserver::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ ImageObserver::Trace(visitor);
+ }
private:
bool should_pause_;
};
Persistent<PauseControlImageObserver> observer_;
scoped_refptr<SVGImage> image_;
- DarkModeGenericClassifier dark_mode_generic_classifier_;
};
const char kAnimatedDocument[] =
@@ -266,70 +236,6 @@ TEST_F(SVGImageTest, DisablesSMILEvents) {
EXPECT_TRUE(time_container->EventsDisabled());
}
-TEST_F(SVGImageTest, DarkModeClassification) {
- DarkModeImageClassifier::Features features;
-
- // Test Case 1:
- // Grayscale
- // Color Buckets Ratio: Low
- // Decision Tree: Apply
- // Neural Network: NA
- EXPECT_TRUE(GetFeaturesAndClassification("/svg/animations/path-animation.svg",
- &features));
- EXPECT_EQ(classifier()->ClassifyUsingDecisionTreeForTesting(features),
- DarkModeClassification::kApplyFilter);
- EXPECT_FALSE(features.is_colorful);
- EXPECT_TRUE(features.is_svg);
- EXPECT_NEAR(0.0625f, features.color_buckets_ratio, kEpsilon);
- EXPECT_NEAR(0.968889f, features.transparency_ratio, kEpsilon);
- EXPECT_NEAR(0.02f, features.background_ratio, kEpsilon);
-
- // Test Case 2:
- // Color
- // Color Buckets Ratio: Low
- // Decision Tree: Apply
- // Neural Network: NA.
- EXPECT_TRUE(GetFeaturesAndClassification(
- "/svg/stroke/zero-length-path-linecap-rendering.svg", &features));
- EXPECT_EQ(classifier()->ClassifyUsingDecisionTreeForTesting(features),
- DarkModeClassification::kApplyFilter);
- EXPECT_TRUE(features.is_colorful);
- EXPECT_TRUE(features.is_svg);
- EXPECT_NEAR(0.00170898f, features.color_buckets_ratio, kEpsilon);
- EXPECT_NEAR(0.0f, features.transparency_ratio, kEpsilon);
- EXPECT_NEAR(0.0f, features.background_ratio, kEpsilon);
-
- // Test Case 3:
- // Color
- // Color Buckets Ratio: Low
- // Decision Tree: Apply
- // Neural Network: NA.
- EXPECT_TRUE(GetFeaturesAndClassification(
- "/svg/foreignObject/fixed-position.svg", &features));
- EXPECT_EQ(classifier()->ClassifyUsingDecisionTreeForTesting(features),
- DarkModeClassification::kApplyFilter);
- EXPECT_TRUE(features.is_colorful);
- EXPECT_TRUE(features.is_svg);
- EXPECT_NEAR(0.000244141f, features.color_buckets_ratio, kEpsilon);
- EXPECT_NEAR(0.777778f, features.transparency_ratio, kEpsilon);
- EXPECT_NEAR(0.0f, features.background_ratio, kEpsilon);
-
- // Test Case 4:
- // Grayscale
- // Color Buckets Ratio: Low
- // Decision Tree: Apply
- // Neural Network: NA.
- EXPECT_TRUE(GetFeaturesAndClassification("/svg/clip-path/clip-in-mask.svg",
- &features));
- EXPECT_EQ(classifier()->ClassifyUsingDecisionTreeForTesting(features),
- DarkModeClassification::kApplyFilter);
- EXPECT_FALSE(features.is_colorful);
- EXPECT_TRUE(features.is_svg);
- EXPECT_NEAR(0.0625f, features.color_buckets_ratio, kEpsilon);
- EXPECT_NEAR(0.888889f, features.transparency_ratio, kEpsilon);
- EXPECT_NEAR(0.11f, features.background_ratio, kEpsilon);
-}
-
class SVGImageSimTest : public SimTest, private ScopedMockOverlayScrollbars {};
TEST_F(SVGImageSimTest, PageVisibilityHiddenToVisible) {
diff --git a/chromium/third_party/blink/renderer/core/svg/linear_gradient_attributes.h b/chromium/third_party/blink/renderer/core/svg/linear_gradient_attributes.h
index aa759fa71bf..bda65f987a5 100644
--- a/chromium/third_party/blink/renderer/core/svg/linear_gradient_attributes.h
+++ b/chromium/third_party/blink/renderer/core/svg/linear_gradient_attributes.h
@@ -70,7 +70,7 @@ struct LinearGradientAttributes : GradientAttributes {
bool HasX2() const { return x2_set_; }
bool HasY2() const { return y2_set_; }
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(x1_);
visitor->Trace(y1_);
visitor->Trace(x2_);
@@ -101,7 +101,7 @@ class LinearGradientAttributesWrapper final
void Set(const LinearGradientAttributes& attributes) {
attributes_ = attributes;
}
- void Trace(Visitor* visitor) { visitor->Trace(attributes_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(attributes_); }
private:
LinearGradientAttributes attributes_;
diff --git a/chromium/third_party/blink/renderer/core/svg/pattern_attributes.h b/chromium/third_party/blink/renderer/core/svg/pattern_attributes.h
index 7aef7ddd25b..70aeb6a58d5 100644
--- a/chromium/third_party/blink/renderer/core/svg/pattern_attributes.h
+++ b/chromium/third_party/blink/renderer/core/svg/pattern_attributes.h
@@ -133,7 +133,7 @@ class PatternAttributes final {
bool HasPatternTransform() const { return pattern_transform_set_; }
bool HasPatternContentElement() const { return pattern_content_element_set_; }
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(width_);
@@ -176,7 +176,7 @@ class PatternAttributesWrapper
PatternAttributes& Attributes() { return attributes_; }
void Set(const PatternAttributes& attributes) { attributes_ = attributes; }
- void Trace(Visitor* visitor) { visitor->Trace(attributes_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(attributes_); }
private:
PatternAttributes attributes_;
diff --git a/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc b/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc
index 3b73e215eaa..16d907eafff 100644
--- a/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc
+++ b/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc
@@ -58,7 +58,7 @@ SVGAnimatedPropertyBase::SVGAnimatedPropertyBase(
SVGAnimatedPropertyBase::~SVGAnimatedPropertyBase() = default;
-void SVGAnimatedPropertyBase::Trace(Visitor* visitor) {
+void SVGAnimatedPropertyBase::Trace(Visitor* visitor) const {
visitor->Trace(context_element_);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.h b/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.h
index 5acb3121fe0..857e00b6a20 100644
--- a/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.h
+++ b/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.h
@@ -78,7 +78,7 @@ class SVGAnimatedPropertyBase : public GarbageCollectedMixin {
bool IsSpecified() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void BaseValueChanged();
void EnsureAnimValUpdated();
@@ -157,7 +157,7 @@ class SVGAnimatedPropertyCommon : public SVGAnimatedPropertyBase {
current_value_ = base_value_;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(base_value_);
visitor->Trace(current_value_);
SVGAnimatedPropertyBase::Trace(visitor);
@@ -269,7 +269,7 @@ class SVGAnimatedProperty<Property, TearOffType, void>
return anim_val_tear_off_;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(base_val_tear_off_);
visitor->Trace(anim_val_tear_off_);
SVGAnimatedPropertyCommon<Property>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_helper.h b/chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_helper.h
index 24f2aed8241..151a991f8cf 100644
--- a/chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_helper.h
+++ b/chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_helper.h
@@ -101,13 +101,13 @@ class SVGListPropertyHelper : public SVGPropertyHelper<Derived> {
ItemPropertyType* AppendItem(ItemPropertyType*);
ItemPropertyType* ReplaceItem(ItemPropertyType*, uint32_t, ExceptionState&);
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(values_);
SVGPropertyHelper<Derived>::Trace(visitor);
}
protected:
- void DeepCopy(Derived*);
+ void DeepCopy(const Derived*);
bool AdjustFromToListValues(Derived* from_list,
Derived* to_list,
@@ -227,7 +227,8 @@ bool SVGListPropertyHelper<Derived, ItemProperty>::CheckIndexBound(
}
template <typename Derived, typename ItemProperty>
-void SVGListPropertyHelper<Derived, ItemProperty>::DeepCopy(Derived* from) {
+void SVGListPropertyHelper<Derived, ItemProperty>::DeepCopy(
+ const Derived* from) {
Clear();
for (const auto& from_value : from->values_)
Append(from_value->Clone());
diff --git a/chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_tear_off_helper.h b/chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_tear_off_helper.h
index a98b0cc5e5b..ae3f6d6a54b 100644
--- a/chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_tear_off_helper.h
+++ b/chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_tear_off_helper.h
@@ -38,48 +38,12 @@
namespace blink {
-template <typename ItemProperty>
-class ListItemPropertyTraits {
- STATIC_ONLY(ListItemPropertyTraits);
-
- public:
- typedef ItemProperty ItemPropertyType;
- typedef typename ItemPropertyType::TearOffType ItemTearOffType;
-
- static ItemPropertyType* GetValueForInsertionFromTearOff(
- ItemTearOffType* new_item,
- SVGAnimatedPropertyBase* binding) {
- // |newItem| is immutable, OR
- // |newItem| belongs to a SVGElement, but it does not belong to an animated
- // list, e.g. "textElement.x.baseVal.appendItem(rectElement.width.baseVal)"
- // Spec: If newItem is already in a list, then a new object is created with
- // the same values as newItem and this item is inserted into the list.
- // Otherwise, newItem itself is inserted into the list.
- if (new_item->IsImmutable() || new_item->Target()->OwnerList() ||
- new_item->ContextElement()) {
- // We have to copy the incoming |newItem|,
- // Otherwise we'll end up having two tearoffs that operate on the same
- // SVGProperty. Consider the example below: SVGRectElements
- // SVGAnimatedLength 'width' property baseVal points to the same tear off
- // object that's inserted into SVGTextElements SVGAnimatedLengthList 'x'.
- // textElement.x.baseVal.getItem(0).value += 150 would mutate the
- // rectElement width _and_ the textElement x list. That's obviously wrong,
- // take care of that.
- return new_item->Target()->Clone();
- }
-
- new_item->Bind(binding);
- return new_item->Target();
- }
-};
-
template <typename Derived, typename ListProperty>
class SVGListPropertyTearOffHelper : public SVGPropertyTearOff<ListProperty> {
public:
typedef ListProperty ListPropertyType;
typedef typename ListPropertyType::ItemPropertyType ItemPropertyType;
typedef typename ItemPropertyType::TearOffType ItemTearOffType;
- typedef ListItemPropertyTraits<ItemPropertyType> ItemTraits;
// SVG*List DOM interface:
@@ -182,9 +146,29 @@ class SVGListPropertyTearOffHelper : public SVGPropertyTearOff<ListProperty> {
binding,
property_is_anim_val) {}
- ItemPropertyType* GetValueForInsertionFromTearOff(ItemTearOffType* new_item) {
- return ItemTraits::GetValueForInsertionFromTearOff(
- new_item, ToDerived()->GetBinding());
+ ItemPropertyType* GetValueForInsertionFromTearOff(
+ ItemTearOffType* item_tear_off) {
+ ItemPropertyType* item = item_tear_off->Target();
+ // |new_item| is immutable, OR
+ // |new_item| belongs to a SVGElement, but it does not belong to an animated
+ // list, e.g. "textElement.x.baseVal.appendItem(rectElement.width.baseVal)"
+ // Spec: If |new_item| is already in a list, then a new object is created
+ // with the same values as |new_item| and this item is inserted into the
+ // list. Otherwise, |new_item| itself is inserted into the list.
+ if (item_tear_off->IsImmutable() || item->OwnerList() ||
+ item_tear_off->ContextElement()) {
+ // We have to copy the incoming |new_item|,
+ // otherwise we'll end up having two tear-offs that operate on the same
+ // SVGProperty. Consider the example below: SVGRectElements
+ // SVGAnimatedLength 'width' property baseVal points to the same tear-off
+ // object that's inserted into SVGTextElements SVGAnimatedLengthList 'x'.
+ // textElement.x.baseVal.getItem(0).value += 150 would mutate the
+ // rectElement width _and_ the textElement x list. That's obviously wrong,
+ // take care of that.
+ return item->Clone();
+ }
+ item_tear_off->Bind(ToDerived()->GetBinding());
+ return item;
}
ItemTearOffType* CreateItemTearOff(ItemPropertyType* value) {
diff --git a/chromium/third_party/blink/renderer/core/svg/properties/svg_property.h b/chromium/third_party/blink/renderer/core/svg/properties/svg_property.h
index a58d5a8ea62..75f40eac663 100644
--- a/chromium/third_party/blink/renderer/core/svg/properties/svg_property.h
+++ b/chromium/third_party/blink/renderer/core/svg/properties/svg_property.h
@@ -85,7 +85,7 @@ class SVGPropertyBase : public GarbageCollected<SVGPropertyBase> {
owner_list_ = owner_list;
}
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
SVGPropertyBase() : owner_list_(nullptr) {}
diff --git a/chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.cc b/chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.cc
index 1db1f82f94f..d0c0d2a6028 100644
--- a/chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.cc
+++ b/chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.cc
@@ -49,7 +49,7 @@ SVGPropertyTearOffBase::SVGPropertyTearOffBase(SVGElement* context_element)
binding_(nullptr),
property_is_anim_val_(kPropertyIsNotAnimVal) {}
-void SVGPropertyTearOffBase::Trace(Visitor* visitor) {
+void SVGPropertyTearOffBase::Trace(Visitor* visitor) const {
visitor->Trace(context_element_);
visitor->Trace(binding_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.h b/chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.h
index a2c2a97d1c9..e7918d6a1d5 100644
--- a/chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.h
+++ b/chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.h
@@ -61,7 +61,7 @@ class SVGPropertyTearOffBase : public ScriptWrappable {
void Bind(SVGAnimatedPropertyBase* binding);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
static void ThrowReadOnly(ExceptionState&);
@@ -90,7 +90,7 @@ class SVGPropertyTearOff : public SVGPropertyTearOffBase {
void SetTarget(Property* target) { target_ = target; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(target_);
SVGPropertyTearOffBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/radial_gradient_attributes.h b/chromium/third_party/blink/renderer/core/svg/radial_gradient_attributes.h
index 9143d140e19..54a6d428ced 100644
--- a/chromium/third_party/blink/renderer/core/svg/radial_gradient_attributes.h
+++ b/chromium/third_party/blink/renderer/core/svg/radial_gradient_attributes.h
@@ -86,7 +86,7 @@ struct RadialGradientAttributes final : GradientAttributes {
bool HasFy() const { return fy_set_; }
bool HasFr() const { return fr_set_; }
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(cx_);
visitor->Trace(cy_);
visitor->Trace(r_);
@@ -123,7 +123,7 @@ class RadialGradientAttributesWrapper final
void Set(const RadialGradientAttributes& attributes) {
attributes_ = attributes;
}
- void Trace(Visitor* visitor) { visitor->Trace(attributes_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(attributes_); }
private:
RadialGradientAttributes attributes_;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_a_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_a_element.cc
index b27a8885972..5ac5fdc4411 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_a_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_a_element.cc
@@ -58,7 +58,7 @@ SVGAElement::SVGAElement(Document& document)
AddToPropertyMap(svg_target_);
}
-void SVGAElement::Trace(Visitor* visitor) {
+void SVGAElement::Trace(Visitor* visitor) const {
visitor->Trace(svg_target_);
SVGGraphicsElement::Trace(visitor);
SVGURIReference::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_a_element.h b/chromium/third_party/blink/renderer/core/svg/svg_a_element.h
index 79e0722aa83..a094c7e6e59 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_a_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_a_element.h
@@ -38,7 +38,7 @@ class CORE_EXPORT SVGAElement final : public SVGGraphicsElement,
explicit SVGAElement(Document&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String title() const override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_angle.cc b/chromium/third_party/blink/renderer/core/svg/svg_angle.cc
index 87d2ce53ce4..01ce1928787 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_angle.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_angle.cc
@@ -41,46 +41,28 @@ const SVGEnumerationMap& GetEnumerationMap<SVGMarkerOrientType>() {
return entries;
}
-SVGMarkerOrientEnumeration::SVGMarkerOrientEnumeration(SVGAngle* angle)
- : SVGEnumeration<SVGMarkerOrientType>(kSVGMarkerOrientAngle),
- angle_(angle) {}
+namespace {
-SVGMarkerOrientEnumeration::~SVGMarkerOrientEnumeration() = default;
+class SVGMarkerOrientEnumeration final : public SVGEnumeration {
+ public:
+ explicit SVGMarkerOrientEnumeration(SVGAngle* angle)
+ : SVGEnumeration(kSVGMarkerOrientAngle), angle_(angle) {}
-void SVGMarkerOrientEnumeration::Trace(Visitor* visitor) {
- visitor->Trace(angle_);
- SVGEnumeration<SVGMarkerOrientType>::Trace(visitor);
-}
+ void Trace(Visitor* visitor) const override {
+ visitor->Trace(angle_);
+ SVGEnumeration::Trace(visitor);
+ }
-void SVGMarkerOrientEnumeration::NotifyChange() {
- DCHECK(angle_);
- angle_->OrientTypeChanged();
-}
+ private:
+ void NotifyChange() override {
+ DCHECK(angle_);
+ angle_->OrientTypeChanged();
+ }
-void SVGMarkerOrientEnumeration::Add(SVGPropertyBase*, SVGElement*) {
- // SVGMarkerOrientEnumeration is only animated via SVGAngle
- NOTREACHED();
-}
+ Member<SVGAngle> angle_;
+};
-void SVGMarkerOrientEnumeration::CalculateAnimatedValue(
- const SVGAnimateElement&,
- float percentage,
- unsigned repeat_count,
- SVGPropertyBase* from,
- SVGPropertyBase* to,
- SVGPropertyBase* to_at_end_of_duration_value,
- SVGElement* context_element) {
- // SVGMarkerOrientEnumeration is only animated via SVGAngle
- NOTREACHED();
-}
-
-float SVGMarkerOrientEnumeration::CalculateDistance(
- SVGPropertyBase* to,
- SVGElement* context_element) {
- // SVGMarkerOrientEnumeration is only animated via SVGAngle
- NOTREACHED();
- return -1.0;
-}
+} // namespace
SVGAngle::SVGAngle()
: unit_type_(kSvgAngletypeUnspecified),
@@ -98,14 +80,14 @@ SVGAngle::SVGAngle(SVGAngleType unit_type,
SVGAngle::~SVGAngle() = default;
-void SVGAngle::Trace(Visitor* visitor) {
+void SVGAngle::Trace(Visitor* visitor) const {
visitor->Trace(orient_type_);
SVGPropertyHelper<SVGAngle>::Trace(visitor);
}
SVGAngle* SVGAngle::Clone() const {
return MakeGarbageCollected<SVGAngle>(unit_type_, value_in_specified_units_,
- orient_type_->EnumValue());
+ OrientTypeValue());
}
float SVGAngle::Value() const {
@@ -366,21 +348,19 @@ void SVGAngle::Add(SVGPropertyBase* other, SVGElement*) {
// Only respect by animations, if from and by are both specified in angles
// (and not, for example, 'auto').
- if (OrientType()->EnumValue() != kSVGMarkerOrientAngle ||
- other_angle->OrientType()->EnumValue() != kSVGMarkerOrientAngle)
+ if (!IsNumeric() || !other_angle->IsNumeric())
return;
SetValue(Value() + other_angle->Value());
}
void SVGAngle::Assign(const SVGAngle& other) {
- SVGMarkerOrientType other_orient_type = other.OrientType()->EnumValue();
- if (other_orient_type == kSVGMarkerOrientAngle) {
+ if (other.IsNumeric()) {
NewValueSpecifiedUnits(other.UnitType(), other.ValueInSpecifiedUnits());
return;
}
value_in_specified_units_ = 0;
- orient_type_->SetEnumValue(other_orient_type);
+ orient_type_->SetEnumValue(other.OrientTypeValue());
}
void SVGAngle::CalculateAnimatedValue(
@@ -393,13 +373,10 @@ void SVGAngle::CalculateAnimatedValue(
SVGElement*) {
auto* from_angle = To<SVGAngle>(from);
auto* to_angle = To<SVGAngle>(to);
- SVGMarkerOrientType from_orient_type = from_angle->OrientType()->EnumValue();
- SVGMarkerOrientType to_orient_type = to_angle->OrientType()->EnumValue();
// We can only interpolate between two SVGAngles with orient-type 'angle',
// all other cases will use discrete animation.
- if (from_orient_type != to_orient_type ||
- from_orient_type != kSVGMarkerOrientAngle) {
+ if (!from_angle->IsNumeric() || !to_angle->IsNumeric()) {
Assign(percentage < 0.5f ? *from_angle : *to_angle);
return;
}
@@ -417,11 +394,18 @@ float SVGAngle::CalculateDistance(SVGPropertyBase* other, SVGElement*) {
}
void SVGAngle::OrientTypeChanged() {
- if (OrientType()->EnumValue() == kSVGMarkerOrientAuto ||
- OrientType()->EnumValue() == kSVGMarkerOrientAutoStartReverse) {
- unit_type_ = kSvgAngletypeUnspecified;
- value_in_specified_units_ = 0;
- }
+ if (IsNumeric())
+ return;
+ unit_type_ = kSvgAngletypeUnspecified;
+ value_in_specified_units_ = 0;
+}
+
+SVGMarkerOrientType SVGAngle::OrientTypeValue() const {
+ return orient_type_->EnumValue<SVGMarkerOrientType>();
+}
+
+bool SVGAngle::IsNumeric() const {
+ return OrientTypeValue() == kSVGMarkerOrientAngle;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_angle.h b/chromium/third_party/blink/renderer/core/svg/svg_angle.h
index 4ec7825fb0a..df55c4623d3 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_angle.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_angle.h
@@ -41,30 +41,6 @@ enum SVGMarkerOrientType {
};
DECLARE_SVG_ENUM_MAP(SVGMarkerOrientType);
-class SVGMarkerOrientEnumeration final
- : public SVGEnumeration<SVGMarkerOrientType> {
- public:
- SVGMarkerOrientEnumeration(SVGAngle*);
- ~SVGMarkerOrientEnumeration() override;
-
- void Add(SVGPropertyBase*, SVGElement*) override;
- void CalculateAnimatedValue(const SVGAnimateElement&,
- float,
- unsigned,
- SVGPropertyBase*,
- SVGPropertyBase*,
- SVGPropertyBase*,
- SVGElement*) override;
- float CalculateDistance(SVGPropertyBase*, SVGElement*) override;
-
- void Trace(Visitor*) override;
-
- private:
- void NotifyChange() override;
-
- Member<SVGAngle> angle_;
-};
-
class SVGAngle final : public SVGPropertyHelper<SVGAngle> {
public:
typedef SVGAngleTearOff TearOffType;
@@ -103,12 +79,9 @@ class SVGAngle final : public SVGPropertyHelper<SVGAngle> {
float value_in_specified_units);
void ConvertToSpecifiedUnits(SVGAngleType unit_type);
- SVGEnumeration<SVGMarkerOrientType>* OrientType() {
- return orient_type_.Get();
- }
- const SVGEnumeration<SVGMarkerOrientType>* OrientType() const {
- return orient_type_.Get();
- }
+ SVGEnumeration* OrientType() { return orient_type_.Get(); }
+ SVGMarkerOrientType OrientTypeValue() const;
+ bool IsNumeric() const;
void OrientTypeChanged();
// SVGPropertyBase:
@@ -131,14 +104,14 @@ class SVGAngle final : public SVGPropertyHelper<SVGAngle> {
static AnimatedPropertyType ClassType() { return kAnimatedAngle; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void Assign(const SVGAngle&);
SVGAngleType unit_type_;
float value_in_specified_units_;
- Member<SVGMarkerOrientEnumeration> orient_type_;
+ Member<SVGEnumeration> orient_type_;
};
template <>
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animate_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_animate_element.cc
index 47090b5d649..07ae0781d64 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animate_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animate_element.cc
@@ -187,7 +187,7 @@ void SVGAnimateElement::ResolveTargetProperty() {
AttributeName().LocalName())
: CSSPropertyID::kInvalid;
}
- // Blacklist <script> targets here for now to prevent unpleasantries. This
+ // Disallow <script> targets here for now to prevent unpleasantries. This
// also disallows the perfectly "valid" animation of 'className' on said
// element. If SVGScriptElement.href is transitioned off of SVGAnimatedHref,
// this can be removed.
@@ -586,7 +586,7 @@ void SVGAnimateElement::SetAttributeType(
AnimationAttributeChanged();
}
-void SVGAnimateElement::Trace(Visitor* visitor) {
+void SVGAnimateElement::Trace(Visitor* visitor) const {
visitor->Trace(from_property_);
visitor->Trace(to_property_);
visitor->Trace(to_at_end_of_duration_property_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animate_element.h b/chromium/third_party/blink/renderer/core/svg/svg_animate_element.h
index 4411ec1b9c5..7646f03ef41 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animate_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animate_element.h
@@ -44,7 +44,7 @@ class CORE_EXPORT SVGAnimateElement : public SVGAnimationElement {
SVGAnimateElement(const QualifiedName&, Document&);
~SVGAnimateElement() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool IsSVGAnimationAttributeSettingJavaScriptURL(
const Attribute&) const override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_angle.cc b/chromium/third_party/blink/renderer/core/svg/svg_animated_angle.cc
index e1044af8017..6de9f10f22d 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_angle.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_angle.cc
@@ -47,7 +47,7 @@ SVGAnimatedAngle::SVGAnimatedAngle(SVGElement* context_element)
SVGAnimatedAngle::~SVGAnimatedAngle() = default;
-void SVGAnimatedAngle::Trace(Visitor* visitor) {
+void SVGAnimatedAngle::Trace(Visitor* visitor) const {
visitor->Trace(orient_type_);
SVGAnimatedProperty<SVGAngle>::Trace(visitor);
ScriptWrappable::Trace(visitor);
@@ -59,9 +59,9 @@ bool SVGAnimatedAngle::NeedsSynchronizeAttribute() const {
}
void SVGAnimatedAngle::SynchronizeAttribute() {
- // If the current value is not an <angle> we synchronize the value of the
- // wrapped enumeration.
- if (orient_type_->CurrentValue()->EnumValue() != kSVGMarkerOrientAngle) {
+ // If the value is not an <angle> we synchronize the value of the wrapped
+ // enumeration.
+ if (!BaseValue()->IsNumeric()) {
orient_type_->SynchronizeAttribute();
return;
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_angle.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_angle.h
index 4702d1e66b8..6ea0dc8272d 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_angle.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_angle.h
@@ -58,7 +58,7 @@ class SVGAnimatedAngle final : public ScriptWrappable,
void SetAnimatedValue(SVGPropertyBase*) override;
void AnimationEnded() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<SVGAnimatedEnumeration<SVGMarkerOrientType>> orient_type_;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_boolean.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_boolean.h
index 1a1d4bd3619..ea23d59dcb9 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_boolean.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_boolean.h
@@ -50,7 +50,7 @@ class SVGAnimatedBoolean final : public ScriptWrappable,
attribute_name,
MakeGarbageCollected<SVGBoolean>()) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
SVGAnimatedProperty<SVGBoolean>::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_color.cc b/chromium/third_party/blink/renderer/core/svg/svg_animated_color.cc
index 355977b9ff7..d8afc250aea 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_color.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_color.cc
@@ -21,7 +21,7 @@
#include "third_party/blink/renderer/core/css/css_color_value.h"
#include "third_party/blink/renderer/core/css/parser/css_parser.h"
-#include "third_party/blink/renderer/core/layout/layout_object.h"
+#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/svg/color_distance.h"
#include "third_party/blink/renderer/core/svg/svg_animate_element.h"
@@ -49,8 +49,8 @@ SVGPropertyBase* SVGColorProperty::CloneForAnimation(const String&) const {
static inline Color FallbackColorForCurrentColor(SVGElement* target_element) {
DCHECK(target_element);
- if (LayoutObject* target_layout_object = target_element->GetLayoutObject())
- return target_layout_object->ResolveColor(GetCSSPropertyColor());
+ if (const ComputedStyle* target_style = target_element->GetComputedStyle())
+ return target_style->VisitedDependentColor(GetCSSPropertyColor());
return Color::kTransparent;
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration.h
index 74b39a25ec9..783fc65acc9 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration.h
@@ -45,40 +45,20 @@ class SVGAnimatedEnumeration : public SVGAnimatedEnumerationBase {
: SVGAnimatedEnumerationBase(
context_element,
attribute_name,
- MakeGarbageCollected<SVGEnumeration<Enum>>(initial_value),
+ MakeGarbageCollected<SVGEnumeration>(initial_value),
static_cast<unsigned>(initial_value)) {}
SVGAnimatedEnumeration(SVGElement* context_element,
const QualifiedName& attribute_name,
- SVGEnumeration<Enum>* initial_value)
+ SVGEnumeration* initial_value)
: SVGAnimatedEnumerationBase(
context_element,
attribute_name,
initial_value,
- static_cast<unsigned>(initial_value->EnumValue())) {}
+ static_cast<unsigned>(initial_value->EnumValue<Enum>())) {}
- SVGAnimatedEnumeration(SVGElement* context_element,
- const QualifiedName& attribute_name,
- SVGEnumeration<Enum>* initial_value,
- unsigned initial_enum_value)
- : SVGAnimatedEnumerationBase(context_element,
- attribute_name,
- initial_value,
- initial_enum_value) {}
-
- SVGEnumeration<Enum>* BaseValue() {
- return static_cast<SVGEnumeration<Enum>*>(
- SVGAnimatedEnumerationBase::BaseValue());
- }
-
- SVGEnumeration<Enum>* CurrentValue() {
- return static_cast<SVGEnumeration<Enum>*>(
- SVGAnimatedEnumerationBase::CurrentValue());
- }
-
- const SVGEnumeration<Enum>* CurrentValue() const {
- return static_cast<const SVGEnumeration<Enum>*>(
- SVGAnimatedEnumerationBase::CurrentValue());
+ Enum CurrentEnumValue() const {
+ return CurrentValue()->template EnumValue<Enum>();
}
};
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration_base.cc b/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration_base.cc
index c6eae1ae34b..a0628409751 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration_base.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration_base.cc
@@ -52,7 +52,7 @@ void SVGAnimatedEnumerationBase::setBaseVal(uint16_t value,
return;
}
- SVGAnimatedProperty<SVGEnumerationBase>::setBaseVal(value, exception_state);
+ SVGAnimatedProperty<SVGEnumeration>::setBaseVal(value, exception_state);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration_base.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration_base.h
index 6ed348fb8a5..f2f518cbefa 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration_base.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration_base.h
@@ -37,9 +37,8 @@
namespace blink {
-class SVGAnimatedEnumerationBase
- : public ScriptWrappable,
- public SVGAnimatedProperty<SVGEnumerationBase> {
+class SVGAnimatedEnumerationBase : public ScriptWrappable,
+ public SVGAnimatedProperty<SVGEnumeration> {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(SVGAnimatedEnumerationBase);
@@ -48,21 +47,21 @@ class SVGAnimatedEnumerationBase
void setBaseVal(uint16_t, ExceptionState&);
- void Trace(Visitor* visitor) override {
- SVGAnimatedProperty<SVGEnumerationBase>::Trace(visitor);
+ void Trace(Visitor* visitor) const override {
+ SVGAnimatedProperty<SVGEnumeration>::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
protected:
SVGAnimatedEnumerationBase(SVGElement* context_element,
const QualifiedName& attribute_name,
- SVGEnumerationBase* initial_value,
+ SVGEnumeration* initial_value,
unsigned initial_enum_value)
- : SVGAnimatedProperty<SVGEnumerationBase>(context_element,
- attribute_name,
- initial_value,
- CSSPropertyID::kInvalid,
- initial_enum_value) {}
+ : SVGAnimatedProperty<SVGEnumeration>(context_element,
+ attribute_name,
+ initial_value,
+ CSSPropertyID::kInvalid,
+ initial_enum_value) {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_href.cc b/chromium/third_party/blink/renderer/core/svg/svg_animated_href.cc
index 9d0bce7ecb3..734d8094c70 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_href.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_href.cc
@@ -14,7 +14,9 @@
namespace blink {
-void SVGAnimatedHref::Trace(Visitor* visitor) {
+class StringOrTrustedScriptURL;
+
+void SVGAnimatedHref::Trace(Visitor* visitor) const {
visitor->Trace(xlink_href_);
SVGAnimatedString::Trace(visitor);
}
@@ -43,13 +45,14 @@ const SVGString* SVGAnimatedHref::CurrentValue() const {
return BackingString()->SVGAnimatedString::CurrentValue();
}
-String SVGAnimatedHref::baseVal() {
+void SVGAnimatedHref::baseVal(
+ StringOrTrustedScriptURL& string_or_trusted_script_url) {
UseCounter::Count(ContextElement()->GetDocument(),
WebFeature::kSVGHrefBaseVal);
- return BackingString()->SVGAnimatedString::baseVal();
+ BackingString()->SVGAnimatedString::baseVal(string_or_trusted_script_url);
}
-void SVGAnimatedHref::setBaseVal(const String& value,
+void SVGAnimatedHref::setBaseVal(const StringOrTrustedScriptURL& value,
ExceptionState& exception_state) {
UseCounter::Count(ContextElement()->GetDocument(),
WebFeature::kSVGHrefBaseVal);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_href.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_href.h
index 807f6145b48..cd6d15d0a45 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_href.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_href.h
@@ -9,6 +9,8 @@
namespace blink {
+class StringOrTrustedScriptURL;
+
// This is an "access wrapper" for the 'href' attribute. The object
// itself holds the value for 'href' in the null/default NS and wraps
// one for 'href' in the XLink NS. Both objects are added to an
@@ -24,8 +26,8 @@ class SVGAnimatedHref final : public SVGAnimatedString {
SVGString* CurrentValue();
const SVGString* CurrentValue() const;
- String baseVal() override;
- void setBaseVal(const String&, ExceptionState&) override;
+ void baseVal(StringOrTrustedScriptURL&) override;
+ void setBaseVal(const StringOrTrustedScriptURL&, ExceptionState&) override;
String animVal() override;
bool IsSpecified() const {
@@ -35,7 +37,7 @@ class SVGAnimatedHref final : public SVGAnimatedString {
static bool IsKnownAttribute(const QualifiedName&);
void AddToPropertyMap(SVGElement*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
SVGAnimatedString* BackingString();
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_integer.cc b/chromium/third_party/blink/renderer/core/svg/svg_animated_integer.cc
index 14c630b5ada..ce03d7fe119 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_integer.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_integer.cc
@@ -43,7 +43,7 @@ void SVGAnimatedInteger::SynchronizeAttribute() {
SVGAnimatedProperty<SVGInteger>::SynchronizeAttribute();
}
-void SVGAnimatedInteger::Trace(Visitor* visitor) {
+void SVGAnimatedInteger::Trace(Visitor* visitor) const {
visitor->Trace(parent_integer_optional_integer_);
SVGAnimatedProperty<SVGInteger>::Trace(visitor);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_integer.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_integer.h
index ce95e61066c..66d8abe6211 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_integer.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_integer.h
@@ -72,7 +72,7 @@ class SVGAnimatedInteger : public ScriptWrappable,
parent_integer_optional_integer_ = number_optional_integer;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
Member<SVGAnimatedIntegerOptionalInteger> parent_integer_optional_integer_;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_integer_optional_integer.cc b/chromium/third_party/blink/renderer/core/svg/svg_animated_integer_optional_integer.cc
index 4e13a4a7be1..ac626acd41f 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_integer_optional_integer.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_integer_optional_integer.cc
@@ -58,7 +58,7 @@ SVGAnimatedIntegerOptionalInteger::SVGAnimatedIntegerOptionalInteger(
second_integer_->SetParentOptionalInteger(this);
}
-void SVGAnimatedIntegerOptionalInteger::Trace(Visitor* visitor) {
+void SVGAnimatedIntegerOptionalInteger::Trace(Visitor* visitor) const {
visitor->Trace(first_integer_);
visitor->Trace(second_integer_);
SVGAnimatedPropertyCommon<SVGIntegerOptionalInteger>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_integer_optional_integer.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_integer_optional_integer.h
index 2378c5ded90..e94f6d975f8 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_integer_optional_integer.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_integer_optional_integer.h
@@ -60,7 +60,7 @@ class SVGAnimatedIntegerOptionalInteger
SVGAnimatedInteger* FirstInteger() { return first_integer_.Get(); }
SVGAnimatedInteger* SecondInteger() { return second_integer_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
Member<SVGAnimatedInteger> first_integer_;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_length.cc b/chromium/third_party/blink/renderer/core/svg/svg_animated_length.cc
index bb89af577ec..57963438d49 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_length.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_length.cc
@@ -50,7 +50,7 @@ SVGParsingError SVGAnimatedLength::AttributeChanged(const String& value) {
return parse_status;
}
-void SVGAnimatedLength::Trace(Visitor* visitor) {
+void SVGAnimatedLength::Trace(Visitor* visitor) const {
SVGAnimatedProperty<SVGLength>::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_length.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_length.h
index f2fb5351fc6..cd617a0ca13 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_length.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_length.h
@@ -62,7 +62,7 @@ class SVGAnimatedLength : public ScriptWrappable,
return CurrentValue()->AsCSSPrimitiveValue();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_length_list.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_length_list.h
index e65babb3577..827db1acb22 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_length_list.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_length_list.h
@@ -52,7 +52,7 @@ class SVGAnimatedLengthList final : public ScriptWrappable,
attribute_name,
initial_value) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
SVGAnimatedProperty<SVGLengthList>::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_number.cc b/chromium/third_party/blink/renderer/core/svg/svg_animated_number.cc
index 5224f2b880e..6e1603b4b7c 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_number.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_number.cc
@@ -43,7 +43,7 @@ void SVGAnimatedNumber::SynchronizeAttribute() {
SVGAnimatedProperty<SVGNumber>::SynchronizeAttribute();
}
-void SVGAnimatedNumber::Trace(Visitor* visitor) {
+void SVGAnimatedNumber::Trace(Visitor* visitor) const {
visitor->Trace(parent_number_optional_number_);
SVGAnimatedProperty<SVGNumber>::Trace(visitor);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_number.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_number.h
index 1f31b2675a4..237fb2e641e 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_number.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_number.h
@@ -73,7 +73,7 @@ class SVGAnimatedNumber : public ScriptWrappable,
parent_number_optional_number_ = number_optional_number;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
Member<SVGAnimatedNumberOptionalNumber> parent_number_optional_number_;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_number_list.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_number_list.h
index ed78b7a454f..d8514e09bf3 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_number_list.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_number_list.h
@@ -53,7 +53,7 @@ class SVGAnimatedNumberList final : public ScriptWrappable,
attribute_name,
MakeGarbageCollected<SVGNumberList>()) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
SVGAnimatedProperty<SVGNumberList>::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_number_optional_number.cc b/chromium/third_party/blink/renderer/core/svg/svg_animated_number_optional_number.cc
index 4f05129af86..ca2ca9d3451 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_number_optional_number.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_number_optional_number.cc
@@ -46,7 +46,7 @@ SVGAnimatedNumberOptionalNumber::SVGAnimatedNumberOptionalNumber(
second_number_->SetParentOptionalNumber(this);
}
-void SVGAnimatedNumberOptionalNumber::Trace(Visitor* visitor) {
+void SVGAnimatedNumberOptionalNumber::Trace(Visitor* visitor) const {
visitor->Trace(first_number_);
visitor->Trace(second_number_);
SVGAnimatedPropertyCommon<SVGNumberOptionalNumber>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_number_optional_number.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_number_optional_number.h
index a8b0d462136..00169826adc 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_number_optional_number.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_number_optional_number.h
@@ -60,7 +60,7 @@ class SVGAnimatedNumberOptionalNumber
SVGAnimatedNumber* FirstNumber() { return first_number_.Get(); }
SVGAnimatedNumber* SecondNumber() { return second_number_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
Member<SVGAnimatedNumber> first_number_;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_preserve_aspect_ratio.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_preserve_aspect_ratio.h
index b9643d84d78..f27ef0225b0 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_preserve_aspect_ratio.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_preserve_aspect_ratio.h
@@ -52,7 +52,7 @@ class SVGAnimatedPreserveAspectRatio
attribute_name,
MakeGarbageCollected<SVGPreserveAspectRatio>()) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
SVGAnimatedProperty<SVGPreserveAspectRatio>::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_rect.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_rect.h
index da6dffd7fd6..39b7f8de612 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_rect.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_rect.h
@@ -49,7 +49,7 @@ class SVGAnimatedRect : public ScriptWrappable,
attribute_name,
SVGRect::CreateInvalid()) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
SVGAnimatedProperty<SVGRect>::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_string.cc b/chromium/third_party/blink/renderer/core/svg/svg_animated_string.cc
index 649221ed5a7..cdce2cd1c92 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_string.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_string.cc
@@ -4,22 +4,44 @@
#include "third_party/blink/renderer/core/svg/svg_animated_string.h"
+#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script_url.h"
+#include "third_party/blink/renderer/core/svg/svg_element.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_script_url.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h"
+
namespace blink {
-String SVGAnimatedString::baseVal() {
- return SVGAnimatedProperty<SVGString>::baseVal();
+void SVGAnimatedString::setBaseVal(
+ const StringOrTrustedScriptURL& string_or_trusted_script_url,
+ ExceptionState& exception_state) {
+ String value;
+ // See:
+ // https://w3c.github.io/webappsec-trusted-types/dist/spec/#integration-with-svg
+ if (string_or_trusted_script_url.IsTrustedScriptURL()) {
+ value = string_or_trusted_script_url.GetAsTrustedScriptURL()->toString();
+ } else {
+ value = string_or_trusted_script_url.GetAsString();
+ if (ContextElement()->IsScriptElement()) {
+ value = TrustedTypesCheckForScriptURL(
+ value, ContextElement()->GetExecutionContext(), exception_state);
+ if (exception_state.HadException())
+ return;
+ }
+ }
+ SVGAnimatedProperty<SVGString>::setBaseVal(value, exception_state);
}
-void SVGAnimatedString::setBaseVal(const String& value,
- ExceptionState& exception_state) {
- return SVGAnimatedProperty<SVGString>::setBaseVal(value, exception_state);
+void SVGAnimatedString::baseVal(
+ StringOrTrustedScriptURL& string_or_trusted_script_url) {
+ string_or_trusted_script_url.SetString(
+ SVGAnimatedProperty<SVGString>::baseVal());
}
String SVGAnimatedString::animVal() {
return SVGAnimatedProperty<SVGString>::animVal();
}
-void SVGAnimatedString::Trace(Visitor* visitor) {
+void SVGAnimatedString::Trace(Visitor* visitor) const {
SVGAnimatedProperty<SVGString>::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_string.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_string.h
index 971ef0b4d9c..6861961102d 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_string.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_string.h
@@ -38,6 +38,8 @@
namespace blink {
+class StringOrTrustedScriptURL;
+
class SVGAnimatedString : public ScriptWrappable,
public SVGAnimatedProperty<SVGString> {
DEFINE_WRAPPERTYPEINFO();
@@ -50,11 +52,12 @@ class SVGAnimatedString : public ScriptWrappable,
attribute_name,
MakeGarbageCollected<SVGString>()) {}
- virtual String baseVal();
- virtual void setBaseVal(const String&, ExceptionState&);
+ virtual void setBaseVal(const StringOrTrustedScriptURL&, ExceptionState&);
+ virtual void baseVal(StringOrTrustedScriptURL&);
+
virtual String animVal();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_string.idl b/chromium/third_party/blink/renderer/core/svg/svg_animated_string.idl
index 2b1b8e971de..61550eaabb0 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_string.idl
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_string.idl
@@ -27,6 +27,6 @@
[Exposed=Window]
interface SVGAnimatedString {
- [RaisesException=Setter] attribute DOMString baseVal;
+ [RaisesException=Setter] attribute (DOMString or TrustedScriptURL) baseVal;
readonly attribute DOMString animVal;
};
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_transform_list.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_transform_list.h
index 5e413bd8ff3..6a6c22f7050 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_transform_list.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_transform_list.h
@@ -56,7 +56,7 @@ class SVGAnimatedTransformList final
MakeGarbageCollected<SVGTransformList>(),
css_property_id) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
SVGAnimatedProperty<SVGTransformList>::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_circle_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_circle_element.cc
index 6ec31ddde90..b322e86fe17 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_circle_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_circle_element.cc
@@ -51,7 +51,7 @@ SVGCircleElement::SVGCircleElement(Document& document)
AddToPropertyMap(r_);
}
-void SVGCircleElement::Trace(Visitor* visitor) {
+void SVGCircleElement::Trace(Visitor* visitor) const {
visitor->Trace(cx_);
visitor->Trace(cy_);
visitor->Trace(r_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_circle_element.h b/chromium/third_party/blink/renderer/core/svg/svg_circle_element.h
index 56ef0c7bab8..4866c28304d 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_circle_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_circle_element.h
@@ -39,7 +39,7 @@ class SVGCircleElement final : public SVGGeometryElement {
SVGAnimatedLength* cy() const { return cy_.Get(); }
SVGAnimatedLength* r() const { return r_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_clip_path_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_clip_path_element.cc
index c48dd93af9a..52c10601819 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_clip_path_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_clip_path_element.cc
@@ -36,7 +36,7 @@ SVGClipPathElement::SVGClipPathElement(Document& document)
AddToPropertyMap(clip_path_units_);
}
-void SVGClipPathElement::Trace(Visitor* visitor) {
+void SVGClipPathElement::Trace(Visitor* visitor) const {
visitor->Trace(clip_path_units_);
SVGGraphicsElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_clip_path_element.h b/chromium/third_party/blink/renderer/core/svg/svg_clip_path_element.h
index 66fb5ba08c4..2ed4287e3e7 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_clip_path_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_clip_path_element.h
@@ -42,7 +42,7 @@ class SVGClipPathElement final : public SVGGraphicsElement {
bool SupportsFocus() const override { return false; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_component_transfer_function_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_component_transfer_function_element.cc
index c4148a8c1e1..5619e4c95e1 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_component_transfer_function_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_component_transfer_function_element.cc
@@ -79,7 +79,7 @@ SVGComponentTransferFunctionElement::SVGComponentTransferFunctionElement(
AddToPropertyMap(type_);
}
-void SVGComponentTransferFunctionElement::Trace(Visitor* visitor) {
+void SVGComponentTransferFunctionElement::Trace(Visitor* visitor) const {
visitor->Trace(table_values_);
visitor->Trace(slope_);
visitor->Trace(intercept_);
@@ -110,7 +110,7 @@ void SVGComponentTransferFunctionElement::SvgAttributeChanged(
ComponentTransferFunction
SVGComponentTransferFunctionElement::TransferFunction() const {
ComponentTransferFunction func;
- func.type = type_->CurrentValue()->EnumValue();
+ func.type = type_->CurrentEnumValue();
func.slope = slope_->CurrentValue()->Value();
func.intercept = intercept_->CurrentValue()->Value();
func.amplitude = amplitude_->CurrentValue()->Value();
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_component_transfer_function_element.h b/chromium/third_party/blink/renderer/core/svg/svg_component_transfer_function_element.h
index bb8c936f776..453b1a210b1 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_component_transfer_function_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_component_transfer_function_element.h
@@ -46,7 +46,7 @@ class SVGComponentTransferFunctionElement : public SVGElement {
SVGAnimatedNumber* offset() { return offset_.Get(); }
SVGAnimatedEnumeration<ComponentTransferType>* type() { return type_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
SVGComponentTransferFunctionElement(const QualifiedName&, Document&);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_document_extensions.cc b/chromium/third_party/blink/renderer/core/svg/svg_document_extensions.cc
index 28834f7ccdd..ae50f287ef6 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_document_extensions.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_document_extensions.cc
@@ -162,7 +162,7 @@ SVGSVGElement* SVGDocumentExtensions::rootElement() const {
return rootElement(*document_);
}
-void SVGDocumentExtensions::Trace(Visitor* visitor) {
+void SVGDocumentExtensions::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(time_containers_);
visitor->Trace(web_animations_pending_svg_elements_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_document_extensions.h b/chromium/third_party/blink/renderer/core/svg/svg_document_extensions.h
index cf22eaa6011..c22f7e4387c 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_document_extensions.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_document_extensions.h
@@ -71,7 +71,7 @@ class CORE_EXPORT SVGDocumentExtensions final
static SVGSVGElement* rootElement(const Document&);
SVGSVGElement* rootElement() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<Document> document_;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_element.cc
index 3fe6911ca7d..49891db428f 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_element.cc
@@ -1248,7 +1248,7 @@ SVGElementResourceClient& SVGElement::EnsureSVGResourceClient() {
return EnsureSVGRareData()->EnsureSVGResourceClient(this);
}
-void SVGElement::Trace(Visitor* visitor) {
+void SVGElement::Trace(Visitor* visitor) const {
visitor->Trace(elements_with_relative_lengths_);
visitor->Trace(attribute_to_property_map_);
visitor->Trace(svg_rare_data_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_element.h b/chromium/third_party/blink/renderer/core/svg/svg_element.h
index 3a626772952..42e318b46c0 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_element.h
@@ -209,7 +209,7 @@ class CORE_EXPORT SVGElement : public Element {
void SetNeedsStyleRecalcForInstances(StyleChangeType,
const StyleChangeReasonForTracing&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
static const AtomicString& EventParameterName();
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_element_rare_data.cc b/chromium/third_party/blink/renderer/core/svg/svg_element_rare_data.cc
index 7e01c8db53f..0d05f255cad 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_element_rare_data.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_element_rare_data.cc
@@ -57,7 +57,7 @@ SVGElementResourceClient& SVGElementRareData::EnsureSVGResourceClient(
return *resource_client_;
}
-void SVGElementRareData::Trace(Visitor* visitor) {
+void SVGElementRareData::Trace(Visitor* visitor) const {
visitor->Trace(outgoing_references_);
visitor->Trace(incoming_references_);
visitor->Trace(animated_smil_style_properties_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_element_rare_data.h b/chromium/third_party/blink/renderer/core/svg/svg_element_rare_data.h
index 05881f5f07b..6a60be5ce90 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_element_rare_data.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_element_rare_data.h
@@ -104,7 +104,7 @@ class SVGElementRareData final : public GarbageCollected<SVGElementRareData> {
AffineTransform* AnimateMotionTransform();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
SVGElementSet outgoing_references_;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_ellipse_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_ellipse_element.cc
index 83220afa1a5..a5098d79428 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_ellipse_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_ellipse_element.cc
@@ -58,7 +58,7 @@ SVGEllipseElement::SVGEllipseElement(Document& document)
AddToPropertyMap(ry_);
}
-void SVGEllipseElement::Trace(Visitor* visitor) {
+void SVGEllipseElement::Trace(Visitor* visitor) const {
visitor->Trace(cx_);
visitor->Trace(cy_);
visitor->Trace(rx_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_ellipse_element.h b/chromium/third_party/blink/renderer/core/svg/svg_ellipse_element.h
index 7ba0af3f1db..4cce1139d21 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_ellipse_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_ellipse_element.h
@@ -40,7 +40,7 @@ class SVGEllipseElement final : public SVGGeometryElement {
SVGAnimatedLength* rx() const { return rx_.Get(); }
SVGAnimatedLength* ry() const { return ry_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void CollectStyleForPresentationAttribute(
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_enumeration.cc b/chromium/third_party/blink/renderer/core/svg/svg_enumeration.cc
index 3a7a398bf39..7f4ec4d02d8 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_enumeration.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_enumeration.cc
@@ -34,16 +34,13 @@
namespace blink {
-SVGEnumerationBase::~SVGEnumerationBase() = default;
-
-SVGPropertyBase* SVGEnumerationBase::CloneForAnimation(
- const String& value) const {
- SVGEnumerationBase* svg_enumeration = Clone();
+SVGPropertyBase* SVGEnumeration::CloneForAnimation(const String& value) const {
+ SVGEnumeration* svg_enumeration = Clone();
svg_enumeration->SetValueAsString(value);
return svg_enumeration;
}
-String SVGEnumerationBase::ValueAsString() const {
+String SVGEnumeration::ValueAsString() const {
if (const char* enum_name = map_.NameFromValue(value_))
return String(enum_name);
@@ -51,27 +48,34 @@ String SVGEnumerationBase::ValueAsString() const {
return g_empty_string;
}
-void SVGEnumerationBase::SetValue(uint16_t value) {
+void SVGEnumeration::SetValue(uint16_t value) {
value_ = value;
NotifyChange();
}
-SVGParsingError SVGEnumerationBase::SetValueAsString(const String& string) {
+SVGParsingError SVGEnumeration::SetValueAsString(const String& string) {
uint16_t value = map_.ValueFromName(string);
if (value) {
- value_ = value;
- NotifyChange();
+ SetValue(value);
return SVGParseStatus::kNoError;
}
NotifyChange();
return SVGParseStatus::kExpectedEnumeration;
}
-void SVGEnumerationBase::Add(SVGPropertyBase*, SVGElement*) {
+uint16_t SVGEnumeration::MaxExposedEnumValue() const {
+ return map_.MaxExposedValue();
+}
+
+uint16_t SVGEnumeration::MaxInternalEnumValue() const {
+ return map_.ValueOfLast();
+}
+
+void SVGEnumeration::Add(SVGPropertyBase*, SVGElement*) {
NOTREACHED();
}
-void SVGEnumerationBase::CalculateAnimatedValue(
+void SVGEnumeration::CalculateAnimatedValue(
const SVGAnimateElement& animation_element,
float percentage,
unsigned repeat_count,
@@ -82,17 +86,9 @@ void SVGEnumerationBase::CalculateAnimatedValue(
NOTREACHED();
}
-float SVGEnumerationBase::CalculateDistance(SVGPropertyBase*, SVGElement*) {
- // No paced animations for boolean.
+float SVGEnumeration::CalculateDistance(SVGPropertyBase*, SVGElement*) {
+ // No paced animations for enumerations.
return -1;
}
-uint16_t SVGEnumerationBase::MaxExposedEnumValue() const {
- return map_.MaxExposedValue();
-}
-
-uint16_t SVGEnumerationBase::MaxInternalEnumValue() const {
- return map_.ValueOfLast();
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_enumeration.h b/chromium/third_party/blink/renderer/core/svg/svg_enumeration.h
index 22ed17f58e3..b1efe1b20e3 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_enumeration.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_enumeration.h
@@ -39,21 +39,42 @@ namespace blink {
class SVGEnumerationMap;
-class SVGEnumerationBase : public SVGPropertyBase {
+template <typename Enum>
+const SVGEnumerationMap& GetEnumerationMap();
+
+class SVGEnumeration : public SVGPropertyBase {
public:
// SVGEnumeration does not have a tear-off type.
typedef void TearOffType;
typedef uint16_t PrimitiveType;
- ~SVGEnumerationBase() override;
+ SVGEnumeration(uint16_t value, const SVGEnumerationMap& map)
+ : value_(value), map_(map) {}
+
+ template <typename Enum>
+ explicit SVGEnumeration(Enum new_value)
+ : SVGEnumeration(new_value, GetEnumerationMap<Enum>()) {}
uint16_t Value() const {
return value_ <= MaxExposedEnumValue() ? value_ : 0;
}
void SetValue(uint16_t);
+ // Typed accessors. These should generally be used instead of the above ones.
+ template <typename Enum>
+ Enum EnumValue() const {
+ DCHECK_LE(value_, MaxInternalEnumValue());
+ return static_cast<Enum>(value_);
+ }
+ template <typename Enum>
+ void SetEnumValue(Enum value) {
+ SetValue(value);
+ }
+
// SVGPropertyBase:
- virtual SVGEnumerationBase* Clone() const = 0;
+ SVGEnumeration* Clone() const {
+ return MakeGarbageCollected<SVGEnumeration>(value_, map_);
+ }
SVGPropertyBase* CloneForAnimation(const String&) const override;
String ValueAsString() const override;
@@ -80,9 +101,6 @@ class SVGEnumerationBase : public SVGPropertyBase {
static constexpr int kInitialValueBits = 3;
protected:
- SVGEnumerationBase(uint16_t value, const SVGEnumerationMap& map)
- : value_(value), map_(map) {}
-
// This is the maximum value of all the internal enumeration values.
// This assumes that the map is sorted on the enumeration value.
uint16_t MaxInternalEnumValue() const;
@@ -94,35 +112,10 @@ class SVGEnumerationBase : public SVGPropertyBase {
const SVGEnumerationMap& map_;
};
-template <typename Enum>
-const SVGEnumerationMap& GetEnumerationMap();
-
#define DECLARE_SVG_ENUM_MAP(cpp_enum_type) \
template <> \
const SVGEnumerationMap& GetEnumerationMap<cpp_enum_type>()
-template <typename Enum>
-class SVGEnumeration : public SVGEnumerationBase {
- public:
- explicit SVGEnumeration(Enum new_value)
- : SVGEnumerationBase(new_value, GetEnumerationMap<Enum>()) {}
- ~SVGEnumeration() override = default;
-
- SVGEnumerationBase* Clone() const override {
- return MakeGarbageCollected<SVGEnumeration>(EnumValue());
- }
-
- Enum EnumValue() const {
- DCHECK_LE(value_, MaxInternalEnumValue());
- return static_cast<Enum>(value_);
- }
-
- void SetEnumValue(Enum value) {
- value_ = value;
- NotifyChange();
- }
-};
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_ENUMERATION_H_
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_enumeration_map.h b/chromium/third_party/blink/renderer/core/svg/svg_enumeration_map.h
index 06586b5c98b..21114756fe9 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_enumeration_map.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_enumeration_map.h
@@ -5,6 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_ENUMERATION_MAP_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_ENUMERATION_MAP_H_
+#include "base/check.h"
+#include "base/check_op.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_external_document_cache.cc b/chromium/third_party/blink/renderer/core/svg/svg_external_document_cache.cc
index 91a0eaaf0c1..c64e3671352 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_external_document_cache.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_external_document_cache.cc
@@ -48,7 +48,7 @@ void SVGExternalDocumentCache::Entry::AddClient(Client* client) {
clients_.insert(client);
return;
}
- context_document_->GetTaskRunner(TaskType::kInternalLoading)
+ context_->GetTaskRunner(TaskType::kInternalLoading)
->PostTask(
FROM_HERE,
WTF::Bind(&SVGExternalDocumentCache::Client::NotifyFinished,
@@ -70,16 +70,16 @@ Document* SVGExternalDocumentCache::Entry::GetDocument() {
document_ = XMLDocument::CreateSVG(
DocumentInit::Create()
.WithURL(resource->GetResponse().CurrentRequestUrl())
- .WithContextDocument(context_document_));
+ .WithExecutionContext(context_.Get()));
document_->SetContent(resource->DecodedText());
}
return document_.Get();
}
-void SVGExternalDocumentCache::Entry::Trace(Visitor* visitor) {
+void SVGExternalDocumentCache::Entry::Trace(Visitor* visitor) const {
ResourceClient::Trace(visitor);
visitor->Trace(document_);
- visitor->Trace(context_document_);
+ visitor->Trace(context_);
visitor->Trace(clients_);
}
@@ -114,7 +114,8 @@ SVGExternalDocumentCache::Entry* SVGExternalDocumentCache::Get(
params.SetRequestDestination(network::mojom::RequestDestination::kImage);
Document* context_document = GetSupplementable();
- Entry* entry = MakeGarbageCollected<Entry>(context_document);
+ Entry* entry =
+ MakeGarbageCollected<Entry>(context_document->GetExecutionContext());
Resource* resource = TextResource::FetchSVGDocument(
params, context_document->Fetcher(), entry);
// TODO(fs): Handle revalidations that return a new/different resource without
@@ -126,7 +127,7 @@ SVGExternalDocumentCache::Entry* SVGExternalDocumentCache::Get(
return entry;
}
-void SVGExternalDocumentCache::Trace(Visitor* visitor) {
+void SVGExternalDocumentCache::Trace(Visitor* visitor) const {
Supplement<Document>::Trace(visitor);
visitor->Trace(entries_);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_external_document_cache.h b/chromium/third_party/blink/renderer/core/svg/svg_external_document_cache.h
index a5eba9a0da4..8ff0d5f6fe9 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_external_document_cache.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_external_document_cache.h
@@ -32,6 +32,7 @@
namespace blink {
class Document;
+class ExecutionContext;
class CORE_EXPORT SVGExternalDocumentCache
: public GarbageCollected<SVGExternalDocumentCache>,
@@ -42,7 +43,7 @@ class CORE_EXPORT SVGExternalDocumentCache
static const char kSupplementName[];
static SVGExternalDocumentCache* From(Document&);
explicit SVGExternalDocumentCache(Document&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
class Client : public GarbageCollectedMixin {
public:
@@ -54,10 +55,9 @@ class CORE_EXPORT SVGExternalDocumentCache
USING_GARBAGE_COLLECTED_MIXIN(Entry);
public:
- explicit Entry(Document* context_document)
- : context_document_(context_document) {}
+ explicit Entry(ExecutionContext* context) : context_(context) {}
~Entry() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
Document* GetDocument();
const KURL& Url() const { return GetResource()->Url(); }
@@ -70,7 +70,7 @@ class CORE_EXPORT SVGExternalDocumentCache
String DebugName() const override { return "SVGExternalDocumentCache"; }
Member<Document> document_;
- Member<Document> context_document_;
+ Member<ExecutionContext> context_;
HeapHashSet<WeakMember<Client>> clients_;
};
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_blend_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_blend_element.cc
index 996a30cc855..bb733f2cdbf 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_blend_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_blend_element.cc
@@ -94,7 +94,7 @@ SVGFEBlendElement::SVGFEBlendElement(Document& document)
AddToPropertyMap(mode_);
}
-void SVGFEBlendElement::Trace(Visitor* visitor) {
+void SVGFEBlendElement::Trace(Visitor* visitor) const {
visitor->Trace(in1_);
visitor->Trace(in2_);
visitor->Trace(mode_);
@@ -106,7 +106,7 @@ bool SVGFEBlendElement::SetFilterEffectAttribute(
const QualifiedName& attr_name) {
FEBlend* blend = static_cast<FEBlend*>(effect);
if (attr_name == svg_names::kModeAttr)
- return blend->SetBlendMode(ToBlendMode(mode_->CurrentValue()->EnumValue()));
+ return blend->SetBlendMode(ToBlendMode(mode_->CurrentEnumValue()));
return SVGFilterPrimitiveStandardAttributes::SetFilterEffectAttribute(
effect, attr_name);
@@ -138,7 +138,7 @@ FilterEffect* SVGFEBlendElement::Build(SVGFilterBuilder* filter_builder,
DCHECK(input2);
auto* effect = MakeGarbageCollected<FEBlend>(
- filter, ToBlendMode(mode_->CurrentValue()->EnumValue()));
+ filter, ToBlendMode(mode_->CurrentEnumValue()));
FilterEffectVector& input_effects = effect->InputEffects();
input_effects.ReserveCapacity(2);
input_effects.push_back(input1);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_blend_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_blend_element.h
index 4fd2ea96ca0..6a00a00d314 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_blend_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_blend_element.h
@@ -57,7 +57,7 @@ class SVGFEBlendElement final : public SVGFilterPrimitiveStandardAttributes {
SVGAnimatedString* in2() { return in2_.Get(); }
SVGAnimatedEnumeration<Mode>* mode() { return mode_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool SetFilterEffectAttribute(FilterEffect*,
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.cc
index 0a4651ec757..1187739737e 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.cc
@@ -55,7 +55,7 @@ SVGFEColorMatrixElement::SVGFEColorMatrixElement(Document& document)
AddToPropertyMap(type_);
}
-void SVGFEColorMatrixElement::Trace(Visitor* visitor) {
+void SVGFEColorMatrixElement::Trace(Visitor* visitor) const {
visitor->Trace(values_);
visitor->Trace(in1_);
visitor->Trace(type_);
@@ -67,7 +67,7 @@ bool SVGFEColorMatrixElement::SetFilterEffectAttribute(
const QualifiedName& attr_name) {
FEColorMatrix* color_matrix = static_cast<FEColorMatrix*>(effect);
if (attr_name == svg_names::kTypeAttr)
- return color_matrix->SetType(type_->CurrentValue()->EnumValue());
+ return color_matrix->SetType(type_->CurrentEnumValue());
if (attr_name == svg_names::kValuesAttr)
return color_matrix->SetValues(values_->CurrentValue()->ToFloatVector());
@@ -99,7 +99,7 @@ FilterEffect* SVGFEColorMatrixElement::Build(SVGFilterBuilder* filter_builder,
AtomicString(in1_->CurrentValue()->Value()));
DCHECK(input1);
- ColorMatrixType filter_type = type_->CurrentValue()->EnumValue();
+ ColorMatrixType filter_type = type_->CurrentEnumValue();
auto* effect = MakeGarbageCollected<FEColorMatrix>(
filter, filter_type, values_->CurrentValue()->ToFloatVector());
effect->InputEffects().push_back(input1);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.h
index aedf2140077..bc78acad210 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.h
@@ -42,7 +42,7 @@ class SVGFEColorMatrixElement final
SVGAnimatedString* in1() { return in1_.Get(); }
SVGAnimatedEnumeration<ColorMatrixType>* type() { return type_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool SetFilterEffectAttribute(FilterEffect*, const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.cc
index 1464024dc7c..bffacef42fb 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.cc
@@ -39,7 +39,7 @@ SVGFEComponentTransferElement::SVGFEComponentTransferElement(Document& document)
AddToPropertyMap(in1_);
}
-void SVGFEComponentTransferElement::Trace(Visitor* visitor) {
+void SVGFEComponentTransferElement::Trace(Visitor* visitor) const {
visitor->Trace(in1_);
SVGFilterPrimitiveStandardAttributes::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.h
index 2c2f3ed758c..ae5f775492e 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.h
@@ -35,7 +35,7 @@ class SVGFEComponentTransferElement final
SVGAnimatedString* in1() { return in1_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_composite_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_composite_element.cc
index 0613666c59d..1b2f6a6bbcf 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_composite_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_composite_element.cc
@@ -74,7 +74,7 @@ SVGFECompositeElement::SVGFECompositeElement(Document& document)
AddToPropertyMap(svg_operator_);
}
-void SVGFECompositeElement::Trace(Visitor* visitor) {
+void SVGFECompositeElement::Trace(Visitor* visitor) const {
visitor->Trace(k1_);
visitor->Trace(k2_);
visitor->Trace(k3_);
@@ -90,7 +90,7 @@ bool SVGFECompositeElement::SetFilterEffectAttribute(
const QualifiedName& attr_name) {
FEComposite* composite = static_cast<FEComposite*>(effect);
if (attr_name == svg_names::kOperatorAttr)
- return composite->SetOperation(svg_operator_->CurrentValue()->EnumValue());
+ return composite->SetOperation(svg_operator_->CurrentEnumValue());
if (attr_name == svg_names::kK1Attr)
return composite->SetK1(k1_->CurrentValue()->Value());
if (attr_name == svg_names::kK2Attr)
@@ -133,9 +133,9 @@ FilterEffect* SVGFECompositeElement::Build(SVGFilterBuilder* filter_builder,
DCHECK(input2);
auto* effect = MakeGarbageCollected<FEComposite>(
- filter, svg_operator_->CurrentValue()->EnumValue(),
- k1_->CurrentValue()->Value(), k2_->CurrentValue()->Value(),
- k3_->CurrentValue()->Value(), k4_->CurrentValue()->Value());
+ filter, svg_operator_->CurrentEnumValue(), k1_->CurrentValue()->Value(),
+ k2_->CurrentValue()->Value(), k3_->CurrentValue()->Value(),
+ k4_->CurrentValue()->Value());
FilterEffectVector& input_effects = effect->InputEffects();
input_effects.ReserveCapacity(2);
input_effects.push_back(input1);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_composite_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_composite_element.h
index 63cac0f631b..80f0a1cbc99 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_composite_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_composite_element.h
@@ -48,7 +48,7 @@ class SVGFECompositeElement final
return svg_operator_.Get();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool SetFilterEffectAttribute(FilterEffect*, const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.cc
index d37f9815c99..383993435fc 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.cc
@@ -116,7 +116,7 @@ SVGFEConvolveMatrixElement::SVGFEConvolveMatrixElement(Document& document)
AddToPropertyMap(target_y_);
}
-void SVGFEConvolveMatrixElement::Trace(Visitor* visitor) {
+void SVGFEConvolveMatrixElement::Trace(Visitor* visitor) const {
visitor->Trace(bias_);
visitor->Trace(divisor_);
visitor->Trace(in1_);
@@ -166,8 +166,7 @@ bool SVGFEConvolveMatrixElement::SetFilterEffectAttribute(
const QualifiedName& attr_name) {
FEConvolveMatrix* convolve_matrix = static_cast<FEConvolveMatrix*>(effect);
if (attr_name == svg_names::kEdgeModeAttr)
- return convolve_matrix->SetEdgeMode(
- edge_mode_->CurrentValue()->EnumValue());
+ return convolve_matrix->SetEdgeMode(edge_mode_->CurrentEnumValue());
if (attr_name == svg_names::kDivisorAttr)
return convolve_matrix->SetDivisor(ComputeDivisor());
if (attr_name == svg_names::kBiasAttr)
@@ -214,7 +213,7 @@ FilterEffect* SVGFEConvolveMatrixElement::Build(
auto* effect = MakeGarbageCollected<FEConvolveMatrix>(
filter, MatrixOrder(), ComputeDivisor(), bias_->CurrentValue()->Value(),
- TargetPoint(), edge_mode_->CurrentValue()->EnumValue(),
+ TargetPoint(), edge_mode_->CurrentEnumValue(),
preserve_alpha_->CurrentValue()->Value(),
kernel_matrix_->CurrentValue()->ToFloatVector());
effect->InputEffects().push_back(input1);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.h
index c5916541436..4bce746a679 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.h
@@ -59,7 +59,7 @@ class SVGFEConvolveMatrixElement final
SVGAnimatedInteger* targetX() { return target_x_.Get(); }
SVGAnimatedInteger* targetY() { return target_y_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
IntSize MatrixOrder() const;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc
index 58e58653468..eba0dc1eeef 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc
@@ -50,7 +50,7 @@ SVGFEDiffuseLightingElement::SVGFEDiffuseLightingElement(Document& document)
AddToPropertyMap(in1_);
}
-void SVGFEDiffuseLightingElement::Trace(Visitor* visitor) {
+void SVGFEDiffuseLightingElement::Trace(Visitor* visitor) const {
visitor->Trace(diffuse_constant_);
visitor->Trace(surface_scale_);
visitor->Trace(kernel_unit_length_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.h
index d93cf6520e8..0748ed2f0a7 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.h
@@ -49,7 +49,7 @@ class SVGFEDiffuseLightingElement final
}
SVGAnimatedString* in1() { return in1_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool SetFilterEffectAttribute(FilterEffect*, const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.cc
index bfd5b1e2997..6d2ce378e22 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.cc
@@ -60,7 +60,7 @@ SVGFEDisplacementMapElement::SVGFEDisplacementMapElement(Document& document)
AddToPropertyMap(y_channel_selector_);
}
-void SVGFEDisplacementMapElement::Trace(Visitor* visitor) {
+void SVGFEDisplacementMapElement::Trace(Visitor* visitor) const {
visitor->Trace(scale_);
visitor->Trace(in1_);
visitor->Trace(in2_);
@@ -73,12 +73,14 @@ bool SVGFEDisplacementMapElement::SetFilterEffectAttribute(
FilterEffect* effect,
const QualifiedName& attr_name) {
FEDisplacementMap* displacement_map = static_cast<FEDisplacementMap*>(effect);
- if (attr_name == svg_names::kXChannelSelectorAttr)
+ if (attr_name == svg_names::kXChannelSelectorAttr) {
return displacement_map->SetXChannelSelector(
- x_channel_selector_->CurrentValue()->EnumValue());
- if (attr_name == svg_names::kYChannelSelectorAttr)
+ x_channel_selector_->CurrentEnumValue());
+ }
+ if (attr_name == svg_names::kYChannelSelectorAttr) {
return displacement_map->SetYChannelSelector(
- y_channel_selector_->CurrentValue()->EnumValue());
+ y_channel_selector_->CurrentEnumValue());
+ }
if (attr_name == svg_names::kScaleAttr)
return displacement_map->SetScale(scale_->CurrentValue()->Value());
@@ -116,9 +118,8 @@ FilterEffect* SVGFEDisplacementMapElement::Build(
DCHECK(input2);
auto* effect = MakeGarbageCollected<FEDisplacementMap>(
- filter, x_channel_selector_->CurrentValue()->EnumValue(),
- y_channel_selector_->CurrentValue()->EnumValue(),
- scale_->CurrentValue()->Value());
+ filter, x_channel_selector_->CurrentEnumValue(),
+ y_channel_selector_->CurrentEnumValue(), scale_->CurrentValue()->Value());
FilterEffectVector& input_effects = effect->InputEffects();
input_effects.ReserveCapacity(2);
input_effects.push_back(input1);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.h
index 0dafd29b177..d345789ef60 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.h
@@ -49,7 +49,7 @@ class SVGFEDisplacementMapElement final
return y_channel_selector_.Get();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool SetFilterEffectAttribute(FilterEffect*,
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc
index 7cced8f4409..85ba2dc6592 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc
@@ -45,7 +45,7 @@ SVGFEDropShadowElement::SVGFEDropShadowElement(Document& document)
AddToPropertyMap(in1_);
}
-void SVGFEDropShadowElement::Trace(Visitor* visitor) {
+void SVGFEDropShadowElement::Trace(Visitor* visitor) const {
visitor->Trace(dx_);
visitor->Trace(dy_);
visitor->Trace(std_deviation_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.h
index ce229e782b2..85d93b1252c 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.h
@@ -42,7 +42,7 @@ class SVGFEDropShadowElement final
SVGAnimatedNumber* stdDeviationY() { return std_deviation_->SecondNumber(); }
SVGAnimatedString* in1() { return in1_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.cc
index 51933a73a5f..83afab8d521 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.cc
@@ -39,7 +39,7 @@ SVGFEGaussianBlurElement::SVGFEGaussianBlurElement(Document& document)
AddToPropertyMap(in1_);
}
-void SVGFEGaussianBlurElement::Trace(Visitor* visitor) {
+void SVGFEGaussianBlurElement::Trace(Visitor* visitor) const {
visitor->Trace(std_deviation_);
visitor->Trace(in1_);
SVGFilterPrimitiveStandardAttributes::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.h
index 9dc19929d39..30cfbb2a427 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.h
@@ -40,7 +40,7 @@ class SVGFEGaussianBlurElement final
SVGAnimatedNumber* stdDeviationY() { return std_deviation_->SecondNumber(); }
SVGAnimatedString* in1() { return in1_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.cc
index daa126edaef..7169a9d90c6 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.cc
@@ -51,7 +51,7 @@ void SVGFEImageElement::Dispose() {
ClearImageResource();
}
-void SVGFEImageElement::Trace(Visitor* visitor) {
+void SVGFEImageElement::Trace(Visitor* visitor) const {
visitor->Trace(preserve_aspect_ratio_);
visitor->Trace(cached_image_);
visitor->Trace(target_id_observer_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.h
index 2366d7b9dac..475a615acba 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.h
@@ -52,7 +52,7 @@ class SVGFEImageElement final : public SVGFilterPrimitiveStandardAttributes,
void Dispose();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_light_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_light_element.cc
index 80aa829c848..4ad379b7662 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_light_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_light_element.cc
@@ -81,7 +81,7 @@ SVGFELightElement::SVGFELightElement(const QualifiedName& tag_name,
AddToPropertyMap(limiting_cone_angle_);
}
-void SVGFELightElement::Trace(Visitor* visitor) {
+void SVGFELightElement::Trace(Visitor* visitor) const {
visitor->Trace(azimuth_);
visitor->Trace(elevation_);
visitor->Trace(x_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_light_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_light_element.h
index d416833aa04..8a4687f5f6d 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_light_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_light_element.h
@@ -65,7 +65,7 @@ class SVGFELightElement : public SVGElement {
return limiting_cone_angle_.Get();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
SVGFELightElement(const QualifiedName&, Document&);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_merge_node_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_merge_node_element.cc
index 6df184e02c3..6b901176d48 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_merge_node_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_merge_node_element.cc
@@ -31,7 +31,7 @@ SVGFEMergeNodeElement::SVGFEMergeNodeElement(Document& document)
AddToPropertyMap(in1_);
}
-void SVGFEMergeNodeElement::Trace(Visitor* visitor) {
+void SVGFEMergeNodeElement::Trace(Visitor* visitor) const {
visitor->Trace(in1_);
SVGElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_merge_node_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_merge_node_element.h
index c6491784fb4..91c8a254d1d 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_merge_node_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_merge_node_element.h
@@ -35,7 +35,7 @@ class SVGFEMergeNodeElement final : public SVGElement {
SVGAnimatedString* in1() { return in1_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_morphology_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_morphology_element.cc
index 5ee79e507d3..2049ec50663 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_morphology_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_morphology_element.cc
@@ -54,7 +54,7 @@ SVGFEMorphologyElement::SVGFEMorphologyElement(Document& document)
AddToPropertyMap(svg_operator_);
}
-void SVGFEMorphologyElement::Trace(Visitor* visitor) {
+void SVGFEMorphologyElement::Trace(Visitor* visitor) const {
visitor->Trace(radius_);
visitor->Trace(in1_);
visitor->Trace(svg_operator_);
@@ -66,8 +66,7 @@ bool SVGFEMorphologyElement::SetFilterEffectAttribute(
const QualifiedName& attr_name) {
FEMorphology* morphology = static_cast<FEMorphology*>(effect);
if (attr_name == svg_names::kOperatorAttr)
- return morphology->SetMorphologyOperator(
- svg_operator_->CurrentValue()->EnumValue());
+ return morphology->SetMorphologyOperator(svg_operator_->CurrentEnumValue());
if (attr_name == svg_names::kRadiusAttr) {
// Both setRadius functions should be evaluated separately.
bool is_radius_x_changed =
@@ -114,7 +113,7 @@ FilterEffect* SVGFEMorphologyElement::Build(SVGFilterBuilder* filter_builder,
float x_radius = radiusX()->CurrentValue()->Value();
float y_radius = radiusY()->CurrentValue()->Value();
auto* effect = MakeGarbageCollected<FEMorphology>(
- filter, svg_operator_->CurrentValue()->EnumValue(), x_radius, y_radius);
+ filter, svg_operator_->CurrentEnumValue(), x_radius, y_radius);
effect->InputEffects().push_back(input1);
return effect;
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_morphology_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_morphology_element.h
index 80ab5105480..fbba044e926 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_morphology_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_morphology_element.h
@@ -44,7 +44,7 @@ class SVGFEMorphologyElement final
return svg_operator_.Get();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool SetFilterEffectAttribute(FilterEffect*, const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_offset_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_offset_element.cc
index b08be255166..dc4f2d40b88 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_offset_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_offset_element.cc
@@ -41,7 +41,7 @@ SVGFEOffsetElement::SVGFEOffsetElement(Document& document)
AddToPropertyMap(in1_);
}
-void SVGFEOffsetElement::Trace(Visitor* visitor) {
+void SVGFEOffsetElement::Trace(Visitor* visitor) const {
visitor->Trace(dx_);
visitor->Trace(dy_);
visitor->Trace(in1_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_offset_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_offset_element.h
index 908adbda57e..979f3e8c2ea 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_offset_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_offset_element.h
@@ -37,7 +37,7 @@ class SVGFEOffsetElement final : public SVGFilterPrimitiveStandardAttributes {
SVGAnimatedNumber* dy() { return dy_.Get(); }
SVGAnimatedString* in1() { return in1_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc
index e857938b3fb..694ce9d87a5 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc
@@ -57,7 +57,7 @@ SVGFESpecularLightingElement::SVGFESpecularLightingElement(Document& document)
AddToPropertyMap(in1_);
}
-void SVGFESpecularLightingElement::Trace(Visitor* visitor) {
+void SVGFESpecularLightingElement::Trace(Visitor* visitor) const {
visitor->Trace(specular_constant_);
visitor->Trace(specular_exponent_);
visitor->Trace(surface_scale_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.h
index 64d75d05b10..9d3d768445b 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.h
@@ -51,7 +51,7 @@ class SVGFESpecularLightingElement final
}
SVGAnimatedString* in1() { return in1_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool SetFilterEffectAttribute(FilterEffect*, const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_tile_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_tile_element.cc
index 220b8e03787..29bcf6359a0 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_tile_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_tile_element.cc
@@ -33,7 +33,7 @@ SVGFETileElement::SVGFETileElement(Document& document)
AddToPropertyMap(in1_);
}
-void SVGFETileElement::Trace(Visitor* visitor) {
+void SVGFETileElement::Trace(Visitor* visitor) const {
visitor->Trace(in1_);
SVGFilterPrimitiveStandardAttributes::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_tile_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_tile_element.h
index b22f758db17..faa7e913b47 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_tile_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_tile_element.h
@@ -34,7 +34,7 @@ class SVGFETileElement final : public SVGFilterPrimitiveStandardAttributes {
SVGAnimatedString* in1() { return in1_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.cc
index 1136c829f3f..06e1c8a98c2 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.cc
@@ -75,7 +75,7 @@ SVGFETurbulenceElement::SVGFETurbulenceElement(Document& document)
AddToPropertyMap(num_octaves_);
}
-void SVGFETurbulenceElement::Trace(Visitor* visitor) {
+void SVGFETurbulenceElement::Trace(Visitor* visitor) const {
visitor->Trace(base_frequency_);
visitor->Trace(seed_);
visitor->Trace(stitch_tiles_);
@@ -89,10 +89,11 @@ bool SVGFETurbulenceElement::SetFilterEffectAttribute(
const QualifiedName& attr_name) {
FETurbulence* turbulence = static_cast<FETurbulence*>(effect);
if (attr_name == svg_names::kTypeAttr)
- return turbulence->SetType(type_->CurrentValue()->EnumValue());
- if (attr_name == svg_names::kStitchTilesAttr)
- return turbulence->SetStitchTiles(
- stitch_tiles_->CurrentValue()->EnumValue() == kSvgStitchtypeStitch);
+ return turbulence->SetType(type_->CurrentEnumValue());
+ if (attr_name == svg_names::kStitchTilesAttr) {
+ return turbulence->SetStitchTiles(stitch_tiles_->CurrentEnumValue() ==
+ kSvgStitchtypeStitch);
+ }
if (attr_name == svg_names::kBaseFrequencyAttr) {
bool base_frequency_x_changed = turbulence->SetBaseFrequencyX(
baseFrequencyX()->CurrentValue()->Value());
@@ -126,11 +127,11 @@ void SVGFETurbulenceElement::SvgAttributeChanged(
FilterEffect* SVGFETurbulenceElement::Build(SVGFilterBuilder*, Filter* filter) {
return MakeGarbageCollected<FETurbulence>(
- filter, type_->CurrentValue()->EnumValue(),
+ filter, type_->CurrentEnumValue(),
baseFrequencyX()->CurrentValue()->Value(),
baseFrequencyY()->CurrentValue()->Value(),
num_octaves_->CurrentValue()->Value(), seed_->CurrentValue()->Value(),
- stitch_tiles_->CurrentValue()->EnumValue() == kSvgStitchtypeStitch);
+ stitch_tiles_->CurrentEnumValue() == kSvgStitchtypeStitch);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.h
index 39c953c95cd..0abb0b0157b 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.h
@@ -58,7 +58,7 @@ class SVGFETurbulenceElement final
SVGAnimatedEnumeration<TurbulenceType>* type() { return type_.Get(); }
SVGAnimatedInteger* numOctaves() { return num_octaves_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Turbulence takes no inputs and doesn't taint origin, so we can always
// return false.
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_filter_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_filter_element.cc
index 510b134064c..25c0f8392bd 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_filter_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_filter_element.cc
@@ -77,7 +77,7 @@ SVGFilterElement::SVGFilterElement(Document& document)
SVGFilterElement::~SVGFilterElement() = default;
-void SVGFilterElement::Trace(Visitor* visitor) {
+void SVGFilterElement::Trace(Visitor* visitor) const {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(width_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_filter_element.h b/chromium/third_party/blink/renderer/core/svg/svg_filter_element.h
index 39d2c615efb..09508d43aae 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_filter_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_filter_element.h
@@ -42,7 +42,7 @@ class CORE_EXPORT SVGFilterElement final : public SVGElement,
USING_GARBAGE_COLLECTED_MIXIN(SVGFilterElement);
public:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
explicit SVGFilterElement(Document&);
~SVGFilterElement() override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.cc b/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.cc
index 5654af88baf..07b1b38209a 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.cc
@@ -69,7 +69,7 @@ SVGFilterPrimitiveStandardAttributes::SVGFilterPrimitiveStandardAttributes(
AddToPropertyMap(result_);
}
-void SVGFilterPrimitiveStandardAttributes::Trace(Visitor* visitor) {
+void SVGFilterPrimitiveStandardAttributes::Trace(Visitor* visitor) const {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(width_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h b/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h
index 50aba21ab89..79ef104287c 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h
@@ -55,7 +55,7 @@ class SVGFilterPrimitiveStandardAttributes : public SVGElement {
SVGAnimatedLength* height() const { return height_.Get(); }
SVGAnimatedString* result() const { return result_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void PrimitiveAttributeChanged(const QualifiedName&);
void Invalidate();
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fit_to_view_box.cc b/chromium/third_party/blink/renderer/core/svg/svg_fit_to_view_box.cc
index 2284b380fae..b3dcf66e47f 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fit_to_view_box.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fit_to_view_box.cc
@@ -60,7 +60,7 @@ SVGFitToViewBox::SVGFitToViewBox(SVGElement* element)
element->AddToPropertyMap(preserve_aspect_ratio_);
}
-void SVGFitToViewBox::Trace(Visitor* visitor) {
+void SVGFitToViewBox::Trace(Visitor* visitor) const {
visitor->Trace(view_box_);
visitor->Trace(preserve_aspect_ratio_);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fit_to_view_box.h b/chromium/third_party/blink/renderer/core/svg/svg_fit_to_view_box.h
index 54d922bee5a..dec540808bf 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fit_to_view_box.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fit_to_view_box.h
@@ -54,7 +54,7 @@ class SVGFitToViewBox : public GarbageCollectedMixin {
return preserve_aspect_ratio_.Get();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit SVGFitToViewBox(SVGElement*);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.cc
index e570ca8bc8e..61a51d300e7 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.cc
@@ -64,7 +64,7 @@ SVGForeignObjectElement::SVGForeignObjectElement(Document& document)
UseCounter::Count(document, WebFeature::kSVGForeignObjectElement);
}
-void SVGForeignObjectElement::Trace(Visitor* visitor) {
+void SVGForeignObjectElement::Trace(Visitor* visitor) const {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(width_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.h b/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.h
index b9559036a59..e3b79ee3898 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.h
@@ -37,7 +37,7 @@ class SVGForeignObjectElement final : public SVGGraphicsElement {
SVGAnimatedLength* width() const { return width_.Get(); }
SVGAnimatedLength* height() const { return height_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void CollectStyleForPresentationAttribute(
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_geometry_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_geometry_element.cc
index aad481f8d48..47104211cb5 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_geometry_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_geometry_element.cc
@@ -75,7 +75,7 @@ void SVGGeometryElement::SvgAttributeChanged(const QualifiedName& attr_name) {
SVGGraphicsElement::SvgAttributeChanged(attr_name);
}
-void SVGGeometryElement::Trace(Visitor* visitor) {
+void SVGGeometryElement::Trace(Visitor* visitor) const {
visitor->Trace(path_length_);
SVGGraphicsElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_geometry_element.h b/chromium/third_party/blink/renderer/core/svg/svg_geometry_element.h
index c6de7fb18db..8ec93d84ceb 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_geometry_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_geometry_element.h
@@ -59,7 +59,7 @@ class SVGGeometryElement : public SVGGraphicsElement {
static float PathLengthScaleFactor(float computed_path_length,
float author_path_length);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
SVGGeometryElement(const QualifiedName&,
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.cc
index 749dcbdcbcc..68914717f18 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.cc
@@ -67,7 +67,7 @@ SVGGradientElement::SVGGradientElement(const QualifiedName& tag_name,
AddToPropertyMap(gradient_units_);
}
-void SVGGradientElement::Trace(Visitor* visitor) {
+void SVGGradientElement::Trace(Visitor* visitor) const {
visitor->Trace(gradient_transform_);
visitor->Trace(spread_method_);
visitor->Trace(gradient_units_);
@@ -168,10 +168,10 @@ void SVGGradientElement::InvalidateDependentGradients() {
void SVGGradientElement::CollectCommonAttributes(
GradientAttributes& attributes) const {
if (!attributes.HasSpreadMethod() && spreadMethod()->IsSpecified())
- attributes.SetSpreadMethod(spreadMethod()->CurrentValue()->EnumValue());
+ attributes.SetSpreadMethod(spreadMethod()->CurrentEnumValue());
if (!attributes.HasGradientUnits() && gradientUnits()->IsSpecified())
- attributes.SetGradientUnits(gradientUnits()->CurrentValue()->EnumValue());
+ attributes.SetGradientUnits(gradientUnits()->CurrentEnumValue());
if (!attributes.HasGradientTransform() &&
HasTransform(SVGElement::kExcludeMotionTransform)) {
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.h b/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.h
index 4e8cf91995a..139c5ec99e6 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.h
@@ -64,7 +64,7 @@ class SVGGradientElement : public SVGElement, public SVGURIReference {
const SVGGradientElement* ReferencedElement() const;
void CollectCommonAttributes(GradientAttributes&) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
SVGGradientElement(const QualifiedName&, Document&);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.cc
index 37d3f45a698..27adfbc5543 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.cc
@@ -46,7 +46,7 @@ SVGGraphicsElement::SVGGraphicsElement(const QualifiedName& tag_name,
SVGGraphicsElement::~SVGGraphicsElement() = default;
-void SVGGraphicsElement::Trace(Visitor* visitor) {
+void SVGGraphicsElement::Trace(Visitor* visitor) const {
visitor->Trace(transform_);
SVGElement::Trace(visitor);
SVGTests::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.h b/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.h
index 5fbcc82e5e2..c2ca7ebacb8 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.h
@@ -64,7 +64,7 @@ class CORE_EXPORT SVGGraphicsElement : public SVGElement, public SVGTests {
CTMScope mode,
const SVGGraphicsElement* ancestor = nullptr) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
SVGGraphicsElement(const QualifiedName&,
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_image_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_image_element.cc
index 4ab1768f3a5..3dd31c2fb4d 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_image_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_image_element.cc
@@ -36,8 +36,10 @@ namespace blink {
SVGImageElement::SVGImageElement(Document& document)
: SVGGraphicsElement(svg_names::kImageTag, document),
SVGURIReference(this),
- is_default_overridden_intrinsic_size_(!document.IsFeatureEnabled(
- mojom::blink::DocumentPolicyFeature::kUnsizedMedia)),
+ is_default_overridden_intrinsic_size_(
+ GetExecutionContext() &&
+ !GetExecutionContext()->IsFeatureEnabled(
+ mojom::blink::DocumentPolicyFeature::kUnsizedMedia)),
x_(MakeGarbageCollected<SVGAnimatedLength>(
this,
svg_names::kXAttr,
@@ -74,7 +76,7 @@ SVGImageElement::SVGImageElement(Document& document)
AddToPropertyMap(preserve_aspect_ratio_);
}
-void SVGImageElement::Trace(Visitor* visitor) {
+void SVGImageElement::Trace(Visitor* visitor) const {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(width_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_image_element.h b/chromium/third_party/blink/renderer/core/svg/svg_image_element.h
index 049e9c7ab63..c529dfbd36b 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_image_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_image_element.h
@@ -43,7 +43,7 @@ class CORE_EXPORT SVGImageElement final
public:
explicit SVGImageElement(Document&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool CurrentFrameHasSingleSecurityOrigin() const;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_integer_optional_integer.cc b/chromium/third_party/blink/renderer/core/svg/svg_integer_optional_integer.cc
index 2c9a363c780..2628466c5ae 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_integer_optional_integer.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_integer_optional_integer.cc
@@ -39,7 +39,7 @@ SVGIntegerOptionalInteger::SVGIntegerOptionalInteger(SVGInteger* first_integer,
SVGInteger* second_integer)
: first_integer_(first_integer), second_integer_(second_integer) {}
-void SVGIntegerOptionalInteger::Trace(Visitor* visitor) {
+void SVGIntegerOptionalInteger::Trace(Visitor* visitor) const {
visitor->Trace(first_integer_);
visitor->Trace(second_integer_);
SVGPropertyBase::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_integer_optional_integer.h b/chromium/third_party/blink/renderer/core/svg/svg_integer_optional_integer.h
index 334fef29f01..3e7eab70703 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_integer_optional_integer.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_integer_optional_integer.h
@@ -74,7 +74,7 @@ class SVGIntegerOptionalInteger final : public SVGPropertyBase {
SVGInteger* FirstInteger() const { return first_integer_; }
SVGInteger* SecondInteger() const { return second_integer_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
Member<SVGInteger> first_integer_;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_length.cc b/chromium/third_party/blink/renderer/core/svg/svg_length.cc
index 77535c4717d..8609421a3d3 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_length.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_length.cc
@@ -85,7 +85,7 @@ SVGLength::SVGLength(const CSSPrimitiveValue& value, SVGLengthMode mode)
DCHECK_EQ(UnitMode(), mode);
}
-void SVGLength::Trace(Visitor* visitor) {
+void SVGLength::Trace(Visitor* visitor) const {
visitor->Trace(value_);
SVGPropertyBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_length.h b/chromium/third_party/blink/renderer/core/svg/svg_length.h
index bb11984f65d..c49540d8d53 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_length.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_length.h
@@ -61,7 +61,7 @@ class CORE_EXPORT SVGLength final : public SVGPropertyBase {
void SetInitial(unsigned);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
SVGLength* Clone() const;
SVGPropertyBase* CloneForAnimation(const String&) const override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_line_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_line_element.cc
index 988db51b0dc..b3013d280be 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_line_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_line_element.cc
@@ -54,7 +54,7 @@ SVGLineElement::SVGLineElement(Document& document)
AddToPropertyMap(y2_);
}
-void SVGLineElement::Trace(Visitor* visitor) {
+void SVGLineElement::Trace(Visitor* visitor) const {
visitor->Trace(x1_);
visitor->Trace(y1_);
visitor->Trace(x2_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_line_element.h b/chromium/third_party/blink/renderer/core/svg/svg_line_element.h
index 04acb82a98f..07429ed6553 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_line_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_line_element.h
@@ -40,7 +40,7 @@ class SVGLineElement final : public SVGGeometryElement {
SVGAnimatedLength* x2() const { return x2_.Get(); }
SVGAnimatedLength* y2() const { return y2_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_linear_gradient_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_linear_gradient_element.cc
index 9c0c7072b12..604956c40dd 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_linear_gradient_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_linear_gradient_element.cc
@@ -62,7 +62,7 @@ SVGLinearGradientElement::SVGLinearGradientElement(Document& document)
AddToPropertyMap(y2_);
}
-void SVGLinearGradientElement::Trace(Visitor* visitor) {
+void SVGLinearGradientElement::Trace(Visitor* visitor) const {
visitor->Trace(x1_);
visitor->Trace(y1_);
visitor->Trace(x2_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_linear_gradient_element.h b/chromium/third_party/blink/renderer/core/svg/svg_linear_gradient_element.h
index 1b1b218d836..791f5471520 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_linear_gradient_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_linear_gradient_element.h
@@ -42,7 +42,7 @@ class SVGLinearGradientElement final : public SVGGradientElement {
SVGAnimatedLength* x2() const { return x2_.Get(); }
SVGAnimatedLength* y2() const { return y2_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_marker_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_marker_element.cc
index 4920b8ba495..45426289b7d 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_marker_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_marker_element.cc
@@ -79,7 +79,7 @@ SVGMarkerElement::SVGMarkerElement(Document& document)
AddToPropertyMap(marker_units_);
}
-void SVGMarkerElement::Trace(Visitor* visitor) {
+void SVGMarkerElement::Trace(Visitor* visitor) const {
visitor->Trace(ref_x_);
visitor->Trace(ref_y_);
visitor->Trace(marker_width_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_marker_element.h b/chromium/third_party/blink/renderer/core/svg/svg_marker_element.h
index 542d5ba1bd5..1bc6a21c5a0 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_marker_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_marker_element.h
@@ -76,7 +76,7 @@ class SVGMarkerElement final : public SVGElement, public SVGFitToViewBox {
return orient_angle_->OrientType();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_mask_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_mask_element.cc
index db873b16b0e..79e116955dd 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_mask_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_mask_element.cc
@@ -78,7 +78,7 @@ SVGMaskElement::SVGMaskElement(Document& document)
AddToPropertyMap(mask_content_units_);
}
-void SVGMaskElement::Trace(Visitor* visitor) {
+void SVGMaskElement::Trace(Visitor* visitor) const {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(width_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_mask_element.h b/chromium/third_party/blink/renderer/core/svg/svg_mask_element.h
index d45cdf20e87..44ad1fb192c 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_mask_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_mask_element.h
@@ -47,7 +47,7 @@ class SVGMaskElement final : public SVGElement, public SVGTests {
return mask_content_units_.Get();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool IsValid() const override { return SVGTests::IsValid(); }
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_matrix_tear_off.cc b/chromium/third_party/blink/renderer/core/svg/svg_matrix_tear_off.cc
index e7db4ffa088..3afdd7bca1f 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_matrix_tear_off.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_matrix_tear_off.cc
@@ -44,7 +44,7 @@ SVGMatrixTearOff::SVGMatrixTearOff(SVGTransformTearOff* transform)
DCHECK(transform);
}
-void SVGMatrixTearOff::Trace(Visitor* visitor) {
+void SVGMatrixTearOff::Trace(Visitor* visitor) const {
visitor->Trace(context_transform_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_matrix_tear_off.h b/chromium/third_party/blink/renderer/core/svg/svg_matrix_tear_off.h
index 3b8bf2fa439..6a154dfb432 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_matrix_tear_off.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_matrix_tear_off.h
@@ -82,7 +82,7 @@ class CORE_EXPORT SVGMatrixTearOff final : public ScriptWrappable {
const AffineTransform& Value() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
AffineTransform* MutableValue();
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_mpath_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_mpath_element.cc
index 65eb8f47ce1..a626d40594c 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_mpath_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_mpath_element.cc
@@ -30,7 +30,7 @@ namespace blink {
SVGMPathElement::SVGMPathElement(Document& document)
: SVGElement(svg_names::kMPathTag, document), SVGURIReference(this) {}
-void SVGMPathElement::Trace(Visitor* visitor) {
+void SVGMPathElement::Trace(Visitor* visitor) const {
visitor->Trace(target_id_observer_);
SVGElement::Trace(visitor);
SVGURIReference::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_mpath_element.h b/chromium/third_party/blink/renderer/core/svg/svg_mpath_element.h
index 89ed7cca9c5..29cb1741d48 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_mpath_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_mpath_element.h
@@ -39,7 +39,7 @@ class SVGMPathElement final : public SVGElement, public SVGURIReference {
void TargetPathChanged();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void BuildPendingResource() override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_number_optional_number.cc b/chromium/third_party/blink/renderer/core/svg/svg_number_optional_number.cc
index a1477bae1c3..c97775e2db9 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_number_optional_number.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_number_optional_number.cc
@@ -39,7 +39,7 @@ SVGNumberOptionalNumber::SVGNumberOptionalNumber(SVGNumber* first_number,
SVGNumber* second_number)
: first_number_(first_number), second_number_(second_number) {}
-void SVGNumberOptionalNumber::Trace(Visitor* visitor) {
+void SVGNumberOptionalNumber::Trace(Visitor* visitor) const {
visitor->Trace(first_number_);
visitor->Trace(second_number_);
SVGPropertyBase::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_number_optional_number.h b/chromium/third_party/blink/renderer/core/svg/svg_number_optional_number.h
index 6f5f810cca4..b1f26f5a140 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_number_optional_number.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_number_optional_number.h
@@ -73,7 +73,7 @@ class SVGNumberOptionalNumber final : public SVGPropertyBase {
SVGNumber* FirstNumber() const { return first_number_; }
SVGNumber* SecondNumber() const { return second_number_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
Member<SVGNumber> first_number_;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_parser_utilities.cc b/chromium/third_party/blink/renderer/core/svg/svg_parser_utilities.cc
index c7b613fd34c..34656853629 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_parser_utilities.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_parser_utilities.cc
@@ -24,6 +24,7 @@
#include <limits>
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
+#include "third_party/blink/renderer/platform/wtf/text/character_visitor.h"
namespace blink {
@@ -195,34 +196,22 @@ bool ParseArcFlag(const UChar*& ptr, const UChar* end, bool& flag) {
return GenericParseArcFlag(ptr, end, flag);
}
-template <typename CharType>
-static bool GenericParseNumberOptionalNumber(const CharType*& ptr,
- const CharType* end,
- float& x,
- float& y) {
- if (!ParseNumber(ptr, end, x))
- return false;
-
- if (ptr == end)
- y = x;
- else if (!ParseNumber(ptr, end, y, kAllowLeadingAndTrailingWhitespace))
- return false;
-
- return ptr == end;
-}
-
bool ParseNumberOptionalNumber(const String& string, float& x, float& y) {
if (string.IsEmpty())
return false;
- if (string.Is8Bit()) {
- const LChar* ptr = string.Characters8();
- const LChar* end = ptr + string.length();
- return GenericParseNumberOptionalNumber(ptr, end, x, y);
- }
- const UChar* ptr = string.Characters16();
- const UChar* end = ptr + string.length();
- return GenericParseNumberOptionalNumber(ptr, end, x, y);
+ return WTF::VisitCharacters(string, [&](const auto* ptr, unsigned length) {
+ const auto* end = ptr + length;
+ if (!ParseNumber(ptr, end, x))
+ return false;
+
+ if (ptr == end)
+ y = x;
+ else if (!ParseNumber(ptr, end, y, kAllowLeadingAndTrailingWhitespace))
+ return false;
+
+ return ptr == end;
+ });
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_parsing_error.cc b/chromium/third_party/blink/renderer/core/svg/svg_parsing_error.cc
index 1f3e44d5a8c..9c1c01a6830 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_parsing_error.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_parsing_error.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/svg/svg_parsing_error.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/core/dom/qualified_name.h"
#include "third_party/blink/renderer/platform/json/json_values.h"
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_path.cc b/chromium/third_party/blink/renderer/core/svg/svg_path.cc
index 393b6f1d592..e4468034348 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_path.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_path.cc
@@ -188,7 +188,7 @@ float SVGPath::CalculateDistance(SVGPropertyBase* to, SVGElement*) {
return -1;
}
-void SVGPath::Trace(Visitor* visitor) {
+void SVGPath::Trace(Visitor* visitor) const {
visitor->Trace(path_value_);
SVGPropertyBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_path.h b/chromium/third_party/blink/renderer/core/svg/svg_path.h
index b6376e5d1e3..cbd3115a73c 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_path.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_path.h
@@ -72,7 +72,7 @@ class SVGPath final : public SVGPropertyBase {
static AnimatedPropertyType ClassType() { return kAnimatedPath; }
AnimatedPropertyType GetType() const override { return ClassType(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<cssvalue::CSSPathValue> path_value_;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_path_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_path_element.cc
index c57638d1bb9..0a3c9caf75f 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_path_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_path_element.cc
@@ -37,7 +37,7 @@ SVGPathElement::SVGPathElement(Document& document)
AddToPropertyMap(path_);
}
-void SVGPathElement::Trace(Visitor* visitor) {
+void SVGPathElement::Trace(Visitor* visitor) const {
visitor->Trace(path_);
SVGGeometryElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_path_element.h b/chromium/third_party/blink/renderer/core/svg/svg_path_element.h
index 2b1540003fd..babb968d63d 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_path_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_path_element.h
@@ -49,7 +49,7 @@ class SVGPathElement final : public SVGGeometryElement {
FloatRect GetBBox() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const StylePath* GetStylePath() const;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.cc
index cf4523d4a8d..a168c2b7dfa 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.cc
@@ -83,7 +83,7 @@ SVGPatternElement::SVGPatternElement(Document& document)
AddToPropertyMap(pattern_content_units_);
}
-void SVGPatternElement::Trace(Visitor* visitor) {
+void SVGPatternElement::Trace(Visitor* visitor) const {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(width_);
@@ -225,14 +225,13 @@ static void SetPatternAttributes(const SVGPatternElement& element,
}
if (!attributes.HasPatternUnits() && element.patternUnits()->IsSpecified()) {
- attributes.SetPatternUnits(
- element.patternUnits()->CurrentValue()->EnumValue());
+ attributes.SetPatternUnits(element.patternUnits()->CurrentEnumValue());
}
if (!attributes.HasPatternContentUnits() &&
element.patternContentUnits()->IsSpecified()) {
attributes.SetPatternContentUnits(
- element.patternContentUnits()->CurrentValue()->EnumValue());
+ element.patternContentUnits()->CurrentEnumValue());
}
if (!attributes.HasPatternTransform() &&
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.h b/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.h
index 8df0c30ad06..0305681c55f 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.h
@@ -80,7 +80,7 @@ class SVGPatternElement final : public SVGElement,
const SVGPatternElement* ReferencedElement() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool IsValid() const override { return SVGTests::IsValid(); }
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_poly_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_poly_element.cc
index 43555c37454..d612f35ad18 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_poly_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_poly_element.cc
@@ -36,7 +36,7 @@ SVGPolyElement::SVGPolyElement(const QualifiedName& tag_name,
AddToPropertyMap(points_);
}
-void SVGPolyElement::Trace(Visitor* visitor) {
+void SVGPolyElement::Trace(Visitor* visitor) const {
visitor->Trace(points_);
SVGGeometryElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_poly_element.h b/chromium/third_party/blink/renderer/core/svg/svg_poly_element.h
index dd9c67e8a31..9d9e0fa7ee3 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_poly_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_poly_element.h
@@ -35,7 +35,7 @@ class SVGPolyElement : public SVGGeometryElement {
SVGPointListTearOff* pointsFromJavascript() { return points_->baseVal(); }
SVGPointListTearOff* animatedPoints() { return points_->animVal(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
SVGPolyElement(const QualifiedName&, Document&);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.cc
index 3c96ac2b33e..c815b4fd9a7 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.cc
@@ -73,7 +73,7 @@ SVGRadialGradientElement::SVGRadialGradientElement(Document& document)
AddToPropertyMap(fr_);
}
-void SVGRadialGradientElement::Trace(Visitor* visitor) {
+void SVGRadialGradientElement::Trace(Visitor* visitor) const {
visitor->Trace(cx_);
visitor->Trace(cy_);
visitor->Trace(r_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.h b/chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.h
index 5aa965d0768..8a96940f121 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.h
@@ -44,7 +44,7 @@ class SVGRadialGradientElement final : public SVGGradientElement {
SVGAnimatedLength* fy() const { return fy_.Get(); }
SVGAnimatedLength* fr() const { return fr_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_rect.cc b/chromium/third_party/blink/renderer/core/svg/svg_rect.cc
index 096bd566ec8..a1ca2ab12d3 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_rect.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_rect.cc
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/core/svg/svg_animate_element.h"
#include "third_party/blink/renderer/core/svg/svg_parser_utilities.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/wtf/text/character_visitor.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -68,14 +69,9 @@ SVGParsingError SVGRect::SetValueAsString(const String& string) {
if (string.IsEmpty())
return SVGParsingError(SVGParseStatus::kExpectedNumber, 0);
- if (string.Is8Bit()) {
- const LChar* ptr = string.Characters8();
- const LChar* end = ptr + string.length();
- return Parse(ptr, end);
- }
- const UChar* ptr = string.Characters16();
- const UChar* end = ptr + string.length();
- return Parse(ptr, end);
+ return WTF::VisitCharacters(string, [&](const auto* chars, unsigned length) {
+ return Parse(chars, chars + length);
+ });
}
String SVGRect::ValueAsString() const {
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_rect_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_rect_element.cc
index d3386c383ee..a98dde36d03 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_rect_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_rect_element.cc
@@ -72,7 +72,7 @@ SVGRectElement::SVGRectElement(Document& document)
AddToPropertyMap(ry_);
}
-void SVGRectElement::Trace(Visitor* visitor) {
+void SVGRectElement::Trace(Visitor* visitor) const {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(width_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_rect_element.h b/chromium/third_party/blink/renderer/core/svg/svg_rect_element.h
index 15a81e7ef33..e58b9df17a4 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_rect_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_rect_element.h
@@ -42,7 +42,7 @@ class SVGRectElement final : public SVGGeometryElement {
SVGAnimatedLength* rx() const { return rx_.Get(); }
SVGAnimatedLength* ry() const { return ry_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void CollectStyleForPresentationAttribute(
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_resource.cc b/chromium/third_party/blink/renderer/core/svg/svg_resource.cc
index b10a69917be..6e8fc34a1e2 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_resource.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_resource.cc
@@ -19,7 +19,7 @@ SVGResource::SVGResource() = default;
SVGResource::~SVGResource() = default;
-void SVGResource::Trace(Visitor* visitor) {
+void SVGResource::Trace(Visitor* visitor) const {
visitor->Trace(target_);
visitor->Trace(clients_);
}
@@ -121,7 +121,7 @@ void LocalSVGResource::TargetChanged(const AtomicString& id) {
NotifyElementChanged();
}
-void LocalSVGResource::Trace(Visitor* visitor) {
+void LocalSVGResource::Trace(Visitor* visitor) const {
visitor->Trace(tree_scope_);
visitor->Trace(id_observer_);
SVGResource::Trace(visitor);
@@ -167,7 +167,7 @@ Element* ExternalSVGResource::ResolveTarget() {
return external_document->getElementById(decoded_fragment);
}
-void ExternalSVGResource::Trace(Visitor* visitor) {
+void ExternalSVGResource::Trace(Visitor* visitor) const {
visitor->Trace(cache_entry_);
SVGResource::Trace(visitor);
SVGExternalDocumentCache::Client::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_resource.h b/chromium/third_party/blink/renderer/core/svg/svg_resource.h
index 15bc41f5e75..18a974b0619 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_resource.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_resource.h
@@ -71,7 +71,7 @@ class SVGResource : public GarbageCollected<SVGResource> {
void AddClient(SVGResourceClient&);
void RemoveClient(SVGResourceClient&);
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
protected:
SVGResource();
@@ -100,7 +100,7 @@ class LocalSVGResource final : public SVGResource {
void NotifyResourceAttached(LayoutSVGResourceContainer&);
void NotifyResourceDestroyed(LayoutSVGResourceContainer&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void TargetChanged(const AtomicString& id);
@@ -120,7 +120,7 @@ class ExternalSVGResource final : public SVGResource,
void Load(Document&) override;
void LoadWithoutCSP(Document&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Element* ResolveTarget();
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_script_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_script_element.cc
index 3d274d2436b..ecebe50b76f 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_script_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_script_element.cc
@@ -37,8 +37,7 @@ SVGScriptElement::SVGScriptElement(Document& document,
const CreateElementFlags flags)
: SVGElement(svg_names::kScriptTag, document),
SVGURIReference(this),
- loader_(InitializeScriptLoader(flags.IsCreatedByParser(),
- flags.WasAlreadyStarted())) {}
+ loader_(InitializeScriptLoader(flags)) {}
void SVGScriptElement::ParseAttribute(
const AttributeModificationParams& params) {
@@ -138,7 +137,7 @@ bool SVGScriptElement::AllowInlineScriptForCSP(
const AtomicString& nonce,
const WTF::OrdinalNumber& context_line,
const String& script_content) {
- return GetDocument().GetContentSecurityPolicyForWorld()->AllowInline(
+ return GetExecutionContext()->GetContentSecurityPolicyForWorld()->AllowInline(
ContentSecurityPolicy::InlineType::kScript, this, script_content, nonce,
GetDocument().Url(), context_line);
}
@@ -197,7 +196,7 @@ const AttrNameToTrustedType& SVGScriptElement::GetCheckedAttributeTypes()
return attribute_map;
}
-void SVGScriptElement::Trace(Visitor* visitor) {
+void SVGScriptElement::Trace(Visitor* visitor) const {
visitor->Trace(loader_);
SVGElement::Trace(visitor);
SVGURIReference::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_script_element.h b/chromium/third_party/blink/renderer/core/svg/svg_script_element.h
index e24d3f074df..e1ac02513fe 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_script_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_script_element.h
@@ -52,7 +52,7 @@ class SVGScriptElement final : public SVGElement,
const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void ParseAttribute(const AttributeModificationParams&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_static_string_list.cc b/chromium/third_party/blink/renderer/core/svg/svg_static_string_list.cc
index f01b5cedb7f..1ba5b10123c 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_static_string_list.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_static_string_list.cc
@@ -47,7 +47,7 @@ SVGStaticStringList::SVGStaticStringList(SVGElement* context_element,
SVGStaticStringList::~SVGStaticStringList() = default;
-void SVGStaticStringList::Trace(Visitor* visitor) {
+void SVGStaticStringList::Trace(Visitor* visitor) const {
visitor->Trace(value_);
visitor->Trace(tear_off_);
SVGAnimatedPropertyBase::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_static_string_list.h b/chromium/third_party/blink/renderer/core/svg/svg_static_string_list.h
index 611736480b2..f5f26444e61 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_static_string_list.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_static_string_list.h
@@ -73,7 +73,7 @@ class SVGStaticStringList final : public GarbageCollected<SVGStaticStringList>,
SVGStringListBase* Value() { return value_.Get(); }
SVGStringListTearOff* TearOff();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<SVGStringListBase> value_;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_stop_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_stop_element.cc
index 53d12cfe254..1ea67e85d03 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_stop_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_stop_element.cc
@@ -40,7 +40,7 @@ SVGStopElement::SVGStopElement(Document& document)
DCHECK(HasCustomStyleCallbacks());
}
-void SVGStopElement::Trace(Visitor* visitor) {
+void SVGStopElement::Trace(Visitor* visitor) const {
visitor->Trace(offset_);
SVGElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_stop_element.h b/chromium/third_party/blink/renderer/core/svg/svg_stop_element.h
index 32364f286ce..c414e6c10fb 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_stop_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_stop_element.h
@@ -39,7 +39,7 @@ class SVGStopElement final : public SVGElement {
SVGAnimatedNumber* offset() const { return offset_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
void DidRecalcStyle(const StyleRecalcChange) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_style_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_style_element.cc
index 09fd3f44911..836c891372a 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_style_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_style_element.cc
@@ -138,7 +138,7 @@ void SVGStyleElement::DispatchPendingEvent() {
DispatchEvent(*Event::Create(event_type_names::kError));
}
-void SVGStyleElement::Trace(Visitor* visitor) {
+void SVGStyleElement::Trace(Visitor* visitor) const {
StyleElement::Trace(visitor);
SVGElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_style_element.h b/chromium/third_party/blink/renderer/core/svg/svg_style_element.h
index d00ea8a36f5..950fa41fd9e 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_style_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_style_element.h
@@ -51,7 +51,7 @@ class SVGStyleElement final : public SVGElement, public StyleElement {
void DispatchPendingEvent();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void ParseAttribute(const AttributeModificationParams&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_svg_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_svg_element.cc
index 116c26092a3..97607e40f74 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_svg_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_svg_element.cc
@@ -670,15 +670,9 @@ AffineTransform SVGSVGElement::ViewBoxToViewTransform(float view_width,
view_height);
if (!view_spec_ || !view_spec_->Transform())
return ctm;
-
const SVGTransformList* transform_list = view_spec_->Transform();
- if (transform_list->IsEmpty())
- return ctm;
-
- AffineTransform transform;
- if (transform_list->Concatenate(transform))
- ctm *= transform;
-
+ if (!transform_list->IsEmpty())
+ ctm *= transform_list->Concatenate();
return ctm;
}
@@ -735,7 +729,7 @@ void SVGSVGElement::FinishParsingChildren() {
SendSVGLoadEventIfPossible();
}
-void SVGSVGElement::Trace(Visitor* visitor) {
+void SVGSVGElement::Trace(Visitor* visitor) const {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(width_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_svg_element.h b/chromium/third_party/blink/renderer/core/svg/svg_svg_element.h
index d153b348082..f74b9c81c96 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_svg_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_svg_element.h
@@ -109,7 +109,7 @@ class SVGSVGElement final : public SVGGraphicsElement,
SVGAnimatedLength* width() const { return width_.Get(); }
SVGAnimatedLength* height() const { return height_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~SVGSVGElement() override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_symbol_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_symbol_element.cc
index 7341f491adb..60533aab29a 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_symbol_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_symbol_element.cc
@@ -28,7 +28,7 @@ namespace blink {
SVGSymbolElement::SVGSymbolElement(Document& document)
: SVGElement(svg_names::kSymbolTag, document), SVGFitToViewBox(this) {}
-void SVGSymbolElement::Trace(Visitor* visitor) {
+void SVGSymbolElement::Trace(Visitor* visitor) const {
SVGElement::Trace(visitor);
SVGFitToViewBox::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_symbol_element.h b/chromium/third_party/blink/renderer/core/svg/svg_symbol_element.h
index f54c16d8535..9d4f99f6ddf 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_symbol_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_symbol_element.h
@@ -33,7 +33,7 @@ class SVGSymbolElement final : public SVGElement, public SVGFitToViewBox {
public:
explicit SVGSymbolElement(Document&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_tests.cc b/chromium/third_party/blink/renderer/core/svg/svg_tests.cc
index fff3d4a17f9..7ec00f38dde 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_tests.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_tests.cc
@@ -44,7 +44,7 @@ SVGTests::SVGTests(SVGElement* context_element)
context_element->AddToPropertyMap(system_language_);
}
-void SVGTests::Trace(Visitor* visitor) {
+void SVGTests::Trace(Visitor* visitor) const {
visitor->Trace(required_extensions_);
visitor->Trace(system_language_);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_tests.h b/chromium/third_party/blink/renderer/core/svg/svg_tests.h
index ed920cf8899..cae061887dd 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_tests.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_tests.h
@@ -39,7 +39,7 @@ class CORE_EXPORT SVGTests : public GarbageCollectedMixin {
bool IsValid() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit SVGTests(SVGElement* context_element);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.cc
index 542db849b2a..3821c2c1f1d 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.cc
@@ -85,7 +85,7 @@ SVGTextContentElement::SVGTextContentElement(const QualifiedName& tag_name,
AddToPropertyMap(length_adjust_);
}
-void SVGTextContentElement::Trace(Visitor* visitor) {
+void SVGTextContentElement::Trace(Visitor* visitor) const {
visitor->Trace(text_length_);
visitor->Trace(length_adjust_);
SVGGraphicsElement::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.h b/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.h
index 8f55e3b9d2a..eb29f8f712f 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.h
@@ -71,7 +71,7 @@ class CORE_EXPORT SVGTextContentElement : public SVGGraphicsElement {
return length_adjust_.Get();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
SVGTextContentElement(const QualifiedName&, Document&);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.cc
index 392c4cb6fa8..a0d586e0973 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.cc
@@ -71,7 +71,7 @@ SVGTextPathElement::SVGTextPathElement(Document& document)
SVGTextPathElement::~SVGTextPathElement() = default;
-void SVGTextPathElement::Trace(Visitor* visitor) {
+void SVGTextPathElement::Trace(Visitor* visitor) const {
visitor->Trace(start_offset_);
visitor->Trace(method_);
visitor->Trace(spacing_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.h b/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.h
index 497cd084d99..fa67bedecba 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.h
@@ -66,7 +66,7 @@ class SVGTextPathElement final : public SVGTextContentElement,
return spacing_.Get();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~SVGTextPathElement() override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.cc
index a0cb80821d1..caeca5c57bb 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.cc
@@ -58,7 +58,7 @@ SVGTextPositioningElement::SVGTextPositioningElement(
AddToPropertyMap(rotate_);
}
-void SVGTextPositioningElement::Trace(Visitor* visitor) {
+void SVGTextPositioningElement::Trace(Visitor* visitor) const {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(dx_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.h b/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.h
index ab1f9a77ef1..7f5df05ea99 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.h
@@ -38,7 +38,7 @@ class SVGTextPositioningElement : public SVGTextContentElement {
SVGAnimatedLengthList* dy() { return dy_.Get(); }
SVGAnimatedNumberList* rotate() { return rotate_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
SVGTextPositioningElement(const QualifiedName&, Document&);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_transform_list.cc b/chromium/third_party/blink/renderer/core/svg/svg_transform_list.cc
index f621334240a..6ec92e28bc6 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_transform_list.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_transform_list.cc
@@ -181,22 +181,11 @@ SVGTransformList::SVGTransformList(SVGTransformType transform_type,
SVGTransformList::~SVGTransformList() = default;
-SVGTransform* SVGTransformList::Consolidate() {
- AffineTransform matrix;
- if (!Concatenate(matrix))
- return nullptr;
-
- return Initialize(MakeGarbageCollected<SVGTransform>(matrix));
-}
-
-bool SVGTransformList::Concatenate(AffineTransform& result) const {
- if (IsEmpty())
- return false;
-
+AffineTransform SVGTransformList::Concatenate() const {
+ AffineTransform result;
for (const auto& item : *this)
result *= item->Matrix();
-
- return true;
+ return result;
}
namespace {
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_transform_list.h b/chromium/third_party/blink/renderer/core/svg/svg_transform_list.h
index 28930b5d87d..de6c2748a92 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_transform_list.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_transform_list.h
@@ -50,9 +50,7 @@ class SVGTransformList final
SVGTransformList(SVGTransformType, const String&);
~SVGTransformList() override;
- SVGTransform* Consolidate();
-
- bool Concatenate(AffineTransform& result) const;
+ AffineTransform Concatenate() const;
// SVGPropertyBase:
SVGPropertyBase* CloneForAnimation(const String&) const override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_transform_list_tear_off.cc b/chromium/third_party/blink/renderer/core/svg/svg_transform_list_tear_off.cc
index e49fdf2129b..172a1cb1223 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_transform_list_tear_off.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_transform_list_tear_off.cc
@@ -57,7 +57,13 @@ SVGTransformTearOff* SVGTransformListTearOff::consolidate(
ThrowReadOnly(exception_state);
return nullptr;
}
- return CreateItemTearOff(Target()->Consolidate());
+ SVGTransformList* transform_list = Target();
+ if (transform_list->IsEmpty())
+ return nullptr;
+ auto* concatenated_transform =
+ MakeGarbageCollected<SVGTransform>(transform_list->Concatenate());
+ transform_list->Initialize(concatenated_transform);
+ return CreateItemTearOff(concatenated_transform);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_transform_tear_off.cc b/chromium/third_party/blink/renderer/core/svg/svg_transform_tear_off.cc
index fb466b1f1e8..9408c4d1116 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_transform_tear_off.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_transform_tear_off.cc
@@ -48,7 +48,7 @@ SVGTransformTearOff::SVGTransformTearOff(
SVGTransformTearOff::~SVGTransformTearOff() = default;
-void SVGTransformTearOff::Trace(Visitor* visitor) {
+void SVGTransformTearOff::Trace(Visitor* visitor) const {
visitor->Trace(matrix_tearoff_);
SVGPropertyTearOff<SVGTransform>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_transform_tear_off.h b/chromium/third_party/blink/renderer/core/svg/svg_transform_tear_off.h
index 3fc02bc4a8c..155549c1ff5 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_transform_tear_off.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_transform_tear_off.h
@@ -74,7 +74,7 @@ class SVGTransformTearOff final : public SVGPropertyTearOff<SVGTransform> {
void setSkewX(float, ExceptionState&);
void setSkewY(float, ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<SVGMatrixTearOff> matrix_tearoff_;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc b/chromium/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc
index 9ad5d0a1c46..5feb50931ff 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc
@@ -42,7 +42,7 @@ void SVGTreeScopeResources::ProcessCustomWeakness(const LivenessBroker& info) {
resources_.RemoveAll(to_remove);
}
-void SVGTreeScopeResources::Trace(Visitor* visitor) {
+void SVGTreeScopeResources::Trace(Visitor* visitor) const {
visitor->template RegisterWeakCallbackMethod<
SVGTreeScopeResources, &SVGTreeScopeResources::ProcessCustomWeakness>(
this);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_tree_scope_resources.h b/chromium/third_party/blink/renderer/core/svg/svg_tree_scope_resources.h
index 5d3c32c85cd..2267e752687 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_tree_scope_resources.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_tree_scope_resources.h
@@ -26,7 +26,7 @@ class SVGTreeScopeResources final
LocalSVGResource* ResourceForId(const AtomicString& id);
LocalSVGResource* ExistingResourceForId(const AtomicString& id) const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void ProcessCustomWeakness(const LivenessBroker&);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.cc b/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.cc
index 4a3bb14b8d0..ce4d4969b34 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.cc
@@ -52,7 +52,7 @@ SVGURIReference::SVGURIReference(SVGElement* element)
href_->AddToPropertyMap(element);
}
-void SVGURIReference::Trace(Visitor* visitor) {
+void SVGURIReference::Trace(Visitor* visitor) const {
visitor->Trace(href_);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.h b/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.h
index d36385c2700..8c10c7afa5d 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.h
@@ -81,7 +81,7 @@ class CORE_EXPORT SVGURIReference : public GarbageCollectedMixin {
// JS API
SVGAnimatedHref* href() const { return href_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit SVGURIReference(SVGElement*);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_use_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_use_element.cc
index 70ece8b9cf4..258f76ac78d 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_use_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_use_element.cc
@@ -91,7 +91,7 @@ SVGUseElement::SVGUseElement(Document& document)
SVGUseElement::~SVGUseElement() = default;
-void SVGUseElement::Trace(Visitor* visitor) {
+void SVGUseElement::Trace(Visitor* visitor) const {
visitor->Trace(cache_entry_);
visitor->Trace(x_);
visitor->Trace(y_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_use_element.h b/chromium/third_party/blink/renderer/core/svg/svg_use_element.h
index d74a9b3d64f..cdaa634211b 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_use_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_use_element.h
@@ -61,7 +61,7 @@ class SVGUseElement final : public SVGGraphicsElement,
void DispatchPendingEvent();
Path ToClipPath() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
FloatRect GetBBox() override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_view_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_view_element.cc
index ac872c18cd3..7bb80627e98 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_view_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_view_element.cc
@@ -32,7 +32,7 @@ SVGViewElement::SVGViewElement(Document& document)
UseCounter::Count(document, WebFeature::kSVGViewElement);
}
-void SVGViewElement::Trace(Visitor* visitor) {
+void SVGViewElement::Trace(Visitor* visitor) const {
SVGElement::Trace(visitor);
SVGFitToViewBox::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_view_element.h b/chromium/third_party/blink/renderer/core/svg/svg_view_element.h
index f42c137721c..8796a97428b 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_view_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_view_element.h
@@ -37,7 +37,7 @@ class SVGViewElement final : public SVGElement,
public:
explicit SVGViewElement(Document&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void ParseAttribute(const AttributeModificationParams&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_view_spec.cc b/chromium/third_party/blink/renderer/core/svg/svg_view_spec.cc
index be5843487ba..ba36ee103df 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_view_spec.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_view_spec.cc
@@ -31,7 +31,7 @@ namespace blink {
SVGViewSpec::SVGViewSpec() : zoom_and_pan_(kSVGZoomAndPanUnknown) {}
-void SVGViewSpec::Trace(Visitor* visitor) {
+void SVGViewSpec::Trace(Visitor* visitor) const {
visitor->Trace(view_box_);
visitor->Trace(preserve_aspect_ratio_);
visitor->Trace(transform_);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_view_spec.h b/chromium/third_party/blink/renderer/core/svg/svg_view_spec.h
index 41867c78786..932fe94a31c 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_view_spec.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_view_spec.h
@@ -44,7 +44,7 @@ class SVGViewSpec final : public GarbageCollected<SVGViewSpec> {
const SVGTransformList* Transform() const { return transform_; }
SVGZoomAndPanType ZoomAndPan() const { return zoom_and_pan_; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
bool ParseViewSpec(const String&);
diff --git a/chromium/third_party/blink/renderer/core/svg/unsafe_svg_attribute_sanitization_test.cc b/chromium/third_party/blink/renderer/core/svg/unsafe_svg_attribute_sanitization_test.cc
index f34d987083d..826efc707a4 100644
--- a/chromium/third_party/blink/renderer/core/svg/unsafe_svg_attribute_sanitization_test.cc
+++ b/chromium/third_party/blink/renderer/core/svg/unsafe_svg_attribute_sanitization_test.cc
@@ -273,7 +273,7 @@ TEST(
// Element::stripScriptingAttributes, perhaps to strip all
// SVG animation attributes.
TEST(UnsafeSVGAttributeSanitizationTest, stringsShouldNotSupportAddition) {
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* target = MakeGarbageCollected<SVGAElement>(*document);
auto* element = MakeGarbageCollected<SVGAnimateElement>(*document);
element->SetTargetElement(target);
@@ -300,7 +300,7 @@ TEST(UnsafeSVGAttributeSanitizationTest,
attributes.push_back(Attribute(svg_names::kFromAttr, "/home"));
attributes.push_back(Attribute(svg_names::kToAttr, "javascript:own3d()"));
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* element = MakeGarbageCollected<SVGAnimateElement>(*document);
element->StripScriptingAttributes(attributes);
@@ -320,7 +320,7 @@ TEST(UnsafeSVGAttributeSanitizationTest,
TEST(UnsafeSVGAttributeSanitizationTest,
isJavaScriptURLAttribute_hrefContainingJavascriptURL) {
Attribute attribute(svg_names::kHrefAttr, "javascript:alert()");
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* element = MakeGarbageCollected<SVGAElement>(*document);
EXPECT_TRUE(element->IsJavaScriptURLAttribute(attribute))
<< "The 'a' element should identify an 'href' attribute with a "
@@ -330,7 +330,7 @@ TEST(UnsafeSVGAttributeSanitizationTest,
TEST(UnsafeSVGAttributeSanitizationTest,
isJavaScriptURLAttribute_xlinkHrefContainingJavascriptURL) {
Attribute attribute(xlink_names::kHrefAttr, "javascript:alert()");
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* element = MakeGarbageCollected<SVGAElement>(*document);
EXPECT_TRUE(element->IsJavaScriptURLAttribute(attribute))
<< "The 'a' element should identify an 'xlink:href' attribute with a "
@@ -343,7 +343,7 @@ TEST(
QualifiedName href_alternate_prefix("foo", "href",
xlink_names::kNamespaceURI);
Attribute evil_attribute(href_alternate_prefix, "javascript:alert()");
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* element = MakeGarbageCollected<SVGAElement>(*document);
EXPECT_TRUE(element->IsJavaScriptURLAttribute(evil_attribute))
<< "The XLink 'href' attribute with a JavaScript URL value should be "
@@ -354,7 +354,7 @@ TEST(
TEST(UnsafeSVGAttributeSanitizationTest,
isSVGAnimationAttributeSettingJavaScriptURL_fromContainingJavaScriptURL) {
Attribute evil_attribute(svg_names::kFromAttr, "javascript:alert()");
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* element = MakeGarbageCollected<SVGAnimateElement>(*document);
EXPECT_TRUE(
element->IsSVGAnimationAttributeSettingJavaScriptURL(evil_attribute))
@@ -365,7 +365,7 @@ TEST(UnsafeSVGAttributeSanitizationTest,
TEST(UnsafeSVGAttributeSanitizationTest,
isSVGAnimationAttributeSettingJavaScriptURL_toContainingJavaScripURL) {
Attribute evil_attribute(svg_names::kToAttr, "javascript:window.close()");
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* element = MakeGarbageCollected<SVGSetElement>(*document);
EXPECT_TRUE(
element->IsSVGAnimationAttributeSettingJavaScriptURL(evil_attribute))
@@ -377,7 +377,7 @@ TEST(
UnsafeSVGAttributeSanitizationTest,
isSVGAnimationAttributeSettingJavaScriptURL_valuesContainingJavaScriptURL) {
Attribute evil_attribute(svg_names::kValuesAttr, "hi!; javascript:confirm()");
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* element = MakeGarbageCollected<SVGAnimateElement>(*document);
EXPECT_TRUE(
element->IsSVGAnimationAttributeSettingJavaScriptURL(evil_attribute))
@@ -388,7 +388,7 @@ TEST(
TEST(UnsafeSVGAttributeSanitizationTest,
isSVGAnimationAttributeSettingJavaScriptURL_innocuousAnimationAttribute) {
Attribute fine_attribute(svg_names::kFromAttr, "hello, world!");
- auto* document = MakeGarbageCollected<Document>();
+ auto* document = Document::CreateForTest();
auto* element = MakeGarbageCollected<SVGSetElement>(*document);
EXPECT_FALSE(
element->IsSVGAnimationAttributeSettingJavaScriptURL(fine_attribute))
diff --git a/chromium/third_party/blink/renderer/core/testing/color_scheme_helper.h b/chromium/third_party/blink/renderer/core/testing/color_scheme_helper.h
index 25df460ecb4..3f5e5607450 100644
--- a/chromium/third_party/blink/renderer/core/testing/color_scheme_helper.h
+++ b/chromium/third_party/blink/renderer/core/testing/color_scheme_helper.h
@@ -33,7 +33,7 @@ class ColorSchemeHelper {
WebThemeEngine* web_theme_engine_ = nullptr;
Settings& settings_;
PreferredColorScheme default_preferred_color_scheme_ =
- PreferredColorScheme::kNoPreference;
+ PreferredColorScheme::kLight;
ForcedColors default_forced_colors_ = ForcedColors::kNone;
};
diff --git a/chromium/third_party/blink/renderer/core/testing/core_unit_test_helper.h b/chromium/third_party/blink/renderer/core/testing/core_unit_test_helper.h
index 61444e22c95..09aa1dc4853 100644
--- a/chromium/third_party/blink/renderer/core/testing/core_unit_test_helper.h
+++ b/chromium/third_party/blink/renderer/core/testing/core_unit_test_helper.h
@@ -32,7 +32,7 @@ class SingleChildLocalFrameClient final : public EmptyLocalFrameClient {
public:
explicit SingleChildLocalFrameClient() = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(child_);
EmptyLocalFrameClient::Trace(visitor);
}
@@ -52,7 +52,7 @@ class LocalFrameClientWithParent final : public EmptyLocalFrameClient {
public:
explicit LocalFrameClientWithParent(LocalFrame* parent) : parent_(parent) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(parent_);
EmptyLocalFrameClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/testing/data/MaterialIcons-Regular.woff2 b/chromium/third_party/blink/renderer/core/testing/data/MaterialIcons-Regular.woff2
new file mode 100644
index 00000000000..9fa21125208
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/testing/data/MaterialIcons-Regular.woff2
Binary files differ
diff --git a/chromium/third_party/blink/renderer/core/testing/data/first-letter.html b/chromium/third_party/blink/renderer/core/testing/data/first-letter.html
new file mode 100644
index 00000000000..cf4b8a12353
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/testing/data/first-letter.html
@@ -0,0 +1,3 @@
+<style>h2::first-letter {color: red;}</style>
+<h1>Hello</h1>
+<h2>World</h2>
diff --git a/chromium/third_party/blink/renderer/core/testing/data/root-scroller-child.html b/chromium/third_party/blink/renderer/core/testing/data/root-scroller-child.html
index 2c150d60d8e..645089d9363 100644
--- a/chromium/third_party/blink/renderer/core/testing/data/root-scroller-child.html
+++ b/chromium/third_party/blink/renderer/core/testing/data/root-scroller-child.html
@@ -16,23 +16,14 @@
margin: 0px;
}
- #container {
- width: 100%;
- height: 100%;
- overflow: auto;
- }
-
#spacer {
- width: 800px;
- height: 800px;
+ width: 1000px;
+ height: 1000px;
}
</style>
</head>
<body>
- <div id="container">
- <div id="spacer"></div>
- </div>
<div id="spacer"></div>
</body>
</html>
diff --git a/chromium/third_party/blink/renderer/core/testing/data/root-scroller-iframe.html b/chromium/third_party/blink/renderer/core/testing/data/root-scroller-iframe.html
index 4bb6e9bb6fa..9862c3b7770 100644
--- a/chromium/third_party/blink/renderer/core/testing/data/root-scroller-iframe.html
+++ b/chromium/third_party/blink/renderer/core/testing/data/root-scroller-iframe.html
@@ -31,6 +31,5 @@
<body>
<iframe src="root-scroller-child.html" id="iframe"></iframe>
- <div id="spacer"></div>
</body>
</html>
diff --git a/chromium/third_party/blink/renderer/core/testing/data/root-scroller.html b/chromium/third_party/blink/renderer/core/testing/data/root-scroller.html
index bb60553a27c..9ea931059a4 100644
--- a/chromium/third_party/blink/renderer/core/testing/data/root-scroller.html
+++ b/chromium/third_party/blink/renderer/core/testing/data/root-scroller.html
@@ -41,6 +41,5 @@
<div id="empty"></div>
</div>
</div>
- <div class="spacer"></div>
</body>
</html>
diff --git a/chromium/third_party/blink/renderer/core/testing/death_aware_script_wrappable.h b/chromium/third_party/blink/renderer/core/testing/death_aware_script_wrappable.h
index 2666aa5bf80..4666d0390c2 100644
--- a/chromium/third_party/blink/renderer/core/testing/death_aware_script_wrappable.h
+++ b/chromium/third_party/blink/renderer/core/testing/death_aware_script_wrappable.h
@@ -24,7 +24,7 @@ class InObjectContainer {
virtual ~InObjectContainer() {}
- virtual void Trace(Visitor* visitor) { visitor->Trace(dependency_); }
+ virtual void Trace(Visitor* visitor) const { visitor->Trace(dependency_); }
private:
Member<DeathAwareScriptWrappable> dependency_;
@@ -56,7 +56,7 @@ class DeathAwareScriptWrappable : public ScriptWrappable {
}
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(wrapped_dependency_);
visitor->Trace(wrapped_vector_dependency_);
visitor->Trace(wrapped_hash_map_dependency_);
diff --git a/chromium/third_party/blink/renderer/core/testing/dictionary_test.cc b/chromium/third_party/blink/renderer/core/testing/dictionary_test.cc
index 29e6eda3d8b..7d17dbac575 100644
--- a/chromium/third_party/blink/renderer/core/testing/dictionary_test.cc
+++ b/chromium/third_party/blink/renderer/core/testing/dictionary_test.cc
@@ -246,7 +246,7 @@ void DictionaryTest::GetDerivedDerivedInternals(
dict->setDerivedDerivedStringMember(derived_derived_string_member_.value());
}
-void DictionaryTest::Trace(Visitor* visitor) {
+void DictionaryTest::Trace(Visitor* visitor) const {
visitor->Trace(element_member_);
visitor->Trace(element_or_null_member_);
visitor->Trace(object_member_);
diff --git a/chromium/third_party/blink/renderer/core/testing/dictionary_test.h b/chromium/third_party/blink/renderer/core/testing/dictionary_test.h
index 8ed3ed80533..aafaa2a1969 100644
--- a/chromium/third_party/blink/renderer/core/testing/dictionary_test.h
+++ b/chromium/third_party/blink/renderer/core/testing/dictionary_test.h
@@ -41,7 +41,7 @@ class DictionaryTest : public ScriptWrappable {
void setDerivedDerived(const InternalDictionaryDerivedDerived*);
InternalDictionaryDerivedDerived* getDerivedDerived(v8::Isolate* isolate);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void Reset();
diff --git a/chromium/third_party/blink/renderer/core/testing/dummy_modulator.cc b/chromium/third_party/blink/renderer/core/testing/dummy_modulator.cc
index 23f14bb37a8..21a16bde623 100644
--- a/chromium/third_party/blink/renderer/core/testing/dummy_modulator.cc
+++ b/chromium/third_party/blink/renderer/core/testing/dummy_modulator.cc
@@ -42,7 +42,7 @@ DummyModulator::DummyModulator()
DummyModulator::~DummyModulator() = default;
-void DummyModulator::Trace(Visitor* visitor) {
+void DummyModulator::Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
Modulator::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/testing/dummy_modulator.h b/chromium/third_party/blink/renderer/core/testing/dummy_modulator.h
index 7b1d2f60bb3..6d01b7bb3af 100644
--- a/chromium/third_party/blink/renderer/core/testing/dummy_modulator.h
+++ b/chromium/third_party/blink/renderer/core/testing/dummy_modulator.h
@@ -27,7 +27,7 @@ class DummyModulator : public Modulator {
public:
DummyModulator();
~DummyModulator() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
ModuleRecordResolver* GetModuleRecordResolver() override;
base::SingleThreadTaskRunner* TaskRunner() override;
diff --git a/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.cc b/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.cc
index be8b023aa5e..4d0b97d37c3 100644
--- a/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.cc
+++ b/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.cc
@@ -46,9 +46,8 @@ void FakeLocalFrameHost::DocumentAvailableInMainFrame(
bool uses_temporary_zoom_level) {}
void FakeLocalFrameHost::SetNeedsOcclusionTracking(bool needs_tracking) {}
-
-void FakeLocalFrameHost::LifecycleStateChanged(
- mojom::blink::FrameLifecycleState state) {}
+void FakeLocalFrameHost::SetVirtualKeyboardOverlayPolicy(
+ bool vk_overlays_content) {}
void FakeLocalFrameHost::EvictFromBackForwardCache() {}
@@ -63,6 +62,8 @@ void FakeLocalFrameHost::DidFailLoadWithError(const ::blink::KURL& url,
void FakeLocalFrameHost::DidFocusFrame() {}
+void FakeLocalFrameHost::DidCallFocus() {}
+
void FakeLocalFrameHost::EnforceInsecureRequestPolicy(
mojom::InsecureRequestPolicy policy_bitmap) {}
@@ -107,7 +108,7 @@ void FakeLocalFrameHost::RenderFallbackContentInParentProcess() {}
void FakeLocalFrameHost::UpdateTitle(
const WTF::String& title,
- mojo_base::mojom::blink::TextDirection title_direction) {}
+ base::i18n::TextDirection title_direction) {}
void FakeLocalFrameHost::UpdateUserActivationState(
mojom::blink::UserActivationUpdateType update_type) {}
@@ -149,10 +150,6 @@ void FakeLocalFrameHost::RunBeforeUnloadConfirm(
std::move(callback).Run(true);
}
-void FakeLocalFrameHost::Are3DAPIsBlocked(Are3DAPIsBlockedCallback callback) {
- std::move(callback).Run(true);
-}
-
void FakeLocalFrameHost::UpdateFaviconURL(
WTF::Vector<blink::mojom::blink::FaviconURLPtr> favicon_urls) {}
@@ -183,6 +180,13 @@ void FakeLocalFrameHost::DidChangeFrameOwnerProperties(
const base::UnguessableToken& child_frame_token,
mojom::blink::FrameOwnerPropertiesPtr frame_owner_properties) {}
+void FakeLocalFrameHost::DidChangeOpener(
+ const base::Optional<base::UnguessableToken>& opener_frame) {}
+
+void FakeLocalFrameHost::DidChangeFramePolicy(
+ const base::UnguessableToken& child_frame_token,
+ const FramePolicy& frame_policy) {}
+
void FakeLocalFrameHost::BindFrameHostReceiver(
mojo::ScopedInterfaceEndpointHandle handle) {
receiver_.Bind(mojo::PendingAssociatedReceiver<mojom::blink::LocalFrameHost>(
diff --git a/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.h b/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.h
index ea9e15846b4..f9b2cbc6f52 100644
--- a/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.h
+++ b/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.h
@@ -40,7 +40,7 @@ class FakeLocalFrameHost : public mojom::blink::LocalFrameHost {
void DidContainInsecureFormAction() override;
void DocumentAvailableInMainFrame(bool uses_temporary_zoom_level) override;
void SetNeedsOcclusionTracking(bool needs_tracking) override;
- void LifecycleStateChanged(mojom::blink::FrameLifecycleState state) override;
+ void SetVirtualKeyboardOverlayPolicy(bool vk_overlays_content) override;
void EvictFromBackForwardCache() override;
void VisibilityChanged(mojom::blink::FrameVisibility visibility) override;
void DidChangeThemeColor(
@@ -48,6 +48,7 @@ class FakeLocalFrameHost : public mojom::blink::LocalFrameHost {
void DidFailLoadWithError(const ::blink::KURL& url,
int32_t error_code) override;
void DidFocusFrame() override;
+ void DidCallFocus() override;
void EnforceInsecureRequestPolicy(
mojom::InsecureRequestPolicy policy_bitmap) override;
void EnforceInsecureNavigationsSet(const WTF::Vector<uint32_t>& set) override;
@@ -71,9 +72,8 @@ class FakeLocalFrameHost : public mojom::blink::LocalFrameHost {
void DispatchLoad() override;
void GoToEntryAtOffset(int32_t offset, bool has_user_gesture) override;
void RenderFallbackContentInParentProcess() override;
- void UpdateTitle(
- const WTF::String& title,
- mojo_base::mojom::blink::TextDirection title_direction) override;
+ void UpdateTitle(const WTF::String& title,
+ base::i18n::TextDirection title_direction) override;
void UpdateUserActivationState(
mojom::blink::UserActivationUpdateType update_type) override;
void HandleAccessibilityFindInPageResult(
@@ -92,7 +92,6 @@ class FakeLocalFrameHost : public mojom::blink::LocalFrameHost {
RunModalPromptDialogCallback callback) override;
void RunBeforeUnloadConfirm(bool is_reload,
RunBeforeUnloadConfirmCallback callback) override;
- void Are3DAPIsBlocked(Are3DAPIsBlockedCallback callback) override;
void UpdateFaviconURL(
WTF::Vector<blink::mojom::blink::FaviconURLPtr> favicon_urls) override;
void DownloadURL(mojom::blink::DownloadURLParamsPtr params) override;
@@ -115,6 +114,10 @@ class FakeLocalFrameHost : public mojom::blink::LocalFrameHost {
void DidChangeFrameOwnerProperties(
const base::UnguessableToken& child_frame_token,
mojom::blink::FrameOwnerPropertiesPtr frame_owner_properties) override;
+ void DidChangeOpener(
+ const base::Optional<base::UnguessableToken>& opener_frame) override;
+ void DidChangeFramePolicy(const base::UnguessableToken& child_frame_token,
+ const FramePolicy& frame_policy) override;
private:
void BindFrameHostReceiver(mojo::ScopedInterfaceEndpointHandle handle);
diff --git a/chromium/third_party/blink/renderer/core/testing/fake_remote_frame_host.cc b/chromium/third_party/blink/renderer/core/testing/fake_remote_frame_host.cc
index aec12d3a732..3d32bdc2102 100644
--- a/chromium/third_party/blink/renderer/core/testing/fake_remote_frame_host.cc
+++ b/chromium/third_party/blink/renderer/core/testing/fake_remote_frame_host.cc
@@ -33,6 +33,19 @@ void FakeRemoteFrameHost::CapturePaintPreviewOfCrossProcessSubframe(
void FakeRemoteFrameHost::SetIsInert(bool inert) {}
+void FakeRemoteFrameHost::DidChangeOpener(
+ const base::Optional<base::UnguessableToken>& opener_frame_token) {}
+
+void FakeRemoteFrameHost::AdvanceFocus(
+ blink::mojom::FocusType focus_type,
+ const base::UnguessableToken& source_frame_token) {}
+
+void FakeRemoteFrameHost::RouteMessageEvent(
+ const base::Optional<base::UnguessableToken>& source_frame_token,
+ const String& source_origin,
+ const String& target_origin,
+ BlinkTransferableMessage message) {}
+
void FakeRemoteFrameHost::BindFrameHostReceiver(
mojo::ScopedInterfaceEndpointHandle handle) {
receiver_.Bind(mojo::PendingAssociatedReceiver<mojom::blink::RemoteFrameHost>(
diff --git a/chromium/third_party/blink/renderer/core/testing/fake_remote_frame_host.h b/chromium/third_party/blink/renderer/core/testing/fake_remote_frame_host.h
index cf0189c9e78..a83b0f13ecc 100644
--- a/chromium/third_party/blink/renderer/core/testing/fake_remote_frame_host.h
+++ b/chromium/third_party/blink/renderer/core/testing/fake_remote_frame_host.h
@@ -5,10 +5,13 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_FAKE_REMOTE_FRAME_HOST_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_FAKE_REMOTE_FRAME_HOST_H_
+#include "base/optional.h"
+#include "base/unguessable_token.h"
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/mojom/frame/frame.mojom-blink.h"
+#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
namespace blink {
@@ -31,6 +34,15 @@ class FakeRemoteFrameHost : public mojom::blink::RemoteFrameHost {
const gfx::Rect& clip_rect,
const base::UnguessableToken& guid) override;
void SetIsInert(bool inert) override;
+ void DidChangeOpener(
+ const base::Optional<base::UnguessableToken>& opener_frame) override;
+ void AdvanceFocus(blink::mojom::FocusType focus_type,
+ const base::UnguessableToken& source_frame_token) override;
+ void RouteMessageEvent(
+ const base::Optional<base::UnguessableToken>& source_frame_token,
+ const String& source_origin,
+ const String& target_origin,
+ BlinkTransferableMessage message) override;
private:
void BindFrameHostReceiver(mojo::ScopedInterfaceEndpointHandle handle);
diff --git a/chromium/third_party/blink/renderer/core/testing/hit_test_layer_rect.h b/chromium/third_party/blink/renderer/core/testing/hit_test_layer_rect.h
index 88b85fcf25f..187b338b485 100644
--- a/chromium/third_party/blink/renderer/core/testing/hit_test_layer_rect.h
+++ b/chromium/third_party/blink/renderer/core/testing/hit_test_layer_rect.h
@@ -51,7 +51,7 @@ class HitTestLayerRect final : public ScriptWrappable {
DOMRectReadOnly* layerRect() const { return layer_rect_.Get(); }
DOMRectReadOnly* hitTestRect() const { return hit_test_rect_.Get(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(layer_rect_);
visitor->Trace(hit_test_rect_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/testing/hit_test_layer_rect_list.cc b/chromium/third_party/blink/renderer/core/testing/hit_test_layer_rect_list.cc
index 8e94a1d49e2..95ee4240525 100644
--- a/chromium/third_party/blink/renderer/core/testing/hit_test_layer_rect_list.cc
+++ b/chromium/third_party/blink/renderer/core/testing/hit_test_layer_rect_list.cc
@@ -54,7 +54,7 @@ void HitTestLayerRectList::Append(DOMRectReadOnly* layer_rect,
MakeGarbageCollected<HitTestLayerRect>(layer_rect, hit_test_rect));
}
-void HitTestLayerRectList::Trace(Visitor* visitor) {
+void HitTestLayerRectList::Trace(Visitor* visitor) const {
visitor->Trace(list_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/testing/hit_test_layer_rect_list.h b/chromium/third_party/blink/renderer/core/testing/hit_test_layer_rect_list.h
index d5f2ef265be..392c3281a01 100644
--- a/chromium/third_party/blink/renderer/core/testing/hit_test_layer_rect_list.h
+++ b/chromium/third_party/blink/renderer/core/testing/hit_test_layer_rect_list.h
@@ -51,7 +51,7 @@ class HitTestLayerRectList final : public ScriptWrappable {
HitTestLayerRect* item(unsigned index);
void Append(DOMRectReadOnly* layer_rect, DOMRectReadOnly* hit_test_rect);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<HitTestLayerRect>> list_;
diff --git a/chromium/third_party/blink/renderer/core/testing/internal_settings.cc b/chromium/third_party/blink/renderer/core/testing/internal_settings.cc
index 65ed71e7d7c..aa94f430a2c 100644
--- a/chromium/third_party/blink/renderer/core/testing/internal_settings.cc
+++ b/chromium/third_party/blink/renderer/core/testing/internal_settings.cc
@@ -345,7 +345,7 @@ void InternalSettings::setDefaultVideoPosterURL(
GetSettings()->SetDefaultVideoPosterURL(url);
}
-void InternalSettings::Trace(Visitor* visitor) {
+void InternalSettings::Trace(Visitor* visitor) const {
InternalSettingsGenerated::Trace(visitor);
Supplement<Page>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/testing/internal_settings.h b/chromium/third_party/blink/renderer/core/testing/internal_settings.h
index a89f2c3da96..74742d0ef95 100644
--- a/chromium/third_party/blink/renderer/core/testing/internal_settings.h
+++ b/chromium/third_party/blink/renderer/core/testing/internal_settings.h
@@ -131,7 +131,7 @@ class InternalSettings final : public InternalSettingsGenerated,
void setImageAnimationPolicy(const String&, ExceptionState&);
void setScrollTopLeftInteropEnabled(bool);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void setAvailablePointerTypes(const String&, ExceptionState&);
void setPrimaryPointerType(const String&, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/core/testing/internals.cc b/chromium/third_party/blink/renderer/core/testing/internals.cc
index 24f1f352a2d..1aefe74e104 100644
--- a/chromium/third_party/blink/renderer/core/testing/internals.cc
+++ b/chromium/third_party/blink/renderer/core/testing/internals.cc
@@ -214,7 +214,7 @@ class UseCounterHelperObserverImpl final : public UseCounterHelper::Observer {
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
UseCounterHelper::Observer::Trace(visitor);
visitor->Trace(resolver_);
}
@@ -308,6 +308,8 @@ void Internals::ResetToConsistentState(Page* page) {
IntersectionObserver::SetThrottleDelayEnabledForTesting(true);
g_mock_overlay_scrollbars.reset();
+
+ Page::SetMaxNumberOfFramesToTenForTesting(false);
}
Internals::Internals(ExecutionContext* context)
@@ -613,11 +615,11 @@ void Internals::advanceImageAnimation(Element* image,
ExceptionState& exception_state) {
DCHECK(image);
- ImageResourceContent* resource = nullptr;
+ ImageResourceContent* content = nullptr;
if (auto* html_image = DynamicTo<HTMLImageElement>(*image)) {
- resource = html_image->CachedImage();
+ content = html_image->CachedImage();
} else if (auto* svg_image = DynamicTo<SVGImageElement>(*image)) {
- resource = svg_image->CachedImage();
+ content = svg_image->CachedImage();
} else {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidAccessError,
@@ -625,13 +627,13 @@ void Internals::advanceImageAnimation(Element* image,
return;
}
- if (!resource || !resource->HasImage()) {
+ if (!content || !content->HasImage()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError,
"The image resource is not available.");
return;
}
- Image* image_data = resource->GetImage();
+ Image* image_data = content->GetImage();
image_data->AdvanceAnimationForTesting();
}
@@ -1853,35 +1855,6 @@ static void MergeRects(Vector<IntRect>& rects) {
}
}
-static void AccumulateTouchActionRectList(
- PaintLayerCompositor* compositor,
- GraphicsLayer* graphics_layer,
- HitTestLayerRectList* hit_test_rects) {
- const cc::TouchActionRegion& touch_action_region =
- graphics_layer->CcLayer()->touch_action_region();
- if (!touch_action_region.GetAllRegions().IsEmpty()) {
- const auto& layer_position = graphics_layer->GetOffsetFromTransformNode();
- const auto& layer_bounds = graphics_layer->CcLayer()->bounds();
- IntRect layer_rect(layer_position.X(), layer_position.Y(),
- layer_bounds.width(), layer_bounds.height());
-
- Vector<IntRect> layer_hit_test_rects;
- for (const gfx::Rect& hit_test_rect : touch_action_region.GetAllRegions())
- layer_hit_test_rects.push_back(IntRect(hit_test_rect));
- MergeRects(layer_hit_test_rects);
-
- for (const IntRect& hit_test_rect : layer_hit_test_rects) {
- if (!hit_test_rect.IsEmpty()) {
- hit_test_rects->Append(DOMRectReadOnly::FromIntRect(layer_rect),
- DOMRectReadOnly::FromIntRect(hit_test_rect));
- }
- }
- }
-
- for (GraphicsLayer* child_layer : graphics_layer->Children())
- AccumulateTouchActionRectList(compositor, child_layer, hit_test_rects);
-}
-
HitTestLayerRectList* Internals::touchEventTargetLayerRects(
Document* document,
ExceptionState& exception_state) {
@@ -1892,60 +1865,31 @@ HitTestLayerRectList* Internals::touchEventTargetLayerRects(
return nullptr;
}
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- auto* pac = document->View()->GetPaintArtifactCompositor();
- document->View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
-
- auto* hit_test_rects = MakeGarbageCollected<HitTestLayerRectList>();
- for (const auto& layer : pac->RootLayer()->children()) {
- const cc::TouchActionRegion& touch_action_region =
- layer->touch_action_region();
- if (!touch_action_region.GetAllRegions().IsEmpty()) {
- const auto& offset = layer->offset_to_transform_parent();
- IntRect layer_rect(RoundedIntPoint(FloatPoint(offset.x(), offset.y())),
- IntSize(layer->bounds()));
-
- Vector<IntRect> layer_hit_test_rects;
- for (const auto& hit_test_rect : touch_action_region.GetAllRegions())
- layer_hit_test_rects.push_back(IntRect(hit_test_rect));
- MergeRects(layer_hit_test_rects);
-
- for (const IntRect& hit_test_rect : layer_hit_test_rects) {
- if (!hit_test_rect.IsEmpty()) {
- hit_test_rects->Append(DOMRectReadOnly::FromIntRect(layer_rect),
- DOMRectReadOnly::FromIntRect(hit_test_rect));
- }
- }
- }
- }
- return hit_test_rects;
- }
-
- if (ScrollingCoordinator* scrolling_coordinator =
- document->GetPage()->GetScrollingCoordinator()) {
- FrameView* view = document->GetPage()->MainFrame()->View();
- if (view->IsLocalFrameView()) {
- scrolling_coordinator->UpdateAfterPaint(
- static_cast<LocalFrameView*>(view));
- } else {
- NOTREACHED();
- }
- }
+ document->View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
- if (auto* view = document->GetLayoutView()) {
- if (PaintLayerCompositor* compositor = view->Compositor()) {
- // Use the paint-root since we sometimes want to know about touch rects
- // on layers outside the document hierarchy (e.g. when we replace the
- // document with a video layer).
- if (GraphicsLayer* root_layer = compositor->PaintRootGraphicsLayer()) {
- auto* hit_test_rects = MakeGarbageCollected<HitTestLayerRectList>();
- AccumulateTouchActionRectList(compositor, root_layer, hit_test_rects);
- return hit_test_rects;
+ auto* hit_test_rects = MakeGarbageCollected<HitTestLayerRectList>();
+ for (const auto& layer : document->View()->RootCcLayer()->children()) {
+ const cc::TouchActionRegion& touch_action_region =
+ layer->touch_action_region();
+ if (!touch_action_region.GetAllRegions().IsEmpty()) {
+ const auto& offset = layer->offset_to_transform_parent();
+ IntRect layer_rect(RoundedIntPoint(FloatPoint(offset.x(), offset.y())),
+ IntSize(layer->bounds()));
+
+ Vector<IntRect> layer_hit_test_rects;
+ for (const auto& hit_test_rect : touch_action_region.GetAllRegions())
+ layer_hit_test_rects.push_back(IntRect(hit_test_rect));
+ MergeRects(layer_hit_test_rects);
+
+ for (const IntRect& hit_test_rect : layer_hit_test_rects) {
+ if (!hit_test_rect.IsEmpty()) {
+ hit_test_rects->Append(DOMRectReadOnly::FromIntRect(layer_rect),
+ DOMRectReadOnly::FromIntRect(hit_test_rect));
+ }
}
}
}
-
- return nullptr;
+ return hit_test_rects;
}
bool Internals::executeCommand(Document* document,
@@ -2256,10 +2200,6 @@ DOMRectList* Internals::nonFastScrollableRects(
return nullptr;
}
- // Update lifecycle. This includes the compositing update and
- // ScrollingCoordinator::UpdateAfterPaint, which computes the non-fast
- // scrollable region. For CompositeAfterPaint, this includes running
- // PaintArtifactCompositor which updates the non-fast regions.
frame->View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
auto* pac = document->View()->GetPaintArtifactCompositor();
@@ -2432,6 +2372,17 @@ void Internals::setPageScaleFactorLimits(float min_scale_factor,
page->SetDefaultPageScaleLimits(min_scale_factor, max_scale_factor);
}
+float Internals::pageZoomFactor(ExceptionState& exception_state) {
+ if (!document_->GetPage()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidAccessError,
+ "The document's page cannot be retrieved.");
+ return 0;
+ }
+ // Page zoom without Device Scale Factor.
+ return document_->GetPage()->GetChromeClient().UserZoomFactor();
+}
+
void Internals::setIsCursorVisible(Document* document,
bool is_visible,
ExceptionState& exception_state) {
@@ -2444,6 +2395,11 @@ void Internals::setIsCursorVisible(Document* document,
document->GetPage()->SetIsCursorVisible(is_visible);
}
+void Internals::setMaxNumberOfFramesToTen(bool enabled) {
+ // This gets reset by Internals::ResetToConsistentState
+ Page::SetMaxNumberOfFramesToTenForTesting(enabled);
+}
+
String Internals::effectivePreload(HTMLMediaElement* media_element) {
DCHECK(media_element);
return media_element->EffectivePreload();
@@ -3142,7 +3098,7 @@ ScriptPromise Internals::promiseCheckOverload(ScriptState* script_state,
V8String(script_state->GetIsolate(), "done"));
}
-void Internals::Trace(Visitor* visitor) {
+void Internals::Trace(Visitor* visitor) const {
visitor->Trace(runtime_flags_);
visitor->Trace(document_);
ScriptWrappable::Trace(visitor);
@@ -3538,7 +3494,7 @@ void Internals::generateTestReport(const String& message) {
MakeGarbageCollected<Report>("test", document_->Url().GetString(), body);
// Send the test report to any ReportingObservers.
- ReportingContext::From(document_->ExecutingWindow())->QueueReport(report);
+ ReportingContext::From(document_->domWindow())->QueueReport(report);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/testing/internals.h b/chromium/third_party/blink/renderer/core/testing/internals.h
index 0d9705d4e60..489b2a43486 100644
--- a/chromium/third_party/blink/renderer/core/testing/internals.h
+++ b/chromium/third_party/blink/renderer/core/testing/internals.h
@@ -393,7 +393,10 @@ class Internals final : public ScriptWrappable {
float max_scale_factor,
ExceptionState&);
+ float pageZoomFactor(ExceptionState&);
+
void setIsCursorVisible(Document*, bool, ExceptionState&);
+ void setMaxNumberOfFramesToTen(bool);
String effectivePreload(HTMLMediaElement*);
void mediaPlayerRemoteRouteAvailabilityChanged(HTMLMediaElement*, bool);
@@ -484,7 +487,7 @@ class Internals final : public ScriptWrappable {
ScriptPromise promiseCheckOverload(ScriptState*, Document*);
ScriptPromise promiseCheckOverload(ScriptState*, Location*, int32_t, int32_t);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void setValueForUser(HTMLInputElement*, const String&);
diff --git a/chromium/third_party/blink/renderer/core/testing/internals.idl b/chromium/third_party/blink/renderer/core/testing/internals.idl
index 1de7a786821..4ba61a226d9 100644
--- a/chromium/third_party/blink/renderer/core/testing/internals.idl
+++ b/chromium/third_party/blink/renderer/core/testing/internals.idl
@@ -224,7 +224,10 @@
[RaisesException] void setPageScaleFactor(float scaleFactor);
[RaisesException] void setPageScaleFactorLimits(float minScaleFactor, float maxScaleFactor);
+ [RaisesException] float pageZoomFactor();
+
[RaisesException] void setIsCursorVisible(Document document, boolean isVisible);
+ void setMaxNumberOfFramesToTen(boolean enable);
// HTMLMediaElement, HTMLAudioElement and HTMLVideoElement.
DOMString effectivePreload(HTMLMediaElement mediaElement);
diff --git a/chromium/third_party/blink/renderer/core/testing/null_execution_context.cc b/chromium/third_party/blink/renderer/core/testing/null_execution_context.cc
index 9318cc07315..3b8f22dbb7e 100644
--- a/chromium/third_party/blink/renderer/core/testing/null_execution_context.cc
+++ b/chromium/third_party/blink/renderer/core/testing/null_execution_context.cc
@@ -20,13 +20,12 @@ namespace blink {
NullExecutionContext::NullExecutionContext(
OriginTrialContext* origin_trial_context)
- : ExecutionContext(v8::Isolate::GetCurrent()),
+ : ExecutionContext(
+ v8::Isolate::GetCurrent(),
+ MakeGarbageCollected<Agent>(v8::Isolate::GetCurrent(),
+ base::UnguessableToken::Null())),
security_context_(
- SecurityContextInit(
- nullptr /* origin */,
- origin_trial_context,
- MakeGarbageCollected<Agent>(v8::Isolate::GetCurrent(),
- base::UnguessableToken::Null())),
+ SecurityContextInit(nullptr /* origin */, origin_trial_context),
SecurityContext::kWindow),
scheduler_(scheduler::CreateDummyFrameScheduler()) {
if (origin_trial_context)
@@ -56,7 +55,7 @@ BrowserInterfaceBrokerProxy& NullExecutionContext::GetBrowserInterfaceBroker() {
return GetEmptyBrowserInterfaceBroker();
}
-void NullExecutionContext::Trace(Visitor* visitor) {
+void NullExecutionContext::Trace(Visitor* visitor) const {
visitor->Trace(security_context_);
ExecutionContext::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/testing/null_execution_context.h b/chromium/third_party/blink/renderer/core/testing/null_execution_context.h
index fffe259cefd..93b2c07c11f 100644
--- a/chromium/third_party/blink/renderer/core/testing/null_execution_context.h
+++ b/chromium/third_party/blink/renderer/core/testing/null_execution_context.h
@@ -62,7 +62,7 @@ class NullExecutionContext : public GarbageCollected<NullExecutionContext>,
return security_context_;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
KURL url_;
diff --git a/chromium/third_party/blink/renderer/core/testing/origin_trials_test.h b/chromium/third_party/blink/renderer/core/testing/origin_trials_test.h
index b9abd4f8bf9..3332b44c28b 100644
--- a/chromium/third_party/blink/renderer/core/testing/origin_trials_test.h
+++ b/chromium/third_party/blink/renderer/core/testing/origin_trials_test.h
@@ -61,6 +61,8 @@ class OriginTrialsTest : public ScriptWrappable {
bool invalidOSAttribute() { return true; }
bool navigationMethod() { return true; }
+
+ bool thirdPartyAttribute() { return true; }
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/testing/origin_trials_test.idl b/chromium/third_party/blink/renderer/core/testing/origin_trials_test.idl
index e289491a2de..ccb94b748cf 100644
--- a/chromium/third_party/blink/renderer/core/testing/origin_trials_test.idl
+++ b/chromium/third_party/blink/renderer/core/testing/origin_trials_test.idl
@@ -58,4 +58,7 @@ interface OriginTrialsTest {
// These are available if the associated navigation trial is available.
[RuntimeEnabled=OriginTrialsSampleAPINavigation] boolean navigationMethod();
+
+ // These are available if the associated third-party trial is available.
+ [RuntimeEnabled=OriginTrialsSampleAPIThirdParty] readonly attribute boolean thirdPartyAttribute;
};
diff --git a/chromium/third_party/blink/renderer/core/testing/record_test.cc b/chromium/third_party/blink/renderer/core/testing/record_test.cc
index 14db635b94a..12e570790c2 100644
--- a/chromium/third_party/blink/renderer/core/testing/record_test.cc
+++ b/chromium/third_party/blink/renderer/core/testing/record_test.cc
@@ -76,7 +76,7 @@ bool RecordTest::unionReceivedARecord(
return arg.IsByteStringByteStringRecord();
}
-void RecordTest::Trace(Visitor* visitor) {
+void RecordTest::Trace(Visitor* visitor) const {
visitor->Trace(string_element_record_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/testing/record_test.h b/chromium/third_party/blink/renderer/core/testing/record_test.h
index 63a6883859f..068d6483362 100644
--- a/chromium/third_party/blink/renderer/core/testing/record_test.h
+++ b/chromium/third_party/blink/renderer/core/testing/record_test.h
@@ -52,7 +52,7 @@ class RecordTest final : public ScriptWrappable {
void setFloatOrStringElementRecord(const FloatOrStringElementRecord&) {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Vector<std::pair<String, int32_t>> string_long_record_;
diff --git a/chromium/third_party/blink/renderer/core/testing/sequence_test.cc b/chromium/third_party/blink/renderer/core/testing/sequence_test.cc
index 50db90ddeac..20cc094500f 100644
--- a/chromium/third_party/blink/renderer/core/testing/sequence_test.cc
+++ b/chromium/third_party/blink/renderer/core/testing/sequence_test.cc
@@ -47,7 +47,7 @@ bool SequenceTest::unionReceivedSequence(const DoubleOrDoubleSequence& arg) {
return arg.IsDoubleSequence();
}
-void SequenceTest::Trace(Visitor* visitor) {
+void SequenceTest::Trace(Visitor* visitor) const {
visitor->Trace(element_sequence_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/testing/sequence_test.h b/chromium/third_party/blink/renderer/core/testing/sequence_test.h
index 83609c8d23c..4e457561506 100644
--- a/chromium/third_party/blink/renderer/core/testing/sequence_test.h
+++ b/chromium/third_party/blink/renderer/core/testing/sequence_test.h
@@ -35,7 +35,7 @@ class SequenceTest final : public ScriptWrappable {
bool unionReceivedSequence(const DoubleOrDoubleSequence& arg);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<Element>> element_sequence_;
diff --git a/chromium/third_party/blink/renderer/core/testing/sim/sim_compositor.cc b/chromium/third_party/blink/renderer/core/testing/sim/sim_compositor.cc
index 8ea3ac19296..7f95c512a4b 100644
--- a/chromium/third_party/blink/renderer/core/testing/sim/sim_compositor.cc
+++ b/chromium/third_party/blink/renderer/core/testing/sim/sim_compositor.cc
@@ -59,6 +59,9 @@ SimCanvas::Commands SimCompositor::BeginFrame(double time_delta_in_seconds) {
SimCanvas::Commands SimCompositor::PaintFrame() {
DCHECK(web_view_);
+ if (!web_view_->MainFrameImpl())
+ return SimCanvas::Commands();
+
auto* frame = web_view_->MainFrameImpl()->GetFrame();
DocumentLifecycle::AllowThrottlingScope throttling_scope(
frame->GetDocument()->Lifecycle());
diff --git a/chromium/third_party/blink/renderer/core/testing/sim/sim_test.cc b/chromium/third_party/blink/renderer/core/testing/sim/sim_test.cc
index cb62837a51e..e5013dfe580 100644
--- a/chromium/third_party/blink/renderer/core/testing/sim/sim_test.cc
+++ b/chromium/third_party/blink/renderer/core/testing/sim/sim_test.cc
@@ -52,6 +52,7 @@ void SimTest::SetUp() {
compositor_.get());
compositor_->SetWebView(WebView(), *web_view_client_);
page_->SetPage(WebView().GetPage());
+ local_frame_root_ = WebView().MainFrameImpl();
}
void SimTest::TearDown() {
@@ -66,16 +67,29 @@ void SimTest::TearDown() {
web_frame_client_.reset();
compositor_.reset();
network_.reset();
+ local_frame_root_ = nullptr;
+}
+
+void SimTest::InitializeRemote() {
+ web_view_helper_->InitializeRemote();
+ compositor_->SetWebView(WebView(), *web_view_client_);
+ page_->SetPage(WebView().GetPage());
+ web_frame_client_ =
+ std::make_unique<frame_test_helpers::TestWebFrameClient>();
+ local_frame_root_ = frame_test_helpers::CreateLocalChild(
+ *WebView().MainFrame()->ToWebRemoteFrame(), "local_frame_root",
+ WebFrameOwnerProperties(), nullptr, web_frame_client_.get(),
+ compositor_.get());
}
void SimTest::LoadURL(const String& url_string) {
KURL url(url_string);
- frame_test_helpers::LoadFrameDontWait(WebView().MainFrameImpl(), url);
+ frame_test_helpers::LoadFrameDontWait(local_frame_root_.Get(), url);
if (DocumentLoader::WillLoadUrlAsEmpty(url) || url.ProtocolIsData()) {
// Empty documents and data urls are not using mocked out SimRequests,
// but instead load data directly.
frame_test_helpers::PumpPendingRequestsForFrameToLoad(
- WebView().MainFrameImpl());
+ local_frame_root_.Get());
}
}
@@ -99,6 +113,10 @@ WebLocalFrameImpl& SimTest::MainFrame() {
return *WebView().MainFrameImpl();
}
+WebLocalFrameImpl& SimTest::LocalFrameRoot() {
+ return *local_frame_root_;
+}
+
frame_test_helpers::TestWebViewClient& SimTest::WebViewClient() {
return *web_view_client_;
}
diff --git a/chromium/third_party/blink/renderer/core/testing/sim/sim_test.h b/chromium/third_party/blink/renderer/core/testing/sim/sim_test.h
index b7393990433..1d5d8ffb211 100644
--- a/chromium/third_party/blink/renderer/core/testing/sim/sim_test.h
+++ b/chromium/third_party/blink/renderer/core/testing/sim/sim_test.h
@@ -27,6 +27,10 @@ class SimTest : public testing::Test {
void SetUp() override;
void TearDown() override;
+ // Create a remote frame as the main frame and create a local child frame.
+ void InitializeRemote();
+
+ // Load URL in the local frame root.
void LoadURL(const String& url);
// WebView is created after SetUp to allow test to customize
@@ -37,6 +41,7 @@ class SimTest : public testing::Test {
Document& GetDocument();
WebViewImpl& WebView();
WebLocalFrameImpl& MainFrame();
+ WebLocalFrameImpl& LocalFrameRoot();
frame_test_helpers::TestWebViewClient& WebViewClient();
frame_test_helpers::TestWebWidgetClient& WebWidgetClient();
frame_test_helpers::TestWebFrameClient& WebFrameClient();
@@ -54,6 +59,7 @@ class SimTest : public testing::Test {
std::unique_ptr<frame_test_helpers::TestWebViewClient> web_view_client_;
std::unique_ptr<SimPage> page_;
std::unique_ptr<frame_test_helpers::WebViewHelper> web_view_helper_;
+ UntracedMember<WebLocalFrameImpl> local_frame_root_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/testing/static_selection.cc b/chromium/third_party/blink/renderer/core/testing/static_selection.cc
index 8110a6e75d2..2232890f1b7 100644
--- a/chromium/third_party/blink/renderer/core/testing/static_selection.cc
+++ b/chromium/third_party/blink/renderer/core/testing/static_selection.cc
@@ -36,7 +36,7 @@ bool StaticSelection::isCollapsed() const {
return anchor_node_ == focus_node_ && anchor_offset_ == focus_offset_;
}
-void StaticSelection::Trace(Visitor* visitor) {
+void StaticSelection::Trace(Visitor* visitor) const {
visitor->Trace(anchor_node_);
visitor->Trace(focus_node_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/testing/static_selection.h b/chromium/third_party/blink/renderer/core/testing/static_selection.h
index 2d17e1a3e94..6c4b3cba9a2 100644
--- a/chromium/third_party/blink/renderer/core/testing/static_selection.h
+++ b/chromium/third_party/blink/renderer/core/testing/static_selection.h
@@ -29,7 +29,7 @@ class StaticSelection final : public ScriptWrappable {
unsigned focusOffset() const { return focus_offset_; }
bool isCollapsed() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const Member<Node> anchor_node_;
diff --git a/chromium/third_party/blink/renderer/core/testing/v8/web_core_test_support.cc b/chromium/third_party/blink/renderer/core/testing/v8/web_core_test_support.cc
index 24f92480788..634b955495d 100644
--- a/chromium/third_party/blink/renderer/core/testing/v8/web_core_test_support.cc
+++ b/chromium/third_party/blink/renderer/core/testing/v8/web_core_test_support.cc
@@ -119,6 +119,12 @@ void InstallOriginTrialFeaturesForTesting(
script_state->GetIsolate(), script_state->World(),
v8::Local<v8::Object>(), prototype_object, interface_object);
}
+ if (RuntimeEnabledFeatures::OriginTrialsSampleAPIThirdPartyEnabled(
+ execution_context)) {
+ V8OriginTrialsTest::InstallOriginTrialsSampleAPIThirdParty(
+ script_state->GetIsolate(), script_state->World(),
+ v8::Local<v8::Object>(), prototype_object, interface_object);
+ }
}
}
@@ -192,6 +198,17 @@ void InstallPendingOriginTrialFeatureForTesting(
}
break;
}
+ case OriginTrialFeature::kOriginTrialsSampleAPIThirdParty: {
+ if (script_state->PerContextData()
+ ->GetExistingConstructorAndPrototypeForType(
+ V8OriginTrialsTest::GetWrapperTypeInfo(), &prototype_object,
+ &interface_object)) {
+ V8OriginTrialsTest::InstallOriginTrialsSampleAPIThirdParty(
+ script_state->GetIsolate(), script_state->World(),
+ v8::Local<v8::Object>(), prototype_object, interface_object);
+ }
+ break;
+ }
default:
break;
}
diff --git a/chromium/third_party/blink/renderer/core/testing/wait_for_event.cc b/chromium/third_party/blink/renderer/core/testing/wait_for_event.cc
index d4a2da07d86..405cc582410 100644
--- a/chromium/third_party/blink/renderer/core/testing/wait_for_event.cc
+++ b/chromium/third_party/blink/renderer/core/testing/wait_for_event.cc
@@ -21,7 +21,7 @@ void WaitForEvent::Invoke(ExecutionContext*, Event*) {
element_->removeEventListener(event_name_, this);
}
-void WaitForEvent::Trace(Visitor* visitor) {
+void WaitForEvent::Trace(Visitor* visitor) const {
NativeEventListener::Trace(visitor);
visitor->Trace(element_);
}
diff --git a/chromium/third_party/blink/renderer/core/testing/wait_for_event.h b/chromium/third_party/blink/renderer/core/testing/wait_for_event.h
index 9949bd3cddb..40f0e65702e 100644
--- a/chromium/third_party/blink/renderer/core/testing/wait_for_event.h
+++ b/chromium/third_party/blink/renderer/core/testing/wait_for_event.h
@@ -20,7 +20,7 @@ class WaitForEvent : public NativeEventListener {
void Invoke(ExecutionContext*, Event*) final;
- void Trace(Visitor*) final;
+ void Trace(Visitor*) const final;
private:
base::RunLoop run_loop_;
diff --git a/chromium/third_party/blink/renderer/core/timing/dom_window_performance.cc b/chromium/third_party/blink/renderer/core/timing/dom_window_performance.cc
index 38bbebce582..c322f6101bd 100644
--- a/chromium/third_party/blink/renderer/core/timing/dom_window_performance.cc
+++ b/chromium/third_party/blink/renderer/core/timing/dom_window_performance.cc
@@ -12,7 +12,7 @@ namespace blink {
DOMWindowPerformance::DOMWindowPerformance(LocalDOMWindow& window)
: Supplement<LocalDOMWindow>(window) {}
-void DOMWindowPerformance::Trace(Visitor* visitor) {
+void DOMWindowPerformance::Trace(Visitor* visitor) const {
visitor->Trace(performance_);
Supplement<LocalDOMWindow>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/dom_window_performance.h b/chromium/third_party/blink/renderer/core/timing/dom_window_performance.h
index 54d282f254e..ea744ce9a62 100644
--- a/chromium/third_party/blink/renderer/core/timing/dom_window_performance.h
+++ b/chromium/third_party/blink/renderer/core/timing/dom_window_performance.h
@@ -28,7 +28,7 @@ class CORE_EXPORT DOMWindowPerformance final
explicit DOMWindowPerformance(LocalDOMWindow&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
WindowPerformance* performance();
diff --git a/chromium/third_party/blink/renderer/core/timing/event_counts.cc b/chromium/third_party/blink/renderer/core/timing/event_counts.cc
index 45a3fca8734..0e003b130f4 100644
--- a/chromium/third_party/blink/renderer/core/timing/event_counts.cc
+++ b/chromium/third_party/blink/renderer/core/timing/event_counts.cc
@@ -26,7 +26,7 @@ class EventCountsIterationSource final
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(map_);
PairIterable<AtomicString, unsigned>::IterationSource::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/event_counts.h b/chromium/third_party/blink/renderer/core/timing/event_counts.h
index a2ae1431248..5f5c1ddf9a2 100644
--- a/chromium/third_party/blink/renderer/core/timing/event_counts.h
+++ b/chromium/third_party/blink/renderer/core/timing/event_counts.h
@@ -29,7 +29,9 @@ class EventCounts final : public ScriptWrappable,
void Add(const AtomicString& event_type);
- void Trace(Visitor* visitor) override { ScriptWrappable::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ ScriptWrappable::Trace(visitor);
+ }
private:
// Maplike implementation.
diff --git a/chromium/third_party/blink/renderer/core/timing/event_timing.cc b/chromium/third_party/blink/renderer/core/timing/event_timing.cc
index 4ced9145940..3b3b1fa63b9 100644
--- a/chromium/third_party/blink/renderer/core/timing/event_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/event_timing.cc
@@ -68,10 +68,12 @@ bool ShouldReportForEventTiming(WindowPerformance* performance) {
EventTiming::EventTiming(base::TimeTicks processing_start,
base::TimeTicks event_timestamp,
- WindowPerformance* performance)
+ WindowPerformance* performance,
+ bool should_log_event)
: processing_start_(processing_start),
event_timestamp_(event_timestamp),
- performance_(performance) {}
+ performance_(performance),
+ should_log_event_(should_log_event) {}
// static
std::unique_ptr<EventTiming> EventTiming::Create(LocalDOMWindow* window,
@@ -92,6 +94,7 @@ std::unique_ptr<EventTiming> EventTiming::Create(LocalDOMWindow* window,
: event.PlatformTimeStamp();
base::TimeTicks processing_start = Now();
+
if (should_log_event) {
InteractiveDetector* interactive_detector =
InteractiveDetector::From(*window->document());
@@ -103,15 +106,24 @@ std::unique_ptr<EventTiming> EventTiming::Create(LocalDOMWindow* window,
return should_report_for_event_timing
? std::make_unique<EventTiming>(processing_start, event_timestamp,
- performance)
+ performance, should_log_event)
: nullptr;
}
-void EventTiming::DidDispatchEvent(const Event& event) {
+void EventTiming::DidDispatchEvent(const Event& event, Document& document) {
Node* target = event.target() ? event.target()->ToNode() : nullptr;
+ base::TimeTicks processing_end = Now();
performance_->RegisterEventTiming(event.type(), event_timestamp_,
- processing_start_, Now(),
+ processing_start_, processing_end,
event.cancelable(), target);
+ if (should_log_event_) {
+ InteractiveDetector* interactive_detector =
+ InteractiveDetector::From(document);
+ if (interactive_detector) {
+ interactive_detector->RecordInputEventTimingUKM(
+ event, event_timestamp_, processing_start_, processing_end);
+ }
+ }
}
// static
diff --git a/chromium/third_party/blink/renderer/core/timing/event_timing.h b/chromium/third_party/blink/renderer/core/timing/event_timing.h
index a6d7eef4bd4..dc8c16d9eeb 100644
--- a/chromium/third_party/blink/renderer/core/timing/event_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/event_timing.h
@@ -30,10 +30,11 @@ class CORE_EXPORT EventTiming final {
explicit EventTiming(base::TimeTicks processing_start,
base::TimeTicks event_timestamp,
- WindowPerformance* performance);
+ WindowPerformance* performance,
+ bool should_log);
// Notifies the Performance object that the event has been dispatched.
- void DidDispatchEvent(const Event&);
+ void DidDispatchEvent(const Event&, Document& document);
// The caller owns the |clock| which must outlive the EventTiming.
static void SetTickClockForTesting(const base::TickClock* clock);
@@ -45,6 +46,9 @@ class CORE_EXPORT EventTiming final {
base::TimeTicks event_timestamp_;
Persistent<WindowPerformance> performance_;
+
+ bool should_log_event_;
+
DISALLOW_COPY_AND_ASSIGN(EventTiming);
};
diff --git a/chromium/third_party/blink/renderer/core/timing/largest_contentful_paint.cc b/chromium/third_party/blink/renderer/core/timing/largest_contentful_paint.cc
index f7c5f33e7a8..0a9ee3b72ac 100644
--- a/chromium/third_party/blink/renderer/core/timing/largest_contentful_paint.cc
+++ b/chromium/third_party/blink/renderer/core/timing/largest_contentful_paint.cc
@@ -58,7 +58,7 @@ void LargestContentfulPaint::BuildJSONValue(V8ObjectBuilder& builder) const {
builder.Add("element", element());
}
-void LargestContentfulPaint::Trace(Visitor* visitor) {
+void LargestContentfulPaint::Trace(Visitor* visitor) const {
visitor->Trace(element_);
PerformanceEntry::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/largest_contentful_paint.h b/chromium/third_party/blink/renderer/core/timing/largest_contentful_paint.h
index cbfba5a201e..bbebf97d0ca 100644
--- a/chromium/third_party/blink/renderer/core/timing/largest_contentful_paint.h
+++ b/chromium/third_party/blink/renderer/core/timing/largest_contentful_paint.h
@@ -38,7 +38,7 @@ class CORE_EXPORT LargestContentfulPaint final : public PerformanceEntry {
const String& url() const { return url_; }
Element* element() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void BuildJSONValue(V8ObjectBuilder&) const override;
diff --git a/chromium/third_party/blink/renderer/core/timing/layout_shift.cc b/chromium/third_party/blink/renderer/core/timing/layout_shift.cc
index fb5ad66572f..bb54b97879b 100644
--- a/chromium/third_party/blink/renderer/core/timing/layout_shift.cc
+++ b/chromium/third_party/blink/renderer/core/timing/layout_shift.cc
@@ -54,7 +54,7 @@ void LayoutShift::BuildJSONValue(V8ObjectBuilder& builder) const {
}
}
-void LayoutShift::Trace(Visitor* visitor) {
+void LayoutShift::Trace(Visitor* visitor) const {
PerformanceEntry::Trace(visitor);
visitor->Trace(sources_);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/layout_shift.h b/chromium/third_party/blink/renderer/core/timing/layout_shift.h
index d5d29f59659..f20e951713e 100644
--- a/chromium/third_party/blink/renderer/core/timing/layout_shift.h
+++ b/chromium/third_party/blink/renderer/core/timing/layout_shift.h
@@ -47,7 +47,7 @@ class CORE_EXPORT LayoutShift final : public PerformanceEntry {
AttributionList sources() const { return sources_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void BuildJSONValue(V8ObjectBuilder&) const override;
diff --git a/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.cc b/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.cc
index b9fc9107c01..1da6afd1bf0 100644
--- a/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.cc
+++ b/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.cc
@@ -48,7 +48,7 @@ ScriptValue LayoutShiftAttribution::toJSONForBinding(
return builder.GetScriptValue();
}
-void LayoutShiftAttribution::Trace(Visitor* visitor) {
+void LayoutShiftAttribution::Trace(Visitor* visitor) const {
visitor->Trace(node_);
visitor->Trace(previous_rect_);
visitor->Trace(current_rect_);
diff --git a/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.h b/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.h
index d68704bf200..62fa9253d2e 100644
--- a/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.h
+++ b/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.h
@@ -31,7 +31,7 @@ class CORE_EXPORT LayoutShiftAttribution : public ScriptWrappable {
DOMRectReadOnly* currentRect() const;
ScriptValue toJSONForBinding(ScriptState*) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
WeakMember<Node> node_;
Member<DOMRectReadOnly> previous_rect_;
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.cc b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.cc
index 325bbf35aab..7940d878bc0 100644
--- a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.cc
+++ b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.cc
@@ -5,15 +5,18 @@
#include "third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/public/platform/web_security_origin.h"
+#include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_measure_memory.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_measure_memory_breakdown.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/frame.h"
+#include "third_party/blink/renderer/core/frame/frame_owner.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/core/page/frame_tree.h"
+#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -77,7 +80,7 @@ bool MeasureMemoryDelegate::ShouldMeasure(v8::Local<v8::Context> context) {
namespace {
// Helper functions for constructing a memory measurement result.
-const LocalFrame* GetFrame(v8::Local<v8::Context> context) {
+LocalFrame* GetLocalFrame(v8::Local<v8::Context> context) {
LocalDOMWindow* window = ToLocalDOMWindow(context);
if (!window) {
// The context was detached. Ignore it.
@@ -86,17 +89,63 @@ const LocalFrame* GetFrame(v8::Local<v8::Context> context) {
return window->GetFrame();
}
-String GetUrl(const LocalFrame* frame) {
- if (frame->IsCrossOriginToParentFrame()) {
- // The function must be called only for the first cross-origin iframe on
- // the path down from the main frame. Thus the parent frame is guaranteed
- // to be the same origin as the main frame.
- DCHECK(!frame->Tree().Parent() ||
- !frame->Tree().Parent()->IsCrossOriginToMainFrame());
- base::Optional<String> url = frame->FirstUrlCrossOriginToParent();
- return url ? url.value() : "";
- }
- return frame->GetDocument()->Url().GetString();
+// Returns true if all frames on the path from the main frame to
+// the given frame (excluding the given frame) have the same origin.
+bool AllAncestorsAndOpenersAreSameOrigin(const WebFrame* main_frame,
+ const WebFrame* frame) {
+ while (frame != main_frame) {
+ frame = frame->Parent() ? frame->Parent() : frame->Opener();
+ if (!main_frame->GetSecurityOrigin().CanAccess(frame->GetSecurityOrigin()))
+ return false;
+ }
+ return true;
+}
+
+// Returns the URL corresponding to the given frame. It is:
+// - document's URL if the frame is a same-origin top frame.
+// - the src attribute of the owner iframe element if the frame is
+// an iframe.
+// - nullopt, otherwise.
+// Preconditions:
+// - If the frame is cross-origin, then all its ancestors/openers
+// must be of the same origin as the main frame.
+// - The frame must be attached to the DOM tree and the main frame
+// must be reachable via child => parent and openee => opener edges.
+String GetUrl(const WebFrame* main_frame, const WebFrame* frame) {
+ DCHECK(AllAncestorsAndOpenersAreSameOrigin(main_frame, frame));
+ if (!frame->Parent()) {
+ // TODO(ulan): Turn this conditional into a DCHECK once the API
+ // is gated behind COOP+COEP. Only same-origin frames can appear here.
+ if (!main_frame->GetSecurityOrigin().CanAccess(frame->GetSecurityOrigin()))
+ return {};
+ // The frame must be local because it is in the same browsing context
+ // group as the main frame and has the same origin.
+ // Check to avoid memory corruption in the case if our invariant is off.
+ CHECK(IsA<LocalFrame>(WebFrame::ToCoreFrame(*frame)));
+ LocalFrame* local = To<LocalFrame>(WebFrame::ToCoreFrame(*frame));
+ return local->GetDocument()->Url().GetString();
+ }
+ FrameOwner* frame_owner = WebFrame::ToCoreFrame(*frame)->Owner();
+ // The frame owner must be local because the parent of the frame has
+ // the same origin as the main frame. Also the frame cannot be provisional
+ // here because it is attached and has a document.
+ // Check to avoid of memory corruption in the case if our invariant is off.
+ CHECK(IsA<HTMLFrameOwnerElement>(frame_owner));
+ HTMLFrameOwnerElement* owner_element = To<HTMLFrameOwnerElement>(frame_owner);
+ switch (owner_element->OwnerType()) {
+ case mojom::blink::FrameOwnerElementType::kIframe:
+ return owner_element->getAttribute(html_names::kSrcAttr);
+ case mojom::blink::FrameOwnerElementType::kObject:
+ case mojom::blink::FrameOwnerElementType::kEmbed:
+ case mojom::blink::FrameOwnerElementType::kFrame:
+ case mojom::blink::FrameOwnerElementType::kPortal:
+ // TODO(ulan): return the data/src attribute after adding tests.
+ return {};
+ case mojom::blink::FrameOwnerElementType::kNone:
+ // The main frame was handled as a local frame above.
+ NOTREACHED();
+ return {};
+ }
}
// To avoid information leaks cross-origin iframes are considered opaque for
@@ -104,50 +153,59 @@ String GetUrl(const LocalFrame* frame) {
// in a cross-origin iframe is attributed to the cross-origin iframe.
// See https://github.com/WICG/performance-measure-memory for more details.
//
-// Given the main frame and the current context, this function walks up the
-// tree and finds the topmost cross-origin ancestor frame in the path.
-// If that doesn't exist, then all frames in the path are same-origin,
-// so the frame corresponding to the current context is returned.
+// Given the main frame and a frame, this function find the first cross-origin
+// frame in the path from the main frame to the given frame. Edges in the path
+// are parent/child and opener/openee edges.
+// If the path doesn't exist then it returns nullptr.
+// If there are no cross-origin frames, then it returns the given frame.
//
-// The function returns nullptr if the context was detached.
-const LocalFrame* GetAttributionFrame(const LocalFrame* main_frame,
- v8::Local<v8::Context> context) {
- const LocalFrame* frame = GetFrame(context);
- if (!frame) {
- // The context was detached. Ignore it.
- return nullptr;
- }
- if (&frame->Tree().Top() != main_frame) {
- // This can happen if the frame was detached.
- // See the comment in FrameTree::Top().
- return nullptr;
- }
- // Walk up the tree and find the topmost cross-origin ancestor frame.
- const LocalFrame* result = frame;
- // The parent is guaranteed to be LocalFrame because |frame| and
- // |main_frame| belong to the same JS agent.
- frame = To<LocalFrame>(frame->Tree().Parent());
- while (frame) {
- if (frame->IsCrossOriginToMainFrame())
+// Precondition: the frame must be attached to the DOM tree.
+const WebFrame* GetAttributionFrame(const WebFrame* main_frame,
+ const WebFrame* frame) {
+ WebSecurityOrigin main_security_origin = main_frame->GetSecurityOrigin();
+ // Walk up the tree and the openers to find the first cross-origin frame
+ // on the path from the main frame to the given frame.
+ const WebFrame* result = frame;
+ while (frame != main_frame) {
+ if (frame->Parent()) {
+ frame = frame->Parent();
+ } else if (frame->Opener()) {
+ frame = frame->Opener();
+ } else {
+ // The opener was reset. We cannot get the attribution.
+ return nullptr;
+ }
+ if (!main_security_origin.CanAccess(frame->GetSecurityOrigin()))
result = frame;
- frame = To<LocalFrame>(frame->Tree().Parent());
}
+ // The result frame must be attached because we started from an attached
+ // frame (precondition) and followed the parent and opener references until
+ // the main frame, which is also attached.
+ DCHECK(WebFrame::ToCoreFrame(*result)->IsAttached());
return result;
}
// Return per-frame sizes based on the given per-context size.
// TODO(ulan): Revisit this after Origin Trial and see if the results
// are precise enough or if we need to additionally group by JS agent.
-HeapHashMap<Member<const LocalFrame>, size_t> GroupByFrame(
- const LocalFrame* main_frame,
- const std::vector<std::pair<v8::Local<v8::Context>, size_t>>&
- context_sizes) {
- HeapHashMap<Member<const LocalFrame>, size_t> per_frame;
+HashMap<const WebFrame*, size_t> GroupByFrame(
+ const WebFrame* main_frame,
+ const std::vector<std::pair<v8::Local<v8::Context>, size_t>>& context_sizes,
+ size_t& detached_size,
+ size_t& unknown_frame_size) {
+ detached_size = 0;
+ unknown_frame_size = 0;
+ HashMap<const WebFrame*, size_t> per_frame;
for (const auto& context_size : context_sizes) {
- const LocalFrame* frame =
- GetAttributionFrame(main_frame, context_size.first);
+ const WebFrame* frame =
+ WebFrame::FromFrame(GetLocalFrame(context_size.first));
+ if (!frame) {
+ detached_size += context_size.second;
+ continue;
+ }
+ frame = GetAttributionFrame(main_frame, frame);
if (!frame) {
- // The context was detached. Ignore it.
+ unknown_frame_size += context_size.second;
continue;
}
auto it = per_frame.find(frame);
@@ -183,12 +241,12 @@ void MeasureMemoryDelegate::MeasurementComplete(
return;
}
v8::Local<v8::Context> context = context_.NewLocal(isolate_);
- const LocalFrame* frame = GetFrame(context);
- if (!frame) {
+ const WebFrame* main_frame = WebFrame::FromFrame(GetLocalFrame(context));
+ if (!main_frame) {
// The context was detached in the meantime.
return;
}
- DCHECK(frame->IsMainFrame());
+ DCHECK(!main_frame->Parent());
v8::Context::Scope context_scope(context);
size_t total_size = 0;
for (const auto& context_size : context_sizes) {
@@ -197,23 +255,38 @@ void MeasureMemoryDelegate::MeasurementComplete(
MeasureMemory* result = MeasureMemory::Create();
result->setBytes(total_size + unattributed_size);
HeapVector<Member<MeasureMemoryBreakdown>> breakdown;
- HeapHashMap<Member<const LocalFrame>, size_t> per_frame(
- GroupByFrame(frame, context_sizes));
+ size_t detached_size;
+ size_t unknown_frame_size;
+ HashMap<const WebFrame*, size_t> per_frame(GroupByFrame(
+ main_frame, context_sizes, detached_size, unknown_frame_size));
size_t attributed_size = 0;
const String kWindow("Window");
const String kJS("JS");
+ const Vector<String> js_window_types = {kWindow, kJS};
for (const auto& it : per_frame) {
+ String url = GetUrl(main_frame, it.key);
+ if (url.IsNull()) {
+ unknown_frame_size += it.value;
+ continue;
+ }
attributed_size += it.value;
+ breakdown.push_back(
+ CreateMeasureMemoryBreakdown(it.value, js_window_types, url));
+ }
+ if (detached_size) {
+ const String kDetached("Detached");
+ breakdown.push_back(CreateMeasureMemoryBreakdown(
+ detached_size, Vector<String>{kWindow, kJS, kDetached}, ""));
+ }
+ if (unattributed_size) {
+ const String kShared("Shared");
breakdown.push_back(CreateMeasureMemoryBreakdown(
- it.value, Vector<String>{kWindow, kJS}, GetUrl(it.key)));
- }
- const String kDetached("Detached");
- const String kShared("Shared");
- size_t detached_size = total_size - attributed_size;
- breakdown.push_back(CreateMeasureMemoryBreakdown(
- detached_size, Vector<String>{kWindow, kJS, kDetached}, ""));
- breakdown.push_back(CreateMeasureMemoryBreakdown(
- unattributed_size, Vector<String>{kWindow, kJS, kShared}, ""));
+ unattributed_size, Vector<String>{kWindow, kJS, kShared}, ""));
+ }
+ if (unknown_frame_size) {
+ breakdown.push_back(CreateMeasureMemoryBreakdown(
+ unknown_frame_size, Vector<String>{kWindow, kJS}, ""));
+ }
result->setBreakdown(breakdown);
v8::Local<v8::Promise::Resolver> promise_resolver =
promise_resolver_.NewLocal(isolate_);
diff --git a/chromium/third_party/blink/renderer/core/timing/performance.cc b/chromium/third_party/blink/renderer/core/timing/performance.cc
index ba1ce5825d5..222eb694274 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance.cc
@@ -503,7 +503,7 @@ void Performance::GenerateAndAddResourceTiming(
AddResourceTiming(
GenerateResourceTiming(*security_origin, info, *context),
!initiator_type.IsNull() ? initiator_type : info.InitiatorType(),
- info.TakeWorkerTimingReceiver());
+ info.TakeWorkerTimingReceiver(), context);
}
mojom::blink::ResourceTimingInfoPtr Performance::GenerateResourceTiming(
@@ -592,9 +592,11 @@ void Performance::AddResourceTiming(
mojom::blink::ResourceTimingInfoPtr info,
const AtomicString& initiator_type,
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
- worker_timing_receiver) {
+ worker_timing_receiver,
+ ExecutionContext* context) {
auto* entry = MakeGarbageCollected<PerformanceResourceTiming>(
- *info, time_origin_, initiator_type, std::move(worker_timing_receiver));
+ *info, time_origin_, initiator_type, std::move(worker_timing_receiver),
+ context);
NotifyObserversOfEntry(*entry);
// https://w3c.github.io/resource-timing/#dfn-add-a-performanceresourcetiming-entry
if (CanAddResourceTimingEntry() &&
@@ -839,44 +841,53 @@ PerformanceMeasure* Performance::MeasureInternal(
return nullptr;
}
- base::Optional<double> duration = base::nullopt;
+ base::Optional<StringOrDouble> start;
+ if (options->hasStart()) {
+ start = options->start();
+ }
+ base::Optional<double> duration;
if (options->hasDuration()) {
duration = options->duration();
}
+ base::Optional<StringOrDouble> end;
+ if (options->hasEnd()) {
+ end = options->end();
+ }
- return MeasureWithDetail(script_state, measure_name, options->start(),
- std::move(duration), options->end(),
- options->detail(), exception_state);
+ return MeasureWithDetail(
+ script_state, measure_name, start, duration, end,
+ options->hasDetail() ? options->detail() : ScriptValue(),
+ exception_state);
}
+
// measure("name", "mark1", *)
- StringOrDouble converted_start;
+ base::Optional<StringOrDouble> start;
if (start_or_options.IsString()) {
- converted_start =
- StringOrDouble::FromString(start_or_options.GetAsString());
+ start = StringOrDouble::FromString(start_or_options.GetAsString());
}
// We let |end_mark| behave the same whether it's empty, undefined or null
// in JS, as long as |end_mark| is null in C++.
- return MeasureWithDetail(
- script_state, measure_name, converted_start,
- /* duration = */ base::nullopt,
- end_mark ? StringOrDouble::FromString(*end_mark) : StringOrDouble(),
- ScriptValue::CreateNull(script_state->GetIsolate()), exception_state);
+ base::Optional<StringOrDouble> end;
+ if (end_mark) {
+ end = StringOrDouble::FromString(*end_mark);
+ }
+ return MeasureWithDetail(script_state, measure_name, start,
+ /* duration = */ base::nullopt, end,
+ ScriptValue::CreateNull(script_state->GetIsolate()),
+ exception_state);
}
PerformanceMeasure* Performance::MeasureWithDetail(
ScriptState* script_state,
const AtomicString& measure_name,
- const StringOrDouble& start,
- base::Optional<double> duration,
- const StringOrDouble& end,
+ const base::Optional<StringOrDouble>& start,
+ const base::Optional<double>& duration,
+ const base::Optional<StringOrDouble>& end,
const ScriptValue& detail,
ExceptionState& exception_state) {
- StringOrDouble original_start = start;
- StringOrDouble original_end = end;
-
- PerformanceMeasure* performance_measure = GetUserTiming().Measure(
- script_state, measure_name, original_start, std::move(duration),
- original_end, detail, exception_state);
+ PerformanceMeasure* performance_measure =
+ GetUserTiming().Measure(script_state, measure_name, start, duration, end,
+ detail, exception_state);
if (performance_measure)
NotifyObserversOfEntry(*performance_measure);
return performance_measure;
@@ -1045,7 +1056,7 @@ void Performance::BuildJSONValue(V8ObjectBuilder& builder) const {
// |memory| is not part of the spec, omitted.
}
-void Performance::Trace(Visitor* visitor) {
+void Performance::Trace(Visitor* visitor) const {
visitor->Trace(resource_timing_buffer_);
visitor->Trace(resource_timing_secondary_buffer_);
visitor->Trace(element_timing_buffer_);
diff --git a/chromium/third_party/blink/renderer/core/timing/performance.h b/chromium/third_party/blink/renderer/core/timing/performance.h
index 70d4d20d51d..37dead0b4ad 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance.h
@@ -180,7 +180,8 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
mojom::blink::ResourceTimingInfoPtr,
const AtomicString& initiator_type,
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
- worker_timing_receiver);
+ worker_timing_receiver,
+ ExecutionContext* context);
void NotifyNavigationTimingToObservers();
@@ -304,7 +305,7 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
ScriptValue toJSONForBinding(ScriptState*) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// The caller owns the |clock|.
void SetClocksForTesting(const base::Clock* clock,
@@ -322,13 +323,14 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
base::Optional<String> end_mark,
ExceptionState&);
- PerformanceMeasure* MeasureWithDetail(ScriptState*,
- const AtomicString& measure_name,
- const StringOrDouble& start,
- base::Optional<double> duration,
- const StringOrDouble& end,
- const ScriptValue& detail,
- ExceptionState&);
+ PerformanceMeasure* MeasureWithDetail(
+ ScriptState*,
+ const AtomicString& measure_name,
+ const base::Optional<StringOrDouble>& start,
+ const base::Optional<double>& duration,
+ const base::Optional<StringOrDouble>& end,
+ const ScriptValue& detail,
+ ExceptionState&);
void CopySecondaryBuffer();
PerformanceEntryVector getEntriesByTypeInternal(
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_element_timing.cc b/chromium/third_party/blink/renderer/core/timing/performance_element_timing.cc
index dddad84e15d..71fca759cf3 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_element_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_element_timing.cc
@@ -84,7 +84,7 @@ void PerformanceElementTiming::BuildJSONValue(V8ObjectBuilder& builder) const {
builder.Add("url", url_);
}
-void PerformanceElementTiming::Trace(Visitor* visitor) {
+void PerformanceElementTiming::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(intersection_rect_);
PerformanceEntry::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_element_timing.h b/chromium/third_party/blink/renderer/core/timing/performance_element_timing.h
index 682165c2441..6730da05e09 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_element_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_element_timing.h
@@ -58,7 +58,7 @@ class CORE_EXPORT PerformanceElementTiming final : public PerformanceEntry {
String url() const { return url_; }
Element* element() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void BuildJSONValue(V8ObjectBuilder&) const override;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_event_timing.cc b/chromium/third_party/blink/renderer/core/timing/performance_event_timing.cc
index 85dd00b9251..a5723822a4f 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_event_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_event_timing.cc
@@ -88,7 +88,7 @@ void PerformanceEventTiming::BuildJSONValue(V8ObjectBuilder& builder) const {
builder.Add("target", target());
}
-void PerformanceEventTiming::Trace(Visitor* visitor) {
+void PerformanceEventTiming::Trace(Visitor* visitor) const {
PerformanceEntry::Trace(visitor);
visitor->Trace(target_);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_event_timing.h b/chromium/third_party/blink/renderer/core/timing/performance_event_timing.h
index bb05e7c6da0..78560ef5ed2 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_event_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_event_timing.h
@@ -49,7 +49,7 @@ class CORE_EXPORT PerformanceEventTiming final : public PerformanceEntry {
void BuildJSONValue(V8ObjectBuilder&) const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
AtomicString entry_type_;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.cc b/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
index 92f48fb5a25..83ced4ebcb9 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
@@ -48,7 +48,7 @@ void PerformanceLongTaskTiming::BuildJSONValue(V8ObjectBuilder& builder) const {
script_state->GetIsolate()));
}
-void PerformanceLongTaskTiming::Trace(Visitor* visitor) {
+void PerformanceLongTaskTiming::Trace(Visitor* visitor) const {
visitor->Trace(attribution_);
PerformanceEntry::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.h b/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.h
index e5abb1bb37c..8dd3530ebcb 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.h
@@ -32,7 +32,7 @@ class PerformanceLongTaskTiming final : public PerformanceEntry {
TaskAttributionVector attribution() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~PerformanceLongTaskTiming() override;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_mark.cc b/chromium/third_party/blink/renderer/core/timing/performance_mark.cc
index f6eed565a79..f4346b0ed89 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_mark.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_mark.cc
@@ -54,7 +54,8 @@ PerformanceMark* PerformanceMark::Create(ScriptState* script_state,
start = performance->now();
}
- detail = mark_options->detail();
+ if (mark_options->hasDetail())
+ detail = mark_options->detail();
} else {
start = performance->now();
}
@@ -69,16 +70,13 @@ PerformanceMark* PerformanceMark::Create(ScriptState* script_state,
return nullptr;
}
- scoped_refptr<SerializedScriptValue> serialized_detail;
- if (detail.IsEmpty()) {
- serialized_detail = SerializedScriptValue::NullValue();
- } else {
- serialized_detail = SerializedScriptValue::Serialize(
- script_state->GetIsolate(), detail.V8Value(),
- SerializedScriptValue::SerializeOptions(), exception_state);
- if (exception_state.HadException())
- return nullptr;
- }
+ scoped_refptr<SerializedScriptValue> serialized_detail =
+ SerializedScriptValue::Serialize(
+ script_state->GetIsolate(), detail.V8Value(),
+ SerializedScriptValue::SerializeOptions(), exception_state);
+ if (exception_state.HadException())
+ return nullptr;
+
return MakeGarbageCollected<PerformanceMark>(
mark_name, start, std::move(serialized_detail), exception_state);
}
@@ -114,7 +112,7 @@ ScriptValue PerformanceMark::detail(ScriptState* script_state) {
return ScriptValue(isolate, value);
}
-void PerformanceMark::Trace(Visitor* visitor) {
+void PerformanceMark::Trace(Visitor* visitor) const {
visitor->Trace(deserialized_detail_map_);
PerformanceEntry::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_mark.h b/chromium/third_party/blink/renderer/core/timing/performance_mark.h
index b4d4b5e2633..2ae62a7e5f0 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_mark.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_mark.h
@@ -66,7 +66,7 @@ class CORE_EXPORT PerformanceMark final : public PerformanceEntry {
ScriptValue detail(ScriptState*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~PerformanceMark() override = default;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_measure.cc b/chromium/third_party/blink/renderer/core/timing/performance_measure.cc
index 85a7d5b7036..d2a1ba91e25 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_measure.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_measure.cc
@@ -76,7 +76,7 @@ PerformanceMeasure::ToMojoPerformanceMarkOrMeasure() {
return mojo_performance_mark_or_measure;
}
-void PerformanceMeasure::Trace(Visitor* visitor) {
+void PerformanceMeasure::Trace(Visitor* visitor) const {
visitor->Trace(deserialized_detail_map_);
PerformanceEntry::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_measure.h b/chromium/third_party/blink/renderer/core/timing/performance_measure.h
index 087585d8bed..f1258ced973 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_measure.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_measure.h
@@ -64,7 +64,7 @@ class CORE_EXPORT PerformanceMeasure final : public PerformanceEntry {
mojom::blink::PerformanceMarkOrMeasurePtr ToMojoPerformanceMarkOrMeasure()
override;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
~PerformanceMeasure() override = default;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_navigation.cc b/chromium/third_party/blink/renderer/core/timing/performance_navigation.cc
index 2a7f72bb96f..7dd856a0268 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_navigation.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_navigation.cc
@@ -83,7 +83,7 @@ ScriptValue PerformanceNavigation::toJSONForBinding(
return result.GetScriptValue();
}
-void PerformanceNavigation::Trace(Visitor* visitor) {
+void PerformanceNavigation::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_navigation.h b/chromium/third_party/blink/renderer/core/timing/performance_navigation.h
index f2ae0ce1212..96946e0a224 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_navigation.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_navigation.h
@@ -63,7 +63,7 @@ class CORE_EXPORT PerformanceNavigation final : public ScriptWrappable,
ScriptValue toJSONForBinding(ScriptState*) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.cc b/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.cc
index 0fd8f9f87dd..10b27f550d6 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.cc
@@ -57,7 +57,8 @@ PerformanceNavigationTiming::PerformanceNavigationTiming(
: g_empty_atom,
time_origin,
SecurityOrigin::IsSecure(frame->GetDocument()->Url()),
- std::move(server_timing)),
+ std::move(server_timing),
+ frame->DomWindow()),
ExecutionContextClient(frame),
resource_timing_info_(info) {
DCHECK(frame);
@@ -75,7 +76,7 @@ PerformanceEntryType PerformanceNavigationTiming::EntryTypeEnum() const {
return PerformanceEntry::EntryType::kNavigation;
}
-void PerformanceNavigationTiming::Trace(Visitor* visitor) {
+void PerformanceNavigationTiming::Trace(Visitor* visitor) const {
ExecutionContextClient::Trace(visitor);
PerformanceResourceTiming::Trace(visitor);
}
@@ -317,4 +318,4 @@ void PerformanceNavigationTiming::BuildJSONValue(
builder.AddString("type", type());
builder.AddNumber("redirectCount", redirectCount());
}
-}
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.h b/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.h
index 36a2dc17259..afe419a0e3e 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.h
@@ -62,7 +62,7 @@ class CORE_EXPORT PerformanceNavigationTiming final
DOMHighResTimeStamp redirectEnd() const override;
DOMHighResTimeStamp responseEnd() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
void BuildJSONValue(V8ObjectBuilder&) const override;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_observer.cc b/chromium/third_party/blink/renderer/core/timing/performance_observer.cc
index 67ab1a64478..ab1c68616e0 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_observer.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_observer.cc
@@ -269,7 +269,7 @@ void PerformanceObserver::ContextLifecycleStateChanged(
performance_->SuspendObserver(*this);
}
-void PerformanceObserver::Trace(Visitor* visitor) {
+void PerformanceObserver::Trace(Visitor* visitor) const {
visitor->Trace(callback_);
visitor->Trace(performance_);
visitor->Trace(performance_entries_);
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_observer.h b/chromium/third_party/blink/renderer/core/timing/performance_observer.h
index 14c3f6f2348..29de2627056 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_observer.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_observer.h
@@ -56,7 +56,7 @@ class CORE_EXPORT PerformanceObserver final
void ContextLifecycleStateChanged(mojom::FrameLifecycleState) final;
void ContextDestroyed() final {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// This describes the types of parameters that an observer can have in its
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_observer_entry_list.cc b/chromium/third_party/blink/renderer/core/timing/performance_observer_entry_list.cc
index 3e36caf2277..7ec0c295816 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_observer_entry_list.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_observer_entry_list.cc
@@ -68,7 +68,7 @@ PerformanceEntryVector PerformanceObserverEntryList::getEntriesByName(
return entries;
}
-void PerformanceObserverEntryList::Trace(Visitor* visitor) {
+void PerformanceObserverEntryList::Trace(Visitor* visitor) const {
visitor->Trace(performance_entries_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_observer_entry_list.h b/chromium/third_party/blink/renderer/core/timing/performance_observer_entry_list.h
index f2a5628b6ed..864e2204878 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_observer_entry_list.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_observer_entry_list.h
@@ -29,7 +29,7 @@ class PerformanceObserverEntryList : public ScriptWrappable {
const String& name,
const AtomicString& entry_type = g_null_atom);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
PerformanceEntryVector performance_entries_;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_resource_timing.cc b/chromium/third_party/blink/renderer/core/timing/performance_resource_timing.cc
index d1265f389b6..41c92f25b81 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_resource_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_resource_timing.cc
@@ -43,6 +43,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
namespace blink {
@@ -51,7 +52,8 @@ PerformanceResourceTiming::PerformanceResourceTiming(
base::TimeTicks time_origin,
const AtomicString& initiator_type,
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
- worker_timing_receiver)
+ worker_timing_receiver,
+ ExecutionContext* context)
: PerformanceEntry(AtomicString(info.name),
Performance::MonotonicTimeToDOMHighResTimeStamp(
time_origin,
@@ -83,7 +85,12 @@ PerformanceResourceTiming::PerformanceResourceTiming(
is_secure_context_(info.is_secure_context),
server_timing_(
PerformanceServerTiming::FromParsedServerTiming(info.server_timing)),
- worker_timing_receiver_(this, std::move(worker_timing_receiver)) {}
+ worker_timing_receiver_(this, context) {
+ DCHECK(context);
+ worker_timing_receiver_.Bind(
+ std::move(worker_timing_receiver),
+ context->GetTaskRunner(TaskType::kMiscPlatformAPI));
+}
// This constructor is for PerformanceNavigationTiming.
// TODO(https://crbug.com/900700): Set a Mojo pending receiver for
@@ -93,14 +100,19 @@ PerformanceResourceTiming::PerformanceResourceTiming(
const AtomicString& name,
base::TimeTicks time_origin,
bool is_secure_context,
- HeapVector<Member<PerformanceServerTiming>> server_timing)
+ HeapVector<Member<PerformanceServerTiming>> server_timing,
+ ExecutionContext* context)
: PerformanceEntry(name, 0.0, 0.0),
time_origin_(time_origin),
context_type_(mojom::RequestContextType::HYPERLINK),
request_destination_(network::mojom::RequestDestination::kDocument),
is_secure_context_(is_secure_context),
server_timing_(std::move(server_timing)),
- worker_timing_receiver_(this, mojo::NullReceiver()) {}
+ worker_timing_receiver_(this, context) {
+ DCHECK(context);
+ worker_timing_receiver_.Bind(
+ mojo::NullReceiver(), context->GetTaskRunner(TaskType::kMiscPlatformAPI));
+}
PerformanceResourceTiming::~PerformanceResourceTiming() = default;
@@ -439,9 +451,10 @@ void PerformanceResourceTiming::AddPerformanceEntry(
}
}
-void PerformanceResourceTiming::Trace(Visitor* visitor) {
+void PerformanceResourceTiming::Trace(Visitor* visitor) const {
visitor->Trace(server_timing_);
visitor->Trace(worker_timing_);
+ visitor->Trace(worker_timing_receiver_);
PerformanceEntry::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_resource_timing.h b/chromium/third_party/blink/renderer/core/timing/performance_resource_timing.h
index 373c111901b..8321566b29e 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_resource_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_resource_timing.h
@@ -32,15 +32,16 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_RESOURCE_TIMING_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_RESOURCE_TIMING_H_
-#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/mojom/timing/performance_mark_or_measure.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/timing/resource_timing.mojom-blink.h"
#include "third_party/blink/public/mojom/timing/worker_timing_container.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/timing/performance_entry.h"
#include "third_party/blink/renderer/core/timing/performance_server_timing.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
namespace blink {
@@ -60,13 +61,15 @@ class CORE_EXPORT PerformanceResourceTiming
const AtomicString& name,
base::TimeTicks time_origin,
bool is_secure_context,
- HeapVector<Member<PerformanceServerTiming>> server_timing);
+ HeapVector<Member<PerformanceServerTiming>> server_timing,
+ ExecutionContext* context);
PerformanceResourceTiming(
const mojom::blink::ResourceTimingInfo&,
base::TimeTicks time_origin,
const AtomicString& initiator_type,
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
- worker_timing_receiver);
+ worker_timing_receiver,
+ ExecutionContext* context);
~PerformanceResourceTiming() override;
AtomicString entryType() const override;
@@ -96,7 +99,7 @@ class CORE_EXPORT PerformanceResourceTiming
// Implements blink::mojom::blink::WorkerTimingContainer
void AddPerformanceEntry(
mojom::blink::PerformanceMarkOrMeasurePtr entry) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
void BuildJSONValue(V8ObjectBuilder&) const override;
@@ -146,7 +149,9 @@ class CORE_EXPORT PerformanceResourceTiming
// Used for getting entries from a service worker to add to
// PerformanceResourceTiming#workerTiming. Null when no service worker handles
// a request for the resource.
- mojo::Receiver<mojom::blink::WorkerTimingContainer> worker_timing_receiver_;
+ HeapMojoReceiver<mojom::blink::WorkerTimingContainer,
+ PerformanceResourceTiming>
+ worker_timing_receiver_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_resource_timing_test.cc b/chromium/third_party/blink/renderer/core/timing/performance_resource_timing_test.cc
index ee04f6b4a30..382bdebf39d 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_resource_timing_test.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_resource_timing_test.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/timing/performance_resource_timing.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
namespace blink {
@@ -14,10 +15,15 @@ class PerformanceResourceTimingTest : public testing::Test {
const AtomicString& connection_info) {
mojom::blink::ResourceTimingInfo info;
info.allow_timing_details = true;
- PerformanceResourceTiming timing(
- info, base::TimeTicks(), /*initiator_type=*/"",
- mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>());
- return timing.GetNextHopProtocol(alpn_negotiated_protocol, connection_info);
+ std::unique_ptr<DummyPageHolder> dummy_page_holder =
+ std::make_unique<DummyPageHolder>();
+ PerformanceResourceTiming* timing =
+ MakeGarbageCollected<PerformanceResourceTiming>(
+ info, base::TimeTicks(), /*initiator_type=*/"",
+ mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>(),
+ dummy_page_holder->GetDocument().GetExecutionContext());
+ return timing->GetNextHopProtocol(alpn_negotiated_protocol,
+ connection_info);
}
};
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_test.cc b/chromium/third_party/blink/renderer/core/timing/performance_test.cc
index f048933eda6..d423813523f 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_test.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_test.cc
@@ -40,7 +40,7 @@ class TestPerformance : public Performance {
return HasObserverFor(entry_type);
}
- void Trace(Visitor* visitor) override { Performance::Trace(visitor); }
+ void Trace(Visitor* visitor) const override { Performance::Trace(visitor); }
};
class PerformanceTest : public PageTestBase {
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_timing.cc b/chromium/third_party/blink/renderer/core/timing/performance_timing.cc
index 7258c4089bd..aecd922eb4d 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_timing.cc
@@ -321,6 +321,41 @@ base::TimeTicks PerformanceTiming::NavigationStartAsMonotonicTime() const {
return timing->NavigationStart();
}
+PerformanceTiming::BackForwardCacheRestoreTimings
+PerformanceTiming::BackForwardCacheRestore() const {
+ DocumentLoadTiming* load_timing = GetDocumentLoadTiming();
+ if (!load_timing)
+ return {};
+
+ const PaintTiming* paint_timing = GetPaintTiming();
+ if (!paint_timing)
+ return {};
+
+ const InteractiveDetector* interactive_detector = GetInteractiveDetector();
+ if (!interactive_detector)
+ return {};
+
+ WTF::Vector<base::TimeTicks> navigation_starts =
+ load_timing->BackForwardCacheRestoreNavigationStarts();
+ WTF::Vector<base::TimeTicks> first_paints =
+ paint_timing->FirstPaintsAfterBackForwardCacheRestore();
+ WTF::Vector<base::Optional<base::TimeDelta>> first_input_delays =
+ interactive_detector->GetFirstInputDelaysAfterBackForwardCacheRestore();
+ DCHECK_EQ(navigation_starts.size(), first_paints.size());
+ DCHECK_EQ(navigation_starts.size(), first_input_delays.size());
+
+ WTF::Vector<BackForwardCacheRestoreTiming> restore_timings(
+ navigation_starts.size());
+ for (size_t i = 0; i < restore_timings.size(); i++) {
+ restore_timings[i].navigation_start =
+ MonotonicTimeToIntegerMilliseconds(navigation_starts[i]);
+ restore_timings[i].first_paint =
+ MonotonicTimeToIntegerMilliseconds(first_paints[i]);
+ restore_timings[i].first_input_delay = first_input_delays[i];
+ }
+ return restore_timings;
+}
+
uint64_t PerformanceTiming::FirstPaint() const {
const PaintTiming* timing = GetPaintTiming();
if (!timing)
@@ -404,6 +439,48 @@ uint64_t PerformanceTiming::LargestTextPaintSize() const {
return paint_timing_detector->LargestTextPaintSize();
}
+uint64_t PerformanceTiming::ExperimentalLargestImagePaint() const {
+ PaintTimingDetector* paint_timing_detector = GetPaintTimingDetector();
+ if (!paint_timing_detector)
+ return 0;
+
+ return MonotonicTimeToIntegerMilliseconds(
+ paint_timing_detector->ExperimentalLargestImagePaint());
+}
+
+uint64_t PerformanceTiming::ExperimentalLargestImagePaintSize() const {
+ PaintTimingDetector* paint_timing_detector = GetPaintTimingDetector();
+ if (!paint_timing_detector)
+ return 0;
+
+ return paint_timing_detector->ExperimentalLargestImagePaintSize();
+}
+
+uint64_t PerformanceTiming::ExperimentalLargestTextPaint() const {
+ PaintTimingDetector* paint_timing_detector = GetPaintTimingDetector();
+ if (!paint_timing_detector)
+ return 0;
+
+ return MonotonicTimeToIntegerMilliseconds(
+ paint_timing_detector->ExperimentalLargestTextPaint());
+}
+
+uint64_t PerformanceTiming::ExperimentalLargestTextPaintSize() const {
+ PaintTimingDetector* paint_timing_detector = GetPaintTimingDetector();
+ if (!paint_timing_detector)
+ return 0;
+
+ return paint_timing_detector->ExperimentalLargestTextPaintSize();
+}
+
+uint64_t PerformanceTiming::FirstEligibleToPaint() const {
+ const PaintTiming* timing = GetPaintTiming();
+ if (!timing)
+ return 0;
+
+ return MonotonicTimeToIntegerMilliseconds(timing->FirstEligibleToPaint());
+}
+
uint64_t PerformanceTiming::FirstInputOrScrollNotifiedTimestamp() const {
PaintTimingDetector* paint_timing_detector = GetPaintTimingDetector();
if (!paint_timing_detector)
@@ -448,6 +525,33 @@ base::Optional<base::TimeDelta> PerformanceTiming::LongestInputTimestamp()
interactive_detector->GetLongestInputTimestamp());
}
+base::Optional<base::TimeDelta> PerformanceTiming::FirstInputProcessingTime()
+ const {
+ const InteractiveDetector* interactive_detector = GetInteractiveDetector();
+ if (!interactive_detector)
+ return base::nullopt;
+
+ return interactive_detector->GetFirstInputProcessingTime();
+}
+
+base::Optional<base::TimeDelta> PerformanceTiming::FirstScrollDelay() const {
+ const InteractiveDetector* interactive_detector = GetInteractiveDetector();
+ if (!interactive_detector)
+ return base::nullopt;
+
+ return interactive_detector->GetFirstScrollDelay();
+}
+
+base::Optional<base::TimeDelta> PerformanceTiming::FirstScrollTimestamp()
+ const {
+ const InteractiveDetector* interactive_detector = GetInteractiveDetector();
+ if (!interactive_detector)
+ return base::nullopt;
+
+ return MonotonicTimeToPseudoWallTime(
+ interactive_detector->GetFirstScrollTimestamp());
+}
+
uint64_t PerformanceTiming::ParseStart() const {
const DocumentParserTiming* timing = GetDocumentParserTiming();
if (!timing)
@@ -502,6 +606,15 @@ PerformanceTiming::ParseBlockedOnScriptExecutionFromDocumentWriteDuration()
timing->ParserBlockedOnScriptExecutionFromDocumentWriteDuration());
}
+base::Optional<base::TimeTicks> PerformanceTiming::LastPortalActivatedPaint()
+ const {
+ const PaintTiming* timing = GetPaintTiming();
+ if (!timing)
+ return base::nullopt;
+
+ return timing->LastPortalActivatedPaint();
+}
+
DocumentLoader* PerformanceTiming::GetDocumentLoader() const {
if (!GetFrame())
return nullptr;
@@ -653,7 +766,7 @@ uint64_t PerformanceTiming::MonotonicTimeToIntegerMilliseconds(
return ToIntegerMilliseconds(timing->MonotonicTimeToPseudoWallTime(time));
}
-void PerformanceTiming::Trace(Visitor* visitor) {
+void PerformanceTiming::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_timing.h b/chromium/third_party/blink/renderer/core/timing/performance_timing.h
index cd707b2b5e3..030e828eabf 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_timing.h
@@ -60,6 +60,15 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
USING_GARBAGE_COLLECTED_MIXIN(PerformanceTiming);
public:
+ struct BackForwardCacheRestoreTiming {
+ uint64_t navigation_start;
+ uint64_t first_paint;
+ base::Optional<base::TimeDelta> first_input_delay;
+ };
+
+ using BackForwardCacheRestoreTimings =
+ WTF::Vector<BackForwardCacheRestoreTiming>;
+
explicit PerformanceTiming(LocalFrame*);
uint64_t navigationStart() const;
@@ -92,6 +101,8 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
// fetchStart. Intended to be used for correlation with other events internal
// to blink. Not to be exposed to JavaScript.
base::TimeTicks NavigationStartAsMonotonicTime() const;
+ // The timings after the page is restored from back-forward cache.
+ BackForwardCacheRestoreTimings BackForwardCacheRestore() const;
// The time the first paint operation was performed.
uint64_t FirstPaint() const;
// The time the first paint operation for image was performed.
@@ -124,6 +135,16 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
// are the time and size of it.
uint64_t LargestTextPaint() const;
uint64_t LargestTextPaintSize() const;
+ // Experimental versions of the above metrics. Currently these are computed by
+ // considering the largest content seen so far, regardless of DOM node
+ // removal.
+ uint64_t ExperimentalLargestImagePaint() const;
+ uint64_t ExperimentalLargestImagePaintSize() const;
+ uint64_t ExperimentalLargestTextPaint() const;
+ uint64_t ExperimentalLargestTextPaintSize() const;
+ // The time at which the frame is first eligible for painting due to not
+ // being throttled. A zero value indicates throttling.
+ uint64_t FirstEligibleToPaint() const;
// The time at which we are notified of the first input or scroll event which
// causes the largest contentful paint algorithm to stop.
uint64_t FirstInputOrScrollNotifiedTimestamp() const;
@@ -139,6 +160,12 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
base::Optional<base::TimeDelta> LongestInputDelay() const;
// The timestamp of the event whose delay is reported by LongestInputDelay().
base::Optional<base::TimeDelta> LongestInputTimestamp() const;
+ // The duration of event handlers processing the first input event.
+ base::Optional<base::TimeDelta> FirstInputProcessingTime() const;
+ // The duration between the user's first scroll and display update.
+ base::Optional<base::TimeDelta> FirstScrollDelay() const;
+ // The hardware timestamp of the first scroll.
+ base::Optional<base::TimeDelta> FirstScrollTimestamp() const;
uint64_t ParseStart() const;
uint64_t ParseStop() const;
@@ -147,13 +174,16 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
uint64_t ParseBlockedOnScriptExecutionDuration() const;
uint64_t ParseBlockedOnScriptExecutionFromDocumentWriteDuration() const;
+ // The time of the first paint after a portal activation.
+ base::Optional<base::TimeTicks> LastPortalActivatedPaint() const;
+
typedef uint64_t (PerformanceTiming::*PerformanceTimingGetter)() const;
using NameToAttributeMap = HashMap<AtomicString, PerformanceTimingGetter>;
static const NameToAttributeMap& GetAttributeMapping();
ScriptValue toJSONForBinding(ScriptState*) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
uint64_t MonotonicTimeToIntegerMilliseconds(base::TimeTicks) const;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_user_timing.cc b/chromium/third_party/blink/renderer/core/timing/performance_user_timing.cc
index b1533768d44..380276ebf24 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_user_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_user_timing.cc
@@ -133,23 +133,25 @@ double UserTiming::GetTimeOrFindMarkTime(const AtomicString& measure_name,
return time;
}
-PerformanceMeasure* UserTiming::Measure(ScriptState* script_state,
- const AtomicString& measure_name,
- const StringOrDouble& start,
- base::Optional<double> duration,
- const StringOrDouble& end,
- const ScriptValue& detail,
- ExceptionState& exception_state) {
+PerformanceMeasure* UserTiming::Measure(
+ ScriptState* script_state,
+ const AtomicString& measure_name,
+ const base::Optional<StringOrDouble>& start,
+ const base::Optional<double>& duration,
+ const base::Optional<StringOrDouble>& end,
+ const ScriptValue& detail,
+ ExceptionState& exception_state) {
double start_time =
- start.IsNull()
- ? 0.0
- : GetTimeOrFindMarkTime(measure_name, start, exception_state);
+ start.has_value()
+ ? GetTimeOrFindMarkTime(measure_name, start.value(), exception_state)
+ : 0;
if (exception_state.HadException())
return nullptr;
double end_time =
- end.IsNull() ? performance_->now()
- : GetTimeOrFindMarkTime(measure_name, end, exception_state);
+ end.has_value()
+ ? GetTimeOrFindMarkTime(measure_name, end.value(), exception_state)
+ : performance_->now();
if (exception_state.HadException())
return nullptr;
@@ -157,11 +159,11 @@ PerformanceMeasure* UserTiming::Measure(ScriptState* script_state,
// When |duration| is specified, we require that exactly one of |start| and
// |end| were specified. Then, since |start| + |duration| = |end|, we'll
// compute the missing boundary.
- if (start.IsNull()) {
+ if (!start) {
start_time = end_time - duration.value();
} else {
- DCHECK(end.IsNull()) << "When duration is specified, one of 'start' or "
- "'end' must be unspecified";
+ DCHECK(!end) << "When duration is specified, one of 'start' or "
+ "'end' must be unspecified";
end_time = start_time + duration.value();
}
}
@@ -234,7 +236,7 @@ PerformanceEntryVector UserTiming::GetMeasures(const AtomicString& name) const {
return GetEntrySequenceByName(measures_map_, name);
}
-void UserTiming::Trace(Visitor* visitor) {
+void UserTiming::Trace(Visitor* visitor) const {
visitor->Trace(performance_);
visitor->Trace(marks_map_);
visitor->Trace(measures_map_);
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_user_timing.h b/chromium/third_party/blink/renderer/core/timing/performance_user_timing.h
index 6a249d8ecd5..ae6c48db7ba 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_user_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_user_timing.h
@@ -46,9 +46,9 @@ class UserTiming final : public GarbageCollected<UserTiming> {
PerformanceMeasure* Measure(ScriptState*,
const AtomicString& measure_name,
- const StringOrDouble& start,
- base::Optional<double> duration,
- const StringOrDouble& end,
+ const base::Optional<StringOrDouble>& start,
+ const base::Optional<double>& duration,
+ const base::Optional<StringOrDouble>& end,
const ScriptValue& detail,
ExceptionState&);
void ClearMeasures(const AtomicString& measure_name);
@@ -60,7 +60,7 @@ class UserTiming final : public GarbageCollected<UserTiming> {
PerformanceEntryVector GetMarks(const AtomicString& name) const;
PerformanceEntryVector GetMeasures(const AtomicString& name) const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
double FindExistingMarkStartTime(const AtomicString& mark_name,
diff --git a/chromium/third_party/blink/renderer/core/timing/profiler.cc b/chromium/third_party/blink/renderer/core/timing/profiler.cc
index f9161ac7024..bd4b33936b2 100644
--- a/chromium/third_party/blink/renderer/core/timing/profiler.cc
+++ b/chromium/third_party/blink/renderer/core/timing/profiler.cc
@@ -10,7 +10,7 @@
namespace blink {
-void Profiler::Trace(Visitor* visitor) {
+void Profiler::Trace(Visitor* visitor) const {
visitor->Trace(profiler_group_);
visitor->Trace(script_state_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/timing/profiler.h b/chromium/third_party/blink/renderer/core/timing/profiler.h
index e35646ba1d4..50fc898d2d0 100644
--- a/chromium/third_party/blink/renderer/core/timing/profiler.h
+++ b/chromium/third_party/blink/renderer/core/timing/profiler.h
@@ -43,7 +43,7 @@ class CORE_EXPORT Profiler final : public ScriptWrappable {
~Profiler() override = default;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
void DisposeAsync();
diff --git a/chromium/third_party/blink/renderer/core/timing/profiler_group.cc b/chromium/third_party/blink/renderer/core/timing/profiler_group.cc
index f17a821d650..1f7b00f81dc 100644
--- a/chromium/third_party/blink/renderer/core/timing/profiler_group.cc
+++ b/chromium/third_party/blink/renderer/core/timing/profiler_group.cc
@@ -125,18 +125,20 @@ ProfilerGroup::~ProfilerGroup() {
}
void ProfilerGroup::WillBeDestroyed() {
- for (auto& profiler : profilers_) {
+ while (!profilers_.IsEmpty()) {
+ Profiler* profiler = profilers_.begin()->Get();
DCHECK(profiler);
CancelProfiler(profiler);
profiler->RemovedFromProfilerGroup();
DCHECK(profiler->stopped());
+ DCHECK(!profilers_.Contains(profiler));
}
if (cpu_profiler_)
TeardownV8Profiler();
}
-void ProfilerGroup::Trace(Visitor* visitor) {
+void ProfilerGroup::Trace(Visitor* visitor) const {
visitor->Trace(profilers_);
V8PerIsolateData::GarbageCollectedData::Trace(visitor);
}
@@ -179,6 +181,8 @@ void ProfilerGroup::StopProfiler(ScriptState* script_state,
if (profile)
profile->Delete();
+ profilers_.erase(profiler);
+
if (--num_active_profilers_ == 0)
TeardownV8Profiler();
}
@@ -186,6 +190,7 @@ void ProfilerGroup::StopProfiler(ScriptState* script_state,
void ProfilerGroup::CancelProfiler(Profiler* profiler) {
DCHECK(cpu_profiler_);
DCHECK(!profiler->stopped());
+ profilers_.erase(profiler);
CancelProfilerImpl(profiler->ProfilerId());
}
@@ -193,6 +198,7 @@ void ProfilerGroup::CancelProfilerAsync(ScriptState* script_state,
Profiler* profiler) {
DCHECK(cpu_profiler_);
DCHECK(!profiler->stopped());
+ profilers_.erase(profiler);
ExecutionContext::From(script_state)
->GetTaskRunner(TaskType::kInternalDefault)
->PostTask(FROM_HERE,
diff --git a/chromium/third_party/blink/renderer/core/timing/profiler_group.h b/chromium/third_party/blink/renderer/core/timing/profiler_group.h
index 7f9cc217aae..c775f27c1be 100644
--- a/chromium/third_party/blink/renderer/core/timing/profiler_group.h
+++ b/chromium/third_party/blink/renderer/core/timing/profiler_group.h
@@ -41,7 +41,7 @@ class CORE_EXPORT ProfilerGroup
ExceptionState&);
void WillBeDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class Profiler;
diff --git a/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.cc b/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.cc
index 2c5833fb697..aedbad1455f 100644
--- a/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.cc
@@ -55,7 +55,7 @@ void TaskAttributionTiming::BuildJSONValue(V8ObjectBuilder& builder) const {
builder.AddString("containerName", containerName());
}
-void TaskAttributionTiming::Trace(Visitor* visitor) {
+void TaskAttributionTiming::Trace(Visitor* visitor) const {
PerformanceEntry::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.h b/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.h
index f5e72b9e8ec..53c031d03a3 100644
--- a/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.h
@@ -24,7 +24,7 @@ class TaskAttributionTiming final : public PerformanceEntry {
String containerId() const;
String containerName() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
TaskAttributionTiming(const AtomicString& type,
const AtomicString& container_type,
diff --git a/chromium/third_party/blink/renderer/core/timing/window_performance.cc b/chromium/third_party/blink/renderer/core/timing/window_performance.cc
index 6dc40bff1f7..2941e63a5a3 100644
--- a/chromium/third_party/blink/renderer/core/timing/window_performance.cc
+++ b/chromium/third_party/blink/renderer/core/timing/window_performance.cc
@@ -40,6 +40,7 @@
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/timing/largest_contentful_paint.h"
@@ -48,6 +49,7 @@
#include "third_party/blink/renderer/core/timing/performance_event_timing.h"
#include "third_party/blink/renderer/core/timing/performance_observer.h"
#include "third_party/blink/renderer/core/timing/performance_timing.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -139,21 +141,13 @@ AtomicString SameOriginAttribution(Frame* observer_frame,
} // namespace
static base::TimeTicks ToTimeOrigin(LocalDOMWindow* window) {
- Document* document = window->document();
- if (!document)
- return base::TimeTicks();
-
- DocumentLoader* loader = document->Loader();
- if (!loader)
- return base::TimeTicks();
-
+ DocumentLoader* loader = window->GetFrame()->Loader().GetDocumentLoader();
return loader->GetTiming().ReferenceMonotonicTime();
}
WindowPerformance::WindowPerformance(LocalDOMWindow* window)
- : Performance(
- ToTimeOrigin(window),
- window->document()->GetTaskRunner(TaskType::kPerformanceTimeline)),
+ : Performance(ToTimeOrigin(window),
+ window->GetTaskRunner(TaskType::kPerformanceTimeline)),
ExecutionContextClient(window) {
DCHECK(GetFrame());
DCHECK(GetFrame()->GetPerformanceMonitor());
@@ -220,7 +214,7 @@ void WindowPerformance::BuildJSONValue(V8ObjectBuilder& builder) const {
builder.Add("navigation", navigation());
}
-void WindowPerformance::Trace(Visitor* visitor) {
+void WindowPerformance::Trace(Visitor* visitor) const {
visitor->Trace(event_timings_);
visitor->Trace(first_pointer_down_event_timing_);
visitor->Trace(event_counts_);
@@ -346,25 +340,55 @@ void WindowPerformance::RegisterEventTiming(const AtomicString& event_type,
event_type, MonotonicTimeToDOMHighResTimeStamp(start_time),
MonotonicTimeToDOMHighResTimeStamp(processing_start),
MonotonicTimeToDOMHighResTimeStamp(processing_end), cancelable, target);
+ // Add |entry| to the end of the queue along with the frame index at which is
+ // is being queued to know when to queue a swap promise for it.
event_timings_.push_back(entry);
- // Only queue a swap promise when |event_timings_| was empty. All of the
- // elements in |event_timings_| will be processed in a single call of
- // ReportEventTimings() when the promise suceeds or fails. This method also
- // clears the vector, so a promise has already been queued when the vector was
- // not previously empty.
- if (event_timings_.size() == 1) {
+ event_frames_.push_back(frame_index_);
+ bool should_queue_swap_promise = false;
+ // If there are no pending swap promises, we should queue one. This ensures
+ // that |event_timings_| are processed even if the Blink lifecycle does not
+ // occur due to no DOM updates.
+ if (pending_swap_promise_count_ == 0u) {
+ should_queue_swap_promise = true;
+ } else {
+ // There are pending swap promises, so only queue one if the event
+ // corresponds to a later frame than the one of the latest queued swap
+ // promise.
+ should_queue_swap_promise = frame_index_ > last_registered_frame_index_;
+ }
+ if (should_queue_swap_promise) {
GetFrame()->GetChromeClient().NotifySwapTime(
- *GetFrame(), CrossThreadBindOnce(&WindowPerformance::ReportEventTimings,
- WrapCrossThreadWeakPersistent(this)));
+ *GetFrame(),
+ CrossThreadBindOnce(&WindowPerformance::ReportEventTimings,
+ WrapCrossThreadWeakPersistent(this), frame_index_));
+ last_registered_frame_index_ = frame_index_;
+ ++pending_swap_promise_count_;
}
}
-void WindowPerformance::ReportEventTimings(WebSwapResult result,
+void WindowPerformance::ReportEventTimings(uint64_t frame_index,
+ WebSwapResult result,
base::TimeTicks timestamp) {
- DOMHighResTimeStamp end_time = MonotonicTimeToDOMHighResTimeStamp(timestamp);
+ DCHECK(pending_swap_promise_count_);
+ --pending_swap_promise_count_;
+ // |event_timings_| and |event_frames_| should always have the same size.
+ DCHECK(event_timings_.size() == event_frames_.size());
bool event_timing_enabled =
RuntimeEnabledFeatures::EventTimingEnabled(GetExecutionContext());
- for (const auto& entry : event_timings_) {
+ while (!event_timings_.IsEmpty()) {
+ PerformanceEventTiming* entry = event_timings_.front();
+ uint64_t entry_frame_index = event_frames_.front();
+ // If the entry was queued at a frame index that is larger than
+ // |frame_index|, then we've reached the end of the entries that we can
+ // process during this callback.
+ if (entry_frame_index > frame_index)
+ break;
+
+ event_timings_.pop_front();
+ event_frames_.pop_front();
+ DOMHighResTimeStamp end_time =
+ MonotonicTimeToDOMHighResTimeStamp(timestamp);
+
int duration_in_ms = std::round((end_time - entry->startTime()) / 8) * 8;
entry->SetDuration(duration_in_ms);
if (!first_input_timing_) {
@@ -396,7 +420,6 @@ void WindowPerformance::ReportEventTimings(WebSwapResult result,
AddEventTimingBuffer(*entry);
}
}
- event_timings_.clear();
}
void WindowPerformance::AddElementTiming(const AtomicString& name,
@@ -467,4 +490,8 @@ void WindowPerformance::OnLargestContentfulPaintUpdated(
AddLargestContentfulPaint(entry);
}
+void WindowPerformance::OnPaintFinished() {
+ ++frame_index_;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/timing/window_performance.h b/chromium/third_party/blink/renderer/core/timing/window_performance.h
index 6c79d80650c..3d5a6368868 100644
--- a/chromium/third_party/blink/renderer/core/timing/window_performance.h
+++ b/chromium/third_party/blink/renderer/core/timing/window_performance.h
@@ -76,6 +76,8 @@ class CORE_EXPORT WindowPerformance final : public Performance,
bool cancelable,
Node*);
+ void OnPaintFinished();
+
void AddElementTiming(const AtomicString& name,
const String& url,
const FloatRect& rect,
@@ -95,7 +97,7 @@ class CORE_EXPORT WindowPerformance final : public Performance,
const String& url,
Element*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
PerformanceNavigationTiming* CreateNavigationTimingInstance() override;
@@ -115,14 +117,32 @@ class CORE_EXPORT WindowPerformance final : public Performance,
// Method called once swap promise is resolved. It will add all event timings
// that have not been added since the last swap promise.
- void ReportEventTimings(WebSwapResult result, base::TimeTicks timestamp);
+ void ReportEventTimings(uint64_t frame_index,
+ WebSwapResult result,
+ base::TimeTicks timestamp);
void DispatchFirstInputTiming(PerformanceEventTiming* entry);
- // PerformanceEventTiming entries that have not been added yet: the event
- // dispatch has been completed but the swap promise used to determine
- // |duration| has not been resolved.
- HeapVector<Member<PerformanceEventTiming>> event_timings_;
+ // Counter of the current frame index, based on calls to OnPaintFinished().
+ uint64_t frame_index_ = 1;
+ // Monotonically increasing value with the last frame index on which a swap
+ // promise was queued;
+ uint64_t last_registered_frame_index_ = 0;
+ // Number of pending swap promises.
+ uint16_t pending_swap_promise_count_ = 0;
+ // PerformanceEventTiming entries that have not been sent to observers yet:
+ // the event dispatch has been completed but the swap promise used to
+ // determine |duration| has not yet been resolved. It is handled as a queue:
+ // FIFO.
+ HeapDeque<Member<PerformanceEventTiming>> event_timings_;
+ // Entries corresponding to frame indices in which the entries in
+ // |event_timings_| were added. This could be combined with |event_timings_|
+ // into a single deque, but PerformanceEventTiming is GarbageCollected so it
+ // would need to be a HeapDeque. HeapDeque does not allow std::pair as its
+ // type, so we would have to add a new wrapper GarbageCollected class that
+ // contains the PerformanceEventTiming object as well as the frame index. This
+ // is more work than having two separate deques.
+ Deque<uint64_t> event_frames_;
Member<PerformanceEventTiming> first_pointer_down_event_timing_;
Member<EventCounts> event_counts_;
mutable Member<PerformanceNavigation> navigation_;
diff --git a/chromium/third_party/blink/renderer/core/timing/window_performance_test.cc b/chromium/third_party/blink/renderer/core/timing/window_performance_test.cc
index 7e0dcd1b1d6..1b8b8e70bc6 100644
--- a/chromium/third_party/blink/renderer/core/timing/window_performance_test.cc
+++ b/chromium/third_party/blink/renderer/core/timing/window_performance_test.cc
@@ -62,7 +62,8 @@ class WindowPerformanceTest : public testing::Test {
}
void SimulateSwapPromise(base::TimeTicks timestamp) {
- performance_->ReportEventTimings(WebSwapResult::kDidSwap, timestamp);
+ performance_->ReportEventTimings(frame_counter++, WebSwapResult::kDidSwap,
+ timestamp);
}
LocalFrame* GetFrame() const { return &page_holder_->GetFrame(); }
@@ -93,6 +94,7 @@ class WindowPerformanceTest : public testing::Test {
return ToScriptStateForMainWorld(page_holder_->GetDocument().GetFrame());
}
+ uint64_t frame_counter = 1;
Persistent<WindowPerformance> performance_;
std::unique_ptr<DummyPageHolder> page_holder_;
scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
@@ -158,6 +160,12 @@ TEST_F(WindowPerformanceTest, NavigateAway) {
// document.
TEST(PerformanceLifetimeTest, SurviveContextSwitch) {
auto page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+ // Emulate a new window inheriting the origin for its initial empty document
+ // from its opener. This is necessary to ensure window reuse below, as that
+ // only happens when origins match.
+ KURL url("https://example.com");
+ page_holder->GetDocument().GetSecurityContext().SetSecurityOriginForTesting(
+ SecurityOrigin::Create(KURL(url)));
WindowPerformance* perf =
DOMWindowPerformance::performance(*page_holder->GetFrame().DomWindow());
@@ -173,18 +181,16 @@ TEST(PerformanceLifetimeTest, SurviveContextSwitch) {
EXPECT_NE(0U, navigation_start);
// Simulate changing the document while keeping the window.
- page_holder->GetDocument().Shutdown();
- page_holder->GetFrame().DomWindow()->InstallNewDocument(
- DocumentInit::Create()
- .WithDocumentLoader(document_loader)
- .WithTypeFrom("text/html"));
+ std::unique_ptr<WebNavigationParams> params =
+ WebNavigationParams::CreateWithHTMLBuffer(SharedBuffer::Create(), url);
+ page_holder->GetFrame().Loader().CommitNavigation(std::move(params), nullptr);
EXPECT_EQ(perf, DOMWindowPerformance::performance(
*page_holder->GetFrame().DomWindow()));
EXPECT_EQ(timing, perf->timing());
EXPECT_EQ(&page_holder->GetFrame(), perf->GetFrame());
EXPECT_EQ(&page_holder->GetFrame(), timing->GetFrame());
- EXPECT_EQ(navigation_start, timing->navigationStart());
+ EXPECT_LE(navigation_start, timing->navigationStart());
}
// Make sure the output entries with the same timestamps follow the insertion
@@ -316,7 +322,9 @@ TEST_F(WindowPerformanceTest, EventTimingDuration) {
EXPECT_EQ(2u, performance_->getBufferedEntriesByType("event").size());
}
-TEST_F(WindowPerformanceTest, MultipleEventsSameSwap) {
+// Test the case where multiple events are registered and then their swap
+// promise is resolved.
+TEST_F(WindowPerformanceTest, MultipleEventsThenSwap) {
ScopedEventTimingForTest event_timing(true);
size_t num_events = 10;
@@ -360,7 +368,7 @@ TEST_F(WindowPerformanceTest, FirstInput) {
}
}
-// Test that the 'firstInput' is populated after some irrelevant events are
+// Test that the 'first-input' is populated after some irrelevant events are
// ignored.
TEST_F(WindowPerformanceTest, FirstInputAfterIgnored) {
AtomicString several_events[] = {"mouseover", "mousedown", "pointerup"};
@@ -369,8 +377,8 @@ TEST_F(WindowPerformanceTest, FirstInputAfterIgnored) {
event, GetTimeOrigin(),
GetTimeOrigin() + base::TimeDelta::FromMilliseconds(1),
GetTimeOrigin() + base::TimeDelta::FromMilliseconds(2), false, nullptr);
+ SimulateSwapPromise(GetTimeOrigin() + base::TimeDelta::FromMilliseconds(3));
}
- SimulateSwapPromise(GetTimeOrigin() + base::TimeDelta::FromMilliseconds(3));
ASSERT_EQ(1u, performance_->getEntriesByType("first-input").size());
EXPECT_EQ("mousedown",
performance_->getEntriesByType("first-input")[0]->name());
diff --git a/chromium/third_party/blink/renderer/core/timing/worker_global_scope_performance.cc b/chromium/third_party/blink/renderer/core/timing/worker_global_scope_performance.cc
index ddde8497264..faaa254119a 100644
--- a/chromium/third_party/blink/renderer/core/timing/worker_global_scope_performance.cc
+++ b/chromium/third_party/blink/renderer/core/timing/worker_global_scope_performance.cc
@@ -67,7 +67,7 @@ WorkerPerformance* WorkerGlobalScopePerformance::performance(
return performance_.Get();
}
-void WorkerGlobalScopePerformance::Trace(Visitor* visitor) {
+void WorkerGlobalScopePerformance::Trace(Visitor* visitor) const {
visitor->Trace(performance_);
Supplement<WorkerGlobalScope>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/worker_global_scope_performance.h b/chromium/third_party/blink/renderer/core/timing/worker_global_scope_performance.h
index 9a81ae19b62..3554a4f9ae4 100644
--- a/chromium/third_party/blink/renderer/core/timing/worker_global_scope_performance.h
+++ b/chromium/third_party/blink/renderer/core/timing/worker_global_scope_performance.h
@@ -55,7 +55,7 @@ class CORE_EXPORT WorkerGlobalScopePerformance final
explicit WorkerGlobalScopePerformance(WorkerGlobalScope&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
WorkerPerformance* performance(WorkerGlobalScope*);
diff --git a/chromium/third_party/blink/renderer/core/timing/worker_performance.cc b/chromium/third_party/blink/renderer/core/timing/worker_performance.cc
index d84e83462b5..835c295863b 100644
--- a/chromium/third_party/blink/renderer/core/timing/worker_performance.cc
+++ b/chromium/third_party/blink/renderer/core/timing/worker_performance.cc
@@ -44,7 +44,7 @@ WorkerPerformance::WorkerPerformance(WorkerGlobalScope* context)
context->GetTaskRunner(TaskType::kPerformanceTimeline)),
execution_context_(context) {}
-void WorkerPerformance::Trace(Visitor* visitor) {
+void WorkerPerformance::Trace(Visitor* visitor) const {
visitor->Trace(execution_context_);
Performance::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/worker_performance.h b/chromium/third_party/blink/renderer/core/timing/worker_performance.h
index 42e6fa055b0..e5b79862d58 100644
--- a/chromium/third_party/blink/renderer/core/timing/worker_performance.h
+++ b/chromium/third_party/blink/renderer/core/timing/worker_performance.h
@@ -49,7 +49,7 @@ class WorkerPerformance final : public Performance {
return execution_context_;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<ExecutionContext> execution_context_;
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.cc b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.cc
index 2ffbaa90a0c..da295291317 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.cc
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.cc
@@ -4,6 +4,9 @@
#include "third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_create_html_callback.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_create_script_callback.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_create_url_callback.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_html.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_script.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_script_url.h"
@@ -45,7 +48,7 @@ TrustedHTML* TrustedTypePolicy::CreateHTML(v8::Isolate* isolate,
const String& input,
const HeapVector<ScriptValue>& args,
ExceptionState& exception_state) {
- if (!policy_options_->createHTML()) {
+ if (!policy_options_->hasCreateHTML()) {
exception_state.ThrowTypeError(
"Policy " + name_ +
"'s TrustedTypePolicyOptions did not specify a 'createHTML' member.");
@@ -66,7 +69,7 @@ TrustedScript* TrustedTypePolicy::CreateScript(
const String& input,
const HeapVector<ScriptValue>& args,
ExceptionState& exception_state) {
- if (!policy_options_->createScript()) {
+ if (!policy_options_->hasCreateScript()) {
exception_state.ThrowTypeError(
"Policy " + name_ +
"'s TrustedTypePolicyOptions did not specify a 'createScript' member.");
@@ -89,7 +92,7 @@ TrustedScriptURL* TrustedTypePolicy::CreateScriptURL(
const String& input,
const HeapVector<ScriptValue>& args,
ExceptionState& exception_state) {
- if (!policy_options_->createScriptURL()) {
+ if (!policy_options_->hasCreateScriptURL()) {
exception_state.ThrowTypeError("Policy " + name_ +
"'s TrustedTypePolicyOptions did not "
"specify a 'createScriptURL' member.");
@@ -108,22 +111,22 @@ TrustedScriptURL* TrustedTypePolicy::CreateScriptURL(
}
bool TrustedTypePolicy::HasCreateHTML() {
- return policy_options_->createHTML();
+ return policy_options_->hasCreateHTML();
}
bool TrustedTypePolicy::HasCreateScript() {
- return policy_options_->createScript();
+ return policy_options_->hasCreateScript();
}
bool TrustedTypePolicy::HasCreateScriptURL() {
- return policy_options_->createScriptURL();
+ return policy_options_->hasCreateScriptURL();
}
String TrustedTypePolicy::name() const {
return name_;
}
-void TrustedTypePolicy::Trace(Visitor* visitor) {
+void TrustedTypePolicy::Trace(Visitor* visitor) const {
visitor->Trace(policy_options_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h
index 07382f6c8e2..af13e11476c 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h
@@ -58,7 +58,7 @@ class CORE_EXPORT TrustedTypePolicy final : public ScriptWrappable {
String name() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String name_;
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.cc b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.cc
index 4935a61fe88..588b1e68da9 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.cc
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.cc
@@ -308,7 +308,7 @@ void TrustedTypePolicyFactory::CountTrustedTypeAssignmentError() {
}
}
-void TrustedTypePolicyFactory::Trace(Visitor* visitor) {
+void TrustedTypePolicyFactory::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
visitor->Trace(empty_html_);
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.h b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.h
index cc2a11fb888..1ee549d29ab 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.h
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.h
@@ -68,7 +68,7 @@ class CORE_EXPORT TrustedTypePolicyFactory final
// relate it to the total number of TT enabled documents.)
void CountTrustedTypeAssignmentError();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const WrapperTypeInfo* GetWrapperTypeInfoFromScriptValue(ScriptState*,
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc
index 0858ac2a1f1..403279910bf 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h"
+#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/reporting/reporting.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
@@ -12,6 +13,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/script/script_element_base.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_html.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_script.h"
@@ -43,6 +45,11 @@ enum TrustedTypeViolationKind {
kScriptExecutionAndDefaultPolicyFailed,
};
+const char kFunctionConstructorFailureConsoleMessage[] =
+ "The JavaScript Function constructor does not accept TrustedString "
+ "arguments. See https://github.com/w3c/webappsec-trusted-types/wiki/"
+ "Trusted-Types-for-function-constructor for more information.";
+
const char* GetMessage(TrustedTypeViolationKind kind) {
switch (kind) {
case kTrustedHTMLAssignment:
@@ -147,16 +154,41 @@ bool TrustedTypeFail(TrustedTypeViolationKind kind,
if (!execution_context)
return true;
- // Test case docs (MakeGarbageCollected<Document>()) might not have a window
+ // Test case docs (Document::CreateForTest()) might not have a window
// and hence no TrustedTypesPolicyFactory.
if (execution_context->GetTrustedTypes())
execution_context->GetTrustedTypes()->CountTrustedTypeAssignmentError();
+ const char* kAnonymousPrefix = "(function anonymous";
+ String prefix = GetSamplePrefix(exception_state);
+ if (prefix == "eval" && value.StartsWith(kAnonymousPrefix)) {
+ prefix = "Function";
+ }
bool allow =
execution_context->GetSecurityContext()
.GetContentSecurityPolicy()
- ->AllowTrustedTypeAssignmentFailure(GetMessage(kind), value,
- GetSamplePrefix(exception_state));
+ ->AllowTrustedTypeAssignmentFailure(
+ GetMessage(kind),
+ prefix == "Function" ? value.Substring(strlen(kAnonymousPrefix))
+ : value,
+ prefix);
+
+ // TODO(1087743): Add a console message for Trusted Type-related Function
+ // constructor failures, to warn the developer of the outstanding issues
+ // with TT and Function constructors. This should be removed once the
+ // underlying issue has been fixed.
+ if (prefix == "Function" && !allow) {
+ DCHECK(kind == kTrustedScriptAssignment ||
+ kind == kTrustedScriptAssignmentAndDefaultPolicyFailed ||
+ kind == kTrustedScriptAssignmentAndNoDefaultPolicyExisted);
+ execution_context->GetSecurityContext()
+ .GetContentSecurityPolicy()
+ ->LogToConsole(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kRecommendation,
+ mojom::blink::ConsoleMessageLevel::kInfo,
+ kFunctionConstructorFailureConsoleMessage));
+ }
+
if (!allow) {
exception_state.ThrowTypeError(GetMessage(kind));
}
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.cc b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.cc
index fe4485a3479..5026ce05c5e 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.cc
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.cc
@@ -116,9 +116,8 @@ void* ArrayBufferContents::AllocateMemoryWithFlags(size_t size,
if (policy == kZeroInitialize) {
flags |= base::PartitionAllocZeroFill;
}
- void* data = PartitionAllocGenericFlags(
- WTF::Partitions::ArrayBufferPartition(), flags, size,
- WTF_HEAP_PROFILER_TYPE_NAME(ArrayBufferContents));
+ void* data = WTF::Partitions::ArrayBufferPartition()->AllocFlags(
+ flags, size, WTF_HEAP_PROFILER_TYPE_NAME(ArrayBufferContents));
InstanceCounters::IncrementCounter(
InstanceCounters::kArrayBufferContentsCounter);
return data;
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h
index 5fa03cb3550..bf1049afb28 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h
@@ -64,7 +64,7 @@ class NotShared {
T* operator->() const { return GetRaw(); }
T& operator*() const { return *GetRaw(); }
- void Trace(Visitor* visitor) { visitor->Trace(typed_array_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(typed_array_); }
private:
T* GetRaw() const { return typed_array_; }
@@ -122,7 +122,7 @@ class MaybeShared {
T* operator->() const { return GetRaw(); }
T& operator*() const { return *GetRaw(); }
- void Trace(Visitor* visitor) { visitor->Trace(typed_array_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(typed_array_); }
private:
T* GetRaw() const { return typed_array_; }
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h
index 3b863d46da5..bb36bc043f0 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h
@@ -127,7 +127,7 @@ class CORE_EXPORT DOMArrayBufferView : public ScriptWrappable {
return v8::Local<v8::Object>();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(dom_array_buffer_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/url/dom_url.cc b/chromium/third_party/blink/renderer/core/url/dom_url.cc
index 1c13f28e14f..336b3af30c9 100644
--- a/chromium/third_party/blink/renderer/core/url/dom_url.cc
+++ b/chromium/third_party/blink/renderer/core/url/dom_url.cc
@@ -50,7 +50,7 @@ DOMURL::DOMURL(const String& url,
DOMURL::~DOMURL() = default;
-void DOMURL::Trace(Visitor* visitor) {
+void DOMURL::Trace(Visitor* visitor) const {
visitor->Trace(search_params_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/url/dom_url.h b/chromium/third_party/blink/renderer/core/url/dom_url.h
index 3cfc0845119..adb7f8c47f5 100644
--- a/chromium/third_party/blink/renderer/core/url/dom_url.h
+++ b/chromium/third_party/blink/renderer/core/url/dom_url.h
@@ -73,7 +73,7 @@ class CORE_EXPORT DOMURL final : public ScriptWrappable, public DOMURLUtils {
String toJSON() { return href(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class URLSearchParams;
diff --git a/chromium/third_party/blink/renderer/core/url/url_search_params.cc b/chromium/third_party/blink/renderer/core/url/url_search_params.cc
index 69a7d532f83..25d1cd3e31d 100644
--- a/chromium/third_party/blink/renderer/core/url/url_search_params.cc
+++ b/chromium/third_party/blink/renderer/core/url/url_search_params.cc
@@ -36,7 +36,7 @@ class URLSearchParamsIterationSource final
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(params_);
PairIterable<String, String>::IterationSource::Trace(visitor);
}
@@ -111,7 +111,7 @@ URLSearchParams* URLSearchParams::Create(
URLSearchParams::~URLSearchParams() = default;
-void URLSearchParams::Trace(Visitor* visitor) {
+void URLSearchParams::Trace(Visitor* visitor) const {
visitor->Trace(url_object_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/url/url_search_params.h b/chromium/third_party/blink/renderer/core/url/url_search_params.h
index ab27f7cf5a9..59e7856dbe6 100644
--- a/chromium/third_party/blink/renderer/core/url/url_search_params.h
+++ b/chromium/third_party/blink/renderer/core/url/url_search_params.h
@@ -61,7 +61,7 @@ class CORE_EXPORT URLSearchParams final : public ScriptWrappable,
DOMURL* UrlObject() const;
#endif
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
FRIEND_TEST_ALL_PREFIXES(URLSearchParamsTest, EncodedFormData);
diff --git a/chromium/third_party/blink/renderer/core/workers/abstract_worker.cc b/chromium/third_party/blink/renderer/core/workers/abstract_worker.cc
index a53c674b831..b225e9b32d2 100644
--- a/chromium/third_party/blink/renderer/core/workers/abstract_worker.cc
+++ b/chromium/third_party/blink/renderer/core/workers/abstract_worker.cc
@@ -43,12 +43,9 @@ AbstractWorker::AbstractWorker(ExecutionContext* context)
AbstractWorker::~AbstractWorker() = default;
// static
-KURL AbstractWorker::ResolveURL(
- ExecutionContext* execution_context,
- const String& url,
- ExceptionState& exception_state,
- mojom::RequestContextType request_context,
- network::mojom::RequestDestination request_destination) {
+KURL AbstractWorker::ResolveURL(ExecutionContext* execution_context,
+ const String& url,
+ ExceptionState& exception_state) {
KURL script_url = execution_context->CompleteURL(url);
if (!script_url.IsValid()) {
exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
@@ -69,9 +66,7 @@ KURL AbstractWorker::ResolveURL(
if (ContentSecurityPolicy* csp =
execution_context->GetContentSecurityPolicy()) {
- if (!csp->AllowRequestWithoutIntegrity(request_context, request_destination,
- script_url) ||
- !csp->AllowWorkerContextFromSource(script_url)) {
+ if (!csp->AllowWorkerContextFromSource(script_url)) {
exception_state.ThrowSecurityError(
"Access to the script at '" + script_url.ElidedString() +
"' is denied by the document's Content Security Policy.");
@@ -82,7 +77,7 @@ KURL AbstractWorker::ResolveURL(
return script_url;
}
-void AbstractWorker::Trace(Visitor* visitor) {
+void AbstractWorker::Trace(Visitor* visitor) const {
EventTargetWithInlineData::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/workers/abstract_worker.h b/chromium/third_party/blink/renderer/core/workers/abstract_worker.h
index 51d9911fba1..380abce5f73 100644
--- a/chromium/third_party/blink/renderer/core/workers/abstract_worker.h
+++ b/chromium/third_party/blink/renderer/core/workers/abstract_worker.h
@@ -66,17 +66,12 @@ class CORE_EXPORT AbstractWorker
AbstractWorker(ExecutionContext*);
~AbstractWorker() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
// Helper function that converts a URL to an absolute URL and checks the
// result for validity.
- static KURL ResolveURL(
- ExecutionContext*,
- const String& url,
- ExceptionState&,
- mojom::RequestContextType,
- network::mojom::RequestDestination request_destination);
+ static KURL ResolveURL(ExecutionContext*, const String& url, ExceptionState&);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/workers/dedicated_worker.cc b/chromium/third_party/blink/renderer/core/workers/dedicated_worker.cc
index c2d425c152c..09d7bbe9661 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker.cc
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker.cc
@@ -64,9 +64,7 @@ DedicatedWorker* DedicatedWorker::Create(ExecutionContext* context,
return nullptr;
}
- KURL script_request_url = ResolveURL(
- context, url, exception_state, mojom::RequestContextType::SCRIPT,
- network::mojom::RequestDestination::kScript);
+ KURL script_request_url = ResolveURL(context, url, exception_state);
if (!script_request_url.IsValid()) {
// Don't throw an exception here because it's already thrown in
// ResolveURL().
@@ -195,10 +193,9 @@ void DedicatedWorker::Start() {
}
factory_client_->CreateWorkerHost(
- script_request_url_,
- credentials_mode,
+ script_request_url_, credentials_mode,
WebFetchClientSettingsObject(*outside_fetch_client_settings_object_),
- blob_url_token.PassPipe());
+ std::move(blob_url_token));
// Continue in OnScriptLoadStarted() or OnScriptLoadStartFailed().
return;
}
@@ -292,12 +289,10 @@ bool DedicatedWorker::HasPendingActivity() const {
}
void DedicatedWorker::OnWorkerHostCreated(
- mojo::ScopedMessagePipeHandle browser_interface_broker) {
+ CrossVariantMojoRemote<mojom::blink::BrowserInterfaceBrokerInterfaceBase>
+ browser_interface_broker) {
DCHECK(!browser_interface_broker_);
- browser_interface_broker_ =
- mojo::PendingRemote<mojom::blink::BrowserInterfaceBroker>(
- std::move(browser_interface_broker),
- mojom::blink::BrowserInterfaceBroker::Version_);
+ browser_interface_broker_ = std::move(browser_interface_broker);
}
void DedicatedWorker::OnScriptLoadStarted() {
@@ -471,14 +466,12 @@ void DedicatedWorker::ContextLifecycleStateChanged(
break;
case mojom::FrameLifecycleState::kFrozen:
case mojom::FrameLifecycleState::kFrozenAutoResumeMedia:
- factory_client_->LifecycleStateChanged(state);
if (!requested_frozen_) {
requested_frozen_ = true;
context_proxy_->Freeze();
}
break;
case mojom::FrameLifecycleState::kRunning:
- factory_client_->LifecycleStateChanged(state);
if (requested_frozen_) {
context_proxy_->Resume();
requested_frozen_ = false;
@@ -487,7 +480,7 @@ void DedicatedWorker::ContextLifecycleStateChanged(
}
}
-void DedicatedWorker::Trace(Visitor* visitor) {
+void DedicatedWorker::Trace(Visitor* visitor) const {
visitor->Trace(options_);
visitor->Trace(outside_fetch_client_settings_object_);
visitor->Trace(context_proxy_);
diff --git a/chromium/third_party/blink/renderer/core/workers/dedicated_worker.h b/chromium/third_party/blink/renderer/core/workers/dedicated_worker.h
index 2f5e6109697..7590e5f7e66 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker.h
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker.h
@@ -86,7 +86,8 @@ class CORE_EXPORT DedicatedWorker final
// Implements WebDedicatedWorker.
// Called only when PlzDedicatedWorker is enabled.
void OnWorkerHostCreated(
- mojo::ScopedMessagePipeHandle browser_interface_broker) override;
+ CrossVariantMojoRemote<mojom::blink::BrowserInterfaceBrokerInterfaceBase>
+ browser_interface_broker) override;
void OnScriptLoadStarted() override;
void OnScriptLoadStartFailed() override;
@@ -95,7 +96,7 @@ class CORE_EXPORT DedicatedWorker final
DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
void ContextLifecycleStateChanged(mojom::FrameLifecycleState state) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Starts the worker.
diff --git a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
index 71d37009caf..1fc5345ba61 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
@@ -365,7 +365,7 @@ DedicatedWorkerObjectProxy& DedicatedWorkerGlobalScope::WorkerObjectProxy()
return static_cast<DedicatedWorkerThread*>(GetThread())->WorkerObjectProxy();
}
-void DedicatedWorkerGlobalScope::Trace(Visitor* visitor) {
+void DedicatedWorkerGlobalScope::Trace(Visitor* visitor) const {
visitor->Trace(animation_frame_provider_);
WorkerGlobalScope::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
index eda1c4f4ee7..e91902ec715 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
@@ -123,7 +123,7 @@ class CORE_EXPORT DedicatedWorkerGlobalScope final : public WorkerGlobalScope {
}
// Called by the Oilpan.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DidReceiveResponseForClassicScript(
diff --git a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc
index 448d1a2c71c..8868d12ebfe 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc
@@ -232,7 +232,7 @@ void DedicatedWorkerMessagingProxy::DispatchErrorEvent(
GetExecutionContext()->DispatchErrorEvent(event, mute_script_errors);
}
-void DedicatedWorkerMessagingProxy::Trace(Visitor* visitor) {
+void DedicatedWorkerMessagingProxy::Trace(Visitor* visitor) const {
visitor->Trace(worker_object_);
ThreadedMessagingProxyBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.h b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.h
index dad2f2ab86a..3c93d610a30 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.h
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.h
@@ -67,7 +67,7 @@ class CORE_EXPORT DedicatedWorkerMessagingProxy
return *worker_object_proxy_.get();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class DedicatedWorkerMessagingProxyForTest;
diff --git a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_test.cc b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_test.cc
index 0d9cafcf2d4..7ad6ada9650 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_test.cc
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_test.cc
@@ -155,7 +155,7 @@ class DedicatedWorkerMessagingProxyForTest
return static_cast<DedicatedWorkerThreadForTest*>(GetWorkerThread());
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
DedicatedWorkerMessagingProxy::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc b/chromium/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc
index 66e6f5ec091..ba75f12871e 100644
--- a/chromium/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc
+++ b/chromium/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc
@@ -119,16 +119,19 @@ TEST_F(MainThreadWorkletTest, ContentSecurityPolicy) {
// The "script-src 'self'" directive allows this.
EXPECT_TRUE(csp->AllowScriptFromSource(
- global_scope_->Url(), String(), IntegrityMetadataSet(), kParserInserted));
+ global_scope_->Url(), String(), IntegrityMetadataSet(), kParserInserted,
+ global_scope_->Url(), RedirectStatus::kNoRedirect));
// The "script-src https://allowed.example.com" should allow this.
- EXPECT_TRUE(csp->AllowScriptFromSource(KURL("https://allowed.example.com"),
- String(), IntegrityMetadataSet(),
- kParserInserted));
+ EXPECT_TRUE(csp->AllowScriptFromSource(
+ KURL("https://allowed.example.com"), String(), IntegrityMetadataSet(),
+ kParserInserted, KURL("https://allowed.example.com"),
+ RedirectStatus::kNoRedirect));
EXPECT_FALSE(csp->AllowScriptFromSource(
KURL("https://disallowed.example.com"), String(), IntegrityMetadataSet(),
- kParserInserted));
+ kParserInserted, KURL("https://disallowed.example.com"),
+ RedirectStatus::kNoRedirect));
}
TEST_F(MainThreadWorkletTest, UseCounter) {
diff --git a/chromium/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.cc b/chromium/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.cc
index ac1fc8b5900..60b60ee99e0 100644
--- a/chromium/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.cc
+++ b/chromium/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.cc
@@ -45,7 +45,7 @@ ParentExecutionContextTaskRunners::Get(TaskType type) {
return task_runners_.at(type);
}
-void ParentExecutionContextTaskRunners::Trace(Visitor* visitor) {
+void ParentExecutionContextTaskRunners::Trace(Visitor* visitor) const {
ExecutionContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h b/chromium/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h
index 0a910eabebd..401599019d0 100644
--- a/chromium/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h
+++ b/chromium/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h
@@ -44,7 +44,7 @@ class CORE_EXPORT ParentExecutionContextTaskRunners final
scoped_refptr<base::SingleThreadTaskRunner> Get(TaskType)
LOCKS_EXCLUDED(mutex_);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
using TaskRunnerHashMap = HashMap<TaskType,
diff --git a/chromium/third_party/blink/renderer/core/workers/shared_worker.cc b/chromium/third_party/blink/renderer/core/workers/shared_worker.cc
index b814a575ad2..b40973b0cce 100644
--- a/chromium/third_party/blink/renderer/core/workers/shared_worker.cc
+++ b/chromium/third_party/blink/renderer/core/workers/shared_worker.cc
@@ -99,9 +99,7 @@ SharedWorker* SharedWorker::Create(ExecutionContext* context,
UseCounter::Count(window, WebFeature::kFileAccessedSharedWorker);
}
- KURL script_url = ResolveURL(
- context, url, exception_state, mojom::RequestContextType::SHARED_WORKER,
- network::mojom::RequestDestination::kSharedWorker);
+ KURL script_url = ResolveURL(context, url, exception_state);
if (script_url.IsEmpty())
return nullptr;
@@ -161,7 +159,7 @@ bool SharedWorker::HasPendingActivity() const {
void SharedWorker::ContextLifecycleStateChanged(
mojom::FrameLifecycleState state) {}
-void SharedWorker::Trace(Visitor* visitor) {
+void SharedWorker::Trace(Visitor* visitor) const {
visitor->Trace(port_);
AbstractWorker::Trace(visitor);
Supplementable<SharedWorker>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/workers/shared_worker.h b/chromium/third_party/blink/renderer/core/workers/shared_worker.h
index 4b3c3433978..d75954eb8dc 100644
--- a/chromium/third_party/blink/renderer/core/workers/shared_worker.h
+++ b/chromium/third_party/blink/renderer/core/workers/shared_worker.h
@@ -70,7 +70,7 @@ class CORE_EXPORT SharedWorker final
bool HasPendingActivity() const final;
void ContextLifecycleStateChanged(mojom::FrameLifecycleState state) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<MessagePort> port_;
diff --git a/chromium/third_party/blink/renderer/core/workers/shared_worker_client_holder.cc b/chromium/third_party/blink/renderer/core/workers/shared_worker_client_holder.cc
index 3e61484883f..aa712d09d18 100644
--- a/chromium/third_party/blink/renderer/core/workers/shared_worker_client_holder.cc
+++ b/chromium/third_party/blink/renderer/core/workers/shared_worker_client_holder.cc
@@ -140,7 +140,7 @@ void SharedWorkerClientHolder::Connect(
blob_url_token.PassPipe(), mojom::blink::BlobURLToken::Version_));
}
-void SharedWorkerClientHolder::Trace(Visitor* visitor) {
+void SharedWorkerClientHolder::Trace(Visitor* visitor) const {
visitor->Trace(connector_);
visitor->Trace(client_receivers_);
Supplement<LocalDOMWindow>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/workers/shared_worker_client_holder.h b/chromium/third_party/blink/renderer/core/workers/shared_worker_client_holder.h
index 3e2bd9e3c29..5986c1bba5f 100644
--- a/chromium/third_party/blink/renderer/core/workers/shared_worker_client_holder.h
+++ b/chromium/third_party/blink/renderer/core/workers/shared_worker_client_holder.h
@@ -80,7 +80,7 @@ class CORE_EXPORT SharedWorkerClientHolder final
mojo::PendingRemote<mojom::blink::BlobURLToken>,
mojom::blink::WorkerOptionsPtr options);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
HeapMojoRemote<mojom::blink::SharedWorkerConnector> connector_;
diff --git a/chromium/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc b/chromium/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc
index 003eeb4c980..b04fab4c0e6 100644
--- a/chromium/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc
+++ b/chromium/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc
@@ -264,7 +264,7 @@ void SharedWorkerGlobalScope::ExceptionThrown(ErrorEvent* event) {
debugger->ExceptionThrown(GetThread(), event);
}
-void SharedWorkerGlobalScope::Trace(Visitor* visitor) {
+void SharedWorkerGlobalScope::Trace(Visitor* visitor) const {
visitor->Trace(appcache_host_);
WorkerGlobalScope::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/workers/shared_worker_global_scope.h b/chromium/third_party/blink/renderer/core/workers/shared_worker_global_scope.h
index 9ebf4afa07f..08d78b9fd1d 100644
--- a/chromium/third_party/blink/renderer/core/workers/shared_worker_global_scope.h
+++ b/chromium/third_party/blink/renderer/core/workers/shared_worker_global_scope.h
@@ -87,7 +87,7 @@ class CORE_EXPORT SharedWorkerGlobalScope final : public WorkerGlobalScope {
void OnAppCacheSelected();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DidReceiveResponseForClassicScript(
diff --git a/chromium/third_party/blink/renderer/core/workers/shared_worker_reporting_proxy.cc b/chromium/third_party/blink/renderer/core/workers/shared_worker_reporting_proxy.cc
index f62aded8c34..c0193e45277 100644
--- a/chromium/third_party/blink/renderer/core/workers/shared_worker_reporting_proxy.cc
+++ b/chromium/third_party/blink/renderer/core/workers/shared_worker_reporting_proxy.cc
@@ -117,7 +117,7 @@ void SharedWorkerReportingProxy::DidTerminateWorkerThread() {
CrossThreadUnretained(worker_)));
}
-void SharedWorkerReportingProxy::Trace(Visitor* visitor) {
+void SharedWorkerReportingProxy::Trace(Visitor* visitor) const {
visitor->Trace(parent_execution_context_task_runners_);
}
diff --git a/chromium/third_party/blink/renderer/core/workers/shared_worker_reporting_proxy.h b/chromium/third_party/blink/renderer/core/workers/shared_worker_reporting_proxy.h
index d07ed43fc37..fe9f774ea62 100644
--- a/chromium/third_party/blink/renderer/core/workers/shared_worker_reporting_proxy.h
+++ b/chromium/third_party/blink/renderer/core/workers/shared_worker_reporting_proxy.h
@@ -43,7 +43,7 @@ class SharedWorkerReportingProxy final
void WillDestroyWorkerGlobalScope() override {}
void DidTerminateWorkerThread() override;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// Not owned because this outlives the reporting proxy.
diff --git a/chromium/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc b/chromium/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc
index 4e4eb537c81..dc07ba1f23a 100644
--- a/chromium/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc
+++ b/chromium/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc
@@ -53,7 +53,7 @@ int ThreadedMessagingProxyBase::ProxyCount() {
return g_live_messaging_proxy_count;
}
-void ThreadedMessagingProxyBase::Trace(Visitor* visitor) {
+void ThreadedMessagingProxyBase::Trace(Visitor* visitor) const {
visitor->Trace(execution_context_);
}
diff --git a/chromium/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.h b/chromium/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.h
index d565596d50c..441d2d817ba 100644
--- a/chromium/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.h
+++ b/chromium/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.h
@@ -66,7 +66,7 @@ class CORE_EXPORT ThreadedMessagingProxyBase
// Number of live messaging proxies, used by leak detection.
static int ProxyCount();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
protected:
explicit ThreadedMessagingProxyBase(ExecutionContext*);
diff --git a/chromium/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc b/chromium/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc
index 1b0025264fe..d0e70e0b39d 100644
--- a/chromium/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc
+++ b/chromium/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc
@@ -81,7 +81,7 @@ void ThreadedWorkletMessagingProxy::Initialize(
thread_startup_data);
}
-void ThreadedWorkletMessagingProxy::Trace(Visitor* visitor) {
+void ThreadedWorkletMessagingProxy::Trace(Visitor* visitor) const {
ThreadedMessagingProxyBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h b/chromium/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h
index fa8a05799f6..bcdd975a523 100644
--- a/chromium/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h
+++ b/chromium/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h
@@ -38,7 +38,7 @@ class CORE_EXPORT ThreadedWorkletMessagingProxy
WorkletModuleResponsesMap*,
const base::Optional<WorkerBackingThreadStartupData>& = base::nullopt);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit ThreadedWorkletMessagingProxy(ExecutionContext*);
diff --git a/chromium/third_party/blink/renderer/core/workers/threaded_worklet_test.cc b/chromium/third_party/blink/renderer/core/workers/threaded_worklet_test.cc
index d3d601d60e8..ed970bc881a 100644
--- a/chromium/third_party/blink/renderer/core/workers/threaded_worklet_test.cc
+++ b/chromium/third_party/blink/renderer/core/workers/threaded_worklet_test.cc
@@ -106,18 +106,20 @@ class ThreadedWorkletThreadForTest : public WorkerThread {
ContentSecurityPolicy* csp = GlobalScope()->GetContentSecurityPolicy();
// The "script-src 'self'" directive allows this.
- EXPECT_TRUE(csp->AllowScriptFromSource(GlobalScope()->Url(), String(),
- IntegrityMetadataSet(),
- kParserInserted));
+ EXPECT_TRUE(csp->AllowScriptFromSource(
+ GlobalScope()->Url(), String(), IntegrityMetadataSet(), kParserInserted,
+ GlobalScope()->Url(), RedirectStatus::kNoRedirect));
// The "script-src https://allowed.example.com" should allow this.
- EXPECT_TRUE(csp->AllowScriptFromSource(KURL("https://allowed.example.com"),
- String(), IntegrityMetadataSet(),
- kParserInserted));
+ EXPECT_TRUE(csp->AllowScriptFromSource(
+ KURL("https://allowed.example.com"), String(), IntegrityMetadataSet(),
+ kParserInserted, KURL("https://allowed.example.com"),
+ RedirectStatus::kNoRedirect));
EXPECT_FALSE(csp->AllowScriptFromSource(
KURL("https://disallowed.example.com"), String(),
- IntegrityMetadataSet(), kParserInserted));
+ IntegrityMetadataSet(), kParserInserted,
+ KURL("https://disallowed.example.com"), RedirectStatus::kNoRedirect));
PostCrossThreadTask(*GetParentTaskRunnerForTesting(), FROM_HERE,
CrossThreadBindOnce(&test::ExitRunLoop));
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc b/chromium/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
index dc1858e41ce..c8a4f02e694 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
@@ -277,7 +277,7 @@ void WorkerClassicScriptLoader::DidFailRedirectCheck() {
NotifyError();
}
-void WorkerClassicScriptLoader::Trace(Visitor* visitor) {
+void WorkerClassicScriptLoader::Trace(Visitor* visitor) const {
visitor->Trace(threadable_loader_);
visitor->Trace(content_security_policy_);
visitor->Trace(fetch_client_settings_object_fetcher_);
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_classic_script_loader.h b/chromium/third_party/blink/renderer/core/workers/worker_classic_script_loader.h
index bbdf03d7a41..86754a7d517 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_classic_script_loader.h
+++ b/chromium/third_party/blink/renderer/core/workers/worker_classic_script_loader.h
@@ -131,7 +131,7 @@ class CORE_EXPORT WorkerClassicScriptLoader final
void DidFail(const ResourceError&) override;
void DidFailRedirectCheck() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void NotifyError();
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_clients.h b/chromium/third_party/blink/renderer/core/workers/worker_clients.h
index 479d2cf40a4..e4ebcfe7d76 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_clients.h
+++ b/chromium/third_party/blink/renderer/core/workers/worker_clients.h
@@ -49,7 +49,7 @@ class CORE_EXPORT WorkerClients final : public GarbageCollected<WorkerClients>,
public:
WorkerClients() = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
Supplementable<WorkerClients>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_global_scope.cc b/chromium/third_party/blink/renderer/core/workers/worker_global_scope.cc
index 487b17c2e23..4c20b7d4975 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_global_scope.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worker_global_scope.cc
@@ -178,6 +178,10 @@ void WorkerGlobalScope::Dispose() {
WorkerOrWorkletGlobalScope::Dispose();
}
+const base::UnguessableToken& WorkerGlobalScope::GetDevToolsToken() const {
+ return GetThread()->GetDevToolsWorkerToken();
+}
+
void WorkerGlobalScope::ExceptionUnhandled(int exception_id) {
ErrorEvent* event = pending_error_events_.Take(exception_id);
DCHECK(event);
@@ -249,7 +253,8 @@ void WorkerGlobalScope::ImportScriptsInternal(const Vector<String>& urls,
return;
}
if (!GetContentSecurityPolicy()->AllowScriptFromSource(
- url, AtomicString(), IntegrityMetadataSet(), kNotParserInserted)) {
+ url, AtomicString(), IntegrityMetadataSet(), kNotParserInserted,
+ url, RedirectStatus::kNoRedirect)) {
exception_state.ThrowDOMException(
DOMExceptionCode::kNetworkError,
"The script at '" + url.ElidedString() + "' failed to load.");
@@ -569,7 +574,7 @@ TrustedTypePolicyFactory* WorkerGlobalScope::GetTrustedTypes() const {
return trusted_types_.Get();
}
-void WorkerGlobalScope::Trace(Visitor* visitor) {
+void WorkerGlobalScope::Trace(Visitor* visitor) const {
visitor->Trace(location_);
visitor->Trace(navigator_);
visitor->Trace(pending_error_events_);
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_global_scope.h b/chromium/third_party/blink/renderer/core/workers/worker_global_scope.h
index 05935ca9706..16ae342a983 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_global_scope.h
+++ b/chromium/third_party/blink/renderer/core/workers/worker_global_scope.h
@@ -83,6 +83,7 @@ class CORE_EXPORT WorkerGlobalScope
bool IsClosing() const final { return closing_; }
void Dispose() override;
WorkerThread* GetThread() const final { return thread_; }
+ const base::UnguessableToken& GetDevToolsToken() const override;
void ExceptionUnhandled(int exception_id);
@@ -179,7 +180,7 @@ class CORE_EXPORT WorkerGlobalScope
base::TimeTicks TimeOrigin() const { return time_origin_; }
WorkerSettings* GetWorkerSettings() const { return worker_settings_.get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
virtual InstalledScriptsManager* GetInstalledScriptsManager() {
return nullptr;
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_module_tree_client.cc b/chromium/third_party/blink/renderer/core/workers/worker_module_tree_client.cc
index fd24be11440..c3a6cabae0e 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_module_tree_client.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worker_module_tree_client.cc
@@ -51,7 +51,7 @@ void WorkerModuleTreeClient::NotifyModuleTreeLoadFinished(
*module_script, base::nullopt /* v8_inspector::V8StackTraceId */);
}
-void WorkerModuleTreeClient::Trace(Visitor* visitor) {
+void WorkerModuleTreeClient::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
ModuleTreeClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_module_tree_client.h b/chromium/third_party/blink/renderer/core/workers/worker_module_tree_client.h
index 14d27127640..3bc995cc22d 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_module_tree_client.h
+++ b/chromium/third_party/blink/renderer/core/workers/worker_module_tree_client.h
@@ -22,7 +22,7 @@ class CORE_EXPORT WorkerModuleTreeClient final : public ModuleTreeClient {
// Implements ModuleTreeClient.
void NotifyModuleTreeLoadFinished(ModuleScript*) final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<ScriptState> script_state_;
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_navigator.cc b/chromium/third_party/blink/renderer/core/workers/worker_navigator.cc
index 99f3efbc7f1..041d106e451 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_navigator.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worker_navigator.cc
@@ -40,6 +40,7 @@ WorkerNavigator::WorkerNavigator(const String& user_agent,
const UserAgentMetadata& ua_metadata,
ExecutionContext* execution_context)
: ExecutionContextClient(execution_context),
+ NavigatorDeviceMemory(nullptr),
NavigatorLanguage(execution_context),
user_agent_(user_agent),
ua_metadata_(ua_metadata) {}
@@ -68,11 +69,12 @@ void WorkerNavigator::NotifyUpdate() {
*Event::Create(event_type_names::kLanguagechange));
}
-void WorkerNavigator::Trace(Visitor* visitor) {
+void WorkerNavigator::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
NavigatorLanguage::Trace(visitor);
Supplementable<WorkerNavigator>::Trace(visitor);
+ NavigatorDeviceMemory::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_navigator.h b/chromium/third_party/blink/renderer/core/workers/worker_navigator.h
index 553fb13d783..89f4e98725d 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_navigator.h
+++ b/chromium/third_party/blink/renderer/core/workers/worker_navigator.h
@@ -71,7 +71,7 @@ class CORE_EXPORT WorkerNavigator final
// AcceptLanguagesWatcher override
void NotifyUpdate() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
UserAgentMetadata GetUserAgentMetadata() const override {
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc b/chromium/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
index d39a0d26cec..46b20b944fd 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
@@ -66,7 +66,7 @@ class OutsideSettingsCSPDelegate final
DCHECK(global_scope_for_logging_->IsContextThread());
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(global_scope_for_logging_);
visitor->Trace(outside_settings_object_);
}
@@ -183,11 +183,10 @@ WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope(
std::unique_ptr<WebContentSettingsClient> content_settings_client,
scoped_refptr<WebWorkerFetchContext> web_worker_fetch_context,
WorkerReportingProxy& reporting_proxy)
- : ExecutionContext(isolate),
+ : ExecutionContext(isolate, agent),
security_context_(
SecurityContextInit(origin,
- MakeGarbageCollected<OriginTrialContext>(),
- agent),
+ MakeGarbageCollected<OriginTrialContext>()),
SecurityContext::kWorker),
name_(name),
parent_devtools_token_(parent_devtools_token),
@@ -359,7 +358,8 @@ ResourceFetcher* WorkerOrWorkletGlobalScope::CreateFetcherInternal(
fetcher->SetResourceLoadObserver(
MakeGarbageCollected<ResourceLoadObserverForWorker>(
*probe::ToCoreProbeSink(static_cast<ExecutionContext*>(this)),
- fetcher->GetProperties(), web_worker_fetch_context_));
+ fetcher->GetProperties(), web_worker_fetch_context_,
+ GetDevToolsToken()));
} else {
auto& properties =
*MakeGarbageCollected<DetachableResourceFetcherProperties>(
@@ -545,7 +545,7 @@ int WorkerOrWorkletGlobalScope::GetOutstandingThrottledLimit() const {
return 2;
}
-void WorkerOrWorkletGlobalScope::Trace(Visitor* visitor) {
+void WorkerOrWorkletGlobalScope::Trace(Visitor* visitor) const {
visitor->Trace(security_context_);
visitor->Trace(inside_settings_resource_fetcher_);
visitor->Trace(resource_fetchers_);
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h b/chromium/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
index e09324a71e5..80e3e0af519 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
+++ b/chromium/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
@@ -7,6 +7,7 @@
#include <bitset>
#include "base/single_thread_task_runner.h"
+#include "base/unguessable_token.h"
#include "services/network/public/mojom/fetch_api.mojom-blink-forward.h"
#include "services/network/public/mojom/web_sandbox_flags.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_url_request.h"
@@ -135,6 +136,7 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
const base::UnguessableToken& GetParentDevToolsToken() {
return parent_devtools_token_;
}
+ virtual const base::UnguessableToken& GetDevToolsToken() const = 0;
WorkerClients* Clients() const { return worker_clients_.Get(); }
@@ -150,7 +152,7 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
WorkerReportingProxy& ReportingProxy() { return reporting_proxy_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType) override;
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_thread.cc b/chromium/third_party/blink/renderer/core/workers/worker_thread.cc
index fe98ad619b9..05414c7fba0 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_thread.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worker_thread.cc
@@ -71,7 +71,6 @@ using ExitCode = WorkerThread::ExitCode;
namespace {
-// TODO(nhiroki): Adjust the delay based on UMA.
constexpr base::TimeDelta kForcibleTerminationDelay =
base::TimeDelta::FromSeconds(2);
@@ -322,11 +321,7 @@ void WorkerThread::DidProcessTask(const base::PendingTask& pending_task) {
// TODO(tzik): Move this to WorkerThreadScheduler::OnTaskCompleted(), so that
// metrics for microtasks are counted as a part of the preceding task.
- // TODO(nhiroki): Replace this null check with DCHECK(agent) after making
- // WorkletGlobalScope take a proper Agent.
- if (Agent* agent = GlobalScope()->GetAgent()) {
- agent->event_loop()->PerformMicrotaskCheckpoint();
- }
+ GlobalScope()->GetAgent()->event_loop()->PerformMicrotaskCheckpoint();
// Microtask::PerformCheckpoint() runs microtasks and its completion hooks for
// the default microtask queue. The default queue may contain the microtasks
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet.cc b/chromium/third_party/blink/renderer/core/workers/worklet.cc
index 9148ae9a367..263cff9ee8a 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worklet.cc
@@ -189,7 +189,7 @@ wtf_size_t Worklet::SelectGlobalScope() {
return 0u;
}
-void Worklet::Trace(Visitor* visitor) {
+void Worklet::Trace(Visitor* visitor) const {
visitor->Trace(proxies_);
visitor->Trace(module_responses_map_);
visitor->Trace(pending_tasks_set_);
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet.h b/chromium/third_party/blink/renderer/core/workers/worklet.h
index 4b747f7cb87..5a5f200cd6b 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet.h
+++ b/chromium/third_party/blink/renderer/core/workers/worklet.h
@@ -51,7 +51,7 @@ class CORE_EXPORT Worklet : public ScriptWrappable,
// Called by WorkletPendingTasks to notify the Worklet.
void FinishPendingTasks(WorkletPendingTasks*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit Worklet(LocalDOMWindow&);
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet_global_scope.cc b/chromium/third_party/blink/renderer/core/workers/worklet_global_scope.cc
index 5f2f2a191ae..a8f908f9b1e 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet_global_scope.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worklet_global_scope.cc
@@ -191,6 +191,13 @@ WorkerThread* WorkletGlobalScope::GetThread() const {
return worker_thread_;
}
+const base::UnguessableToken& WorkletGlobalScope::GetDevToolsToken() const {
+ if (IsMainThreadWorkletGlobalScope()) {
+ return frame_->GetDevToolsFrameToken();
+ }
+ return GetThread()->GetDevToolsWorkerToken();
+}
+
CoreProbeSink* WorkletGlobalScope::GetProbeSink() {
if (IsMainThreadWorkletGlobalScope())
return probe::ToCoreProbeSink(frame_);
@@ -275,7 +282,7 @@ void WorkletGlobalScope::BindContentSecurityPolicyToExecutionContext() {
GetContentSecurityPolicy()->SetupSelf(*document_security_origin_);
}
-void WorkletGlobalScope::Trace(Visitor* visitor) {
+void WorkletGlobalScope::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
WorkerOrWorkletGlobalScope::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet_global_scope.h b/chromium/third_party/blink/renderer/core/workers/worklet_global_scope.h
index f6153a47998..bf720df7dfc 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet_global_scope.h
+++ b/chromium/third_party/blink/renderer/core/workers/worklet_global_scope.h
@@ -68,6 +68,7 @@ class CORE_EXPORT WorkletGlobalScope
// WorkerOrWorkletGlobalScope
void Dispose() override;
WorkerThread* GetThread() const final;
+ const base::UnguessableToken& GetDevToolsToken() const override;
virtual LocalFrame* GetFrame() const;
@@ -101,7 +102,7 @@ class CORE_EXPORT WorkletGlobalScope
// document.
bool DocumentSecureContext() const { return document_secure_context_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
HttpsState GetHttpsState() const override { return https_state_; }
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet_module_responses_map.h b/chromium/third_party/blink/renderer/core/workers/worklet_module_responses_map.h
index f217ebf92cb..92fcebc86c4 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet_module_responses_map.h
+++ b/chromium/third_party/blink/renderer/core/workers/worklet_module_responses_map.h
@@ -56,7 +56,7 @@ class CORE_EXPORT WorkletModuleResponsesMap final
// Called on main thread.
void Dispose() LOCKS_EXCLUDED(mutex_);
- void Trace(Visitor*) {}
+ void Trace(Visitor*) const {}
private:
class Entry final {
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet_module_responses_map_test.cc b/chromium/third_party/blink/renderer/core/workers/worklet_module_responses_map_test.cc
index 6e33782257a..41754f28022 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet_module_responses_map_test.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worklet_module_responses_map_test.cc
@@ -94,7 +94,8 @@ class WorkletModuleResponsesMapTest : public testing::Test {
TEST_F(WorkletModuleResponsesMapTest, Basic) {
const KURL kUrl("https://example.com/module.js");
url_test_helpers::RegisterMockedURLLoad(
- kUrl, test::CoreTestDataPath("module.js"), "text/javascript");
+ kUrl, test::CoreTestDataPath("module.js"), "text/javascript",
+ platform_->GetURLLoaderMockFactory());
HeapVector<Member<ClientImpl>> clients;
// An initial read call initiates a fetch request.
@@ -124,7 +125,8 @@ TEST_F(WorkletModuleResponsesMapTest, Basic) {
TEST_F(WorkletModuleResponsesMapTest, Failure) {
const KURL kUrl("https://example.com/module.js");
- url_test_helpers::RegisterMockedErrorURLLoad(kUrl);
+ url_test_helpers::RegisterMockedErrorURLLoad(
+ kUrl, platform_->GetURLLoaderMockFactory());
HeapVector<Member<ClientImpl>> clients;
// An initial read call initiates a fetch request.
@@ -155,9 +157,11 @@ TEST_F(WorkletModuleResponsesMapTest, Failure) {
TEST_F(WorkletModuleResponsesMapTest, Isolation) {
const KURL kUrl1("https://example.com/module?1.js");
const KURL kUrl2("https://example.com/module?2.js");
- url_test_helpers::RegisterMockedErrorURLLoad(kUrl1);
+ url_test_helpers::RegisterMockedErrorURLLoad(
+ kUrl1, platform_->GetURLLoaderMockFactory());
url_test_helpers::RegisterMockedURLLoad(
- kUrl2, test::CoreTestDataPath("module.js"), "text/javascript");
+ kUrl2, test::CoreTestDataPath("module.js"), "text/javascript",
+ platform_->GetURLLoaderMockFactory());
HeapVector<Member<ClientImpl>> clients;
// An initial read call for |kUrl1| initiates a fetch request.
@@ -230,9 +234,11 @@ TEST_F(WorkletModuleResponsesMapTest, Dispose) {
const KURL kUrl1("https://example.com/module?1.js");
const KURL kUrl2("https://example.com/module?2.js");
url_test_helpers::RegisterMockedURLLoad(
- kUrl1, test::CoreTestDataPath("module.js"), "text/javascript");
+ kUrl1, test::CoreTestDataPath("module.js"), "text/javascript",
+ platform_->GetURLLoaderMockFactory());
url_test_helpers::RegisterMockedURLLoad(
- kUrl2, test::CoreTestDataPath("module.js"), "text/javascript");
+ kUrl2, test::CoreTestDataPath("module.js"), "text/javascript",
+ platform_->GetURLLoaderMockFactory());
HeapVector<Member<ClientImpl>> clients;
// An initial read call for |kUrl1| creates a placeholder entry and asks the
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet_module_tree_client.cc b/chromium/third_party/blink/renderer/core/workers/worklet_module_tree_client.cc
index 3e0011f7ba8..45fdc924af9 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet_module_tree_client.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worklet_module_tree_client.cc
@@ -89,7 +89,7 @@ void WorkletModuleTreeClient::NotifyModuleTreeLoadFinished(
WrapCrossThreadPersistent(pending_tasks_.Get())));
}
-void WorkletModuleTreeClient::Trace(Visitor* visitor) {
+void WorkletModuleTreeClient::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
ModuleTreeClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet_module_tree_client.h b/chromium/third_party/blink/renderer/core/workers/worklet_module_tree_client.h
index 47eb608031f..8f3c179d885 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet_module_tree_client.h
+++ b/chromium/third_party/blink/renderer/core/workers/worklet_module_tree_client.h
@@ -26,7 +26,7 @@ class WorkletModuleTreeClient final : public ModuleTreeClient {
// Implements ModuleTreeClient.
void NotifyModuleTreeLoadFinished(ModuleScript*) final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<ScriptState> script_state_;
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet_pending_tasks.cc b/chromium/third_party/blink/renderer/core/workers/worklet_pending_tasks.cc
index 4c41608d98e..865ed0b3c0c 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet_pending_tasks.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worklet_pending_tasks.cc
@@ -71,7 +71,7 @@ void WorkletPendingTasks::DecrementCounter() {
}
}
-void WorkletPendingTasks::Trace(Visitor* visitor) {
+void WorkletPendingTasks::Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
visitor->Trace(worklet_);
}
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet_pending_tasks.h b/chromium/third_party/blink/renderer/core/workers/worklet_pending_tasks.h
index d70936fc7ed..91a64871fa4 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet_pending_tasks.h
+++ b/chromium/third_party/blink/renderer/core/workers/worklet_pending_tasks.h
@@ -37,7 +37,7 @@ class CORE_EXPORT WorkletPendingTasks final
// Decrements |counter_| and resolves the promise if the counter becomes 0.
void DecrementCounter();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
// The number of pending tasks. -1 indicates these tasks are aborted and
diff --git a/chromium/third_party/blink/renderer/core/xml/document_xpath_evaluator.cc b/chromium/third_party/blink/renderer/core/xml/document_xpath_evaluator.cc
index 7d520cd9662..c38a7b43be0 100644
--- a/chromium/third_party/blink/renderer/core/xml/document_xpath_evaluator.cc
+++ b/chromium/third_party/blink/renderer/core/xml/document_xpath_evaluator.cc
@@ -82,7 +82,7 @@ XPathResult* DocumentXPathEvaluator::evaluate(Document& document,
expression, context_node, resolver, type, ScriptValue(), exception_state);
}
-void DocumentXPathEvaluator::Trace(Visitor* visitor) {
+void DocumentXPathEvaluator::Trace(Visitor* visitor) const {
visitor->Trace(xpath_evaluator_);
Supplement<Document>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/xml/document_xpath_evaluator.h b/chromium/third_party/blink/renderer/core/xml/document_xpath_evaluator.h
index 2ec9d4603c4..c08ea5df359 100644
--- a/chromium/third_party/blink/renderer/core/xml/document_xpath_evaluator.h
+++ b/chromium/third_party/blink/renderer/core/xml/document_xpath_evaluator.h
@@ -60,7 +60,7 @@ class CORE_EXPORT DocumentXPathEvaluator final
ExceptionState&);
explicit DocumentXPathEvaluator(Document&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<XPathEvaluator> xpath_evaluator_;
diff --git a/chromium/third_party/blink/renderer/core/xml/document_xslt.cc b/chromium/third_party/blink/renderer/core/xml/document_xslt.cc
index 4ad397ea7a2..8fefbffd43f 100644
--- a/chromium/third_party/blink/renderer/core/xml/document_xslt.cc
+++ b/chromium/third_party/blink/renderer/core/xml/document_xslt.cc
@@ -55,7 +55,7 @@ class DOMContentLoadedListener final
EventListener* ToEventListener() override { return this; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(processing_instruction_);
NativeEventListener::Trace(visitor);
ProcessingInstruction::DetachableEventListener::Trace(visitor);
@@ -165,7 +165,7 @@ DocumentXSLT& DocumentXSLT::From(Document& document) {
return *supplement;
}
-void DocumentXSLT::Trace(Visitor* visitor) {
+void DocumentXSLT::Trace(Visitor* visitor) const {
visitor->Trace(transform_source_document_);
Supplement<Document>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/xml/document_xslt.h b/chromium/third_party/blink/renderer/core/xml/document_xslt.h
index 1b9fe11caf8..4e38f26a4c6 100644
--- a/chromium/third_party/blink/renderer/core/xml/document_xslt.h
+++ b/chromium/third_party/blink/renderer/core/xml/document_xslt.h
@@ -45,7 +45,7 @@ class DocumentXSLT final : public GarbageCollected<DocumentXSLT>,
static bool HasTransformSourceDocument(Document&);
explicit DocumentXSLT(Document&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Document> transform_source_document_;
diff --git a/chromium/third_party/blink/renderer/core/xml/dom_parser.cc b/chromium/third_party/blink/renderer/core/xml/dom_parser.cc
index e66ec1de7c2..c7e72fde5d4 100644
--- a/chromium/third_party/blink/renderer/core/xml/dom_parser.cc
+++ b/chromium/third_party/blink/renderer/core/xml/dom_parser.cc
@@ -20,7 +20,6 @@
#include "third_party/blink/renderer/core/xml/dom_parser.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/document_init.h"
-#include "third_party/blink/renderer/core/dom/dom_implementation.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -29,13 +28,12 @@
namespace blink {
Document* DOMParser::parseFromString(const String& str, const String& type) {
- Document* doc = DOMImplementation::createDocument(
- DocumentInit::Create()
- .WithURL(GetDocument()->Url())
- .WithTypeFrom(type)
- .WithContextDocument(GetDocument())
- .WithOwnerDocument(GetDocument())
- .WithContentSecurityPolicyFromContextDoc());
+ Document* doc = DocumentInit::Create()
+ .WithURL(GetDocument()->Url())
+ .WithTypeFrom(type)
+ .WithExecutionContext(window_)
+ .WithOwnerDocument(GetDocument())
+ .CreateDocument();
doc->SetContent(str);
doc->SetMimeType(AtomicString(type));
return doc;
@@ -44,7 +42,7 @@ Document* DOMParser::parseFromString(const String& str, const String& type) {
DOMParser::DOMParser(ScriptState* script_state)
: window_(LocalDOMWindow::From(script_state)) {}
-void DOMParser::Trace(Visitor* visitor) {
+void DOMParser::Trace(Visitor* visitor) const {
visitor->Trace(window_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/xml/dom_parser.h b/chromium/third_party/blink/renderer/core/xml/dom_parser.h
index 9bd336929f3..b4b45c8e866 100644
--- a/chromium/third_party/blink/renderer/core/xml/dom_parser.h
+++ b/chromium/third_party/blink/renderer/core/xml/dom_parser.h
@@ -42,7 +42,7 @@ class DOMParser final : public ScriptWrappable {
Document* parseFromString(const String&, const String& type);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
Document* GetDocument() const;
diff --git a/chromium/third_party/blink/renderer/core/xml/native_xpath_ns_resolver.cc b/chromium/third_party/blink/renderer/core/xml/native_xpath_ns_resolver.cc
index 3dadcfffe3d..21bc10d815c 100644
--- a/chromium/third_party/blink/renderer/core/xml/native_xpath_ns_resolver.cc
+++ b/chromium/third_party/blink/renderer/core/xml/native_xpath_ns_resolver.cc
@@ -42,7 +42,7 @@ AtomicString NativeXPathNSResolver::lookupNamespaceURI(const String& prefix) {
return node_ ? node_->lookupNamespaceURI(prefix) : g_null_atom;
}
-void NativeXPathNSResolver::Trace(Visitor* visitor) {
+void NativeXPathNSResolver::Trace(Visitor* visitor) const {
visitor->Trace(node_);
XPathNSResolver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/xml/native_xpath_ns_resolver.h b/chromium/third_party/blink/renderer/core/xml/native_xpath_ns_resolver.h
index 0898d698bd8..1e993921ca0 100644
--- a/chromium/third_party/blink/renderer/core/xml/native_xpath_ns_resolver.h
+++ b/chromium/third_party/blink/renderer/core/xml/native_xpath_ns_resolver.h
@@ -39,7 +39,7 @@ class NativeXPathNSResolver final : public XPathNSResolver {
AtomicString lookupNamespaceURI(const String& prefix) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Node> node_;
diff --git a/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc b/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
index 5de26fc1d9e..47a0718ed76 100644
--- a/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
+++ b/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
@@ -756,6 +756,7 @@ XMLDocumentParser::XMLDocumentParser(Document& document,
requesting_script_(false),
finish_called_(false),
xml_errors_(&document),
+ document_(&document),
script_runner_(frame_view
? MakeGarbageCollected<XMLParserScriptRunner>(this)
: nullptr), // Don't execute scripts for
@@ -783,6 +784,7 @@ XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment,
requesting_script_(false),
finish_called_(false),
xml_errors_(&fragment->GetDocument()),
+ document_(&fragment->GetDocument()),
script_runner_(nullptr), // Don't execute scripts for document fragments.
script_start_position_(TextPosition::BelowRangePosition()),
parsing_fragment_(true) {
@@ -827,11 +829,12 @@ XMLParserContext::~XMLParserContext() {
XMLDocumentParser::~XMLDocumentParser() = default;
-void XMLDocumentParser::Trace(Visitor* visitor) {
+void XMLDocumentParser::Trace(Visitor* visitor) const {
visitor->Trace(current_node_);
visitor->Trace(current_node_stack_);
visitor->Trace(leaf_text_node_);
visitor->Trace(xml_errors_);
+ visitor->Trace(document_);
visitor->Trace(script_runner_);
ScriptableDocumentParser::Trace(visitor);
XMLParserScriptRunnerHost::Trace(visitor);
@@ -1011,8 +1014,8 @@ void XMLDocumentParser::StartElementNs(const AtomicString& local_name,
q_name = QualifiedName(g_null_atom, prefix + ":" + local_name, g_null_atom);
Element* new_element = current_node_->GetDocument().CreateElement(
q_name,
- parsing_fragment_ ? CreateElementFlags::ByFragmentParser()
- : CreateElementFlags::ByParser(),
+ parsing_fragment_ ? CreateElementFlags::ByFragmentParser(document_)
+ : CreateElementFlags::ByParser(document_),
is);
if (!new_element) {
StopParsing();
diff --git a/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser.h b/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser.h
index e832a3e7657..df3e98c9851 100644
--- a/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser.h
+++ b/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser.h
@@ -77,7 +77,7 @@ class XMLDocumentParser final : public ScriptableDocumentParser,
explicit XMLDocumentParser(Document&, LocalFrameView* = nullptr);
XMLDocumentParser(DocumentFragment*, Element*, ParserContentPolicy);
~XMLDocumentParser() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Exposed for callbacks:
void HandleError(XMLErrors::ErrorType, const char* message, TextPosition);
@@ -218,6 +218,7 @@ class XMLDocumentParser final : public ScriptableDocumentParser,
XMLErrors xml_errors_;
+ Member<Document> document_;
Member<XMLParserScriptRunner> script_runner_;
TextPosition script_start_position_;
diff --git a/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser_test.cc b/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser_test.cc
index d23e1f8c451..109ef7220e0 100644
--- a/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser_test.cc
+++ b/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser_test.cc
@@ -13,7 +13,7 @@ namespace blink {
// crbug.com/932380
TEST(XMLDocumentParserTest, NodeNamespaceWithParseError) {
- auto& doc = *MakeGarbageCollected<Document>();
+ auto& doc = *Document::CreateForTest();
doc.SetContent(
"<html xmlns='http://www.w3.org/1999/xhtml'>"
"<body><d:foo/></body></html>");
diff --git a/chromium/third_party/blink/renderer/core/xml/parser/xml_errors.cc b/chromium/third_party/blink/renderer/core/xml/parser/xml_errors.cc
index 56452f12b27..64a41f47665 100644
--- a/chromium/third_party/blink/renderer/core/xml/parser/xml_errors.cc
+++ b/chromium/third_party/blink/renderer/core/xml/parser/xml_errors.cc
@@ -45,7 +45,7 @@ XMLErrors::XMLErrors(Document* document)
error_count_(0),
last_error_position_(TextPosition::BelowRangePosition()) {}
-void XMLErrors::Trace(Visitor* visitor) {
+void XMLErrors::Trace(Visitor* visitor) const {
visitor->Trace(document_);
}
@@ -95,7 +95,7 @@ void XMLErrors::AppendErrorMessage(const String& type_string,
static inline Element* CreateXHTMLParserErrorHeader(
Document* doc,
const String& error_messages) {
- const CreateElementFlags flags = CreateElementFlags::ByParser();
+ const CreateElementFlags flags = CreateElementFlags::ByParser(doc);
Element* report_element = doc->CreateRawElement(
QualifiedName(g_null_atom, "parsererror", html_names::xhtmlNamespaceURI),
flags);
@@ -135,7 +135,7 @@ void XMLErrors::InsertErrorMessageBlock() {
// manually and includes line/col info regarding where the errors are located)
// Create elements for display
- const CreateElementFlags flags = CreateElementFlags::ByParser();
+ const CreateElementFlags flags = CreateElementFlags::ByParser(document_);
Element* document_element = document_->documentElement();
if (!document_element) {
Element* root_element =
diff --git a/chromium/third_party/blink/renderer/core/xml/parser/xml_errors.h b/chromium/third_party/blink/renderer/core/xml/parser/xml_errors.h
index 7a0adf16219..8902ef81a0a 100644
--- a/chromium/third_party/blink/renderer/core/xml/parser/xml_errors.h
+++ b/chromium/third_party/blink/renderer/core/xml/parser/xml_errors.h
@@ -42,7 +42,7 @@ class XMLErrors {
public:
explicit XMLErrors(Document*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// Exposed for callbacks:
enum ErrorType { kErrorTypeWarning, kErrorTypeNonFatal, kErrorTypeFatal };
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_expression.cc b/chromium/third_party/blink/renderer/core/xml/xpath_expression.cc
index 0b112519a93..9331f37a15f 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_expression.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_expression.cc
@@ -53,7 +53,7 @@ XPathExpression* XPathExpression::CreateExpression(
return expr;
}
-void XPathExpression::Trace(Visitor* visitor) {
+void XPathExpression::Trace(Visitor* visitor) const {
visitor->Trace(top_expression_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_expression.h b/chromium/third_party/blink/renderer/core/xml/xpath_expression.h
index 76036cfd96d..faf381dbd35 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_expression.h
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_expression.h
@@ -57,7 +57,7 @@ class XPathExpression : public ScriptWrappable {
const ScriptValue&,
ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<xpath::Expression> top_expression_;
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_expression_node.cc b/chromium/third_party/blink/renderer/core/xml/xpath_expression_node.cc
index 02b43ac7e5b..3e695507b84 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_expression_node.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_expression_node.cc
@@ -45,7 +45,7 @@ Expression::Expression()
Expression::~Expression() = default;
-void Expression::Trace(Visitor* visitor) {
+void Expression::Trace(Visitor* visitor) const {
visitor->Trace(sub_expressions_);
ParseNode::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_expression_node.h b/chromium/third_party/blink/renderer/core/xml/xpath_expression_node.h
index e587ea4c224..6c24488c625 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_expression_node.h
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_expression_node.h
@@ -58,14 +58,14 @@ struct CORE_EXPORT EvaluationContext {
class CORE_EXPORT ParseNode : public GarbageCollected<ParseNode> {
public:
virtual ~ParseNode() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
class CORE_EXPORT Expression : public ParseNode {
public:
Expression();
~Expression() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
virtual Value Evaluate(EvaluationContext&) const = 0;
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_functions_test.cc b/chromium/third_party/blink/renderer/core/xml/xpath_functions_test.cc
index dfed2c080b9..794e042b911 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_functions_test.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_functions_test.cc
@@ -25,7 +25,7 @@ class XPathContext {
public:
XPathContext()
- : document_(MakeGarbageCollected<Document>()),
+ : document_(Document::CreateForTest()),
context_(*document_, had_type_conversion_error_) {}
xpath::EvaluationContext& Context() { return context_; }
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_node_set.h b/chromium/third_party/blink/renderer/core/xml/xpath_node_set.h
index 7ce4c803945..3cdf9139e62 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_node_set.h
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_node_set.h
@@ -41,7 +41,7 @@ class NodeSet final : public GarbageCollected<NodeSet> {
NodeSet() : is_sorted_(true), subtrees_are_disjoint_(false) {}
- void Trace(Visitor* visitor) { visitor->Trace(nodes_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(nodes_); }
wtf_size_t size() const { return nodes_.size(); }
bool IsEmpty() const { return !nodes_.size(); }
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_path.cc b/chromium/third_party/blink/renderer/core/xml/xpath_path.cc
index a62d43336ea..02c23e16583 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_path.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_path.cc
@@ -46,7 +46,7 @@ Filter::Filter(Expression* expr, HeapVector<Member<Predicate>>& predicates)
Filter::~Filter() = default;
-void Filter::Trace(Visitor* visitor) {
+void Filter::Trace(Visitor* visitor) const {
visitor->Trace(expr_);
visitor->Trace(predicates_);
Expression::Trace(visitor);
@@ -82,7 +82,7 @@ LocationPath::LocationPath() : absolute_(false) {
LocationPath::~LocationPath() = default;
-void LocationPath::Trace(Visitor* visitor) {
+void LocationPath::Trace(Visitor* visitor) const {
visitor->Trace(steps_);
Expression::Trace(visitor);
}
@@ -183,7 +183,7 @@ Path::Path(Expression* filter, LocationPath* path)
Path::~Path() = default;
-void Path::Trace(Visitor* visitor) {
+void Path::Trace(Visitor* visitor) const {
visitor->Trace(filter_);
visitor->Trace(path_);
Expression::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_path.h b/chromium/third_party/blink/renderer/core/xml/xpath_path.h
index f0c6c089d59..7dc8edc6502 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_path.h
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_path.h
@@ -41,7 +41,7 @@ class Filter final : public Expression {
public:
Filter(Expression*, HeapVector<Member<Predicate>>&);
~Filter() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
Value Evaluate(EvaluationContext&) const override;
@@ -56,7 +56,7 @@ class LocationPath final : public Expression {
public:
LocationPath();
~LocationPath() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
Value Evaluate(EvaluationContext&) const override;
void SetAbsolute(bool value) {
@@ -79,7 +79,7 @@ class Path final : public Expression {
public:
Path(Expression*, LocationPath*);
~Path() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
Value Evaluate(EvaluationContext&) const override;
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_predicate.cc b/chromium/third_party/blink/renderer/core/xml/xpath_predicate.cc
index 51eb97f7250..e94e6ddded3 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_predicate.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_predicate.cc
@@ -38,7 +38,7 @@ namespace xpath {
Number::Number(double value) : value_(value) {}
-void Number::Trace(Visitor* visitor) {
+void Number::Trace(Visitor* visitor) const {
visitor->Trace(value_);
Expression::Trace(visitor);
}
@@ -49,7 +49,7 @@ Value Number::Evaluate(EvaluationContext&) const {
StringExpression::StringExpression(const String& value) : value_(value) {}
-void StringExpression::Trace(Visitor* visitor) {
+void StringExpression::Trace(Visitor* visitor) const {
visitor->Trace(value_);
Expression::Trace(visitor);
}
@@ -262,7 +262,7 @@ Value Union::Evaluate(EvaluationContext& context) const {
Predicate::Predicate(Expression* expr) : expr_(expr) {}
-void Predicate::Trace(Visitor* visitor) {
+void Predicate::Trace(Visitor* visitor) const {
visitor->Trace(expr_);
}
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_predicate.h b/chromium/third_party/blink/renderer/core/xml/xpath_predicate.h
index a9846d6646b..f6b47e8bf4e 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_predicate.h
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_predicate.h
@@ -39,7 +39,7 @@ namespace xpath {
class CORE_EXPORT Number final : public Expression {
public:
explicit Number(double);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Value Evaluate(EvaluationContext&) const override;
@@ -51,7 +51,7 @@ class CORE_EXPORT Number final : public Expression {
class CORE_EXPORT StringExpression final : public Expression {
public:
explicit StringExpression(const String&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Value Evaluate(EvaluationContext&) const override;
@@ -120,7 +120,7 @@ class Union final : public Expression {
class Predicate final : public GarbageCollected<Predicate> {
public:
explicit Predicate(Expression*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
bool Evaluate(EvaluationContext&) const;
bool IsContextPositionSensitive() const {
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_result.cc b/chromium/third_party/blink/renderer/core/xml/xpath_result.cc
index 659e8d30604..9c0e7f58f29 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_result.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_result.cc
@@ -57,7 +57,7 @@ XPathResult::XPathResult(xpath::EvaluationContext& context,
NOTREACHED();
}
-void XPathResult::Trace(Visitor* visitor) {
+void XPathResult::Trace(Visitor* visitor) const {
visitor->Trace(value_);
visitor->Trace(node_set_);
visitor->Trace(document_);
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_result.h b/chromium/third_party/blink/renderer/core/xml/xpath_result.h
index 5d8de537cd2..06dd4538f52 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_result.h
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_result.h
@@ -77,7 +77,7 @@ class XPathResult final : public ScriptWrappable {
const xpath::Value& GetValue() const { return value_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
xpath::NodeSet& GetNodeSet() { return *node_set_; }
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_step.cc b/chromium/third_party/blink/renderer/core/xml/xpath_step.cc
index 1c816c3bab0..bf7cc05093d 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_step.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_step.cc
@@ -51,7 +51,7 @@ Step::Step(Axis axis,
Step::~Step() = default;
-void Step::Trace(Visitor* visitor) {
+void Step::Trace(Visitor* visitor) const {
visitor->Trace(node_test_);
visitor->Trace(predicates_);
ParseNode::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_step.h b/chromium/third_party/blink/renderer/core/xml/xpath_step.h
index 44c844188db..5d03a5437bf 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_step.h
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_step.h
@@ -85,7 +85,7 @@ class Step final : public ParseNode {
DCHECK(o.merged_predicates_.IsEmpty());
return *this;
}
- void Trace(Visitor* visitor) { visitor->Trace(merged_predicates_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(merged_predicates_); }
Kind GetKind() const { return kind_; }
const AtomicString& Data() const { return data_; }
@@ -110,7 +110,7 @@ class Step final : public ParseNode {
Step(Axis, const NodeTest&);
Step(Axis, const NodeTest&, HeapVector<Member<Predicate>>&);
~Step() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Optimize();
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_value.cc b/chromium/third_party/blink/renderer/core/xml/xpath_value.cc
index cafef7929f8..84b3e4dba55 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_value.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_value.cc
@@ -38,11 +38,11 @@ namespace xpath {
const Value::AdoptTag Value::kAdopt = {};
-void ValueData::Trace(Visitor* visitor) {
+void ValueData::Trace(Visitor* visitor) const {
visitor->Trace(node_set_);
}
-void Value::Trace(Visitor* visitor) {
+void Value::Trace(Visitor* visitor) const {
visitor->Trace(data_);
}
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_value.h b/chromium/third_party/blink/renderer/core/xml/xpath_value.h
index b10c629adce..6a25218cabf 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_value.h
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_value.h
@@ -46,7 +46,7 @@ class ValueData final : public GarbageCollected<ValueData> {
explicit ValueData(const String& string)
: string_(string), node_set_(NodeSet::Create()) {}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
NodeSet& GetNodeSet() { return *node_set_; }
String string_;
@@ -89,7 +89,7 @@ class CORE_EXPORT Value {
data_(MakeGarbageCollected<ValueData>()) {
data_->GetNodeSet().Append(value);
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// This is needed to safely implement constructing from bool - with normal
// function overloading, any pointer type would match.
diff --git a/chromium/third_party/blink/renderer/core/xml/xsl_style_sheet.h b/chromium/third_party/blink/renderer/core/xml/xsl_style_sheet.h
index 18da053f9c2..de3667e5c3c 100644
--- a/chromium/third_party/blink/renderer/core/xml/xsl_style_sheet.h
+++ b/chromium/third_party/blink/renderer/core/xml/xsl_style_sheet.h
@@ -82,7 +82,7 @@ class XSLStyleSheet final : public StyleSheet {
KURL BaseURL() const override { return final_url_; }
bool IsLoading() const override { return false; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void LoadChildSheets();
diff --git a/chromium/third_party/blink/renderer/core/xml/xsl_style_sheet_libxslt.cc b/chromium/third_party/blink/renderer/core/xml/xsl_style_sheet_libxslt.cc
index 23f535941d8..5376241322b 100644
--- a/chromium/third_party/blink/renderer/core/xml/xsl_style_sheet_libxslt.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xsl_style_sheet_libxslt.cc
@@ -321,7 +321,7 @@ void XSLStyleSheet::MarkAsProcessed() {
stylesheet_doc_taken_ = true;
}
-void XSLStyleSheet::Trace(Visitor* visitor) {
+void XSLStyleSheet::Trace(Visitor* visitor) const {
visitor->Trace(owner_node_);
visitor->Trace(children_);
visitor->Trace(parent_style_sheet_);
diff --git a/chromium/third_party/blink/renderer/core/xml/xslt_processor.cc b/chromium/third_party/blink/renderer/core/xml/xslt_processor.cc
index 49782f0c144..1549d0a44e6 100644
--- a/chromium/third_party/blink/renderer/core/xml/xslt_processor.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xslt_processor.cc
@@ -25,7 +25,6 @@
#include "third_party/blink/renderer/core/dom/document_encoding_data.h"
#include "third_party/blink/renderer/core/dom/document_fragment.h"
#include "third_party/blink/renderer/core/dom/document_init.h"
-#include "third_party/blink/renderer/core/dom/dom_implementation.h"
#include "third_party/blink/renderer/core/dom/ignore_opens_during_unload_count_incrementer.h"
#include "third_party/blink/renderer/core/editing/serializers/serialization.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
@@ -35,6 +34,7 @@
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/xml/document_xslt.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -68,6 +68,9 @@ Document* XSLTProcessor::CreateDocumentFromSource(
const String& source_mime_type,
Node* source_node,
LocalFrame* frame) {
+ if (!source_node->GetExecutionContext())
+ return nullptr;
+
KURL url = NullURL();
Document* owner_document = &source_node->GetDocument();
if (owner_document == source_node)
@@ -100,13 +103,21 @@ Document* XSLTProcessor::CreateDocumentFromSource(
DocumentInit::Create()
.WithURL(url)
.WithTypeFrom(mime_type)
- .WithContextDocument(owner_document->ContextDocument());
- Document* document = DOMImplementation::createDocument(init);
- DocumentEncodingData data;
- data.SetEncoding(source_encoding.IsEmpty()
- ? UTF8Encoding()
- : WTF::TextEncoding(source_encoding));
- document->SetEncodingData(data);
+ .WithExecutionContext(owner_document->GetExecutionContext());
+ Document* document = init.CreateDocument();
+ auto parsed_source_encoding = source_encoding.IsEmpty()
+ ? UTF8Encoding()
+ : WTF::TextEncoding(source_encoding);
+ if (parsed_source_encoding.IsValid()) {
+ DocumentEncodingData data;
+ data.SetEncoding(parsed_source_encoding);
+ document->SetEncodingData(data);
+ } else {
+ document_->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kXml,
+ mojom::blink::ConsoleMessageLevel::kWarning,
+ String("Document encoding not valid: ") + source_encoding));
+ }
document->SetContent(document_source);
return document;
}
@@ -166,7 +177,7 @@ void XSLTProcessor::reset() {
parameters_.clear();
}
-void XSLTProcessor::Trace(Visitor* visitor) {
+void XSLTProcessor::Trace(Visitor* visitor) const {
visitor->Trace(stylesheet_);
visitor->Trace(stylesheet_root_node_);
visitor->Trace(document_);
diff --git a/chromium/third_party/blink/renderer/core/xml/xslt_processor.h b/chromium/third_party/blink/renderer/core/xml/xslt_processor.h
index 2030e632e54..e501cf17c37 100644
--- a/chromium/third_party/blink/renderer/core/xml/xslt_processor.h
+++ b/chromium/third_party/blink/renderer/core/xml/xslt_processor.h
@@ -87,7 +87,7 @@ class XSLTProcessor final : public ScriptWrappable {
typedef HashMap<String, String> ParameterMap;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<XSLStyleSheet> stylesheet_;
diff --git a/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc b/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
index 2f3330e03ed..72031cfbcf2 100644
--- a/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
+++ b/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
@@ -37,12 +37,11 @@
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/platform/web_url_request.h"
-#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view_or_blob_or_document_or_string_or_form_data_or_url_search_params.h"
#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view_or_blob_or_usv_string.h"
+#include "third_party/blink/renderer/bindings/core/v8/document_or_xml_http_request_body_init.h"
#include "third_party/blink/renderer/core/dom/document_init.h"
#include "third_party/blink/renderer/core/dom/document_parser.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
-#include "third_party/blink/renderer/core/dom/dom_implementation.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/xml_document.h"
#include "third_party/blink/renderer/core/editing/serializers/serialization.h"
@@ -92,6 +91,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h"
#include "third_party/blink/renderer/platform/network/http_names.h"
#include "third_party/blink/renderer/platform/network/http_parsers.h"
+#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
#include "third_party/blink/renderer/platform/network/network_log.h"
#include "third_party/blink/renderer/platform/network/parsed_content_type.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -264,7 +264,7 @@ class XMLHttpRequest::BlobLoader final
void Cancel() { loader_->Cancel(); }
- void Trace(Visitor* visitor) { visitor->Trace(xhr_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(xhr_); }
private:
Member<XMLHttpRequest> xhr_;
@@ -355,10 +355,9 @@ void XMLHttpRequest::InitResponseDocument() {
}
DocumentInit init = DocumentInit::Create()
- .WithContextDocument(GetDocument()->ContextDocument())
- .WithOwnerDocument(GetDocument()->ContextDocument())
- .WithURL(response_.ResponseUrl())
- .WithContentSecurityPolicyFromContextDoc();
+ .WithExecutionContext(GetExecutionContext())
+ .WithOwnerDocument(GetDocument())
+ .WithURL(response_.ResponseUrl());
if (is_html)
response_document_ = MakeGarbageCollected<HTMLDocument>(init);
else
@@ -742,7 +741,7 @@ bool XMLHttpRequest::InitSend(ExceptionState& exception_state) {
if (!async_) {
if (GetExecutionContext()->IsDocument() &&
- !GetDocument()->IsFeatureEnabled(
+ !GetExecutionContext()->IsFeatureEnabled(
mojom::blink::FeaturePolicyFeature::kSyncXHR,
ReportOptions::kReportOnFailure,
"Synchronous requests are disabled by Feature Policy.")) {
@@ -762,7 +761,7 @@ bool XMLHttpRequest::InitSend(ExceptionState& exception_state) {
}
void XMLHttpRequest::send(
- const ArrayBufferOrArrayBufferViewOrBlobOrDocumentOrStringOrFormDataOrURLSearchParams&
+ const DocumentOrBlobOrArrayBufferOrArrayBufferViewOrFormDataOrURLSearchParamsOrUSVString&
body,
ExceptionState& exception_state) {
probe::WillSendXMLHttpOrFetchNetworkRequest(GetExecutionContext(), Url());
@@ -772,23 +771,23 @@ void XMLHttpRequest::send(
return;
}
- if (body.IsArrayBuffer()) {
- send(body.GetAsArrayBuffer(), exception_state);
+ if (body.IsDocument()) {
+ send(body.GetAsDocument(), exception_state);
return;
}
- if (body.IsArrayBufferView()) {
- send(body.GetAsArrayBufferView().View(), exception_state);
+ if (body.IsBlob()) {
+ send(body.GetAsBlob(), exception_state);
return;
}
- if (body.IsBlob()) {
- send(body.GetAsBlob(), exception_state);
+ if (body.IsArrayBuffer()) {
+ send(body.GetAsArrayBuffer(), exception_state);
return;
}
- if (body.IsDocument()) {
- send(body.GetAsDocument(), exception_state);
+ if (body.IsArrayBufferView()) {
+ send(body.GetAsArrayBufferView().View(), exception_state);
return;
}
@@ -802,8 +801,8 @@ void XMLHttpRequest::send(
return;
}
- DCHECK(body.IsString());
- send(body.GetAsString(), exception_state);
+ DCHECK(body.IsUSVString());
+ send(body.GetAsUSVString(), exception_state);
}
bool XMLHttpRequest::AreMethodAndURLValidForSend() {
@@ -1658,7 +1657,7 @@ void XMLHttpRequest::UpdateContentTypeAndCharset(
}
bool XMLHttpRequest::ResponseIsXML() const {
- return DOMImplementation::IsXMLMIMEType(FinalResponseMIMETypeWithFallback());
+ return MIMETypeRegistry::IsXMLMIMEType(FinalResponseMIMETypeWithFallback());
}
bool XMLHttpRequest::ResponseIsHTML() const {
@@ -1869,8 +1868,10 @@ void XMLHttpRequest::ParseDocumentChunk(const char* data, unsigned len) {
if (!response_document_)
return;
- response_document_parser_ =
- response_document_->ImplicitOpen(kAllowAsynchronousParsing);
+ response_document_parser_ = response_document_->ImplicitOpen(
+ RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()
+ ? kAllowDeferredParsing
+ : kAllowAsynchronousParsing);
response_document_parser_->AddClient(this);
}
DCHECK(response_document_parser_);
@@ -2093,7 +2094,7 @@ void XMLHttpRequest::ReportMemoryUsageToV8() {
isolate_->AdjustAmountOfExternalAllocatedMemory(diff);
}
-void XMLHttpRequest::Trace(Visitor* visitor) {
+void XMLHttpRequest::Trace(Visitor* visitor) const {
visitor->Trace(response_blob_);
visitor->Trace(loader_);
visitor->Trace(response_document_);
diff --git a/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h b/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
index bd835627bf1..665090c5741 100644
--- a/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
+++ b/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
@@ -55,7 +55,7 @@
namespace blink {
class
- ArrayBufferOrArrayBufferViewOrBlobOrDocumentOrStringOrFormDataOrURLSearchParams;
+ DocumentOrBlobOrArrayBufferOrArrayBufferViewOrFormDataOrURLSearchParamsOrUSVString;
class Blob;
class BlobDataHandle;
class DOMArrayBuffer;
@@ -136,7 +136,7 @@ class XMLHttpRequest final : public XMLHttpRequestEventTarget,
bool async,
ExceptionState&);
void send(
- const ArrayBufferOrArrayBufferViewOrBlobOrDocumentOrStringOrFormDataOrURLSearchParams&,
+ const DocumentOrBlobOrArrayBufferOrArrayBufferViewOrFormDataOrURLSearchParamsOrUSVString&,
ExceptionState&);
void abort();
void Dispose();
@@ -175,7 +175,7 @@ class XMLHttpRequest final : public XMLHttpRequestEventTarget,
DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange, kReadystatechange)
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override { return "XMLHttpRequest"; }
private:
diff --git a/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.idl b/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.idl
index 53f65e0d104..8ff21db2d0f 100644
--- a/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.idl
+++ b/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.idl
@@ -37,6 +37,9 @@ enum XMLHttpRequestResponseType {
"text",
};
+// This is in fetch.idl in the standard, but for simplicity we define it here.
+typedef (Blob or BufferSource or FormData or URLSearchParams or USVString) XMLHttpRequestBodyInit;
+
[
ActiveScriptWrappable,
Exposed=(Window,DedicatedWorker,SharedWorker)
@@ -61,9 +64,7 @@ enum XMLHttpRequestResponseType {
[RaisesException=Setter] attribute unsigned long timeout;
[RaisesException=Setter] attribute boolean withCredentials;
readonly attribute XMLHttpRequestUpload upload;
- // TODO(foolip): The data argument should be of type
- // (Document or BodyInit)?
- [RaisesException] void send(optional (ArrayBuffer or ArrayBufferView or Blob or Document or DOMString or FormData or URLSearchParams)? body = null);
+ [RaisesException] void send(optional (Document or XMLHttpRequestBodyInit)? body = null);
void abort();
// response
diff --git a/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.cc b/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.cc
index f200afc4acb..87bbe324ccd 100644
--- a/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.cc
+++ b/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.cc
@@ -175,7 +175,7 @@ void XMLHttpRequestProgressEventThrottle::Fired() {
StartOneShot(kMinimumProgressEventDispatchingInterval, FROM_HERE);
}
-void XMLHttpRequestProgressEventThrottle::Trace(Visitor* visitor) {
+void XMLHttpRequestProgressEventThrottle::Trace(Visitor* visitor) const {
visitor->Trace(target_);
}
diff --git a/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.h b/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.h
index 08ccd907b1d..f500267b0a7 100644
--- a/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.h
+++ b/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.h
@@ -83,7 +83,7 @@ class XMLHttpRequestProgressEventThrottle final
// depending on the value of the ProgressEventAction argument.
void DispatchReadyStateChangeEvent(Event*, DeferredEventAction);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// Dispatches a "progress" progress event and usually a readyStateChange
diff --git a/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.cc b/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.cc
index 017449dcadc..9379e974d37 100644
--- a/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.cc
+++ b/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.cc
@@ -84,7 +84,7 @@ void XMLHttpRequestUpload::HandleRequestError(const AtomicString& type) {
last_total_bytes_to_be_sent_);
}
-void XMLHttpRequestUpload::Trace(Visitor* visitor) {
+void XMLHttpRequestUpload::Trace(Visitor* visitor) const {
visitor->Trace(xml_http_request_);
XMLHttpRequestEventTarget::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.h b/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.h
index ee159c79338..791ef575b73 100644
--- a/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.h
+++ b/chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.h
@@ -53,7 +53,7 @@ class XMLHttpRequestUpload final : public XMLHttpRequestEventTarget {
void HandleRequestError(const AtomicString&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<XMLHttpRequest> xml_http_request_;